i386.md revision 237021
1;; GCC machine description for IA-32 and x86-64.
2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3;; 2001, 2002, 2003, 2004, 2005, 2006
4;; Free Software Foundation, Inc.
5;; Mostly by William Schelter.
6;; x86_64 support added by Jan Hubicka
7;;
8;; This file is part of GCC.
9;;
10;; GCC is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14;;
15;; GCC is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18;; GNU General Public License for more details.
19;;
20;; You should have received a copy of the GNU General Public License
21;; along with GCC; see the file COPYING.  If not, write to
22;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23;; Boston, MA 02110-1301, USA.  */
24;;
25;; The original PO technology requires these to be ordered by speed,
26;; so that assigner will pick the fastest.
27;;
28;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29;;
30;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31;; constraint letters.
32;;
33;; The special asm out single letter directives following a '%' are:
34;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35;;     operands[1].
36;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40;; 'S' Print the opcode suffix for a 32-bit float opcode.
41;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42;; 'J' Print the appropriate jump operand.
43;;
44;; 'b' Print the QImode name of the register for the indicated operand.
45;;     %b0 would print %al if operands[0] is reg 0.
46;; 'w' Likewise, print the HImode name of the register.
47;; 'k' Likewise, print the SImode name of the register.
48;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49;; 'y' Print "st(0)" instead of "st" as a register.
50
51;; UNSPEC usage:
52
53(define_constants
54  [; Relocation specifiers
55   (UNSPEC_GOT			0)
56   (UNSPEC_GOTOFF		1)
57   (UNSPEC_GOTPCREL		2)
58   (UNSPEC_GOTTPOFF		3)
59   (UNSPEC_TPOFF		4)
60   (UNSPEC_NTPOFF		5)
61   (UNSPEC_DTPOFF		6)
62   (UNSPEC_GOTNTPOFF		7)
63   (UNSPEC_INDNTPOFF		8)
64
65   ; Prologue support
66   (UNSPEC_STACK_ALLOC		11)
67   (UNSPEC_SET_GOT		12)
68   (UNSPEC_SSE_PROLOGUE_SAVE	13)
69   (UNSPEC_REG_SAVE		14)
70   (UNSPEC_DEF_CFA		15)
71
72   ; TLS support
73   (UNSPEC_TP			16)
74   (UNSPEC_TLS_GD		17)
75   (UNSPEC_TLS_LD_BASE		18)
76   (UNSPEC_TLSDESC		19)
77
78   ; Other random patterns
79   (UNSPEC_SCAS			20)
80   (UNSPEC_FNSTSW		21)
81   (UNSPEC_SAHF			22)
82   (UNSPEC_FSTCW		23)
83   (UNSPEC_ADD_CARRY		24)
84   (UNSPEC_FLDCW		25)
85   (UNSPEC_REP			26)
86   (UNSPEC_EH_RETURN		27)
87   (UNSPEC_LD_MPIC		28)	; load_macho_picbase
88
89   ; For SSE/MMX support:
90   (UNSPEC_FIX_NOTRUNC		30)
91   (UNSPEC_MASKMOV		31)
92   (UNSPEC_MOVMSK		32)
93   (UNSPEC_MOVNT		33)
94   (UNSPEC_MOVU			34)
95   (UNSPEC_RCP			35)
96   (UNSPEC_RSQRT		36)
97   (UNSPEC_SFENCE		37)
98   (UNSPEC_NOP			38)	; prevents combiner cleverness
99   (UNSPEC_PFRCP		39)
100   (UNSPEC_PFRCPIT1		40)
101   (UNSPEC_PFRCPIT2		41)
102   (UNSPEC_PFRSQRT		42)
103   (UNSPEC_PFRSQIT1		43)
104   (UNSPEC_MFENCE		44)
105   (UNSPEC_LFENCE		45)
106   (UNSPEC_PSADBW		46)
107   (UNSPEC_LDQQU		47)
108
109   ; Generic math support
110   (UNSPEC_COPYSIGN		50)
111   (UNSPEC_IEEE_MIN		51)	; not commutative
112   (UNSPEC_IEEE_MAX		52)	; not commutative
113
114   ; x87 Floating point
115   (UNSPEC_SIN			60)
116   (UNSPEC_COS			61)
117   (UNSPEC_FPATAN		62)
118   (UNSPEC_FYL2X		63)
119   (UNSPEC_FYL2XP1		64)
120   (UNSPEC_FRNDINT		65)
121   (UNSPEC_FIST			66)
122   (UNSPEC_F2XM1		67)
123
124   ; x87 Rounding
125   (UNSPEC_FRNDINT_FLOOR	70)
126   (UNSPEC_FRNDINT_CEIL 	71)
127   (UNSPEC_FRNDINT_TRUNC	72)
128   (UNSPEC_FRNDINT_MASK_PM	73)
129   (UNSPEC_FIST_FLOOR		74)
130   (UNSPEC_FIST_CEIL 		75)
131
132   ; x87 Double output FP
133   (UNSPEC_SINCOS_COS		80)
134   (UNSPEC_SINCOS_SIN		81)
135   (UNSPEC_TAN_ONE		82)
136   (UNSPEC_TAN_TAN		83)
137   (UNSPEC_XTRACT_FRACT		84)
138   (UNSPEC_XTRACT_EXP		85)
139   (UNSPEC_FSCALE_FRACT		86)
140   (UNSPEC_FSCALE_EXP		87)
141   (UNSPEC_FPREM_F		88)
142   (UNSPEC_FPREM_U		89)
143   (UNSPEC_FPREM1_F		90)
144   (UNSPEC_FPREM1_U		91)
145
146   ; SSP patterns
147   (UNSPEC_SP_SET		100)
148   (UNSPEC_SP_TEST		101)
149   (UNSPEC_SP_TLS_SET		102)
150   (UNSPEC_SP_TLS_TEST		103)
151
152   ; SSSE3
153   (UNSPEC_PSHUFB		120)
154   (UNSPEC_PSIGN		121)
155   (UNSPEC_PALIGNR		122)
156  ])
157
158(define_constants
159  [(UNSPECV_BLOCKAGE		0)
160   (UNSPECV_STACK_PROBE		1)
161   (UNSPECV_EMMS		2)
162   (UNSPECV_LDMXCSR		3)
163   (UNSPECV_STMXCSR		4)
164   (UNSPECV_FEMMS		5)
165   (UNSPECV_CLFLUSH		6)
166   (UNSPECV_ALIGN		7)
167   (UNSPECV_MONITOR		8)
168   (UNSPECV_MWAIT		9)
169   (UNSPECV_CMPXCHG_1		10)
170   (UNSPECV_CMPXCHG_2		11)
171   (UNSPECV_XCHG		12)
172   (UNSPECV_LOCK		13)
173  ])
174
175;; Registers by name.
176(define_constants
177  [(BP_REG			 6)
178   (SP_REG			 7)
179   (FLAGS_REG			17)
180   (FPSR_REG			18)
181   (DIRFLAG_REG			19)
182  ])
183
184;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
185;; from i386.c.
186
187;; In C guard expressions, put expressions which may be compile-time
188;; constants first.  This allows for better optimization.  For
189;; example, write "TARGET_64BIT && reload_completed", not
190;; "reload_completed && TARGET_64BIT".
191
192
193;; Processor type.  This attribute must exactly match the processor_type
194;; enumeration in i386.h.
195(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
196  (const (symbol_ref "ix86_tune")))
197
198;; A basic instruction type.  Refinements due to arguments to be
199;; provided in other attributes.
200(define_attr "type"
201  "other,multi,
202   alu,alu1,negnot,imov,imovx,lea,
203   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
204   icmp,test,ibr,setcc,icmov,
205   push,pop,call,callv,leave,
206   str,cld,
207   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
208   sselog,sselog1,sseiadd,sseishft,sseimul,
209   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
210   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
211  (const_string "other"))
212
213;; Main data type used by the insn
214(define_attr "mode"
215  "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
216  (const_string "unknown"))
217
218;; The CPU unit operations uses.
219(define_attr "unit" "integer,i387,sse,mmx,unknown"
220  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
221	   (const_string "i387")
222	 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
223			  sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
224	   (const_string "sse")
225	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
226	   (const_string "mmx")
227	 (eq_attr "type" "other")
228	   (const_string "unknown")]
229	 (const_string "integer")))
230
231;; The (bounding maximum) length of an instruction immediate.
232(define_attr "length_immediate" ""
233  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
234	   (const_int 0)
235	 (eq_attr "unit" "i387,sse,mmx")
236	   (const_int 0)
237	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
238			  imul,icmp,push,pop")
239	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
240	 (eq_attr "type" "imov,test")
241	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
242	 (eq_attr "type" "call")
243	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
244	     (const_int 4)
245	     (const_int 0))
246	 (eq_attr "type" "callv")
247	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
248	     (const_int 4)
249	     (const_int 0))
250	 ;; We don't know the size before shorten_branches.  Expect
251	 ;; the instruction to fit for better scheduling.
252	 (eq_attr "type" "ibr")
253	   (const_int 1)
254	 ]
255	 (symbol_ref "/* Update immediate_length and other attributes! */
256		      gcc_unreachable (),1")))
257
258;; The (bounding maximum) length of an instruction address.
259(define_attr "length_address" ""
260  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
261	   (const_int 0)
262	 (and (eq_attr "type" "call")
263	      (match_operand 0 "constant_call_address_operand" ""))
264	     (const_int 0)
265	 (and (eq_attr "type" "callv")
266	      (match_operand 1 "constant_call_address_operand" ""))
267	     (const_int 0)
268	 ]
269	 (symbol_ref "ix86_attr_length_address_default (insn)")))
270
271;; Set when length prefix is used.
272(define_attr "prefix_data16" ""
273  (if_then_else (ior (eq_attr "mode" "HI")
274		     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
275    (const_int 1)
276    (const_int 0)))
277
278;; Set when string REP prefix is used.
279(define_attr "prefix_rep" "" 
280  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
281    (const_int 1)
282    (const_int 0)))
283
284;; Set when 0f opcode prefix is used.
285(define_attr "prefix_0f" ""
286  (if_then_else 
287    (ior (eq_attr "type" "imovx,setcc,icmov")
288	 (eq_attr "unit" "sse,mmx"))
289    (const_int 1)
290    (const_int 0)))
291
292;; Set when REX opcode prefix is used.
293(define_attr "prefix_rex" ""
294  (cond [(and (eq_attr "mode" "DI")
295  	      (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
296	   (const_int 1)
297	 (and (eq_attr "mode" "QI")
298	      (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
299		  (const_int 0)))
300	   (const_int 1)
301	 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
302	     (const_int 0))
303	   (const_int 1)
304	]
305	(const_int 0)))
306
307;; Set when modrm byte is used.
308(define_attr "modrm" ""
309  (cond [(eq_attr "type" "str,cld,leave")
310	   (const_int 0)
311	 (eq_attr "unit" "i387")
312	   (const_int 0)
313         (and (eq_attr "type" "incdec")
314	      (ior (match_operand:SI 1 "register_operand" "")
315		   (match_operand:HI 1 "register_operand" "")))
316	   (const_int 0)
317	 (and (eq_attr "type" "push")
318	      (not (match_operand 1 "memory_operand" "")))
319	   (const_int 0)
320	 (and (eq_attr "type" "pop")
321	      (not (match_operand 0 "memory_operand" "")))
322	   (const_int 0)
323	 (and (eq_attr "type" "imov")
324	      (ior (and (match_operand 0 "register_operand" "")
325			(match_operand 1 "immediate_operand" ""))
326		   (ior (and (match_operand 0 "ax_reg_operand" "")
327			     (match_operand 1 "memory_displacement_only_operand" ""))
328			(and (match_operand 0 "memory_displacement_only_operand" "")
329			     (match_operand 1 "ax_reg_operand" "")))))
330	   (const_int 0)
331	 (and (eq_attr "type" "call")
332	      (match_operand 0 "constant_call_address_operand" ""))
333	     (const_int 0)
334	 (and (eq_attr "type" "callv")
335	      (match_operand 1 "constant_call_address_operand" ""))
336	     (const_int 0)
337	 ]
338	 (const_int 1)))
339
340;; The (bounding maximum) length of an instruction in bytes.
341;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
342;; Later we may want to split them and compute proper length as for
343;; other insns.
344(define_attr "length" ""
345  (cond [(eq_attr "type" "other,multi,fistp,frndint")
346	   (const_int 16)
347	 (eq_attr "type" "fcmp")
348	   (const_int 4)
349	 (eq_attr "unit" "i387")
350	   (plus (const_int 2)
351		 (plus (attr "prefix_data16")
352		       (attr "length_address")))]
353	 (plus (plus (attr "modrm")
354		     (plus (attr "prefix_0f")
355			   (plus (attr "prefix_rex")
356				 (const_int 1))))
357	       (plus (attr "prefix_rep")
358		     (plus (attr "prefix_data16")
359			   (plus (attr "length_immediate")
360				 (attr "length_address")))))))
361
362;; The `memory' attribute is `none' if no memory is referenced, `load' or
363;; `store' if there is a simple memory reference therein, or `unknown'
364;; if the instruction is complex.
365
366(define_attr "memory" "none,load,store,both,unknown"
367  (cond [(eq_attr "type" "other,multi,str")
368	   (const_string "unknown")
369	 (eq_attr "type" "lea,fcmov,fpspc,cld")
370	   (const_string "none")
371	 (eq_attr "type" "fistp,leave")
372	   (const_string "both")
373	 (eq_attr "type" "frndint")
374	   (const_string "load")
375	 (eq_attr "type" "push")
376	   (if_then_else (match_operand 1 "memory_operand" "")
377	     (const_string "both")
378	     (const_string "store"))
379	 (eq_attr "type" "pop")
380	   (if_then_else (match_operand 0 "memory_operand" "")
381	     (const_string "both")
382	     (const_string "load"))
383	 (eq_attr "type" "setcc")
384	   (if_then_else (match_operand 0 "memory_operand" "")
385	     (const_string "store")
386	     (const_string "none"))
387	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
388	   (if_then_else (ior (match_operand 0 "memory_operand" "")
389			      (match_operand 1 "memory_operand" ""))
390	     (const_string "load")
391	     (const_string "none"))
392	 (eq_attr "type" "ibr")
393	   (if_then_else (match_operand 0 "memory_operand" "")
394	     (const_string "load")
395	     (const_string "none"))
396	 (eq_attr "type" "call")
397	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
398	     (const_string "none")
399	     (const_string "load"))
400	 (eq_attr "type" "callv")
401	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
402	     (const_string "none")
403	     (const_string "load"))
404	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
405	      (match_operand 1 "memory_operand" ""))
406	   (const_string "both")
407	 (and (match_operand 0 "memory_operand" "")
408	      (match_operand 1 "memory_operand" ""))
409	   (const_string "both")
410	 (match_operand 0 "memory_operand" "")
411	   (const_string "store")
412	 (match_operand 1 "memory_operand" "")
413	   (const_string "load")
414	 (and (eq_attr "type"
415		 "!alu1,negnot,ishift1,
416		   imov,imovx,icmp,test,
417		   fmov,fcmp,fsgn,
418		   sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
419		   mmx,mmxmov,mmxcmp,mmxcvt")
420	      (match_operand 2 "memory_operand" ""))
421	   (const_string "load")
422	 (and (eq_attr "type" "icmov")
423	      (match_operand 3 "memory_operand" ""))
424	   (const_string "load")
425	]
426	(const_string "none")))
427
428;; Indicates if an instruction has both an immediate and a displacement.
429
430(define_attr "imm_disp" "false,true,unknown"
431  (cond [(eq_attr "type" "other,multi")
432	   (const_string "unknown")
433	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
434	      (and (match_operand 0 "memory_displacement_operand" "")
435		   (match_operand 1 "immediate_operand" "")))
436	   (const_string "true")
437	 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
438	      (and (match_operand 0 "memory_displacement_operand" "")
439		   (match_operand 2 "immediate_operand" "")))
440	   (const_string "true")
441	]
442	(const_string "false")))
443
444;; Indicates if an FP operation has an integer source.
445
446(define_attr "fp_int_src" "false,true"
447  (const_string "false"))
448
449;; Defines rounding mode of an FP operation.
450
451(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
452  (const_string "any"))
453
454;; Describe a user's asm statement.
455(define_asm_attributes
456  [(set_attr "length" "128")
457   (set_attr "type" "multi")])
458
459;; All x87 floating point modes
460(define_mode_macro X87MODEF [SF DF XF])
461 
462;; All integer modes handled by x87 fisttp operator.
463(define_mode_macro X87MODEI [HI SI DI])
464
465;; All integer modes handled by integer x87 operators.
466(define_mode_macro X87MODEI12 [HI SI])
467
468;; All SSE floating point modes
469(define_mode_macro SSEMODEF [SF DF])
470 
471;; All integer modes handled by SSE cvtts?2si* operators.
472(define_mode_macro SSEMODEI24 [SI DI])
473
474
475;; Scheduling descriptions
476
477(include "pentium.md")
478(include "ppro.md")
479(include "k6.md")
480(include "athlon.md")
481(include "geode.md")
482
483
484;; Operand and operator predicates and constraints
485
486(include "predicates.md")
487(include "constraints.md")
488
489
490;; Compare instructions.
491
492;; All compare insns have expanders that save the operands away without
493;; actually generating RTL.  The bCOND or sCOND (emitted immediately
494;; after the cmp) will actually emit the cmpM.
495
496(define_expand "cmpti"
497  [(set (reg:CC FLAGS_REG)
498	(compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
499		    (match_operand:TI 1 "x86_64_general_operand" "")))]
500  "TARGET_64BIT"
501{
502  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
503    operands[0] = force_reg (TImode, operands[0]);
504  ix86_compare_op0 = operands[0];
505  ix86_compare_op1 = operands[1];
506  DONE;
507})
508
509(define_expand "cmpdi"
510  [(set (reg:CC FLAGS_REG)
511	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
512		    (match_operand:DI 1 "x86_64_general_operand" "")))]
513  ""
514{
515  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
516    operands[0] = force_reg (DImode, operands[0]);
517  ix86_compare_op0 = operands[0];
518  ix86_compare_op1 = operands[1];
519  DONE;
520})
521
522(define_expand "cmpsi"
523  [(set (reg:CC FLAGS_REG)
524	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
525		    (match_operand:SI 1 "general_operand" "")))]
526  ""
527{
528  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
529    operands[0] = force_reg (SImode, operands[0]);
530  ix86_compare_op0 = operands[0];
531  ix86_compare_op1 = operands[1];
532  DONE;
533})
534
535(define_expand "cmphi"
536  [(set (reg:CC FLAGS_REG)
537	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
538		    (match_operand:HI 1 "general_operand" "")))]
539  ""
540{
541  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
542    operands[0] = force_reg (HImode, operands[0]);
543  ix86_compare_op0 = operands[0];
544  ix86_compare_op1 = operands[1];
545  DONE;
546})
547
548(define_expand "cmpqi"
549  [(set (reg:CC FLAGS_REG)
550	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
551		    (match_operand:QI 1 "general_operand" "")))]
552  "TARGET_QIMODE_MATH"
553{
554  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
555    operands[0] = force_reg (QImode, operands[0]);
556  ix86_compare_op0 = operands[0];
557  ix86_compare_op1 = operands[1];
558  DONE;
559})
560
561(define_insn "cmpdi_ccno_1_rex64"
562  [(set (reg FLAGS_REG)
563	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
564		 (match_operand:DI 1 "const0_operand" "n,n")))]
565  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
566  "@
567   test{q}\t{%0, %0|%0, %0}
568   cmp{q}\t{%1, %0|%0, %1}"
569  [(set_attr "type" "test,icmp")
570   (set_attr "length_immediate" "0,1")
571   (set_attr "mode" "DI")])
572
573(define_insn "*cmpdi_minus_1_rex64"
574  [(set (reg FLAGS_REG)
575	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
576			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
577		 (const_int 0)))]
578  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
579  "cmp{q}\t{%1, %0|%0, %1}"
580  [(set_attr "type" "icmp")
581   (set_attr "mode" "DI")])
582
583(define_expand "cmpdi_1_rex64"
584  [(set (reg:CC FLAGS_REG)
585	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
586		    (match_operand:DI 1 "general_operand" "")))]
587  "TARGET_64BIT"
588  "")
589
590(define_insn "cmpdi_1_insn_rex64"
591  [(set (reg FLAGS_REG)
592	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
593		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
594  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
595  "cmp{q}\t{%1, %0|%0, %1}"
596  [(set_attr "type" "icmp")
597   (set_attr "mode" "DI")])
598
599
600(define_insn "*cmpsi_ccno_1"
601  [(set (reg FLAGS_REG)
602	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
603		 (match_operand:SI 1 "const0_operand" "n,n")))]
604  "ix86_match_ccmode (insn, CCNOmode)"
605  "@
606   test{l}\t{%0, %0|%0, %0}
607   cmp{l}\t{%1, %0|%0, %1}"
608  [(set_attr "type" "test,icmp")
609   (set_attr "length_immediate" "0,1")
610   (set_attr "mode" "SI")])
611
612(define_insn "*cmpsi_minus_1"
613  [(set (reg FLAGS_REG)
614	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
615			   (match_operand:SI 1 "general_operand" "ri,mr"))
616		 (const_int 0)))]
617  "ix86_match_ccmode (insn, CCGOCmode)"
618  "cmp{l}\t{%1, %0|%0, %1}"
619  [(set_attr "type" "icmp")
620   (set_attr "mode" "SI")])
621
622(define_expand "cmpsi_1"
623  [(set (reg:CC FLAGS_REG)
624	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
625		    (match_operand:SI 1 "general_operand" "ri,mr")))]
626  ""
627  "")
628
629(define_insn "*cmpsi_1_insn"
630  [(set (reg FLAGS_REG)
631	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632		 (match_operand:SI 1 "general_operand" "ri,mr")))]
633  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
634    && ix86_match_ccmode (insn, CCmode)"
635  "cmp{l}\t{%1, %0|%0, %1}"
636  [(set_attr "type" "icmp")
637   (set_attr "mode" "SI")])
638
639(define_insn "*cmphi_ccno_1"
640  [(set (reg FLAGS_REG)
641	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
642		 (match_operand:HI 1 "const0_operand" "n,n")))]
643  "ix86_match_ccmode (insn, CCNOmode)"
644  "@
645   test{w}\t{%0, %0|%0, %0}
646   cmp{w}\t{%1, %0|%0, %1}"
647  [(set_attr "type" "test,icmp")
648   (set_attr "length_immediate" "0,1")
649   (set_attr "mode" "HI")])
650
651(define_insn "*cmphi_minus_1"
652  [(set (reg FLAGS_REG)
653	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
654			   (match_operand:HI 1 "general_operand" "ri,mr"))
655		 (const_int 0)))]
656  "ix86_match_ccmode (insn, CCGOCmode)"
657  "cmp{w}\t{%1, %0|%0, %1}"
658  [(set_attr "type" "icmp")
659   (set_attr "mode" "HI")])
660
661(define_insn "*cmphi_1"
662  [(set (reg FLAGS_REG)
663	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
664		 (match_operand:HI 1 "general_operand" "ri,mr")))]
665  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
666   && ix86_match_ccmode (insn, CCmode)"
667  "cmp{w}\t{%1, %0|%0, %1}"
668  [(set_attr "type" "icmp")
669   (set_attr "mode" "HI")])
670
671(define_insn "*cmpqi_ccno_1"
672  [(set (reg FLAGS_REG)
673	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
674		 (match_operand:QI 1 "const0_operand" "n,n")))]
675  "ix86_match_ccmode (insn, CCNOmode)"
676  "@
677   test{b}\t{%0, %0|%0, %0}
678   cmp{b}\t{$0, %0|%0, 0}"
679  [(set_attr "type" "test,icmp")
680   (set_attr "length_immediate" "0,1")
681   (set_attr "mode" "QI")])
682
683(define_insn "*cmpqi_1"
684  [(set (reg FLAGS_REG)
685	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
686		 (match_operand:QI 1 "general_operand" "qi,mq")))]
687  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
688    && ix86_match_ccmode (insn, CCmode)"
689  "cmp{b}\t{%1, %0|%0, %1}"
690  [(set_attr "type" "icmp")
691   (set_attr "mode" "QI")])
692
693(define_insn "*cmpqi_minus_1"
694  [(set (reg FLAGS_REG)
695	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
696			   (match_operand:QI 1 "general_operand" "qi,mq"))
697		 (const_int 0)))]
698  "ix86_match_ccmode (insn, CCGOCmode)"
699  "cmp{b}\t{%1, %0|%0, %1}"
700  [(set_attr "type" "icmp")
701   (set_attr "mode" "QI")])
702
703(define_insn "*cmpqi_ext_1"
704  [(set (reg FLAGS_REG)
705	(compare
706	  (match_operand:QI 0 "general_operand" "Qm")
707	  (subreg:QI
708	    (zero_extract:SI
709	      (match_operand 1 "ext_register_operand" "Q")
710	      (const_int 8)
711	      (const_int 8)) 0)))]
712  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
713  "cmp{b}\t{%h1, %0|%0, %h1}"
714  [(set_attr "type" "icmp")
715   (set_attr "mode" "QI")])
716
717(define_insn "*cmpqi_ext_1_rex64"
718  [(set (reg FLAGS_REG)
719	(compare
720	  (match_operand:QI 0 "register_operand" "Q")
721	  (subreg:QI
722	    (zero_extract:SI
723	      (match_operand 1 "ext_register_operand" "Q")
724	      (const_int 8)
725	      (const_int 8)) 0)))]
726  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
727  "cmp{b}\t{%h1, %0|%0, %h1}"
728  [(set_attr "type" "icmp")
729   (set_attr "mode" "QI")])
730
731(define_insn "*cmpqi_ext_2"
732  [(set (reg FLAGS_REG)
733	(compare
734	  (subreg:QI
735	    (zero_extract:SI
736	      (match_operand 0 "ext_register_operand" "Q")
737	      (const_int 8)
738	      (const_int 8)) 0)
739	  (match_operand:QI 1 "const0_operand" "n")))]
740  "ix86_match_ccmode (insn, CCNOmode)"
741  "test{b}\t%h0, %h0"
742  [(set_attr "type" "test")
743   (set_attr "length_immediate" "0")
744   (set_attr "mode" "QI")])
745
746(define_expand "cmpqi_ext_3"
747  [(set (reg:CC FLAGS_REG)
748	(compare:CC
749	  (subreg:QI
750	    (zero_extract:SI
751	      (match_operand 0 "ext_register_operand" "")
752	      (const_int 8)
753	      (const_int 8)) 0)
754	  (match_operand:QI 1 "general_operand" "")))]
755  ""
756  "")
757
758(define_insn "cmpqi_ext_3_insn"
759  [(set (reg FLAGS_REG)
760	(compare
761	  (subreg:QI
762	    (zero_extract:SI
763	      (match_operand 0 "ext_register_operand" "Q")
764	      (const_int 8)
765	      (const_int 8)) 0)
766	  (match_operand:QI 1 "general_operand" "Qmn")))]
767  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
768  "cmp{b}\t{%1, %h0|%h0, %1}"
769  [(set_attr "type" "icmp")
770   (set_attr "mode" "QI")])
771
772(define_insn "cmpqi_ext_3_insn_rex64"
773  [(set (reg FLAGS_REG)
774	(compare
775	  (subreg:QI
776	    (zero_extract:SI
777	      (match_operand 0 "ext_register_operand" "Q")
778	      (const_int 8)
779	      (const_int 8)) 0)
780	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
781  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
782  "cmp{b}\t{%1, %h0|%h0, %1}"
783  [(set_attr "type" "icmp")
784   (set_attr "mode" "QI")])
785
786(define_insn "*cmpqi_ext_4"
787  [(set (reg FLAGS_REG)
788	(compare
789	  (subreg:QI
790	    (zero_extract:SI
791	      (match_operand 0 "ext_register_operand" "Q")
792	      (const_int 8)
793	      (const_int 8)) 0)
794	  (subreg:QI
795	    (zero_extract:SI
796	      (match_operand 1 "ext_register_operand" "Q")
797	      (const_int 8)
798	      (const_int 8)) 0)))]
799  "ix86_match_ccmode (insn, CCmode)"
800  "cmp{b}\t{%h1, %h0|%h0, %h1}"
801  [(set_attr "type" "icmp")
802   (set_attr "mode" "QI")])
803
804;; These implement float point compares.
805;; %%% See if we can get away with VOIDmode operands on the actual insns,
806;; which would allow mix and match FP modes on the compares.  Which is what
807;; the old patterns did, but with many more of them.
808
809(define_expand "cmpxf"
810  [(set (reg:CC FLAGS_REG)
811	(compare:CC (match_operand:XF 0 "nonmemory_operand" "")
812		    (match_operand:XF 1 "nonmemory_operand" "")))]
813  "TARGET_80387"
814{
815  ix86_compare_op0 = operands[0];
816  ix86_compare_op1 = operands[1];
817  DONE;
818})
819
820(define_expand "cmpdf"
821  [(set (reg:CC FLAGS_REG)
822	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
823		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
824  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
825{
826  ix86_compare_op0 = operands[0];
827  ix86_compare_op1 = operands[1];
828  DONE;
829})
830
831(define_expand "cmpsf"
832  [(set (reg:CC FLAGS_REG)
833	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
834		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
835  "TARGET_80387 || TARGET_SSE_MATH"
836{
837  ix86_compare_op0 = operands[0];
838  ix86_compare_op1 = operands[1];
839  DONE;
840})
841
842;; FP compares, step 1:
843;; Set the FP condition codes.
844;;
845;; CCFPmode	compare with exceptions
846;; CCFPUmode	compare with no exceptions
847
848;; We may not use "#" to split and emit these, since the REG_DEAD notes
849;; used to manage the reg stack popping would not be preserved.
850
851(define_insn "*cmpfp_0"
852  [(set (match_operand:HI 0 "register_operand" "=a")
853	(unspec:HI
854	  [(compare:CCFP
855	     (match_operand 1 "register_operand" "f")
856	     (match_operand 2 "const0_operand" "X"))]
857	UNSPEC_FNSTSW))]
858  "TARGET_80387
859   && FLOAT_MODE_P (GET_MODE (operands[1]))
860   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
861  "* return output_fp_compare (insn, operands, 0, 0);"
862  [(set_attr "type" "multi")
863   (set_attr "unit" "i387")
864   (set (attr "mode")
865     (cond [(match_operand:SF 1 "" "")
866	      (const_string "SF")
867	    (match_operand:DF 1 "" "")
868	      (const_string "DF")
869	   ]
870	   (const_string "XF")))])
871
872(define_insn "*cmpfp_sf"
873  [(set (match_operand:HI 0 "register_operand" "=a")
874	(unspec:HI
875	  [(compare:CCFP
876	     (match_operand:SF 1 "register_operand" "f")
877	     (match_operand:SF 2 "nonimmediate_operand" "fm"))]
878	  UNSPEC_FNSTSW))]
879  "TARGET_80387"
880  "* return output_fp_compare (insn, operands, 0, 0);"
881  [(set_attr "type" "multi")
882   (set_attr "unit" "i387")
883   (set_attr "mode" "SF")])
884
885(define_insn "*cmpfp_df"
886  [(set (match_operand:HI 0 "register_operand" "=a")
887	(unspec:HI
888	  [(compare:CCFP
889	     (match_operand:DF 1 "register_operand" "f")
890	     (match_operand:DF 2 "nonimmediate_operand" "fm"))]
891	  UNSPEC_FNSTSW))]
892  "TARGET_80387"
893  "* return output_fp_compare (insn, operands, 0, 0);"
894  [(set_attr "type" "multi")
895   (set_attr "unit" "i387")
896   (set_attr "mode" "DF")])
897
898(define_insn "*cmpfp_xf"
899  [(set (match_operand:HI 0 "register_operand" "=a")
900	(unspec:HI
901	  [(compare:CCFP
902	     (match_operand:XF 1 "register_operand" "f")
903	     (match_operand:XF 2 "register_operand" "f"))]
904	  UNSPEC_FNSTSW))]
905  "TARGET_80387"
906  "* return output_fp_compare (insn, operands, 0, 0);"
907  [(set_attr "type" "multi")
908   (set_attr "unit" "i387")
909   (set_attr "mode" "XF")])
910
911(define_insn "*cmpfp_u"
912  [(set (match_operand:HI 0 "register_operand" "=a")
913	(unspec:HI
914	  [(compare:CCFPU
915	     (match_operand 1 "register_operand" "f")
916	     (match_operand 2 "register_operand" "f"))]
917	  UNSPEC_FNSTSW))]
918  "TARGET_80387
919   && FLOAT_MODE_P (GET_MODE (operands[1]))
920   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
921  "* return output_fp_compare (insn, operands, 0, 1);"
922  [(set_attr "type" "multi")
923   (set_attr "unit" "i387")
924   (set (attr "mode")
925     (cond [(match_operand:SF 1 "" "")
926	      (const_string "SF")
927	    (match_operand:DF 1 "" "")
928	      (const_string "DF")
929	   ]
930	   (const_string "XF")))])
931
932(define_insn "*cmpfp_<mode>"
933  [(set (match_operand:HI 0 "register_operand" "=a")
934	(unspec:HI
935	  [(compare:CCFP
936	     (match_operand 1 "register_operand" "f")
937	     (match_operator 3 "float_operator"
938	       [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
939	  UNSPEC_FNSTSW))]
940  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
941   && FLOAT_MODE_P (GET_MODE (operands[1]))
942   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
943  "* return output_fp_compare (insn, operands, 0, 0);"
944  [(set_attr "type" "multi")
945   (set_attr "unit" "i387")
946   (set_attr "fp_int_src" "true")
947   (set_attr "mode" "<MODE>")])
948
949;; FP compares, step 2
950;; Move the fpsw to ax.
951
952(define_insn "x86_fnstsw_1"
953  [(set (match_operand:HI 0 "register_operand" "=a")
954	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
955  "TARGET_80387"
956  "fnstsw\t%0"
957  [(set_attr "length" "2")
958   (set_attr "mode" "SI")
959   (set_attr "unit" "i387")])
960
961;; FP compares, step 3
962;; Get ax into flags, general case.
963
964(define_insn "x86_sahf_1"
965  [(set (reg:CC FLAGS_REG)
966	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
967  "!TARGET_64BIT"
968  "sahf"
969  [(set_attr "length" "1")
970   (set_attr "athlon_decode" "vector")
971   (set_attr "mode" "SI")])
972
973;; Pentium Pro can do steps 1 through 3 in one go.
974
975(define_insn "*cmpfp_i_mixed"
976  [(set (reg:CCFP FLAGS_REG)
977	(compare:CCFP (match_operand 0 "register_operand" "f,x")
978		      (match_operand 1 "nonimmediate_operand" "f,xm")))]
979  "TARGET_MIX_SSE_I387
980   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
981   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
982  "* return output_fp_compare (insn, operands, 1, 0);"
983  [(set_attr "type" "fcmp,ssecomi")
984   (set (attr "mode")
985     (if_then_else (match_operand:SF 1 "" "")
986        (const_string "SF")
987        (const_string "DF")))
988   (set_attr "athlon_decode" "vector")])
989
990(define_insn "*cmpfp_i_sse"
991  [(set (reg:CCFP FLAGS_REG)
992	(compare:CCFP (match_operand 0 "register_operand" "x")
993		      (match_operand 1 "nonimmediate_operand" "xm")))]
994  "TARGET_SSE_MATH
995   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
996   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
997  "* return output_fp_compare (insn, operands, 1, 0);"
998  [(set_attr "type" "ssecomi")
999   (set (attr "mode")
1000     (if_then_else (match_operand:SF 1 "" "")
1001        (const_string "SF")
1002        (const_string "DF")))
1003   (set_attr "athlon_decode" "vector")])
1004
1005(define_insn "*cmpfp_i_i387"
1006  [(set (reg:CCFP FLAGS_REG)
1007	(compare:CCFP (match_operand 0 "register_operand" "f")
1008		      (match_operand 1 "register_operand" "f")))]
1009  "TARGET_80387 && TARGET_CMOVE
1010   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1011   && FLOAT_MODE_P (GET_MODE (operands[0]))
1012   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1013  "* return output_fp_compare (insn, operands, 1, 0);"
1014  [(set_attr "type" "fcmp")
1015   (set (attr "mode")
1016     (cond [(match_operand:SF 1 "" "")
1017	      (const_string "SF")
1018	    (match_operand:DF 1 "" "")
1019	      (const_string "DF")
1020	   ]
1021	   (const_string "XF")))
1022   (set_attr "athlon_decode" "vector")])
1023
1024(define_insn "*cmpfp_iu_mixed"
1025  [(set (reg:CCFPU FLAGS_REG)
1026	(compare:CCFPU (match_operand 0 "register_operand" "f,x")
1027		       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1028  "TARGET_MIX_SSE_I387
1029   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1030   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1031  "* return output_fp_compare (insn, operands, 1, 1);"
1032  [(set_attr "type" "fcmp,ssecomi")
1033   (set (attr "mode")
1034     (if_then_else (match_operand:SF 1 "" "")
1035        (const_string "SF")
1036        (const_string "DF")))
1037   (set_attr "athlon_decode" "vector")])
1038
1039(define_insn "*cmpfp_iu_sse"
1040  [(set (reg:CCFPU FLAGS_REG)
1041	(compare:CCFPU (match_operand 0 "register_operand" "x")
1042		       (match_operand 1 "nonimmediate_operand" "xm")))]
1043  "TARGET_SSE_MATH
1044   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1045   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1046  "* return output_fp_compare (insn, operands, 1, 1);"
1047  [(set_attr "type" "ssecomi")
1048   (set (attr "mode")
1049     (if_then_else (match_operand:SF 1 "" "")
1050        (const_string "SF")
1051        (const_string "DF")))
1052   (set_attr "athlon_decode" "vector")])
1053
1054(define_insn "*cmpfp_iu_387"
1055  [(set (reg:CCFPU FLAGS_REG)
1056	(compare:CCFPU (match_operand 0 "register_operand" "f")
1057		       (match_operand 1 "register_operand" "f")))]
1058  "TARGET_80387 && TARGET_CMOVE
1059   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1060   && FLOAT_MODE_P (GET_MODE (operands[0]))
1061   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1062  "* return output_fp_compare (insn, operands, 1, 1);"
1063  [(set_attr "type" "fcmp")
1064   (set (attr "mode")
1065     (cond [(match_operand:SF 1 "" "")
1066	      (const_string "SF")
1067	    (match_operand:DF 1 "" "")
1068	      (const_string "DF")
1069	   ]
1070	   (const_string "XF")))
1071   (set_attr "athlon_decode" "vector")])
1072
1073;; Move instructions.
1074
1075;; General case of fullword move.
1076
1077(define_expand "movsi"
1078  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1079	(match_operand:SI 1 "general_operand" ""))]
1080  ""
1081  "ix86_expand_move (SImode, operands); DONE;")
1082
1083;; Push/pop instructions.  They are separate since autoinc/dec is not a
1084;; general_operand.
1085;;
1086;; %%% We don't use a post-inc memory reference because x86 is not a 
1087;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1088;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1089;; targets without our curiosities, and it is just as easy to represent
1090;; this differently.
1091
1092(define_insn "*pushsi2"
1093  [(set (match_operand:SI 0 "push_operand" "=<")
1094	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1095  "!TARGET_64BIT"
1096  "push{l}\t%1"
1097  [(set_attr "type" "push")
1098   (set_attr "mode" "SI")])
1099
1100;; For 64BIT abi we always round up to 8 bytes.
1101(define_insn "*pushsi2_rex64"
1102  [(set (match_operand:SI 0 "push_operand" "=X")
1103	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1104  "TARGET_64BIT"
1105  "push{q}\t%q1"
1106  [(set_attr "type" "push")
1107   (set_attr "mode" "SI")])
1108
1109(define_insn "*pushsi2_prologue"
1110  [(set (match_operand:SI 0 "push_operand" "=<")
1111	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1112   (clobber (mem:BLK (scratch)))]
1113  "!TARGET_64BIT"
1114  "push{l}\t%1"
1115  [(set_attr "type" "push")
1116   (set_attr "mode" "SI")])
1117
1118(define_insn "*popsi1_epilogue"
1119  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1120	(mem:SI (reg:SI SP_REG)))
1121   (set (reg:SI SP_REG)
1122	(plus:SI (reg:SI SP_REG) (const_int 4)))
1123   (clobber (mem:BLK (scratch)))]
1124  "!TARGET_64BIT"
1125  "pop{l}\t%0"
1126  [(set_attr "type" "pop")
1127   (set_attr "mode" "SI")])
1128
1129(define_insn "popsi1"
1130  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1131	(mem:SI (reg:SI SP_REG)))
1132   (set (reg:SI SP_REG)
1133	(plus:SI (reg:SI SP_REG) (const_int 4)))]
1134  "!TARGET_64BIT"
1135  "pop{l}\t%0"
1136  [(set_attr "type" "pop")
1137   (set_attr "mode" "SI")])
1138
1139(define_insn "*movsi_xor"
1140  [(set (match_operand:SI 0 "register_operand" "=r")
1141	(match_operand:SI 1 "const0_operand" "i"))
1142   (clobber (reg:CC FLAGS_REG))]
1143  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1144  "xor{l}\t{%0, %0|%0, %0}"
1145  [(set_attr "type" "alu1")
1146   (set_attr "mode" "SI")
1147   (set_attr "length_immediate" "0")])
1148 
1149(define_insn "*movsi_or"
1150  [(set (match_operand:SI 0 "register_operand" "=r")
1151	(match_operand:SI 1 "immediate_operand" "i"))
1152   (clobber (reg:CC FLAGS_REG))]
1153  "reload_completed
1154   && operands[1] == constm1_rtx
1155   && (TARGET_PENTIUM || optimize_size)"
1156{
1157  operands[1] = constm1_rtx;
1158  return "or{l}\t{%1, %0|%0, %1}";
1159}
1160  [(set_attr "type" "alu1")
1161   (set_attr "mode" "SI")
1162   (set_attr "length_immediate" "1")])
1163
1164(define_insn "*movsi_1"
1165  [(set (match_operand:SI 0 "nonimmediate_operand"
1166			"=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1167	(match_operand:SI 1 "general_operand"
1168			"rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1169  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1170{
1171  switch (get_attr_type (insn))
1172    {
1173    case TYPE_SSELOG1:
1174      if (get_attr_mode (insn) == MODE_TI)
1175        return "pxor\t%0, %0";
1176      return "xorps\t%0, %0";
1177
1178    case TYPE_SSEMOV:
1179      switch (get_attr_mode (insn))
1180	{
1181	case MODE_TI:
1182	  return "movdqa\t{%1, %0|%0, %1}";
1183	case MODE_V4SF:
1184	  return "movaps\t{%1, %0|%0, %1}";
1185	case MODE_SI:
1186          return "movd\t{%1, %0|%0, %1}";
1187	case MODE_SF:
1188          return "movss\t{%1, %0|%0, %1}";
1189	default:
1190	  gcc_unreachable ();
1191	}
1192
1193    case TYPE_MMXADD:
1194      return "pxor\t%0, %0";
1195
1196    case TYPE_MMXMOV:
1197      if (get_attr_mode (insn) == MODE_DI)
1198	return "movq\t{%1, %0|%0, %1}";
1199      return "movd\t{%1, %0|%0, %1}";
1200
1201    case TYPE_LEA:
1202      return "lea{l}\t{%1, %0|%0, %1}";
1203
1204    default:
1205      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1206      return "mov{l}\t{%1, %0|%0, %1}";
1207    }
1208}
1209  [(set (attr "type")
1210     (cond [(eq_attr "alternative" "2")
1211	      (const_string "mmxadd")
1212	    (eq_attr "alternative" "3,4,5")
1213	      (const_string "mmxmov")
1214	    (eq_attr "alternative" "6")
1215	      (const_string "sselog1")
1216	    (eq_attr "alternative" "7,8,9,10,11")
1217	      (const_string "ssemov")
1218 	    (match_operand:DI 1 "pic_32bit_operand" "")
1219	      (const_string "lea")
1220	   ]
1221	   (const_string "imov")))
1222   (set (attr "mode")
1223     (cond [(eq_attr "alternative" "2,3")
1224	      (const_string "DI")
1225	    (eq_attr "alternative" "6,7")
1226	      (if_then_else
1227	        (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1228	        (const_string "V4SF")
1229	        (const_string "TI"))
1230	    (and (eq_attr "alternative" "8,9,10,11")
1231	         (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1232	      (const_string "SF")
1233	   ]
1234	   (const_string "SI")))])
1235
1236;; Stores and loads of ax to arbitrary constant address.
1237;; We fake an second form of instruction to force reload to load address
1238;; into register when rax is not available
1239(define_insn "*movabssi_1_rex64"
1240  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1241	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
1242  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1243  "@
1244   movabs{l}\t{%1, %P0|%P0, %1}
1245   mov{l}\t{%1, %a0|%a0, %1}"
1246  [(set_attr "type" "imov")
1247   (set_attr "modrm" "0,*")
1248   (set_attr "length_address" "8,0")
1249   (set_attr "length_immediate" "0,*")
1250   (set_attr "memory" "store")
1251   (set_attr "mode" "SI")])
1252
1253(define_insn "*movabssi_2_rex64"
1254  [(set (match_operand:SI 0 "register_operand" "=a,r")
1255        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1256  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1257  "@
1258   movabs{l}\t{%P1, %0|%0, %P1}
1259   mov{l}\t{%a1, %0|%0, %a1}"
1260  [(set_attr "type" "imov")
1261   (set_attr "modrm" "0,*")
1262   (set_attr "length_address" "8,0")
1263   (set_attr "length_immediate" "0")
1264   (set_attr "memory" "load")
1265   (set_attr "mode" "SI")])
1266
1267(define_insn "*swapsi"
1268  [(set (match_operand:SI 0 "register_operand" "+r")
1269	(match_operand:SI 1 "register_operand" "+r"))
1270   (set (match_dup 1)
1271	(match_dup 0))]
1272  ""
1273  "xchg{l}\t%1, %0"
1274  [(set_attr "type" "imov")
1275   (set_attr "mode" "SI")
1276   (set_attr "pent_pair" "np")
1277   (set_attr "athlon_decode" "vector")])
1278
1279(define_expand "movhi"
1280  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1281        (match_operand:HI 1 "general_operand" ""))]
1282  ""
1283  "ix86_expand_move (HImode, operands); DONE;")
1284
1285(define_insn "*pushhi2"
1286  [(set (match_operand:HI 0 "push_operand" "=X")
1287	(match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1288  "!TARGET_64BIT"
1289  "push{l}\t%k1"
1290  [(set_attr "type" "push")
1291   (set_attr "mode" "SI")])
1292
1293;; For 64BIT abi we always round up to 8 bytes.
1294(define_insn "*pushhi2_rex64"
1295  [(set (match_operand:HI 0 "push_operand" "=X")
1296	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1297  "TARGET_64BIT"
1298  "push{q}\t%q1"
1299  [(set_attr "type" "push")
1300   (set_attr "mode" "DI")])
1301
1302(define_insn "*movhi_1"
1303  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1304	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1305  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1306{
1307  switch (get_attr_type (insn))
1308    {
1309    case TYPE_IMOVX:
1310      /* movzwl is faster than movw on p2 due to partial word stalls,
1311	 though not as fast as an aligned movl.  */
1312      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1313    default:
1314      if (get_attr_mode (insn) == MODE_SI)
1315        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1316      else
1317        return "mov{w}\t{%1, %0|%0, %1}";
1318    }
1319}
1320  [(set (attr "type")
1321     (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1322	      (const_string "imov")
1323	    (and (eq_attr "alternative" "0")
1324		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1325			  (const_int 0))
1326		      (eq (symbol_ref "TARGET_HIMODE_MATH")
1327			  (const_int 0))))
1328	      (const_string "imov")
1329	    (and (eq_attr "alternative" "1,2")
1330		 (match_operand:HI 1 "aligned_operand" ""))
1331	      (const_string "imov")
1332	    (and (ne (symbol_ref "TARGET_MOVX")
1333		     (const_int 0))
1334		 (eq_attr "alternative" "0,2"))
1335	      (const_string "imovx")
1336	   ]
1337	   (const_string "imov")))
1338    (set (attr "mode")
1339      (cond [(eq_attr "type" "imovx")
1340	       (const_string "SI")
1341	     (and (eq_attr "alternative" "1,2")
1342		  (match_operand:HI 1 "aligned_operand" ""))
1343	       (const_string "SI")
1344	     (and (eq_attr "alternative" "0")
1345		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1346			   (const_int 0))
1347		       (eq (symbol_ref "TARGET_HIMODE_MATH")
1348			   (const_int 0))))
1349	       (const_string "SI")
1350	    ]
1351	    (const_string "HI")))])
1352
1353;; Stores and loads of ax to arbitrary constant address.
1354;; We fake an second form of instruction to force reload to load address
1355;; into register when rax is not available
1356(define_insn "*movabshi_1_rex64"
1357  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1358	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
1359  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1360  "@
1361   movabs{w}\t{%1, %P0|%P0, %1}
1362   mov{w}\t{%1, %a0|%a0, %1}"
1363  [(set_attr "type" "imov")
1364   (set_attr "modrm" "0,*")
1365   (set_attr "length_address" "8,0")
1366   (set_attr "length_immediate" "0,*")
1367   (set_attr "memory" "store")
1368   (set_attr "mode" "HI")])
1369
1370(define_insn "*movabshi_2_rex64"
1371  [(set (match_operand:HI 0 "register_operand" "=a,r")
1372        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1373  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1374  "@
1375   movabs{w}\t{%P1, %0|%0, %P1}
1376   mov{w}\t{%a1, %0|%0, %a1}"
1377  [(set_attr "type" "imov")
1378   (set_attr "modrm" "0,*")
1379   (set_attr "length_address" "8,0")
1380   (set_attr "length_immediate" "0")
1381   (set_attr "memory" "load")
1382   (set_attr "mode" "HI")])
1383
1384(define_insn "*swaphi_1"
1385  [(set (match_operand:HI 0 "register_operand" "+r")
1386	(match_operand:HI 1 "register_operand" "+r"))
1387   (set (match_dup 1)
1388	(match_dup 0))]
1389  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1390  "xchg{l}\t%k1, %k0"
1391  [(set_attr "type" "imov")
1392   (set_attr "mode" "SI")
1393   (set_attr "pent_pair" "np")
1394   (set_attr "athlon_decode" "vector")])
1395
1396(define_insn "*swaphi_2"
1397  [(set (match_operand:HI 0 "register_operand" "+r")
1398	(match_operand:HI 1 "register_operand" "+r"))
1399   (set (match_dup 1)
1400	(match_dup 0))]
1401  "TARGET_PARTIAL_REG_STALL"
1402  "xchg{w}\t%1, %0"
1403  [(set_attr "type" "imov")
1404   (set_attr "mode" "HI")
1405   (set_attr "pent_pair" "np")
1406   (set_attr "athlon_decode" "vector")])
1407
1408(define_expand "movstricthi"
1409  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1410	(match_operand:HI 1 "general_operand" ""))]
1411  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1412{
1413  /* Don't generate memory->memory moves, go through a register */
1414  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1415    operands[1] = force_reg (HImode, operands[1]);
1416})
1417
1418(define_insn "*movstricthi_1"
1419  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1420	(match_operand:HI 1 "general_operand" "rn,m"))]
1421  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1422   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1423  "mov{w}\t{%1, %0|%0, %1}"
1424  [(set_attr "type" "imov")
1425   (set_attr "mode" "HI")])
1426
1427(define_insn "*movstricthi_xor"
1428  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1429	(match_operand:HI 1 "const0_operand" "i"))
1430   (clobber (reg:CC FLAGS_REG))]
1431  "reload_completed
1432   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1433  "xor{w}\t{%0, %0|%0, %0}"
1434  [(set_attr "type" "alu1")
1435   (set_attr "mode" "HI")
1436   (set_attr "length_immediate" "0")])
1437
1438(define_expand "movqi"
1439  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1440	(match_operand:QI 1 "general_operand" ""))]
1441  ""
1442  "ix86_expand_move (QImode, operands); DONE;")
1443
1444;; emit_push_insn when it calls move_by_pieces requires an insn to
1445;; "push a byte".  But actually we use pushl, which has the effect
1446;; of rounding the amount pushed up to a word.
1447
1448(define_insn "*pushqi2"
1449  [(set (match_operand:QI 0 "push_operand" "=X")
1450	(match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1451  "!TARGET_64BIT"
1452  "push{l}\t%k1"
1453  [(set_attr "type" "push")
1454   (set_attr "mode" "SI")])
1455
1456;; For 64BIT abi we always round up to 8 bytes.
1457(define_insn "*pushqi2_rex64"
1458  [(set (match_operand:QI 0 "push_operand" "=X")
1459	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1460  "TARGET_64BIT"
1461  "push{q}\t%q1"
1462  [(set_attr "type" "push")
1463   (set_attr "mode" "DI")])
1464
1465;; Situation is quite tricky about when to choose full sized (SImode) move
1466;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1467;; partial register dependency machines (such as AMD Athlon), where QImode
1468;; moves issue extra dependency and for partial register stalls machines
1469;; that don't use QImode patterns (and QImode move cause stall on the next
1470;; instruction).
1471;;
1472;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1473;; register stall machines with, where we use QImode instructions, since
1474;; partial register stall can be caused there.  Then we use movzx.
1475(define_insn "*movqi_1"
1476  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1477	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1478  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1479{
1480  switch (get_attr_type (insn))
1481    {
1482    case TYPE_IMOVX:
1483      gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1484      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1485    default:
1486      if (get_attr_mode (insn) == MODE_SI)
1487        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1488      else
1489        return "mov{b}\t{%1, %0|%0, %1}";
1490    }
1491}
1492  [(set (attr "type")
1493     (cond [(and (eq_attr "alternative" "5")
1494		 (not (match_operand:QI 1 "aligned_operand" "")))
1495	      (const_string "imovx")
1496	    (ne (symbol_ref "optimize_size") (const_int 0))
1497	      (const_string "imov")
1498	    (and (eq_attr "alternative" "3")
1499		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1500			  (const_int 0))
1501		      (eq (symbol_ref "TARGET_QIMODE_MATH")
1502			  (const_int 0))))
1503	      (const_string "imov")
1504	    (eq_attr "alternative" "3,5")
1505	      (const_string "imovx")
1506	    (and (ne (symbol_ref "TARGET_MOVX")
1507		     (const_int 0))
1508		 (eq_attr "alternative" "2"))
1509	      (const_string "imovx")
1510	   ]
1511	   (const_string "imov")))
1512   (set (attr "mode")
1513      (cond [(eq_attr "alternative" "3,4,5")
1514	       (const_string "SI")
1515	     (eq_attr "alternative" "6")
1516	       (const_string "QI")
1517	     (eq_attr "type" "imovx")
1518	       (const_string "SI")
1519	     (and (eq_attr "type" "imov")
1520		  (and (eq_attr "alternative" "0,1")
1521		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1522				(const_int 0))
1523			    (and (eq (symbol_ref "optimize_size")
1524				     (const_int 0))
1525			    	 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1526				     (const_int 0))))))
1527	       (const_string "SI")
1528	     ;; Avoid partial register stalls when not using QImode arithmetic
1529	     (and (eq_attr "type" "imov")
1530		  (and (eq_attr "alternative" "0,1")
1531		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1532				(const_int 0))
1533			    (eq (symbol_ref "TARGET_QIMODE_MATH")
1534				(const_int 0)))))
1535	       (const_string "SI")
1536	   ]
1537	   (const_string "QI")))])
1538
1539(define_expand "reload_outqi"
1540  [(parallel [(match_operand:QI 0 "" "=m")
1541              (match_operand:QI 1 "register_operand" "r")
1542              (match_operand:QI 2 "register_operand" "=&q")])]
1543  ""
1544{
1545  rtx op0, op1, op2;
1546  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1547
1548  gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1549  if (! q_regs_operand (op1, QImode))
1550    {
1551      emit_insn (gen_movqi (op2, op1));
1552      op1 = op2;
1553    }
1554  emit_insn (gen_movqi (op0, op1));
1555  DONE;
1556})
1557
1558(define_insn "*swapqi_1"
1559  [(set (match_operand:QI 0 "register_operand" "+r")
1560	(match_operand:QI 1 "register_operand" "+r"))
1561   (set (match_dup 1)
1562	(match_dup 0))]
1563  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1564  "xchg{l}\t%k1, %k0"
1565  [(set_attr "type" "imov")
1566   (set_attr "mode" "SI")
1567   (set_attr "pent_pair" "np")
1568   (set_attr "athlon_decode" "vector")])
1569
1570(define_insn "*swapqi_2"
1571  [(set (match_operand:QI 0 "register_operand" "+q")
1572	(match_operand:QI 1 "register_operand" "+q"))
1573   (set (match_dup 1)
1574	(match_dup 0))]
1575  "TARGET_PARTIAL_REG_STALL"
1576  "xchg{b}\t%1, %0"
1577  [(set_attr "type" "imov")
1578   (set_attr "mode" "QI")
1579   (set_attr "pent_pair" "np")
1580   (set_attr "athlon_decode" "vector")])
1581
1582(define_expand "movstrictqi"
1583  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1584	(match_operand:QI 1 "general_operand" ""))]
1585  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1586{
1587  /* Don't generate memory->memory moves, go through a register.  */
1588  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1589    operands[1] = force_reg (QImode, operands[1]);
1590})
1591
1592(define_insn "*movstrictqi_1"
1593  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1594	(match_operand:QI 1 "general_operand" "*qn,m"))]
1595  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1596   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1597  "mov{b}\t{%1, %0|%0, %1}"
1598  [(set_attr "type" "imov")
1599   (set_attr "mode" "QI")])
1600
1601(define_insn "*movstrictqi_xor"
1602  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1603	(match_operand:QI 1 "const0_operand" "i"))
1604   (clobber (reg:CC FLAGS_REG))]
1605  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1606  "xor{b}\t{%0, %0|%0, %0}"
1607  [(set_attr "type" "alu1")
1608   (set_attr "mode" "QI")
1609   (set_attr "length_immediate" "0")])
1610
1611(define_insn "*movsi_extv_1"
1612  [(set (match_operand:SI 0 "register_operand" "=R")
1613	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1614			 (const_int 8)
1615			 (const_int 8)))]
1616  ""
1617  "movs{bl|x}\t{%h1, %0|%0, %h1}"
1618  [(set_attr "type" "imovx")
1619   (set_attr "mode" "SI")])
1620
1621(define_insn "*movhi_extv_1"
1622  [(set (match_operand:HI 0 "register_operand" "=R")
1623	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1624			 (const_int 8)
1625			 (const_int 8)))]
1626  ""
1627  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1628  [(set_attr "type" "imovx")
1629   (set_attr "mode" "SI")])
1630
1631(define_insn "*movqi_extv_1"
1632  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1633        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1634                         (const_int 8)
1635                         (const_int 8)))]
1636  "!TARGET_64BIT"
1637{
1638  switch (get_attr_type (insn))
1639    {
1640    case TYPE_IMOVX:
1641      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1642    default:
1643      return "mov{b}\t{%h1, %0|%0, %h1}";
1644    }
1645}
1646  [(set (attr "type")
1647     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1648			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1649			     (ne (symbol_ref "TARGET_MOVX")
1650				 (const_int 0))))
1651	(const_string "imovx")
1652	(const_string "imov")))
1653   (set (attr "mode")
1654     (if_then_else (eq_attr "type" "imovx")
1655	(const_string "SI")
1656	(const_string "QI")))])
1657
1658(define_insn "*movqi_extv_1_rex64"
1659  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1660        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1661                         (const_int 8)
1662                         (const_int 8)))]
1663  "TARGET_64BIT"
1664{
1665  switch (get_attr_type (insn))
1666    {
1667    case TYPE_IMOVX:
1668      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1669    default:
1670      return "mov{b}\t{%h1, %0|%0, %h1}";
1671    }
1672}
1673  [(set (attr "type")
1674     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1675			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1676			     (ne (symbol_ref "TARGET_MOVX")
1677				 (const_int 0))))
1678	(const_string "imovx")
1679	(const_string "imov")))
1680   (set (attr "mode")
1681     (if_then_else (eq_attr "type" "imovx")
1682	(const_string "SI")
1683	(const_string "QI")))])
1684
1685;; Stores and loads of ax to arbitrary constant address.
1686;; We fake an second form of instruction to force reload to load address
1687;; into register when rax is not available
1688(define_insn "*movabsqi_1_rex64"
1689  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1690	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
1691  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1692  "@
1693   movabs{b}\t{%1, %P0|%P0, %1}
1694   mov{b}\t{%1, %a0|%a0, %1}"
1695  [(set_attr "type" "imov")
1696   (set_attr "modrm" "0,*")
1697   (set_attr "length_address" "8,0")
1698   (set_attr "length_immediate" "0,*")
1699   (set_attr "memory" "store")
1700   (set_attr "mode" "QI")])
1701
1702(define_insn "*movabsqi_2_rex64"
1703  [(set (match_operand:QI 0 "register_operand" "=a,r")
1704        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1705  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1706  "@
1707   movabs{b}\t{%P1, %0|%0, %P1}
1708   mov{b}\t{%a1, %0|%0, %a1}"
1709  [(set_attr "type" "imov")
1710   (set_attr "modrm" "0,*")
1711   (set_attr "length_address" "8,0")
1712   (set_attr "length_immediate" "0")
1713   (set_attr "memory" "load")
1714   (set_attr "mode" "QI")])
1715
1716(define_insn "*movdi_extzv_1"
1717  [(set (match_operand:DI 0 "register_operand" "=R")
1718	(zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1719			 (const_int 8)
1720			 (const_int 8)))]
1721  "TARGET_64BIT"
1722  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1723  [(set_attr "type" "imovx")
1724   (set_attr "mode" "DI")])
1725
1726(define_insn "*movsi_extzv_1"
1727  [(set (match_operand:SI 0 "register_operand" "=R")
1728	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1729			 (const_int 8)
1730			 (const_int 8)))]
1731  ""
1732  "movz{bl|x}\t{%h1, %0|%0, %h1}"
1733  [(set_attr "type" "imovx")
1734   (set_attr "mode" "SI")])
1735
1736(define_insn "*movqi_extzv_2"
1737  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1738        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1739				    (const_int 8)
1740				    (const_int 8)) 0))]
1741  "!TARGET_64BIT"
1742{
1743  switch (get_attr_type (insn))
1744    {
1745    case TYPE_IMOVX:
1746      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1747    default:
1748      return "mov{b}\t{%h1, %0|%0, %h1}";
1749    }
1750}
1751  [(set (attr "type")
1752     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1753			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1754			     (ne (symbol_ref "TARGET_MOVX")
1755				 (const_int 0))))
1756	(const_string "imovx")
1757	(const_string "imov")))
1758   (set (attr "mode")
1759     (if_then_else (eq_attr "type" "imovx")
1760	(const_string "SI")
1761	(const_string "QI")))])
1762
1763(define_insn "*movqi_extzv_2_rex64"
1764  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1765        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1766				    (const_int 8)
1767				    (const_int 8)) 0))]
1768  "TARGET_64BIT"
1769{
1770  switch (get_attr_type (insn))
1771    {
1772    case TYPE_IMOVX:
1773      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1774    default:
1775      return "mov{b}\t{%h1, %0|%0, %h1}";
1776    }
1777}
1778  [(set (attr "type")
1779     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1780			(ne (symbol_ref "TARGET_MOVX")
1781			    (const_int 0)))
1782	(const_string "imovx")
1783	(const_string "imov")))
1784   (set (attr "mode")
1785     (if_then_else (eq_attr "type" "imovx")
1786	(const_string "SI")
1787	(const_string "QI")))])
1788
1789(define_insn "movsi_insv_1"
1790  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1791			 (const_int 8)
1792			 (const_int 8))
1793	(match_operand:SI 1 "general_operand" "Qmn"))]
1794  "!TARGET_64BIT"
1795  "mov{b}\t{%b1, %h0|%h0, %b1}"
1796  [(set_attr "type" "imov")
1797   (set_attr "mode" "QI")])
1798
1799(define_insn "movdi_insv_1_rex64"
1800  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1801			 (const_int 8)
1802			 (const_int 8))
1803	(match_operand:DI 1 "nonmemory_operand" "Qn"))]
1804  "TARGET_64BIT"
1805  "mov{b}\t{%b1, %h0|%h0, %b1}"
1806  [(set_attr "type" "imov")
1807   (set_attr "mode" "QI")])
1808
1809(define_insn "*movqi_insv_2"
1810  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811			 (const_int 8)
1812			 (const_int 8))
1813	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1814		     (const_int 8)))]
1815  ""
1816  "mov{b}\t{%h1, %h0|%h0, %h1}"
1817  [(set_attr "type" "imov")
1818   (set_attr "mode" "QI")])
1819
1820(define_expand "movdi"
1821  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1822	(match_operand:DI 1 "general_operand" ""))]
1823  ""
1824  "ix86_expand_move (DImode, operands); DONE;")
1825
1826(define_insn "*pushdi"
1827  [(set (match_operand:DI 0 "push_operand" "=<")
1828	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1829  "!TARGET_64BIT"
1830  "#")
1831
1832(define_insn "*pushdi2_rex64"
1833  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1834	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1835  "TARGET_64BIT"
1836  "@
1837   push{q}\t%1
1838   #"
1839  [(set_attr "type" "push,multi")
1840   (set_attr "mode" "DI")])
1841
1842;; Convert impossible pushes of immediate to existing instructions.
1843;; First try to get scratch register and go through it.  In case this
1844;; fails, push sign extended lower part first and then overwrite
1845;; upper part by 32bit move.
1846(define_peephole2
1847  [(match_scratch:DI 2 "r")
1848   (set (match_operand:DI 0 "push_operand" "")
1849        (match_operand:DI 1 "immediate_operand" ""))]
1850  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1851   && !x86_64_immediate_operand (operands[1], DImode)"
1852  [(set (match_dup 2) (match_dup 1))
1853   (set (match_dup 0) (match_dup 2))]
1854  "")
1855
1856;; We need to define this as both peepholer and splitter for case
1857;; peephole2 pass is not run.
1858;; "&& 1" is needed to keep it from matching the previous pattern.
1859(define_peephole2
1860  [(set (match_operand:DI 0 "push_operand" "")
1861        (match_operand:DI 1 "immediate_operand" ""))]
1862  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1863   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1864  [(set (match_dup 0) (match_dup 1))
1865   (set (match_dup 2) (match_dup 3))]
1866  "split_di (operands + 1, 1, operands + 2, operands + 3);
1867   operands[1] = gen_lowpart (DImode, operands[2]);
1868   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1869						    GEN_INT (4)));
1870  ")
1871
1872(define_split
1873  [(set (match_operand:DI 0 "push_operand" "")
1874        (match_operand:DI 1 "immediate_operand" ""))]
1875  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1876		    ? flow2_completed : reload_completed)
1877   && !symbolic_operand (operands[1], DImode)
1878   && !x86_64_immediate_operand (operands[1], DImode)"
1879  [(set (match_dup 0) (match_dup 1))
1880   (set (match_dup 2) (match_dup 3))]
1881  "split_di (operands + 1, 1, operands + 2, operands + 3);
1882   operands[1] = gen_lowpart (DImode, operands[2]);
1883   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1884						    GEN_INT (4)));
1885  ")
1886
1887(define_insn "*pushdi2_prologue_rex64"
1888  [(set (match_operand:DI 0 "push_operand" "=<")
1889	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
1890   (clobber (mem:BLK (scratch)))]
1891  "TARGET_64BIT"
1892  "push{q}\t%1"
1893  [(set_attr "type" "push")
1894   (set_attr "mode" "DI")])
1895
1896(define_insn "*popdi1_epilogue_rex64"
1897  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1898	(mem:DI (reg:DI SP_REG)))
1899   (set (reg:DI SP_REG)
1900	(plus:DI (reg:DI SP_REG) (const_int 8)))
1901   (clobber (mem:BLK (scratch)))]
1902  "TARGET_64BIT"
1903  "pop{q}\t%0"
1904  [(set_attr "type" "pop")
1905   (set_attr "mode" "DI")])
1906
1907(define_insn "popdi1"
1908  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1909	(mem:DI (reg:DI SP_REG)))
1910   (set (reg:DI SP_REG)
1911	(plus:DI (reg:DI SP_REG) (const_int 8)))]
1912  "TARGET_64BIT"
1913  "pop{q}\t%0"
1914  [(set_attr "type" "pop")
1915   (set_attr "mode" "DI")])
1916
1917(define_insn "*movdi_xor_rex64"
1918  [(set (match_operand:DI 0 "register_operand" "=r")
1919	(match_operand:DI 1 "const0_operand" "i"))
1920   (clobber (reg:CC FLAGS_REG))]
1921  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1922   && reload_completed"
1923  "xor{l}\t{%k0, %k0|%k0, %k0}"
1924  [(set_attr "type" "alu1")
1925   (set_attr "mode" "SI")
1926   (set_attr "length_immediate" "0")])
1927
1928(define_insn "*movdi_or_rex64"
1929  [(set (match_operand:DI 0 "register_operand" "=r")
1930	(match_operand:DI 1 "const_int_operand" "i"))
1931   (clobber (reg:CC FLAGS_REG))]
1932  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1933   && reload_completed
1934   && operands[1] == constm1_rtx"
1935{
1936  operands[1] = constm1_rtx;
1937  return "or{q}\t{%1, %0|%0, %1}";
1938}
1939  [(set_attr "type" "alu1")
1940   (set_attr "mode" "DI")
1941   (set_attr "length_immediate" "1")])
1942
1943(define_insn "*movdi_2"
1944  [(set (match_operand:DI 0 "nonimmediate_operand"
1945				"=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1946	(match_operand:DI 1 "general_operand"
1947				"riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1948  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1949  "@
1950   #
1951   #
1952   pxor\t%0, %0
1953   movq\t{%1, %0|%0, %1}
1954   movq\t{%1, %0|%0, %1}
1955   pxor\t%0, %0
1956   movq\t{%1, %0|%0, %1}
1957   movdqa\t{%1, %0|%0, %1}
1958   movq\t{%1, %0|%0, %1}
1959   xorps\t%0, %0
1960   movlps\t{%1, %0|%0, %1}
1961   movaps\t{%1, %0|%0, %1}
1962   movlps\t{%1, %0|%0, %1}"
1963  [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1964   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1965
1966(define_split
1967  [(set (match_operand:DI 0 "push_operand" "")
1968        (match_operand:DI 1 "general_operand" ""))]
1969  "!TARGET_64BIT && reload_completed
1970   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1971  [(const_int 0)]
1972  "ix86_split_long_move (operands); DONE;")
1973
1974;; %%% This multiword shite has got to go.
1975(define_split
1976  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1977        (match_operand:DI 1 "general_operand" ""))]
1978  "!TARGET_64BIT && reload_completed
1979   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1980   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1981  [(const_int 0)]
1982  "ix86_split_long_move (operands); DONE;")
1983
1984(define_insn "*movdi_1_rex64"
1985  [(set (match_operand:DI 0 "nonimmediate_operand"
1986		"=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1987	(match_operand:DI 1 "general_operand"
1988		"Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1989  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1990{
1991  switch (get_attr_type (insn))
1992    {
1993    case TYPE_SSECVT:
1994      if (which_alternative == 13)
1995	return "movq2dq\t{%1, %0|%0, %1}";
1996      else
1997	return "movdq2q\t{%1, %0|%0, %1}";
1998    case TYPE_SSEMOV:
1999      if (get_attr_mode (insn) == MODE_TI)
2000	  return "movdqa\t{%1, %0|%0, %1}";
2001      /* FALLTHRU */
2002    case TYPE_MMXMOV:
2003      /* Moves from and into integer register is done using movd opcode with
2004 	 REX prefix.  */
2005      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2006	  return "movd\t{%1, %0|%0, %1}";
2007      return "movq\t{%1, %0|%0, %1}";
2008    case TYPE_SSELOG1:
2009    case TYPE_MMXADD:
2010      return "pxor\t%0, %0";
2011    case TYPE_MULTI:
2012      return "#";
2013    case TYPE_LEA:
2014      return "lea{q}\t{%a1, %0|%0, %a1}";
2015    default:
2016      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2017      if (get_attr_mode (insn) == MODE_SI)
2018	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2019      else if (which_alternative == 2)
2020	return "movabs{q}\t{%1, %0|%0, %1}";
2021      else
2022	return "mov{q}\t{%1, %0|%0, %1}";
2023    }
2024}
2025  [(set (attr "type")
2026     (cond [(eq_attr "alternative" "5")
2027	      (const_string "mmxadd")
2028	    (eq_attr "alternative" "6,7,8")
2029	      (const_string "mmxmov")
2030	    (eq_attr "alternative" "9")
2031	      (const_string "sselog1")
2032	    (eq_attr "alternative" "10,11,12")
2033	      (const_string "ssemov")
2034	    (eq_attr "alternative" "13,14")
2035	      (const_string "ssecvt")
2036	    (eq_attr "alternative" "4")
2037	      (const_string "multi")
2038 	    (match_operand:DI 1 "pic_32bit_operand" "")
2039	      (const_string "lea")
2040	   ]
2041	   (const_string "imov")))
2042   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2043   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2044   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2045
2046;; Stores and loads of ax to arbitrary constant address.
2047;; We fake an second form of instruction to force reload to load address
2048;; into register when rax is not available
2049(define_insn "*movabsdi_1_rex64"
2050  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2051	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
2052  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2053  "@
2054   movabs{q}\t{%1, %P0|%P0, %1}
2055   mov{q}\t{%1, %a0|%a0, %1}"
2056  [(set_attr "type" "imov")
2057   (set_attr "modrm" "0,*")
2058   (set_attr "length_address" "8,0")
2059   (set_attr "length_immediate" "0,*")
2060   (set_attr "memory" "store")
2061   (set_attr "mode" "DI")])
2062
2063(define_insn "*movabsdi_2_rex64"
2064  [(set (match_operand:DI 0 "register_operand" "=a,r")
2065        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2066  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2067  "@
2068   movabs{q}\t{%P1, %0|%0, %P1}
2069   mov{q}\t{%a1, %0|%0, %a1}"
2070  [(set_attr "type" "imov")
2071   (set_attr "modrm" "0,*")
2072   (set_attr "length_address" "8,0")
2073   (set_attr "length_immediate" "0")
2074   (set_attr "memory" "load")
2075   (set_attr "mode" "DI")])
2076
2077;; Convert impossible stores of immediate to existing instructions.
2078;; First try to get scratch register and go through it.  In case this
2079;; fails, move by 32bit parts.
2080(define_peephole2
2081  [(match_scratch:DI 2 "r")
2082   (set (match_operand:DI 0 "memory_operand" "")
2083        (match_operand:DI 1 "immediate_operand" ""))]
2084  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2085   && !x86_64_immediate_operand (operands[1], DImode)"
2086  [(set (match_dup 2) (match_dup 1))
2087   (set (match_dup 0) (match_dup 2))]
2088  "")
2089
2090;; We need to define this as both peepholer and splitter for case
2091;; peephole2 pass is not run.
2092;; "&& 1" is needed to keep it from matching the previous pattern.
2093(define_peephole2
2094  [(set (match_operand:DI 0 "memory_operand" "")
2095        (match_operand:DI 1 "immediate_operand" ""))]
2096  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2097   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2098  [(set (match_dup 2) (match_dup 3))
2099   (set (match_dup 4) (match_dup 5))]
2100  "split_di (operands, 2, operands + 2, operands + 4);")
2101
2102(define_split
2103  [(set (match_operand:DI 0 "memory_operand" "")
2104        (match_operand:DI 1 "immediate_operand" ""))]
2105  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2106		    ? flow2_completed : reload_completed)
2107   && !symbolic_operand (operands[1], DImode)
2108   && !x86_64_immediate_operand (operands[1], DImode)"
2109  [(set (match_dup 2) (match_dup 3))
2110   (set (match_dup 4) (match_dup 5))]
2111  "split_di (operands, 2, operands + 2, operands + 4);")
2112
2113(define_insn "*swapdi_rex64"
2114  [(set (match_operand:DI 0 "register_operand" "+r")
2115	(match_operand:DI 1 "register_operand" "+r"))
2116   (set (match_dup 1)
2117	(match_dup 0))]
2118  "TARGET_64BIT"
2119  "xchg{q}\t%1, %0"
2120  [(set_attr "type" "imov")
2121   (set_attr "mode" "DI")
2122   (set_attr "pent_pair" "np")
2123   (set_attr "athlon_decode" "vector")])
2124
2125(define_expand "movti"
2126  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2127	(match_operand:TI 1 "nonimmediate_operand" ""))]
2128  "TARGET_SSE || TARGET_64BIT"
2129{
2130  if (TARGET_64BIT)
2131    ix86_expand_move (TImode, operands);
2132  else
2133    ix86_expand_vector_move (TImode, operands);
2134  DONE;
2135})
2136
2137(define_insn "*movti_internal"
2138  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2139	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2140  "TARGET_SSE && !TARGET_64BIT
2141   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2142{
2143  switch (which_alternative)
2144    {
2145    case 0:
2146      if (get_attr_mode (insn) == MODE_V4SF)
2147	return "xorps\t%0, %0";
2148      else
2149	return "pxor\t%0, %0";
2150    case 1:
2151    case 2:
2152      if (get_attr_mode (insn) == MODE_V4SF)
2153	return "movaps\t{%1, %0|%0, %1}";
2154      else
2155	return "movdqa\t{%1, %0|%0, %1}";
2156    default:
2157      gcc_unreachable ();
2158    }
2159}
2160  [(set_attr "type" "sselog1,ssemov,ssemov")
2161   (set (attr "mode")
2162	(cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2163		    (ne (symbol_ref "optimize_size") (const_int 0)))
2164		 (const_string "V4SF")
2165	       (and (eq_attr "alternative" "2")
2166		    (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2167			(const_int 0)))
2168		 (const_string "V4SF")]
2169	      (const_string "TI")))])
2170
2171(define_insn "*movti_rex64"
2172  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2173	(match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2174  "TARGET_64BIT
2175   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2176{
2177  switch (which_alternative)
2178    {
2179    case 0:
2180    case 1:
2181      return "#";
2182    case 2:
2183      if (get_attr_mode (insn) == MODE_V4SF)
2184	return "xorps\t%0, %0";
2185      else
2186	return "pxor\t%0, %0";
2187    case 3:
2188    case 4:
2189      if (get_attr_mode (insn) == MODE_V4SF)
2190	return "movaps\t{%1, %0|%0, %1}";
2191      else
2192	return "movdqa\t{%1, %0|%0, %1}";
2193    default:
2194      gcc_unreachable ();
2195    }
2196}
2197  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2198   (set (attr "mode")
2199        (cond [(eq_attr "alternative" "2,3")
2200		 (if_then_else
2201		   (ne (symbol_ref "optimize_size")
2202		       (const_int 0))
2203		   (const_string "V4SF")
2204		   (const_string "TI"))
2205	       (eq_attr "alternative" "4")
2206		 (if_then_else
2207		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2208			    (const_int 0))
2209			(ne (symbol_ref "optimize_size")
2210			    (const_int 0)))
2211		   (const_string "V4SF")
2212		   (const_string "TI"))]
2213	       (const_string "DI")))])
2214
2215(define_split
2216  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2217        (match_operand:TI 1 "general_operand" ""))]
2218  "reload_completed && !SSE_REG_P (operands[0])
2219   && !SSE_REG_P (operands[1])"
2220  [(const_int 0)]
2221  "ix86_split_long_move (operands); DONE;")
2222
2223(define_expand "movsf"
2224  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2225	(match_operand:SF 1 "general_operand" ""))]
2226  ""
2227  "ix86_expand_move (SFmode, operands); DONE;")
2228
2229(define_insn "*pushsf"
2230  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2231	(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2232  "!TARGET_64BIT"
2233{
2234  /* Anything else should be already split before reg-stack.  */
2235  gcc_assert (which_alternative == 1);
2236  return "push{l}\t%1";
2237}
2238  [(set_attr "type" "multi,push,multi")
2239   (set_attr "unit" "i387,*,*")
2240   (set_attr "mode" "SF,SI,SF")])
2241
2242(define_insn "*pushsf_rex64"
2243  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2244	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2245  "TARGET_64BIT"
2246{
2247  /* Anything else should be already split before reg-stack.  */
2248  gcc_assert (which_alternative == 1);
2249  return "push{q}\t%q1";
2250}
2251  [(set_attr "type" "multi,push,multi")
2252   (set_attr "unit" "i387,*,*")
2253   (set_attr "mode" "SF,DI,SF")])
2254
2255(define_split
2256  [(set (match_operand:SF 0 "push_operand" "")
2257	(match_operand:SF 1 "memory_operand" ""))]
2258  "reload_completed
2259   && GET_CODE (operands[1]) == MEM
2260   && constant_pool_reference_p (operands[1])"
2261  [(set (match_dup 0)
2262	(match_dup 1))]
2263  "operands[1] = avoid_constant_pool_reference (operands[1]);")
2264
2265
2266;; %%% Kill this when call knows how to work this out.
2267(define_split
2268  [(set (match_operand:SF 0 "push_operand" "")
2269	(match_operand:SF 1 "any_fp_register_operand" ""))]
2270  "!TARGET_64BIT"
2271  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2272   (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2273
2274(define_split
2275  [(set (match_operand:SF 0 "push_operand" "")
2276	(match_operand:SF 1 "any_fp_register_operand" ""))]
2277  "TARGET_64BIT"
2278  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2279   (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2280
2281(define_insn "*movsf_1"
2282  [(set (match_operand:SF 0 "nonimmediate_operand"
2283	  "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2284	(match_operand:SF 1 "general_operand"
2285	  "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2286  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2287   && (reload_in_progress || reload_completed
2288       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2289       || GET_CODE (operands[1]) != CONST_DOUBLE
2290       || memory_operand (operands[0], SFmode))" 
2291{
2292  switch (which_alternative)
2293    {
2294    case 0:
2295      return output_387_reg_move (insn, operands);
2296
2297    case 1:
2298      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2299        return "fstp%z0\t%y0";
2300      else
2301        return "fst%z0\t%y0";
2302
2303    case 2:
2304      return standard_80387_constant_opcode (operands[1]);
2305
2306    case 3:
2307    case 4:
2308      return "mov{l}\t{%1, %0|%0, %1}";
2309    case 5:
2310      if (get_attr_mode (insn) == MODE_TI)
2311	return "pxor\t%0, %0";
2312      else
2313	return "xorps\t%0, %0";
2314    case 6:
2315      if (get_attr_mode (insn) == MODE_V4SF)
2316	return "movaps\t{%1, %0|%0, %1}";
2317      else
2318	return "movss\t{%1, %0|%0, %1}";
2319    case 7:
2320    case 8:
2321      return "movss\t{%1, %0|%0, %1}";
2322
2323    case 9:
2324    case 10:
2325      return "movd\t{%1, %0|%0, %1}";
2326
2327    case 11:
2328      return "movq\t{%1, %0|%0, %1}";
2329
2330    default:
2331      gcc_unreachable ();
2332    }
2333}
2334  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2335   (set (attr "mode")
2336        (cond [(eq_attr "alternative" "3,4,9,10")
2337		 (const_string "SI")
2338	       (eq_attr "alternative" "5")
2339		 (if_then_else
2340		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2341			    	 (const_int 0))
2342			     (ne (symbol_ref "TARGET_SSE2")
2343				 (const_int 0)))
2344			(eq (symbol_ref "optimize_size")
2345			    (const_int 0)))
2346		   (const_string "TI")
2347		   (const_string "V4SF"))
2348	       /* For architectures resolving dependencies on
2349		  whole SSE registers use APS move to break dependency
2350		  chains, otherwise use short move to avoid extra work. 
2351
2352		  Do the same for architectures resolving dependencies on
2353		  the parts.  While in DF mode it is better to always handle
2354		  just register parts, the SF mode is different due to lack
2355		  of instructions to load just part of the register.  It is
2356		  better to maintain the whole registers in single format
2357		  to avoid problems on using packed logical operations.  */
2358	       (eq_attr "alternative" "6")
2359		 (if_then_else
2360		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2361			    (const_int 0))
2362			(ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2363			    (const_int 0)))
2364		   (const_string "V4SF")
2365		   (const_string "SF"))
2366	       (eq_attr "alternative" "11")
2367		 (const_string "DI")]
2368	       (const_string "SF")))])
2369
2370(define_insn "*swapsf"
2371  [(set (match_operand:SF 0 "fp_register_operand" "+f")
2372	(match_operand:SF 1 "fp_register_operand" "+f"))
2373   (set (match_dup 1)
2374	(match_dup 0))]
2375  "reload_completed || TARGET_80387"
2376{
2377  if (STACK_TOP_P (operands[0]))
2378    return "fxch\t%1";
2379  else
2380    return "fxch\t%0";
2381}
2382  [(set_attr "type" "fxch")
2383   (set_attr "mode" "SF")])
2384
2385(define_expand "movdf"
2386  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2387	(match_operand:DF 1 "general_operand" ""))]
2388  ""
2389  "ix86_expand_move (DFmode, operands); DONE;")
2390
2391;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2392;; Size of pushdf using integer instructions is 2+2*memory operand size
2393;; On the average, pushdf using integers can be still shorter.  Allow this
2394;; pattern for optimize_size too.
2395
2396(define_insn "*pushdf_nointeger"
2397  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2398	(match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2399  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2400{
2401  /* This insn should be already split before reg-stack.  */
2402  gcc_unreachable ();
2403}
2404  [(set_attr "type" "multi")
2405   (set_attr "unit" "i387,*,*,*")
2406   (set_attr "mode" "DF,SI,SI,DF")])
2407
2408(define_insn "*pushdf_integer"
2409  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2410	(match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2411  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2412{
2413  /* This insn should be already split before reg-stack.  */
2414  gcc_unreachable ();
2415}
2416  [(set_attr "type" "multi")
2417   (set_attr "unit" "i387,*,*")
2418   (set_attr "mode" "DF,SI,DF")])
2419
2420;; %%% Kill this when call knows how to work this out.
2421(define_split
2422  [(set (match_operand:DF 0 "push_operand" "")
2423	(match_operand:DF 1 "any_fp_register_operand" ""))]
2424  "!TARGET_64BIT && reload_completed"
2425  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2426   (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2427  "")
2428
2429(define_split
2430  [(set (match_operand:DF 0 "push_operand" "")
2431	(match_operand:DF 1 "any_fp_register_operand" ""))]
2432  "TARGET_64BIT && reload_completed"
2433  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2434   (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2435  "")
2436
2437(define_split
2438  [(set (match_operand:DF 0 "push_operand" "")
2439	(match_operand:DF 1 "general_operand" ""))]
2440  "reload_completed"
2441  [(const_int 0)]
2442  "ix86_split_long_move (operands); DONE;")
2443
2444;; Moving is usually shorter when only FP registers are used. This separate
2445;; movdf pattern avoids the use of integer registers for FP operations
2446;; when optimizing for size.
2447
2448(define_insn "*movdf_nointeger"
2449  [(set (match_operand:DF 0 "nonimmediate_operand"
2450			"=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2451	(match_operand:DF 1 "general_operand"
2452			"fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2453  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2454   && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2455   && (reload_in_progress || reload_completed
2456       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2457       || GET_CODE (operands[1]) != CONST_DOUBLE
2458       || memory_operand (operands[0], DFmode))" 
2459{
2460  switch (which_alternative)
2461    {
2462    case 0:
2463      return output_387_reg_move (insn, operands);
2464
2465    case 1:
2466      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2467        return "fstp%z0\t%y0";
2468      else
2469        return "fst%z0\t%y0";
2470
2471    case 2:
2472      return standard_80387_constant_opcode (operands[1]);
2473
2474    case 3:
2475    case 4:
2476      return "#";
2477    case 5:
2478      switch (get_attr_mode (insn))
2479	{
2480	case MODE_V4SF:
2481	  return "xorps\t%0, %0";
2482	case MODE_V2DF:
2483	  return "xorpd\t%0, %0";
2484	case MODE_TI:
2485	  return "pxor\t%0, %0";
2486	default:
2487	  gcc_unreachable ();
2488	}
2489    case 6:
2490    case 7:
2491    case 8:
2492      switch (get_attr_mode (insn))
2493	{
2494	case MODE_V4SF:
2495	  return "movaps\t{%1, %0|%0, %1}";
2496	case MODE_V2DF:
2497	  return "movapd\t{%1, %0|%0, %1}";
2498	case MODE_TI:
2499	  return "movdqa\t{%1, %0|%0, %1}";
2500	case MODE_DI:
2501	  return "movq\t{%1, %0|%0, %1}";
2502	case MODE_DF:
2503	  return "movsd\t{%1, %0|%0, %1}";
2504	case MODE_V1DF:
2505	  return "movlpd\t{%1, %0|%0, %1}";
2506	case MODE_V2SF:
2507	  return "movlps\t{%1, %0|%0, %1}";
2508	default:
2509	  gcc_unreachable ();
2510	}
2511
2512    default:
2513      gcc_unreachable ();
2514    }
2515}
2516  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2517   (set (attr "mode")
2518        (cond [(eq_attr "alternative" "0,1,2")
2519		 (const_string "DF")
2520	       (eq_attr "alternative" "3,4")
2521		 (const_string "SI")
2522
2523	       /* For SSE1, we have many fewer alternatives.  */
2524	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2525		 (cond [(eq_attr "alternative" "5,6")
2526			  (const_string "V4SF")
2527		       ]
2528		   (const_string "V2SF"))
2529
2530	       /* xorps is one byte shorter.  */
2531	       (eq_attr "alternative" "5")
2532		 (cond [(ne (symbol_ref "optimize_size")
2533			    (const_int 0))
2534			  (const_string "V4SF")
2535			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2536			    (const_int 0))
2537			  (const_string "TI")
2538		       ]
2539		       (const_string "V2DF"))
2540
2541	       /* For architectures resolving dependencies on
2542		  whole SSE registers use APD move to break dependency
2543		  chains, otherwise use short move to avoid extra work.
2544
2545		  movaps encodes one byte shorter.  */
2546	       (eq_attr "alternative" "6")
2547		 (cond
2548		   [(ne (symbol_ref "optimize_size")
2549		        (const_int 0))
2550		      (const_string "V4SF")
2551		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2552		        (const_int 0))
2553		      (const_string "V2DF")
2554		   ]
2555		   (const_string "DF"))
2556	       /* For architectures resolving dependencies on register
2557		  parts we may avoid extra work to zero out upper part
2558		  of register.  */
2559	       (eq_attr "alternative" "7")
2560		 (if_then_else
2561		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2562		       (const_int 0))
2563		   (const_string "V1DF")
2564		   (const_string "DF"))
2565	      ]
2566	      (const_string "DF")))])
2567
2568(define_insn "*movdf_integer"
2569  [(set (match_operand:DF 0 "nonimmediate_operand"
2570		"=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2571	(match_operand:DF 1 "general_operand"
2572		"fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2573  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2574   && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2575   && (reload_in_progress || reload_completed
2576       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2577       || GET_CODE (operands[1]) != CONST_DOUBLE
2578       || memory_operand (operands[0], DFmode))" 
2579{
2580  switch (which_alternative)
2581    {
2582    case 0:
2583      return output_387_reg_move (insn, operands);
2584
2585    case 1:
2586      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2587        return "fstp%z0\t%y0";
2588      else
2589        return "fst%z0\t%y0";
2590
2591    case 2:
2592      return standard_80387_constant_opcode (operands[1]);
2593
2594    case 3:
2595    case 4:
2596      return "#";
2597
2598    case 5:
2599      switch (get_attr_mode (insn))
2600	{
2601	case MODE_V4SF:
2602	  return "xorps\t%0, %0";
2603	case MODE_V2DF:
2604	  return "xorpd\t%0, %0";
2605	case MODE_TI:
2606	  return "pxor\t%0, %0";
2607	default:
2608	  gcc_unreachable ();
2609	}
2610    case 6:
2611    case 7:
2612    case 8:
2613      switch (get_attr_mode (insn))
2614	{
2615	case MODE_V4SF:
2616	  return "movaps\t{%1, %0|%0, %1}";
2617	case MODE_V2DF:
2618	  return "movapd\t{%1, %0|%0, %1}";
2619	case MODE_TI:
2620	  return "movdqa\t{%1, %0|%0, %1}";
2621	case MODE_DI:
2622	  return "movq\t{%1, %0|%0, %1}";
2623	case MODE_DF:
2624	  return "movsd\t{%1, %0|%0, %1}";
2625	case MODE_V1DF:
2626	  return "movlpd\t{%1, %0|%0, %1}";
2627	case MODE_V2SF:
2628	  return "movlps\t{%1, %0|%0, %1}";
2629	default:
2630	  gcc_unreachable ();
2631	}
2632
2633    default:
2634      gcc_unreachable();
2635    }
2636}
2637  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2638   (set (attr "mode")
2639        (cond [(eq_attr "alternative" "0,1,2")
2640		 (const_string "DF")
2641	       (eq_attr "alternative" "3,4")
2642		 (const_string "SI")
2643
2644	       /* For SSE1, we have many fewer alternatives.  */
2645	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2646		 (cond [(eq_attr "alternative" "5,6")
2647			  (const_string "V4SF")
2648		       ]
2649		   (const_string "V2SF"))
2650
2651	       /* xorps is one byte shorter.  */
2652	       (eq_attr "alternative" "5")
2653		 (cond [(ne (symbol_ref "optimize_size")
2654			    (const_int 0))
2655			  (const_string "V4SF")
2656			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2657			    (const_int 0))
2658			  (const_string "TI")
2659		       ]
2660		       (const_string "V2DF"))
2661
2662	       /* For architectures resolving dependencies on
2663		  whole SSE registers use APD move to break dependency
2664		  chains, otherwise use short move to avoid extra work.
2665
2666		  movaps encodes one byte shorter.  */
2667	       (eq_attr "alternative" "6")
2668		 (cond
2669		   [(ne (symbol_ref "optimize_size")
2670		        (const_int 0))
2671		      (const_string "V4SF")
2672		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2673		        (const_int 0))
2674		      (const_string "V2DF")
2675		   ]
2676		   (const_string "DF"))
2677	       /* For architectures resolving dependencies on register
2678		  parts we may avoid extra work to zero out upper part
2679		  of register.  */
2680	       (eq_attr "alternative" "7")
2681		 (if_then_else
2682		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2683		       (const_int 0))
2684		   (const_string "V1DF")
2685		   (const_string "DF"))
2686	      ]
2687	      (const_string "DF")))])
2688
2689(define_split
2690  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2691	(match_operand:DF 1 "general_operand" ""))]
2692  "reload_completed
2693   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2694   && ! (ANY_FP_REG_P (operands[0]) || 
2695	 (GET_CODE (operands[0]) == SUBREG
2696	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2697   && ! (ANY_FP_REG_P (operands[1]) || 
2698	 (GET_CODE (operands[1]) == SUBREG
2699	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2700  [(const_int 0)]
2701  "ix86_split_long_move (operands); DONE;")
2702
2703(define_insn "*swapdf"
2704  [(set (match_operand:DF 0 "fp_register_operand" "+f")
2705	(match_operand:DF 1 "fp_register_operand" "+f"))
2706   (set (match_dup 1)
2707	(match_dup 0))]
2708  "reload_completed || TARGET_80387"
2709{
2710  if (STACK_TOP_P (operands[0]))
2711    return "fxch\t%1";
2712  else
2713    return "fxch\t%0";
2714}
2715  [(set_attr "type" "fxch")
2716   (set_attr "mode" "DF")])
2717
2718(define_expand "movxf"
2719  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2720	(match_operand:XF 1 "general_operand" ""))]
2721  ""
2722  "ix86_expand_move (XFmode, operands); DONE;")
2723
2724;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2725;; Size of pushdf using integer instructions is 3+3*memory operand size
2726;; Pushing using integer instructions is longer except for constants
2727;; and direct memory references.
2728;; (assuming that any given constant is pushed only once, but this ought to be
2729;;  handled elsewhere).
2730
2731(define_insn "*pushxf_nointeger"
2732  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2733	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2734  "optimize_size"
2735{
2736  /* This insn should be already split before reg-stack.  */
2737  gcc_unreachable ();
2738}
2739  [(set_attr "type" "multi")
2740   (set_attr "unit" "i387,*,*")
2741   (set_attr "mode" "XF,SI,SI")])
2742
2743(define_insn "*pushxf_integer"
2744  [(set (match_operand:XF 0 "push_operand" "=<,<")
2745	(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2746  "!optimize_size"
2747{
2748  /* This insn should be already split before reg-stack.  */
2749  gcc_unreachable ();
2750}
2751  [(set_attr "type" "multi")
2752   (set_attr "unit" "i387,*")
2753   (set_attr "mode" "XF,SI")])
2754
2755(define_split
2756  [(set (match_operand 0 "push_operand" "")
2757	(match_operand 1 "general_operand" ""))]
2758  "reload_completed
2759   && (GET_MODE (operands[0]) == XFmode
2760       || GET_MODE (operands[0]) == DFmode)
2761   && !ANY_FP_REG_P (operands[1])"
2762  [(const_int 0)]
2763  "ix86_split_long_move (operands); DONE;")
2764
2765(define_split
2766  [(set (match_operand:XF 0 "push_operand" "")
2767	(match_operand:XF 1 "any_fp_register_operand" ""))]
2768  "!TARGET_64BIT"
2769  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2770   (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2771  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772
2773(define_split
2774  [(set (match_operand:XF 0 "push_operand" "")
2775	(match_operand:XF 1 "any_fp_register_operand" ""))]
2776  "TARGET_64BIT"
2777  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2778   (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2779  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2780
2781;; Do not use integer registers when optimizing for size
2782(define_insn "*movxf_nointeger"
2783  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2784	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2785  "optimize_size
2786   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2787   && (reload_in_progress || reload_completed
2788       || GET_CODE (operands[1]) != CONST_DOUBLE
2789       || memory_operand (operands[0], XFmode))" 
2790{
2791  switch (which_alternative)
2792    {
2793    case 0:
2794      return output_387_reg_move (insn, operands);
2795
2796    case 1:
2797      /* There is no non-popping store to memory for XFmode.  So if
2798	 we need one, follow the store with a load.  */
2799      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2800        return "fstp%z0\t%y0\;fld%z0\t%y0";
2801      else
2802        return "fstp%z0\t%y0";
2803
2804    case 2:
2805      return standard_80387_constant_opcode (operands[1]);
2806
2807    case 3: case 4:
2808      return "#";
2809    default:
2810      gcc_unreachable ();
2811    }
2812}
2813  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2814   (set_attr "mode" "XF,XF,XF,SI,SI")])
2815
2816(define_insn "*movxf_integer"
2817  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2818	(match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2819  "!optimize_size
2820   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2821   && (reload_in_progress || reload_completed
2822       || GET_CODE (operands[1]) != CONST_DOUBLE
2823       || memory_operand (operands[0], XFmode))" 
2824{
2825  switch (which_alternative)
2826    {
2827    case 0:
2828      return output_387_reg_move (insn, operands);
2829
2830    case 1:
2831      /* There is no non-popping store to memory for XFmode.  So if
2832	 we need one, follow the store with a load.  */
2833      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2834        return "fstp%z0\t%y0\;fld%z0\t%y0";
2835      else
2836        return "fstp%z0\t%y0";
2837
2838    case 2:
2839      return standard_80387_constant_opcode (operands[1]);
2840
2841    case 3: case 4:
2842      return "#";
2843
2844    default:
2845      gcc_unreachable ();
2846    }
2847}
2848  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2849   (set_attr "mode" "XF,XF,XF,SI,SI")])
2850
2851(define_split
2852  [(set (match_operand 0 "nonimmediate_operand" "")
2853	(match_operand 1 "general_operand" ""))]
2854  "reload_completed
2855   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2856   && GET_MODE (operands[0]) == XFmode
2857   && ! (ANY_FP_REG_P (operands[0]) || 
2858	 (GET_CODE (operands[0]) == SUBREG
2859	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2860   && ! (ANY_FP_REG_P (operands[1]) || 
2861	 (GET_CODE (operands[1]) == SUBREG
2862	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2863  [(const_int 0)]
2864  "ix86_split_long_move (operands); DONE;")
2865
2866(define_split
2867  [(set (match_operand 0 "register_operand" "")
2868	(match_operand 1 "memory_operand" ""))]
2869  "reload_completed
2870   && GET_CODE (operands[1]) == MEM
2871   && (GET_MODE (operands[0]) == XFmode
2872       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2873   && constant_pool_reference_p (operands[1])"
2874  [(set (match_dup 0) (match_dup 1))]
2875{
2876  rtx c = avoid_constant_pool_reference (operands[1]);
2877  rtx r = operands[0];
2878
2879  if (GET_CODE (r) == SUBREG)
2880    r = SUBREG_REG (r);
2881
2882  if (SSE_REG_P (r))
2883    {
2884      if (!standard_sse_constant_p (c))
2885	FAIL;
2886    }
2887  else if (FP_REG_P (r))
2888    {
2889      if (!standard_80387_constant_p (c))
2890	FAIL;
2891    }
2892  else if (MMX_REG_P (r))
2893    FAIL;
2894
2895  operands[1] = c;
2896})
2897
2898(define_insn "swapxf"
2899  [(set (match_operand:XF 0 "register_operand" "+f")
2900	(match_operand:XF 1 "register_operand" "+f"))
2901   (set (match_dup 1)
2902	(match_dup 0))]
2903  "TARGET_80387"
2904{
2905  if (STACK_TOP_P (operands[0]))
2906    return "fxch\t%1";
2907  else
2908    return "fxch\t%0";
2909}
2910  [(set_attr "type" "fxch")
2911   (set_attr "mode" "XF")])
2912
2913(define_expand "movtf"
2914  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2915	(match_operand:TF 1 "nonimmediate_operand" ""))]
2916  "TARGET_64BIT"
2917{
2918  ix86_expand_move (TFmode, operands);
2919  DONE;
2920})
2921
2922(define_insn "*movtf_internal"
2923  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2924	(match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2925  "TARGET_64BIT
2926   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2927{
2928  switch (which_alternative)
2929    {
2930    case 0:
2931    case 1:
2932      return "#";
2933    case 2:
2934      if (get_attr_mode (insn) == MODE_V4SF)
2935	return "xorps\t%0, %0";
2936      else
2937	return "pxor\t%0, %0";
2938    case 3:
2939    case 4:
2940      if (get_attr_mode (insn) == MODE_V4SF)
2941	return "movaps\t{%1, %0|%0, %1}";
2942      else
2943	return "movdqa\t{%1, %0|%0, %1}";
2944    default:
2945      gcc_unreachable ();
2946    }
2947}
2948  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2949   (set (attr "mode")
2950        (cond [(eq_attr "alternative" "2,3")
2951		 (if_then_else
2952		   (ne (symbol_ref "optimize_size")
2953		       (const_int 0))
2954		   (const_string "V4SF")
2955		   (const_string "TI"))
2956	       (eq_attr "alternative" "4")
2957		 (if_then_else
2958		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2959			    (const_int 0))
2960			(ne (symbol_ref "optimize_size")
2961			    (const_int 0)))
2962		   (const_string "V4SF")
2963		   (const_string "TI"))]
2964	       (const_string "DI")))])
2965
2966(define_split
2967  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2968        (match_operand:TF 1 "general_operand" ""))]
2969  "reload_completed && !SSE_REG_P (operands[0])
2970   && !SSE_REG_P (operands[1])"
2971  [(const_int 0)]
2972  "ix86_split_long_move (operands); DONE;")
2973
2974;; Zero extension instructions
2975
2976(define_expand "zero_extendhisi2"
2977  [(set (match_operand:SI 0 "register_operand" "")
2978     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2979  ""
2980{
2981  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2982    {
2983      operands[1] = force_reg (HImode, operands[1]);
2984      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2985      DONE;
2986    }
2987})
2988
2989(define_insn "zero_extendhisi2_and"
2990  [(set (match_operand:SI 0 "register_operand" "=r")
2991     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2992   (clobber (reg:CC FLAGS_REG))]
2993  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2994  "#"
2995  [(set_attr "type" "alu1")
2996   (set_attr "mode" "SI")])
2997
2998(define_split
2999  [(set (match_operand:SI 0 "register_operand" "")
3000	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3001   (clobber (reg:CC FLAGS_REG))]
3002  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3003  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3004	      (clobber (reg:CC FLAGS_REG))])]
3005  "")
3006
3007(define_insn "*zero_extendhisi2_movzwl"
3008  [(set (match_operand:SI 0 "register_operand" "=r")
3009     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3010  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3011  "movz{wl|x}\t{%1, %0|%0, %1}"
3012  [(set_attr "type" "imovx")
3013   (set_attr "mode" "SI")])
3014
3015(define_expand "zero_extendqihi2"
3016  [(parallel
3017    [(set (match_operand:HI 0 "register_operand" "")
3018       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3019     (clobber (reg:CC FLAGS_REG))])]
3020  ""
3021  "")
3022
3023(define_insn "*zero_extendqihi2_and"
3024  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3025     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3026   (clobber (reg:CC FLAGS_REG))]
3027  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3028  "#"
3029  [(set_attr "type" "alu1")
3030   (set_attr "mode" "HI")])
3031
3032(define_insn "*zero_extendqihi2_movzbw_and"
3033  [(set (match_operand:HI 0 "register_operand" "=r,r")
3034     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3035   (clobber (reg:CC FLAGS_REG))]
3036  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3037  "#"
3038  [(set_attr "type" "imovx,alu1")
3039   (set_attr "mode" "HI")])
3040
3041; zero extend to SImode here to avoid partial register stalls
3042(define_insn "*zero_extendqihi2_movzbl"
3043  [(set (match_operand:HI 0 "register_operand" "=r")
3044     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3045  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3046  "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3047  [(set_attr "type" "imovx")
3048   (set_attr "mode" "SI")])
3049
3050;; For the movzbw case strip only the clobber
3051(define_split
3052  [(set (match_operand:HI 0 "register_operand" "")
3053	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3054   (clobber (reg:CC FLAGS_REG))]
3055  "reload_completed 
3056   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3057   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3058  [(set (match_operand:HI 0 "register_operand" "")
3059	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3060
3061;; When source and destination does not overlap, clear destination
3062;; first and then do the movb
3063(define_split
3064  [(set (match_operand:HI 0 "register_operand" "")
3065	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3066   (clobber (reg:CC FLAGS_REG))]
3067  "reload_completed
3068   && ANY_QI_REG_P (operands[0])
3069   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3070   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3071  [(set (match_dup 0) (const_int 0))
3072   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3073  "operands[2] = gen_lowpart (QImode, operands[0]);")
3074
3075;; Rest is handled by single and.
3076(define_split
3077  [(set (match_operand:HI 0 "register_operand" "")
3078	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3079   (clobber (reg:CC FLAGS_REG))]
3080  "reload_completed
3081   && true_regnum (operands[0]) == true_regnum (operands[1])"
3082  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3083	      (clobber (reg:CC FLAGS_REG))])]
3084  "")
3085
3086(define_expand "zero_extendqisi2"
3087  [(parallel
3088    [(set (match_operand:SI 0 "register_operand" "")
3089       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3090     (clobber (reg:CC FLAGS_REG))])]
3091  ""
3092  "")
3093
3094(define_insn "*zero_extendqisi2_and"
3095  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3096     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3097   (clobber (reg:CC FLAGS_REG))]
3098  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3099  "#"
3100  [(set_attr "type" "alu1")
3101   (set_attr "mode" "SI")])
3102
3103(define_insn "*zero_extendqisi2_movzbw_and"
3104  [(set (match_operand:SI 0 "register_operand" "=r,r")
3105     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3106   (clobber (reg:CC FLAGS_REG))]
3107  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3108  "#"
3109  [(set_attr "type" "imovx,alu1")
3110   (set_attr "mode" "SI")])
3111
3112(define_insn "*zero_extendqisi2_movzbw"
3113  [(set (match_operand:SI 0 "register_operand" "=r")
3114     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3115  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3116  "movz{bl|x}\t{%1, %0|%0, %1}"
3117  [(set_attr "type" "imovx")
3118   (set_attr "mode" "SI")])
3119
3120;; For the movzbl case strip only the clobber
3121(define_split
3122  [(set (match_operand:SI 0 "register_operand" "")
3123	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3124   (clobber (reg:CC FLAGS_REG))]
3125  "reload_completed 
3126   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3127   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3128  [(set (match_dup 0)
3129	(zero_extend:SI (match_dup 1)))])
3130
3131;; When source and destination does not overlap, clear destination
3132;; first and then do the movb
3133(define_split
3134  [(set (match_operand:SI 0 "register_operand" "")
3135	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3136   (clobber (reg:CC FLAGS_REG))]
3137  "reload_completed
3138   && ANY_QI_REG_P (operands[0])
3139   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3140   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3141   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3142  [(set (match_dup 0) (const_int 0))
3143   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3144  "operands[2] = gen_lowpart (QImode, operands[0]);")
3145
3146;; Rest is handled by single and.
3147(define_split
3148  [(set (match_operand:SI 0 "register_operand" "")
3149	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3150   (clobber (reg:CC FLAGS_REG))]
3151  "reload_completed
3152   && true_regnum (operands[0]) == true_regnum (operands[1])"
3153  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3154	      (clobber (reg:CC FLAGS_REG))])]
3155  "")
3156
3157;; %%% Kill me once multi-word ops are sane.
3158(define_expand "zero_extendsidi2"
3159  [(set (match_operand:DI 0 "register_operand" "=r")
3160     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3161  ""
3162  "if (!TARGET_64BIT)
3163     {
3164       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3165       DONE;
3166     }
3167  ")
3168
3169(define_insn "zero_extendsidi2_32"
3170  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3171	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3172   (clobber (reg:CC FLAGS_REG))]
3173  "!TARGET_64BIT"
3174  "@
3175   #
3176   #
3177   #
3178   movd\t{%1, %0|%0, %1}
3179   movd\t{%1, %0|%0, %1}"
3180  [(set_attr "mode" "SI,SI,SI,DI,TI")
3181   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3182
3183(define_insn "zero_extendsidi2_rex64"
3184  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3185     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3186  "TARGET_64BIT"
3187  "@
3188   mov\t{%k1, %k0|%k0, %k1}
3189   #
3190   movd\t{%1, %0|%0, %1}
3191   movd\t{%1, %0|%0, %1}"
3192  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3193   (set_attr "mode" "SI,DI,SI,SI")])
3194
3195(define_split
3196  [(set (match_operand:DI 0 "memory_operand" "")
3197     (zero_extend:DI (match_dup 0)))]
3198  "TARGET_64BIT"
3199  [(set (match_dup 4) (const_int 0))]
3200  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3201
3202(define_split 
3203  [(set (match_operand:DI 0 "register_operand" "")
3204	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3205   (clobber (reg:CC FLAGS_REG))]
3206  "!TARGET_64BIT && reload_completed
3207   && true_regnum (operands[0]) == true_regnum (operands[1])"
3208  [(set (match_dup 4) (const_int 0))]
3209  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3210
3211(define_split 
3212  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3213	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3214   (clobber (reg:CC FLAGS_REG))]
3215  "!TARGET_64BIT && reload_completed
3216   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3217  [(set (match_dup 3) (match_dup 1))
3218   (set (match_dup 4) (const_int 0))]
3219  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3220
3221(define_insn "zero_extendhidi2"
3222  [(set (match_operand:DI 0 "register_operand" "=r")
3223     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3224  "TARGET_64BIT"
3225  "movz{wl|x}\t{%1, %k0|%k0, %1}"
3226  [(set_attr "type" "imovx")
3227   (set_attr "mode" "DI")])
3228
3229(define_insn "zero_extendqidi2"
3230  [(set (match_operand:DI 0 "register_operand" "=r")
3231     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3232  "TARGET_64BIT"
3233  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3234  [(set_attr "type" "imovx")
3235   (set_attr "mode" "DI")])
3236
3237;; Sign extension instructions
3238
3239(define_expand "extendsidi2"
3240  [(parallel [(set (match_operand:DI 0 "register_operand" "")
3241		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3242	      (clobber (reg:CC FLAGS_REG))
3243	      (clobber (match_scratch:SI 2 ""))])]
3244  ""
3245{
3246  if (TARGET_64BIT)
3247    {
3248      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3249      DONE;
3250    }
3251})
3252
3253(define_insn "*extendsidi2_1"
3254  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3255	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3256   (clobber (reg:CC FLAGS_REG))
3257   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3258  "!TARGET_64BIT"
3259  "#")
3260
3261(define_insn "extendsidi2_rex64"
3262  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3263	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3264  "TARGET_64BIT"
3265  "@
3266   {cltq|cdqe}
3267   movs{lq|x}\t{%1,%0|%0, %1}"
3268  [(set_attr "type" "imovx")
3269   (set_attr "mode" "DI")
3270   (set_attr "prefix_0f" "0")
3271   (set_attr "modrm" "0,1")])
3272
3273(define_insn "extendhidi2"
3274  [(set (match_operand:DI 0 "register_operand" "=r")
3275	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3276  "TARGET_64BIT"
3277  "movs{wq|x}\t{%1,%0|%0, %1}"
3278  [(set_attr "type" "imovx")
3279   (set_attr "mode" "DI")])
3280
3281(define_insn "extendqidi2"
3282  [(set (match_operand:DI 0 "register_operand" "=r")
3283	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3284  "TARGET_64BIT"
3285  "movs{bq|x}\t{%1,%0|%0, %1}"
3286   [(set_attr "type" "imovx")
3287    (set_attr "mode" "DI")])
3288
3289;; Extend to memory case when source register does die.
3290(define_split 
3291  [(set (match_operand:DI 0 "memory_operand" "")
3292	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3293   (clobber (reg:CC FLAGS_REG))
3294   (clobber (match_operand:SI 2 "register_operand" ""))]
3295  "(reload_completed
3296    && dead_or_set_p (insn, operands[1])
3297    && !reg_mentioned_p (operands[1], operands[0]))"
3298  [(set (match_dup 3) (match_dup 1))
3299   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3300	      (clobber (reg:CC FLAGS_REG))])
3301   (set (match_dup 4) (match_dup 1))]
3302  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3303
3304;; Extend to memory case when source register does not die.
3305(define_split 
3306  [(set (match_operand:DI 0 "memory_operand" "")
3307	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3308   (clobber (reg:CC FLAGS_REG))
3309   (clobber (match_operand:SI 2 "register_operand" ""))]
3310  "reload_completed"
3311  [(const_int 0)]
3312{
3313  split_di (&operands[0], 1, &operands[3], &operands[4]);
3314
3315  emit_move_insn (operands[3], operands[1]);
3316
3317  /* Generate a cltd if possible and doing so it profitable.  */
3318  if (true_regnum (operands[1]) == 0
3319      && true_regnum (operands[2]) == 1
3320      && (optimize_size || TARGET_USE_CLTD))
3321    {
3322      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3323    }
3324  else
3325    {
3326      emit_move_insn (operands[2], operands[1]);
3327      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3328    }
3329  emit_move_insn (operands[4], operands[2]);
3330  DONE;
3331})
3332
3333;; Extend to register case.  Optimize case where source and destination
3334;; registers match and cases where we can use cltd.
3335(define_split 
3336  [(set (match_operand:DI 0 "register_operand" "")
3337	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3338   (clobber (reg:CC FLAGS_REG))
3339   (clobber (match_scratch:SI 2 ""))]
3340  "reload_completed"
3341  [(const_int 0)]
3342{
3343  split_di (&operands[0], 1, &operands[3], &operands[4]);
3344
3345  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3346    emit_move_insn (operands[3], operands[1]);
3347
3348  /* Generate a cltd if possible and doing so it profitable.  */
3349  if (true_regnum (operands[3]) == 0
3350      && (optimize_size || TARGET_USE_CLTD))
3351    {
3352      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3353      DONE;
3354    }
3355
3356  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3357    emit_move_insn (operands[4], operands[1]);
3358
3359  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3360  DONE;
3361})
3362
3363(define_insn "extendhisi2"
3364  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3365	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3366  ""
3367{
3368  switch (get_attr_prefix_0f (insn))
3369    {
3370    case 0:
3371      return "{cwtl|cwde}";
3372    default:
3373      return "movs{wl|x}\t{%1,%0|%0, %1}";
3374    }
3375}
3376  [(set_attr "type" "imovx")
3377   (set_attr "mode" "SI")
3378   (set (attr "prefix_0f")
3379     ;; movsx is short decodable while cwtl is vector decoded.
3380     (if_then_else (and (eq_attr "cpu" "!k6")
3381			(eq_attr "alternative" "0"))
3382	(const_string "0")
3383	(const_string "1")))
3384   (set (attr "modrm")
3385     (if_then_else (eq_attr "prefix_0f" "0")
3386	(const_string "0")
3387	(const_string "1")))])
3388
3389(define_insn "*extendhisi2_zext"
3390  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3391	(zero_extend:DI
3392	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3393  "TARGET_64BIT"
3394{
3395  switch (get_attr_prefix_0f (insn))
3396    {
3397    case 0:
3398      return "{cwtl|cwde}";
3399    default:
3400      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3401    }
3402}
3403  [(set_attr "type" "imovx")
3404   (set_attr "mode" "SI")
3405   (set (attr "prefix_0f")
3406     ;; movsx is short decodable while cwtl is vector decoded.
3407     (if_then_else (and (eq_attr "cpu" "!k6")
3408			(eq_attr "alternative" "0"))
3409	(const_string "0")
3410	(const_string "1")))
3411   (set (attr "modrm")
3412     (if_then_else (eq_attr "prefix_0f" "0")
3413	(const_string "0")
3414	(const_string "1")))])
3415
3416(define_insn "extendqihi2"
3417  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3418	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3419  ""
3420{
3421  switch (get_attr_prefix_0f (insn))
3422    {
3423    case 0:
3424      return "{cbtw|cbw}";
3425    default:
3426      return "movs{bw|x}\t{%1,%0|%0, %1}";
3427    }
3428}
3429  [(set_attr "type" "imovx")
3430   (set_attr "mode" "HI")
3431   (set (attr "prefix_0f")
3432     ;; movsx is short decodable while cwtl is vector decoded.
3433     (if_then_else (and (eq_attr "cpu" "!k6")
3434			(eq_attr "alternative" "0"))
3435	(const_string "0")
3436	(const_string "1")))
3437   (set (attr "modrm")
3438     (if_then_else (eq_attr "prefix_0f" "0")
3439	(const_string "0")
3440	(const_string "1")))])
3441
3442(define_insn "extendqisi2"
3443  [(set (match_operand:SI 0 "register_operand" "=r")
3444	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3445  ""
3446  "movs{bl|x}\t{%1,%0|%0, %1}"
3447   [(set_attr "type" "imovx")
3448    (set_attr "mode" "SI")])
3449
3450(define_insn "*extendqisi2_zext"
3451  [(set (match_operand:DI 0 "register_operand" "=r")
3452	(zero_extend:DI
3453	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3454  "TARGET_64BIT"
3455  "movs{bl|x}\t{%1,%k0|%k0, %1}"
3456   [(set_attr "type" "imovx")
3457    (set_attr "mode" "SI")])
3458
3459;; Conversions between float and double.
3460
3461;; These are all no-ops in the model used for the 80387.  So just
3462;; emit moves.
3463
3464;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3465(define_insn "*dummy_extendsfdf2"
3466  [(set (match_operand:DF 0 "push_operand" "=<")
3467	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3468  "0"
3469  "#")
3470
3471(define_split
3472  [(set (match_operand:DF 0 "push_operand" "")
3473	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3474  "!TARGET_64BIT"
3475  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3476   (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3477
3478(define_split
3479  [(set (match_operand:DF 0 "push_operand" "")
3480	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3481  "TARGET_64BIT"
3482  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3483   (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3484
3485(define_insn "*dummy_extendsfxf2"
3486  [(set (match_operand:XF 0 "push_operand" "=<")
3487	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3488  "0"
3489  "#")
3490
3491(define_split
3492  [(set (match_operand:XF 0 "push_operand" "")
3493	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3494  ""
3495  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3496   (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3497  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3498
3499(define_split
3500  [(set (match_operand:XF 0 "push_operand" "")
3501	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3502  "TARGET_64BIT"
3503  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3504   (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3505  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3506
3507(define_split
3508  [(set (match_operand:XF 0 "push_operand" "")
3509	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3510  ""
3511  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3512   (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3513  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3514
3515(define_split
3516  [(set (match_operand:XF 0 "push_operand" "")
3517	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3518  "TARGET_64BIT"
3519  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3520   (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3521  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3522
3523(define_expand "extendsfdf2"
3524  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3525        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3526  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3527{
3528  /* ??? Needed for compress_float_constant since all fp constants
3529     are LEGITIMATE_CONSTANT_P.  */
3530  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3531    {
3532      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3533	  && standard_80387_constant_p (operands[1]) > 0)
3534	{
3535	  operands[1] = simplify_const_unary_operation
3536	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3537	  emit_move_insn_1 (operands[0], operands[1]);
3538	  DONE;
3539	}
3540      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3541    }
3542  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3543    operands[1] = force_reg (SFmode, operands[1]);
3544})
3545
3546(define_insn "*extendsfdf2_mixed"
3547  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3548        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3549  "TARGET_SSE2 && TARGET_MIX_SSE_I387
3550   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3551{
3552  switch (which_alternative)
3553    {
3554    case 0:
3555      return output_387_reg_move (insn, operands);
3556
3557    case 1:
3558      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3559        return "fstp%z0\t%y0";
3560      else
3561        return "fst%z0\t%y0";
3562
3563    case 2:
3564      return "cvtss2sd\t{%1, %0|%0, %1}";
3565
3566    default:
3567      gcc_unreachable ();
3568    }
3569}
3570  [(set_attr "type" "fmov,fmov,ssecvt")
3571   (set_attr "mode" "SF,XF,DF")])
3572
3573(define_insn "*extendsfdf2_sse"
3574  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3575        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3576  "TARGET_SSE2 && TARGET_SSE_MATH
3577   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3578  "cvtss2sd\t{%1, %0|%0, %1}"
3579  [(set_attr "type" "ssecvt")
3580   (set_attr "mode" "DF")])
3581
3582(define_insn "*extendsfdf2_i387"
3583  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3584        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3585  "TARGET_80387
3586   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3587{
3588  switch (which_alternative)
3589    {
3590    case 0:
3591      return output_387_reg_move (insn, operands);
3592
3593    case 1:
3594      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3595        return "fstp%z0\t%y0";
3596      else
3597        return "fst%z0\t%y0";
3598
3599    default:
3600      gcc_unreachable ();
3601    }
3602}
3603  [(set_attr "type" "fmov")
3604   (set_attr "mode" "SF,XF")])
3605
3606(define_expand "extendsfxf2"
3607  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3608        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3609  "TARGET_80387"
3610{
3611  /* ??? Needed for compress_float_constant since all fp constants
3612     are LEGITIMATE_CONSTANT_P.  */
3613  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3614    {
3615      if (standard_80387_constant_p (operands[1]) > 0)
3616	{
3617	  operands[1] = simplify_const_unary_operation
3618	    (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3619	  emit_move_insn_1 (operands[0], operands[1]);
3620	  DONE;
3621	}
3622      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3623    }
3624  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3625    operands[1] = force_reg (SFmode, operands[1]);
3626})
3627
3628(define_insn "*extendsfxf2_i387"
3629  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3630        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3631  "TARGET_80387
3632   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3633{
3634  switch (which_alternative)
3635    {
3636    case 0:
3637      return output_387_reg_move (insn, operands);
3638
3639    case 1:
3640      /* There is no non-popping store to memory for XFmode.  So if
3641	 we need one, follow the store with a load.  */
3642      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3643        return "fstp%z0\t%y0";
3644      else
3645        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3646
3647    default:
3648      gcc_unreachable ();
3649    }
3650}
3651  [(set_attr "type" "fmov")
3652   (set_attr "mode" "SF,XF")])
3653
3654(define_expand "extenddfxf2"
3655  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3656        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3657  "TARGET_80387"
3658{
3659  /* ??? Needed for compress_float_constant since all fp constants
3660     are LEGITIMATE_CONSTANT_P.  */
3661  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3662    {
3663      if (standard_80387_constant_p (operands[1]) > 0)
3664	{
3665	  operands[1] = simplify_const_unary_operation
3666	    (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3667	  emit_move_insn_1 (operands[0], operands[1]);
3668	  DONE;
3669	}
3670      operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3671    }
3672  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3673    operands[1] = force_reg (DFmode, operands[1]);
3674})
3675
3676(define_insn "*extenddfxf2_i387"
3677  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3678        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3679  "TARGET_80387
3680   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3681{
3682  switch (which_alternative)
3683    {
3684    case 0:
3685      return output_387_reg_move (insn, operands);
3686
3687    case 1:
3688      /* There is no non-popping store to memory for XFmode.  So if
3689	 we need one, follow the store with a load.  */
3690      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3691        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3692      else
3693        return "fstp%z0\t%y0";
3694
3695    default:
3696      gcc_unreachable ();
3697    }
3698}
3699  [(set_attr "type" "fmov")
3700   (set_attr "mode" "DF,XF")])
3701
3702;; %%% This seems bad bad news.
3703;; This cannot output into an f-reg because there is no way to be sure
3704;; of truncating in that case.  Otherwise this is just like a simple move
3705;; insn.  So we pretend we can output to a reg in order to get better
3706;; register preferencing, but we really use a stack slot.
3707
3708;; Conversion from DFmode to SFmode.
3709
3710(define_expand "truncdfsf2"
3711  [(set (match_operand:SF 0 "nonimmediate_operand" "")
3712	(float_truncate:SF
3713	  (match_operand:DF 1 "nonimmediate_operand" "")))]
3714  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3715{
3716  if (MEM_P (operands[0]) && MEM_P (operands[1]))
3717    operands[1] = force_reg (DFmode, operands[1]);
3718
3719  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3720    ;
3721  else if (flag_unsafe_math_optimizations)
3722    ;
3723  else
3724    {
3725      rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3726      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3727      DONE;
3728    }
3729})
3730
3731(define_expand "truncdfsf2_with_temp"
3732  [(parallel [(set (match_operand:SF 0 "" "")
3733		   (float_truncate:SF (match_operand:DF 1 "" "")))
3734	      (clobber (match_operand:SF 2 "" ""))])]
3735  "")
3736
3737(define_insn "*truncdfsf_fast_mixed"
3738  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3739        (float_truncate:SF
3740          (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3741  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3742{
3743  switch (which_alternative)
3744    {
3745    case 0:
3746      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3747	return "fstp%z0\t%y0";
3748      else
3749	return "fst%z0\t%y0";
3750    case 1:
3751      return output_387_reg_move (insn, operands);
3752    case 2:
3753      return "cvtsd2ss\t{%1, %0|%0, %1}";
3754    default:
3755      gcc_unreachable ();
3756    }
3757}
3758  [(set_attr "type" "fmov,fmov,ssecvt")
3759   (set_attr "mode" "SF")])
3760
3761;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3762;; because nothing we do here is unsafe.
3763(define_insn "*truncdfsf_fast_sse"
3764  [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3765        (float_truncate:SF
3766          (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3767  "TARGET_SSE2 && TARGET_SSE_MATH"
3768  "cvtsd2ss\t{%1, %0|%0, %1}"
3769  [(set_attr "type" "ssecvt")
3770   (set_attr "mode" "SF")])
3771
3772(define_insn "*truncdfsf_fast_i387"
3773  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3774        (float_truncate:SF
3775          (match_operand:DF 1 "nonimmediate_operand" "f")))]
3776  "TARGET_80387 && flag_unsafe_math_optimizations"
3777  "* return output_387_reg_move (insn, operands);"
3778  [(set_attr "type" "fmov")
3779   (set_attr "mode" "SF")])
3780
3781(define_insn "*truncdfsf_mixed"
3782  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3783	(float_truncate:SF
3784	  (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3785   (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3786  "TARGET_MIX_SSE_I387"
3787{
3788  switch (which_alternative)
3789    {
3790    case 0:
3791      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3792	return "fstp%z0\t%y0";
3793      else
3794	return "fst%z0\t%y0";
3795    case 1:
3796      return "#";
3797    case 2:
3798      return "cvtsd2ss\t{%1, %0|%0, %1}";
3799    default:
3800      gcc_unreachable ();
3801    }
3802}
3803  [(set_attr "type" "fmov,multi,ssecvt")
3804   (set_attr "unit" "*,i387,*")
3805   (set_attr "mode" "SF")])
3806
3807(define_insn "*truncdfsf_i387"
3808  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3809	(float_truncate:SF
3810	  (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3811   (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3812  "TARGET_80387"
3813{
3814  switch (which_alternative)
3815    {
3816    case 0:
3817      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3818	return "fstp%z0\t%y0";
3819      else
3820	return "fst%z0\t%y0";
3821    case 1:
3822      return "#";
3823    default:
3824      gcc_unreachable ();
3825    }
3826}
3827  [(set_attr "type" "fmov,multi")
3828   (set_attr "unit" "*,i387")
3829   (set_attr "mode" "SF")])
3830
3831(define_insn "*truncdfsf2_i387_1"
3832  [(set (match_operand:SF 0 "memory_operand" "=m")
3833	(float_truncate:SF
3834	  (match_operand:DF 1 "register_operand" "f")))]
3835  "TARGET_80387
3836   && !(TARGET_SSE2 && TARGET_SSE_MATH)
3837   && !TARGET_MIX_SSE_I387"
3838{
3839  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3840    return "fstp%z0\t%y0";
3841  else
3842    return "fst%z0\t%y0";
3843}
3844  [(set_attr "type" "fmov")
3845   (set_attr "mode" "SF")])
3846
3847(define_split
3848  [(set (match_operand:SF 0 "register_operand" "")
3849	(float_truncate:SF
3850	 (match_operand:DF 1 "fp_register_operand" "")))
3851   (clobber (match_operand 2 "" ""))]
3852  "reload_completed"
3853  [(set (match_dup 2) (match_dup 1))
3854   (set (match_dup 0) (match_dup 2))]
3855{
3856  operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3857})
3858
3859;; Conversion from XFmode to SFmode.
3860
3861(define_expand "truncxfsf2"
3862  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3863		   (float_truncate:SF
3864		    (match_operand:XF 1 "register_operand" "")))
3865	      (clobber (match_dup 2))])]
3866  "TARGET_80387"
3867{
3868  if (flag_unsafe_math_optimizations)
3869    {
3870      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3871      emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3872      if (reg != operands[0])
3873	emit_move_insn (operands[0], reg);
3874      DONE;
3875    }
3876  else
3877    operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3878})
3879
3880(define_insn "*truncxfsf2_mixed"
3881  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3882	(float_truncate:SF
3883	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3884   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3885  "TARGET_MIX_SSE_I387"
3886{
3887  gcc_assert (!which_alternative);
3888  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3889    return "fstp%z0\t%y0";
3890  else
3891    return "fst%z0\t%y0";
3892}
3893  [(set_attr "type" "fmov,multi,multi,multi")
3894   (set_attr "unit" "*,i387,i387,i387")
3895   (set_attr "mode" "SF")])
3896
3897(define_insn "truncxfsf2_i387_noop"
3898  [(set (match_operand:SF 0 "register_operand" "=f")
3899	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3900  "TARGET_80387 && flag_unsafe_math_optimizations"
3901{
3902  return output_387_reg_move (insn, operands);
3903}
3904  [(set_attr "type" "fmov")
3905   (set_attr "mode" "SF")])
3906
3907(define_insn "*truncxfsf2_i387"
3908  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3909	(float_truncate:SF
3910	 (match_operand:XF 1 "register_operand" "f,f,f")))
3911   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3912  "TARGET_80387"
3913{
3914  gcc_assert (!which_alternative);
3915  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3916    return "fstp%z0\t%y0";
3917   else
3918     return "fst%z0\t%y0";
3919}
3920  [(set_attr "type" "fmov,multi,multi")
3921   (set_attr "unit" "*,i387,i387")
3922   (set_attr "mode" "SF")])
3923
3924(define_insn "*truncxfsf2_i387_1"
3925  [(set (match_operand:SF 0 "memory_operand" "=m")
3926	(float_truncate:SF
3927	 (match_operand:XF 1 "register_operand" "f")))]
3928  "TARGET_80387"
3929{
3930  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3931    return "fstp%z0\t%y0";
3932  else
3933    return "fst%z0\t%y0";
3934}
3935  [(set_attr "type" "fmov")
3936   (set_attr "mode" "SF")])
3937
3938(define_split
3939  [(set (match_operand:SF 0 "register_operand" "")
3940	(float_truncate:SF
3941	 (match_operand:XF 1 "register_operand" "")))
3942   (clobber (match_operand:SF 2 "memory_operand" ""))]
3943  "TARGET_80387 && reload_completed"
3944  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3945   (set (match_dup 0) (match_dup 2))]
3946  "")
3947
3948(define_split
3949  [(set (match_operand:SF 0 "memory_operand" "")
3950	(float_truncate:SF
3951	 (match_operand:XF 1 "register_operand" "")))
3952   (clobber (match_operand:SF 2 "memory_operand" ""))]
3953  "TARGET_80387"
3954  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3955  "")
3956
3957;; Conversion from XFmode to DFmode.
3958
3959(define_expand "truncxfdf2"
3960  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3961		   (float_truncate:DF
3962		    (match_operand:XF 1 "register_operand" "")))
3963	      (clobber (match_dup 2))])]
3964  "TARGET_80387"
3965{
3966  if (flag_unsafe_math_optimizations)
3967    {
3968      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3969      emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3970      if (reg != operands[0])
3971	emit_move_insn (operands[0], reg);
3972      DONE;
3973    }
3974  else
3975    operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3976})
3977
3978(define_insn "*truncxfdf2_mixed"
3979  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3980	(float_truncate:DF
3981	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3982   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3983  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3984{
3985  gcc_assert (!which_alternative);
3986  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3987    return "fstp%z0\t%y0";
3988  else
3989    return "fst%z0\t%y0";
3990}
3991  [(set_attr "type" "fmov,multi,multi,multi")
3992   (set_attr "unit" "*,i387,i387,i387")
3993   (set_attr "mode" "DF")])
3994
3995(define_insn "truncxfdf2_i387_noop"
3996  [(set (match_operand:DF 0 "register_operand" "=f")
3997	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3998  "TARGET_80387 && flag_unsafe_math_optimizations"
3999{
4000  return output_387_reg_move (insn, operands);
4001}
4002  [(set_attr "type" "fmov")
4003   (set_attr "mode" "DF")])
4004
4005(define_insn "*truncxfdf2_i387"
4006  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4007	(float_truncate:DF
4008	 (match_operand:XF 1 "register_operand" "f,f,f")))
4009   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4010  "TARGET_80387"
4011{
4012  gcc_assert (!which_alternative);
4013  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4014    return "fstp%z0\t%y0";
4015  else
4016    return "fst%z0\t%y0";
4017}
4018  [(set_attr "type" "fmov,multi,multi")
4019   (set_attr "unit" "*,i387,i387")
4020   (set_attr "mode" "DF")])
4021
4022(define_insn "*truncxfdf2_i387_1"
4023  [(set (match_operand:DF 0 "memory_operand" "=m")
4024	(float_truncate:DF
4025	  (match_operand:XF 1 "register_operand" "f")))]
4026  "TARGET_80387"
4027{
4028  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4029    return "fstp%z0\t%y0";
4030  else
4031    return "fst%z0\t%y0";
4032}
4033  [(set_attr "type" "fmov")
4034   (set_attr "mode" "DF")])
4035
4036(define_split
4037  [(set (match_operand:DF 0 "register_operand" "")
4038	(float_truncate:DF
4039	 (match_operand:XF 1 "register_operand" "")))
4040   (clobber (match_operand:DF 2 "memory_operand" ""))]
4041  "TARGET_80387 && reload_completed"
4042  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4043   (set (match_dup 0) (match_dup 2))]
4044  "")
4045
4046(define_split
4047  [(set (match_operand:DF 0 "memory_operand" "")
4048	(float_truncate:DF
4049	 (match_operand:XF 1 "register_operand" "")))
4050   (clobber (match_operand:DF 2 "memory_operand" ""))]
4051  "TARGET_80387"
4052  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4053  "")
4054
4055;; Signed conversion to DImode.
4056
4057(define_expand "fix_truncxfdi2"
4058  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4059                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4060	      (clobber (reg:CC FLAGS_REG))])]
4061  "TARGET_80387"
4062{
4063  if (TARGET_FISTTP)
4064   {
4065     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4066     DONE;
4067   }
4068})
4069
4070(define_expand "fix_trunc<mode>di2"
4071  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072                   (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4073              (clobber (reg:CC FLAGS_REG))])]
4074  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4075{
4076  if (TARGET_FISTTP
4077      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4078   {
4079     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4080     DONE;
4081   }
4082  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4083   {
4084     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4085     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4086     if (out != operands[0])
4087	emit_move_insn (operands[0], out);
4088     DONE;
4089   }
4090})
4091
4092;; Signed conversion to SImode.
4093
4094(define_expand "fix_truncxfsi2"
4095  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4096                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4097	      (clobber (reg:CC FLAGS_REG))])]
4098  "TARGET_80387"
4099{
4100  if (TARGET_FISTTP)
4101   {
4102     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4103     DONE;
4104   }
4105})
4106
4107(define_expand "fix_trunc<mode>si2"
4108  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4109	           (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4110	      (clobber (reg:CC FLAGS_REG))])]
4111  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4112{
4113  if (TARGET_FISTTP
4114      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4115   {
4116     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4117     DONE;
4118   }
4119  if (SSE_FLOAT_MODE_P (<MODE>mode))
4120   {
4121     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4122     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4123     if (out != operands[0])
4124	emit_move_insn (operands[0], out);
4125     DONE;
4126   }
4127})
4128
4129;; Signed conversion to HImode.
4130
4131(define_expand "fix_trunc<mode>hi2"
4132  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4133	           (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4134              (clobber (reg:CC FLAGS_REG))])]
4135  "TARGET_80387
4136   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4137{
4138  if (TARGET_FISTTP)
4139   {
4140     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4141     DONE;
4142   }
4143})
4144
4145;; When SSE is available, it is always faster to use it!
4146(define_insn "fix_truncsfdi_sse"
4147  [(set (match_operand:DI 0 "register_operand" "=r,r")
4148	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4149  "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4150  "cvttss2si{q}\t{%1, %0|%0, %1}"
4151  [(set_attr "type" "sseicvt")
4152   (set_attr "mode" "SF")
4153   (set_attr "athlon_decode" "double,vector")])
4154
4155(define_insn "fix_truncdfdi_sse"
4156  [(set (match_operand:DI 0 "register_operand" "=r,r")
4157	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4158  "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4159  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4160  [(set_attr "type" "sseicvt")
4161   (set_attr "mode" "DF")
4162   (set_attr "athlon_decode" "double,vector")])
4163
4164(define_insn "fix_truncsfsi_sse"
4165  [(set (match_operand:SI 0 "register_operand" "=r,r")
4166	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4167  "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4168  "cvttss2si\t{%1, %0|%0, %1}"
4169  [(set_attr "type" "sseicvt")
4170   (set_attr "mode" "DF")
4171   (set_attr "athlon_decode" "double,vector")])
4172
4173(define_insn "fix_truncdfsi_sse"
4174  [(set (match_operand:SI 0 "register_operand" "=r,r")
4175	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4176  "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4177  "cvttsd2si\t{%1, %0|%0, %1}"
4178  [(set_attr "type" "sseicvt")
4179   (set_attr "mode" "DF")
4180   (set_attr "athlon_decode" "double,vector")])
4181
4182;; Avoid vector decoded forms of the instruction.
4183(define_peephole2
4184  [(match_scratch:DF 2 "Y")
4185   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4186	(fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4187  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4188  [(set (match_dup 2) (match_dup 1))
4189   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4190  "")
4191
4192(define_peephole2
4193  [(match_scratch:SF 2 "x")
4194   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4195	(fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4196  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4197  [(set (match_dup 2) (match_dup 1))
4198   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4199  "")
4200
4201(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4202  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4203	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4204  "TARGET_FISTTP
4205   && FLOAT_MODE_P (GET_MODE (operands[1]))
4206   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4207	 && (TARGET_64BIT || <MODE>mode != DImode))
4208	&& TARGET_SSE_MATH)
4209   && !(reload_completed || reload_in_progress)"
4210  "#"
4211  "&& 1"
4212  [(const_int 0)]
4213{
4214  if (memory_operand (operands[0], VOIDmode))
4215    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4216  else
4217    {
4218      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4219      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4220							    operands[1],
4221							    operands[2]));
4222    }
4223  DONE;
4224}
4225  [(set_attr "type" "fisttp")
4226   (set_attr "mode" "<MODE>")])
4227
4228(define_insn "fix_trunc<mode>_i387_fisttp"
4229  [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4230	(fix:X87MODEI (match_operand 1 "register_operand" "f")))
4231   (clobber (match_scratch:XF 2 "=&1f"))]
4232  "TARGET_FISTTP
4233   && FLOAT_MODE_P (GET_MODE (operands[1]))
4234   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4235	 && (TARGET_64BIT || <MODE>mode != DImode))
4236	&& TARGET_SSE_MATH)"
4237  "* return output_fix_trunc (insn, operands, 1);"
4238  [(set_attr "type" "fisttp")
4239   (set_attr "mode" "<MODE>")])
4240
4241(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4242  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4243	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4244   (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4245   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4246  "TARGET_FISTTP
4247   && FLOAT_MODE_P (GET_MODE (operands[1]))
4248   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249	&& (TARGET_64BIT || <MODE>mode != DImode))
4250	&& TARGET_SSE_MATH)"
4251  "#"
4252  [(set_attr "type" "fisttp")
4253   (set_attr "mode" "<MODE>")])
4254
4255(define_split
4256  [(set (match_operand:X87MODEI 0 "register_operand" "")
4257	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4258   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4259   (clobber (match_scratch 3 ""))]
4260  "reload_completed"
4261  [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4262	      (clobber (match_dup 3))])
4263   (set (match_dup 0) (match_dup 2))]
4264  "")
4265
4266(define_split
4267  [(set (match_operand:X87MODEI 0 "memory_operand" "")
4268	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4269   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4270   (clobber (match_scratch 3 ""))]
4271  "reload_completed"
4272  [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4273	      (clobber (match_dup 3))])]
4274  "")
4275
4276;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4277;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4278;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4279;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4280;; function in i386.c.
4281(define_insn_and_split "*fix_trunc<mode>_i387_1"
4282  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4283	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4284   (clobber (reg:CC FLAGS_REG))]
4285  "TARGET_80387 && !TARGET_FISTTP
4286   && FLOAT_MODE_P (GET_MODE (operands[1]))
4287   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4288	 && (TARGET_64BIT || <MODE>mode != DImode))
4289   && !(reload_completed || reload_in_progress)"
4290  "#"
4291  "&& 1"
4292  [(const_int 0)]
4293{
4294  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4295
4296  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4297  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4298  if (memory_operand (operands[0], VOIDmode))
4299    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4300					 operands[2], operands[3]));
4301  else
4302    {
4303      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4304      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4305						     operands[2], operands[3],
4306						     operands[4]));
4307    }
4308  DONE;
4309}
4310  [(set_attr "type" "fistp")
4311   (set_attr "i387_cw" "trunc")
4312   (set_attr "mode" "<MODE>")])
4313
4314(define_insn "fix_truncdi_i387"
4315  [(set (match_operand:DI 0 "memory_operand" "=m")
4316	(fix:DI (match_operand 1 "register_operand" "f")))
4317   (use (match_operand:HI 2 "memory_operand" "m"))
4318   (use (match_operand:HI 3 "memory_operand" "m"))
4319   (clobber (match_scratch:XF 4 "=&1f"))]
4320  "TARGET_80387 && !TARGET_FISTTP
4321   && FLOAT_MODE_P (GET_MODE (operands[1]))
4322   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4323  "* return output_fix_trunc (insn, operands, 0);"
4324  [(set_attr "type" "fistp")
4325   (set_attr "i387_cw" "trunc")
4326   (set_attr "mode" "DI")])
4327
4328(define_insn "fix_truncdi_i387_with_temp"
4329  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4330	(fix:DI (match_operand 1 "register_operand" "f,f")))
4331   (use (match_operand:HI 2 "memory_operand" "m,m"))
4332   (use (match_operand:HI 3 "memory_operand" "m,m"))
4333   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4334   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4335  "TARGET_80387 && !TARGET_FISTTP
4336   && FLOAT_MODE_P (GET_MODE (operands[1]))
4337   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4338  "#"
4339  [(set_attr "type" "fistp")
4340   (set_attr "i387_cw" "trunc")
4341   (set_attr "mode" "DI")])
4342
4343(define_split 
4344  [(set (match_operand:DI 0 "register_operand" "")
4345	(fix:DI (match_operand 1 "register_operand" "")))
4346   (use (match_operand:HI 2 "memory_operand" ""))
4347   (use (match_operand:HI 3 "memory_operand" ""))
4348   (clobber (match_operand:DI 4 "memory_operand" ""))
4349   (clobber (match_scratch 5 ""))]
4350  "reload_completed"
4351  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4352	      (use (match_dup 2))
4353	      (use (match_dup 3))
4354	      (clobber (match_dup 5))])
4355   (set (match_dup 0) (match_dup 4))]
4356  "")
4357
4358(define_split 
4359  [(set (match_operand:DI 0 "memory_operand" "")
4360	(fix:DI (match_operand 1 "register_operand" "")))
4361   (use (match_operand:HI 2 "memory_operand" ""))
4362   (use (match_operand:HI 3 "memory_operand" ""))
4363   (clobber (match_operand:DI 4 "memory_operand" ""))
4364   (clobber (match_scratch 5 ""))]
4365  "reload_completed"
4366  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4367	      (use (match_dup 2))
4368	      (use (match_dup 3))
4369	      (clobber (match_dup 5))])]
4370  "")
4371
4372(define_insn "fix_trunc<mode>_i387"
4373  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4374	(fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4375   (use (match_operand:HI 2 "memory_operand" "m"))
4376   (use (match_operand:HI 3 "memory_operand" "m"))]
4377  "TARGET_80387 && !TARGET_FISTTP
4378   && FLOAT_MODE_P (GET_MODE (operands[1]))
4379   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4380  "* return output_fix_trunc (insn, operands, 0);"
4381  [(set_attr "type" "fistp")
4382   (set_attr "i387_cw" "trunc")
4383   (set_attr "mode" "<MODE>")])
4384
4385(define_insn "fix_trunc<mode>_i387_with_temp"
4386  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4387	(fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4388   (use (match_operand:HI 2 "memory_operand" "m,m"))
4389   (use (match_operand:HI 3 "memory_operand" "m,m"))
4390   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4391  "TARGET_80387 && !TARGET_FISTTP
4392   && FLOAT_MODE_P (GET_MODE (operands[1]))
4393   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4394  "#"
4395  [(set_attr "type" "fistp")
4396   (set_attr "i387_cw" "trunc")
4397   (set_attr "mode" "<MODE>")])
4398
4399(define_split 
4400  [(set (match_operand:X87MODEI12 0 "register_operand" "")
4401	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4402   (use (match_operand:HI 2 "memory_operand" ""))
4403   (use (match_operand:HI 3 "memory_operand" ""))
4404   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4405  "reload_completed"
4406  [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4407	      (use (match_dup 2))
4408	      (use (match_dup 3))])
4409   (set (match_dup 0) (match_dup 4))]
4410  "")
4411
4412(define_split 
4413  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4414	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4415   (use (match_operand:HI 2 "memory_operand" ""))
4416   (use (match_operand:HI 3 "memory_operand" ""))
4417   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4418  "reload_completed"
4419  [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4420	      (use (match_dup 2))
4421	      (use (match_dup 3))])]
4422  "")
4423
4424(define_insn "x86_fnstcw_1"
4425  [(set (match_operand:HI 0 "memory_operand" "=m")
4426	(unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4427  "TARGET_80387"
4428  "fnstcw\t%0"
4429  [(set_attr "length" "2")
4430   (set_attr "mode" "HI")
4431   (set_attr "unit" "i387")])
4432
4433(define_insn "x86_fldcw_1"
4434  [(set (reg:HI FPSR_REG)
4435	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4436  "TARGET_80387"
4437  "fldcw\t%0"
4438  [(set_attr "length" "2")
4439   (set_attr "mode" "HI")
4440   (set_attr "unit" "i387")
4441   (set_attr "athlon_decode" "vector")])
4442
4443;; Conversion between fixed point and floating point.
4444
4445;; Even though we only accept memory inputs, the backend _really_
4446;; wants to be able to do this between registers.
4447
4448(define_expand "floathisf2"
4449  [(set (match_operand:SF 0 "register_operand" "")
4450	(float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4451  "TARGET_80387 || TARGET_SSE_MATH"
4452{
4453  if (TARGET_SSE_MATH)
4454    {
4455      emit_insn (gen_floatsisf2 (operands[0],
4456				 convert_to_mode (SImode, operands[1], 0)));
4457      DONE;
4458    }
4459})
4460
4461(define_insn "*floathisf2_i387"
4462  [(set (match_operand:SF 0 "register_operand" "=f,f")
4463	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4464  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4465  "@
4466   fild%z1\t%1
4467   #"
4468  [(set_attr "type" "fmov,multi")
4469   (set_attr "mode" "SF")
4470   (set_attr "unit" "*,i387")
4471   (set_attr "fp_int_src" "true")])
4472
4473(define_expand "floatsisf2"
4474  [(set (match_operand:SF 0 "register_operand" "")
4475	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4476  "TARGET_80387 || TARGET_SSE_MATH"
4477  "")
4478
4479(define_insn "*floatsisf2_mixed"
4480  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4481	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4482  "TARGET_MIX_SSE_I387"
4483  "@
4484   fild%z1\t%1
4485   #
4486   cvtsi2ss\t{%1, %0|%0, %1}
4487   cvtsi2ss\t{%1, %0|%0, %1}"
4488  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4489   (set_attr "mode" "SF")
4490   (set_attr "unit" "*,i387,*,*")
4491   (set_attr "athlon_decode" "*,*,vector,double")
4492   (set_attr "fp_int_src" "true")])
4493
4494(define_insn "*floatsisf2_sse"
4495  [(set (match_operand:SF 0 "register_operand" "=x,x")
4496	(float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4497  "TARGET_SSE_MATH"
4498  "cvtsi2ss\t{%1, %0|%0, %1}"
4499  [(set_attr "type" "sseicvt")
4500   (set_attr "mode" "SF")
4501   (set_attr "athlon_decode" "vector,double")
4502   (set_attr "fp_int_src" "true")])
4503
4504(define_insn "*floatsisf2_i387"
4505  [(set (match_operand:SF 0 "register_operand" "=f,f")
4506	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4507  "TARGET_80387"
4508  "@
4509   fild%z1\t%1
4510   #"
4511  [(set_attr "type" "fmov,multi")
4512   (set_attr "mode" "SF")
4513   (set_attr "unit" "*,i387")
4514   (set_attr "fp_int_src" "true")])
4515
4516(define_expand "floatdisf2"
4517  [(set (match_operand:SF 0 "register_operand" "")
4518	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4519  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4520  "")
4521
4522(define_insn "*floatdisf2_mixed"
4523  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4524	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4525  "TARGET_64BIT && TARGET_MIX_SSE_I387"
4526  "@
4527   fild%z1\t%1
4528   #
4529   cvtsi2ss{q}\t{%1, %0|%0, %1}
4530   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4531  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4532   (set_attr "mode" "SF")
4533   (set_attr "unit" "*,i387,*,*")
4534   (set_attr "athlon_decode" "*,*,vector,double")
4535   (set_attr "fp_int_src" "true")])
4536
4537(define_insn "*floatdisf2_sse"
4538  [(set (match_operand:SF 0 "register_operand" "=x,x")
4539	(float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4540  "TARGET_64BIT && TARGET_SSE_MATH"
4541  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4542  [(set_attr "type" "sseicvt")
4543   (set_attr "mode" "SF")
4544   (set_attr "athlon_decode" "vector,double")
4545   (set_attr "fp_int_src" "true")])
4546
4547(define_insn "*floatdisf2_i387"
4548  [(set (match_operand:SF 0 "register_operand" "=f,f")
4549	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4550  "TARGET_80387"
4551  "@
4552   fild%z1\t%1
4553   #"
4554  [(set_attr "type" "fmov,multi")
4555   (set_attr "mode" "SF")
4556   (set_attr "unit" "*,i387")
4557   (set_attr "fp_int_src" "true")])
4558
4559(define_expand "floathidf2"
4560  [(set (match_operand:DF 0 "register_operand" "")
4561	(float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4562  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4563{
4564  if (TARGET_SSE2 && TARGET_SSE_MATH)
4565    {
4566      emit_insn (gen_floatsidf2 (operands[0],
4567				 convert_to_mode (SImode, operands[1], 0)));
4568      DONE;
4569    }
4570})
4571
4572(define_insn "*floathidf2_i387"
4573  [(set (match_operand:DF 0 "register_operand" "=f,f")
4574	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4575  "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4576  "@
4577   fild%z1\t%1
4578   #"
4579  [(set_attr "type" "fmov,multi")
4580   (set_attr "mode" "DF")
4581   (set_attr "unit" "*,i387")
4582   (set_attr "fp_int_src" "true")])
4583
4584(define_expand "floatsidf2"
4585  [(set (match_operand:DF 0 "register_operand" "")
4586	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4587  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4588  "")
4589
4590(define_insn "*floatsidf2_mixed"
4591  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4592	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4593  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4594  "@
4595   fild%z1\t%1
4596   #
4597   cvtsi2sd\t{%1, %0|%0, %1}
4598   cvtsi2sd\t{%1, %0|%0, %1}"
4599  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4600   (set_attr "mode" "DF")
4601   (set_attr "unit" "*,i387,*,*")
4602   (set_attr "athlon_decode" "*,*,double,direct")
4603   (set_attr "fp_int_src" "true")])
4604
4605(define_insn "*floatsidf2_sse"
4606  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4607	(float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4608  "TARGET_SSE2 && TARGET_SSE_MATH"
4609  "cvtsi2sd\t{%1, %0|%0, %1}"
4610  [(set_attr "type" "sseicvt")
4611   (set_attr "mode" "DF")
4612   (set_attr "athlon_decode" "double,direct")
4613   (set_attr "fp_int_src" "true")])
4614
4615(define_insn "*floatsidf2_i387"
4616  [(set (match_operand:DF 0 "register_operand" "=f,f")
4617	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4618  "TARGET_80387"
4619  "@
4620   fild%z1\t%1
4621   #"
4622  [(set_attr "type" "fmov,multi")
4623   (set_attr "mode" "DF")
4624   (set_attr "unit" "*,i387")
4625   (set_attr "fp_int_src" "true")])
4626
4627(define_expand "floatdidf2"
4628  [(set (match_operand:DF 0 "register_operand" "")
4629	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4630  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4631  "")
4632
4633(define_insn "*floatdidf2_mixed"
4634  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4635	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4636  "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4637  "@
4638   fild%z1\t%1
4639   #
4640   cvtsi2sd{q}\t{%1, %0|%0, %1}
4641   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4642  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4643   (set_attr "mode" "DF")
4644   (set_attr "unit" "*,i387,*,*")
4645   (set_attr "athlon_decode" "*,*,double,direct")
4646   (set_attr "fp_int_src" "true")])
4647
4648(define_insn "*floatdidf2_sse"
4649  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4650	(float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4651  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4652  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4653  [(set_attr "type" "sseicvt")
4654   (set_attr "mode" "DF")
4655   (set_attr "athlon_decode" "double,direct")
4656   (set_attr "fp_int_src" "true")])
4657
4658(define_insn "*floatdidf2_i387"
4659  [(set (match_operand:DF 0 "register_operand" "=f,f")
4660	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4661  "TARGET_80387"
4662  "@
4663   fild%z1\t%1
4664   #"
4665  [(set_attr "type" "fmov,multi")
4666   (set_attr "mode" "DF")
4667   (set_attr "unit" "*,i387")
4668   (set_attr "fp_int_src" "true")])
4669
4670(define_insn "floathixf2"
4671  [(set (match_operand:XF 0 "register_operand" "=f,f")
4672	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4673  "TARGET_80387"
4674  "@
4675   fild%z1\t%1
4676   #"
4677  [(set_attr "type" "fmov,multi")
4678   (set_attr "mode" "XF")
4679   (set_attr "unit" "*,i387")
4680   (set_attr "fp_int_src" "true")])
4681
4682(define_insn "floatsixf2"
4683  [(set (match_operand:XF 0 "register_operand" "=f,f")
4684	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4685  "TARGET_80387"
4686  "@
4687   fild%z1\t%1
4688   #"
4689  [(set_attr "type" "fmov,multi")
4690   (set_attr "mode" "XF")
4691   (set_attr "unit" "*,i387")
4692   (set_attr "fp_int_src" "true")])
4693
4694(define_insn "floatdixf2"
4695  [(set (match_operand:XF 0 "register_operand" "=f,f")
4696	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4697  "TARGET_80387"
4698  "@
4699   fild%z1\t%1
4700   #"
4701  [(set_attr "type" "fmov,multi")
4702   (set_attr "mode" "XF")
4703   (set_attr "unit" "*,i387")
4704   (set_attr "fp_int_src" "true")])
4705
4706;; %%% Kill these when reload knows how to do it.
4707(define_split
4708  [(set (match_operand 0 "fp_register_operand" "")
4709	(float (match_operand 1 "register_operand" "")))]
4710  "reload_completed
4711   && TARGET_80387
4712   && FLOAT_MODE_P (GET_MODE (operands[0]))"
4713  [(const_int 0)]
4714{
4715  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4716  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4717  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4718  ix86_free_from_memory (GET_MODE (operands[1]));
4719  DONE;
4720})
4721
4722(define_expand "floatunssisf2"
4723  [(use (match_operand:SF 0 "register_operand" ""))
4724   (use (match_operand:SI 1 "register_operand" ""))]
4725  "!TARGET_64BIT && TARGET_SSE_MATH"
4726  "x86_emit_floatuns (operands); DONE;")
4727
4728(define_expand "floatunsdisf2"
4729  [(use (match_operand:SF 0 "register_operand" ""))
4730   (use (match_operand:DI 1 "register_operand" ""))]
4731  "TARGET_64BIT && TARGET_SSE_MATH"
4732  "x86_emit_floatuns (operands); DONE;")
4733
4734(define_expand "floatunsdidf2"
4735  [(use (match_operand:DF 0 "register_operand" ""))
4736   (use (match_operand:DI 1 "register_operand" ""))]
4737  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4738  "x86_emit_floatuns (operands); DONE;")
4739
4740;; SSE extract/set expanders
4741
4742
4743;; Add instructions
4744
4745;; %%% splits for addditi3
4746
4747(define_expand "addti3"
4748  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4749	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4750		 (match_operand:TI 2 "x86_64_general_operand" "")))
4751   (clobber (reg:CC FLAGS_REG))]
4752  "TARGET_64BIT"
4753  "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4754
4755(define_insn "*addti3_1"
4756  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4757	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4758		 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4759   (clobber (reg:CC FLAGS_REG))]
4760  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4761  "#")
4762
4763(define_split
4764  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4765	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4766		 (match_operand:TI 2 "x86_64_general_operand" "")))
4767   (clobber (reg:CC FLAGS_REG))]
4768  "TARGET_64BIT && reload_completed"
4769  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4770					  UNSPEC_ADD_CARRY))
4771	      (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4772   (parallel [(set (match_dup 3)
4773		   (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4774				     (match_dup 4))
4775			    (match_dup 5)))
4776	      (clobber (reg:CC FLAGS_REG))])]
4777  "split_ti (operands+0, 1, operands+0, operands+3);
4778   split_ti (operands+1, 1, operands+1, operands+4);
4779   split_ti (operands+2, 1, operands+2, operands+5);")
4780
4781;; %%% splits for addsidi3
4782;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4783;	(plus:DI (match_operand:DI 1 "general_operand" "")
4784;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4785
4786(define_expand "adddi3"
4787  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4788	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4789		 (match_operand:DI 2 "x86_64_general_operand" "")))
4790   (clobber (reg:CC FLAGS_REG))]
4791  ""
4792  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4793
4794(define_insn "*adddi3_1"
4795  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4796	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4797		 (match_operand:DI 2 "general_operand" "roiF,riF")))
4798   (clobber (reg:CC FLAGS_REG))]
4799  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4800  "#")
4801
4802(define_split
4803  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4804	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4805		 (match_operand:DI 2 "general_operand" "")))
4806   (clobber (reg:CC FLAGS_REG))]
4807  "!TARGET_64BIT && reload_completed"
4808  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4809					  UNSPEC_ADD_CARRY))
4810	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4811   (parallel [(set (match_dup 3)
4812		   (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4813				     (match_dup 4))
4814			    (match_dup 5)))
4815	      (clobber (reg:CC FLAGS_REG))])]
4816  "split_di (operands+0, 1, operands+0, operands+3);
4817   split_di (operands+1, 1, operands+1, operands+4);
4818   split_di (operands+2, 1, operands+2, operands+5);")
4819
4820(define_insn "adddi3_carry_rex64"
4821  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4822	  (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4823			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4824		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4825   (clobber (reg:CC FLAGS_REG))]
4826  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4827  "adc{q}\t{%2, %0|%0, %2}"
4828  [(set_attr "type" "alu")
4829   (set_attr "pent_pair" "pu")
4830   (set_attr "mode" "DI")])
4831
4832(define_insn "*adddi3_cc_rex64"
4833  [(set (reg:CC FLAGS_REG)
4834	(unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4835		    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4836		   UNSPEC_ADD_CARRY))
4837   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4838	(plus:DI (match_dup 1) (match_dup 2)))]
4839  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4840  "add{q}\t{%2, %0|%0, %2}"
4841  [(set_attr "type" "alu")
4842   (set_attr "mode" "DI")])
4843
4844(define_insn "addqi3_carry"
4845  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4846	  (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4847			    (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4848		   (match_operand:QI 2 "general_operand" "qi,qm")))
4849   (clobber (reg:CC FLAGS_REG))]
4850  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4851  "adc{b}\t{%2, %0|%0, %2}"
4852  [(set_attr "type" "alu")
4853   (set_attr "pent_pair" "pu")
4854   (set_attr "mode" "QI")])
4855
4856(define_insn "addhi3_carry"
4857  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4858	  (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4859			    (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4860		   (match_operand:HI 2 "general_operand" "ri,rm")))
4861   (clobber (reg:CC FLAGS_REG))]
4862  "ix86_binary_operator_ok (PLUS, HImode, operands)"
4863  "adc{w}\t{%2, %0|%0, %2}"
4864  [(set_attr "type" "alu")
4865   (set_attr "pent_pair" "pu")
4866   (set_attr "mode" "HI")])
4867
4868(define_insn "addsi3_carry"
4869  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4870	  (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4871			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4872		   (match_operand:SI 2 "general_operand" "ri,rm")))
4873   (clobber (reg:CC FLAGS_REG))]
4874  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4875  "adc{l}\t{%2, %0|%0, %2}"
4876  [(set_attr "type" "alu")
4877   (set_attr "pent_pair" "pu")
4878   (set_attr "mode" "SI")])
4879
4880(define_insn "*addsi3_carry_zext"
4881  [(set (match_operand:DI 0 "register_operand" "=r")
4882	  (zero_extend:DI 
4883	    (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4884			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
4885		     (match_operand:SI 2 "general_operand" "rim"))))
4886   (clobber (reg:CC FLAGS_REG))]
4887  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4888  "adc{l}\t{%2, %k0|%k0, %2}"
4889  [(set_attr "type" "alu")
4890   (set_attr "pent_pair" "pu")
4891   (set_attr "mode" "SI")])
4892
4893(define_insn "*addsi3_cc"
4894  [(set (reg:CC FLAGS_REG)
4895	(unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4896		    (match_operand:SI 2 "general_operand" "ri,rm")]
4897		   UNSPEC_ADD_CARRY))
4898   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4899	(plus:SI (match_dup 1) (match_dup 2)))]
4900  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4901  "add{l}\t{%2, %0|%0, %2}"
4902  [(set_attr "type" "alu")
4903   (set_attr "mode" "SI")])
4904
4905(define_insn "addqi3_cc"
4906  [(set (reg:CC FLAGS_REG)
4907	(unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4908		    (match_operand:QI 2 "general_operand" "qi,qm")]
4909		   UNSPEC_ADD_CARRY))
4910   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4911	(plus:QI (match_dup 1) (match_dup 2)))]
4912  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4913  "add{b}\t{%2, %0|%0, %2}"
4914  [(set_attr "type" "alu")
4915   (set_attr "mode" "QI")])
4916
4917(define_expand "addsi3"
4918  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4919		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4920			    (match_operand:SI 2 "general_operand" "")))
4921	      (clobber (reg:CC FLAGS_REG))])]
4922  ""
4923  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4924
4925(define_insn "*lea_1"
4926  [(set (match_operand:SI 0 "register_operand" "=r")
4927	(match_operand:SI 1 "no_seg_address_operand" "p"))]
4928  "!TARGET_64BIT"
4929  "lea{l}\t{%a1, %0|%0, %a1}"
4930  [(set_attr "type" "lea")
4931   (set_attr "mode" "SI")])
4932
4933(define_insn "*lea_1_rex64"
4934  [(set (match_operand:SI 0 "register_operand" "=r")
4935	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4936  "TARGET_64BIT"
4937  "lea{l}\t{%a1, %0|%0, %a1}"
4938  [(set_attr "type" "lea")
4939   (set_attr "mode" "SI")])
4940
4941(define_insn "*lea_1_zext"
4942  [(set (match_operand:DI 0 "register_operand" "=r")
4943	(zero_extend:DI
4944	 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4945  "TARGET_64BIT"
4946  "lea{l}\t{%a1, %k0|%k0, %a1}"
4947  [(set_attr "type" "lea")
4948   (set_attr "mode" "SI")])
4949
4950(define_insn "*lea_2_rex64"
4951  [(set (match_operand:DI 0 "register_operand" "=r")
4952	(match_operand:DI 1 "no_seg_address_operand" "p"))]
4953  "TARGET_64BIT"
4954  "lea{q}\t{%a1, %0|%0, %a1}"
4955  [(set_attr "type" "lea")
4956   (set_attr "mode" "DI")])
4957
4958;; The lea patterns for non-Pmodes needs to be matched by several
4959;; insns converted to real lea by splitters.
4960
4961(define_insn_and_split "*lea_general_1"
4962  [(set (match_operand 0 "register_operand" "=r")
4963	(plus (plus (match_operand 1 "index_register_operand" "l")
4964		    (match_operand 2 "register_operand" "r"))
4965	      (match_operand 3 "immediate_operand" "i")))]
4966  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4967    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4968   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4969   && GET_MODE (operands[0]) == GET_MODE (operands[1])
4970   && GET_MODE (operands[0]) == GET_MODE (operands[2])
4971   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4972       || GET_MODE (operands[3]) == VOIDmode)"
4973  "#"
4974  "&& reload_completed"
4975  [(const_int 0)]
4976{
4977  rtx pat;
4978  operands[0] = gen_lowpart (SImode, operands[0]);
4979  operands[1] = gen_lowpart (Pmode, operands[1]);
4980  operands[2] = gen_lowpart (Pmode, operands[2]);
4981  operands[3] = gen_lowpart (Pmode, operands[3]);
4982  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4983  		      operands[3]);
4984  if (Pmode != SImode)
4985    pat = gen_rtx_SUBREG (SImode, pat, 0);
4986  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4987  DONE;
4988}
4989  [(set_attr "type" "lea")
4990   (set_attr "mode" "SI")])
4991
4992(define_insn_and_split "*lea_general_1_zext"
4993  [(set (match_operand:DI 0 "register_operand" "=r")
4994	(zero_extend:DI
4995	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4996			    (match_operand:SI 2 "register_operand" "r"))
4997		   (match_operand:SI 3 "immediate_operand" "i"))))]
4998  "TARGET_64BIT"
4999  "#"
5000  "&& reload_completed"
5001  [(set (match_dup 0)
5002	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5003						     (match_dup 2))
5004					    (match_dup 3)) 0)))]
5005{
5006  operands[1] = gen_lowpart (Pmode, operands[1]);
5007  operands[2] = gen_lowpart (Pmode, operands[2]);
5008  operands[3] = gen_lowpart (Pmode, operands[3]);
5009}
5010  [(set_attr "type" "lea")
5011   (set_attr "mode" "SI")])
5012
5013(define_insn_and_split "*lea_general_2"
5014  [(set (match_operand 0 "register_operand" "=r")
5015	(plus (mult (match_operand 1 "index_register_operand" "l")
5016		    (match_operand 2 "const248_operand" "i"))
5017	      (match_operand 3 "nonmemory_operand" "ri")))]
5018  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5019    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5020   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5021   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5022   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5023       || GET_MODE (operands[3]) == VOIDmode)"
5024  "#"
5025  "&& reload_completed"
5026  [(const_int 0)]
5027{
5028  rtx pat;
5029  operands[0] = gen_lowpart (SImode, operands[0]);
5030  operands[1] = gen_lowpart (Pmode, operands[1]);
5031  operands[3] = gen_lowpart (Pmode, operands[3]);
5032  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5033  		      operands[3]);
5034  if (Pmode != SImode)
5035    pat = gen_rtx_SUBREG (SImode, pat, 0);
5036  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5037  DONE;
5038}
5039  [(set_attr "type" "lea")
5040   (set_attr "mode" "SI")])
5041
5042(define_insn_and_split "*lea_general_2_zext"
5043  [(set (match_operand:DI 0 "register_operand" "=r")
5044	(zero_extend:DI
5045	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5046			    (match_operand:SI 2 "const248_operand" "n"))
5047		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5048  "TARGET_64BIT"
5049  "#"
5050  "&& reload_completed"
5051  [(set (match_dup 0)
5052	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5053						     (match_dup 2))
5054					    (match_dup 3)) 0)))]
5055{
5056  operands[1] = gen_lowpart (Pmode, operands[1]);
5057  operands[3] = gen_lowpart (Pmode, operands[3]);
5058}
5059  [(set_attr "type" "lea")
5060   (set_attr "mode" "SI")])
5061
5062(define_insn_and_split "*lea_general_3"
5063  [(set (match_operand 0 "register_operand" "=r")
5064	(plus (plus (mult (match_operand 1 "index_register_operand" "l")
5065			  (match_operand 2 "const248_operand" "i"))
5066		    (match_operand 3 "register_operand" "r"))
5067	      (match_operand 4 "immediate_operand" "i")))]
5068  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5069    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5070   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5071   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5072   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5073  "#"
5074  "&& reload_completed"
5075  [(const_int 0)]
5076{
5077  rtx pat;
5078  operands[0] = gen_lowpart (SImode, operands[0]);
5079  operands[1] = gen_lowpart (Pmode, operands[1]);
5080  operands[3] = gen_lowpart (Pmode, operands[3]);
5081  operands[4] = gen_lowpart (Pmode, operands[4]);
5082  pat = gen_rtx_PLUS (Pmode,
5083  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5084		      					 operands[2]),
5085				    operands[3]),
5086  		      operands[4]);
5087  if (Pmode != SImode)
5088    pat = gen_rtx_SUBREG (SImode, pat, 0);
5089  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5090  DONE;
5091}
5092  [(set_attr "type" "lea")
5093   (set_attr "mode" "SI")])
5094
5095(define_insn_and_split "*lea_general_3_zext"
5096  [(set (match_operand:DI 0 "register_operand" "=r")
5097	(zero_extend:DI
5098	  (plus:SI (plus:SI (mult:SI
5099			      (match_operand:SI 1 "index_register_operand" "l")
5100			      (match_operand:SI 2 "const248_operand" "n"))
5101			    (match_operand:SI 3 "register_operand" "r"))
5102		   (match_operand:SI 4 "immediate_operand" "i"))))]
5103  "TARGET_64BIT"
5104  "#"
5105  "&& reload_completed"
5106  [(set (match_dup 0)
5107	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5108							      (match_dup 2))
5109						     (match_dup 3))
5110					    (match_dup 4)) 0)))]
5111{
5112  operands[1] = gen_lowpart (Pmode, operands[1]);
5113  operands[3] = gen_lowpart (Pmode, operands[3]);
5114  operands[4] = gen_lowpart (Pmode, operands[4]);
5115}
5116  [(set_attr "type" "lea")
5117   (set_attr "mode" "SI")])
5118
5119(define_insn "*adddi_1_rex64"
5120  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5121	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5122		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5123   (clobber (reg:CC FLAGS_REG))]
5124  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5125{
5126  switch (get_attr_type (insn))
5127    {
5128    case TYPE_LEA:
5129      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5130      return "lea{q}\t{%a2, %0|%0, %a2}";
5131
5132    case TYPE_INCDEC:
5133      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5134      if (operands[2] == const1_rtx)
5135        return "inc{q}\t%0";
5136      else
5137        {
5138	  gcc_assert (operands[2] == constm1_rtx);
5139          return "dec{q}\t%0";
5140	}
5141
5142    default:
5143      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5144
5145      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5146	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5147      if (GET_CODE (operands[2]) == CONST_INT
5148	  /* Avoid overflows.  */
5149	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5150          && (INTVAL (operands[2]) == 128
5151	      || (INTVAL (operands[2]) < 0
5152		  && INTVAL (operands[2]) != -128)))
5153        {
5154          operands[2] = GEN_INT (-INTVAL (operands[2]));
5155          return "sub{q}\t{%2, %0|%0, %2}";
5156        }
5157      return "add{q}\t{%2, %0|%0, %2}";
5158    }
5159}
5160  [(set (attr "type")
5161     (cond [(eq_attr "alternative" "2")
5162	      (const_string "lea")
5163	    ; Current assemblers are broken and do not allow @GOTOFF in
5164	    ; ought but a memory context.
5165	    (match_operand:DI 2 "pic_symbolic_operand" "")
5166	      (const_string "lea")
5167	    (match_operand:DI 2 "incdec_operand" "")
5168	      (const_string "incdec")
5169	   ]
5170	   (const_string "alu")))
5171   (set_attr "mode" "DI")])
5172
5173;; Convert lea to the lea pattern to avoid flags dependency.
5174(define_split
5175  [(set (match_operand:DI 0 "register_operand" "")
5176	(plus:DI (match_operand:DI 1 "register_operand" "")
5177		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5178   (clobber (reg:CC FLAGS_REG))]
5179  "TARGET_64BIT && reload_completed
5180   && true_regnum (operands[0]) != true_regnum (operands[1])"
5181  [(set (match_dup 0)
5182	(plus:DI (match_dup 1)
5183		 (match_dup 2)))]
5184  "")
5185
5186(define_insn "*adddi_2_rex64"
5187  [(set (reg FLAGS_REG)
5188	(compare
5189	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5190		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5191	  (const_int 0)))			
5192   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5193	(plus:DI (match_dup 1) (match_dup 2)))]
5194  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5195   && ix86_binary_operator_ok (PLUS, DImode, operands)
5196   /* Current assemblers are broken and do not allow @GOTOFF in
5197      ought but a memory context.  */
5198   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5199{
5200  switch (get_attr_type (insn))
5201    {
5202    case TYPE_INCDEC:
5203      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5204      if (operands[2] == const1_rtx)
5205        return "inc{q}\t%0";
5206      else
5207        {
5208	  gcc_assert (operands[2] == constm1_rtx);
5209          return "dec{q}\t%0";
5210	}
5211
5212    default:
5213      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214      /* ???? We ought to handle there the 32bit case too
5215	 - do we need new constraint?  */
5216      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5217	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5218      if (GET_CODE (operands[2]) == CONST_INT
5219	  /* Avoid overflows.  */
5220	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5221          && (INTVAL (operands[2]) == 128
5222	      || (INTVAL (operands[2]) < 0
5223		  && INTVAL (operands[2]) != -128)))
5224        {
5225          operands[2] = GEN_INT (-INTVAL (operands[2]));
5226          return "sub{q}\t{%2, %0|%0, %2}";
5227        }
5228      return "add{q}\t{%2, %0|%0, %2}";
5229    }
5230}
5231  [(set (attr "type")
5232     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5233	(const_string "incdec")
5234	(const_string "alu")))
5235   (set_attr "mode" "DI")])
5236
5237(define_insn "*adddi_3_rex64"
5238  [(set (reg FLAGS_REG)
5239	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5240		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5241   (clobber (match_scratch:DI 0 "=r"))]
5242  "TARGET_64BIT
5243   && ix86_match_ccmode (insn, CCZmode)
5244   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5245   /* Current assemblers are broken and do not allow @GOTOFF in
5246      ought but a memory context.  */
5247   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5248{
5249  switch (get_attr_type (insn))
5250    {
5251    case TYPE_INCDEC:
5252      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5253      if (operands[2] == const1_rtx)
5254        return "inc{q}\t%0";
5255      else
5256        {
5257	  gcc_assert (operands[2] == constm1_rtx);
5258          return "dec{q}\t%0";
5259	}
5260
5261    default:
5262      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5263      /* ???? We ought to handle there the 32bit case too
5264	 - do we need new constraint?  */
5265      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5267      if (GET_CODE (operands[2]) == CONST_INT
5268	  /* Avoid overflows.  */
5269	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270          && (INTVAL (operands[2]) == 128
5271	      || (INTVAL (operands[2]) < 0
5272		  && INTVAL (operands[2]) != -128)))
5273        {
5274          operands[2] = GEN_INT (-INTVAL (operands[2]));
5275          return "sub{q}\t{%2, %0|%0, %2}";
5276        }
5277      return "add{q}\t{%2, %0|%0, %2}";
5278    }
5279}
5280  [(set (attr "type")
5281     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282	(const_string "incdec")
5283	(const_string "alu")))
5284   (set_attr "mode" "DI")])
5285
5286; For comparisons against 1, -1 and 128, we may generate better code
5287; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5288; is matched then.  We can't accept general immediate, because for
5289; case of overflows,  the result is messed up.
5290; This pattern also don't hold of 0x8000000000000000, since the value overflows
5291; when negated.
5292; Also carry flag is reversed compared to cmp, so this conversion is valid
5293; only for comparisons not depending on it.
5294(define_insn "*adddi_4_rex64"
5295  [(set (reg FLAGS_REG)
5296	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
5297		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5298   (clobber (match_scratch:DI 0 "=rm"))]
5299  "TARGET_64BIT
5300   &&  ix86_match_ccmode (insn, CCGCmode)"
5301{
5302  switch (get_attr_type (insn))
5303    {
5304    case TYPE_INCDEC:
5305      if (operands[2] == constm1_rtx)
5306        return "inc{q}\t%0";
5307      else
5308        {
5309	  gcc_assert (operands[2] == const1_rtx);
5310          return "dec{q}\t%0";
5311	}
5312
5313    default:
5314      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5315      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5316	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5317      if ((INTVAL (operands[2]) == -128
5318	   || (INTVAL (operands[2]) > 0
5319	       && INTVAL (operands[2]) != 128))
5320	  /* Avoid overflows.  */
5321	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5322	return "sub{q}\t{%2, %0|%0, %2}";
5323      operands[2] = GEN_INT (-INTVAL (operands[2]));
5324      return "add{q}\t{%2, %0|%0, %2}";
5325    }
5326}
5327  [(set (attr "type")
5328     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5329	(const_string "incdec")
5330	(const_string "alu")))
5331   (set_attr "mode" "DI")])
5332
5333(define_insn "*adddi_5_rex64"
5334  [(set (reg FLAGS_REG)
5335	(compare
5336	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5337		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
5338	  (const_int 0)))			
5339   (clobber (match_scratch:DI 0 "=r"))]
5340  "TARGET_64BIT
5341   && ix86_match_ccmode (insn, CCGOCmode)
5342   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5343   /* Current assemblers are broken and do not allow @GOTOFF in
5344      ought but a memory context.  */
5345   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5346{
5347  switch (get_attr_type (insn))
5348    {
5349    case TYPE_INCDEC:
5350      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5351      if (operands[2] == const1_rtx)
5352        return "inc{q}\t%0";
5353      else
5354        {
5355          gcc_assert (operands[2] == constm1_rtx);
5356          return "dec{q}\t%0";
5357	}
5358
5359    default:
5360      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5361      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5362	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5363      if (GET_CODE (operands[2]) == CONST_INT
5364	  /* Avoid overflows.  */
5365	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5366          && (INTVAL (operands[2]) == 128
5367	      || (INTVAL (operands[2]) < 0
5368		  && INTVAL (operands[2]) != -128)))
5369        {
5370          operands[2] = GEN_INT (-INTVAL (operands[2]));
5371          return "sub{q}\t{%2, %0|%0, %2}";
5372        }
5373      return "add{q}\t{%2, %0|%0, %2}";
5374    }
5375}
5376  [(set (attr "type")
5377     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378	(const_string "incdec")
5379	(const_string "alu")))
5380   (set_attr "mode" "DI")])
5381
5382
5383(define_insn "*addsi_1"
5384  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5385	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5386		 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5387   (clobber (reg:CC FLAGS_REG))]
5388  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5389{
5390  switch (get_attr_type (insn))
5391    {
5392    case TYPE_LEA:
5393      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5394      return "lea{l}\t{%a2, %0|%0, %a2}";
5395
5396    case TYPE_INCDEC:
5397      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398      if (operands[2] == const1_rtx)
5399        return "inc{l}\t%0";
5400      else
5401	{
5402  	  gcc_assert (operands[2] == constm1_rtx);
5403          return "dec{l}\t%0";
5404	}
5405
5406    default:
5407      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5408
5409      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5410	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5411      if (GET_CODE (operands[2]) == CONST_INT
5412          && (INTVAL (operands[2]) == 128
5413	      || (INTVAL (operands[2]) < 0
5414		  && INTVAL (operands[2]) != -128)))
5415        {
5416          operands[2] = GEN_INT (-INTVAL (operands[2]));
5417          return "sub{l}\t{%2, %0|%0, %2}";
5418        }
5419      return "add{l}\t{%2, %0|%0, %2}";
5420    }
5421}
5422  [(set (attr "type")
5423     (cond [(eq_attr "alternative" "2")
5424	      (const_string "lea")
5425	    ; Current assemblers are broken and do not allow @GOTOFF in
5426	    ; ought but a memory context.
5427	    (match_operand:SI 2 "pic_symbolic_operand" "")
5428	      (const_string "lea")
5429	    (match_operand:SI 2 "incdec_operand" "")
5430	      (const_string "incdec")
5431	   ]
5432	   (const_string "alu")))
5433   (set_attr "mode" "SI")])
5434
5435;; Convert lea to the lea pattern to avoid flags dependency.
5436(define_split
5437  [(set (match_operand 0 "register_operand" "")
5438	(plus (match_operand 1 "register_operand" "")
5439              (match_operand 2 "nonmemory_operand" "")))
5440   (clobber (reg:CC FLAGS_REG))]
5441  "reload_completed
5442   && true_regnum (operands[0]) != true_regnum (operands[1])"
5443  [(const_int 0)]
5444{
5445  rtx pat;
5446  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5447     may confuse gen_lowpart.  */
5448  if (GET_MODE (operands[0]) != Pmode)
5449    {
5450      operands[1] = gen_lowpart (Pmode, operands[1]);
5451      operands[2] = gen_lowpart (Pmode, operands[2]);
5452    }
5453  operands[0] = gen_lowpart (SImode, operands[0]);
5454  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5455  if (Pmode != SImode)
5456    pat = gen_rtx_SUBREG (SImode, pat, 0);
5457  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5458  DONE;
5459})
5460
5461;; It may seem that nonimmediate operand is proper one for operand 1.
5462;; The addsi_1 pattern allows nonimmediate operand at that place and
5463;; we take care in ix86_binary_operator_ok to not allow two memory
5464;; operands so proper swapping will be done in reload.  This allow
5465;; patterns constructed from addsi_1 to match.
5466(define_insn "addsi_1_zext"
5467  [(set (match_operand:DI 0 "register_operand" "=r,r")
5468	(zero_extend:DI
5469	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5470		   (match_operand:SI 2 "general_operand" "rmni,lni"))))
5471   (clobber (reg:CC FLAGS_REG))]
5472  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5473{
5474  switch (get_attr_type (insn))
5475    {
5476    case TYPE_LEA:
5477      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5478      return "lea{l}\t{%a2, %k0|%k0, %a2}";
5479
5480    case TYPE_INCDEC:
5481      if (operands[2] == const1_rtx)
5482        return "inc{l}\t%k0";
5483      else
5484        {
5485	  gcc_assert (operands[2] == constm1_rtx);
5486          return "dec{l}\t%k0";
5487	}
5488
5489    default:
5490      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5491	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5492      if (GET_CODE (operands[2]) == CONST_INT
5493          && (INTVAL (operands[2]) == 128
5494	      || (INTVAL (operands[2]) < 0
5495		  && INTVAL (operands[2]) != -128)))
5496        {
5497          operands[2] = GEN_INT (-INTVAL (operands[2]));
5498          return "sub{l}\t{%2, %k0|%k0, %2}";
5499        }
5500      return "add{l}\t{%2, %k0|%k0, %2}";
5501    }
5502}
5503  [(set (attr "type")
5504     (cond [(eq_attr "alternative" "1")
5505	      (const_string "lea")
5506	    ; Current assemblers are broken and do not allow @GOTOFF in
5507	    ; ought but a memory context.
5508	    (match_operand:SI 2 "pic_symbolic_operand" "")
5509	      (const_string "lea")
5510	    (match_operand:SI 2 "incdec_operand" "")
5511	      (const_string "incdec")
5512	   ]
5513	   (const_string "alu")))
5514   (set_attr "mode" "SI")])
5515
5516;; Convert lea to the lea pattern to avoid flags dependency.
5517(define_split
5518  [(set (match_operand:DI 0 "register_operand" "")
5519	(zero_extend:DI
5520	  (plus:SI (match_operand:SI 1 "register_operand" "")
5521		   (match_operand:SI 2 "nonmemory_operand" ""))))
5522   (clobber (reg:CC FLAGS_REG))]
5523  "TARGET_64BIT && reload_completed
5524   && true_regnum (operands[0]) != true_regnum (operands[1])"
5525  [(set (match_dup 0)
5526	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5527{
5528  operands[1] = gen_lowpart (Pmode, operands[1]);
5529  operands[2] = gen_lowpart (Pmode, operands[2]);
5530})
5531
5532(define_insn "*addsi_2"
5533  [(set (reg FLAGS_REG)
5534	(compare
5535	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5536		   (match_operand:SI 2 "general_operand" "rmni,rni"))
5537	  (const_int 0)))			
5538   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5539	(plus:SI (match_dup 1) (match_dup 2)))]
5540  "ix86_match_ccmode (insn, CCGOCmode)
5541   && ix86_binary_operator_ok (PLUS, SImode, operands)
5542   /* Current assemblers are broken and do not allow @GOTOFF in
5543      ought but a memory context.  */
5544   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5545{
5546  switch (get_attr_type (insn))
5547    {
5548    case TYPE_INCDEC:
5549      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5550      if (operands[2] == const1_rtx)
5551        return "inc{l}\t%0";
5552      else
5553        {
5554	  gcc_assert (operands[2] == constm1_rtx);
5555          return "dec{l}\t%0";
5556	}
5557
5558    default:
5559      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5561	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5562      if (GET_CODE (operands[2]) == CONST_INT
5563          && (INTVAL (operands[2]) == 128
5564	      || (INTVAL (operands[2]) < 0
5565		  && INTVAL (operands[2]) != -128)))
5566        {
5567          operands[2] = GEN_INT (-INTVAL (operands[2]));
5568          return "sub{l}\t{%2, %0|%0, %2}";
5569        }
5570      return "add{l}\t{%2, %0|%0, %2}";
5571    }
5572}
5573  [(set (attr "type")
5574     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5575	(const_string "incdec")
5576	(const_string "alu")))
5577   (set_attr "mode" "SI")])
5578
5579;; See comment for addsi_1_zext why we do use nonimmediate_operand
5580(define_insn "*addsi_2_zext"
5581  [(set (reg FLAGS_REG)
5582	(compare
5583	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5584		   (match_operand:SI 2 "general_operand" "rmni"))
5585	  (const_int 0)))			
5586   (set (match_operand:DI 0 "register_operand" "=r")
5587	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5588  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5589   && ix86_binary_operator_ok (PLUS, SImode, operands)
5590   /* Current assemblers are broken and do not allow @GOTOFF in
5591      ought but a memory context.  */
5592   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5593{
5594  switch (get_attr_type (insn))
5595    {
5596    case TYPE_INCDEC:
5597      if (operands[2] == const1_rtx)
5598        return "inc{l}\t%k0";
5599      else
5600	{
5601	  gcc_assert (operands[2] == constm1_rtx);
5602          return "dec{l}\t%k0";
5603	}
5604
5605    default:
5606      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5607	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5608      if (GET_CODE (operands[2]) == CONST_INT
5609          && (INTVAL (operands[2]) == 128
5610	      || (INTVAL (operands[2]) < 0
5611		  && INTVAL (operands[2]) != -128)))
5612        {
5613          operands[2] = GEN_INT (-INTVAL (operands[2]));
5614          return "sub{l}\t{%2, %k0|%k0, %2}";
5615        }
5616      return "add{l}\t{%2, %k0|%k0, %2}";
5617    }
5618}
5619  [(set (attr "type")
5620     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5621	(const_string "incdec")
5622	(const_string "alu")))
5623   (set_attr "mode" "SI")])
5624
5625(define_insn "*addsi_3"
5626  [(set (reg FLAGS_REG)
5627	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5628		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5629   (clobber (match_scratch:SI 0 "=r"))]
5630  "ix86_match_ccmode (insn, CCZmode)
5631   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5632   /* Current assemblers are broken and do not allow @GOTOFF in
5633      ought but a memory context.  */
5634   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5635{
5636  switch (get_attr_type (insn))
5637    {
5638    case TYPE_INCDEC:
5639      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5640      if (operands[2] == const1_rtx)
5641        return "inc{l}\t%0";
5642      else
5643        {
5644	  gcc_assert (operands[2] == constm1_rtx);
5645          return "dec{l}\t%0";
5646	}
5647
5648    default:
5649      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5650      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5651	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5652      if (GET_CODE (operands[2]) == CONST_INT
5653          && (INTVAL (operands[2]) == 128
5654	      || (INTVAL (operands[2]) < 0
5655		  && INTVAL (operands[2]) != -128)))
5656        {
5657          operands[2] = GEN_INT (-INTVAL (operands[2]));
5658          return "sub{l}\t{%2, %0|%0, %2}";
5659        }
5660      return "add{l}\t{%2, %0|%0, %2}";
5661    }
5662}
5663  [(set (attr "type")
5664     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5665	(const_string "incdec")
5666	(const_string "alu")))
5667   (set_attr "mode" "SI")])
5668
5669;; See comment for addsi_1_zext why we do use nonimmediate_operand
5670(define_insn "*addsi_3_zext"
5671  [(set (reg FLAGS_REG)
5672	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5673		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5674   (set (match_operand:DI 0 "register_operand" "=r")
5675	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5676  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5677   && ix86_binary_operator_ok (PLUS, SImode, operands)
5678   /* Current assemblers are broken and do not allow @GOTOFF in
5679      ought but a memory context.  */
5680   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5681{
5682  switch (get_attr_type (insn))
5683    {
5684    case TYPE_INCDEC:
5685      if (operands[2] == const1_rtx)
5686        return "inc{l}\t%k0";
5687      else
5688        {
5689	  gcc_assert (operands[2] == constm1_rtx);
5690          return "dec{l}\t%k0";
5691	}
5692
5693    default:
5694      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5695	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5696      if (GET_CODE (operands[2]) == CONST_INT
5697          && (INTVAL (operands[2]) == 128
5698	      || (INTVAL (operands[2]) < 0
5699		  && INTVAL (operands[2]) != -128)))
5700        {
5701          operands[2] = GEN_INT (-INTVAL (operands[2]));
5702          return "sub{l}\t{%2, %k0|%k0, %2}";
5703        }
5704      return "add{l}\t{%2, %k0|%k0, %2}";
5705    }
5706}
5707  [(set (attr "type")
5708     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5709	(const_string "incdec")
5710	(const_string "alu")))
5711   (set_attr "mode" "SI")])
5712
5713; For comparisons against 1, -1 and 128, we may generate better code
5714; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5715; is matched then.  We can't accept general immediate, because for
5716; case of overflows,  the result is messed up.
5717; This pattern also don't hold of 0x80000000, since the value overflows
5718; when negated.
5719; Also carry flag is reversed compared to cmp, so this conversion is valid
5720; only for comparisons not depending on it.
5721(define_insn "*addsi_4"
5722  [(set (reg FLAGS_REG)
5723	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
5724		 (match_operand:SI 2 "const_int_operand" "n")))
5725   (clobber (match_scratch:SI 0 "=rm"))]
5726  "ix86_match_ccmode (insn, CCGCmode)
5727   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5728{
5729  switch (get_attr_type (insn))
5730    {
5731    case TYPE_INCDEC:
5732      if (operands[2] == constm1_rtx)
5733        return "inc{l}\t%0";
5734      else
5735        {
5736	  gcc_assert (operands[2] == const1_rtx);
5737          return "dec{l}\t%0";
5738	}
5739
5740    default:
5741      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5742      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5743	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5744      if ((INTVAL (operands[2]) == -128
5745	   || (INTVAL (operands[2]) > 0
5746	       && INTVAL (operands[2]) != 128)))
5747	return "sub{l}\t{%2, %0|%0, %2}";
5748      operands[2] = GEN_INT (-INTVAL (operands[2]));
5749      return "add{l}\t{%2, %0|%0, %2}";
5750    }
5751}
5752  [(set (attr "type")
5753     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5754	(const_string "incdec")
5755	(const_string "alu")))
5756   (set_attr "mode" "SI")])
5757
5758(define_insn "*addsi_5"
5759  [(set (reg FLAGS_REG)
5760	(compare
5761	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5762		   (match_operand:SI 2 "general_operand" "rmni"))
5763	  (const_int 0)))			
5764   (clobber (match_scratch:SI 0 "=r"))]
5765  "ix86_match_ccmode (insn, CCGOCmode)
5766   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5767   /* Current assemblers are broken and do not allow @GOTOFF in
5768      ought but a memory context.  */
5769   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5770{
5771  switch (get_attr_type (insn))
5772    {
5773    case TYPE_INCDEC:
5774      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5775      if (operands[2] == const1_rtx)
5776        return "inc{l}\t%0";
5777      else
5778        {
5779	  gcc_assert (operands[2] == constm1_rtx);
5780          return "dec{l}\t%0";
5781	}
5782
5783    default:
5784      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5785      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5786	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5787      if (GET_CODE (operands[2]) == CONST_INT
5788          && (INTVAL (operands[2]) == 128
5789	      || (INTVAL (operands[2]) < 0
5790		  && INTVAL (operands[2]) != -128)))
5791        {
5792          operands[2] = GEN_INT (-INTVAL (operands[2]));
5793          return "sub{l}\t{%2, %0|%0, %2}";
5794        }
5795      return "add{l}\t{%2, %0|%0, %2}";
5796    }
5797}
5798  [(set (attr "type")
5799     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5800	(const_string "incdec")
5801	(const_string "alu")))
5802   (set_attr "mode" "SI")])
5803
5804(define_expand "addhi3"
5805  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5806		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5807			    (match_operand:HI 2 "general_operand" "")))
5808	      (clobber (reg:CC FLAGS_REG))])]
5809  "TARGET_HIMODE_MATH"
5810  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5811
5812;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5813;; type optimizations enabled by define-splits.  This is not important
5814;; for PII, and in fact harmful because of partial register stalls.
5815
5816(define_insn "*addhi_1_lea"
5817  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5818	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5819		 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5820   (clobber (reg:CC FLAGS_REG))]
5821  "!TARGET_PARTIAL_REG_STALL
5822   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5823{
5824  switch (get_attr_type (insn))
5825    {
5826    case TYPE_LEA:
5827      return "#";
5828    case TYPE_INCDEC:
5829      if (operands[2] == const1_rtx)
5830	return "inc{w}\t%0";
5831      else
5832	{
5833	  gcc_assert (operands[2] == constm1_rtx);
5834	  return "dec{w}\t%0";
5835	}
5836
5837    default:
5838      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5839	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5840      if (GET_CODE (operands[2]) == CONST_INT
5841          && (INTVAL (operands[2]) == 128
5842	      || (INTVAL (operands[2]) < 0
5843		  && INTVAL (operands[2]) != -128)))
5844	{
5845	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5846	  return "sub{w}\t{%2, %0|%0, %2}";
5847	}
5848      return "add{w}\t{%2, %0|%0, %2}";
5849    }
5850}
5851  [(set (attr "type")
5852     (if_then_else (eq_attr "alternative" "2")
5853	(const_string "lea")
5854	(if_then_else (match_operand:HI 2 "incdec_operand" "")
5855	   (const_string "incdec")
5856	   (const_string "alu"))))
5857   (set_attr "mode" "HI,HI,SI")])
5858
5859(define_insn "*addhi_1"
5860  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5861	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5862		 (match_operand:HI 2 "general_operand" "ri,rm")))
5863   (clobber (reg:CC FLAGS_REG))]
5864  "TARGET_PARTIAL_REG_STALL
5865   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5866{
5867  switch (get_attr_type (insn))
5868    {
5869    case TYPE_INCDEC:
5870      if (operands[2] == const1_rtx)
5871	return "inc{w}\t%0";
5872      else
5873        {
5874	  gcc_assert (operands[2] == constm1_rtx);
5875	  return "dec{w}\t%0";
5876	}
5877
5878    default:
5879      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5880	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5881      if (GET_CODE (operands[2]) == CONST_INT
5882          && (INTVAL (operands[2]) == 128
5883	      || (INTVAL (operands[2]) < 0
5884		  && INTVAL (operands[2]) != -128)))
5885	{
5886	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5887	  return "sub{w}\t{%2, %0|%0, %2}";
5888	}
5889      return "add{w}\t{%2, %0|%0, %2}";
5890    }
5891}
5892  [(set (attr "type")
5893     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5894	(const_string "incdec")
5895	(const_string "alu")))
5896   (set_attr "mode" "HI")])
5897
5898(define_insn "*addhi_2"
5899  [(set (reg FLAGS_REG)
5900	(compare
5901	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5902		   (match_operand:HI 2 "general_operand" "rmni,rni"))
5903	  (const_int 0)))			
5904   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5905	(plus:HI (match_dup 1) (match_dup 2)))]
5906  "ix86_match_ccmode (insn, CCGOCmode)
5907   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5908{
5909  switch (get_attr_type (insn))
5910    {
5911    case TYPE_INCDEC:
5912      if (operands[2] == const1_rtx)
5913	return "inc{w}\t%0";
5914      else
5915        {
5916	  gcc_assert (operands[2] == constm1_rtx);
5917	  return "dec{w}\t%0";
5918	}
5919
5920    default:
5921      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5922	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5923      if (GET_CODE (operands[2]) == CONST_INT
5924          && (INTVAL (operands[2]) == 128
5925	      || (INTVAL (operands[2]) < 0
5926		  && INTVAL (operands[2]) != -128)))
5927	{
5928	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5929	  return "sub{w}\t{%2, %0|%0, %2}";
5930	}
5931      return "add{w}\t{%2, %0|%0, %2}";
5932    }
5933}
5934  [(set (attr "type")
5935     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5936	(const_string "incdec")
5937	(const_string "alu")))
5938   (set_attr "mode" "HI")])
5939
5940(define_insn "*addhi_3"
5941  [(set (reg FLAGS_REG)
5942	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5943		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5944   (clobber (match_scratch:HI 0 "=r"))]
5945  "ix86_match_ccmode (insn, CCZmode)
5946   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5947{
5948  switch (get_attr_type (insn))
5949    {
5950    case TYPE_INCDEC:
5951      if (operands[2] == const1_rtx)
5952	return "inc{w}\t%0";
5953      else
5954        {
5955	  gcc_assert (operands[2] == constm1_rtx);
5956	  return "dec{w}\t%0";
5957	}
5958
5959    default:
5960      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5962      if (GET_CODE (operands[2]) == CONST_INT
5963          && (INTVAL (operands[2]) == 128
5964	      || (INTVAL (operands[2]) < 0
5965		  && INTVAL (operands[2]) != -128)))
5966	{
5967	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5968	  return "sub{w}\t{%2, %0|%0, %2}";
5969	}
5970      return "add{w}\t{%2, %0|%0, %2}";
5971    }
5972}
5973  [(set (attr "type")
5974     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5975	(const_string "incdec")
5976	(const_string "alu")))
5977   (set_attr "mode" "HI")])
5978
5979; See comments above addsi_4 for details.
5980(define_insn "*addhi_4"
5981  [(set (reg FLAGS_REG)
5982	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
5983		 (match_operand:HI 2 "const_int_operand" "n")))
5984   (clobber (match_scratch:HI 0 "=rm"))]
5985  "ix86_match_ccmode (insn, CCGCmode)
5986   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5987{
5988  switch (get_attr_type (insn))
5989    {
5990    case TYPE_INCDEC:
5991      if (operands[2] == constm1_rtx)
5992        return "inc{w}\t%0";
5993      else
5994	{
5995	  gcc_assert (operands[2] == const1_rtx);
5996          return "dec{w}\t%0";
5997	}
5998
5999    default:
6000      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6001      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003      if ((INTVAL (operands[2]) == -128
6004	   || (INTVAL (operands[2]) > 0
6005	       && INTVAL (operands[2]) != 128)))
6006	return "sub{w}\t{%2, %0|%0, %2}";
6007      operands[2] = GEN_INT (-INTVAL (operands[2]));
6008      return "add{w}\t{%2, %0|%0, %2}";
6009    }
6010}
6011  [(set (attr "type")
6012     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6013	(const_string "incdec")
6014	(const_string "alu")))
6015   (set_attr "mode" "SI")])
6016
6017
6018(define_insn "*addhi_5"
6019  [(set (reg FLAGS_REG)
6020	(compare
6021	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6022		   (match_operand:HI 2 "general_operand" "rmni"))
6023	  (const_int 0)))			
6024   (clobber (match_scratch:HI 0 "=r"))]
6025  "ix86_match_ccmode (insn, CCGOCmode)
6026   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6027{
6028  switch (get_attr_type (insn))
6029    {
6030    case TYPE_INCDEC:
6031      if (operands[2] == const1_rtx)
6032	return "inc{w}\t%0";
6033      else
6034	{
6035	  gcc_assert (operands[2] == constm1_rtx);
6036	  return "dec{w}\t%0";
6037	}
6038
6039    default:
6040      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6041	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6042      if (GET_CODE (operands[2]) == CONST_INT
6043          && (INTVAL (operands[2]) == 128
6044	      || (INTVAL (operands[2]) < 0
6045		  && INTVAL (operands[2]) != -128)))
6046	{
6047	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6048	  return "sub{w}\t{%2, %0|%0, %2}";
6049	}
6050      return "add{w}\t{%2, %0|%0, %2}";
6051    }
6052}
6053  [(set (attr "type")
6054     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6055	(const_string "incdec")
6056	(const_string "alu")))
6057   (set_attr "mode" "HI")])
6058
6059(define_expand "addqi3"
6060  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6061		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6062			    (match_operand:QI 2 "general_operand" "")))
6063	      (clobber (reg:CC FLAGS_REG))])]
6064  "TARGET_QIMODE_MATH"
6065  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6066
6067;; %%% Potential partial reg stall on alternative 2.  What to do?
6068(define_insn "*addqi_1_lea"
6069  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6070	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6071		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6072   (clobber (reg:CC FLAGS_REG))]
6073  "!TARGET_PARTIAL_REG_STALL
6074   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6075{
6076  int widen = (which_alternative == 2);
6077  switch (get_attr_type (insn))
6078    {
6079    case TYPE_LEA:
6080      return "#";
6081    case TYPE_INCDEC:
6082      if (operands[2] == const1_rtx)
6083	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6084      else
6085	{
6086	  gcc_assert (operands[2] == constm1_rtx);
6087	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6088	}
6089
6090    default:
6091      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6092	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6093      if (GET_CODE (operands[2]) == CONST_INT
6094          && (INTVAL (operands[2]) == 128
6095	      || (INTVAL (operands[2]) < 0
6096		  && INTVAL (operands[2]) != -128)))
6097	{
6098	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6099	  if (widen)
6100	    return "sub{l}\t{%2, %k0|%k0, %2}";
6101	  else
6102	    return "sub{b}\t{%2, %0|%0, %2}";
6103	}
6104      if (widen)
6105        return "add{l}\t{%k2, %k0|%k0, %k2}";
6106      else
6107        return "add{b}\t{%2, %0|%0, %2}";
6108    }
6109}
6110  [(set (attr "type")
6111     (if_then_else (eq_attr "alternative" "3")
6112	(const_string "lea")
6113	(if_then_else (match_operand:QI 2 "incdec_operand" "")
6114	   (const_string "incdec")
6115	   (const_string "alu"))))
6116   (set_attr "mode" "QI,QI,SI,SI")])
6117
6118(define_insn "*addqi_1"
6119  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6120	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6121		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6122   (clobber (reg:CC FLAGS_REG))]
6123  "TARGET_PARTIAL_REG_STALL
6124   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6125{
6126  int widen = (which_alternative == 2);
6127  switch (get_attr_type (insn))
6128    {
6129    case TYPE_INCDEC:
6130      if (operands[2] == const1_rtx)
6131	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6132      else
6133	{
6134	  gcc_assert (operands[2] == constm1_rtx);
6135	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6136	}
6137
6138    default:
6139      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6140	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6141      if (GET_CODE (operands[2]) == CONST_INT
6142          && (INTVAL (operands[2]) == 128
6143	      || (INTVAL (operands[2]) < 0
6144		  && INTVAL (operands[2]) != -128)))
6145	{
6146	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6147	  if (widen)
6148	    return "sub{l}\t{%2, %k0|%k0, %2}";
6149	  else
6150	    return "sub{b}\t{%2, %0|%0, %2}";
6151	}
6152      if (widen)
6153        return "add{l}\t{%k2, %k0|%k0, %k2}";
6154      else
6155        return "add{b}\t{%2, %0|%0, %2}";
6156    }
6157}
6158  [(set (attr "type")
6159     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6160	(const_string "incdec")
6161	(const_string "alu")))
6162   (set_attr "mode" "QI,QI,SI")])
6163
6164(define_insn "*addqi_1_slp"
6165  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6166	(plus:QI (match_dup 0)
6167		 (match_operand:QI 1 "general_operand" "qn,qnm")))
6168   (clobber (reg:CC FLAGS_REG))]
6169  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6170   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6171{
6172  switch (get_attr_type (insn))
6173    {
6174    case TYPE_INCDEC:
6175      if (operands[1] == const1_rtx)
6176	return "inc{b}\t%0";
6177      else
6178	{
6179	  gcc_assert (operands[1] == constm1_rtx);
6180	  return "dec{b}\t%0";
6181	}
6182
6183    default:
6184      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6185      if (GET_CODE (operands[1]) == CONST_INT
6186	  && INTVAL (operands[1]) < 0)
6187	{
6188	  operands[1] = GEN_INT (-INTVAL (operands[1]));
6189	  return "sub{b}\t{%1, %0|%0, %1}";
6190	}
6191      return "add{b}\t{%1, %0|%0, %1}";
6192    }
6193}
6194  [(set (attr "type")
6195     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6196	(const_string "incdec")
6197	(const_string "alu1")))
6198   (set (attr "memory")
6199     (if_then_else (match_operand 1 "memory_operand" "")
6200        (const_string "load")
6201        (const_string "none")))
6202   (set_attr "mode" "QI")])
6203
6204(define_insn "*addqi_2"
6205  [(set (reg FLAGS_REG)
6206	(compare
6207	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6208		   (match_operand:QI 2 "general_operand" "qmni,qni"))
6209	  (const_int 0)))
6210   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6211	(plus:QI (match_dup 1) (match_dup 2)))]
6212  "ix86_match_ccmode (insn, CCGOCmode)
6213   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6214{
6215  switch (get_attr_type (insn))
6216    {
6217    case TYPE_INCDEC:
6218      if (operands[2] == const1_rtx)
6219	return "inc{b}\t%0";
6220      else
6221        {
6222	  gcc_assert (operands[2] == constm1_rtx
6223		      || (GET_CODE (operands[2]) == CONST_INT
6224		          && INTVAL (operands[2]) == 255));
6225	  return "dec{b}\t%0";
6226	}
6227
6228    default:
6229      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6230      if (GET_CODE (operands[2]) == CONST_INT
6231          && INTVAL (operands[2]) < 0)
6232	{
6233	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6234	  return "sub{b}\t{%2, %0|%0, %2}";
6235	}
6236      return "add{b}\t{%2, %0|%0, %2}";
6237    }
6238}
6239  [(set (attr "type")
6240     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6241	(const_string "incdec")
6242	(const_string "alu")))
6243   (set_attr "mode" "QI")])
6244
6245(define_insn "*addqi_3"
6246  [(set (reg FLAGS_REG)
6247	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6248		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6249   (clobber (match_scratch:QI 0 "=q"))]
6250  "ix86_match_ccmode (insn, CCZmode)
6251   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6252{
6253  switch (get_attr_type (insn))
6254    {
6255    case TYPE_INCDEC:
6256      if (operands[2] == const1_rtx)
6257	return "inc{b}\t%0";
6258      else
6259        {
6260	  gcc_assert (operands[2] == constm1_rtx
6261		      || (GET_CODE (operands[2]) == CONST_INT
6262			  && INTVAL (operands[2]) == 255));
6263	  return "dec{b}\t%0";
6264	}
6265
6266    default:
6267      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6268      if (GET_CODE (operands[2]) == CONST_INT
6269          && INTVAL (operands[2]) < 0)
6270	{
6271	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6272	  return "sub{b}\t{%2, %0|%0, %2}";
6273	}
6274      return "add{b}\t{%2, %0|%0, %2}";
6275    }
6276}
6277  [(set (attr "type")
6278     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6279	(const_string "incdec")
6280	(const_string "alu")))
6281   (set_attr "mode" "QI")])
6282
6283; See comments above addsi_4 for details.
6284(define_insn "*addqi_4"
6285  [(set (reg FLAGS_REG)
6286	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
6287		 (match_operand:QI 2 "const_int_operand" "n")))
6288   (clobber (match_scratch:QI 0 "=qm"))]
6289  "ix86_match_ccmode (insn, CCGCmode)
6290   && (INTVAL (operands[2]) & 0xff) != 0x80"
6291{
6292  switch (get_attr_type (insn))
6293    {
6294    case TYPE_INCDEC:
6295      if (operands[2] == constm1_rtx
6296	  || (GET_CODE (operands[2]) == CONST_INT
6297	      && INTVAL (operands[2]) == 255))
6298        return "inc{b}\t%0";
6299      else
6300	{
6301	  gcc_assert (operands[2] == const1_rtx);
6302          return "dec{b}\t%0";
6303	}
6304
6305    default:
6306      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6307      if (INTVAL (operands[2]) < 0)
6308        {
6309          operands[2] = GEN_INT (-INTVAL (operands[2]));
6310          return "add{b}\t{%2, %0|%0, %2}";
6311        }
6312      return "sub{b}\t{%2, %0|%0, %2}";
6313    }
6314}
6315  [(set (attr "type")
6316     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6317	(const_string "incdec")
6318	(const_string "alu")))
6319   (set_attr "mode" "QI")])
6320
6321
6322(define_insn "*addqi_5"
6323  [(set (reg FLAGS_REG)
6324	(compare
6325	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6326		   (match_operand:QI 2 "general_operand" "qmni"))
6327	  (const_int 0)))
6328   (clobber (match_scratch:QI 0 "=q"))]
6329  "ix86_match_ccmode (insn, CCGOCmode)
6330   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6331{
6332  switch (get_attr_type (insn))
6333    {
6334    case TYPE_INCDEC:
6335      if (operands[2] == const1_rtx)
6336	return "inc{b}\t%0";
6337      else
6338        {
6339	  gcc_assert (operands[2] == constm1_rtx
6340		      || (GET_CODE (operands[2]) == CONST_INT
6341			  && INTVAL (operands[2]) == 255));
6342	  return "dec{b}\t%0";
6343	}
6344
6345    default:
6346      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6347      if (GET_CODE (operands[2]) == CONST_INT
6348          && INTVAL (operands[2]) < 0)
6349	{
6350	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6351	  return "sub{b}\t{%2, %0|%0, %2}";
6352	}
6353      return "add{b}\t{%2, %0|%0, %2}";
6354    }
6355}
6356  [(set (attr "type")
6357     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6358	(const_string "incdec")
6359	(const_string "alu")))
6360   (set_attr "mode" "QI")])
6361
6362
6363(define_insn "addqi_ext_1"
6364  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6365			 (const_int 8)
6366			 (const_int 8))
6367	(plus:SI
6368	  (zero_extract:SI
6369	    (match_operand 1 "ext_register_operand" "0")
6370	    (const_int 8)
6371	    (const_int 8))
6372	  (match_operand:QI 2 "general_operand" "Qmn")))
6373   (clobber (reg:CC FLAGS_REG))]
6374  "!TARGET_64BIT"
6375{
6376  switch (get_attr_type (insn))
6377    {
6378    case TYPE_INCDEC:
6379      if (operands[2] == const1_rtx)
6380	return "inc{b}\t%h0";
6381      else
6382        {
6383	  gcc_assert (operands[2] == constm1_rtx
6384		      || (GET_CODE (operands[2]) == CONST_INT
6385			  && INTVAL (operands[2]) == 255));
6386          return "dec{b}\t%h0";
6387	}
6388
6389    default:
6390      return "add{b}\t{%2, %h0|%h0, %2}";
6391    }
6392}
6393  [(set (attr "type")
6394     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6395	(const_string "incdec")
6396	(const_string "alu")))
6397   (set_attr "mode" "QI")])
6398
6399(define_insn "*addqi_ext_1_rex64"
6400  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6401			 (const_int 8)
6402			 (const_int 8))
6403	(plus:SI
6404	  (zero_extract:SI
6405	    (match_operand 1 "ext_register_operand" "0")
6406	    (const_int 8)
6407	    (const_int 8))
6408	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6409   (clobber (reg:CC FLAGS_REG))]
6410  "TARGET_64BIT"
6411{
6412  switch (get_attr_type (insn))
6413    {
6414    case TYPE_INCDEC:
6415      if (operands[2] == const1_rtx)
6416	return "inc{b}\t%h0";
6417      else
6418        {
6419	  gcc_assert (operands[2] == constm1_rtx
6420		      || (GET_CODE (operands[2]) == CONST_INT
6421			  && INTVAL (operands[2]) == 255));
6422          return "dec{b}\t%h0";
6423        }
6424
6425    default:
6426      return "add{b}\t{%2, %h0|%h0, %2}";
6427    }
6428}
6429  [(set (attr "type")
6430     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6431	(const_string "incdec")
6432	(const_string "alu")))
6433   (set_attr "mode" "QI")])
6434
6435(define_insn "*addqi_ext_2"
6436  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6437			 (const_int 8)
6438			 (const_int 8))
6439	(plus:SI
6440	  (zero_extract:SI
6441	    (match_operand 1 "ext_register_operand" "%0")
6442	    (const_int 8)
6443	    (const_int 8))
6444	  (zero_extract:SI
6445	    (match_operand 2 "ext_register_operand" "Q")
6446	    (const_int 8)
6447	    (const_int 8))))
6448   (clobber (reg:CC FLAGS_REG))]
6449  ""
6450  "add{b}\t{%h2, %h0|%h0, %h2}"
6451  [(set_attr "type" "alu")
6452   (set_attr "mode" "QI")])
6453
6454;; The patterns that match these are at the end of this file.
6455
6456(define_expand "addxf3"
6457  [(set (match_operand:XF 0 "register_operand" "")
6458	(plus:XF (match_operand:XF 1 "register_operand" "")
6459		 (match_operand:XF 2 "register_operand" "")))]
6460  "TARGET_80387"
6461  "")
6462
6463(define_expand "adddf3"
6464  [(set (match_operand:DF 0 "register_operand" "")
6465	(plus:DF (match_operand:DF 1 "register_operand" "")
6466		 (match_operand:DF 2 "nonimmediate_operand" "")))]
6467  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6468  "")
6469
6470(define_expand "addsf3"
6471  [(set (match_operand:SF 0 "register_operand" "")
6472	(plus:SF (match_operand:SF 1 "register_operand" "")
6473		 (match_operand:SF 2 "nonimmediate_operand" "")))]
6474  "TARGET_80387 || TARGET_SSE_MATH"
6475  "")
6476
6477;; Subtract instructions
6478
6479;; %%% splits for subditi3
6480
6481(define_expand "subti3"
6482  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6483		   (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6484			     (match_operand:TI 2 "x86_64_general_operand" "")))
6485	      (clobber (reg:CC FLAGS_REG))])]
6486  "TARGET_64BIT"
6487  "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6488
6489(define_insn "*subti3_1"
6490  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6491	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6492		  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6493   (clobber (reg:CC FLAGS_REG))]
6494  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6495  "#")
6496
6497(define_split
6498  [(set (match_operand:TI 0 "nonimmediate_operand" "")
6499	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6500		  (match_operand:TI 2 "x86_64_general_operand" "")))
6501   (clobber (reg:CC FLAGS_REG))]
6502  "TARGET_64BIT && reload_completed"
6503  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6504	      (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6505   (parallel [(set (match_dup 3)
6506		   (minus:DI (match_dup 4)
6507			     (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6508				      (match_dup 5))))
6509	      (clobber (reg:CC FLAGS_REG))])]
6510  "split_ti (operands+0, 1, operands+0, operands+3);
6511   split_ti (operands+1, 1, operands+1, operands+4);
6512   split_ti (operands+2, 1, operands+2, operands+5);")
6513
6514;; %%% splits for subsidi3
6515
6516(define_expand "subdi3"
6517  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6518		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6519			     (match_operand:DI 2 "x86_64_general_operand" "")))
6520	      (clobber (reg:CC FLAGS_REG))])]
6521  ""
6522  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6523
6524(define_insn "*subdi3_1"
6525  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6526	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6527		  (match_operand:DI 2 "general_operand" "roiF,riF")))
6528   (clobber (reg:CC FLAGS_REG))]
6529  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6530  "#")
6531
6532(define_split
6533  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6534	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6535		  (match_operand:DI 2 "general_operand" "")))
6536   (clobber (reg:CC FLAGS_REG))]
6537  "!TARGET_64BIT && reload_completed"
6538  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6539	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6540   (parallel [(set (match_dup 3)
6541		   (minus:SI (match_dup 4)
6542			     (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6543				      (match_dup 5))))
6544	      (clobber (reg:CC FLAGS_REG))])]
6545  "split_di (operands+0, 1, operands+0, operands+3);
6546   split_di (operands+1, 1, operands+1, operands+4);
6547   split_di (operands+2, 1, operands+2, operands+5);")
6548
6549(define_insn "subdi3_carry_rex64"
6550  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6551	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6552	    (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6553	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6554   (clobber (reg:CC FLAGS_REG))]
6555  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6556  "sbb{q}\t{%2, %0|%0, %2}"
6557  [(set_attr "type" "alu")
6558   (set_attr "pent_pair" "pu")
6559   (set_attr "mode" "DI")])
6560
6561(define_insn "*subdi_1_rex64"
6562  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6563	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6564		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6565   (clobber (reg:CC FLAGS_REG))]
6566  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6567  "sub{q}\t{%2, %0|%0, %2}"
6568  [(set_attr "type" "alu")
6569   (set_attr "mode" "DI")])
6570
6571(define_insn "*subdi_2_rex64"
6572  [(set (reg FLAGS_REG)
6573	(compare
6574	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6575		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6576	  (const_int 0)))
6577   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6578	(minus:DI (match_dup 1) (match_dup 2)))]
6579  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6580   && ix86_binary_operator_ok (MINUS, DImode, operands)"
6581  "sub{q}\t{%2, %0|%0, %2}"
6582  [(set_attr "type" "alu")
6583   (set_attr "mode" "DI")])
6584
6585(define_insn "*subdi_3_rex63"
6586  [(set (reg FLAGS_REG)
6587	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6588		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6589   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6590	(minus:DI (match_dup 1) (match_dup 2)))]
6591  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6592   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6593  "sub{q}\t{%2, %0|%0, %2}"
6594  [(set_attr "type" "alu")
6595   (set_attr "mode" "DI")])
6596
6597(define_insn "subqi3_carry"
6598  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6599	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6600	    (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6601	       (match_operand:QI 2 "general_operand" "qi,qm"))))
6602   (clobber (reg:CC FLAGS_REG))]
6603  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6604  "sbb{b}\t{%2, %0|%0, %2}"
6605  [(set_attr "type" "alu")
6606   (set_attr "pent_pair" "pu")
6607   (set_attr "mode" "QI")])
6608
6609(define_insn "subhi3_carry"
6610  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6611	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6612	    (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6613	       (match_operand:HI 2 "general_operand" "ri,rm"))))
6614   (clobber (reg:CC FLAGS_REG))]
6615  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6616  "sbb{w}\t{%2, %0|%0, %2}"
6617  [(set_attr "type" "alu")
6618   (set_attr "pent_pair" "pu")
6619   (set_attr "mode" "HI")])
6620
6621(define_insn "subsi3_carry"
6622  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6623	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6624	    (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6625	       (match_operand:SI 2 "general_operand" "ri,rm"))))
6626   (clobber (reg:CC FLAGS_REG))]
6627  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6628  "sbb{l}\t{%2, %0|%0, %2}"
6629  [(set_attr "type" "alu")
6630   (set_attr "pent_pair" "pu")
6631   (set_attr "mode" "SI")])
6632
6633(define_insn "subsi3_carry_zext"
6634  [(set (match_operand:DI 0 "register_operand" "=rm,r")
6635	  (zero_extend:DI
6636	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6637	      (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6638		 (match_operand:SI 2 "general_operand" "ri,rm")))))
6639   (clobber (reg:CC FLAGS_REG))]
6640  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6641  "sbb{l}\t{%2, %k0|%k0, %2}"
6642  [(set_attr "type" "alu")
6643   (set_attr "pent_pair" "pu")
6644   (set_attr "mode" "SI")])
6645
6646(define_expand "subsi3"
6647  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6648		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6649			     (match_operand:SI 2 "general_operand" "")))
6650	      (clobber (reg:CC FLAGS_REG))])]
6651  ""
6652  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6653
6654(define_insn "*subsi_1"
6655  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6656	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6657		  (match_operand:SI 2 "general_operand" "ri,rm")))
6658   (clobber (reg:CC FLAGS_REG))]
6659  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6660  "sub{l}\t{%2, %0|%0, %2}"
6661  [(set_attr "type" "alu")
6662   (set_attr "mode" "SI")])
6663
6664(define_insn "*subsi_1_zext"
6665  [(set (match_operand:DI 0 "register_operand" "=r")
6666	(zero_extend:DI
6667	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6668		    (match_operand:SI 2 "general_operand" "rim"))))
6669   (clobber (reg:CC FLAGS_REG))]
6670  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6671  "sub{l}\t{%2, %k0|%k0, %2}"
6672  [(set_attr "type" "alu")
6673   (set_attr "mode" "SI")])
6674
6675(define_insn "*subsi_2"
6676  [(set (reg FLAGS_REG)
6677	(compare
6678	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6679		    (match_operand:SI 2 "general_operand" "ri,rm"))
6680	  (const_int 0)))
6681   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6682	(minus:SI (match_dup 1) (match_dup 2)))]
6683  "ix86_match_ccmode (insn, CCGOCmode)
6684   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6685  "sub{l}\t{%2, %0|%0, %2}"
6686  [(set_attr "type" "alu")
6687   (set_attr "mode" "SI")])
6688
6689(define_insn "*subsi_2_zext"
6690  [(set (reg FLAGS_REG)
6691	(compare
6692	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6693		    (match_operand:SI 2 "general_operand" "rim"))
6694	  (const_int 0)))
6695   (set (match_operand:DI 0 "register_operand" "=r")
6696	(zero_extend:DI
6697	  (minus:SI (match_dup 1)
6698		    (match_dup 2))))]
6699  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6700   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6701  "sub{l}\t{%2, %k0|%k0, %2}"
6702  [(set_attr "type" "alu")
6703   (set_attr "mode" "SI")])
6704
6705(define_insn "*subsi_3"
6706  [(set (reg FLAGS_REG)
6707	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6708		 (match_operand:SI 2 "general_operand" "ri,rm")))
6709   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6710	(minus:SI (match_dup 1) (match_dup 2)))]
6711  "ix86_match_ccmode (insn, CCmode)
6712   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6713  "sub{l}\t{%2, %0|%0, %2}"
6714  [(set_attr "type" "alu")
6715   (set_attr "mode" "SI")])
6716
6717(define_insn "*subsi_3_zext"
6718  [(set (reg FLAGS_REG)
6719	(compare (match_operand:SI 1 "register_operand" "0")
6720		 (match_operand:SI 2 "general_operand" "rim")))
6721   (set (match_operand:DI 0 "register_operand" "=r")
6722	(zero_extend:DI
6723	  (minus:SI (match_dup 1)
6724		    (match_dup 2))))]
6725  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6726   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6727  "sub{l}\t{%2, %1|%1, %2}"
6728  [(set_attr "type" "alu")
6729   (set_attr "mode" "DI")])
6730
6731(define_expand "subhi3"
6732  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6733		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6734			     (match_operand:HI 2 "general_operand" "")))
6735	      (clobber (reg:CC FLAGS_REG))])]
6736  "TARGET_HIMODE_MATH"
6737  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6738
6739(define_insn "*subhi_1"
6740  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6741	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6742		  (match_operand:HI 2 "general_operand" "ri,rm")))
6743   (clobber (reg:CC FLAGS_REG))]
6744  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6745  "sub{w}\t{%2, %0|%0, %2}"
6746  [(set_attr "type" "alu")
6747   (set_attr "mode" "HI")])
6748
6749(define_insn "*subhi_2"
6750  [(set (reg FLAGS_REG)
6751	(compare
6752	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6753		    (match_operand:HI 2 "general_operand" "ri,rm"))
6754	  (const_int 0)))
6755   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6756	(minus:HI (match_dup 1) (match_dup 2)))]
6757  "ix86_match_ccmode (insn, CCGOCmode)
6758   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6759  "sub{w}\t{%2, %0|%0, %2}"
6760  [(set_attr "type" "alu")
6761   (set_attr "mode" "HI")])
6762
6763(define_insn "*subhi_3"
6764  [(set (reg FLAGS_REG)
6765	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6766		 (match_operand:HI 2 "general_operand" "ri,rm")))
6767   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6768	(minus:HI (match_dup 1) (match_dup 2)))]
6769  "ix86_match_ccmode (insn, CCmode)
6770   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6771  "sub{w}\t{%2, %0|%0, %2}"
6772  [(set_attr "type" "alu")
6773   (set_attr "mode" "HI")])
6774
6775(define_expand "subqi3"
6776  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6777		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6778			     (match_operand:QI 2 "general_operand" "")))
6779	      (clobber (reg:CC FLAGS_REG))])]
6780  "TARGET_QIMODE_MATH"
6781  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6782
6783(define_insn "*subqi_1"
6784  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6785	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6786		  (match_operand:QI 2 "general_operand" "qn,qmn")))
6787   (clobber (reg:CC FLAGS_REG))]
6788  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6789  "sub{b}\t{%2, %0|%0, %2}"
6790  [(set_attr "type" "alu")
6791   (set_attr "mode" "QI")])
6792
6793(define_insn "*subqi_1_slp"
6794  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6795	(minus:QI (match_dup 0)
6796		  (match_operand:QI 1 "general_operand" "qn,qmn")))
6797   (clobber (reg:CC FLAGS_REG))]
6798  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6799   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6800  "sub{b}\t{%1, %0|%0, %1}"
6801  [(set_attr "type" "alu1")
6802   (set_attr "mode" "QI")])
6803
6804(define_insn "*subqi_2"
6805  [(set (reg FLAGS_REG)
6806	(compare
6807	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6808		    (match_operand:QI 2 "general_operand" "qi,qm"))
6809	  (const_int 0)))
6810   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6811	(minus:HI (match_dup 1) (match_dup 2)))]
6812  "ix86_match_ccmode (insn, CCGOCmode)
6813   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6814  "sub{b}\t{%2, %0|%0, %2}"
6815  [(set_attr "type" "alu")
6816   (set_attr "mode" "QI")])
6817
6818(define_insn "*subqi_3"
6819  [(set (reg FLAGS_REG)
6820	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6821		 (match_operand:QI 2 "general_operand" "qi,qm")))
6822   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6823	(minus:HI (match_dup 1) (match_dup 2)))]
6824  "ix86_match_ccmode (insn, CCmode)
6825   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6826  "sub{b}\t{%2, %0|%0, %2}"
6827  [(set_attr "type" "alu")
6828   (set_attr "mode" "QI")])
6829
6830;; The patterns that match these are at the end of this file.
6831
6832(define_expand "subxf3"
6833  [(set (match_operand:XF 0 "register_operand" "")
6834	(minus:XF (match_operand:XF 1 "register_operand" "")
6835		  (match_operand:XF 2 "register_operand" "")))]
6836  "TARGET_80387"
6837  "")
6838
6839(define_expand "subdf3"
6840  [(set (match_operand:DF 0 "register_operand" "")
6841	(minus:DF (match_operand:DF 1 "register_operand" "")
6842		  (match_operand:DF 2 "nonimmediate_operand" "")))]
6843  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6844  "")
6845
6846(define_expand "subsf3"
6847  [(set (match_operand:SF 0 "register_operand" "")
6848	(minus:SF (match_operand:SF 1 "register_operand" "")
6849		  (match_operand:SF 2 "nonimmediate_operand" "")))]
6850  "TARGET_80387 || TARGET_SSE_MATH"
6851  "")
6852
6853;; Multiply instructions
6854
6855(define_expand "muldi3"
6856  [(parallel [(set (match_operand:DI 0 "register_operand" "")
6857		   (mult:DI (match_operand:DI 1 "register_operand" "")
6858			    (match_operand:DI 2 "x86_64_general_operand" "")))
6859	      (clobber (reg:CC FLAGS_REG))])]
6860  "TARGET_64BIT"
6861  "")
6862
6863(define_insn "*muldi3_1_rex64"
6864  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6865	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6866		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6867   (clobber (reg:CC FLAGS_REG))]
6868  "TARGET_64BIT
6869   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6870  "@
6871   imul{q}\t{%2, %1, %0|%0, %1, %2}
6872   imul{q}\t{%2, %1, %0|%0, %1, %2}
6873   imul{q}\t{%2, %0|%0, %2}"
6874  [(set_attr "type" "imul")
6875   (set_attr "prefix_0f" "0,0,1")
6876   (set (attr "athlon_decode")
6877	(cond [(eq_attr "cpu" "athlon")
6878		  (const_string "vector")
6879	       (eq_attr "alternative" "1")
6880		  (const_string "vector")
6881	       (and (eq_attr "alternative" "2")
6882		    (match_operand 1 "memory_operand" ""))
6883		  (const_string "vector")]
6884	      (const_string "direct")))
6885   (set_attr "mode" "DI")])
6886
6887(define_expand "mulsi3"
6888  [(parallel [(set (match_operand:SI 0 "register_operand" "")
6889		   (mult:SI (match_operand:SI 1 "register_operand" "")
6890			    (match_operand:SI 2 "general_operand" "")))
6891	      (clobber (reg:CC FLAGS_REG))])]
6892  ""
6893  "")
6894
6895(define_insn "*mulsi3_1"
6896  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6897	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6898		 (match_operand:SI 2 "general_operand" "K,i,mr")))
6899   (clobber (reg:CC FLAGS_REG))]
6900  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6901  "@
6902   imul{l}\t{%2, %1, %0|%0, %1, %2}
6903   imul{l}\t{%2, %1, %0|%0, %1, %2}
6904   imul{l}\t{%2, %0|%0, %2}"
6905  [(set_attr "type" "imul")
6906   (set_attr "prefix_0f" "0,0,1")
6907   (set (attr "athlon_decode")
6908	(cond [(eq_attr "cpu" "athlon")
6909		  (const_string "vector")
6910	       (eq_attr "alternative" "1")
6911		  (const_string "vector")
6912	       (and (eq_attr "alternative" "2")
6913		    (match_operand 1 "memory_operand" ""))
6914		  (const_string "vector")]
6915	      (const_string "direct")))
6916   (set_attr "mode" "SI")])
6917
6918(define_insn "*mulsi3_1_zext"
6919  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6920	(zero_extend:DI
6921	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6922		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
6923   (clobber (reg:CC FLAGS_REG))]
6924  "TARGET_64BIT
6925   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6926  "@
6927   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6928   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6929   imul{l}\t{%2, %k0|%k0, %2}"
6930  [(set_attr "type" "imul")
6931   (set_attr "prefix_0f" "0,0,1")
6932   (set (attr "athlon_decode")
6933	(cond [(eq_attr "cpu" "athlon")
6934		  (const_string "vector")
6935	       (eq_attr "alternative" "1")
6936		  (const_string "vector")
6937	       (and (eq_attr "alternative" "2")
6938		    (match_operand 1 "memory_operand" ""))
6939		  (const_string "vector")]
6940	      (const_string "direct")))
6941   (set_attr "mode" "SI")])
6942
6943(define_expand "mulhi3"
6944  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6945		   (mult:HI (match_operand:HI 1 "register_operand" "")
6946			    (match_operand:HI 2 "general_operand" "")))
6947	      (clobber (reg:CC FLAGS_REG))])]
6948  "TARGET_HIMODE_MATH"
6949  "")
6950
6951(define_insn "*mulhi3_1"
6952  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6953	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6954		 (match_operand:HI 2 "general_operand" "K,i,mr")))
6955   (clobber (reg:CC FLAGS_REG))]
6956  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6957  "@
6958   imul{w}\t{%2, %1, %0|%0, %1, %2}
6959   imul{w}\t{%2, %1, %0|%0, %1, %2}
6960   imul{w}\t{%2, %0|%0, %2}"
6961  [(set_attr "type" "imul")
6962   (set_attr "prefix_0f" "0,0,1")
6963   (set (attr "athlon_decode")
6964	(cond [(eq_attr "cpu" "athlon")
6965		  (const_string "vector")
6966	       (eq_attr "alternative" "1,2")
6967		  (const_string "vector")]
6968	      (const_string "direct")))
6969   (set_attr "mode" "HI")])
6970
6971(define_expand "mulqi3"
6972  [(parallel [(set (match_operand:QI 0 "register_operand" "")
6973		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6974			    (match_operand:QI 2 "register_operand" "")))
6975	      (clobber (reg:CC FLAGS_REG))])]
6976  "TARGET_QIMODE_MATH"
6977  "")
6978
6979(define_insn "*mulqi3_1"
6980  [(set (match_operand:QI 0 "register_operand" "=a")
6981	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6982		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6983   (clobber (reg:CC FLAGS_REG))]
6984  "TARGET_QIMODE_MATH
6985   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6986  "mul{b}\t%2"
6987  [(set_attr "type" "imul")
6988   (set_attr "length_immediate" "0")
6989   (set (attr "athlon_decode")
6990     (if_then_else (eq_attr "cpu" "athlon")
6991        (const_string "vector")
6992        (const_string "direct")))
6993   (set_attr "mode" "QI")])
6994
6995(define_expand "umulqihi3"
6996  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6997		   (mult:HI (zero_extend:HI
6998			      (match_operand:QI 1 "nonimmediate_operand" ""))
6999			    (zero_extend:HI
7000			      (match_operand:QI 2 "register_operand" ""))))
7001	      (clobber (reg:CC FLAGS_REG))])]
7002  "TARGET_QIMODE_MATH"
7003  "")
7004
7005(define_insn "*umulqihi3_1"
7006  [(set (match_operand:HI 0 "register_operand" "=a")
7007	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7008		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7009   (clobber (reg:CC FLAGS_REG))]
7010  "TARGET_QIMODE_MATH
7011   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7012  "mul{b}\t%2"
7013  [(set_attr "type" "imul")
7014   (set_attr "length_immediate" "0")
7015   (set (attr "athlon_decode")
7016     (if_then_else (eq_attr "cpu" "athlon")
7017        (const_string "vector")
7018        (const_string "direct")))
7019   (set_attr "mode" "QI")])
7020
7021(define_expand "mulqihi3"
7022  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7023		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7024			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7025	      (clobber (reg:CC FLAGS_REG))])]
7026  "TARGET_QIMODE_MATH"
7027  "")
7028
7029(define_insn "*mulqihi3_insn"
7030  [(set (match_operand:HI 0 "register_operand" "=a")
7031	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7032		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7033   (clobber (reg:CC FLAGS_REG))]
7034  "TARGET_QIMODE_MATH
7035   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7036  "imul{b}\t%2"
7037  [(set_attr "type" "imul")
7038   (set_attr "length_immediate" "0")
7039   (set (attr "athlon_decode")
7040     (if_then_else (eq_attr "cpu" "athlon")
7041        (const_string "vector")
7042        (const_string "direct")))
7043   (set_attr "mode" "QI")])
7044
7045(define_expand "umulditi3"
7046  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7047		   (mult:TI (zero_extend:TI
7048			      (match_operand:DI 1 "nonimmediate_operand" ""))
7049			    (zero_extend:TI
7050			      (match_operand:DI 2 "register_operand" ""))))
7051	      (clobber (reg:CC FLAGS_REG))])]
7052  "TARGET_64BIT"
7053  "")
7054
7055(define_insn "*umulditi3_insn"
7056  [(set (match_operand:TI 0 "register_operand" "=A")
7057	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7058		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7059   (clobber (reg:CC FLAGS_REG))]
7060  "TARGET_64BIT
7061   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7062  "mul{q}\t%2"
7063  [(set_attr "type" "imul")
7064   (set_attr "length_immediate" "0")
7065   (set (attr "athlon_decode")
7066     (if_then_else (eq_attr "cpu" "athlon")
7067        (const_string "vector")
7068        (const_string "double")))
7069   (set_attr "mode" "DI")])
7070
7071;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7072(define_expand "umulsidi3"
7073  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7074		   (mult:DI (zero_extend:DI
7075			      (match_operand:SI 1 "nonimmediate_operand" ""))
7076			    (zero_extend:DI
7077			      (match_operand:SI 2 "register_operand" ""))))
7078	      (clobber (reg:CC FLAGS_REG))])]
7079  "!TARGET_64BIT"
7080  "")
7081
7082(define_insn "*umulsidi3_insn"
7083  [(set (match_operand:DI 0 "register_operand" "=A")
7084	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7085		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7086   (clobber (reg:CC FLAGS_REG))]
7087  "!TARGET_64BIT
7088   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7089  "mul{l}\t%2"
7090  [(set_attr "type" "imul")
7091   (set_attr "length_immediate" "0")
7092   (set (attr "athlon_decode")
7093     (if_then_else (eq_attr "cpu" "athlon")
7094        (const_string "vector")
7095        (const_string "double")))
7096   (set_attr "mode" "SI")])
7097
7098(define_expand "mulditi3"
7099  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7100		   (mult:TI (sign_extend:TI
7101			      (match_operand:DI 1 "nonimmediate_operand" ""))
7102			    (sign_extend:TI
7103			      (match_operand:DI 2 "register_operand" ""))))
7104	      (clobber (reg:CC FLAGS_REG))])]
7105  "TARGET_64BIT"
7106  "")
7107
7108(define_insn "*mulditi3_insn"
7109  [(set (match_operand:TI 0 "register_operand" "=A")
7110	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7111		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7112   (clobber (reg:CC FLAGS_REG))]
7113  "TARGET_64BIT
7114   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7115  "imul{q}\t%2"
7116  [(set_attr "type" "imul")
7117   (set_attr "length_immediate" "0")
7118   (set (attr "athlon_decode")
7119     (if_then_else (eq_attr "cpu" "athlon")
7120        (const_string "vector")
7121        (const_string "double")))
7122   (set_attr "mode" "DI")])
7123
7124(define_expand "mulsidi3"
7125  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7126		   (mult:DI (sign_extend:DI
7127			      (match_operand:SI 1 "nonimmediate_operand" ""))
7128			    (sign_extend:DI
7129			      (match_operand:SI 2 "register_operand" ""))))
7130	      (clobber (reg:CC FLAGS_REG))])]
7131  "!TARGET_64BIT"
7132  "")
7133
7134(define_insn "*mulsidi3_insn"
7135  [(set (match_operand:DI 0 "register_operand" "=A")
7136	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7137		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7138   (clobber (reg:CC FLAGS_REG))]
7139  "!TARGET_64BIT
7140   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7141  "imul{l}\t%2"
7142  [(set_attr "type" "imul")
7143   (set_attr "length_immediate" "0")
7144   (set (attr "athlon_decode")
7145     (if_then_else (eq_attr "cpu" "athlon")
7146        (const_string "vector")
7147        (const_string "double")))
7148   (set_attr "mode" "SI")])
7149
7150(define_expand "umuldi3_highpart"
7151  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7152		   (truncate:DI
7153		     (lshiftrt:TI
7154		       (mult:TI (zero_extend:TI
7155				  (match_operand:DI 1 "nonimmediate_operand" ""))
7156				(zero_extend:TI
7157				  (match_operand:DI 2 "register_operand" "")))
7158		       (const_int 64))))
7159	      (clobber (match_scratch:DI 3 ""))
7160	      (clobber (reg:CC FLAGS_REG))])]
7161  "TARGET_64BIT"
7162  "")
7163
7164(define_insn "*umuldi3_highpart_rex64"
7165  [(set (match_operand:DI 0 "register_operand" "=d")
7166	(truncate:DI
7167	  (lshiftrt:TI
7168	    (mult:TI (zero_extend:TI
7169		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7170		     (zero_extend:TI
7171		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7172	    (const_int 64))))
7173   (clobber (match_scratch:DI 3 "=1"))
7174   (clobber (reg:CC FLAGS_REG))]
7175  "TARGET_64BIT
7176   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7177  "mul{q}\t%2"
7178  [(set_attr "type" "imul")
7179   (set_attr "length_immediate" "0")
7180   (set (attr "athlon_decode")
7181     (if_then_else (eq_attr "cpu" "athlon")
7182        (const_string "vector")
7183        (const_string "double")))
7184   (set_attr "mode" "DI")])
7185
7186(define_expand "umulsi3_highpart"
7187  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7188		   (truncate:SI
7189		     (lshiftrt:DI
7190		       (mult:DI (zero_extend:DI
7191				  (match_operand:SI 1 "nonimmediate_operand" ""))
7192				(zero_extend:DI
7193				  (match_operand:SI 2 "register_operand" "")))
7194		       (const_int 32))))
7195	      (clobber (match_scratch:SI 3 ""))
7196	      (clobber (reg:CC FLAGS_REG))])]
7197  ""
7198  "")
7199
7200(define_insn "*umulsi3_highpart_insn"
7201  [(set (match_operand:SI 0 "register_operand" "=d")
7202	(truncate:SI
7203	  (lshiftrt:DI
7204	    (mult:DI (zero_extend:DI
7205		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7206		     (zero_extend:DI
7207		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7208	    (const_int 32))))
7209   (clobber (match_scratch:SI 3 "=1"))
7210   (clobber (reg:CC FLAGS_REG))]
7211  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7212  "mul{l}\t%2"
7213  [(set_attr "type" "imul")
7214   (set_attr "length_immediate" "0")
7215   (set (attr "athlon_decode")
7216     (if_then_else (eq_attr "cpu" "athlon")
7217        (const_string "vector")
7218        (const_string "double")))
7219   (set_attr "mode" "SI")])
7220
7221(define_insn "*umulsi3_highpart_zext"
7222  [(set (match_operand:DI 0 "register_operand" "=d")
7223	(zero_extend:DI (truncate:SI
7224	  (lshiftrt:DI
7225	    (mult:DI (zero_extend:DI
7226		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7227		     (zero_extend:DI
7228		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7229	    (const_int 32)))))
7230   (clobber (match_scratch:SI 3 "=1"))
7231   (clobber (reg:CC FLAGS_REG))]
7232  "TARGET_64BIT
7233   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7234  "mul{l}\t%2"
7235  [(set_attr "type" "imul")
7236   (set_attr "length_immediate" "0")
7237   (set (attr "athlon_decode")
7238     (if_then_else (eq_attr "cpu" "athlon")
7239        (const_string "vector")
7240        (const_string "double")))
7241   (set_attr "mode" "SI")])
7242
7243(define_expand "smuldi3_highpart"
7244  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7245		   (truncate:DI
7246		     (lshiftrt:TI
7247		       (mult:TI (sign_extend:TI
7248				  (match_operand:DI 1 "nonimmediate_operand" ""))
7249				(sign_extend:TI
7250				  (match_operand:DI 2 "register_operand" "")))
7251		       (const_int 64))))
7252	      (clobber (match_scratch:DI 3 ""))
7253	      (clobber (reg:CC FLAGS_REG))])]
7254  "TARGET_64BIT"
7255  "")
7256
7257(define_insn "*smuldi3_highpart_rex64"
7258  [(set (match_operand:DI 0 "register_operand" "=d")
7259	(truncate:DI
7260	  (lshiftrt:TI
7261	    (mult:TI (sign_extend:TI
7262		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7263		     (sign_extend:TI
7264		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7265	    (const_int 64))))
7266   (clobber (match_scratch:DI 3 "=1"))
7267   (clobber (reg:CC FLAGS_REG))]
7268  "TARGET_64BIT
7269   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7270  "imul{q}\t%2"
7271  [(set_attr "type" "imul")
7272   (set (attr "athlon_decode")
7273     (if_then_else (eq_attr "cpu" "athlon")
7274        (const_string "vector")
7275        (const_string "double")))
7276   (set_attr "mode" "DI")])
7277
7278(define_expand "smulsi3_highpart"
7279  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7280		   (truncate:SI
7281		     (lshiftrt:DI
7282		       (mult:DI (sign_extend:DI
7283				  (match_operand:SI 1 "nonimmediate_operand" ""))
7284				(sign_extend:DI
7285				  (match_operand:SI 2 "register_operand" "")))
7286		       (const_int 32))))
7287	      (clobber (match_scratch:SI 3 ""))
7288	      (clobber (reg:CC FLAGS_REG))])]
7289  ""
7290  "")
7291
7292(define_insn "*smulsi3_highpart_insn"
7293  [(set (match_operand:SI 0 "register_operand" "=d")
7294	(truncate:SI
7295	  (lshiftrt:DI
7296	    (mult:DI (sign_extend:DI
7297		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7298		     (sign_extend:DI
7299		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7300	    (const_int 32))))
7301   (clobber (match_scratch:SI 3 "=1"))
7302   (clobber (reg:CC FLAGS_REG))]
7303  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7304  "imul{l}\t%2"
7305  [(set_attr "type" "imul")
7306   (set (attr "athlon_decode")
7307     (if_then_else (eq_attr "cpu" "athlon")
7308        (const_string "vector")
7309        (const_string "double")))
7310   (set_attr "mode" "SI")])
7311
7312(define_insn "*smulsi3_highpart_zext"
7313  [(set (match_operand:DI 0 "register_operand" "=d")
7314	(zero_extend:DI (truncate:SI
7315	  (lshiftrt:DI
7316	    (mult:DI (sign_extend:DI
7317		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7318		     (sign_extend:DI
7319		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7320	    (const_int 32)))))
7321   (clobber (match_scratch:SI 3 "=1"))
7322   (clobber (reg:CC FLAGS_REG))]
7323  "TARGET_64BIT
7324   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7325  "imul{l}\t%2"
7326  [(set_attr "type" "imul")
7327   (set (attr "athlon_decode")
7328     (if_then_else (eq_attr "cpu" "athlon")
7329        (const_string "vector")
7330        (const_string "double")))
7331   (set_attr "mode" "SI")])
7332
7333;; The patterns that match these are at the end of this file.
7334
7335(define_expand "mulxf3"
7336  [(set (match_operand:XF 0 "register_operand" "")
7337	(mult:XF (match_operand:XF 1 "register_operand" "")
7338		 (match_operand:XF 2 "register_operand" "")))]
7339  "TARGET_80387"
7340  "")
7341
7342(define_expand "muldf3"
7343  [(set (match_operand:DF 0 "register_operand" "")
7344	(mult:DF (match_operand:DF 1 "register_operand" "")
7345		 (match_operand:DF 2 "nonimmediate_operand" "")))]
7346  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7347  "")
7348
7349(define_expand "mulsf3"
7350  [(set (match_operand:SF 0 "register_operand" "")
7351	(mult:SF (match_operand:SF 1 "register_operand" "")
7352		 (match_operand:SF 2 "nonimmediate_operand" "")))]
7353  "TARGET_80387 || TARGET_SSE_MATH"
7354  "")
7355
7356;; Divide instructions
7357
7358(define_insn "divqi3"
7359  [(set (match_operand:QI 0 "register_operand" "=a")
7360	(div:QI (match_operand:HI 1 "register_operand" "0")
7361		(match_operand:QI 2 "nonimmediate_operand" "qm")))
7362   (clobber (reg:CC FLAGS_REG))]
7363  "TARGET_QIMODE_MATH"
7364  "idiv{b}\t%2"
7365  [(set_attr "type" "idiv")
7366   (set_attr "mode" "QI")])
7367
7368(define_insn "udivqi3"
7369  [(set (match_operand:QI 0 "register_operand" "=a")
7370	(udiv:QI (match_operand:HI 1 "register_operand" "0")
7371		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7372   (clobber (reg:CC FLAGS_REG))]
7373  "TARGET_QIMODE_MATH"
7374  "div{b}\t%2"
7375  [(set_attr "type" "idiv")
7376   (set_attr "mode" "QI")])
7377
7378;; The patterns that match these are at the end of this file.
7379
7380(define_expand "divxf3"
7381  [(set (match_operand:XF 0 "register_operand" "")
7382	(div:XF (match_operand:XF 1 "register_operand" "")
7383		(match_operand:XF 2 "register_operand" "")))]
7384  "TARGET_80387"
7385  "")
7386
7387(define_expand "divdf3"
7388  [(set (match_operand:DF 0 "register_operand" "")
7389 	(div:DF (match_operand:DF 1 "register_operand" "")
7390 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7391   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7392   "")
7393 
7394(define_expand "divsf3"
7395  [(set (match_operand:SF 0 "register_operand" "")
7396	(div:SF (match_operand:SF 1 "register_operand" "")
7397		(match_operand:SF 2 "nonimmediate_operand" "")))]
7398  "TARGET_80387 || TARGET_SSE_MATH"
7399  "")
7400
7401;; Remainder instructions.
7402
7403(define_expand "divmoddi4"
7404  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7405		   (div:DI (match_operand:DI 1 "register_operand" "")
7406			   (match_operand:DI 2 "nonimmediate_operand" "")))
7407	      (set (match_operand:DI 3 "register_operand" "")
7408		   (mod:DI (match_dup 1) (match_dup 2)))
7409	      (clobber (reg:CC FLAGS_REG))])]
7410  "TARGET_64BIT"
7411  "")
7412
7413;; Allow to come the parameter in eax or edx to avoid extra moves.
7414;; Penalize eax case slightly because it results in worse scheduling
7415;; of code.
7416(define_insn "*divmoddi4_nocltd_rex64"
7417  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7418	(div:DI (match_operand:DI 2 "register_operand" "1,0")
7419		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7420   (set (match_operand:DI 1 "register_operand" "=&d,&d")
7421	(mod:DI (match_dup 2) (match_dup 3)))
7422   (clobber (reg:CC FLAGS_REG))]
7423  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7424  "#"
7425  [(set_attr "type" "multi")])
7426
7427(define_insn "*divmoddi4_cltd_rex64"
7428  [(set (match_operand:DI 0 "register_operand" "=a")
7429	(div:DI (match_operand:DI 2 "register_operand" "a")
7430		(match_operand:DI 3 "nonimmediate_operand" "rm")))
7431   (set (match_operand:DI 1 "register_operand" "=&d")
7432	(mod:DI (match_dup 2) (match_dup 3)))
7433   (clobber (reg:CC FLAGS_REG))]
7434  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7435  "#"
7436  [(set_attr "type" "multi")])
7437
7438(define_insn "*divmoddi_noext_rex64"
7439  [(set (match_operand:DI 0 "register_operand" "=a")
7440	(div:DI (match_operand:DI 1 "register_operand" "0")
7441		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7442   (set (match_operand:DI 3 "register_operand" "=d")
7443	(mod:DI (match_dup 1) (match_dup 2)))
7444   (use (match_operand:DI 4 "register_operand" "3"))
7445   (clobber (reg:CC FLAGS_REG))]
7446  "TARGET_64BIT"
7447  "idiv{q}\t%2"
7448  [(set_attr "type" "idiv")
7449   (set_attr "mode" "DI")])
7450
7451(define_split
7452  [(set (match_operand:DI 0 "register_operand" "")
7453	(div:DI (match_operand:DI 1 "register_operand" "")
7454		(match_operand:DI 2 "nonimmediate_operand" "")))
7455   (set (match_operand:DI 3 "register_operand" "")
7456	(mod:DI (match_dup 1) (match_dup 2)))
7457   (clobber (reg:CC FLAGS_REG))]
7458  "TARGET_64BIT && reload_completed"
7459  [(parallel [(set (match_dup 3)
7460		   (ashiftrt:DI (match_dup 4) (const_int 63)))
7461	      (clobber (reg:CC FLAGS_REG))])
7462   (parallel [(set (match_dup 0)
7463	           (div:DI (reg:DI 0) (match_dup 2)))
7464	      (set (match_dup 3)
7465		   (mod:DI (reg:DI 0) (match_dup 2)))
7466	      (use (match_dup 3))
7467	      (clobber (reg:CC FLAGS_REG))])]
7468{
7469  /* Avoid use of cltd in favor of a mov+shift.  */
7470  if (!TARGET_USE_CLTD && !optimize_size)
7471    {
7472      if (true_regnum (operands[1]))
7473        emit_move_insn (operands[0], operands[1]);
7474      else
7475	emit_move_insn (operands[3], operands[1]);
7476      operands[4] = operands[3];
7477    }
7478  else
7479    {
7480      gcc_assert (!true_regnum (operands[1]));
7481      operands[4] = operands[1];
7482    }
7483})
7484
7485
7486(define_expand "divmodsi4"
7487  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7488		   (div:SI (match_operand:SI 1 "register_operand" "")
7489			   (match_operand:SI 2 "nonimmediate_operand" "")))
7490	      (set (match_operand:SI 3 "register_operand" "")
7491		   (mod:SI (match_dup 1) (match_dup 2)))
7492	      (clobber (reg:CC FLAGS_REG))])]
7493  ""
7494  "")
7495
7496;; Allow to come the parameter in eax or edx to avoid extra moves.
7497;; Penalize eax case slightly because it results in worse scheduling
7498;; of code.
7499(define_insn "*divmodsi4_nocltd"
7500  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7501	(div:SI (match_operand:SI 2 "register_operand" "1,0")
7502		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7503   (set (match_operand:SI 1 "register_operand" "=&d,&d")
7504	(mod:SI (match_dup 2) (match_dup 3)))
7505   (clobber (reg:CC FLAGS_REG))]
7506  "!optimize_size && !TARGET_USE_CLTD"
7507  "#"
7508  [(set_attr "type" "multi")])
7509
7510(define_insn "*divmodsi4_cltd"
7511  [(set (match_operand:SI 0 "register_operand" "=a")
7512	(div:SI (match_operand:SI 2 "register_operand" "a")
7513		(match_operand:SI 3 "nonimmediate_operand" "rm")))
7514   (set (match_operand:SI 1 "register_operand" "=&d")
7515	(mod:SI (match_dup 2) (match_dup 3)))
7516   (clobber (reg:CC FLAGS_REG))]
7517  "optimize_size || TARGET_USE_CLTD"
7518  "#"
7519  [(set_attr "type" "multi")])
7520
7521(define_insn "*divmodsi_noext"
7522  [(set (match_operand:SI 0 "register_operand" "=a")
7523	(div:SI (match_operand:SI 1 "register_operand" "0")
7524		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7525   (set (match_operand:SI 3 "register_operand" "=d")
7526	(mod:SI (match_dup 1) (match_dup 2)))
7527   (use (match_operand:SI 4 "register_operand" "3"))
7528   (clobber (reg:CC FLAGS_REG))]
7529  ""
7530  "idiv{l}\t%2"
7531  [(set_attr "type" "idiv")
7532   (set_attr "mode" "SI")])
7533
7534(define_split
7535  [(set (match_operand:SI 0 "register_operand" "")
7536	(div:SI (match_operand:SI 1 "register_operand" "")
7537		(match_operand:SI 2 "nonimmediate_operand" "")))
7538   (set (match_operand:SI 3 "register_operand" "")
7539	(mod:SI (match_dup 1) (match_dup 2)))
7540   (clobber (reg:CC FLAGS_REG))]
7541  "reload_completed"
7542  [(parallel [(set (match_dup 3)
7543		   (ashiftrt:SI (match_dup 4) (const_int 31)))
7544	      (clobber (reg:CC FLAGS_REG))])
7545   (parallel [(set (match_dup 0)
7546	           (div:SI (reg:SI 0) (match_dup 2)))
7547	      (set (match_dup 3)
7548		   (mod:SI (reg:SI 0) (match_dup 2)))
7549	      (use (match_dup 3))
7550	      (clobber (reg:CC FLAGS_REG))])]
7551{
7552  /* Avoid use of cltd in favor of a mov+shift.  */
7553  if (!TARGET_USE_CLTD && !optimize_size)
7554    {
7555      if (true_regnum (operands[1]))
7556        emit_move_insn (operands[0], operands[1]);
7557      else
7558	emit_move_insn (operands[3], operands[1]);
7559      operands[4] = operands[3];
7560    }
7561  else
7562    {
7563      gcc_assert (!true_regnum (operands[1]));
7564      operands[4] = operands[1];
7565    }
7566})
7567;; %%% Split me.
7568(define_insn "divmodhi4"
7569  [(set (match_operand:HI 0 "register_operand" "=a")
7570	(div:HI (match_operand:HI 1 "register_operand" "0")
7571		(match_operand:HI 2 "nonimmediate_operand" "rm")))
7572   (set (match_operand:HI 3 "register_operand" "=&d")
7573	(mod:HI (match_dup 1) (match_dup 2)))
7574   (clobber (reg:CC FLAGS_REG))]
7575  "TARGET_HIMODE_MATH"
7576  "cwtd\;idiv{w}\t%2"
7577  [(set_attr "type" "multi")
7578   (set_attr "length_immediate" "0")
7579   (set_attr "mode" "SI")])
7580
7581(define_insn "udivmoddi4"
7582  [(set (match_operand:DI 0 "register_operand" "=a")
7583	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7584		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7585   (set (match_operand:DI 3 "register_operand" "=&d")
7586	(umod:DI (match_dup 1) (match_dup 2)))
7587   (clobber (reg:CC FLAGS_REG))]
7588  "TARGET_64BIT"
7589  "xor{q}\t%3, %3\;div{q}\t%2"
7590  [(set_attr "type" "multi")
7591   (set_attr "length_immediate" "0")
7592   (set_attr "mode" "DI")])
7593
7594(define_insn "*udivmoddi4_noext"
7595  [(set (match_operand:DI 0 "register_operand" "=a")
7596	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7597		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7598   (set (match_operand:DI 3 "register_operand" "=d")
7599	(umod:DI (match_dup 1) (match_dup 2)))
7600   (use (match_dup 3))
7601   (clobber (reg:CC FLAGS_REG))]
7602  "TARGET_64BIT"
7603  "div{q}\t%2"
7604  [(set_attr "type" "idiv")
7605   (set_attr "mode" "DI")])
7606
7607(define_split
7608  [(set (match_operand:DI 0 "register_operand" "")
7609	(udiv:DI (match_operand:DI 1 "register_operand" "")
7610		 (match_operand:DI 2 "nonimmediate_operand" "")))
7611   (set (match_operand:DI 3 "register_operand" "")
7612	(umod:DI (match_dup 1) (match_dup 2)))
7613   (clobber (reg:CC FLAGS_REG))]
7614  "TARGET_64BIT && reload_completed"
7615  [(set (match_dup 3) (const_int 0))
7616   (parallel [(set (match_dup 0)
7617		   (udiv:DI (match_dup 1) (match_dup 2)))
7618	      (set (match_dup 3)
7619		   (umod:DI (match_dup 1) (match_dup 2)))
7620	      (use (match_dup 3))
7621	      (clobber (reg:CC FLAGS_REG))])]
7622  "")
7623
7624(define_insn "udivmodsi4"
7625  [(set (match_operand:SI 0 "register_operand" "=a")
7626	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7627		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7628   (set (match_operand:SI 3 "register_operand" "=&d")
7629	(umod:SI (match_dup 1) (match_dup 2)))
7630   (clobber (reg:CC FLAGS_REG))]
7631  ""
7632  "xor{l}\t%3, %3\;div{l}\t%2"
7633  [(set_attr "type" "multi")
7634   (set_attr "length_immediate" "0")
7635   (set_attr "mode" "SI")])
7636
7637(define_insn "*udivmodsi4_noext"
7638  [(set (match_operand:SI 0 "register_operand" "=a")
7639	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7640		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7641   (set (match_operand:SI 3 "register_operand" "=d")
7642	(umod:SI (match_dup 1) (match_dup 2)))
7643   (use (match_dup 3))
7644   (clobber (reg:CC FLAGS_REG))]
7645  ""
7646  "div{l}\t%2"
7647  [(set_attr "type" "idiv")
7648   (set_attr "mode" "SI")])
7649
7650(define_split
7651  [(set (match_operand:SI 0 "register_operand" "")
7652	(udiv:SI (match_operand:SI 1 "register_operand" "")
7653		 (match_operand:SI 2 "nonimmediate_operand" "")))
7654   (set (match_operand:SI 3 "register_operand" "")
7655	(umod:SI (match_dup 1) (match_dup 2)))
7656   (clobber (reg:CC FLAGS_REG))]
7657  "reload_completed"
7658  [(set (match_dup 3) (const_int 0))
7659   (parallel [(set (match_dup 0)
7660		   (udiv:SI (match_dup 1) (match_dup 2)))
7661	      (set (match_dup 3)
7662		   (umod:SI (match_dup 1) (match_dup 2)))
7663	      (use (match_dup 3))
7664	      (clobber (reg:CC FLAGS_REG))])]
7665  "")
7666
7667(define_expand "udivmodhi4"
7668  [(set (match_dup 4) (const_int 0))
7669   (parallel [(set (match_operand:HI 0 "register_operand" "")
7670		   (udiv:HI (match_operand:HI 1 "register_operand" "")
7671		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
7672	      (set (match_operand:HI 3 "register_operand" "")
7673	   	   (umod:HI (match_dup 1) (match_dup 2)))
7674	      (use (match_dup 4))
7675	      (clobber (reg:CC FLAGS_REG))])]
7676  "TARGET_HIMODE_MATH"
7677  "operands[4] = gen_reg_rtx (HImode);")
7678
7679(define_insn "*udivmodhi_noext"
7680  [(set (match_operand:HI 0 "register_operand" "=a")
7681	(udiv:HI (match_operand:HI 1 "register_operand" "0")
7682		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7683   (set (match_operand:HI 3 "register_operand" "=d")
7684	(umod:HI (match_dup 1) (match_dup 2)))
7685   (use (match_operand:HI 4 "register_operand" "3"))
7686   (clobber (reg:CC FLAGS_REG))]
7687  ""
7688  "div{w}\t%2"
7689  [(set_attr "type" "idiv")
7690   (set_attr "mode" "HI")])
7691
7692;; We cannot use div/idiv for double division, because it causes
7693;; "division by zero" on the overflow and that's not what we expect
7694;; from truncate.  Because true (non truncating) double division is
7695;; never generated, we can't create this insn anyway.
7696;
7697;(define_insn ""
7698;  [(set (match_operand:SI 0 "register_operand" "=a")
7699;	(truncate:SI
7700;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7701;		   (zero_extend:DI
7702;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7703;   (set (match_operand:SI 3 "register_operand" "=d")
7704;	(truncate:SI
7705;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7706;   (clobber (reg:CC FLAGS_REG))]
7707;  ""
7708;  "div{l}\t{%2, %0|%0, %2}"
7709;  [(set_attr "type" "idiv")])
7710
7711;;- Logical AND instructions
7712
7713;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7714;; Note that this excludes ah.
7715
7716(define_insn "*testdi_1_rex64"
7717  [(set (reg FLAGS_REG)
7718	(compare
7719	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7720		  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7721	  (const_int 0)))]
7722  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7723   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7724  "@
7725   test{l}\t{%k1, %k0|%k0, %k1}
7726   test{l}\t{%k1, %k0|%k0, %k1}
7727   test{q}\t{%1, %0|%0, %1}
7728   test{q}\t{%1, %0|%0, %1}
7729   test{q}\t{%1, %0|%0, %1}"
7730  [(set_attr "type" "test")
7731   (set_attr "modrm" "0,1,0,1,1")
7732   (set_attr "mode" "SI,SI,DI,DI,DI")
7733   (set_attr "pent_pair" "uv,np,uv,np,uv")])
7734
7735(define_insn "testsi_1"
7736  [(set (reg FLAGS_REG)
7737	(compare
7738	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7739		  (match_operand:SI 1 "general_operand" "in,in,rin"))
7740	  (const_int 0)))]
7741  "ix86_match_ccmode (insn, CCNOmode)
7742   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7743  "test{l}\t{%1, %0|%0, %1}"
7744  [(set_attr "type" "test")
7745   (set_attr "modrm" "0,1,1")
7746   (set_attr "mode" "SI")
7747   (set_attr "pent_pair" "uv,np,uv")])
7748
7749(define_expand "testsi_ccno_1"
7750  [(set (reg:CCNO FLAGS_REG)
7751	(compare:CCNO
7752	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7753		  (match_operand:SI 1 "nonmemory_operand" ""))
7754	  (const_int 0)))]
7755  ""
7756  "")
7757
7758(define_insn "*testhi_1"
7759  [(set (reg FLAGS_REG)
7760        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7761			 (match_operand:HI 1 "general_operand" "n,n,rn"))
7762		 (const_int 0)))]
7763  "ix86_match_ccmode (insn, CCNOmode)
7764   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7765  "test{w}\t{%1, %0|%0, %1}"
7766  [(set_attr "type" "test")
7767   (set_attr "modrm" "0,1,1")
7768   (set_attr "mode" "HI")
7769   (set_attr "pent_pair" "uv,np,uv")])
7770
7771(define_expand "testqi_ccz_1"
7772  [(set (reg:CCZ FLAGS_REG)
7773        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7774			     (match_operand:QI 1 "nonmemory_operand" ""))
7775		 (const_int 0)))]
7776  ""
7777  "")
7778
7779(define_insn "*testqi_1_maybe_si"
7780  [(set (reg FLAGS_REG)
7781        (compare
7782	  (and:QI
7783	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7784	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7785	  (const_int 0)))]
7786   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7787    && ix86_match_ccmode (insn,
7788 			 GET_CODE (operands[1]) == CONST_INT
7789 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7790{
7791  if (which_alternative == 3)
7792    {
7793      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7794	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7795      return "test{l}\t{%1, %k0|%k0, %1}";
7796    }
7797  return "test{b}\t{%1, %0|%0, %1}";
7798}
7799  [(set_attr "type" "test")
7800   (set_attr "modrm" "0,1,1,1")
7801   (set_attr "mode" "QI,QI,QI,SI")
7802   (set_attr "pent_pair" "uv,np,uv,np")])
7803
7804(define_insn "*testqi_1"
7805  [(set (reg FLAGS_REG)
7806        (compare
7807	  (and:QI
7808	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7809	    (match_operand:QI 1 "general_operand" "n,n,qn"))
7810	  (const_int 0)))]
7811  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7812   && ix86_match_ccmode (insn, CCNOmode)"
7813  "test{b}\t{%1, %0|%0, %1}"
7814  [(set_attr "type" "test")
7815   (set_attr "modrm" "0,1,1")
7816   (set_attr "mode" "QI")
7817   (set_attr "pent_pair" "uv,np,uv")])
7818
7819(define_expand "testqi_ext_ccno_0"
7820  [(set (reg:CCNO FLAGS_REG)
7821	(compare:CCNO
7822	  (and:SI
7823	    (zero_extract:SI
7824	      (match_operand 0 "ext_register_operand" "")
7825	      (const_int 8)
7826	      (const_int 8))
7827	    (match_operand 1 "const_int_operand" ""))
7828	  (const_int 0)))]
7829  ""
7830  "")
7831
7832(define_insn "*testqi_ext_0"
7833  [(set (reg FLAGS_REG)
7834	(compare
7835	  (and:SI
7836	    (zero_extract:SI
7837	      (match_operand 0 "ext_register_operand" "Q")
7838	      (const_int 8)
7839	      (const_int 8))
7840	    (match_operand 1 "const_int_operand" "n"))
7841	  (const_int 0)))]
7842  "ix86_match_ccmode (insn, CCNOmode)"
7843  "test{b}\t{%1, %h0|%h0, %1}"
7844  [(set_attr "type" "test")
7845   (set_attr "mode" "QI")
7846   (set_attr "length_immediate" "1")
7847   (set_attr "pent_pair" "np")])
7848
7849(define_insn "*testqi_ext_1"
7850  [(set (reg FLAGS_REG)
7851	(compare
7852	  (and:SI
7853	    (zero_extract:SI
7854	      (match_operand 0 "ext_register_operand" "Q")
7855	      (const_int 8)
7856	      (const_int 8))
7857	    (zero_extend:SI
7858	      (match_operand:QI 1 "general_operand" "Qm")))
7859	  (const_int 0)))]
7860  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7861   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7862  "test{b}\t{%1, %h0|%h0, %1}"
7863  [(set_attr "type" "test")
7864   (set_attr "mode" "QI")])
7865
7866(define_insn "*testqi_ext_1_rex64"
7867  [(set (reg FLAGS_REG)
7868	(compare
7869	  (and:SI
7870	    (zero_extract:SI
7871	      (match_operand 0 "ext_register_operand" "Q")
7872	      (const_int 8)
7873	      (const_int 8))
7874	    (zero_extend:SI
7875	      (match_operand:QI 1 "register_operand" "Q")))
7876	  (const_int 0)))]
7877  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7878  "test{b}\t{%1, %h0|%h0, %1}"
7879  [(set_attr "type" "test")
7880   (set_attr "mode" "QI")])
7881
7882(define_insn "*testqi_ext_2"
7883  [(set (reg FLAGS_REG)
7884	(compare
7885	  (and:SI
7886	    (zero_extract:SI
7887	      (match_operand 0 "ext_register_operand" "Q")
7888	      (const_int 8)
7889	      (const_int 8))
7890	    (zero_extract:SI
7891	      (match_operand 1 "ext_register_operand" "Q")
7892	      (const_int 8)
7893	      (const_int 8)))
7894	  (const_int 0)))]
7895  "ix86_match_ccmode (insn, CCNOmode)"
7896  "test{b}\t{%h1, %h0|%h0, %h1}"
7897  [(set_attr "type" "test")
7898   (set_attr "mode" "QI")])
7899
7900;; Combine likes to form bit extractions for some tests.  Humor it.
7901(define_insn "*testqi_ext_3"
7902  [(set (reg FLAGS_REG)
7903        (compare (zero_extract:SI
7904		   (match_operand 0 "nonimmediate_operand" "rm")
7905		   (match_operand:SI 1 "const_int_operand" "")
7906		   (match_operand:SI 2 "const_int_operand" ""))
7907		 (const_int 0)))]
7908  "ix86_match_ccmode (insn, CCNOmode)
7909   && INTVAL (operands[1]) > 0
7910   && INTVAL (operands[2]) >= 0
7911   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7912   && (GET_MODE (operands[0]) == SImode
7913       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7914       || GET_MODE (operands[0]) == HImode
7915       || GET_MODE (operands[0]) == QImode)"
7916  "#")
7917
7918(define_insn "*testqi_ext_3_rex64"
7919  [(set (reg FLAGS_REG)
7920        (compare (zero_extract:DI
7921		   (match_operand 0 "nonimmediate_operand" "rm")
7922		   (match_operand:DI 1 "const_int_operand" "")
7923		   (match_operand:DI 2 "const_int_operand" ""))
7924		 (const_int 0)))]
7925  "TARGET_64BIT
7926   && ix86_match_ccmode (insn, CCNOmode)
7927   && INTVAL (operands[1]) > 0
7928   && INTVAL (operands[2]) >= 0
7929   /* Ensure that resulting mask is zero or sign extended operand.  */
7930   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7931       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7932	   && INTVAL (operands[1]) > 32))
7933   && (GET_MODE (operands[0]) == SImode
7934       || GET_MODE (operands[0]) == DImode
7935       || GET_MODE (operands[0]) == HImode
7936       || GET_MODE (operands[0]) == QImode)"
7937  "#")
7938
7939(define_split
7940  [(set (match_operand 0 "flags_reg_operand" "")
7941        (match_operator 1 "compare_operator"
7942	  [(zero_extract
7943	     (match_operand 2 "nonimmediate_operand" "")
7944	     (match_operand 3 "const_int_operand" "")
7945	     (match_operand 4 "const_int_operand" ""))
7946	   (const_int 0)]))]
7947  "ix86_match_ccmode (insn, CCNOmode)"
7948  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7949{
7950  rtx val = operands[2];
7951  HOST_WIDE_INT len = INTVAL (operands[3]);
7952  HOST_WIDE_INT pos = INTVAL (operands[4]);
7953  HOST_WIDE_INT mask;
7954  enum machine_mode mode, submode;
7955
7956  mode = GET_MODE (val);
7957  if (GET_CODE (val) == MEM)
7958    {
7959      /* ??? Combine likes to put non-volatile mem extractions in QImode
7960	 no matter the size of the test.  So find a mode that works.  */
7961      if (! MEM_VOLATILE_P (val))
7962	{
7963	  mode = smallest_mode_for_size (pos + len, MODE_INT);
7964	  val = adjust_address (val, mode, 0);
7965	}
7966    }
7967  else if (GET_CODE (val) == SUBREG
7968	   && (submode = GET_MODE (SUBREG_REG (val)),
7969	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7970	   && pos + len <= GET_MODE_BITSIZE (submode))
7971    {
7972      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7973      mode = submode;
7974      val = SUBREG_REG (val);
7975    }
7976  else if (mode == HImode && pos + len <= 8)
7977    {
7978      /* Small HImode tests can be converted to QImode.  */
7979      mode = QImode;
7980      val = gen_lowpart (QImode, val);
7981    }
7982
7983  if (len == HOST_BITS_PER_WIDE_INT)
7984    mask = -1;
7985  else
7986    mask = ((HOST_WIDE_INT)1 << len) - 1;
7987  mask <<= pos;
7988
7989  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7990})
7991
7992;; Convert HImode/SImode test instructions with immediate to QImode ones.
7993;; i386 does not allow to encode test with 8bit sign extended immediate, so
7994;; this is relatively important trick.
7995;; Do the conversion only post-reload to avoid limiting of the register class
7996;; to QI regs.
7997(define_split
7998  [(set (match_operand 0 "flags_reg_operand" "")
7999	(match_operator 1 "compare_operator"
8000	  [(and (match_operand 2 "register_operand" "")
8001	        (match_operand 3 "const_int_operand" ""))
8002	   (const_int 0)]))]
8003   "reload_completed
8004    && QI_REG_P (operands[2])
8005    && GET_MODE (operands[2]) != QImode
8006    && ((ix86_match_ccmode (insn, CCZmode)
8007    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
8008	|| (ix86_match_ccmode (insn, CCNOmode)
8009	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
8010  [(set (match_dup 0)
8011	(match_op_dup 1
8012	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8013		   (match_dup 3))
8014	   (const_int 0)]))]
8015  "operands[2] = gen_lowpart (SImode, operands[2]);
8016   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8017
8018(define_split
8019  [(set (match_operand 0 "flags_reg_operand" "")
8020	(match_operator 1 "compare_operator"
8021	  [(and (match_operand 2 "nonimmediate_operand" "")
8022	        (match_operand 3 "const_int_operand" ""))
8023	   (const_int 0)]))]
8024   "reload_completed
8025    && GET_MODE (operands[2]) != QImode
8026    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8027    && ((ix86_match_ccmode (insn, CCZmode)
8028	 && !(INTVAL (operands[3]) & ~255))
8029	|| (ix86_match_ccmode (insn, CCNOmode)
8030	    && !(INTVAL (operands[3]) & ~127)))"
8031  [(set (match_dup 0)
8032	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8033			 (const_int 0)]))]
8034  "operands[2] = gen_lowpart (QImode, operands[2]);
8035   operands[3] = gen_lowpart (QImode, operands[3]);")
8036
8037
8038;; %%% This used to optimize known byte-wide and operations to memory,
8039;; and sometimes to QImode registers.  If this is considered useful,
8040;; it should be done with splitters.
8041
8042(define_expand "anddi3"
8043  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8044	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8045		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
8046   (clobber (reg:CC FLAGS_REG))]
8047  "TARGET_64BIT"
8048  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8049
8050(define_insn "*anddi_1_rex64"
8051  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8052	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8053		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8054   (clobber (reg:CC FLAGS_REG))]
8055  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8056{
8057  switch (get_attr_type (insn))
8058    {
8059    case TYPE_IMOVX:
8060      {
8061	enum machine_mode mode;
8062
8063	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8064        if (INTVAL (operands[2]) == 0xff)
8065	  mode = QImode;
8066	else
8067	  {
8068	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8069	    mode = HImode;
8070	  }
8071	
8072	operands[1] = gen_lowpart (mode, operands[1]);
8073	if (mode == QImode)
8074	  return "movz{bq|x}\t{%1,%0|%0, %1}";
8075	else
8076	  return "movz{wq|x}\t{%1,%0|%0, %1}";
8077      }
8078
8079    default:
8080      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8081      if (get_attr_mode (insn) == MODE_SI)
8082	return "and{l}\t{%k2, %k0|%k0, %k2}";
8083      else
8084	return "and{q}\t{%2, %0|%0, %2}";
8085    }
8086}
8087  [(set_attr "type" "alu,alu,alu,imovx")
8088   (set_attr "length_immediate" "*,*,*,0")
8089   (set_attr "mode" "SI,DI,DI,DI")])
8090
8091(define_insn "*anddi_2"
8092  [(set (reg FLAGS_REG)
8093	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8094			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8095		 (const_int 0)))
8096   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8097	(and:DI (match_dup 1) (match_dup 2)))]
8098  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8099   && ix86_binary_operator_ok (AND, DImode, operands)"
8100  "@
8101   and{l}\t{%k2, %k0|%k0, %k2}
8102   and{q}\t{%2, %0|%0, %2}
8103   and{q}\t{%2, %0|%0, %2}"
8104  [(set_attr "type" "alu")
8105   (set_attr "mode" "SI,DI,DI")])
8106
8107(define_expand "andsi3"
8108  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8109	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8110		(match_operand:SI 2 "general_operand" "")))
8111   (clobber (reg:CC FLAGS_REG))]
8112  ""
8113  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8114
8115(define_insn "*andsi_1"
8116  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8117	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8118		(match_operand:SI 2 "general_operand" "ri,rm,L")))
8119   (clobber (reg:CC FLAGS_REG))]
8120  "ix86_binary_operator_ok (AND, SImode, operands)"
8121{
8122  switch (get_attr_type (insn))
8123    {
8124    case TYPE_IMOVX:
8125      {
8126	enum machine_mode mode;
8127
8128	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8129        if (INTVAL (operands[2]) == 0xff)
8130	  mode = QImode;
8131	else
8132	  {
8133	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8134	    mode = HImode;
8135	  }
8136	
8137	operands[1] = gen_lowpart (mode, operands[1]);
8138	if (mode == QImode)
8139	  return "movz{bl|x}\t{%1,%0|%0, %1}";
8140	else
8141	  return "movz{wl|x}\t{%1,%0|%0, %1}";
8142      }
8143
8144    default:
8145      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8146      return "and{l}\t{%2, %0|%0, %2}";
8147    }
8148}
8149  [(set_attr "type" "alu,alu,imovx")
8150   (set_attr "length_immediate" "*,*,0")
8151   (set_attr "mode" "SI")])
8152
8153(define_split
8154  [(set (match_operand 0 "register_operand" "")
8155	(and (match_dup 0)
8156	     (const_int -65536)))
8157   (clobber (reg:CC FLAGS_REG))]
8158  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8159  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8160  "operands[1] = gen_lowpart (HImode, operands[0]);")
8161
8162(define_split
8163  [(set (match_operand 0 "ext_register_operand" "")
8164	(and (match_dup 0)
8165	     (const_int -256)))
8166   (clobber (reg:CC FLAGS_REG))]
8167  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8168  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8169  "operands[1] = gen_lowpart (QImode, operands[0]);")
8170
8171(define_split
8172  [(set (match_operand 0 "ext_register_operand" "")
8173	(and (match_dup 0)
8174	     (const_int -65281)))
8175   (clobber (reg:CC FLAGS_REG))]
8176  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8177  [(parallel [(set (zero_extract:SI (match_dup 0)
8178				    (const_int 8)
8179				    (const_int 8))
8180		   (xor:SI 
8181		     (zero_extract:SI (match_dup 0)
8182				      (const_int 8)
8183				      (const_int 8))
8184		     (zero_extract:SI (match_dup 0)
8185				      (const_int 8)
8186				      (const_int 8))))
8187	      (clobber (reg:CC FLAGS_REG))])]
8188  "operands[0] = gen_lowpart (SImode, operands[0]);")
8189
8190;; See comment for addsi_1_zext why we do use nonimmediate_operand
8191(define_insn "*andsi_1_zext"
8192  [(set (match_operand:DI 0 "register_operand" "=r")
8193	(zero_extend:DI
8194	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8195		  (match_operand:SI 2 "general_operand" "rim"))))
8196   (clobber (reg:CC FLAGS_REG))]
8197  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8198  "and{l}\t{%2, %k0|%k0, %2}"
8199  [(set_attr "type" "alu")
8200   (set_attr "mode" "SI")])
8201
8202(define_insn "*andsi_2"
8203  [(set (reg FLAGS_REG)
8204	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8205			 (match_operand:SI 2 "general_operand" "rim,ri"))
8206		 (const_int 0)))
8207   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8208	(and:SI (match_dup 1) (match_dup 2)))]
8209  "ix86_match_ccmode (insn, CCNOmode)
8210   && ix86_binary_operator_ok (AND, SImode, operands)"
8211  "and{l}\t{%2, %0|%0, %2}"
8212  [(set_attr "type" "alu")
8213   (set_attr "mode" "SI")])
8214
8215;; See comment for addsi_1_zext why we do use nonimmediate_operand
8216(define_insn "*andsi_2_zext"
8217  [(set (reg FLAGS_REG)
8218	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8219			 (match_operand:SI 2 "general_operand" "rim"))
8220		 (const_int 0)))
8221   (set (match_operand:DI 0 "register_operand" "=r")
8222	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8223  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8224   && ix86_binary_operator_ok (AND, SImode, operands)"
8225  "and{l}\t{%2, %k0|%k0, %2}"
8226  [(set_attr "type" "alu")
8227   (set_attr "mode" "SI")])
8228
8229(define_expand "andhi3"
8230  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8231	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8232		(match_operand:HI 2 "general_operand" "")))
8233   (clobber (reg:CC FLAGS_REG))]
8234  "TARGET_HIMODE_MATH"
8235  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8236
8237(define_insn "*andhi_1"
8238  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8239	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8240		(match_operand:HI 2 "general_operand" "ri,rm,L")))
8241   (clobber (reg:CC FLAGS_REG))]
8242  "ix86_binary_operator_ok (AND, HImode, operands)"
8243{
8244  switch (get_attr_type (insn))
8245    {
8246    case TYPE_IMOVX:
8247      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8248      gcc_assert (INTVAL (operands[2]) == 0xff);
8249      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8250
8251    default:
8252      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8253
8254      return "and{w}\t{%2, %0|%0, %2}";
8255    }
8256}
8257  [(set_attr "type" "alu,alu,imovx")
8258   (set_attr "length_immediate" "*,*,0")
8259   (set_attr "mode" "HI,HI,SI")])
8260
8261(define_insn "*andhi_2"
8262  [(set (reg FLAGS_REG)
8263	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8264			 (match_operand:HI 2 "general_operand" "rim,ri"))
8265		 (const_int 0)))
8266   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8267	(and:HI (match_dup 1) (match_dup 2)))]
8268  "ix86_match_ccmode (insn, CCNOmode)
8269   && ix86_binary_operator_ok (AND, HImode, operands)"
8270  "and{w}\t{%2, %0|%0, %2}"
8271  [(set_attr "type" "alu")
8272   (set_attr "mode" "HI")])
8273
8274(define_expand "andqi3"
8275  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8276	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8277		(match_operand:QI 2 "general_operand" "")))
8278   (clobber (reg:CC FLAGS_REG))]
8279  "TARGET_QIMODE_MATH"
8280  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8281
8282;; %%% Potential partial reg stall on alternative 2.  What to do?
8283(define_insn "*andqi_1"
8284  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8285	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8286		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8287   (clobber (reg:CC FLAGS_REG))]
8288  "ix86_binary_operator_ok (AND, QImode, operands)"
8289  "@
8290   and{b}\t{%2, %0|%0, %2}
8291   and{b}\t{%2, %0|%0, %2}
8292   and{l}\t{%k2, %k0|%k0, %k2}"
8293  [(set_attr "type" "alu")
8294   (set_attr "mode" "QI,QI,SI")])
8295
8296(define_insn "*andqi_1_slp"
8297  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8298	(and:QI (match_dup 0)
8299		(match_operand:QI 1 "general_operand" "qi,qmi")))
8300   (clobber (reg:CC FLAGS_REG))]
8301  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8302   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8303  "and{b}\t{%1, %0|%0, %1}"
8304  [(set_attr "type" "alu1")
8305   (set_attr "mode" "QI")])
8306
8307(define_insn "*andqi_2_maybe_si"
8308  [(set (reg FLAGS_REG)
8309	(compare (and:QI
8310		      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8311		      (match_operand:QI 2 "general_operand" "qim,qi,i"))
8312		 (const_int 0)))
8313   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8314	(and:QI (match_dup 1) (match_dup 2)))]
8315  "ix86_binary_operator_ok (AND, QImode, operands)
8316   && ix86_match_ccmode (insn,
8317			 GET_CODE (operands[2]) == CONST_INT
8318			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8319{
8320  if (which_alternative == 2)
8321    {
8322      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8323        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8324      return "and{l}\t{%2, %k0|%k0, %2}";
8325    }
8326  return "and{b}\t{%2, %0|%0, %2}";
8327}
8328  [(set_attr "type" "alu")
8329   (set_attr "mode" "QI,QI,SI")])
8330
8331(define_insn "*andqi_2"
8332  [(set (reg FLAGS_REG)
8333	(compare (and:QI
8334		   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8335		   (match_operand:QI 2 "general_operand" "qim,qi"))
8336		 (const_int 0)))
8337   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8338	(and:QI (match_dup 1) (match_dup 2)))]
8339  "ix86_match_ccmode (insn, CCNOmode)
8340   && ix86_binary_operator_ok (AND, QImode, operands)"
8341  "and{b}\t{%2, %0|%0, %2}"
8342  [(set_attr "type" "alu")
8343   (set_attr "mode" "QI")])
8344
8345(define_insn "*andqi_2_slp"
8346  [(set (reg FLAGS_REG)
8347	(compare (and:QI
8348		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8349		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8350		 (const_int 0)))
8351   (set (strict_low_part (match_dup 0))
8352	(and:QI (match_dup 0) (match_dup 1)))]
8353  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8354   && ix86_match_ccmode (insn, CCNOmode)
8355   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8356  "and{b}\t{%1, %0|%0, %1}"
8357  [(set_attr "type" "alu1")
8358   (set_attr "mode" "QI")])
8359
8360;; ??? A bug in recog prevents it from recognizing a const_int as an
8361;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8362;; for a QImode operand, which of course failed.
8363
8364(define_insn "andqi_ext_0"
8365  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366			 (const_int 8)
8367			 (const_int 8))
8368	(and:SI 
8369	  (zero_extract:SI
8370	    (match_operand 1 "ext_register_operand" "0")
8371	    (const_int 8)
8372	    (const_int 8))
8373	  (match_operand 2 "const_int_operand" "n")))
8374   (clobber (reg:CC FLAGS_REG))]
8375  ""
8376  "and{b}\t{%2, %h0|%h0, %2}"
8377  [(set_attr "type" "alu")
8378   (set_attr "length_immediate" "1")
8379   (set_attr "mode" "QI")])
8380
8381;; Generated by peephole translating test to and.  This shows up
8382;; often in fp comparisons.
8383
8384(define_insn "*andqi_ext_0_cc"
8385  [(set (reg FLAGS_REG)
8386	(compare
8387	  (and:SI
8388	    (zero_extract:SI
8389	      (match_operand 1 "ext_register_operand" "0")
8390	      (const_int 8)
8391	      (const_int 8))
8392	    (match_operand 2 "const_int_operand" "n"))
8393	  (const_int 0)))
8394   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8395			 (const_int 8)
8396			 (const_int 8))
8397	(and:SI 
8398	  (zero_extract:SI
8399	    (match_dup 1)
8400	    (const_int 8)
8401	    (const_int 8))
8402	  (match_dup 2)))]
8403  "ix86_match_ccmode (insn, CCNOmode)"
8404  "and{b}\t{%2, %h0|%h0, %2}"
8405  [(set_attr "type" "alu")
8406   (set_attr "length_immediate" "1")
8407   (set_attr "mode" "QI")])
8408
8409(define_insn "*andqi_ext_1"
8410  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8411			 (const_int 8)
8412			 (const_int 8))
8413	(and:SI 
8414	  (zero_extract:SI
8415	    (match_operand 1 "ext_register_operand" "0")
8416	    (const_int 8)
8417	    (const_int 8))
8418	  (zero_extend:SI
8419	    (match_operand:QI 2 "general_operand" "Qm"))))
8420   (clobber (reg:CC FLAGS_REG))]
8421  "!TARGET_64BIT"
8422  "and{b}\t{%2, %h0|%h0, %2}"
8423  [(set_attr "type" "alu")
8424   (set_attr "length_immediate" "0")
8425   (set_attr "mode" "QI")])
8426
8427(define_insn "*andqi_ext_1_rex64"
8428  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8429			 (const_int 8)
8430			 (const_int 8))
8431	(and:SI 
8432	  (zero_extract:SI
8433	    (match_operand 1 "ext_register_operand" "0")
8434	    (const_int 8)
8435	    (const_int 8))
8436	  (zero_extend:SI
8437	    (match_operand 2 "ext_register_operand" "Q"))))
8438   (clobber (reg:CC FLAGS_REG))]
8439  "TARGET_64BIT"
8440  "and{b}\t{%2, %h0|%h0, %2}"
8441  [(set_attr "type" "alu")
8442   (set_attr "length_immediate" "0")
8443   (set_attr "mode" "QI")])
8444
8445(define_insn "*andqi_ext_2"
8446  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8447			 (const_int 8)
8448			 (const_int 8))
8449	(and:SI
8450	  (zero_extract:SI
8451	    (match_operand 1 "ext_register_operand" "%0")
8452	    (const_int 8)
8453	    (const_int 8))
8454	  (zero_extract:SI
8455	    (match_operand 2 "ext_register_operand" "Q")
8456	    (const_int 8)
8457	    (const_int 8))))
8458   (clobber (reg:CC FLAGS_REG))]
8459  ""
8460  "and{b}\t{%h2, %h0|%h0, %h2}"
8461  [(set_attr "type" "alu")
8462   (set_attr "length_immediate" "0")
8463   (set_attr "mode" "QI")])
8464
8465;; Convert wide AND instructions with immediate operand to shorter QImode
8466;; equivalents when possible.
8467;; Don't do the splitting with memory operands, since it introduces risk
8468;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8469;; for size, but that can (should?) be handled by generic code instead.
8470(define_split
8471  [(set (match_operand 0 "register_operand" "")
8472	(and (match_operand 1 "register_operand" "")
8473	     (match_operand 2 "const_int_operand" "")))
8474   (clobber (reg:CC FLAGS_REG))]
8475   "reload_completed
8476    && QI_REG_P (operands[0])
8477    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8478    && !(~INTVAL (operands[2]) & ~(255 << 8))
8479    && GET_MODE (operands[0]) != QImode"
8480  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8481		   (and:SI (zero_extract:SI (match_dup 1)
8482					    (const_int 8) (const_int 8))
8483			   (match_dup 2)))
8484	      (clobber (reg:CC FLAGS_REG))])]
8485  "operands[0] = gen_lowpart (SImode, operands[0]);
8486   operands[1] = gen_lowpart (SImode, operands[1]);
8487   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8488
8489;; Since AND can be encoded with sign extended immediate, this is only
8490;; profitable when 7th bit is not set.
8491(define_split
8492  [(set (match_operand 0 "register_operand" "")
8493	(and (match_operand 1 "general_operand" "")
8494	     (match_operand 2 "const_int_operand" "")))
8495   (clobber (reg:CC FLAGS_REG))]
8496   "reload_completed
8497    && ANY_QI_REG_P (operands[0])
8498    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8499    && !(~INTVAL (operands[2]) & ~255)
8500    && !(INTVAL (operands[2]) & 128)
8501    && GET_MODE (operands[0]) != QImode"
8502  [(parallel [(set (strict_low_part (match_dup 0))
8503		   (and:QI (match_dup 1)
8504			   (match_dup 2)))
8505	      (clobber (reg:CC FLAGS_REG))])]
8506  "operands[0] = gen_lowpart (QImode, operands[0]);
8507   operands[1] = gen_lowpart (QImode, operands[1]);
8508   operands[2] = gen_lowpart (QImode, operands[2]);")
8509
8510;; Logical inclusive OR instructions
8511
8512;; %%% This used to optimize known byte-wide and operations to memory.
8513;; If this is considered useful, it should be done with splitters.
8514
8515(define_expand "iordi3"
8516  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8517	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8518		(match_operand:DI 2 "x86_64_general_operand" "")))
8519   (clobber (reg:CC FLAGS_REG))]
8520  "TARGET_64BIT"
8521  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8522
8523(define_insn "*iordi_1_rex64"
8524  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8525	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8526		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8527   (clobber (reg:CC FLAGS_REG))]
8528  "TARGET_64BIT
8529   && ix86_binary_operator_ok (IOR, DImode, operands)"
8530  "or{q}\t{%2, %0|%0, %2}"
8531  [(set_attr "type" "alu")
8532   (set_attr "mode" "DI")])
8533
8534(define_insn "*iordi_2_rex64"
8535  [(set (reg FLAGS_REG)
8536	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8537			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8538		 (const_int 0)))
8539   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8540	(ior:DI (match_dup 1) (match_dup 2)))]
8541  "TARGET_64BIT
8542   && ix86_match_ccmode (insn, CCNOmode)
8543   && ix86_binary_operator_ok (IOR, DImode, operands)"
8544  "or{q}\t{%2, %0|%0, %2}"
8545  [(set_attr "type" "alu")
8546   (set_attr "mode" "DI")])
8547
8548(define_insn "*iordi_3_rex64"
8549  [(set (reg FLAGS_REG)
8550	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8551			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8552		 (const_int 0)))
8553   (clobber (match_scratch:DI 0 "=r"))]
8554  "TARGET_64BIT
8555   && ix86_match_ccmode (insn, CCNOmode)
8556   && ix86_binary_operator_ok (IOR, DImode, operands)"
8557  "or{q}\t{%2, %0|%0, %2}"
8558  [(set_attr "type" "alu")
8559   (set_attr "mode" "DI")])
8560
8561
8562(define_expand "iorsi3"
8563  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8564	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8565		(match_operand:SI 2 "general_operand" "")))
8566   (clobber (reg:CC FLAGS_REG))]
8567  ""
8568  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8569
8570(define_insn "*iorsi_1"
8571  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8572	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8573		(match_operand:SI 2 "general_operand" "ri,rmi")))
8574   (clobber (reg:CC FLAGS_REG))]
8575  "ix86_binary_operator_ok (IOR, SImode, operands)"
8576  "or{l}\t{%2, %0|%0, %2}"
8577  [(set_attr "type" "alu")
8578   (set_attr "mode" "SI")])
8579
8580;; See comment for addsi_1_zext why we do use nonimmediate_operand
8581(define_insn "*iorsi_1_zext"
8582  [(set (match_operand:DI 0 "register_operand" "=rm")
8583	(zero_extend:DI
8584	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585		  (match_operand:SI 2 "general_operand" "rim"))))
8586   (clobber (reg:CC FLAGS_REG))]
8587  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8588  "or{l}\t{%2, %k0|%k0, %2}"
8589  [(set_attr "type" "alu")
8590   (set_attr "mode" "SI")])
8591
8592(define_insn "*iorsi_1_zext_imm"
8593  [(set (match_operand:DI 0 "register_operand" "=rm")
8594	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8595		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8596   (clobber (reg:CC FLAGS_REG))]
8597  "TARGET_64BIT"
8598  "or{l}\t{%2, %k0|%k0, %2}"
8599  [(set_attr "type" "alu")
8600   (set_attr "mode" "SI")])
8601
8602(define_insn "*iorsi_2"
8603  [(set (reg FLAGS_REG)
8604	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8605			 (match_operand:SI 2 "general_operand" "rim,ri"))
8606		 (const_int 0)))
8607   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8608	(ior:SI (match_dup 1) (match_dup 2)))]
8609  "ix86_match_ccmode (insn, CCNOmode)
8610   && ix86_binary_operator_ok (IOR, SImode, operands)"
8611  "or{l}\t{%2, %0|%0, %2}"
8612  [(set_attr "type" "alu")
8613   (set_attr "mode" "SI")])
8614
8615;; See comment for addsi_1_zext why we do use nonimmediate_operand
8616;; ??? Special case for immediate operand is missing - it is tricky.
8617(define_insn "*iorsi_2_zext"
8618  [(set (reg FLAGS_REG)
8619	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8620			 (match_operand:SI 2 "general_operand" "rim"))
8621		 (const_int 0)))
8622   (set (match_operand:DI 0 "register_operand" "=r")
8623	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8624  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8625   && ix86_binary_operator_ok (IOR, SImode, operands)"
8626  "or{l}\t{%2, %k0|%k0, %2}"
8627  [(set_attr "type" "alu")
8628   (set_attr "mode" "SI")])
8629
8630(define_insn "*iorsi_2_zext_imm"
8631  [(set (reg FLAGS_REG)
8632	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8633			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8634		 (const_int 0)))
8635   (set (match_operand:DI 0 "register_operand" "=r")
8636	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8637  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8638   && ix86_binary_operator_ok (IOR, SImode, operands)"
8639  "or{l}\t{%2, %k0|%k0, %2}"
8640  [(set_attr "type" "alu")
8641   (set_attr "mode" "SI")])
8642
8643(define_insn "*iorsi_3"
8644  [(set (reg FLAGS_REG)
8645	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8646			 (match_operand:SI 2 "general_operand" "rim"))
8647		 (const_int 0)))
8648   (clobber (match_scratch:SI 0 "=r"))]
8649  "ix86_match_ccmode (insn, CCNOmode)
8650   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8651  "or{l}\t{%2, %0|%0, %2}"
8652  [(set_attr "type" "alu")
8653   (set_attr "mode" "SI")])
8654
8655(define_expand "iorhi3"
8656  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8657	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8658		(match_operand:HI 2 "general_operand" "")))
8659   (clobber (reg:CC FLAGS_REG))]
8660  "TARGET_HIMODE_MATH"
8661  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8662
8663(define_insn "*iorhi_1"
8664  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8665	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8666		(match_operand:HI 2 "general_operand" "rmi,ri")))
8667   (clobber (reg:CC FLAGS_REG))]
8668  "ix86_binary_operator_ok (IOR, HImode, operands)"
8669  "or{w}\t{%2, %0|%0, %2}"
8670  [(set_attr "type" "alu")
8671   (set_attr "mode" "HI")])
8672
8673(define_insn "*iorhi_2"
8674  [(set (reg FLAGS_REG)
8675	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8676			 (match_operand:HI 2 "general_operand" "rim,ri"))
8677		 (const_int 0)))
8678   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8679	(ior:HI (match_dup 1) (match_dup 2)))]
8680  "ix86_match_ccmode (insn, CCNOmode)
8681   && ix86_binary_operator_ok (IOR, HImode, operands)"
8682  "or{w}\t{%2, %0|%0, %2}"
8683  [(set_attr "type" "alu")
8684   (set_attr "mode" "HI")])
8685
8686(define_insn "*iorhi_3"
8687  [(set (reg FLAGS_REG)
8688	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8689			 (match_operand:HI 2 "general_operand" "rim"))
8690		 (const_int 0)))
8691   (clobber (match_scratch:HI 0 "=r"))]
8692  "ix86_match_ccmode (insn, CCNOmode)
8693   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8694  "or{w}\t{%2, %0|%0, %2}"
8695  [(set_attr "type" "alu")
8696   (set_attr "mode" "HI")])
8697
8698(define_expand "iorqi3"
8699  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8700	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8701		(match_operand:QI 2 "general_operand" "")))
8702   (clobber (reg:CC FLAGS_REG))]
8703  "TARGET_QIMODE_MATH"
8704  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8705
8706;; %%% Potential partial reg stall on alternative 2.  What to do?
8707(define_insn "*iorqi_1"
8708  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8709	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8710		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8711   (clobber (reg:CC FLAGS_REG))]
8712  "ix86_binary_operator_ok (IOR, QImode, operands)"
8713  "@
8714   or{b}\t{%2, %0|%0, %2}
8715   or{b}\t{%2, %0|%0, %2}
8716   or{l}\t{%k2, %k0|%k0, %k2}"
8717  [(set_attr "type" "alu")
8718   (set_attr "mode" "QI,QI,SI")])
8719
8720(define_insn "*iorqi_1_slp"
8721  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8722	(ior:QI (match_dup 0)
8723		(match_operand:QI 1 "general_operand" "qmi,qi")))
8724   (clobber (reg:CC FLAGS_REG))]
8725  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8726   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8727  "or{b}\t{%1, %0|%0, %1}"
8728  [(set_attr "type" "alu1")
8729   (set_attr "mode" "QI")])
8730
8731(define_insn "*iorqi_2"
8732  [(set (reg FLAGS_REG)
8733	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8734			 (match_operand:QI 2 "general_operand" "qim,qi"))
8735		 (const_int 0)))
8736   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8737	(ior:QI (match_dup 1) (match_dup 2)))]
8738  "ix86_match_ccmode (insn, CCNOmode)
8739   && ix86_binary_operator_ok (IOR, QImode, operands)"
8740  "or{b}\t{%2, %0|%0, %2}"
8741  [(set_attr "type" "alu")
8742   (set_attr "mode" "QI")])
8743
8744(define_insn "*iorqi_2_slp"
8745  [(set (reg FLAGS_REG)
8746	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8747			 (match_operand:QI 1 "general_operand" "qim,qi"))
8748		 (const_int 0)))
8749   (set (strict_low_part (match_dup 0))
8750	(ior:QI (match_dup 0) (match_dup 1)))]
8751  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8752   && ix86_match_ccmode (insn, CCNOmode)
8753   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8754  "or{b}\t{%1, %0|%0, %1}"
8755  [(set_attr "type" "alu1")
8756   (set_attr "mode" "QI")])
8757
8758(define_insn "*iorqi_3"
8759  [(set (reg FLAGS_REG)
8760	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8761			 (match_operand:QI 2 "general_operand" "qim"))
8762		 (const_int 0)))
8763   (clobber (match_scratch:QI 0 "=q"))]
8764  "ix86_match_ccmode (insn, CCNOmode)
8765   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8766  "or{b}\t{%2, %0|%0, %2}"
8767  [(set_attr "type" "alu")
8768   (set_attr "mode" "QI")])
8769
8770(define_insn "iorqi_ext_0"
8771  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8772			 (const_int 8)
8773			 (const_int 8))
8774	(ior:SI 
8775	  (zero_extract:SI
8776	    (match_operand 1 "ext_register_operand" "0")
8777	    (const_int 8)
8778	    (const_int 8))
8779	  (match_operand 2 "const_int_operand" "n")))
8780   (clobber (reg:CC FLAGS_REG))]
8781  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8782  "or{b}\t{%2, %h0|%h0, %2}"
8783  [(set_attr "type" "alu")
8784   (set_attr "length_immediate" "1")
8785   (set_attr "mode" "QI")])
8786
8787(define_insn "*iorqi_ext_1"
8788  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8789			 (const_int 8)
8790			 (const_int 8))
8791	(ior:SI 
8792	  (zero_extract:SI
8793	    (match_operand 1 "ext_register_operand" "0")
8794	    (const_int 8)
8795	    (const_int 8))
8796	  (zero_extend:SI
8797	    (match_operand:QI 2 "general_operand" "Qm"))))
8798   (clobber (reg:CC FLAGS_REG))]
8799  "!TARGET_64BIT
8800   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8801  "or{b}\t{%2, %h0|%h0, %2}"
8802  [(set_attr "type" "alu")
8803   (set_attr "length_immediate" "0")
8804   (set_attr "mode" "QI")])
8805
8806(define_insn "*iorqi_ext_1_rex64"
8807  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8808			 (const_int 8)
8809			 (const_int 8))
8810	(ior:SI 
8811	  (zero_extract:SI
8812	    (match_operand 1 "ext_register_operand" "0")
8813	    (const_int 8)
8814	    (const_int 8))
8815	  (zero_extend:SI
8816	    (match_operand 2 "ext_register_operand" "Q"))))
8817   (clobber (reg:CC FLAGS_REG))]
8818  "TARGET_64BIT
8819   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8820  "or{b}\t{%2, %h0|%h0, %2}"
8821  [(set_attr "type" "alu")
8822   (set_attr "length_immediate" "0")
8823   (set_attr "mode" "QI")])
8824
8825(define_insn "*iorqi_ext_2"
8826  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8827			 (const_int 8)
8828			 (const_int 8))
8829	(ior:SI 
8830	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8831	  		   (const_int 8)
8832			   (const_int 8))
8833	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8834	  		   (const_int 8)
8835			   (const_int 8))))
8836   (clobber (reg:CC FLAGS_REG))]
8837  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8838  "ior{b}\t{%h2, %h0|%h0, %h2}"
8839  [(set_attr "type" "alu")
8840   (set_attr "length_immediate" "0")
8841   (set_attr "mode" "QI")])
8842
8843(define_split
8844  [(set (match_operand 0 "register_operand" "")
8845	(ior (match_operand 1 "register_operand" "")
8846	     (match_operand 2 "const_int_operand" "")))
8847   (clobber (reg:CC FLAGS_REG))]
8848   "reload_completed
8849    && QI_REG_P (operands[0])
8850    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8851    && !(INTVAL (operands[2]) & ~(255 << 8))
8852    && GET_MODE (operands[0]) != QImode"
8853  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8854		   (ior:SI (zero_extract:SI (match_dup 1)
8855					    (const_int 8) (const_int 8))
8856			   (match_dup 2)))
8857	      (clobber (reg:CC FLAGS_REG))])]
8858  "operands[0] = gen_lowpart (SImode, operands[0]);
8859   operands[1] = gen_lowpart (SImode, operands[1]);
8860   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8861
8862;; Since OR can be encoded with sign extended immediate, this is only
8863;; profitable when 7th bit is set.
8864(define_split
8865  [(set (match_operand 0 "register_operand" "")
8866	(ior (match_operand 1 "general_operand" "")
8867	     (match_operand 2 "const_int_operand" "")))
8868   (clobber (reg:CC FLAGS_REG))]
8869   "reload_completed
8870    && ANY_QI_REG_P (operands[0])
8871    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8872    && !(INTVAL (operands[2]) & ~255)
8873    && (INTVAL (operands[2]) & 128)
8874    && GET_MODE (operands[0]) != QImode"
8875  [(parallel [(set (strict_low_part (match_dup 0))
8876		   (ior:QI (match_dup 1)
8877			   (match_dup 2)))
8878	      (clobber (reg:CC FLAGS_REG))])]
8879  "operands[0] = gen_lowpart (QImode, operands[0]);
8880   operands[1] = gen_lowpart (QImode, operands[1]);
8881   operands[2] = gen_lowpart (QImode, operands[2]);")
8882
8883;; Logical XOR instructions
8884
8885;; %%% This used to optimize known byte-wide and operations to memory.
8886;; If this is considered useful, it should be done with splitters.
8887
8888(define_expand "xordi3"
8889  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8890	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8891		(match_operand:DI 2 "x86_64_general_operand" "")))
8892   (clobber (reg:CC FLAGS_REG))]
8893  "TARGET_64BIT"
8894  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8895
8896(define_insn "*xordi_1_rex64"
8897  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8898	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8899		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8900   (clobber (reg:CC FLAGS_REG))]
8901  "TARGET_64BIT
8902   && ix86_binary_operator_ok (XOR, DImode, operands)"
8903  "@
8904   xor{q}\t{%2, %0|%0, %2}
8905   xor{q}\t{%2, %0|%0, %2}"
8906  [(set_attr "type" "alu")
8907   (set_attr "mode" "DI,DI")])
8908
8909(define_insn "*xordi_2_rex64"
8910  [(set (reg FLAGS_REG)
8911	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8912			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8913		 (const_int 0)))
8914   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8915	(xor:DI (match_dup 1) (match_dup 2)))]
8916  "TARGET_64BIT
8917   && ix86_match_ccmode (insn, CCNOmode)
8918   && ix86_binary_operator_ok (XOR, DImode, operands)"
8919  "@
8920   xor{q}\t{%2, %0|%0, %2}
8921   xor{q}\t{%2, %0|%0, %2}"
8922  [(set_attr "type" "alu")
8923   (set_attr "mode" "DI,DI")])
8924
8925(define_insn "*xordi_3_rex64"
8926  [(set (reg FLAGS_REG)
8927	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8928			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8929		 (const_int 0)))
8930   (clobber (match_scratch:DI 0 "=r"))]
8931  "TARGET_64BIT
8932   && ix86_match_ccmode (insn, CCNOmode)
8933   && ix86_binary_operator_ok (XOR, DImode, operands)"
8934  "xor{q}\t{%2, %0|%0, %2}"
8935  [(set_attr "type" "alu")
8936   (set_attr "mode" "DI")])
8937
8938(define_expand "xorsi3"
8939  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8940	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8941		(match_operand:SI 2 "general_operand" "")))
8942   (clobber (reg:CC FLAGS_REG))]
8943  ""
8944  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8945
8946(define_insn "*xorsi_1"
8947  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8948	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8949		(match_operand:SI 2 "general_operand" "ri,rm")))
8950   (clobber (reg:CC FLAGS_REG))]
8951  "ix86_binary_operator_ok (XOR, SImode, operands)"
8952  "xor{l}\t{%2, %0|%0, %2}"
8953  [(set_attr "type" "alu")
8954   (set_attr "mode" "SI")])
8955
8956;; See comment for addsi_1_zext why we do use nonimmediate_operand
8957;; Add speccase for immediates
8958(define_insn "*xorsi_1_zext"
8959  [(set (match_operand:DI 0 "register_operand" "=r")
8960	(zero_extend:DI
8961	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8962		  (match_operand:SI 2 "general_operand" "rim"))))
8963   (clobber (reg:CC FLAGS_REG))]
8964  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8965  "xor{l}\t{%2, %k0|%k0, %2}"
8966  [(set_attr "type" "alu")
8967   (set_attr "mode" "SI")])
8968
8969(define_insn "*xorsi_1_zext_imm"
8970  [(set (match_operand:DI 0 "register_operand" "=r")
8971	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8972		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8973   (clobber (reg:CC FLAGS_REG))]
8974  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8975  "xor{l}\t{%2, %k0|%k0, %2}"
8976  [(set_attr "type" "alu")
8977   (set_attr "mode" "SI")])
8978
8979(define_insn "*xorsi_2"
8980  [(set (reg FLAGS_REG)
8981	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8982			 (match_operand:SI 2 "general_operand" "rim,ri"))
8983		 (const_int 0)))
8984   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8985	(xor:SI (match_dup 1) (match_dup 2)))]
8986  "ix86_match_ccmode (insn, CCNOmode)
8987   && ix86_binary_operator_ok (XOR, SImode, operands)"
8988  "xor{l}\t{%2, %0|%0, %2}"
8989  [(set_attr "type" "alu")
8990   (set_attr "mode" "SI")])
8991
8992;; See comment for addsi_1_zext why we do use nonimmediate_operand
8993;; ??? Special case for immediate operand is missing - it is tricky.
8994(define_insn "*xorsi_2_zext"
8995  [(set (reg FLAGS_REG)
8996	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8997			 (match_operand:SI 2 "general_operand" "rim"))
8998		 (const_int 0)))
8999   (set (match_operand:DI 0 "register_operand" "=r")
9000	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9001  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9002   && ix86_binary_operator_ok (XOR, SImode, operands)"
9003  "xor{l}\t{%2, %k0|%k0, %2}"
9004  [(set_attr "type" "alu")
9005   (set_attr "mode" "SI")])
9006
9007(define_insn "*xorsi_2_zext_imm"
9008  [(set (reg FLAGS_REG)
9009	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9010			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9011		 (const_int 0)))
9012   (set (match_operand:DI 0 "register_operand" "=r")
9013	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9014  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9015   && ix86_binary_operator_ok (XOR, SImode, operands)"
9016  "xor{l}\t{%2, %k0|%k0, %2}"
9017  [(set_attr "type" "alu")
9018   (set_attr "mode" "SI")])
9019
9020(define_insn "*xorsi_3"
9021  [(set (reg FLAGS_REG)
9022	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9023			 (match_operand:SI 2 "general_operand" "rim"))
9024		 (const_int 0)))
9025   (clobber (match_scratch:SI 0 "=r"))]
9026  "ix86_match_ccmode (insn, CCNOmode)
9027   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9028  "xor{l}\t{%2, %0|%0, %2}"
9029  [(set_attr "type" "alu")
9030   (set_attr "mode" "SI")])
9031
9032(define_expand "xorhi3"
9033  [(set (match_operand:HI 0 "nonimmediate_operand" "")
9034	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9035		(match_operand:HI 2 "general_operand" "")))
9036   (clobber (reg:CC FLAGS_REG))]
9037  "TARGET_HIMODE_MATH"
9038  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9039
9040(define_insn "*xorhi_1"
9041  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9042	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9043		(match_operand:HI 2 "general_operand" "rmi,ri")))
9044   (clobber (reg:CC FLAGS_REG))]
9045  "ix86_binary_operator_ok (XOR, HImode, operands)"
9046  "xor{w}\t{%2, %0|%0, %2}"
9047  [(set_attr "type" "alu")
9048   (set_attr "mode" "HI")])
9049
9050(define_insn "*xorhi_2"
9051  [(set (reg FLAGS_REG)
9052	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9053			 (match_operand:HI 2 "general_operand" "rim,ri"))
9054		 (const_int 0)))
9055   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9056	(xor:HI (match_dup 1) (match_dup 2)))]
9057  "ix86_match_ccmode (insn, CCNOmode)
9058   && ix86_binary_operator_ok (XOR, HImode, operands)"
9059  "xor{w}\t{%2, %0|%0, %2}"
9060  [(set_attr "type" "alu")
9061   (set_attr "mode" "HI")])
9062
9063(define_insn "*xorhi_3"
9064  [(set (reg FLAGS_REG)
9065	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9066			 (match_operand:HI 2 "general_operand" "rim"))
9067		 (const_int 0)))
9068   (clobber (match_scratch:HI 0 "=r"))]
9069  "ix86_match_ccmode (insn, CCNOmode)
9070   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9071  "xor{w}\t{%2, %0|%0, %2}"
9072  [(set_attr "type" "alu")
9073   (set_attr "mode" "HI")])
9074
9075(define_expand "xorqi3"
9076  [(set (match_operand:QI 0 "nonimmediate_operand" "")
9077	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9078		(match_operand:QI 2 "general_operand" "")))
9079   (clobber (reg:CC FLAGS_REG))]
9080  "TARGET_QIMODE_MATH"
9081  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9082
9083;; %%% Potential partial reg stall on alternative 2.  What to do?
9084(define_insn "*xorqi_1"
9085  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9086	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9087		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9088   (clobber (reg:CC FLAGS_REG))]
9089  "ix86_binary_operator_ok (XOR, QImode, operands)"
9090  "@
9091   xor{b}\t{%2, %0|%0, %2}
9092   xor{b}\t{%2, %0|%0, %2}
9093   xor{l}\t{%k2, %k0|%k0, %k2}"
9094  [(set_attr "type" "alu")
9095   (set_attr "mode" "QI,QI,SI")])
9096
9097(define_insn "*xorqi_1_slp"
9098  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9099	(xor:QI (match_dup 0)
9100		(match_operand:QI 1 "general_operand" "qi,qmi")))
9101   (clobber (reg:CC FLAGS_REG))]
9102  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9103   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9104  "xor{b}\t{%1, %0|%0, %1}"
9105  [(set_attr "type" "alu1")
9106   (set_attr "mode" "QI")])
9107
9108(define_insn "xorqi_ext_0"
9109  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9110			 (const_int 8)
9111			 (const_int 8))
9112	(xor:SI 
9113	  (zero_extract:SI
9114	    (match_operand 1 "ext_register_operand" "0")
9115	    (const_int 8)
9116	    (const_int 8))
9117	  (match_operand 2 "const_int_operand" "n")))
9118   (clobber (reg:CC FLAGS_REG))]
9119  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9120  "xor{b}\t{%2, %h0|%h0, %2}"
9121  [(set_attr "type" "alu")
9122   (set_attr "length_immediate" "1")
9123   (set_attr "mode" "QI")])
9124
9125(define_insn "*xorqi_ext_1"
9126  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127			 (const_int 8)
9128			 (const_int 8))
9129	(xor:SI 
9130	  (zero_extract:SI
9131	    (match_operand 1 "ext_register_operand" "0")
9132	    (const_int 8)
9133	    (const_int 8))
9134	  (zero_extend:SI
9135	    (match_operand:QI 2 "general_operand" "Qm"))))
9136   (clobber (reg:CC FLAGS_REG))]
9137  "!TARGET_64BIT
9138   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9139  "xor{b}\t{%2, %h0|%h0, %2}"
9140  [(set_attr "type" "alu")
9141   (set_attr "length_immediate" "0")
9142   (set_attr "mode" "QI")])
9143
9144(define_insn "*xorqi_ext_1_rex64"
9145  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9146			 (const_int 8)
9147			 (const_int 8))
9148	(xor:SI 
9149	  (zero_extract:SI
9150	    (match_operand 1 "ext_register_operand" "0")
9151	    (const_int 8)
9152	    (const_int 8))
9153	  (zero_extend:SI
9154	    (match_operand 2 "ext_register_operand" "Q"))))
9155   (clobber (reg:CC FLAGS_REG))]
9156  "TARGET_64BIT
9157   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9158  "xor{b}\t{%2, %h0|%h0, %2}"
9159  [(set_attr "type" "alu")
9160   (set_attr "length_immediate" "0")
9161   (set_attr "mode" "QI")])
9162
9163(define_insn "*xorqi_ext_2"
9164  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9165			 (const_int 8)
9166			 (const_int 8))
9167	(xor:SI 
9168	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9169	  		   (const_int 8)
9170			   (const_int 8))
9171	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9172	  		   (const_int 8)
9173			   (const_int 8))))
9174   (clobber (reg:CC FLAGS_REG))]
9175  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9176  "xor{b}\t{%h2, %h0|%h0, %h2}"
9177  [(set_attr "type" "alu")
9178   (set_attr "length_immediate" "0")
9179   (set_attr "mode" "QI")])
9180
9181(define_insn "*xorqi_cc_1"
9182  [(set (reg FLAGS_REG)
9183	(compare
9184	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9185		  (match_operand:QI 2 "general_operand" "qim,qi"))
9186	  (const_int 0)))
9187   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9188	(xor:QI (match_dup 1) (match_dup 2)))]
9189  "ix86_match_ccmode (insn, CCNOmode)
9190   && ix86_binary_operator_ok (XOR, QImode, operands)"
9191  "xor{b}\t{%2, %0|%0, %2}"
9192  [(set_attr "type" "alu")
9193   (set_attr "mode" "QI")])
9194
9195(define_insn "*xorqi_2_slp"
9196  [(set (reg FLAGS_REG)
9197	(compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9198			 (match_operand:QI 1 "general_operand" "qim,qi"))
9199		 (const_int 0)))
9200   (set (strict_low_part (match_dup 0))
9201	(xor:QI (match_dup 0) (match_dup 1)))]
9202  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9203   && ix86_match_ccmode (insn, CCNOmode)
9204   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9205  "xor{b}\t{%1, %0|%0, %1}"
9206  [(set_attr "type" "alu1")
9207   (set_attr "mode" "QI")])
9208
9209(define_insn "*xorqi_cc_2"
9210  [(set (reg FLAGS_REG)
9211	(compare
9212	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9213		  (match_operand:QI 2 "general_operand" "qim"))
9214	  (const_int 0)))
9215   (clobber (match_scratch:QI 0 "=q"))]
9216  "ix86_match_ccmode (insn, CCNOmode)
9217   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9218  "xor{b}\t{%2, %0|%0, %2}"
9219  [(set_attr "type" "alu")
9220   (set_attr "mode" "QI")])
9221
9222(define_insn "*xorqi_cc_ext_1"
9223  [(set (reg FLAGS_REG)
9224	(compare
9225	  (xor:SI
9226	    (zero_extract:SI
9227	      (match_operand 1 "ext_register_operand" "0")
9228	      (const_int 8)
9229	      (const_int 8))
9230	    (match_operand:QI 2 "general_operand" "qmn"))
9231	  (const_int 0)))
9232   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9233			 (const_int 8)
9234			 (const_int 8))
9235	(xor:SI 
9236	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9237	  (match_dup 2)))]
9238  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9239  "xor{b}\t{%2, %h0|%h0, %2}"
9240  [(set_attr "type" "alu")
9241   (set_attr "mode" "QI")])
9242
9243(define_insn "*xorqi_cc_ext_1_rex64"
9244  [(set (reg FLAGS_REG)
9245	(compare
9246	  (xor:SI
9247	    (zero_extract:SI
9248	      (match_operand 1 "ext_register_operand" "0")
9249	      (const_int 8)
9250	      (const_int 8))
9251	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
9252	  (const_int 0)))
9253   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9254			 (const_int 8)
9255			 (const_int 8))
9256	(xor:SI 
9257	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9258	  (match_dup 2)))]
9259  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9260  "xor{b}\t{%2, %h0|%h0, %2}"
9261  [(set_attr "type" "alu")
9262   (set_attr "mode" "QI")])
9263
9264(define_expand "xorqi_cc_ext_1"
9265  [(parallel [
9266     (set (reg:CCNO FLAGS_REG)
9267	  (compare:CCNO
9268	    (xor:SI
9269	      (zero_extract:SI
9270		(match_operand 1 "ext_register_operand" "")
9271		(const_int 8)
9272		(const_int 8))
9273	      (match_operand:QI 2 "general_operand" ""))
9274	    (const_int 0)))
9275     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9276			   (const_int 8)
9277			   (const_int 8))
9278	  (xor:SI 
9279	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9280	    (match_dup 2)))])]
9281  ""
9282  "")
9283
9284(define_split
9285  [(set (match_operand 0 "register_operand" "")
9286	(xor (match_operand 1 "register_operand" "")
9287	     (match_operand 2 "const_int_operand" "")))
9288   (clobber (reg:CC FLAGS_REG))]
9289   "reload_completed
9290    && QI_REG_P (operands[0])
9291    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9292    && !(INTVAL (operands[2]) & ~(255 << 8))
9293    && GET_MODE (operands[0]) != QImode"
9294  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9295		   (xor:SI (zero_extract:SI (match_dup 1)
9296					    (const_int 8) (const_int 8))
9297			   (match_dup 2)))
9298	      (clobber (reg:CC FLAGS_REG))])]
9299  "operands[0] = gen_lowpart (SImode, operands[0]);
9300   operands[1] = gen_lowpart (SImode, operands[1]);
9301   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9302
9303;; Since XOR can be encoded with sign extended immediate, this is only
9304;; profitable when 7th bit is set.
9305(define_split
9306  [(set (match_operand 0 "register_operand" "")
9307	(xor (match_operand 1 "general_operand" "")
9308	     (match_operand 2 "const_int_operand" "")))
9309   (clobber (reg:CC FLAGS_REG))]
9310   "reload_completed
9311    && ANY_QI_REG_P (operands[0])
9312    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9313    && !(INTVAL (operands[2]) & ~255)
9314    && (INTVAL (operands[2]) & 128)
9315    && GET_MODE (operands[0]) != QImode"
9316  [(parallel [(set (strict_low_part (match_dup 0))
9317		   (xor:QI (match_dup 1)
9318			   (match_dup 2)))
9319	      (clobber (reg:CC FLAGS_REG))])]
9320  "operands[0] = gen_lowpart (QImode, operands[0]);
9321   operands[1] = gen_lowpart (QImode, operands[1]);
9322   operands[2] = gen_lowpart (QImode, operands[2]);")
9323
9324;; Negation instructions
9325
9326(define_expand "negti2"
9327  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9328		   (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9329	      (clobber (reg:CC FLAGS_REG))])]
9330  "TARGET_64BIT"
9331  "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9332
9333(define_insn "*negti2_1"
9334  [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9335	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9336   (clobber (reg:CC FLAGS_REG))]
9337  "TARGET_64BIT
9338   && ix86_unary_operator_ok (NEG, TImode, operands)"
9339  "#")
9340
9341(define_split
9342  [(set (match_operand:TI 0 "nonimmediate_operand" "")
9343	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9344   (clobber (reg:CC FLAGS_REG))]
9345  "TARGET_64BIT && reload_completed"
9346  [(parallel
9347    [(set (reg:CCZ FLAGS_REG)
9348	  (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9349     (set (match_dup 0) (neg:DI (match_dup 2)))])
9350   (parallel
9351    [(set (match_dup 1)
9352	  (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9353			    (match_dup 3))
9354		   (const_int 0)))
9355     (clobber (reg:CC FLAGS_REG))])
9356   (parallel
9357    [(set (match_dup 1)
9358	  (neg:DI (match_dup 1)))
9359     (clobber (reg:CC FLAGS_REG))])]
9360  "split_ti (operands+1, 1, operands+2, operands+3);
9361   split_ti (operands+0, 1, operands+0, operands+1);")
9362
9363(define_expand "negdi2"
9364  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9365		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9366	      (clobber (reg:CC FLAGS_REG))])]
9367  ""
9368  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9369
9370(define_insn "*negdi2_1"
9371  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9372	(neg:DI (match_operand:DI 1 "general_operand" "0")))
9373   (clobber (reg:CC FLAGS_REG))]
9374  "!TARGET_64BIT
9375   && ix86_unary_operator_ok (NEG, DImode, operands)"
9376  "#")
9377
9378(define_split
9379  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9380	(neg:DI (match_operand:DI 1 "general_operand" "")))
9381   (clobber (reg:CC FLAGS_REG))]
9382  "!TARGET_64BIT && reload_completed"
9383  [(parallel
9384    [(set (reg:CCZ FLAGS_REG)
9385	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9386     (set (match_dup 0) (neg:SI (match_dup 2)))])
9387   (parallel
9388    [(set (match_dup 1)
9389	  (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9390			    (match_dup 3))
9391		   (const_int 0)))
9392     (clobber (reg:CC FLAGS_REG))])
9393   (parallel
9394    [(set (match_dup 1)
9395	  (neg:SI (match_dup 1)))
9396     (clobber (reg:CC FLAGS_REG))])]
9397  "split_di (operands+1, 1, operands+2, operands+3);
9398   split_di (operands+0, 1, operands+0, operands+1);")
9399
9400(define_insn "*negdi2_1_rex64"
9401  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9402	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9403   (clobber (reg:CC FLAGS_REG))]
9404  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9405  "neg{q}\t%0"
9406  [(set_attr "type" "negnot")
9407   (set_attr "mode" "DI")])
9408
9409;; The problem with neg is that it does not perform (compare x 0),
9410;; it really performs (compare 0 x), which leaves us with the zero
9411;; flag being the only useful item.
9412
9413(define_insn "*negdi2_cmpz_rex64"
9414  [(set (reg:CCZ FLAGS_REG)
9415	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9416		     (const_int 0)))
9417   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9418	(neg:DI (match_dup 1)))]
9419  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9420  "neg{q}\t%0"
9421  [(set_attr "type" "negnot")
9422   (set_attr "mode" "DI")])
9423
9424
9425(define_expand "negsi2"
9426  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9427		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9428	      (clobber (reg:CC FLAGS_REG))])]
9429  ""
9430  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9431
9432(define_insn "*negsi2_1"
9433  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9434	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9435   (clobber (reg:CC FLAGS_REG))]
9436  "ix86_unary_operator_ok (NEG, SImode, operands)"
9437  "neg{l}\t%0"
9438  [(set_attr "type" "negnot")
9439   (set_attr "mode" "SI")])
9440
9441;; Combine is quite creative about this pattern.
9442(define_insn "*negsi2_1_zext"
9443  [(set (match_operand:DI 0 "register_operand" "=r")
9444	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9445					(const_int 32)))
9446		     (const_int 32)))
9447   (clobber (reg:CC FLAGS_REG))]
9448  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9449  "neg{l}\t%k0"
9450  [(set_attr "type" "negnot")
9451   (set_attr "mode" "SI")])
9452
9453;; The problem with neg is that it does not perform (compare x 0),
9454;; it really performs (compare 0 x), which leaves us with the zero
9455;; flag being the only useful item.
9456
9457(define_insn "*negsi2_cmpz"
9458  [(set (reg:CCZ FLAGS_REG)
9459	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9460		     (const_int 0)))
9461   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9462	(neg:SI (match_dup 1)))]
9463  "ix86_unary_operator_ok (NEG, SImode, operands)"
9464  "neg{l}\t%0"
9465  [(set_attr "type" "negnot")
9466   (set_attr "mode" "SI")])
9467
9468(define_insn "*negsi2_cmpz_zext"
9469  [(set (reg:CCZ FLAGS_REG)
9470	(compare:CCZ (lshiftrt:DI
9471		       (neg:DI (ashift:DI
9472				 (match_operand:DI 1 "register_operand" "0")
9473				 (const_int 32)))
9474		       (const_int 32))
9475		     (const_int 0)))
9476   (set (match_operand:DI 0 "register_operand" "=r")
9477	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9478					(const_int 32)))
9479		     (const_int 32)))]
9480  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9481  "neg{l}\t%k0"
9482  [(set_attr "type" "negnot")
9483   (set_attr "mode" "SI")])
9484
9485(define_expand "neghi2"
9486  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9487		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9488	      (clobber (reg:CC FLAGS_REG))])]
9489  "TARGET_HIMODE_MATH"
9490  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9491
9492(define_insn "*neghi2_1"
9493  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9494	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9495   (clobber (reg:CC FLAGS_REG))]
9496  "ix86_unary_operator_ok (NEG, HImode, operands)"
9497  "neg{w}\t%0"
9498  [(set_attr "type" "negnot")
9499   (set_attr "mode" "HI")])
9500
9501(define_insn "*neghi2_cmpz"
9502  [(set (reg:CCZ FLAGS_REG)
9503	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9504		     (const_int 0)))
9505   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9506	(neg:HI (match_dup 1)))]
9507  "ix86_unary_operator_ok (NEG, HImode, operands)"
9508  "neg{w}\t%0"
9509  [(set_attr "type" "negnot")
9510   (set_attr "mode" "HI")])
9511
9512(define_expand "negqi2"
9513  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9514		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9515	      (clobber (reg:CC FLAGS_REG))])]
9516  "TARGET_QIMODE_MATH"
9517  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9518
9519(define_insn "*negqi2_1"
9520  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9521	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9522   (clobber (reg:CC FLAGS_REG))]
9523  "ix86_unary_operator_ok (NEG, QImode, operands)"
9524  "neg{b}\t%0"
9525  [(set_attr "type" "negnot")
9526   (set_attr "mode" "QI")])
9527
9528(define_insn "*negqi2_cmpz"
9529  [(set (reg:CCZ FLAGS_REG)
9530	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9531		     (const_int 0)))
9532   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9533	(neg:QI (match_dup 1)))]
9534  "ix86_unary_operator_ok (NEG, QImode, operands)"
9535  "neg{b}\t%0"
9536  [(set_attr "type" "negnot")
9537   (set_attr "mode" "QI")])
9538
9539;; Changing of sign for FP values is doable using integer unit too.
9540
9541(define_expand "negsf2"
9542  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544  "TARGET_80387 || TARGET_SSE_MATH"
9545  "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9546
9547(define_expand "abssf2"
9548  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9549	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9550  "TARGET_80387 || TARGET_SSE_MATH"
9551  "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9552
9553(define_insn "*absnegsf2_mixed"
9554  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9555	(match_operator:SF 3 "absneg_operator"
9556	  [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9557   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9558   (clobber (reg:CC FLAGS_REG))]
9559  "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9560   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9561  "#")
9562
9563(define_insn "*absnegsf2_sse"
9564  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9565	(match_operator:SF 3 "absneg_operator"
9566	  [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9567   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9568   (clobber (reg:CC FLAGS_REG))]
9569  "TARGET_SSE_MATH
9570   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9571  "#")
9572
9573(define_insn "*absnegsf2_i387"
9574  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9575	(match_operator:SF 3 "absneg_operator"
9576	  [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9577   (use (match_operand 2 "" ""))
9578   (clobber (reg:CC FLAGS_REG))]
9579  "TARGET_80387 && !TARGET_SSE_MATH
9580   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9581  "#")
9582
9583(define_expand "copysignsf3"
9584  [(match_operand:SF 0 "register_operand" "")
9585   (match_operand:SF 1 "nonmemory_operand" "")
9586   (match_operand:SF 2 "register_operand" "")]
9587  "TARGET_SSE_MATH"
9588{
9589  ix86_expand_copysign (operands);
9590  DONE;
9591})
9592
9593(define_insn_and_split "copysignsf3_const"
9594  [(set (match_operand:SF 0 "register_operand"          "=x")
9595	(unspec:SF
9596	  [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9597	   (match_operand:SF 2 "register_operand"       "0")
9598	   (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9599	  UNSPEC_COPYSIGN))]
9600  "TARGET_SSE_MATH"
9601  "#"
9602  "&& reload_completed"
9603  [(const_int 0)]
9604{
9605  ix86_split_copysign_const (operands);
9606  DONE;
9607})
9608
9609(define_insn "copysignsf3_var"
9610  [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9611	(unspec:SF
9612	  [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9613	   (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9614	   (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9615	   (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9616	  UNSPEC_COPYSIGN))
9617   (clobber (match_scratch:V4SF 1			"=x, x, x, x,x"))]
9618  "TARGET_SSE_MATH"
9619  "#")
9620
9621(define_split
9622  [(set (match_operand:SF 0 "register_operand" "")
9623	(unspec:SF
9624	  [(match_operand:SF 2 "register_operand" "")
9625	   (match_operand:SF 3 "register_operand" "")
9626	   (match_operand:V4SF 4 "" "")
9627	   (match_operand:V4SF 5 "" "")]
9628	  UNSPEC_COPYSIGN))
9629   (clobber (match_scratch:V4SF 1 ""))]
9630  "TARGET_SSE_MATH && reload_completed"
9631  [(const_int 0)]
9632{
9633  ix86_split_copysign_var (operands);
9634  DONE;
9635})
9636
9637(define_expand "negdf2"
9638  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641  "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9642
9643(define_expand "absdf2"
9644  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9645	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9646  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9647  "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9648
9649(define_insn "*absnegdf2_mixed"
9650  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9651	(match_operator:DF 3 "absneg_operator"
9652	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9653   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9654   (clobber (reg:CC FLAGS_REG))]
9655  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9656   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9657  "#")
9658
9659(define_insn "*absnegdf2_sse"
9660  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9661	(match_operator:DF 3 "absneg_operator"
9662	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9663   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9664   (clobber (reg:CC FLAGS_REG))]
9665  "TARGET_SSE2 && TARGET_SSE_MATH
9666   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9667  "#")
9668
9669(define_insn "*absnegdf2_i387"
9670  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9671	(match_operator:DF 3 "absneg_operator"
9672	  [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9673   (use (match_operand 2 "" ""))
9674   (clobber (reg:CC FLAGS_REG))]
9675  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9676   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9677  "#")
9678
9679(define_expand "copysigndf3"
9680  [(match_operand:DF 0 "register_operand" "")
9681   (match_operand:DF 1 "nonmemory_operand" "")
9682   (match_operand:DF 2 "register_operand" "")]
9683  "TARGET_SSE2 && TARGET_SSE_MATH"
9684{
9685  ix86_expand_copysign (operands);
9686  DONE;
9687})
9688
9689(define_insn_and_split "copysigndf3_const"
9690  [(set (match_operand:DF 0 "register_operand"          "=x")
9691	(unspec:DF
9692	  [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9693	   (match_operand:DF 2 "register_operand"       "0")
9694	   (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9695	  UNSPEC_COPYSIGN))]
9696  "TARGET_SSE2 && TARGET_SSE_MATH"
9697  "#"
9698  "&& reload_completed"
9699  [(const_int 0)]
9700{
9701  ix86_split_copysign_const (operands);
9702  DONE;
9703})
9704
9705(define_insn "copysigndf3_var"
9706  [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9707	(unspec:DF
9708	  [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9709	   (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9710	   (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9711	   (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9712	  UNSPEC_COPYSIGN))
9713   (clobber (match_scratch:V2DF 1			"=x, x, x, x,x"))]
9714  "TARGET_SSE2 && TARGET_SSE_MATH"
9715  "#")
9716
9717(define_split
9718  [(set (match_operand:DF 0 "register_operand" "")
9719	(unspec:DF
9720	  [(match_operand:DF 2 "register_operand" "")
9721	   (match_operand:DF 3 "register_operand" "")
9722	   (match_operand:V2DF 4 "" "")
9723	   (match_operand:V2DF 5 "" "")]
9724	  UNSPEC_COPYSIGN))
9725   (clobber (match_scratch:V2DF 1 ""))]
9726  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9727  [(const_int 0)]
9728{
9729  ix86_split_copysign_var (operands);
9730  DONE;
9731})
9732
9733(define_expand "negxf2"
9734  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9736  "TARGET_80387"
9737  "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9738
9739(define_expand "absxf2"
9740  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9741	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9742  "TARGET_80387"
9743  "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9744
9745(define_insn "*absnegxf2_i387"
9746  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9747	(match_operator:XF 3 "absneg_operator"
9748	  [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9749   (use (match_operand 2 "" ""))
9750   (clobber (reg:CC FLAGS_REG))]
9751  "TARGET_80387
9752   && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9753  "#")
9754
9755;; Splitters for fp abs and neg.
9756
9757(define_split
9758  [(set (match_operand 0 "fp_register_operand" "")
9759	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9760   (use (match_operand 2 "" ""))
9761   (clobber (reg:CC FLAGS_REG))]
9762  "reload_completed"
9763  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9764
9765(define_split
9766  [(set (match_operand 0 "register_operand" "")
9767	(match_operator 3 "absneg_operator"
9768	  [(match_operand 1 "register_operand" "")]))
9769   (use (match_operand 2 "nonimmediate_operand" ""))
9770   (clobber (reg:CC FLAGS_REG))]
9771  "reload_completed && SSE_REG_P (operands[0])"
9772  [(set (match_dup 0) (match_dup 3))]
9773{
9774  enum machine_mode mode = GET_MODE (operands[0]);
9775  enum machine_mode vmode = GET_MODE (operands[2]);
9776  rtx tmp;
9777  
9778  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9779  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9780  if (operands_match_p (operands[0], operands[2]))
9781    {
9782      tmp = operands[1];
9783      operands[1] = operands[2];
9784      operands[2] = tmp;
9785    }
9786  if (GET_CODE (operands[3]) == ABS)
9787    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9788  else
9789    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9790  operands[3] = tmp;
9791})
9792
9793(define_split
9794  [(set (match_operand:SF 0 "register_operand" "")
9795	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9796   (use (match_operand:V4SF 2 "" ""))
9797   (clobber (reg:CC FLAGS_REG))]
9798  "reload_completed"
9799  [(parallel [(set (match_dup 0) (match_dup 1))
9800	      (clobber (reg:CC FLAGS_REG))])]
9801{ 
9802  rtx tmp;
9803  operands[0] = gen_lowpart (SImode, operands[0]);
9804  if (GET_CODE (operands[1]) == ABS)
9805    {
9806      tmp = gen_int_mode (0x7fffffff, SImode);
9807      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9808    }
9809  else
9810    {
9811      tmp = gen_int_mode (0x80000000, SImode);
9812      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9813    }
9814  operands[1] = tmp;
9815})
9816
9817(define_split
9818  [(set (match_operand:DF 0 "register_operand" "")
9819	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9820   (use (match_operand 2 "" ""))
9821   (clobber (reg:CC FLAGS_REG))]
9822  "reload_completed"
9823  [(parallel [(set (match_dup 0) (match_dup 1))
9824	      (clobber (reg:CC FLAGS_REG))])]
9825{
9826  rtx tmp;
9827  if (TARGET_64BIT)
9828    {
9829      tmp = gen_lowpart (DImode, operands[0]);
9830      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9831      operands[0] = tmp;
9832
9833      if (GET_CODE (operands[1]) == ABS)
9834	tmp = const0_rtx;
9835      else
9836	tmp = gen_rtx_NOT (DImode, tmp);
9837    }
9838  else
9839    {
9840      operands[0] = gen_highpart (SImode, operands[0]);
9841      if (GET_CODE (operands[1]) == ABS)
9842	{
9843	  tmp = gen_int_mode (0x7fffffff, SImode);
9844	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
9845	}
9846      else
9847	{
9848	  tmp = gen_int_mode (0x80000000, SImode);
9849	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9850	}
9851    }
9852  operands[1] = tmp;
9853})
9854
9855(define_split
9856  [(set (match_operand:XF 0 "register_operand" "")
9857	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9858   (use (match_operand 2 "" ""))
9859   (clobber (reg:CC FLAGS_REG))]
9860  "reload_completed"
9861  [(parallel [(set (match_dup 0) (match_dup 1))
9862	      (clobber (reg:CC FLAGS_REG))])]
9863{
9864  rtx tmp;
9865  operands[0] = gen_rtx_REG (SImode,
9866			     true_regnum (operands[0])
9867			     + (TARGET_64BIT ? 1 : 2));
9868  if (GET_CODE (operands[1]) == ABS)
9869    {
9870      tmp = GEN_INT (0x7fff);
9871      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9872    }
9873  else
9874    {
9875      tmp = GEN_INT (0x8000);
9876      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9877    }
9878  operands[1] = tmp;
9879})
9880
9881(define_split
9882  [(set (match_operand 0 "memory_operand" "")
9883	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9884   (use (match_operand 2 "" ""))
9885   (clobber (reg:CC FLAGS_REG))]
9886  "reload_completed"
9887  [(parallel [(set (match_dup 0) (match_dup 1))
9888	      (clobber (reg:CC FLAGS_REG))])]
9889{
9890  enum machine_mode mode = GET_MODE (operands[0]);
9891  int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9892  rtx tmp;
9893
9894  operands[0] = adjust_address (operands[0], QImode, size - 1);
9895  if (GET_CODE (operands[1]) == ABS)
9896    {
9897      tmp = gen_int_mode (0x7f, QImode);
9898      tmp = gen_rtx_AND (QImode, operands[0], tmp);
9899    }
9900  else
9901    {
9902      tmp = gen_int_mode (0x80, QImode);
9903      tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9904    }
9905  operands[1] = tmp;
9906})
9907
9908;; Conditionalize these after reload. If they match before reload, we 
9909;; lose the clobber and ability to use integer instructions.
9910
9911(define_insn "*negsf2_1"
9912  [(set (match_operand:SF 0 "register_operand" "=f")
9913	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
9914  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9915  "fchs"
9916  [(set_attr "type" "fsgn")
9917   (set_attr "mode" "SF")])
9918
9919(define_insn "*negdf2_1"
9920  [(set (match_operand:DF 0 "register_operand" "=f")
9921	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
9922  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9923  "fchs"
9924  [(set_attr "type" "fsgn")
9925   (set_attr "mode" "DF")])
9926
9927(define_insn "*negxf2_1"
9928  [(set (match_operand:XF 0 "register_operand" "=f")
9929	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
9930  "TARGET_80387"
9931  "fchs"
9932  [(set_attr "type" "fsgn")
9933   (set_attr "mode" "XF")])
9934
9935(define_insn "*abssf2_1"
9936  [(set (match_operand:SF 0 "register_operand" "=f")
9937	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
9938  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9939  "fabs"
9940  [(set_attr "type" "fsgn")
9941   (set_attr "mode" "SF")])
9942
9943(define_insn "*absdf2_1"
9944  [(set (match_operand:DF 0 "register_operand" "=f")
9945	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
9946  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9947  "fabs"
9948  [(set_attr "type" "fsgn")
9949   (set_attr "mode" "DF")])
9950
9951(define_insn "*absxf2_1"
9952  [(set (match_operand:XF 0 "register_operand" "=f")
9953	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
9954  "TARGET_80387"
9955  "fabs"
9956  [(set_attr "type" "fsgn")
9957   (set_attr "mode" "DF")])
9958
9959(define_insn "*negextendsfdf2"
9960  [(set (match_operand:DF 0 "register_operand" "=f")
9961	(neg:DF (float_extend:DF
9962		  (match_operand:SF 1 "register_operand" "0"))))]
9963  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9964  "fchs"
9965  [(set_attr "type" "fsgn")
9966   (set_attr "mode" "DF")])
9967
9968(define_insn "*negextenddfxf2"
9969  [(set (match_operand:XF 0 "register_operand" "=f")
9970	(neg:XF (float_extend:XF
9971		  (match_operand:DF 1 "register_operand" "0"))))]
9972  "TARGET_80387"
9973  "fchs"
9974  [(set_attr "type" "fsgn")
9975   (set_attr "mode" "XF")])
9976
9977(define_insn "*negextendsfxf2"
9978  [(set (match_operand:XF 0 "register_operand" "=f")
9979	(neg:XF (float_extend:XF
9980		  (match_operand:SF 1 "register_operand" "0"))))]
9981  "TARGET_80387"
9982  "fchs"
9983  [(set_attr "type" "fsgn")
9984   (set_attr "mode" "XF")])
9985
9986(define_insn "*absextendsfdf2"
9987  [(set (match_operand:DF 0 "register_operand" "=f")
9988	(abs:DF (float_extend:DF
9989		  (match_operand:SF 1 "register_operand" "0"))))]
9990  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9991  "fabs"
9992  [(set_attr "type" "fsgn")
9993   (set_attr "mode" "DF")])
9994
9995(define_insn "*absextenddfxf2"
9996  [(set (match_operand:XF 0 "register_operand" "=f")
9997	(abs:XF (float_extend:XF
9998	  (match_operand:DF 1 "register_operand" "0"))))]
9999  "TARGET_80387"
10000  "fabs"
10001  [(set_attr "type" "fsgn")
10002   (set_attr "mode" "XF")])
10003
10004(define_insn "*absextendsfxf2"
10005  [(set (match_operand:XF 0 "register_operand" "=f")
10006	(abs:XF (float_extend:XF
10007	  (match_operand:SF 1 "register_operand" "0"))))]
10008  "TARGET_80387"
10009  "fabs"
10010  [(set_attr "type" "fsgn")
10011   (set_attr "mode" "XF")])
10012
10013;; One complement instructions
10014
10015(define_expand "one_cmpldi2"
10016  [(set (match_operand:DI 0 "nonimmediate_operand" "")
10017	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10018  "TARGET_64BIT"
10019  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10020
10021(define_insn "*one_cmpldi2_1_rex64"
10022  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10023	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10024  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10025  "not{q}\t%0"
10026  [(set_attr "type" "negnot")
10027   (set_attr "mode" "DI")])
10028
10029(define_insn "*one_cmpldi2_2_rex64"
10030  [(set (reg FLAGS_REG)
10031	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10032		 (const_int 0)))
10033   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10034	(not:DI (match_dup 1)))]
10035  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10036   && ix86_unary_operator_ok (NOT, DImode, operands)"
10037  "#"
10038  [(set_attr "type" "alu1")
10039   (set_attr "mode" "DI")])
10040
10041(define_split
10042  [(set (match_operand 0 "flags_reg_operand" "")
10043	(match_operator 2 "compare_operator"
10044	  [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10045	   (const_int 0)]))
10046   (set (match_operand:DI 1 "nonimmediate_operand" "")
10047	(not:DI (match_dup 3)))]
10048  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10049  [(parallel [(set (match_dup 0)
10050		   (match_op_dup 2
10051		     [(xor:DI (match_dup 3) (const_int -1))
10052		      (const_int 0)]))
10053	      (set (match_dup 1)
10054		   (xor:DI (match_dup 3) (const_int -1)))])]
10055  "")
10056
10057(define_expand "one_cmplsi2"
10058  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10059	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10060  ""
10061  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10062
10063(define_insn "*one_cmplsi2_1"
10064  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10065	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10066  "ix86_unary_operator_ok (NOT, SImode, operands)"
10067  "not{l}\t%0"
10068  [(set_attr "type" "negnot")
10069   (set_attr "mode" "SI")])
10070
10071;; ??? Currently never generated - xor is used instead.
10072(define_insn "*one_cmplsi2_1_zext"
10073  [(set (match_operand:DI 0 "register_operand" "=r")
10074	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10075  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10076  "not{l}\t%k0"
10077  [(set_attr "type" "negnot")
10078   (set_attr "mode" "SI")])
10079
10080(define_insn "*one_cmplsi2_2"
10081  [(set (reg FLAGS_REG)
10082	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10083		 (const_int 0)))
10084   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10085	(not:SI (match_dup 1)))]
10086  "ix86_match_ccmode (insn, CCNOmode)
10087   && ix86_unary_operator_ok (NOT, SImode, operands)"
10088  "#"
10089  [(set_attr "type" "alu1")
10090   (set_attr "mode" "SI")])
10091
10092(define_split
10093  [(set (match_operand 0 "flags_reg_operand" "")
10094	(match_operator 2 "compare_operator"
10095	  [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10096	   (const_int 0)]))
10097   (set (match_operand:SI 1 "nonimmediate_operand" "")
10098	(not:SI (match_dup 3)))]
10099  "ix86_match_ccmode (insn, CCNOmode)"
10100  [(parallel [(set (match_dup 0)
10101		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10102				    (const_int 0)]))
10103	      (set (match_dup 1)
10104		   (xor:SI (match_dup 3) (const_int -1)))])]
10105  "")
10106
10107;; ??? Currently never generated - xor is used instead.
10108(define_insn "*one_cmplsi2_2_zext"
10109  [(set (reg FLAGS_REG)
10110	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10111		 (const_int 0)))
10112   (set (match_operand:DI 0 "register_operand" "=r")
10113	(zero_extend:DI (not:SI (match_dup 1))))]
10114  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10115   && ix86_unary_operator_ok (NOT, SImode, operands)"
10116  "#"
10117  [(set_attr "type" "alu1")
10118   (set_attr "mode" "SI")])
10119
10120(define_split
10121  [(set (match_operand 0 "flags_reg_operand" "")
10122	(match_operator 2 "compare_operator"
10123	  [(not:SI (match_operand:SI 3 "register_operand" ""))
10124	   (const_int 0)]))
10125   (set (match_operand:DI 1 "register_operand" "")
10126	(zero_extend:DI (not:SI (match_dup 3))))]
10127  "ix86_match_ccmode (insn, CCNOmode)"
10128  [(parallel [(set (match_dup 0)
10129		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10130				    (const_int 0)]))
10131	      (set (match_dup 1)
10132		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10133  "")
10134
10135(define_expand "one_cmplhi2"
10136  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10137	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10138  "TARGET_HIMODE_MATH"
10139  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10140
10141(define_insn "*one_cmplhi2_1"
10142  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10143	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10144  "ix86_unary_operator_ok (NOT, HImode, operands)"
10145  "not{w}\t%0"
10146  [(set_attr "type" "negnot")
10147   (set_attr "mode" "HI")])
10148
10149(define_insn "*one_cmplhi2_2"
10150  [(set (reg FLAGS_REG)
10151	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10152		 (const_int 0)))
10153   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10154	(not:HI (match_dup 1)))]
10155  "ix86_match_ccmode (insn, CCNOmode)
10156   && ix86_unary_operator_ok (NEG, HImode, operands)"
10157  "#"
10158  [(set_attr "type" "alu1")
10159   (set_attr "mode" "HI")])
10160
10161(define_split
10162  [(set (match_operand 0 "flags_reg_operand" "")
10163	(match_operator 2 "compare_operator"
10164	  [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10165	   (const_int 0)]))
10166   (set (match_operand:HI 1 "nonimmediate_operand" "")
10167	(not:HI (match_dup 3)))]
10168  "ix86_match_ccmode (insn, CCNOmode)"
10169  [(parallel [(set (match_dup 0)
10170		   (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10171		      		    (const_int 0)]))
10172	      (set (match_dup 1)
10173		   (xor:HI (match_dup 3) (const_int -1)))])]
10174  "")
10175
10176;; %%% Potential partial reg stall on alternative 1.  What to do?
10177(define_expand "one_cmplqi2"
10178  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10179	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10180  "TARGET_QIMODE_MATH"
10181  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10182
10183(define_insn "*one_cmplqi2_1"
10184  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10185	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10186  "ix86_unary_operator_ok (NOT, QImode, operands)"
10187  "@
10188   not{b}\t%0
10189   not{l}\t%k0"
10190  [(set_attr "type" "negnot")
10191   (set_attr "mode" "QI,SI")])
10192
10193(define_insn "*one_cmplqi2_2"
10194  [(set (reg FLAGS_REG)
10195	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10196		 (const_int 0)))
10197   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10198	(not:QI (match_dup 1)))]
10199  "ix86_match_ccmode (insn, CCNOmode)
10200   && ix86_unary_operator_ok (NOT, QImode, operands)"
10201  "#"
10202  [(set_attr "type" "alu1")
10203   (set_attr "mode" "QI")])
10204
10205(define_split
10206  [(set (match_operand 0 "flags_reg_operand" "")
10207	(match_operator 2 "compare_operator"
10208	  [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10209	   (const_int 0)]))
10210   (set (match_operand:QI 1 "nonimmediate_operand" "")
10211	(not:QI (match_dup 3)))]
10212  "ix86_match_ccmode (insn, CCNOmode)"
10213  [(parallel [(set (match_dup 0)
10214		   (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10215		      		    (const_int 0)]))
10216	      (set (match_dup 1)
10217		   (xor:QI (match_dup 3) (const_int -1)))])]
10218  "")
10219
10220;; Arithmetic shift instructions
10221
10222;; DImode shifts are implemented using the i386 "shift double" opcode,
10223;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10224;; is variable, then the count is in %cl and the "imm" operand is dropped
10225;; from the assembler input.
10226;;
10227;; This instruction shifts the target reg/mem as usual, but instead of
10228;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10229;; is a left shift double, bits are taken from the high order bits of
10230;; reg, else if the insn is a shift right double, bits are taken from the
10231;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10232;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10233;;
10234;; Since sh[lr]d does not change the `reg' operand, that is done
10235;; separately, making all shifts emit pairs of shift double and normal
10236;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10237;; support a 63 bit shift, each shift where the count is in a reg expands
10238;; to a pair of shifts, a branch, a shift by 32 and a label.
10239;;
10240;; If the shift count is a constant, we need never emit more than one
10241;; shift pair, instead using moves and sign extension for counts greater
10242;; than 31.
10243
10244(define_expand "ashlti3"
10245  [(parallel [(set (match_operand:TI 0 "register_operand" "")
10246		   (ashift:TI (match_operand:TI 1 "register_operand" "")
10247			      (match_operand:QI 2 "nonmemory_operand" "")))
10248	      (clobber (reg:CC FLAGS_REG))])]
10249  "TARGET_64BIT"
10250{
10251  if (! immediate_operand (operands[2], QImode))
10252    {
10253      emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10254      DONE;
10255    }
10256  ix86_expand_binary_operator (ASHIFT, TImode, operands);
10257  DONE;
10258})
10259
10260(define_insn "ashlti3_1"
10261  [(set (match_operand:TI 0 "register_operand" "=r")
10262	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10263		   (match_operand:QI 2 "register_operand" "c")))
10264   (clobber (match_scratch:DI 3 "=&r"))
10265   (clobber (reg:CC FLAGS_REG))]
10266  "TARGET_64BIT"
10267  "#"
10268  [(set_attr "type" "multi")])
10269
10270(define_insn "*ashlti3_2"
10271  [(set (match_operand:TI 0 "register_operand" "=r")
10272	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10273		   (match_operand:QI 2 "immediate_operand" "O")))
10274   (clobber (reg:CC FLAGS_REG))]
10275  "TARGET_64BIT"
10276  "#"
10277  [(set_attr "type" "multi")])
10278
10279(define_split
10280  [(set (match_operand:TI 0 "register_operand" "")
10281	(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10282		   (match_operand:QI 2 "register_operand" "")))
10283   (clobber (match_scratch:DI 3 ""))
10284   (clobber (reg:CC FLAGS_REG))]
10285  "TARGET_64BIT && reload_completed"
10286  [(const_int 0)]
10287  "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10288
10289(define_split
10290  [(set (match_operand:TI 0 "register_operand" "")
10291	(ashift:TI (match_operand:TI 1 "register_operand" "")
10292		   (match_operand:QI 2 "immediate_operand" "")))
10293   (clobber (reg:CC FLAGS_REG))]
10294  "TARGET_64BIT && reload_completed"
10295  [(const_int 0)]
10296  "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10297
10298(define_insn "x86_64_shld"
10299  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10300        (ior:DI (ashift:DI (match_dup 0)
10301		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
10302		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10303		  (minus:QI (const_int 64) (match_dup 2)))))
10304   (clobber (reg:CC FLAGS_REG))]
10305  "TARGET_64BIT"
10306  "@
10307   shld{q}\t{%2, %1, %0|%0, %1, %2}
10308   shld{q}\t{%s2%1, %0|%0, %1, %2}"
10309  [(set_attr "type" "ishift")
10310   (set_attr "prefix_0f" "1")
10311   (set_attr "mode" "DI")
10312   (set_attr "athlon_decode" "vector")])
10313
10314(define_expand "x86_64_shift_adj"
10315  [(set (reg:CCZ FLAGS_REG)
10316	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10317			     (const_int 64))
10318		     (const_int 0)))
10319   (set (match_operand:DI 0 "register_operand" "")
10320        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10321			 (match_operand:DI 1 "register_operand" "")
10322			 (match_dup 0)))
10323   (set (match_dup 1)
10324	(if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10325			 (match_operand:DI 3 "register_operand" "r")
10326			 (match_dup 1)))]
10327  "TARGET_64BIT"
10328  "")
10329
10330(define_expand "ashldi3"
10331  [(set (match_operand:DI 0 "shiftdi_operand" "")
10332	(ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10333		   (match_operand:QI 2 "nonmemory_operand" "")))]
10334  ""
10335  "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10336
10337(define_insn "*ashldi3_1_rex64"
10338  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10339	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10340		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10341   (clobber (reg:CC FLAGS_REG))]
10342  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10343{
10344  switch (get_attr_type (insn))
10345    {
10346    case TYPE_ALU:
10347      gcc_assert (operands[2] == const1_rtx);
10348      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10349      return "add{q}\t{%0, %0|%0, %0}";
10350
10351    case TYPE_LEA:
10352      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10353      gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10354      operands[1] = gen_rtx_MULT (DImode, operands[1],
10355				  GEN_INT (1 << INTVAL (operands[2])));
10356      return "lea{q}\t{%a1, %0|%0, %a1}";
10357
10358    default:
10359      if (REG_P (operands[2]))
10360	return "sal{q}\t{%b2, %0|%0, %b2}";
10361      else if (operands[2] == const1_rtx
10362	       && (TARGET_SHIFT1 || optimize_size))
10363	return "sal{q}\t%0";
10364      else
10365	return "sal{q}\t{%2, %0|%0, %2}";
10366    }
10367}
10368  [(set (attr "type")
10369     (cond [(eq_attr "alternative" "1")
10370	      (const_string "lea")
10371            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10372		          (const_int 0))
10373		      (match_operand 0 "register_operand" ""))
10374		 (match_operand 2 "const1_operand" ""))
10375	      (const_string "alu")
10376	   ]
10377	   (const_string "ishift")))
10378   (set_attr "mode" "DI")])
10379
10380;; Convert lea to the lea pattern to avoid flags dependency.
10381(define_split
10382  [(set (match_operand:DI 0 "register_operand" "")
10383	(ashift:DI (match_operand:DI 1 "index_register_operand" "")
10384		   (match_operand:QI 2 "immediate_operand" "")))
10385   (clobber (reg:CC FLAGS_REG))]
10386  "TARGET_64BIT && reload_completed
10387   && true_regnum (operands[0]) != true_regnum (operands[1])"
10388  [(set (match_dup 0)
10389	(mult:DI (match_dup 1)
10390		 (match_dup 2)))]
10391  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10392
10393;; This pattern can't accept a variable shift count, since shifts by
10394;; zero don't affect the flags.  We assume that shifts by constant
10395;; zero are optimized away.
10396(define_insn "*ashldi3_cmp_rex64"
10397  [(set (reg FLAGS_REG)
10398	(compare
10399	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10400		     (match_operand:QI 2 "immediate_operand" "e"))
10401	  (const_int 0)))
10402   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10403	(ashift:DI (match_dup 1) (match_dup 2)))]
10404  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10405   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10406   && (optimize_size
10407       || !TARGET_PARTIAL_FLAG_REG_STALL
10408       || (operands[2] == const1_rtx
10409	   && (TARGET_SHIFT1
10410	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10411{
10412  switch (get_attr_type (insn))
10413    {
10414    case TYPE_ALU:
10415      gcc_assert (operands[2] == const1_rtx);
10416      return "add{q}\t{%0, %0|%0, %0}";
10417
10418    default:
10419      if (REG_P (operands[2]))
10420	return "sal{q}\t{%b2, %0|%0, %b2}";
10421      else if (operands[2] == const1_rtx
10422	       && (TARGET_SHIFT1 || optimize_size))
10423	return "sal{q}\t%0";
10424      else
10425	return "sal{q}\t{%2, %0|%0, %2}";
10426    }
10427}
10428  [(set (attr "type")
10429     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10430		          (const_int 0))
10431		      (match_operand 0 "register_operand" ""))
10432		 (match_operand 2 "const1_operand" ""))
10433	      (const_string "alu")
10434	   ]
10435	   (const_string "ishift")))
10436   (set_attr "mode" "DI")])
10437
10438(define_insn "*ashldi3_cconly_rex64"
10439  [(set (reg FLAGS_REG)
10440	(compare
10441	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10442		     (match_operand:QI 2 "immediate_operand" "e"))
10443	  (const_int 0)))
10444   (clobber (match_scratch:DI 0 "=r"))]
10445  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10446   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10447   && (optimize_size
10448       || !TARGET_PARTIAL_FLAG_REG_STALL
10449       || (operands[2] == const1_rtx
10450	   && (TARGET_SHIFT1
10451	       || TARGET_DOUBLE_WITH_ADD)))"
10452{
10453  switch (get_attr_type (insn))
10454    {
10455    case TYPE_ALU:
10456      gcc_assert (operands[2] == const1_rtx);
10457      return "add{q}\t{%0, %0|%0, %0}";
10458
10459    default:
10460      if (REG_P (operands[2]))
10461	return "sal{q}\t{%b2, %0|%0, %b2}";
10462      else if (operands[2] == const1_rtx
10463	       && (TARGET_SHIFT1 || optimize_size))
10464	return "sal{q}\t%0";
10465      else
10466	return "sal{q}\t{%2, %0|%0, %2}";
10467    }
10468}
10469  [(set (attr "type")
10470     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10471		          (const_int 0))
10472		      (match_operand 0 "register_operand" ""))
10473		 (match_operand 2 "const1_operand" ""))
10474	      (const_string "alu")
10475	   ]
10476	   (const_string "ishift")))
10477   (set_attr "mode" "DI")])
10478
10479(define_insn "*ashldi3_1"
10480  [(set (match_operand:DI 0 "register_operand" "=&r,r")
10481	(ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10482		   (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10483   (clobber (reg:CC FLAGS_REG))]
10484  "!TARGET_64BIT"
10485  "#"
10486  [(set_attr "type" "multi")])
10487
10488;; By default we don't ask for a scratch register, because when DImode
10489;; values are manipulated, registers are already at a premium.  But if
10490;; we have one handy, we won't turn it away.
10491(define_peephole2
10492  [(match_scratch:SI 3 "r")
10493   (parallel [(set (match_operand:DI 0 "register_operand" "")
10494		   (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10495			      (match_operand:QI 2 "nonmemory_operand" "")))
10496	      (clobber (reg:CC FLAGS_REG))])
10497   (match_dup 3)]
10498  "!TARGET_64BIT && TARGET_CMOVE"
10499  [(const_int 0)]
10500  "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10501
10502(define_split
10503  [(set (match_operand:DI 0 "register_operand" "")
10504	(ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10505		   (match_operand:QI 2 "nonmemory_operand" "")))
10506   (clobber (reg:CC FLAGS_REG))]
10507  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10508		     ? flow2_completed : reload_completed)"
10509  [(const_int 0)]
10510  "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10511
10512(define_insn "x86_shld_1"
10513  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10514        (ior:SI (ashift:SI (match_dup 0)
10515		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
10516		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10517		  (minus:QI (const_int 32) (match_dup 2)))))
10518   (clobber (reg:CC FLAGS_REG))]
10519  ""
10520  "@
10521   shld{l}\t{%2, %1, %0|%0, %1, %2}
10522   shld{l}\t{%s2%1, %0|%0, %1, %2}"
10523  [(set_attr "type" "ishift")
10524   (set_attr "prefix_0f" "1")
10525   (set_attr "mode" "SI")
10526   (set_attr "pent_pair" "np")
10527   (set_attr "athlon_decode" "vector")])
10528
10529(define_expand "x86_shift_adj_1"
10530  [(set (reg:CCZ FLAGS_REG)
10531	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10532			     (const_int 32))
10533		     (const_int 0)))
10534   (set (match_operand:SI 0 "register_operand" "")
10535        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10536			 (match_operand:SI 1 "register_operand" "")
10537			 (match_dup 0)))
10538   (set (match_dup 1)
10539	(if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10540			 (match_operand:SI 3 "register_operand" "r")
10541			 (match_dup 1)))]
10542  "TARGET_CMOVE"
10543  "")
10544
10545(define_expand "x86_shift_adj_2"
10546  [(use (match_operand:SI 0 "register_operand" ""))
10547   (use (match_operand:SI 1 "register_operand" ""))
10548   (use (match_operand:QI 2 "register_operand" ""))]
10549  ""
10550{
10551  rtx label = gen_label_rtx ();
10552  rtx tmp;
10553
10554  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10555
10556  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10557  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10558  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10559			      gen_rtx_LABEL_REF (VOIDmode, label),
10560			      pc_rtx);
10561  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10562  JUMP_LABEL (tmp) = label;
10563
10564  emit_move_insn (operands[0], operands[1]);
10565  ix86_expand_clear (operands[1]);
10566
10567  emit_label (label);
10568  LABEL_NUSES (label) = 1;
10569
10570  DONE;
10571})
10572
10573(define_expand "ashlsi3"
10574  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10575	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10576		   (match_operand:QI 2 "nonmemory_operand" "")))
10577   (clobber (reg:CC FLAGS_REG))]
10578  ""
10579  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10580
10581(define_insn "*ashlsi3_1"
10582  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10583	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10584		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10585   (clobber (reg:CC FLAGS_REG))]
10586  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10587{
10588  switch (get_attr_type (insn))
10589    {
10590    case TYPE_ALU:
10591      gcc_assert (operands[2] == const1_rtx);
10592      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10593      return "add{l}\t{%0, %0|%0, %0}";
10594
10595    case TYPE_LEA:
10596      return "#";
10597
10598    default:
10599      if (REG_P (operands[2]))
10600	return "sal{l}\t{%b2, %0|%0, %b2}";
10601      else if (operands[2] == const1_rtx
10602	       && (TARGET_SHIFT1 || optimize_size))
10603	return "sal{l}\t%0";
10604      else
10605	return "sal{l}\t{%2, %0|%0, %2}";
10606    }
10607}
10608  [(set (attr "type")
10609     (cond [(eq_attr "alternative" "1")
10610	      (const_string "lea")
10611            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10612		          (const_int 0))
10613		      (match_operand 0 "register_operand" ""))
10614		 (match_operand 2 "const1_operand" ""))
10615	      (const_string "alu")
10616	   ]
10617	   (const_string "ishift")))
10618   (set_attr "mode" "SI")])
10619
10620;; Convert lea to the lea pattern to avoid flags dependency.
10621(define_split
10622  [(set (match_operand 0 "register_operand" "")
10623	(ashift (match_operand 1 "index_register_operand" "")
10624                (match_operand:QI 2 "const_int_operand" "")))
10625   (clobber (reg:CC FLAGS_REG))]
10626  "reload_completed
10627   && true_regnum (operands[0]) != true_regnum (operands[1])
10628   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10629  [(const_int 0)]
10630{
10631  rtx pat;
10632  enum machine_mode mode = GET_MODE (operands[0]);
10633
10634  if (GET_MODE_SIZE (mode) < 4)
10635    operands[0] = gen_lowpart (SImode, operands[0]);
10636  if (mode != Pmode)
10637    operands[1] = gen_lowpart (Pmode, operands[1]);
10638  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10639
10640  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10641  if (Pmode != SImode)
10642    pat = gen_rtx_SUBREG (SImode, pat, 0);
10643  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10644  DONE;
10645})
10646
10647;; Rare case of shifting RSP is handled by generating move and shift
10648(define_split
10649  [(set (match_operand 0 "register_operand" "")
10650	(ashift (match_operand 1 "register_operand" "")
10651                (match_operand:QI 2 "const_int_operand" "")))
10652   (clobber (reg:CC FLAGS_REG))]
10653  "reload_completed
10654   && true_regnum (operands[0]) != true_regnum (operands[1])"
10655  [(const_int 0)]
10656{
10657  rtx pat, clob;
10658  emit_move_insn (operands[0], operands[1]);
10659  pat = gen_rtx_SET (VOIDmode, operands[0],
10660		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10661				     operands[0], operands[2]));
10662  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10663  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10664  DONE;
10665})
10666
10667(define_insn "*ashlsi3_1_zext"
10668  [(set (match_operand:DI 0 "register_operand" "=r,r")
10669	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10670			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10671   (clobber (reg:CC FLAGS_REG))]
10672  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10673{
10674  switch (get_attr_type (insn))
10675    {
10676    case TYPE_ALU:
10677      gcc_assert (operands[2] == const1_rtx);
10678      return "add{l}\t{%k0, %k0|%k0, %k0}";
10679
10680    case TYPE_LEA:
10681      return "#";
10682
10683    default:
10684      if (REG_P (operands[2]))
10685	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10686      else if (operands[2] == const1_rtx
10687	       && (TARGET_SHIFT1 || optimize_size))
10688	return "sal{l}\t%k0";
10689      else
10690	return "sal{l}\t{%2, %k0|%k0, %2}";
10691    }
10692}
10693  [(set (attr "type")
10694     (cond [(eq_attr "alternative" "1")
10695	      (const_string "lea")
10696            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10697		     (const_int 0))
10698		 (match_operand 2 "const1_operand" ""))
10699	      (const_string "alu")
10700	   ]
10701	   (const_string "ishift")))
10702   (set_attr "mode" "SI")])
10703
10704;; Convert lea to the lea pattern to avoid flags dependency.
10705(define_split
10706  [(set (match_operand:DI 0 "register_operand" "")
10707	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10708				(match_operand:QI 2 "const_int_operand" ""))))
10709   (clobber (reg:CC FLAGS_REG))]
10710  "TARGET_64BIT && reload_completed
10711   && true_regnum (operands[0]) != true_regnum (operands[1])"
10712  [(set (match_dup 0) (zero_extend:DI
10713			(subreg:SI (mult:SI (match_dup 1)
10714					    (match_dup 2)) 0)))]
10715{
10716  operands[1] = gen_lowpart (Pmode, operands[1]);
10717  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10718})
10719
10720;; This pattern can't accept a variable shift count, since shifts by
10721;; zero don't affect the flags.  We assume that shifts by constant
10722;; zero are optimized away.
10723(define_insn "*ashlsi3_cmp"
10724  [(set (reg FLAGS_REG)
10725	(compare
10726	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10727		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10728	  (const_int 0)))
10729   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10730	(ashift:SI (match_dup 1) (match_dup 2)))]
10731  "ix86_match_ccmode (insn, CCGOCmode)
10732   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10733   && (optimize_size
10734       || !TARGET_PARTIAL_FLAG_REG_STALL
10735       || (operands[2] == const1_rtx
10736	   && (TARGET_SHIFT1
10737	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10738{
10739  switch (get_attr_type (insn))
10740    {
10741    case TYPE_ALU:
10742      gcc_assert (operands[2] == const1_rtx);
10743      return "add{l}\t{%0, %0|%0, %0}";
10744
10745    default:
10746      if (REG_P (operands[2]))
10747	return "sal{l}\t{%b2, %0|%0, %b2}";
10748      else if (operands[2] == const1_rtx
10749	       && (TARGET_SHIFT1 || optimize_size))
10750	return "sal{l}\t%0";
10751      else
10752	return "sal{l}\t{%2, %0|%0, %2}";
10753    }
10754}
10755  [(set (attr "type")
10756     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10757		          (const_int 0))
10758		      (match_operand 0 "register_operand" ""))
10759		 (match_operand 2 "const1_operand" ""))
10760	      (const_string "alu")
10761	   ]
10762	   (const_string "ishift")))
10763   (set_attr "mode" "SI")])
10764
10765(define_insn "*ashlsi3_cconly"
10766  [(set (reg FLAGS_REG)
10767	(compare
10768	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10769		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10770	  (const_int 0)))
10771   (clobber (match_scratch:SI 0 "=r"))]
10772  "ix86_match_ccmode (insn, CCGOCmode)
10773   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10774   && (optimize_size
10775       || !TARGET_PARTIAL_FLAG_REG_STALL
10776       || (operands[2] == const1_rtx
10777	   && (TARGET_SHIFT1
10778	       || TARGET_DOUBLE_WITH_ADD)))"
10779{
10780  switch (get_attr_type (insn))
10781    {
10782    case TYPE_ALU:
10783      gcc_assert (operands[2] == const1_rtx);
10784      return "add{l}\t{%0, %0|%0, %0}";
10785
10786    default:
10787      if (REG_P (operands[2]))
10788	return "sal{l}\t{%b2, %0|%0, %b2}";
10789      else if (operands[2] == const1_rtx
10790	       && (TARGET_SHIFT1 || optimize_size))
10791	return "sal{l}\t%0";
10792      else
10793	return "sal{l}\t{%2, %0|%0, %2}";
10794    }
10795}
10796  [(set (attr "type")
10797     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10798		          (const_int 0))
10799		      (match_operand 0 "register_operand" ""))
10800		 (match_operand 2 "const1_operand" ""))
10801	      (const_string "alu")
10802	   ]
10803	   (const_string "ishift")))
10804   (set_attr "mode" "SI")])
10805
10806(define_insn "*ashlsi3_cmp_zext"
10807  [(set (reg FLAGS_REG)
10808	(compare
10809	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10810		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10811	  (const_int 0)))
10812   (set (match_operand:DI 0 "register_operand" "=r")
10813	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10814  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10815   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10816   && (optimize_size
10817       || !TARGET_PARTIAL_FLAG_REG_STALL
10818       || (operands[2] == const1_rtx
10819	   && (TARGET_SHIFT1
10820	       || TARGET_DOUBLE_WITH_ADD)))"
10821{
10822  switch (get_attr_type (insn))
10823    {
10824    case TYPE_ALU:
10825      gcc_assert (operands[2] == const1_rtx);
10826      return "add{l}\t{%k0, %k0|%k0, %k0}";
10827
10828    default:
10829      if (REG_P (operands[2]))
10830	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10831      else if (operands[2] == const1_rtx
10832	       && (TARGET_SHIFT1 || optimize_size))
10833	return "sal{l}\t%k0";
10834      else
10835	return "sal{l}\t{%2, %k0|%k0, %2}";
10836    }
10837}
10838  [(set (attr "type")
10839     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10840		     (const_int 0))
10841		 (match_operand 2 "const1_operand" ""))
10842	      (const_string "alu")
10843	   ]
10844	   (const_string "ishift")))
10845   (set_attr "mode" "SI")])
10846
10847(define_expand "ashlhi3"
10848  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10849	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10850		   (match_operand:QI 2 "nonmemory_operand" "")))
10851   (clobber (reg:CC FLAGS_REG))]
10852  "TARGET_HIMODE_MATH"
10853  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10854
10855(define_insn "*ashlhi3_1_lea"
10856  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10857	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10858		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10859   (clobber (reg:CC FLAGS_REG))]
10860  "!TARGET_PARTIAL_REG_STALL
10861   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10862{
10863  switch (get_attr_type (insn))
10864    {
10865    case TYPE_LEA:
10866      return "#";
10867    case TYPE_ALU:
10868      gcc_assert (operands[2] == const1_rtx);
10869      return "add{w}\t{%0, %0|%0, %0}";
10870
10871    default:
10872      if (REG_P (operands[2]))
10873	return "sal{w}\t{%b2, %0|%0, %b2}";
10874      else if (operands[2] == const1_rtx
10875	       && (TARGET_SHIFT1 || optimize_size))
10876	return "sal{w}\t%0";
10877      else
10878	return "sal{w}\t{%2, %0|%0, %2}";
10879    }
10880}
10881  [(set (attr "type")
10882     (cond [(eq_attr "alternative" "1")
10883	      (const_string "lea")
10884            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10885		          (const_int 0))
10886		      (match_operand 0 "register_operand" ""))
10887		 (match_operand 2 "const1_operand" ""))
10888	      (const_string "alu")
10889	   ]
10890	   (const_string "ishift")))
10891   (set_attr "mode" "HI,SI")])
10892
10893(define_insn "*ashlhi3_1"
10894  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10895	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10896		   (match_operand:QI 2 "nonmemory_operand" "cI")))
10897   (clobber (reg:CC FLAGS_REG))]
10898  "TARGET_PARTIAL_REG_STALL
10899   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10900{
10901  switch (get_attr_type (insn))
10902    {
10903    case TYPE_ALU:
10904      gcc_assert (operands[2] == const1_rtx);
10905      return "add{w}\t{%0, %0|%0, %0}";
10906
10907    default:
10908      if (REG_P (operands[2]))
10909	return "sal{w}\t{%b2, %0|%0, %b2}";
10910      else if (operands[2] == const1_rtx
10911	       && (TARGET_SHIFT1 || optimize_size))
10912	return "sal{w}\t%0";
10913      else
10914	return "sal{w}\t{%2, %0|%0, %2}";
10915    }
10916}
10917  [(set (attr "type")
10918     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10919		          (const_int 0))
10920		      (match_operand 0 "register_operand" ""))
10921		 (match_operand 2 "const1_operand" ""))
10922	      (const_string "alu")
10923	   ]
10924	   (const_string "ishift")))
10925   (set_attr "mode" "HI")])
10926
10927;; This pattern can't accept a variable shift count, since shifts by
10928;; zero don't affect the flags.  We assume that shifts by constant
10929;; zero are optimized away.
10930(define_insn "*ashlhi3_cmp"
10931  [(set (reg FLAGS_REG)
10932	(compare
10933	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10934		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10935	  (const_int 0)))
10936   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10937	(ashift:HI (match_dup 1) (match_dup 2)))]
10938  "ix86_match_ccmode (insn, CCGOCmode)
10939   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10940   && (optimize_size
10941       || !TARGET_PARTIAL_FLAG_REG_STALL
10942       || (operands[2] == const1_rtx
10943	   && (TARGET_SHIFT1
10944	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10945{
10946  switch (get_attr_type (insn))
10947    {
10948    case TYPE_ALU:
10949      gcc_assert (operands[2] == const1_rtx);
10950      return "add{w}\t{%0, %0|%0, %0}";
10951
10952    default:
10953      if (REG_P (operands[2]))
10954	return "sal{w}\t{%b2, %0|%0, %b2}";
10955      else if (operands[2] == const1_rtx
10956	       && (TARGET_SHIFT1 || optimize_size))
10957	return "sal{w}\t%0";
10958      else
10959	return "sal{w}\t{%2, %0|%0, %2}";
10960    }
10961}
10962  [(set (attr "type")
10963     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10964		          (const_int 0))
10965		      (match_operand 0 "register_operand" ""))
10966		 (match_operand 2 "const1_operand" ""))
10967	      (const_string "alu")
10968	   ]
10969	   (const_string "ishift")))
10970   (set_attr "mode" "HI")])
10971
10972(define_insn "*ashlhi3_cconly"
10973  [(set (reg FLAGS_REG)
10974	(compare
10975	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10976		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10977	  (const_int 0)))
10978   (clobber (match_scratch:HI 0 "=r"))]
10979  "ix86_match_ccmode (insn, CCGOCmode)
10980   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10981   && (optimize_size
10982       || !TARGET_PARTIAL_FLAG_REG_STALL
10983       || (operands[2] == const1_rtx
10984	   && (TARGET_SHIFT1
10985	       || TARGET_DOUBLE_WITH_ADD)))"
10986{
10987  switch (get_attr_type (insn))
10988    {
10989    case TYPE_ALU:
10990      gcc_assert (operands[2] == const1_rtx);
10991      return "add{w}\t{%0, %0|%0, %0}";
10992
10993    default:
10994      if (REG_P (operands[2]))
10995	return "sal{w}\t{%b2, %0|%0, %b2}";
10996      else if (operands[2] == const1_rtx
10997	       && (TARGET_SHIFT1 || optimize_size))
10998	return "sal{w}\t%0";
10999      else
11000	return "sal{w}\t{%2, %0|%0, %2}";
11001    }
11002}
11003  [(set (attr "type")
11004     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11005		          (const_int 0))
11006		      (match_operand 0 "register_operand" ""))
11007		 (match_operand 2 "const1_operand" ""))
11008	      (const_string "alu")
11009	   ]
11010	   (const_string "ishift")))
11011   (set_attr "mode" "HI")])
11012
11013(define_expand "ashlqi3"
11014  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11015	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11016		   (match_operand:QI 2 "nonmemory_operand" "")))
11017   (clobber (reg:CC FLAGS_REG))]
11018  "TARGET_QIMODE_MATH"
11019  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11020
11021;; %%% Potential partial reg stall on alternative 2.  What to do?
11022
11023(define_insn "*ashlqi3_1_lea"
11024  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11025	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11026		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11027   (clobber (reg:CC FLAGS_REG))]
11028  "!TARGET_PARTIAL_REG_STALL
11029   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11030{
11031  switch (get_attr_type (insn))
11032    {
11033    case TYPE_LEA:
11034      return "#";
11035    case TYPE_ALU:
11036      gcc_assert (operands[2] == const1_rtx);
11037      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11038        return "add{l}\t{%k0, %k0|%k0, %k0}";
11039      else
11040        return "add{b}\t{%0, %0|%0, %0}";
11041
11042    default:
11043      if (REG_P (operands[2]))
11044	{
11045	  if (get_attr_mode (insn) == MODE_SI)
11046	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11047	  else
11048	    return "sal{b}\t{%b2, %0|%0, %b2}";
11049	}
11050      else if (operands[2] == const1_rtx
11051	       && (TARGET_SHIFT1 || optimize_size))
11052	{
11053	  if (get_attr_mode (insn) == MODE_SI)
11054	    return "sal{l}\t%0";
11055	  else
11056	    return "sal{b}\t%0";
11057	}
11058      else
11059	{
11060	  if (get_attr_mode (insn) == MODE_SI)
11061	    return "sal{l}\t{%2, %k0|%k0, %2}";
11062	  else
11063	    return "sal{b}\t{%2, %0|%0, %2}";
11064	}
11065    }
11066}
11067  [(set (attr "type")
11068     (cond [(eq_attr "alternative" "2")
11069	      (const_string "lea")
11070            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11071		          (const_int 0))
11072		      (match_operand 0 "register_operand" ""))
11073		 (match_operand 2 "const1_operand" ""))
11074	      (const_string "alu")
11075	   ]
11076	   (const_string "ishift")))
11077   (set_attr "mode" "QI,SI,SI")])
11078
11079(define_insn "*ashlqi3_1"
11080  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11081	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11082		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11083   (clobber (reg:CC FLAGS_REG))]
11084  "TARGET_PARTIAL_REG_STALL
11085   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11086{
11087  switch (get_attr_type (insn))
11088    {
11089    case TYPE_ALU:
11090      gcc_assert (operands[2] == const1_rtx);
11091      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11092        return "add{l}\t{%k0, %k0|%k0, %k0}";
11093      else
11094        return "add{b}\t{%0, %0|%0, %0}";
11095
11096    default:
11097      if (REG_P (operands[2]))
11098	{
11099	  if (get_attr_mode (insn) == MODE_SI)
11100	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11101	  else
11102	    return "sal{b}\t{%b2, %0|%0, %b2}";
11103	}
11104      else if (operands[2] == const1_rtx
11105	       && (TARGET_SHIFT1 || optimize_size))
11106	{
11107	  if (get_attr_mode (insn) == MODE_SI)
11108	    return "sal{l}\t%0";
11109	  else
11110	    return "sal{b}\t%0";
11111	}
11112      else
11113	{
11114	  if (get_attr_mode (insn) == MODE_SI)
11115	    return "sal{l}\t{%2, %k0|%k0, %2}";
11116	  else
11117	    return "sal{b}\t{%2, %0|%0, %2}";
11118	}
11119    }
11120}
11121  [(set (attr "type")
11122     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11123		          (const_int 0))
11124		      (match_operand 0 "register_operand" ""))
11125		 (match_operand 2 "const1_operand" ""))
11126	      (const_string "alu")
11127	   ]
11128	   (const_string "ishift")))
11129   (set_attr "mode" "QI,SI")])
11130
11131;; This pattern can't accept a variable shift count, since shifts by
11132;; zero don't affect the flags.  We assume that shifts by constant
11133;; zero are optimized away.
11134(define_insn "*ashlqi3_cmp"
11135  [(set (reg FLAGS_REG)
11136	(compare
11137	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11138		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11139	  (const_int 0)))
11140   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11141	(ashift:QI (match_dup 1) (match_dup 2)))]
11142  "ix86_match_ccmode (insn, CCGOCmode)
11143   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11144   && (optimize_size
11145       || !TARGET_PARTIAL_FLAG_REG_STALL
11146       || (operands[2] == const1_rtx
11147	   && (TARGET_SHIFT1
11148	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11149{
11150  switch (get_attr_type (insn))
11151    {
11152    case TYPE_ALU:
11153      gcc_assert (operands[2] == const1_rtx);
11154      return "add{b}\t{%0, %0|%0, %0}";
11155
11156    default:
11157      if (REG_P (operands[2]))
11158	return "sal{b}\t{%b2, %0|%0, %b2}";
11159      else if (operands[2] == const1_rtx
11160	       && (TARGET_SHIFT1 || optimize_size))
11161	return "sal{b}\t%0";
11162      else
11163	return "sal{b}\t{%2, %0|%0, %2}";
11164    }
11165}
11166  [(set (attr "type")
11167     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11168		          (const_int 0))
11169		      (match_operand 0 "register_operand" ""))
11170		 (match_operand 2 "const1_operand" ""))
11171	      (const_string "alu")
11172	   ]
11173	   (const_string "ishift")))
11174   (set_attr "mode" "QI")])
11175
11176(define_insn "*ashlqi3_cconly"
11177  [(set (reg FLAGS_REG)
11178	(compare
11179	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11180		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11181	  (const_int 0)))
11182   (clobber (match_scratch:QI 0 "=q"))]
11183  "ix86_match_ccmode (insn, CCGOCmode)
11184   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11185   && (optimize_size
11186       || !TARGET_PARTIAL_FLAG_REG_STALL
11187       || (operands[2] == const1_rtx
11188	   && (TARGET_SHIFT1
11189	       || TARGET_DOUBLE_WITH_ADD)))"
11190{
11191  switch (get_attr_type (insn))
11192    {
11193    case TYPE_ALU:
11194      gcc_assert (operands[2] == const1_rtx);
11195      return "add{b}\t{%0, %0|%0, %0}";
11196
11197    default:
11198      if (REG_P (operands[2]))
11199	return "sal{b}\t{%b2, %0|%0, %b2}";
11200      else if (operands[2] == const1_rtx
11201	       && (TARGET_SHIFT1 || optimize_size))
11202	return "sal{b}\t%0";
11203      else
11204	return "sal{b}\t{%2, %0|%0, %2}";
11205    }
11206}
11207  [(set (attr "type")
11208     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11209		          (const_int 0))
11210		      (match_operand 0 "register_operand" ""))
11211		 (match_operand 2 "const1_operand" ""))
11212	      (const_string "alu")
11213	   ]
11214	   (const_string "ishift")))
11215   (set_attr "mode" "QI")])
11216
11217;; See comment above `ashldi3' about how this works.
11218
11219(define_expand "ashrti3"
11220  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11221		   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11222				(match_operand:QI 2 "nonmemory_operand" "")))
11223	      (clobber (reg:CC FLAGS_REG))])]
11224  "TARGET_64BIT"
11225{
11226  if (! immediate_operand (operands[2], QImode))
11227    {
11228      emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11229      DONE;
11230    }
11231  ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11232  DONE;
11233})
11234
11235(define_insn "ashrti3_1"
11236  [(set (match_operand:TI 0 "register_operand" "=r")
11237	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11238		     (match_operand:QI 2 "register_operand" "c")))
11239   (clobber (match_scratch:DI 3 "=&r"))
11240   (clobber (reg:CC FLAGS_REG))]
11241  "TARGET_64BIT"
11242  "#"
11243  [(set_attr "type" "multi")])
11244
11245(define_insn "*ashrti3_2"
11246  [(set (match_operand:TI 0 "register_operand" "=r")
11247	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11248		     (match_operand:QI 2 "immediate_operand" "O")))
11249   (clobber (reg:CC FLAGS_REG))]
11250  "TARGET_64BIT"
11251  "#"
11252  [(set_attr "type" "multi")])
11253
11254(define_split
11255  [(set (match_operand:TI 0 "register_operand" "")
11256	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11257		     (match_operand:QI 2 "register_operand" "")))
11258   (clobber (match_scratch:DI 3 ""))
11259   (clobber (reg:CC FLAGS_REG))]
11260  "TARGET_64BIT && reload_completed"
11261  [(const_int 0)]
11262  "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11263
11264(define_split
11265  [(set (match_operand:TI 0 "register_operand" "")
11266	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11267		     (match_operand:QI 2 "immediate_operand" "")))
11268   (clobber (reg:CC FLAGS_REG))]
11269  "TARGET_64BIT && reload_completed"
11270  [(const_int 0)]
11271  "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11272
11273(define_insn "x86_64_shrd"
11274  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11275        (ior:DI (ashiftrt:DI (match_dup 0)
11276		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
11277		(ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11278		  (minus:QI (const_int 64) (match_dup 2)))))
11279   (clobber (reg:CC FLAGS_REG))]
11280  "TARGET_64BIT"
11281  "@
11282   shrd{q}\t{%2, %1, %0|%0, %1, %2}
11283   shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11284  [(set_attr "type" "ishift")
11285   (set_attr "prefix_0f" "1")
11286   (set_attr "mode" "DI")
11287   (set_attr "athlon_decode" "vector")])
11288
11289(define_expand "ashrdi3"
11290  [(set (match_operand:DI 0 "shiftdi_operand" "")
11291	(ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11292		     (match_operand:QI 2 "nonmemory_operand" "")))]
11293  ""
11294  "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11295
11296(define_insn "*ashrdi3_63_rex64"
11297  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11298	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11299		     (match_operand:DI 2 "const_int_operand" "i,i")))
11300   (clobber (reg:CC FLAGS_REG))]
11301  "TARGET_64BIT && INTVAL (operands[2]) == 63
11302   && (TARGET_USE_CLTD || optimize_size)
11303   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11304  "@
11305   {cqto|cqo}
11306   sar{q}\t{%2, %0|%0, %2}"
11307  [(set_attr "type" "imovx,ishift")
11308   (set_attr "prefix_0f" "0,*")
11309   (set_attr "length_immediate" "0,*")
11310   (set_attr "modrm" "0,1")
11311   (set_attr "mode" "DI")])
11312
11313(define_insn "*ashrdi3_1_one_bit_rex64"
11314  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11315	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11316		     (match_operand:QI 2 "const1_operand" "")))
11317   (clobber (reg:CC FLAGS_REG))]
11318  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11319   && (TARGET_SHIFT1 || optimize_size)"
11320  "sar{q}\t%0"
11321  [(set_attr "type" "ishift")
11322   (set (attr "length") 
11323     (if_then_else (match_operand:DI 0 "register_operand" "") 
11324	(const_string "2")
11325	(const_string "*")))])
11326
11327(define_insn "*ashrdi3_1_rex64"
11328  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11329	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11330		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11331   (clobber (reg:CC FLAGS_REG))]
11332  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11333  "@
11334   sar{q}\t{%2, %0|%0, %2}
11335   sar{q}\t{%b2, %0|%0, %b2}"
11336  [(set_attr "type" "ishift")
11337   (set_attr "mode" "DI")])
11338
11339;; This pattern can't accept a variable shift count, since shifts by
11340;; zero don't affect the flags.  We assume that shifts by constant
11341;; zero are optimized away.
11342(define_insn "*ashrdi3_one_bit_cmp_rex64"
11343  [(set (reg FLAGS_REG)
11344	(compare
11345	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11346		       (match_operand:QI 2 "const1_operand" ""))
11347	  (const_int 0)))
11348   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11349	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11350  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11351   && (TARGET_SHIFT1 || optimize_size)
11352   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353  "sar{q}\t%0"
11354  [(set_attr "type" "ishift")
11355   (set (attr "length") 
11356     (if_then_else (match_operand:DI 0 "register_operand" "") 
11357	(const_string "2")
11358	(const_string "*")))])
11359
11360(define_insn "*ashrdi3_one_bit_cconly_rex64"
11361  [(set (reg FLAGS_REG)
11362	(compare
11363	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11364		       (match_operand:QI 2 "const1_operand" ""))
11365	  (const_int 0)))
11366   (clobber (match_scratch:DI 0 "=r"))]
11367  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11368   && (TARGET_SHIFT1 || optimize_size)
11369   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11370  "sar{q}\t%0"
11371  [(set_attr "type" "ishift")
11372   (set_attr "length" "2")])
11373
11374;; This pattern can't accept a variable shift count, since shifts by
11375;; zero don't affect the flags.  We assume that shifts by constant
11376;; zero are optimized away.
11377(define_insn "*ashrdi3_cmp_rex64"
11378  [(set (reg FLAGS_REG)
11379	(compare
11380	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11381		       (match_operand:QI 2 "const_int_operand" "n"))
11382	  (const_int 0)))
11383   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11384	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11385  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11386   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11387   && (optimize_size
11388       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11389  "sar{q}\t{%2, %0|%0, %2}"
11390  [(set_attr "type" "ishift")
11391   (set_attr "mode" "DI")])
11392
11393(define_insn "*ashrdi3_cconly_rex64"
11394  [(set (reg FLAGS_REG)
11395	(compare
11396	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11397		       (match_operand:QI 2 "const_int_operand" "n"))
11398	  (const_int 0)))
11399   (clobber (match_scratch:DI 0 "=r"))]
11400  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11401   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11402   && (optimize_size
11403       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11404  "sar{q}\t{%2, %0|%0, %2}"
11405  [(set_attr "type" "ishift")
11406   (set_attr "mode" "DI")])
11407
11408(define_insn "*ashrdi3_1"
11409  [(set (match_operand:DI 0 "register_operand" "=r")
11410	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11411		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11412   (clobber (reg:CC FLAGS_REG))]
11413  "!TARGET_64BIT"
11414  "#"
11415  [(set_attr "type" "multi")])
11416
11417;; By default we don't ask for a scratch register, because when DImode
11418;; values are manipulated, registers are already at a premium.  But if
11419;; we have one handy, we won't turn it away.
11420(define_peephole2
11421  [(match_scratch:SI 3 "r")
11422   (parallel [(set (match_operand:DI 0 "register_operand" "")
11423		   (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11424			        (match_operand:QI 2 "nonmemory_operand" "")))
11425	      (clobber (reg:CC FLAGS_REG))])
11426   (match_dup 3)]
11427  "!TARGET_64BIT && TARGET_CMOVE"
11428  [(const_int 0)]
11429  "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11430
11431(define_split
11432  [(set (match_operand:DI 0 "register_operand" "")
11433	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11434		     (match_operand:QI 2 "nonmemory_operand" "")))
11435   (clobber (reg:CC FLAGS_REG))]
11436  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11437		     ? flow2_completed : reload_completed)"
11438  [(const_int 0)]
11439  "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11440
11441(define_insn "x86_shrd_1"
11442  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11443        (ior:SI (ashiftrt:SI (match_dup 0)
11444		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
11445		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11446		  (minus:QI (const_int 32) (match_dup 2)))))
11447   (clobber (reg:CC FLAGS_REG))]
11448  ""
11449  "@
11450   shrd{l}\t{%2, %1, %0|%0, %1, %2}
11451   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11452  [(set_attr "type" "ishift")
11453   (set_attr "prefix_0f" "1")
11454   (set_attr "pent_pair" "np")
11455   (set_attr "mode" "SI")])
11456
11457(define_expand "x86_shift_adj_3"
11458  [(use (match_operand:SI 0 "register_operand" ""))
11459   (use (match_operand:SI 1 "register_operand" ""))
11460   (use (match_operand:QI 2 "register_operand" ""))]
11461  ""
11462{
11463  rtx label = gen_label_rtx ();
11464  rtx tmp;
11465
11466  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11467
11468  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11469  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11470  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11471			      gen_rtx_LABEL_REF (VOIDmode, label),
11472			      pc_rtx);
11473  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11474  JUMP_LABEL (tmp) = label;
11475
11476  emit_move_insn (operands[0], operands[1]);
11477  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11478
11479  emit_label (label);
11480  LABEL_NUSES (label) = 1;
11481
11482  DONE;
11483})
11484
11485(define_insn "ashrsi3_31"
11486  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11487	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11488		     (match_operand:SI 2 "const_int_operand" "i,i")))
11489   (clobber (reg:CC FLAGS_REG))]
11490  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11491   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11492  "@
11493   {cltd|cdq}
11494   sar{l}\t{%2, %0|%0, %2}"
11495  [(set_attr "type" "imovx,ishift")
11496   (set_attr "prefix_0f" "0,*")
11497   (set_attr "length_immediate" "0,*")
11498   (set_attr "modrm" "0,1")
11499   (set_attr "mode" "SI")])
11500
11501(define_insn "*ashrsi3_31_zext"
11502  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11503	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11504				     (match_operand:SI 2 "const_int_operand" "i,i"))))
11505   (clobber (reg:CC FLAGS_REG))]
11506  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11507   && INTVAL (operands[2]) == 31
11508   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11509  "@
11510   {cltd|cdq}
11511   sar{l}\t{%2, %k0|%k0, %2}"
11512  [(set_attr "type" "imovx,ishift")
11513   (set_attr "prefix_0f" "0,*")
11514   (set_attr "length_immediate" "0,*")
11515   (set_attr "modrm" "0,1")
11516   (set_attr "mode" "SI")])
11517
11518(define_expand "ashrsi3"
11519  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11520	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11521		     (match_operand:QI 2 "nonmemory_operand" "")))
11522   (clobber (reg:CC FLAGS_REG))]
11523  ""
11524  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11525
11526(define_insn "*ashrsi3_1_one_bit"
11527  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11528	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11529		     (match_operand:QI 2 "const1_operand" "")))
11530   (clobber (reg:CC FLAGS_REG))]
11531  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11532   && (TARGET_SHIFT1 || optimize_size)"
11533  "sar{l}\t%0"
11534  [(set_attr "type" "ishift")
11535   (set (attr "length") 
11536     (if_then_else (match_operand:SI 0 "register_operand" "") 
11537	(const_string "2")
11538	(const_string "*")))])
11539
11540(define_insn "*ashrsi3_1_one_bit_zext"
11541  [(set (match_operand:DI 0 "register_operand" "=r")
11542	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11543				     (match_operand:QI 2 "const1_operand" ""))))
11544   (clobber (reg:CC FLAGS_REG))]
11545  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11546   && (TARGET_SHIFT1 || optimize_size)"
11547  "sar{l}\t%k0"
11548  [(set_attr "type" "ishift")
11549   (set_attr "length" "2")])
11550
11551(define_insn "*ashrsi3_1"
11552  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11553	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11554		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11555   (clobber (reg:CC FLAGS_REG))]
11556  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11557  "@
11558   sar{l}\t{%2, %0|%0, %2}
11559   sar{l}\t{%b2, %0|%0, %b2}"
11560  [(set_attr "type" "ishift")
11561   (set_attr "mode" "SI")])
11562
11563(define_insn "*ashrsi3_1_zext"
11564  [(set (match_operand:DI 0 "register_operand" "=r,r")
11565	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11566				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11567   (clobber (reg:CC FLAGS_REG))]
11568  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11569  "@
11570   sar{l}\t{%2, %k0|%k0, %2}
11571   sar{l}\t{%b2, %k0|%k0, %b2}"
11572  [(set_attr "type" "ishift")
11573   (set_attr "mode" "SI")])
11574
11575;; This pattern can't accept a variable shift count, since shifts by
11576;; zero don't affect the flags.  We assume that shifts by constant
11577;; zero are optimized away.
11578(define_insn "*ashrsi3_one_bit_cmp"
11579  [(set (reg FLAGS_REG)
11580	(compare
11581	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11582		       (match_operand:QI 2 "const1_operand" ""))
11583	  (const_int 0)))
11584   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11585	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11586  "ix86_match_ccmode (insn, CCGOCmode)
11587   && (TARGET_SHIFT1 || optimize_size)
11588   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11589  "sar{l}\t%0"
11590  [(set_attr "type" "ishift")
11591   (set (attr "length") 
11592     (if_then_else (match_operand:SI 0 "register_operand" "") 
11593	(const_string "2")
11594	(const_string "*")))])
11595
11596(define_insn "*ashrsi3_one_bit_cconly"
11597  [(set (reg FLAGS_REG)
11598	(compare
11599	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11600		       (match_operand:QI 2 "const1_operand" ""))
11601	  (const_int 0)))
11602   (clobber (match_scratch:SI 0 "=r"))]
11603  "ix86_match_ccmode (insn, CCGOCmode)
11604   && (TARGET_SHIFT1 || optimize_size)
11605   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606  "sar{l}\t%0"
11607  [(set_attr "type" "ishift")
11608   (set_attr "length" "2")])
11609
11610(define_insn "*ashrsi3_one_bit_cmp_zext"
11611  [(set (reg FLAGS_REG)
11612	(compare
11613	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11614		       (match_operand:QI 2 "const1_operand" ""))
11615	  (const_int 0)))
11616   (set (match_operand:DI 0 "register_operand" "=r")
11617	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11618  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11619   && (TARGET_SHIFT1 || optimize_size)
11620   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11621  "sar{l}\t%k0"
11622  [(set_attr "type" "ishift")
11623   (set_attr "length" "2")])
11624
11625;; This pattern can't accept a variable shift count, since shifts by
11626;; zero don't affect the flags.  We assume that shifts by constant
11627;; zero are optimized away.
11628(define_insn "*ashrsi3_cmp"
11629  [(set (reg FLAGS_REG)
11630	(compare
11631	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11632		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11633	  (const_int 0)))
11634   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11635	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11636  "ix86_match_ccmode (insn, CCGOCmode)
11637   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11638   && (optimize_size
11639       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11640  "sar{l}\t{%2, %0|%0, %2}"
11641  [(set_attr "type" "ishift")
11642   (set_attr "mode" "SI")])
11643
11644(define_insn "*ashrsi3_cconly"
11645  [(set (reg FLAGS_REG)
11646	(compare
11647	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11648		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11649	  (const_int 0)))
11650   (clobber (match_scratch:SI 0 "=r"))]
11651  "ix86_match_ccmode (insn, CCGOCmode)
11652   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11653   && (optimize_size
11654       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11655  "sar{l}\t{%2, %0|%0, %2}"
11656  [(set_attr "type" "ishift")
11657   (set_attr "mode" "SI")])
11658
11659(define_insn "*ashrsi3_cmp_zext"
11660  [(set (reg FLAGS_REG)
11661	(compare
11662	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11663		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11664	  (const_int 0)))
11665   (set (match_operand:DI 0 "register_operand" "=r")
11666	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11667  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11668   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11669   && (optimize_size
11670       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11671  "sar{l}\t{%2, %k0|%k0, %2}"
11672  [(set_attr "type" "ishift")
11673   (set_attr "mode" "SI")])
11674
11675(define_expand "ashrhi3"
11676  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11677	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11678		     (match_operand:QI 2 "nonmemory_operand" "")))
11679   (clobber (reg:CC FLAGS_REG))]
11680  "TARGET_HIMODE_MATH"
11681  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11682
11683(define_insn "*ashrhi3_1_one_bit"
11684  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11685	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11686		     (match_operand:QI 2 "const1_operand" "")))
11687   (clobber (reg:CC FLAGS_REG))]
11688  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11689   && (TARGET_SHIFT1 || optimize_size)"
11690  "sar{w}\t%0"
11691  [(set_attr "type" "ishift")
11692   (set (attr "length") 
11693     (if_then_else (match_operand 0 "register_operand" "") 
11694	(const_string "2")
11695	(const_string "*")))])
11696
11697(define_insn "*ashrhi3_1"
11698  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11699	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11700		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11701   (clobber (reg:CC FLAGS_REG))]
11702  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11703  "@
11704   sar{w}\t{%2, %0|%0, %2}
11705   sar{w}\t{%b2, %0|%0, %b2}"
11706  [(set_attr "type" "ishift")
11707   (set_attr "mode" "HI")])
11708
11709;; This pattern can't accept a variable shift count, since shifts by
11710;; zero don't affect the flags.  We assume that shifts by constant
11711;; zero are optimized away.
11712(define_insn "*ashrhi3_one_bit_cmp"
11713  [(set (reg FLAGS_REG)
11714	(compare
11715	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11716		       (match_operand:QI 2 "const1_operand" ""))
11717	  (const_int 0)))
11718   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11719	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11720  "ix86_match_ccmode (insn, CCGOCmode)
11721   && (TARGET_SHIFT1 || optimize_size)
11722   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11723  "sar{w}\t%0"
11724  [(set_attr "type" "ishift")
11725   (set (attr "length") 
11726     (if_then_else (match_operand 0 "register_operand" "") 
11727	(const_string "2")
11728	(const_string "*")))])
11729
11730(define_insn "*ashrhi3_one_bit_cconly"
11731  [(set (reg FLAGS_REG)
11732	(compare
11733	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11734		       (match_operand:QI 2 "const1_operand" ""))
11735	  (const_int 0)))
11736   (clobber (match_scratch:HI 0 "=r"))]
11737  "ix86_match_ccmode (insn, CCGOCmode)
11738   && (TARGET_SHIFT1 || optimize_size)
11739   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11740  "sar{w}\t%0"
11741  [(set_attr "type" "ishift")
11742   (set_attr "length" "2")])
11743
11744;; This pattern can't accept a variable shift count, since shifts by
11745;; zero don't affect the flags.  We assume that shifts by constant
11746;; zero are optimized away.
11747(define_insn "*ashrhi3_cmp"
11748  [(set (reg FLAGS_REG)
11749	(compare
11750	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11751		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11752	  (const_int 0)))
11753   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11754	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11755  "ix86_match_ccmode (insn, CCGOCmode)
11756   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11757   && (optimize_size
11758       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11759  "sar{w}\t{%2, %0|%0, %2}"
11760  [(set_attr "type" "ishift")
11761   (set_attr "mode" "HI")])
11762
11763(define_insn "*ashrhi3_cconly"
11764  [(set (reg FLAGS_REG)
11765	(compare
11766	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11767		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11768	  (const_int 0)))
11769   (clobber (match_scratch:HI 0 "=r"))]
11770  "ix86_match_ccmode (insn, CCGOCmode)
11771   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11772   && (optimize_size
11773       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11774  "sar{w}\t{%2, %0|%0, %2}"
11775  [(set_attr "type" "ishift")
11776   (set_attr "mode" "HI")])
11777
11778(define_expand "ashrqi3"
11779  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11780	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11781		     (match_operand:QI 2 "nonmemory_operand" "")))
11782   (clobber (reg:CC FLAGS_REG))]
11783  "TARGET_QIMODE_MATH"
11784  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11785
11786(define_insn "*ashrqi3_1_one_bit"
11787  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11788	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11789		     (match_operand:QI 2 "const1_operand" "")))
11790   (clobber (reg:CC FLAGS_REG))]
11791  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11792   && (TARGET_SHIFT1 || optimize_size)"
11793  "sar{b}\t%0"
11794  [(set_attr "type" "ishift")
11795   (set (attr "length") 
11796     (if_then_else (match_operand 0 "register_operand" "") 
11797	(const_string "2")
11798	(const_string "*")))])
11799
11800(define_insn "*ashrqi3_1_one_bit_slp"
11801  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11802	(ashiftrt:QI (match_dup 0)
11803		     (match_operand:QI 1 "const1_operand" "")))
11804   (clobber (reg:CC FLAGS_REG))]
11805  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11806   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11807   && (TARGET_SHIFT1 || optimize_size)"
11808  "sar{b}\t%0"
11809  [(set_attr "type" "ishift1")
11810   (set (attr "length") 
11811     (if_then_else (match_operand 0 "register_operand" "") 
11812	(const_string "2")
11813	(const_string "*")))])
11814
11815(define_insn "*ashrqi3_1"
11816  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11817	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11818		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11819   (clobber (reg:CC FLAGS_REG))]
11820  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11821  "@
11822   sar{b}\t{%2, %0|%0, %2}
11823   sar{b}\t{%b2, %0|%0, %b2}"
11824  [(set_attr "type" "ishift")
11825   (set_attr "mode" "QI")])
11826
11827(define_insn "*ashrqi3_1_slp"
11828  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11829	(ashiftrt:QI (match_dup 0)
11830		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11831   (clobber (reg:CC FLAGS_REG))]
11832  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11833   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11834  "@
11835   sar{b}\t{%1, %0|%0, %1}
11836   sar{b}\t{%b1, %0|%0, %b1}"
11837  [(set_attr "type" "ishift1")
11838   (set_attr "mode" "QI")])
11839
11840;; This pattern can't accept a variable shift count, since shifts by
11841;; zero don't affect the flags.  We assume that shifts by constant
11842;; zero are optimized away.
11843(define_insn "*ashrqi3_one_bit_cmp"
11844  [(set (reg FLAGS_REG)
11845	(compare
11846	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11847		       (match_operand:QI 2 "const1_operand" "I"))
11848	  (const_int 0)))
11849   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11850	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11851  "ix86_match_ccmode (insn, CCGOCmode)
11852   && (TARGET_SHIFT1 || optimize_size)
11853   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11854  "sar{b}\t%0"
11855  [(set_attr "type" "ishift")
11856   (set (attr "length") 
11857     (if_then_else (match_operand 0 "register_operand" "") 
11858	(const_string "2")
11859	(const_string "*")))])
11860
11861(define_insn "*ashrqi3_one_bit_cconly"
11862  [(set (reg FLAGS_REG)
11863	(compare
11864	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11865		       (match_operand:QI 2 "const1_operand" "I"))
11866	  (const_int 0)))
11867   (clobber (match_scratch:QI 0 "=q"))]
11868  "ix86_match_ccmode (insn, CCGOCmode)
11869   && (TARGET_SHIFT1 || optimize_size)
11870   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11871  "sar{b}\t%0"
11872  [(set_attr "type" "ishift")
11873   (set_attr "length" "2")])
11874
11875;; This pattern can't accept a variable shift count, since shifts by
11876;; zero don't affect the flags.  We assume that shifts by constant
11877;; zero are optimized away.
11878(define_insn "*ashrqi3_cmp"
11879  [(set (reg FLAGS_REG)
11880	(compare
11881	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11882		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11883	  (const_int 0)))
11884   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11885	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11886  "ix86_match_ccmode (insn, CCGOCmode)
11887   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11888   && (optimize_size
11889       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11890  "sar{b}\t{%2, %0|%0, %2}"
11891  [(set_attr "type" "ishift")
11892   (set_attr "mode" "QI")])
11893
11894(define_insn "*ashrqi3_cconly"
11895  [(set (reg FLAGS_REG)
11896	(compare
11897	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11898		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11899	  (const_int 0)))
11900   (clobber (match_scratch:QI 0 "=q"))]
11901  "ix86_match_ccmode (insn, CCGOCmode)
11902   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11903   && (optimize_size
11904       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11905  "sar{b}\t{%2, %0|%0, %2}"
11906  [(set_attr "type" "ishift")
11907   (set_attr "mode" "QI")])
11908
11909
11910;; Logical shift instructions
11911
11912;; See comment above `ashldi3' about how this works.
11913
11914(define_expand "lshrti3"
11915  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11916		   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11917			        (match_operand:QI 2 "nonmemory_operand" "")))
11918	      (clobber (reg:CC FLAGS_REG))])]
11919  "TARGET_64BIT"
11920{
11921  if (! immediate_operand (operands[2], QImode))
11922    {
11923      emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11924      DONE;
11925    }
11926  ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11927  DONE;
11928})
11929
11930(define_insn "lshrti3_1"
11931  [(set (match_operand:TI 0 "register_operand" "=r")
11932	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11933		     (match_operand:QI 2 "register_operand" "c")))
11934   (clobber (match_scratch:DI 3 "=&r"))
11935   (clobber (reg:CC FLAGS_REG))]
11936  "TARGET_64BIT"
11937  "#"
11938  [(set_attr "type" "multi")])
11939
11940(define_insn "*lshrti3_2"
11941  [(set (match_operand:TI 0 "register_operand" "=r")
11942	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11943		     (match_operand:QI 2 "immediate_operand" "O")))
11944   (clobber (reg:CC FLAGS_REG))]
11945  "TARGET_64BIT"
11946  "#"
11947  [(set_attr "type" "multi")])
11948
11949(define_split 
11950  [(set (match_operand:TI 0 "register_operand" "")
11951	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11952		     (match_operand:QI 2 "register_operand" "")))
11953   (clobber (match_scratch:DI 3 ""))
11954   (clobber (reg:CC FLAGS_REG))]
11955  "TARGET_64BIT && reload_completed"
11956  [(const_int 0)]
11957  "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11958
11959(define_split 
11960  [(set (match_operand:TI 0 "register_operand" "")
11961	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11962		     (match_operand:QI 2 "immediate_operand" "")))
11963   (clobber (reg:CC FLAGS_REG))]
11964  "TARGET_64BIT && reload_completed"
11965  [(const_int 0)]
11966  "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11967
11968(define_expand "lshrdi3"
11969  [(set (match_operand:DI 0 "shiftdi_operand" "")
11970	(lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11971		     (match_operand:QI 2 "nonmemory_operand" "")))]
11972  ""
11973  "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11974
11975(define_insn "*lshrdi3_1_one_bit_rex64"
11976  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11977	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11978		     (match_operand:QI 2 "const1_operand" "")))
11979   (clobber (reg:CC FLAGS_REG))]
11980  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11981   && (TARGET_SHIFT1 || optimize_size)"
11982  "shr{q}\t%0"
11983  [(set_attr "type" "ishift")
11984   (set (attr "length") 
11985     (if_then_else (match_operand:DI 0 "register_operand" "") 
11986	(const_string "2")
11987	(const_string "*")))])
11988
11989(define_insn "*lshrdi3_1_rex64"
11990  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11991	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11992		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11993   (clobber (reg:CC FLAGS_REG))]
11994  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11995  "@
11996   shr{q}\t{%2, %0|%0, %2}
11997   shr{q}\t{%b2, %0|%0, %b2}"
11998  [(set_attr "type" "ishift")
11999   (set_attr "mode" "DI")])
12000
12001;; This pattern can't accept a variable shift count, since shifts by
12002;; zero don't affect the flags.  We assume that shifts by constant
12003;; zero are optimized away.
12004(define_insn "*lshrdi3_cmp_one_bit_rex64"
12005  [(set (reg FLAGS_REG)
12006	(compare
12007	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12008		       (match_operand:QI 2 "const1_operand" ""))
12009	  (const_int 0)))
12010   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12011	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12012  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12013   && (TARGET_SHIFT1 || optimize_size)
12014   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12015  "shr{q}\t%0"
12016  [(set_attr "type" "ishift")
12017   (set (attr "length") 
12018     (if_then_else (match_operand:DI 0 "register_operand" "") 
12019	(const_string "2")
12020	(const_string "*")))])
12021
12022(define_insn "*lshrdi3_cconly_one_bit_rex64"
12023  [(set (reg FLAGS_REG)
12024	(compare
12025	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12026		       (match_operand:QI 2 "const1_operand" ""))
12027	  (const_int 0)))
12028   (clobber (match_scratch:DI 0 "=r"))]
12029  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12030   && (TARGET_SHIFT1 || optimize_size)
12031   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12032  "shr{q}\t%0"
12033  [(set_attr "type" "ishift")
12034   (set_attr "length" "2")])
12035
12036;; This pattern can't accept a variable shift count, since shifts by
12037;; zero don't affect the flags.  We assume that shifts by constant
12038;; zero are optimized away.
12039(define_insn "*lshrdi3_cmp_rex64"
12040  [(set (reg FLAGS_REG)
12041	(compare
12042	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12043		       (match_operand:QI 2 "const_int_operand" "e"))
12044	  (const_int 0)))
12045   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12046	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12047  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12048   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12049   && (optimize_size
12050       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12051  "shr{q}\t{%2, %0|%0, %2}"
12052  [(set_attr "type" "ishift")
12053   (set_attr "mode" "DI")])
12054
12055(define_insn "*lshrdi3_cconly_rex64"
12056  [(set (reg FLAGS_REG)
12057	(compare
12058	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12059		       (match_operand:QI 2 "const_int_operand" "e"))
12060	  (const_int 0)))
12061   (clobber (match_scratch:DI 0 "=r"))]
12062  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12063   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12064   && (optimize_size
12065       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12066  "shr{q}\t{%2, %0|%0, %2}"
12067  [(set_attr "type" "ishift")
12068   (set_attr "mode" "DI")])
12069
12070(define_insn "*lshrdi3_1"
12071  [(set (match_operand:DI 0 "register_operand" "=r")
12072	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12073		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
12074   (clobber (reg:CC FLAGS_REG))]
12075  "!TARGET_64BIT"
12076  "#"
12077  [(set_attr "type" "multi")])
12078
12079;; By default we don't ask for a scratch register, because when DImode
12080;; values are manipulated, registers are already at a premium.  But if
12081;; we have one handy, we won't turn it away.
12082(define_peephole2
12083  [(match_scratch:SI 3 "r")
12084   (parallel [(set (match_operand:DI 0 "register_operand" "")
12085		   (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12086			        (match_operand:QI 2 "nonmemory_operand" "")))
12087	      (clobber (reg:CC FLAGS_REG))])
12088   (match_dup 3)]
12089  "!TARGET_64BIT && TARGET_CMOVE"
12090  [(const_int 0)]
12091  "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12092
12093(define_split 
12094  [(set (match_operand:DI 0 "register_operand" "")
12095	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12096		     (match_operand:QI 2 "nonmemory_operand" "")))
12097   (clobber (reg:CC FLAGS_REG))]
12098  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12099		     ? flow2_completed : reload_completed)"
12100  [(const_int 0)]
12101  "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12102
12103(define_expand "lshrsi3"
12104  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12105	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12106		     (match_operand:QI 2 "nonmemory_operand" "")))
12107   (clobber (reg:CC FLAGS_REG))]
12108  ""
12109  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12110
12111(define_insn "*lshrsi3_1_one_bit"
12112  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12113	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12114		     (match_operand:QI 2 "const1_operand" "")))
12115   (clobber (reg:CC FLAGS_REG))]
12116  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12117   && (TARGET_SHIFT1 || optimize_size)"
12118  "shr{l}\t%0"
12119  [(set_attr "type" "ishift")
12120   (set (attr "length") 
12121     (if_then_else (match_operand:SI 0 "register_operand" "") 
12122	(const_string "2")
12123	(const_string "*")))])
12124
12125(define_insn "*lshrsi3_1_one_bit_zext"
12126  [(set (match_operand:DI 0 "register_operand" "=r")
12127	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12128		     (match_operand:QI 2 "const1_operand" "")))
12129   (clobber (reg:CC FLAGS_REG))]
12130  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12131   && (TARGET_SHIFT1 || optimize_size)"
12132  "shr{l}\t%k0"
12133  [(set_attr "type" "ishift")
12134   (set_attr "length" "2")])
12135
12136(define_insn "*lshrsi3_1"
12137  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12138	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12139		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12140   (clobber (reg:CC FLAGS_REG))]
12141  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12142  "@
12143   shr{l}\t{%2, %0|%0, %2}
12144   shr{l}\t{%b2, %0|%0, %b2}"
12145  [(set_attr "type" "ishift")
12146   (set_attr "mode" "SI")])
12147
12148(define_insn "*lshrsi3_1_zext"
12149  [(set (match_operand:DI 0 "register_operand" "=r,r")
12150	(zero_extend:DI
12151	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12152		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12153   (clobber (reg:CC FLAGS_REG))]
12154  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12155  "@
12156   shr{l}\t{%2, %k0|%k0, %2}
12157   shr{l}\t{%b2, %k0|%k0, %b2}"
12158  [(set_attr "type" "ishift")
12159   (set_attr "mode" "SI")])
12160
12161;; This pattern can't accept a variable shift count, since shifts by
12162;; zero don't affect the flags.  We assume that shifts by constant
12163;; zero are optimized away.
12164(define_insn "*lshrsi3_one_bit_cmp"
12165  [(set (reg FLAGS_REG)
12166	(compare
12167	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12168		       (match_operand:QI 2 "const1_operand" ""))
12169	  (const_int 0)))
12170   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12171	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12172  "ix86_match_ccmode (insn, CCGOCmode)
12173   && (TARGET_SHIFT1 || optimize_size)
12174   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12175  "shr{l}\t%0"
12176  [(set_attr "type" "ishift")
12177   (set (attr "length") 
12178     (if_then_else (match_operand:SI 0 "register_operand" "") 
12179	(const_string "2")
12180	(const_string "*")))])
12181
12182(define_insn "*lshrsi3_one_bit_cconly"
12183  [(set (reg FLAGS_REG)
12184	(compare
12185	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12186		       (match_operand:QI 2 "const1_operand" ""))
12187	  (const_int 0)))
12188   (clobber (match_scratch:SI 0 "=r"))]
12189  "ix86_match_ccmode (insn, CCGOCmode)
12190   && (TARGET_SHIFT1 || optimize_size)
12191   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12192  "shr{l}\t%0"
12193  [(set_attr "type" "ishift")
12194   (set_attr "length" "2")])
12195
12196(define_insn "*lshrsi3_cmp_one_bit_zext"
12197  [(set (reg FLAGS_REG)
12198	(compare
12199	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12200		       (match_operand:QI 2 "const1_operand" ""))
12201	  (const_int 0)))
12202   (set (match_operand:DI 0 "register_operand" "=r")
12203	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12204  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12205   && (TARGET_SHIFT1 || optimize_size)
12206   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12207  "shr{l}\t%k0"
12208  [(set_attr "type" "ishift")
12209   (set_attr "length" "2")])
12210
12211;; This pattern can't accept a variable shift count, since shifts by
12212;; zero don't affect the flags.  We assume that shifts by constant
12213;; zero are optimized away.
12214(define_insn "*lshrsi3_cmp"
12215  [(set (reg FLAGS_REG)
12216	(compare
12217	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12218		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12219	  (const_int 0)))
12220   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12221	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12222  "ix86_match_ccmode (insn, CCGOCmode)
12223   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12224   && (optimize_size
12225       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12226  "shr{l}\t{%2, %0|%0, %2}"
12227  [(set_attr "type" "ishift")
12228   (set_attr "mode" "SI")])
12229
12230(define_insn "*lshrsi3_cconly"
12231  [(set (reg FLAGS_REG)
12232      (compare
12233	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
12235        (const_int 0)))
12236   (clobber (match_scratch:SI 0 "=r"))]
12237  "ix86_match_ccmode (insn, CCGOCmode)
12238   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12239   && (optimize_size
12240       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12241  "shr{l}\t{%2, %0|%0, %2}"
12242  [(set_attr "type" "ishift")
12243   (set_attr "mode" "SI")])
12244
12245(define_insn "*lshrsi3_cmp_zext"
12246  [(set (reg FLAGS_REG)
12247	(compare
12248	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12249		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12250	  (const_int 0)))
12251   (set (match_operand:DI 0 "register_operand" "=r")
12252	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12253  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12254   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12255   && (optimize_size
12256       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12257  "shr{l}\t{%2, %k0|%k0, %2}"
12258  [(set_attr "type" "ishift")
12259   (set_attr "mode" "SI")])
12260
12261(define_expand "lshrhi3"
12262  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12263	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12264		     (match_operand:QI 2 "nonmemory_operand" "")))
12265   (clobber (reg:CC FLAGS_REG))]
12266  "TARGET_HIMODE_MATH"
12267  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12268
12269(define_insn "*lshrhi3_1_one_bit"
12270  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12271	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12272		     (match_operand:QI 2 "const1_operand" "")))
12273   (clobber (reg:CC FLAGS_REG))]
12274  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12275   && (TARGET_SHIFT1 || optimize_size)"
12276  "shr{w}\t%0"
12277  [(set_attr "type" "ishift")
12278   (set (attr "length") 
12279     (if_then_else (match_operand 0 "register_operand" "") 
12280	(const_string "2")
12281	(const_string "*")))])
12282
12283(define_insn "*lshrhi3_1"
12284  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12285	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12286		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12287   (clobber (reg:CC FLAGS_REG))]
12288  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289  "@
12290   shr{w}\t{%2, %0|%0, %2}
12291   shr{w}\t{%b2, %0|%0, %b2}"
12292  [(set_attr "type" "ishift")
12293   (set_attr "mode" "HI")])
12294
12295;; This pattern can't accept a variable shift count, since shifts by
12296;; zero don't affect the flags.  We assume that shifts by constant
12297;; zero are optimized away.
12298(define_insn "*lshrhi3_one_bit_cmp"
12299  [(set (reg FLAGS_REG)
12300	(compare
12301	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12302		       (match_operand:QI 2 "const1_operand" ""))
12303	  (const_int 0)))
12304   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12305	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12306  "ix86_match_ccmode (insn, CCGOCmode)
12307   && (TARGET_SHIFT1 || optimize_size)
12308   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12309  "shr{w}\t%0"
12310  [(set_attr "type" "ishift")
12311   (set (attr "length") 
12312     (if_then_else (match_operand:SI 0 "register_operand" "") 
12313	(const_string "2")
12314	(const_string "*")))])
12315
12316(define_insn "*lshrhi3_one_bit_cconly"
12317  [(set (reg FLAGS_REG)
12318	(compare
12319	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12320		       (match_operand:QI 2 "const1_operand" ""))
12321	  (const_int 0)))
12322   (clobber (match_scratch:HI 0 "=r"))]
12323  "ix86_match_ccmode (insn, CCGOCmode)
12324   && (TARGET_SHIFT1 || optimize_size)
12325   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12326  "shr{w}\t%0"
12327  [(set_attr "type" "ishift")
12328   (set_attr "length" "2")])
12329
12330;; This pattern can't accept a variable shift count, since shifts by
12331;; zero don't affect the flags.  We assume that shifts by constant
12332;; zero are optimized away.
12333(define_insn "*lshrhi3_cmp"
12334  [(set (reg FLAGS_REG)
12335	(compare
12336	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12337		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12338	  (const_int 0)))
12339   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12340	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12341  "ix86_match_ccmode (insn, CCGOCmode)
12342   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12343   && (optimize_size
12344       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12345  "shr{w}\t{%2, %0|%0, %2}"
12346  [(set_attr "type" "ishift")
12347   (set_attr "mode" "HI")])
12348
12349(define_insn "*lshrhi3_cconly"
12350  [(set (reg FLAGS_REG)
12351	(compare
12352	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12353		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12354	  (const_int 0)))
12355   (clobber (match_scratch:HI 0 "=r"))]
12356  "ix86_match_ccmode (insn, CCGOCmode)
12357   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12358   && (optimize_size
12359       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12360  "shr{w}\t{%2, %0|%0, %2}"
12361  [(set_attr "type" "ishift")
12362   (set_attr "mode" "HI")])
12363
12364(define_expand "lshrqi3"
12365  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12366	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12367		     (match_operand:QI 2 "nonmemory_operand" "")))
12368   (clobber (reg:CC FLAGS_REG))]
12369  "TARGET_QIMODE_MATH"
12370  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12371
12372(define_insn "*lshrqi3_1_one_bit"
12373  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12374	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12375		     (match_operand:QI 2 "const1_operand" "")))
12376   (clobber (reg:CC FLAGS_REG))]
12377  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12378   && (TARGET_SHIFT1 || optimize_size)"
12379  "shr{b}\t%0"
12380  [(set_attr "type" "ishift")
12381   (set (attr "length") 
12382     (if_then_else (match_operand 0 "register_operand" "") 
12383	(const_string "2")
12384	(const_string "*")))])
12385
12386(define_insn "*lshrqi3_1_one_bit_slp"
12387  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12388	(lshiftrt:QI (match_dup 0)
12389		     (match_operand:QI 1 "const1_operand" "")))
12390   (clobber (reg:CC FLAGS_REG))]
12391  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12392   && (TARGET_SHIFT1 || optimize_size)"
12393  "shr{b}\t%0"
12394  [(set_attr "type" "ishift1")
12395   (set (attr "length") 
12396     (if_then_else (match_operand 0 "register_operand" "") 
12397	(const_string "2")
12398	(const_string "*")))])
12399
12400(define_insn "*lshrqi3_1"
12401  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12402	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12403		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12404   (clobber (reg:CC FLAGS_REG))]
12405  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12406  "@
12407   shr{b}\t{%2, %0|%0, %2}
12408   shr{b}\t{%b2, %0|%0, %b2}"
12409  [(set_attr "type" "ishift")
12410   (set_attr "mode" "QI")])
12411
12412(define_insn "*lshrqi3_1_slp"
12413  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12414	(lshiftrt:QI (match_dup 0)
12415		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12416   (clobber (reg:CC FLAGS_REG))]
12417  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12418   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12419  "@
12420   shr{b}\t{%1, %0|%0, %1}
12421   shr{b}\t{%b1, %0|%0, %b1}"
12422  [(set_attr "type" "ishift1")
12423   (set_attr "mode" "QI")])
12424
12425;; This pattern can't accept a variable shift count, since shifts by
12426;; zero don't affect the flags.  We assume that shifts by constant
12427;; zero are optimized away.
12428(define_insn "*lshrqi2_one_bit_cmp"
12429  [(set (reg FLAGS_REG)
12430	(compare
12431	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12432		       (match_operand:QI 2 "const1_operand" ""))
12433	  (const_int 0)))
12434   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12435	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12436  "ix86_match_ccmode (insn, CCGOCmode)
12437   && (TARGET_SHIFT1 || optimize_size)
12438   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12439  "shr{b}\t%0"
12440  [(set_attr "type" "ishift")
12441   (set (attr "length") 
12442     (if_then_else (match_operand:SI 0 "register_operand" "") 
12443	(const_string "2")
12444	(const_string "*")))])
12445
12446(define_insn "*lshrqi2_one_bit_cconly"
12447  [(set (reg FLAGS_REG)
12448	(compare
12449	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12450		       (match_operand:QI 2 "const1_operand" ""))
12451	  (const_int 0)))
12452   (clobber (match_scratch:QI 0 "=q"))]
12453  "ix86_match_ccmode (insn, CCGOCmode)
12454   && (TARGET_SHIFT1 || optimize_size)
12455   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12456  "shr{b}\t%0"
12457  [(set_attr "type" "ishift")
12458   (set_attr "length" "2")])
12459
12460;; This pattern can't accept a variable shift count, since shifts by
12461;; zero don't affect the flags.  We assume that shifts by constant
12462;; zero are optimized away.
12463(define_insn "*lshrqi2_cmp"
12464  [(set (reg FLAGS_REG)
12465	(compare
12466	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12467		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12468	  (const_int 0)))
12469   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12471  "ix86_match_ccmode (insn, CCGOCmode)
12472   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12473   && (optimize_size
12474       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12475  "shr{b}\t{%2, %0|%0, %2}"
12476  [(set_attr "type" "ishift")
12477   (set_attr "mode" "QI")])
12478
12479(define_insn "*lshrqi2_cconly"
12480  [(set (reg FLAGS_REG)
12481	(compare
12482	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12483		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12484	  (const_int 0)))
12485   (clobber (match_scratch:QI 0 "=q"))]
12486  "ix86_match_ccmode (insn, CCGOCmode)
12487   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12488   && (optimize_size
12489       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12490  "shr{b}\t{%2, %0|%0, %2}"
12491  [(set_attr "type" "ishift")
12492   (set_attr "mode" "QI")])
12493
12494;; Rotate instructions
12495
12496(define_expand "rotldi3"
12497  [(set (match_operand:DI 0 "shiftdi_operand" "")
12498	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12499		   (match_operand:QI 2 "nonmemory_operand" "")))
12500   (clobber (reg:CC FLAGS_REG))]
12501 ""
12502{
12503  if (TARGET_64BIT)
12504    {
12505      ix86_expand_binary_operator (ROTATE, DImode, operands);
12506      DONE;
12507    }
12508  if (!const_1_to_31_operand (operands[2], VOIDmode))
12509    FAIL;
12510  emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12511  DONE;
12512})
12513
12514;; Implement rotation using two double-precision shift instructions
12515;; and a scratch register.   
12516(define_insn_and_split "ix86_rotldi3"
12517 [(set (match_operand:DI 0 "register_operand" "=r")
12518       (rotate:DI (match_operand:DI 1 "register_operand" "0")
12519                  (match_operand:QI 2 "const_1_to_31_operand" "I")))
12520  (clobber (reg:CC FLAGS_REG))
12521  (clobber (match_scratch:SI 3 "=&r"))]
12522 "!TARGET_64BIT"
12523 "" 
12524 "&& reload_completed"
12525 [(set (match_dup 3) (match_dup 4))
12526  (parallel
12527   [(set (match_dup 4)
12528         (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12529                 (lshiftrt:SI (match_dup 5)
12530                              (minus:QI (const_int 32) (match_dup 2)))))
12531    (clobber (reg:CC FLAGS_REG))])
12532  (parallel
12533   [(set (match_dup 5)
12534         (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12535                 (lshiftrt:SI (match_dup 3)
12536                              (minus:QI (const_int 32) (match_dup 2)))))
12537    (clobber (reg:CC FLAGS_REG))])]
12538 "split_di (operands, 1, operands + 4, operands + 5);")
12539 
12540(define_insn "*rotlsi3_1_one_bit_rex64"
12541  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12542	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12543		   (match_operand:QI 2 "const1_operand" "")))
12544   (clobber (reg:CC FLAGS_REG))]
12545  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12546   && (TARGET_SHIFT1 || optimize_size)"
12547  "rol{q}\t%0"
12548  [(set_attr "type" "rotate")
12549   (set (attr "length") 
12550     (if_then_else (match_operand:DI 0 "register_operand" "") 
12551	(const_string "2")
12552	(const_string "*")))])
12553
12554(define_insn "*rotldi3_1_rex64"
12555  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12556	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12557		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12558   (clobber (reg:CC FLAGS_REG))]
12559  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12560  "@
12561   rol{q}\t{%2, %0|%0, %2}
12562   rol{q}\t{%b2, %0|%0, %b2}"
12563  [(set_attr "type" "rotate")
12564   (set_attr "mode" "DI")])
12565
12566(define_expand "rotlsi3"
12567  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12568	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12569		   (match_operand:QI 2 "nonmemory_operand" "")))
12570   (clobber (reg:CC FLAGS_REG))]
12571  ""
12572  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12573
12574(define_insn "*rotlsi3_1_one_bit"
12575  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12576	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12577		   (match_operand:QI 2 "const1_operand" "")))
12578   (clobber (reg:CC FLAGS_REG))]
12579  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12580   && (TARGET_SHIFT1 || optimize_size)"
12581  "rol{l}\t%0"
12582  [(set_attr "type" "rotate")
12583   (set (attr "length") 
12584     (if_then_else (match_operand:SI 0 "register_operand" "") 
12585	(const_string "2")
12586	(const_string "*")))])
12587
12588(define_insn "*rotlsi3_1_one_bit_zext"
12589  [(set (match_operand:DI 0 "register_operand" "=r")
12590	(zero_extend:DI
12591	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
12592		     (match_operand:QI 2 "const1_operand" ""))))
12593   (clobber (reg:CC FLAGS_REG))]
12594  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12595   && (TARGET_SHIFT1 || optimize_size)"
12596  "rol{l}\t%k0"
12597  [(set_attr "type" "rotate")
12598   (set_attr "length" "2")])
12599
12600(define_insn "*rotlsi3_1"
12601  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12602	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12603		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12604   (clobber (reg:CC FLAGS_REG))]
12605  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12606  "@
12607   rol{l}\t{%2, %0|%0, %2}
12608   rol{l}\t{%b2, %0|%0, %b2}"
12609  [(set_attr "type" "rotate")
12610   (set_attr "mode" "SI")])
12611
12612(define_insn "*rotlsi3_1_zext"
12613  [(set (match_operand:DI 0 "register_operand" "=r,r")
12614	(zero_extend:DI
12615	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12616		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12617   (clobber (reg:CC FLAGS_REG))]
12618  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12619  "@
12620   rol{l}\t{%2, %k0|%k0, %2}
12621   rol{l}\t{%b2, %k0|%k0, %b2}"
12622  [(set_attr "type" "rotate")
12623   (set_attr "mode" "SI")])
12624
12625(define_expand "rotlhi3"
12626  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12627	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12628		   (match_operand:QI 2 "nonmemory_operand" "")))
12629   (clobber (reg:CC FLAGS_REG))]
12630  "TARGET_HIMODE_MATH"
12631  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12632
12633(define_insn "*rotlhi3_1_one_bit"
12634  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12635	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12636		   (match_operand:QI 2 "const1_operand" "")))
12637   (clobber (reg:CC FLAGS_REG))]
12638  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12639   && (TARGET_SHIFT1 || optimize_size)"
12640  "rol{w}\t%0"
12641  [(set_attr "type" "rotate")
12642   (set (attr "length") 
12643     (if_then_else (match_operand 0 "register_operand" "") 
12644	(const_string "2")
12645	(const_string "*")))])
12646
12647(define_insn "*rotlhi3_1"
12648  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12649	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12650		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12651   (clobber (reg:CC FLAGS_REG))]
12652  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12653  "@
12654   rol{w}\t{%2, %0|%0, %2}
12655   rol{w}\t{%b2, %0|%0, %b2}"
12656  [(set_attr "type" "rotate")
12657   (set_attr "mode" "HI")])
12658
12659(define_expand "rotlqi3"
12660  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12661	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12662		   (match_operand:QI 2 "nonmemory_operand" "")))
12663   (clobber (reg:CC FLAGS_REG))]
12664  "TARGET_QIMODE_MATH"
12665  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12666
12667(define_insn "*rotlqi3_1_one_bit_slp"
12668  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12669	(rotate:QI (match_dup 0)
12670		   (match_operand:QI 1 "const1_operand" "")))
12671   (clobber (reg:CC FLAGS_REG))]
12672  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12673   && (TARGET_SHIFT1 || optimize_size)"
12674  "rol{b}\t%0"
12675  [(set_attr "type" "rotate1")
12676   (set (attr "length") 
12677     (if_then_else (match_operand 0 "register_operand" "") 
12678	(const_string "2")
12679	(const_string "*")))])
12680
12681(define_insn "*rotlqi3_1_one_bit"
12682  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12683	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12684		   (match_operand:QI 2 "const1_operand" "")))
12685   (clobber (reg:CC FLAGS_REG))]
12686  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12687   && (TARGET_SHIFT1 || optimize_size)"
12688  "rol{b}\t%0"
12689  [(set_attr "type" "rotate")
12690   (set (attr "length") 
12691     (if_then_else (match_operand 0 "register_operand" "") 
12692	(const_string "2")
12693	(const_string "*")))])
12694
12695(define_insn "*rotlqi3_1_slp"
12696  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12697	(rotate:QI (match_dup 0)
12698		   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12699   (clobber (reg:CC FLAGS_REG))]
12700  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12701   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12702  "@
12703   rol{b}\t{%1, %0|%0, %1}
12704   rol{b}\t{%b1, %0|%0, %b1}"
12705  [(set_attr "type" "rotate1")
12706   (set_attr "mode" "QI")])
12707
12708(define_insn "*rotlqi3_1"
12709  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12710	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12711		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12712   (clobber (reg:CC FLAGS_REG))]
12713  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12714  "@
12715   rol{b}\t{%2, %0|%0, %2}
12716   rol{b}\t{%b2, %0|%0, %b2}"
12717  [(set_attr "type" "rotate")
12718   (set_attr "mode" "QI")])
12719
12720(define_expand "rotrdi3"
12721  [(set (match_operand:DI 0 "shiftdi_operand" "")
12722	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12723		   (match_operand:QI 2 "nonmemory_operand" "")))
12724   (clobber (reg:CC FLAGS_REG))]
12725 ""
12726{
12727  if (TARGET_64BIT)
12728    {
12729      ix86_expand_binary_operator (ROTATERT, DImode, operands);
12730      DONE;
12731    }
12732  if (!const_1_to_31_operand (operands[2], VOIDmode))
12733    FAIL;
12734  emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12735  DONE;
12736})
12737  
12738;; Implement rotation using two double-precision shift instructions
12739;; and a scratch register.   
12740(define_insn_and_split "ix86_rotrdi3"
12741 [(set (match_operand:DI 0 "register_operand" "=r")
12742       (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12743                    (match_operand:QI 2 "const_1_to_31_operand" "I")))
12744  (clobber (reg:CC FLAGS_REG))
12745  (clobber (match_scratch:SI 3 "=&r"))]
12746 "!TARGET_64BIT"
12747 ""
12748 "&& reload_completed"
12749 [(set (match_dup 3) (match_dup 4))
12750  (parallel
12751   [(set (match_dup 4)
12752         (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12753                 (ashift:SI (match_dup 5)
12754                            (minus:QI (const_int 32) (match_dup 2)))))
12755    (clobber (reg:CC FLAGS_REG))])
12756  (parallel
12757   [(set (match_dup 5)
12758         (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12759                 (ashift:SI (match_dup 3)
12760                            (minus:QI (const_int 32) (match_dup 2)))))
12761    (clobber (reg:CC FLAGS_REG))])]
12762 "split_di (operands, 1, operands + 4, operands + 5);")
12763
12764(define_insn "*rotrdi3_1_one_bit_rex64"
12765  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12766	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12767		     (match_operand:QI 2 "const1_operand" "")))
12768   (clobber (reg:CC FLAGS_REG))]
12769  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12770   && (TARGET_SHIFT1 || optimize_size)"
12771  "ror{q}\t%0"
12772  [(set_attr "type" "rotate")
12773   (set (attr "length") 
12774     (if_then_else (match_operand:DI 0 "register_operand" "") 
12775	(const_string "2")
12776	(const_string "*")))])
12777
12778(define_insn "*rotrdi3_1_rex64"
12779  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12780	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12781		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12782   (clobber (reg:CC FLAGS_REG))]
12783  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12784  "@
12785   ror{q}\t{%2, %0|%0, %2}
12786   ror{q}\t{%b2, %0|%0, %b2}"
12787  [(set_attr "type" "rotate")
12788   (set_attr "mode" "DI")])
12789
12790(define_expand "rotrsi3"
12791  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12792	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12793		     (match_operand:QI 2 "nonmemory_operand" "")))
12794   (clobber (reg:CC FLAGS_REG))]
12795  ""
12796  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12797
12798(define_insn "*rotrsi3_1_one_bit"
12799  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12800	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12801		     (match_operand:QI 2 "const1_operand" "")))
12802   (clobber (reg:CC FLAGS_REG))]
12803  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12804   && (TARGET_SHIFT1 || optimize_size)"
12805  "ror{l}\t%0"
12806  [(set_attr "type" "rotate")
12807   (set (attr "length") 
12808     (if_then_else (match_operand:SI 0 "register_operand" "") 
12809	(const_string "2")
12810	(const_string "*")))])
12811
12812(define_insn "*rotrsi3_1_one_bit_zext"
12813  [(set (match_operand:DI 0 "register_operand" "=r")
12814	(zero_extend:DI
12815	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12816		       (match_operand:QI 2 "const1_operand" ""))))
12817   (clobber (reg:CC FLAGS_REG))]
12818  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12819   && (TARGET_SHIFT1 || optimize_size)"
12820  "ror{l}\t%k0"
12821  [(set_attr "type" "rotate")
12822   (set (attr "length") 
12823     (if_then_else (match_operand:SI 0 "register_operand" "") 
12824	(const_string "2")
12825	(const_string "*")))])
12826
12827(define_insn "*rotrsi3_1"
12828  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12829	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12830		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12831   (clobber (reg:CC FLAGS_REG))]
12832  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12833  "@
12834   ror{l}\t{%2, %0|%0, %2}
12835   ror{l}\t{%b2, %0|%0, %b2}"
12836  [(set_attr "type" "rotate")
12837   (set_attr "mode" "SI")])
12838
12839(define_insn "*rotrsi3_1_zext"
12840  [(set (match_operand:DI 0 "register_operand" "=r,r")
12841	(zero_extend:DI
12842	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12843		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12844   (clobber (reg:CC FLAGS_REG))]
12845  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12846  "@
12847   ror{l}\t{%2, %k0|%k0, %2}
12848   ror{l}\t{%b2, %k0|%k0, %b2}"
12849  [(set_attr "type" "rotate")
12850   (set_attr "mode" "SI")])
12851
12852(define_expand "rotrhi3"
12853  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12854	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12855		     (match_operand:QI 2 "nonmemory_operand" "")))
12856   (clobber (reg:CC FLAGS_REG))]
12857  "TARGET_HIMODE_MATH"
12858  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12859
12860(define_insn "*rotrhi3_one_bit"
12861  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12862	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12863		     (match_operand:QI 2 "const1_operand" "")))
12864   (clobber (reg:CC FLAGS_REG))]
12865  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12866   && (TARGET_SHIFT1 || optimize_size)"
12867  "ror{w}\t%0"
12868  [(set_attr "type" "rotate")
12869   (set (attr "length") 
12870     (if_then_else (match_operand 0 "register_operand" "") 
12871	(const_string "2")
12872	(const_string "*")))])
12873
12874(define_insn "*rotrhi3"
12875  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12876	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12877		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12878   (clobber (reg:CC FLAGS_REG))]
12879  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12880  "@
12881   ror{w}\t{%2, %0|%0, %2}
12882   ror{w}\t{%b2, %0|%0, %b2}"
12883  [(set_attr "type" "rotate")
12884   (set_attr "mode" "HI")])
12885
12886(define_expand "rotrqi3"
12887  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12888	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12889		     (match_operand:QI 2 "nonmemory_operand" "")))
12890   (clobber (reg:CC FLAGS_REG))]
12891  "TARGET_QIMODE_MATH"
12892  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12893
12894(define_insn "*rotrqi3_1_one_bit"
12895  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12896	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12897		     (match_operand:QI 2 "const1_operand" "")))
12898   (clobber (reg:CC FLAGS_REG))]
12899  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12900   && (TARGET_SHIFT1 || optimize_size)"
12901  "ror{b}\t%0"
12902  [(set_attr "type" "rotate")
12903   (set (attr "length") 
12904     (if_then_else (match_operand 0 "register_operand" "") 
12905	(const_string "2")
12906	(const_string "*")))])
12907
12908(define_insn "*rotrqi3_1_one_bit_slp"
12909  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12910	(rotatert:QI (match_dup 0)
12911		     (match_operand:QI 1 "const1_operand" "")))
12912   (clobber (reg:CC FLAGS_REG))]
12913  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12914   && (TARGET_SHIFT1 || optimize_size)"
12915  "ror{b}\t%0"
12916  [(set_attr "type" "rotate1")
12917   (set (attr "length") 
12918     (if_then_else (match_operand 0 "register_operand" "") 
12919	(const_string "2")
12920	(const_string "*")))])
12921
12922(define_insn "*rotrqi3_1"
12923  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12924	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12925		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12926   (clobber (reg:CC FLAGS_REG))]
12927  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12928  "@
12929   ror{b}\t{%2, %0|%0, %2}
12930   ror{b}\t{%b2, %0|%0, %b2}"
12931  [(set_attr "type" "rotate")
12932   (set_attr "mode" "QI")])
12933
12934(define_insn "*rotrqi3_1_slp"
12935  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12936	(rotatert:QI (match_dup 0)
12937		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12938   (clobber (reg:CC FLAGS_REG))]
12939  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12940   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12941  "@
12942   ror{b}\t{%1, %0|%0, %1}
12943   ror{b}\t{%b1, %0|%0, %b1}"
12944  [(set_attr "type" "rotate1")
12945   (set_attr "mode" "QI")])
12946
12947;; Bit set / bit test instructions
12948
12949(define_expand "extv"
12950  [(set (match_operand:SI 0 "register_operand" "")
12951	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
12952			 (match_operand:SI 2 "const8_operand" "")
12953			 (match_operand:SI 3 "const8_operand" "")))]
12954  ""
12955{
12956  /* Handle extractions from %ah et al.  */
12957  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12958    FAIL;
12959
12960  /* From mips.md: extract_bit_field doesn't verify that our source
12961     matches the predicate, so check it again here.  */
12962  if (! ext_register_operand (operands[1], VOIDmode))
12963    FAIL;
12964})
12965
12966(define_expand "extzv"
12967  [(set (match_operand:SI 0 "register_operand" "")
12968	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
12969			 (match_operand:SI 2 "const8_operand" "")
12970			 (match_operand:SI 3 "const8_operand" "")))]
12971  ""
12972{
12973  /* Handle extractions from %ah et al.  */
12974  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12975    FAIL;
12976
12977  /* From mips.md: extract_bit_field doesn't verify that our source
12978     matches the predicate, so check it again here.  */
12979  if (! ext_register_operand (operands[1], VOIDmode))
12980    FAIL;
12981})
12982
12983(define_expand "insv"
12984  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12985		      (match_operand 1 "const8_operand" "")
12986		      (match_operand 2 "const8_operand" ""))
12987        (match_operand 3 "register_operand" ""))]
12988  ""
12989{
12990  /* Handle insertions to %ah et al.  */
12991  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12992    FAIL;
12993
12994  /* From mips.md: insert_bit_field doesn't verify that our source
12995     matches the predicate, so check it again here.  */
12996  if (! ext_register_operand (operands[0], VOIDmode))
12997    FAIL;
12998
12999  if (TARGET_64BIT)
13000    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13001  else
13002    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13003
13004  DONE;
13005})
13006
13007;; %%% bts, btr, btc, bt.
13008;; In general these instructions are *slow* when applied to memory,
13009;; since they enforce atomic operation.  When applied to registers,
13010;; it depends on the cpu implementation.  They're never faster than
13011;; the corresponding and/ior/xor operations, so with 32-bit there's
13012;; no point.  But in 64-bit, we can't hold the relevant immediates
13013;; within the instruction itself, so operating on bits in the high
13014;; 32-bits of a register becomes easier.
13015;;
13016;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13017;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13018;; negdf respectively, so they can never be disabled entirely.
13019
13020(define_insn "*btsq"
13021  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13022			 (const_int 1)
13023			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13024	(const_int 1))
13025   (clobber (reg:CC FLAGS_REG))]
13026  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13027  "bts{q} %1,%0"
13028  [(set_attr "type" "alu1")])
13029
13030(define_insn "*btrq"
13031  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13032			 (const_int 1)
13033			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13034	(const_int 0))
13035   (clobber (reg:CC FLAGS_REG))]
13036  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13037  "btr{q} %1,%0"
13038  [(set_attr "type" "alu1")])
13039
13040(define_insn "*btcq"
13041  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13042			 (const_int 1)
13043			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13044	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13045   (clobber (reg:CC FLAGS_REG))]
13046  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13047  "btc{q} %1,%0"
13048  [(set_attr "type" "alu1")])
13049
13050;; Allow Nocona to avoid these instructions if a register is available.
13051
13052(define_peephole2
13053  [(match_scratch:DI 2 "r")
13054   (parallel [(set (zero_extract:DI
13055		     (match_operand:DI 0 "register_operand" "")
13056		     (const_int 1)
13057		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13058		   (const_int 1))
13059	      (clobber (reg:CC FLAGS_REG))])]
13060  "TARGET_64BIT && !TARGET_USE_BT"
13061  [(const_int 0)]
13062{
13063  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13064  rtx op1;
13065
13066  if (HOST_BITS_PER_WIDE_INT >= 64)
13067    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13068  else if (i < HOST_BITS_PER_WIDE_INT)
13069    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13070  else
13071    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13072
13073  op1 = immed_double_const (lo, hi, DImode);
13074  if (i >= 31)
13075    {
13076      emit_move_insn (operands[2], op1);
13077      op1 = operands[2];
13078    }
13079
13080  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13081  DONE;
13082})
13083
13084(define_peephole2
13085  [(match_scratch:DI 2 "r")
13086   (parallel [(set (zero_extract:DI
13087		     (match_operand:DI 0 "register_operand" "")
13088		     (const_int 1)
13089		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13090		   (const_int 0))
13091	      (clobber (reg:CC FLAGS_REG))])]
13092  "TARGET_64BIT && !TARGET_USE_BT"
13093  [(const_int 0)]
13094{
13095  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13096  rtx op1;
13097
13098  if (HOST_BITS_PER_WIDE_INT >= 64)
13099    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13100  else if (i < HOST_BITS_PER_WIDE_INT)
13101    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13102  else
13103    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13104
13105  op1 = immed_double_const (~lo, ~hi, DImode);
13106  if (i >= 32)
13107    {
13108      emit_move_insn (operands[2], op1);
13109      op1 = operands[2];
13110    }
13111
13112  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13113  DONE;
13114})
13115
13116(define_peephole2
13117  [(match_scratch:DI 2 "r")
13118   (parallel [(set (zero_extract:DI
13119		     (match_operand:DI 0 "register_operand" "")
13120		     (const_int 1)
13121		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13122	      (not:DI (zero_extract:DI
13123			(match_dup 0) (const_int 1) (match_dup 1))))
13124	      (clobber (reg:CC FLAGS_REG))])]
13125  "TARGET_64BIT && !TARGET_USE_BT"
13126  [(const_int 0)]
13127{
13128  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13129  rtx op1;
13130
13131  if (HOST_BITS_PER_WIDE_INT >= 64)
13132    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13133  else if (i < HOST_BITS_PER_WIDE_INT)
13134    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13135  else
13136    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13137
13138  op1 = immed_double_const (lo, hi, DImode);
13139  if (i >= 31)
13140    {
13141      emit_move_insn (operands[2], op1);
13142      op1 = operands[2];
13143    }
13144
13145  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13146  DONE;
13147})
13148
13149;; Store-flag instructions.
13150
13151;; For all sCOND expanders, also expand the compare or test insn that
13152;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13153
13154;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13155;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13156;; way, which can later delete the movzx if only QImode is needed.
13157
13158(define_expand "seq"
13159  [(set (match_operand:QI 0 "register_operand" "")
13160        (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13161  ""
13162  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13163
13164(define_expand "sne"
13165  [(set (match_operand:QI 0 "register_operand" "")
13166        (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13167  ""
13168  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13169
13170(define_expand "sgt"
13171  [(set (match_operand:QI 0 "register_operand" "")
13172        (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13173  ""
13174  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13175
13176(define_expand "sgtu"
13177  [(set (match_operand:QI 0 "register_operand" "")
13178        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13179  ""
13180  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13181
13182(define_expand "slt"
13183  [(set (match_operand:QI 0 "register_operand" "")
13184        (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13185  ""
13186  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13187
13188(define_expand "sltu"
13189  [(set (match_operand:QI 0 "register_operand" "")
13190        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13191  ""
13192  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13193
13194(define_expand "sge"
13195  [(set (match_operand:QI 0 "register_operand" "")
13196        (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13197  ""
13198  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13199
13200(define_expand "sgeu"
13201  [(set (match_operand:QI 0 "register_operand" "")
13202        (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13203  ""
13204  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13205
13206(define_expand "sle"
13207  [(set (match_operand:QI 0 "register_operand" "")
13208        (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13209  ""
13210  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13211
13212(define_expand "sleu"
13213  [(set (match_operand:QI 0 "register_operand" "")
13214        (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13215  ""
13216  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13217
13218(define_expand "sunordered"
13219  [(set (match_operand:QI 0 "register_operand" "")
13220        (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13221  "TARGET_80387 || TARGET_SSE"
13222  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13223
13224(define_expand "sordered"
13225  [(set (match_operand:QI 0 "register_operand" "")
13226        (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227  "TARGET_80387"
13228  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13229
13230(define_expand "suneq"
13231  [(set (match_operand:QI 0 "register_operand" "")
13232        (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233  "TARGET_80387 || TARGET_SSE"
13234  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13235
13236(define_expand "sunge"
13237  [(set (match_operand:QI 0 "register_operand" "")
13238        (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239  "TARGET_80387 || TARGET_SSE"
13240  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13241
13242(define_expand "sungt"
13243  [(set (match_operand:QI 0 "register_operand" "")
13244        (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245  "TARGET_80387 || TARGET_SSE"
13246  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13247
13248(define_expand "sunle"
13249  [(set (match_operand:QI 0 "register_operand" "")
13250        (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251  "TARGET_80387 || TARGET_SSE"
13252  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13253
13254(define_expand "sunlt"
13255  [(set (match_operand:QI 0 "register_operand" "")
13256        (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257  "TARGET_80387 || TARGET_SSE"
13258  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13259
13260(define_expand "sltgt"
13261  [(set (match_operand:QI 0 "register_operand" "")
13262        (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263  "TARGET_80387 || TARGET_SSE"
13264  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13265
13266(define_insn "*setcc_1"
13267  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13268	(match_operator:QI 1 "ix86_comparison_operator"
13269	  [(reg FLAGS_REG) (const_int 0)]))]
13270  ""
13271  "set%C1\t%0"
13272  [(set_attr "type" "setcc")
13273   (set_attr "mode" "QI")])
13274
13275(define_insn "*setcc_2"
13276  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13277	(match_operator:QI 1 "ix86_comparison_operator"
13278	  [(reg FLAGS_REG) (const_int 0)]))]
13279  ""
13280  "set%C1\t%0"
13281  [(set_attr "type" "setcc")
13282   (set_attr "mode" "QI")])
13283
13284;; In general it is not safe to assume too much about CCmode registers,
13285;; so simplify-rtx stops when it sees a second one.  Under certain 
13286;; conditions this is safe on x86, so help combine not create
13287;;
13288;;	seta	%al
13289;;	testb	%al, %al
13290;;	sete	%al
13291
13292(define_split 
13293  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13294	(ne:QI (match_operator 1 "ix86_comparison_operator"
13295	         [(reg FLAGS_REG) (const_int 0)])
13296	    (const_int 0)))]
13297  ""
13298  [(set (match_dup 0) (match_dup 1))]
13299{
13300  PUT_MODE (operands[1], QImode);
13301})
13302
13303(define_split 
13304  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13305	(ne:QI (match_operator 1 "ix86_comparison_operator"
13306	         [(reg FLAGS_REG) (const_int 0)])
13307	    (const_int 0)))]
13308  ""
13309  [(set (match_dup 0) (match_dup 1))]
13310{
13311  PUT_MODE (operands[1], QImode);
13312})
13313
13314(define_split 
13315  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13316	(eq:QI (match_operator 1 "ix86_comparison_operator"
13317	         [(reg FLAGS_REG) (const_int 0)])
13318	    (const_int 0)))]
13319  ""
13320  [(set (match_dup 0) (match_dup 1))]
13321{
13322  rtx new_op1 = copy_rtx (operands[1]);
13323  operands[1] = new_op1;
13324  PUT_MODE (new_op1, QImode);
13325  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13326					     GET_MODE (XEXP (new_op1, 0))));
13327
13328  /* Make sure that (a) the CCmode we have for the flags is strong
13329     enough for the reversed compare or (b) we have a valid FP compare.  */
13330  if (! ix86_comparison_operator (new_op1, VOIDmode))
13331    FAIL;
13332})
13333
13334(define_split 
13335  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13336	(eq:QI (match_operator 1 "ix86_comparison_operator"
13337	         [(reg FLAGS_REG) (const_int 0)])
13338	    (const_int 0)))]
13339  ""
13340  [(set (match_dup 0) (match_dup 1))]
13341{
13342  rtx new_op1 = copy_rtx (operands[1]);
13343  operands[1] = new_op1;
13344  PUT_MODE (new_op1, QImode);
13345  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13346					     GET_MODE (XEXP (new_op1, 0))));
13347
13348  /* Make sure that (a) the CCmode we have for the flags is strong
13349     enough for the reversed compare or (b) we have a valid FP compare.  */
13350  if (! ix86_comparison_operator (new_op1, VOIDmode))
13351    FAIL;
13352})
13353
13354;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13355;; subsequent logical operations are used to imitate conditional moves.
13356;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13357;; it directly.
13358
13359(define_insn "*sse_setccsf"
13360  [(set (match_operand:SF 0 "register_operand" "=x")
13361	(match_operator:SF 1 "sse_comparison_operator"
13362	  [(match_operand:SF 2 "register_operand" "0")
13363	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13364  "TARGET_SSE"
13365  "cmp%D1ss\t{%3, %0|%0, %3}"
13366  [(set_attr "type" "ssecmp")
13367   (set_attr "mode" "SF")])
13368
13369(define_insn "*sse_setccdf"
13370  [(set (match_operand:DF 0 "register_operand" "=Y")
13371	(match_operator:DF 1 "sse_comparison_operator"
13372	  [(match_operand:DF 2 "register_operand" "0")
13373	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13374  "TARGET_SSE2"
13375  "cmp%D1sd\t{%3, %0|%0, %3}"
13376  [(set_attr "type" "ssecmp")
13377   (set_attr "mode" "DF")])
13378
13379;; Basic conditional jump instructions.
13380;; We ignore the overflow flag for signed branch instructions.
13381
13382;; For all bCOND expanders, also expand the compare or test insn that
13383;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13384
13385(define_expand "beq"
13386  [(set (pc)
13387	(if_then_else (match_dup 1)
13388		      (label_ref (match_operand 0 "" ""))
13389		      (pc)))]
13390  ""
13391  "ix86_expand_branch (EQ, operands[0]); DONE;")
13392
13393(define_expand "bne"
13394  [(set (pc)
13395	(if_then_else (match_dup 1)
13396		      (label_ref (match_operand 0 "" ""))
13397		      (pc)))]
13398  ""
13399  "ix86_expand_branch (NE, operands[0]); DONE;")
13400
13401(define_expand "bgt"
13402  [(set (pc)
13403	(if_then_else (match_dup 1)
13404		      (label_ref (match_operand 0 "" ""))
13405		      (pc)))]
13406  ""
13407  "ix86_expand_branch (GT, operands[0]); DONE;")
13408
13409(define_expand "bgtu"
13410  [(set (pc)
13411	(if_then_else (match_dup 1)
13412		      (label_ref (match_operand 0 "" ""))
13413		      (pc)))]
13414  ""
13415  "ix86_expand_branch (GTU, operands[0]); DONE;")
13416
13417(define_expand "blt"
13418  [(set (pc)
13419	(if_then_else (match_dup 1)
13420		      (label_ref (match_operand 0 "" ""))
13421		      (pc)))]
13422  ""
13423  "ix86_expand_branch (LT, operands[0]); DONE;")
13424
13425(define_expand "bltu"
13426  [(set (pc)
13427	(if_then_else (match_dup 1)
13428		      (label_ref (match_operand 0 "" ""))
13429		      (pc)))]
13430  ""
13431  "ix86_expand_branch (LTU, operands[0]); DONE;")
13432
13433(define_expand "bge"
13434  [(set (pc)
13435	(if_then_else (match_dup 1)
13436		      (label_ref (match_operand 0 "" ""))
13437		      (pc)))]
13438  ""
13439  "ix86_expand_branch (GE, operands[0]); DONE;")
13440
13441(define_expand "bgeu"
13442  [(set (pc)
13443	(if_then_else (match_dup 1)
13444		      (label_ref (match_operand 0 "" ""))
13445		      (pc)))]
13446  ""
13447  "ix86_expand_branch (GEU, operands[0]); DONE;")
13448
13449(define_expand "ble"
13450  [(set (pc)
13451	(if_then_else (match_dup 1)
13452		      (label_ref (match_operand 0 "" ""))
13453		      (pc)))]
13454  ""
13455  "ix86_expand_branch (LE, operands[0]); DONE;")
13456
13457(define_expand "bleu"
13458  [(set (pc)
13459	(if_then_else (match_dup 1)
13460		      (label_ref (match_operand 0 "" ""))
13461		      (pc)))]
13462  ""
13463  "ix86_expand_branch (LEU, operands[0]); DONE;")
13464
13465(define_expand "bunordered"
13466  [(set (pc)
13467	(if_then_else (match_dup 1)
13468		      (label_ref (match_operand 0 "" ""))
13469		      (pc)))]
13470  "TARGET_80387 || TARGET_SSE_MATH"
13471  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13472
13473(define_expand "bordered"
13474  [(set (pc)
13475	(if_then_else (match_dup 1)
13476		      (label_ref (match_operand 0 "" ""))
13477		      (pc)))]
13478  "TARGET_80387 || TARGET_SSE_MATH"
13479  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13480
13481(define_expand "buneq"
13482  [(set (pc)
13483	(if_then_else (match_dup 1)
13484		      (label_ref (match_operand 0 "" ""))
13485		      (pc)))]
13486  "TARGET_80387 || TARGET_SSE_MATH"
13487  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13488
13489(define_expand "bunge"
13490  [(set (pc)
13491	(if_then_else (match_dup 1)
13492		      (label_ref (match_operand 0 "" ""))
13493		      (pc)))]
13494  "TARGET_80387 || TARGET_SSE_MATH"
13495  "ix86_expand_branch (UNGE, operands[0]); DONE;")
13496
13497(define_expand "bungt"
13498  [(set (pc)
13499	(if_then_else (match_dup 1)
13500		      (label_ref (match_operand 0 "" ""))
13501		      (pc)))]
13502  "TARGET_80387 || TARGET_SSE_MATH"
13503  "ix86_expand_branch (UNGT, operands[0]); DONE;")
13504
13505(define_expand "bunle"
13506  [(set (pc)
13507	(if_then_else (match_dup 1)
13508		      (label_ref (match_operand 0 "" ""))
13509		      (pc)))]
13510  "TARGET_80387 || TARGET_SSE_MATH"
13511  "ix86_expand_branch (UNLE, operands[0]); DONE;")
13512
13513(define_expand "bunlt"
13514  [(set (pc)
13515	(if_then_else (match_dup 1)
13516		      (label_ref (match_operand 0 "" ""))
13517		      (pc)))]
13518  "TARGET_80387 || TARGET_SSE_MATH"
13519  "ix86_expand_branch (UNLT, operands[0]); DONE;")
13520
13521(define_expand "bltgt"
13522  [(set (pc)
13523	(if_then_else (match_dup 1)
13524		      (label_ref (match_operand 0 "" ""))
13525		      (pc)))]
13526  "TARGET_80387 || TARGET_SSE_MATH"
13527  "ix86_expand_branch (LTGT, operands[0]); DONE;")
13528
13529(define_insn "*jcc_1"
13530  [(set (pc)
13531	(if_then_else (match_operator 1 "ix86_comparison_operator"
13532				      [(reg FLAGS_REG) (const_int 0)])
13533		      (label_ref (match_operand 0 "" ""))
13534		      (pc)))]
13535  ""
13536  "%+j%C1\t%l0"
13537  [(set_attr "type" "ibr")
13538   (set_attr "modrm" "0")
13539   (set (attr "length")
13540	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13541				  (const_int -126))
13542			      (lt (minus (match_dup 0) (pc))
13543				  (const_int 128)))
13544	     (const_int 2)
13545	     (const_int 6)))])
13546
13547(define_insn "*jcc_2"
13548  [(set (pc)
13549	(if_then_else (match_operator 1 "ix86_comparison_operator"
13550				      [(reg FLAGS_REG) (const_int 0)])
13551		      (pc)
13552		      (label_ref (match_operand 0 "" ""))))]
13553  ""
13554  "%+j%c1\t%l0"
13555  [(set_attr "type" "ibr")
13556   (set_attr "modrm" "0")
13557   (set (attr "length")
13558	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13559				  (const_int -126))
13560			      (lt (minus (match_dup 0) (pc))
13561				  (const_int 128)))
13562	     (const_int 2)
13563	     (const_int 6)))])
13564
13565;; In general it is not safe to assume too much about CCmode registers,
13566;; so simplify-rtx stops when it sees a second one.  Under certain 
13567;; conditions this is safe on x86, so help combine not create
13568;;
13569;;	seta	%al
13570;;	testb	%al, %al
13571;;	je	Lfoo
13572
13573(define_split 
13574  [(set (pc)
13575	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13576				      [(reg FLAGS_REG) (const_int 0)])
13577			  (const_int 0))
13578		      (label_ref (match_operand 1 "" ""))
13579		      (pc)))]
13580  ""
13581  [(set (pc)
13582	(if_then_else (match_dup 0)
13583		      (label_ref (match_dup 1))
13584		      (pc)))]
13585{
13586  PUT_MODE (operands[0], VOIDmode);
13587})
13588  
13589(define_split 
13590  [(set (pc)
13591	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13592				      [(reg FLAGS_REG) (const_int 0)])
13593			  (const_int 0))
13594		      (label_ref (match_operand 1 "" ""))
13595		      (pc)))]
13596  ""
13597  [(set (pc)
13598	(if_then_else (match_dup 0)
13599		      (label_ref (match_dup 1))
13600		      (pc)))]
13601{
13602  rtx new_op0 = copy_rtx (operands[0]);
13603  operands[0] = new_op0;
13604  PUT_MODE (new_op0, VOIDmode);
13605  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13606					     GET_MODE (XEXP (new_op0, 0))));
13607
13608  /* Make sure that (a) the CCmode we have for the flags is strong
13609     enough for the reversed compare or (b) we have a valid FP compare.  */
13610  if (! ix86_comparison_operator (new_op0, VOIDmode))
13611    FAIL;
13612})
13613
13614;; Define combination compare-and-branch fp compare instructions to use
13615;; during early optimization.  Splitting the operation apart early makes
13616;; for bad code when we want to reverse the operation.
13617
13618(define_insn "*fp_jcc_1_mixed"
13619  [(set (pc)
13620	(if_then_else (match_operator 0 "comparison_operator"
13621			[(match_operand 1 "register_operand" "f,x")
13622			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13623	  (label_ref (match_operand 3 "" ""))
13624	  (pc)))
13625   (clobber (reg:CCFP FPSR_REG))
13626   (clobber (reg:CCFP FLAGS_REG))]
13627  "TARGET_MIX_SSE_I387
13628   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13629   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13630   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13631  "#")
13632
13633(define_insn "*fp_jcc_1_sse"
13634  [(set (pc)
13635	(if_then_else (match_operator 0 "comparison_operator"
13636			[(match_operand 1 "register_operand" "x")
13637			 (match_operand 2 "nonimmediate_operand" "xm")])
13638	  (label_ref (match_operand 3 "" ""))
13639	  (pc)))
13640   (clobber (reg:CCFP FPSR_REG))
13641   (clobber (reg:CCFP FLAGS_REG))]
13642  "TARGET_SSE_MATH
13643   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13644   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13645   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13646  "#")
13647
13648(define_insn "*fp_jcc_1_387"
13649  [(set (pc)
13650	(if_then_else (match_operator 0 "comparison_operator"
13651			[(match_operand 1 "register_operand" "f")
13652			 (match_operand 2 "register_operand" "f")])
13653	  (label_ref (match_operand 3 "" ""))
13654	  (pc)))
13655   (clobber (reg:CCFP FPSR_REG))
13656   (clobber (reg:CCFP FLAGS_REG))]
13657  "TARGET_CMOVE && TARGET_80387
13658   && FLOAT_MODE_P (GET_MODE (operands[1]))
13659   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13660   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13661  "#")
13662
13663(define_insn "*fp_jcc_2_mixed"
13664  [(set (pc)
13665	(if_then_else (match_operator 0 "comparison_operator"
13666			[(match_operand 1 "register_operand" "f,x")
13667			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13668	  (pc)
13669	  (label_ref (match_operand 3 "" ""))))
13670   (clobber (reg:CCFP FPSR_REG))
13671   (clobber (reg:CCFP FLAGS_REG))]
13672  "TARGET_MIX_SSE_I387
13673   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13674   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13675   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13676  "#")
13677
13678(define_insn "*fp_jcc_2_sse"
13679  [(set (pc)
13680	(if_then_else (match_operator 0 "comparison_operator"
13681			[(match_operand 1 "register_operand" "x")
13682			 (match_operand 2 "nonimmediate_operand" "xm")])
13683	  (pc)
13684	  (label_ref (match_operand 3 "" ""))))
13685   (clobber (reg:CCFP FPSR_REG))
13686   (clobber (reg:CCFP FLAGS_REG))]
13687  "TARGET_SSE_MATH
13688   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13689   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13690   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13691  "#")
13692
13693(define_insn "*fp_jcc_2_387"
13694  [(set (pc)
13695	(if_then_else (match_operator 0 "comparison_operator"
13696			[(match_operand 1 "register_operand" "f")
13697			 (match_operand 2 "register_operand" "f")])
13698	  (pc)
13699	  (label_ref (match_operand 3 "" ""))))
13700   (clobber (reg:CCFP FPSR_REG))
13701   (clobber (reg:CCFP FLAGS_REG))]
13702  "TARGET_CMOVE && TARGET_80387
13703   && FLOAT_MODE_P (GET_MODE (operands[1]))
13704   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13705   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13706  "#")
13707
13708(define_insn "*fp_jcc_3_387"
13709  [(set (pc)
13710	(if_then_else (match_operator 0 "comparison_operator"
13711			[(match_operand 1 "register_operand" "f")
13712			 (match_operand 2 "nonimmediate_operand" "fm")])
13713	  (label_ref (match_operand 3 "" ""))
13714	  (pc)))
13715   (clobber (reg:CCFP FPSR_REG))
13716   (clobber (reg:CCFP FLAGS_REG))
13717   (clobber (match_scratch:HI 4 "=a"))]
13718  "TARGET_80387
13719   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13720   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13721   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13722   && SELECT_CC_MODE (GET_CODE (operands[0]),
13723		      operands[1], operands[2]) == CCFPmode
13724   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13725  "#")
13726
13727(define_insn "*fp_jcc_4_387"
13728  [(set (pc)
13729	(if_then_else (match_operator 0 "comparison_operator"
13730			[(match_operand 1 "register_operand" "f")
13731			 (match_operand 2 "nonimmediate_operand" "fm")])
13732	  (pc)
13733	  (label_ref (match_operand 3 "" ""))))
13734   (clobber (reg:CCFP FPSR_REG))
13735   (clobber (reg:CCFP FLAGS_REG))
13736   (clobber (match_scratch:HI 4 "=a"))]
13737  "TARGET_80387
13738   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13739   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13740   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13741   && SELECT_CC_MODE (GET_CODE (operands[0]),
13742		      operands[1], operands[2]) == CCFPmode
13743   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13744  "#")
13745
13746(define_insn "*fp_jcc_5_387"
13747  [(set (pc)
13748	(if_then_else (match_operator 0 "comparison_operator"
13749			[(match_operand 1 "register_operand" "f")
13750			 (match_operand 2 "register_operand" "f")])
13751	  (label_ref (match_operand 3 "" ""))
13752	  (pc)))
13753   (clobber (reg:CCFP FPSR_REG))
13754   (clobber (reg:CCFP FLAGS_REG))
13755   (clobber (match_scratch:HI 4 "=a"))]
13756  "TARGET_80387
13757   && FLOAT_MODE_P (GET_MODE (operands[1]))
13758   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13759   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13760  "#")
13761
13762(define_insn "*fp_jcc_6_387"
13763  [(set (pc)
13764	(if_then_else (match_operator 0 "comparison_operator"
13765			[(match_operand 1 "register_operand" "f")
13766			 (match_operand 2 "register_operand" "f")])
13767	  (pc)
13768	  (label_ref (match_operand 3 "" ""))))
13769   (clobber (reg:CCFP FPSR_REG))
13770   (clobber (reg:CCFP FLAGS_REG))
13771   (clobber (match_scratch:HI 4 "=a"))]
13772  "TARGET_80387
13773   && FLOAT_MODE_P (GET_MODE (operands[1]))
13774   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13775   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13776  "#")
13777
13778(define_insn "*fp_jcc_7_387"
13779  [(set (pc)
13780	(if_then_else (match_operator 0 "comparison_operator"
13781			[(match_operand 1 "register_operand" "f")
13782			 (match_operand 2 "const0_operand" "X")])
13783	  (label_ref (match_operand 3 "" ""))
13784	  (pc)))
13785   (clobber (reg:CCFP FPSR_REG))
13786   (clobber (reg:CCFP FLAGS_REG))
13787   (clobber (match_scratch:HI 4 "=a"))]
13788  "TARGET_80387
13789   && FLOAT_MODE_P (GET_MODE (operands[1]))
13790   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13791   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13792   && SELECT_CC_MODE (GET_CODE (operands[0]),
13793		      operands[1], operands[2]) == CCFPmode
13794   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13795  "#")
13796
13797;; The order of operands in *fp_jcc_8_387 is forced by combine in
13798;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13799;; with a precedence over other operators and is always put in the first
13800;; place. Swap condition and operands to match ficom instruction.
13801
13802(define_insn "*fp_jcc_8<mode>_387"
13803  [(set (pc)
13804	(if_then_else (match_operator 0 "comparison_operator"
13805			[(match_operator 1 "float_operator"
13806			   [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13807			   (match_operand 3 "register_operand" "f,f")])
13808	  (label_ref (match_operand 4 "" ""))
13809	  (pc)))
13810   (clobber (reg:CCFP FPSR_REG))
13811   (clobber (reg:CCFP FLAGS_REG))
13812   (clobber (match_scratch:HI 5 "=a,a"))]
13813  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13814   && FLOAT_MODE_P (GET_MODE (operands[3]))
13815   && GET_MODE (operands[1]) == GET_MODE (operands[3])
13816   && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13817   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13818   && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13819  "#")
13820
13821(define_split
13822  [(set (pc)
13823	(if_then_else (match_operator 0 "comparison_operator"
13824			[(match_operand 1 "register_operand" "")
13825			 (match_operand 2 "nonimmediate_operand" "")])
13826	  (match_operand 3 "" "")
13827	  (match_operand 4 "" "")))
13828   (clobber (reg:CCFP FPSR_REG))
13829   (clobber (reg:CCFP FLAGS_REG))]
13830  "reload_completed"
13831  [(const_int 0)]
13832{
13833  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13834	                operands[3], operands[4], NULL_RTX, NULL_RTX);
13835  DONE;
13836})
13837
13838(define_split
13839  [(set (pc)
13840	(if_then_else (match_operator 0 "comparison_operator"
13841			[(match_operand 1 "register_operand" "")
13842			 (match_operand 2 "general_operand" "")])
13843	  (match_operand 3 "" "")
13844	  (match_operand 4 "" "")))
13845   (clobber (reg:CCFP FPSR_REG))
13846   (clobber (reg:CCFP FLAGS_REG))
13847   (clobber (match_scratch:HI 5 "=a"))]
13848  "reload_completed"
13849  [(const_int 0)]
13850{
13851  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13852	     		operands[3], operands[4], operands[5], NULL_RTX);
13853  DONE;
13854})
13855
13856(define_split
13857  [(set (pc)
13858	(if_then_else (match_operator 0 "comparison_operator"
13859			[(match_operator 1 "float_operator"
13860			   [(match_operand:X87MODEI12 2 "memory_operand" "")])
13861			   (match_operand 3 "register_operand" "")])
13862	  (match_operand 4 "" "")
13863	  (match_operand 5 "" "")))
13864   (clobber (reg:CCFP FPSR_REG))
13865   (clobber (reg:CCFP FLAGS_REG))
13866   (clobber (match_scratch:HI 6 "=a"))]
13867  "reload_completed"
13868  [(const_int 0)]
13869{
13870  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13871  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13872			operands[3], operands[7],
13873			operands[4], operands[5], operands[6], NULL_RTX);
13874  DONE;
13875})
13876
13877;; %%% Kill this when reload knows how to do it.
13878(define_split
13879  [(set (pc)
13880	(if_then_else (match_operator 0 "comparison_operator"
13881			[(match_operator 1 "float_operator"
13882			   [(match_operand:X87MODEI12 2 "register_operand" "")])
13883			   (match_operand 3 "register_operand" "")])
13884	  (match_operand 4 "" "")
13885	  (match_operand 5 "" "")))
13886   (clobber (reg:CCFP FPSR_REG))
13887   (clobber (reg:CCFP FLAGS_REG))
13888   (clobber (match_scratch:HI 6 "=a"))]
13889  "reload_completed"
13890  [(const_int 0)]
13891{
13892  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13893  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13894  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13895			operands[3], operands[7],
13896			operands[4], operands[5], operands[6], operands[2]);
13897  DONE;
13898})
13899
13900;; Unconditional and other jump instructions
13901
13902(define_insn "jump"
13903  [(set (pc)
13904	(label_ref (match_operand 0 "" "")))]
13905  ""
13906  "jmp\t%l0"
13907  [(set_attr "type" "ibr")
13908   (set (attr "length")
13909	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13910				  (const_int -126))
13911			      (lt (minus (match_dup 0) (pc))
13912				  (const_int 128)))
13913	     (const_int 2)
13914	     (const_int 5)))
13915   (set_attr "modrm" "0")])
13916
13917(define_expand "indirect_jump"
13918  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13919  ""
13920  "")
13921
13922(define_insn "*indirect_jump"
13923  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13924  "!TARGET_64BIT"
13925  "jmp\t%A0"
13926  [(set_attr "type" "ibr")
13927   (set_attr "length_immediate" "0")])
13928
13929(define_insn "*indirect_jump_rtx64"
13930  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13931  "TARGET_64BIT"
13932  "jmp\t%A0"
13933  [(set_attr "type" "ibr")
13934   (set_attr "length_immediate" "0")])
13935
13936(define_expand "tablejump"
13937  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13938	      (use (label_ref (match_operand 1 "" "")))])]
13939  ""
13940{
13941  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13942     relative.  Convert the relative address to an absolute address.  */
13943  if (flag_pic)
13944    {
13945      rtx op0, op1;
13946      enum rtx_code code;
13947
13948      if (TARGET_64BIT)
13949	{
13950	  code = PLUS;
13951	  op0 = operands[0];
13952	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13953	}
13954      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13955	{
13956	  code = PLUS;
13957	  op0 = operands[0];
13958	  op1 = pic_offset_table_rtx;
13959	}
13960      else
13961	{
13962	  code = MINUS;
13963	  op0 = pic_offset_table_rtx;
13964	  op1 = operands[0];
13965	}
13966
13967      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13968					 OPTAB_DIRECT);
13969    }
13970})
13971
13972(define_insn "*tablejump_1"
13973  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13974   (use (label_ref (match_operand 1 "" "")))]
13975  "!TARGET_64BIT"
13976  "jmp\t%A0"
13977  [(set_attr "type" "ibr")
13978   (set_attr "length_immediate" "0")])
13979
13980(define_insn "*tablejump_1_rtx64"
13981  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13982   (use (label_ref (match_operand 1 "" "")))]
13983  "TARGET_64BIT"
13984  "jmp\t%A0"
13985  [(set_attr "type" "ibr")
13986   (set_attr "length_immediate" "0")])
13987
13988;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13989
13990(define_peephole2
13991  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13992   (set (match_operand:QI 1 "register_operand" "")
13993	(match_operator:QI 2 "ix86_comparison_operator"
13994	  [(reg FLAGS_REG) (const_int 0)]))
13995   (set (match_operand 3 "q_regs_operand" "")
13996	(zero_extend (match_dup 1)))]
13997  "(peep2_reg_dead_p (3, operands[1])
13998    || operands_match_p (operands[1], operands[3]))
13999   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14000  [(set (match_dup 4) (match_dup 0))
14001   (set (strict_low_part (match_dup 5))
14002	(match_dup 2))]
14003{
14004  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14005  operands[5] = gen_lowpart (QImode, operands[3]);
14006  ix86_expand_clear (operands[3]);
14007})
14008
14009;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14010
14011(define_peephole2
14012  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14013   (set (match_operand:QI 1 "register_operand" "")
14014	(match_operator:QI 2 "ix86_comparison_operator"
14015	  [(reg FLAGS_REG) (const_int 0)]))
14016   (parallel [(set (match_operand 3 "q_regs_operand" "")
14017		   (zero_extend (match_dup 1)))
14018	      (clobber (reg:CC FLAGS_REG))])]
14019  "(peep2_reg_dead_p (3, operands[1])
14020    || operands_match_p (operands[1], operands[3]))
14021   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14022  [(set (match_dup 4) (match_dup 0))
14023   (set (strict_low_part (match_dup 5))
14024	(match_dup 2))]
14025{
14026  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14027  operands[5] = gen_lowpart (QImode, operands[3]);
14028  ix86_expand_clear (operands[3]);
14029})
14030
14031;; Call instructions.
14032
14033;; The predicates normally associated with named expanders are not properly
14034;; checked for calls.  This is a bug in the generic code, but it isn't that
14035;; easy to fix.  Ignore it for now and be prepared to fix things up.
14036
14037;; Call subroutine returning no value.
14038
14039(define_expand "call_pop"
14040  [(parallel [(call (match_operand:QI 0 "" "")
14041		    (match_operand:SI 1 "" ""))
14042	      (set (reg:SI SP_REG)
14043		   (plus:SI (reg:SI SP_REG)
14044			    (match_operand:SI 3 "" "")))])]
14045  "!TARGET_64BIT"
14046{
14047  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14048  DONE;
14049})
14050
14051(define_insn "*call_pop_0"
14052  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14053	 (match_operand:SI 1 "" ""))
14054   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14055			    (match_operand:SI 2 "immediate_operand" "")))]
14056  "!TARGET_64BIT"
14057{
14058  if (SIBLING_CALL_P (insn))
14059    return "jmp\t%P0";
14060  else
14061    return "call\t%P0";
14062}
14063  [(set_attr "type" "call")])
14064  
14065(define_insn "*call_pop_1"
14066  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14067	 (match_operand:SI 1 "" ""))
14068   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14069			    (match_operand:SI 2 "immediate_operand" "i")))]
14070  "!TARGET_64BIT"
14071{
14072  if (constant_call_address_operand (operands[0], Pmode))
14073    {
14074      if (SIBLING_CALL_P (insn))
14075	return "jmp\t%P0";
14076      else
14077	return "call\t%P0";
14078    }
14079  if (SIBLING_CALL_P (insn))
14080    return "jmp\t%A0";
14081  else
14082    return "call\t%A0";
14083}
14084  [(set_attr "type" "call")])
14085
14086(define_expand "call"
14087  [(call (match_operand:QI 0 "" "")
14088	 (match_operand 1 "" ""))
14089   (use (match_operand 2 "" ""))]
14090  ""
14091{
14092  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14093  DONE;
14094})
14095
14096(define_expand "sibcall"
14097  [(call (match_operand:QI 0 "" "")
14098	 (match_operand 1 "" ""))
14099   (use (match_operand 2 "" ""))]
14100  ""
14101{
14102  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14103  DONE;
14104})
14105
14106(define_insn "*call_0"
14107  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14108	 (match_operand 1 "" ""))]
14109  ""
14110{
14111  if (SIBLING_CALL_P (insn))
14112    return "jmp\t%P0";
14113  else
14114    return "call\t%P0";
14115}
14116  [(set_attr "type" "call")])
14117
14118(define_insn "*call_1"
14119  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14120	 (match_operand 1 "" ""))]
14121  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14122{
14123  if (constant_call_address_operand (operands[0], Pmode))
14124    return "call\t%P0";
14125  return "call\t%A0";
14126}
14127  [(set_attr "type" "call")])
14128
14129(define_insn "*sibcall_1"
14130  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14131	 (match_operand 1 "" ""))]
14132  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14133{
14134  if (constant_call_address_operand (operands[0], Pmode))
14135    return "jmp\t%P0";
14136  return "jmp\t%A0";
14137}
14138  [(set_attr "type" "call")])
14139
14140(define_insn "*call_1_rex64"
14141  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14142	 (match_operand 1 "" ""))]
14143  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14144{
14145  if (constant_call_address_operand (operands[0], Pmode))
14146    return "call\t%P0";
14147  return "call\t%A0";
14148}
14149  [(set_attr "type" "call")])
14150
14151(define_insn "*sibcall_1_rex64"
14152  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14153	 (match_operand 1 "" ""))]
14154  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14155  "jmp\t%P0"
14156  [(set_attr "type" "call")])
14157
14158(define_insn "*sibcall_1_rex64_v"
14159  [(call (mem:QI (reg:DI 40))
14160	 (match_operand 0 "" ""))]
14161  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14162  "jmp\t*%%r11"
14163  [(set_attr "type" "call")])
14164
14165
14166;; Call subroutine, returning value in operand 0
14167
14168(define_expand "call_value_pop"
14169  [(parallel [(set (match_operand 0 "" "")
14170		   (call (match_operand:QI 1 "" "")
14171			 (match_operand:SI 2 "" "")))
14172	      (set (reg:SI SP_REG)
14173		   (plus:SI (reg:SI SP_REG)
14174			    (match_operand:SI 4 "" "")))])]
14175  "!TARGET_64BIT"
14176{
14177  ix86_expand_call (operands[0], operands[1], operands[2],
14178		    operands[3], operands[4], 0);
14179  DONE;
14180})
14181
14182(define_expand "call_value"
14183  [(set (match_operand 0 "" "")
14184	(call (match_operand:QI 1 "" "")
14185	      (match_operand:SI 2 "" "")))
14186   (use (match_operand:SI 3 "" ""))]
14187  ;; Operand 2 not used on the i386.
14188  ""
14189{
14190  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14191  DONE;
14192})
14193
14194(define_expand "sibcall_value"
14195  [(set (match_operand 0 "" "")
14196	(call (match_operand:QI 1 "" "")
14197	      (match_operand:SI 2 "" "")))
14198   (use (match_operand:SI 3 "" ""))]
14199  ;; Operand 2 not used on the i386.
14200  ""
14201{
14202  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14203  DONE;
14204})
14205
14206;; Call subroutine returning any type.
14207
14208(define_expand "untyped_call"
14209  [(parallel [(call (match_operand 0 "" "")
14210		    (const_int 0))
14211	      (match_operand 1 "" "")
14212	      (match_operand 2 "" "")])]
14213  ""
14214{
14215  int i;
14216
14217  /* In order to give reg-stack an easier job in validating two
14218     coprocessor registers as containing a possible return value,
14219     simply pretend the untyped call returns a complex long double
14220     value.  */
14221
14222  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14223		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14224		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14225		    NULL, 0);
14226
14227  for (i = 0; i < XVECLEN (operands[2], 0); i++)
14228    {
14229      rtx set = XVECEXP (operands[2], 0, i);
14230      emit_move_insn (SET_DEST (set), SET_SRC (set));
14231    }
14232
14233  /* The optimizer does not know that the call sets the function value
14234     registers we stored in the result block.  We avoid problems by
14235     claiming that all hard registers are used and clobbered at this
14236     point.  */
14237  emit_insn (gen_blockage (const0_rtx));
14238
14239  DONE;
14240})
14241
14242;; Prologue and epilogue instructions
14243
14244;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14245;; all of memory.  This blocks insns from being moved across this point.
14246
14247(define_insn "blockage"
14248  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14249  ""
14250  ""
14251  [(set_attr "length" "0")])
14252
14253;; Insn emitted into the body of a function to return from a function.
14254;; This is only done if the function's epilogue is known to be simple.
14255;; See comments for ix86_can_use_return_insn_p in i386.c.
14256
14257(define_expand "return"
14258  [(return)]
14259  "ix86_can_use_return_insn_p ()"
14260{
14261  if (current_function_pops_args)
14262    {
14263      rtx popc = GEN_INT (current_function_pops_args);
14264      emit_jump_insn (gen_return_pop_internal (popc));
14265      DONE;
14266    }
14267})
14268
14269(define_insn "return_internal"
14270  [(return)]
14271  "reload_completed"
14272  "ret"
14273  [(set_attr "length" "1")
14274   (set_attr "length_immediate" "0")
14275   (set_attr "modrm" "0")])
14276
14277;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14278;; instruction Athlon and K8 have.
14279
14280(define_insn "return_internal_long"
14281  [(return)
14282   (unspec [(const_int 0)] UNSPEC_REP)]
14283  "reload_completed"
14284  "rep {;} ret"
14285  [(set_attr "length" "1")
14286   (set_attr "length_immediate" "0")
14287   (set_attr "prefix_rep" "1")
14288   (set_attr "modrm" "0")])
14289
14290(define_insn "return_pop_internal"
14291  [(return)
14292   (use (match_operand:SI 0 "const_int_operand" ""))]
14293  "reload_completed"
14294  "ret\t%0"
14295  [(set_attr "length" "3")
14296   (set_attr "length_immediate" "2")
14297   (set_attr "modrm" "0")])
14298
14299(define_insn "return_indirect_internal"
14300  [(return)
14301   (use (match_operand:SI 0 "register_operand" "r"))]
14302  "reload_completed"
14303  "jmp\t%A0"
14304  [(set_attr "type" "ibr")
14305   (set_attr "length_immediate" "0")])
14306
14307(define_insn "nop"
14308  [(const_int 0)]
14309  ""
14310  "nop"
14311  [(set_attr "length" "1")
14312   (set_attr "length_immediate" "0")
14313   (set_attr "modrm" "0")])
14314
14315;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14316;; branch prediction penalty for the third jump in a 16-byte
14317;; block on K8.
14318
14319(define_insn "align"
14320  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14321  ""
14322{
14323#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14324  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14325#else
14326  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14327     The align insn is used to avoid 3 jump instructions in the row to improve
14328     branch prediction and the benefits hardly outweigh the cost of extra 8
14329     nops on the average inserted by full alignment pseudo operation.  */
14330#endif
14331  return "";
14332}
14333  [(set_attr "length" "16")])
14334
14335(define_expand "prologue"
14336  [(const_int 1)]
14337  ""
14338  "ix86_expand_prologue (); DONE;")
14339
14340(define_insn "set_got"
14341  [(set (match_operand:SI 0 "register_operand" "=r")
14342	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14343   (clobber (reg:CC FLAGS_REG))]
14344  "!TARGET_64BIT"
14345  { return output_set_got (operands[0], NULL_RTX); }
14346  [(set_attr "type" "multi")
14347   (set_attr "length" "12")])
14348
14349(define_insn "set_got_labelled"
14350  [(set (match_operand:SI 0 "register_operand" "=r")
14351	(unspec:SI [(label_ref (match_operand 1 "" ""))]
14352	 UNSPEC_SET_GOT))
14353   (clobber (reg:CC FLAGS_REG))]
14354  "!TARGET_64BIT"
14355  { return output_set_got (operands[0], operands[1]); }
14356  [(set_attr "type" "multi")
14357   (set_attr "length" "12")])
14358
14359(define_insn "set_got_rex64"
14360  [(set (match_operand:DI 0 "register_operand" "=r")
14361	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14362  "TARGET_64BIT"
14363  "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14364  [(set_attr "type" "lea")
14365   (set_attr "length" "6")])
14366
14367(define_expand "epilogue"
14368  [(const_int 1)]
14369  ""
14370  "ix86_expand_epilogue (1); DONE;")
14371
14372(define_expand "sibcall_epilogue"
14373  [(const_int 1)]
14374  ""
14375  "ix86_expand_epilogue (0); DONE;")
14376
14377(define_expand "eh_return"
14378  [(use (match_operand 0 "register_operand" ""))]
14379  ""
14380{
14381  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14382
14383  /* Tricky bit: we write the address of the handler to which we will
14384     be returning into someone else's stack frame, one word below the
14385     stack address we wish to restore.  */
14386  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14387  tmp = plus_constant (tmp, -UNITS_PER_WORD);
14388  tmp = gen_rtx_MEM (Pmode, tmp);
14389  emit_move_insn (tmp, ra);
14390
14391  if (Pmode == SImode)
14392    emit_jump_insn (gen_eh_return_si (sa));
14393  else
14394    emit_jump_insn (gen_eh_return_di (sa));
14395  emit_barrier ();
14396  DONE;
14397})
14398
14399(define_insn_and_split "eh_return_si"
14400  [(set (pc) 
14401        (unspec [(match_operand:SI 0 "register_operand" "c")]
14402	         UNSPEC_EH_RETURN))]
14403  "!TARGET_64BIT"
14404  "#"
14405  "reload_completed"
14406  [(const_int 1)]
14407  "ix86_expand_epilogue (2); DONE;")
14408
14409(define_insn_and_split "eh_return_di"
14410  [(set (pc) 
14411        (unspec [(match_operand:DI 0 "register_operand" "c")]
14412	         UNSPEC_EH_RETURN))]
14413  "TARGET_64BIT"
14414  "#"
14415  "reload_completed"
14416  [(const_int 1)]
14417  "ix86_expand_epilogue (2); DONE;")
14418
14419(define_insn "leave"
14420  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14421   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14422   (clobber (mem:BLK (scratch)))]
14423  "!TARGET_64BIT"
14424  "leave"
14425  [(set_attr "type" "leave")])
14426
14427(define_insn "leave_rex64"
14428  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14429   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14430   (clobber (mem:BLK (scratch)))]
14431  "TARGET_64BIT"
14432  "leave"
14433  [(set_attr "type" "leave")])
14434
14435(define_expand "ffssi2"
14436  [(parallel
14437     [(set (match_operand:SI 0 "register_operand" "") 
14438	   (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14439      (clobber (match_scratch:SI 2 ""))
14440      (clobber (reg:CC FLAGS_REG))])]
14441  ""
14442  "")
14443
14444(define_insn_and_split "*ffs_cmove"
14445  [(set (match_operand:SI 0 "register_operand" "=r") 
14446	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14447   (clobber (match_scratch:SI 2 "=&r"))
14448   (clobber (reg:CC FLAGS_REG))]
14449  "TARGET_CMOVE"
14450  "#"
14451  "&& reload_completed"
14452  [(set (match_dup 2) (const_int -1))
14453   (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14454	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14455   (set (match_dup 0) (if_then_else:SI
14456			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14457			(match_dup 2)
14458			(match_dup 0)))
14459   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14460	      (clobber (reg:CC FLAGS_REG))])]
14461  "")
14462
14463(define_insn_and_split "*ffs_no_cmove"
14464  [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14465	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14466   (clobber (match_scratch:SI 2 "=&q"))
14467   (clobber (reg:CC FLAGS_REG))]
14468  ""
14469  "#"
14470  "reload_completed"
14471  [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14472	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14473   (set (strict_low_part (match_dup 3))
14474	(eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14475   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14476	      (clobber (reg:CC FLAGS_REG))])
14477   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14478	      (clobber (reg:CC FLAGS_REG))])
14479   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14480	      (clobber (reg:CC FLAGS_REG))])]
14481{
14482  operands[3] = gen_lowpart (QImode, operands[2]);
14483  ix86_expand_clear (operands[2]);
14484})
14485
14486(define_insn "*ffssi_1"
14487  [(set (reg:CCZ FLAGS_REG)
14488	(compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14489		     (const_int 0)))
14490   (set (match_operand:SI 0 "register_operand" "=r")
14491	(ctz:SI (match_dup 1)))]
14492  ""
14493  "bsf{l}\t{%1, %0|%0, %1}"
14494  [(set_attr "prefix_0f" "1")])
14495
14496(define_expand "ffsdi2"
14497  [(parallel
14498     [(set (match_operand:DI 0 "register_operand" "") 
14499	   (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14500      (clobber (match_scratch:DI 2 ""))
14501      (clobber (reg:CC FLAGS_REG))])]
14502  "TARGET_64BIT && TARGET_CMOVE"
14503  "")
14504
14505(define_insn_and_split "*ffs_rex64"
14506  [(set (match_operand:DI 0 "register_operand" "=r") 
14507	(ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14508   (clobber (match_scratch:DI 2 "=&r"))
14509   (clobber (reg:CC FLAGS_REG))]
14510  "TARGET_64BIT && TARGET_CMOVE"
14511  "#"
14512  "&& reload_completed"
14513  [(set (match_dup 2) (const_int -1))
14514   (parallel [(set (reg:CCZ FLAGS_REG)
14515		   (compare:CCZ (match_dup 1) (const_int 0)))
14516	      (set (match_dup 0) (ctz:DI (match_dup 1)))])
14517   (set (match_dup 0) (if_then_else:DI
14518			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14519			(match_dup 2)
14520			(match_dup 0)))
14521   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14522	      (clobber (reg:CC FLAGS_REG))])]
14523  "")
14524
14525(define_insn "*ffsdi_1"
14526  [(set (reg:CCZ FLAGS_REG)
14527	(compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14528		     (const_int 0)))
14529   (set (match_operand:DI 0 "register_operand" "=r")
14530	(ctz:DI (match_dup 1)))]
14531  "TARGET_64BIT"
14532  "bsf{q}\t{%1, %0|%0, %1}"
14533  [(set_attr "prefix_0f" "1")])
14534
14535(define_insn "ctzsi2"
14536  [(set (match_operand:SI 0 "register_operand" "=r")
14537	(ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14538   (clobber (reg:CC FLAGS_REG))]
14539  ""
14540  "bsf{l}\t{%1, %0|%0, %1}"
14541  [(set_attr "prefix_0f" "1")])
14542
14543(define_insn "ctzdi2"
14544  [(set (match_operand:DI 0 "register_operand" "=r")
14545	(ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14546   (clobber (reg:CC FLAGS_REG))]
14547  "TARGET_64BIT"
14548  "bsf{q}\t{%1, %0|%0, %1}"
14549  [(set_attr "prefix_0f" "1")])
14550
14551(define_expand "clzsi2"
14552  [(parallel
14553     [(set (match_operand:SI 0 "register_operand" "")
14554	   (minus:SI (const_int 31)
14555		     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14556      (clobber (reg:CC FLAGS_REG))])
14557   (parallel
14558     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14559      (clobber (reg:CC FLAGS_REG))])]
14560  ""
14561  "")
14562
14563(define_insn "*bsr"
14564  [(set (match_operand:SI 0 "register_operand" "=r")
14565	(minus:SI (const_int 31)
14566		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14567   (clobber (reg:CC FLAGS_REG))]
14568  ""
14569  "bsr{l}\t{%1, %0|%0, %1}"
14570  [(set_attr "prefix_0f" "1")])
14571
14572(define_expand "clzdi2"
14573  [(parallel
14574     [(set (match_operand:DI 0 "register_operand" "")
14575	   (minus:DI (const_int 63)
14576		     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14577      (clobber (reg:CC FLAGS_REG))])
14578   (parallel
14579     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14580      (clobber (reg:CC FLAGS_REG))])]
14581  "TARGET_64BIT"
14582  "")
14583
14584(define_insn "*bsr_rex64"
14585  [(set (match_operand:DI 0 "register_operand" "=r")
14586	(minus:DI (const_int 63)
14587		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14588   (clobber (reg:CC FLAGS_REG))]
14589  "TARGET_64BIT"
14590  "bsr{q}\t{%1, %0|%0, %1}"
14591  [(set_attr "prefix_0f" "1")])
14592
14593;; Thread-local storage patterns for ELF.
14594;;
14595;; Note that these code sequences must appear exactly as shown
14596;; in order to allow linker relaxation.
14597
14598(define_insn "*tls_global_dynamic_32_gnu"
14599  [(set (match_operand:SI 0 "register_operand" "=a")
14600	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14601		    (match_operand:SI 2 "tls_symbolic_operand" "")
14602		    (match_operand:SI 3 "call_insn_operand" "")]
14603		    UNSPEC_TLS_GD))
14604   (clobber (match_scratch:SI 4 "=d"))
14605   (clobber (match_scratch:SI 5 "=c"))
14606   (clobber (reg:CC FLAGS_REG))]
14607  "!TARGET_64BIT && TARGET_GNU_TLS"
14608  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14609  [(set_attr "type" "multi")
14610   (set_attr "length" "12")])
14611
14612(define_insn "*tls_global_dynamic_32_sun"
14613  [(set (match_operand:SI 0 "register_operand" "=a")
14614	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14615		    (match_operand:SI 2 "tls_symbolic_operand" "")
14616		    (match_operand:SI 3 "call_insn_operand" "")]
14617		    UNSPEC_TLS_GD))
14618   (clobber (match_scratch:SI 4 "=d"))
14619   (clobber (match_scratch:SI 5 "=c"))
14620   (clobber (reg:CC FLAGS_REG))]
14621  "!TARGET_64BIT && TARGET_SUN_TLS"
14622  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14623	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14624  [(set_attr "type" "multi")
14625   (set_attr "length" "14")])
14626
14627(define_expand "tls_global_dynamic_32"
14628  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14629		   (unspec:SI
14630		    [(match_dup 2)
14631		     (match_operand:SI 1 "tls_symbolic_operand" "")
14632		     (match_dup 3)]
14633		    UNSPEC_TLS_GD))
14634	      (clobber (match_scratch:SI 4 ""))
14635	      (clobber (match_scratch:SI 5 ""))
14636	      (clobber (reg:CC FLAGS_REG))])]
14637  ""
14638{
14639  if (flag_pic)
14640    operands[2] = pic_offset_table_rtx;
14641  else
14642    {
14643      operands[2] = gen_reg_rtx (Pmode);
14644      emit_insn (gen_set_got (operands[2]));
14645    }
14646  if (TARGET_GNU2_TLS)
14647    {
14648       emit_insn (gen_tls_dynamic_gnu2_32
14649		  (operands[0], operands[1], operands[2]));
14650       DONE;
14651    }
14652  operands[3] = ix86_tls_get_addr ();
14653})
14654
14655(define_insn "*tls_global_dynamic_64"
14656  [(set (match_operand:DI 0 "register_operand" "=a")
14657	(call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14658		 (match_operand:DI 3 "" "")))
14659   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14660	      UNSPEC_TLS_GD)]
14661  "TARGET_64BIT"
14662  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14663  [(set_attr "type" "multi")
14664   (set_attr "length" "16")])
14665
14666(define_expand "tls_global_dynamic_64"
14667  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14668		   (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14669	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14670			 UNSPEC_TLS_GD)])]
14671  ""
14672{
14673  if (TARGET_GNU2_TLS)
14674    {
14675       emit_insn (gen_tls_dynamic_gnu2_64
14676		  (operands[0], operands[1]));
14677       DONE;
14678    }
14679  operands[2] = ix86_tls_get_addr ();
14680})
14681
14682(define_insn "*tls_local_dynamic_base_32_gnu"
14683  [(set (match_operand:SI 0 "register_operand" "=a")
14684	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14685                    (match_operand:SI 2 "call_insn_operand" "")]
14686		   UNSPEC_TLS_LD_BASE))
14687   (clobber (match_scratch:SI 3 "=d"))
14688   (clobber (match_scratch:SI 4 "=c"))
14689   (clobber (reg:CC FLAGS_REG))]
14690  "!TARGET_64BIT && TARGET_GNU_TLS"
14691  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14692  [(set_attr "type" "multi")
14693   (set_attr "length" "11")])
14694
14695(define_insn "*tls_local_dynamic_base_32_sun"
14696  [(set (match_operand:SI 0 "register_operand" "=a")
14697	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14698                    (match_operand:SI 2 "call_insn_operand" "")]
14699		   UNSPEC_TLS_LD_BASE))
14700   (clobber (match_scratch:SI 3 "=d"))
14701   (clobber (match_scratch:SI 4 "=c"))
14702   (clobber (reg:CC FLAGS_REG))]
14703  "!TARGET_64BIT && TARGET_SUN_TLS"
14704  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14705	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14706  [(set_attr "type" "multi")
14707   (set_attr "length" "13")])
14708
14709(define_expand "tls_local_dynamic_base_32"
14710  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14711		   (unspec:SI [(match_dup 1) (match_dup 2)]
14712			      UNSPEC_TLS_LD_BASE))
14713	      (clobber (match_scratch:SI 3 ""))
14714	      (clobber (match_scratch:SI 4 ""))
14715	      (clobber (reg:CC FLAGS_REG))])]
14716  ""
14717{
14718  if (flag_pic)
14719    operands[1] = pic_offset_table_rtx;
14720  else
14721    {
14722      operands[1] = gen_reg_rtx (Pmode);
14723      emit_insn (gen_set_got (operands[1]));
14724    }
14725  if (TARGET_GNU2_TLS)
14726    {
14727       emit_insn (gen_tls_dynamic_gnu2_32
14728		  (operands[0], ix86_tls_module_base (), operands[1]));
14729       DONE;
14730    }
14731  operands[2] = ix86_tls_get_addr ();
14732})
14733
14734(define_insn "*tls_local_dynamic_base_64"
14735  [(set (match_operand:DI 0 "register_operand" "=a")
14736	(call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14737		 (match_operand:DI 2 "" "")))
14738   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14739  "TARGET_64BIT"
14740  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14741  [(set_attr "type" "multi")
14742   (set_attr "length" "12")])
14743
14744(define_expand "tls_local_dynamic_base_64"
14745  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14746		   (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14747	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14748  ""
14749{
14750  if (TARGET_GNU2_TLS)
14751    {
14752       emit_insn (gen_tls_dynamic_gnu2_64
14753		  (operands[0], ix86_tls_module_base ()));
14754       DONE;
14755    }
14756  operands[1] = ix86_tls_get_addr ();
14757})
14758
14759;; Local dynamic of a single variable is a lose.  Show combine how
14760;; to convert that back to global dynamic.
14761
14762(define_insn_and_split "*tls_local_dynamic_32_once"
14763  [(set (match_operand:SI 0 "register_operand" "=a")
14764	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14765			     (match_operand:SI 2 "call_insn_operand" "")]
14766			    UNSPEC_TLS_LD_BASE)
14767		 (const:SI (unspec:SI
14768			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
14769			    UNSPEC_DTPOFF))))
14770   (clobber (match_scratch:SI 4 "=d"))
14771   (clobber (match_scratch:SI 5 "=c"))
14772   (clobber (reg:CC FLAGS_REG))]
14773  ""
14774  "#"
14775  ""
14776  [(parallel [(set (match_dup 0)
14777		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14778			      UNSPEC_TLS_GD))
14779	      (clobber (match_dup 4))
14780	      (clobber (match_dup 5))
14781	      (clobber (reg:CC FLAGS_REG))])]
14782  "")
14783
14784;; Load and add the thread base pointer from %gs:0.
14785
14786(define_insn "*load_tp_si"
14787  [(set (match_operand:SI 0 "register_operand" "=r")
14788	(unspec:SI [(const_int 0)] UNSPEC_TP))]
14789  "!TARGET_64BIT"
14790  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14791  [(set_attr "type" "imov")
14792   (set_attr "modrm" "0")
14793   (set_attr "length" "7")
14794   (set_attr "memory" "load")
14795   (set_attr "imm_disp" "false")])
14796
14797(define_insn "*add_tp_si"
14798  [(set (match_operand:SI 0 "register_operand" "=r")
14799	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14800		 (match_operand:SI 1 "register_operand" "0")))
14801   (clobber (reg:CC FLAGS_REG))]
14802  "!TARGET_64BIT"
14803  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14804  [(set_attr "type" "alu")
14805   (set_attr "modrm" "0")
14806   (set_attr "length" "7")
14807   (set_attr "memory" "load")
14808   (set_attr "imm_disp" "false")])
14809
14810(define_insn "*load_tp_di"
14811  [(set (match_operand:DI 0 "register_operand" "=r")
14812	(unspec:DI [(const_int 0)] UNSPEC_TP))]
14813  "TARGET_64BIT"
14814  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14815  [(set_attr "type" "imov")
14816   (set_attr "modrm" "0")
14817   (set_attr "length" "7")
14818   (set_attr "memory" "load")
14819   (set_attr "imm_disp" "false")])
14820
14821(define_insn "*add_tp_di"
14822  [(set (match_operand:DI 0 "register_operand" "=r")
14823	(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14824		 (match_operand:DI 1 "register_operand" "0")))
14825   (clobber (reg:CC FLAGS_REG))]
14826  "TARGET_64BIT"
14827  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14828  [(set_attr "type" "alu")
14829   (set_attr "modrm" "0")
14830   (set_attr "length" "7")
14831   (set_attr "memory" "load")
14832   (set_attr "imm_disp" "false")])
14833
14834;; GNU2 TLS patterns can be split.
14835
14836(define_expand "tls_dynamic_gnu2_32"
14837  [(set (match_dup 3)
14838	(plus:SI (match_operand:SI 2 "register_operand" "")
14839		 (const:SI
14840		  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14841			     UNSPEC_TLSDESC))))
14842   (parallel
14843    [(set (match_operand:SI 0 "register_operand" "")
14844	  (unspec:SI [(match_dup 1) (match_dup 3)
14845		      (match_dup 2) (reg:SI SP_REG)]
14846		      UNSPEC_TLSDESC))
14847     (clobber (reg:CC FLAGS_REG))])]
14848  "!TARGET_64BIT && TARGET_GNU2_TLS"
14849{
14850  operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14851  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14852})
14853
14854(define_insn "*tls_dynamic_lea_32"
14855  [(set (match_operand:SI 0 "register_operand" "=r")
14856	(plus:SI (match_operand:SI 1 "register_operand" "b")
14857		 (const:SI
14858		  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14859			      UNSPEC_TLSDESC))))]
14860  "!TARGET_64BIT && TARGET_GNU2_TLS"
14861  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14862  [(set_attr "type" "lea")
14863   (set_attr "mode" "SI")
14864   (set_attr "length" "6")
14865   (set_attr "length_address" "4")])
14866
14867(define_insn "*tls_dynamic_call_32"
14868  [(set (match_operand:SI 0 "register_operand" "=a")
14869	(unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14870		    (match_operand:SI 2 "register_operand" "0")
14871		    ;; we have to make sure %ebx still points to the GOT
14872		    (match_operand:SI 3 "register_operand" "b")
14873		    (reg:SI SP_REG)]
14874		   UNSPEC_TLSDESC))
14875   (clobber (reg:CC FLAGS_REG))]
14876  "!TARGET_64BIT && TARGET_GNU2_TLS"
14877  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14878  [(set_attr "type" "call")
14879   (set_attr "length" "2")
14880   (set_attr "length_address" "0")])
14881
14882(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14883  [(set (match_operand:SI 0 "register_operand" "=&a")
14884	(plus:SI
14885	 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14886		     (match_operand:SI 4 "" "")
14887		     (match_operand:SI 2 "register_operand" "b")
14888		     (reg:SI SP_REG)]
14889		    UNSPEC_TLSDESC)
14890	 (const:SI (unspec:SI
14891		    [(match_operand:SI 1 "tls_symbolic_operand" "")]
14892		    UNSPEC_DTPOFF))))
14893   (clobber (reg:CC FLAGS_REG))]
14894  "!TARGET_64BIT && TARGET_GNU2_TLS"
14895  "#"
14896  ""
14897  [(set (match_dup 0) (match_dup 5))]
14898{
14899  operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14900  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14901})
14902
14903(define_expand "tls_dynamic_gnu2_64"
14904  [(set (match_dup 2)
14905	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14906		   UNSPEC_TLSDESC))
14907   (parallel
14908    [(set (match_operand:DI 0 "register_operand" "")
14909	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14910		     UNSPEC_TLSDESC))
14911     (clobber (reg:CC FLAGS_REG))])]
14912  "TARGET_64BIT && TARGET_GNU2_TLS"
14913{
14914  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14915  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14916})
14917
14918(define_insn "*tls_dynamic_lea_64"
14919  [(set (match_operand:DI 0 "register_operand" "=r")
14920	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14921		   UNSPEC_TLSDESC))]
14922  "TARGET_64BIT && TARGET_GNU2_TLS"
14923  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14924  [(set_attr "type" "lea")
14925   (set_attr "mode" "DI")
14926   (set_attr "length" "7")
14927   (set_attr "length_address" "4")])
14928
14929(define_insn "*tls_dynamic_call_64"
14930  [(set (match_operand:DI 0 "register_operand" "=a")
14931	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14932		    (match_operand:DI 2 "register_operand" "0")
14933		    (reg:DI SP_REG)]
14934		   UNSPEC_TLSDESC))
14935   (clobber (reg:CC FLAGS_REG))]
14936  "TARGET_64BIT && TARGET_GNU2_TLS"
14937  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14938  [(set_attr "type" "call")
14939   (set_attr "length" "2")
14940   (set_attr "length_address" "0")])
14941
14942(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14943  [(set (match_operand:DI 0 "register_operand" "=&a")
14944	(plus:DI
14945	 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14946		     (match_operand:DI 3 "" "")
14947		     (reg:DI SP_REG)]
14948		    UNSPEC_TLSDESC)
14949	 (const:DI (unspec:DI
14950		    [(match_operand:DI 1 "tls_symbolic_operand" "")]
14951		    UNSPEC_DTPOFF))))
14952   (clobber (reg:CC FLAGS_REG))]
14953  "TARGET_64BIT && TARGET_GNU2_TLS"
14954  "#"
14955  ""
14956  [(set (match_dup 0) (match_dup 4))]
14957{
14958  operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14959  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14960})
14961
14962;;
14963
14964;; These patterns match the binary 387 instructions for addM3, subM3,
14965;; mulM3 and divM3.  There are three patterns for each of DFmode and
14966;; SFmode.  The first is the normal insn, the second the same insn but
14967;; with one operand a conversion, and the third the same insn but with
14968;; the other operand a conversion.  The conversion may be SFmode or
14969;; SImode if the target mode DFmode, but only SImode if the target mode
14970;; is SFmode.
14971
14972;; Gcc is slightly more smart about handling normal two address instructions
14973;; so use special patterns for add and mull.
14974
14975(define_insn "*fop_sf_comm_mixed"
14976  [(set (match_operand:SF 0 "register_operand" "=f,x")
14977	(match_operator:SF 3 "binary_fp_operator"
14978			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14979			 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14980  "TARGET_MIX_SSE_I387
14981   && COMMUTATIVE_ARITH_P (operands[3])
14982   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14983  "* return output_387_binary_op (insn, operands);"
14984  [(set (attr "type") 
14985	(if_then_else (eq_attr "alternative" "1")
14986	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14987	      (const_string "ssemul")
14988	      (const_string "sseadd"))
14989	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
14990	      (const_string "fmul")
14991	      (const_string "fop"))))
14992   (set_attr "mode" "SF")])
14993
14994(define_insn "*fop_sf_comm_sse"
14995  [(set (match_operand:SF 0 "register_operand" "=x")
14996	(match_operator:SF 3 "binary_fp_operator"
14997			[(match_operand:SF 1 "nonimmediate_operand" "%0")
14998			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14999  "TARGET_SSE_MATH
15000   && COMMUTATIVE_ARITH_P (operands[3])
15001   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15002  "* return output_387_binary_op (insn, operands);"
15003  [(set (attr "type") 
15004        (if_then_else (match_operand:SF 3 "mult_operator" "") 
15005	   (const_string "ssemul")
15006	   (const_string "sseadd")))
15007   (set_attr "mode" "SF")])
15008
15009(define_insn "*fop_sf_comm_i387"
15010  [(set (match_operand:SF 0 "register_operand" "=f")
15011	(match_operator:SF 3 "binary_fp_operator"
15012			[(match_operand:SF 1 "nonimmediate_operand" "%0")
15013			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15014  "TARGET_80387
15015   && COMMUTATIVE_ARITH_P (operands[3])
15016   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15017  "* return output_387_binary_op (insn, operands);"
15018  [(set (attr "type") 
15019	(if_then_else (match_operand:SF 3 "mult_operator" "") 
15020	   (const_string "fmul")
15021	   (const_string "fop")))
15022   (set_attr "mode" "SF")])
15023
15024(define_insn "*fop_sf_1_mixed"
15025  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15026	(match_operator:SF 3 "binary_fp_operator"
15027			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15028			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15029  "TARGET_MIX_SSE_I387
15030   && !COMMUTATIVE_ARITH_P (operands[3])
15031   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15032  "* return output_387_binary_op (insn, operands);"
15033  [(set (attr "type") 
15034        (cond [(and (eq_attr "alternative" "2")
15035	            (match_operand:SF 3 "mult_operator" ""))
15036                 (const_string "ssemul")
15037	       (and (eq_attr "alternative" "2")
15038	            (match_operand:SF 3 "div_operator" ""))
15039                 (const_string "ssediv")
15040	       (eq_attr "alternative" "2")
15041                 (const_string "sseadd")
15042	       (match_operand:SF 3 "mult_operator" "") 
15043                 (const_string "fmul")
15044               (match_operand:SF 3 "div_operator" "") 
15045                 (const_string "fdiv")
15046              ]
15047              (const_string "fop")))
15048   (set_attr "mode" "SF")])
15049
15050(define_insn "*fop_sf_1_sse"
15051  [(set (match_operand:SF 0 "register_operand" "=x")
15052	(match_operator:SF 3 "binary_fp_operator"
15053			[(match_operand:SF 1 "register_operand" "0")
15054			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15055  "TARGET_SSE_MATH
15056   && !COMMUTATIVE_ARITH_P (operands[3])"
15057  "* return output_387_binary_op (insn, operands);"
15058  [(set (attr "type") 
15059        (cond [(match_operand:SF 3 "mult_operator" "")
15060                 (const_string "ssemul")
15061	       (match_operand:SF 3 "div_operator" "")
15062                 (const_string "ssediv")
15063              ]
15064              (const_string "sseadd")))
15065   (set_attr "mode" "SF")])
15066
15067;; This pattern is not fully shadowed by the pattern above.
15068(define_insn "*fop_sf_1_i387"
15069  [(set (match_operand:SF 0 "register_operand" "=f,f")
15070	(match_operator:SF 3 "binary_fp_operator"
15071			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15072			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15073  "TARGET_80387 && !TARGET_SSE_MATH
15074   && !COMMUTATIVE_ARITH_P (operands[3])
15075   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15076  "* return output_387_binary_op (insn, operands);"
15077  [(set (attr "type") 
15078        (cond [(match_operand:SF 3 "mult_operator" "") 
15079                 (const_string "fmul")
15080               (match_operand:SF 3 "div_operator" "") 
15081                 (const_string "fdiv")
15082              ]
15083              (const_string "fop")))
15084   (set_attr "mode" "SF")])
15085
15086;; ??? Add SSE splitters for these!
15087(define_insn "*fop_sf_2<mode>_i387"
15088  [(set (match_operand:SF 0 "register_operand" "=f,f")
15089	(match_operator:SF 3 "binary_fp_operator"
15090	  [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15091	   (match_operand:SF 2 "register_operand" "0,0")]))]
15092  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15093  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15094  [(set (attr "type") 
15095        (cond [(match_operand:SF 3 "mult_operator" "") 
15096                 (const_string "fmul")
15097               (match_operand:SF 3 "div_operator" "") 
15098                 (const_string "fdiv")
15099              ]
15100              (const_string "fop")))
15101   (set_attr "fp_int_src" "true")
15102   (set_attr "mode" "<MODE>")])
15103
15104(define_insn "*fop_sf_3<mode>_i387"
15105  [(set (match_operand:SF 0 "register_operand" "=f,f")
15106	(match_operator:SF 3 "binary_fp_operator"
15107	  [(match_operand:SF 1 "register_operand" "0,0")
15108	   (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15109  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15110  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15111  [(set (attr "type") 
15112        (cond [(match_operand:SF 3 "mult_operator" "") 
15113                 (const_string "fmul")
15114               (match_operand:SF 3 "div_operator" "") 
15115                 (const_string "fdiv")
15116              ]
15117              (const_string "fop")))
15118   (set_attr "fp_int_src" "true")
15119   (set_attr "mode" "<MODE>")])
15120
15121(define_insn "*fop_df_comm_mixed"
15122  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15123	(match_operator:DF 3 "binary_fp_operator"
15124			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15125			 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15126  "TARGET_SSE2 && TARGET_MIX_SSE_I387
15127   && COMMUTATIVE_ARITH_P (operands[3])
15128   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15129  "* return output_387_binary_op (insn, operands);"
15130  [(set (attr "type") 
15131	(if_then_else (eq_attr "alternative" "1")
15132	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15133	      (const_string "ssemul")
15134	      (const_string "sseadd"))
15135	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15136	      (const_string "fmul")
15137	      (const_string "fop"))))
15138   (set_attr "mode" "DF")])
15139
15140(define_insn "*fop_df_comm_sse"
15141  [(set (match_operand:DF 0 "register_operand" "=Y")
15142	(match_operator:DF 3 "binary_fp_operator"
15143			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15144			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15145  "TARGET_SSE2 && TARGET_SSE_MATH
15146   && COMMUTATIVE_ARITH_P (operands[3])
15147   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15148  "* return output_387_binary_op (insn, operands);"
15149  [(set (attr "type") 
15150        (if_then_else (match_operand:DF 3 "mult_operator" "") 
15151	   (const_string "ssemul")
15152	   (const_string "sseadd")))
15153   (set_attr "mode" "DF")])
15154
15155(define_insn "*fop_df_comm_i387"
15156  [(set (match_operand:DF 0 "register_operand" "=f")
15157	(match_operator:DF 3 "binary_fp_operator"
15158			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15159			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15160  "TARGET_80387
15161   && COMMUTATIVE_ARITH_P (operands[3])
15162   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15163  "* return output_387_binary_op (insn, operands);"
15164  [(set (attr "type") 
15165	(if_then_else (match_operand:DF 3 "mult_operator" "") 
15166	   (const_string "fmul")
15167	   (const_string "fop")))
15168   (set_attr "mode" "DF")])
15169
15170(define_insn "*fop_df_1_mixed"
15171  [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15172	(match_operator:DF 3 "binary_fp_operator"
15173			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15174			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15175  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15176   && !COMMUTATIVE_ARITH_P (operands[3])
15177   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15178  "* return output_387_binary_op (insn, operands);"
15179  [(set (attr "type") 
15180        (cond [(and (eq_attr "alternative" "2")
15181	            (match_operand:DF 3 "mult_operator" ""))
15182                 (const_string "ssemul")
15183	       (and (eq_attr "alternative" "2")
15184	            (match_operand:DF 3 "div_operator" ""))
15185                 (const_string "ssediv")
15186	       (eq_attr "alternative" "2")
15187                 (const_string "sseadd")
15188	       (match_operand:DF 3 "mult_operator" "") 
15189                 (const_string "fmul")
15190               (match_operand:DF 3 "div_operator" "") 
15191                 (const_string "fdiv")
15192              ]
15193              (const_string "fop")))
15194   (set_attr "mode" "DF")])
15195
15196(define_insn "*fop_df_1_sse"
15197  [(set (match_operand:DF 0 "register_operand" "=Y")
15198	(match_operator:DF 3 "binary_fp_operator"
15199			[(match_operand:DF 1 "register_operand" "0")
15200			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15201  "TARGET_SSE2 && TARGET_SSE_MATH
15202   && !COMMUTATIVE_ARITH_P (operands[3])"
15203  "* return output_387_binary_op (insn, operands);"
15204  [(set_attr "mode" "DF")
15205   (set (attr "type") 
15206        (cond [(match_operand:DF 3 "mult_operator" "")
15207                 (const_string "ssemul")
15208	       (match_operand:DF 3 "div_operator" "")
15209                 (const_string "ssediv")
15210              ]
15211              (const_string "sseadd")))])
15212
15213;; This pattern is not fully shadowed by the pattern above.
15214(define_insn "*fop_df_1_i387"
15215  [(set (match_operand:DF 0 "register_operand" "=f,f")
15216	(match_operator:DF 3 "binary_fp_operator"
15217			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15218			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15219  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15220   && !COMMUTATIVE_ARITH_P (operands[3])
15221   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15222  "* return output_387_binary_op (insn, operands);"
15223  [(set (attr "type") 
15224        (cond [(match_operand:DF 3 "mult_operator" "") 
15225                 (const_string "fmul")
15226               (match_operand:DF 3 "div_operator" "")
15227                 (const_string "fdiv")
15228              ]
15229              (const_string "fop")))
15230   (set_attr "mode" "DF")])
15231
15232;; ??? Add SSE splitters for these!
15233(define_insn "*fop_df_2<mode>_i387"
15234  [(set (match_operand:DF 0 "register_operand" "=f,f")
15235	(match_operator:DF 3 "binary_fp_operator"
15236	   [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15237	    (match_operand:DF 2 "register_operand" "0,0")]))]
15238  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15239   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15240  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15241  [(set (attr "type") 
15242        (cond [(match_operand:DF 3 "mult_operator" "") 
15243                 (const_string "fmul")
15244               (match_operand:DF 3 "div_operator" "") 
15245                 (const_string "fdiv")
15246              ]
15247              (const_string "fop")))
15248   (set_attr "fp_int_src" "true")
15249   (set_attr "mode" "<MODE>")])
15250
15251(define_insn "*fop_df_3<mode>_i387"
15252  [(set (match_operand:DF 0 "register_operand" "=f,f")
15253	(match_operator:DF 3 "binary_fp_operator"
15254	   [(match_operand:DF 1 "register_operand" "0,0")
15255	    (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15256  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15257   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15258  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15259  [(set (attr "type") 
15260        (cond [(match_operand:DF 3 "mult_operator" "") 
15261                 (const_string "fmul")
15262               (match_operand:DF 3 "div_operator" "") 
15263                 (const_string "fdiv")
15264              ]
15265              (const_string "fop")))
15266   (set_attr "fp_int_src" "true")
15267   (set_attr "mode" "<MODE>")])
15268
15269(define_insn "*fop_df_4_i387"
15270  [(set (match_operand:DF 0 "register_operand" "=f,f")
15271	(match_operator:DF 3 "binary_fp_operator"
15272	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15273	    (match_operand:DF 2 "register_operand" "0,f")]))]
15274  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15275   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15276  "* return output_387_binary_op (insn, operands);"
15277  [(set (attr "type") 
15278        (cond [(match_operand:DF 3 "mult_operator" "") 
15279                 (const_string "fmul")
15280               (match_operand:DF 3 "div_operator" "") 
15281                 (const_string "fdiv")
15282              ]
15283              (const_string "fop")))
15284   (set_attr "mode" "SF")])
15285
15286(define_insn "*fop_df_5_i387"
15287  [(set (match_operand:DF 0 "register_operand" "=f,f")
15288	(match_operator:DF 3 "binary_fp_operator"
15289	  [(match_operand:DF 1 "register_operand" "0,f")
15290	   (float_extend:DF
15291	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15292  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15293  "* return output_387_binary_op (insn, operands);"
15294  [(set (attr "type") 
15295        (cond [(match_operand:DF 3 "mult_operator" "") 
15296                 (const_string "fmul")
15297               (match_operand:DF 3 "div_operator" "") 
15298                 (const_string "fdiv")
15299              ]
15300              (const_string "fop")))
15301   (set_attr "mode" "SF")])
15302
15303(define_insn "*fop_df_6_i387"
15304  [(set (match_operand:DF 0 "register_operand" "=f,f")
15305	(match_operator:DF 3 "binary_fp_operator"
15306	  [(float_extend:DF
15307	    (match_operand:SF 1 "register_operand" "0,f"))
15308	   (float_extend:DF
15309	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15310  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15311  "* return output_387_binary_op (insn, operands);"
15312  [(set (attr "type") 
15313        (cond [(match_operand:DF 3 "mult_operator" "") 
15314                 (const_string "fmul")
15315               (match_operand:DF 3 "div_operator" "") 
15316                 (const_string "fdiv")
15317              ]
15318              (const_string "fop")))
15319   (set_attr "mode" "SF")])
15320
15321(define_insn "*fop_xf_comm_i387"
15322  [(set (match_operand:XF 0 "register_operand" "=f")
15323	(match_operator:XF 3 "binary_fp_operator"
15324			[(match_operand:XF 1 "register_operand" "%0")
15325			 (match_operand:XF 2 "register_operand" "f")]))]
15326  "TARGET_80387
15327   && COMMUTATIVE_ARITH_P (operands[3])"
15328  "* return output_387_binary_op (insn, operands);"
15329  [(set (attr "type") 
15330        (if_then_else (match_operand:XF 3 "mult_operator" "") 
15331           (const_string "fmul")
15332           (const_string "fop")))
15333   (set_attr "mode" "XF")])
15334
15335(define_insn "*fop_xf_1_i387"
15336  [(set (match_operand:XF 0 "register_operand" "=f,f")
15337	(match_operator:XF 3 "binary_fp_operator"
15338			[(match_operand:XF 1 "register_operand" "0,f")
15339			 (match_operand:XF 2 "register_operand" "f,0")]))]
15340  "TARGET_80387
15341   && !COMMUTATIVE_ARITH_P (operands[3])"
15342  "* return output_387_binary_op (insn, operands);"
15343  [(set (attr "type") 
15344        (cond [(match_operand:XF 3 "mult_operator" "") 
15345                 (const_string "fmul")
15346               (match_operand:XF 3 "div_operator" "") 
15347                 (const_string "fdiv")
15348              ]
15349              (const_string "fop")))
15350   (set_attr "mode" "XF")])
15351
15352(define_insn "*fop_xf_2<mode>_i387"
15353  [(set (match_operand:XF 0 "register_operand" "=f,f")
15354	(match_operator:XF 3 "binary_fp_operator"
15355	   [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15356	    (match_operand:XF 2 "register_operand" "0,0")]))]
15357  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15358  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15359  [(set (attr "type") 
15360        (cond [(match_operand:XF 3 "mult_operator" "") 
15361                 (const_string "fmul")
15362               (match_operand:XF 3 "div_operator" "") 
15363                 (const_string "fdiv")
15364              ]
15365              (const_string "fop")))
15366   (set_attr "fp_int_src" "true")
15367   (set_attr "mode" "<MODE>")])
15368
15369(define_insn "*fop_xf_3<mode>_i387"
15370  [(set (match_operand:XF 0 "register_operand" "=f,f")
15371	(match_operator:XF 3 "binary_fp_operator"
15372	  [(match_operand:XF 1 "register_operand" "0,0")
15373	   (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15374  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15375  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15376  [(set (attr "type") 
15377        (cond [(match_operand:XF 3 "mult_operator" "") 
15378                 (const_string "fmul")
15379               (match_operand:XF 3 "div_operator" "") 
15380                 (const_string "fdiv")
15381              ]
15382              (const_string "fop")))
15383   (set_attr "fp_int_src" "true")
15384   (set_attr "mode" "<MODE>")])
15385
15386(define_insn "*fop_xf_4_i387"
15387  [(set (match_operand:XF 0 "register_operand" "=f,f")
15388	(match_operator:XF 3 "binary_fp_operator"
15389	   [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15390	    (match_operand:XF 2 "register_operand" "0,f")]))]
15391  "TARGET_80387"
15392  "* return output_387_binary_op (insn, operands);"
15393  [(set (attr "type") 
15394        (cond [(match_operand:XF 3 "mult_operator" "") 
15395                 (const_string "fmul")
15396               (match_operand:XF 3 "div_operator" "") 
15397                 (const_string "fdiv")
15398              ]
15399              (const_string "fop")))
15400   (set_attr "mode" "SF")])
15401
15402(define_insn "*fop_xf_5_i387"
15403  [(set (match_operand:XF 0 "register_operand" "=f,f")
15404	(match_operator:XF 3 "binary_fp_operator"
15405	  [(match_operand:XF 1 "register_operand" "0,f")
15406	   (float_extend:XF
15407	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15408  "TARGET_80387"
15409  "* return output_387_binary_op (insn, operands);"
15410  [(set (attr "type") 
15411        (cond [(match_operand:XF 3 "mult_operator" "") 
15412                 (const_string "fmul")
15413               (match_operand:XF 3 "div_operator" "") 
15414                 (const_string "fdiv")
15415              ]
15416              (const_string "fop")))
15417   (set_attr "mode" "SF")])
15418
15419(define_insn "*fop_xf_6_i387"
15420  [(set (match_operand:XF 0 "register_operand" "=f,f")
15421	(match_operator:XF 3 "binary_fp_operator"
15422	  [(float_extend:XF
15423	    (match_operand 1 "register_operand" "0,f"))
15424	   (float_extend:XF
15425	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15426  "TARGET_80387"
15427  "* return output_387_binary_op (insn, operands);"
15428  [(set (attr "type") 
15429        (cond [(match_operand:XF 3 "mult_operator" "") 
15430                 (const_string "fmul")
15431               (match_operand:XF 3 "div_operator" "") 
15432                 (const_string "fdiv")
15433              ]
15434              (const_string "fop")))
15435   (set_attr "mode" "SF")])
15436
15437(define_split
15438  [(set (match_operand 0 "register_operand" "")
15439	(match_operator 3 "binary_fp_operator"
15440	   [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15441	    (match_operand 2 "register_operand" "")]))]
15442  "TARGET_80387 && reload_completed
15443   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15444  [(const_int 0)]
15445{ 
15446  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15447  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15448  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15449			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15450					  GET_MODE (operands[3]),
15451					  operands[4],
15452					  operands[2])));
15453  ix86_free_from_memory (GET_MODE (operands[1]));
15454  DONE;
15455})
15456
15457(define_split
15458  [(set (match_operand 0 "register_operand" "")
15459	(match_operator 3 "binary_fp_operator"
15460	   [(match_operand 1 "register_operand" "")
15461	    (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15462  "TARGET_80387 && reload_completed
15463   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15464  [(const_int 0)]
15465{
15466  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15467  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15468  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15469			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15470					  GET_MODE (operands[3]),
15471					  operands[1],
15472					  operands[4])));
15473  ix86_free_from_memory (GET_MODE (operands[2]));
15474  DONE;
15475})
15476
15477;; FPU special functions.
15478
15479(define_expand "sqrtsf2"
15480  [(set (match_operand:SF 0 "register_operand" "")
15481	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15482  "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15483{
15484  if (!TARGET_SSE_MATH)
15485    operands[1] = force_reg (SFmode, operands[1]);
15486})
15487
15488(define_insn "*sqrtsf2_mixed"
15489  [(set (match_operand:SF 0 "register_operand" "=f,x")
15490	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15491  "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15492  "@
15493   fsqrt
15494   sqrtss\t{%1, %0|%0, %1}"
15495  [(set_attr "type" "fpspc,sse")
15496   (set_attr "mode" "SF,SF")
15497   (set_attr "athlon_decode" "direct,*")])
15498
15499(define_insn "*sqrtsf2_sse"
15500  [(set (match_operand:SF 0 "register_operand" "=x")
15501	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15502  "TARGET_SSE_MATH"
15503  "sqrtss\t{%1, %0|%0, %1}"
15504  [(set_attr "type" "sse")
15505   (set_attr "mode" "SF")
15506   (set_attr "athlon_decode" "*")])
15507
15508(define_insn "*sqrtsf2_i387"
15509  [(set (match_operand:SF 0 "register_operand" "=f")
15510	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15511  "TARGET_USE_FANCY_MATH_387"
15512  "fsqrt"
15513  [(set_attr "type" "fpspc")
15514   (set_attr "mode" "SF")
15515   (set_attr "athlon_decode" "direct")])
15516
15517(define_expand "sqrtdf2"
15518  [(set (match_operand:DF 0 "register_operand" "")
15519	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15520  "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15521{
15522  if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15523    operands[1] = force_reg (DFmode, operands[1]);
15524})
15525
15526(define_insn "*sqrtdf2_mixed"
15527  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15528	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15529  "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15530  "@
15531   fsqrt
15532   sqrtsd\t{%1, %0|%0, %1}"
15533  [(set_attr "type" "fpspc,sse")
15534   (set_attr "mode" "DF,DF")
15535   (set_attr "athlon_decode" "direct,*")])
15536
15537(define_insn "*sqrtdf2_sse"
15538  [(set (match_operand:DF 0 "register_operand" "=Y")
15539	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15540  "TARGET_SSE2 && TARGET_SSE_MATH"
15541  "sqrtsd\t{%1, %0|%0, %1}"
15542  [(set_attr "type" "sse")
15543   (set_attr "mode" "DF")
15544   (set_attr "athlon_decode" "*")])
15545
15546(define_insn "*sqrtdf2_i387"
15547  [(set (match_operand:DF 0 "register_operand" "=f")
15548	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15549  "TARGET_USE_FANCY_MATH_387"
15550  "fsqrt"
15551  [(set_attr "type" "fpspc")
15552   (set_attr "mode" "DF")
15553   (set_attr "athlon_decode" "direct")])
15554
15555(define_insn "*sqrtextendsfdf2_i387"
15556  [(set (match_operand:DF 0 "register_operand" "=f")
15557	(sqrt:DF (float_extend:DF
15558		  (match_operand:SF 1 "register_operand" "0"))))]
15559  "TARGET_USE_FANCY_MATH_387
15560   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15561  "fsqrt"
15562  [(set_attr "type" "fpspc")
15563   (set_attr "mode" "DF")
15564   (set_attr "athlon_decode" "direct")])
15565
15566(define_insn "sqrtxf2"
15567  [(set (match_operand:XF 0 "register_operand" "=f")
15568	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15569  "TARGET_USE_FANCY_MATH_387"
15570  "fsqrt"
15571  [(set_attr "type" "fpspc")
15572   (set_attr "mode" "XF")
15573   (set_attr "athlon_decode" "direct")])
15574
15575(define_insn "*sqrtextendsfxf2_i387"
15576  [(set (match_operand:XF 0 "register_operand" "=f")
15577	(sqrt:XF (float_extend:XF
15578		  (match_operand:SF 1 "register_operand" "0"))))]
15579  "TARGET_USE_FANCY_MATH_387"
15580  "fsqrt"
15581  [(set_attr "type" "fpspc")
15582   (set_attr "mode" "XF")
15583   (set_attr "athlon_decode" "direct")])
15584
15585(define_insn "*sqrtextenddfxf2_i387"
15586  [(set (match_operand:XF 0 "register_operand" "=f")
15587	(sqrt:XF (float_extend:XF
15588		  (match_operand:DF 1 "register_operand" "0"))))]
15589  "TARGET_USE_FANCY_MATH_387"
15590  "fsqrt"
15591  [(set_attr "type" "fpspc")
15592   (set_attr "mode" "XF")
15593   (set_attr "athlon_decode" "direct")])
15594
15595(define_insn "fpremxf4"
15596  [(set (match_operand:XF 0 "register_operand" "=f")
15597	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15598		    (match_operand:XF 3 "register_operand" "1")]
15599		   UNSPEC_FPREM_F))
15600   (set (match_operand:XF 1 "register_operand" "=u")
15601	(unspec:XF [(match_dup 2) (match_dup 3)]
15602		   UNSPEC_FPREM_U))
15603   (set (reg:CCFP FPSR_REG)
15604	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15605  "TARGET_USE_FANCY_MATH_387
15606   && flag_unsafe_math_optimizations"
15607  "fprem"
15608  [(set_attr "type" "fpspc")
15609   (set_attr "mode" "XF")])
15610
15611(define_expand "fmodsf3"
15612  [(use (match_operand:SF 0 "register_operand" ""))
15613   (use (match_operand:SF 1 "register_operand" ""))
15614   (use (match_operand:SF 2 "register_operand" ""))]
15615  "TARGET_USE_FANCY_MATH_387
15616   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15617   && flag_unsafe_math_optimizations"
15618{
15619  rtx label = gen_label_rtx ();
15620
15621  rtx op1 = gen_reg_rtx (XFmode);
15622  rtx op2 = gen_reg_rtx (XFmode);
15623
15624  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15625  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15626
15627  emit_label (label);
15628
15629  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15630  ix86_emit_fp_unordered_jump (label);
15631
15632  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15633  DONE;
15634})
15635
15636(define_expand "fmoddf3"
15637  [(use (match_operand:DF 0 "register_operand" ""))
15638   (use (match_operand:DF 1 "register_operand" ""))
15639   (use (match_operand:DF 2 "register_operand" ""))]
15640  "TARGET_USE_FANCY_MATH_387
15641   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15642   && flag_unsafe_math_optimizations"
15643{
15644  rtx label = gen_label_rtx ();
15645
15646  rtx op1 = gen_reg_rtx (XFmode);
15647  rtx op2 = gen_reg_rtx (XFmode);
15648
15649  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15650  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15651
15652  emit_label (label);
15653
15654  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15655  ix86_emit_fp_unordered_jump (label);
15656
15657  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15658  DONE;
15659})
15660
15661(define_expand "fmodxf3"
15662  [(use (match_operand:XF 0 "register_operand" ""))
15663   (use (match_operand:XF 1 "register_operand" ""))
15664   (use (match_operand:XF 2 "register_operand" ""))]
15665  "TARGET_USE_FANCY_MATH_387
15666   && flag_unsafe_math_optimizations"
15667{
15668  rtx label = gen_label_rtx ();
15669
15670  emit_label (label);
15671
15672  emit_insn (gen_fpremxf4 (operands[1], operands[2],
15673			   operands[1], operands[2]));
15674  ix86_emit_fp_unordered_jump (label);
15675
15676  emit_move_insn (operands[0], operands[1]);
15677  DONE;
15678})
15679
15680(define_insn "fprem1xf4"
15681  [(set (match_operand:XF 0 "register_operand" "=f")
15682	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15683		    (match_operand:XF 3 "register_operand" "1")]
15684		   UNSPEC_FPREM1_F))
15685   (set (match_operand:XF 1 "register_operand" "=u")
15686	(unspec:XF [(match_dup 2) (match_dup 3)]
15687		   UNSPEC_FPREM1_U))
15688   (set (reg:CCFP FPSR_REG)
15689	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15690  "TARGET_USE_FANCY_MATH_387
15691   && flag_unsafe_math_optimizations"
15692  "fprem1"
15693  [(set_attr "type" "fpspc")
15694   (set_attr "mode" "XF")])
15695
15696(define_expand "dremsf3"
15697  [(use (match_operand:SF 0 "register_operand" ""))
15698   (use (match_operand:SF 1 "register_operand" ""))
15699   (use (match_operand:SF 2 "register_operand" ""))]
15700  "TARGET_USE_FANCY_MATH_387
15701   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15702   && flag_unsafe_math_optimizations"
15703{
15704  rtx label = gen_label_rtx ();
15705
15706  rtx op1 = gen_reg_rtx (XFmode);
15707  rtx op2 = gen_reg_rtx (XFmode);
15708
15709  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15710  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15711
15712  emit_label (label);
15713
15714  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15715  ix86_emit_fp_unordered_jump (label);
15716
15717  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15718  DONE;
15719})
15720
15721(define_expand "dremdf3"
15722  [(use (match_operand:DF 0 "register_operand" ""))
15723   (use (match_operand:DF 1 "register_operand" ""))
15724   (use (match_operand:DF 2 "register_operand" ""))]
15725  "TARGET_USE_FANCY_MATH_387
15726   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15727   && flag_unsafe_math_optimizations"
15728{
15729  rtx label = gen_label_rtx ();
15730
15731  rtx op1 = gen_reg_rtx (XFmode);
15732  rtx op2 = gen_reg_rtx (XFmode);
15733
15734  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15735  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15736
15737  emit_label (label);
15738
15739  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15740  ix86_emit_fp_unordered_jump (label);
15741
15742  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15743  DONE;
15744})
15745
15746(define_expand "dremxf3"
15747  [(use (match_operand:XF 0 "register_operand" ""))
15748   (use (match_operand:XF 1 "register_operand" ""))
15749   (use (match_operand:XF 2 "register_operand" ""))]
15750  "TARGET_USE_FANCY_MATH_387
15751   && flag_unsafe_math_optimizations"
15752{
15753  rtx label = gen_label_rtx ();
15754
15755  emit_label (label);
15756
15757  emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15758			    operands[1], operands[2]));
15759  ix86_emit_fp_unordered_jump (label);
15760
15761  emit_move_insn (operands[0], operands[1]);
15762  DONE;
15763})
15764
15765(define_insn "*sindf2"
15766  [(set (match_operand:DF 0 "register_operand" "=f")
15767	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15768  "TARGET_USE_FANCY_MATH_387
15769   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15770   && flag_unsafe_math_optimizations"
15771  "fsin"
15772  [(set_attr "type" "fpspc")
15773   (set_attr "mode" "DF")])
15774
15775(define_insn "*sinsf2"
15776  [(set (match_operand:SF 0 "register_operand" "=f")
15777	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15778  "TARGET_USE_FANCY_MATH_387
15779   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15780   && flag_unsafe_math_optimizations"
15781  "fsin"
15782  [(set_attr "type" "fpspc")
15783   (set_attr "mode" "SF")])
15784
15785(define_insn "*sinextendsfdf2"
15786  [(set (match_operand:DF 0 "register_operand" "=f")
15787	(unspec:DF [(float_extend:DF
15788		     (match_operand:SF 1 "register_operand" "0"))]
15789		   UNSPEC_SIN))]
15790  "TARGET_USE_FANCY_MATH_387
15791   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15792   && flag_unsafe_math_optimizations"
15793  "fsin"
15794  [(set_attr "type" "fpspc")
15795   (set_attr "mode" "DF")])
15796
15797(define_insn "*sinxf2"
15798  [(set (match_operand:XF 0 "register_operand" "=f")
15799	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15800  "TARGET_USE_FANCY_MATH_387
15801   && flag_unsafe_math_optimizations"
15802  "fsin"
15803  [(set_attr "type" "fpspc")
15804   (set_attr "mode" "XF")])
15805
15806(define_insn "*cosdf2"
15807  [(set (match_operand:DF 0 "register_operand" "=f")
15808	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15809  "TARGET_USE_FANCY_MATH_387
15810   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15811   && flag_unsafe_math_optimizations"
15812  "fcos"
15813  [(set_attr "type" "fpspc")
15814   (set_attr "mode" "DF")])
15815
15816(define_insn "*cossf2"
15817  [(set (match_operand:SF 0 "register_operand" "=f")
15818	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15819  "TARGET_USE_FANCY_MATH_387
15820   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15821   && flag_unsafe_math_optimizations"
15822  "fcos"
15823  [(set_attr "type" "fpspc")
15824   (set_attr "mode" "SF")])
15825
15826(define_insn "*cosextendsfdf2"
15827  [(set (match_operand:DF 0 "register_operand" "=f")
15828	(unspec:DF [(float_extend:DF
15829		     (match_operand:SF 1 "register_operand" "0"))]
15830		   UNSPEC_COS))]
15831  "TARGET_USE_FANCY_MATH_387
15832   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15833   && flag_unsafe_math_optimizations"
15834  "fcos"
15835  [(set_attr "type" "fpspc")
15836   (set_attr "mode" "DF")])
15837
15838(define_insn "*cosxf2"
15839  [(set (match_operand:XF 0 "register_operand" "=f")
15840	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15841  "TARGET_USE_FANCY_MATH_387
15842   && flag_unsafe_math_optimizations"
15843  "fcos"
15844  [(set_attr "type" "fpspc")
15845   (set_attr "mode" "XF")])
15846
15847;; With sincos pattern defined, sin and cos builtin function will be
15848;; expanded to sincos pattern with one of its outputs left unused. 
15849;; Cse pass  will detected, if two sincos patterns can be combined,
15850;; otherwise sincos pattern will be split back to sin or cos pattern,
15851;; depending on the unused output.
15852
15853(define_insn "sincosdf3"
15854  [(set (match_operand:DF 0 "register_operand" "=f")
15855	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15856		   UNSPEC_SINCOS_COS))
15857   (set (match_operand:DF 1 "register_operand" "=u")
15858        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15859  "TARGET_USE_FANCY_MATH_387
15860   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15861   && flag_unsafe_math_optimizations"
15862  "fsincos"
15863  [(set_attr "type" "fpspc")
15864   (set_attr "mode" "DF")])
15865
15866(define_split
15867  [(set (match_operand:DF 0 "register_operand" "")
15868	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
15869		   UNSPEC_SINCOS_COS))
15870   (set (match_operand:DF 1 "register_operand" "")
15871	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15872  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15873   && !reload_completed && !reload_in_progress"
15874  [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15875  "")
15876
15877(define_split
15878  [(set (match_operand:DF 0 "register_operand" "")
15879	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
15880		   UNSPEC_SINCOS_COS))
15881   (set (match_operand:DF 1 "register_operand" "")
15882	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15883  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15884   && !reload_completed && !reload_in_progress"
15885  [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15886  "")
15887
15888(define_insn "sincossf3"
15889  [(set (match_operand:SF 0 "register_operand" "=f")
15890	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15891		   UNSPEC_SINCOS_COS))
15892   (set (match_operand:SF 1 "register_operand" "=u")
15893        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15894  "TARGET_USE_FANCY_MATH_387
15895   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15896   && flag_unsafe_math_optimizations"
15897  "fsincos"
15898  [(set_attr "type" "fpspc")
15899   (set_attr "mode" "SF")])
15900
15901(define_split
15902  [(set (match_operand:SF 0 "register_operand" "")
15903	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
15904		   UNSPEC_SINCOS_COS))
15905   (set (match_operand:SF 1 "register_operand" "")
15906	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15907  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15908   && !reload_completed && !reload_in_progress"
15909  [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15910  "")
15911
15912(define_split
15913  [(set (match_operand:SF 0 "register_operand" "")
15914	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
15915		   UNSPEC_SINCOS_COS))
15916   (set (match_operand:SF 1 "register_operand" "")
15917	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15918  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15919   && !reload_completed && !reload_in_progress"
15920  [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15921  "")
15922
15923(define_insn "*sincosextendsfdf3"
15924  [(set (match_operand:DF 0 "register_operand" "=f")
15925	(unspec:DF [(float_extend:DF
15926		     (match_operand:SF 2 "register_operand" "0"))]
15927		   UNSPEC_SINCOS_COS))
15928   (set (match_operand:DF 1 "register_operand" "=u")
15929        (unspec:DF [(float_extend:DF
15930		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15931  "TARGET_USE_FANCY_MATH_387
15932   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15933   && flag_unsafe_math_optimizations"
15934  "fsincos"
15935  [(set_attr "type" "fpspc")
15936   (set_attr "mode" "DF")])
15937
15938(define_split
15939  [(set (match_operand:DF 0 "register_operand" "")
15940	(unspec:DF [(float_extend:DF
15941		     (match_operand:SF 2 "register_operand" ""))]
15942		   UNSPEC_SINCOS_COS))
15943   (set (match_operand:DF 1 "register_operand" "")
15944        (unspec:DF [(float_extend:DF
15945		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15946  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15947   && !reload_completed && !reload_in_progress"
15948  [(set (match_dup 1) (unspec:DF [(float_extend:DF
15949				   (match_dup 2))] UNSPEC_SIN))]
15950  "")
15951
15952(define_split
15953  [(set (match_operand:DF 0 "register_operand" "")
15954	(unspec:DF [(float_extend:DF
15955		     (match_operand:SF 2 "register_operand" ""))]
15956		   UNSPEC_SINCOS_COS))
15957   (set (match_operand:DF 1 "register_operand" "")
15958        (unspec:DF [(float_extend:DF
15959		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
15960  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15961   && !reload_completed && !reload_in_progress"
15962  [(set (match_dup 0) (unspec:DF [(float_extend:DF
15963				   (match_dup 2))] UNSPEC_COS))]
15964  "")
15965
15966(define_insn "sincosxf3"
15967  [(set (match_operand:XF 0 "register_operand" "=f")
15968	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15969		   UNSPEC_SINCOS_COS))
15970   (set (match_operand:XF 1 "register_operand" "=u")
15971        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15972  "TARGET_USE_FANCY_MATH_387
15973   && flag_unsafe_math_optimizations"
15974  "fsincos"
15975  [(set_attr "type" "fpspc")
15976   (set_attr "mode" "XF")])
15977
15978(define_split
15979  [(set (match_operand:XF 0 "register_operand" "")
15980	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
15981		   UNSPEC_SINCOS_COS))
15982   (set (match_operand:XF 1 "register_operand" "")
15983	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15984  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15985   && !reload_completed && !reload_in_progress"
15986  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15987  "")
15988
15989(define_split
15990  [(set (match_operand:XF 0 "register_operand" "")
15991	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
15992		   UNSPEC_SINCOS_COS))
15993   (set (match_operand:XF 1 "register_operand" "")
15994	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15995  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15996   && !reload_completed && !reload_in_progress"
15997  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15998  "")
15999
16000(define_insn "*tandf3_1"
16001  [(set (match_operand:DF 0 "register_operand" "=f")
16002	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16003		   UNSPEC_TAN_ONE))
16004   (set (match_operand:DF 1 "register_operand" "=u")
16005        (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16006  "TARGET_USE_FANCY_MATH_387
16007   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16008   && flag_unsafe_math_optimizations"
16009  "fptan"
16010  [(set_attr "type" "fpspc")
16011   (set_attr "mode" "DF")])
16012
16013;; optimize sequence: fptan
16014;;		      fstp    %st(0)
16015;;		      fld1
16016;; into fptan insn.
16017
16018(define_peephole2
16019  [(parallel[(set (match_operand:DF 0 "register_operand" "")
16020		  (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16021			     UNSPEC_TAN_ONE))
16022	     (set (match_operand:DF 1 "register_operand" "")
16023		  (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16024   (set (match_dup 0)
16025        (match_operand:DF 3 "immediate_operand" ""))]
16026  "standard_80387_constant_p (operands[3]) == 2"
16027  [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16028   	     (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16029  "")
16030
16031(define_expand "tandf2"
16032  [(parallel [(set (match_dup 2)
16033		   (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16034			      UNSPEC_TAN_ONE))
16035	      (set (match_operand:DF 0 "register_operand" "")
16036		   (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16037  "TARGET_USE_FANCY_MATH_387
16038   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16039   && flag_unsafe_math_optimizations"
16040{
16041  operands[2] = gen_reg_rtx (DFmode);
16042})
16043
16044(define_insn "*tansf3_1"
16045  [(set (match_operand:SF 0 "register_operand" "=f")
16046	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16047		   UNSPEC_TAN_ONE))
16048   (set (match_operand:SF 1 "register_operand" "=u")
16049        (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16050  "TARGET_USE_FANCY_MATH_387
16051   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16052   && flag_unsafe_math_optimizations"
16053  "fptan"
16054  [(set_attr "type" "fpspc")
16055   (set_attr "mode" "SF")])
16056
16057;; optimize sequence: fptan
16058;;		      fstp    %st(0)
16059;;		      fld1
16060;; into fptan insn.
16061
16062(define_peephole2
16063  [(parallel[(set (match_operand:SF 0 "register_operand" "")
16064		  (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16065			     UNSPEC_TAN_ONE))
16066	     (set (match_operand:SF 1 "register_operand" "")
16067		  (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16068   (set (match_dup 0)
16069        (match_operand:SF 3 "immediate_operand" ""))]
16070  "standard_80387_constant_p (operands[3]) == 2"
16071  [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16072   	     (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16073  "")
16074
16075(define_expand "tansf2"
16076  [(parallel [(set (match_dup 2)
16077		   (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16078			      UNSPEC_TAN_ONE))
16079	      (set (match_operand:SF 0 "register_operand" "")
16080		   (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16081  "TARGET_USE_FANCY_MATH_387
16082   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16083   && flag_unsafe_math_optimizations"
16084{
16085  operands[2] = gen_reg_rtx (SFmode);
16086})
16087
16088(define_insn "*tanxf3_1"
16089  [(set (match_operand:XF 0 "register_operand" "=f")
16090	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16091		   UNSPEC_TAN_ONE))
16092   (set (match_operand:XF 1 "register_operand" "=u")
16093        (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16094  "TARGET_USE_FANCY_MATH_387
16095   && flag_unsafe_math_optimizations"
16096  "fptan"
16097  [(set_attr "type" "fpspc")
16098   (set_attr "mode" "XF")])
16099
16100;; optimize sequence: fptan
16101;;		      fstp    %st(0)
16102;;		      fld1
16103;; into fptan insn.
16104
16105(define_peephole2
16106  [(parallel[(set (match_operand:XF 0 "register_operand" "")
16107		  (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16108			     UNSPEC_TAN_ONE))
16109	     (set (match_operand:XF 1 "register_operand" "")
16110		  (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16111   (set (match_dup 0)
16112        (match_operand:XF 3 "immediate_operand" ""))]
16113  "standard_80387_constant_p (operands[3]) == 2"
16114  [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16115   	     (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16116  "")
16117
16118(define_expand "tanxf2"
16119  [(parallel [(set (match_dup 2)
16120		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16121			      UNSPEC_TAN_ONE))
16122	      (set (match_operand:XF 0 "register_operand" "")
16123		   (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16124  "TARGET_USE_FANCY_MATH_387
16125   && flag_unsafe_math_optimizations"
16126{
16127  operands[2] = gen_reg_rtx (XFmode);
16128})
16129
16130(define_insn "atan2df3_1"
16131  [(set (match_operand:DF 0 "register_operand" "=f")
16132	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
16133		    (match_operand:DF 1 "register_operand" "u")]
16134		   UNSPEC_FPATAN))
16135   (clobber (match_scratch:DF 3 "=1"))]
16136  "TARGET_USE_FANCY_MATH_387
16137   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16138   && flag_unsafe_math_optimizations"
16139  "fpatan"
16140  [(set_attr "type" "fpspc")
16141   (set_attr "mode" "DF")])
16142
16143(define_expand "atan2df3"
16144  [(use (match_operand:DF 0 "register_operand" ""))
16145   (use (match_operand:DF 2 "register_operand" ""))
16146   (use (match_operand:DF 1 "register_operand" ""))]
16147  "TARGET_USE_FANCY_MATH_387
16148   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16149   && flag_unsafe_math_optimizations"
16150{
16151  rtx copy = gen_reg_rtx (DFmode);
16152  emit_move_insn (copy, operands[1]);
16153  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16154  DONE;
16155})
16156
16157(define_expand "atandf2"
16158  [(parallel [(set (match_operand:DF 0 "register_operand" "")
16159		   (unspec:DF [(match_dup 2)
16160			       (match_operand:DF 1 "register_operand" "")]
16161		    UNSPEC_FPATAN))
16162	      (clobber (match_scratch:DF 3 ""))])]
16163  "TARGET_USE_FANCY_MATH_387
16164   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16165   && flag_unsafe_math_optimizations"
16166{
16167  operands[2] = gen_reg_rtx (DFmode);
16168  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16169})
16170
16171(define_insn "atan2sf3_1"
16172  [(set (match_operand:SF 0 "register_operand" "=f")
16173        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16174		    (match_operand:SF 1 "register_operand" "u")]
16175		   UNSPEC_FPATAN))
16176   (clobber (match_scratch:SF 3 "=1"))]
16177  "TARGET_USE_FANCY_MATH_387
16178   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16179   && flag_unsafe_math_optimizations"
16180  "fpatan"
16181  [(set_attr "type" "fpspc")
16182   (set_attr "mode" "SF")])
16183
16184(define_expand "atan2sf3"
16185  [(use (match_operand:SF 0 "register_operand" ""))
16186   (use (match_operand:SF 2 "register_operand" ""))
16187   (use (match_operand:SF 1 "register_operand" ""))]
16188  "TARGET_USE_FANCY_MATH_387
16189   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16190   && flag_unsafe_math_optimizations"
16191{
16192  rtx copy = gen_reg_rtx (SFmode);
16193  emit_move_insn (copy, operands[1]);
16194  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16195  DONE;
16196})
16197
16198(define_expand "atansf2"
16199  [(parallel [(set (match_operand:SF 0 "register_operand" "")
16200		   (unspec:SF [(match_dup 2)
16201			       (match_operand:SF 1 "register_operand" "")]
16202		    UNSPEC_FPATAN))
16203	      (clobber (match_scratch:SF 3 ""))])]
16204  "TARGET_USE_FANCY_MATH_387
16205   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16206   && flag_unsafe_math_optimizations"
16207{
16208  operands[2] = gen_reg_rtx (SFmode);
16209  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16210})
16211
16212(define_insn "atan2xf3_1"
16213  [(set (match_operand:XF 0 "register_operand" "=f")
16214        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16215	            (match_operand:XF 1 "register_operand" "u")]
16216	           UNSPEC_FPATAN))
16217   (clobber (match_scratch:XF 3 "=1"))]
16218  "TARGET_USE_FANCY_MATH_387
16219   && flag_unsafe_math_optimizations"
16220  "fpatan"
16221  [(set_attr "type" "fpspc")
16222   (set_attr "mode" "XF")])
16223
16224(define_expand "atan2xf3"
16225  [(use (match_operand:XF 0 "register_operand" ""))
16226   (use (match_operand:XF 2 "register_operand" ""))
16227   (use (match_operand:XF 1 "register_operand" ""))]
16228  "TARGET_USE_FANCY_MATH_387
16229   && flag_unsafe_math_optimizations"
16230{
16231  rtx copy = gen_reg_rtx (XFmode);
16232  emit_move_insn (copy, operands[1]);
16233  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16234  DONE;
16235})
16236
16237(define_expand "atanxf2"
16238  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16239		   (unspec:XF [(match_dup 2)
16240			       (match_operand:XF 1 "register_operand" "")]
16241		    UNSPEC_FPATAN))
16242	      (clobber (match_scratch:XF 3 ""))])]
16243  "TARGET_USE_FANCY_MATH_387
16244   && flag_unsafe_math_optimizations"
16245{
16246  operands[2] = gen_reg_rtx (XFmode);
16247  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16248})
16249
16250(define_expand "asindf2"
16251  [(set (match_dup 2)
16252	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16253   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16254   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16255   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16256   (parallel [(set (match_dup 7)
16257        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16258			      UNSPEC_FPATAN))
16259   	      (clobber (match_scratch:XF 8 ""))])
16260   (set (match_operand:DF 0 "register_operand" "")
16261	(float_truncate:DF (match_dup 7)))]
16262  "TARGET_USE_FANCY_MATH_387
16263   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16264   && flag_unsafe_math_optimizations"
16265{
16266  int i;
16267
16268  for (i=2; i<8; i++)
16269    operands[i] = gen_reg_rtx (XFmode);
16270
16271  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16272})
16273
16274(define_expand "asinsf2"
16275  [(set (match_dup 2)
16276	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16277   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16278   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16279   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16280   (parallel [(set (match_dup 7)
16281        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16282			      UNSPEC_FPATAN))
16283   	      (clobber (match_scratch:XF 8 ""))])
16284   (set (match_operand:SF 0 "register_operand" "")
16285	(float_truncate:SF (match_dup 7)))]
16286  "TARGET_USE_FANCY_MATH_387
16287   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16288   && flag_unsafe_math_optimizations"
16289{
16290  int i;
16291
16292  for (i=2; i<8; i++)
16293    operands[i] = gen_reg_rtx (XFmode);
16294
16295  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16296})
16297
16298(define_expand "asinxf2"
16299  [(set (match_dup 2)
16300	(mult:XF (match_operand:XF 1 "register_operand" "")
16301		 (match_dup 1)))
16302   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16303   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16304   (parallel [(set (match_operand:XF 0 "register_operand" "")
16305        	   (unspec:XF [(match_dup 5) (match_dup 1)]
16306			      UNSPEC_FPATAN))
16307   	      (clobber (match_scratch:XF 6 ""))])]
16308  "TARGET_USE_FANCY_MATH_387
16309   && flag_unsafe_math_optimizations"
16310{
16311  int i;
16312
16313  for (i=2; i<6; i++)
16314    operands[i] = gen_reg_rtx (XFmode);
16315
16316  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16317})
16318
16319(define_expand "acosdf2"
16320  [(set (match_dup 2)
16321	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16322   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16323   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16324   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16325   (parallel [(set (match_dup 7)
16326        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16327			      UNSPEC_FPATAN))
16328   	      (clobber (match_scratch:XF 8 ""))])
16329   (set (match_operand:DF 0 "register_operand" "")
16330	(float_truncate:DF (match_dup 7)))]
16331  "TARGET_USE_FANCY_MATH_387
16332   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16333   && flag_unsafe_math_optimizations"
16334{
16335  int i;
16336
16337  for (i=2; i<8; i++)
16338    operands[i] = gen_reg_rtx (XFmode);
16339
16340  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16341})
16342
16343(define_expand "acossf2"
16344  [(set (match_dup 2)
16345	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16346   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16347   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16348   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16349   (parallel [(set (match_dup 7)
16350        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16351			      UNSPEC_FPATAN))
16352   	      (clobber (match_scratch:XF 8 ""))])
16353   (set (match_operand:SF 0 "register_operand" "")
16354	(float_truncate:SF (match_dup 7)))]
16355  "TARGET_USE_FANCY_MATH_387
16356   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16357   && flag_unsafe_math_optimizations"
16358{
16359  int i;
16360
16361  for (i=2; i<8; i++)
16362    operands[i] = gen_reg_rtx (XFmode);
16363
16364  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16365})
16366
16367(define_expand "acosxf2"
16368  [(set (match_dup 2)
16369	(mult:XF (match_operand:XF 1 "register_operand" "")
16370		 (match_dup 1)))
16371   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16372   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16373   (parallel [(set (match_operand:XF 0 "register_operand" "")
16374        	   (unspec:XF [(match_dup 1) (match_dup 5)]
16375			      UNSPEC_FPATAN))
16376   	      (clobber (match_scratch:XF 6 ""))])]
16377  "TARGET_USE_FANCY_MATH_387
16378   && flag_unsafe_math_optimizations"
16379{
16380  int i;
16381
16382  for (i=2; i<6; i++)
16383    operands[i] = gen_reg_rtx (XFmode);
16384
16385  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16386})
16387
16388(define_insn "fyl2x_xf3"
16389  [(set (match_operand:XF 0 "register_operand" "=f")
16390        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16391		    (match_operand:XF 1 "register_operand" "u")]
16392	           UNSPEC_FYL2X))
16393   (clobber (match_scratch:XF 3 "=1"))]
16394  "TARGET_USE_FANCY_MATH_387
16395   && flag_unsafe_math_optimizations"
16396  "fyl2x"
16397  [(set_attr "type" "fpspc")
16398   (set_attr "mode" "XF")])
16399
16400(define_expand "logsf2"
16401  [(set (match_dup 2)
16402	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16403   (parallel [(set (match_dup 4)
16404		   (unspec:XF [(match_dup 2)
16405			       (match_dup 3)] UNSPEC_FYL2X))
16406	      (clobber (match_scratch:XF 5 ""))])
16407   (set (match_operand:SF 0 "register_operand" "")
16408	(float_truncate:SF (match_dup 4)))]
16409  "TARGET_USE_FANCY_MATH_387
16410   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16411   && flag_unsafe_math_optimizations"
16412{
16413  rtx temp;
16414
16415  operands[2] = gen_reg_rtx (XFmode);
16416  operands[3] = gen_reg_rtx (XFmode);
16417  operands[4] = gen_reg_rtx (XFmode);
16418
16419  temp = standard_80387_constant_rtx (4); /* fldln2 */
16420  emit_move_insn (operands[3], temp);
16421})
16422
16423(define_expand "logdf2"
16424  [(set (match_dup 2)
16425	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16426   (parallel [(set (match_dup 4)
16427		   (unspec:XF [(match_dup 2)
16428			       (match_dup 3)] UNSPEC_FYL2X))
16429	      (clobber (match_scratch:XF 5 ""))])
16430   (set (match_operand:DF 0 "register_operand" "")
16431	(float_truncate:DF (match_dup 4)))]
16432  "TARGET_USE_FANCY_MATH_387
16433   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16434   && flag_unsafe_math_optimizations"
16435{
16436  rtx temp;
16437
16438  operands[2] = gen_reg_rtx (XFmode);
16439  operands[3] = gen_reg_rtx (XFmode);
16440  operands[4] = gen_reg_rtx (XFmode);
16441
16442  temp = standard_80387_constant_rtx (4); /* fldln2 */
16443  emit_move_insn (operands[3], temp);
16444})
16445
16446(define_expand "logxf2"
16447  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16448		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16449			       (match_dup 2)] UNSPEC_FYL2X))
16450	      (clobber (match_scratch:XF 3 ""))])]
16451  "TARGET_USE_FANCY_MATH_387
16452   && flag_unsafe_math_optimizations"
16453{
16454  rtx temp;
16455
16456  operands[2] = gen_reg_rtx (XFmode);
16457  temp = standard_80387_constant_rtx (4); /* fldln2 */
16458  emit_move_insn (operands[2], temp);
16459})
16460
16461(define_expand "log10sf2"
16462  [(set (match_dup 2)
16463	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16464   (parallel [(set (match_dup 4)
16465		   (unspec:XF [(match_dup 2)
16466			       (match_dup 3)] UNSPEC_FYL2X))
16467	      (clobber (match_scratch:XF 5 ""))])
16468   (set (match_operand:SF 0 "register_operand" "")
16469	(float_truncate:SF (match_dup 4)))]
16470  "TARGET_USE_FANCY_MATH_387
16471   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16472   && flag_unsafe_math_optimizations"
16473{
16474  rtx temp;
16475
16476  operands[2] = gen_reg_rtx (XFmode);
16477  operands[3] = gen_reg_rtx (XFmode);
16478  operands[4] = gen_reg_rtx (XFmode);
16479
16480  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16481  emit_move_insn (operands[3], temp);
16482})
16483
16484(define_expand "log10df2"
16485  [(set (match_dup 2)
16486	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16487   (parallel [(set (match_dup 4)
16488		   (unspec:XF [(match_dup 2)
16489			       (match_dup 3)] UNSPEC_FYL2X))
16490	      (clobber (match_scratch:XF 5 ""))])
16491   (set (match_operand:DF 0 "register_operand" "")
16492	(float_truncate:DF (match_dup 4)))]
16493  "TARGET_USE_FANCY_MATH_387
16494   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16495   && flag_unsafe_math_optimizations"
16496{
16497  rtx temp;
16498
16499  operands[2] = gen_reg_rtx (XFmode);
16500  operands[3] = gen_reg_rtx (XFmode);
16501  operands[4] = gen_reg_rtx (XFmode);
16502
16503  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16504  emit_move_insn (operands[3], temp);
16505})
16506
16507(define_expand "log10xf2"
16508  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16509		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16510			       (match_dup 2)] UNSPEC_FYL2X))
16511	      (clobber (match_scratch:XF 3 ""))])]
16512  "TARGET_USE_FANCY_MATH_387
16513   && flag_unsafe_math_optimizations"
16514{
16515  rtx temp;
16516
16517  operands[2] = gen_reg_rtx (XFmode);
16518  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16519  emit_move_insn (operands[2], temp);
16520})
16521
16522(define_expand "log2sf2"
16523  [(set (match_dup 2)
16524	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16525   (parallel [(set (match_dup 4)
16526		   (unspec:XF [(match_dup 2)
16527			       (match_dup 3)] UNSPEC_FYL2X))
16528	      (clobber (match_scratch:XF 5 ""))])
16529   (set (match_operand:SF 0 "register_operand" "")
16530	(float_truncate:SF (match_dup 4)))]
16531  "TARGET_USE_FANCY_MATH_387
16532   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16533   && flag_unsafe_math_optimizations"
16534{
16535  operands[2] = gen_reg_rtx (XFmode);
16536  operands[3] = gen_reg_rtx (XFmode);
16537  operands[4] = gen_reg_rtx (XFmode);
16538
16539  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16540})
16541
16542(define_expand "log2df2"
16543  [(set (match_dup 2)
16544	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16545   (parallel [(set (match_dup 4)
16546		   (unspec:XF [(match_dup 2)
16547			       (match_dup 3)] UNSPEC_FYL2X))
16548	      (clobber (match_scratch:XF 5 ""))])
16549   (set (match_operand:DF 0 "register_operand" "")
16550	(float_truncate:DF (match_dup 4)))]
16551  "TARGET_USE_FANCY_MATH_387
16552   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16553   && flag_unsafe_math_optimizations"
16554{
16555  operands[2] = gen_reg_rtx (XFmode);
16556  operands[3] = gen_reg_rtx (XFmode);
16557  operands[4] = gen_reg_rtx (XFmode);
16558
16559  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16560})
16561
16562(define_expand "log2xf2"
16563  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16564		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16565			       (match_dup 2)] UNSPEC_FYL2X))
16566	      (clobber (match_scratch:XF 3 ""))])]
16567  "TARGET_USE_FANCY_MATH_387
16568   && flag_unsafe_math_optimizations"
16569{
16570  operands[2] = gen_reg_rtx (XFmode);
16571  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16572})
16573
16574(define_insn "fyl2xp1_xf3"
16575  [(set (match_operand:XF 0 "register_operand" "=f")
16576        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16577		    (match_operand:XF 1 "register_operand" "u")]
16578	           UNSPEC_FYL2XP1))
16579   (clobber (match_scratch:XF 3 "=1"))]
16580  "TARGET_USE_FANCY_MATH_387
16581   && flag_unsafe_math_optimizations"
16582  "fyl2xp1"
16583  [(set_attr "type" "fpspc")
16584   (set_attr "mode" "XF")])
16585
16586(define_expand "log1psf2"
16587  [(use (match_operand:SF 0 "register_operand" ""))
16588   (use (match_operand:SF 1 "register_operand" ""))]
16589  "TARGET_USE_FANCY_MATH_387
16590   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16591   && flag_unsafe_math_optimizations"
16592{
16593  rtx op0 = gen_reg_rtx (XFmode);
16594  rtx op1 = gen_reg_rtx (XFmode);
16595
16596  emit_insn (gen_extendsfxf2 (op1, operands[1]));
16597  ix86_emit_i387_log1p (op0, op1);
16598  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16599  DONE;
16600})
16601
16602(define_expand "log1pdf2"
16603  [(use (match_operand:DF 0 "register_operand" ""))
16604   (use (match_operand:DF 1 "register_operand" ""))]
16605  "TARGET_USE_FANCY_MATH_387
16606   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16607   && flag_unsafe_math_optimizations"
16608{
16609  rtx op0 = gen_reg_rtx (XFmode);
16610  rtx op1 = gen_reg_rtx (XFmode);
16611
16612  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16613  ix86_emit_i387_log1p (op0, op1);
16614  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16615  DONE;
16616})
16617
16618(define_expand "log1pxf2"
16619  [(use (match_operand:XF 0 "register_operand" ""))
16620   (use (match_operand:XF 1 "register_operand" ""))]
16621  "TARGET_USE_FANCY_MATH_387
16622   && flag_unsafe_math_optimizations"
16623{
16624  ix86_emit_i387_log1p (operands[0], operands[1]);
16625  DONE;
16626})
16627
16628(define_insn "*fxtractxf3"
16629  [(set (match_operand:XF 0 "register_operand" "=f")
16630	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16631		   UNSPEC_XTRACT_FRACT))
16632   (set (match_operand:XF 1 "register_operand" "=u")
16633        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16634  "TARGET_USE_FANCY_MATH_387
16635   && flag_unsafe_math_optimizations"
16636  "fxtract"
16637  [(set_attr "type" "fpspc")
16638   (set_attr "mode" "XF")])
16639
16640(define_expand "logbsf2"
16641  [(set (match_dup 2)
16642	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16643   (parallel [(set (match_dup 3)
16644		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16645	      (set (match_dup 4)
16646		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16647   (set (match_operand:SF 0 "register_operand" "")
16648	(float_truncate:SF (match_dup 4)))]
16649  "TARGET_USE_FANCY_MATH_387
16650   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16651   && flag_unsafe_math_optimizations"
16652{
16653  operands[2] = gen_reg_rtx (XFmode);
16654  operands[3] = gen_reg_rtx (XFmode);
16655  operands[4] = gen_reg_rtx (XFmode);
16656})
16657
16658(define_expand "logbdf2"
16659  [(set (match_dup 2)
16660	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16661   (parallel [(set (match_dup 3)
16662		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16663	      (set (match_dup 4)
16664		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16665   (set (match_operand:DF 0 "register_operand" "")
16666	(float_truncate:DF (match_dup 4)))]
16667  "TARGET_USE_FANCY_MATH_387
16668   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16669   && flag_unsafe_math_optimizations"
16670{
16671  operands[2] = gen_reg_rtx (XFmode);
16672  operands[3] = gen_reg_rtx (XFmode);
16673  operands[4] = gen_reg_rtx (XFmode);
16674})
16675
16676(define_expand "logbxf2"
16677  [(parallel [(set (match_dup 2)
16678		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16679			      UNSPEC_XTRACT_FRACT))
16680	      (set (match_operand:XF 0 "register_operand" "")
16681		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16682  "TARGET_USE_FANCY_MATH_387
16683   && flag_unsafe_math_optimizations"
16684{
16685  operands[2] = gen_reg_rtx (XFmode);
16686})
16687
16688(define_expand "ilogbsi2"
16689  [(parallel [(set (match_dup 2)
16690		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16691			      UNSPEC_XTRACT_FRACT))
16692	      (set (match_operand:XF 3 "register_operand" "")
16693		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16694   (parallel [(set (match_operand:SI 0 "register_operand" "")
16695	           (fix:SI (match_dup 3)))
16696	      (clobber (reg:CC FLAGS_REG))])]
16697  "TARGET_USE_FANCY_MATH_387
16698   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16699   && flag_unsafe_math_optimizations"
16700{
16701  operands[2] = gen_reg_rtx (XFmode);
16702  operands[3] = gen_reg_rtx (XFmode);
16703})
16704
16705(define_insn "*f2xm1xf2"
16706  [(set (match_operand:XF 0 "register_operand" "=f")
16707	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16708	 UNSPEC_F2XM1))]
16709  "TARGET_USE_FANCY_MATH_387
16710   && flag_unsafe_math_optimizations"
16711  "f2xm1"
16712  [(set_attr "type" "fpspc")
16713   (set_attr "mode" "XF")])
16714
16715(define_insn "*fscalexf4"
16716  [(set (match_operand:XF 0 "register_operand" "=f")
16717	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
16718		    (match_operand:XF 3 "register_operand" "1")]
16719		   UNSPEC_FSCALE_FRACT))
16720   (set (match_operand:XF 1 "register_operand" "=u")
16721	(unspec:XF [(match_dup 2) (match_dup 3)]
16722		   UNSPEC_FSCALE_EXP))]
16723  "TARGET_USE_FANCY_MATH_387
16724   && flag_unsafe_math_optimizations"
16725  "fscale"
16726  [(set_attr "type" "fpspc")
16727   (set_attr "mode" "XF")])
16728
16729(define_expand "expsf2"
16730  [(set (match_dup 2)
16731	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16732   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16733   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16734   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16735   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16736   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16737   (parallel [(set (match_dup 10)
16738		   (unspec:XF [(match_dup 9) (match_dup 5)]
16739			      UNSPEC_FSCALE_FRACT))
16740	      (set (match_dup 11)
16741		   (unspec:XF [(match_dup 9) (match_dup 5)]
16742			      UNSPEC_FSCALE_EXP))])
16743   (set (match_operand:SF 0 "register_operand" "")
16744	(float_truncate:SF (match_dup 10)))]
16745  "TARGET_USE_FANCY_MATH_387
16746   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16747   && flag_unsafe_math_optimizations"
16748{
16749  rtx temp;
16750  int i;
16751
16752  for (i=2; i<12; i++)
16753    operands[i] = gen_reg_rtx (XFmode);
16754  temp = standard_80387_constant_rtx (5); /* fldl2e */
16755  emit_move_insn (operands[3], temp);
16756  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16757})
16758
16759(define_expand "expdf2"
16760  [(set (match_dup 2)
16761	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16762   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16763   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16764   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16765   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16766   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16767   (parallel [(set (match_dup 10)
16768		   (unspec:XF [(match_dup 9) (match_dup 5)]
16769			      UNSPEC_FSCALE_FRACT))
16770	      (set (match_dup 11)
16771		   (unspec:XF [(match_dup 9) (match_dup 5)]
16772			      UNSPEC_FSCALE_EXP))])
16773   (set (match_operand:DF 0 "register_operand" "")
16774	(float_truncate:DF (match_dup 10)))]
16775  "TARGET_USE_FANCY_MATH_387
16776   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16777   && flag_unsafe_math_optimizations"
16778{
16779  rtx temp;
16780  int i;
16781
16782  for (i=2; i<12; i++)
16783    operands[i] = gen_reg_rtx (XFmode);
16784  temp = standard_80387_constant_rtx (5); /* fldl2e */
16785  emit_move_insn (operands[3], temp);
16786  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16787})
16788
16789(define_expand "expxf2"
16790  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16791			       (match_dup 2)))
16792   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16793   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16794   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16795   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16796   (parallel [(set (match_operand:XF 0 "register_operand" "")
16797		   (unspec:XF [(match_dup 8) (match_dup 4)]
16798			      UNSPEC_FSCALE_FRACT))
16799	      (set (match_dup 9)
16800		   (unspec:XF [(match_dup 8) (match_dup 4)]
16801			      UNSPEC_FSCALE_EXP))])]
16802  "TARGET_USE_FANCY_MATH_387
16803   && flag_unsafe_math_optimizations"
16804{
16805  rtx temp;
16806  int i;
16807
16808  for (i=2; i<10; i++)
16809    operands[i] = gen_reg_rtx (XFmode);
16810  temp = standard_80387_constant_rtx (5); /* fldl2e */
16811  emit_move_insn (operands[2], temp);
16812  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16813})
16814
16815(define_expand "exp10sf2"
16816  [(set (match_dup 2)
16817	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16818   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16819   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16820   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16821   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16822   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16823   (parallel [(set (match_dup 10)
16824		   (unspec:XF [(match_dup 9) (match_dup 5)]
16825			      UNSPEC_FSCALE_FRACT))
16826	      (set (match_dup 11)
16827		   (unspec:XF [(match_dup 9) (match_dup 5)]
16828			      UNSPEC_FSCALE_EXP))])
16829   (set (match_operand:SF 0 "register_operand" "")
16830	(float_truncate:SF (match_dup 10)))]
16831  "TARGET_USE_FANCY_MATH_387
16832   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16833   && flag_unsafe_math_optimizations"
16834{
16835  rtx temp;
16836  int i;
16837
16838  for (i=2; i<12; i++)
16839    operands[i] = gen_reg_rtx (XFmode);
16840  temp = standard_80387_constant_rtx (6); /* fldl2t */
16841  emit_move_insn (operands[3], temp);
16842  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16843})
16844
16845(define_expand "exp10df2"
16846  [(set (match_dup 2)
16847	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16848   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16849   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16850   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16851   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16852   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16853   (parallel [(set (match_dup 10)
16854		   (unspec:XF [(match_dup 9) (match_dup 5)]
16855			      UNSPEC_FSCALE_FRACT))
16856	      (set (match_dup 11)
16857		   (unspec:XF [(match_dup 9) (match_dup 5)]
16858			      UNSPEC_FSCALE_EXP))])
16859   (set (match_operand:DF 0 "register_operand" "")
16860	(float_truncate:DF (match_dup 10)))]
16861  "TARGET_USE_FANCY_MATH_387
16862   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16863   && flag_unsafe_math_optimizations"
16864{
16865  rtx temp;
16866  int i;
16867
16868  for (i=2; i<12; i++)
16869    operands[i] = gen_reg_rtx (XFmode);
16870  temp = standard_80387_constant_rtx (6); /* fldl2t */
16871  emit_move_insn (operands[3], temp);
16872  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16873})
16874
16875(define_expand "exp10xf2"
16876  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16877			       (match_dup 2)))
16878   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16879   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16880   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16881   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16882   (parallel [(set (match_operand:XF 0 "register_operand" "")
16883		   (unspec:XF [(match_dup 8) (match_dup 4)]
16884			      UNSPEC_FSCALE_FRACT))
16885	      (set (match_dup 9)
16886		   (unspec:XF [(match_dup 8) (match_dup 4)]
16887			      UNSPEC_FSCALE_EXP))])]
16888  "TARGET_USE_FANCY_MATH_387
16889   && flag_unsafe_math_optimizations"
16890{
16891  rtx temp;
16892  int i;
16893
16894  for (i=2; i<10; i++)
16895    operands[i] = gen_reg_rtx (XFmode);
16896  temp = standard_80387_constant_rtx (6); /* fldl2t */
16897  emit_move_insn (operands[2], temp);
16898  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16899})
16900
16901(define_expand "exp2sf2"
16902  [(set (match_dup 2)
16903	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16904   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16905   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16906   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16907   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16908   (parallel [(set (match_dup 8)
16909		   (unspec:XF [(match_dup 7) (match_dup 3)]
16910			      UNSPEC_FSCALE_FRACT))
16911	      (set (match_dup 9)
16912		   (unspec:XF [(match_dup 7) (match_dup 3)]
16913			      UNSPEC_FSCALE_EXP))])
16914   (set (match_operand:SF 0 "register_operand" "")
16915	(float_truncate:SF (match_dup 8)))]
16916  "TARGET_USE_FANCY_MATH_387
16917   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16918   && flag_unsafe_math_optimizations"
16919{
16920  int i;
16921
16922  for (i=2; i<10; i++)
16923    operands[i] = gen_reg_rtx (XFmode);
16924  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16925})
16926
16927(define_expand "exp2df2"
16928  [(set (match_dup 2)
16929	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16930   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16931   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16932   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16933   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16934   (parallel [(set (match_dup 8)
16935		   (unspec:XF [(match_dup 7) (match_dup 3)]
16936			      UNSPEC_FSCALE_FRACT))
16937	      (set (match_dup 9)
16938		   (unspec:XF [(match_dup 7) (match_dup 3)]
16939			      UNSPEC_FSCALE_EXP))])
16940   (set (match_operand:DF 0 "register_operand" "")
16941	(float_truncate:DF (match_dup 8)))]
16942  "TARGET_USE_FANCY_MATH_387
16943   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16944   && flag_unsafe_math_optimizations"
16945{
16946  int i;
16947
16948  for (i=2; i<10; i++)
16949    operands[i] = gen_reg_rtx (XFmode);
16950  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16951})
16952
16953(define_expand "exp2xf2"
16954  [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16955   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16956   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16957   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16958   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16959   (parallel [(set (match_operand:XF 0 "register_operand" "")
16960		   (unspec:XF [(match_dup 7) (match_dup 3)]
16961			      UNSPEC_FSCALE_FRACT))
16962	      (set (match_dup 8)
16963		   (unspec:XF [(match_dup 7) (match_dup 3)]
16964			      UNSPEC_FSCALE_EXP))])]
16965  "TARGET_USE_FANCY_MATH_387
16966   && flag_unsafe_math_optimizations"
16967{
16968  int i;
16969
16970  for (i=2; i<9; i++)
16971    operands[i] = gen_reg_rtx (XFmode);
16972  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16973})
16974
16975(define_expand "expm1df2"
16976  [(set (match_dup 2)
16977	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16978   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16979   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16980   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16981   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16982   (parallel [(set (match_dup 8)
16983		   (unspec:XF [(match_dup 7) (match_dup 5)]
16984			      UNSPEC_FSCALE_FRACT))
16985		   (set (match_dup 9)
16986		   (unspec:XF [(match_dup 7) (match_dup 5)]
16987			      UNSPEC_FSCALE_EXP))])
16988   (parallel [(set (match_dup 11)
16989		   (unspec:XF [(match_dup 10) (match_dup 9)]
16990			      UNSPEC_FSCALE_FRACT))
16991	      (set (match_dup 12)
16992		   (unspec:XF [(match_dup 10) (match_dup 9)]
16993			      UNSPEC_FSCALE_EXP))])
16994   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16995   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16996   (set (match_operand:DF 0 "register_operand" "")
16997	(float_truncate:DF (match_dup 14)))]
16998  "TARGET_USE_FANCY_MATH_387
16999   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17000   && flag_unsafe_math_optimizations"
17001{
17002  rtx temp;
17003  int i;
17004
17005  for (i=2; i<15; i++)
17006    operands[i] = gen_reg_rtx (XFmode);
17007  temp = standard_80387_constant_rtx (5); /* fldl2e */
17008  emit_move_insn (operands[3], temp);
17009  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17010})
17011
17012(define_expand "expm1sf2"
17013  [(set (match_dup 2)
17014	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17015   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17016   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17017   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17018   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17019   (parallel [(set (match_dup 8)
17020		   (unspec:XF [(match_dup 7) (match_dup 5)]
17021			      UNSPEC_FSCALE_FRACT))
17022		   (set (match_dup 9)
17023		   (unspec:XF [(match_dup 7) (match_dup 5)]
17024			      UNSPEC_FSCALE_EXP))])
17025   (parallel [(set (match_dup 11)
17026		   (unspec:XF [(match_dup 10) (match_dup 9)]
17027			      UNSPEC_FSCALE_FRACT))
17028	      (set (match_dup 12)
17029		   (unspec:XF [(match_dup 10) (match_dup 9)]
17030			      UNSPEC_FSCALE_EXP))])
17031   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17032   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17033   (set (match_operand:SF 0 "register_operand" "")
17034	(float_truncate:SF (match_dup 14)))]
17035  "TARGET_USE_FANCY_MATH_387
17036   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17037   && flag_unsafe_math_optimizations"
17038{
17039  rtx temp;
17040  int i;
17041
17042  for (i=2; i<15; i++)
17043    operands[i] = gen_reg_rtx (XFmode);
17044  temp = standard_80387_constant_rtx (5); /* fldl2e */
17045  emit_move_insn (operands[3], temp);
17046  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17047})
17048
17049(define_expand "expm1xf2"
17050  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17051			       (match_dup 2)))
17052   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17053   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17054   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17055   (parallel [(set (match_dup 7)
17056		   (unspec:XF [(match_dup 6) (match_dup 4)]
17057			      UNSPEC_FSCALE_FRACT))
17058		   (set (match_dup 8)
17059		   (unspec:XF [(match_dup 6) (match_dup 4)]
17060			      UNSPEC_FSCALE_EXP))])
17061   (parallel [(set (match_dup 10)
17062		   (unspec:XF [(match_dup 9) (match_dup 8)]
17063			      UNSPEC_FSCALE_FRACT))
17064	      (set (match_dup 11)
17065		   (unspec:XF [(match_dup 9) (match_dup 8)]
17066			      UNSPEC_FSCALE_EXP))])
17067   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17068   (set (match_operand:XF 0 "register_operand" "")
17069	(plus:XF (match_dup 12) (match_dup 7)))]
17070  "TARGET_USE_FANCY_MATH_387
17071   && flag_unsafe_math_optimizations"
17072{
17073  rtx temp;
17074  int i;
17075
17076  for (i=2; i<13; i++)
17077    operands[i] = gen_reg_rtx (XFmode);
17078  temp = standard_80387_constant_rtx (5); /* fldl2e */
17079  emit_move_insn (operands[2], temp);
17080  emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17081})
17082
17083(define_expand "ldexpdf3"
17084  [(set (match_dup 3)
17085	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17086   (set (match_dup 4)
17087	(float:XF (match_operand:SI 2 "register_operand" "")))
17088   (parallel [(set (match_dup 5)
17089		   (unspec:XF [(match_dup 3) (match_dup 4)]
17090			      UNSPEC_FSCALE_FRACT))
17091	      (set (match_dup 6)
17092		   (unspec:XF [(match_dup 3) (match_dup 4)]
17093			      UNSPEC_FSCALE_EXP))])
17094   (set (match_operand:DF 0 "register_operand" "")
17095	(float_truncate:DF (match_dup 5)))]
17096  "TARGET_USE_FANCY_MATH_387
17097   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17098   && flag_unsafe_math_optimizations"
17099{
17100  int i;
17101
17102  for (i=3; i<7; i++)
17103    operands[i] = gen_reg_rtx (XFmode);
17104})
17105
17106(define_expand "ldexpsf3"
17107  [(set (match_dup 3)
17108	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17109   (set (match_dup 4)
17110	(float:XF (match_operand:SI 2 "register_operand" "")))
17111   (parallel [(set (match_dup 5)
17112		   (unspec:XF [(match_dup 3) (match_dup 4)]
17113			      UNSPEC_FSCALE_FRACT))
17114	      (set (match_dup 6)
17115		   (unspec:XF [(match_dup 3) (match_dup 4)]
17116			      UNSPEC_FSCALE_EXP))])
17117   (set (match_operand:SF 0 "register_operand" "")
17118	(float_truncate:SF (match_dup 5)))]
17119  "TARGET_USE_FANCY_MATH_387
17120   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17121   && flag_unsafe_math_optimizations"
17122{
17123  int i;
17124
17125  for (i=3; i<7; i++)
17126    operands[i] = gen_reg_rtx (XFmode);
17127})
17128
17129(define_expand "ldexpxf3"
17130  [(set (match_dup 3)
17131	(float:XF (match_operand:SI 2 "register_operand" "")))
17132   (parallel [(set (match_operand:XF 0 " register_operand" "")
17133		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
17134			       (match_dup 3)]
17135			      UNSPEC_FSCALE_FRACT))
17136	      (set (match_dup 4)
17137		   (unspec:XF [(match_dup 1) (match_dup 3)]
17138			      UNSPEC_FSCALE_EXP))])]
17139  "TARGET_USE_FANCY_MATH_387
17140   && flag_unsafe_math_optimizations"
17141{
17142  int i;
17143
17144  for (i=3; i<5; i++)
17145    operands[i] = gen_reg_rtx (XFmode);
17146})
17147
17148
17149(define_insn "frndintxf2"
17150  [(set (match_operand:XF 0 "register_operand" "=f")
17151	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17152	 UNSPEC_FRNDINT))]
17153  "TARGET_USE_FANCY_MATH_387
17154   && flag_unsafe_math_optimizations"
17155  "frndint"
17156  [(set_attr "type" "fpspc")
17157   (set_attr "mode" "XF")])
17158
17159(define_expand "rintdf2"
17160  [(use (match_operand:DF 0 "register_operand" ""))
17161   (use (match_operand:DF 1 "register_operand" ""))]
17162  "TARGET_USE_FANCY_MATH_387
17163   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17164   && flag_unsafe_math_optimizations"
17165{
17166  rtx op0 = gen_reg_rtx (XFmode);
17167  rtx op1 = gen_reg_rtx (XFmode);
17168
17169  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17170  emit_insn (gen_frndintxf2 (op0, op1));
17171
17172  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17173  DONE;
17174})
17175
17176(define_expand "rintsf2"
17177  [(use (match_operand:SF 0 "register_operand" ""))
17178   (use (match_operand:SF 1 "register_operand" ""))]
17179  "TARGET_USE_FANCY_MATH_387
17180   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17181   && flag_unsafe_math_optimizations"
17182{
17183  rtx op0 = gen_reg_rtx (XFmode);
17184  rtx op1 = gen_reg_rtx (XFmode);
17185
17186  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17187  emit_insn (gen_frndintxf2 (op0, op1));
17188
17189  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17190  DONE;
17191})
17192
17193(define_expand "rintxf2"
17194  [(use (match_operand:XF 0 "register_operand" ""))
17195   (use (match_operand:XF 1 "register_operand" ""))]
17196  "TARGET_USE_FANCY_MATH_387
17197   && flag_unsafe_math_optimizations"
17198{
17199  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17200  DONE;
17201})
17202
17203(define_insn_and_split "*fistdi2_1"
17204  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17205	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17206	 UNSPEC_FIST))]
17207  "TARGET_USE_FANCY_MATH_387
17208   && flag_unsafe_math_optimizations
17209   && !(reload_completed || reload_in_progress)"
17210  "#"
17211  "&& 1"
17212  [(const_int 0)]
17213{
17214  if (memory_operand (operands[0], VOIDmode))
17215    emit_insn (gen_fistdi2 (operands[0], operands[1]));
17216  else
17217    {
17218      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17219      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17220					 operands[2]));
17221    }
17222  DONE;
17223}
17224  [(set_attr "type" "fpspc")
17225   (set_attr "mode" "DI")])
17226
17227(define_insn "fistdi2"
17228  [(set (match_operand:DI 0 "memory_operand" "=m")
17229	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17230	 UNSPEC_FIST))
17231   (clobber (match_scratch:XF 2 "=&1f"))]
17232  "TARGET_USE_FANCY_MATH_387
17233   && flag_unsafe_math_optimizations"
17234  "* return output_fix_trunc (insn, operands, 0);"
17235  [(set_attr "type" "fpspc")
17236   (set_attr "mode" "DI")])
17237
17238(define_insn "fistdi2_with_temp"
17239  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17240	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17241	 UNSPEC_FIST))
17242   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17243   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17244  "TARGET_USE_FANCY_MATH_387
17245   && flag_unsafe_math_optimizations"
17246  "#"
17247  [(set_attr "type" "fpspc")
17248   (set_attr "mode" "DI")])
17249
17250(define_split 
17251  [(set (match_operand:DI 0 "register_operand" "")
17252	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17253	 UNSPEC_FIST))
17254   (clobber (match_operand:DI 2 "memory_operand" ""))
17255   (clobber (match_scratch 3 ""))]
17256  "reload_completed"
17257  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17258	      (clobber (match_dup 3))])
17259   (set (match_dup 0) (match_dup 2))]
17260  "")
17261
17262(define_split 
17263  [(set (match_operand:DI 0 "memory_operand" "")
17264	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17265	 UNSPEC_FIST))
17266   (clobber (match_operand:DI 2 "memory_operand" ""))
17267   (clobber (match_scratch 3 ""))]
17268  "reload_completed"
17269  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17270	      (clobber (match_dup 3))])]
17271  "")
17272
17273(define_insn_and_split "*fist<mode>2_1"
17274  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17275	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17276	 UNSPEC_FIST))]
17277  "TARGET_USE_FANCY_MATH_387
17278   && flag_unsafe_math_optimizations
17279   && !(reload_completed || reload_in_progress)"
17280  "#"
17281  "&& 1"
17282  [(const_int 0)]
17283{
17284  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17285  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17286					operands[2]));
17287  DONE;
17288}
17289  [(set_attr "type" "fpspc")
17290   (set_attr "mode" "<MODE>")])
17291
17292(define_insn "fist<mode>2"
17293  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17294	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17295	 UNSPEC_FIST))]
17296  "TARGET_USE_FANCY_MATH_387
17297   && flag_unsafe_math_optimizations"
17298  "* return output_fix_trunc (insn, operands, 0);"
17299  [(set_attr "type" "fpspc")
17300   (set_attr "mode" "<MODE>")])
17301
17302(define_insn "fist<mode>2_with_temp"
17303  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17304	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17305	 UNSPEC_FIST))
17306   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17307  "TARGET_USE_FANCY_MATH_387
17308   && flag_unsafe_math_optimizations"
17309  "#"
17310  [(set_attr "type" "fpspc")
17311   (set_attr "mode" "<MODE>")])
17312
17313(define_split 
17314  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17315	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17316	 UNSPEC_FIST))
17317   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17318  "reload_completed"
17319  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17320		       UNSPEC_FIST))
17321   (set (match_dup 0) (match_dup 2))]
17322  "")
17323
17324(define_split 
17325  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17326	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17327	 UNSPEC_FIST))
17328   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17329  "reload_completed"
17330  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17331		       UNSPEC_FIST))]
17332  "")
17333
17334(define_expand "lrint<mode>2"
17335  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17336	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17337	 UNSPEC_FIST))]
17338  "TARGET_USE_FANCY_MATH_387
17339   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17340   && flag_unsafe_math_optimizations"
17341  "")
17342
17343;; Rounding mode control word calculation could clobber FLAGS_REG.
17344(define_insn_and_split "frndintxf2_floor"
17345  [(set (match_operand:XF 0 "register_operand" "=f")
17346	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17347	 UNSPEC_FRNDINT_FLOOR))
17348   (clobber (reg:CC FLAGS_REG))]
17349  "TARGET_USE_FANCY_MATH_387
17350   && flag_unsafe_math_optimizations
17351   && !(reload_completed || reload_in_progress)"
17352  "#"
17353  "&& 1"
17354  [(const_int 0)]
17355{
17356  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17357
17358  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17359  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17360
17361  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17362					operands[2], operands[3]));
17363  DONE;
17364}
17365  [(set_attr "type" "frndint")
17366   (set_attr "i387_cw" "floor")
17367   (set_attr "mode" "XF")])
17368
17369(define_insn "frndintxf2_floor_i387"
17370  [(set (match_operand:XF 0 "register_operand" "=f")
17371	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17372	 UNSPEC_FRNDINT_FLOOR))
17373   (use (match_operand:HI 2 "memory_operand" "m"))
17374   (use (match_operand:HI 3 "memory_operand" "m"))]
17375  "TARGET_USE_FANCY_MATH_387
17376   && flag_unsafe_math_optimizations"
17377  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17378  [(set_attr "type" "frndint")
17379   (set_attr "i387_cw" "floor")
17380   (set_attr "mode" "XF")])
17381
17382(define_expand "floorxf2"
17383  [(use (match_operand:XF 0 "register_operand" ""))
17384   (use (match_operand:XF 1 "register_operand" ""))]
17385  "TARGET_USE_FANCY_MATH_387
17386   && flag_unsafe_math_optimizations"
17387{
17388  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17389  DONE;
17390})
17391
17392(define_expand "floordf2"
17393  [(use (match_operand:DF 0 "register_operand" ""))
17394   (use (match_operand:DF 1 "register_operand" ""))]
17395  "TARGET_USE_FANCY_MATH_387
17396   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17397   && flag_unsafe_math_optimizations"
17398{
17399  rtx op0 = gen_reg_rtx (XFmode);
17400  rtx op1 = gen_reg_rtx (XFmode);
17401
17402  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17403  emit_insn (gen_frndintxf2_floor (op0, op1));
17404
17405  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17406  DONE;
17407})
17408
17409(define_expand "floorsf2"
17410  [(use (match_operand:SF 0 "register_operand" ""))
17411   (use (match_operand:SF 1 "register_operand" ""))]
17412  "TARGET_USE_FANCY_MATH_387
17413   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17414   && flag_unsafe_math_optimizations"
17415{
17416  rtx op0 = gen_reg_rtx (XFmode);
17417  rtx op1 = gen_reg_rtx (XFmode);
17418
17419  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17420  emit_insn (gen_frndintxf2_floor (op0, op1));
17421
17422  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17423  DONE;
17424})
17425
17426(define_insn_and_split "*fist<mode>2_floor_1"
17427  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17428	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17429	 UNSPEC_FIST_FLOOR))
17430   (clobber (reg:CC FLAGS_REG))]
17431  "TARGET_USE_FANCY_MATH_387
17432   && flag_unsafe_math_optimizations
17433   && !(reload_completed || reload_in_progress)"
17434  "#"
17435  "&& 1"
17436  [(const_int 0)]
17437{
17438  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17439
17440  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17441  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17442  if (memory_operand (operands[0], VOIDmode))
17443    emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17444				      operands[2], operands[3]));
17445  else
17446    {
17447      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17448      emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17449						  operands[2], operands[3],
17450						  operands[4]));
17451    }
17452  DONE;
17453}
17454  [(set_attr "type" "fistp")
17455   (set_attr "i387_cw" "floor")
17456   (set_attr "mode" "<MODE>")])
17457
17458(define_insn "fistdi2_floor"
17459  [(set (match_operand:DI 0 "memory_operand" "=m")
17460	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17461	 UNSPEC_FIST_FLOOR))
17462   (use (match_operand:HI 2 "memory_operand" "m"))
17463   (use (match_operand:HI 3 "memory_operand" "m"))
17464   (clobber (match_scratch:XF 4 "=&1f"))]
17465  "TARGET_USE_FANCY_MATH_387
17466   && flag_unsafe_math_optimizations"
17467  "* return output_fix_trunc (insn, operands, 0);"
17468  [(set_attr "type" "fistp")
17469   (set_attr "i387_cw" "floor")
17470   (set_attr "mode" "DI")])
17471
17472(define_insn "fistdi2_floor_with_temp"
17473  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17474	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17475	 UNSPEC_FIST_FLOOR))
17476   (use (match_operand:HI 2 "memory_operand" "m,m"))
17477   (use (match_operand:HI 3 "memory_operand" "m,m"))
17478   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17479   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17480  "TARGET_USE_FANCY_MATH_387
17481   && flag_unsafe_math_optimizations"
17482  "#"
17483  [(set_attr "type" "fistp")
17484   (set_attr "i387_cw" "floor")
17485   (set_attr "mode" "DI")])
17486
17487(define_split 
17488  [(set (match_operand:DI 0 "register_operand" "")
17489	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17490	 UNSPEC_FIST_FLOOR))
17491   (use (match_operand:HI 2 "memory_operand" ""))
17492   (use (match_operand:HI 3 "memory_operand" ""))
17493   (clobber (match_operand:DI 4 "memory_operand" ""))
17494   (clobber (match_scratch 5 ""))]
17495  "reload_completed"
17496  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17497	      (use (match_dup 2))
17498	      (use (match_dup 3))
17499	      (clobber (match_dup 5))])
17500   (set (match_dup 0) (match_dup 4))]
17501  "")
17502
17503(define_split 
17504  [(set (match_operand:DI 0 "memory_operand" "")
17505	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17506	 UNSPEC_FIST_FLOOR))
17507   (use (match_operand:HI 2 "memory_operand" ""))
17508   (use (match_operand:HI 3 "memory_operand" ""))
17509   (clobber (match_operand:DI 4 "memory_operand" ""))
17510   (clobber (match_scratch 5 ""))]
17511  "reload_completed"
17512  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17513	      (use (match_dup 2))
17514	      (use (match_dup 3))
17515	      (clobber (match_dup 5))])]
17516  "")
17517
17518(define_insn "fist<mode>2_floor"
17519  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17520	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17521	 UNSPEC_FIST_FLOOR))
17522   (use (match_operand:HI 2 "memory_operand" "m"))
17523   (use (match_operand:HI 3 "memory_operand" "m"))]
17524  "TARGET_USE_FANCY_MATH_387
17525   && flag_unsafe_math_optimizations"
17526  "* return output_fix_trunc (insn, operands, 0);"
17527  [(set_attr "type" "fistp")
17528   (set_attr "i387_cw" "floor")
17529   (set_attr "mode" "<MODE>")])
17530
17531(define_insn "fist<mode>2_floor_with_temp"
17532  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17533	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17534	 UNSPEC_FIST_FLOOR))
17535   (use (match_operand:HI 2 "memory_operand" "m,m"))
17536   (use (match_operand:HI 3 "memory_operand" "m,m"))
17537   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17538  "TARGET_USE_FANCY_MATH_387
17539   && flag_unsafe_math_optimizations"
17540  "#"
17541  [(set_attr "type" "fistp")
17542   (set_attr "i387_cw" "floor")
17543   (set_attr "mode" "<MODE>")])
17544
17545(define_split 
17546  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17547	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17548	 UNSPEC_FIST_FLOOR))
17549   (use (match_operand:HI 2 "memory_operand" ""))
17550   (use (match_operand:HI 3 "memory_operand" ""))
17551   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17552  "reload_completed"
17553  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17554				  UNSPEC_FIST_FLOOR))
17555	      (use (match_dup 2))
17556	      (use (match_dup 3))])
17557   (set (match_dup 0) (match_dup 4))]
17558  "")
17559
17560(define_split 
17561  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17562	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17563	 UNSPEC_FIST_FLOOR))
17564   (use (match_operand:HI 2 "memory_operand" ""))
17565   (use (match_operand:HI 3 "memory_operand" ""))
17566   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17567  "reload_completed"
17568  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17569				  UNSPEC_FIST_FLOOR))
17570	      (use (match_dup 2))
17571	      (use (match_dup 3))])]
17572  "")
17573
17574(define_expand "lfloor<mode>2"
17575  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17576		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17577		    UNSPEC_FIST_FLOOR))
17578	      (clobber (reg:CC FLAGS_REG))])]
17579  "TARGET_USE_FANCY_MATH_387
17580   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17581   && flag_unsafe_math_optimizations"
17582  "")
17583
17584;; Rounding mode control word calculation could clobber FLAGS_REG.
17585(define_insn_and_split "frndintxf2_ceil"
17586  [(set (match_operand:XF 0 "register_operand" "=f")
17587	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17588	 UNSPEC_FRNDINT_CEIL))
17589   (clobber (reg:CC FLAGS_REG))]
17590  "TARGET_USE_FANCY_MATH_387
17591   && flag_unsafe_math_optimizations
17592   && !(reload_completed || reload_in_progress)"
17593  "#"
17594  "&& 1"
17595  [(const_int 0)]
17596{
17597  ix86_optimize_mode_switching[I387_CEIL] = 1;
17598
17599  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17600  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17601
17602  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17603				       operands[2], operands[3]));
17604  DONE;
17605}
17606  [(set_attr "type" "frndint")
17607   (set_attr "i387_cw" "ceil")
17608   (set_attr "mode" "XF")])
17609
17610(define_insn "frndintxf2_ceil_i387"
17611  [(set (match_operand:XF 0 "register_operand" "=f")
17612	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17613	 UNSPEC_FRNDINT_CEIL))
17614   (use (match_operand:HI 2 "memory_operand" "m"))
17615   (use (match_operand:HI 3 "memory_operand" "m"))]
17616  "TARGET_USE_FANCY_MATH_387
17617   && flag_unsafe_math_optimizations"
17618  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17619  [(set_attr "type" "frndint")
17620   (set_attr "i387_cw" "ceil")
17621   (set_attr "mode" "XF")])
17622
17623(define_expand "ceilxf2"
17624  [(use (match_operand:XF 0 "register_operand" ""))
17625   (use (match_operand:XF 1 "register_operand" ""))]
17626  "TARGET_USE_FANCY_MATH_387
17627   && flag_unsafe_math_optimizations"
17628{
17629  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17630  DONE;
17631})
17632
17633(define_expand "ceildf2"
17634  [(use (match_operand:DF 0 "register_operand" ""))
17635   (use (match_operand:DF 1 "register_operand" ""))]
17636  "TARGET_USE_FANCY_MATH_387
17637   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17638   && flag_unsafe_math_optimizations"
17639{
17640  rtx op0 = gen_reg_rtx (XFmode);
17641  rtx op1 = gen_reg_rtx (XFmode);
17642
17643  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17644  emit_insn (gen_frndintxf2_ceil (op0, op1));
17645
17646  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17647  DONE;
17648})
17649
17650(define_expand "ceilsf2"
17651  [(use (match_operand:SF 0 "register_operand" ""))
17652   (use (match_operand:SF 1 "register_operand" ""))]
17653  "TARGET_USE_FANCY_MATH_387
17654   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17655   && flag_unsafe_math_optimizations"
17656{
17657  rtx op0 = gen_reg_rtx (XFmode);
17658  rtx op1 = gen_reg_rtx (XFmode);
17659
17660  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17661  emit_insn (gen_frndintxf2_ceil (op0, op1));
17662
17663  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17664  DONE;
17665})
17666
17667(define_insn_and_split "*fist<mode>2_ceil_1"
17668  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17669	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17670	 UNSPEC_FIST_CEIL))
17671   (clobber (reg:CC FLAGS_REG))]
17672  "TARGET_USE_FANCY_MATH_387
17673   && flag_unsafe_math_optimizations
17674   && !(reload_completed || reload_in_progress)"
17675  "#"
17676  "&& 1"
17677  [(const_int 0)]
17678{
17679  ix86_optimize_mode_switching[I387_CEIL] = 1;
17680
17681  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17682  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17683  if (memory_operand (operands[0], VOIDmode))
17684    emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17685				     operands[2], operands[3]));
17686  else
17687    {
17688      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17689      emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17690						 operands[2], operands[3],
17691						 operands[4]));
17692    }
17693  DONE;
17694}
17695  [(set_attr "type" "fistp")
17696   (set_attr "i387_cw" "ceil")
17697   (set_attr "mode" "<MODE>")])
17698
17699(define_insn "fistdi2_ceil"
17700  [(set (match_operand:DI 0 "memory_operand" "=m")
17701	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17702	 UNSPEC_FIST_CEIL))
17703   (use (match_operand:HI 2 "memory_operand" "m"))
17704   (use (match_operand:HI 3 "memory_operand" "m"))
17705   (clobber (match_scratch:XF 4 "=&1f"))]
17706  "TARGET_USE_FANCY_MATH_387
17707   && flag_unsafe_math_optimizations"
17708  "* return output_fix_trunc (insn, operands, 0);"
17709  [(set_attr "type" "fistp")
17710   (set_attr "i387_cw" "ceil")
17711   (set_attr "mode" "DI")])
17712
17713(define_insn "fistdi2_ceil_with_temp"
17714  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17715	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17716	 UNSPEC_FIST_CEIL))
17717   (use (match_operand:HI 2 "memory_operand" "m,m"))
17718   (use (match_operand:HI 3 "memory_operand" "m,m"))
17719   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17720   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17721  "TARGET_USE_FANCY_MATH_387
17722   && flag_unsafe_math_optimizations"
17723  "#"
17724  [(set_attr "type" "fistp")
17725   (set_attr "i387_cw" "ceil")
17726   (set_attr "mode" "DI")])
17727
17728(define_split 
17729  [(set (match_operand:DI 0 "register_operand" "")
17730	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17731	 UNSPEC_FIST_CEIL))
17732   (use (match_operand:HI 2 "memory_operand" ""))
17733   (use (match_operand:HI 3 "memory_operand" ""))
17734   (clobber (match_operand:DI 4 "memory_operand" ""))
17735   (clobber (match_scratch 5 ""))]
17736  "reload_completed"
17737  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17738	      (use (match_dup 2))
17739	      (use (match_dup 3))
17740	      (clobber (match_dup 5))])
17741   (set (match_dup 0) (match_dup 4))]
17742  "")
17743
17744(define_split 
17745  [(set (match_operand:DI 0 "memory_operand" "")
17746	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17747	 UNSPEC_FIST_CEIL))
17748   (use (match_operand:HI 2 "memory_operand" ""))
17749   (use (match_operand:HI 3 "memory_operand" ""))
17750   (clobber (match_operand:DI 4 "memory_operand" ""))
17751   (clobber (match_scratch 5 ""))]
17752  "reload_completed"
17753  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17754	      (use (match_dup 2))
17755	      (use (match_dup 3))
17756	      (clobber (match_dup 5))])]
17757  "")
17758
17759(define_insn "fist<mode>2_ceil"
17760  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17761	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17762	 UNSPEC_FIST_CEIL))
17763   (use (match_operand:HI 2 "memory_operand" "m"))
17764   (use (match_operand:HI 3 "memory_operand" "m"))]
17765  "TARGET_USE_FANCY_MATH_387
17766   && flag_unsafe_math_optimizations"
17767  "* return output_fix_trunc (insn, operands, 0);"
17768  [(set_attr "type" "fistp")
17769   (set_attr "i387_cw" "ceil")
17770   (set_attr "mode" "<MODE>")])
17771
17772(define_insn "fist<mode>2_ceil_with_temp"
17773  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17774	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17775	 UNSPEC_FIST_CEIL))
17776   (use (match_operand:HI 2 "memory_operand" "m,m"))
17777   (use (match_operand:HI 3 "memory_operand" "m,m"))
17778   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17779  "TARGET_USE_FANCY_MATH_387
17780   && flag_unsafe_math_optimizations"
17781  "#"
17782  [(set_attr "type" "fistp")
17783   (set_attr "i387_cw" "ceil")
17784   (set_attr "mode" "<MODE>")])
17785
17786(define_split 
17787  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17788	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17789	 UNSPEC_FIST_CEIL))
17790   (use (match_operand:HI 2 "memory_operand" ""))
17791   (use (match_operand:HI 3 "memory_operand" ""))
17792   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17793  "reload_completed"
17794  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17795				  UNSPEC_FIST_CEIL))
17796	      (use (match_dup 2))
17797	      (use (match_dup 3))])
17798   (set (match_dup 0) (match_dup 4))]
17799  "")
17800
17801(define_split 
17802  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17803	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17804	 UNSPEC_FIST_CEIL))
17805   (use (match_operand:HI 2 "memory_operand" ""))
17806   (use (match_operand:HI 3 "memory_operand" ""))
17807   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17808  "reload_completed"
17809  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17810				  UNSPEC_FIST_CEIL))
17811	      (use (match_dup 2))
17812	      (use (match_dup 3))])]
17813  "")
17814
17815(define_expand "lceil<mode>2"
17816  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17817		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17818		    UNSPEC_FIST_CEIL))
17819	      (clobber (reg:CC FLAGS_REG))])]
17820  "TARGET_USE_FANCY_MATH_387
17821   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17822   && flag_unsafe_math_optimizations"
17823  "")
17824
17825;; Rounding mode control word calculation could clobber FLAGS_REG.
17826(define_insn_and_split "frndintxf2_trunc"
17827  [(set (match_operand:XF 0 "register_operand" "=f")
17828	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17829	 UNSPEC_FRNDINT_TRUNC))
17830   (clobber (reg:CC FLAGS_REG))]
17831  "TARGET_USE_FANCY_MATH_387
17832   && flag_unsafe_math_optimizations
17833   && !(reload_completed || reload_in_progress)"
17834  "#"
17835  "&& 1"
17836  [(const_int 0)]
17837{
17838  ix86_optimize_mode_switching[I387_TRUNC] = 1;
17839
17840  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17841  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17842
17843  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17844					operands[2], operands[3]));
17845  DONE;
17846}
17847  [(set_attr "type" "frndint")
17848   (set_attr "i387_cw" "trunc")
17849   (set_attr "mode" "XF")])
17850
17851(define_insn "frndintxf2_trunc_i387"
17852  [(set (match_operand:XF 0 "register_operand" "=f")
17853	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17854	 UNSPEC_FRNDINT_TRUNC))
17855   (use (match_operand:HI 2 "memory_operand" "m"))
17856   (use (match_operand:HI 3 "memory_operand" "m"))]
17857  "TARGET_USE_FANCY_MATH_387
17858   && flag_unsafe_math_optimizations"
17859  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17860  [(set_attr "type" "frndint")
17861   (set_attr "i387_cw" "trunc")
17862   (set_attr "mode" "XF")])
17863
17864(define_expand "btruncxf2"
17865  [(use (match_operand:XF 0 "register_operand" ""))
17866   (use (match_operand:XF 1 "register_operand" ""))]
17867  "TARGET_USE_FANCY_MATH_387
17868   && flag_unsafe_math_optimizations"
17869{
17870  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17871  DONE;
17872})
17873
17874(define_expand "btruncdf2"
17875  [(use (match_operand:DF 0 "register_operand" ""))
17876   (use (match_operand:DF 1 "register_operand" ""))]
17877  "TARGET_USE_FANCY_MATH_387
17878   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17879   && flag_unsafe_math_optimizations"
17880{
17881  rtx op0 = gen_reg_rtx (XFmode);
17882  rtx op1 = gen_reg_rtx (XFmode);
17883
17884  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17885  emit_insn (gen_frndintxf2_trunc (op0, op1));
17886
17887  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17888  DONE;
17889})
17890
17891(define_expand "btruncsf2"
17892  [(use (match_operand:SF 0 "register_operand" ""))
17893   (use (match_operand:SF 1 "register_operand" ""))]
17894  "TARGET_USE_FANCY_MATH_387
17895   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17896   && flag_unsafe_math_optimizations"
17897{
17898  rtx op0 = gen_reg_rtx (XFmode);
17899  rtx op1 = gen_reg_rtx (XFmode);
17900
17901  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17902  emit_insn (gen_frndintxf2_trunc (op0, op1));
17903
17904  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17905  DONE;
17906})
17907
17908;; Rounding mode control word calculation could clobber FLAGS_REG.
17909(define_insn_and_split "frndintxf2_mask_pm"
17910  [(set (match_operand:XF 0 "register_operand" "=f")
17911	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17912	 UNSPEC_FRNDINT_MASK_PM))
17913   (clobber (reg:CC FLAGS_REG))]
17914  "TARGET_USE_FANCY_MATH_387
17915   && flag_unsafe_math_optimizations
17916   && !(reload_completed || reload_in_progress)"
17917  "#"
17918  "&& 1"
17919  [(const_int 0)]
17920{
17921  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17922
17923  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17924  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17925
17926  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17927					  operands[2], operands[3]));
17928  DONE;
17929}
17930  [(set_attr "type" "frndint")
17931   (set_attr "i387_cw" "mask_pm")
17932   (set_attr "mode" "XF")])
17933
17934(define_insn "frndintxf2_mask_pm_i387"
17935  [(set (match_operand:XF 0 "register_operand" "=f")
17936	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17937	 UNSPEC_FRNDINT_MASK_PM))
17938   (use (match_operand:HI 2 "memory_operand" "m"))
17939   (use (match_operand:HI 3 "memory_operand" "m"))]
17940  "TARGET_USE_FANCY_MATH_387
17941   && flag_unsafe_math_optimizations"
17942  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17943  [(set_attr "type" "frndint")
17944   (set_attr "i387_cw" "mask_pm")
17945   (set_attr "mode" "XF")])
17946
17947(define_expand "nearbyintxf2"
17948  [(use (match_operand:XF 0 "register_operand" ""))
17949   (use (match_operand:XF 1 "register_operand" ""))]
17950  "TARGET_USE_FANCY_MATH_387
17951   && flag_unsafe_math_optimizations"
17952{
17953  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17954
17955  DONE;
17956})
17957
17958(define_expand "nearbyintdf2"
17959  [(use (match_operand:DF 0 "register_operand" ""))
17960   (use (match_operand:DF 1 "register_operand" ""))]
17961  "TARGET_USE_FANCY_MATH_387
17962   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17963   && flag_unsafe_math_optimizations"
17964{
17965  rtx op0 = gen_reg_rtx (XFmode);
17966  rtx op1 = gen_reg_rtx (XFmode);
17967
17968  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17969  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17970
17971  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17972  DONE;
17973})
17974
17975(define_expand "nearbyintsf2"
17976  [(use (match_operand:SF 0 "register_operand" ""))
17977   (use (match_operand:SF 1 "register_operand" ""))]
17978  "TARGET_USE_FANCY_MATH_387
17979   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17980   && flag_unsafe_math_optimizations"
17981{
17982  rtx op0 = gen_reg_rtx (XFmode);
17983  rtx op1 = gen_reg_rtx (XFmode);
17984
17985  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17986  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17987
17988  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17989  DONE;
17990})
17991
17992
17993;; Block operation instructions
17994
17995(define_insn "cld"
17996 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17997 ""
17998 "cld"
17999  [(set_attr "type" "cld")])
18000
18001(define_expand "movmemsi"
18002  [(use (match_operand:BLK 0 "memory_operand" ""))
18003   (use (match_operand:BLK 1 "memory_operand" ""))
18004   (use (match_operand:SI 2 "nonmemory_operand" ""))
18005   (use (match_operand:SI 3 "const_int_operand" ""))]
18006  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18007{
18008 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18009   DONE;
18010 else
18011   FAIL;
18012})
18013
18014(define_expand "movmemdi"
18015  [(use (match_operand:BLK 0 "memory_operand" ""))
18016   (use (match_operand:BLK 1 "memory_operand" ""))
18017   (use (match_operand:DI 2 "nonmemory_operand" ""))
18018   (use (match_operand:DI 3 "const_int_operand" ""))]
18019  "TARGET_64BIT"
18020{
18021 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18022   DONE;
18023 else
18024   FAIL;
18025})
18026
18027;; Most CPUs don't like single string operations
18028;; Handle this case here to simplify previous expander.
18029
18030(define_expand "strmov"
18031  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18032   (set (match_operand 1 "memory_operand" "") (match_dup 4))
18033   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18034	      (clobber (reg:CC FLAGS_REG))])
18035   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18036	      (clobber (reg:CC FLAGS_REG))])]
18037  ""
18038{
18039  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18040
18041  /* If .md ever supports :P for Pmode, these can be directly
18042     in the pattern above.  */
18043  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18044  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18045
18046  if (TARGET_SINGLE_STRINGOP || optimize_size)
18047    {
18048      emit_insn (gen_strmov_singleop (operands[0], operands[1],
18049				      operands[2], operands[3],
18050				      operands[5], operands[6]));
18051      DONE;
18052    }
18053
18054  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18055})
18056
18057(define_expand "strmov_singleop"
18058  [(parallel [(set (match_operand 1 "memory_operand" "")
18059		   (match_operand 3 "memory_operand" ""))
18060	      (set (match_operand 0 "register_operand" "")
18061		   (match_operand 4 "" ""))
18062	      (set (match_operand 2 "register_operand" "")
18063		   (match_operand 5 "" ""))
18064	      (use (reg:SI DIRFLAG_REG))])]
18065  "TARGET_SINGLE_STRINGOP || optimize_size"
18066  "")
18067
18068(define_insn "*strmovdi_rex_1"
18069  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18070	(mem:DI (match_operand:DI 3 "register_operand" "1")))
18071   (set (match_operand:DI 0 "register_operand" "=D")
18072	(plus:DI (match_dup 2)
18073		 (const_int 8)))
18074   (set (match_operand:DI 1 "register_operand" "=S")
18075	(plus:DI (match_dup 3)
18076		 (const_int 8)))
18077   (use (reg:SI DIRFLAG_REG))]
18078  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18079  "movsq"
18080  [(set_attr "type" "str")
18081   (set_attr "mode" "DI")
18082   (set_attr "memory" "both")])
18083
18084(define_insn "*strmovsi_1"
18085  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18086	(mem:SI (match_operand:SI 3 "register_operand" "1")))
18087   (set (match_operand:SI 0 "register_operand" "=D")
18088	(plus:SI (match_dup 2)
18089		 (const_int 4)))
18090   (set (match_operand:SI 1 "register_operand" "=S")
18091	(plus:SI (match_dup 3)
18092		 (const_int 4)))
18093   (use (reg:SI DIRFLAG_REG))]
18094  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18095  "{movsl|movsd}"
18096  [(set_attr "type" "str")
18097   (set_attr "mode" "SI")
18098   (set_attr "memory" "both")])
18099
18100(define_insn "*strmovsi_rex_1"
18101  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18102	(mem:SI (match_operand:DI 3 "register_operand" "1")))
18103   (set (match_operand:DI 0 "register_operand" "=D")
18104	(plus:DI (match_dup 2)
18105		 (const_int 4)))
18106   (set (match_operand:DI 1 "register_operand" "=S")
18107	(plus:DI (match_dup 3)
18108		 (const_int 4)))
18109   (use (reg:SI DIRFLAG_REG))]
18110  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18111  "{movsl|movsd}"
18112  [(set_attr "type" "str")
18113   (set_attr "mode" "SI")
18114   (set_attr "memory" "both")])
18115
18116(define_insn "*strmovhi_1"
18117  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18118	(mem:HI (match_operand:SI 3 "register_operand" "1")))
18119   (set (match_operand:SI 0 "register_operand" "=D")
18120	(plus:SI (match_dup 2)
18121		 (const_int 2)))
18122   (set (match_operand:SI 1 "register_operand" "=S")
18123	(plus:SI (match_dup 3)
18124		 (const_int 2)))
18125   (use (reg:SI DIRFLAG_REG))]
18126  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18127  "movsw"
18128  [(set_attr "type" "str")
18129   (set_attr "memory" "both")
18130   (set_attr "mode" "HI")])
18131
18132(define_insn "*strmovhi_rex_1"
18133  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18134	(mem:HI (match_operand:DI 3 "register_operand" "1")))
18135   (set (match_operand:DI 0 "register_operand" "=D")
18136	(plus:DI (match_dup 2)
18137		 (const_int 2)))
18138   (set (match_operand:DI 1 "register_operand" "=S")
18139	(plus:DI (match_dup 3)
18140		 (const_int 2)))
18141   (use (reg:SI DIRFLAG_REG))]
18142  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18143  "movsw"
18144  [(set_attr "type" "str")
18145   (set_attr "memory" "both")
18146   (set_attr "mode" "HI")])
18147
18148(define_insn "*strmovqi_1"
18149  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18150	(mem:QI (match_operand:SI 3 "register_operand" "1")))
18151   (set (match_operand:SI 0 "register_operand" "=D")
18152	(plus:SI (match_dup 2)
18153		 (const_int 1)))
18154   (set (match_operand:SI 1 "register_operand" "=S")
18155	(plus:SI (match_dup 3)
18156		 (const_int 1)))
18157   (use (reg:SI DIRFLAG_REG))]
18158  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18159  "movsb"
18160  [(set_attr "type" "str")
18161   (set_attr "memory" "both")
18162   (set_attr "mode" "QI")])
18163
18164(define_insn "*strmovqi_rex_1"
18165  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18166	(mem:QI (match_operand:DI 3 "register_operand" "1")))
18167   (set (match_operand:DI 0 "register_operand" "=D")
18168	(plus:DI (match_dup 2)
18169		 (const_int 1)))
18170   (set (match_operand:DI 1 "register_operand" "=S")
18171	(plus:DI (match_dup 3)
18172		 (const_int 1)))
18173   (use (reg:SI DIRFLAG_REG))]
18174  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18175  "movsb"
18176  [(set_attr "type" "str")
18177   (set_attr "memory" "both")
18178   (set_attr "mode" "QI")])
18179
18180(define_expand "rep_mov"
18181  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18182	      (set (match_operand 0 "register_operand" "")
18183		   (match_operand 5 "" ""))
18184	      (set (match_operand 2 "register_operand" "")
18185		   (match_operand 6 "" ""))
18186	      (set (match_operand 1 "memory_operand" "")
18187		   (match_operand 3 "memory_operand" ""))
18188	      (use (match_dup 4))
18189	      (use (reg:SI DIRFLAG_REG))])]
18190  ""
18191  "")
18192
18193(define_insn "*rep_movdi_rex64"
18194  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18195   (set (match_operand:DI 0 "register_operand" "=D") 
18196        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18197			    (const_int 3))
18198		 (match_operand:DI 3 "register_operand" "0")))
18199   (set (match_operand:DI 1 "register_operand" "=S") 
18200        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18201		 (match_operand:DI 4 "register_operand" "1")))
18202   (set (mem:BLK (match_dup 3))
18203	(mem:BLK (match_dup 4)))
18204   (use (match_dup 5))
18205   (use (reg:SI DIRFLAG_REG))]
18206  "TARGET_64BIT"
18207  "{rep\;movsq|rep movsq}"
18208  [(set_attr "type" "str")
18209   (set_attr "prefix_rep" "1")
18210   (set_attr "memory" "both")
18211   (set_attr "mode" "DI")])
18212
18213(define_insn "*rep_movsi"
18214  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18215   (set (match_operand:SI 0 "register_operand" "=D") 
18216        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18217			    (const_int 2))
18218		 (match_operand:SI 3 "register_operand" "0")))
18219   (set (match_operand:SI 1 "register_operand" "=S") 
18220        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18221		 (match_operand:SI 4 "register_operand" "1")))
18222   (set (mem:BLK (match_dup 3))
18223	(mem:BLK (match_dup 4)))
18224   (use (match_dup 5))
18225   (use (reg:SI DIRFLAG_REG))]
18226  "!TARGET_64BIT"
18227  "{rep\;movsl|rep movsd}"
18228  [(set_attr "type" "str")
18229   (set_attr "prefix_rep" "1")
18230   (set_attr "memory" "both")
18231   (set_attr "mode" "SI")])
18232
18233(define_insn "*rep_movsi_rex64"
18234  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18235   (set (match_operand:DI 0 "register_operand" "=D") 
18236        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18237			    (const_int 2))
18238		 (match_operand:DI 3 "register_operand" "0")))
18239   (set (match_operand:DI 1 "register_operand" "=S") 
18240        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18241		 (match_operand:DI 4 "register_operand" "1")))
18242   (set (mem:BLK (match_dup 3))
18243	(mem:BLK (match_dup 4)))
18244   (use (match_dup 5))
18245   (use (reg:SI DIRFLAG_REG))]
18246  "TARGET_64BIT"
18247  "{rep\;movsl|rep movsd}"
18248  [(set_attr "type" "str")
18249   (set_attr "prefix_rep" "1")
18250   (set_attr "memory" "both")
18251   (set_attr "mode" "SI")])
18252
18253(define_insn "*rep_movqi"
18254  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18255   (set (match_operand:SI 0 "register_operand" "=D") 
18256        (plus:SI (match_operand:SI 3 "register_operand" "0")
18257		 (match_operand:SI 5 "register_operand" "2")))
18258   (set (match_operand:SI 1 "register_operand" "=S") 
18259        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18260   (set (mem:BLK (match_dup 3))
18261	(mem:BLK (match_dup 4)))
18262   (use (match_dup 5))
18263   (use (reg:SI DIRFLAG_REG))]
18264  "!TARGET_64BIT"
18265  "{rep\;movsb|rep movsb}"
18266  [(set_attr "type" "str")
18267   (set_attr "prefix_rep" "1")
18268   (set_attr "memory" "both")
18269   (set_attr "mode" "SI")])
18270
18271(define_insn "*rep_movqi_rex64"
18272  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18273   (set (match_operand:DI 0 "register_operand" "=D") 
18274        (plus:DI (match_operand:DI 3 "register_operand" "0")
18275		 (match_operand:DI 5 "register_operand" "2")))
18276   (set (match_operand:DI 1 "register_operand" "=S") 
18277        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18278   (set (mem:BLK (match_dup 3))
18279	(mem:BLK (match_dup 4)))
18280   (use (match_dup 5))
18281   (use (reg:SI DIRFLAG_REG))]
18282  "TARGET_64BIT"
18283  "{rep\;movsb|rep movsb}"
18284  [(set_attr "type" "str")
18285   (set_attr "prefix_rep" "1")
18286   (set_attr "memory" "both")
18287   (set_attr "mode" "SI")])
18288
18289(define_expand "setmemsi"
18290   [(use (match_operand:BLK 0 "memory_operand" ""))
18291    (use (match_operand:SI 1 "nonmemory_operand" ""))
18292    (use (match_operand 2 "const_int_operand" ""))
18293    (use (match_operand 3 "const_int_operand" ""))]
18294  ""
18295{
18296 /* If value to set is not zero, use the library routine.  */
18297 if (operands[2] != const0_rtx)
18298   FAIL;
18299
18300 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18301   DONE;
18302 else
18303   FAIL;
18304})
18305
18306(define_expand "setmemdi"
18307   [(use (match_operand:BLK 0 "memory_operand" ""))
18308    (use (match_operand:DI 1 "nonmemory_operand" ""))
18309    (use (match_operand 2 "const_int_operand" ""))
18310    (use (match_operand 3 "const_int_operand" ""))]
18311  "TARGET_64BIT"
18312{
18313 /* If value to set is not zero, use the library routine.  */
18314 if (operands[2] != const0_rtx)
18315   FAIL;
18316
18317 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18318   DONE;
18319 else
18320   FAIL;
18321})
18322
18323;; Most CPUs don't like single string operations
18324;; Handle this case here to simplify previous expander.
18325
18326(define_expand "strset"
18327  [(set (match_operand 1 "memory_operand" "")
18328	(match_operand 2 "register_operand" ""))
18329   (parallel [(set (match_operand 0 "register_operand" "")
18330		   (match_dup 3))
18331	      (clobber (reg:CC FLAGS_REG))])]
18332  ""
18333{
18334  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18335    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18336
18337  /* If .md ever supports :P for Pmode, this can be directly
18338     in the pattern above.  */
18339  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18340			      GEN_INT (GET_MODE_SIZE (GET_MODE
18341						      (operands[2]))));
18342  if (TARGET_SINGLE_STRINGOP || optimize_size)
18343    {
18344      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18345				      operands[3]));
18346      DONE;
18347    }
18348})
18349
18350(define_expand "strset_singleop"
18351  [(parallel [(set (match_operand 1 "memory_operand" "")
18352		   (match_operand 2 "register_operand" ""))
18353	      (set (match_operand 0 "register_operand" "")
18354		   (match_operand 3 "" ""))
18355	      (use (reg:SI DIRFLAG_REG))])]
18356  "TARGET_SINGLE_STRINGOP || optimize_size"
18357  "")
18358
18359(define_insn "*strsetdi_rex_1"
18360  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18361	(match_operand:DI 2 "register_operand" "a"))
18362   (set (match_operand:DI 0 "register_operand" "=D")
18363	(plus:DI (match_dup 1)
18364		 (const_int 8)))
18365   (use (reg:SI DIRFLAG_REG))]
18366  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18367  "stosq"
18368  [(set_attr "type" "str")
18369   (set_attr "memory" "store")
18370   (set_attr "mode" "DI")])
18371
18372(define_insn "*strsetsi_1"
18373  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18374	(match_operand:SI 2 "register_operand" "a"))
18375   (set (match_operand:SI 0 "register_operand" "=D")
18376	(plus:SI (match_dup 1)
18377		 (const_int 4)))
18378   (use (reg:SI DIRFLAG_REG))]
18379  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18380  "{stosl|stosd}"
18381  [(set_attr "type" "str")
18382   (set_attr "memory" "store")
18383   (set_attr "mode" "SI")])
18384
18385(define_insn "*strsetsi_rex_1"
18386  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18387	(match_operand:SI 2 "register_operand" "a"))
18388   (set (match_operand:DI 0 "register_operand" "=D")
18389	(plus:DI (match_dup 1)
18390		 (const_int 4)))
18391   (use (reg:SI DIRFLAG_REG))]
18392  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18393  "{stosl|stosd}"
18394  [(set_attr "type" "str")
18395   (set_attr "memory" "store")
18396   (set_attr "mode" "SI")])
18397
18398(define_insn "*strsethi_1"
18399  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18400	(match_operand:HI 2 "register_operand" "a"))
18401   (set (match_operand:SI 0 "register_operand" "=D")
18402	(plus:SI (match_dup 1)
18403		 (const_int 2)))
18404   (use (reg:SI DIRFLAG_REG))]
18405  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18406  "stosw"
18407  [(set_attr "type" "str")
18408   (set_attr "memory" "store")
18409   (set_attr "mode" "HI")])
18410
18411(define_insn "*strsethi_rex_1"
18412  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18413	(match_operand:HI 2 "register_operand" "a"))
18414   (set (match_operand:DI 0 "register_operand" "=D")
18415	(plus:DI (match_dup 1)
18416		 (const_int 2)))
18417   (use (reg:SI DIRFLAG_REG))]
18418  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18419  "stosw"
18420  [(set_attr "type" "str")
18421   (set_attr "memory" "store")
18422   (set_attr "mode" "HI")])
18423
18424(define_insn "*strsetqi_1"
18425  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18426	(match_operand:QI 2 "register_operand" "a"))
18427   (set (match_operand:SI 0 "register_operand" "=D")
18428	(plus:SI (match_dup 1)
18429		 (const_int 1)))
18430   (use (reg:SI DIRFLAG_REG))]
18431  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18432  "stosb"
18433  [(set_attr "type" "str")
18434   (set_attr "memory" "store")
18435   (set_attr "mode" "QI")])
18436
18437(define_insn "*strsetqi_rex_1"
18438  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18439	(match_operand:QI 2 "register_operand" "a"))
18440   (set (match_operand:DI 0 "register_operand" "=D")
18441	(plus:DI (match_dup 1)
18442		 (const_int 1)))
18443   (use (reg:SI DIRFLAG_REG))]
18444  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18445  "stosb"
18446  [(set_attr "type" "str")
18447   (set_attr "memory" "store")
18448   (set_attr "mode" "QI")])
18449
18450(define_expand "rep_stos"
18451  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18452	      (set (match_operand 0 "register_operand" "")
18453		   (match_operand 4 "" ""))
18454	      (set (match_operand 2 "memory_operand" "") (const_int 0))
18455	      (use (match_operand 3 "register_operand" ""))
18456	      (use (match_dup 1))
18457	      (use (reg:SI DIRFLAG_REG))])]
18458  ""
18459  "")
18460
18461(define_insn "*rep_stosdi_rex64"
18462  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18463   (set (match_operand:DI 0 "register_operand" "=D") 
18464        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18465			    (const_int 3))
18466		 (match_operand:DI 3 "register_operand" "0")))
18467   (set (mem:BLK (match_dup 3))
18468	(const_int 0))
18469   (use (match_operand:DI 2 "register_operand" "a"))
18470   (use (match_dup 4))
18471   (use (reg:SI DIRFLAG_REG))]
18472  "TARGET_64BIT"
18473  "{rep\;stosq|rep stosq}"
18474  [(set_attr "type" "str")
18475   (set_attr "prefix_rep" "1")
18476   (set_attr "memory" "store")
18477   (set_attr "mode" "DI")])
18478
18479(define_insn "*rep_stossi"
18480  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18481   (set (match_operand:SI 0 "register_operand" "=D") 
18482        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18483			    (const_int 2))
18484		 (match_operand:SI 3 "register_operand" "0")))
18485   (set (mem:BLK (match_dup 3))
18486	(const_int 0))
18487   (use (match_operand:SI 2 "register_operand" "a"))
18488   (use (match_dup 4))
18489   (use (reg:SI DIRFLAG_REG))]
18490  "!TARGET_64BIT"
18491  "{rep\;stosl|rep stosd}"
18492  [(set_attr "type" "str")
18493   (set_attr "prefix_rep" "1")
18494   (set_attr "memory" "store")
18495   (set_attr "mode" "SI")])
18496
18497(define_insn "*rep_stossi_rex64"
18498  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18499   (set (match_operand:DI 0 "register_operand" "=D") 
18500        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18501			    (const_int 2))
18502		 (match_operand:DI 3 "register_operand" "0")))
18503   (set (mem:BLK (match_dup 3))
18504	(const_int 0))
18505   (use (match_operand:SI 2 "register_operand" "a"))
18506   (use (match_dup 4))
18507   (use (reg:SI DIRFLAG_REG))]
18508  "TARGET_64BIT"
18509  "{rep\;stosl|rep stosd}"
18510  [(set_attr "type" "str")
18511   (set_attr "prefix_rep" "1")
18512   (set_attr "memory" "store")
18513   (set_attr "mode" "SI")])
18514
18515(define_insn "*rep_stosqi"
18516  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18517   (set (match_operand:SI 0 "register_operand" "=D") 
18518        (plus:SI (match_operand:SI 3 "register_operand" "0")
18519		 (match_operand:SI 4 "register_operand" "1")))
18520   (set (mem:BLK (match_dup 3))
18521	(const_int 0))
18522   (use (match_operand:QI 2 "register_operand" "a"))
18523   (use (match_dup 4))
18524   (use (reg:SI DIRFLAG_REG))]
18525  "!TARGET_64BIT"
18526  "{rep\;stosb|rep stosb}"
18527  [(set_attr "type" "str")
18528   (set_attr "prefix_rep" "1")
18529   (set_attr "memory" "store")
18530   (set_attr "mode" "QI")])
18531
18532(define_insn "*rep_stosqi_rex64"
18533  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18534   (set (match_operand:DI 0 "register_operand" "=D") 
18535        (plus:DI (match_operand:DI 3 "register_operand" "0")
18536		 (match_operand:DI 4 "register_operand" "1")))
18537   (set (mem:BLK (match_dup 3))
18538	(const_int 0))
18539   (use (match_operand:QI 2 "register_operand" "a"))
18540   (use (match_dup 4))
18541   (use (reg:SI DIRFLAG_REG))]
18542  "TARGET_64BIT"
18543  "{rep\;stosb|rep stosb}"
18544  [(set_attr "type" "str")
18545   (set_attr "prefix_rep" "1")
18546   (set_attr "memory" "store")
18547   (set_attr "mode" "QI")])
18548
18549(define_expand "cmpstrnsi"
18550  [(set (match_operand:SI 0 "register_operand" "")
18551	(compare:SI (match_operand:BLK 1 "general_operand" "")
18552		    (match_operand:BLK 2 "general_operand" "")))
18553   (use (match_operand 3 "general_operand" ""))
18554   (use (match_operand 4 "immediate_operand" ""))]
18555  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18556{
18557  rtx addr1, addr2, out, outlow, count, countreg, align;
18558
18559  /* Can't use this if the user has appropriated esi or edi.  */
18560  if (global_regs[4] || global_regs[5])
18561    FAIL;
18562
18563  out = operands[0];
18564  if (GET_CODE (out) != REG)
18565    out = gen_reg_rtx (SImode);
18566
18567  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18568  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18569  if (addr1 != XEXP (operands[1], 0))
18570    operands[1] = replace_equiv_address_nv (operands[1], addr1);
18571  if (addr2 != XEXP (operands[2], 0))
18572    operands[2] = replace_equiv_address_nv (operands[2], addr2);
18573
18574  count = operands[3];
18575  countreg = ix86_zero_extend_to_Pmode (count);
18576
18577  /* %%% Iff we are testing strict equality, we can use known alignment
18578     to good advantage.  This may be possible with combine, particularly
18579     once cc0 is dead.  */
18580  align = operands[4];
18581
18582  emit_insn (gen_cld ());
18583  if (GET_CODE (count) == CONST_INT)
18584    {
18585      if (INTVAL (count) == 0)
18586	{
18587	  emit_move_insn (operands[0], const0_rtx);
18588	  DONE;
18589	}
18590      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18591				     operands[1], operands[2]));
18592    }
18593  else
18594    {
18595      if (TARGET_64BIT)
18596	emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18597      else
18598	emit_insn (gen_cmpsi_1 (countreg, countreg));
18599      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18600				  operands[1], operands[2]));
18601    }
18602
18603  outlow = gen_lowpart (QImode, out);
18604  emit_insn (gen_cmpintqi (outlow));
18605  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18606
18607  if (operands[0] != out)
18608    emit_move_insn (operands[0], out);
18609
18610  DONE;
18611})
18612
18613;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18614
18615(define_expand "cmpintqi"
18616  [(set (match_dup 1)
18617	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18618   (set (match_dup 2)
18619	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18620   (parallel [(set (match_operand:QI 0 "register_operand" "")
18621		   (minus:QI (match_dup 1)
18622			     (match_dup 2)))
18623	      (clobber (reg:CC FLAGS_REG))])]
18624  ""
18625  "operands[1] = gen_reg_rtx (QImode);
18626   operands[2] = gen_reg_rtx (QImode);")
18627
18628;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18629;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18630
18631(define_expand "cmpstrnqi_nz_1"
18632  [(parallel [(set (reg:CC FLAGS_REG)
18633		   (compare:CC (match_operand 4 "memory_operand" "")
18634			       (match_operand 5 "memory_operand" "")))
18635	      (use (match_operand 2 "register_operand" ""))
18636	      (use (match_operand:SI 3 "immediate_operand" ""))
18637	      (use (reg:SI DIRFLAG_REG))
18638	      (clobber (match_operand 0 "register_operand" ""))
18639	      (clobber (match_operand 1 "register_operand" ""))
18640	      (clobber (match_dup 2))])]
18641  ""
18642  "")
18643
18644(define_insn "*cmpstrnqi_nz_1"
18645  [(set (reg:CC FLAGS_REG)
18646	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18647		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18648   (use (match_operand:SI 6 "register_operand" "2"))
18649   (use (match_operand:SI 3 "immediate_operand" "i"))
18650   (use (reg:SI DIRFLAG_REG))
18651   (clobber (match_operand:SI 0 "register_operand" "=S"))
18652   (clobber (match_operand:SI 1 "register_operand" "=D"))
18653   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18654  "!TARGET_64BIT"
18655  "repz{\;| }cmpsb"
18656  [(set_attr "type" "str")
18657   (set_attr "mode" "QI")
18658   (set_attr "prefix_rep" "1")])
18659
18660(define_insn "*cmpstrnqi_nz_rex_1"
18661  [(set (reg:CC FLAGS_REG)
18662	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18663		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18664   (use (match_operand:DI 6 "register_operand" "2"))
18665   (use (match_operand:SI 3 "immediate_operand" "i"))
18666   (use (reg:SI DIRFLAG_REG))
18667   (clobber (match_operand:DI 0 "register_operand" "=S"))
18668   (clobber (match_operand:DI 1 "register_operand" "=D"))
18669   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18670  "TARGET_64BIT"
18671  "repz{\;| }cmpsb"
18672  [(set_attr "type" "str")
18673   (set_attr "mode" "QI")
18674   (set_attr "prefix_rep" "1")])
18675
18676;; The same, but the count is not known to not be zero.
18677
18678(define_expand "cmpstrnqi_1"
18679  [(parallel [(set (reg:CC FLAGS_REG)
18680		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
18681				     (const_int 0))
18682		  (compare:CC (match_operand 4 "memory_operand" "")
18683			      (match_operand 5 "memory_operand" ""))
18684		  (const_int 0)))
18685	      (use (match_operand:SI 3 "immediate_operand" ""))
18686	      (use (reg:CC FLAGS_REG))
18687	      (use (reg:SI DIRFLAG_REG))
18688	      (clobber (match_operand 0 "register_operand" ""))
18689	      (clobber (match_operand 1 "register_operand" ""))
18690	      (clobber (match_dup 2))])]
18691  ""
18692  "")
18693
18694(define_insn "*cmpstrnqi_1"
18695  [(set (reg:CC FLAGS_REG)
18696	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18697			     (const_int 0))
18698	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18699		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18700	  (const_int 0)))
18701   (use (match_operand:SI 3 "immediate_operand" "i"))
18702   (use (reg:CC FLAGS_REG))
18703   (use (reg:SI DIRFLAG_REG))
18704   (clobber (match_operand:SI 0 "register_operand" "=S"))
18705   (clobber (match_operand:SI 1 "register_operand" "=D"))
18706   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18707  "!TARGET_64BIT"
18708  "repz{\;| }cmpsb"
18709  [(set_attr "type" "str")
18710   (set_attr "mode" "QI")
18711   (set_attr "prefix_rep" "1")])
18712
18713(define_insn "*cmpstrnqi_rex_1"
18714  [(set (reg:CC FLAGS_REG)
18715	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18716			     (const_int 0))
18717	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18718		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18719	  (const_int 0)))
18720   (use (match_operand:SI 3 "immediate_operand" "i"))
18721   (use (reg:CC FLAGS_REG))
18722   (use (reg:SI DIRFLAG_REG))
18723   (clobber (match_operand:DI 0 "register_operand" "=S"))
18724   (clobber (match_operand:DI 1 "register_operand" "=D"))
18725   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18726  "TARGET_64BIT"
18727  "repz{\;| }cmpsb"
18728  [(set_attr "type" "str")
18729   (set_attr "mode" "QI")
18730   (set_attr "prefix_rep" "1")])
18731
18732(define_expand "strlensi"
18733  [(set (match_operand:SI 0 "register_operand" "")
18734	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
18735		    (match_operand:QI 2 "immediate_operand" "")
18736		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18737  ""
18738{
18739 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18740   DONE;
18741 else
18742   FAIL;
18743})
18744
18745(define_expand "strlendi"
18746  [(set (match_operand:DI 0 "register_operand" "")
18747	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
18748		    (match_operand:QI 2 "immediate_operand" "")
18749		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18750  ""
18751{
18752 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18753   DONE;
18754 else
18755   FAIL;
18756})
18757
18758(define_expand "strlenqi_1"
18759  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18760	      (use (reg:SI DIRFLAG_REG))
18761	      (clobber (match_operand 1 "register_operand" ""))
18762	      (clobber (reg:CC FLAGS_REG))])]
18763  ""
18764  "")
18765
18766(define_insn "*strlenqi_1"
18767  [(set (match_operand:SI 0 "register_operand" "=&c")
18768	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18769		    (match_operand:QI 2 "register_operand" "a")
18770		    (match_operand:SI 3 "immediate_operand" "i")
18771		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18772   (use (reg:SI DIRFLAG_REG))
18773   (clobber (match_operand:SI 1 "register_operand" "=D"))
18774   (clobber (reg:CC FLAGS_REG))]
18775  "!TARGET_64BIT"
18776  "repnz{\;| }scasb"
18777  [(set_attr "type" "str")
18778   (set_attr "mode" "QI")
18779   (set_attr "prefix_rep" "1")])
18780
18781(define_insn "*strlenqi_rex_1"
18782  [(set (match_operand:DI 0 "register_operand" "=&c")
18783	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18784		    (match_operand:QI 2 "register_operand" "a")
18785		    (match_operand:DI 3 "immediate_operand" "i")
18786		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18787   (use (reg:SI DIRFLAG_REG))
18788   (clobber (match_operand:DI 1 "register_operand" "=D"))
18789   (clobber (reg:CC FLAGS_REG))]
18790  "TARGET_64BIT"
18791  "repnz{\;| }scasb"
18792  [(set_attr "type" "str")
18793   (set_attr "mode" "QI")
18794   (set_attr "prefix_rep" "1")])
18795
18796;; Peephole optimizations to clean up after cmpstrn*.  This should be
18797;; handled in combine, but it is not currently up to the task.
18798;; When used for their truth value, the cmpstrn* expanders generate
18799;; code like this:
18800;;
18801;;   repz cmpsb
18802;;   seta 	%al
18803;;   setb 	%dl
18804;;   cmpb 	%al, %dl
18805;;   jcc	label
18806;;
18807;; The intermediate three instructions are unnecessary.
18808
18809;; This one handles cmpstrn*_nz_1...
18810(define_peephole2
18811  [(parallel[
18812     (set (reg:CC FLAGS_REG)
18813	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18814		      (mem:BLK (match_operand 5 "register_operand" ""))))
18815     (use (match_operand 6 "register_operand" ""))
18816     (use (match_operand:SI 3 "immediate_operand" ""))
18817     (use (reg:SI DIRFLAG_REG))
18818     (clobber (match_operand 0 "register_operand" ""))
18819     (clobber (match_operand 1 "register_operand" ""))
18820     (clobber (match_operand 2 "register_operand" ""))])
18821   (set (match_operand:QI 7 "register_operand" "")
18822	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18823   (set (match_operand:QI 8 "register_operand" "")
18824	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18825   (set (reg FLAGS_REG)
18826	(compare (match_dup 7) (match_dup 8)))
18827  ]
18828  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18829  [(parallel[
18830     (set (reg:CC FLAGS_REG)
18831	  (compare:CC (mem:BLK (match_dup 4))
18832		      (mem:BLK (match_dup 5))))
18833     (use (match_dup 6))
18834     (use (match_dup 3))
18835     (use (reg:SI DIRFLAG_REG))
18836     (clobber (match_dup 0))
18837     (clobber (match_dup 1))
18838     (clobber (match_dup 2))])]
18839  "")
18840
18841;; ...and this one handles cmpstrn*_1.
18842(define_peephole2
18843  [(parallel[
18844     (set (reg:CC FLAGS_REG)
18845	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18846			       (const_int 0))
18847	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18848		        (mem:BLK (match_operand 5 "register_operand" "")))
18849	    (const_int 0)))
18850     (use (match_operand:SI 3 "immediate_operand" ""))
18851     (use (reg:CC FLAGS_REG))
18852     (use (reg:SI DIRFLAG_REG))
18853     (clobber (match_operand 0 "register_operand" ""))
18854     (clobber (match_operand 1 "register_operand" ""))
18855     (clobber (match_operand 2 "register_operand" ""))])
18856   (set (match_operand:QI 7 "register_operand" "")
18857	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18858   (set (match_operand:QI 8 "register_operand" "")
18859	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18860   (set (reg FLAGS_REG)
18861	(compare (match_dup 7) (match_dup 8)))
18862  ]
18863  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18864  [(parallel[
18865     (set (reg:CC FLAGS_REG)
18866	  (if_then_else:CC (ne (match_dup 6)
18867			       (const_int 0))
18868	    (compare:CC (mem:BLK (match_dup 4))
18869			(mem:BLK (match_dup 5)))
18870	    (const_int 0)))
18871     (use (match_dup 3))
18872     (use (reg:CC FLAGS_REG))
18873     (use (reg:SI DIRFLAG_REG))
18874     (clobber (match_dup 0))
18875     (clobber (match_dup 1))
18876     (clobber (match_dup 2))])]
18877  "")
18878
18879
18880
18881;; Conditional move instructions.
18882
18883(define_expand "movdicc"
18884  [(set (match_operand:DI 0 "register_operand" "")
18885	(if_then_else:DI (match_operand 1 "comparison_operator" "")
18886			 (match_operand:DI 2 "general_operand" "")
18887			 (match_operand:DI 3 "general_operand" "")))]
18888  "TARGET_64BIT"
18889  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18890
18891(define_insn "x86_movdicc_0_m1_rex64"
18892  [(set (match_operand:DI 0 "register_operand" "=r")
18893	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18894	  (const_int -1)
18895	  (const_int 0)))
18896   (clobber (reg:CC FLAGS_REG))]
18897  "TARGET_64BIT"
18898  "sbb{q}\t%0, %0"
18899  ; Since we don't have the proper number of operands for an alu insn,
18900  ; fill in all the blanks.
18901  [(set_attr "type" "alu")
18902   (set_attr "pent_pair" "pu")
18903   (set_attr "memory" "none")
18904   (set_attr "imm_disp" "false")
18905   (set_attr "mode" "DI")
18906   (set_attr "length_immediate" "0")])
18907
18908(define_insn "*movdicc_c_rex64"
18909  [(set (match_operand:DI 0 "register_operand" "=r,r")
18910	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
18911				[(reg FLAGS_REG) (const_int 0)])
18912		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18913		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18914  "TARGET_64BIT && TARGET_CMOVE
18915   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18916  "@
18917   cmov%O2%C1\t{%2, %0|%0, %2}
18918   cmov%O2%c1\t{%3, %0|%0, %3}"
18919  [(set_attr "type" "icmov")
18920   (set_attr "mode" "DI")])
18921
18922(define_expand "movsicc"
18923  [(set (match_operand:SI 0 "register_operand" "")
18924	(if_then_else:SI (match_operand 1 "comparison_operator" "")
18925			 (match_operand:SI 2 "general_operand" "")
18926			 (match_operand:SI 3 "general_operand" "")))]
18927  ""
18928  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18929
18930;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18931;; the register first winds up with `sbbl $0,reg', which is also weird.
18932;; So just document what we're doing explicitly.
18933
18934(define_insn "x86_movsicc_0_m1"
18935  [(set (match_operand:SI 0 "register_operand" "=r")
18936	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18937	  (const_int -1)
18938	  (const_int 0)))
18939   (clobber (reg:CC FLAGS_REG))]
18940  ""
18941  "sbb{l}\t%0, %0"
18942  ; Since we don't have the proper number of operands for an alu insn,
18943  ; fill in all the blanks.
18944  [(set_attr "type" "alu")
18945   (set_attr "pent_pair" "pu")
18946   (set_attr "memory" "none")
18947   (set_attr "imm_disp" "false")
18948   (set_attr "mode" "SI")
18949   (set_attr "length_immediate" "0")])
18950
18951(define_insn "*movsicc_noc"
18952  [(set (match_operand:SI 0 "register_operand" "=r,r")
18953	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
18954				[(reg FLAGS_REG) (const_int 0)])
18955		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18956		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18957  "TARGET_CMOVE
18958   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18959  "@
18960   cmov%O2%C1\t{%2, %0|%0, %2}
18961   cmov%O2%c1\t{%3, %0|%0, %3}"
18962  [(set_attr "type" "icmov")
18963   (set_attr "mode" "SI")])
18964
18965(define_expand "movhicc"
18966  [(set (match_operand:HI 0 "register_operand" "")
18967	(if_then_else:HI (match_operand 1 "comparison_operator" "")
18968			 (match_operand:HI 2 "general_operand" "")
18969			 (match_operand:HI 3 "general_operand" "")))]
18970  "TARGET_HIMODE_MATH"
18971  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18972
18973(define_insn "*movhicc_noc"
18974  [(set (match_operand:HI 0 "register_operand" "=r,r")
18975	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
18976				[(reg FLAGS_REG) (const_int 0)])
18977		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18978		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18979  "TARGET_CMOVE
18980   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18981  "@
18982   cmov%O2%C1\t{%2, %0|%0, %2}
18983   cmov%O2%c1\t{%3, %0|%0, %3}"
18984  [(set_attr "type" "icmov")
18985   (set_attr "mode" "HI")])
18986
18987(define_expand "movqicc"
18988  [(set (match_operand:QI 0 "register_operand" "")
18989	(if_then_else:QI (match_operand 1 "comparison_operator" "")
18990			 (match_operand:QI 2 "general_operand" "")
18991			 (match_operand:QI 3 "general_operand" "")))]
18992  "TARGET_QIMODE_MATH"
18993  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18994
18995(define_insn_and_split "*movqicc_noc"
18996  [(set (match_operand:QI 0 "register_operand" "=r,r")
18997	(if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
18998				[(match_operand 4 "flags_reg_operand" "")
18999				 (const_int 0)])
19000		      (match_operand:QI 2 "register_operand" "r,0")
19001		      (match_operand:QI 3 "register_operand" "0,r")))]
19002  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19003  "#"
19004  "&& reload_completed"
19005  [(set (match_dup 0)
19006	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19007		      (match_dup 2)
19008		      (match_dup 3)))]
19009  "operands[0] = gen_lowpart (SImode, operands[0]);
19010   operands[2] = gen_lowpart (SImode, operands[2]);
19011   operands[3] = gen_lowpart (SImode, operands[3]);"
19012  [(set_attr "type" "icmov")
19013   (set_attr "mode" "SI")])
19014
19015(define_expand "movsfcc"
19016  [(set (match_operand:SF 0 "register_operand" "")
19017	(if_then_else:SF (match_operand 1 "comparison_operator" "")
19018			 (match_operand:SF 2 "register_operand" "")
19019			 (match_operand:SF 3 "register_operand" "")))]
19020  "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19021  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19022
19023(define_insn "*movsfcc_1_387"
19024  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19025	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19026				[(reg FLAGS_REG) (const_int 0)])
19027		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19028		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19029  "TARGET_80387 && TARGET_CMOVE
19030   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19031  "@
19032   fcmov%F1\t{%2, %0|%0, %2}
19033   fcmov%f1\t{%3, %0|%0, %3}
19034   cmov%O2%C1\t{%2, %0|%0, %2}
19035   cmov%O2%c1\t{%3, %0|%0, %3}"
19036  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19037   (set_attr "mode" "SF,SF,SI,SI")])
19038
19039(define_expand "movdfcc"
19040  [(set (match_operand:DF 0 "register_operand" "")
19041	(if_then_else:DF (match_operand 1 "comparison_operator" "")
19042			 (match_operand:DF 2 "register_operand" "")
19043			 (match_operand:DF 3 "register_operand" "")))]
19044  "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19045  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19046
19047(define_insn "*movdfcc_1"
19048  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19049	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19050				[(reg FLAGS_REG) (const_int 0)])
19051		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19052		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19053  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19054   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19055  "@
19056   fcmov%F1\t{%2, %0|%0, %2}
19057   fcmov%f1\t{%3, %0|%0, %3}
19058   #
19059   #"
19060  [(set_attr "type" "fcmov,fcmov,multi,multi")
19061   (set_attr "mode" "DF")])
19062
19063(define_insn "*movdfcc_1_rex64"
19064  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19065	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19066				[(reg FLAGS_REG) (const_int 0)])
19067		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19068		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19069  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19070   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19071  "@
19072   fcmov%F1\t{%2, %0|%0, %2}
19073   fcmov%f1\t{%3, %0|%0, %3}
19074   cmov%O2%C1\t{%2, %0|%0, %2}
19075   cmov%O2%c1\t{%3, %0|%0, %3}"
19076  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19077   (set_attr "mode" "DF")])
19078
19079(define_split
19080  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19081	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19082				[(match_operand 4 "flags_reg_operand" "")
19083				 (const_int 0)])
19084		      (match_operand:DF 2 "nonimmediate_operand" "")
19085		      (match_operand:DF 3 "nonimmediate_operand" "")))]
19086  "!TARGET_64BIT && reload_completed"
19087  [(set (match_dup 2)
19088	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19089		      (match_dup 5)
19090		      (match_dup 7)))
19091   (set (match_dup 3)
19092	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19093		      (match_dup 6)
19094		      (match_dup 8)))]
19095  "split_di (operands+2, 1, operands+5, operands+6);
19096   split_di (operands+3, 1, operands+7, operands+8);
19097   split_di (operands, 1, operands+2, operands+3);")
19098
19099(define_expand "movxfcc"
19100  [(set (match_operand:XF 0 "register_operand" "")
19101	(if_then_else:XF (match_operand 1 "comparison_operator" "")
19102			 (match_operand:XF 2 "register_operand" "")
19103			 (match_operand:XF 3 "register_operand" "")))]
19104  "TARGET_80387 && TARGET_CMOVE"
19105  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19106
19107(define_insn "*movxfcc_1"
19108  [(set (match_operand:XF 0 "register_operand" "=f,f")
19109	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19110				[(reg FLAGS_REG) (const_int 0)])
19111		      (match_operand:XF 2 "register_operand" "f,0")
19112		      (match_operand:XF 3 "register_operand" "0,f")))]
19113  "TARGET_80387 && TARGET_CMOVE"
19114  "@
19115   fcmov%F1\t{%2, %0|%0, %2}
19116   fcmov%f1\t{%3, %0|%0, %3}"
19117  [(set_attr "type" "fcmov")
19118   (set_attr "mode" "XF")])
19119
19120;; These versions of the min/max patterns are intentionally ignorant of
19121;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19122;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19123;; are undefined in this condition, we're certain this is correct.
19124
19125(define_insn "sminsf3"
19126  [(set (match_operand:SF 0 "register_operand" "=x")
19127	(smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19128		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19129  "TARGET_SSE_MATH"
19130  "minss\t{%2, %0|%0, %2}"
19131  [(set_attr "type" "sseadd")
19132   (set_attr "mode" "SF")])
19133
19134(define_insn "smaxsf3"
19135  [(set (match_operand:SF 0 "register_operand" "=x")
19136	(smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19137		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19138  "TARGET_SSE_MATH"
19139  "maxss\t{%2, %0|%0, %2}"
19140  [(set_attr "type" "sseadd")
19141   (set_attr "mode" "SF")])
19142
19143(define_insn "smindf3"
19144  [(set (match_operand:DF 0 "register_operand" "=x")
19145	(smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19146		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19147  "TARGET_SSE2 && TARGET_SSE_MATH"
19148  "minsd\t{%2, %0|%0, %2}"
19149  [(set_attr "type" "sseadd")
19150   (set_attr "mode" "DF")])
19151
19152(define_insn "smaxdf3"
19153  [(set (match_operand:DF 0 "register_operand" "=x")
19154	(smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19155		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19156  "TARGET_SSE2 && TARGET_SSE_MATH"
19157  "maxsd\t{%2, %0|%0, %2}"
19158  [(set_attr "type" "sseadd")
19159   (set_attr "mode" "DF")])
19160
19161;; These versions of the min/max patterns implement exactly the operations
19162;;   min = (op1 < op2 ? op1 : op2)
19163;;   max = (!(op1 < op2) ? op1 : op2)
19164;; Their operands are not commutative, and thus they may be used in the
19165;; presence of -0.0 and NaN.
19166
19167(define_insn "*ieee_sminsf3"
19168  [(set (match_operand:SF 0 "register_operand" "=x")
19169	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19170		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19171		   UNSPEC_IEEE_MIN))]
19172  "TARGET_SSE_MATH"
19173  "minss\t{%2, %0|%0, %2}"
19174  [(set_attr "type" "sseadd")
19175   (set_attr "mode" "SF")])
19176
19177(define_insn "*ieee_smaxsf3"
19178  [(set (match_operand:SF 0 "register_operand" "=x")
19179	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19180		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19181		   UNSPEC_IEEE_MAX))]
19182  "TARGET_SSE_MATH"
19183  "maxss\t{%2, %0|%0, %2}"
19184  [(set_attr "type" "sseadd")
19185   (set_attr "mode" "SF")])
19186
19187(define_insn "*ieee_smindf3"
19188  [(set (match_operand:DF 0 "register_operand" "=x")
19189	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19190		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19191		   UNSPEC_IEEE_MIN))]
19192  "TARGET_SSE2 && TARGET_SSE_MATH"
19193  "minsd\t{%2, %0|%0, %2}"
19194  [(set_attr "type" "sseadd")
19195   (set_attr "mode" "DF")])
19196
19197(define_insn "*ieee_smaxdf3"
19198  [(set (match_operand:DF 0 "register_operand" "=x")
19199	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19200		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19201		   UNSPEC_IEEE_MAX))]
19202  "TARGET_SSE2 && TARGET_SSE_MATH"
19203  "maxsd\t{%2, %0|%0, %2}"
19204  [(set_attr "type" "sseadd")
19205   (set_attr "mode" "DF")])
19206
19207;; Make two stack loads independent:
19208;;   fld aa              fld aa
19209;;   fld %st(0)     ->   fld bb
19210;;   fmul bb             fmul %st(1), %st
19211;;
19212;; Actually we only match the last two instructions for simplicity.
19213(define_peephole2
19214  [(set (match_operand 0 "fp_register_operand" "")
19215	(match_operand 1 "fp_register_operand" ""))
19216   (set (match_dup 0)
19217	(match_operator 2 "binary_fp_operator"
19218	   [(match_dup 0)
19219	    (match_operand 3 "memory_operand" "")]))]
19220  "REGNO (operands[0]) != REGNO (operands[1])"
19221  [(set (match_dup 0) (match_dup 3))
19222   (set (match_dup 0) (match_dup 4))]
19223
19224  ;; The % modifier is not operational anymore in peephole2's, so we have to
19225  ;; swap the operands manually in the case of addition and multiplication.
19226  "if (COMMUTATIVE_ARITH_P (operands[2]))
19227     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19228				 operands[0], operands[1]);
19229   else
19230     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19231				 operands[1], operands[0]);")
19232
19233;; Conditional addition patterns
19234(define_expand "addqicc"
19235  [(match_operand:QI 0 "register_operand" "")
19236   (match_operand 1 "comparison_operator" "")
19237   (match_operand:QI 2 "register_operand" "")
19238   (match_operand:QI 3 "const_int_operand" "")]
19239  ""
19240  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19241
19242(define_expand "addhicc"
19243  [(match_operand:HI 0 "register_operand" "")
19244   (match_operand 1 "comparison_operator" "")
19245   (match_operand:HI 2 "register_operand" "")
19246   (match_operand:HI 3 "const_int_operand" "")]
19247  ""
19248  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19249
19250(define_expand "addsicc"
19251  [(match_operand:SI 0 "register_operand" "")
19252   (match_operand 1 "comparison_operator" "")
19253   (match_operand:SI 2 "register_operand" "")
19254   (match_operand:SI 3 "const_int_operand" "")]
19255  ""
19256  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19257
19258(define_expand "adddicc"
19259  [(match_operand:DI 0 "register_operand" "")
19260   (match_operand 1 "comparison_operator" "")
19261   (match_operand:DI 2 "register_operand" "")
19262   (match_operand:DI 3 "const_int_operand" "")]
19263  "TARGET_64BIT"
19264  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19265
19266
19267;; Misc patterns (?)
19268
19269;; This pattern exists to put a dependency on all ebp-based memory accesses.
19270;; Otherwise there will be nothing to keep
19271;; 
19272;; [(set (reg ebp) (reg esp))]
19273;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19274;;  (clobber (eflags)]
19275;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19276;;
19277;; in proper program order.
19278(define_insn "pro_epilogue_adjust_stack_1"
19279  [(set (match_operand:SI 0 "register_operand" "=r,r")
19280	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
19281	         (match_operand:SI 2 "immediate_operand" "i,i")))
19282   (clobber (reg:CC FLAGS_REG))
19283   (clobber (mem:BLK (scratch)))]
19284  "!TARGET_64BIT"
19285{
19286  switch (get_attr_type (insn))
19287    {
19288    case TYPE_IMOV:
19289      return "mov{l}\t{%1, %0|%0, %1}";
19290
19291    case TYPE_ALU:
19292      if (GET_CODE (operands[2]) == CONST_INT
19293          && (INTVAL (operands[2]) == 128
19294	      || (INTVAL (operands[2]) < 0
19295	          && INTVAL (operands[2]) != -128)))
19296	{
19297	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19298	  return "sub{l}\t{%2, %0|%0, %2}";
19299	}
19300      return "add{l}\t{%2, %0|%0, %2}";
19301
19302    case TYPE_LEA:
19303      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19304      return "lea{l}\t{%a2, %0|%0, %a2}";
19305
19306    default:
19307      gcc_unreachable ();
19308    }
19309}
19310  [(set (attr "type")
19311	(cond [(eq_attr "alternative" "0")
19312		 (const_string "alu")
19313	       (match_operand:SI 2 "const0_operand" "")
19314		 (const_string "imov")
19315	      ]
19316	      (const_string "lea")))
19317   (set_attr "mode" "SI")])
19318
19319(define_insn "pro_epilogue_adjust_stack_rex64"
19320  [(set (match_operand:DI 0 "register_operand" "=r,r")
19321	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19322		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19323   (clobber (reg:CC FLAGS_REG))
19324   (clobber (mem:BLK (scratch)))]
19325  "TARGET_64BIT"
19326{
19327  switch (get_attr_type (insn))
19328    {
19329    case TYPE_IMOV:
19330      return "mov{q}\t{%1, %0|%0, %1}";
19331
19332    case TYPE_ALU:
19333      if (GET_CODE (operands[2]) == CONST_INT
19334	  /* Avoid overflows.  */
19335	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19336          && (INTVAL (operands[2]) == 128
19337	      || (INTVAL (operands[2]) < 0
19338	          && INTVAL (operands[2]) != -128)))
19339	{
19340	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19341	  return "sub{q}\t{%2, %0|%0, %2}";
19342	}
19343      return "add{q}\t{%2, %0|%0, %2}";
19344
19345    case TYPE_LEA:
19346      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19347      return "lea{q}\t{%a2, %0|%0, %a2}";
19348
19349    default:
19350      gcc_unreachable ();
19351    }
19352}
19353  [(set (attr "type")
19354	(cond [(eq_attr "alternative" "0")
19355		 (const_string "alu")
19356	       (match_operand:DI 2 "const0_operand" "")
19357		 (const_string "imov")
19358	      ]
19359	      (const_string "lea")))
19360   (set_attr "mode" "DI")])
19361
19362(define_insn "pro_epilogue_adjust_stack_rex64_2"
19363  [(set (match_operand:DI 0 "register_operand" "=r,r")
19364	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19365		 (match_operand:DI 3 "immediate_operand" "i,i")))
19366   (use (match_operand:DI 2 "register_operand" "r,r"))
19367   (clobber (reg:CC FLAGS_REG))
19368   (clobber (mem:BLK (scratch)))]
19369  "TARGET_64BIT"
19370{
19371  switch (get_attr_type (insn))
19372    {
19373    case TYPE_ALU:
19374      return "add{q}\t{%2, %0|%0, %2}";
19375
19376    case TYPE_LEA:
19377      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19378      return "lea{q}\t{%a2, %0|%0, %a2}";
19379
19380    default:
19381      gcc_unreachable ();
19382    }
19383}
19384  [(set_attr "type" "alu,lea")
19385   (set_attr "mode" "DI")])
19386
19387(define_expand "allocate_stack_worker"
19388  [(match_operand:SI 0 "register_operand" "")]
19389  "TARGET_STACK_PROBE"
19390{
19391  if (reload_completed)
19392    {
19393      if (TARGET_64BIT)
19394	emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19395      else
19396	emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19397    }
19398  else
19399    {
19400      if (TARGET_64BIT)
19401	emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19402      else
19403	emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19404    }
19405  DONE;
19406})
19407
19408(define_insn "allocate_stack_worker_1"
19409  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19410    UNSPECV_STACK_PROBE)
19411   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19412   (clobber (match_scratch:SI 1 "=0"))
19413   (clobber (reg:CC FLAGS_REG))]
19414  "!TARGET_64BIT && TARGET_STACK_PROBE"
19415  "call\t__alloca"
19416  [(set_attr "type" "multi")
19417   (set_attr "length" "5")])
19418
19419(define_expand "allocate_stack_worker_postreload"
19420  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19421				    UNSPECV_STACK_PROBE)
19422	      (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19423	      (clobber (match_dup 0))
19424	      (clobber (reg:CC FLAGS_REG))])]
19425  ""
19426  "")
19427
19428(define_insn "allocate_stack_worker_rex64"
19429  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19430    UNSPECV_STACK_PROBE)
19431   (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19432   (clobber (match_scratch:DI 1 "=0"))
19433   (clobber (reg:CC FLAGS_REG))]
19434  "TARGET_64BIT && TARGET_STACK_PROBE"
19435  "call\t__alloca"
19436  [(set_attr "type" "multi")
19437   (set_attr "length" "5")])
19438
19439(define_expand "allocate_stack_worker_rex64_postreload"
19440  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19441				    UNSPECV_STACK_PROBE)
19442	      (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19443	      (clobber (match_dup 0))
19444	      (clobber (reg:CC FLAGS_REG))])]
19445  ""
19446  "")
19447
19448(define_expand "allocate_stack"
19449  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19450		   (minus:SI (reg:SI SP_REG)
19451			     (match_operand:SI 1 "general_operand" "")))
19452	      (clobber (reg:CC FLAGS_REG))])
19453   (parallel [(set (reg:SI SP_REG)
19454		   (minus:SI (reg:SI SP_REG) (match_dup 1)))
19455	      (clobber (reg:CC FLAGS_REG))])]
19456  "TARGET_STACK_PROBE"
19457{
19458#ifdef CHECK_STACK_LIMIT
19459  if (GET_CODE (operands[1]) == CONST_INT
19460      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19461    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19462			   operands[1]));
19463  else 
19464#endif
19465    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19466							    operands[1])));
19467
19468  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19469  DONE;
19470})
19471
19472(define_expand "builtin_setjmp_receiver"
19473  [(label_ref (match_operand 0 "" ""))]
19474  "!TARGET_64BIT && flag_pic"
19475{
19476  if (TARGET_MACHO)
19477    {
19478      rtx xops[3];
19479      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19480      rtx label_rtx = gen_label_rtx ();
19481      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19482      xops[0] = xops[1] = picreg;
19483      xops[2] = gen_rtx_CONST (SImode,
19484	          gen_rtx_MINUS (SImode,
19485		    gen_rtx_LABEL_REF (SImode, label_rtx),
19486		    gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19487      ix86_expand_binary_operator (MINUS, SImode, xops);
19488    }
19489  else
19490    emit_insn (gen_set_got (pic_offset_table_rtx));
19491  DONE;
19492})
19493
19494;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19495
19496(define_split
19497  [(set (match_operand 0 "register_operand" "")
19498	(match_operator 3 "promotable_binary_operator"
19499	   [(match_operand 1 "register_operand" "")
19500	    (match_operand 2 "aligned_operand" "")]))
19501   (clobber (reg:CC FLAGS_REG))]
19502  "! TARGET_PARTIAL_REG_STALL && reload_completed
19503   && ((GET_MODE (operands[0]) == HImode 
19504	&& ((!optimize_size && !TARGET_FAST_PREFIX)
19505            /* ??? next two lines just !satisfies_constraint_K (...) */
19506	    || GET_CODE (operands[2]) != CONST_INT
19507	    || satisfies_constraint_K (operands[2])))
19508       || (GET_MODE (operands[0]) == QImode 
19509	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19510  [(parallel [(set (match_dup 0)
19511		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19512	      (clobber (reg:CC FLAGS_REG))])]
19513  "operands[0] = gen_lowpart (SImode, operands[0]);
19514   operands[1] = gen_lowpart (SImode, operands[1]);
19515   if (GET_CODE (operands[3]) != ASHIFT)
19516     operands[2] = gen_lowpart (SImode, operands[2]);
19517   PUT_MODE (operands[3], SImode);")
19518
19519; Promote the QImode tests, as i386 has encoding of the AND
19520; instruction with 32-bit sign-extended immediate and thus the
19521; instruction size is unchanged, except in the %eax case for
19522; which it is increased by one byte, hence the ! optimize_size.
19523(define_split
19524  [(set (match_operand 0 "flags_reg_operand" "")
19525	(match_operator 2 "compare_operator"
19526	  [(and (match_operand 3 "aligned_operand" "")
19527		(match_operand 4 "const_int_operand" ""))
19528	   (const_int 0)]))
19529   (set (match_operand 1 "register_operand" "")
19530	(and (match_dup 3) (match_dup 4)))]
19531  "! TARGET_PARTIAL_REG_STALL && reload_completed
19532   /* Ensure that the operand will remain sign-extended immediate.  */
19533   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19534   && ! optimize_size
19535   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19536       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19537  [(parallel [(set (match_dup 0)
19538		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19539			            (const_int 0)]))
19540	      (set (match_dup 1)
19541		   (and:SI (match_dup 3) (match_dup 4)))])]
19542{
19543  operands[4]
19544    = gen_int_mode (INTVAL (operands[4])
19545		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19546  operands[1] = gen_lowpart (SImode, operands[1]);
19547  operands[3] = gen_lowpart (SImode, operands[3]);
19548})
19549
19550; Don't promote the QImode tests, as i386 doesn't have encoding of
19551; the TEST instruction with 32-bit sign-extended immediate and thus
19552; the instruction size would at least double, which is not what we
19553; want even with ! optimize_size.
19554(define_split
19555  [(set (match_operand 0 "flags_reg_operand" "")
19556	(match_operator 1 "compare_operator"
19557	  [(and (match_operand:HI 2 "aligned_operand" "")
19558		(match_operand:HI 3 "const_int_operand" ""))
19559	   (const_int 0)]))]
19560  "! TARGET_PARTIAL_REG_STALL && reload_completed
19561   /* Ensure that the operand will remain sign-extended immediate.  */
19562   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19563   && ! TARGET_FAST_PREFIX
19564   && ! optimize_size"
19565  [(set (match_dup 0)
19566	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19567		         (const_int 0)]))]
19568{
19569  operands[3]
19570    = gen_int_mode (INTVAL (operands[3])
19571		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19572  operands[2] = gen_lowpart (SImode, operands[2]);
19573})
19574
19575(define_split
19576  [(set (match_operand 0 "register_operand" "")
19577	(neg (match_operand 1 "register_operand" "")))
19578   (clobber (reg:CC FLAGS_REG))]
19579  "! TARGET_PARTIAL_REG_STALL && reload_completed
19580   && (GET_MODE (operands[0]) == HImode
19581       || (GET_MODE (operands[0]) == QImode 
19582	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19583  [(parallel [(set (match_dup 0)
19584		   (neg:SI (match_dup 1)))
19585	      (clobber (reg:CC FLAGS_REG))])]
19586  "operands[0] = gen_lowpart (SImode, operands[0]);
19587   operands[1] = gen_lowpart (SImode, operands[1]);")
19588
19589(define_split
19590  [(set (match_operand 0 "register_operand" "")
19591	(not (match_operand 1 "register_operand" "")))]
19592  "! TARGET_PARTIAL_REG_STALL && reload_completed
19593   && (GET_MODE (operands[0]) == HImode
19594       || (GET_MODE (operands[0]) == QImode 
19595	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19596  [(set (match_dup 0)
19597	(not:SI (match_dup 1)))]
19598  "operands[0] = gen_lowpart (SImode, operands[0]);
19599   operands[1] = gen_lowpart (SImode, operands[1]);")
19600
19601(define_split 
19602  [(set (match_operand 0 "register_operand" "")
19603	(if_then_else (match_operator 1 "comparison_operator" 
19604				[(reg FLAGS_REG) (const_int 0)])
19605		      (match_operand 2 "register_operand" "")
19606		      (match_operand 3 "register_operand" "")))]
19607  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19608   && (GET_MODE (operands[0]) == HImode
19609       || (GET_MODE (operands[0]) == QImode 
19610	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19611  [(set (match_dup 0)
19612	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19613  "operands[0] = gen_lowpart (SImode, operands[0]);
19614   operands[2] = gen_lowpart (SImode, operands[2]);
19615   operands[3] = gen_lowpart (SImode, operands[3]);")
19616			
19617
19618;; RTL Peephole optimizations, run before sched2.  These primarily look to
19619;; transform a complex memory operation into two memory to register operations.
19620
19621;; Don't push memory operands
19622(define_peephole2
19623  [(set (match_operand:SI 0 "push_operand" "")
19624	(match_operand:SI 1 "memory_operand" ""))
19625   (match_scratch:SI 2 "r")]
19626  "!optimize_size && !TARGET_PUSH_MEMORY
19627   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19628  [(set (match_dup 2) (match_dup 1))
19629   (set (match_dup 0) (match_dup 2))]
19630  "")
19631
19632(define_peephole2
19633  [(set (match_operand:DI 0 "push_operand" "")
19634	(match_operand:DI 1 "memory_operand" ""))
19635   (match_scratch:DI 2 "r")]
19636  "!optimize_size && !TARGET_PUSH_MEMORY
19637   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19638  [(set (match_dup 2) (match_dup 1))
19639   (set (match_dup 0) (match_dup 2))]
19640  "")
19641
19642;; We need to handle SFmode only, because DFmode and XFmode is split to
19643;; SImode pushes.
19644(define_peephole2
19645  [(set (match_operand:SF 0 "push_operand" "")
19646	(match_operand:SF 1 "memory_operand" ""))
19647   (match_scratch:SF 2 "r")]
19648  "!optimize_size && !TARGET_PUSH_MEMORY
19649   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19650  [(set (match_dup 2) (match_dup 1))
19651   (set (match_dup 0) (match_dup 2))]
19652  "")
19653
19654(define_peephole2
19655  [(set (match_operand:HI 0 "push_operand" "")
19656	(match_operand:HI 1 "memory_operand" ""))
19657   (match_scratch:HI 2 "r")]
19658  "!optimize_size && !TARGET_PUSH_MEMORY
19659   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19660  [(set (match_dup 2) (match_dup 1))
19661   (set (match_dup 0) (match_dup 2))]
19662  "")
19663
19664(define_peephole2
19665  [(set (match_operand:QI 0 "push_operand" "")
19666	(match_operand:QI 1 "memory_operand" ""))
19667   (match_scratch:QI 2 "q")]
19668  "!optimize_size && !TARGET_PUSH_MEMORY
19669   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19670  [(set (match_dup 2) (match_dup 1))
19671   (set (match_dup 0) (match_dup 2))]
19672  "")
19673
19674;; Don't move an immediate directly to memory when the instruction
19675;; gets too big.
19676(define_peephole2
19677  [(match_scratch:SI 1 "r")
19678   (set (match_operand:SI 0 "memory_operand" "")
19679        (const_int 0))]
19680  "! optimize_size
19681   && ! TARGET_USE_MOV0
19682   && TARGET_SPLIT_LONG_MOVES
19683   && get_attr_length (insn) >= ix86_cost->large_insn
19684   && peep2_regno_dead_p (0, FLAGS_REG)"
19685  [(parallel [(set (match_dup 1) (const_int 0))
19686	      (clobber (reg:CC FLAGS_REG))])
19687   (set (match_dup 0) (match_dup 1))]
19688  "")
19689
19690(define_peephole2
19691  [(match_scratch:HI 1 "r")
19692   (set (match_operand:HI 0 "memory_operand" "")
19693        (const_int 0))]
19694  "! optimize_size
19695   && ! TARGET_USE_MOV0
19696   && TARGET_SPLIT_LONG_MOVES
19697   && get_attr_length (insn) >= ix86_cost->large_insn
19698   && peep2_regno_dead_p (0, FLAGS_REG)"
19699  [(parallel [(set (match_dup 2) (const_int 0))
19700	      (clobber (reg:CC FLAGS_REG))])
19701   (set (match_dup 0) (match_dup 1))]
19702  "operands[2] = gen_lowpart (SImode, operands[1]);")
19703
19704(define_peephole2
19705  [(match_scratch:QI 1 "q")
19706   (set (match_operand:QI 0 "memory_operand" "")
19707        (const_int 0))]
19708  "! optimize_size
19709   && ! TARGET_USE_MOV0
19710   && TARGET_SPLIT_LONG_MOVES
19711   && get_attr_length (insn) >= ix86_cost->large_insn
19712   && peep2_regno_dead_p (0, FLAGS_REG)"
19713  [(parallel [(set (match_dup 2) (const_int 0))
19714	      (clobber (reg:CC FLAGS_REG))])
19715   (set (match_dup 0) (match_dup 1))]
19716  "operands[2] = gen_lowpart (SImode, operands[1]);")
19717
19718(define_peephole2
19719  [(match_scratch:SI 2 "r")
19720   (set (match_operand:SI 0 "memory_operand" "")
19721        (match_operand:SI 1 "immediate_operand" ""))]
19722  "! optimize_size
19723   && get_attr_length (insn) >= ix86_cost->large_insn
19724   && TARGET_SPLIT_LONG_MOVES"
19725  [(set (match_dup 2) (match_dup 1))
19726   (set (match_dup 0) (match_dup 2))]
19727  "")
19728
19729(define_peephole2
19730  [(match_scratch:HI 2 "r")
19731   (set (match_operand:HI 0 "memory_operand" "")
19732        (match_operand:HI 1 "immediate_operand" ""))]
19733  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19734  && TARGET_SPLIT_LONG_MOVES"
19735  [(set (match_dup 2) (match_dup 1))
19736   (set (match_dup 0) (match_dup 2))]
19737  "")
19738
19739(define_peephole2
19740  [(match_scratch:QI 2 "q")
19741   (set (match_operand:QI 0 "memory_operand" "")
19742        (match_operand:QI 1 "immediate_operand" ""))]
19743  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19744  && TARGET_SPLIT_LONG_MOVES"
19745  [(set (match_dup 2) (match_dup 1))
19746   (set (match_dup 0) (match_dup 2))]
19747  "")
19748
19749;; Don't compare memory with zero, load and use a test instead.
19750(define_peephole2
19751  [(set (match_operand 0 "flags_reg_operand" "")
19752 	(match_operator 1 "compare_operator"
19753	  [(match_operand:SI 2 "memory_operand" "")
19754	   (const_int 0)]))
19755   (match_scratch:SI 3 "r")]
19756  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19757  [(set (match_dup 3) (match_dup 2))
19758   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19759  "")
19760
19761;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
19762;; Don't split NOTs with a displacement operand, because resulting XOR
19763;; will not be pairable anyway.
19764;;
19765;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19766;; represented using a modRM byte.  The XOR replacement is long decoded,
19767;; so this split helps here as well.
19768;;
19769;; Note: Can't do this as a regular split because we can't get proper
19770;; lifetime information then.
19771
19772(define_peephole2
19773  [(set (match_operand:SI 0 "nonimmediate_operand" "")
19774	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19775  "!optimize_size
19776   && peep2_regno_dead_p (0, FLAGS_REG)
19777   && ((TARGET_PENTIUM 
19778        && (GET_CODE (operands[0]) != MEM
19779            || !memory_displacement_operand (operands[0], SImode)))
19780       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19781  [(parallel [(set (match_dup 0)
19782		   (xor:SI (match_dup 1) (const_int -1)))
19783	      (clobber (reg:CC FLAGS_REG))])]
19784  "")
19785
19786(define_peephole2
19787  [(set (match_operand:HI 0 "nonimmediate_operand" "")
19788	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19789  "!optimize_size
19790   && peep2_regno_dead_p (0, FLAGS_REG)
19791   && ((TARGET_PENTIUM 
19792        && (GET_CODE (operands[0]) != MEM
19793            || !memory_displacement_operand (operands[0], HImode)))
19794       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19795  [(parallel [(set (match_dup 0)
19796		   (xor:HI (match_dup 1) (const_int -1)))
19797	      (clobber (reg:CC FLAGS_REG))])]
19798  "")
19799
19800(define_peephole2
19801  [(set (match_operand:QI 0 "nonimmediate_operand" "")
19802	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19803  "!optimize_size
19804   && peep2_regno_dead_p (0, FLAGS_REG)
19805   && ((TARGET_PENTIUM 
19806        && (GET_CODE (operands[0]) != MEM
19807            || !memory_displacement_operand (operands[0], QImode)))
19808       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19809  [(parallel [(set (match_dup 0)
19810		   (xor:QI (match_dup 1) (const_int -1)))
19811	      (clobber (reg:CC FLAGS_REG))])]
19812  "")
19813
19814;; Non pairable "test imm, reg" instructions can be translated to
19815;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19816;; byte opcode instead of two, have a short form for byte operands),
19817;; so do it for other CPUs as well.  Given that the value was dead,
19818;; this should not create any new dependencies.  Pass on the sub-word
19819;; versions if we're concerned about partial register stalls.
19820
19821(define_peephole2
19822  [(set (match_operand 0 "flags_reg_operand" "")
19823	(match_operator 1 "compare_operator"
19824	  [(and:SI (match_operand:SI 2 "register_operand" "")
19825		   (match_operand:SI 3 "immediate_operand" ""))
19826	   (const_int 0)]))]
19827  "ix86_match_ccmode (insn, CCNOmode)
19828   && (true_regnum (operands[2]) != 0
19829       || satisfies_constraint_K (operands[3]))
19830   && peep2_reg_dead_p (1, operands[2])"
19831  [(parallel
19832     [(set (match_dup 0)
19833	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19834		            (const_int 0)]))
19835      (set (match_dup 2)
19836	   (and:SI (match_dup 2) (match_dup 3)))])]
19837  "")
19838
19839;; We don't need to handle HImode case, because it will be promoted to SImode
19840;; on ! TARGET_PARTIAL_REG_STALL
19841
19842(define_peephole2
19843  [(set (match_operand 0 "flags_reg_operand" "")
19844	(match_operator 1 "compare_operator"
19845	  [(and:QI (match_operand:QI 2 "register_operand" "")
19846		   (match_operand:QI 3 "immediate_operand" ""))
19847	   (const_int 0)]))]
19848  "! TARGET_PARTIAL_REG_STALL
19849   && ix86_match_ccmode (insn, CCNOmode)
19850   && true_regnum (operands[2]) != 0
19851   && peep2_reg_dead_p (1, operands[2])"
19852  [(parallel
19853     [(set (match_dup 0)
19854	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19855		            (const_int 0)]))
19856      (set (match_dup 2)
19857	   (and:QI (match_dup 2) (match_dup 3)))])]
19858  "")
19859
19860(define_peephole2
19861  [(set (match_operand 0 "flags_reg_operand" "")
19862	(match_operator 1 "compare_operator"
19863	  [(and:SI
19864	     (zero_extract:SI
19865	       (match_operand 2 "ext_register_operand" "")
19866	       (const_int 8)
19867	       (const_int 8))
19868	     (match_operand 3 "const_int_operand" ""))
19869	   (const_int 0)]))]
19870  "! TARGET_PARTIAL_REG_STALL
19871   && ix86_match_ccmode (insn, CCNOmode)
19872   && true_regnum (operands[2]) != 0
19873   && peep2_reg_dead_p (1, operands[2])"
19874  [(parallel [(set (match_dup 0)
19875		   (match_op_dup 1
19876		     [(and:SI
19877			(zero_extract:SI
19878			  (match_dup 2)
19879			  (const_int 8)
19880			  (const_int 8))
19881			(match_dup 3))
19882		      (const_int 0)]))
19883	      (set (zero_extract:SI (match_dup 2)
19884				    (const_int 8)
19885				    (const_int 8))
19886		   (and:SI 
19887		     (zero_extract:SI
19888		       (match_dup 2)
19889		       (const_int 8)
19890		       (const_int 8))
19891		     (match_dup 3)))])]
19892  "")
19893
19894;; Don't do logical operations with memory inputs.
19895(define_peephole2
19896  [(match_scratch:SI 2 "r")
19897   (parallel [(set (match_operand:SI 0 "register_operand" "")
19898                   (match_operator:SI 3 "arith_or_logical_operator"
19899                     [(match_dup 0)
19900                      (match_operand:SI 1 "memory_operand" "")]))
19901              (clobber (reg:CC FLAGS_REG))])]
19902  "! optimize_size && ! TARGET_READ_MODIFY"
19903  [(set (match_dup 2) (match_dup 1))
19904   (parallel [(set (match_dup 0)
19905                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19906              (clobber (reg:CC FLAGS_REG))])]
19907  "")
19908
19909(define_peephole2
19910  [(match_scratch:SI 2 "r")
19911   (parallel [(set (match_operand:SI 0 "register_operand" "")
19912                   (match_operator:SI 3 "arith_or_logical_operator"
19913                     [(match_operand:SI 1 "memory_operand" "")
19914                      (match_dup 0)]))
19915              (clobber (reg:CC FLAGS_REG))])]
19916  "! optimize_size && ! TARGET_READ_MODIFY"
19917  [(set (match_dup 2) (match_dup 1))
19918   (parallel [(set (match_dup 0)
19919                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19920              (clobber (reg:CC FLAGS_REG))])]
19921  "")
19922
19923; Don't do logical operations with memory outputs
19924;
19925; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19926; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19927; the same decoder scheduling characteristics as the original.
19928
19929(define_peephole2
19930  [(match_scratch:SI 2 "r")
19931   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19932                   (match_operator:SI 3 "arith_or_logical_operator"
19933                     [(match_dup 0)
19934                      (match_operand:SI 1 "nonmemory_operand" "")]))
19935              (clobber (reg:CC FLAGS_REG))])]
19936  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19937  [(set (match_dup 2) (match_dup 0))
19938   (parallel [(set (match_dup 2)
19939                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19940              (clobber (reg:CC FLAGS_REG))])
19941   (set (match_dup 0) (match_dup 2))]
19942  "")
19943
19944(define_peephole2
19945  [(match_scratch:SI 2 "r")
19946   (parallel [(set (match_operand:SI 0 "memory_operand" "")
19947                   (match_operator:SI 3 "arith_or_logical_operator"
19948                     [(match_operand:SI 1 "nonmemory_operand" "")
19949                      (match_dup 0)]))
19950              (clobber (reg:CC FLAGS_REG))])]
19951  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19952  [(set (match_dup 2) (match_dup 0))
19953   (parallel [(set (match_dup 2)
19954                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19955              (clobber (reg:CC FLAGS_REG))])
19956   (set (match_dup 0) (match_dup 2))]
19957  "")
19958
19959;; Attempt to always use XOR for zeroing registers.
19960(define_peephole2
19961  [(set (match_operand 0 "register_operand" "")
19962	(match_operand 1 "const0_operand" ""))]
19963  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19964   && (! TARGET_USE_MOV0 || optimize_size)
19965   && GENERAL_REG_P (operands[0])
19966   && peep2_regno_dead_p (0, FLAGS_REG)"
19967  [(parallel [(set (match_dup 0) (const_int 0))
19968	      (clobber (reg:CC FLAGS_REG))])]
19969{
19970  operands[0] = gen_lowpart (word_mode, operands[0]);
19971})
19972
19973(define_peephole2
19974  [(set (strict_low_part (match_operand 0 "register_operand" ""))
19975	(const_int 0))]
19976  "(GET_MODE (operands[0]) == QImode
19977    || GET_MODE (operands[0]) == HImode)
19978   && (! TARGET_USE_MOV0 || optimize_size)
19979   && peep2_regno_dead_p (0, FLAGS_REG)"
19980  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19981	      (clobber (reg:CC FLAGS_REG))])])
19982
19983;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19984(define_peephole2
19985  [(set (match_operand 0 "register_operand" "")
19986	(const_int -1))]
19987  "(GET_MODE (operands[0]) == HImode
19988    || GET_MODE (operands[0]) == SImode 
19989    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19990   && (optimize_size || TARGET_PENTIUM)
19991   && peep2_regno_dead_p (0, FLAGS_REG)"
19992  [(parallel [(set (match_dup 0) (const_int -1))
19993	      (clobber (reg:CC FLAGS_REG))])]
19994  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19995			      operands[0]);")
19996
19997;; Attempt to convert simple leas to adds. These can be created by
19998;; move expanders.
19999(define_peephole2
20000  [(set (match_operand:SI 0 "register_operand" "")
20001  	(plus:SI (match_dup 0)
20002		 (match_operand:SI 1 "nonmemory_operand" "")))]
20003  "peep2_regno_dead_p (0, FLAGS_REG)"
20004  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20005	      (clobber (reg:CC FLAGS_REG))])]
20006  "")
20007
20008(define_peephole2
20009  [(set (match_operand:SI 0 "register_operand" "")
20010  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20011			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20012  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20013  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20014	      (clobber (reg:CC FLAGS_REG))])]
20015  "operands[2] = gen_lowpart (SImode, operands[2]);")
20016
20017(define_peephole2
20018  [(set (match_operand:DI 0 "register_operand" "")
20019  	(plus:DI (match_dup 0)
20020		 (match_operand:DI 1 "x86_64_general_operand" "")))]
20021  "peep2_regno_dead_p (0, FLAGS_REG)"
20022  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20023	      (clobber (reg:CC FLAGS_REG))])]
20024  "")
20025
20026(define_peephole2
20027  [(set (match_operand:SI 0 "register_operand" "")
20028  	(mult:SI (match_dup 0)
20029		 (match_operand:SI 1 "const_int_operand" "")))]
20030  "exact_log2 (INTVAL (operands[1])) >= 0
20031   && peep2_regno_dead_p (0, FLAGS_REG)"
20032  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20033	      (clobber (reg:CC FLAGS_REG))])]
20034  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20035
20036(define_peephole2
20037  [(set (match_operand:DI 0 "register_operand" "")
20038  	(mult:DI (match_dup 0)
20039		 (match_operand:DI 1 "const_int_operand" "")))]
20040  "exact_log2 (INTVAL (operands[1])) >= 0
20041   && peep2_regno_dead_p (0, FLAGS_REG)"
20042  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20043	      (clobber (reg:CC FLAGS_REG))])]
20044  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20045
20046(define_peephole2
20047  [(set (match_operand:SI 0 "register_operand" "")
20048  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20049		   (match_operand:DI 2 "const_int_operand" "")) 0))]
20050  "exact_log2 (INTVAL (operands[2])) >= 0
20051   && REGNO (operands[0]) == REGNO (operands[1])
20052   && peep2_regno_dead_p (0, FLAGS_REG)"
20053  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20054	      (clobber (reg:CC FLAGS_REG))])]
20055  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20056
20057;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20058;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20059;; many CPUs it is also faster, since special hardware to avoid esp
20060;; dependencies is present.
20061
20062;; While some of these conversions may be done using splitters, we use peepholes
20063;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20064
20065;; Convert prologue esp subtractions to push.
20066;; We need register to push.  In order to keep verify_flow_info happy we have
20067;; two choices
20068;; - use scratch and clobber it in order to avoid dependencies
20069;; - use already live register
20070;; We can't use the second way right now, since there is no reliable way how to
20071;; verify that given register is live.  First choice will also most likely in
20072;; fewer dependencies.  On the place of esp adjustments it is very likely that
20073;; call clobbered registers are dead.  We may want to use base pointer as an
20074;; alternative when no register is available later.
20075
20076(define_peephole2
20077  [(match_scratch:SI 0 "r")
20078   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20079	      (clobber (reg:CC FLAGS_REG))
20080	      (clobber (mem:BLK (scratch)))])]
20081  "optimize_size || !TARGET_SUB_ESP_4"
20082  [(clobber (match_dup 0))
20083   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20084	      (clobber (mem:BLK (scratch)))])])
20085
20086(define_peephole2
20087  [(match_scratch:SI 0 "r")
20088   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20089	      (clobber (reg:CC FLAGS_REG))
20090	      (clobber (mem:BLK (scratch)))])]
20091  "optimize_size || !TARGET_SUB_ESP_8"
20092  [(clobber (match_dup 0))
20093   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20094   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20095	      (clobber (mem:BLK (scratch)))])])
20096
20097;; Convert esp subtractions to push.
20098(define_peephole2
20099  [(match_scratch:SI 0 "r")
20100   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20101	      (clobber (reg:CC FLAGS_REG))])]
20102  "optimize_size || !TARGET_SUB_ESP_4"
20103  [(clobber (match_dup 0))
20104   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20105
20106(define_peephole2
20107  [(match_scratch:SI 0 "r")
20108   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20109	      (clobber (reg:CC FLAGS_REG))])]
20110  "optimize_size || !TARGET_SUB_ESP_8"
20111  [(clobber (match_dup 0))
20112   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20113   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20114
20115;; Convert epilogue deallocator to pop.
20116(define_peephole2
20117  [(match_scratch:SI 0 "r")
20118   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20119	      (clobber (reg:CC FLAGS_REG))
20120	      (clobber (mem:BLK (scratch)))])]
20121  "optimize_size || !TARGET_ADD_ESP_4"
20122  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20123	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20124	      (clobber (mem:BLK (scratch)))])]
20125  "")
20126
20127;; Two pops case is tricky, since pop causes dependency on destination register.
20128;; We use two registers if available.
20129(define_peephole2
20130  [(match_scratch:SI 0 "r")
20131   (match_scratch:SI 1 "r")
20132   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20133	      (clobber (reg:CC FLAGS_REG))
20134	      (clobber (mem:BLK (scratch)))])]
20135  "optimize_size || !TARGET_ADD_ESP_8"
20136  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20137	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20138	      (clobber (mem:BLK (scratch)))])
20139   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20140	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20141  "")
20142
20143(define_peephole2
20144  [(match_scratch:SI 0 "r")
20145   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20146	      (clobber (reg:CC FLAGS_REG))
20147	      (clobber (mem:BLK (scratch)))])]
20148  "optimize_size"
20149  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20150	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20151	      (clobber (mem:BLK (scratch)))])
20152   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20153	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20154  "")
20155
20156;; Convert esp additions to pop.
20157(define_peephole2
20158  [(match_scratch:SI 0 "r")
20159   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20160	      (clobber (reg:CC FLAGS_REG))])]
20161  ""
20162  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20163	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20164  "")
20165
20166;; Two pops case is tricky, since pop causes dependency on destination register.
20167;; We use two registers if available.
20168(define_peephole2
20169  [(match_scratch:SI 0 "r")
20170   (match_scratch:SI 1 "r")
20171   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20172	      (clobber (reg:CC FLAGS_REG))])]
20173  ""
20174  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20175	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20176   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20177	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20178  "")
20179
20180(define_peephole2
20181  [(match_scratch:SI 0 "r")
20182   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20183	      (clobber (reg:CC FLAGS_REG))])]
20184  "optimize_size"
20185  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20186	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20187   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20188	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20189  "")
20190
20191;; Convert compares with 1 to shorter inc/dec operations when CF is not
20192;; required and register dies.  Similarly for 128 to plus -128.
20193(define_peephole2
20194  [(set (match_operand 0 "flags_reg_operand" "")
20195	(match_operator 1 "compare_operator"
20196	  [(match_operand 2 "register_operand" "")
20197	   (match_operand 3 "const_int_operand" "")]))]
20198  "(INTVAL (operands[3]) == -1
20199    || INTVAL (operands[3]) == 1
20200    || INTVAL (operands[3]) == 128)
20201   && ix86_match_ccmode (insn, CCGCmode)
20202   && peep2_reg_dead_p (1, operands[2])"
20203  [(parallel [(set (match_dup 0)
20204		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20205	      (clobber (match_dup 2))])]
20206  "")
20207
20208(define_peephole2
20209  [(match_scratch:DI 0 "r")
20210   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20211	      (clobber (reg:CC FLAGS_REG))
20212	      (clobber (mem:BLK (scratch)))])]
20213  "optimize_size || !TARGET_SUB_ESP_4"
20214  [(clobber (match_dup 0))
20215   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20216	      (clobber (mem:BLK (scratch)))])])
20217
20218(define_peephole2
20219  [(match_scratch:DI 0 "r")
20220   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20221	      (clobber (reg:CC FLAGS_REG))
20222	      (clobber (mem:BLK (scratch)))])]
20223  "optimize_size || !TARGET_SUB_ESP_8"
20224  [(clobber (match_dup 0))
20225   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20226   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20227	      (clobber (mem:BLK (scratch)))])])
20228
20229;; Convert esp subtractions to push.
20230(define_peephole2
20231  [(match_scratch:DI 0 "r")
20232   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20233	      (clobber (reg:CC FLAGS_REG))])]
20234  "optimize_size || !TARGET_SUB_ESP_4"
20235  [(clobber (match_dup 0))
20236   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20237
20238(define_peephole2
20239  [(match_scratch:DI 0 "r")
20240   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20241	      (clobber (reg:CC FLAGS_REG))])]
20242  "optimize_size || !TARGET_SUB_ESP_8"
20243  [(clobber (match_dup 0))
20244   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20245   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20246
20247;; Convert epilogue deallocator to pop.
20248(define_peephole2
20249  [(match_scratch:DI 0 "r")
20250   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20251	      (clobber (reg:CC FLAGS_REG))
20252	      (clobber (mem:BLK (scratch)))])]
20253  "optimize_size || !TARGET_ADD_ESP_4"
20254  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20255	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20256	      (clobber (mem:BLK (scratch)))])]
20257  "")
20258
20259;; Two pops case is tricky, since pop causes dependency on destination register.
20260;; We use two registers if available.
20261(define_peephole2
20262  [(match_scratch:DI 0 "r")
20263   (match_scratch:DI 1 "r")
20264   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20265	      (clobber (reg:CC FLAGS_REG))
20266	      (clobber (mem:BLK (scratch)))])]
20267  "optimize_size || !TARGET_ADD_ESP_8"
20268  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20269	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20270	      (clobber (mem:BLK (scratch)))])
20271   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20272	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20273  "")
20274
20275(define_peephole2
20276  [(match_scratch:DI 0 "r")
20277   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20278	      (clobber (reg:CC FLAGS_REG))
20279	      (clobber (mem:BLK (scratch)))])]
20280  "optimize_size"
20281  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20282	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20283	      (clobber (mem:BLK (scratch)))])
20284   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20285	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20286  "")
20287
20288;; Convert esp additions to pop.
20289(define_peephole2
20290  [(match_scratch:DI 0 "r")
20291   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20292	      (clobber (reg:CC FLAGS_REG))])]
20293  ""
20294  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20295	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20296  "")
20297
20298;; Two pops case is tricky, since pop causes dependency on destination register.
20299;; We use two registers if available.
20300(define_peephole2
20301  [(match_scratch:DI 0 "r")
20302   (match_scratch:DI 1 "r")
20303   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20304	      (clobber (reg:CC FLAGS_REG))])]
20305  ""
20306  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20307	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20308   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20309	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20310  "")
20311
20312(define_peephole2
20313  [(match_scratch:DI 0 "r")
20314   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20315	      (clobber (reg:CC FLAGS_REG))])]
20316  "optimize_size"
20317  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20318	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20319   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20320	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20321  "")
20322
20323;; Convert imul by three, five and nine into lea
20324(define_peephole2
20325  [(parallel
20326    [(set (match_operand:SI 0 "register_operand" "")
20327	  (mult:SI (match_operand:SI 1 "register_operand" "")
20328		   (match_operand:SI 2 "const_int_operand" "")))
20329     (clobber (reg:CC FLAGS_REG))])]
20330  "INTVAL (operands[2]) == 3
20331   || INTVAL (operands[2]) == 5
20332   || INTVAL (operands[2]) == 9"
20333  [(set (match_dup 0)
20334        (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20335                 (match_dup 1)))]
20336  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20337
20338(define_peephole2
20339  [(parallel
20340    [(set (match_operand:SI 0 "register_operand" "")
20341          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20342                   (match_operand:SI 2 "const_int_operand" "")))
20343     (clobber (reg:CC FLAGS_REG))])]
20344  "!optimize_size 
20345   && (INTVAL (operands[2]) == 3
20346       || INTVAL (operands[2]) == 5
20347       || INTVAL (operands[2]) == 9)"
20348  [(set (match_dup 0) (match_dup 1))
20349   (set (match_dup 0)
20350        (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20351                 (match_dup 0)))]
20352  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20353
20354(define_peephole2
20355  [(parallel
20356    [(set (match_operand:DI 0 "register_operand" "")
20357	  (mult:DI (match_operand:DI 1 "register_operand" "")
20358		   (match_operand:DI 2 "const_int_operand" "")))
20359     (clobber (reg:CC FLAGS_REG))])]
20360  "TARGET_64BIT
20361   && (INTVAL (operands[2]) == 3
20362       || INTVAL (operands[2]) == 5
20363       || INTVAL (operands[2]) == 9)"
20364  [(set (match_dup 0)
20365        (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20366                 (match_dup 1)))]
20367  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20368
20369(define_peephole2
20370  [(parallel
20371    [(set (match_operand:DI 0 "register_operand" "")
20372          (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20373                   (match_operand:DI 2 "const_int_operand" "")))
20374     (clobber (reg:CC FLAGS_REG))])]
20375  "TARGET_64BIT
20376   && !optimize_size 
20377   && (INTVAL (operands[2]) == 3
20378       || INTVAL (operands[2]) == 5
20379       || INTVAL (operands[2]) == 9)"
20380  [(set (match_dup 0) (match_dup 1))
20381   (set (match_dup 0)
20382        (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20383                 (match_dup 0)))]
20384  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20385
20386;; Imul $32bit_imm, mem, reg is vector decoded, while
20387;; imul $32bit_imm, reg, reg is direct decoded.
20388(define_peephole2
20389  [(match_scratch:DI 3 "r")
20390   (parallel [(set (match_operand:DI 0 "register_operand" "")
20391		   (mult:DI (match_operand:DI 1 "memory_operand" "")
20392			    (match_operand:DI 2 "immediate_operand" "")))
20393	      (clobber (reg:CC FLAGS_REG))])]
20394  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20395   && !satisfies_constraint_K (operands[2])"
20396  [(set (match_dup 3) (match_dup 1))
20397   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20398	      (clobber (reg:CC FLAGS_REG))])]
20399"")
20400
20401(define_peephole2
20402  [(match_scratch:SI 3 "r")
20403   (parallel [(set (match_operand:SI 0 "register_operand" "")
20404		   (mult:SI (match_operand:SI 1 "memory_operand" "")
20405			    (match_operand:SI 2 "immediate_operand" "")))
20406	      (clobber (reg:CC FLAGS_REG))])]
20407  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20408   && !satisfies_constraint_K (operands[2])"
20409  [(set (match_dup 3) (match_dup 1))
20410   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20411	      (clobber (reg:CC FLAGS_REG))])]
20412"")
20413
20414(define_peephole2
20415  [(match_scratch:SI 3 "r")
20416   (parallel [(set (match_operand:DI 0 "register_operand" "")
20417		   (zero_extend:DI
20418		     (mult:SI (match_operand:SI 1 "memory_operand" "")
20419			      (match_operand:SI 2 "immediate_operand" ""))))
20420	      (clobber (reg:CC FLAGS_REG))])]
20421  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20422   && !satisfies_constraint_K (operands[2])"
20423  [(set (match_dup 3) (match_dup 1))
20424   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20425	      (clobber (reg:CC FLAGS_REG))])]
20426"")
20427
20428;; imul $8/16bit_imm, regmem, reg is vector decoded.
20429;; Convert it into imul reg, reg
20430;; It would be better to force assembler to encode instruction using long
20431;; immediate, but there is apparently no way to do so.
20432(define_peephole2
20433  [(parallel [(set (match_operand:DI 0 "register_operand" "")
20434		   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20435			    (match_operand:DI 2 "const_int_operand" "")))
20436	      (clobber (reg:CC FLAGS_REG))])
20437   (match_scratch:DI 3 "r")]
20438  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20439   && satisfies_constraint_K (operands[2])"
20440  [(set (match_dup 3) (match_dup 2))
20441   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20442	      (clobber (reg:CC FLAGS_REG))])]
20443{
20444  if (!rtx_equal_p (operands[0], operands[1]))
20445    emit_move_insn (operands[0], operands[1]);
20446})
20447
20448(define_peephole2
20449  [(parallel [(set (match_operand:SI 0 "register_operand" "")
20450		   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20451			    (match_operand:SI 2 "const_int_operand" "")))
20452	      (clobber (reg:CC FLAGS_REG))])
20453   (match_scratch:SI 3 "r")]
20454  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20455   && satisfies_constraint_K (operands[2])"
20456  [(set (match_dup 3) (match_dup 2))
20457   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20458	      (clobber (reg:CC FLAGS_REG))])]
20459{
20460  if (!rtx_equal_p (operands[0], operands[1]))
20461    emit_move_insn (operands[0], operands[1]);
20462})
20463
20464(define_peephole2
20465  [(parallel [(set (match_operand:HI 0 "register_operand" "")
20466		   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20467			    (match_operand:HI 2 "immediate_operand" "")))
20468	      (clobber (reg:CC FLAGS_REG))])
20469   (match_scratch:HI 3 "r")]
20470  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20471  [(set (match_dup 3) (match_dup 2))
20472   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20473	      (clobber (reg:CC FLAGS_REG))])]
20474{
20475  if (!rtx_equal_p (operands[0], operands[1]))
20476    emit_move_insn (operands[0], operands[1]);
20477})
20478
20479;; After splitting up read-modify operations, array accesses with memory
20480;; operands might end up in form:
20481;;  sall    $2, %eax
20482;;  movl    4(%esp), %edx
20483;;  addl    %edx, %eax
20484;; instead of pre-splitting:
20485;;  sall    $2, %eax
20486;;  addl    4(%esp), %eax
20487;; Turn it into:
20488;;  movl    4(%esp), %edx
20489;;  leal    (%edx,%eax,4), %eax
20490
20491(define_peephole2
20492  [(parallel [(set (match_operand 0 "register_operand" "")
20493		   (ashift (match_operand 1 "register_operand" "")
20494			   (match_operand 2 "const_int_operand" "")))
20495	       (clobber (reg:CC FLAGS_REG))])
20496   (set (match_operand 3 "register_operand")
20497        (match_operand 4 "x86_64_general_operand" ""))
20498   (parallel [(set (match_operand 5 "register_operand" "")
20499		   (plus (match_operand 6 "register_operand" "")
20500			 (match_operand 7 "register_operand" "")))
20501		   (clobber (reg:CC FLAGS_REG))])]
20502  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20503   /* Validate MODE for lea.  */
20504   && ((!TARGET_PARTIAL_REG_STALL
20505	&& (GET_MODE (operands[0]) == QImode
20506	    || GET_MODE (operands[0]) == HImode))
20507       || GET_MODE (operands[0]) == SImode 
20508       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20509   /* We reorder load and the shift.  */
20510   && !rtx_equal_p (operands[1], operands[3])
20511   && !reg_overlap_mentioned_p (operands[0], operands[4])
20512   /* Last PLUS must consist of operand 0 and 3.  */
20513   && !rtx_equal_p (operands[0], operands[3])
20514   && (rtx_equal_p (operands[3], operands[6])
20515       || rtx_equal_p (operands[3], operands[7]))
20516   && (rtx_equal_p (operands[0], operands[6])
20517       || rtx_equal_p (operands[0], operands[7]))
20518   /* The intermediate operand 0 must die or be same as output.  */
20519   && (rtx_equal_p (operands[0], operands[5])
20520       || peep2_reg_dead_p (3, operands[0]))"
20521  [(set (match_dup 3) (match_dup 4))
20522   (set (match_dup 0) (match_dup 1))]
20523{
20524  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20525  int scale = 1 << INTVAL (operands[2]);
20526  rtx index = gen_lowpart (Pmode, operands[1]);
20527  rtx base = gen_lowpart (Pmode, operands[3]);
20528  rtx dest = gen_lowpart (mode, operands[5]);
20529
20530  operands[1] = gen_rtx_PLUS (Pmode, base,
20531  			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20532  if (mode != Pmode)
20533    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20534  operands[0] = dest;
20535})
20536
20537;; Call-value patterns last so that the wildcard operand does not
20538;; disrupt insn-recog's switch tables.
20539
20540(define_insn "*call_value_pop_0"
20541  [(set (match_operand 0 "" "")
20542	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20543	      (match_operand:SI 2 "" "")))
20544   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20545			    (match_operand:SI 3 "immediate_operand" "")))]
20546  "!TARGET_64BIT"
20547{
20548  if (SIBLING_CALL_P (insn))
20549    return "jmp\t%P1";
20550  else
20551    return "call\t%P1";
20552}
20553  [(set_attr "type" "callv")])
20554
20555(define_insn "*call_value_pop_1"
20556  [(set (match_operand 0 "" "")
20557	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20558	      (match_operand:SI 2 "" "")))
20559   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20560			    (match_operand:SI 3 "immediate_operand" "i")))]
20561  "!TARGET_64BIT"
20562{
20563  if (constant_call_address_operand (operands[1], Pmode))
20564    {
20565      if (SIBLING_CALL_P (insn))
20566	return "jmp\t%P1";
20567      else
20568	return "call\t%P1";
20569    }
20570  if (SIBLING_CALL_P (insn))
20571    return "jmp\t%A1";
20572  else
20573    return "call\t%A1";
20574}
20575  [(set_attr "type" "callv")])
20576
20577(define_insn "*call_value_0"
20578  [(set (match_operand 0 "" "")
20579	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20580	      (match_operand:SI 2 "" "")))]
20581  "!TARGET_64BIT"
20582{
20583  if (SIBLING_CALL_P (insn))
20584    return "jmp\t%P1";
20585  else
20586    return "call\t%P1";
20587}
20588  [(set_attr "type" "callv")])
20589
20590(define_insn "*call_value_0_rex64"
20591  [(set (match_operand 0 "" "")
20592	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20593	      (match_operand:DI 2 "const_int_operand" "")))]
20594  "TARGET_64BIT"
20595{
20596  if (SIBLING_CALL_P (insn))
20597    return "jmp\t%P1";
20598  else
20599    return "call\t%P1";
20600}
20601  [(set_attr "type" "callv")])
20602
20603(define_insn "*call_value_1"
20604  [(set (match_operand 0 "" "")
20605	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20606	      (match_operand:SI 2 "" "")))]
20607  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20608{
20609  if (constant_call_address_operand (operands[1], Pmode))
20610    return "call\t%P1";
20611  return "call\t%A1";
20612}
20613  [(set_attr "type" "callv")])
20614
20615(define_insn "*sibcall_value_1"
20616  [(set (match_operand 0 "" "")
20617	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20618	      (match_operand:SI 2 "" "")))]
20619  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20620{
20621  if (constant_call_address_operand (operands[1], Pmode))
20622    return "jmp\t%P1";
20623  return "jmp\t%A1";
20624}
20625  [(set_attr "type" "callv")])
20626
20627(define_insn "*call_value_1_rex64"
20628  [(set (match_operand 0 "" "")
20629	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20630	      (match_operand:DI 2 "" "")))]
20631  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20632{
20633  if (constant_call_address_operand (operands[1], Pmode))
20634    return "call\t%P1";
20635  return "call\t%A1";
20636}
20637  [(set_attr "type" "callv")])
20638
20639(define_insn "*sibcall_value_1_rex64"
20640  [(set (match_operand 0 "" "")
20641	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20642	      (match_operand:DI 2 "" "")))]
20643  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20644  "jmp\t%P1"
20645  [(set_attr "type" "callv")])
20646
20647(define_insn "*sibcall_value_1_rex64_v"
20648  [(set (match_operand 0 "" "")
20649	(call (mem:QI (reg:DI 40))
20650	      (match_operand:DI 1 "" "")))]
20651  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20652  "jmp\t*%%r11"
20653  [(set_attr "type" "callv")])
20654
20655;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20656;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20657;; caught for use by garbage collectors and the like.  Using an insn that
20658;; maps to SIGILL makes it more likely the program will rightfully die.
20659;; Keeping with tradition, "6" is in honor of #UD.
20660(define_insn "trap"
20661  [(trap_if (const_int 1) (const_int 6))]
20662  ""
20663  { return ASM_SHORT "0x0b0f"; }
20664  [(set_attr "length" "2")])
20665
20666(define_expand "sse_prologue_save"
20667  [(parallel [(set (match_operand:BLK 0 "" "")
20668		   (unspec:BLK [(reg:DI 21)
20669				(reg:DI 22)
20670				(reg:DI 23)
20671				(reg:DI 24)
20672				(reg:DI 25)
20673				(reg:DI 26)
20674				(reg:DI 27)
20675				(reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20676	      (use (match_operand:DI 1 "register_operand" ""))
20677	      (use (match_operand:DI 2 "immediate_operand" ""))
20678	      (use (label_ref:DI (match_operand 3 "" "")))])]
20679  "TARGET_64BIT"
20680  "")
20681
20682(define_insn "*sse_prologue_save_insn"
20683  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20684			  (match_operand:DI 4 "const_int_operand" "n")))
20685	(unspec:BLK [(reg:DI 21)
20686		     (reg:DI 22)
20687		     (reg:DI 23)
20688		     (reg:DI 24)
20689		     (reg:DI 25)
20690		     (reg:DI 26)
20691		     (reg:DI 27)
20692		     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20693   (use (match_operand:DI 1 "register_operand" "r"))
20694   (use (match_operand:DI 2 "const_int_operand" "i"))
20695   (use (label_ref:DI (match_operand 3 "" "X")))]
20696  "TARGET_64BIT
20697   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20698   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20699  "*
20700{
20701  int i;
20702  operands[0] = gen_rtx_MEM (Pmode,
20703			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20704  output_asm_insn (\"jmp\\t%A1\", operands);
20705  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20706    {
20707      operands[4] = adjust_address (operands[0], DImode, i*16);
20708      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20709      PUT_MODE (operands[4], TImode);
20710      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20711        output_asm_insn (\"rex\", operands);
20712      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20713    }
20714  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20715			     CODE_LABEL_NUMBER (operands[3]));
20716  RET;
20717}
20718  "
20719  [(set_attr "type" "other")
20720   (set_attr "length_immediate" "0")
20721   (set_attr "length_address" "0")
20722   (set_attr "length" "135")
20723   (set_attr "memory" "store")
20724   (set_attr "modrm" "0")
20725   (set_attr "mode" "DI")])
20726
20727(define_expand "prefetch"
20728  [(prefetch (match_operand 0 "address_operand" "")
20729	     (match_operand:SI 1 "const_int_operand" "")
20730	     (match_operand:SI 2 "const_int_operand" ""))]
20731  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20732{
20733  int rw = INTVAL (operands[1]);
20734  int locality = INTVAL (operands[2]);
20735
20736  gcc_assert (rw == 0 || rw == 1);
20737  gcc_assert (locality >= 0 && locality <= 3);
20738  gcc_assert (GET_MODE (operands[0]) == Pmode
20739	      || GET_MODE (operands[0]) == VOIDmode);
20740
20741  /* Use 3dNOW prefetch in case we are asking for write prefetch not
20742     supported by SSE counterpart or the SSE prefetch is not available
20743     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20744     of locality.  */
20745  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20746    operands[2] = GEN_INT (3);
20747  else
20748    operands[1] = const0_rtx;
20749})
20750
20751(define_insn "*prefetch_sse"
20752  [(prefetch (match_operand:SI 0 "address_operand" "p")
20753	     (const_int 0)
20754	     (match_operand:SI 1 "const_int_operand" ""))]
20755  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20756{
20757  static const char * const patterns[4] = {
20758   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20759  };
20760
20761  int locality = INTVAL (operands[1]);
20762  gcc_assert (locality >= 0 && locality <= 3);
20763
20764  return patterns[locality];  
20765}
20766  [(set_attr "type" "sse")
20767   (set_attr "memory" "none")])
20768
20769(define_insn "*prefetch_sse_rex"
20770  [(prefetch (match_operand:DI 0 "address_operand" "p")
20771	     (const_int 0)
20772	     (match_operand:SI 1 "const_int_operand" ""))]
20773  "TARGET_PREFETCH_SSE && TARGET_64BIT"
20774{
20775  static const char * const patterns[4] = {
20776   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20777  };
20778
20779  int locality = INTVAL (operands[1]);
20780  gcc_assert (locality >= 0 && locality <= 3);
20781
20782  return patterns[locality];  
20783}
20784  [(set_attr "type" "sse")
20785   (set_attr "memory" "none")])
20786
20787(define_insn "*prefetch_3dnow"
20788  [(prefetch (match_operand:SI 0 "address_operand" "p")
20789	     (match_operand:SI 1 "const_int_operand" "n")
20790	     (const_int 3))]
20791  "TARGET_3DNOW && !TARGET_64BIT"
20792{
20793  if (INTVAL (operands[1]) == 0)
20794    return "prefetch\t%a0";
20795  else
20796    return "prefetchw\t%a0";
20797}
20798  [(set_attr "type" "mmx")
20799   (set_attr "memory" "none")])
20800
20801(define_insn "*prefetch_3dnow_rex"
20802  [(prefetch (match_operand:DI 0 "address_operand" "p")
20803	     (match_operand:SI 1 "const_int_operand" "n")
20804	     (const_int 3))]
20805  "TARGET_3DNOW && TARGET_64BIT"
20806{
20807  if (INTVAL (operands[1]) == 0)
20808    return "prefetch\t%a0";
20809  else
20810    return "prefetchw\t%a0";
20811}
20812  [(set_attr "type" "mmx")
20813   (set_attr "memory" "none")])
20814
20815(define_expand "stack_protect_set"
20816  [(match_operand 0 "memory_operand" "")
20817   (match_operand 1 "memory_operand" "")]
20818  ""
20819{
20820#ifdef TARGET_THREAD_SSP_OFFSET
20821  if (TARGET_64BIT)
20822    emit_insn (gen_stack_tls_protect_set_di (operands[0],
20823					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20824  else
20825    emit_insn (gen_stack_tls_protect_set_si (operands[0],
20826					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20827#else
20828  if (TARGET_64BIT)
20829    emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20830  else
20831    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20832#endif
20833  DONE;
20834})
20835
20836(define_insn "stack_protect_set_si"
20837  [(set (match_operand:SI 0 "memory_operand" "=m")
20838	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20839   (set (match_scratch:SI 2 "=&r") (const_int 0))
20840   (clobber (reg:CC FLAGS_REG))]
20841  ""
20842  "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20843  [(set_attr "type" "multi")])
20844
20845(define_insn "stack_protect_set_di"
20846  [(set (match_operand:DI 0 "memory_operand" "=m")
20847	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20848   (set (match_scratch:DI 2 "=&r") (const_int 0))
20849   (clobber (reg:CC FLAGS_REG))]
20850  "TARGET_64BIT"
20851  "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20852  [(set_attr "type" "multi")])
20853
20854(define_insn "stack_tls_protect_set_si"
20855  [(set (match_operand:SI 0 "memory_operand" "=m")
20856	(unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20857   (set (match_scratch:SI 2 "=&r") (const_int 0))
20858   (clobber (reg:CC FLAGS_REG))]
20859  ""
20860  "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20861  [(set_attr "type" "multi")])
20862
20863(define_insn "stack_tls_protect_set_di"
20864  [(set (match_operand:DI 0 "memory_operand" "=m")
20865	(unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20866   (set (match_scratch:DI 2 "=&r") (const_int 0))
20867   (clobber (reg:CC FLAGS_REG))]
20868  "TARGET_64BIT"
20869  {
20870     /* The kernel uses a different segment register for performance reasons; a
20871        system call would not have to trash the userspace segment register,
20872        which would be expensive */
20873     if (ix86_cmodel != CM_KERNEL)
20874        return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20875     else
20876        return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20877  }
20878  [(set_attr "type" "multi")])
20879
20880(define_expand "stack_protect_test"
20881  [(match_operand 0 "memory_operand" "")
20882   (match_operand 1 "memory_operand" "")
20883   (match_operand 2 "" "")]
20884  ""
20885{
20886  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20887  ix86_compare_op0 = operands[0];
20888  ix86_compare_op1 = operands[1];
20889  ix86_compare_emitted = flags;
20890
20891#ifdef TARGET_THREAD_SSP_OFFSET
20892  if (TARGET_64BIT)
20893    emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20894					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20895  else
20896    emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20897					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20898#else
20899  if (TARGET_64BIT)
20900    emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20901  else
20902    emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20903#endif
20904  emit_jump_insn (gen_beq (operands[2]));
20905  DONE;
20906})
20907
20908(define_insn "stack_protect_test_si"
20909  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20910	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20911		     (match_operand:SI 2 "memory_operand" "m")]
20912		    UNSPEC_SP_TEST))
20913   (clobber (match_scratch:SI 3 "=&r"))]
20914  ""
20915  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20916  [(set_attr "type" "multi")])
20917
20918(define_insn "stack_protect_test_di"
20919  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20920	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20921		     (match_operand:DI 2 "memory_operand" "m")]
20922		    UNSPEC_SP_TEST))
20923   (clobber (match_scratch:DI 3 "=&r"))]
20924  "TARGET_64BIT"
20925  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20926  [(set_attr "type" "multi")])
20927
20928(define_insn "stack_tls_protect_test_si"
20929  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20930	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20931		     (match_operand:SI 2 "const_int_operand" "i")]
20932		    UNSPEC_SP_TLS_TEST))
20933   (clobber (match_scratch:SI 3 "=r"))]
20934  ""
20935  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20936  [(set_attr "type" "multi")])
20937
20938(define_insn "stack_tls_protect_test_di"
20939  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20940	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20941		     (match_operand:DI 2 "const_int_operand" "i")]
20942		    UNSPEC_SP_TLS_TEST))
20943   (clobber (match_scratch:DI 3 "=r"))]
20944  "TARGET_64BIT"
20945  {
20946     /* The kernel uses a different segment register for performance reasons; a
20947        system call would not have to trash the userspace segment register,
20948        which would be expensive */
20949     if (ix86_cmodel != CM_KERNEL)
20950        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20951     else
20952        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20953  }
20954  [(set_attr "type" "multi")])
20955
20956(include "mmx.md")
20957(include "sse.md")
20958(include "sync.md")
20959