i386.md revision 256281
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   ; For SSE4A support
158   (UNSPEC_EXTRQI               130)
159   (UNSPEC_EXTRQ                131)   
160   (UNSPEC_INSERTQI             132)
161   (UNSPEC_INSERTQ              133)
162  ])
163
164(define_constants
165  [(UNSPECV_BLOCKAGE		0)
166   (UNSPECV_STACK_PROBE		1)
167   (UNSPECV_EMMS		2)
168   (UNSPECV_LDMXCSR		3)
169   (UNSPECV_STMXCSR		4)
170   (UNSPECV_FEMMS		5)
171   (UNSPECV_CLFLUSH		6)
172   (UNSPECV_ALIGN		7)
173   (UNSPECV_MONITOR		8)
174   (UNSPECV_MWAIT		9)
175   (UNSPECV_CMPXCHG_1		10)
176   (UNSPECV_CMPXCHG_2		11)
177   (UNSPECV_XCHG		12)
178   (UNSPECV_LOCK		13)
179  ])
180
181;; Registers by name.
182(define_constants
183  [(BP_REG			 6)
184   (SP_REG			 7)
185   (FLAGS_REG			17)
186   (FPSR_REG			18)
187   (DIRFLAG_REG			19)
188  ])
189
190;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
191;; from i386.c.
192
193;; In C guard expressions, put expressions which may be compile-time
194;; constants first.  This allows for better optimization.  For
195;; example, write "TARGET_64BIT && reload_completed", not
196;; "reload_completed && TARGET_64BIT".
197
198
199;; Processor type.  This attribute must exactly match the processor_type
200;; enumeration in i386.h.
201(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
202                    nocona,core2,generic32,generic64,amdfam10"
203  (const (symbol_ref "ix86_tune")))
204
205;; A basic instruction type.  Refinements due to arguments to be
206;; provided in other attributes.
207(define_attr "type"
208  "other,multi,
209   alu,alu1,negnot,imov,imovx,lea,
210   incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
211   icmp,test,ibr,setcc,icmov,
212   push,pop,call,callv,leave,
213   str,bitmanip,cld,
214   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
215   sselog,sselog1,sseiadd,sseishft,sseimul,
216   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
217   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
218  (const_string "other"))
219
220;; Main data type used by the insn
221(define_attr "mode"
222  "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
223  (const_string "unknown"))
224
225;; The CPU unit operations uses.
226(define_attr "unit" "integer,i387,sse,mmx,unknown"
227  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
228	   (const_string "i387")
229	 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
230			  sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
231	   (const_string "sse")
232	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
233	   (const_string "mmx")
234	 (eq_attr "type" "other")
235	   (const_string "unknown")]
236	 (const_string "integer")))
237
238;; The (bounding maximum) length of an instruction immediate.
239(define_attr "length_immediate" ""
240  (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave,
241                          bitmanip")
242	   (const_int 0)
243	 (eq_attr "unit" "i387,sse,mmx")
244	   (const_int 0)
245	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
246			  imul,icmp,push,pop")
247	   (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
248	 (eq_attr "type" "imov,test")
249	   (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
250	 (eq_attr "type" "call")
251	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
252	     (const_int 4)
253	     (const_int 0))
254	 (eq_attr "type" "callv")
255	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
256	     (const_int 4)
257	     (const_int 0))
258	 ;; We don't know the size before shorten_branches.  Expect
259	 ;; the instruction to fit for better scheduling.
260	 (eq_attr "type" "ibr")
261	   (const_int 1)
262	 ]
263	 (symbol_ref "/* Update immediate_length and other attributes! */
264		      gcc_unreachable (),1")))
265
266;; The (bounding maximum) length of an instruction address.
267(define_attr "length_address" ""
268  (cond [(eq_attr "type" "str,cld,other,multi,fxch")
269	   (const_int 0)
270	 (and (eq_attr "type" "call")
271	      (match_operand 0 "constant_call_address_operand" ""))
272	     (const_int 0)
273	 (and (eq_attr "type" "callv")
274	      (match_operand 1 "constant_call_address_operand" ""))
275	     (const_int 0)
276	 ]
277	 (symbol_ref "ix86_attr_length_address_default (insn)")))
278
279;; Set when length prefix is used.
280(define_attr "prefix_data16" ""
281  (if_then_else (ior (eq_attr "mode" "HI")
282		     (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
283    (const_int 1)
284    (const_int 0)))
285
286;; Set when string REP prefix is used.
287(define_attr "prefix_rep" "" 
288  (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
289    (const_int 1)
290    (const_int 0)))
291
292;; Set when 0f opcode prefix is used.
293(define_attr "prefix_0f" ""
294  (if_then_else 
295    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
296	 (eq_attr "unit" "sse,mmx"))
297    (const_int 1)
298    (const_int 0)))
299
300;; Set when REX opcode prefix is used.
301(define_attr "prefix_rex" ""
302  (cond [(and (eq_attr "mode" "DI")
303  	      (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
304	   (const_int 1)
305	 (and (eq_attr "mode" "QI")
306	      (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
307		  (const_int 0)))
308	   (const_int 1)
309	 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
310	     (const_int 0))
311	   (const_int 1)
312	]
313	(const_int 0)))
314
315;; Set when modrm byte is used.
316(define_attr "modrm" ""
317  (cond [(eq_attr "type" "str,cld,leave")
318	   (const_int 0)
319	 (eq_attr "unit" "i387")
320	   (const_int 0)
321         (and (eq_attr "type" "incdec")
322	      (ior (match_operand:SI 1 "register_operand" "")
323		   (match_operand:HI 1 "register_operand" "")))
324	   (const_int 0)
325	 (and (eq_attr "type" "push")
326	      (not (match_operand 1 "memory_operand" "")))
327	   (const_int 0)
328	 (and (eq_attr "type" "pop")
329	      (not (match_operand 0 "memory_operand" "")))
330	   (const_int 0)
331	 (and (eq_attr "type" "imov")
332	      (ior (and (match_operand 0 "register_operand" "")
333			(match_operand 1 "immediate_operand" ""))
334		   (ior (and (match_operand 0 "ax_reg_operand" "")
335			     (match_operand 1 "memory_displacement_only_operand" ""))
336			(and (match_operand 0 "memory_displacement_only_operand" "")
337			     (match_operand 1 "ax_reg_operand" "")))))
338	   (const_int 0)
339	 (and (eq_attr "type" "call")
340	      (match_operand 0 "constant_call_address_operand" ""))
341	     (const_int 0)
342	 (and (eq_attr "type" "callv")
343	      (match_operand 1 "constant_call_address_operand" ""))
344	     (const_int 0)
345	 ]
346	 (const_int 1)))
347
348;; The (bounding maximum) length of an instruction in bytes.
349;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
350;; Later we may want to split them and compute proper length as for
351;; other insns.
352(define_attr "length" ""
353  (cond [(eq_attr "type" "other,multi,fistp,frndint")
354	   (const_int 16)
355	 (eq_attr "type" "fcmp")
356	   (const_int 4)
357	 (eq_attr "unit" "i387")
358	   (plus (const_int 2)
359		 (plus (attr "prefix_data16")
360		       (attr "length_address")))]
361	 (plus (plus (attr "modrm")
362		     (plus (attr "prefix_0f")
363			   (plus (attr "prefix_rex")
364				 (const_int 1))))
365	       (plus (attr "prefix_rep")
366		     (plus (attr "prefix_data16")
367			   (plus (attr "length_immediate")
368				 (attr "length_address")))))))
369
370;; The `memory' attribute is `none' if no memory is referenced, `load' or
371;; `store' if there is a simple memory reference therein, or `unknown'
372;; if the instruction is complex.
373
374(define_attr "memory" "none,load,store,both,unknown"
375  (cond [(eq_attr "type" "other,multi,str")
376	   (const_string "unknown")
377	 (eq_attr "type" "lea,fcmov,fpspc,cld")
378	   (const_string "none")
379	 (eq_attr "type" "fistp,leave")
380	   (const_string "both")
381	 (eq_attr "type" "frndint")
382	   (const_string "load")
383	 (eq_attr "type" "push")
384	   (if_then_else (match_operand 1 "memory_operand" "")
385	     (const_string "both")
386	     (const_string "store"))
387	 (eq_attr "type" "pop")
388	   (if_then_else (match_operand 0 "memory_operand" "")
389	     (const_string "both")
390	     (const_string "load"))
391	 (eq_attr "type" "setcc")
392	   (if_then_else (match_operand 0 "memory_operand" "")
393	     (const_string "store")
394	     (const_string "none"))
395	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
396	   (if_then_else (ior (match_operand 0 "memory_operand" "")
397			      (match_operand 1 "memory_operand" ""))
398	     (const_string "load")
399	     (const_string "none"))
400	 (eq_attr "type" "ibr")
401	   (if_then_else (match_operand 0 "memory_operand" "")
402	     (const_string "load")
403	     (const_string "none"))
404	 (eq_attr "type" "call")
405	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
406	     (const_string "none")
407	     (const_string "load"))
408	 (eq_attr "type" "callv")
409	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
410	     (const_string "none")
411	     (const_string "load"))
412	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
413	      (match_operand 1 "memory_operand" ""))
414	   (const_string "both")
415	 (and (match_operand 0 "memory_operand" "")
416	      (match_operand 1 "memory_operand" ""))
417	   (const_string "both")
418	 (match_operand 0 "memory_operand" "")
419	   (const_string "store")
420	 (match_operand 1 "memory_operand" "")
421	   (const_string "load")
422	 (and (eq_attr "type"
423		 "!alu1,negnot,ishift1,
424		   imov,imovx,icmp,test,bitmanip,
425		   fmov,fcmp,fsgn,
426		   sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
427		   mmx,mmxmov,mmxcmp,mmxcvt")
428	      (match_operand 2 "memory_operand" ""))
429	   (const_string "load")
430	 (and (eq_attr "type" "icmov")
431	      (match_operand 3 "memory_operand" ""))
432	   (const_string "load")
433	]
434	(const_string "none")))
435
436;; Indicates if an instruction has both an immediate and a displacement.
437
438(define_attr "imm_disp" "false,true,unknown"
439  (cond [(eq_attr "type" "other,multi")
440	   (const_string "unknown")
441	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
442	      (and (match_operand 0 "memory_displacement_operand" "")
443		   (match_operand 1 "immediate_operand" "")))
444	   (const_string "true")
445	 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
446	      (and (match_operand 0 "memory_displacement_operand" "")
447		   (match_operand 2 "immediate_operand" "")))
448	   (const_string "true")
449	]
450	(const_string "false")))
451
452;; Indicates if an FP operation has an integer source.
453
454(define_attr "fp_int_src" "false,true"
455  (const_string "false"))
456
457;; Defines rounding mode of an FP operation.
458
459(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
460  (const_string "any"))
461
462;; Describe a user's asm statement.
463(define_asm_attributes
464  [(set_attr "length" "128")
465   (set_attr "type" "multi")])
466
467;; All x87 floating point modes
468(define_mode_macro X87MODEF [SF DF XF])
469 
470;; All integer modes handled by x87 fisttp operator.
471(define_mode_macro X87MODEI [HI SI DI])
472
473;; All integer modes handled by integer x87 operators.
474(define_mode_macro X87MODEI12 [HI SI])
475
476;; All SSE floating point modes
477(define_mode_macro SSEMODEF [SF DF])
478 
479;; All integer modes handled by SSE cvtts?2si* operators.
480(define_mode_macro SSEMODEI24 [SI DI])
481
482
483;; Scheduling descriptions
484
485(include "pentium.md")
486(include "ppro.md")
487(include "k6.md")
488(include "athlon.md")
489(include "geode.md")
490
491
492;; Operand and operator predicates and constraints
493
494(include "predicates.md")
495(include "constraints.md")
496
497
498;; Compare instructions.
499
500;; All compare insns have expanders that save the operands away without
501;; actually generating RTL.  The bCOND or sCOND (emitted immediately
502;; after the cmp) will actually emit the cmpM.
503
504(define_expand "cmpti"
505  [(set (reg:CC FLAGS_REG)
506	(compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
507		    (match_operand:TI 1 "x86_64_general_operand" "")))]
508  "TARGET_64BIT"
509{
510  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
511    operands[0] = force_reg (TImode, operands[0]);
512  ix86_compare_op0 = operands[0];
513  ix86_compare_op1 = operands[1];
514  DONE;
515})
516
517(define_expand "cmpdi"
518  [(set (reg:CC FLAGS_REG)
519	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
520		    (match_operand:DI 1 "x86_64_general_operand" "")))]
521  ""
522{
523  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
524    operands[0] = force_reg (DImode, operands[0]);
525  ix86_compare_op0 = operands[0];
526  ix86_compare_op1 = operands[1];
527  DONE;
528})
529
530(define_expand "cmpsi"
531  [(set (reg:CC FLAGS_REG)
532	(compare:CC (match_operand:SI 0 "cmpsi_operand" "")
533		    (match_operand:SI 1 "general_operand" "")))]
534  ""
535{
536  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
537    operands[0] = force_reg (SImode, operands[0]);
538  ix86_compare_op0 = operands[0];
539  ix86_compare_op1 = operands[1];
540  DONE;
541})
542
543(define_expand "cmphi"
544  [(set (reg:CC FLAGS_REG)
545	(compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
546		    (match_operand:HI 1 "general_operand" "")))]
547  ""
548{
549  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
550    operands[0] = force_reg (HImode, operands[0]);
551  ix86_compare_op0 = operands[0];
552  ix86_compare_op1 = operands[1];
553  DONE;
554})
555
556(define_expand "cmpqi"
557  [(set (reg:CC FLAGS_REG)
558	(compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
559		    (match_operand:QI 1 "general_operand" "")))]
560  "TARGET_QIMODE_MATH"
561{
562  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
563    operands[0] = force_reg (QImode, operands[0]);
564  ix86_compare_op0 = operands[0];
565  ix86_compare_op1 = operands[1];
566  DONE;
567})
568
569(define_insn "cmpdi_ccno_1_rex64"
570  [(set (reg FLAGS_REG)
571	(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
572		 (match_operand:DI 1 "const0_operand" "n,n")))]
573  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
574  "@
575   test{q}\t{%0, %0|%0, %0}
576   cmp{q}\t{%1, %0|%0, %1}"
577  [(set_attr "type" "test,icmp")
578   (set_attr "length_immediate" "0,1")
579   (set_attr "mode" "DI")])
580
581(define_insn "*cmpdi_minus_1_rex64"
582  [(set (reg FLAGS_REG)
583	(compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
584			   (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
585		 (const_int 0)))]
586  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
587  "cmp{q}\t{%1, %0|%0, %1}"
588  [(set_attr "type" "icmp")
589   (set_attr "mode" "DI")])
590
591(define_expand "cmpdi_1_rex64"
592  [(set (reg:CC FLAGS_REG)
593	(compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
594		    (match_operand:DI 1 "general_operand" "")))]
595  "TARGET_64BIT"
596  "")
597
598(define_insn "cmpdi_1_insn_rex64"
599  [(set (reg FLAGS_REG)
600	(compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
601		 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
602  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603  "cmp{q}\t{%1, %0|%0, %1}"
604  [(set_attr "type" "icmp")
605   (set_attr "mode" "DI")])
606
607
608(define_insn "*cmpsi_ccno_1"
609  [(set (reg FLAGS_REG)
610	(compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
611		 (match_operand:SI 1 "const0_operand" "n,n")))]
612  "ix86_match_ccmode (insn, CCNOmode)"
613  "@
614   test{l}\t{%0, %0|%0, %0}
615   cmp{l}\t{%1, %0|%0, %1}"
616  [(set_attr "type" "test,icmp")
617   (set_attr "length_immediate" "0,1")
618   (set_attr "mode" "SI")])
619
620(define_insn "*cmpsi_minus_1"
621  [(set (reg FLAGS_REG)
622	(compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623			   (match_operand:SI 1 "general_operand" "ri,mr"))
624		 (const_int 0)))]
625  "ix86_match_ccmode (insn, CCGOCmode)"
626  "cmp{l}\t{%1, %0|%0, %1}"
627  [(set_attr "type" "icmp")
628   (set_attr "mode" "SI")])
629
630(define_expand "cmpsi_1"
631  [(set (reg:CC FLAGS_REG)
632	(compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
633		    (match_operand:SI 1 "general_operand" "ri,mr")))]
634  ""
635  "")
636
637(define_insn "*cmpsi_1_insn"
638  [(set (reg FLAGS_REG)
639	(compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
640		 (match_operand:SI 1 "general_operand" "ri,mr")))]
641  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
642    && ix86_match_ccmode (insn, CCmode)"
643  "cmp{l}\t{%1, %0|%0, %1}"
644  [(set_attr "type" "icmp")
645   (set_attr "mode" "SI")])
646
647(define_insn "*cmphi_ccno_1"
648  [(set (reg FLAGS_REG)
649	(compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
650		 (match_operand:HI 1 "const0_operand" "n,n")))]
651  "ix86_match_ccmode (insn, CCNOmode)"
652  "@
653   test{w}\t{%0, %0|%0, %0}
654   cmp{w}\t{%1, %0|%0, %1}"
655  [(set_attr "type" "test,icmp")
656   (set_attr "length_immediate" "0,1")
657   (set_attr "mode" "HI")])
658
659(define_insn "*cmphi_minus_1"
660  [(set (reg FLAGS_REG)
661	(compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
662			   (match_operand:HI 1 "general_operand" "ri,mr"))
663		 (const_int 0)))]
664  "ix86_match_ccmode (insn, CCGOCmode)"
665  "cmp{w}\t{%1, %0|%0, %1}"
666  [(set_attr "type" "icmp")
667   (set_attr "mode" "HI")])
668
669(define_insn "*cmphi_1"
670  [(set (reg FLAGS_REG)
671	(compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
672		 (match_operand:HI 1 "general_operand" "ri,mr")))]
673  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
674   && ix86_match_ccmode (insn, CCmode)"
675  "cmp{w}\t{%1, %0|%0, %1}"
676  [(set_attr "type" "icmp")
677   (set_attr "mode" "HI")])
678
679(define_insn "*cmpqi_ccno_1"
680  [(set (reg FLAGS_REG)
681	(compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
682		 (match_operand:QI 1 "const0_operand" "n,n")))]
683  "ix86_match_ccmode (insn, CCNOmode)"
684  "@
685   test{b}\t{%0, %0|%0, %0}
686   cmp{b}\t{$0, %0|%0, 0}"
687  [(set_attr "type" "test,icmp")
688   (set_attr "length_immediate" "0,1")
689   (set_attr "mode" "QI")])
690
691(define_insn "*cmpqi_1"
692  [(set (reg FLAGS_REG)
693	(compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
694		 (match_operand:QI 1 "general_operand" "qi,mq")))]
695  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
696    && ix86_match_ccmode (insn, CCmode)"
697  "cmp{b}\t{%1, %0|%0, %1}"
698  [(set_attr "type" "icmp")
699   (set_attr "mode" "QI")])
700
701(define_insn "*cmpqi_minus_1"
702  [(set (reg FLAGS_REG)
703	(compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
704			   (match_operand:QI 1 "general_operand" "qi,mq"))
705		 (const_int 0)))]
706  "ix86_match_ccmode (insn, CCGOCmode)"
707  "cmp{b}\t{%1, %0|%0, %1}"
708  [(set_attr "type" "icmp")
709   (set_attr "mode" "QI")])
710
711(define_insn "*cmpqi_ext_1"
712  [(set (reg FLAGS_REG)
713	(compare
714	  (match_operand:QI 0 "general_operand" "Qm")
715	  (subreg:QI
716	    (zero_extract:SI
717	      (match_operand 1 "ext_register_operand" "Q")
718	      (const_int 8)
719	      (const_int 8)) 0)))]
720  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721  "cmp{b}\t{%h1, %0|%0, %h1}"
722  [(set_attr "type" "icmp")
723   (set_attr "mode" "QI")])
724
725(define_insn "*cmpqi_ext_1_rex64"
726  [(set (reg FLAGS_REG)
727	(compare
728	  (match_operand:QI 0 "register_operand" "Q")
729	  (subreg:QI
730	    (zero_extract:SI
731	      (match_operand 1 "ext_register_operand" "Q")
732	      (const_int 8)
733	      (const_int 8)) 0)))]
734  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735  "cmp{b}\t{%h1, %0|%0, %h1}"
736  [(set_attr "type" "icmp")
737   (set_attr "mode" "QI")])
738
739(define_insn "*cmpqi_ext_2"
740  [(set (reg FLAGS_REG)
741	(compare
742	  (subreg:QI
743	    (zero_extract:SI
744	      (match_operand 0 "ext_register_operand" "Q")
745	      (const_int 8)
746	      (const_int 8)) 0)
747	  (match_operand:QI 1 "const0_operand" "n")))]
748  "ix86_match_ccmode (insn, CCNOmode)"
749  "test{b}\t%h0, %h0"
750  [(set_attr "type" "test")
751   (set_attr "length_immediate" "0")
752   (set_attr "mode" "QI")])
753
754(define_expand "cmpqi_ext_3"
755  [(set (reg:CC FLAGS_REG)
756	(compare:CC
757	  (subreg:QI
758	    (zero_extract:SI
759	      (match_operand 0 "ext_register_operand" "")
760	      (const_int 8)
761	      (const_int 8)) 0)
762	  (match_operand:QI 1 "general_operand" "")))]
763  ""
764  "")
765
766(define_insn "cmpqi_ext_3_insn"
767  [(set (reg FLAGS_REG)
768	(compare
769	  (subreg:QI
770	    (zero_extract:SI
771	      (match_operand 0 "ext_register_operand" "Q")
772	      (const_int 8)
773	      (const_int 8)) 0)
774	  (match_operand:QI 1 "general_operand" "Qmn")))]
775  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776  "cmp{b}\t{%1, %h0|%h0, %1}"
777  [(set_attr "type" "icmp")
778   (set_attr "mode" "QI")])
779
780(define_insn "cmpqi_ext_3_insn_rex64"
781  [(set (reg FLAGS_REG)
782	(compare
783	  (subreg:QI
784	    (zero_extract:SI
785	      (match_operand 0 "ext_register_operand" "Q")
786	      (const_int 8)
787	      (const_int 8)) 0)
788	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
789  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790  "cmp{b}\t{%1, %h0|%h0, %1}"
791  [(set_attr "type" "icmp")
792   (set_attr "mode" "QI")])
793
794(define_insn "*cmpqi_ext_4"
795  [(set (reg FLAGS_REG)
796	(compare
797	  (subreg:QI
798	    (zero_extract:SI
799	      (match_operand 0 "ext_register_operand" "Q")
800	      (const_int 8)
801	      (const_int 8)) 0)
802	  (subreg:QI
803	    (zero_extract:SI
804	      (match_operand 1 "ext_register_operand" "Q")
805	      (const_int 8)
806	      (const_int 8)) 0)))]
807  "ix86_match_ccmode (insn, CCmode)"
808  "cmp{b}\t{%h1, %h0|%h0, %h1}"
809  [(set_attr "type" "icmp")
810   (set_attr "mode" "QI")])
811
812;; These implement float point compares.
813;; %%% See if we can get away with VOIDmode operands on the actual insns,
814;; which would allow mix and match FP modes on the compares.  Which is what
815;; the old patterns did, but with many more of them.
816
817(define_expand "cmpxf"
818  [(set (reg:CC FLAGS_REG)
819	(compare:CC (match_operand:XF 0 "nonmemory_operand" "")
820		    (match_operand:XF 1 "nonmemory_operand" "")))]
821  "TARGET_80387"
822{
823  ix86_compare_op0 = operands[0];
824  ix86_compare_op1 = operands[1];
825  DONE;
826})
827
828(define_expand "cmpdf"
829  [(set (reg:CC FLAGS_REG)
830	(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
831		    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
832  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
833{
834  ix86_compare_op0 = operands[0];
835  ix86_compare_op1 = operands[1];
836  DONE;
837})
838
839(define_expand "cmpsf"
840  [(set (reg:CC FLAGS_REG)
841	(compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
842		    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
843  "TARGET_80387 || TARGET_SSE_MATH"
844{
845  ix86_compare_op0 = operands[0];
846  ix86_compare_op1 = operands[1];
847  DONE;
848})
849
850;; FP compares, step 1:
851;; Set the FP condition codes.
852;;
853;; CCFPmode	compare with exceptions
854;; CCFPUmode	compare with no exceptions
855
856;; We may not use "#" to split and emit these, since the REG_DEAD notes
857;; used to manage the reg stack popping would not be preserved.
858
859(define_insn "*cmpfp_0"
860  [(set (match_operand:HI 0 "register_operand" "=a")
861	(unspec:HI
862	  [(compare:CCFP
863	     (match_operand 1 "register_operand" "f")
864	     (match_operand 2 "const0_operand" "X"))]
865	UNSPEC_FNSTSW))]
866  "TARGET_80387
867   && FLOAT_MODE_P (GET_MODE (operands[1]))
868   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
869  "* return output_fp_compare (insn, operands, 0, 0);"
870  [(set_attr "type" "multi")
871   (set_attr "unit" "i387")
872   (set (attr "mode")
873     (cond [(match_operand:SF 1 "" "")
874	      (const_string "SF")
875	    (match_operand:DF 1 "" "")
876	      (const_string "DF")
877	   ]
878	   (const_string "XF")))])
879
880(define_insn "*cmpfp_sf"
881  [(set (match_operand:HI 0 "register_operand" "=a")
882	(unspec:HI
883	  [(compare:CCFP
884	     (match_operand:SF 1 "register_operand" "f")
885	     (match_operand:SF 2 "nonimmediate_operand" "fm"))]
886	  UNSPEC_FNSTSW))]
887  "TARGET_80387"
888  "* return output_fp_compare (insn, operands, 0, 0);"
889  [(set_attr "type" "multi")
890   (set_attr "unit" "i387")
891   (set_attr "mode" "SF")])
892
893(define_insn "*cmpfp_df"
894  [(set (match_operand:HI 0 "register_operand" "=a")
895	(unspec:HI
896	  [(compare:CCFP
897	     (match_operand:DF 1 "register_operand" "f")
898	     (match_operand:DF 2 "nonimmediate_operand" "fm"))]
899	  UNSPEC_FNSTSW))]
900  "TARGET_80387"
901  "* return output_fp_compare (insn, operands, 0, 0);"
902  [(set_attr "type" "multi")
903   (set_attr "unit" "i387")
904   (set_attr "mode" "DF")])
905
906(define_insn "*cmpfp_xf"
907  [(set (match_operand:HI 0 "register_operand" "=a")
908	(unspec:HI
909	  [(compare:CCFP
910	     (match_operand:XF 1 "register_operand" "f")
911	     (match_operand:XF 2 "register_operand" "f"))]
912	  UNSPEC_FNSTSW))]
913  "TARGET_80387"
914  "* return output_fp_compare (insn, operands, 0, 0);"
915  [(set_attr "type" "multi")
916   (set_attr "unit" "i387")
917   (set_attr "mode" "XF")])
918
919(define_insn "*cmpfp_u"
920  [(set (match_operand:HI 0 "register_operand" "=a")
921	(unspec:HI
922	  [(compare:CCFPU
923	     (match_operand 1 "register_operand" "f")
924	     (match_operand 2 "register_operand" "f"))]
925	  UNSPEC_FNSTSW))]
926  "TARGET_80387
927   && FLOAT_MODE_P (GET_MODE (operands[1]))
928   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
929  "* return output_fp_compare (insn, operands, 0, 1);"
930  [(set_attr "type" "multi")
931   (set_attr "unit" "i387")
932   (set (attr "mode")
933     (cond [(match_operand:SF 1 "" "")
934	      (const_string "SF")
935	    (match_operand:DF 1 "" "")
936	      (const_string "DF")
937	   ]
938	   (const_string "XF")))])
939
940(define_insn "*cmpfp_<mode>"
941  [(set (match_operand:HI 0 "register_operand" "=a")
942	(unspec:HI
943	  [(compare:CCFP
944	     (match_operand 1 "register_operand" "f")
945	     (match_operator 3 "float_operator"
946	       [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
947	  UNSPEC_FNSTSW))]
948  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
949   && FLOAT_MODE_P (GET_MODE (operands[1]))
950   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
951  "* return output_fp_compare (insn, operands, 0, 0);"
952  [(set_attr "type" "multi")
953   (set_attr "unit" "i387")
954   (set_attr "fp_int_src" "true")
955   (set_attr "mode" "<MODE>")])
956
957;; FP compares, step 2
958;; Move the fpsw to ax.
959
960(define_insn "x86_fnstsw_1"
961  [(set (match_operand:HI 0 "register_operand" "=a")
962	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
963  "TARGET_80387"
964  "fnstsw\t%0"
965  [(set_attr "length" "2")
966   (set_attr "mode" "SI")
967   (set_attr "unit" "i387")])
968
969;; FP compares, step 3
970;; Get ax into flags, general case.
971
972(define_insn "x86_sahf_1"
973  [(set (reg:CC FLAGS_REG)
974	(unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975  "!TARGET_64BIT"
976  "sahf"
977  [(set_attr "length" "1")
978   (set_attr "athlon_decode" "vector")
979   (set_attr "amdfam10_decode" "direct")
980   (set_attr "mode" "SI")])
981
982;; Pentium Pro can do steps 1 through 3 in one go.
983;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
984(define_insn "*cmpfp_i_mixed"
985  [(set (reg:CCFP FLAGS_REG)
986	(compare:CCFP (match_operand 0 "register_operand" "f,x")
987		      (match_operand 1 "nonimmediate_operand" "f,xm")))]
988  "TARGET_MIX_SSE_I387
989   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991  "* return output_fp_compare (insn, operands, 1, 0);"
992  [(set_attr "type" "fcmp,ssecomi")
993   (set (attr "mode")
994     (if_then_else (match_operand:SF 1 "" "")
995        (const_string "SF")
996        (const_string "DF")))
997   (set_attr "athlon_decode" "vector")
998   (set_attr "amdfam10_decode" "direct")])
999
1000(define_insn "*cmpfp_i_sse"
1001  [(set (reg:CCFP FLAGS_REG)
1002	(compare:CCFP (match_operand 0 "register_operand" "x")
1003		      (match_operand 1 "nonimmediate_operand" "xm")))]
1004  "TARGET_SSE_MATH
1005   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1006   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007  "* return output_fp_compare (insn, operands, 1, 0);"
1008  [(set_attr "type" "ssecomi")
1009   (set (attr "mode")
1010     (if_then_else (match_operand:SF 1 "" "")
1011        (const_string "SF")
1012        (const_string "DF")))
1013   (set_attr "athlon_decode" "vector")
1014   (set_attr "amdfam10_decode" "direct")])
1015
1016(define_insn "*cmpfp_i_i387"
1017  [(set (reg:CCFP FLAGS_REG)
1018	(compare:CCFP (match_operand 0 "register_operand" "f")
1019		      (match_operand 1 "register_operand" "f")))]
1020  "TARGET_80387 && TARGET_CMOVE
1021   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1022   && FLOAT_MODE_P (GET_MODE (operands[0]))
1023   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1024  "* return output_fp_compare (insn, operands, 1, 0);"
1025  [(set_attr "type" "fcmp")
1026   (set (attr "mode")
1027     (cond [(match_operand:SF 1 "" "")
1028	      (const_string "SF")
1029	    (match_operand:DF 1 "" "")
1030	      (const_string "DF")
1031	   ]
1032	   (const_string "XF")))
1033   (set_attr "athlon_decode" "vector")
1034   (set_attr "amdfam10_decode" "direct")])
1035
1036(define_insn "*cmpfp_iu_mixed"
1037  [(set (reg:CCFPU FLAGS_REG)
1038	(compare:CCFPU (match_operand 0 "register_operand" "f,x")
1039		       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1040  "TARGET_MIX_SSE_I387
1041   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1042   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1043  "* return output_fp_compare (insn, operands, 1, 1);"
1044  [(set_attr "type" "fcmp,ssecomi")
1045   (set (attr "mode")
1046     (if_then_else (match_operand:SF 1 "" "")
1047        (const_string "SF")
1048        (const_string "DF")))
1049   (set_attr "athlon_decode" "vector")
1050   (set_attr "amdfam10_decode" "direct")])
1051
1052(define_insn "*cmpfp_iu_sse"
1053  [(set (reg:CCFPU FLAGS_REG)
1054	(compare:CCFPU (match_operand 0 "register_operand" "x")
1055		       (match_operand 1 "nonimmediate_operand" "xm")))]
1056  "TARGET_SSE_MATH
1057   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1058   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1059  "* return output_fp_compare (insn, operands, 1, 1);"
1060  [(set_attr "type" "ssecomi")
1061   (set (attr "mode")
1062     (if_then_else (match_operand:SF 1 "" "")
1063        (const_string "SF")
1064        (const_string "DF")))
1065   (set_attr "athlon_decode" "vector")
1066   (set_attr "amdfam10_decode" "direct")])
1067
1068(define_insn "*cmpfp_iu_387"
1069  [(set (reg:CCFPU FLAGS_REG)
1070	(compare:CCFPU (match_operand 0 "register_operand" "f")
1071		       (match_operand 1 "register_operand" "f")))]
1072  "TARGET_80387 && TARGET_CMOVE
1073   && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1074   && FLOAT_MODE_P (GET_MODE (operands[0]))
1075   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1076  "* return output_fp_compare (insn, operands, 1, 1);"
1077  [(set_attr "type" "fcmp")
1078   (set (attr "mode")
1079     (cond [(match_operand:SF 1 "" "")
1080	      (const_string "SF")
1081	    (match_operand:DF 1 "" "")
1082	      (const_string "DF")
1083	   ]
1084	   (const_string "XF")))
1085   (set_attr "athlon_decode" "vector")
1086   (set_attr "amdfam10_decode" "direct")])
1087
1088;; Move instructions.
1089
1090;; General case of fullword move.
1091
1092(define_expand "movsi"
1093  [(set (match_operand:SI 0 "nonimmediate_operand" "")
1094	(match_operand:SI 1 "general_operand" ""))]
1095  ""
1096  "ix86_expand_move (SImode, operands); DONE;")
1097
1098;; Push/pop instructions.  They are separate since autoinc/dec is not a
1099;; general_operand.
1100;;
1101;; %%% We don't use a post-inc memory reference because x86 is not a 
1102;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1103;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1104;; targets without our curiosities, and it is just as easy to represent
1105;; this differently.
1106
1107(define_insn "*pushsi2"
1108  [(set (match_operand:SI 0 "push_operand" "=<")
1109	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1110  "!TARGET_64BIT"
1111  "push{l}\t%1"
1112  [(set_attr "type" "push")
1113   (set_attr "mode" "SI")])
1114
1115;; For 64BIT abi we always round up to 8 bytes.
1116(define_insn "*pushsi2_rex64"
1117  [(set (match_operand:SI 0 "push_operand" "=X")
1118	(match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1119  "TARGET_64BIT"
1120  "push{q}\t%q1"
1121  [(set_attr "type" "push")
1122   (set_attr "mode" "SI")])
1123
1124(define_insn "*pushsi2_prologue"
1125  [(set (match_operand:SI 0 "push_operand" "=<")
1126	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1127   (clobber (mem:BLK (scratch)))]
1128  "!TARGET_64BIT"
1129  "push{l}\t%1"
1130  [(set_attr "type" "push")
1131   (set_attr "mode" "SI")])
1132
1133(define_insn "*popsi1_epilogue"
1134  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1135	(mem:SI (reg:SI SP_REG)))
1136   (set (reg:SI SP_REG)
1137	(plus:SI (reg:SI SP_REG) (const_int 4)))
1138   (clobber (mem:BLK (scratch)))]
1139  "!TARGET_64BIT"
1140  "pop{l}\t%0"
1141  [(set_attr "type" "pop")
1142   (set_attr "mode" "SI")])
1143
1144(define_insn "popsi1"
1145  [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1146	(mem:SI (reg:SI SP_REG)))
1147   (set (reg:SI SP_REG)
1148	(plus:SI (reg:SI SP_REG) (const_int 4)))]
1149  "!TARGET_64BIT"
1150  "pop{l}\t%0"
1151  [(set_attr "type" "pop")
1152   (set_attr "mode" "SI")])
1153
1154(define_insn "*movsi_xor"
1155  [(set (match_operand:SI 0 "register_operand" "=r")
1156	(match_operand:SI 1 "const0_operand" "i"))
1157   (clobber (reg:CC FLAGS_REG))]
1158  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1159  "xor{l}\t{%0, %0|%0, %0}"
1160  [(set_attr "type" "alu1")
1161   (set_attr "mode" "SI")
1162   (set_attr "length_immediate" "0")])
1163 
1164(define_insn "*movsi_or"
1165  [(set (match_operand:SI 0 "register_operand" "=r")
1166	(match_operand:SI 1 "immediate_operand" "i"))
1167   (clobber (reg:CC FLAGS_REG))]
1168  "reload_completed
1169   && operands[1] == constm1_rtx
1170   && (TARGET_PENTIUM || optimize_size)"
1171{
1172  operands[1] = constm1_rtx;
1173  return "or{l}\t{%1, %0|%0, %1}";
1174}
1175  [(set_attr "type" "alu1")
1176   (set_attr "mode" "SI")
1177   (set_attr "length_immediate" "1")])
1178
1179(define_insn "*movsi_1"
1180  [(set (match_operand:SI 0 "nonimmediate_operand"
1181			"=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1182	(match_operand:SI 1 "general_operand"
1183			"rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1184  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1185{
1186  switch (get_attr_type (insn))
1187    {
1188    case TYPE_SSELOG1:
1189      if (get_attr_mode (insn) == MODE_TI)
1190        return "pxor\t%0, %0";
1191      return "xorps\t%0, %0";
1192
1193    case TYPE_SSEMOV:
1194      switch (get_attr_mode (insn))
1195	{
1196	case MODE_TI:
1197	  return "movdqa\t{%1, %0|%0, %1}";
1198	case MODE_V4SF:
1199	  return "movaps\t{%1, %0|%0, %1}";
1200	case MODE_SI:
1201          return "movd\t{%1, %0|%0, %1}";
1202	case MODE_SF:
1203          return "movss\t{%1, %0|%0, %1}";
1204	default:
1205	  gcc_unreachable ();
1206	}
1207
1208    case TYPE_MMXADD:
1209      return "pxor\t%0, %0";
1210
1211    case TYPE_MMXMOV:
1212      if (get_attr_mode (insn) == MODE_DI)
1213	return "movq\t{%1, %0|%0, %1}";
1214      return "movd\t{%1, %0|%0, %1}";
1215
1216    case TYPE_LEA:
1217      return "lea{l}\t{%1, %0|%0, %1}";
1218
1219    default:
1220      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1221      return "mov{l}\t{%1, %0|%0, %1}";
1222    }
1223}
1224  [(set (attr "type")
1225     (cond [(eq_attr "alternative" "2")
1226	      (const_string "mmxadd")
1227	    (eq_attr "alternative" "3,4,5")
1228	      (const_string "mmxmov")
1229	    (eq_attr "alternative" "6")
1230	      (const_string "sselog1")
1231	    (eq_attr "alternative" "7,8,9,10,11")
1232	      (const_string "ssemov")
1233 	    (match_operand:DI 1 "pic_32bit_operand" "")
1234	      (const_string "lea")
1235	   ]
1236	   (const_string "imov")))
1237   (set (attr "mode")
1238     (cond [(eq_attr "alternative" "2,3")
1239	      (const_string "DI")
1240	    (eq_attr "alternative" "6,7")
1241	      (if_then_else
1242	        (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1243	        (const_string "V4SF")
1244	        (const_string "TI"))
1245	    (and (eq_attr "alternative" "8,9,10,11")
1246	         (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1247	      (const_string "SF")
1248	   ]
1249	   (const_string "SI")))])
1250
1251;; Stores and loads of ax to arbitrary constant address.
1252;; We fake an second form of instruction to force reload to load address
1253;; into register when rax is not available
1254(define_insn "*movabssi_1_rex64"
1255  [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1256	(match_operand:SI 1 "nonmemory_operand" "a,er"))]
1257  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1258  "@
1259   movabs{l}\t{%1, %P0|%P0, %1}
1260   mov{l}\t{%1, %a0|%a0, %1}"
1261  [(set_attr "type" "imov")
1262   (set_attr "modrm" "0,*")
1263   (set_attr "length_address" "8,0")
1264   (set_attr "length_immediate" "0,*")
1265   (set_attr "memory" "store")
1266   (set_attr "mode" "SI")])
1267
1268(define_insn "*movabssi_2_rex64"
1269  [(set (match_operand:SI 0 "register_operand" "=a,r")
1270        (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1271  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1272  "@
1273   movabs{l}\t{%P1, %0|%0, %P1}
1274   mov{l}\t{%a1, %0|%0, %a1}"
1275  [(set_attr "type" "imov")
1276   (set_attr "modrm" "0,*")
1277   (set_attr "length_address" "8,0")
1278   (set_attr "length_immediate" "0")
1279   (set_attr "memory" "load")
1280   (set_attr "mode" "SI")])
1281
1282(define_insn "*swapsi"
1283  [(set (match_operand:SI 0 "register_operand" "+r")
1284	(match_operand:SI 1 "register_operand" "+r"))
1285   (set (match_dup 1)
1286	(match_dup 0))]
1287  ""
1288  "xchg{l}\t%1, %0"
1289  [(set_attr "type" "imov")
1290   (set_attr "mode" "SI")
1291   (set_attr "pent_pair" "np")
1292   (set_attr "athlon_decode" "vector")
1293   (set_attr "amdfam10_decode" "double")])   
1294
1295(define_expand "movhi"
1296  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1297        (match_operand:HI 1 "general_operand" ""))]
1298  ""
1299  "ix86_expand_move (HImode, operands); DONE;")
1300
1301(define_insn "*pushhi2"
1302  [(set (match_operand:HI 0 "push_operand" "=X")
1303	(match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1304  "!TARGET_64BIT"
1305  "push{l}\t%k1"
1306  [(set_attr "type" "push")
1307   (set_attr "mode" "SI")])
1308
1309;; For 64BIT abi we always round up to 8 bytes.
1310(define_insn "*pushhi2_rex64"
1311  [(set (match_operand:HI 0 "push_operand" "=X")
1312	(match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1313  "TARGET_64BIT"
1314  "push{q}\t%q1"
1315  [(set_attr "type" "push")
1316   (set_attr "mode" "DI")])
1317
1318(define_insn "*movhi_1"
1319  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1320	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1321  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1322{
1323  switch (get_attr_type (insn))
1324    {
1325    case TYPE_IMOVX:
1326      /* movzwl is faster than movw on p2 due to partial word stalls,
1327	 though not as fast as an aligned movl.  */
1328      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1329    default:
1330      if (get_attr_mode (insn) == MODE_SI)
1331        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1332      else
1333        return "mov{w}\t{%1, %0|%0, %1}";
1334    }
1335}
1336  [(set (attr "type")
1337     (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1338	      (const_string "imov")
1339	    (and (eq_attr "alternative" "0")
1340		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341			  (const_int 0))
1342		      (eq (symbol_ref "TARGET_HIMODE_MATH")
1343			  (const_int 0))))
1344	      (const_string "imov")
1345	    (and (eq_attr "alternative" "1,2")
1346		 (match_operand:HI 1 "aligned_operand" ""))
1347	      (const_string "imov")
1348	    (and (ne (symbol_ref "TARGET_MOVX")
1349		     (const_int 0))
1350		 (eq_attr "alternative" "0,2"))
1351	      (const_string "imovx")
1352	   ]
1353	   (const_string "imov")))
1354    (set (attr "mode")
1355      (cond [(eq_attr "type" "imovx")
1356	       (const_string "SI")
1357	     (and (eq_attr "alternative" "1,2")
1358		  (match_operand:HI 1 "aligned_operand" ""))
1359	       (const_string "SI")
1360	     (and (eq_attr "alternative" "0")
1361		  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1362			   (const_int 0))
1363		       (eq (symbol_ref "TARGET_HIMODE_MATH")
1364			   (const_int 0))))
1365	       (const_string "SI")
1366	    ]
1367	    (const_string "HI")))])
1368
1369;; Stores and loads of ax to arbitrary constant address.
1370;; We fake an second form of instruction to force reload to load address
1371;; into register when rax is not available
1372(define_insn "*movabshi_1_rex64"
1373  [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1374	(match_operand:HI 1 "nonmemory_operand" "a,er"))]
1375  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1376  "@
1377   movabs{w}\t{%1, %P0|%P0, %1}
1378   mov{w}\t{%1, %a0|%a0, %1}"
1379  [(set_attr "type" "imov")
1380   (set_attr "modrm" "0,*")
1381   (set_attr "length_address" "8,0")
1382   (set_attr "length_immediate" "0,*")
1383   (set_attr "memory" "store")
1384   (set_attr "mode" "HI")])
1385
1386(define_insn "*movabshi_2_rex64"
1387  [(set (match_operand:HI 0 "register_operand" "=a,r")
1388        (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1389  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1390  "@
1391   movabs{w}\t{%P1, %0|%0, %P1}
1392   mov{w}\t{%a1, %0|%0, %a1}"
1393  [(set_attr "type" "imov")
1394   (set_attr "modrm" "0,*")
1395   (set_attr "length_address" "8,0")
1396   (set_attr "length_immediate" "0")
1397   (set_attr "memory" "load")
1398   (set_attr "mode" "HI")])
1399
1400(define_insn "*swaphi_1"
1401  [(set (match_operand:HI 0 "register_operand" "+r")
1402	(match_operand:HI 1 "register_operand" "+r"))
1403   (set (match_dup 1)
1404	(match_dup 0))]
1405  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1406  "xchg{l}\t%k1, %k0"
1407  [(set_attr "type" "imov")
1408   (set_attr "mode" "SI")
1409   (set_attr "pent_pair" "np")
1410   (set_attr "athlon_decode" "vector")
1411   (set_attr "amdfam10_decode" "double")])   
1412
1413;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1414(define_insn "*swaphi_2"
1415  [(set (match_operand:HI 0 "register_operand" "+r")
1416	(match_operand:HI 1 "register_operand" "+r"))
1417   (set (match_dup 1)
1418	(match_dup 0))]
1419  "TARGET_PARTIAL_REG_STALL"
1420  "xchg{w}\t%1, %0"
1421  [(set_attr "type" "imov")
1422   (set_attr "mode" "HI")
1423   (set_attr "pent_pair" "np")
1424   (set_attr "athlon_decode" "vector")])
1425
1426(define_expand "movstricthi"
1427  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1428	(match_operand:HI 1 "general_operand" ""))]
1429  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1430{
1431  /* Don't generate memory->memory moves, go through a register */
1432  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1433    operands[1] = force_reg (HImode, operands[1]);
1434})
1435
1436(define_insn "*movstricthi_1"
1437  [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1438	(match_operand:HI 1 "general_operand" "rn,m"))]
1439  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1440   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1441  "mov{w}\t{%1, %0|%0, %1}"
1442  [(set_attr "type" "imov")
1443   (set_attr "mode" "HI")])
1444
1445(define_insn "*movstricthi_xor"
1446  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1447	(match_operand:HI 1 "const0_operand" "i"))
1448   (clobber (reg:CC FLAGS_REG))]
1449  "reload_completed
1450   && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1451  "xor{w}\t{%0, %0|%0, %0}"
1452  [(set_attr "type" "alu1")
1453   (set_attr "mode" "HI")
1454   (set_attr "length_immediate" "0")])
1455
1456(define_expand "movqi"
1457  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1458	(match_operand:QI 1 "general_operand" ""))]
1459  ""
1460  "ix86_expand_move (QImode, operands); DONE;")
1461
1462;; emit_push_insn when it calls move_by_pieces requires an insn to
1463;; "push a byte".  But actually we use pushl, which has the effect
1464;; of rounding the amount pushed up to a word.
1465
1466(define_insn "*pushqi2"
1467  [(set (match_operand:QI 0 "push_operand" "=X")
1468	(match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1469  "!TARGET_64BIT"
1470  "push{l}\t%k1"
1471  [(set_attr "type" "push")
1472   (set_attr "mode" "SI")])
1473
1474;; For 64BIT abi we always round up to 8 bytes.
1475(define_insn "*pushqi2_rex64"
1476  [(set (match_operand:QI 0 "push_operand" "=X")
1477	(match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1478  "TARGET_64BIT"
1479  "push{q}\t%q1"
1480  [(set_attr "type" "push")
1481   (set_attr "mode" "DI")])
1482
1483;; Situation is quite tricky about when to choose full sized (SImode) move
1484;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1485;; partial register dependency machines (such as AMD Athlon), where QImode
1486;; moves issue extra dependency and for partial register stalls machines
1487;; that don't use QImode patterns (and QImode move cause stall on the next
1488;; instruction).
1489;;
1490;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1491;; register stall machines with, where we use QImode instructions, since
1492;; partial register stall can be caused there.  Then we use movzx.
1493(define_insn "*movqi_1"
1494  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1495	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1496  "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1497{
1498  switch (get_attr_type (insn))
1499    {
1500    case TYPE_IMOVX:
1501      gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1502      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1503    default:
1504      if (get_attr_mode (insn) == MODE_SI)
1505        return "mov{l}\t{%k1, %k0|%k0, %k1}";
1506      else
1507        return "mov{b}\t{%1, %0|%0, %1}";
1508    }
1509}
1510  [(set (attr "type")
1511     (cond [(and (eq_attr "alternative" "5")
1512		 (not (match_operand:QI 1 "aligned_operand" "")))
1513	      (const_string "imovx")
1514	    (ne (symbol_ref "optimize_size") (const_int 0))
1515	      (const_string "imov")
1516	    (and (eq_attr "alternative" "3")
1517		 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518			  (const_int 0))
1519		      (eq (symbol_ref "TARGET_QIMODE_MATH")
1520			  (const_int 0))))
1521	      (const_string "imov")
1522	    (eq_attr "alternative" "3,5")
1523	      (const_string "imovx")
1524	    (and (ne (symbol_ref "TARGET_MOVX")
1525		     (const_int 0))
1526		 (eq_attr "alternative" "2"))
1527	      (const_string "imovx")
1528	   ]
1529	   (const_string "imov")))
1530   (set (attr "mode")
1531      (cond [(eq_attr "alternative" "3,4,5")
1532	       (const_string "SI")
1533	     (eq_attr "alternative" "6")
1534	       (const_string "QI")
1535	     (eq_attr "type" "imovx")
1536	       (const_string "SI")
1537	     (and (eq_attr "type" "imov")
1538		  (and (eq_attr "alternative" "0,1")
1539		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1540				(const_int 0))
1541			    (and (eq (symbol_ref "optimize_size")
1542				     (const_int 0))
1543			    	 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1544				     (const_int 0))))))
1545	       (const_string "SI")
1546	     ;; Avoid partial register stalls when not using QImode arithmetic
1547	     (and (eq_attr "type" "imov")
1548		  (and (eq_attr "alternative" "0,1")
1549		       (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1550				(const_int 0))
1551			    (eq (symbol_ref "TARGET_QIMODE_MATH")
1552				(const_int 0)))))
1553	       (const_string "SI")
1554	   ]
1555	   (const_string "QI")))])
1556
1557(define_expand "reload_outqi"
1558  [(parallel [(match_operand:QI 0 "" "=m")
1559              (match_operand:QI 1 "register_operand" "r")
1560              (match_operand:QI 2 "register_operand" "=&q")])]
1561  ""
1562{
1563  rtx op0, op1, op2;
1564  op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1565
1566  gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1567  if (! q_regs_operand (op1, QImode))
1568    {
1569      emit_insn (gen_movqi (op2, op1));
1570      op1 = op2;
1571    }
1572  emit_insn (gen_movqi (op0, op1));
1573  DONE;
1574})
1575
1576(define_insn "*swapqi_1"
1577  [(set (match_operand:QI 0 "register_operand" "+r")
1578	(match_operand:QI 1 "register_operand" "+r"))
1579   (set (match_dup 1)
1580	(match_dup 0))]
1581  "!TARGET_PARTIAL_REG_STALL || optimize_size"
1582  "xchg{l}\t%k1, %k0"
1583  [(set_attr "type" "imov")
1584   (set_attr "mode" "SI")
1585   (set_attr "pent_pair" "np")
1586   (set_attr "athlon_decode" "vector")
1587   (set_attr "amdfam10_decode" "vector")])   
1588
1589;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1590(define_insn "*swapqi_2"
1591  [(set (match_operand:QI 0 "register_operand" "+q")
1592	(match_operand:QI 1 "register_operand" "+q"))
1593   (set (match_dup 1)
1594	(match_dup 0))]
1595  "TARGET_PARTIAL_REG_STALL"
1596  "xchg{b}\t%1, %0"
1597  [(set_attr "type" "imov")
1598   (set_attr "mode" "QI")
1599   (set_attr "pent_pair" "np")
1600   (set_attr "athlon_decode" "vector")])
1601
1602(define_expand "movstrictqi"
1603  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1604	(match_operand:QI 1 "general_operand" ""))]
1605  "! TARGET_PARTIAL_REG_STALL || optimize_size"
1606{
1607  /* Don't generate memory->memory moves, go through a register.  */
1608  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1609    operands[1] = force_reg (QImode, operands[1]);
1610})
1611
1612(define_insn "*movstrictqi_1"
1613  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1614	(match_operand:QI 1 "general_operand" "*qn,m"))]
1615  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1616   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1617  "mov{b}\t{%1, %0|%0, %1}"
1618  [(set_attr "type" "imov")
1619   (set_attr "mode" "QI")])
1620
1621(define_insn "*movstrictqi_xor"
1622  [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1623	(match_operand:QI 1 "const0_operand" "i"))
1624   (clobber (reg:CC FLAGS_REG))]
1625  "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1626  "xor{b}\t{%0, %0|%0, %0}"
1627  [(set_attr "type" "alu1")
1628   (set_attr "mode" "QI")
1629   (set_attr "length_immediate" "0")])
1630
1631(define_insn "*movsi_extv_1"
1632  [(set (match_operand:SI 0 "register_operand" "=R")
1633	(sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1634			 (const_int 8)
1635			 (const_int 8)))]
1636  ""
1637  "movs{bl|x}\t{%h1, %0|%0, %h1}"
1638  [(set_attr "type" "imovx")
1639   (set_attr "mode" "SI")])
1640
1641(define_insn "*movhi_extv_1"
1642  [(set (match_operand:HI 0 "register_operand" "=R")
1643	(sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1644			 (const_int 8)
1645			 (const_int 8)))]
1646  ""
1647  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1648  [(set_attr "type" "imovx")
1649   (set_attr "mode" "SI")])
1650
1651(define_insn "*movqi_extv_1"
1652  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1653        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1654                         (const_int 8)
1655                         (const_int 8)))]
1656  "!TARGET_64BIT"
1657{
1658  switch (get_attr_type (insn))
1659    {
1660    case TYPE_IMOVX:
1661      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1662    default:
1663      return "mov{b}\t{%h1, %0|%0, %h1}";
1664    }
1665}
1666  [(set (attr "type")
1667     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1668			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1669			     (ne (symbol_ref "TARGET_MOVX")
1670				 (const_int 0))))
1671	(const_string "imovx")
1672	(const_string "imov")))
1673   (set (attr "mode")
1674     (if_then_else (eq_attr "type" "imovx")
1675	(const_string "SI")
1676	(const_string "QI")))])
1677
1678(define_insn "*movqi_extv_1_rex64"
1679  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1680        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1681                         (const_int 8)
1682                         (const_int 8)))]
1683  "TARGET_64BIT"
1684{
1685  switch (get_attr_type (insn))
1686    {
1687    case TYPE_IMOVX:
1688      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1689    default:
1690      return "mov{b}\t{%h1, %0|%0, %h1}";
1691    }
1692}
1693  [(set (attr "type")
1694     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1695			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1696			     (ne (symbol_ref "TARGET_MOVX")
1697				 (const_int 0))))
1698	(const_string "imovx")
1699	(const_string "imov")))
1700   (set (attr "mode")
1701     (if_then_else (eq_attr "type" "imovx")
1702	(const_string "SI")
1703	(const_string "QI")))])
1704
1705;; Stores and loads of ax to arbitrary constant address.
1706;; We fake an second form of instruction to force reload to load address
1707;; into register when rax is not available
1708(define_insn "*movabsqi_1_rex64"
1709  [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1710	(match_operand:QI 1 "nonmemory_operand" "a,er"))]
1711  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1712  "@
1713   movabs{b}\t{%1, %P0|%P0, %1}
1714   mov{b}\t{%1, %a0|%a0, %1}"
1715  [(set_attr "type" "imov")
1716   (set_attr "modrm" "0,*")
1717   (set_attr "length_address" "8,0")
1718   (set_attr "length_immediate" "0,*")
1719   (set_attr "memory" "store")
1720   (set_attr "mode" "QI")])
1721
1722(define_insn "*movabsqi_2_rex64"
1723  [(set (match_operand:QI 0 "register_operand" "=a,r")
1724        (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1725  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1726  "@
1727   movabs{b}\t{%P1, %0|%0, %P1}
1728   mov{b}\t{%a1, %0|%0, %a1}"
1729  [(set_attr "type" "imov")
1730   (set_attr "modrm" "0,*")
1731   (set_attr "length_address" "8,0")
1732   (set_attr "length_immediate" "0")
1733   (set_attr "memory" "load")
1734   (set_attr "mode" "QI")])
1735
1736(define_insn "*movdi_extzv_1"
1737  [(set (match_operand:DI 0 "register_operand" "=R")
1738	(zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1739			 (const_int 8)
1740			 (const_int 8)))]
1741  "TARGET_64BIT"
1742  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1743  [(set_attr "type" "imovx")
1744   (set_attr "mode" "DI")])
1745
1746(define_insn "*movsi_extzv_1"
1747  [(set (match_operand:SI 0 "register_operand" "=R")
1748	(zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1749			 (const_int 8)
1750			 (const_int 8)))]
1751  ""
1752  "movz{bl|x}\t{%h1, %0|%0, %h1}"
1753  [(set_attr "type" "imovx")
1754   (set_attr "mode" "SI")])
1755
1756(define_insn "*movqi_extzv_2"
1757  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1758        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1759				    (const_int 8)
1760				    (const_int 8)) 0))]
1761  "!TARGET_64BIT"
1762{
1763  switch (get_attr_type (insn))
1764    {
1765    case TYPE_IMOVX:
1766      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1767    default:
1768      return "mov{b}\t{%h1, %0|%0, %h1}";
1769    }
1770}
1771  [(set (attr "type")
1772     (if_then_else (and (match_operand:QI 0 "register_operand" "")
1773			(ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774			     (ne (symbol_ref "TARGET_MOVX")
1775				 (const_int 0))))
1776	(const_string "imovx")
1777	(const_string "imov")))
1778   (set (attr "mode")
1779     (if_then_else (eq_attr "type" "imovx")
1780	(const_string "SI")
1781	(const_string "QI")))])
1782
1783(define_insn "*movqi_extzv_2_rex64"
1784  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1785        (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1786				    (const_int 8)
1787				    (const_int 8)) 0))]
1788  "TARGET_64BIT"
1789{
1790  switch (get_attr_type (insn))
1791    {
1792    case TYPE_IMOVX:
1793      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1794    default:
1795      return "mov{b}\t{%h1, %0|%0, %h1}";
1796    }
1797}
1798  [(set (attr "type")
1799     (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1800			(ne (symbol_ref "TARGET_MOVX")
1801			    (const_int 0)))
1802	(const_string "imovx")
1803	(const_string "imov")))
1804   (set (attr "mode")
1805     (if_then_else (eq_attr "type" "imovx")
1806	(const_string "SI")
1807	(const_string "QI")))])
1808
1809(define_insn "movsi_insv_1"
1810  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1811			 (const_int 8)
1812			 (const_int 8))
1813	(match_operand:SI 1 "general_operand" "Qmn"))]
1814  "!TARGET_64BIT"
1815  "mov{b}\t{%b1, %h0|%h0, %b1}"
1816  [(set_attr "type" "imov")
1817   (set_attr "mode" "QI")])
1818
1819(define_insn "movdi_insv_1_rex64"
1820  [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1821			 (const_int 8)
1822			 (const_int 8))
1823	(match_operand:DI 1 "nonmemory_operand" "Qn"))]
1824  "TARGET_64BIT"
1825  "mov{b}\t{%b1, %h0|%h0, %b1}"
1826  [(set_attr "type" "imov")
1827   (set_attr "mode" "QI")])
1828
1829(define_insn "*movqi_insv_2"
1830  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1831			 (const_int 8)
1832			 (const_int 8))
1833	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1834		     (const_int 8)))]
1835  ""
1836  "mov{b}\t{%h1, %h0|%h0, %h1}"
1837  [(set_attr "type" "imov")
1838   (set_attr "mode" "QI")])
1839
1840(define_expand "movdi"
1841  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1842	(match_operand:DI 1 "general_operand" ""))]
1843  ""
1844  "ix86_expand_move (DImode, operands); DONE;")
1845
1846(define_insn "*pushdi"
1847  [(set (match_operand:DI 0 "push_operand" "=<")
1848	(match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1849  "!TARGET_64BIT"
1850  "#")
1851
1852(define_insn "*pushdi2_rex64"
1853  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1854	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1855  "TARGET_64BIT"
1856  "@
1857   push{q}\t%1
1858   #"
1859  [(set_attr "type" "push,multi")
1860   (set_attr "mode" "DI")])
1861
1862;; Convert impossible pushes of immediate to existing instructions.
1863;; First try to get scratch register and go through it.  In case this
1864;; fails, push sign extended lower part first and then overwrite
1865;; upper part by 32bit move.
1866(define_peephole2
1867  [(match_scratch:DI 2 "r")
1868   (set (match_operand:DI 0 "push_operand" "")
1869        (match_operand:DI 1 "immediate_operand" ""))]
1870  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1871   && !x86_64_immediate_operand (operands[1], DImode)"
1872  [(set (match_dup 2) (match_dup 1))
1873   (set (match_dup 0) (match_dup 2))]
1874  "")
1875
1876;; We need to define this as both peepholer and splitter for case
1877;; peephole2 pass is not run.
1878;; "&& 1" is needed to keep it from matching the previous pattern.
1879(define_peephole2
1880  [(set (match_operand:DI 0 "push_operand" "")
1881        (match_operand:DI 1 "immediate_operand" ""))]
1882  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1883   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1884  [(set (match_dup 0) (match_dup 1))
1885   (set (match_dup 2) (match_dup 3))]
1886  "split_di (operands + 1, 1, operands + 2, operands + 3);
1887   operands[1] = gen_lowpart (DImode, operands[2]);
1888   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1889						    GEN_INT (4)));
1890  ")
1891
1892(define_split
1893  [(set (match_operand:DI 0 "push_operand" "")
1894        (match_operand:DI 1 "immediate_operand" ""))]
1895  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1896		    ? flow2_completed : reload_completed)
1897   && !symbolic_operand (operands[1], DImode)
1898   && !x86_64_immediate_operand (operands[1], DImode)"
1899  [(set (match_dup 0) (match_dup 1))
1900   (set (match_dup 2) (match_dup 3))]
1901  "split_di (operands + 1, 1, operands + 2, operands + 3);
1902   operands[1] = gen_lowpart (DImode, operands[2]);
1903   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1904						    GEN_INT (4)));
1905  ")
1906
1907(define_insn "*pushdi2_prologue_rex64"
1908  [(set (match_operand:DI 0 "push_operand" "=<")
1909	(match_operand:DI 1 "general_no_elim_operand" "re*m"))
1910   (clobber (mem:BLK (scratch)))]
1911  "TARGET_64BIT"
1912  "push{q}\t%1"
1913  [(set_attr "type" "push")
1914   (set_attr "mode" "DI")])
1915
1916(define_insn "*popdi1_epilogue_rex64"
1917  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918	(mem:DI (reg:DI SP_REG)))
1919   (set (reg:DI SP_REG)
1920	(plus:DI (reg:DI SP_REG) (const_int 8)))
1921   (clobber (mem:BLK (scratch)))]
1922  "TARGET_64BIT"
1923  "pop{q}\t%0"
1924  [(set_attr "type" "pop")
1925   (set_attr "mode" "DI")])
1926
1927(define_insn "popdi1"
1928  [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1929	(mem:DI (reg:DI SP_REG)))
1930   (set (reg:DI SP_REG)
1931	(plus:DI (reg:DI SP_REG) (const_int 8)))]
1932  "TARGET_64BIT"
1933  "pop{q}\t%0"
1934  [(set_attr "type" "pop")
1935   (set_attr "mode" "DI")])
1936
1937(define_insn "*movdi_xor_rex64"
1938  [(set (match_operand:DI 0 "register_operand" "=r")
1939	(match_operand:DI 1 "const0_operand" "i"))
1940   (clobber (reg:CC FLAGS_REG))]
1941  "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1942   && reload_completed"
1943  "xor{l}\t{%k0, %k0|%k0, %k0}"
1944  [(set_attr "type" "alu1")
1945   (set_attr "mode" "SI")
1946   (set_attr "length_immediate" "0")])
1947
1948(define_insn "*movdi_or_rex64"
1949  [(set (match_operand:DI 0 "register_operand" "=r")
1950	(match_operand:DI 1 "const_int_operand" "i"))
1951   (clobber (reg:CC FLAGS_REG))]
1952  "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1953   && reload_completed
1954   && operands[1] == constm1_rtx"
1955{
1956  operands[1] = constm1_rtx;
1957  return "or{q}\t{%1, %0|%0, %1}";
1958}
1959  [(set_attr "type" "alu1")
1960   (set_attr "mode" "DI")
1961   (set_attr "length_immediate" "1")])
1962
1963(define_insn "*movdi_2"
1964  [(set (match_operand:DI 0 "nonimmediate_operand"
1965				"=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1966	(match_operand:DI 1 "general_operand"
1967				"riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1968  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1969  "@
1970   #
1971   #
1972   pxor\t%0, %0
1973   movq\t{%1, %0|%0, %1}
1974   movq\t{%1, %0|%0, %1}
1975   pxor\t%0, %0
1976   movq\t{%1, %0|%0, %1}
1977   movdqa\t{%1, %0|%0, %1}
1978   movq\t{%1, %0|%0, %1}
1979   xorps\t%0, %0
1980   movlps\t{%1, %0|%0, %1}
1981   movaps\t{%1, %0|%0, %1}
1982   movlps\t{%1, %0|%0, %1}"
1983  [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1984   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1985
1986(define_split
1987  [(set (match_operand:DI 0 "push_operand" "")
1988        (match_operand:DI 1 "general_operand" ""))]
1989  "!TARGET_64BIT && reload_completed
1990   && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1991  [(const_int 0)]
1992  "ix86_split_long_move (operands); DONE;")
1993
1994;; %%% This multiword shite has got to go.
1995(define_split
1996  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1997        (match_operand:DI 1 "general_operand" ""))]
1998  "!TARGET_64BIT && reload_completed
1999   && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2000   && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2001  [(const_int 0)]
2002  "ix86_split_long_move (operands); DONE;")
2003
2004(define_insn "*movdi_1_rex64"
2005  [(set (match_operand:DI 0 "nonimmediate_operand"
2006		"=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2007	(match_operand:DI 1 "general_operand"
2008		"Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2009  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2010{
2011  switch (get_attr_type (insn))
2012    {
2013    case TYPE_SSECVT:
2014      if (which_alternative == 13)
2015	return "movq2dq\t{%1, %0|%0, %1}";
2016      else
2017	return "movdq2q\t{%1, %0|%0, %1}";
2018    case TYPE_SSEMOV:
2019      if (get_attr_mode (insn) == MODE_TI)
2020	  return "movdqa\t{%1, %0|%0, %1}";
2021      /* FALLTHRU */
2022    case TYPE_MMXMOV:
2023      /* Moves from and into integer register is done using movd opcode with
2024 	 REX prefix.  */
2025      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2026	  return "movd\t{%1, %0|%0, %1}";
2027      return "movq\t{%1, %0|%0, %1}";
2028    case TYPE_SSELOG1:
2029    case TYPE_MMXADD:
2030      return "pxor\t%0, %0";
2031    case TYPE_MULTI:
2032      return "#";
2033    case TYPE_LEA:
2034      return "lea{q}\t{%a1, %0|%0, %a1}";
2035    default:
2036      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2037      if (get_attr_mode (insn) == MODE_SI)
2038	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2039      else if (which_alternative == 2)
2040	return "movabs{q}\t{%1, %0|%0, %1}";
2041      else
2042	return "mov{q}\t{%1, %0|%0, %1}";
2043    }
2044}
2045  [(set (attr "type")
2046     (cond [(eq_attr "alternative" "5")
2047	      (const_string "mmxadd")
2048	    (eq_attr "alternative" "6,7,8")
2049	      (const_string "mmxmov")
2050	    (eq_attr "alternative" "9")
2051	      (const_string "sselog1")
2052	    (eq_attr "alternative" "10,11,12")
2053	      (const_string "ssemov")
2054	    (eq_attr "alternative" "13,14")
2055	      (const_string "ssecvt")
2056	    (eq_attr "alternative" "4")
2057	      (const_string "multi")
2058 	    (match_operand:DI 1 "pic_32bit_operand" "")
2059	      (const_string "lea")
2060	   ]
2061	   (const_string "imov")))
2062   (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2063   (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2064   (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2065
2066;; Stores and loads of ax to arbitrary constant address.
2067;; We fake an second form of instruction to force reload to load address
2068;; into register when rax is not available
2069(define_insn "*movabsdi_1_rex64"
2070  [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2071	(match_operand:DI 1 "nonmemory_operand" "a,er"))]
2072  "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2073  "@
2074   movabs{q}\t{%1, %P0|%P0, %1}
2075   mov{q}\t{%1, %a0|%a0, %1}"
2076  [(set_attr "type" "imov")
2077   (set_attr "modrm" "0,*")
2078   (set_attr "length_address" "8,0")
2079   (set_attr "length_immediate" "0,*")
2080   (set_attr "memory" "store")
2081   (set_attr "mode" "DI")])
2082
2083(define_insn "*movabsdi_2_rex64"
2084  [(set (match_operand:DI 0 "register_operand" "=a,r")
2085        (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2086  "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2087  "@
2088   movabs{q}\t{%P1, %0|%0, %P1}
2089   mov{q}\t{%a1, %0|%0, %a1}"
2090  [(set_attr "type" "imov")
2091   (set_attr "modrm" "0,*")
2092   (set_attr "length_address" "8,0")
2093   (set_attr "length_immediate" "0")
2094   (set_attr "memory" "load")
2095   (set_attr "mode" "DI")])
2096
2097;; Convert impossible stores of immediate to existing instructions.
2098;; First try to get scratch register and go through it.  In case this
2099;; fails, move by 32bit parts.
2100(define_peephole2
2101  [(match_scratch:DI 2 "r")
2102   (set (match_operand:DI 0 "memory_operand" "")
2103        (match_operand:DI 1 "immediate_operand" ""))]
2104  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2105   && !x86_64_immediate_operand (operands[1], DImode)"
2106  [(set (match_dup 2) (match_dup 1))
2107   (set (match_dup 0) (match_dup 2))]
2108  "")
2109
2110;; We need to define this as both peepholer and splitter for case
2111;; peephole2 pass is not run.
2112;; "&& 1" is needed to keep it from matching the previous pattern.
2113(define_peephole2
2114  [(set (match_operand:DI 0 "memory_operand" "")
2115        (match_operand:DI 1 "immediate_operand" ""))]
2116  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2117   && !x86_64_immediate_operand (operands[1], DImode) && 1"
2118  [(set (match_dup 2) (match_dup 3))
2119   (set (match_dup 4) (match_dup 5))]
2120  "split_di (operands, 2, operands + 2, operands + 4);")
2121
2122(define_split
2123  [(set (match_operand:DI 0 "memory_operand" "")
2124        (match_operand:DI 1 "immediate_operand" ""))]
2125  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2126		    ? flow2_completed : reload_completed)
2127   && !symbolic_operand (operands[1], DImode)
2128   && !x86_64_immediate_operand (operands[1], DImode)"
2129  [(set (match_dup 2) (match_dup 3))
2130   (set (match_dup 4) (match_dup 5))]
2131  "split_di (operands, 2, operands + 2, operands + 4);")
2132
2133(define_insn "*swapdi_rex64"
2134  [(set (match_operand:DI 0 "register_operand" "+r")
2135	(match_operand:DI 1 "register_operand" "+r"))
2136   (set (match_dup 1)
2137	(match_dup 0))]
2138  "TARGET_64BIT"
2139  "xchg{q}\t%1, %0"
2140  [(set_attr "type" "imov")
2141   (set_attr "mode" "DI")
2142   (set_attr "pent_pair" "np")
2143   (set_attr "athlon_decode" "vector")
2144   (set_attr "amdfam10_decode" "double")])   
2145
2146(define_expand "movti"
2147  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2148	(match_operand:TI 1 "nonimmediate_operand" ""))]
2149  "TARGET_SSE || TARGET_64BIT"
2150{
2151  if (TARGET_64BIT)
2152    ix86_expand_move (TImode, operands);
2153  else
2154    ix86_expand_vector_move (TImode, operands);
2155  DONE;
2156})
2157
2158(define_insn "*movti_internal"
2159  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2160	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2161  "TARGET_SSE && !TARGET_64BIT
2162   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2163{
2164  switch (which_alternative)
2165    {
2166    case 0:
2167      if (get_attr_mode (insn) == MODE_V4SF)
2168	return "xorps\t%0, %0";
2169      else
2170	return "pxor\t%0, %0";
2171    case 1:
2172    case 2:
2173      if (get_attr_mode (insn) == MODE_V4SF)
2174	return "movaps\t{%1, %0|%0, %1}";
2175      else
2176	return "movdqa\t{%1, %0|%0, %1}";
2177    default:
2178      gcc_unreachable ();
2179    }
2180}
2181  [(set_attr "type" "sselog1,ssemov,ssemov")
2182   (set (attr "mode")
2183	(cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2184		    (ne (symbol_ref "optimize_size") (const_int 0)))
2185		 (const_string "V4SF")
2186	       (and (eq_attr "alternative" "2")
2187		    (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2188			(const_int 0)))
2189		 (const_string "V4SF")]
2190	      (const_string "TI")))])
2191
2192(define_insn "*movti_rex64"
2193  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2194	(match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2195  "TARGET_64BIT
2196   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2197{
2198  switch (which_alternative)
2199    {
2200    case 0:
2201    case 1:
2202      return "#";
2203    case 2:
2204      if (get_attr_mode (insn) == MODE_V4SF)
2205	return "xorps\t%0, %0";
2206      else
2207	return "pxor\t%0, %0";
2208    case 3:
2209    case 4:
2210      if (get_attr_mode (insn) == MODE_V4SF)
2211	return "movaps\t{%1, %0|%0, %1}";
2212      else
2213	return "movdqa\t{%1, %0|%0, %1}";
2214    default:
2215      gcc_unreachable ();
2216    }
2217}
2218  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2219   (set (attr "mode")
2220        (cond [(eq_attr "alternative" "2,3")
2221		 (if_then_else
2222		   (ne (symbol_ref "optimize_size")
2223		       (const_int 0))
2224		   (const_string "V4SF")
2225		   (const_string "TI"))
2226	       (eq_attr "alternative" "4")
2227		 (if_then_else
2228		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2229			    (const_int 0))
2230			(ne (symbol_ref "optimize_size")
2231			    (const_int 0)))
2232		   (const_string "V4SF")
2233		   (const_string "TI"))]
2234	       (const_string "DI")))])
2235
2236(define_split
2237  [(set (match_operand:TI 0 "nonimmediate_operand" "")
2238        (match_operand:TI 1 "general_operand" ""))]
2239  "reload_completed && !SSE_REG_P (operands[0])
2240   && !SSE_REG_P (operands[1])"
2241  [(const_int 0)]
2242  "ix86_split_long_move (operands); DONE;")
2243
2244(define_expand "movsf"
2245  [(set (match_operand:SF 0 "nonimmediate_operand" "")
2246	(match_operand:SF 1 "general_operand" ""))]
2247  ""
2248  "ix86_expand_move (SFmode, operands); DONE;")
2249
2250(define_insn "*pushsf"
2251  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2252	(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2253  "!TARGET_64BIT"
2254{
2255  /* Anything else should be already split before reg-stack.  */
2256  gcc_assert (which_alternative == 1);
2257  return "push{l}\t%1";
2258}
2259  [(set_attr "type" "multi,push,multi")
2260   (set_attr "unit" "i387,*,*")
2261   (set_attr "mode" "SF,SI,SF")])
2262
2263(define_insn "*pushsf_rex64"
2264  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2265	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2266  "TARGET_64BIT"
2267{
2268  /* Anything else should be already split before reg-stack.  */
2269  gcc_assert (which_alternative == 1);
2270  return "push{q}\t%q1";
2271}
2272  [(set_attr "type" "multi,push,multi")
2273   (set_attr "unit" "i387,*,*")
2274   (set_attr "mode" "SF,DI,SF")])
2275
2276(define_split
2277  [(set (match_operand:SF 0 "push_operand" "")
2278	(match_operand:SF 1 "memory_operand" ""))]
2279  "reload_completed
2280   && GET_CODE (operands[1]) == MEM
2281   && constant_pool_reference_p (operands[1])"
2282  [(set (match_dup 0)
2283	(match_dup 1))]
2284  "operands[1] = avoid_constant_pool_reference (operands[1]);")
2285
2286
2287;; %%% Kill this when call knows how to work this out.
2288(define_split
2289  [(set (match_operand:SF 0 "push_operand" "")
2290	(match_operand:SF 1 "any_fp_register_operand" ""))]
2291  "!TARGET_64BIT"
2292  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2293   (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2294
2295(define_split
2296  [(set (match_operand:SF 0 "push_operand" "")
2297	(match_operand:SF 1 "any_fp_register_operand" ""))]
2298  "TARGET_64BIT"
2299  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2300   (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2301
2302(define_insn "*movsf_1"
2303  [(set (match_operand:SF 0 "nonimmediate_operand"
2304	  "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2305	(match_operand:SF 1 "general_operand"
2306	  "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2307  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2308   && (reload_in_progress || reload_completed
2309       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2310       || GET_CODE (operands[1]) != CONST_DOUBLE
2311       || memory_operand (operands[0], SFmode))" 
2312{
2313  switch (which_alternative)
2314    {
2315    case 0:
2316      return output_387_reg_move (insn, operands);
2317
2318    case 1:
2319      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320        return "fstp%z0\t%y0";
2321      else
2322        return "fst%z0\t%y0";
2323
2324    case 2:
2325      return standard_80387_constant_opcode (operands[1]);
2326
2327    case 3:
2328    case 4:
2329      return "mov{l}\t{%1, %0|%0, %1}";
2330    case 5:
2331      if (get_attr_mode (insn) == MODE_TI)
2332	return "pxor\t%0, %0";
2333      else
2334	return "xorps\t%0, %0";
2335    case 6:
2336      if (get_attr_mode (insn) == MODE_V4SF)
2337	return "movaps\t{%1, %0|%0, %1}";
2338      else
2339	return "movss\t{%1, %0|%0, %1}";
2340    case 7:
2341    case 8:
2342      return "movss\t{%1, %0|%0, %1}";
2343
2344    case 9:
2345    case 10:
2346      return "movd\t{%1, %0|%0, %1}";
2347
2348    case 11:
2349      return "movq\t{%1, %0|%0, %1}";
2350
2351    default:
2352      gcc_unreachable ();
2353    }
2354}
2355  [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2356   (set (attr "mode")
2357        (cond [(eq_attr "alternative" "3,4,9,10")
2358		 (const_string "SI")
2359	       (eq_attr "alternative" "5")
2360		 (if_then_else
2361		   (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2362			    	 (const_int 0))
2363			     (ne (symbol_ref "TARGET_SSE2")
2364				 (const_int 0)))
2365			(eq (symbol_ref "optimize_size")
2366			    (const_int 0)))
2367		   (const_string "TI")
2368		   (const_string "V4SF"))
2369	       /* For architectures resolving dependencies on
2370		  whole SSE registers use APS move to break dependency
2371		  chains, otherwise use short move to avoid extra work. 
2372
2373		  Do the same for architectures resolving dependencies on
2374		  the parts.  While in DF mode it is better to always handle
2375		  just register parts, the SF mode is different due to lack
2376		  of instructions to load just part of the register.  It is
2377		  better to maintain the whole registers in single format
2378		  to avoid problems on using packed logical operations.  */
2379	       (eq_attr "alternative" "6")
2380		 (if_then_else
2381		   (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2382			    (const_int 0))
2383			(ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2384			    (const_int 0)))
2385		   (const_string "V4SF")
2386		   (const_string "SF"))
2387	       (eq_attr "alternative" "11")
2388		 (const_string "DI")]
2389	       (const_string "SF")))])
2390
2391(define_insn "*swapsf"
2392  [(set (match_operand:SF 0 "fp_register_operand" "+f")
2393	(match_operand:SF 1 "fp_register_operand" "+f"))
2394   (set (match_dup 1)
2395	(match_dup 0))]
2396  "reload_completed || TARGET_80387"
2397{
2398  if (STACK_TOP_P (operands[0]))
2399    return "fxch\t%1";
2400  else
2401    return "fxch\t%0";
2402}
2403  [(set_attr "type" "fxch")
2404   (set_attr "mode" "SF")])
2405
2406(define_expand "movdf"
2407  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408	(match_operand:DF 1 "general_operand" ""))]
2409  ""
2410  "ix86_expand_move (DFmode, operands); DONE;")
2411
2412;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413;; Size of pushdf using integer instructions is 2+2*memory operand size
2414;; On the average, pushdf using integers can be still shorter.  Allow this
2415;; pattern for optimize_size too.
2416
2417(define_insn "*pushdf_nointeger"
2418  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419	(match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2420  "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2421{
2422  /* This insn should be already split before reg-stack.  */
2423  gcc_unreachable ();
2424}
2425  [(set_attr "type" "multi")
2426   (set_attr "unit" "i387,*,*,*")
2427   (set_attr "mode" "DF,SI,SI,DF")])
2428
2429(define_insn "*pushdf_integer"
2430  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431	(match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2432  "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2433{
2434  /* This insn should be already split before reg-stack.  */
2435  gcc_unreachable ();
2436}
2437  [(set_attr "type" "multi")
2438   (set_attr "unit" "i387,*,*")
2439   (set_attr "mode" "DF,SI,DF")])
2440
2441;; %%% Kill this when call knows how to work this out.
2442(define_split
2443  [(set (match_operand:DF 0 "push_operand" "")
2444	(match_operand:DF 1 "any_fp_register_operand" ""))]
2445  "!TARGET_64BIT && reload_completed"
2446  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2447   (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2448  "")
2449
2450(define_split
2451  [(set (match_operand:DF 0 "push_operand" "")
2452	(match_operand:DF 1 "any_fp_register_operand" ""))]
2453  "TARGET_64BIT && reload_completed"
2454  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2455   (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2456  "")
2457
2458(define_split
2459  [(set (match_operand:DF 0 "push_operand" "")
2460	(match_operand:DF 1 "general_operand" ""))]
2461  "reload_completed"
2462  [(const_int 0)]
2463  "ix86_split_long_move (operands); DONE;")
2464
2465;; Moving is usually shorter when only FP registers are used. This separate
2466;; movdf pattern avoids the use of integer registers for FP operations
2467;; when optimizing for size.
2468
2469(define_insn "*movdf_nointeger"
2470  [(set (match_operand:DF 0 "nonimmediate_operand"
2471			"=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2472	(match_operand:DF 1 "general_operand"
2473			"fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2474  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2475   && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2476   && (reload_in_progress || reload_completed
2477       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2478       || GET_CODE (operands[1]) != CONST_DOUBLE
2479       || memory_operand (operands[0], DFmode))" 
2480{
2481  switch (which_alternative)
2482    {
2483    case 0:
2484      return output_387_reg_move (insn, operands);
2485
2486    case 1:
2487      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2488        return "fstp%z0\t%y0";
2489      else
2490        return "fst%z0\t%y0";
2491
2492    case 2:
2493      return standard_80387_constant_opcode (operands[1]);
2494
2495    case 3:
2496    case 4:
2497      return "#";
2498    case 5:
2499      switch (get_attr_mode (insn))
2500	{
2501	case MODE_V4SF:
2502	  return "xorps\t%0, %0";
2503	case MODE_V2DF:
2504	  return "xorpd\t%0, %0";
2505	case MODE_TI:
2506	  return "pxor\t%0, %0";
2507	default:
2508	  gcc_unreachable ();
2509	}
2510    case 6:
2511    case 7:
2512    case 8:
2513      switch (get_attr_mode (insn))
2514	{
2515	case MODE_V4SF:
2516	  return "movaps\t{%1, %0|%0, %1}";
2517	case MODE_V2DF:
2518	  return "movapd\t{%1, %0|%0, %1}";
2519	case MODE_TI:
2520	  return "movdqa\t{%1, %0|%0, %1}";
2521	case MODE_DI:
2522	  return "movq\t{%1, %0|%0, %1}";
2523	case MODE_DF:
2524	  return "movsd\t{%1, %0|%0, %1}";
2525	case MODE_V1DF:
2526	  return "movlpd\t{%1, %0|%0, %1}";
2527	case MODE_V2SF:
2528	  return "movlps\t{%1, %0|%0, %1}";
2529	default:
2530	  gcc_unreachable ();
2531	}
2532
2533    default:
2534      gcc_unreachable ();
2535    }
2536}
2537  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2538   (set (attr "mode")
2539        (cond [(eq_attr "alternative" "0,1,2")
2540		 (const_string "DF")
2541	       (eq_attr "alternative" "3,4")
2542		 (const_string "SI")
2543
2544	       /* For SSE1, we have many fewer alternatives.  */
2545	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2546		 (cond [(eq_attr "alternative" "5,6")
2547			  (const_string "V4SF")
2548		       ]
2549		   (const_string "V2SF"))
2550
2551	       /* xorps is one byte shorter.  */
2552	       (eq_attr "alternative" "5")
2553		 (cond [(ne (symbol_ref "optimize_size")
2554			    (const_int 0))
2555			  (const_string "V4SF")
2556			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2557			    (const_int 0))
2558			  (const_string "TI")
2559		       ]
2560		       (const_string "V2DF"))
2561
2562	       /* For architectures resolving dependencies on
2563		  whole SSE registers use APD move to break dependency
2564		  chains, otherwise use short move to avoid extra work.
2565
2566		  movaps encodes one byte shorter.  */
2567	       (eq_attr "alternative" "6")
2568		 (cond
2569		   [(ne (symbol_ref "optimize_size")
2570		        (const_int 0))
2571		      (const_string "V4SF")
2572		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2573		        (const_int 0))
2574		      (const_string "V2DF")
2575		   ]
2576		   (const_string "DF"))
2577	       /* For architectures resolving dependencies on register
2578		  parts we may avoid extra work to zero out upper part
2579		  of register.  */
2580	       (eq_attr "alternative" "7")
2581		 (if_then_else
2582		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2583		       (const_int 0))
2584		   (const_string "V1DF")
2585		   (const_string "DF"))
2586	      ]
2587	      (const_string "DF")))])
2588
2589(define_insn "*movdf_integer"
2590  [(set (match_operand:DF 0 "nonimmediate_operand"
2591		"=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2592	(match_operand:DF 1 "general_operand"
2593		"fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2594  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2595   && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2596   && (reload_in_progress || reload_completed
2597       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2598       || GET_CODE (operands[1]) != CONST_DOUBLE
2599       || memory_operand (operands[0], DFmode))" 
2600{
2601  switch (which_alternative)
2602    {
2603    case 0:
2604      return output_387_reg_move (insn, operands);
2605
2606    case 1:
2607      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2608        return "fstp%z0\t%y0";
2609      else
2610        return "fst%z0\t%y0";
2611
2612    case 2:
2613      return standard_80387_constant_opcode (operands[1]);
2614
2615    case 3:
2616    case 4:
2617      return "#";
2618
2619    case 5:
2620      switch (get_attr_mode (insn))
2621	{
2622	case MODE_V4SF:
2623	  return "xorps\t%0, %0";
2624	case MODE_V2DF:
2625	  return "xorpd\t%0, %0";
2626	case MODE_TI:
2627	  return "pxor\t%0, %0";
2628	default:
2629	  gcc_unreachable ();
2630	}
2631    case 6:
2632    case 7:
2633    case 8:
2634      switch (get_attr_mode (insn))
2635	{
2636	case MODE_V4SF:
2637	  return "movaps\t{%1, %0|%0, %1}";
2638	case MODE_V2DF:
2639	  return "movapd\t{%1, %0|%0, %1}";
2640	case MODE_TI:
2641	  return "movdqa\t{%1, %0|%0, %1}";
2642	case MODE_DI:
2643	  return "movq\t{%1, %0|%0, %1}";
2644	case MODE_DF:
2645	  return "movsd\t{%1, %0|%0, %1}";
2646	case MODE_V1DF:
2647	  return "movlpd\t{%1, %0|%0, %1}";
2648	case MODE_V2SF:
2649	  return "movlps\t{%1, %0|%0, %1}";
2650	default:
2651	  gcc_unreachable ();
2652	}
2653
2654    default:
2655      gcc_unreachable();
2656    }
2657}
2658  [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2659   (set (attr "mode")
2660        (cond [(eq_attr "alternative" "0,1,2")
2661		 (const_string "DF")
2662	       (eq_attr "alternative" "3,4")
2663		 (const_string "SI")
2664
2665	       /* For SSE1, we have many fewer alternatives.  */
2666	       (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2667		 (cond [(eq_attr "alternative" "5,6")
2668			  (const_string "V4SF")
2669		       ]
2670		   (const_string "V2SF"))
2671
2672	       /* xorps is one byte shorter.  */
2673	       (eq_attr "alternative" "5")
2674		 (cond [(ne (symbol_ref "optimize_size")
2675			    (const_int 0))
2676			  (const_string "V4SF")
2677			(ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2678			    (const_int 0))
2679			  (const_string "TI")
2680		       ]
2681		       (const_string "V2DF"))
2682
2683	       /* For architectures resolving dependencies on
2684		  whole SSE registers use APD move to break dependency
2685		  chains, otherwise use short move to avoid extra work.
2686
2687		  movaps encodes one byte shorter.  */
2688	       (eq_attr "alternative" "6")
2689		 (cond
2690		   [(ne (symbol_ref "optimize_size")
2691		        (const_int 0))
2692		      (const_string "V4SF")
2693		    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2694		        (const_int 0))
2695		      (const_string "V2DF")
2696		   ]
2697		   (const_string "DF"))
2698	       /* For architectures resolving dependencies on register
2699		  parts we may avoid extra work to zero out upper part
2700		  of register.  */
2701	       (eq_attr "alternative" "7")
2702		 (if_then_else
2703		   (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2704		       (const_int 0))
2705		   (const_string "V1DF")
2706		   (const_string "DF"))
2707	      ]
2708	      (const_string "DF")))])
2709
2710(define_split
2711  [(set (match_operand:DF 0 "nonimmediate_operand" "")
2712	(match_operand:DF 1 "general_operand" ""))]
2713  "reload_completed
2714   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2715   && ! (ANY_FP_REG_P (operands[0]) || 
2716	 (GET_CODE (operands[0]) == SUBREG
2717	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2718   && ! (ANY_FP_REG_P (operands[1]) || 
2719	 (GET_CODE (operands[1]) == SUBREG
2720	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2721  [(const_int 0)]
2722  "ix86_split_long_move (operands); DONE;")
2723
2724(define_insn "*swapdf"
2725  [(set (match_operand:DF 0 "fp_register_operand" "+f")
2726	(match_operand:DF 1 "fp_register_operand" "+f"))
2727   (set (match_dup 1)
2728	(match_dup 0))]
2729  "reload_completed || TARGET_80387"
2730{
2731  if (STACK_TOP_P (operands[0]))
2732    return "fxch\t%1";
2733  else
2734    return "fxch\t%0";
2735}
2736  [(set_attr "type" "fxch")
2737   (set_attr "mode" "DF")])
2738
2739(define_expand "movxf"
2740  [(set (match_operand:XF 0 "nonimmediate_operand" "")
2741	(match_operand:XF 1 "general_operand" ""))]
2742  ""
2743  "ix86_expand_move (XFmode, operands); DONE;")
2744
2745;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2746;; Size of pushdf using integer instructions is 3+3*memory operand size
2747;; Pushing using integer instructions is longer except for constants
2748;; and direct memory references.
2749;; (assuming that any given constant is pushed only once, but this ought to be
2750;;  handled elsewhere).
2751
2752(define_insn "*pushxf_nointeger"
2753  [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2754	(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2755  "optimize_size"
2756{
2757  /* This insn should be already split before reg-stack.  */
2758  gcc_unreachable ();
2759}
2760  [(set_attr "type" "multi")
2761   (set_attr "unit" "i387,*,*")
2762   (set_attr "mode" "XF,SI,SI")])
2763
2764(define_insn "*pushxf_integer"
2765  [(set (match_operand:XF 0 "push_operand" "=<,<")
2766	(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2767  "!optimize_size"
2768{
2769  /* This insn should be already split before reg-stack.  */
2770  gcc_unreachable ();
2771}
2772  [(set_attr "type" "multi")
2773   (set_attr "unit" "i387,*")
2774   (set_attr "mode" "XF,SI")])
2775
2776(define_split
2777  [(set (match_operand 0 "push_operand" "")
2778	(match_operand 1 "general_operand" ""))]
2779  "reload_completed
2780   && (GET_MODE (operands[0]) == XFmode
2781       || GET_MODE (operands[0]) == DFmode)
2782   && !ANY_FP_REG_P (operands[1])"
2783  [(const_int 0)]
2784  "ix86_split_long_move (operands); DONE;")
2785
2786(define_split
2787  [(set (match_operand:XF 0 "push_operand" "")
2788	(match_operand:XF 1 "any_fp_register_operand" ""))]
2789  "!TARGET_64BIT"
2790  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2791   (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2792  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2793
2794(define_split
2795  [(set (match_operand:XF 0 "push_operand" "")
2796	(match_operand:XF 1 "any_fp_register_operand" ""))]
2797  "TARGET_64BIT"
2798  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2799   (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2800  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2801
2802;; Do not use integer registers when optimizing for size
2803(define_insn "*movxf_nointeger"
2804  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2805	(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2806  "optimize_size
2807   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808   && (reload_in_progress || reload_completed
2809       || GET_CODE (operands[1]) != CONST_DOUBLE
2810       || memory_operand (operands[0], XFmode))" 
2811{
2812  switch (which_alternative)
2813    {
2814    case 0:
2815      return output_387_reg_move (insn, operands);
2816
2817    case 1:
2818      /* There is no non-popping store to memory for XFmode.  So if
2819	 we need one, follow the store with a load.  */
2820      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2821        return "fstp%z0\t%y0\;fld%z0\t%y0";
2822      else
2823        return "fstp%z0\t%y0";
2824
2825    case 2:
2826      return standard_80387_constant_opcode (operands[1]);
2827
2828    case 3: case 4:
2829      return "#";
2830    default:
2831      gcc_unreachable ();
2832    }
2833}
2834  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2835   (set_attr "mode" "XF,XF,XF,SI,SI")])
2836
2837(define_insn "*movxf_integer"
2838  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2839	(match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2840  "!optimize_size
2841   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2842   && (reload_in_progress || reload_completed
2843       || GET_CODE (operands[1]) != CONST_DOUBLE
2844       || memory_operand (operands[0], XFmode))" 
2845{
2846  switch (which_alternative)
2847    {
2848    case 0:
2849      return output_387_reg_move (insn, operands);
2850
2851    case 1:
2852      /* There is no non-popping store to memory for XFmode.  So if
2853	 we need one, follow the store with a load.  */
2854      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2855        return "fstp%z0\t%y0\;fld%z0\t%y0";
2856      else
2857        return "fstp%z0\t%y0";
2858
2859    case 2:
2860      return standard_80387_constant_opcode (operands[1]);
2861
2862    case 3: case 4:
2863      return "#";
2864
2865    default:
2866      gcc_unreachable ();
2867    }
2868}
2869  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2870   (set_attr "mode" "XF,XF,XF,SI,SI")])
2871
2872(define_split
2873  [(set (match_operand 0 "nonimmediate_operand" "")
2874	(match_operand 1 "general_operand" ""))]
2875  "reload_completed
2876   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2877   && GET_MODE (operands[0]) == XFmode
2878   && ! (ANY_FP_REG_P (operands[0]) || 
2879	 (GET_CODE (operands[0]) == SUBREG
2880	  && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2881   && ! (ANY_FP_REG_P (operands[1]) || 
2882	 (GET_CODE (operands[1]) == SUBREG
2883	  && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2884  [(const_int 0)]
2885  "ix86_split_long_move (operands); DONE;")
2886
2887(define_split
2888  [(set (match_operand 0 "register_operand" "")
2889	(match_operand 1 "memory_operand" ""))]
2890  "reload_completed
2891   && GET_CODE (operands[1]) == MEM
2892   && (GET_MODE (operands[0]) == XFmode
2893       || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2894   && constant_pool_reference_p (operands[1])"
2895  [(set (match_dup 0) (match_dup 1))]
2896{
2897  rtx c = avoid_constant_pool_reference (operands[1]);
2898  rtx r = operands[0];
2899
2900  if (GET_CODE (r) == SUBREG)
2901    r = SUBREG_REG (r);
2902
2903  if (SSE_REG_P (r))
2904    {
2905      if (!standard_sse_constant_p (c))
2906	FAIL;
2907    }
2908  else if (FP_REG_P (r))
2909    {
2910      if (!standard_80387_constant_p (c))
2911	FAIL;
2912    }
2913  else if (MMX_REG_P (r))
2914    FAIL;
2915
2916  operands[1] = c;
2917})
2918
2919(define_insn "swapxf"
2920  [(set (match_operand:XF 0 "register_operand" "+f")
2921	(match_operand:XF 1 "register_operand" "+f"))
2922   (set (match_dup 1)
2923	(match_dup 0))]
2924  "TARGET_80387"
2925{
2926  if (STACK_TOP_P (operands[0]))
2927    return "fxch\t%1";
2928  else
2929    return "fxch\t%0";
2930}
2931  [(set_attr "type" "fxch")
2932   (set_attr "mode" "XF")])
2933
2934(define_expand "movtf"
2935  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2936	(match_operand:TF 1 "nonimmediate_operand" ""))]
2937  "TARGET_64BIT"
2938{
2939  ix86_expand_move (TFmode, operands);
2940  DONE;
2941})
2942
2943(define_insn "*movtf_internal"
2944  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2945	(match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2946  "TARGET_64BIT
2947   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2948{
2949  switch (which_alternative)
2950    {
2951    case 0:
2952    case 1:
2953      return "#";
2954    case 2:
2955      if (get_attr_mode (insn) == MODE_V4SF)
2956	return "xorps\t%0, %0";
2957      else
2958	return "pxor\t%0, %0";
2959    case 3:
2960    case 4:
2961      if (get_attr_mode (insn) == MODE_V4SF)
2962	return "movaps\t{%1, %0|%0, %1}";
2963      else
2964	return "movdqa\t{%1, %0|%0, %1}";
2965    default:
2966      gcc_unreachable ();
2967    }
2968}
2969  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2970   (set (attr "mode")
2971        (cond [(eq_attr "alternative" "2,3")
2972		 (if_then_else
2973		   (ne (symbol_ref "optimize_size")
2974		       (const_int 0))
2975		   (const_string "V4SF")
2976		   (const_string "TI"))
2977	       (eq_attr "alternative" "4")
2978		 (if_then_else
2979		   (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2980			    (const_int 0))
2981			(ne (symbol_ref "optimize_size")
2982			    (const_int 0)))
2983		   (const_string "V4SF")
2984		   (const_string "TI"))]
2985	       (const_string "DI")))])
2986
2987(define_split
2988  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2989        (match_operand:TF 1 "general_operand" ""))]
2990  "reload_completed && !SSE_REG_P (operands[0])
2991   && !SSE_REG_P (operands[1])"
2992  [(const_int 0)]
2993  "ix86_split_long_move (operands); DONE;")
2994
2995;; Zero extension instructions
2996
2997(define_expand "zero_extendhisi2"
2998  [(set (match_operand:SI 0 "register_operand" "")
2999     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3000  ""
3001{
3002  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3003    {
3004      operands[1] = force_reg (HImode, operands[1]);
3005      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3006      DONE;
3007    }
3008})
3009
3010(define_insn "zero_extendhisi2_and"
3011  [(set (match_operand:SI 0 "register_operand" "=r")
3012     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3013   (clobber (reg:CC FLAGS_REG))]
3014  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3015  "#"
3016  [(set_attr "type" "alu1")
3017   (set_attr "mode" "SI")])
3018
3019(define_split
3020  [(set (match_operand:SI 0 "register_operand" "")
3021	(zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3022   (clobber (reg:CC FLAGS_REG))]
3023  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3024  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3025	      (clobber (reg:CC FLAGS_REG))])]
3026  "")
3027
3028(define_insn "*zero_extendhisi2_movzwl"
3029  [(set (match_operand:SI 0 "register_operand" "=r")
3030     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3031  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032  "movz{wl|x}\t{%1, %0|%0, %1}"
3033  [(set_attr "type" "imovx")
3034   (set_attr "mode" "SI")])
3035
3036(define_expand "zero_extendqihi2"
3037  [(parallel
3038    [(set (match_operand:HI 0 "register_operand" "")
3039       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3040     (clobber (reg:CC FLAGS_REG))])]
3041  ""
3042  "")
3043
3044(define_insn "*zero_extendqihi2_and"
3045  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3046     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3047   (clobber (reg:CC FLAGS_REG))]
3048  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3049  "#"
3050  [(set_attr "type" "alu1")
3051   (set_attr "mode" "HI")])
3052
3053(define_insn "*zero_extendqihi2_movzbw_and"
3054  [(set (match_operand:HI 0 "register_operand" "=r,r")
3055     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3056   (clobber (reg:CC FLAGS_REG))]
3057  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3058  "#"
3059  [(set_attr "type" "imovx,alu1")
3060   (set_attr "mode" "HI")])
3061
3062; zero extend to SImode here to avoid partial register stalls
3063(define_insn "*zero_extendqihi2_movzbl"
3064  [(set (match_operand:HI 0 "register_operand" "=r")
3065     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3066  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3067  "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3068  [(set_attr "type" "imovx")
3069   (set_attr "mode" "SI")])
3070
3071;; For the movzbw case strip only the clobber
3072(define_split
3073  [(set (match_operand:HI 0 "register_operand" "")
3074	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3075   (clobber (reg:CC FLAGS_REG))]
3076  "reload_completed 
3077   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3078   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3079  [(set (match_operand:HI 0 "register_operand" "")
3080	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3081
3082;; When source and destination does not overlap, clear destination
3083;; first and then do the movb
3084(define_split
3085  [(set (match_operand:HI 0 "register_operand" "")
3086	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3087   (clobber (reg:CC FLAGS_REG))]
3088  "reload_completed
3089   && ANY_QI_REG_P (operands[0])
3090   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3091   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3092  [(set (match_dup 0) (const_int 0))
3093   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3094  "operands[2] = gen_lowpart (QImode, operands[0]);")
3095
3096;; Rest is handled by single and.
3097(define_split
3098  [(set (match_operand:HI 0 "register_operand" "")
3099	(zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3100   (clobber (reg:CC FLAGS_REG))]
3101  "reload_completed
3102   && true_regnum (operands[0]) == true_regnum (operands[1])"
3103  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3104	      (clobber (reg:CC FLAGS_REG))])]
3105  "")
3106
3107(define_expand "zero_extendqisi2"
3108  [(parallel
3109    [(set (match_operand:SI 0 "register_operand" "")
3110       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111     (clobber (reg:CC FLAGS_REG))])]
3112  ""
3113  "")
3114
3115(define_insn "*zero_extendqisi2_and"
3116  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3117     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3118   (clobber (reg:CC FLAGS_REG))]
3119  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3120  "#"
3121  [(set_attr "type" "alu1")
3122   (set_attr "mode" "SI")])
3123
3124(define_insn "*zero_extendqisi2_movzbw_and"
3125  [(set (match_operand:SI 0 "register_operand" "=r,r")
3126     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3127   (clobber (reg:CC FLAGS_REG))]
3128  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3129  "#"
3130  [(set_attr "type" "imovx,alu1")
3131   (set_attr "mode" "SI")])
3132
3133(define_insn "*zero_extendqisi2_movzbw"
3134  [(set (match_operand:SI 0 "register_operand" "=r")
3135     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3136  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3137  "movz{bl|x}\t{%1, %0|%0, %1}"
3138  [(set_attr "type" "imovx")
3139   (set_attr "mode" "SI")])
3140
3141;; For the movzbl case strip only the clobber
3142(define_split
3143  [(set (match_operand:SI 0 "register_operand" "")
3144	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3145   (clobber (reg:CC FLAGS_REG))]
3146  "reload_completed 
3147   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3148   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3149  [(set (match_dup 0)
3150	(zero_extend:SI (match_dup 1)))])
3151
3152;; When source and destination does not overlap, clear destination
3153;; first and then do the movb
3154(define_split
3155  [(set (match_operand:SI 0 "register_operand" "")
3156	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3157   (clobber (reg:CC FLAGS_REG))]
3158  "reload_completed
3159   && ANY_QI_REG_P (operands[0])
3160   && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3161   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3162   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3163  [(set (match_dup 0) (const_int 0))
3164   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3165  "operands[2] = gen_lowpart (QImode, operands[0]);")
3166
3167;; Rest is handled by single and.
3168(define_split
3169  [(set (match_operand:SI 0 "register_operand" "")
3170	(zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3171   (clobber (reg:CC FLAGS_REG))]
3172  "reload_completed
3173   && true_regnum (operands[0]) == true_regnum (operands[1])"
3174  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3175	      (clobber (reg:CC FLAGS_REG))])]
3176  "")
3177
3178;; %%% Kill me once multi-word ops are sane.
3179(define_expand "zero_extendsidi2"
3180  [(set (match_operand:DI 0 "register_operand" "=r")
3181     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3182  ""
3183  "if (!TARGET_64BIT)
3184     {
3185       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3186       DONE;
3187     }
3188  ")
3189
3190(define_insn "zero_extendsidi2_32"
3191  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3192	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3193   (clobber (reg:CC FLAGS_REG))]
3194  "!TARGET_64BIT"
3195  "@
3196   #
3197   #
3198   #
3199   movd\t{%1, %0|%0, %1}
3200   movd\t{%1, %0|%0, %1}"
3201  [(set_attr "mode" "SI,SI,SI,DI,TI")
3202   (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3203
3204(define_insn "zero_extendsidi2_rex64"
3205  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3206     (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3207  "TARGET_64BIT"
3208  "@
3209   mov\t{%k1, %k0|%k0, %k1}
3210   #
3211   movd\t{%1, %0|%0, %1}
3212   movd\t{%1, %0|%0, %1}"
3213  [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3214   (set_attr "mode" "SI,DI,SI,SI")])
3215
3216(define_split
3217  [(set (match_operand:DI 0 "memory_operand" "")
3218     (zero_extend:DI (match_dup 0)))]
3219  "TARGET_64BIT"
3220  [(set (match_dup 4) (const_int 0))]
3221  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3222
3223(define_split 
3224  [(set (match_operand:DI 0 "register_operand" "")
3225	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3226   (clobber (reg:CC FLAGS_REG))]
3227  "!TARGET_64BIT && reload_completed
3228   && true_regnum (operands[0]) == true_regnum (operands[1])"
3229  [(set (match_dup 4) (const_int 0))]
3230  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3231
3232(define_split 
3233  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3234	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3235   (clobber (reg:CC FLAGS_REG))]
3236  "!TARGET_64BIT && reload_completed
3237   && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3238  [(set (match_dup 3) (match_dup 1))
3239   (set (match_dup 4) (const_int 0))]
3240  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3241
3242(define_insn "zero_extendhidi2"
3243  [(set (match_operand:DI 0 "register_operand" "=r")
3244     (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3245  "TARGET_64BIT"
3246  "movz{wl|x}\t{%1, %k0|%k0, %1}"
3247  [(set_attr "type" "imovx")
3248   (set_attr "mode" "DI")])
3249
3250(define_insn "zero_extendqidi2"
3251  [(set (match_operand:DI 0 "register_operand" "=r")
3252     (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3253  "TARGET_64BIT"
3254  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3255  [(set_attr "type" "imovx")
3256   (set_attr "mode" "DI")])
3257
3258;; Sign extension instructions
3259
3260(define_expand "extendsidi2"
3261  [(parallel [(set (match_operand:DI 0 "register_operand" "")
3262		   (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3263	      (clobber (reg:CC FLAGS_REG))
3264	      (clobber (match_scratch:SI 2 ""))])]
3265  ""
3266{
3267  if (TARGET_64BIT)
3268    {
3269      emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3270      DONE;
3271    }
3272})
3273
3274(define_insn "*extendsidi2_1"
3275  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3276	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3277   (clobber (reg:CC FLAGS_REG))
3278   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3279  "!TARGET_64BIT"
3280  "#")
3281
3282(define_insn "extendsidi2_rex64"
3283  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3284	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3285  "TARGET_64BIT"
3286  "@
3287   {cltq|cdqe}
3288   movs{lq|x}\t{%1,%0|%0, %1}"
3289  [(set_attr "type" "imovx")
3290   (set_attr "mode" "DI")
3291   (set_attr "prefix_0f" "0")
3292   (set_attr "modrm" "0,1")])
3293
3294(define_insn "extendhidi2"
3295  [(set (match_operand:DI 0 "register_operand" "=r")
3296	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3297  "TARGET_64BIT"
3298  "movs{wq|x}\t{%1,%0|%0, %1}"
3299  [(set_attr "type" "imovx")
3300   (set_attr "mode" "DI")])
3301
3302(define_insn "extendqidi2"
3303  [(set (match_operand:DI 0 "register_operand" "=r")
3304	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3305  "TARGET_64BIT"
3306  "movs{bq|x}\t{%1,%0|%0, %1}"
3307   [(set_attr "type" "imovx")
3308    (set_attr "mode" "DI")])
3309
3310;; Extend to memory case when source register does die.
3311(define_split 
3312  [(set (match_operand:DI 0 "memory_operand" "")
3313	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3314   (clobber (reg:CC FLAGS_REG))
3315   (clobber (match_operand:SI 2 "register_operand" ""))]
3316  "(reload_completed
3317    && dead_or_set_p (insn, operands[1])
3318    && !reg_mentioned_p (operands[1], operands[0]))"
3319  [(set (match_dup 3) (match_dup 1))
3320   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3321	      (clobber (reg:CC FLAGS_REG))])
3322   (set (match_dup 4) (match_dup 1))]
3323  "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3324
3325;; Extend to memory case when source register does not die.
3326(define_split 
3327  [(set (match_operand:DI 0 "memory_operand" "")
3328	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3329   (clobber (reg:CC FLAGS_REG))
3330   (clobber (match_operand:SI 2 "register_operand" ""))]
3331  "reload_completed"
3332  [(const_int 0)]
3333{
3334  split_di (&operands[0], 1, &operands[3], &operands[4]);
3335
3336  emit_move_insn (operands[3], operands[1]);
3337
3338  /* Generate a cltd if possible and doing so it profitable.  */
3339  if (true_regnum (operands[1]) == 0
3340      && true_regnum (operands[2]) == 1
3341      && (optimize_size || TARGET_USE_CLTD))
3342    {
3343      emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3344    }
3345  else
3346    {
3347      emit_move_insn (operands[2], operands[1]);
3348      emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3349    }
3350  emit_move_insn (operands[4], operands[2]);
3351  DONE;
3352})
3353
3354;; Extend to register case.  Optimize case where source and destination
3355;; registers match and cases where we can use cltd.
3356(define_split 
3357  [(set (match_operand:DI 0 "register_operand" "")
3358	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3359   (clobber (reg:CC FLAGS_REG))
3360   (clobber (match_scratch:SI 2 ""))]
3361  "reload_completed"
3362  [(const_int 0)]
3363{
3364  split_di (&operands[0], 1, &operands[3], &operands[4]);
3365
3366  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3367    emit_move_insn (operands[3], operands[1]);
3368
3369  /* Generate a cltd if possible and doing so it profitable.  */
3370  if (true_regnum (operands[3]) == 0
3371      && (optimize_size || TARGET_USE_CLTD))
3372    {
3373      emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3374      DONE;
3375    }
3376
3377  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3378    emit_move_insn (operands[4], operands[1]);
3379
3380  emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3381  DONE;
3382})
3383
3384(define_insn "extendhisi2"
3385  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3386	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3387  ""
3388{
3389  switch (get_attr_prefix_0f (insn))
3390    {
3391    case 0:
3392      return "{cwtl|cwde}";
3393    default:
3394      return "movs{wl|x}\t{%1,%0|%0, %1}";
3395    }
3396}
3397  [(set_attr "type" "imovx")
3398   (set_attr "mode" "SI")
3399   (set (attr "prefix_0f")
3400     ;; movsx is short decodable while cwtl is vector decoded.
3401     (if_then_else (and (eq_attr "cpu" "!k6")
3402			(eq_attr "alternative" "0"))
3403	(const_string "0")
3404	(const_string "1")))
3405   (set (attr "modrm")
3406     (if_then_else (eq_attr "prefix_0f" "0")
3407	(const_string "0")
3408	(const_string "1")))])
3409
3410(define_insn "*extendhisi2_zext"
3411  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3412	(zero_extend:DI
3413	  (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3414  "TARGET_64BIT"
3415{
3416  switch (get_attr_prefix_0f (insn))
3417    {
3418    case 0:
3419      return "{cwtl|cwde}";
3420    default:
3421      return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3422    }
3423}
3424  [(set_attr "type" "imovx")
3425   (set_attr "mode" "SI")
3426   (set (attr "prefix_0f")
3427     ;; movsx is short decodable while cwtl is vector decoded.
3428     (if_then_else (and (eq_attr "cpu" "!k6")
3429			(eq_attr "alternative" "0"))
3430	(const_string "0")
3431	(const_string "1")))
3432   (set (attr "modrm")
3433     (if_then_else (eq_attr "prefix_0f" "0")
3434	(const_string "0")
3435	(const_string "1")))])
3436
3437(define_insn "extendqihi2"
3438  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3439	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3440  ""
3441{
3442  switch (get_attr_prefix_0f (insn))
3443    {
3444    case 0:
3445      return "{cbtw|cbw}";
3446    default:
3447      return "movs{bw|x}\t{%1,%0|%0, %1}";
3448    }
3449}
3450  [(set_attr "type" "imovx")
3451   (set_attr "mode" "HI")
3452   (set (attr "prefix_0f")
3453     ;; movsx is short decodable while cwtl is vector decoded.
3454     (if_then_else (and (eq_attr "cpu" "!k6")
3455			(eq_attr "alternative" "0"))
3456	(const_string "0")
3457	(const_string "1")))
3458   (set (attr "modrm")
3459     (if_then_else (eq_attr "prefix_0f" "0")
3460	(const_string "0")
3461	(const_string "1")))])
3462
3463(define_insn "extendqisi2"
3464  [(set (match_operand:SI 0 "register_operand" "=r")
3465	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3466  ""
3467  "movs{bl|x}\t{%1,%0|%0, %1}"
3468   [(set_attr "type" "imovx")
3469    (set_attr "mode" "SI")])
3470
3471(define_insn "*extendqisi2_zext"
3472  [(set (match_operand:DI 0 "register_operand" "=r")
3473	(zero_extend:DI
3474	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3475  "TARGET_64BIT"
3476  "movs{bl|x}\t{%1,%k0|%k0, %1}"
3477   [(set_attr "type" "imovx")
3478    (set_attr "mode" "SI")])
3479
3480;; Conversions between float and double.
3481
3482;; These are all no-ops in the model used for the 80387.  So just
3483;; emit moves.
3484
3485;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3486(define_insn "*dummy_extendsfdf2"
3487  [(set (match_operand:DF 0 "push_operand" "=<")
3488	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3489  "0"
3490  "#")
3491
3492(define_split
3493  [(set (match_operand:DF 0 "push_operand" "")
3494	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3495  "!TARGET_64BIT"
3496  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3497   (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3498
3499(define_split
3500  [(set (match_operand:DF 0 "push_operand" "")
3501	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3502  "TARGET_64BIT"
3503  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3504   (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3505
3506(define_insn "*dummy_extendsfxf2"
3507  [(set (match_operand:XF 0 "push_operand" "=<")
3508	(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3509  "0"
3510  "#")
3511
3512(define_split
3513  [(set (match_operand:XF 0 "push_operand" "")
3514	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3515  ""
3516  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3517   (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3518  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3519
3520(define_split
3521  [(set (match_operand:XF 0 "push_operand" "")
3522	(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3523  "TARGET_64BIT"
3524  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3525   (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3526  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3527
3528(define_split
3529  [(set (match_operand:XF 0 "push_operand" "")
3530	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3531  ""
3532  [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3533   (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3534  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3535
3536(define_split
3537  [(set (match_operand:XF 0 "push_operand" "")
3538	(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3539  "TARGET_64BIT"
3540  [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3541   (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3542  "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3543
3544(define_expand "extendsfdf2"
3545  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3546        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3547  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3548{
3549  /* ??? Needed for compress_float_constant since all fp constants
3550     are LEGITIMATE_CONSTANT_P.  */
3551  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3552    {
3553      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3554	  && standard_80387_constant_p (operands[1]) > 0)
3555	{
3556	  operands[1] = simplify_const_unary_operation
3557	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3558	  emit_move_insn_1 (operands[0], operands[1]);
3559	  DONE;
3560	}
3561      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3562    }
3563  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3564    operands[1] = force_reg (SFmode, operands[1]);
3565})
3566
3567(define_insn "*extendsfdf2_mixed"
3568  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3569        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3570  "TARGET_SSE2 && TARGET_MIX_SSE_I387
3571   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572{
3573  switch (which_alternative)
3574    {
3575    case 0:
3576      return output_387_reg_move (insn, operands);
3577
3578    case 1:
3579      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3580        return "fstp%z0\t%y0";
3581      else
3582        return "fst%z0\t%y0";
3583
3584    case 2:
3585      return "cvtss2sd\t{%1, %0|%0, %1}";
3586
3587    default:
3588      gcc_unreachable ();
3589    }
3590}
3591  [(set_attr "type" "fmov,fmov,ssecvt")
3592   (set_attr "mode" "SF,XF,DF")])
3593
3594(define_insn "*extendsfdf2_sse"
3595  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3596        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3597  "TARGET_SSE2 && TARGET_SSE_MATH
3598   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3599  "cvtss2sd\t{%1, %0|%0, %1}"
3600  [(set_attr "type" "ssecvt")
3601   (set_attr "mode" "DF")])
3602
3603(define_insn "*extendsfdf2_i387"
3604  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3605        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3606  "TARGET_80387
3607   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3608{
3609  switch (which_alternative)
3610    {
3611    case 0:
3612      return output_387_reg_move (insn, operands);
3613
3614    case 1:
3615      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3616        return "fstp%z0\t%y0";
3617      else
3618        return "fst%z0\t%y0";
3619
3620    default:
3621      gcc_unreachable ();
3622    }
3623}
3624  [(set_attr "type" "fmov")
3625   (set_attr "mode" "SF,XF")])
3626
3627(define_expand "extendsfxf2"
3628  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3629        (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3630  "TARGET_80387"
3631{
3632  /* ??? Needed for compress_float_constant since all fp constants
3633     are LEGITIMATE_CONSTANT_P.  */
3634  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3635    {
3636      if (standard_80387_constant_p (operands[1]) > 0)
3637	{
3638	  operands[1] = simplify_const_unary_operation
3639	    (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3640	  emit_move_insn_1 (operands[0], operands[1]);
3641	  DONE;
3642	}
3643      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3644    }
3645  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3646    operands[1] = force_reg (SFmode, operands[1]);
3647})
3648
3649(define_insn "*extendsfxf2_i387"
3650  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3651        (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3652  "TARGET_80387
3653   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3654{
3655  switch (which_alternative)
3656    {
3657    case 0:
3658      return output_387_reg_move (insn, operands);
3659
3660    case 1:
3661      /* There is no non-popping store to memory for XFmode.  So if
3662	 we need one, follow the store with a load.  */
3663      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3664        return "fstp%z0\t%y0";
3665      else
3666        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3667
3668    default:
3669      gcc_unreachable ();
3670    }
3671}
3672  [(set_attr "type" "fmov")
3673   (set_attr "mode" "SF,XF")])
3674
3675(define_expand "extenddfxf2"
3676  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3677        (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3678  "TARGET_80387"
3679{
3680  /* ??? Needed for compress_float_constant since all fp constants
3681     are LEGITIMATE_CONSTANT_P.  */
3682  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3683    {
3684      if (standard_80387_constant_p (operands[1]) > 0)
3685	{
3686	  operands[1] = simplify_const_unary_operation
3687	    (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3688	  emit_move_insn_1 (operands[0], operands[1]);
3689	  DONE;
3690	}
3691      operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3692    }
3693  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3694    operands[1] = force_reg (DFmode, operands[1]);
3695})
3696
3697(define_insn "*extenddfxf2_i387"
3698  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3699        (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3700  "TARGET_80387
3701   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3702{
3703  switch (which_alternative)
3704    {
3705    case 0:
3706      return output_387_reg_move (insn, operands);
3707
3708    case 1:
3709      /* There is no non-popping store to memory for XFmode.  So if
3710	 we need one, follow the store with a load.  */
3711      if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3712        return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3713      else
3714        return "fstp%z0\t%y0";
3715
3716    default:
3717      gcc_unreachable ();
3718    }
3719}
3720  [(set_attr "type" "fmov")
3721   (set_attr "mode" "DF,XF")])
3722
3723;; %%% This seems bad bad news.
3724;; This cannot output into an f-reg because there is no way to be sure
3725;; of truncating in that case.  Otherwise this is just like a simple move
3726;; insn.  So we pretend we can output to a reg in order to get better
3727;; register preferencing, but we really use a stack slot.
3728
3729;; Conversion from DFmode to SFmode.
3730
3731(define_expand "truncdfsf2"
3732  [(set (match_operand:SF 0 "nonimmediate_operand" "")
3733	(float_truncate:SF
3734	  (match_operand:DF 1 "nonimmediate_operand" "")))]
3735  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3736{
3737  if (MEM_P (operands[0]) && MEM_P (operands[1]))
3738    operands[1] = force_reg (DFmode, operands[1]);
3739
3740  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3741    ;
3742  else if (flag_unsafe_math_optimizations)
3743    ;
3744  else
3745    {
3746      rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3747      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3748      DONE;
3749    }
3750})
3751
3752(define_expand "truncdfsf2_with_temp"
3753  [(parallel [(set (match_operand:SF 0 "" "")
3754		   (float_truncate:SF (match_operand:DF 1 "" "")))
3755	      (clobber (match_operand:SF 2 "" ""))])]
3756  "")
3757
3758(define_insn "*truncdfsf_fast_mixed"
3759  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3760        (float_truncate:SF
3761          (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3762  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3763{
3764  switch (which_alternative)
3765    {
3766    case 0:
3767      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3768	return "fstp%z0\t%y0";
3769      else
3770	return "fst%z0\t%y0";
3771    case 1:
3772      return output_387_reg_move (insn, operands);
3773    case 2:
3774      return "cvtsd2ss\t{%1, %0|%0, %1}";
3775    default:
3776      gcc_unreachable ();
3777    }
3778}
3779  [(set_attr "type" "fmov,fmov,ssecvt")
3780   (set_attr "mode" "SF")])
3781
3782;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3783;; because nothing we do here is unsafe.
3784(define_insn "*truncdfsf_fast_sse"
3785  [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3786        (float_truncate:SF
3787          (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3788  "TARGET_SSE2 && TARGET_SSE_MATH"
3789  "cvtsd2ss\t{%1, %0|%0, %1}"
3790  [(set_attr "type" "ssecvt")
3791   (set_attr "mode" "SF")])
3792
3793(define_insn "*truncdfsf_fast_i387"
3794  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3795        (float_truncate:SF
3796          (match_operand:DF 1 "nonimmediate_operand" "f")))]
3797  "TARGET_80387 && flag_unsafe_math_optimizations"
3798  "* return output_387_reg_move (insn, operands);"
3799  [(set_attr "type" "fmov")
3800   (set_attr "mode" "SF")])
3801
3802(define_insn "*truncdfsf_mixed"
3803  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3804	(float_truncate:SF
3805	  (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3806   (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3807  "TARGET_MIX_SSE_I387"
3808{
3809  switch (which_alternative)
3810    {
3811    case 0:
3812      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813	return "fstp%z0\t%y0";
3814      else
3815	return "fst%z0\t%y0";
3816    case 1:
3817      return "#";
3818    case 2:
3819      return "cvtsd2ss\t{%1, %0|%0, %1}";
3820    default:
3821      gcc_unreachable ();
3822    }
3823}
3824  [(set_attr "type" "fmov,multi,ssecvt")
3825   (set_attr "unit" "*,i387,*")
3826   (set_attr "mode" "SF")])
3827
3828(define_insn "*truncdfsf_i387"
3829  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3830	(float_truncate:SF
3831	  (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3832   (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3833  "TARGET_80387"
3834{
3835  switch (which_alternative)
3836    {
3837    case 0:
3838      if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3839	return "fstp%z0\t%y0";
3840      else
3841	return "fst%z0\t%y0";
3842    case 1:
3843      return "#";
3844    default:
3845      gcc_unreachable ();
3846    }
3847}
3848  [(set_attr "type" "fmov,multi")
3849   (set_attr "unit" "*,i387")
3850   (set_attr "mode" "SF")])
3851
3852(define_insn "*truncdfsf2_i387_1"
3853  [(set (match_operand:SF 0 "memory_operand" "=m")
3854	(float_truncate:SF
3855	  (match_operand:DF 1 "register_operand" "f")))]
3856  "TARGET_80387
3857   && !(TARGET_SSE2 && TARGET_SSE_MATH)
3858   && !TARGET_MIX_SSE_I387"
3859{
3860  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3861    return "fstp%z0\t%y0";
3862  else
3863    return "fst%z0\t%y0";
3864}
3865  [(set_attr "type" "fmov")
3866   (set_attr "mode" "SF")])
3867
3868(define_split
3869  [(set (match_operand:SF 0 "register_operand" "")
3870	(float_truncate:SF
3871	 (match_operand:DF 1 "fp_register_operand" "")))
3872   (clobber (match_operand 2 "" ""))]
3873  "reload_completed"
3874  [(set (match_dup 2) (match_dup 1))
3875   (set (match_dup 0) (match_dup 2))]
3876{
3877  operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3878})
3879
3880;; Conversion from XFmode to SFmode.
3881
3882(define_expand "truncxfsf2"
3883  [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3884		   (float_truncate:SF
3885		    (match_operand:XF 1 "register_operand" "")))
3886	      (clobber (match_dup 2))])]
3887  "TARGET_80387"
3888{
3889  if (flag_unsafe_math_optimizations)
3890    {
3891      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3892      emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3893      if (reg != operands[0])
3894	emit_move_insn (operands[0], reg);
3895      DONE;
3896    }
3897  else
3898    operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3899})
3900
3901(define_insn "*truncxfsf2_mixed"
3902  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3903	(float_truncate:SF
3904	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3905   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3906  "TARGET_MIX_SSE_I387"
3907{
3908  gcc_assert (!which_alternative);
3909  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910    return "fstp%z0\t%y0";
3911  else
3912    return "fst%z0\t%y0";
3913}
3914  [(set_attr "type" "fmov,multi,multi,multi")
3915   (set_attr "unit" "*,i387,i387,i387")
3916   (set_attr "mode" "SF")])
3917
3918(define_insn "truncxfsf2_i387_noop"
3919  [(set (match_operand:SF 0 "register_operand" "=f")
3920	(float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3921  "TARGET_80387 && flag_unsafe_math_optimizations"
3922{
3923  return output_387_reg_move (insn, operands);
3924}
3925  [(set_attr "type" "fmov")
3926   (set_attr "mode" "SF")])
3927
3928(define_insn "*truncxfsf2_i387"
3929  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3930	(float_truncate:SF
3931	 (match_operand:XF 1 "register_operand" "f,f,f")))
3932   (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3933  "TARGET_80387"
3934{
3935  gcc_assert (!which_alternative);
3936  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3937    return "fstp%z0\t%y0";
3938   else
3939     return "fst%z0\t%y0";
3940}
3941  [(set_attr "type" "fmov,multi,multi")
3942   (set_attr "unit" "*,i387,i387")
3943   (set_attr "mode" "SF")])
3944
3945(define_insn "*truncxfsf2_i387_1"
3946  [(set (match_operand:SF 0 "memory_operand" "=m")
3947	(float_truncate:SF
3948	 (match_operand:XF 1 "register_operand" "f")))]
3949  "TARGET_80387"
3950{
3951  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3952    return "fstp%z0\t%y0";
3953  else
3954    return "fst%z0\t%y0";
3955}
3956  [(set_attr "type" "fmov")
3957   (set_attr "mode" "SF")])
3958
3959(define_split
3960  [(set (match_operand:SF 0 "register_operand" "")
3961	(float_truncate:SF
3962	 (match_operand:XF 1 "register_operand" "")))
3963   (clobber (match_operand:SF 2 "memory_operand" ""))]
3964  "TARGET_80387 && reload_completed"
3965  [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3966   (set (match_dup 0) (match_dup 2))]
3967  "")
3968
3969(define_split
3970  [(set (match_operand:SF 0 "memory_operand" "")
3971	(float_truncate:SF
3972	 (match_operand:XF 1 "register_operand" "")))
3973   (clobber (match_operand:SF 2 "memory_operand" ""))]
3974  "TARGET_80387"
3975  [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3976  "")
3977
3978;; Conversion from XFmode to DFmode.
3979
3980(define_expand "truncxfdf2"
3981  [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3982		   (float_truncate:DF
3983		    (match_operand:XF 1 "register_operand" "")))
3984	      (clobber (match_dup 2))])]
3985  "TARGET_80387"
3986{
3987  if (flag_unsafe_math_optimizations)
3988    {
3989      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3990      emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3991      if (reg != operands[0])
3992	emit_move_insn (operands[0], reg);
3993      DONE;
3994    }
3995  else
3996    operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3997})
3998
3999(define_insn "*truncxfdf2_mixed"
4000  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4001	(float_truncate:DF
4002	 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4003   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4004  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4005{
4006  gcc_assert (!which_alternative);
4007  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008    return "fstp%z0\t%y0";
4009  else
4010    return "fst%z0\t%y0";
4011}
4012  [(set_attr "type" "fmov,multi,multi,multi")
4013   (set_attr "unit" "*,i387,i387,i387")
4014   (set_attr "mode" "DF")])
4015
4016(define_insn "truncxfdf2_i387_noop"
4017  [(set (match_operand:DF 0 "register_operand" "=f")
4018	(float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4019  "TARGET_80387 && flag_unsafe_math_optimizations"
4020{
4021  return output_387_reg_move (insn, operands);
4022}
4023  [(set_attr "type" "fmov")
4024   (set_attr "mode" "DF")])
4025
4026(define_insn "*truncxfdf2_i387"
4027  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4028	(float_truncate:DF
4029	 (match_operand:XF 1 "register_operand" "f,f,f")))
4030   (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4031  "TARGET_80387"
4032{
4033  gcc_assert (!which_alternative);
4034  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4035    return "fstp%z0\t%y0";
4036  else
4037    return "fst%z0\t%y0";
4038}
4039  [(set_attr "type" "fmov,multi,multi")
4040   (set_attr "unit" "*,i387,i387")
4041   (set_attr "mode" "DF")])
4042
4043(define_insn "*truncxfdf2_i387_1"
4044  [(set (match_operand:DF 0 "memory_operand" "=m")
4045	(float_truncate:DF
4046	  (match_operand:XF 1 "register_operand" "f")))]
4047  "TARGET_80387"
4048{
4049  if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4050    return "fstp%z0\t%y0";
4051  else
4052    return "fst%z0\t%y0";
4053}
4054  [(set_attr "type" "fmov")
4055   (set_attr "mode" "DF")])
4056
4057(define_split
4058  [(set (match_operand:DF 0 "register_operand" "")
4059	(float_truncate:DF
4060	 (match_operand:XF 1 "register_operand" "")))
4061   (clobber (match_operand:DF 2 "memory_operand" ""))]
4062  "TARGET_80387 && reload_completed"
4063  [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4064   (set (match_dup 0) (match_dup 2))]
4065  "")
4066
4067(define_split
4068  [(set (match_operand:DF 0 "memory_operand" "")
4069	(float_truncate:DF
4070	 (match_operand:XF 1 "register_operand" "")))
4071   (clobber (match_operand:DF 2 "memory_operand" ""))]
4072  "TARGET_80387"
4073  [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4074  "")
4075
4076;; Signed conversion to DImode.
4077
4078(define_expand "fix_truncxfdi2"
4079  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4081	      (clobber (reg:CC FLAGS_REG))])]
4082  "TARGET_80387"
4083{
4084  if (TARGET_FISTTP)
4085   {
4086     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4087     DONE;
4088   }
4089})
4090
4091(define_expand "fix_trunc<mode>di2"
4092  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4093                   (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4094              (clobber (reg:CC FLAGS_REG))])]
4095  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4096{
4097  if (TARGET_FISTTP
4098      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4099   {
4100     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4101     DONE;
4102   }
4103  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4104   {
4105     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4106     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4107     if (out != operands[0])
4108	emit_move_insn (operands[0], out);
4109     DONE;
4110   }
4111})
4112
4113;; Signed conversion to SImode.
4114
4115(define_expand "fix_truncxfsi2"
4116  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4117                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4118	      (clobber (reg:CC FLAGS_REG))])]
4119  "TARGET_80387"
4120{
4121  if (TARGET_FISTTP)
4122   {
4123     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4124     DONE;
4125   }
4126})
4127
4128(define_expand "fix_trunc<mode>si2"
4129  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4130	           (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4131	      (clobber (reg:CC FLAGS_REG))])]
4132  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4133{
4134  if (TARGET_FISTTP
4135      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4136   {
4137     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4138     DONE;
4139   }
4140  if (SSE_FLOAT_MODE_P (<MODE>mode))
4141   {
4142     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4143     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4144     if (out != operands[0])
4145	emit_move_insn (operands[0], out);
4146     DONE;
4147   }
4148})
4149
4150;; Signed conversion to HImode.
4151
4152(define_expand "fix_trunc<mode>hi2"
4153  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4154	           (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4155              (clobber (reg:CC FLAGS_REG))])]
4156  "TARGET_80387
4157   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4158{
4159  if (TARGET_FISTTP)
4160   {
4161     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4162     DONE;
4163   }
4164})
4165
4166;; When SSE is available, it is always faster to use it!
4167(define_insn "fix_truncsfdi_sse"
4168  [(set (match_operand:DI 0 "register_operand" "=r,r")
4169	(fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4170  "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171  "cvttss2si{q}\t{%1, %0|%0, %1}"
4172  [(set_attr "type" "sseicvt")
4173   (set_attr "mode" "SF")
4174   (set_attr "athlon_decode" "double,vector")
4175   (set_attr "amdfam10_decode" "double,double")])
4176
4177(define_insn "fix_truncdfdi_sse"
4178  [(set (match_operand:DI 0 "register_operand" "=r,r")
4179	(fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4180  "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4181  "cvttsd2si{q}\t{%1, %0|%0, %1}"
4182  [(set_attr "type" "sseicvt")
4183   (set_attr "mode" "DF")
4184   (set_attr "athlon_decode" "double,vector")
4185   (set_attr "amdfam10_decode" "double,double")])
4186
4187(define_insn "fix_truncsfsi_sse"
4188  [(set (match_operand:SI 0 "register_operand" "=r,r")
4189	(fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4190  "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4191  "cvttss2si\t{%1, %0|%0, %1}"
4192  [(set_attr "type" "sseicvt")
4193   (set_attr "mode" "DF")
4194   (set_attr "athlon_decode" "double,vector")
4195   (set_attr "amdfam10_decode" "double,double")])
4196
4197(define_insn "fix_truncdfsi_sse"
4198  [(set (match_operand:SI 0 "register_operand" "=r,r")
4199	(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4200  "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4201  "cvttsd2si\t{%1, %0|%0, %1}"
4202  [(set_attr "type" "sseicvt")
4203   (set_attr "mode" "DF")
4204   (set_attr "athlon_decode" "double,vector")
4205   (set_attr "amdfam10_decode" "double,double")])
4206
4207;; Avoid vector decoded forms of the instruction.
4208(define_peephole2
4209  [(match_scratch:DF 2 "Y")
4210   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4211	(fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4212  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4213  [(set (match_dup 2) (match_dup 1))
4214   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4215  "")
4216
4217(define_peephole2
4218  [(match_scratch:SF 2 "x")
4219   (set (match_operand:SSEMODEI24 0 "register_operand" "")
4220	(fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4221  "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4222  [(set (match_dup 2) (match_dup 1))
4223   (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4224  "")
4225
4226(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4227  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4228	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4229  "TARGET_FISTTP
4230   && FLOAT_MODE_P (GET_MODE (operands[1]))
4231   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4232	 && (TARGET_64BIT || <MODE>mode != DImode))
4233	&& TARGET_SSE_MATH)
4234   && !(reload_completed || reload_in_progress)"
4235  "#"
4236  "&& 1"
4237  [(const_int 0)]
4238{
4239  if (memory_operand (operands[0], VOIDmode))
4240    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4241  else
4242    {
4243      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4244      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4245							    operands[1],
4246							    operands[2]));
4247    }
4248  DONE;
4249}
4250  [(set_attr "type" "fisttp")
4251   (set_attr "mode" "<MODE>")])
4252
4253(define_insn "fix_trunc<mode>_i387_fisttp"
4254  [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4255	(fix:X87MODEI (match_operand 1 "register_operand" "f")))
4256   (clobber (match_scratch:XF 2 "=&1f"))]
4257  "TARGET_FISTTP
4258   && FLOAT_MODE_P (GET_MODE (operands[1]))
4259   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4260	 && (TARGET_64BIT || <MODE>mode != DImode))
4261	&& TARGET_SSE_MATH)"
4262  "* return output_fix_trunc (insn, operands, 1);"
4263  [(set_attr "type" "fisttp")
4264   (set_attr "mode" "<MODE>")])
4265
4266(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4267  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4268	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4269   (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4270   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4271  "TARGET_FISTTP
4272   && FLOAT_MODE_P (GET_MODE (operands[1]))
4273   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4274	&& (TARGET_64BIT || <MODE>mode != DImode))
4275	&& TARGET_SSE_MATH)"
4276  "#"
4277  [(set_attr "type" "fisttp")
4278   (set_attr "mode" "<MODE>")])
4279
4280(define_split
4281  [(set (match_operand:X87MODEI 0 "register_operand" "")
4282	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4283   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4284   (clobber (match_scratch 3 ""))]
4285  "reload_completed"
4286  [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4287	      (clobber (match_dup 3))])
4288   (set (match_dup 0) (match_dup 2))]
4289  "")
4290
4291(define_split
4292  [(set (match_operand:X87MODEI 0 "memory_operand" "")
4293	(fix:X87MODEI (match_operand 1 "register_operand" "")))
4294   (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4295   (clobber (match_scratch 3 ""))]
4296  "reload_completed"
4297  [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4298	      (clobber (match_dup 3))])]
4299  "")
4300
4301;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4302;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4303;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4304;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4305;; function in i386.c.
4306(define_insn_and_split "*fix_trunc<mode>_i387_1"
4307  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4308	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4309   (clobber (reg:CC FLAGS_REG))]
4310  "TARGET_80387 && !TARGET_FISTTP
4311   && FLOAT_MODE_P (GET_MODE (operands[1]))
4312   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4313	 && (TARGET_64BIT || <MODE>mode != DImode))
4314   && !(reload_completed || reload_in_progress)"
4315  "#"
4316  "&& 1"
4317  [(const_int 0)]
4318{
4319  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4320
4321  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4322  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4323  if (memory_operand (operands[0], VOIDmode))
4324    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4325					 operands[2], operands[3]));
4326  else
4327    {
4328      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4329      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4330						     operands[2], operands[3],
4331						     operands[4]));
4332    }
4333  DONE;
4334}
4335  [(set_attr "type" "fistp")
4336   (set_attr "i387_cw" "trunc")
4337   (set_attr "mode" "<MODE>")])
4338
4339(define_insn "fix_truncdi_i387"
4340  [(set (match_operand:DI 0 "memory_operand" "=m")
4341	(fix:DI (match_operand 1 "register_operand" "f")))
4342   (use (match_operand:HI 2 "memory_operand" "m"))
4343   (use (match_operand:HI 3 "memory_operand" "m"))
4344   (clobber (match_scratch:XF 4 "=&1f"))]
4345  "TARGET_80387 && !TARGET_FISTTP
4346   && FLOAT_MODE_P (GET_MODE (operands[1]))
4347   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4348  "* return output_fix_trunc (insn, operands, 0);"
4349  [(set_attr "type" "fistp")
4350   (set_attr "i387_cw" "trunc")
4351   (set_attr "mode" "DI")])
4352
4353(define_insn "fix_truncdi_i387_with_temp"
4354  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4355	(fix:DI (match_operand 1 "register_operand" "f,f")))
4356   (use (match_operand:HI 2 "memory_operand" "m,m"))
4357   (use (match_operand:HI 3 "memory_operand" "m,m"))
4358   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4359   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4360  "TARGET_80387 && !TARGET_FISTTP
4361   && FLOAT_MODE_P (GET_MODE (operands[1]))
4362   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4363  "#"
4364  [(set_attr "type" "fistp")
4365   (set_attr "i387_cw" "trunc")
4366   (set_attr "mode" "DI")])
4367
4368(define_split 
4369  [(set (match_operand:DI 0 "register_operand" "")
4370	(fix:DI (match_operand 1 "register_operand" "")))
4371   (use (match_operand:HI 2 "memory_operand" ""))
4372   (use (match_operand:HI 3 "memory_operand" ""))
4373   (clobber (match_operand:DI 4 "memory_operand" ""))
4374   (clobber (match_scratch 5 ""))]
4375  "reload_completed"
4376  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4377	      (use (match_dup 2))
4378	      (use (match_dup 3))
4379	      (clobber (match_dup 5))])
4380   (set (match_dup 0) (match_dup 4))]
4381  "")
4382
4383(define_split 
4384  [(set (match_operand:DI 0 "memory_operand" "")
4385	(fix:DI (match_operand 1 "register_operand" "")))
4386   (use (match_operand:HI 2 "memory_operand" ""))
4387   (use (match_operand:HI 3 "memory_operand" ""))
4388   (clobber (match_operand:DI 4 "memory_operand" ""))
4389   (clobber (match_scratch 5 ""))]
4390  "reload_completed"
4391  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4392	      (use (match_dup 2))
4393	      (use (match_dup 3))
4394	      (clobber (match_dup 5))])]
4395  "")
4396
4397(define_insn "fix_trunc<mode>_i387"
4398  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4399	(fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4400   (use (match_operand:HI 2 "memory_operand" "m"))
4401   (use (match_operand:HI 3 "memory_operand" "m"))]
4402  "TARGET_80387 && !TARGET_FISTTP
4403   && FLOAT_MODE_P (GET_MODE (operands[1]))
4404   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4405  "* return output_fix_trunc (insn, operands, 0);"
4406  [(set_attr "type" "fistp")
4407   (set_attr "i387_cw" "trunc")
4408   (set_attr "mode" "<MODE>")])
4409
4410(define_insn "fix_trunc<mode>_i387_with_temp"
4411  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4412	(fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4413   (use (match_operand:HI 2 "memory_operand" "m,m"))
4414   (use (match_operand:HI 3 "memory_operand" "m,m"))
4415   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4416  "TARGET_80387 && !TARGET_FISTTP
4417   && FLOAT_MODE_P (GET_MODE (operands[1]))
4418   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4419  "#"
4420  [(set_attr "type" "fistp")
4421   (set_attr "i387_cw" "trunc")
4422   (set_attr "mode" "<MODE>")])
4423
4424(define_split 
4425  [(set (match_operand:X87MODEI12 0 "register_operand" "")
4426	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4427   (use (match_operand:HI 2 "memory_operand" ""))
4428   (use (match_operand:HI 3 "memory_operand" ""))
4429   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4430  "reload_completed"
4431  [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4432	      (use (match_dup 2))
4433	      (use (match_dup 3))])
4434   (set (match_dup 0) (match_dup 4))]
4435  "")
4436
4437(define_split 
4438  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4439	(fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4440   (use (match_operand:HI 2 "memory_operand" ""))
4441   (use (match_operand:HI 3 "memory_operand" ""))
4442   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4443  "reload_completed"
4444  [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4445	      (use (match_dup 2))
4446	      (use (match_dup 3))])]
4447  "")
4448
4449(define_insn "x86_fnstcw_1"
4450  [(set (match_operand:HI 0 "memory_operand" "=m")
4451	(unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4452  "TARGET_80387"
4453  "fnstcw\t%0"
4454  [(set_attr "length" "2")
4455   (set_attr "mode" "HI")
4456   (set_attr "unit" "i387")])
4457
4458(define_insn "x86_fldcw_1"
4459  [(set (reg:HI FPSR_REG)
4460	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4461  "TARGET_80387"
4462  "fldcw\t%0"
4463  [(set_attr "length" "2")
4464   (set_attr "mode" "HI")
4465   (set_attr "unit" "i387")
4466   (set_attr "athlon_decode" "vector")
4467   (set_attr "amdfam10_decode" "vector")])   
4468
4469;; Conversion between fixed point and floating point.
4470
4471;; Even though we only accept memory inputs, the backend _really_
4472;; wants to be able to do this between registers.
4473
4474(define_expand "floathisf2"
4475  [(set (match_operand:SF 0 "register_operand" "")
4476	(float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4477  "TARGET_80387 || TARGET_SSE_MATH"
4478{
4479  if (TARGET_SSE_MATH)
4480    {
4481      emit_insn (gen_floatsisf2 (operands[0],
4482				 convert_to_mode (SImode, operands[1], 0)));
4483      DONE;
4484    }
4485})
4486
4487(define_insn "*floathisf2_i387"
4488  [(set (match_operand:SF 0 "register_operand" "=f,f")
4489	(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4490  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4491  "@
4492   fild%z1\t%1
4493   #"
4494  [(set_attr "type" "fmov,multi")
4495   (set_attr "mode" "SF")
4496   (set_attr "unit" "*,i387")
4497   (set_attr "fp_int_src" "true")])
4498
4499(define_expand "floatsisf2"
4500  [(set (match_operand:SF 0 "register_operand" "")
4501	(float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4502  "TARGET_80387 || TARGET_SSE_MATH"
4503  "")
4504
4505(define_insn "*floatsisf2_mixed"
4506  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4507	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4508  "TARGET_MIX_SSE_I387"
4509  "@
4510   fild%z1\t%1
4511   #
4512   cvtsi2ss\t{%1, %0|%0, %1}
4513   cvtsi2ss\t{%1, %0|%0, %1}"
4514  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4515   (set_attr "mode" "SF")
4516   (set_attr "unit" "*,i387,*,*")
4517   (set_attr "athlon_decode" "*,*,vector,double")
4518   (set_attr "amdfam10_decode" "*,*,vector,double")
4519   (set_attr "fp_int_src" "true")])
4520
4521(define_insn "*floatsisf2_sse"
4522  [(set (match_operand:SF 0 "register_operand" "=x,x")
4523	(float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4524  "TARGET_SSE_MATH"
4525  "cvtsi2ss\t{%1, %0|%0, %1}"
4526  [(set_attr "type" "sseicvt")
4527   (set_attr "mode" "SF")
4528   (set_attr "athlon_decode" "vector,double")
4529   (set_attr "amdfam10_decode" "vector,double")
4530   (set_attr "fp_int_src" "true")])
4531
4532(define_insn "*floatsisf2_i387"
4533  [(set (match_operand:SF 0 "register_operand" "=f,f")
4534	(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4535  "TARGET_80387"
4536  "@
4537   fild%z1\t%1
4538   #"
4539  [(set_attr "type" "fmov,multi")
4540   (set_attr "mode" "SF")
4541   (set_attr "unit" "*,i387")
4542   (set_attr "fp_int_src" "true")])
4543
4544(define_expand "floatdisf2"
4545  [(set (match_operand:SF 0 "register_operand" "")
4546	(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4547  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4548  "")
4549
4550(define_insn "*floatdisf2_mixed"
4551  [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4552	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4553  "TARGET_64BIT && TARGET_MIX_SSE_I387"
4554  "@
4555   fild%z1\t%1
4556   #
4557   cvtsi2ss{q}\t{%1, %0|%0, %1}
4558   cvtsi2ss{q}\t{%1, %0|%0, %1}"
4559  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4560   (set_attr "mode" "SF")
4561   (set_attr "unit" "*,i387,*,*")
4562   (set_attr "athlon_decode" "*,*,vector,double")
4563   (set_attr "amdfam10_decode" "*,*,vector,double")
4564   (set_attr "fp_int_src" "true")])
4565
4566(define_insn "*floatdisf2_sse"
4567  [(set (match_operand:SF 0 "register_operand" "=x,x")
4568	(float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4569  "TARGET_64BIT && TARGET_SSE_MATH"
4570  "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4571  [(set_attr "type" "sseicvt")
4572   (set_attr "mode" "SF")
4573   (set_attr "athlon_decode" "vector,double")
4574   (set_attr "amdfam10_decode" "vector,double")
4575   (set_attr "fp_int_src" "true")])
4576
4577(define_insn "*floatdisf2_i387"
4578  [(set (match_operand:SF 0 "register_operand" "=f,f")
4579	(float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4580  "TARGET_80387"
4581  "@
4582   fild%z1\t%1
4583   #"
4584  [(set_attr "type" "fmov,multi")
4585   (set_attr "mode" "SF")
4586   (set_attr "unit" "*,i387")
4587   (set_attr "fp_int_src" "true")])
4588
4589(define_expand "floathidf2"
4590  [(set (match_operand:DF 0 "register_operand" "")
4591	(float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4592  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4593{
4594  if (TARGET_SSE2 && TARGET_SSE_MATH)
4595    {
4596      emit_insn (gen_floatsidf2 (operands[0],
4597				 convert_to_mode (SImode, operands[1], 0)));
4598      DONE;
4599    }
4600})
4601
4602(define_insn "*floathidf2_i387"
4603  [(set (match_operand:DF 0 "register_operand" "=f,f")
4604	(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4605  "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4606  "@
4607   fild%z1\t%1
4608   #"
4609  [(set_attr "type" "fmov,multi")
4610   (set_attr "mode" "DF")
4611   (set_attr "unit" "*,i387")
4612   (set_attr "fp_int_src" "true")])
4613
4614(define_expand "floatsidf2"
4615  [(set (match_operand:DF 0 "register_operand" "")
4616	(float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4617  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4618  "")
4619
4620(define_insn "*floatsidf2_mixed"
4621  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4622	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4623  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4624  "@
4625   fild%z1\t%1
4626   #
4627   cvtsi2sd\t{%1, %0|%0, %1}
4628   cvtsi2sd\t{%1, %0|%0, %1}"
4629  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4630   (set_attr "mode" "DF")
4631   (set_attr "unit" "*,i387,*,*")
4632   (set_attr "athlon_decode" "*,*,double,direct")
4633   (set_attr "amdfam10_decode" "*,*,vector,double")
4634   (set_attr "fp_int_src" "true")])
4635
4636(define_insn "*floatsidf2_sse"
4637  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4638	(float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4639  "TARGET_SSE2 && TARGET_SSE_MATH"
4640  "cvtsi2sd\t{%1, %0|%0, %1}"
4641  [(set_attr "type" "sseicvt")
4642   (set_attr "mode" "DF")
4643   (set_attr "athlon_decode" "double,direct")
4644   (set_attr "amdfam10_decode" "vector,double")
4645   (set_attr "fp_int_src" "true")])
4646
4647(define_insn "*floatsidf2_i387"
4648  [(set (match_operand:DF 0 "register_operand" "=f,f")
4649	(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4650  "TARGET_80387"
4651  "@
4652   fild%z1\t%1
4653   #"
4654  [(set_attr "type" "fmov,multi")
4655   (set_attr "mode" "DF")
4656   (set_attr "unit" "*,i387")
4657   (set_attr "fp_int_src" "true")])
4658
4659(define_expand "floatdidf2"
4660  [(set (match_operand:DF 0 "register_operand" "")
4661	(float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4662  "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4663  "")
4664
4665(define_insn "*floatdidf2_mixed"
4666  [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4667	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4668  "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4669  "@
4670   fild%z1\t%1
4671   #
4672   cvtsi2sd{q}\t{%1, %0|%0, %1}
4673   cvtsi2sd{q}\t{%1, %0|%0, %1}"
4674  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4675   (set_attr "mode" "DF")
4676   (set_attr "unit" "*,i387,*,*")
4677   (set_attr "athlon_decode" "*,*,double,direct")
4678   (set_attr "amdfam10_decode" "*,*,vector,double")
4679   (set_attr "fp_int_src" "true")])
4680
4681(define_insn "*floatdidf2_sse"
4682  [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4683	(float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4684  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4685  "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4686  [(set_attr "type" "sseicvt")
4687   (set_attr "mode" "DF")
4688   (set_attr "athlon_decode" "double,direct")
4689   (set_attr "amdfam10_decode" "vector,double")
4690   (set_attr "fp_int_src" "true")])
4691
4692(define_insn "*floatdidf2_i387"
4693  [(set (match_operand:DF 0 "register_operand" "=f,f")
4694	(float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4695  "TARGET_80387"
4696  "@
4697   fild%z1\t%1
4698   #"
4699  [(set_attr "type" "fmov,multi")
4700   (set_attr "mode" "DF")
4701   (set_attr "unit" "*,i387")
4702   (set_attr "fp_int_src" "true")])
4703
4704(define_insn "floathixf2"
4705  [(set (match_operand:XF 0 "register_operand" "=f,f")
4706	(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4707  "TARGET_80387"
4708  "@
4709   fild%z1\t%1
4710   #"
4711  [(set_attr "type" "fmov,multi")
4712   (set_attr "mode" "XF")
4713   (set_attr "unit" "*,i387")
4714   (set_attr "fp_int_src" "true")])
4715
4716(define_insn "floatsixf2"
4717  [(set (match_operand:XF 0 "register_operand" "=f,f")
4718	(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4719  "TARGET_80387"
4720  "@
4721   fild%z1\t%1
4722   #"
4723  [(set_attr "type" "fmov,multi")
4724   (set_attr "mode" "XF")
4725   (set_attr "unit" "*,i387")
4726   (set_attr "fp_int_src" "true")])
4727
4728(define_insn "floatdixf2"
4729  [(set (match_operand:XF 0 "register_operand" "=f,f")
4730	(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4731  "TARGET_80387"
4732  "@
4733   fild%z1\t%1
4734   #"
4735  [(set_attr "type" "fmov,multi")
4736   (set_attr "mode" "XF")
4737   (set_attr "unit" "*,i387")
4738   (set_attr "fp_int_src" "true")])
4739
4740;; %%% Kill these when reload knows how to do it.
4741(define_split
4742  [(set (match_operand 0 "fp_register_operand" "")
4743	(float (match_operand 1 "register_operand" "")))]
4744  "reload_completed
4745   && TARGET_80387
4746   && FLOAT_MODE_P (GET_MODE (operands[0]))"
4747  [(const_int 0)]
4748{
4749  operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4750  operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4751  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4752  ix86_free_from_memory (GET_MODE (operands[1]));
4753  DONE;
4754})
4755
4756(define_expand "floatunssisf2"
4757  [(use (match_operand:SF 0 "register_operand" ""))
4758   (use (match_operand:SI 1 "register_operand" ""))]
4759  "!TARGET_64BIT && TARGET_SSE_MATH"
4760  "x86_emit_floatuns (operands); DONE;")
4761
4762(define_expand "floatunsdisf2"
4763  [(use (match_operand:SF 0 "register_operand" ""))
4764   (use (match_operand:DI 1 "register_operand" ""))]
4765  "TARGET_64BIT && TARGET_SSE_MATH"
4766  "x86_emit_floatuns (operands); DONE;")
4767
4768(define_expand "floatunsdidf2"
4769  [(use (match_operand:DF 0 "register_operand" ""))
4770   (use (match_operand:DI 1 "register_operand" ""))]
4771  "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4772  "x86_emit_floatuns (operands); DONE;")
4773
4774;; SSE extract/set expanders
4775
4776
4777;; Add instructions
4778
4779;; %%% splits for addditi3
4780
4781(define_expand "addti3"
4782  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4783	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4784		 (match_operand:TI 2 "x86_64_general_operand" "")))
4785   (clobber (reg:CC FLAGS_REG))]
4786  "TARGET_64BIT"
4787  "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4788
4789(define_insn "*addti3_1"
4790  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4791	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4792		 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4793   (clobber (reg:CC FLAGS_REG))]
4794  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4795  "#")
4796
4797(define_split
4798  [(set (match_operand:TI 0 "nonimmediate_operand" "")
4799	(plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4800		 (match_operand:TI 2 "x86_64_general_operand" "")))
4801   (clobber (reg:CC FLAGS_REG))]
4802  "TARGET_64BIT && reload_completed"
4803  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4804					  UNSPEC_ADD_CARRY))
4805	      (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4806   (parallel [(set (match_dup 3)
4807		   (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4808				     (match_dup 4))
4809			    (match_dup 5)))
4810	      (clobber (reg:CC FLAGS_REG))])]
4811  "split_ti (operands+0, 1, operands+0, operands+3);
4812   split_ti (operands+1, 1, operands+1, operands+4);
4813   split_ti (operands+2, 1, operands+2, operands+5);")
4814
4815;; %%% splits for addsidi3
4816;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4817;	(plus:DI (match_operand:DI 1 "general_operand" "")
4818;		 (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4819
4820(define_expand "adddi3"
4821  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4822	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4823		 (match_operand:DI 2 "x86_64_general_operand" "")))
4824   (clobber (reg:CC FLAGS_REG))]
4825  ""
4826  "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4827
4828(define_insn "*adddi3_1"
4829  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4830	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4831		 (match_operand:DI 2 "general_operand" "roiF,riF")))
4832   (clobber (reg:CC FLAGS_REG))]
4833  "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834  "#")
4835
4836(define_split
4837  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4838	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4839		 (match_operand:DI 2 "general_operand" "")))
4840   (clobber (reg:CC FLAGS_REG))]
4841  "!TARGET_64BIT && reload_completed"
4842  [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4843					  UNSPEC_ADD_CARRY))
4844	      (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4845   (parallel [(set (match_dup 3)
4846		   (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4847				     (match_dup 4))
4848			    (match_dup 5)))
4849	      (clobber (reg:CC FLAGS_REG))])]
4850  "split_di (operands+0, 1, operands+0, operands+3);
4851   split_di (operands+1, 1, operands+1, operands+4);
4852   split_di (operands+2, 1, operands+2, operands+5);")
4853
4854(define_insn "adddi3_carry_rex64"
4855  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4856	  (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4857			    (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4858		   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4859   (clobber (reg:CC FLAGS_REG))]
4860  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4861  "adc{q}\t{%2, %0|%0, %2}"
4862  [(set_attr "type" "alu")
4863   (set_attr "pent_pair" "pu")
4864   (set_attr "mode" "DI")])
4865
4866(define_insn "*adddi3_cc_rex64"
4867  [(set (reg:CC FLAGS_REG)
4868	(unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4869		    (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4870		   UNSPEC_ADD_CARRY))
4871   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4872	(plus:DI (match_dup 1) (match_dup 2)))]
4873  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4874  "add{q}\t{%2, %0|%0, %2}"
4875  [(set_attr "type" "alu")
4876   (set_attr "mode" "DI")])
4877
4878(define_insn "addqi3_carry"
4879  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4880	  (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4881			    (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4882		   (match_operand:QI 2 "general_operand" "qi,qm")))
4883   (clobber (reg:CC FLAGS_REG))]
4884  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4885  "adc{b}\t{%2, %0|%0, %2}"
4886  [(set_attr "type" "alu")
4887   (set_attr "pent_pair" "pu")
4888   (set_attr "mode" "QI")])
4889
4890(define_insn "addhi3_carry"
4891  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4892	  (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4893			    (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4894		   (match_operand:HI 2 "general_operand" "ri,rm")))
4895   (clobber (reg:CC FLAGS_REG))]
4896  "ix86_binary_operator_ok (PLUS, HImode, operands)"
4897  "adc{w}\t{%2, %0|%0, %2}"
4898  [(set_attr "type" "alu")
4899   (set_attr "pent_pair" "pu")
4900   (set_attr "mode" "HI")])
4901
4902(define_insn "addsi3_carry"
4903  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4904	  (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4905			    (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4906		   (match_operand:SI 2 "general_operand" "ri,rm")))
4907   (clobber (reg:CC FLAGS_REG))]
4908  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4909  "adc{l}\t{%2, %0|%0, %2}"
4910  [(set_attr "type" "alu")
4911   (set_attr "pent_pair" "pu")
4912   (set_attr "mode" "SI")])
4913
4914(define_insn "*addsi3_carry_zext"
4915  [(set (match_operand:DI 0 "register_operand" "=r")
4916	  (zero_extend:DI 
4917	    (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4918			      (match_operand:SI 1 "nonimmediate_operand" "%0"))
4919		     (match_operand:SI 2 "general_operand" "rim"))))
4920   (clobber (reg:CC FLAGS_REG))]
4921  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4922  "adc{l}\t{%2, %k0|%k0, %2}"
4923  [(set_attr "type" "alu")
4924   (set_attr "pent_pair" "pu")
4925   (set_attr "mode" "SI")])
4926
4927(define_insn "*addsi3_cc"
4928  [(set (reg:CC FLAGS_REG)
4929	(unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4930		    (match_operand:SI 2 "general_operand" "ri,rm")]
4931		   UNSPEC_ADD_CARRY))
4932   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4933	(plus:SI (match_dup 1) (match_dup 2)))]
4934  "ix86_binary_operator_ok (PLUS, SImode, operands)"
4935  "add{l}\t{%2, %0|%0, %2}"
4936  [(set_attr "type" "alu")
4937   (set_attr "mode" "SI")])
4938
4939(define_insn "addqi3_cc"
4940  [(set (reg:CC FLAGS_REG)
4941	(unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4942		    (match_operand:QI 2 "general_operand" "qi,qm")]
4943		   UNSPEC_ADD_CARRY))
4944   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4945	(plus:QI (match_dup 1) (match_dup 2)))]
4946  "ix86_binary_operator_ok (PLUS, QImode, operands)"
4947  "add{b}\t{%2, %0|%0, %2}"
4948  [(set_attr "type" "alu")
4949   (set_attr "mode" "QI")])
4950
4951(define_expand "addsi3"
4952  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4953		   (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4954			    (match_operand:SI 2 "general_operand" "")))
4955	      (clobber (reg:CC FLAGS_REG))])]
4956  ""
4957  "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4958
4959(define_insn "*lea_1"
4960  [(set (match_operand:SI 0 "register_operand" "=r")
4961	(match_operand:SI 1 "no_seg_address_operand" "p"))]
4962  "!TARGET_64BIT"
4963  "lea{l}\t{%a1, %0|%0, %a1}"
4964  [(set_attr "type" "lea")
4965   (set_attr "mode" "SI")])
4966
4967(define_insn "*lea_1_rex64"
4968  [(set (match_operand:SI 0 "register_operand" "=r")
4969	(subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4970  "TARGET_64BIT"
4971  "lea{l}\t{%a1, %0|%0, %a1}"
4972  [(set_attr "type" "lea")
4973   (set_attr "mode" "SI")])
4974
4975(define_insn "*lea_1_zext"
4976  [(set (match_operand:DI 0 "register_operand" "=r")
4977	(zero_extend:DI
4978	 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4979  "TARGET_64BIT"
4980  "lea{l}\t{%a1, %k0|%k0, %a1}"
4981  [(set_attr "type" "lea")
4982   (set_attr "mode" "SI")])
4983
4984(define_insn "*lea_2_rex64"
4985  [(set (match_operand:DI 0 "register_operand" "=r")
4986	(match_operand:DI 1 "no_seg_address_operand" "p"))]
4987  "TARGET_64BIT"
4988  "lea{q}\t{%a1, %0|%0, %a1}"
4989  [(set_attr "type" "lea")
4990   (set_attr "mode" "DI")])
4991
4992;; The lea patterns for non-Pmodes needs to be matched by several
4993;; insns converted to real lea by splitters.
4994
4995(define_insn_and_split "*lea_general_1"
4996  [(set (match_operand 0 "register_operand" "=r")
4997	(plus (plus (match_operand 1 "index_register_operand" "l")
4998		    (match_operand 2 "register_operand" "r"))
4999	      (match_operand 3 "immediate_operand" "i")))]
5000  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5001    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5002   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5003   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5004   && GET_MODE (operands[0]) == GET_MODE (operands[2])
5005   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5006       || GET_MODE (operands[3]) == VOIDmode)"
5007  "#"
5008  "&& reload_completed"
5009  [(const_int 0)]
5010{
5011  rtx pat;
5012  operands[0] = gen_lowpart (SImode, operands[0]);
5013  operands[1] = gen_lowpart (Pmode, operands[1]);
5014  operands[2] = gen_lowpart (Pmode, operands[2]);
5015  operands[3] = gen_lowpart (Pmode, operands[3]);
5016  pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5017  		      operands[3]);
5018  if (Pmode != SImode)
5019    pat = gen_rtx_SUBREG (SImode, pat, 0);
5020  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5021  DONE;
5022}
5023  [(set_attr "type" "lea")
5024   (set_attr "mode" "SI")])
5025
5026(define_insn_and_split "*lea_general_1_zext"
5027  [(set (match_operand:DI 0 "register_operand" "=r")
5028	(zero_extend:DI
5029	  (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5030			    (match_operand:SI 2 "register_operand" "r"))
5031		   (match_operand:SI 3 "immediate_operand" "i"))))]
5032  "TARGET_64BIT"
5033  "#"
5034  "&& reload_completed"
5035  [(set (match_dup 0)
5036	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5037						     (match_dup 2))
5038					    (match_dup 3)) 0)))]
5039{
5040  operands[1] = gen_lowpart (Pmode, operands[1]);
5041  operands[2] = gen_lowpart (Pmode, operands[2]);
5042  operands[3] = gen_lowpart (Pmode, operands[3]);
5043}
5044  [(set_attr "type" "lea")
5045   (set_attr "mode" "SI")])
5046
5047(define_insn_and_split "*lea_general_2"
5048  [(set (match_operand 0 "register_operand" "=r")
5049	(plus (mult (match_operand 1 "index_register_operand" "l")
5050		    (match_operand 2 "const248_operand" "i"))
5051	      (match_operand 3 "nonmemory_operand" "ri")))]
5052  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5053    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5054   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5055   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5056   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5057       || GET_MODE (operands[3]) == VOIDmode)"
5058  "#"
5059  "&& reload_completed"
5060  [(const_int 0)]
5061{
5062  rtx pat;
5063  operands[0] = gen_lowpart (SImode, operands[0]);
5064  operands[1] = gen_lowpart (Pmode, operands[1]);
5065  operands[3] = gen_lowpart (Pmode, operands[3]);
5066  pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5067  		      operands[3]);
5068  if (Pmode != SImode)
5069    pat = gen_rtx_SUBREG (SImode, pat, 0);
5070  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5071  DONE;
5072}
5073  [(set_attr "type" "lea")
5074   (set_attr "mode" "SI")])
5075
5076(define_insn_and_split "*lea_general_2_zext"
5077  [(set (match_operand:DI 0 "register_operand" "=r")
5078	(zero_extend:DI
5079	  (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5080			    (match_operand:SI 2 "const248_operand" "n"))
5081		   (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5082  "TARGET_64BIT"
5083  "#"
5084  "&& reload_completed"
5085  [(set (match_dup 0)
5086	(zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5087						     (match_dup 2))
5088					    (match_dup 3)) 0)))]
5089{
5090  operands[1] = gen_lowpart (Pmode, operands[1]);
5091  operands[3] = gen_lowpart (Pmode, operands[3]);
5092}
5093  [(set_attr "type" "lea")
5094   (set_attr "mode" "SI")])
5095
5096(define_insn_and_split "*lea_general_3"
5097  [(set (match_operand 0 "register_operand" "=r")
5098	(plus (plus (mult (match_operand 1 "index_register_operand" "l")
5099			  (match_operand 2 "const248_operand" "i"))
5100		    (match_operand 3 "register_operand" "r"))
5101	      (match_operand 4 "immediate_operand" "i")))]
5102  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5103    || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5104   && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5105   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5106   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5107  "#"
5108  "&& reload_completed"
5109  [(const_int 0)]
5110{
5111  rtx pat;
5112  operands[0] = gen_lowpart (SImode, operands[0]);
5113  operands[1] = gen_lowpart (Pmode, operands[1]);
5114  operands[3] = gen_lowpart (Pmode, operands[3]);
5115  operands[4] = gen_lowpart (Pmode, operands[4]);
5116  pat = gen_rtx_PLUS (Pmode,
5117  		      gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5118		      					 operands[2]),
5119				    operands[3]),
5120  		      operands[4]);
5121  if (Pmode != SImode)
5122    pat = gen_rtx_SUBREG (SImode, pat, 0);
5123  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5124  DONE;
5125}
5126  [(set_attr "type" "lea")
5127   (set_attr "mode" "SI")])
5128
5129(define_insn_and_split "*lea_general_3_zext"
5130  [(set (match_operand:DI 0 "register_operand" "=r")
5131	(zero_extend:DI
5132	  (plus:SI (plus:SI (mult:SI
5133			      (match_operand:SI 1 "index_register_operand" "l")
5134			      (match_operand:SI 2 "const248_operand" "n"))
5135			    (match_operand:SI 3 "register_operand" "r"))
5136		   (match_operand:SI 4 "immediate_operand" "i"))))]
5137  "TARGET_64BIT"
5138  "#"
5139  "&& reload_completed"
5140  [(set (match_dup 0)
5141	(zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5142							      (match_dup 2))
5143						     (match_dup 3))
5144					    (match_dup 4)) 0)))]
5145{
5146  operands[1] = gen_lowpart (Pmode, operands[1]);
5147  operands[3] = gen_lowpart (Pmode, operands[3]);
5148  operands[4] = gen_lowpart (Pmode, operands[4]);
5149}
5150  [(set_attr "type" "lea")
5151   (set_attr "mode" "SI")])
5152
5153(define_insn "*adddi_1_rex64"
5154  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5155	(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5156		 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5157   (clobber (reg:CC FLAGS_REG))]
5158  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5159{
5160  switch (get_attr_type (insn))
5161    {
5162    case TYPE_LEA:
5163      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5164      return "lea{q}\t{%a2, %0|%0, %a2}";
5165
5166    case TYPE_INCDEC:
5167      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168      if (operands[2] == const1_rtx)
5169        return "inc{q}\t%0";
5170      else
5171        {
5172	  gcc_assert (operands[2] == constm1_rtx);
5173          return "dec{q}\t%0";
5174	}
5175
5176    default:
5177      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5178
5179      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5180	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5181      if (GET_CODE (operands[2]) == CONST_INT
5182	  /* Avoid overflows.  */
5183	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5184          && (INTVAL (operands[2]) == 128
5185	      || (INTVAL (operands[2]) < 0
5186		  && INTVAL (operands[2]) != -128)))
5187        {
5188          operands[2] = GEN_INT (-INTVAL (operands[2]));
5189          return "sub{q}\t{%2, %0|%0, %2}";
5190        }
5191      return "add{q}\t{%2, %0|%0, %2}";
5192    }
5193}
5194  [(set (attr "type")
5195     (cond [(eq_attr "alternative" "2")
5196	      (const_string "lea")
5197	    ; Current assemblers are broken and do not allow @GOTOFF in
5198	    ; ought but a memory context.
5199	    (match_operand:DI 2 "pic_symbolic_operand" "")
5200	      (const_string "lea")
5201	    (match_operand:DI 2 "incdec_operand" "")
5202	      (const_string "incdec")
5203	   ]
5204	   (const_string "alu")))
5205   (set_attr "mode" "DI")])
5206
5207;; Convert lea to the lea pattern to avoid flags dependency.
5208(define_split
5209  [(set (match_operand:DI 0 "register_operand" "")
5210	(plus:DI (match_operand:DI 1 "register_operand" "")
5211		 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5212   (clobber (reg:CC FLAGS_REG))]
5213  "TARGET_64BIT && reload_completed
5214   && true_regnum (operands[0]) != true_regnum (operands[1])"
5215  [(set (match_dup 0)
5216	(plus:DI (match_dup 1)
5217		 (match_dup 2)))]
5218  "")
5219
5220(define_insn "*adddi_2_rex64"
5221  [(set (reg FLAGS_REG)
5222	(compare
5223	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5224		   (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5225	  (const_int 0)))			
5226   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5227	(plus:DI (match_dup 1) (match_dup 2)))]
5228  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5229   && ix86_binary_operator_ok (PLUS, DImode, operands)
5230   /* Current assemblers are broken and do not allow @GOTOFF in
5231      ought but a memory context.  */
5232   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5233{
5234  switch (get_attr_type (insn))
5235    {
5236    case TYPE_INCDEC:
5237      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5238      if (operands[2] == const1_rtx)
5239        return "inc{q}\t%0";
5240      else
5241        {
5242	  gcc_assert (operands[2] == constm1_rtx);
5243          return "dec{q}\t%0";
5244	}
5245
5246    default:
5247      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5248      /* ???? We ought to handle there the 32bit case too
5249	 - do we need new constraint?  */
5250      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5251	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5252      if (GET_CODE (operands[2]) == CONST_INT
5253	  /* Avoid overflows.  */
5254	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5255          && (INTVAL (operands[2]) == 128
5256	      || (INTVAL (operands[2]) < 0
5257		  && INTVAL (operands[2]) != -128)))
5258        {
5259          operands[2] = GEN_INT (-INTVAL (operands[2]));
5260          return "sub{q}\t{%2, %0|%0, %2}";
5261        }
5262      return "add{q}\t{%2, %0|%0, %2}";
5263    }
5264}
5265  [(set (attr "type")
5266     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5267	(const_string "incdec")
5268	(const_string "alu")))
5269   (set_attr "mode" "DI")])
5270
5271(define_insn "*adddi_3_rex64"
5272  [(set (reg FLAGS_REG)
5273	(compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5274		 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5275   (clobber (match_scratch:DI 0 "=r"))]
5276  "TARGET_64BIT
5277   && ix86_match_ccmode (insn, CCZmode)
5278   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5279   /* Current assemblers are broken and do not allow @GOTOFF in
5280      ought but a memory context.  */
5281   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5282{
5283  switch (get_attr_type (insn))
5284    {
5285    case TYPE_INCDEC:
5286      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5287      if (operands[2] == const1_rtx)
5288        return "inc{q}\t%0";
5289      else
5290        {
5291	  gcc_assert (operands[2] == constm1_rtx);
5292          return "dec{q}\t%0";
5293	}
5294
5295    default:
5296      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5297      /* ???? We ought to handle there the 32bit case too
5298	 - do we need new constraint?  */
5299      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5300	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5301      if (GET_CODE (operands[2]) == CONST_INT
5302	  /* Avoid overflows.  */
5303	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5304          && (INTVAL (operands[2]) == 128
5305	      || (INTVAL (operands[2]) < 0
5306		  && INTVAL (operands[2]) != -128)))
5307        {
5308          operands[2] = GEN_INT (-INTVAL (operands[2]));
5309          return "sub{q}\t{%2, %0|%0, %2}";
5310        }
5311      return "add{q}\t{%2, %0|%0, %2}";
5312    }
5313}
5314  [(set (attr "type")
5315     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5316	(const_string "incdec")
5317	(const_string "alu")))
5318   (set_attr "mode" "DI")])
5319
5320; For comparisons against 1, -1 and 128, we may generate better code
5321; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5322; is matched then.  We can't accept general immediate, because for
5323; case of overflows,  the result is messed up.
5324; This pattern also don't hold of 0x8000000000000000, since the value overflows
5325; when negated.
5326; Also carry flag is reversed compared to cmp, so this conversion is valid
5327; only for comparisons not depending on it.
5328(define_insn "*adddi_4_rex64"
5329  [(set (reg FLAGS_REG)
5330	(compare (match_operand:DI 1 "nonimmediate_operand" "0")
5331		 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5332   (clobber (match_scratch:DI 0 "=rm"))]
5333  "TARGET_64BIT
5334   &&  ix86_match_ccmode (insn, CCGCmode)"
5335{
5336  switch (get_attr_type (insn))
5337    {
5338    case TYPE_INCDEC:
5339      if (operands[2] == constm1_rtx)
5340        return "inc{q}\t%0";
5341      else
5342        {
5343	  gcc_assert (operands[2] == const1_rtx);
5344          return "dec{q}\t%0";
5345	}
5346
5347    default:
5348      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5349      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5350	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5351      if ((INTVAL (operands[2]) == -128
5352	   || (INTVAL (operands[2]) > 0
5353	       && INTVAL (operands[2]) != 128))
5354	  /* Avoid overflows.  */
5355	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5356	return "sub{q}\t{%2, %0|%0, %2}";
5357      operands[2] = GEN_INT (-INTVAL (operands[2]));
5358      return "add{q}\t{%2, %0|%0, %2}";
5359    }
5360}
5361  [(set (attr "type")
5362     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5363	(const_string "incdec")
5364	(const_string "alu")))
5365   (set_attr "mode" "DI")])
5366
5367(define_insn "*adddi_5_rex64"
5368  [(set (reg FLAGS_REG)
5369	(compare
5370	  (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5371		   (match_operand:DI 2 "x86_64_general_operand" "rme"))
5372	  (const_int 0)))			
5373   (clobber (match_scratch:DI 0 "=r"))]
5374  "TARGET_64BIT
5375   && ix86_match_ccmode (insn, CCGOCmode)
5376   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5377   /* Current assemblers are broken and do not allow @GOTOFF in
5378      ought but a memory context.  */
5379   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5380{
5381  switch (get_attr_type (insn))
5382    {
5383    case TYPE_INCDEC:
5384      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5385      if (operands[2] == const1_rtx)
5386        return "inc{q}\t%0";
5387      else
5388        {
5389          gcc_assert (operands[2] == constm1_rtx);
5390          return "dec{q}\t%0";
5391	}
5392
5393    default:
5394      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5395      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5396	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5397      if (GET_CODE (operands[2]) == CONST_INT
5398	  /* Avoid overflows.  */
5399	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5400          && (INTVAL (operands[2]) == 128
5401	      || (INTVAL (operands[2]) < 0
5402		  && INTVAL (operands[2]) != -128)))
5403        {
5404          operands[2] = GEN_INT (-INTVAL (operands[2]));
5405          return "sub{q}\t{%2, %0|%0, %2}";
5406        }
5407      return "add{q}\t{%2, %0|%0, %2}";
5408    }
5409}
5410  [(set (attr "type")
5411     (if_then_else (match_operand:DI 2 "incdec_operand" "")
5412	(const_string "incdec")
5413	(const_string "alu")))
5414   (set_attr "mode" "DI")])
5415
5416
5417(define_insn "*addsi_1"
5418  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5419	(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5420		 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5421   (clobber (reg:CC FLAGS_REG))]
5422  "ix86_binary_operator_ok (PLUS, SImode, operands)"
5423{
5424  switch (get_attr_type (insn))
5425    {
5426    case TYPE_LEA:
5427      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5428      return "lea{l}\t{%a2, %0|%0, %a2}";
5429
5430    case TYPE_INCDEC:
5431      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5432      if (operands[2] == const1_rtx)
5433        return "inc{l}\t%0";
5434      else
5435	{
5436  	  gcc_assert (operands[2] == constm1_rtx);
5437          return "dec{l}\t%0";
5438	}
5439
5440    default:
5441      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5442
5443      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5445      if (GET_CODE (operands[2]) == CONST_INT
5446          && (INTVAL (operands[2]) == 128
5447	      || (INTVAL (operands[2]) < 0
5448		  && INTVAL (operands[2]) != -128)))
5449        {
5450          operands[2] = GEN_INT (-INTVAL (operands[2]));
5451          return "sub{l}\t{%2, %0|%0, %2}";
5452        }
5453      return "add{l}\t{%2, %0|%0, %2}";
5454    }
5455}
5456  [(set (attr "type")
5457     (cond [(eq_attr "alternative" "2")
5458	      (const_string "lea")
5459	    ; Current assemblers are broken and do not allow @GOTOFF in
5460	    ; ought but a memory context.
5461	    (match_operand:SI 2 "pic_symbolic_operand" "")
5462	      (const_string "lea")
5463	    (match_operand:SI 2 "incdec_operand" "")
5464	      (const_string "incdec")
5465	   ]
5466	   (const_string "alu")))
5467   (set_attr "mode" "SI")])
5468
5469;; Convert lea to the lea pattern to avoid flags dependency.
5470(define_split
5471  [(set (match_operand 0 "register_operand" "")
5472	(plus (match_operand 1 "register_operand" "")
5473              (match_operand 2 "nonmemory_operand" "")))
5474   (clobber (reg:CC FLAGS_REG))]
5475  "reload_completed
5476   && true_regnum (operands[0]) != true_regnum (operands[1])"
5477  [(const_int 0)]
5478{
5479  rtx pat;
5480  /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5481     may confuse gen_lowpart.  */
5482  if (GET_MODE (operands[0]) != Pmode)
5483    {
5484      operands[1] = gen_lowpart (Pmode, operands[1]);
5485      operands[2] = gen_lowpart (Pmode, operands[2]);
5486    }
5487  operands[0] = gen_lowpart (SImode, operands[0]);
5488  pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5489  if (Pmode != SImode)
5490    pat = gen_rtx_SUBREG (SImode, pat, 0);
5491  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5492  DONE;
5493})
5494
5495;; It may seem that nonimmediate operand is proper one for operand 1.
5496;; The addsi_1 pattern allows nonimmediate operand at that place and
5497;; we take care in ix86_binary_operator_ok to not allow two memory
5498;; operands so proper swapping will be done in reload.  This allow
5499;; patterns constructed from addsi_1 to match.
5500(define_insn "addsi_1_zext"
5501  [(set (match_operand:DI 0 "register_operand" "=r,r")
5502	(zero_extend:DI
5503	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5504		   (match_operand:SI 2 "general_operand" "rmni,lni"))))
5505   (clobber (reg:CC FLAGS_REG))]
5506  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5507{
5508  switch (get_attr_type (insn))
5509    {
5510    case TYPE_LEA:
5511      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5512      return "lea{l}\t{%a2, %k0|%k0, %a2}";
5513
5514    case TYPE_INCDEC:
5515      if (operands[2] == const1_rtx)
5516        return "inc{l}\t%k0";
5517      else
5518        {
5519	  gcc_assert (operands[2] == constm1_rtx);
5520          return "dec{l}\t%k0";
5521	}
5522
5523    default:
5524      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5525	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5526      if (GET_CODE (operands[2]) == CONST_INT
5527          && (INTVAL (operands[2]) == 128
5528	      || (INTVAL (operands[2]) < 0
5529		  && INTVAL (operands[2]) != -128)))
5530        {
5531          operands[2] = GEN_INT (-INTVAL (operands[2]));
5532          return "sub{l}\t{%2, %k0|%k0, %2}";
5533        }
5534      return "add{l}\t{%2, %k0|%k0, %2}";
5535    }
5536}
5537  [(set (attr "type")
5538     (cond [(eq_attr "alternative" "1")
5539	      (const_string "lea")
5540	    ; Current assemblers are broken and do not allow @GOTOFF in
5541	    ; ought but a memory context.
5542	    (match_operand:SI 2 "pic_symbolic_operand" "")
5543	      (const_string "lea")
5544	    (match_operand:SI 2 "incdec_operand" "")
5545	      (const_string "incdec")
5546	   ]
5547	   (const_string "alu")))
5548   (set_attr "mode" "SI")])
5549
5550;; Convert lea to the lea pattern to avoid flags dependency.
5551(define_split
5552  [(set (match_operand:DI 0 "register_operand" "")
5553	(zero_extend:DI
5554	  (plus:SI (match_operand:SI 1 "register_operand" "")
5555		   (match_operand:SI 2 "nonmemory_operand" ""))))
5556   (clobber (reg:CC FLAGS_REG))]
5557  "TARGET_64BIT && reload_completed
5558   && true_regnum (operands[0]) != true_regnum (operands[1])"
5559  [(set (match_dup 0)
5560	(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5561{
5562  operands[1] = gen_lowpart (Pmode, operands[1]);
5563  operands[2] = gen_lowpart (Pmode, operands[2]);
5564})
5565
5566(define_insn "*addsi_2"
5567  [(set (reg FLAGS_REG)
5568	(compare
5569	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5570		   (match_operand:SI 2 "general_operand" "rmni,rni"))
5571	  (const_int 0)))			
5572   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5573	(plus:SI (match_dup 1) (match_dup 2)))]
5574  "ix86_match_ccmode (insn, CCGOCmode)
5575   && ix86_binary_operator_ok (PLUS, SImode, operands)
5576   /* Current assemblers are broken and do not allow @GOTOFF in
5577      ought but a memory context.  */
5578   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5579{
5580  switch (get_attr_type (insn))
5581    {
5582    case TYPE_INCDEC:
5583      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584      if (operands[2] == const1_rtx)
5585        return "inc{l}\t%0";
5586      else
5587        {
5588	  gcc_assert (operands[2] == constm1_rtx);
5589          return "dec{l}\t%0";
5590	}
5591
5592    default:
5593      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5594      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5595	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5596      if (GET_CODE (operands[2]) == CONST_INT
5597          && (INTVAL (operands[2]) == 128
5598	      || (INTVAL (operands[2]) < 0
5599		  && INTVAL (operands[2]) != -128)))
5600        {
5601          operands[2] = GEN_INT (-INTVAL (operands[2]));
5602          return "sub{l}\t{%2, %0|%0, %2}";
5603        }
5604      return "add{l}\t{%2, %0|%0, %2}";
5605    }
5606}
5607  [(set (attr "type")
5608     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5609	(const_string "incdec")
5610	(const_string "alu")))
5611   (set_attr "mode" "SI")])
5612
5613;; See comment for addsi_1_zext why we do use nonimmediate_operand
5614(define_insn "*addsi_2_zext"
5615  [(set (reg FLAGS_REG)
5616	(compare
5617	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5618		   (match_operand:SI 2 "general_operand" "rmni"))
5619	  (const_int 0)))			
5620   (set (match_operand:DI 0 "register_operand" "=r")
5621	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5622  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5623   && ix86_binary_operator_ok (PLUS, SImode, operands)
5624   /* Current assemblers are broken and do not allow @GOTOFF in
5625      ought but a memory context.  */
5626   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5627{
5628  switch (get_attr_type (insn))
5629    {
5630    case TYPE_INCDEC:
5631      if (operands[2] == const1_rtx)
5632        return "inc{l}\t%k0";
5633      else
5634	{
5635	  gcc_assert (operands[2] == constm1_rtx);
5636          return "dec{l}\t%k0";
5637	}
5638
5639    default:
5640      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5641	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5642      if (GET_CODE (operands[2]) == CONST_INT
5643          && (INTVAL (operands[2]) == 128
5644	      || (INTVAL (operands[2]) < 0
5645		  && INTVAL (operands[2]) != -128)))
5646        {
5647          operands[2] = GEN_INT (-INTVAL (operands[2]));
5648          return "sub{l}\t{%2, %k0|%k0, %2}";
5649        }
5650      return "add{l}\t{%2, %k0|%k0, %2}";
5651    }
5652}
5653  [(set (attr "type")
5654     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5655	(const_string "incdec")
5656	(const_string "alu")))
5657   (set_attr "mode" "SI")])
5658
5659(define_insn "*addsi_3"
5660  [(set (reg FLAGS_REG)
5661	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5662		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5663   (clobber (match_scratch:SI 0 "=r"))]
5664  "ix86_match_ccmode (insn, CCZmode)
5665   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5666   /* Current assemblers are broken and do not allow @GOTOFF in
5667      ought but a memory context.  */
5668   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5669{
5670  switch (get_attr_type (insn))
5671    {
5672    case TYPE_INCDEC:
5673      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5674      if (operands[2] == const1_rtx)
5675        return "inc{l}\t%0";
5676      else
5677        {
5678	  gcc_assert (operands[2] == constm1_rtx);
5679          return "dec{l}\t%0";
5680	}
5681
5682    default:
5683      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5685	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5686      if (GET_CODE (operands[2]) == CONST_INT
5687          && (INTVAL (operands[2]) == 128
5688	      || (INTVAL (operands[2]) < 0
5689		  && INTVAL (operands[2]) != -128)))
5690        {
5691          operands[2] = GEN_INT (-INTVAL (operands[2]));
5692          return "sub{l}\t{%2, %0|%0, %2}";
5693        }
5694      return "add{l}\t{%2, %0|%0, %2}";
5695    }
5696}
5697  [(set (attr "type")
5698     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5699	(const_string "incdec")
5700	(const_string "alu")))
5701   (set_attr "mode" "SI")])
5702
5703;; See comment for addsi_1_zext why we do use nonimmediate_operand
5704(define_insn "*addsi_3_zext"
5705  [(set (reg FLAGS_REG)
5706	(compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5707		 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5708   (set (match_operand:DI 0 "register_operand" "=r")
5709	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5710  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5711   && ix86_binary_operator_ok (PLUS, SImode, operands)
5712   /* Current assemblers are broken and do not allow @GOTOFF in
5713      ought but a memory context.  */
5714   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5715{
5716  switch (get_attr_type (insn))
5717    {
5718    case TYPE_INCDEC:
5719      if (operands[2] == const1_rtx)
5720        return "inc{l}\t%k0";
5721      else
5722        {
5723	  gcc_assert (operands[2] == constm1_rtx);
5724          return "dec{l}\t%k0";
5725	}
5726
5727    default:
5728      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5729	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5730      if (GET_CODE (operands[2]) == CONST_INT
5731          && (INTVAL (operands[2]) == 128
5732	      || (INTVAL (operands[2]) < 0
5733		  && INTVAL (operands[2]) != -128)))
5734        {
5735          operands[2] = GEN_INT (-INTVAL (operands[2]));
5736          return "sub{l}\t{%2, %k0|%k0, %2}";
5737        }
5738      return "add{l}\t{%2, %k0|%k0, %2}";
5739    }
5740}
5741  [(set (attr "type")
5742     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5743	(const_string "incdec")
5744	(const_string "alu")))
5745   (set_attr "mode" "SI")])
5746
5747; For comparisons against 1, -1 and 128, we may generate better code
5748; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5749; is matched then.  We can't accept general immediate, because for
5750; case of overflows,  the result is messed up.
5751; This pattern also don't hold of 0x80000000, since the value overflows
5752; when negated.
5753; Also carry flag is reversed compared to cmp, so this conversion is valid
5754; only for comparisons not depending on it.
5755(define_insn "*addsi_4"
5756  [(set (reg FLAGS_REG)
5757	(compare (match_operand:SI 1 "nonimmediate_operand" "0")
5758		 (match_operand:SI 2 "const_int_operand" "n")))
5759   (clobber (match_scratch:SI 0 "=rm"))]
5760  "ix86_match_ccmode (insn, CCGCmode)
5761   && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5762{
5763  switch (get_attr_type (insn))
5764    {
5765    case TYPE_INCDEC:
5766      if (operands[2] == constm1_rtx)
5767        return "inc{l}\t%0";
5768      else
5769        {
5770	  gcc_assert (operands[2] == const1_rtx);
5771          return "dec{l}\t%0";
5772	}
5773
5774    default:
5775      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5776      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5777	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5778      if ((INTVAL (operands[2]) == -128
5779	   || (INTVAL (operands[2]) > 0
5780	       && INTVAL (operands[2]) != 128)))
5781	return "sub{l}\t{%2, %0|%0, %2}";
5782      operands[2] = GEN_INT (-INTVAL (operands[2]));
5783      return "add{l}\t{%2, %0|%0, %2}";
5784    }
5785}
5786  [(set (attr "type")
5787     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5788	(const_string "incdec")
5789	(const_string "alu")))
5790   (set_attr "mode" "SI")])
5791
5792(define_insn "*addsi_5"
5793  [(set (reg FLAGS_REG)
5794	(compare
5795	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5796		   (match_operand:SI 2 "general_operand" "rmni"))
5797	  (const_int 0)))			
5798   (clobber (match_scratch:SI 0 "=r"))]
5799  "ix86_match_ccmode (insn, CCGOCmode)
5800   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5801   /* Current assemblers are broken and do not allow @GOTOFF in
5802      ought but a memory context.  */
5803   && ! pic_symbolic_operand (operands[2], VOIDmode)"
5804{
5805  switch (get_attr_type (insn))
5806    {
5807    case TYPE_INCDEC:
5808      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809      if (operands[2] == const1_rtx)
5810        return "inc{l}\t%0";
5811      else
5812        {
5813	  gcc_assert (operands[2] == constm1_rtx);
5814          return "dec{l}\t%0";
5815	}
5816
5817    default:
5818      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5819      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5820	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5821      if (GET_CODE (operands[2]) == CONST_INT
5822          && (INTVAL (operands[2]) == 128
5823	      || (INTVAL (operands[2]) < 0
5824		  && INTVAL (operands[2]) != -128)))
5825        {
5826          operands[2] = GEN_INT (-INTVAL (operands[2]));
5827          return "sub{l}\t{%2, %0|%0, %2}";
5828        }
5829      return "add{l}\t{%2, %0|%0, %2}";
5830    }
5831}
5832  [(set (attr "type")
5833     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5834	(const_string "incdec")
5835	(const_string "alu")))
5836   (set_attr "mode" "SI")])
5837
5838(define_expand "addhi3"
5839  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5840		   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5841			    (match_operand:HI 2 "general_operand" "")))
5842	      (clobber (reg:CC FLAGS_REG))])]
5843  "TARGET_HIMODE_MATH"
5844  "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5845
5846;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5847;; type optimizations enabled by define-splits.  This is not important
5848;; for PII, and in fact harmful because of partial register stalls.
5849
5850(define_insn "*addhi_1_lea"
5851  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5852	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5853		 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5854   (clobber (reg:CC FLAGS_REG))]
5855  "!TARGET_PARTIAL_REG_STALL
5856   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5857{
5858  switch (get_attr_type (insn))
5859    {
5860    case TYPE_LEA:
5861      return "#";
5862    case TYPE_INCDEC:
5863      if (operands[2] == const1_rtx)
5864	return "inc{w}\t%0";
5865      else
5866	{
5867	  gcc_assert (operands[2] == constm1_rtx);
5868	  return "dec{w}\t%0";
5869	}
5870
5871    default:
5872      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5873	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5874      if (GET_CODE (operands[2]) == CONST_INT
5875          && (INTVAL (operands[2]) == 128
5876	      || (INTVAL (operands[2]) < 0
5877		  && INTVAL (operands[2]) != -128)))
5878	{
5879	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5880	  return "sub{w}\t{%2, %0|%0, %2}";
5881	}
5882      return "add{w}\t{%2, %0|%0, %2}";
5883    }
5884}
5885  [(set (attr "type")
5886     (if_then_else (eq_attr "alternative" "2")
5887	(const_string "lea")
5888	(if_then_else (match_operand:HI 2 "incdec_operand" "")
5889	   (const_string "incdec")
5890	   (const_string "alu"))))
5891   (set_attr "mode" "HI,HI,SI")])
5892
5893(define_insn "*addhi_1"
5894  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5895	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896		 (match_operand:HI 2 "general_operand" "ri,rm")))
5897   (clobber (reg:CC FLAGS_REG))]
5898  "TARGET_PARTIAL_REG_STALL
5899   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5900{
5901  switch (get_attr_type (insn))
5902    {
5903    case TYPE_INCDEC:
5904      if (operands[2] == const1_rtx)
5905	return "inc{w}\t%0";
5906      else
5907        {
5908	  gcc_assert (operands[2] == constm1_rtx);
5909	  return "dec{w}\t%0";
5910	}
5911
5912    default:
5913      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5915      if (GET_CODE (operands[2]) == CONST_INT
5916          && (INTVAL (operands[2]) == 128
5917	      || (INTVAL (operands[2]) < 0
5918		  && INTVAL (operands[2]) != -128)))
5919	{
5920	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5921	  return "sub{w}\t{%2, %0|%0, %2}";
5922	}
5923      return "add{w}\t{%2, %0|%0, %2}";
5924    }
5925}
5926  [(set (attr "type")
5927     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5928	(const_string "incdec")
5929	(const_string "alu")))
5930   (set_attr "mode" "HI")])
5931
5932(define_insn "*addhi_2"
5933  [(set (reg FLAGS_REG)
5934	(compare
5935	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5936		   (match_operand:HI 2 "general_operand" "rmni,rni"))
5937	  (const_int 0)))			
5938   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5939	(plus:HI (match_dup 1) (match_dup 2)))]
5940  "ix86_match_ccmode (insn, CCGOCmode)
5941   && ix86_binary_operator_ok (PLUS, HImode, operands)"
5942{
5943  switch (get_attr_type (insn))
5944    {
5945    case TYPE_INCDEC:
5946      if (operands[2] == const1_rtx)
5947	return "inc{w}\t%0";
5948      else
5949        {
5950	  gcc_assert (operands[2] == constm1_rtx);
5951	  return "dec{w}\t%0";
5952	}
5953
5954    default:
5955      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5957      if (GET_CODE (operands[2]) == CONST_INT
5958          && (INTVAL (operands[2]) == 128
5959	      || (INTVAL (operands[2]) < 0
5960		  && INTVAL (operands[2]) != -128)))
5961	{
5962	  operands[2] = GEN_INT (-INTVAL (operands[2]));
5963	  return "sub{w}\t{%2, %0|%0, %2}";
5964	}
5965      return "add{w}\t{%2, %0|%0, %2}";
5966    }
5967}
5968  [(set (attr "type")
5969     (if_then_else (match_operand:HI 2 "incdec_operand" "")
5970	(const_string "incdec")
5971	(const_string "alu")))
5972   (set_attr "mode" "HI")])
5973
5974(define_insn "*addhi_3"
5975  [(set (reg FLAGS_REG)
5976	(compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5977		 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5978   (clobber (match_scratch:HI 0 "=r"))]
5979  "ix86_match_ccmode (insn, CCZmode)
5980   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5981{
5982  switch (get_attr_type (insn))
5983    {
5984    case TYPE_INCDEC:
5985      if (operands[2] == const1_rtx)
5986	return "inc{w}\t%0";
5987      else
5988        {
5989	  gcc_assert (operands[2] == constm1_rtx);
5990	  return "dec{w}\t%0";
5991	}
5992
5993    default:
5994      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5995	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5996      if (GET_CODE (operands[2]) == CONST_INT
5997          && (INTVAL (operands[2]) == 128
5998	      || (INTVAL (operands[2]) < 0
5999		  && INTVAL (operands[2]) != -128)))
6000	{
6001	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6002	  return "sub{w}\t{%2, %0|%0, %2}";
6003	}
6004      return "add{w}\t{%2, %0|%0, %2}";
6005    }
6006}
6007  [(set (attr "type")
6008     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6009	(const_string "incdec")
6010	(const_string "alu")))
6011   (set_attr "mode" "HI")])
6012
6013; See comments above addsi_4 for details.
6014(define_insn "*addhi_4"
6015  [(set (reg FLAGS_REG)
6016	(compare (match_operand:HI 1 "nonimmediate_operand" "0")
6017		 (match_operand:HI 2 "const_int_operand" "n")))
6018   (clobber (match_scratch:HI 0 "=rm"))]
6019  "ix86_match_ccmode (insn, CCGCmode)
6020   && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6021{
6022  switch (get_attr_type (insn))
6023    {
6024    case TYPE_INCDEC:
6025      if (operands[2] == constm1_rtx)
6026        return "inc{w}\t%0";
6027      else
6028	{
6029	  gcc_assert (operands[2] == const1_rtx);
6030          return "dec{w}\t%0";
6031	}
6032
6033    default:
6034      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6036	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6037      if ((INTVAL (operands[2]) == -128
6038	   || (INTVAL (operands[2]) > 0
6039	       && INTVAL (operands[2]) != 128)))
6040	return "sub{w}\t{%2, %0|%0, %2}";
6041      operands[2] = GEN_INT (-INTVAL (operands[2]));
6042      return "add{w}\t{%2, %0|%0, %2}";
6043    }
6044}
6045  [(set (attr "type")
6046     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047	(const_string "incdec")
6048	(const_string "alu")))
6049   (set_attr "mode" "SI")])
6050
6051
6052(define_insn "*addhi_5"
6053  [(set (reg FLAGS_REG)
6054	(compare
6055	  (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6056		   (match_operand:HI 2 "general_operand" "rmni"))
6057	  (const_int 0)))			
6058   (clobber (match_scratch:HI 0 "=r"))]
6059  "ix86_match_ccmode (insn, CCGOCmode)
6060   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6061{
6062  switch (get_attr_type (insn))
6063    {
6064    case TYPE_INCDEC:
6065      if (operands[2] == const1_rtx)
6066	return "inc{w}\t%0";
6067      else
6068	{
6069	  gcc_assert (operands[2] == constm1_rtx);
6070	  return "dec{w}\t%0";
6071	}
6072
6073    default:
6074      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6075	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6076      if (GET_CODE (operands[2]) == CONST_INT
6077          && (INTVAL (operands[2]) == 128
6078	      || (INTVAL (operands[2]) < 0
6079		  && INTVAL (operands[2]) != -128)))
6080	{
6081	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6082	  return "sub{w}\t{%2, %0|%0, %2}";
6083	}
6084      return "add{w}\t{%2, %0|%0, %2}";
6085    }
6086}
6087  [(set (attr "type")
6088     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6089	(const_string "incdec")
6090	(const_string "alu")))
6091   (set_attr "mode" "HI")])
6092
6093(define_expand "addqi3"
6094  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6095		   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6096			    (match_operand:QI 2 "general_operand" "")))
6097	      (clobber (reg:CC FLAGS_REG))])]
6098  "TARGET_QIMODE_MATH"
6099  "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6100
6101;; %%% Potential partial reg stall on alternative 2.  What to do?
6102(define_insn "*addqi_1_lea"
6103  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6104	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6105		 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6106   (clobber (reg:CC FLAGS_REG))]
6107  "!TARGET_PARTIAL_REG_STALL
6108   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6109{
6110  int widen = (which_alternative == 2);
6111  switch (get_attr_type (insn))
6112    {
6113    case TYPE_LEA:
6114      return "#";
6115    case TYPE_INCDEC:
6116      if (operands[2] == const1_rtx)
6117	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6118      else
6119	{
6120	  gcc_assert (operands[2] == constm1_rtx);
6121	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6122	}
6123
6124    default:
6125      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6127      if (GET_CODE (operands[2]) == CONST_INT
6128          && (INTVAL (operands[2]) == 128
6129	      || (INTVAL (operands[2]) < 0
6130		  && INTVAL (operands[2]) != -128)))
6131	{
6132	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6133	  if (widen)
6134	    return "sub{l}\t{%2, %k0|%k0, %2}";
6135	  else
6136	    return "sub{b}\t{%2, %0|%0, %2}";
6137	}
6138      if (widen)
6139        return "add{l}\t{%k2, %k0|%k0, %k2}";
6140      else
6141        return "add{b}\t{%2, %0|%0, %2}";
6142    }
6143}
6144  [(set (attr "type")
6145     (if_then_else (eq_attr "alternative" "3")
6146	(const_string "lea")
6147	(if_then_else (match_operand:QI 2 "incdec_operand" "")
6148	   (const_string "incdec")
6149	   (const_string "alu"))))
6150   (set_attr "mode" "QI,QI,SI,SI")])
6151
6152(define_insn "*addqi_1"
6153  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6154	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6155		 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6156   (clobber (reg:CC FLAGS_REG))]
6157  "TARGET_PARTIAL_REG_STALL
6158   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6159{
6160  int widen = (which_alternative == 2);
6161  switch (get_attr_type (insn))
6162    {
6163    case TYPE_INCDEC:
6164      if (operands[2] == const1_rtx)
6165	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6166      else
6167	{
6168	  gcc_assert (operands[2] == constm1_rtx);
6169	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6170	}
6171
6172    default:
6173      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6174	 Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6175      if (GET_CODE (operands[2]) == CONST_INT
6176          && (INTVAL (operands[2]) == 128
6177	      || (INTVAL (operands[2]) < 0
6178		  && INTVAL (operands[2]) != -128)))
6179	{
6180	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6181	  if (widen)
6182	    return "sub{l}\t{%2, %k0|%k0, %2}";
6183	  else
6184	    return "sub{b}\t{%2, %0|%0, %2}";
6185	}
6186      if (widen)
6187        return "add{l}\t{%k2, %k0|%k0, %k2}";
6188      else
6189        return "add{b}\t{%2, %0|%0, %2}";
6190    }
6191}
6192  [(set (attr "type")
6193     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6194	(const_string "incdec")
6195	(const_string "alu")))
6196   (set_attr "mode" "QI,QI,SI")])
6197
6198(define_insn "*addqi_1_slp"
6199  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6200	(plus:QI (match_dup 0)
6201		 (match_operand:QI 1 "general_operand" "qn,qnm")))
6202   (clobber (reg:CC FLAGS_REG))]
6203  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6204   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6205{
6206  switch (get_attr_type (insn))
6207    {
6208    case TYPE_INCDEC:
6209      if (operands[1] == const1_rtx)
6210	return "inc{b}\t%0";
6211      else
6212	{
6213	  gcc_assert (operands[1] == constm1_rtx);
6214	  return "dec{b}\t%0";
6215	}
6216
6217    default:
6218      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6219      if (GET_CODE (operands[1]) == CONST_INT
6220	  && INTVAL (operands[1]) < 0)
6221	{
6222	  operands[1] = GEN_INT (-INTVAL (operands[1]));
6223	  return "sub{b}\t{%1, %0|%0, %1}";
6224	}
6225      return "add{b}\t{%1, %0|%0, %1}";
6226    }
6227}
6228  [(set (attr "type")
6229     (if_then_else (match_operand:QI 1 "incdec_operand" "")
6230	(const_string "incdec")
6231	(const_string "alu1")))
6232   (set (attr "memory")
6233     (if_then_else (match_operand 1 "memory_operand" "")
6234        (const_string "load")
6235        (const_string "none")))
6236   (set_attr "mode" "QI")])
6237
6238(define_insn "*addqi_2"
6239  [(set (reg FLAGS_REG)
6240	(compare
6241	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6242		   (match_operand:QI 2 "general_operand" "qmni,qni"))
6243	  (const_int 0)))
6244   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6245	(plus:QI (match_dup 1) (match_dup 2)))]
6246  "ix86_match_ccmode (insn, CCGOCmode)
6247   && ix86_binary_operator_ok (PLUS, QImode, operands)"
6248{
6249  switch (get_attr_type (insn))
6250    {
6251    case TYPE_INCDEC:
6252      if (operands[2] == const1_rtx)
6253	return "inc{b}\t%0";
6254      else
6255        {
6256	  gcc_assert (operands[2] == constm1_rtx
6257		      || (GET_CODE (operands[2]) == CONST_INT
6258		          && INTVAL (operands[2]) == 255));
6259	  return "dec{b}\t%0";
6260	}
6261
6262    default:
6263      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6264      if (GET_CODE (operands[2]) == CONST_INT
6265          && INTVAL (operands[2]) < 0)
6266	{
6267	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6268	  return "sub{b}\t{%2, %0|%0, %2}";
6269	}
6270      return "add{b}\t{%2, %0|%0, %2}";
6271    }
6272}
6273  [(set (attr "type")
6274     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6275	(const_string "incdec")
6276	(const_string "alu")))
6277   (set_attr "mode" "QI")])
6278
6279(define_insn "*addqi_3"
6280  [(set (reg FLAGS_REG)
6281	(compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6282		 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6283   (clobber (match_scratch:QI 0 "=q"))]
6284  "ix86_match_ccmode (insn, CCZmode)
6285   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6286{
6287  switch (get_attr_type (insn))
6288    {
6289    case TYPE_INCDEC:
6290      if (operands[2] == const1_rtx)
6291	return "inc{b}\t%0";
6292      else
6293        {
6294	  gcc_assert (operands[2] == constm1_rtx
6295		      || (GET_CODE (operands[2]) == CONST_INT
6296			  && INTVAL (operands[2]) == 255));
6297	  return "dec{b}\t%0";
6298	}
6299
6300    default:
6301      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6302      if (GET_CODE (operands[2]) == CONST_INT
6303          && INTVAL (operands[2]) < 0)
6304	{
6305	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6306	  return "sub{b}\t{%2, %0|%0, %2}";
6307	}
6308      return "add{b}\t{%2, %0|%0, %2}";
6309    }
6310}
6311  [(set (attr "type")
6312     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6313	(const_string "incdec")
6314	(const_string "alu")))
6315   (set_attr "mode" "QI")])
6316
6317; See comments above addsi_4 for details.
6318(define_insn "*addqi_4"
6319  [(set (reg FLAGS_REG)
6320	(compare (match_operand:QI 1 "nonimmediate_operand" "0")
6321		 (match_operand:QI 2 "const_int_operand" "n")))
6322   (clobber (match_scratch:QI 0 "=qm"))]
6323  "ix86_match_ccmode (insn, CCGCmode)
6324   && (INTVAL (operands[2]) & 0xff) != 0x80"
6325{
6326  switch (get_attr_type (insn))
6327    {
6328    case TYPE_INCDEC:
6329      if (operands[2] == constm1_rtx
6330	  || (GET_CODE (operands[2]) == CONST_INT
6331	      && INTVAL (operands[2]) == 255))
6332        return "inc{b}\t%0";
6333      else
6334	{
6335	  gcc_assert (operands[2] == const1_rtx);
6336          return "dec{b}\t%0";
6337	}
6338
6339    default:
6340      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6341      if (INTVAL (operands[2]) < 0)
6342        {
6343          operands[2] = GEN_INT (-INTVAL (operands[2]));
6344          return "add{b}\t{%2, %0|%0, %2}";
6345        }
6346      return "sub{b}\t{%2, %0|%0, %2}";
6347    }
6348}
6349  [(set (attr "type")
6350     (if_then_else (match_operand:HI 2 "incdec_operand" "")
6351	(const_string "incdec")
6352	(const_string "alu")))
6353   (set_attr "mode" "QI")])
6354
6355
6356(define_insn "*addqi_5"
6357  [(set (reg FLAGS_REG)
6358	(compare
6359	  (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6360		   (match_operand:QI 2 "general_operand" "qmni"))
6361	  (const_int 0)))
6362   (clobber (match_scratch:QI 0 "=q"))]
6363  "ix86_match_ccmode (insn, CCGOCmode)
6364   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6365{
6366  switch (get_attr_type (insn))
6367    {
6368    case TYPE_INCDEC:
6369      if (operands[2] == const1_rtx)
6370	return "inc{b}\t%0";
6371      else
6372        {
6373	  gcc_assert (operands[2] == constm1_rtx
6374		      || (GET_CODE (operands[2]) == CONST_INT
6375			  && INTVAL (operands[2]) == 255));
6376	  return "dec{b}\t%0";
6377	}
6378
6379    default:
6380      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6381      if (GET_CODE (operands[2]) == CONST_INT
6382          && INTVAL (operands[2]) < 0)
6383	{
6384	  operands[2] = GEN_INT (-INTVAL (operands[2]));
6385	  return "sub{b}\t{%2, %0|%0, %2}";
6386	}
6387      return "add{b}\t{%2, %0|%0, %2}";
6388    }
6389}
6390  [(set (attr "type")
6391     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392	(const_string "incdec")
6393	(const_string "alu")))
6394   (set_attr "mode" "QI")])
6395
6396
6397(define_insn "addqi_ext_1"
6398  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399			 (const_int 8)
6400			 (const_int 8))
6401	(plus:SI
6402	  (zero_extract:SI
6403	    (match_operand 1 "ext_register_operand" "0")
6404	    (const_int 8)
6405	    (const_int 8))
6406	  (match_operand:QI 2 "general_operand" "Qmn")))
6407   (clobber (reg:CC FLAGS_REG))]
6408  "!TARGET_64BIT"
6409{
6410  switch (get_attr_type (insn))
6411    {
6412    case TYPE_INCDEC:
6413      if (operands[2] == const1_rtx)
6414	return "inc{b}\t%h0";
6415      else
6416        {
6417	  gcc_assert (operands[2] == constm1_rtx
6418		      || (GET_CODE (operands[2]) == CONST_INT
6419			  && INTVAL (operands[2]) == 255));
6420          return "dec{b}\t%h0";
6421	}
6422
6423    default:
6424      return "add{b}\t{%2, %h0|%h0, %2}";
6425    }
6426}
6427  [(set (attr "type")
6428     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6429	(const_string "incdec")
6430	(const_string "alu")))
6431   (set_attr "mode" "QI")])
6432
6433(define_insn "*addqi_ext_1_rex64"
6434  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6435			 (const_int 8)
6436			 (const_int 8))
6437	(plus:SI
6438	  (zero_extract:SI
6439	    (match_operand 1 "ext_register_operand" "0")
6440	    (const_int 8)
6441	    (const_int 8))
6442	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6443   (clobber (reg:CC FLAGS_REG))]
6444  "TARGET_64BIT"
6445{
6446  switch (get_attr_type (insn))
6447    {
6448    case TYPE_INCDEC:
6449      if (operands[2] == const1_rtx)
6450	return "inc{b}\t%h0";
6451      else
6452        {
6453	  gcc_assert (operands[2] == constm1_rtx
6454		      || (GET_CODE (operands[2]) == CONST_INT
6455			  && INTVAL (operands[2]) == 255));
6456          return "dec{b}\t%h0";
6457        }
6458
6459    default:
6460      return "add{b}\t{%2, %h0|%h0, %2}";
6461    }
6462}
6463  [(set (attr "type")
6464     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465	(const_string "incdec")
6466	(const_string "alu")))
6467   (set_attr "mode" "QI")])
6468
6469(define_insn "*addqi_ext_2"
6470  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6471			 (const_int 8)
6472			 (const_int 8))
6473	(plus:SI
6474	  (zero_extract:SI
6475	    (match_operand 1 "ext_register_operand" "%0")
6476	    (const_int 8)
6477	    (const_int 8))
6478	  (zero_extract:SI
6479	    (match_operand 2 "ext_register_operand" "Q")
6480	    (const_int 8)
6481	    (const_int 8))))
6482   (clobber (reg:CC FLAGS_REG))]
6483  ""
6484  "add{b}\t{%h2, %h0|%h0, %h2}"
6485  [(set_attr "type" "alu")
6486   (set_attr "mode" "QI")])
6487
6488;; The patterns that match these are at the end of this file.
6489
6490(define_expand "addxf3"
6491  [(set (match_operand:XF 0 "register_operand" "")
6492	(plus:XF (match_operand:XF 1 "register_operand" "")
6493		 (match_operand:XF 2 "register_operand" "")))]
6494  "TARGET_80387"
6495  "")
6496
6497(define_expand "adddf3"
6498  [(set (match_operand:DF 0 "register_operand" "")
6499	(plus:DF (match_operand:DF 1 "register_operand" "")
6500		 (match_operand:DF 2 "nonimmediate_operand" "")))]
6501  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6502  "")
6503
6504(define_expand "addsf3"
6505  [(set (match_operand:SF 0 "register_operand" "")
6506	(plus:SF (match_operand:SF 1 "register_operand" "")
6507		 (match_operand:SF 2 "nonimmediate_operand" "")))]
6508  "TARGET_80387 || TARGET_SSE_MATH"
6509  "")
6510
6511;; Subtract instructions
6512
6513;; %%% splits for subditi3
6514
6515(define_expand "subti3"
6516  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6517		   (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6518			     (match_operand:TI 2 "x86_64_general_operand" "")))
6519	      (clobber (reg:CC FLAGS_REG))])]
6520  "TARGET_64BIT"
6521  "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6522
6523(define_insn "*subti3_1"
6524  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6525	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6526		  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6527   (clobber (reg:CC FLAGS_REG))]
6528  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6529  "#")
6530
6531(define_split
6532  [(set (match_operand:TI 0 "nonimmediate_operand" "")
6533	(minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6534		  (match_operand:TI 2 "x86_64_general_operand" "")))
6535   (clobber (reg:CC FLAGS_REG))]
6536  "TARGET_64BIT && reload_completed"
6537  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6538	      (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6539   (parallel [(set (match_dup 3)
6540		   (minus:DI (match_dup 4)
6541			     (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6542				      (match_dup 5))))
6543	      (clobber (reg:CC FLAGS_REG))])]
6544  "split_ti (operands+0, 1, operands+0, operands+3);
6545   split_ti (operands+1, 1, operands+1, operands+4);
6546   split_ti (operands+2, 1, operands+2, operands+5);")
6547
6548;; %%% splits for subsidi3
6549
6550(define_expand "subdi3"
6551  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6552		   (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6553			     (match_operand:DI 2 "x86_64_general_operand" "")))
6554	      (clobber (reg:CC FLAGS_REG))])]
6555  ""
6556  "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6557
6558(define_insn "*subdi3_1"
6559  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6560	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561		  (match_operand:DI 2 "general_operand" "roiF,riF")))
6562   (clobber (reg:CC FLAGS_REG))]
6563  "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6564  "#")
6565
6566(define_split
6567  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6568	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6569		  (match_operand:DI 2 "general_operand" "")))
6570   (clobber (reg:CC FLAGS_REG))]
6571  "!TARGET_64BIT && reload_completed"
6572  [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6573	      (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6574   (parallel [(set (match_dup 3)
6575		   (minus:SI (match_dup 4)
6576			     (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6577				      (match_dup 5))))
6578	      (clobber (reg:CC FLAGS_REG))])]
6579  "split_di (operands+0, 1, operands+0, operands+3);
6580   split_di (operands+1, 1, operands+1, operands+4);
6581   split_di (operands+2, 1, operands+2, operands+5);")
6582
6583(define_insn "subdi3_carry_rex64"
6584  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6585	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6586	    (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6587	       (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6588   (clobber (reg:CC FLAGS_REG))]
6589  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590  "sbb{q}\t{%2, %0|%0, %2}"
6591  [(set_attr "type" "alu")
6592   (set_attr "pent_pair" "pu")
6593   (set_attr "mode" "DI")])
6594
6595(define_insn "*subdi_1_rex64"
6596  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6597	(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598		  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6599   (clobber (reg:CC FLAGS_REG))]
6600  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6601  "sub{q}\t{%2, %0|%0, %2}"
6602  [(set_attr "type" "alu")
6603   (set_attr "mode" "DI")])
6604
6605(define_insn "*subdi_2_rex64"
6606  [(set (reg FLAGS_REG)
6607	(compare
6608	  (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609		    (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6610	  (const_int 0)))
6611   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612	(minus:DI (match_dup 1) (match_dup 2)))]
6613  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6614   && ix86_binary_operator_ok (MINUS, DImode, operands)"
6615  "sub{q}\t{%2, %0|%0, %2}"
6616  [(set_attr "type" "alu")
6617   (set_attr "mode" "DI")])
6618
6619(define_insn "*subdi_3_rex63"
6620  [(set (reg FLAGS_REG)
6621	(compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6622		 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6623   (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624	(minus:DI (match_dup 1) (match_dup 2)))]
6625  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6626   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6627  "sub{q}\t{%2, %0|%0, %2}"
6628  [(set_attr "type" "alu")
6629   (set_attr "mode" "DI")])
6630
6631(define_insn "subqi3_carry"
6632  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6633	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6634	    (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6635	       (match_operand:QI 2 "general_operand" "qi,qm"))))
6636   (clobber (reg:CC FLAGS_REG))]
6637  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6638  "sbb{b}\t{%2, %0|%0, %2}"
6639  [(set_attr "type" "alu")
6640   (set_attr "pent_pair" "pu")
6641   (set_attr "mode" "QI")])
6642
6643(define_insn "subhi3_carry"
6644  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6645	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6646	    (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6647	       (match_operand:HI 2 "general_operand" "ri,rm"))))
6648   (clobber (reg:CC FLAGS_REG))]
6649  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6650  "sbb{w}\t{%2, %0|%0, %2}"
6651  [(set_attr "type" "alu")
6652   (set_attr "pent_pair" "pu")
6653   (set_attr "mode" "HI")])
6654
6655(define_insn "subsi3_carry"
6656  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6657	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6658	    (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6659	       (match_operand:SI 2 "general_operand" "ri,rm"))))
6660   (clobber (reg:CC FLAGS_REG))]
6661  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6662  "sbb{l}\t{%2, %0|%0, %2}"
6663  [(set_attr "type" "alu")
6664   (set_attr "pent_pair" "pu")
6665   (set_attr "mode" "SI")])
6666
6667(define_insn "subsi3_carry_zext"
6668  [(set (match_operand:DI 0 "register_operand" "=rm,r")
6669	  (zero_extend:DI
6670	    (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6671	      (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6672		 (match_operand:SI 2 "general_operand" "ri,rm")))))
6673   (clobber (reg:CC FLAGS_REG))]
6674  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6675  "sbb{l}\t{%2, %k0|%k0, %2}"
6676  [(set_attr "type" "alu")
6677   (set_attr "pent_pair" "pu")
6678   (set_attr "mode" "SI")])
6679
6680(define_expand "subsi3"
6681  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6682		   (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6683			     (match_operand:SI 2 "general_operand" "")))
6684	      (clobber (reg:CC FLAGS_REG))])]
6685  ""
6686  "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6687
6688(define_insn "*subsi_1"
6689  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690	(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6691		  (match_operand:SI 2 "general_operand" "ri,rm")))
6692   (clobber (reg:CC FLAGS_REG))]
6693  "ix86_binary_operator_ok (MINUS, SImode, operands)"
6694  "sub{l}\t{%2, %0|%0, %2}"
6695  [(set_attr "type" "alu")
6696   (set_attr "mode" "SI")])
6697
6698(define_insn "*subsi_1_zext"
6699  [(set (match_operand:DI 0 "register_operand" "=r")
6700	(zero_extend:DI
6701	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6702		    (match_operand:SI 2 "general_operand" "rim"))))
6703   (clobber (reg:CC FLAGS_REG))]
6704  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6705  "sub{l}\t{%2, %k0|%k0, %2}"
6706  [(set_attr "type" "alu")
6707   (set_attr "mode" "SI")])
6708
6709(define_insn "*subsi_2"
6710  [(set (reg FLAGS_REG)
6711	(compare
6712	  (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6713		    (match_operand:SI 2 "general_operand" "ri,rm"))
6714	  (const_int 0)))
6715   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6716	(minus:SI (match_dup 1) (match_dup 2)))]
6717  "ix86_match_ccmode (insn, CCGOCmode)
6718   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719  "sub{l}\t{%2, %0|%0, %2}"
6720  [(set_attr "type" "alu")
6721   (set_attr "mode" "SI")])
6722
6723(define_insn "*subsi_2_zext"
6724  [(set (reg FLAGS_REG)
6725	(compare
6726	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6727		    (match_operand:SI 2 "general_operand" "rim"))
6728	  (const_int 0)))
6729   (set (match_operand:DI 0 "register_operand" "=r")
6730	(zero_extend:DI
6731	  (minus:SI (match_dup 1)
6732		    (match_dup 2))))]
6733  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6734   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735  "sub{l}\t{%2, %k0|%k0, %2}"
6736  [(set_attr "type" "alu")
6737   (set_attr "mode" "SI")])
6738
6739(define_insn "*subsi_3"
6740  [(set (reg FLAGS_REG)
6741	(compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6742		 (match_operand:SI 2 "general_operand" "ri,rm")))
6743   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6744	(minus:SI (match_dup 1) (match_dup 2)))]
6745  "ix86_match_ccmode (insn, CCmode)
6746   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747  "sub{l}\t{%2, %0|%0, %2}"
6748  [(set_attr "type" "alu")
6749   (set_attr "mode" "SI")])
6750
6751(define_insn "*subsi_3_zext"
6752  [(set (reg FLAGS_REG)
6753	(compare (match_operand:SI 1 "register_operand" "0")
6754		 (match_operand:SI 2 "general_operand" "rim")))
6755   (set (match_operand:DI 0 "register_operand" "=r")
6756	(zero_extend:DI
6757	  (minus:SI (match_dup 1)
6758		    (match_dup 2))))]
6759  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6760   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6761  "sub{l}\t{%2, %1|%1, %2}"
6762  [(set_attr "type" "alu")
6763   (set_attr "mode" "DI")])
6764
6765(define_expand "subhi3"
6766  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6767		   (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6768			     (match_operand:HI 2 "general_operand" "")))
6769	      (clobber (reg:CC FLAGS_REG))])]
6770  "TARGET_HIMODE_MATH"
6771  "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6772
6773(define_insn "*subhi_1"
6774  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6775	(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6776		  (match_operand:HI 2 "general_operand" "ri,rm")))
6777   (clobber (reg:CC FLAGS_REG))]
6778  "ix86_binary_operator_ok (MINUS, HImode, operands)"
6779  "sub{w}\t{%2, %0|%0, %2}"
6780  [(set_attr "type" "alu")
6781   (set_attr "mode" "HI")])
6782
6783(define_insn "*subhi_2"
6784  [(set (reg FLAGS_REG)
6785	(compare
6786	  (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6787		    (match_operand:HI 2 "general_operand" "ri,rm"))
6788	  (const_int 0)))
6789   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790	(minus:HI (match_dup 1) (match_dup 2)))]
6791  "ix86_match_ccmode (insn, CCGOCmode)
6792   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6793  "sub{w}\t{%2, %0|%0, %2}"
6794  [(set_attr "type" "alu")
6795   (set_attr "mode" "HI")])
6796
6797(define_insn "*subhi_3"
6798  [(set (reg FLAGS_REG)
6799	(compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6800		 (match_operand:HI 2 "general_operand" "ri,rm")))
6801   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6802	(minus:HI (match_dup 1) (match_dup 2)))]
6803  "ix86_match_ccmode (insn, CCmode)
6804   && ix86_binary_operator_ok (MINUS, HImode, operands)"
6805  "sub{w}\t{%2, %0|%0, %2}"
6806  [(set_attr "type" "alu")
6807   (set_attr "mode" "HI")])
6808
6809(define_expand "subqi3"
6810  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6811		   (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6812			     (match_operand:QI 2 "general_operand" "")))
6813	      (clobber (reg:CC FLAGS_REG))])]
6814  "TARGET_QIMODE_MATH"
6815  "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6816
6817(define_insn "*subqi_1"
6818  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6819	(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6820		  (match_operand:QI 2 "general_operand" "qn,qmn")))
6821   (clobber (reg:CC FLAGS_REG))]
6822  "ix86_binary_operator_ok (MINUS, QImode, operands)"
6823  "sub{b}\t{%2, %0|%0, %2}"
6824  [(set_attr "type" "alu")
6825   (set_attr "mode" "QI")])
6826
6827(define_insn "*subqi_1_slp"
6828  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6829	(minus:QI (match_dup 0)
6830		  (match_operand:QI 1 "general_operand" "qn,qmn")))
6831   (clobber (reg:CC FLAGS_REG))]
6832  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6833   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6834  "sub{b}\t{%1, %0|%0, %1}"
6835  [(set_attr "type" "alu1")
6836   (set_attr "mode" "QI")])
6837
6838(define_insn "*subqi_2"
6839  [(set (reg FLAGS_REG)
6840	(compare
6841	  (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6842		    (match_operand:QI 2 "general_operand" "qi,qm"))
6843	  (const_int 0)))
6844   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6845	(minus:HI (match_dup 1) (match_dup 2)))]
6846  "ix86_match_ccmode (insn, CCGOCmode)
6847   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6848  "sub{b}\t{%2, %0|%0, %2}"
6849  [(set_attr "type" "alu")
6850   (set_attr "mode" "QI")])
6851
6852(define_insn "*subqi_3"
6853  [(set (reg FLAGS_REG)
6854	(compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6855		 (match_operand:QI 2 "general_operand" "qi,qm")))
6856   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6857	(minus:HI (match_dup 1) (match_dup 2)))]
6858  "ix86_match_ccmode (insn, CCmode)
6859   && ix86_binary_operator_ok (MINUS, QImode, operands)"
6860  "sub{b}\t{%2, %0|%0, %2}"
6861  [(set_attr "type" "alu")
6862   (set_attr "mode" "QI")])
6863
6864;; The patterns that match these are at the end of this file.
6865
6866(define_expand "subxf3"
6867  [(set (match_operand:XF 0 "register_operand" "")
6868	(minus:XF (match_operand:XF 1 "register_operand" "")
6869		  (match_operand:XF 2 "register_operand" "")))]
6870  "TARGET_80387"
6871  "")
6872
6873(define_expand "subdf3"
6874  [(set (match_operand:DF 0 "register_operand" "")
6875	(minus:DF (match_operand:DF 1 "register_operand" "")
6876		  (match_operand:DF 2 "nonimmediate_operand" "")))]
6877  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6878  "")
6879
6880(define_expand "subsf3"
6881  [(set (match_operand:SF 0 "register_operand" "")
6882	(minus:SF (match_operand:SF 1 "register_operand" "")
6883		  (match_operand:SF 2 "nonimmediate_operand" "")))]
6884  "TARGET_80387 || TARGET_SSE_MATH"
6885  "")
6886
6887;; Multiply instructions
6888
6889(define_expand "muldi3"
6890  [(parallel [(set (match_operand:DI 0 "register_operand" "")
6891		   (mult:DI (match_operand:DI 1 "register_operand" "")
6892			    (match_operand:DI 2 "x86_64_general_operand" "")))
6893	      (clobber (reg:CC FLAGS_REG))])]
6894  "TARGET_64BIT"
6895  "")
6896
6897;; On AMDFAM10 
6898;; IMUL reg64, reg64, imm8 	Direct
6899;; IMUL reg64, mem64, imm8 	VectorPath
6900;; IMUL reg64, reg64, imm32 	Direct
6901;; IMUL reg64, mem64, imm32 	VectorPath 
6902;; IMUL reg64, reg64 		Direct
6903;; IMUL reg64, mem64 		Direct
6904
6905(define_insn "*muldi3_1_rex64"
6906  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6907	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6908		 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6909   (clobber (reg:CC FLAGS_REG))]
6910  "TARGET_64BIT
6911   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6912  "@
6913   imul{q}\t{%2, %1, %0|%0, %1, %2}
6914   imul{q}\t{%2, %1, %0|%0, %1, %2}
6915   imul{q}\t{%2, %0|%0, %2}"
6916  [(set_attr "type" "imul")
6917   (set_attr "prefix_0f" "0,0,1")
6918   (set (attr "athlon_decode")
6919	(cond [(eq_attr "cpu" "athlon")
6920		  (const_string "vector")
6921	       (eq_attr "alternative" "1")
6922		  (const_string "vector")
6923	       (and (eq_attr "alternative" "2")
6924		    (match_operand 1 "memory_operand" ""))
6925		  (const_string "vector")]
6926	      (const_string "direct")))
6927   (set (attr "amdfam10_decode")
6928	(cond [(and (eq_attr "alternative" "0,1")
6929		    (match_operand 1 "memory_operand" ""))
6930		  (const_string "vector")]
6931	      (const_string "direct")))	      
6932   (set_attr "mode" "DI")])
6933
6934(define_expand "mulsi3"
6935  [(parallel [(set (match_operand:SI 0 "register_operand" "")
6936		   (mult:SI (match_operand:SI 1 "register_operand" "")
6937			    (match_operand:SI 2 "general_operand" "")))
6938	      (clobber (reg:CC FLAGS_REG))])]
6939  ""
6940  "")
6941
6942;; On AMDFAM10 
6943;; IMUL reg32, reg32, imm8 	Direct
6944;; IMUL reg32, mem32, imm8 	VectorPath
6945;; IMUL reg32, reg32, imm32 	Direct
6946;; IMUL reg32, mem32, imm32 	VectorPath
6947;; IMUL reg32, reg32 		Direct
6948;; IMUL reg32, mem32 		Direct
6949
6950(define_insn "*mulsi3_1"
6951  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6952	(mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6953		 (match_operand:SI 2 "general_operand" "K,i,mr")))
6954   (clobber (reg:CC FLAGS_REG))]
6955  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6956  "@
6957   imul{l}\t{%2, %1, %0|%0, %1, %2}
6958   imul{l}\t{%2, %1, %0|%0, %1, %2}
6959   imul{l}\t{%2, %0|%0, %2}"
6960  [(set_attr "type" "imul")
6961   (set_attr "prefix_0f" "0,0,1")
6962   (set (attr "athlon_decode")
6963	(cond [(eq_attr "cpu" "athlon")
6964		  (const_string "vector")
6965	       (eq_attr "alternative" "1")
6966		  (const_string "vector")
6967	       (and (eq_attr "alternative" "2")
6968		    (match_operand 1 "memory_operand" ""))
6969		  (const_string "vector")]
6970	      (const_string "direct")))
6971   (set (attr "amdfam10_decode")
6972	(cond [(and (eq_attr "alternative" "0,1")
6973		    (match_operand 1 "memory_operand" ""))
6974		  (const_string "vector")]
6975	      (const_string "direct")))	      
6976   (set_attr "mode" "SI")])
6977
6978(define_insn "*mulsi3_1_zext"
6979  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6980	(zero_extend:DI
6981	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6982		   (match_operand:SI 2 "general_operand" "K,i,mr"))))
6983   (clobber (reg:CC FLAGS_REG))]
6984  "TARGET_64BIT
6985   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6986  "@
6987   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6988   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6989   imul{l}\t{%2, %k0|%k0, %2}"
6990  [(set_attr "type" "imul")
6991   (set_attr "prefix_0f" "0,0,1")
6992   (set (attr "athlon_decode")
6993	(cond [(eq_attr "cpu" "athlon")
6994		  (const_string "vector")
6995	       (eq_attr "alternative" "1")
6996		  (const_string "vector")
6997	       (and (eq_attr "alternative" "2")
6998		    (match_operand 1 "memory_operand" ""))
6999		  (const_string "vector")]
7000	      (const_string "direct")))
7001   (set (attr "amdfam10_decode")
7002	(cond [(and (eq_attr "alternative" "0,1")
7003		    (match_operand 1 "memory_operand" ""))
7004		  (const_string "vector")]
7005	      (const_string "direct")))	      
7006   (set_attr "mode" "SI")])
7007
7008(define_expand "mulhi3"
7009  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7010		   (mult:HI (match_operand:HI 1 "register_operand" "")
7011			    (match_operand:HI 2 "general_operand" "")))
7012	      (clobber (reg:CC FLAGS_REG))])]
7013  "TARGET_HIMODE_MATH"
7014  "")
7015
7016;; On AMDFAM10
7017;; IMUL reg16, reg16, imm8 	VectorPath
7018;; IMUL reg16, mem16, imm8 	VectorPath
7019;; IMUL reg16, reg16, imm16 	VectorPath
7020;; IMUL reg16, mem16, imm16 	VectorPath
7021;; IMUL reg16, reg16 		Direct
7022;; IMUL reg16, mem16 		Direct
7023(define_insn "*mulhi3_1"
7024  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7025	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7026		 (match_operand:HI 2 "general_operand" "K,i,mr")))
7027   (clobber (reg:CC FLAGS_REG))]
7028  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7029  "@
7030   imul{w}\t{%2, %1, %0|%0, %1, %2}
7031   imul{w}\t{%2, %1, %0|%0, %1, %2}
7032   imul{w}\t{%2, %0|%0, %2}"
7033  [(set_attr "type" "imul")
7034   (set_attr "prefix_0f" "0,0,1")
7035   (set (attr "athlon_decode")
7036	(cond [(eq_attr "cpu" "athlon")
7037		  (const_string "vector")
7038	       (eq_attr "alternative" "1,2")
7039		  (const_string "vector")]
7040	      (const_string "direct")))
7041   (set (attr "amdfam10_decode")
7042	(cond [(eq_attr "alternative" "0,1")
7043		  (const_string "vector")]
7044	      (const_string "direct")))
7045   (set_attr "mode" "HI")])
7046
7047(define_expand "mulqi3"
7048  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7049		   (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7050			    (match_operand:QI 2 "register_operand" "")))
7051	      (clobber (reg:CC FLAGS_REG))])]
7052  "TARGET_QIMODE_MATH"
7053  "")
7054
7055;;On AMDFAM10
7056;; MUL reg8 	Direct
7057;; MUL mem8 	Direct
7058
7059(define_insn "*mulqi3_1"
7060  [(set (match_operand:QI 0 "register_operand" "=a")
7061	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7062		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7063   (clobber (reg:CC FLAGS_REG))]
7064  "TARGET_QIMODE_MATH
7065   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7066  "mul{b}\t%2"
7067  [(set_attr "type" "imul")
7068   (set_attr "length_immediate" "0")
7069   (set (attr "athlon_decode")
7070     (if_then_else (eq_attr "cpu" "athlon")
7071        (const_string "vector")
7072        (const_string "direct")))
7073   (set_attr "amdfam10_decode" "direct")        
7074   (set_attr "mode" "QI")])
7075
7076(define_expand "umulqihi3"
7077  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7078		   (mult:HI (zero_extend:HI
7079			      (match_operand:QI 1 "nonimmediate_operand" ""))
7080			    (zero_extend:HI
7081			      (match_operand:QI 2 "register_operand" ""))))
7082	      (clobber (reg:CC FLAGS_REG))])]
7083  "TARGET_QIMODE_MATH"
7084  "")
7085
7086(define_insn "*umulqihi3_1"
7087  [(set (match_operand:HI 0 "register_operand" "=a")
7088	(mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7089		 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7090   (clobber (reg:CC FLAGS_REG))]
7091  "TARGET_QIMODE_MATH
7092   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7093  "mul{b}\t%2"
7094  [(set_attr "type" "imul")
7095   (set_attr "length_immediate" "0")
7096   (set (attr "athlon_decode")
7097     (if_then_else (eq_attr "cpu" "athlon")
7098        (const_string "vector")
7099        (const_string "direct")))
7100   (set_attr "amdfam10_decode" "direct")        
7101   (set_attr "mode" "QI")])
7102
7103(define_expand "mulqihi3"
7104  [(parallel [(set (match_operand:HI 0 "register_operand" "")
7105		   (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7106			    (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7107	      (clobber (reg:CC FLAGS_REG))])]
7108  "TARGET_QIMODE_MATH"
7109  "")
7110
7111(define_insn "*mulqihi3_insn"
7112  [(set (match_operand:HI 0 "register_operand" "=a")
7113	(mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7114		 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7115   (clobber (reg:CC FLAGS_REG))]
7116  "TARGET_QIMODE_MATH
7117   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7118  "imul{b}\t%2"
7119  [(set_attr "type" "imul")
7120   (set_attr "length_immediate" "0")
7121   (set (attr "athlon_decode")
7122     (if_then_else (eq_attr "cpu" "athlon")
7123        (const_string "vector")
7124        (const_string "direct")))
7125   (set_attr "amdfam10_decode" "direct")        
7126   (set_attr "mode" "QI")])
7127
7128(define_expand "umulditi3"
7129  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7130		   (mult:TI (zero_extend:TI
7131			      (match_operand:DI 1 "nonimmediate_operand" ""))
7132			    (zero_extend:TI
7133			      (match_operand:DI 2 "register_operand" ""))))
7134	      (clobber (reg:CC FLAGS_REG))])]
7135  "TARGET_64BIT"
7136  "")
7137
7138(define_insn "*umulditi3_insn"
7139  [(set (match_operand:TI 0 "register_operand" "=A")
7140	(mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7141		 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7142   (clobber (reg:CC FLAGS_REG))]
7143  "TARGET_64BIT
7144   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7145  "mul{q}\t%2"
7146  [(set_attr "type" "imul")
7147   (set_attr "length_immediate" "0")
7148   (set (attr "athlon_decode")
7149     (if_then_else (eq_attr "cpu" "athlon")
7150        (const_string "vector")
7151        (const_string "double")))
7152   (set_attr "amdfam10_decode" "double")        
7153   (set_attr "mode" "DI")])
7154
7155;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7156(define_expand "umulsidi3"
7157  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7158		   (mult:DI (zero_extend:DI
7159			      (match_operand:SI 1 "nonimmediate_operand" ""))
7160			    (zero_extend:DI
7161			      (match_operand:SI 2 "register_operand" ""))))
7162	      (clobber (reg:CC FLAGS_REG))])]
7163  "!TARGET_64BIT"
7164  "")
7165
7166(define_insn "*umulsidi3_insn"
7167  [(set (match_operand:DI 0 "register_operand" "=A")
7168	(mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7169		 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7170   (clobber (reg:CC FLAGS_REG))]
7171  "!TARGET_64BIT
7172   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7173  "mul{l}\t%2"
7174  [(set_attr "type" "imul")
7175   (set_attr "length_immediate" "0")
7176   (set (attr "athlon_decode")
7177     (if_then_else (eq_attr "cpu" "athlon")
7178        (const_string "vector")
7179        (const_string "double")))
7180   (set_attr "amdfam10_decode" "double")        
7181   (set_attr "mode" "SI")])
7182
7183(define_expand "mulditi3"
7184  [(parallel [(set (match_operand:TI 0 "register_operand" "")
7185		   (mult:TI (sign_extend:TI
7186			      (match_operand:DI 1 "nonimmediate_operand" ""))
7187			    (sign_extend:TI
7188			      (match_operand:DI 2 "register_operand" ""))))
7189	      (clobber (reg:CC FLAGS_REG))])]
7190  "TARGET_64BIT"
7191  "")
7192
7193(define_insn "*mulditi3_insn"
7194  [(set (match_operand:TI 0 "register_operand" "=A")
7195	(mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7196		 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7197   (clobber (reg:CC FLAGS_REG))]
7198  "TARGET_64BIT
7199   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7200  "imul{q}\t%2"
7201  [(set_attr "type" "imul")
7202   (set_attr "length_immediate" "0")
7203   (set (attr "athlon_decode")
7204     (if_then_else (eq_attr "cpu" "athlon")
7205        (const_string "vector")
7206        (const_string "double")))
7207   (set_attr "amdfam10_decode" "double")
7208   (set_attr "mode" "DI")])
7209
7210(define_expand "mulsidi3"
7211  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7212		   (mult:DI (sign_extend:DI
7213			      (match_operand:SI 1 "nonimmediate_operand" ""))
7214			    (sign_extend:DI
7215			      (match_operand:SI 2 "register_operand" ""))))
7216	      (clobber (reg:CC FLAGS_REG))])]
7217  "!TARGET_64BIT"
7218  "")
7219
7220(define_insn "*mulsidi3_insn"
7221  [(set (match_operand:DI 0 "register_operand" "=A")
7222	(mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7223		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7224   (clobber (reg:CC FLAGS_REG))]
7225  "!TARGET_64BIT
7226   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7227  "imul{l}\t%2"
7228  [(set_attr "type" "imul")
7229   (set_attr "length_immediate" "0")
7230   (set (attr "athlon_decode")
7231     (if_then_else (eq_attr "cpu" "athlon")
7232        (const_string "vector")
7233        (const_string "double")))
7234   (set_attr "amdfam10_decode" "double")        
7235   (set_attr "mode" "SI")])
7236
7237(define_expand "umuldi3_highpart"
7238  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7239		   (truncate:DI
7240		     (lshiftrt:TI
7241		       (mult:TI (zero_extend:TI
7242				  (match_operand:DI 1 "nonimmediate_operand" ""))
7243				(zero_extend:TI
7244				  (match_operand:DI 2 "register_operand" "")))
7245		       (const_int 64))))
7246	      (clobber (match_scratch:DI 3 ""))
7247	      (clobber (reg:CC FLAGS_REG))])]
7248  "TARGET_64BIT"
7249  "")
7250
7251(define_insn "*umuldi3_highpart_rex64"
7252  [(set (match_operand:DI 0 "register_operand" "=d")
7253	(truncate:DI
7254	  (lshiftrt:TI
7255	    (mult:TI (zero_extend:TI
7256		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7257		     (zero_extend:TI
7258		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7259	    (const_int 64))))
7260   (clobber (match_scratch:DI 3 "=1"))
7261   (clobber (reg:CC FLAGS_REG))]
7262  "TARGET_64BIT
7263   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7264  "mul{q}\t%2"
7265  [(set_attr "type" "imul")
7266   (set_attr "length_immediate" "0")
7267   (set (attr "athlon_decode")
7268     (if_then_else (eq_attr "cpu" "athlon")
7269        (const_string "vector")
7270        (const_string "double")))
7271   (set_attr "amdfam10_decode" "double")        
7272   (set_attr "mode" "DI")])
7273
7274(define_expand "umulsi3_highpart"
7275  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7276		   (truncate:SI
7277		     (lshiftrt:DI
7278		       (mult:DI (zero_extend:DI
7279				  (match_operand:SI 1 "nonimmediate_operand" ""))
7280				(zero_extend:DI
7281				  (match_operand:SI 2 "register_operand" "")))
7282		       (const_int 32))))
7283	      (clobber (match_scratch:SI 3 ""))
7284	      (clobber (reg:CC FLAGS_REG))])]
7285  ""
7286  "")
7287
7288(define_insn "*umulsi3_highpart_insn"
7289  [(set (match_operand:SI 0 "register_operand" "=d")
7290	(truncate:SI
7291	  (lshiftrt:DI
7292	    (mult:DI (zero_extend:DI
7293		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7294		     (zero_extend:DI
7295		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7296	    (const_int 32))))
7297   (clobber (match_scratch:SI 3 "=1"))
7298   (clobber (reg:CC FLAGS_REG))]
7299  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7300  "mul{l}\t%2"
7301  [(set_attr "type" "imul")
7302   (set_attr "length_immediate" "0")
7303   (set (attr "athlon_decode")
7304     (if_then_else (eq_attr "cpu" "athlon")
7305        (const_string "vector")
7306        (const_string "double")))
7307   (set_attr "amdfam10_decode" "double")
7308   (set_attr "mode" "SI")])
7309
7310(define_insn "*umulsi3_highpart_zext"
7311  [(set (match_operand:DI 0 "register_operand" "=d")
7312	(zero_extend:DI (truncate:SI
7313	  (lshiftrt:DI
7314	    (mult:DI (zero_extend:DI
7315		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7316		     (zero_extend:DI
7317		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7318	    (const_int 32)))))
7319   (clobber (match_scratch:SI 3 "=1"))
7320   (clobber (reg:CC FLAGS_REG))]
7321  "TARGET_64BIT
7322   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7323  "mul{l}\t%2"
7324  [(set_attr "type" "imul")
7325   (set_attr "length_immediate" "0")
7326   (set (attr "athlon_decode")
7327     (if_then_else (eq_attr "cpu" "athlon")
7328        (const_string "vector")
7329        (const_string "double")))
7330   (set_attr "amdfam10_decode" "double")
7331   (set_attr "mode" "SI")])
7332
7333(define_expand "smuldi3_highpart"
7334  [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7335		   (truncate:DI
7336		     (lshiftrt:TI
7337		       (mult:TI (sign_extend:TI
7338				  (match_operand:DI 1 "nonimmediate_operand" ""))
7339				(sign_extend:TI
7340				  (match_operand:DI 2 "register_operand" "")))
7341		       (const_int 64))))
7342	      (clobber (match_scratch:DI 3 ""))
7343	      (clobber (reg:CC FLAGS_REG))])]
7344  "TARGET_64BIT"
7345  "")
7346
7347(define_insn "*smuldi3_highpart_rex64"
7348  [(set (match_operand:DI 0 "register_operand" "=d")
7349	(truncate:DI
7350	  (lshiftrt:TI
7351	    (mult:TI (sign_extend:TI
7352		       (match_operand:DI 1 "nonimmediate_operand" "%a"))
7353		     (sign_extend:TI
7354		       (match_operand:DI 2 "nonimmediate_operand" "rm")))
7355	    (const_int 64))))
7356   (clobber (match_scratch:DI 3 "=1"))
7357   (clobber (reg:CC FLAGS_REG))]
7358  "TARGET_64BIT
7359   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7360  "imul{q}\t%2"
7361  [(set_attr "type" "imul")
7362   (set (attr "athlon_decode")
7363     (if_then_else (eq_attr "cpu" "athlon")
7364        (const_string "vector")
7365        (const_string "double")))
7366   (set_attr "amdfam10_decode" "double")
7367   (set_attr "mode" "DI")])
7368
7369(define_expand "smulsi3_highpart"
7370  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7371		   (truncate:SI
7372		     (lshiftrt:DI
7373		       (mult:DI (sign_extend:DI
7374				  (match_operand:SI 1 "nonimmediate_operand" ""))
7375				(sign_extend:DI
7376				  (match_operand:SI 2 "register_operand" "")))
7377		       (const_int 32))))
7378	      (clobber (match_scratch:SI 3 ""))
7379	      (clobber (reg:CC FLAGS_REG))])]
7380  ""
7381  "")
7382
7383(define_insn "*smulsi3_highpart_insn"
7384  [(set (match_operand:SI 0 "register_operand" "=d")
7385	(truncate:SI
7386	  (lshiftrt:DI
7387	    (mult:DI (sign_extend:DI
7388		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7389		     (sign_extend:DI
7390		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7391	    (const_int 32))))
7392   (clobber (match_scratch:SI 3 "=1"))
7393   (clobber (reg:CC FLAGS_REG))]
7394  "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7395  "imul{l}\t%2"
7396  [(set_attr "type" "imul")
7397   (set (attr "athlon_decode")
7398     (if_then_else (eq_attr "cpu" "athlon")
7399        (const_string "vector")
7400        (const_string "double")))
7401   (set_attr "amdfam10_decode" "double")
7402   (set_attr "mode" "SI")])
7403
7404(define_insn "*smulsi3_highpart_zext"
7405  [(set (match_operand:DI 0 "register_operand" "=d")
7406	(zero_extend:DI (truncate:SI
7407	  (lshiftrt:DI
7408	    (mult:DI (sign_extend:DI
7409		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7410		     (sign_extend:DI
7411		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7412	    (const_int 32)))))
7413   (clobber (match_scratch:SI 3 "=1"))
7414   (clobber (reg:CC FLAGS_REG))]
7415  "TARGET_64BIT
7416   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7417  "imul{l}\t%2"
7418  [(set_attr "type" "imul")
7419   (set (attr "athlon_decode")
7420     (if_then_else (eq_attr "cpu" "athlon")
7421        (const_string "vector")
7422        (const_string "double")))
7423   (set_attr "amdfam10_decode" "double")
7424   (set_attr "mode" "SI")])
7425
7426;; The patterns that match these are at the end of this file.
7427
7428(define_expand "mulxf3"
7429  [(set (match_operand:XF 0 "register_operand" "")
7430	(mult:XF (match_operand:XF 1 "register_operand" "")
7431		 (match_operand:XF 2 "register_operand" "")))]
7432  "TARGET_80387"
7433  "")
7434
7435(define_expand "muldf3"
7436  [(set (match_operand:DF 0 "register_operand" "")
7437	(mult:DF (match_operand:DF 1 "register_operand" "")
7438		 (match_operand:DF 2 "nonimmediate_operand" "")))]
7439  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7440  "")
7441
7442(define_expand "mulsf3"
7443  [(set (match_operand:SF 0 "register_operand" "")
7444	(mult:SF (match_operand:SF 1 "register_operand" "")
7445		 (match_operand:SF 2 "nonimmediate_operand" "")))]
7446  "TARGET_80387 || TARGET_SSE_MATH"
7447  "")
7448
7449;; Divide instructions
7450
7451(define_insn "divqi3"
7452  [(set (match_operand:QI 0 "register_operand" "=a")
7453	(div:QI (match_operand:HI 1 "register_operand" "0")
7454		(match_operand:QI 2 "nonimmediate_operand" "qm")))
7455   (clobber (reg:CC FLAGS_REG))]
7456  "TARGET_QIMODE_MATH"
7457  "idiv{b}\t%2"
7458  [(set_attr "type" "idiv")
7459   (set_attr "mode" "QI")])
7460
7461(define_insn "udivqi3"
7462  [(set (match_operand:QI 0 "register_operand" "=a")
7463	(udiv:QI (match_operand:HI 1 "register_operand" "0")
7464		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7465   (clobber (reg:CC FLAGS_REG))]
7466  "TARGET_QIMODE_MATH"
7467  "div{b}\t%2"
7468  [(set_attr "type" "idiv")
7469   (set_attr "mode" "QI")])
7470
7471;; The patterns that match these are at the end of this file.
7472
7473(define_expand "divxf3"
7474  [(set (match_operand:XF 0 "register_operand" "")
7475	(div:XF (match_operand:XF 1 "register_operand" "")
7476		(match_operand:XF 2 "register_operand" "")))]
7477  "TARGET_80387"
7478  "")
7479
7480(define_expand "divdf3"
7481  [(set (match_operand:DF 0 "register_operand" "")
7482 	(div:DF (match_operand:DF 1 "register_operand" "")
7483 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7484   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7485   "")
7486 
7487(define_expand "divsf3"
7488  [(set (match_operand:SF 0 "register_operand" "")
7489	(div:SF (match_operand:SF 1 "register_operand" "")
7490		(match_operand:SF 2 "nonimmediate_operand" "")))]
7491  "TARGET_80387 || TARGET_SSE_MATH"
7492  "")
7493
7494;; Remainder instructions.
7495
7496(define_expand "divmoddi4"
7497  [(parallel [(set (match_operand:DI 0 "register_operand" "")
7498		   (div:DI (match_operand:DI 1 "register_operand" "")
7499			   (match_operand:DI 2 "nonimmediate_operand" "")))
7500	      (set (match_operand:DI 3 "register_operand" "")
7501		   (mod:DI (match_dup 1) (match_dup 2)))
7502	      (clobber (reg:CC FLAGS_REG))])]
7503  "TARGET_64BIT"
7504  "")
7505
7506;; Allow to come the parameter in eax or edx to avoid extra moves.
7507;; Penalize eax case slightly because it results in worse scheduling
7508;; of code.
7509(define_insn "*divmoddi4_nocltd_rex64"
7510  [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7511	(div:DI (match_operand:DI 2 "register_operand" "1,0")
7512		(match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7513   (set (match_operand:DI 1 "register_operand" "=&d,&d")
7514	(mod:DI (match_dup 2) (match_dup 3)))
7515   (clobber (reg:CC FLAGS_REG))]
7516  "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7517  "#"
7518  [(set_attr "type" "multi")])
7519
7520(define_insn "*divmoddi4_cltd_rex64"
7521  [(set (match_operand:DI 0 "register_operand" "=a")
7522	(div:DI (match_operand:DI 2 "register_operand" "a")
7523		(match_operand:DI 3 "nonimmediate_operand" "rm")))
7524   (set (match_operand:DI 1 "register_operand" "=&d")
7525	(mod:DI (match_dup 2) (match_dup 3)))
7526   (clobber (reg:CC FLAGS_REG))]
7527  "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7528  "#"
7529  [(set_attr "type" "multi")])
7530
7531(define_insn "*divmoddi_noext_rex64"
7532  [(set (match_operand:DI 0 "register_operand" "=a")
7533	(div:DI (match_operand:DI 1 "register_operand" "0")
7534		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7535   (set (match_operand:DI 3 "register_operand" "=d")
7536	(mod:DI (match_dup 1) (match_dup 2)))
7537   (use (match_operand:DI 4 "register_operand" "3"))
7538   (clobber (reg:CC FLAGS_REG))]
7539  "TARGET_64BIT"
7540  "idiv{q}\t%2"
7541  [(set_attr "type" "idiv")
7542   (set_attr "mode" "DI")])
7543
7544(define_split
7545  [(set (match_operand:DI 0 "register_operand" "")
7546	(div:DI (match_operand:DI 1 "register_operand" "")
7547		(match_operand:DI 2 "nonimmediate_operand" "")))
7548   (set (match_operand:DI 3 "register_operand" "")
7549	(mod:DI (match_dup 1) (match_dup 2)))
7550   (clobber (reg:CC FLAGS_REG))]
7551  "TARGET_64BIT && reload_completed"
7552  [(parallel [(set (match_dup 3)
7553		   (ashiftrt:DI (match_dup 4) (const_int 63)))
7554	      (clobber (reg:CC FLAGS_REG))])
7555   (parallel [(set (match_dup 0)
7556	           (div:DI (reg:DI 0) (match_dup 2)))
7557	      (set (match_dup 3)
7558		   (mod:DI (reg:DI 0) (match_dup 2)))
7559	      (use (match_dup 3))
7560	      (clobber (reg:CC FLAGS_REG))])]
7561{
7562  /* Avoid use of cltd in favor of a mov+shift.  */
7563  if (!TARGET_USE_CLTD && !optimize_size)
7564    {
7565      if (true_regnum (operands[1]))
7566        emit_move_insn (operands[0], operands[1]);
7567      else
7568	emit_move_insn (operands[3], operands[1]);
7569      operands[4] = operands[3];
7570    }
7571  else
7572    {
7573      gcc_assert (!true_regnum (operands[1]));
7574      operands[4] = operands[1];
7575    }
7576})
7577
7578
7579(define_expand "divmodsi4"
7580  [(parallel [(set (match_operand:SI 0 "register_operand" "")
7581		   (div:SI (match_operand:SI 1 "register_operand" "")
7582			   (match_operand:SI 2 "nonimmediate_operand" "")))
7583	      (set (match_operand:SI 3 "register_operand" "")
7584		   (mod:SI (match_dup 1) (match_dup 2)))
7585	      (clobber (reg:CC FLAGS_REG))])]
7586  ""
7587  "")
7588
7589;; Allow to come the parameter in eax or edx to avoid extra moves.
7590;; Penalize eax case slightly because it results in worse scheduling
7591;; of code.
7592(define_insn "*divmodsi4_nocltd"
7593  [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7594	(div:SI (match_operand:SI 2 "register_operand" "1,0")
7595		(match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7596   (set (match_operand:SI 1 "register_operand" "=&d,&d")
7597	(mod:SI (match_dup 2) (match_dup 3)))
7598   (clobber (reg:CC FLAGS_REG))]
7599  "!optimize_size && !TARGET_USE_CLTD"
7600  "#"
7601  [(set_attr "type" "multi")])
7602
7603(define_insn "*divmodsi4_cltd"
7604  [(set (match_operand:SI 0 "register_operand" "=a")
7605	(div:SI (match_operand:SI 2 "register_operand" "a")
7606		(match_operand:SI 3 "nonimmediate_operand" "rm")))
7607   (set (match_operand:SI 1 "register_operand" "=&d")
7608	(mod:SI (match_dup 2) (match_dup 3)))
7609   (clobber (reg:CC FLAGS_REG))]
7610  "optimize_size || TARGET_USE_CLTD"
7611  "#"
7612  [(set_attr "type" "multi")])
7613
7614(define_insn "*divmodsi_noext"
7615  [(set (match_operand:SI 0 "register_operand" "=a")
7616	(div:SI (match_operand:SI 1 "register_operand" "0")
7617		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7618   (set (match_operand:SI 3 "register_operand" "=d")
7619	(mod:SI (match_dup 1) (match_dup 2)))
7620   (use (match_operand:SI 4 "register_operand" "3"))
7621   (clobber (reg:CC FLAGS_REG))]
7622  ""
7623  "idiv{l}\t%2"
7624  [(set_attr "type" "idiv")
7625   (set_attr "mode" "SI")])
7626
7627(define_split
7628  [(set (match_operand:SI 0 "register_operand" "")
7629	(div:SI (match_operand:SI 1 "register_operand" "")
7630		(match_operand:SI 2 "nonimmediate_operand" "")))
7631   (set (match_operand:SI 3 "register_operand" "")
7632	(mod:SI (match_dup 1) (match_dup 2)))
7633   (clobber (reg:CC FLAGS_REG))]
7634  "reload_completed"
7635  [(parallel [(set (match_dup 3)
7636		   (ashiftrt:SI (match_dup 4) (const_int 31)))
7637	      (clobber (reg:CC FLAGS_REG))])
7638   (parallel [(set (match_dup 0)
7639	           (div:SI (reg:SI 0) (match_dup 2)))
7640	      (set (match_dup 3)
7641		   (mod:SI (reg:SI 0) (match_dup 2)))
7642	      (use (match_dup 3))
7643	      (clobber (reg:CC FLAGS_REG))])]
7644{
7645  /* Avoid use of cltd in favor of a mov+shift.  */
7646  if (!TARGET_USE_CLTD && !optimize_size)
7647    {
7648      if (true_regnum (operands[1]))
7649        emit_move_insn (operands[0], operands[1]);
7650      else
7651	emit_move_insn (operands[3], operands[1]);
7652      operands[4] = operands[3];
7653    }
7654  else
7655    {
7656      gcc_assert (!true_regnum (operands[1]));
7657      operands[4] = operands[1];
7658    }
7659})
7660;; %%% Split me.
7661(define_insn "divmodhi4"
7662  [(set (match_operand:HI 0 "register_operand" "=a")
7663	(div:HI (match_operand:HI 1 "register_operand" "0")
7664		(match_operand:HI 2 "nonimmediate_operand" "rm")))
7665   (set (match_operand:HI 3 "register_operand" "=&d")
7666	(mod:HI (match_dup 1) (match_dup 2)))
7667   (clobber (reg:CC FLAGS_REG))]
7668  "TARGET_HIMODE_MATH"
7669  "cwtd\;idiv{w}\t%2"
7670  [(set_attr "type" "multi")
7671   (set_attr "length_immediate" "0")
7672   (set_attr "mode" "SI")])
7673
7674(define_insn "udivmoddi4"
7675  [(set (match_operand:DI 0 "register_operand" "=a")
7676	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7677		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7678   (set (match_operand:DI 3 "register_operand" "=&d")
7679	(umod:DI (match_dup 1) (match_dup 2)))
7680   (clobber (reg:CC FLAGS_REG))]
7681  "TARGET_64BIT"
7682  "xor{q}\t%3, %3\;div{q}\t%2"
7683  [(set_attr "type" "multi")
7684   (set_attr "length_immediate" "0")
7685   (set_attr "mode" "DI")])
7686
7687(define_insn "*udivmoddi4_noext"
7688  [(set (match_operand:DI 0 "register_operand" "=a")
7689	(udiv:DI (match_operand:DI 1 "register_operand" "0")
7690		 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7691   (set (match_operand:DI 3 "register_operand" "=d")
7692	(umod:DI (match_dup 1) (match_dup 2)))
7693   (use (match_dup 3))
7694   (clobber (reg:CC FLAGS_REG))]
7695  "TARGET_64BIT"
7696  "div{q}\t%2"
7697  [(set_attr "type" "idiv")
7698   (set_attr "mode" "DI")])
7699
7700(define_split
7701  [(set (match_operand:DI 0 "register_operand" "")
7702	(udiv:DI (match_operand:DI 1 "register_operand" "")
7703		 (match_operand:DI 2 "nonimmediate_operand" "")))
7704   (set (match_operand:DI 3 "register_operand" "")
7705	(umod:DI (match_dup 1) (match_dup 2)))
7706   (clobber (reg:CC FLAGS_REG))]
7707  "TARGET_64BIT && reload_completed"
7708  [(set (match_dup 3) (const_int 0))
7709   (parallel [(set (match_dup 0)
7710		   (udiv:DI (match_dup 1) (match_dup 2)))
7711	      (set (match_dup 3)
7712		   (umod:DI (match_dup 1) (match_dup 2)))
7713	      (use (match_dup 3))
7714	      (clobber (reg:CC FLAGS_REG))])]
7715  "")
7716
7717(define_insn "udivmodsi4"
7718  [(set (match_operand:SI 0 "register_operand" "=a")
7719	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7720		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7721   (set (match_operand:SI 3 "register_operand" "=&d")
7722	(umod:SI (match_dup 1) (match_dup 2)))
7723   (clobber (reg:CC FLAGS_REG))]
7724  ""
7725  "xor{l}\t%3, %3\;div{l}\t%2"
7726  [(set_attr "type" "multi")
7727   (set_attr "length_immediate" "0")
7728   (set_attr "mode" "SI")])
7729
7730(define_insn "*udivmodsi4_noext"
7731  [(set (match_operand:SI 0 "register_operand" "=a")
7732	(udiv:SI (match_operand:SI 1 "register_operand" "0")
7733		 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7734   (set (match_operand:SI 3 "register_operand" "=d")
7735	(umod:SI (match_dup 1) (match_dup 2)))
7736   (use (match_dup 3))
7737   (clobber (reg:CC FLAGS_REG))]
7738  ""
7739  "div{l}\t%2"
7740  [(set_attr "type" "idiv")
7741   (set_attr "mode" "SI")])
7742
7743(define_split
7744  [(set (match_operand:SI 0 "register_operand" "")
7745	(udiv:SI (match_operand:SI 1 "register_operand" "")
7746		 (match_operand:SI 2 "nonimmediate_operand" "")))
7747   (set (match_operand:SI 3 "register_operand" "")
7748	(umod:SI (match_dup 1) (match_dup 2)))
7749   (clobber (reg:CC FLAGS_REG))]
7750  "reload_completed"
7751  [(set (match_dup 3) (const_int 0))
7752   (parallel [(set (match_dup 0)
7753		   (udiv:SI (match_dup 1) (match_dup 2)))
7754	      (set (match_dup 3)
7755		   (umod:SI (match_dup 1) (match_dup 2)))
7756	      (use (match_dup 3))
7757	      (clobber (reg:CC FLAGS_REG))])]
7758  "")
7759
7760(define_expand "udivmodhi4"
7761  [(set (match_dup 4) (const_int 0))
7762   (parallel [(set (match_operand:HI 0 "register_operand" "")
7763		   (udiv:HI (match_operand:HI 1 "register_operand" "")
7764		 	    (match_operand:HI 2 "nonimmediate_operand" "")))
7765	      (set (match_operand:HI 3 "register_operand" "")
7766	   	   (umod:HI (match_dup 1) (match_dup 2)))
7767	      (use (match_dup 4))
7768	      (clobber (reg:CC FLAGS_REG))])]
7769  "TARGET_HIMODE_MATH"
7770  "operands[4] = gen_reg_rtx (HImode);")
7771
7772(define_insn "*udivmodhi_noext"
7773  [(set (match_operand:HI 0 "register_operand" "=a")
7774	(udiv:HI (match_operand:HI 1 "register_operand" "0")
7775		 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7776   (set (match_operand:HI 3 "register_operand" "=d")
7777	(umod:HI (match_dup 1) (match_dup 2)))
7778   (use (match_operand:HI 4 "register_operand" "3"))
7779   (clobber (reg:CC FLAGS_REG))]
7780  ""
7781  "div{w}\t%2"
7782  [(set_attr "type" "idiv")
7783   (set_attr "mode" "HI")])
7784
7785;; We cannot use div/idiv for double division, because it causes
7786;; "division by zero" on the overflow and that's not what we expect
7787;; from truncate.  Because true (non truncating) double division is
7788;; never generated, we can't create this insn anyway.
7789;
7790;(define_insn ""
7791;  [(set (match_operand:SI 0 "register_operand" "=a")
7792;	(truncate:SI
7793;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7794;		   (zero_extend:DI
7795;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7796;   (set (match_operand:SI 3 "register_operand" "=d")
7797;	(truncate:SI
7798;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7799;   (clobber (reg:CC FLAGS_REG))]
7800;  ""
7801;  "div{l}\t{%2, %0|%0, %2}"
7802;  [(set_attr "type" "idiv")])
7803
7804;;- Logical AND instructions
7805
7806;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7807;; Note that this excludes ah.
7808
7809(define_insn "*testdi_1_rex64"
7810  [(set (reg FLAGS_REG)
7811	(compare
7812	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7813		  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7814	  (const_int 0)))]
7815  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7816   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7817  "@
7818   test{l}\t{%k1, %k0|%k0, %k1}
7819   test{l}\t{%k1, %k0|%k0, %k1}
7820   test{q}\t{%1, %0|%0, %1}
7821   test{q}\t{%1, %0|%0, %1}
7822   test{q}\t{%1, %0|%0, %1}"
7823  [(set_attr "type" "test")
7824   (set_attr "modrm" "0,1,0,1,1")
7825   (set_attr "mode" "SI,SI,DI,DI,DI")
7826   (set_attr "pent_pair" "uv,np,uv,np,uv")])
7827
7828(define_insn "testsi_1"
7829  [(set (reg FLAGS_REG)
7830	(compare
7831	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7832		  (match_operand:SI 1 "general_operand" "in,in,rin"))
7833	  (const_int 0)))]
7834  "ix86_match_ccmode (insn, CCNOmode)
7835   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7836  "test{l}\t{%1, %0|%0, %1}"
7837  [(set_attr "type" "test")
7838   (set_attr "modrm" "0,1,1")
7839   (set_attr "mode" "SI")
7840   (set_attr "pent_pair" "uv,np,uv")])
7841
7842(define_expand "testsi_ccno_1"
7843  [(set (reg:CCNO FLAGS_REG)
7844	(compare:CCNO
7845	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7846		  (match_operand:SI 1 "nonmemory_operand" ""))
7847	  (const_int 0)))]
7848  ""
7849  "")
7850
7851(define_insn "*testhi_1"
7852  [(set (reg FLAGS_REG)
7853        (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7854			 (match_operand:HI 1 "general_operand" "n,n,rn"))
7855		 (const_int 0)))]
7856  "ix86_match_ccmode (insn, CCNOmode)
7857   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7858  "test{w}\t{%1, %0|%0, %1}"
7859  [(set_attr "type" "test")
7860   (set_attr "modrm" "0,1,1")
7861   (set_attr "mode" "HI")
7862   (set_attr "pent_pair" "uv,np,uv")])
7863
7864(define_expand "testqi_ccz_1"
7865  [(set (reg:CCZ FLAGS_REG)
7866        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7867			     (match_operand:QI 1 "nonmemory_operand" ""))
7868		 (const_int 0)))]
7869  ""
7870  "")
7871
7872(define_insn "*testqi_1_maybe_si"
7873  [(set (reg FLAGS_REG)
7874        (compare
7875	  (and:QI
7876	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7877	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7878	  (const_int 0)))]
7879   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7880    && ix86_match_ccmode (insn,
7881 			 GET_CODE (operands[1]) == CONST_INT
7882 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7883{
7884  if (which_alternative == 3)
7885    {
7886      if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7887	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7888      return "test{l}\t{%1, %k0|%k0, %1}";
7889    }
7890  return "test{b}\t{%1, %0|%0, %1}";
7891}
7892  [(set_attr "type" "test")
7893   (set_attr "modrm" "0,1,1,1")
7894   (set_attr "mode" "QI,QI,QI,SI")
7895   (set_attr "pent_pair" "uv,np,uv,np")])
7896
7897(define_insn "*testqi_1"
7898  [(set (reg FLAGS_REG)
7899        (compare
7900	  (and:QI
7901	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7902	    (match_operand:QI 1 "general_operand" "n,n,qn"))
7903	  (const_int 0)))]
7904  "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7905   && ix86_match_ccmode (insn, CCNOmode)"
7906  "test{b}\t{%1, %0|%0, %1}"
7907  [(set_attr "type" "test")
7908   (set_attr "modrm" "0,1,1")
7909   (set_attr "mode" "QI")
7910   (set_attr "pent_pair" "uv,np,uv")])
7911
7912(define_expand "testqi_ext_ccno_0"
7913  [(set (reg:CCNO FLAGS_REG)
7914	(compare:CCNO
7915	  (and:SI
7916	    (zero_extract:SI
7917	      (match_operand 0 "ext_register_operand" "")
7918	      (const_int 8)
7919	      (const_int 8))
7920	    (match_operand 1 "const_int_operand" ""))
7921	  (const_int 0)))]
7922  ""
7923  "")
7924
7925(define_insn "*testqi_ext_0"
7926  [(set (reg FLAGS_REG)
7927	(compare
7928	  (and:SI
7929	    (zero_extract:SI
7930	      (match_operand 0 "ext_register_operand" "Q")
7931	      (const_int 8)
7932	      (const_int 8))
7933	    (match_operand 1 "const_int_operand" "n"))
7934	  (const_int 0)))]
7935  "ix86_match_ccmode (insn, CCNOmode)"
7936  "test{b}\t{%1, %h0|%h0, %1}"
7937  [(set_attr "type" "test")
7938   (set_attr "mode" "QI")
7939   (set_attr "length_immediate" "1")
7940   (set_attr "pent_pair" "np")])
7941
7942(define_insn "*testqi_ext_1"
7943  [(set (reg FLAGS_REG)
7944	(compare
7945	  (and:SI
7946	    (zero_extract:SI
7947	      (match_operand 0 "ext_register_operand" "Q")
7948	      (const_int 8)
7949	      (const_int 8))
7950	    (zero_extend:SI
7951	      (match_operand:QI 1 "general_operand" "Qm")))
7952	  (const_int 0)))]
7953  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7954   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7955  "test{b}\t{%1, %h0|%h0, %1}"
7956  [(set_attr "type" "test")
7957   (set_attr "mode" "QI")])
7958
7959(define_insn "*testqi_ext_1_rex64"
7960  [(set (reg FLAGS_REG)
7961	(compare
7962	  (and:SI
7963	    (zero_extract:SI
7964	      (match_operand 0 "ext_register_operand" "Q")
7965	      (const_int 8)
7966	      (const_int 8))
7967	    (zero_extend:SI
7968	      (match_operand:QI 1 "register_operand" "Q")))
7969	  (const_int 0)))]
7970  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7971  "test{b}\t{%1, %h0|%h0, %1}"
7972  [(set_attr "type" "test")
7973   (set_attr "mode" "QI")])
7974
7975(define_insn "*testqi_ext_2"
7976  [(set (reg FLAGS_REG)
7977	(compare
7978	  (and:SI
7979	    (zero_extract:SI
7980	      (match_operand 0 "ext_register_operand" "Q")
7981	      (const_int 8)
7982	      (const_int 8))
7983	    (zero_extract:SI
7984	      (match_operand 1 "ext_register_operand" "Q")
7985	      (const_int 8)
7986	      (const_int 8)))
7987	  (const_int 0)))]
7988  "ix86_match_ccmode (insn, CCNOmode)"
7989  "test{b}\t{%h1, %h0|%h0, %h1}"
7990  [(set_attr "type" "test")
7991   (set_attr "mode" "QI")])
7992
7993;; Combine likes to form bit extractions for some tests.  Humor it.
7994(define_insn "*testqi_ext_3"
7995  [(set (reg FLAGS_REG)
7996        (compare (zero_extract:SI
7997		   (match_operand 0 "nonimmediate_operand" "rm")
7998		   (match_operand:SI 1 "const_int_operand" "")
7999		   (match_operand:SI 2 "const_int_operand" ""))
8000		 (const_int 0)))]
8001  "ix86_match_ccmode (insn, CCNOmode)
8002   && INTVAL (operands[1]) > 0
8003   && INTVAL (operands[2]) >= 0
8004   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8005   && (GET_MODE (operands[0]) == SImode
8006       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8007       || GET_MODE (operands[0]) == HImode
8008       || GET_MODE (operands[0]) == QImode)"
8009  "#")
8010
8011(define_insn "*testqi_ext_3_rex64"
8012  [(set (reg FLAGS_REG)
8013        (compare (zero_extract:DI
8014		   (match_operand 0 "nonimmediate_operand" "rm")
8015		   (match_operand:DI 1 "const_int_operand" "")
8016		   (match_operand:DI 2 "const_int_operand" ""))
8017		 (const_int 0)))]
8018  "TARGET_64BIT
8019   && ix86_match_ccmode (insn, CCNOmode)
8020   && INTVAL (operands[1]) > 0
8021   && INTVAL (operands[2]) >= 0
8022   /* Ensure that resulting mask is zero or sign extended operand.  */
8023   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8024       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8025	   && INTVAL (operands[1]) > 32))
8026   && (GET_MODE (operands[0]) == SImode
8027       || GET_MODE (operands[0]) == DImode
8028       || GET_MODE (operands[0]) == HImode
8029       || GET_MODE (operands[0]) == QImode)"
8030  "#")
8031
8032(define_split
8033  [(set (match_operand 0 "flags_reg_operand" "")
8034        (match_operator 1 "compare_operator"
8035	  [(zero_extract
8036	     (match_operand 2 "nonimmediate_operand" "")
8037	     (match_operand 3 "const_int_operand" "")
8038	     (match_operand 4 "const_int_operand" ""))
8039	   (const_int 0)]))]
8040  "ix86_match_ccmode (insn, CCNOmode)"
8041  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8042{
8043  rtx val = operands[2];
8044  HOST_WIDE_INT len = INTVAL (operands[3]);
8045  HOST_WIDE_INT pos = INTVAL (operands[4]);
8046  HOST_WIDE_INT mask;
8047  enum machine_mode mode, submode;
8048
8049  mode = GET_MODE (val);
8050  if (GET_CODE (val) == MEM)
8051    {
8052      /* ??? Combine likes to put non-volatile mem extractions in QImode
8053	 no matter the size of the test.  So find a mode that works.  */
8054      if (! MEM_VOLATILE_P (val))
8055	{
8056	  mode = smallest_mode_for_size (pos + len, MODE_INT);
8057	  val = adjust_address (val, mode, 0);
8058	}
8059    }
8060  else if (GET_CODE (val) == SUBREG
8061	   && (submode = GET_MODE (SUBREG_REG (val)),
8062	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8063	   && pos + len <= GET_MODE_BITSIZE (submode))
8064    {
8065      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8066      mode = submode;
8067      val = SUBREG_REG (val);
8068    }
8069  else if (mode == HImode && pos + len <= 8)
8070    {
8071      /* Small HImode tests can be converted to QImode.  */
8072      mode = QImode;
8073      val = gen_lowpart (QImode, val);
8074    }
8075
8076  if (len == HOST_BITS_PER_WIDE_INT)
8077    mask = -1;
8078  else
8079    mask = ((HOST_WIDE_INT)1 << len) - 1;
8080  mask <<= pos;
8081
8082  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8083})
8084
8085;; Convert HImode/SImode test instructions with immediate to QImode ones.
8086;; i386 does not allow to encode test with 8bit sign extended immediate, so
8087;; this is relatively important trick.
8088;; Do the conversion only post-reload to avoid limiting of the register class
8089;; to QI regs.
8090(define_split
8091  [(set (match_operand 0 "flags_reg_operand" "")
8092	(match_operator 1 "compare_operator"
8093	  [(and (match_operand 2 "register_operand" "")
8094	        (match_operand 3 "const_int_operand" ""))
8095	   (const_int 0)]))]
8096   "reload_completed
8097    && QI_REG_P (operands[2])
8098    && GET_MODE (operands[2]) != QImode
8099    && ((ix86_match_ccmode (insn, CCZmode)
8100    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
8101	|| (ix86_match_ccmode (insn, CCNOmode)
8102	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
8103  [(set (match_dup 0)
8104	(match_op_dup 1
8105	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8106		   (match_dup 3))
8107	   (const_int 0)]))]
8108  "operands[2] = gen_lowpart (SImode, operands[2]);
8109   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8110
8111(define_split
8112  [(set (match_operand 0 "flags_reg_operand" "")
8113	(match_operator 1 "compare_operator"
8114	  [(and (match_operand 2 "nonimmediate_operand" "")
8115	        (match_operand 3 "const_int_operand" ""))
8116	   (const_int 0)]))]
8117   "reload_completed
8118    && GET_MODE (operands[2]) != QImode
8119    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8120    && ((ix86_match_ccmode (insn, CCZmode)
8121	 && !(INTVAL (operands[3]) & ~255))
8122	|| (ix86_match_ccmode (insn, CCNOmode)
8123	    && !(INTVAL (operands[3]) & ~127)))"
8124  [(set (match_dup 0)
8125	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8126			 (const_int 0)]))]
8127  "operands[2] = gen_lowpart (QImode, operands[2]);
8128   operands[3] = gen_lowpart (QImode, operands[3]);")
8129
8130
8131;; %%% This used to optimize known byte-wide and operations to memory,
8132;; and sometimes to QImode registers.  If this is considered useful,
8133;; it should be done with splitters.
8134
8135(define_expand "anddi3"
8136  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8137	(and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8138		(match_operand:DI 2 "x86_64_szext_general_operand" "")))
8139   (clobber (reg:CC FLAGS_REG))]
8140  "TARGET_64BIT"
8141  "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8142
8143(define_insn "*anddi_1_rex64"
8144  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8145	(and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8146		(match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8147   (clobber (reg:CC FLAGS_REG))]
8148  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8149{
8150  switch (get_attr_type (insn))
8151    {
8152    case TYPE_IMOVX:
8153      {
8154	enum machine_mode mode;
8155
8156	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8157        if (INTVAL (operands[2]) == 0xff)
8158	  mode = QImode;
8159	else
8160	  {
8161	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8162	    mode = HImode;
8163	  }
8164	
8165	operands[1] = gen_lowpart (mode, operands[1]);
8166	if (mode == QImode)
8167	  return "movz{bq|x}\t{%1,%0|%0, %1}";
8168	else
8169	  return "movz{wq|x}\t{%1,%0|%0, %1}";
8170      }
8171
8172    default:
8173      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8174      if (get_attr_mode (insn) == MODE_SI)
8175	return "and{l}\t{%k2, %k0|%k0, %k2}";
8176      else
8177	return "and{q}\t{%2, %0|%0, %2}";
8178    }
8179}
8180  [(set_attr "type" "alu,alu,alu,imovx")
8181   (set_attr "length_immediate" "*,*,*,0")
8182   (set_attr "mode" "SI,DI,DI,DI")])
8183
8184(define_insn "*anddi_2"
8185  [(set (reg FLAGS_REG)
8186	(compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8187			 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8188		 (const_int 0)))
8189   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8190	(and:DI (match_dup 1) (match_dup 2)))]
8191  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8192   && ix86_binary_operator_ok (AND, DImode, operands)"
8193  "@
8194   and{l}\t{%k2, %k0|%k0, %k2}
8195   and{q}\t{%2, %0|%0, %2}
8196   and{q}\t{%2, %0|%0, %2}"
8197  [(set_attr "type" "alu")
8198   (set_attr "mode" "SI,DI,DI")])
8199
8200(define_expand "andsi3"
8201  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8202	(and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8203		(match_operand:SI 2 "general_operand" "")))
8204   (clobber (reg:CC FLAGS_REG))]
8205  ""
8206  "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8207
8208(define_insn "*andsi_1"
8209  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8210	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8211		(match_operand:SI 2 "general_operand" "ri,rm,L")))
8212   (clobber (reg:CC FLAGS_REG))]
8213  "ix86_binary_operator_ok (AND, SImode, operands)"
8214{
8215  switch (get_attr_type (insn))
8216    {
8217    case TYPE_IMOVX:
8218      {
8219	enum machine_mode mode;
8220
8221	gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8222        if (INTVAL (operands[2]) == 0xff)
8223	  mode = QImode;
8224	else
8225	  {
8226	    gcc_assert (INTVAL (operands[2]) == 0xffff);
8227	    mode = HImode;
8228	  }
8229	
8230	operands[1] = gen_lowpart (mode, operands[1]);
8231	if (mode == QImode)
8232	  return "movz{bl|x}\t{%1,%0|%0, %1}";
8233	else
8234	  return "movz{wl|x}\t{%1,%0|%0, %1}";
8235      }
8236
8237    default:
8238      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8239      return "and{l}\t{%2, %0|%0, %2}";
8240    }
8241}
8242  [(set_attr "type" "alu,alu,imovx")
8243   (set_attr "length_immediate" "*,*,0")
8244   (set_attr "mode" "SI")])
8245
8246(define_split
8247  [(set (match_operand 0 "register_operand" "")
8248	(and (match_dup 0)
8249	     (const_int -65536)))
8250   (clobber (reg:CC FLAGS_REG))]
8251  "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8252  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8253  "operands[1] = gen_lowpart (HImode, operands[0]);")
8254
8255(define_split
8256  [(set (match_operand 0 "ext_register_operand" "")
8257	(and (match_dup 0)
8258	     (const_int -256)))
8259   (clobber (reg:CC FLAGS_REG))]
8260  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8261  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8262  "operands[1] = gen_lowpart (QImode, operands[0]);")
8263
8264(define_split
8265  [(set (match_operand 0 "ext_register_operand" "")
8266	(and (match_dup 0)
8267	     (const_int -65281)))
8268   (clobber (reg:CC FLAGS_REG))]
8269  "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8270  [(parallel [(set (zero_extract:SI (match_dup 0)
8271				    (const_int 8)
8272				    (const_int 8))
8273		   (xor:SI 
8274		     (zero_extract:SI (match_dup 0)
8275				      (const_int 8)
8276				      (const_int 8))
8277		     (zero_extract:SI (match_dup 0)
8278				      (const_int 8)
8279				      (const_int 8))))
8280	      (clobber (reg:CC FLAGS_REG))])]
8281  "operands[0] = gen_lowpart (SImode, operands[0]);")
8282
8283;; See comment for addsi_1_zext why we do use nonimmediate_operand
8284(define_insn "*andsi_1_zext"
8285  [(set (match_operand:DI 0 "register_operand" "=r")
8286	(zero_extend:DI
8287	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8288		  (match_operand:SI 2 "general_operand" "rim"))))
8289   (clobber (reg:CC FLAGS_REG))]
8290  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8291  "and{l}\t{%2, %k0|%k0, %2}"
8292  [(set_attr "type" "alu")
8293   (set_attr "mode" "SI")])
8294
8295(define_insn "*andsi_2"
8296  [(set (reg FLAGS_REG)
8297	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8298			 (match_operand:SI 2 "general_operand" "rim,ri"))
8299		 (const_int 0)))
8300   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8301	(and:SI (match_dup 1) (match_dup 2)))]
8302  "ix86_match_ccmode (insn, CCNOmode)
8303   && ix86_binary_operator_ok (AND, SImode, operands)"
8304  "and{l}\t{%2, %0|%0, %2}"
8305  [(set_attr "type" "alu")
8306   (set_attr "mode" "SI")])
8307
8308;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309(define_insn "*andsi_2_zext"
8310  [(set (reg FLAGS_REG)
8311	(compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8312			 (match_operand:SI 2 "general_operand" "rim"))
8313		 (const_int 0)))
8314   (set (match_operand:DI 0 "register_operand" "=r")
8315	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8316  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8317   && ix86_binary_operator_ok (AND, SImode, operands)"
8318  "and{l}\t{%2, %k0|%k0, %2}"
8319  [(set_attr "type" "alu")
8320   (set_attr "mode" "SI")])
8321
8322(define_expand "andhi3"
8323  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8324	(and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8325		(match_operand:HI 2 "general_operand" "")))
8326   (clobber (reg:CC FLAGS_REG))]
8327  "TARGET_HIMODE_MATH"
8328  "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8329
8330(define_insn "*andhi_1"
8331  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8332	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8333		(match_operand:HI 2 "general_operand" "ri,rm,L")))
8334   (clobber (reg:CC FLAGS_REG))]
8335  "ix86_binary_operator_ok (AND, HImode, operands)"
8336{
8337  switch (get_attr_type (insn))
8338    {
8339    case TYPE_IMOVX:
8340      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8341      gcc_assert (INTVAL (operands[2]) == 0xff);
8342      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8343
8344    default:
8345      gcc_assert (rtx_equal_p (operands[0], operands[1]));
8346
8347      return "and{w}\t{%2, %0|%0, %2}";
8348    }
8349}
8350  [(set_attr "type" "alu,alu,imovx")
8351   (set_attr "length_immediate" "*,*,0")
8352   (set_attr "mode" "HI,HI,SI")])
8353
8354(define_insn "*andhi_2"
8355  [(set (reg FLAGS_REG)
8356	(compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8357			 (match_operand:HI 2 "general_operand" "rim,ri"))
8358		 (const_int 0)))
8359   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8360	(and:HI (match_dup 1) (match_dup 2)))]
8361  "ix86_match_ccmode (insn, CCNOmode)
8362   && ix86_binary_operator_ok (AND, HImode, operands)"
8363  "and{w}\t{%2, %0|%0, %2}"
8364  [(set_attr "type" "alu")
8365   (set_attr "mode" "HI")])
8366
8367(define_expand "andqi3"
8368  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8369	(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8370		(match_operand:QI 2 "general_operand" "")))
8371   (clobber (reg:CC FLAGS_REG))]
8372  "TARGET_QIMODE_MATH"
8373  "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8374
8375;; %%% Potential partial reg stall on alternative 2.  What to do?
8376(define_insn "*andqi_1"
8377  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8378	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8379		(match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8380   (clobber (reg:CC FLAGS_REG))]
8381  "ix86_binary_operator_ok (AND, QImode, operands)"
8382  "@
8383   and{b}\t{%2, %0|%0, %2}
8384   and{b}\t{%2, %0|%0, %2}
8385   and{l}\t{%k2, %k0|%k0, %k2}"
8386  [(set_attr "type" "alu")
8387   (set_attr "mode" "QI,QI,SI")])
8388
8389(define_insn "*andqi_1_slp"
8390  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8391	(and:QI (match_dup 0)
8392		(match_operand:QI 1 "general_operand" "qi,qmi")))
8393   (clobber (reg:CC FLAGS_REG))]
8394  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8395   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8396  "and{b}\t{%1, %0|%0, %1}"
8397  [(set_attr "type" "alu1")
8398   (set_attr "mode" "QI")])
8399
8400(define_insn "*andqi_2_maybe_si"
8401  [(set (reg FLAGS_REG)
8402	(compare (and:QI
8403		      (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8404		      (match_operand:QI 2 "general_operand" "qim,qi,i"))
8405		 (const_int 0)))
8406   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8407	(and:QI (match_dup 1) (match_dup 2)))]
8408  "ix86_binary_operator_ok (AND, QImode, operands)
8409   && ix86_match_ccmode (insn,
8410			 GET_CODE (operands[2]) == CONST_INT
8411			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8412{
8413  if (which_alternative == 2)
8414    {
8415      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8416        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8417      return "and{l}\t{%2, %k0|%k0, %2}";
8418    }
8419  return "and{b}\t{%2, %0|%0, %2}";
8420}
8421  [(set_attr "type" "alu")
8422   (set_attr "mode" "QI,QI,SI")])
8423
8424(define_insn "*andqi_2"
8425  [(set (reg FLAGS_REG)
8426	(compare (and:QI
8427		   (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8428		   (match_operand:QI 2 "general_operand" "qim,qi"))
8429		 (const_int 0)))
8430   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8431	(and:QI (match_dup 1) (match_dup 2)))]
8432  "ix86_match_ccmode (insn, CCNOmode)
8433   && ix86_binary_operator_ok (AND, QImode, operands)"
8434  "and{b}\t{%2, %0|%0, %2}"
8435  [(set_attr "type" "alu")
8436   (set_attr "mode" "QI")])
8437
8438(define_insn "*andqi_2_slp"
8439  [(set (reg FLAGS_REG)
8440	(compare (and:QI
8441		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8442		   (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8443		 (const_int 0)))
8444   (set (strict_low_part (match_dup 0))
8445	(and:QI (match_dup 0) (match_dup 1)))]
8446  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8447   && ix86_match_ccmode (insn, CCNOmode)
8448   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8449  "and{b}\t{%1, %0|%0, %1}"
8450  [(set_attr "type" "alu1")
8451   (set_attr "mode" "QI")])
8452
8453;; ??? A bug in recog prevents it from recognizing a const_int as an
8454;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8455;; for a QImode operand, which of course failed.
8456
8457(define_insn "andqi_ext_0"
8458  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459			 (const_int 8)
8460			 (const_int 8))
8461	(and:SI 
8462	  (zero_extract:SI
8463	    (match_operand 1 "ext_register_operand" "0")
8464	    (const_int 8)
8465	    (const_int 8))
8466	  (match_operand 2 "const_int_operand" "n")))
8467   (clobber (reg:CC FLAGS_REG))]
8468  ""
8469  "and{b}\t{%2, %h0|%h0, %2}"
8470  [(set_attr "type" "alu")
8471   (set_attr "length_immediate" "1")
8472   (set_attr "mode" "QI")])
8473
8474;; Generated by peephole translating test to and.  This shows up
8475;; often in fp comparisons.
8476
8477(define_insn "*andqi_ext_0_cc"
8478  [(set (reg FLAGS_REG)
8479	(compare
8480	  (and:SI
8481	    (zero_extract:SI
8482	      (match_operand 1 "ext_register_operand" "0")
8483	      (const_int 8)
8484	      (const_int 8))
8485	    (match_operand 2 "const_int_operand" "n"))
8486	  (const_int 0)))
8487   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8488			 (const_int 8)
8489			 (const_int 8))
8490	(and:SI 
8491	  (zero_extract:SI
8492	    (match_dup 1)
8493	    (const_int 8)
8494	    (const_int 8))
8495	  (match_dup 2)))]
8496  "ix86_match_ccmode (insn, CCNOmode)"
8497  "and{b}\t{%2, %h0|%h0, %2}"
8498  [(set_attr "type" "alu")
8499   (set_attr "length_immediate" "1")
8500   (set_attr "mode" "QI")])
8501
8502(define_insn "*andqi_ext_1"
8503  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8504			 (const_int 8)
8505			 (const_int 8))
8506	(and:SI 
8507	  (zero_extract:SI
8508	    (match_operand 1 "ext_register_operand" "0")
8509	    (const_int 8)
8510	    (const_int 8))
8511	  (zero_extend:SI
8512	    (match_operand:QI 2 "general_operand" "Qm"))))
8513   (clobber (reg:CC FLAGS_REG))]
8514  "!TARGET_64BIT"
8515  "and{b}\t{%2, %h0|%h0, %2}"
8516  [(set_attr "type" "alu")
8517   (set_attr "length_immediate" "0")
8518   (set_attr "mode" "QI")])
8519
8520(define_insn "*andqi_ext_1_rex64"
8521  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8522			 (const_int 8)
8523			 (const_int 8))
8524	(and:SI 
8525	  (zero_extract:SI
8526	    (match_operand 1 "ext_register_operand" "0")
8527	    (const_int 8)
8528	    (const_int 8))
8529	  (zero_extend:SI
8530	    (match_operand 2 "ext_register_operand" "Q"))))
8531   (clobber (reg:CC FLAGS_REG))]
8532  "TARGET_64BIT"
8533  "and{b}\t{%2, %h0|%h0, %2}"
8534  [(set_attr "type" "alu")
8535   (set_attr "length_immediate" "0")
8536   (set_attr "mode" "QI")])
8537
8538(define_insn "*andqi_ext_2"
8539  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8540			 (const_int 8)
8541			 (const_int 8))
8542	(and:SI
8543	  (zero_extract:SI
8544	    (match_operand 1 "ext_register_operand" "%0")
8545	    (const_int 8)
8546	    (const_int 8))
8547	  (zero_extract:SI
8548	    (match_operand 2 "ext_register_operand" "Q")
8549	    (const_int 8)
8550	    (const_int 8))))
8551   (clobber (reg:CC FLAGS_REG))]
8552  ""
8553  "and{b}\t{%h2, %h0|%h0, %h2}"
8554  [(set_attr "type" "alu")
8555   (set_attr "length_immediate" "0")
8556   (set_attr "mode" "QI")])
8557
8558;; Convert wide AND instructions with immediate operand to shorter QImode
8559;; equivalents when possible.
8560;; Don't do the splitting with memory operands, since it introduces risk
8561;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8562;; for size, but that can (should?) be handled by generic code instead.
8563(define_split
8564  [(set (match_operand 0 "register_operand" "")
8565	(and (match_operand 1 "register_operand" "")
8566	     (match_operand 2 "const_int_operand" "")))
8567   (clobber (reg:CC FLAGS_REG))]
8568   "reload_completed
8569    && QI_REG_P (operands[0])
8570    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8571    && !(~INTVAL (operands[2]) & ~(255 << 8))
8572    && GET_MODE (operands[0]) != QImode"
8573  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8574		   (and:SI (zero_extract:SI (match_dup 1)
8575					    (const_int 8) (const_int 8))
8576			   (match_dup 2)))
8577	      (clobber (reg:CC FLAGS_REG))])]
8578  "operands[0] = gen_lowpart (SImode, operands[0]);
8579   operands[1] = gen_lowpart (SImode, operands[1]);
8580   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8581
8582;; Since AND can be encoded with sign extended immediate, this is only
8583;; profitable when 7th bit is not set.
8584(define_split
8585  [(set (match_operand 0 "register_operand" "")
8586	(and (match_operand 1 "general_operand" "")
8587	     (match_operand 2 "const_int_operand" "")))
8588   (clobber (reg:CC FLAGS_REG))]
8589   "reload_completed
8590    && ANY_QI_REG_P (operands[0])
8591    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8592    && !(~INTVAL (operands[2]) & ~255)
8593    && !(INTVAL (operands[2]) & 128)
8594    && GET_MODE (operands[0]) != QImode"
8595  [(parallel [(set (strict_low_part (match_dup 0))
8596		   (and:QI (match_dup 1)
8597			   (match_dup 2)))
8598	      (clobber (reg:CC FLAGS_REG))])]
8599  "operands[0] = gen_lowpart (QImode, operands[0]);
8600   operands[1] = gen_lowpart (QImode, operands[1]);
8601   operands[2] = gen_lowpart (QImode, operands[2]);")
8602
8603;; Logical inclusive OR instructions
8604
8605;; %%% This used to optimize known byte-wide and operations to memory.
8606;; If this is considered useful, it should be done with splitters.
8607
8608(define_expand "iordi3"
8609  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8610	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8611		(match_operand:DI 2 "x86_64_general_operand" "")))
8612   (clobber (reg:CC FLAGS_REG))]
8613  "TARGET_64BIT"
8614  "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8615
8616(define_insn "*iordi_1_rex64"
8617  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8618	(ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8619		(match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8620   (clobber (reg:CC FLAGS_REG))]
8621  "TARGET_64BIT
8622   && ix86_binary_operator_ok (IOR, DImode, operands)"
8623  "or{q}\t{%2, %0|%0, %2}"
8624  [(set_attr "type" "alu")
8625   (set_attr "mode" "DI")])
8626
8627(define_insn "*iordi_2_rex64"
8628  [(set (reg FLAGS_REG)
8629	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8630			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8631		 (const_int 0)))
8632   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8633	(ior:DI (match_dup 1) (match_dup 2)))]
8634  "TARGET_64BIT
8635   && ix86_match_ccmode (insn, CCNOmode)
8636   && ix86_binary_operator_ok (IOR, DImode, operands)"
8637  "or{q}\t{%2, %0|%0, %2}"
8638  [(set_attr "type" "alu")
8639   (set_attr "mode" "DI")])
8640
8641(define_insn "*iordi_3_rex64"
8642  [(set (reg FLAGS_REG)
8643	(compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8644			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8645		 (const_int 0)))
8646   (clobber (match_scratch:DI 0 "=r"))]
8647  "TARGET_64BIT
8648   && ix86_match_ccmode (insn, CCNOmode)
8649   && ix86_binary_operator_ok (IOR, DImode, operands)"
8650  "or{q}\t{%2, %0|%0, %2}"
8651  [(set_attr "type" "alu")
8652   (set_attr "mode" "DI")])
8653
8654
8655(define_expand "iorsi3"
8656  [(set (match_operand:SI 0 "nonimmediate_operand" "")
8657	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8658		(match_operand:SI 2 "general_operand" "")))
8659   (clobber (reg:CC FLAGS_REG))]
8660  ""
8661  "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8662
8663(define_insn "*iorsi_1"
8664  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8665	(ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8666		(match_operand:SI 2 "general_operand" "ri,rmi")))
8667   (clobber (reg:CC FLAGS_REG))]
8668  "ix86_binary_operator_ok (IOR, SImode, operands)"
8669  "or{l}\t{%2, %0|%0, %2}"
8670  [(set_attr "type" "alu")
8671   (set_attr "mode" "SI")])
8672
8673;; See comment for addsi_1_zext why we do use nonimmediate_operand
8674(define_insn "*iorsi_1_zext"
8675  [(set (match_operand:DI 0 "register_operand" "=rm")
8676	(zero_extend:DI
8677	  (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8678		  (match_operand:SI 2 "general_operand" "rim"))))
8679   (clobber (reg:CC FLAGS_REG))]
8680  "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8681  "or{l}\t{%2, %k0|%k0, %2}"
8682  [(set_attr "type" "alu")
8683   (set_attr "mode" "SI")])
8684
8685(define_insn "*iorsi_1_zext_imm"
8686  [(set (match_operand:DI 0 "register_operand" "=rm")
8687	(ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8688		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8689   (clobber (reg:CC FLAGS_REG))]
8690  "TARGET_64BIT"
8691  "or{l}\t{%2, %k0|%k0, %2}"
8692  [(set_attr "type" "alu")
8693   (set_attr "mode" "SI")])
8694
8695(define_insn "*iorsi_2"
8696  [(set (reg FLAGS_REG)
8697	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8698			 (match_operand:SI 2 "general_operand" "rim,ri"))
8699		 (const_int 0)))
8700   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8701	(ior:SI (match_dup 1) (match_dup 2)))]
8702  "ix86_match_ccmode (insn, CCNOmode)
8703   && ix86_binary_operator_ok (IOR, SImode, operands)"
8704  "or{l}\t{%2, %0|%0, %2}"
8705  [(set_attr "type" "alu")
8706   (set_attr "mode" "SI")])
8707
8708;; See comment for addsi_1_zext why we do use nonimmediate_operand
8709;; ??? Special case for immediate operand is missing - it is tricky.
8710(define_insn "*iorsi_2_zext"
8711  [(set (reg FLAGS_REG)
8712	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8713			 (match_operand:SI 2 "general_operand" "rim"))
8714		 (const_int 0)))
8715   (set (match_operand:DI 0 "register_operand" "=r")
8716	(zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8717  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8718   && ix86_binary_operator_ok (IOR, SImode, operands)"
8719  "or{l}\t{%2, %k0|%k0, %2}"
8720  [(set_attr "type" "alu")
8721   (set_attr "mode" "SI")])
8722
8723(define_insn "*iorsi_2_zext_imm"
8724  [(set (reg FLAGS_REG)
8725	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8726			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8727		 (const_int 0)))
8728   (set (match_operand:DI 0 "register_operand" "=r")
8729	(ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8730  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8731   && ix86_binary_operator_ok (IOR, SImode, operands)"
8732  "or{l}\t{%2, %k0|%k0, %2}"
8733  [(set_attr "type" "alu")
8734   (set_attr "mode" "SI")])
8735
8736(define_insn "*iorsi_3"
8737  [(set (reg FLAGS_REG)
8738	(compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8739			 (match_operand:SI 2 "general_operand" "rim"))
8740		 (const_int 0)))
8741   (clobber (match_scratch:SI 0 "=r"))]
8742  "ix86_match_ccmode (insn, CCNOmode)
8743   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8744  "or{l}\t{%2, %0|%0, %2}"
8745  [(set_attr "type" "alu")
8746   (set_attr "mode" "SI")])
8747
8748(define_expand "iorhi3"
8749  [(set (match_operand:HI 0 "nonimmediate_operand" "")
8750	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8751		(match_operand:HI 2 "general_operand" "")))
8752   (clobber (reg:CC FLAGS_REG))]
8753  "TARGET_HIMODE_MATH"
8754  "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8755
8756(define_insn "*iorhi_1"
8757  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8758	(ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8759		(match_operand:HI 2 "general_operand" "rmi,ri")))
8760   (clobber (reg:CC FLAGS_REG))]
8761  "ix86_binary_operator_ok (IOR, HImode, operands)"
8762  "or{w}\t{%2, %0|%0, %2}"
8763  [(set_attr "type" "alu")
8764   (set_attr "mode" "HI")])
8765
8766(define_insn "*iorhi_2"
8767  [(set (reg FLAGS_REG)
8768	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8769			 (match_operand:HI 2 "general_operand" "rim,ri"))
8770		 (const_int 0)))
8771   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8772	(ior:HI (match_dup 1) (match_dup 2)))]
8773  "ix86_match_ccmode (insn, CCNOmode)
8774   && ix86_binary_operator_ok (IOR, HImode, operands)"
8775  "or{w}\t{%2, %0|%0, %2}"
8776  [(set_attr "type" "alu")
8777   (set_attr "mode" "HI")])
8778
8779(define_insn "*iorhi_3"
8780  [(set (reg FLAGS_REG)
8781	(compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8782			 (match_operand:HI 2 "general_operand" "rim"))
8783		 (const_int 0)))
8784   (clobber (match_scratch:HI 0 "=r"))]
8785  "ix86_match_ccmode (insn, CCNOmode)
8786   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8787  "or{w}\t{%2, %0|%0, %2}"
8788  [(set_attr "type" "alu")
8789   (set_attr "mode" "HI")])
8790
8791(define_expand "iorqi3"
8792  [(set (match_operand:QI 0 "nonimmediate_operand" "")
8793	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8794		(match_operand:QI 2 "general_operand" "")))
8795   (clobber (reg:CC FLAGS_REG))]
8796  "TARGET_QIMODE_MATH"
8797  "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8798
8799;; %%% Potential partial reg stall on alternative 2.  What to do?
8800(define_insn "*iorqi_1"
8801  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8802	(ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8803		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8804   (clobber (reg:CC FLAGS_REG))]
8805  "ix86_binary_operator_ok (IOR, QImode, operands)"
8806  "@
8807   or{b}\t{%2, %0|%0, %2}
8808   or{b}\t{%2, %0|%0, %2}
8809   or{l}\t{%k2, %k0|%k0, %k2}"
8810  [(set_attr "type" "alu")
8811   (set_attr "mode" "QI,QI,SI")])
8812
8813(define_insn "*iorqi_1_slp"
8814  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8815	(ior:QI (match_dup 0)
8816		(match_operand:QI 1 "general_operand" "qmi,qi")))
8817   (clobber (reg:CC FLAGS_REG))]
8818  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8819   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8820  "or{b}\t{%1, %0|%0, %1}"
8821  [(set_attr "type" "alu1")
8822   (set_attr "mode" "QI")])
8823
8824(define_insn "*iorqi_2"
8825  [(set (reg FLAGS_REG)
8826	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8827			 (match_operand:QI 2 "general_operand" "qim,qi"))
8828		 (const_int 0)))
8829   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8830	(ior:QI (match_dup 1) (match_dup 2)))]
8831  "ix86_match_ccmode (insn, CCNOmode)
8832   && ix86_binary_operator_ok (IOR, QImode, operands)"
8833  "or{b}\t{%2, %0|%0, %2}"
8834  [(set_attr "type" "alu")
8835   (set_attr "mode" "QI")])
8836
8837(define_insn "*iorqi_2_slp"
8838  [(set (reg FLAGS_REG)
8839	(compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8840			 (match_operand:QI 1 "general_operand" "qim,qi"))
8841		 (const_int 0)))
8842   (set (strict_low_part (match_dup 0))
8843	(ior:QI (match_dup 0) (match_dup 1)))]
8844  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8845   && ix86_match_ccmode (insn, CCNOmode)
8846   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8847  "or{b}\t{%1, %0|%0, %1}"
8848  [(set_attr "type" "alu1")
8849   (set_attr "mode" "QI")])
8850
8851(define_insn "*iorqi_3"
8852  [(set (reg FLAGS_REG)
8853	(compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8854			 (match_operand:QI 2 "general_operand" "qim"))
8855		 (const_int 0)))
8856   (clobber (match_scratch:QI 0 "=q"))]
8857  "ix86_match_ccmode (insn, CCNOmode)
8858   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8859  "or{b}\t{%2, %0|%0, %2}"
8860  [(set_attr "type" "alu")
8861   (set_attr "mode" "QI")])
8862
8863(define_insn "iorqi_ext_0"
8864  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8865			 (const_int 8)
8866			 (const_int 8))
8867	(ior:SI 
8868	  (zero_extract:SI
8869	    (match_operand 1 "ext_register_operand" "0")
8870	    (const_int 8)
8871	    (const_int 8))
8872	  (match_operand 2 "const_int_operand" "n")))
8873   (clobber (reg:CC FLAGS_REG))]
8874  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8875  "or{b}\t{%2, %h0|%h0, %2}"
8876  [(set_attr "type" "alu")
8877   (set_attr "length_immediate" "1")
8878   (set_attr "mode" "QI")])
8879
8880(define_insn "*iorqi_ext_1"
8881  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8882			 (const_int 8)
8883			 (const_int 8))
8884	(ior:SI 
8885	  (zero_extract:SI
8886	    (match_operand 1 "ext_register_operand" "0")
8887	    (const_int 8)
8888	    (const_int 8))
8889	  (zero_extend:SI
8890	    (match_operand:QI 2 "general_operand" "Qm"))))
8891   (clobber (reg:CC FLAGS_REG))]
8892  "!TARGET_64BIT
8893   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8894  "or{b}\t{%2, %h0|%h0, %2}"
8895  [(set_attr "type" "alu")
8896   (set_attr "length_immediate" "0")
8897   (set_attr "mode" "QI")])
8898
8899(define_insn "*iorqi_ext_1_rex64"
8900  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8901			 (const_int 8)
8902			 (const_int 8))
8903	(ior:SI 
8904	  (zero_extract:SI
8905	    (match_operand 1 "ext_register_operand" "0")
8906	    (const_int 8)
8907	    (const_int 8))
8908	  (zero_extend:SI
8909	    (match_operand 2 "ext_register_operand" "Q"))))
8910   (clobber (reg:CC FLAGS_REG))]
8911  "TARGET_64BIT
8912   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8913  "or{b}\t{%2, %h0|%h0, %2}"
8914  [(set_attr "type" "alu")
8915   (set_attr "length_immediate" "0")
8916   (set_attr "mode" "QI")])
8917
8918(define_insn "*iorqi_ext_2"
8919  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8920			 (const_int 8)
8921			 (const_int 8))
8922	(ior:SI 
8923	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8924	  		   (const_int 8)
8925			   (const_int 8))
8926	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8927	  		   (const_int 8)
8928			   (const_int 8))))
8929   (clobber (reg:CC FLAGS_REG))]
8930  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8931  "ior{b}\t{%h2, %h0|%h0, %h2}"
8932  [(set_attr "type" "alu")
8933   (set_attr "length_immediate" "0")
8934   (set_attr "mode" "QI")])
8935
8936(define_split
8937  [(set (match_operand 0 "register_operand" "")
8938	(ior (match_operand 1 "register_operand" "")
8939	     (match_operand 2 "const_int_operand" "")))
8940   (clobber (reg:CC FLAGS_REG))]
8941   "reload_completed
8942    && QI_REG_P (operands[0])
8943    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8944    && !(INTVAL (operands[2]) & ~(255 << 8))
8945    && GET_MODE (operands[0]) != QImode"
8946  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8947		   (ior:SI (zero_extract:SI (match_dup 1)
8948					    (const_int 8) (const_int 8))
8949			   (match_dup 2)))
8950	      (clobber (reg:CC FLAGS_REG))])]
8951  "operands[0] = gen_lowpart (SImode, operands[0]);
8952   operands[1] = gen_lowpart (SImode, operands[1]);
8953   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8954
8955;; Since OR can be encoded with sign extended immediate, this is only
8956;; profitable when 7th bit is set.
8957(define_split
8958  [(set (match_operand 0 "register_operand" "")
8959	(ior (match_operand 1 "general_operand" "")
8960	     (match_operand 2 "const_int_operand" "")))
8961   (clobber (reg:CC FLAGS_REG))]
8962   "reload_completed
8963    && ANY_QI_REG_P (operands[0])
8964    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8965    && !(INTVAL (operands[2]) & ~255)
8966    && (INTVAL (operands[2]) & 128)
8967    && GET_MODE (operands[0]) != QImode"
8968  [(parallel [(set (strict_low_part (match_dup 0))
8969		   (ior:QI (match_dup 1)
8970			   (match_dup 2)))
8971	      (clobber (reg:CC FLAGS_REG))])]
8972  "operands[0] = gen_lowpart (QImode, operands[0]);
8973   operands[1] = gen_lowpart (QImode, operands[1]);
8974   operands[2] = gen_lowpart (QImode, operands[2]);")
8975
8976;; Logical XOR instructions
8977
8978;; %%% This used to optimize known byte-wide and operations to memory.
8979;; If this is considered useful, it should be done with splitters.
8980
8981(define_expand "xordi3"
8982  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8983	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8984		(match_operand:DI 2 "x86_64_general_operand" "")))
8985   (clobber (reg:CC FLAGS_REG))]
8986  "TARGET_64BIT"
8987  "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8988
8989(define_insn "*xordi_1_rex64"
8990  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8991	(xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8992		(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8993   (clobber (reg:CC FLAGS_REG))]
8994  "TARGET_64BIT
8995   && ix86_binary_operator_ok (XOR, DImode, operands)"
8996  "@
8997   xor{q}\t{%2, %0|%0, %2}
8998   xor{q}\t{%2, %0|%0, %2}"
8999  [(set_attr "type" "alu")
9000   (set_attr "mode" "DI,DI")])
9001
9002(define_insn "*xordi_2_rex64"
9003  [(set (reg FLAGS_REG)
9004	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9005			 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9006		 (const_int 0)))
9007   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9008	(xor:DI (match_dup 1) (match_dup 2)))]
9009  "TARGET_64BIT
9010   && ix86_match_ccmode (insn, CCNOmode)
9011   && ix86_binary_operator_ok (XOR, DImode, operands)"
9012  "@
9013   xor{q}\t{%2, %0|%0, %2}
9014   xor{q}\t{%2, %0|%0, %2}"
9015  [(set_attr "type" "alu")
9016   (set_attr "mode" "DI,DI")])
9017
9018(define_insn "*xordi_3_rex64"
9019  [(set (reg FLAGS_REG)
9020	(compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9021			 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9022		 (const_int 0)))
9023   (clobber (match_scratch:DI 0 "=r"))]
9024  "TARGET_64BIT
9025   && ix86_match_ccmode (insn, CCNOmode)
9026   && ix86_binary_operator_ok (XOR, DImode, operands)"
9027  "xor{q}\t{%2, %0|%0, %2}"
9028  [(set_attr "type" "alu")
9029   (set_attr "mode" "DI")])
9030
9031(define_expand "xorsi3"
9032  [(set (match_operand:SI 0 "nonimmediate_operand" "")
9033	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9034		(match_operand:SI 2 "general_operand" "")))
9035   (clobber (reg:CC FLAGS_REG))]
9036  ""
9037  "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9038
9039(define_insn "*xorsi_1"
9040  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9041	(xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042		(match_operand:SI 2 "general_operand" "ri,rm")))
9043   (clobber (reg:CC FLAGS_REG))]
9044  "ix86_binary_operator_ok (XOR, SImode, operands)"
9045  "xor{l}\t{%2, %0|%0, %2}"
9046  [(set_attr "type" "alu")
9047   (set_attr "mode" "SI")])
9048
9049;; See comment for addsi_1_zext why we do use nonimmediate_operand
9050;; Add speccase for immediates
9051(define_insn "*xorsi_1_zext"
9052  [(set (match_operand:DI 0 "register_operand" "=r")
9053	(zero_extend:DI
9054	  (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9055		  (match_operand:SI 2 "general_operand" "rim"))))
9056   (clobber (reg:CC FLAGS_REG))]
9057  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9058  "xor{l}\t{%2, %k0|%k0, %2}"
9059  [(set_attr "type" "alu")
9060   (set_attr "mode" "SI")])
9061
9062(define_insn "*xorsi_1_zext_imm"
9063  [(set (match_operand:DI 0 "register_operand" "=r")
9064	(xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9065		(match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9066   (clobber (reg:CC FLAGS_REG))]
9067  "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9068  "xor{l}\t{%2, %k0|%k0, %2}"
9069  [(set_attr "type" "alu")
9070   (set_attr "mode" "SI")])
9071
9072(define_insn "*xorsi_2"
9073  [(set (reg FLAGS_REG)
9074	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9075			 (match_operand:SI 2 "general_operand" "rim,ri"))
9076		 (const_int 0)))
9077   (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9078	(xor:SI (match_dup 1) (match_dup 2)))]
9079  "ix86_match_ccmode (insn, CCNOmode)
9080   && ix86_binary_operator_ok (XOR, SImode, operands)"
9081  "xor{l}\t{%2, %0|%0, %2}"
9082  [(set_attr "type" "alu")
9083   (set_attr "mode" "SI")])
9084
9085;; See comment for addsi_1_zext why we do use nonimmediate_operand
9086;; ??? Special case for immediate operand is missing - it is tricky.
9087(define_insn "*xorsi_2_zext"
9088  [(set (reg FLAGS_REG)
9089	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9090			 (match_operand:SI 2 "general_operand" "rim"))
9091		 (const_int 0)))
9092   (set (match_operand:DI 0 "register_operand" "=r")
9093	(zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9094  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9095   && ix86_binary_operator_ok (XOR, SImode, operands)"
9096  "xor{l}\t{%2, %k0|%k0, %2}"
9097  [(set_attr "type" "alu")
9098   (set_attr "mode" "SI")])
9099
9100(define_insn "*xorsi_2_zext_imm"
9101  [(set (reg FLAGS_REG)
9102	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9103			 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9104		 (const_int 0)))
9105   (set (match_operand:DI 0 "register_operand" "=r")
9106	(xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9107  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9108   && ix86_binary_operator_ok (XOR, SImode, operands)"
9109  "xor{l}\t{%2, %k0|%k0, %2}"
9110  [(set_attr "type" "alu")
9111   (set_attr "mode" "SI")])
9112
9113(define_insn "*xorsi_3"
9114  [(set (reg FLAGS_REG)
9115	(compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9116			 (match_operand:SI 2 "general_operand" "rim"))
9117		 (const_int 0)))
9118   (clobber (match_scratch:SI 0 "=r"))]
9119  "ix86_match_ccmode (insn, CCNOmode)
9120   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9121  "xor{l}\t{%2, %0|%0, %2}"
9122  [(set_attr "type" "alu")
9123   (set_attr "mode" "SI")])
9124
9125(define_expand "xorhi3"
9126  [(set (match_operand:HI 0 "nonimmediate_operand" "")
9127	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9128		(match_operand:HI 2 "general_operand" "")))
9129   (clobber (reg:CC FLAGS_REG))]
9130  "TARGET_HIMODE_MATH"
9131  "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9132
9133(define_insn "*xorhi_1"
9134  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9135	(xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9136		(match_operand:HI 2 "general_operand" "rmi,ri")))
9137   (clobber (reg:CC FLAGS_REG))]
9138  "ix86_binary_operator_ok (XOR, HImode, operands)"
9139  "xor{w}\t{%2, %0|%0, %2}"
9140  [(set_attr "type" "alu")
9141   (set_attr "mode" "HI")])
9142
9143(define_insn "*xorhi_2"
9144  [(set (reg FLAGS_REG)
9145	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9146			 (match_operand:HI 2 "general_operand" "rim,ri"))
9147		 (const_int 0)))
9148   (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9149	(xor:HI (match_dup 1) (match_dup 2)))]
9150  "ix86_match_ccmode (insn, CCNOmode)
9151   && ix86_binary_operator_ok (XOR, HImode, operands)"
9152  "xor{w}\t{%2, %0|%0, %2}"
9153  [(set_attr "type" "alu")
9154   (set_attr "mode" "HI")])
9155
9156(define_insn "*xorhi_3"
9157  [(set (reg FLAGS_REG)
9158	(compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9159			 (match_operand:HI 2 "general_operand" "rim"))
9160		 (const_int 0)))
9161   (clobber (match_scratch:HI 0 "=r"))]
9162  "ix86_match_ccmode (insn, CCNOmode)
9163   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9164  "xor{w}\t{%2, %0|%0, %2}"
9165  [(set_attr "type" "alu")
9166   (set_attr "mode" "HI")])
9167
9168(define_expand "xorqi3"
9169  [(set (match_operand:QI 0 "nonimmediate_operand" "")
9170	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9171		(match_operand:QI 2 "general_operand" "")))
9172   (clobber (reg:CC FLAGS_REG))]
9173  "TARGET_QIMODE_MATH"
9174  "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9175
9176;; %%% Potential partial reg stall on alternative 2.  What to do?
9177(define_insn "*xorqi_1"
9178  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9179	(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9180		(match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9181   (clobber (reg:CC FLAGS_REG))]
9182  "ix86_binary_operator_ok (XOR, QImode, operands)"
9183  "@
9184   xor{b}\t{%2, %0|%0, %2}
9185   xor{b}\t{%2, %0|%0, %2}
9186   xor{l}\t{%k2, %k0|%k0, %k2}"
9187  [(set_attr "type" "alu")
9188   (set_attr "mode" "QI,QI,SI")])
9189
9190(define_insn "*xorqi_1_slp"
9191  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9192	(xor:QI (match_dup 0)
9193		(match_operand:QI 1 "general_operand" "qi,qmi")))
9194   (clobber (reg:CC FLAGS_REG))]
9195  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9196   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9197  "xor{b}\t{%1, %0|%0, %1}"
9198  [(set_attr "type" "alu1")
9199   (set_attr "mode" "QI")])
9200
9201(define_insn "xorqi_ext_0"
9202  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9203			 (const_int 8)
9204			 (const_int 8))
9205	(xor:SI 
9206	  (zero_extract:SI
9207	    (match_operand 1 "ext_register_operand" "0")
9208	    (const_int 8)
9209	    (const_int 8))
9210	  (match_operand 2 "const_int_operand" "n")))
9211   (clobber (reg:CC FLAGS_REG))]
9212  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9213  "xor{b}\t{%2, %h0|%h0, %2}"
9214  [(set_attr "type" "alu")
9215   (set_attr "length_immediate" "1")
9216   (set_attr "mode" "QI")])
9217
9218(define_insn "*xorqi_ext_1"
9219  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9220			 (const_int 8)
9221			 (const_int 8))
9222	(xor:SI 
9223	  (zero_extract:SI
9224	    (match_operand 1 "ext_register_operand" "0")
9225	    (const_int 8)
9226	    (const_int 8))
9227	  (zero_extend:SI
9228	    (match_operand:QI 2 "general_operand" "Qm"))))
9229   (clobber (reg:CC FLAGS_REG))]
9230  "!TARGET_64BIT
9231   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9232  "xor{b}\t{%2, %h0|%h0, %2}"
9233  [(set_attr "type" "alu")
9234   (set_attr "length_immediate" "0")
9235   (set_attr "mode" "QI")])
9236
9237(define_insn "*xorqi_ext_1_rex64"
9238  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9239			 (const_int 8)
9240			 (const_int 8))
9241	(xor:SI 
9242	  (zero_extract:SI
9243	    (match_operand 1 "ext_register_operand" "0")
9244	    (const_int 8)
9245	    (const_int 8))
9246	  (zero_extend:SI
9247	    (match_operand 2 "ext_register_operand" "Q"))))
9248   (clobber (reg:CC FLAGS_REG))]
9249  "TARGET_64BIT
9250   && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9251  "xor{b}\t{%2, %h0|%h0, %2}"
9252  [(set_attr "type" "alu")
9253   (set_attr "length_immediate" "0")
9254   (set_attr "mode" "QI")])
9255
9256(define_insn "*xorqi_ext_2"
9257  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9258			 (const_int 8)
9259			 (const_int 8))
9260	(xor:SI 
9261	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9262	  		   (const_int 8)
9263			   (const_int 8))
9264	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9265	  		   (const_int 8)
9266			   (const_int 8))))
9267   (clobber (reg:CC FLAGS_REG))]
9268  "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9269  "xor{b}\t{%h2, %h0|%h0, %h2}"
9270  [(set_attr "type" "alu")
9271   (set_attr "length_immediate" "0")
9272   (set_attr "mode" "QI")])
9273
9274(define_insn "*xorqi_cc_1"
9275  [(set (reg FLAGS_REG)
9276	(compare
9277	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9278		  (match_operand:QI 2 "general_operand" "qim,qi"))
9279	  (const_int 0)))
9280   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9281	(xor:QI (match_dup 1) (match_dup 2)))]
9282  "ix86_match_ccmode (insn, CCNOmode)
9283   && ix86_binary_operator_ok (XOR, QImode, operands)"
9284  "xor{b}\t{%2, %0|%0, %2}"
9285  [(set_attr "type" "alu")
9286   (set_attr "mode" "QI")])
9287
9288(define_insn "*xorqi_2_slp"
9289  [(set (reg FLAGS_REG)
9290	(compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9291			 (match_operand:QI 1 "general_operand" "qim,qi"))
9292		 (const_int 0)))
9293   (set (strict_low_part (match_dup 0))
9294	(xor:QI (match_dup 0) (match_dup 1)))]
9295  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9296   && ix86_match_ccmode (insn, CCNOmode)
9297   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9298  "xor{b}\t{%1, %0|%0, %1}"
9299  [(set_attr "type" "alu1")
9300   (set_attr "mode" "QI")])
9301
9302(define_insn "*xorqi_cc_2"
9303  [(set (reg FLAGS_REG)
9304	(compare
9305	  (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9306		  (match_operand:QI 2 "general_operand" "qim"))
9307	  (const_int 0)))
9308   (clobber (match_scratch:QI 0 "=q"))]
9309  "ix86_match_ccmode (insn, CCNOmode)
9310   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9311  "xor{b}\t{%2, %0|%0, %2}"
9312  [(set_attr "type" "alu")
9313   (set_attr "mode" "QI")])
9314
9315(define_insn "*xorqi_cc_ext_1"
9316  [(set (reg FLAGS_REG)
9317	(compare
9318	  (xor:SI
9319	    (zero_extract:SI
9320	      (match_operand 1 "ext_register_operand" "0")
9321	      (const_int 8)
9322	      (const_int 8))
9323	    (match_operand:QI 2 "general_operand" "qmn"))
9324	  (const_int 0)))
9325   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9326			 (const_int 8)
9327			 (const_int 8))
9328	(xor:SI 
9329	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9330	  (match_dup 2)))]
9331  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9332  "xor{b}\t{%2, %h0|%h0, %2}"
9333  [(set_attr "type" "alu")
9334   (set_attr "mode" "QI")])
9335
9336(define_insn "*xorqi_cc_ext_1_rex64"
9337  [(set (reg FLAGS_REG)
9338	(compare
9339	  (xor:SI
9340	    (zero_extract:SI
9341	      (match_operand 1 "ext_register_operand" "0")
9342	      (const_int 8)
9343	      (const_int 8))
9344	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
9345	  (const_int 0)))
9346   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9347			 (const_int 8)
9348			 (const_int 8))
9349	(xor:SI 
9350	  (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9351	  (match_dup 2)))]
9352  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9353  "xor{b}\t{%2, %h0|%h0, %2}"
9354  [(set_attr "type" "alu")
9355   (set_attr "mode" "QI")])
9356
9357(define_expand "xorqi_cc_ext_1"
9358  [(parallel [
9359     (set (reg:CCNO FLAGS_REG)
9360	  (compare:CCNO
9361	    (xor:SI
9362	      (zero_extract:SI
9363		(match_operand 1 "ext_register_operand" "")
9364		(const_int 8)
9365		(const_int 8))
9366	      (match_operand:QI 2 "general_operand" ""))
9367	    (const_int 0)))
9368     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9369			   (const_int 8)
9370			   (const_int 8))
9371	  (xor:SI 
9372	    (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9373	    (match_dup 2)))])]
9374  ""
9375  "")
9376
9377(define_split
9378  [(set (match_operand 0 "register_operand" "")
9379	(xor (match_operand 1 "register_operand" "")
9380	     (match_operand 2 "const_int_operand" "")))
9381   (clobber (reg:CC FLAGS_REG))]
9382   "reload_completed
9383    && QI_REG_P (operands[0])
9384    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9385    && !(INTVAL (operands[2]) & ~(255 << 8))
9386    && GET_MODE (operands[0]) != QImode"
9387  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9388		   (xor:SI (zero_extract:SI (match_dup 1)
9389					    (const_int 8) (const_int 8))
9390			   (match_dup 2)))
9391	      (clobber (reg:CC FLAGS_REG))])]
9392  "operands[0] = gen_lowpart (SImode, operands[0]);
9393   operands[1] = gen_lowpart (SImode, operands[1]);
9394   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9395
9396;; Since XOR can be encoded with sign extended immediate, this is only
9397;; profitable when 7th bit is set.
9398(define_split
9399  [(set (match_operand 0 "register_operand" "")
9400	(xor (match_operand 1 "general_operand" "")
9401	     (match_operand 2 "const_int_operand" "")))
9402   (clobber (reg:CC FLAGS_REG))]
9403   "reload_completed
9404    && ANY_QI_REG_P (operands[0])
9405    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9406    && !(INTVAL (operands[2]) & ~255)
9407    && (INTVAL (operands[2]) & 128)
9408    && GET_MODE (operands[0]) != QImode"
9409  [(parallel [(set (strict_low_part (match_dup 0))
9410		   (xor:QI (match_dup 1)
9411			   (match_dup 2)))
9412	      (clobber (reg:CC FLAGS_REG))])]
9413  "operands[0] = gen_lowpart (QImode, operands[0]);
9414   operands[1] = gen_lowpart (QImode, operands[1]);
9415   operands[2] = gen_lowpart (QImode, operands[2]);")
9416
9417;; Negation instructions
9418
9419(define_expand "negti2"
9420  [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9421		   (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9422	      (clobber (reg:CC FLAGS_REG))])]
9423  "TARGET_64BIT"
9424  "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9425
9426(define_insn "*negti2_1"
9427  [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9428	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9429   (clobber (reg:CC FLAGS_REG))]
9430  "TARGET_64BIT
9431   && ix86_unary_operator_ok (NEG, TImode, operands)"
9432  "#")
9433
9434(define_split
9435  [(set (match_operand:TI 0 "nonimmediate_operand" "")
9436	(neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9437   (clobber (reg:CC FLAGS_REG))]
9438  "TARGET_64BIT && reload_completed"
9439  [(parallel
9440    [(set (reg:CCZ FLAGS_REG)
9441	  (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9442     (set (match_dup 0) (neg:DI (match_dup 2)))])
9443   (parallel
9444    [(set (match_dup 1)
9445	  (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9446			    (match_dup 3))
9447		   (const_int 0)))
9448     (clobber (reg:CC FLAGS_REG))])
9449   (parallel
9450    [(set (match_dup 1)
9451	  (neg:DI (match_dup 1)))
9452     (clobber (reg:CC FLAGS_REG))])]
9453  "split_ti (operands+1, 1, operands+2, operands+3);
9454   split_ti (operands+0, 1, operands+0, operands+1);")
9455
9456(define_expand "negdi2"
9457  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9458		   (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9459	      (clobber (reg:CC FLAGS_REG))])]
9460  ""
9461  "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9462
9463(define_insn "*negdi2_1"
9464  [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9465	(neg:DI (match_operand:DI 1 "general_operand" "0")))
9466   (clobber (reg:CC FLAGS_REG))]
9467  "!TARGET_64BIT
9468   && ix86_unary_operator_ok (NEG, DImode, operands)"
9469  "#")
9470
9471(define_split
9472  [(set (match_operand:DI 0 "nonimmediate_operand" "")
9473	(neg:DI (match_operand:DI 1 "general_operand" "")))
9474   (clobber (reg:CC FLAGS_REG))]
9475  "!TARGET_64BIT && reload_completed"
9476  [(parallel
9477    [(set (reg:CCZ FLAGS_REG)
9478	  (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9479     (set (match_dup 0) (neg:SI (match_dup 2)))])
9480   (parallel
9481    [(set (match_dup 1)
9482	  (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9483			    (match_dup 3))
9484		   (const_int 0)))
9485     (clobber (reg:CC FLAGS_REG))])
9486   (parallel
9487    [(set (match_dup 1)
9488	  (neg:SI (match_dup 1)))
9489     (clobber (reg:CC FLAGS_REG))])]
9490  "split_di (operands+1, 1, operands+2, operands+3);
9491   split_di (operands+0, 1, operands+0, operands+1);")
9492
9493(define_insn "*negdi2_1_rex64"
9494  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9495	(neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9496   (clobber (reg:CC FLAGS_REG))]
9497  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9498  "neg{q}\t%0"
9499  [(set_attr "type" "negnot")
9500   (set_attr "mode" "DI")])
9501
9502;; The problem with neg is that it does not perform (compare x 0),
9503;; it really performs (compare 0 x), which leaves us with the zero
9504;; flag being the only useful item.
9505
9506(define_insn "*negdi2_cmpz_rex64"
9507  [(set (reg:CCZ FLAGS_REG)
9508	(compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9509		     (const_int 0)))
9510   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9511	(neg:DI (match_dup 1)))]
9512  "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9513  "neg{q}\t%0"
9514  [(set_attr "type" "negnot")
9515   (set_attr "mode" "DI")])
9516
9517
9518(define_expand "negsi2"
9519  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9520		   (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9521	      (clobber (reg:CC FLAGS_REG))])]
9522  ""
9523  "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9524
9525(define_insn "*negsi2_1"
9526  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9527	(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9528   (clobber (reg:CC FLAGS_REG))]
9529  "ix86_unary_operator_ok (NEG, SImode, operands)"
9530  "neg{l}\t%0"
9531  [(set_attr "type" "negnot")
9532   (set_attr "mode" "SI")])
9533
9534;; Combine is quite creative about this pattern.
9535(define_insn "*negsi2_1_zext"
9536  [(set (match_operand:DI 0 "register_operand" "=r")
9537	(lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9538					(const_int 32)))
9539		     (const_int 32)))
9540   (clobber (reg:CC FLAGS_REG))]
9541  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9542  "neg{l}\t%k0"
9543  [(set_attr "type" "negnot")
9544   (set_attr "mode" "SI")])
9545
9546;; The problem with neg is that it does not perform (compare x 0),
9547;; it really performs (compare 0 x), which leaves us with the zero
9548;; flag being the only useful item.
9549
9550(define_insn "*negsi2_cmpz"
9551  [(set (reg:CCZ FLAGS_REG)
9552	(compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9553		     (const_int 0)))
9554   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9555	(neg:SI (match_dup 1)))]
9556  "ix86_unary_operator_ok (NEG, SImode, operands)"
9557  "neg{l}\t%0"
9558  [(set_attr "type" "negnot")
9559   (set_attr "mode" "SI")])
9560
9561(define_insn "*negsi2_cmpz_zext"
9562  [(set (reg:CCZ FLAGS_REG)
9563	(compare:CCZ (lshiftrt:DI
9564		       (neg:DI (ashift:DI
9565				 (match_operand:DI 1 "register_operand" "0")
9566				 (const_int 32)))
9567		       (const_int 32))
9568		     (const_int 0)))
9569   (set (match_operand:DI 0 "register_operand" "=r")
9570	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9571					(const_int 32)))
9572		     (const_int 32)))]
9573  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9574  "neg{l}\t%k0"
9575  [(set_attr "type" "negnot")
9576   (set_attr "mode" "SI")])
9577
9578(define_expand "neghi2"
9579  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9580		   (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9581	      (clobber (reg:CC FLAGS_REG))])]
9582  "TARGET_HIMODE_MATH"
9583  "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9584
9585(define_insn "*neghi2_1"
9586  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9587	(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9588   (clobber (reg:CC FLAGS_REG))]
9589  "ix86_unary_operator_ok (NEG, HImode, operands)"
9590  "neg{w}\t%0"
9591  [(set_attr "type" "negnot")
9592   (set_attr "mode" "HI")])
9593
9594(define_insn "*neghi2_cmpz"
9595  [(set (reg:CCZ FLAGS_REG)
9596	(compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9597		     (const_int 0)))
9598   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9599	(neg:HI (match_dup 1)))]
9600  "ix86_unary_operator_ok (NEG, HImode, operands)"
9601  "neg{w}\t%0"
9602  [(set_attr "type" "negnot")
9603   (set_attr "mode" "HI")])
9604
9605(define_expand "negqi2"
9606  [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9607		   (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9608	      (clobber (reg:CC FLAGS_REG))])]
9609  "TARGET_QIMODE_MATH"
9610  "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9611
9612(define_insn "*negqi2_1"
9613  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9614	(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9615   (clobber (reg:CC FLAGS_REG))]
9616  "ix86_unary_operator_ok (NEG, QImode, operands)"
9617  "neg{b}\t%0"
9618  [(set_attr "type" "negnot")
9619   (set_attr "mode" "QI")])
9620
9621(define_insn "*negqi2_cmpz"
9622  [(set (reg:CCZ FLAGS_REG)
9623	(compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9624		     (const_int 0)))
9625   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9626	(neg:QI (match_dup 1)))]
9627  "ix86_unary_operator_ok (NEG, QImode, operands)"
9628  "neg{b}\t%0"
9629  [(set_attr "type" "negnot")
9630   (set_attr "mode" "QI")])
9631
9632;; Changing of sign for FP values is doable using integer unit too.
9633
9634(define_expand "negsf2"
9635  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9636	(neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9637  "TARGET_80387 || TARGET_SSE_MATH"
9638  "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9639
9640(define_expand "abssf2"
9641  [(set (match_operand:SF 0 "nonimmediate_operand" "")
9642	(abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9643  "TARGET_80387 || TARGET_SSE_MATH"
9644  "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9645
9646(define_insn "*absnegsf2_mixed"
9647  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9648	(match_operator:SF 3 "absneg_operator"
9649	  [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9650   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9651   (clobber (reg:CC FLAGS_REG))]
9652  "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9653   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9654  "#")
9655
9656(define_insn "*absnegsf2_sse"
9657  [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9658	(match_operator:SF 3 "absneg_operator"
9659	  [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9660   (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9661   (clobber (reg:CC FLAGS_REG))]
9662  "TARGET_SSE_MATH
9663   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9664  "#")
9665
9666(define_insn "*absnegsf2_i387"
9667  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9668	(match_operator:SF 3 "absneg_operator"
9669	  [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9670   (use (match_operand 2 "" ""))
9671   (clobber (reg:CC FLAGS_REG))]
9672  "TARGET_80387 && !TARGET_SSE_MATH
9673   && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9674  "#")
9675
9676(define_expand "copysignsf3"
9677  [(match_operand:SF 0 "register_operand" "")
9678   (match_operand:SF 1 "nonmemory_operand" "")
9679   (match_operand:SF 2 "register_operand" "")]
9680  "TARGET_SSE_MATH"
9681{
9682  ix86_expand_copysign (operands);
9683  DONE;
9684})
9685
9686(define_insn_and_split "copysignsf3_const"
9687  [(set (match_operand:SF 0 "register_operand"          "=x")
9688	(unspec:SF
9689	  [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9690	   (match_operand:SF 2 "register_operand"       "0")
9691	   (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9692	  UNSPEC_COPYSIGN))]
9693  "TARGET_SSE_MATH"
9694  "#"
9695  "&& reload_completed"
9696  [(const_int 0)]
9697{
9698  ix86_split_copysign_const (operands);
9699  DONE;
9700})
9701
9702(define_insn "copysignsf3_var"
9703  [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9704	(unspec:SF
9705	  [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9706	   (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9707	   (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9708	   (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9709	  UNSPEC_COPYSIGN))
9710   (clobber (match_scratch:V4SF 1			"=x, x, x, x,x"))]
9711  "TARGET_SSE_MATH"
9712  "#")
9713
9714(define_split
9715  [(set (match_operand:SF 0 "register_operand" "")
9716	(unspec:SF
9717	  [(match_operand:SF 2 "register_operand" "")
9718	   (match_operand:SF 3 "register_operand" "")
9719	   (match_operand:V4SF 4 "" "")
9720	   (match_operand:V4SF 5 "" "")]
9721	  UNSPEC_COPYSIGN))
9722   (clobber (match_scratch:V4SF 1 ""))]
9723  "TARGET_SSE_MATH && reload_completed"
9724  [(const_int 0)]
9725{
9726  ix86_split_copysign_var (operands);
9727  DONE;
9728})
9729
9730(define_expand "negdf2"
9731  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9732	(neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9733  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9734  "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9735
9736(define_expand "absdf2"
9737  [(set (match_operand:DF 0 "nonimmediate_operand" "")
9738	(abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9739  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9740  "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9741
9742(define_insn "*absnegdf2_mixed"
9743  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9744	(match_operator:DF 3 "absneg_operator"
9745	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9746   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9747   (clobber (reg:CC FLAGS_REG))]
9748  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9749   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9750  "#")
9751
9752(define_insn "*absnegdf2_sse"
9753  [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9754	(match_operator:DF 3 "absneg_operator"
9755	  [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9756   (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9757   (clobber (reg:CC FLAGS_REG))]
9758  "TARGET_SSE2 && TARGET_SSE_MATH
9759   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9760  "#")
9761
9762(define_insn "*absnegdf2_i387"
9763  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9764	(match_operator:DF 3 "absneg_operator"
9765	  [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9766   (use (match_operand 2 "" ""))
9767   (clobber (reg:CC FLAGS_REG))]
9768  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9769   && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9770  "#")
9771
9772(define_expand "copysigndf3"
9773  [(match_operand:DF 0 "register_operand" "")
9774   (match_operand:DF 1 "nonmemory_operand" "")
9775   (match_operand:DF 2 "register_operand" "")]
9776  "TARGET_SSE2 && TARGET_SSE_MATH"
9777{
9778  ix86_expand_copysign (operands);
9779  DONE;
9780})
9781
9782(define_insn_and_split "copysigndf3_const"
9783  [(set (match_operand:DF 0 "register_operand"          "=x")
9784	(unspec:DF
9785	  [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9786	   (match_operand:DF 2 "register_operand"       "0")
9787	   (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9788	  UNSPEC_COPYSIGN))]
9789  "TARGET_SSE2 && TARGET_SSE_MATH"
9790  "#"
9791  "&& reload_completed"
9792  [(const_int 0)]
9793{
9794  ix86_split_copysign_const (operands);
9795  DONE;
9796})
9797
9798(define_insn "copysigndf3_var"
9799  [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9800	(unspec:DF
9801	  [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9802	   (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9803	   (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9804	   (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9805	  UNSPEC_COPYSIGN))
9806   (clobber (match_scratch:V2DF 1			"=x, x, x, x,x"))]
9807  "TARGET_SSE2 && TARGET_SSE_MATH"
9808  "#")
9809
9810(define_split
9811  [(set (match_operand:DF 0 "register_operand" "")
9812	(unspec:DF
9813	  [(match_operand:DF 2 "register_operand" "")
9814	   (match_operand:DF 3 "register_operand" "")
9815	   (match_operand:V2DF 4 "" "")
9816	   (match_operand:V2DF 5 "" "")]
9817	  UNSPEC_COPYSIGN))
9818   (clobber (match_scratch:V2DF 1 ""))]
9819  "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9820  [(const_int 0)]
9821{
9822  ix86_split_copysign_var (operands);
9823  DONE;
9824})
9825
9826(define_expand "negxf2"
9827  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9828	(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9829  "TARGET_80387"
9830  "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9831
9832(define_expand "absxf2"
9833  [(set (match_operand:XF 0 "nonimmediate_operand" "")
9834	(abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9835  "TARGET_80387"
9836  "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9837
9838(define_insn "*absnegxf2_i387"
9839  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9840	(match_operator:XF 3 "absneg_operator"
9841	  [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9842   (use (match_operand 2 "" ""))
9843   (clobber (reg:CC FLAGS_REG))]
9844  "TARGET_80387
9845   && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9846  "#")
9847
9848;; Splitters for fp abs and neg.
9849
9850(define_split
9851  [(set (match_operand 0 "fp_register_operand" "")
9852	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9853   (use (match_operand 2 "" ""))
9854   (clobber (reg:CC FLAGS_REG))]
9855  "reload_completed"
9856  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9857
9858(define_split
9859  [(set (match_operand 0 "register_operand" "")
9860	(match_operator 3 "absneg_operator"
9861	  [(match_operand 1 "register_operand" "")]))
9862   (use (match_operand 2 "nonimmediate_operand" ""))
9863   (clobber (reg:CC FLAGS_REG))]
9864  "reload_completed && SSE_REG_P (operands[0])"
9865  [(set (match_dup 0) (match_dup 3))]
9866{
9867  enum machine_mode mode = GET_MODE (operands[0]);
9868  enum machine_mode vmode = GET_MODE (operands[2]);
9869  rtx tmp;
9870  
9871  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9872  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9873  if (operands_match_p (operands[0], operands[2]))
9874    {
9875      tmp = operands[1];
9876      operands[1] = operands[2];
9877      operands[2] = tmp;
9878    }
9879  if (GET_CODE (operands[3]) == ABS)
9880    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9881  else
9882    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9883  operands[3] = tmp;
9884})
9885
9886(define_split
9887  [(set (match_operand:SF 0 "register_operand" "")
9888	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9889   (use (match_operand:V4SF 2 "" ""))
9890   (clobber (reg:CC FLAGS_REG))]
9891  "reload_completed"
9892  [(parallel [(set (match_dup 0) (match_dup 1))
9893	      (clobber (reg:CC FLAGS_REG))])]
9894{ 
9895  rtx tmp;
9896  operands[0] = gen_lowpart (SImode, operands[0]);
9897  if (GET_CODE (operands[1]) == ABS)
9898    {
9899      tmp = gen_int_mode (0x7fffffff, SImode);
9900      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9901    }
9902  else
9903    {
9904      tmp = gen_int_mode (0x80000000, SImode);
9905      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9906    }
9907  operands[1] = tmp;
9908})
9909
9910(define_split
9911  [(set (match_operand:DF 0 "register_operand" "")
9912	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9913   (use (match_operand 2 "" ""))
9914   (clobber (reg:CC FLAGS_REG))]
9915  "reload_completed"
9916  [(parallel [(set (match_dup 0) (match_dup 1))
9917	      (clobber (reg:CC FLAGS_REG))])]
9918{
9919  rtx tmp;
9920  if (TARGET_64BIT)
9921    {
9922      tmp = gen_lowpart (DImode, operands[0]);
9923      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9924      operands[0] = tmp;
9925
9926      if (GET_CODE (operands[1]) == ABS)
9927	tmp = const0_rtx;
9928      else
9929	tmp = gen_rtx_NOT (DImode, tmp);
9930    }
9931  else
9932    {
9933      operands[0] = gen_highpart (SImode, operands[0]);
9934      if (GET_CODE (operands[1]) == ABS)
9935	{
9936	  tmp = gen_int_mode (0x7fffffff, SImode);
9937	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
9938	}
9939      else
9940	{
9941	  tmp = gen_int_mode (0x80000000, SImode);
9942	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9943	}
9944    }
9945  operands[1] = tmp;
9946})
9947
9948(define_split
9949  [(set (match_operand:XF 0 "register_operand" "")
9950	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9951   (use (match_operand 2 "" ""))
9952   (clobber (reg:CC FLAGS_REG))]
9953  "reload_completed"
9954  [(parallel [(set (match_dup 0) (match_dup 1))
9955	      (clobber (reg:CC FLAGS_REG))])]
9956{
9957  rtx tmp;
9958  operands[0] = gen_rtx_REG (SImode,
9959			     true_regnum (operands[0])
9960			     + (TARGET_64BIT ? 1 : 2));
9961  if (GET_CODE (operands[1]) == ABS)
9962    {
9963      tmp = GEN_INT (0x7fff);
9964      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9965    }
9966  else
9967    {
9968      tmp = GEN_INT (0x8000);
9969      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9970    }
9971  operands[1] = tmp;
9972})
9973
9974(define_split
9975  [(set (match_operand 0 "memory_operand" "")
9976	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9977   (use (match_operand 2 "" ""))
9978   (clobber (reg:CC FLAGS_REG))]
9979  "reload_completed"
9980  [(parallel [(set (match_dup 0) (match_dup 1))
9981	      (clobber (reg:CC FLAGS_REG))])]
9982{
9983  enum machine_mode mode = GET_MODE (operands[0]);
9984  int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9985  rtx tmp;
9986
9987  operands[0] = adjust_address (operands[0], QImode, size - 1);
9988  if (GET_CODE (operands[1]) == ABS)
9989    {
9990      tmp = gen_int_mode (0x7f, QImode);
9991      tmp = gen_rtx_AND (QImode, operands[0], tmp);
9992    }
9993  else
9994    {
9995      tmp = gen_int_mode (0x80, QImode);
9996      tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9997    }
9998  operands[1] = tmp;
9999})
10000
10001;; Conditionalize these after reload. If they match before reload, we 
10002;; lose the clobber and ability to use integer instructions.
10003
10004(define_insn "*negsf2_1"
10005  [(set (match_operand:SF 0 "register_operand" "=f")
10006	(neg:SF (match_operand:SF 1 "register_operand" "0")))]
10007  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10008  "fchs"
10009  [(set_attr "type" "fsgn")
10010   (set_attr "mode" "SF")])
10011
10012(define_insn "*negdf2_1"
10013  [(set (match_operand:DF 0 "register_operand" "=f")
10014	(neg:DF (match_operand:DF 1 "register_operand" "0")))]
10015  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10016  "fchs"
10017  [(set_attr "type" "fsgn")
10018   (set_attr "mode" "DF")])
10019
10020(define_insn "*negxf2_1"
10021  [(set (match_operand:XF 0 "register_operand" "=f")
10022	(neg:XF (match_operand:XF 1 "register_operand" "0")))]
10023  "TARGET_80387"
10024  "fchs"
10025  [(set_attr "type" "fsgn")
10026   (set_attr "mode" "XF")])
10027
10028(define_insn "*abssf2_1"
10029  [(set (match_operand:SF 0 "register_operand" "=f")
10030	(abs:SF (match_operand:SF 1 "register_operand" "0")))]
10031  "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10032  "fabs"
10033  [(set_attr "type" "fsgn")
10034   (set_attr "mode" "SF")])
10035
10036(define_insn "*absdf2_1"
10037  [(set (match_operand:DF 0 "register_operand" "=f")
10038	(abs:DF (match_operand:DF 1 "register_operand" "0")))]
10039  "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10040  "fabs"
10041  [(set_attr "type" "fsgn")
10042   (set_attr "mode" "DF")])
10043
10044(define_insn "*absxf2_1"
10045  [(set (match_operand:XF 0 "register_operand" "=f")
10046	(abs:XF (match_operand:XF 1 "register_operand" "0")))]
10047  "TARGET_80387"
10048  "fabs"
10049  [(set_attr "type" "fsgn")
10050   (set_attr "mode" "DF")])
10051
10052(define_insn "*negextendsfdf2"
10053  [(set (match_operand:DF 0 "register_operand" "=f")
10054	(neg:DF (float_extend:DF
10055		  (match_operand:SF 1 "register_operand" "0"))))]
10056  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10057  "fchs"
10058  [(set_attr "type" "fsgn")
10059   (set_attr "mode" "DF")])
10060
10061(define_insn "*negextenddfxf2"
10062  [(set (match_operand:XF 0 "register_operand" "=f")
10063	(neg:XF (float_extend:XF
10064		  (match_operand:DF 1 "register_operand" "0"))))]
10065  "TARGET_80387"
10066  "fchs"
10067  [(set_attr "type" "fsgn")
10068   (set_attr "mode" "XF")])
10069
10070(define_insn "*negextendsfxf2"
10071  [(set (match_operand:XF 0 "register_operand" "=f")
10072	(neg:XF (float_extend:XF
10073		  (match_operand:SF 1 "register_operand" "0"))))]
10074  "TARGET_80387"
10075  "fchs"
10076  [(set_attr "type" "fsgn")
10077   (set_attr "mode" "XF")])
10078
10079(define_insn "*absextendsfdf2"
10080  [(set (match_operand:DF 0 "register_operand" "=f")
10081	(abs:DF (float_extend:DF
10082		  (match_operand:SF 1 "register_operand" "0"))))]
10083  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10084  "fabs"
10085  [(set_attr "type" "fsgn")
10086   (set_attr "mode" "DF")])
10087
10088(define_insn "*absextenddfxf2"
10089  [(set (match_operand:XF 0 "register_operand" "=f")
10090	(abs:XF (float_extend:XF
10091	  (match_operand:DF 1 "register_operand" "0"))))]
10092  "TARGET_80387"
10093  "fabs"
10094  [(set_attr "type" "fsgn")
10095   (set_attr "mode" "XF")])
10096
10097(define_insn "*absextendsfxf2"
10098  [(set (match_operand:XF 0 "register_operand" "=f")
10099	(abs:XF (float_extend:XF
10100	  (match_operand:SF 1 "register_operand" "0"))))]
10101  "TARGET_80387"
10102  "fabs"
10103  [(set_attr "type" "fsgn")
10104   (set_attr "mode" "XF")])
10105
10106;; One complement instructions
10107
10108(define_expand "one_cmpldi2"
10109  [(set (match_operand:DI 0 "nonimmediate_operand" "")
10110	(not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10111  "TARGET_64BIT"
10112  "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10113
10114(define_insn "*one_cmpldi2_1_rex64"
10115  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10116	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10117  "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10118  "not{q}\t%0"
10119  [(set_attr "type" "negnot")
10120   (set_attr "mode" "DI")])
10121
10122(define_insn "*one_cmpldi2_2_rex64"
10123  [(set (reg FLAGS_REG)
10124	(compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10125		 (const_int 0)))
10126   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10127	(not:DI (match_dup 1)))]
10128  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10129   && ix86_unary_operator_ok (NOT, DImode, operands)"
10130  "#"
10131  [(set_attr "type" "alu1")
10132   (set_attr "mode" "DI")])
10133
10134(define_split
10135  [(set (match_operand 0 "flags_reg_operand" "")
10136	(match_operator 2 "compare_operator"
10137	  [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10138	   (const_int 0)]))
10139   (set (match_operand:DI 1 "nonimmediate_operand" "")
10140	(not:DI (match_dup 3)))]
10141  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10142  [(parallel [(set (match_dup 0)
10143		   (match_op_dup 2
10144		     [(xor:DI (match_dup 3) (const_int -1))
10145		      (const_int 0)]))
10146	      (set (match_dup 1)
10147		   (xor:DI (match_dup 3) (const_int -1)))])]
10148  "")
10149
10150(define_expand "one_cmplsi2"
10151  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10152	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10153  ""
10154  "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10155
10156(define_insn "*one_cmplsi2_1"
10157  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10158	(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10159  "ix86_unary_operator_ok (NOT, SImode, operands)"
10160  "not{l}\t%0"
10161  [(set_attr "type" "negnot")
10162   (set_attr "mode" "SI")])
10163
10164;; ??? Currently never generated - xor is used instead.
10165(define_insn "*one_cmplsi2_1_zext"
10166  [(set (match_operand:DI 0 "register_operand" "=r")
10167	(zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10168  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10169  "not{l}\t%k0"
10170  [(set_attr "type" "negnot")
10171   (set_attr "mode" "SI")])
10172
10173(define_insn "*one_cmplsi2_2"
10174  [(set (reg FLAGS_REG)
10175	(compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10176		 (const_int 0)))
10177   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10178	(not:SI (match_dup 1)))]
10179  "ix86_match_ccmode (insn, CCNOmode)
10180   && ix86_unary_operator_ok (NOT, SImode, operands)"
10181  "#"
10182  [(set_attr "type" "alu1")
10183   (set_attr "mode" "SI")])
10184
10185(define_split
10186  [(set (match_operand 0 "flags_reg_operand" "")
10187	(match_operator 2 "compare_operator"
10188	  [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10189	   (const_int 0)]))
10190   (set (match_operand:SI 1 "nonimmediate_operand" "")
10191	(not:SI (match_dup 3)))]
10192  "ix86_match_ccmode (insn, CCNOmode)"
10193  [(parallel [(set (match_dup 0)
10194		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10195				    (const_int 0)]))
10196	      (set (match_dup 1)
10197		   (xor:SI (match_dup 3) (const_int -1)))])]
10198  "")
10199
10200;; ??? Currently never generated - xor is used instead.
10201(define_insn "*one_cmplsi2_2_zext"
10202  [(set (reg FLAGS_REG)
10203	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10204		 (const_int 0)))
10205   (set (match_operand:DI 0 "register_operand" "=r")
10206	(zero_extend:DI (not:SI (match_dup 1))))]
10207  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10208   && ix86_unary_operator_ok (NOT, SImode, operands)"
10209  "#"
10210  [(set_attr "type" "alu1")
10211   (set_attr "mode" "SI")])
10212
10213(define_split
10214  [(set (match_operand 0 "flags_reg_operand" "")
10215	(match_operator 2 "compare_operator"
10216	  [(not:SI (match_operand:SI 3 "register_operand" ""))
10217	   (const_int 0)]))
10218   (set (match_operand:DI 1 "register_operand" "")
10219	(zero_extend:DI (not:SI (match_dup 3))))]
10220  "ix86_match_ccmode (insn, CCNOmode)"
10221  [(parallel [(set (match_dup 0)
10222		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10223				    (const_int 0)]))
10224	      (set (match_dup 1)
10225		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10226  "")
10227
10228(define_expand "one_cmplhi2"
10229  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10230	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10231  "TARGET_HIMODE_MATH"
10232  "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10233
10234(define_insn "*one_cmplhi2_1"
10235  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10236	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10237  "ix86_unary_operator_ok (NOT, HImode, operands)"
10238  "not{w}\t%0"
10239  [(set_attr "type" "negnot")
10240   (set_attr "mode" "HI")])
10241
10242(define_insn "*one_cmplhi2_2"
10243  [(set (reg FLAGS_REG)
10244	(compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10245		 (const_int 0)))
10246   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10247	(not:HI (match_dup 1)))]
10248  "ix86_match_ccmode (insn, CCNOmode)
10249   && ix86_unary_operator_ok (NEG, HImode, operands)"
10250  "#"
10251  [(set_attr "type" "alu1")
10252   (set_attr "mode" "HI")])
10253
10254(define_split
10255  [(set (match_operand 0 "flags_reg_operand" "")
10256	(match_operator 2 "compare_operator"
10257	  [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10258	   (const_int 0)]))
10259   (set (match_operand:HI 1 "nonimmediate_operand" "")
10260	(not:HI (match_dup 3)))]
10261  "ix86_match_ccmode (insn, CCNOmode)"
10262  [(parallel [(set (match_dup 0)
10263		   (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10264		      		    (const_int 0)]))
10265	      (set (match_dup 1)
10266		   (xor:HI (match_dup 3) (const_int -1)))])]
10267  "")
10268
10269;; %%% Potential partial reg stall on alternative 1.  What to do?
10270(define_expand "one_cmplqi2"
10271  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10272	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10273  "TARGET_QIMODE_MATH"
10274  "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10275
10276(define_insn "*one_cmplqi2_1"
10277  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10278	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10279  "ix86_unary_operator_ok (NOT, QImode, operands)"
10280  "@
10281   not{b}\t%0
10282   not{l}\t%k0"
10283  [(set_attr "type" "negnot")
10284   (set_attr "mode" "QI,SI")])
10285
10286(define_insn "*one_cmplqi2_2"
10287  [(set (reg FLAGS_REG)
10288	(compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10289		 (const_int 0)))
10290   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10291	(not:QI (match_dup 1)))]
10292  "ix86_match_ccmode (insn, CCNOmode)
10293   && ix86_unary_operator_ok (NOT, QImode, operands)"
10294  "#"
10295  [(set_attr "type" "alu1")
10296   (set_attr "mode" "QI")])
10297
10298(define_split
10299  [(set (match_operand 0 "flags_reg_operand" "")
10300	(match_operator 2 "compare_operator"
10301	  [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10302	   (const_int 0)]))
10303   (set (match_operand:QI 1 "nonimmediate_operand" "")
10304	(not:QI (match_dup 3)))]
10305  "ix86_match_ccmode (insn, CCNOmode)"
10306  [(parallel [(set (match_dup 0)
10307		   (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10308		      		    (const_int 0)]))
10309	      (set (match_dup 1)
10310		   (xor:QI (match_dup 3) (const_int -1)))])]
10311  "")
10312
10313;; Arithmetic shift instructions
10314
10315;; DImode shifts are implemented using the i386 "shift double" opcode,
10316;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10317;; is variable, then the count is in %cl and the "imm" operand is dropped
10318;; from the assembler input.
10319;;
10320;; This instruction shifts the target reg/mem as usual, but instead of
10321;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10322;; is a left shift double, bits are taken from the high order bits of
10323;; reg, else if the insn is a shift right double, bits are taken from the
10324;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10325;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10326;;
10327;; Since sh[lr]d does not change the `reg' operand, that is done
10328;; separately, making all shifts emit pairs of shift double and normal
10329;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10330;; support a 63 bit shift, each shift where the count is in a reg expands
10331;; to a pair of shifts, a branch, a shift by 32 and a label.
10332;;
10333;; If the shift count is a constant, we need never emit more than one
10334;; shift pair, instead using moves and sign extension for counts greater
10335;; than 31.
10336
10337(define_expand "ashlti3"
10338  [(parallel [(set (match_operand:TI 0 "register_operand" "")
10339		   (ashift:TI (match_operand:TI 1 "register_operand" "")
10340			      (match_operand:QI 2 "nonmemory_operand" "")))
10341	      (clobber (reg:CC FLAGS_REG))])]
10342  "TARGET_64BIT"
10343{
10344  if (! immediate_operand (operands[2], QImode))
10345    {
10346      emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10347      DONE;
10348    }
10349  ix86_expand_binary_operator (ASHIFT, TImode, operands);
10350  DONE;
10351})
10352
10353(define_insn "ashlti3_1"
10354  [(set (match_operand:TI 0 "register_operand" "=r")
10355	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10356		   (match_operand:QI 2 "register_operand" "c")))
10357   (clobber (match_scratch:DI 3 "=&r"))
10358   (clobber (reg:CC FLAGS_REG))]
10359  "TARGET_64BIT"
10360  "#"
10361  [(set_attr "type" "multi")])
10362
10363(define_insn "*ashlti3_2"
10364  [(set (match_operand:TI 0 "register_operand" "=r")
10365	(ashift:TI (match_operand:TI 1 "register_operand" "0")
10366		   (match_operand:QI 2 "immediate_operand" "O")))
10367   (clobber (reg:CC FLAGS_REG))]
10368  "TARGET_64BIT"
10369  "#"
10370  [(set_attr "type" "multi")])
10371
10372(define_split
10373  [(set (match_operand:TI 0 "register_operand" "")
10374	(ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10375		   (match_operand:QI 2 "register_operand" "")))
10376   (clobber (match_scratch:DI 3 ""))
10377   (clobber (reg:CC FLAGS_REG))]
10378  "TARGET_64BIT && reload_completed"
10379  [(const_int 0)]
10380  "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10381
10382(define_split
10383  [(set (match_operand:TI 0 "register_operand" "")
10384	(ashift:TI (match_operand:TI 1 "register_operand" "")
10385		   (match_operand:QI 2 "immediate_operand" "")))
10386   (clobber (reg:CC FLAGS_REG))]
10387  "TARGET_64BIT && reload_completed"
10388  [(const_int 0)]
10389  "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10390
10391(define_insn "x86_64_shld"
10392  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10393        (ior:DI (ashift:DI (match_dup 0)
10394		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
10395		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10396		  (minus:QI (const_int 64) (match_dup 2)))))
10397   (clobber (reg:CC FLAGS_REG))]
10398  "TARGET_64BIT"
10399  "@
10400   shld{q}\t{%2, %1, %0|%0, %1, %2}
10401   shld{q}\t{%s2%1, %0|%0, %1, %2}"
10402  [(set_attr "type" "ishift")
10403   (set_attr "prefix_0f" "1")
10404   (set_attr "mode" "DI")
10405   (set_attr "athlon_decode" "vector")
10406   (set_attr "amdfam10_decode" "vector")])   
10407
10408(define_expand "x86_64_shift_adj"
10409  [(set (reg:CCZ FLAGS_REG)
10410	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10411			     (const_int 64))
10412		     (const_int 0)))
10413   (set (match_operand:DI 0 "register_operand" "")
10414        (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10415			 (match_operand:DI 1 "register_operand" "")
10416			 (match_dup 0)))
10417   (set (match_dup 1)
10418	(if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10419			 (match_operand:DI 3 "register_operand" "r")
10420			 (match_dup 1)))]
10421  "TARGET_64BIT"
10422  "")
10423
10424(define_expand "ashldi3"
10425  [(set (match_operand:DI 0 "shiftdi_operand" "")
10426	(ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10427		   (match_operand:QI 2 "nonmemory_operand" "")))]
10428  ""
10429  "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10430
10431(define_insn "*ashldi3_1_rex64"
10432  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10433	(ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10434		   (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10435   (clobber (reg:CC FLAGS_REG))]
10436  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10437{
10438  switch (get_attr_type (insn))
10439    {
10440    case TYPE_ALU:
10441      gcc_assert (operands[2] == const1_rtx);
10442      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10443      return "add{q}\t{%0, %0|%0, %0}";
10444
10445    case TYPE_LEA:
10446      gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10447      gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10448      operands[1] = gen_rtx_MULT (DImode, operands[1],
10449				  GEN_INT (1 << INTVAL (operands[2])));
10450      return "lea{q}\t{%a1, %0|%0, %a1}";
10451
10452    default:
10453      if (REG_P (operands[2]))
10454	return "sal{q}\t{%b2, %0|%0, %b2}";
10455      else if (operands[2] == const1_rtx
10456	       && (TARGET_SHIFT1 || optimize_size))
10457	return "sal{q}\t%0";
10458      else
10459	return "sal{q}\t{%2, %0|%0, %2}";
10460    }
10461}
10462  [(set (attr "type")
10463     (cond [(eq_attr "alternative" "1")
10464	      (const_string "lea")
10465            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10466		          (const_int 0))
10467		      (match_operand 0 "register_operand" ""))
10468		 (match_operand 2 "const1_operand" ""))
10469	      (const_string "alu")
10470	   ]
10471	   (const_string "ishift")))
10472   (set_attr "mode" "DI")])
10473
10474;; Convert lea to the lea pattern to avoid flags dependency.
10475(define_split
10476  [(set (match_operand:DI 0 "register_operand" "")
10477	(ashift:DI (match_operand:DI 1 "index_register_operand" "")
10478		   (match_operand:QI 2 "immediate_operand" "")))
10479   (clobber (reg:CC FLAGS_REG))]
10480  "TARGET_64BIT && reload_completed
10481   && true_regnum (operands[0]) != true_regnum (operands[1])"
10482  [(set (match_dup 0)
10483	(mult:DI (match_dup 1)
10484		 (match_dup 2)))]
10485  "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10486
10487;; This pattern can't accept a variable shift count, since shifts by
10488;; zero don't affect the flags.  We assume that shifts by constant
10489;; zero are optimized away.
10490(define_insn "*ashldi3_cmp_rex64"
10491  [(set (reg FLAGS_REG)
10492	(compare
10493	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10494		     (match_operand:QI 2 "immediate_operand" "e"))
10495	  (const_int 0)))
10496   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10497	(ashift:DI (match_dup 1) (match_dup 2)))]
10498  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10499   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10500   && (optimize_size
10501       || !TARGET_PARTIAL_FLAG_REG_STALL
10502       || (operands[2] == const1_rtx
10503	   && (TARGET_SHIFT1
10504	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10505{
10506  switch (get_attr_type (insn))
10507    {
10508    case TYPE_ALU:
10509      gcc_assert (operands[2] == const1_rtx);
10510      return "add{q}\t{%0, %0|%0, %0}";
10511
10512    default:
10513      if (REG_P (operands[2]))
10514	return "sal{q}\t{%b2, %0|%0, %b2}";
10515      else if (operands[2] == const1_rtx
10516	       && (TARGET_SHIFT1 || optimize_size))
10517	return "sal{q}\t%0";
10518      else
10519	return "sal{q}\t{%2, %0|%0, %2}";
10520    }
10521}
10522  [(set (attr "type")
10523     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10524		          (const_int 0))
10525		      (match_operand 0 "register_operand" ""))
10526		 (match_operand 2 "const1_operand" ""))
10527	      (const_string "alu")
10528	   ]
10529	   (const_string "ishift")))
10530   (set_attr "mode" "DI")])
10531
10532(define_insn "*ashldi3_cconly_rex64"
10533  [(set (reg FLAGS_REG)
10534	(compare
10535	  (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10536		     (match_operand:QI 2 "immediate_operand" "e"))
10537	  (const_int 0)))
10538   (clobber (match_scratch:DI 0 "=r"))]
10539  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10540   && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10541   && (optimize_size
10542       || !TARGET_PARTIAL_FLAG_REG_STALL
10543       || (operands[2] == const1_rtx
10544	   && (TARGET_SHIFT1
10545	       || TARGET_DOUBLE_WITH_ADD)))"
10546{
10547  switch (get_attr_type (insn))
10548    {
10549    case TYPE_ALU:
10550      gcc_assert (operands[2] == const1_rtx);
10551      return "add{q}\t{%0, %0|%0, %0}";
10552
10553    default:
10554      if (REG_P (operands[2]))
10555	return "sal{q}\t{%b2, %0|%0, %b2}";
10556      else if (operands[2] == const1_rtx
10557	       && (TARGET_SHIFT1 || optimize_size))
10558	return "sal{q}\t%0";
10559      else
10560	return "sal{q}\t{%2, %0|%0, %2}";
10561    }
10562}
10563  [(set (attr "type")
10564     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10565		          (const_int 0))
10566		      (match_operand 0 "register_operand" ""))
10567		 (match_operand 2 "const1_operand" ""))
10568	      (const_string "alu")
10569	   ]
10570	   (const_string "ishift")))
10571   (set_attr "mode" "DI")])
10572
10573(define_insn "*ashldi3_1"
10574  [(set (match_operand:DI 0 "register_operand" "=&r,r")
10575	(ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10576		   (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10577   (clobber (reg:CC FLAGS_REG))]
10578  "!TARGET_64BIT"
10579  "#"
10580  [(set_attr "type" "multi")])
10581
10582;; By default we don't ask for a scratch register, because when DImode
10583;; values are manipulated, registers are already at a premium.  But if
10584;; we have one handy, we won't turn it away.
10585(define_peephole2
10586  [(match_scratch:SI 3 "r")
10587   (parallel [(set (match_operand:DI 0 "register_operand" "")
10588		   (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10589			      (match_operand:QI 2 "nonmemory_operand" "")))
10590	      (clobber (reg:CC FLAGS_REG))])
10591   (match_dup 3)]
10592  "!TARGET_64BIT && TARGET_CMOVE"
10593  [(const_int 0)]
10594  "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10595
10596(define_split
10597  [(set (match_operand:DI 0 "register_operand" "")
10598	(ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10599		   (match_operand:QI 2 "nonmemory_operand" "")))
10600   (clobber (reg:CC FLAGS_REG))]
10601  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10602		     ? flow2_completed : reload_completed)"
10603  [(const_int 0)]
10604  "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10605
10606(define_insn "x86_shld_1"
10607  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10608        (ior:SI (ashift:SI (match_dup 0)
10609		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
10610		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10611		  (minus:QI (const_int 32) (match_dup 2)))))
10612   (clobber (reg:CC FLAGS_REG))]
10613  ""
10614  "@
10615   shld{l}\t{%2, %1, %0|%0, %1, %2}
10616   shld{l}\t{%s2%1, %0|%0, %1, %2}"
10617  [(set_attr "type" "ishift")
10618   (set_attr "prefix_0f" "1")
10619   (set_attr "mode" "SI")
10620   (set_attr "pent_pair" "np")
10621   (set_attr "athlon_decode" "vector")
10622   (set_attr "amdfam10_decode" "vector")])   
10623
10624(define_expand "x86_shift_adj_1"
10625  [(set (reg:CCZ FLAGS_REG)
10626	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10627			     (const_int 32))
10628		     (const_int 0)))
10629   (set (match_operand:SI 0 "register_operand" "")
10630        (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10631			 (match_operand:SI 1 "register_operand" "")
10632			 (match_dup 0)))
10633   (set (match_dup 1)
10634	(if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10635			 (match_operand:SI 3 "register_operand" "r")
10636			 (match_dup 1)))]
10637  "TARGET_CMOVE"
10638  "")
10639
10640(define_expand "x86_shift_adj_2"
10641  [(use (match_operand:SI 0 "register_operand" ""))
10642   (use (match_operand:SI 1 "register_operand" ""))
10643   (use (match_operand:QI 2 "register_operand" ""))]
10644  ""
10645{
10646  rtx label = gen_label_rtx ();
10647  rtx tmp;
10648
10649  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10650
10651  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10652  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10653  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10654			      gen_rtx_LABEL_REF (VOIDmode, label),
10655			      pc_rtx);
10656  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10657  JUMP_LABEL (tmp) = label;
10658
10659  emit_move_insn (operands[0], operands[1]);
10660  ix86_expand_clear (operands[1]);
10661
10662  emit_label (label);
10663  LABEL_NUSES (label) = 1;
10664
10665  DONE;
10666})
10667
10668(define_expand "ashlsi3"
10669  [(set (match_operand:SI 0 "nonimmediate_operand" "")
10670	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10671		   (match_operand:QI 2 "nonmemory_operand" "")))
10672   (clobber (reg:CC FLAGS_REG))]
10673  ""
10674  "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10675
10676(define_insn "*ashlsi3_1"
10677  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10678	(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10679		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10680   (clobber (reg:CC FLAGS_REG))]
10681  "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10682{
10683  switch (get_attr_type (insn))
10684    {
10685    case TYPE_ALU:
10686      gcc_assert (operands[2] == const1_rtx);
10687      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10688      return "add{l}\t{%0, %0|%0, %0}";
10689
10690    case TYPE_LEA:
10691      return "#";
10692
10693    default:
10694      if (REG_P (operands[2]))
10695	return "sal{l}\t{%b2, %0|%0, %b2}";
10696      else if (operands[2] == const1_rtx
10697	       && (TARGET_SHIFT1 || optimize_size))
10698	return "sal{l}\t%0";
10699      else
10700	return "sal{l}\t{%2, %0|%0, %2}";
10701    }
10702}
10703  [(set (attr "type")
10704     (cond [(eq_attr "alternative" "1")
10705	      (const_string "lea")
10706            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10707		          (const_int 0))
10708		      (match_operand 0 "register_operand" ""))
10709		 (match_operand 2 "const1_operand" ""))
10710	      (const_string "alu")
10711	   ]
10712	   (const_string "ishift")))
10713   (set_attr "mode" "SI")])
10714
10715;; Convert lea to the lea pattern to avoid flags dependency.
10716(define_split
10717  [(set (match_operand 0 "register_operand" "")
10718	(ashift (match_operand 1 "index_register_operand" "")
10719                (match_operand:QI 2 "const_int_operand" "")))
10720   (clobber (reg:CC FLAGS_REG))]
10721  "reload_completed
10722   && true_regnum (operands[0]) != true_regnum (operands[1])
10723   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10724  [(const_int 0)]
10725{
10726  rtx pat;
10727  enum machine_mode mode = GET_MODE (operands[0]);
10728
10729  if (GET_MODE_SIZE (mode) < 4)
10730    operands[0] = gen_lowpart (SImode, operands[0]);
10731  if (mode != Pmode)
10732    operands[1] = gen_lowpart (Pmode, operands[1]);
10733  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10734
10735  pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10736  if (Pmode != SImode)
10737    pat = gen_rtx_SUBREG (SImode, pat, 0);
10738  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10739  DONE;
10740})
10741
10742;; Rare case of shifting RSP is handled by generating move and shift
10743(define_split
10744  [(set (match_operand 0 "register_operand" "")
10745	(ashift (match_operand 1 "register_operand" "")
10746                (match_operand:QI 2 "const_int_operand" "")))
10747   (clobber (reg:CC FLAGS_REG))]
10748  "reload_completed
10749   && true_regnum (operands[0]) != true_regnum (operands[1])"
10750  [(const_int 0)]
10751{
10752  rtx pat, clob;
10753  emit_move_insn (operands[0], operands[1]);
10754  pat = gen_rtx_SET (VOIDmode, operands[0],
10755		     gen_rtx_ASHIFT (GET_MODE (operands[0]),
10756				     operands[0], operands[2]));
10757  clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10758  emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10759  DONE;
10760})
10761
10762(define_insn "*ashlsi3_1_zext"
10763  [(set (match_operand:DI 0 "register_operand" "=r,r")
10764	(zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10765			(match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10766   (clobber (reg:CC FLAGS_REG))]
10767  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10768{
10769  switch (get_attr_type (insn))
10770    {
10771    case TYPE_ALU:
10772      gcc_assert (operands[2] == const1_rtx);
10773      return "add{l}\t{%k0, %k0|%k0, %k0}";
10774
10775    case TYPE_LEA:
10776      return "#";
10777
10778    default:
10779      if (REG_P (operands[2]))
10780	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10781      else if (operands[2] == const1_rtx
10782	       && (TARGET_SHIFT1 || optimize_size))
10783	return "sal{l}\t%k0";
10784      else
10785	return "sal{l}\t{%2, %k0|%k0, %2}";
10786    }
10787}
10788  [(set (attr "type")
10789     (cond [(eq_attr "alternative" "1")
10790	      (const_string "lea")
10791            (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10792		     (const_int 0))
10793		 (match_operand 2 "const1_operand" ""))
10794	      (const_string "alu")
10795	   ]
10796	   (const_string "ishift")))
10797   (set_attr "mode" "SI")])
10798
10799;; Convert lea to the lea pattern to avoid flags dependency.
10800(define_split
10801  [(set (match_operand:DI 0 "register_operand" "")
10802	(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10803				(match_operand:QI 2 "const_int_operand" ""))))
10804   (clobber (reg:CC FLAGS_REG))]
10805  "TARGET_64BIT && reload_completed
10806   && true_regnum (operands[0]) != true_regnum (operands[1])"
10807  [(set (match_dup 0) (zero_extend:DI
10808			(subreg:SI (mult:SI (match_dup 1)
10809					    (match_dup 2)) 0)))]
10810{
10811  operands[1] = gen_lowpart (Pmode, operands[1]);
10812  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10813})
10814
10815;; This pattern can't accept a variable shift count, since shifts by
10816;; zero don't affect the flags.  We assume that shifts by constant
10817;; zero are optimized away.
10818(define_insn "*ashlsi3_cmp"
10819  [(set (reg FLAGS_REG)
10820	(compare
10821	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10822		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10823	  (const_int 0)))
10824   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10825	(ashift:SI (match_dup 1) (match_dup 2)))]
10826  "ix86_match_ccmode (insn, CCGOCmode)
10827   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10828   && (optimize_size
10829       || !TARGET_PARTIAL_FLAG_REG_STALL
10830       || (operands[2] == const1_rtx
10831	   && (TARGET_SHIFT1
10832	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10833{
10834  switch (get_attr_type (insn))
10835    {
10836    case TYPE_ALU:
10837      gcc_assert (operands[2] == const1_rtx);
10838      return "add{l}\t{%0, %0|%0, %0}";
10839
10840    default:
10841      if (REG_P (operands[2]))
10842	return "sal{l}\t{%b2, %0|%0, %b2}";
10843      else if (operands[2] == const1_rtx
10844	       && (TARGET_SHIFT1 || optimize_size))
10845	return "sal{l}\t%0";
10846      else
10847	return "sal{l}\t{%2, %0|%0, %2}";
10848    }
10849}
10850  [(set (attr "type")
10851     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10852		          (const_int 0))
10853		      (match_operand 0 "register_operand" ""))
10854		 (match_operand 2 "const1_operand" ""))
10855	      (const_string "alu")
10856	   ]
10857	   (const_string "ishift")))
10858   (set_attr "mode" "SI")])
10859
10860(define_insn "*ashlsi3_cconly"
10861  [(set (reg FLAGS_REG)
10862	(compare
10863	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10864		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10865	  (const_int 0)))
10866   (clobber (match_scratch:SI 0 "=r"))]
10867  "ix86_match_ccmode (insn, CCGOCmode)
10868   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10869   && (optimize_size
10870       || !TARGET_PARTIAL_FLAG_REG_STALL
10871       || (operands[2] == const1_rtx
10872	   && (TARGET_SHIFT1
10873	       || TARGET_DOUBLE_WITH_ADD)))"
10874{
10875  switch (get_attr_type (insn))
10876    {
10877    case TYPE_ALU:
10878      gcc_assert (operands[2] == const1_rtx);
10879      return "add{l}\t{%0, %0|%0, %0}";
10880
10881    default:
10882      if (REG_P (operands[2]))
10883	return "sal{l}\t{%b2, %0|%0, %b2}";
10884      else if (operands[2] == const1_rtx
10885	       && (TARGET_SHIFT1 || optimize_size))
10886	return "sal{l}\t%0";
10887      else
10888	return "sal{l}\t{%2, %0|%0, %2}";
10889    }
10890}
10891  [(set (attr "type")
10892     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10893		          (const_int 0))
10894		      (match_operand 0 "register_operand" ""))
10895		 (match_operand 2 "const1_operand" ""))
10896	      (const_string "alu")
10897	   ]
10898	   (const_string "ishift")))
10899   (set_attr "mode" "SI")])
10900
10901(define_insn "*ashlsi3_cmp_zext"
10902  [(set (reg FLAGS_REG)
10903	(compare
10904	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10905		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10906	  (const_int 0)))
10907   (set (match_operand:DI 0 "register_operand" "=r")
10908	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10909  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10910   && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10911   && (optimize_size
10912       || !TARGET_PARTIAL_FLAG_REG_STALL
10913       || (operands[2] == const1_rtx
10914	   && (TARGET_SHIFT1
10915	       || TARGET_DOUBLE_WITH_ADD)))"
10916{
10917  switch (get_attr_type (insn))
10918    {
10919    case TYPE_ALU:
10920      gcc_assert (operands[2] == const1_rtx);
10921      return "add{l}\t{%k0, %k0|%k0, %k0}";
10922
10923    default:
10924      if (REG_P (operands[2]))
10925	return "sal{l}\t{%b2, %k0|%k0, %b2}";
10926      else if (operands[2] == const1_rtx
10927	       && (TARGET_SHIFT1 || optimize_size))
10928	return "sal{l}\t%k0";
10929      else
10930	return "sal{l}\t{%2, %k0|%k0, %2}";
10931    }
10932}
10933  [(set (attr "type")
10934     (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10935		     (const_int 0))
10936		 (match_operand 2 "const1_operand" ""))
10937	      (const_string "alu")
10938	   ]
10939	   (const_string "ishift")))
10940   (set_attr "mode" "SI")])
10941
10942(define_expand "ashlhi3"
10943  [(set (match_operand:HI 0 "nonimmediate_operand" "")
10944	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10945		   (match_operand:QI 2 "nonmemory_operand" "")))
10946   (clobber (reg:CC FLAGS_REG))]
10947  "TARGET_HIMODE_MATH"
10948  "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10949
10950(define_insn "*ashlhi3_1_lea"
10951  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10952	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10953		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10954   (clobber (reg:CC FLAGS_REG))]
10955  "!TARGET_PARTIAL_REG_STALL
10956   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10957{
10958  switch (get_attr_type (insn))
10959    {
10960    case TYPE_LEA:
10961      return "#";
10962    case TYPE_ALU:
10963      gcc_assert (operands[2] == const1_rtx);
10964      return "add{w}\t{%0, %0|%0, %0}";
10965
10966    default:
10967      if (REG_P (operands[2]))
10968	return "sal{w}\t{%b2, %0|%0, %b2}";
10969      else if (operands[2] == const1_rtx
10970	       && (TARGET_SHIFT1 || optimize_size))
10971	return "sal{w}\t%0";
10972      else
10973	return "sal{w}\t{%2, %0|%0, %2}";
10974    }
10975}
10976  [(set (attr "type")
10977     (cond [(eq_attr "alternative" "1")
10978	      (const_string "lea")
10979            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980		          (const_int 0))
10981		      (match_operand 0 "register_operand" ""))
10982		 (match_operand 2 "const1_operand" ""))
10983	      (const_string "alu")
10984	   ]
10985	   (const_string "ishift")))
10986   (set_attr "mode" "HI,SI")])
10987
10988(define_insn "*ashlhi3_1"
10989  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10990	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10991		   (match_operand:QI 2 "nonmemory_operand" "cI")))
10992   (clobber (reg:CC FLAGS_REG))]
10993  "TARGET_PARTIAL_REG_STALL
10994   && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10995{
10996  switch (get_attr_type (insn))
10997    {
10998    case TYPE_ALU:
10999      gcc_assert (operands[2] == const1_rtx);
11000      return "add{w}\t{%0, %0|%0, %0}";
11001
11002    default:
11003      if (REG_P (operands[2]))
11004	return "sal{w}\t{%b2, %0|%0, %b2}";
11005      else if (operands[2] == const1_rtx
11006	       && (TARGET_SHIFT1 || optimize_size))
11007	return "sal{w}\t%0";
11008      else
11009	return "sal{w}\t{%2, %0|%0, %2}";
11010    }
11011}
11012  [(set (attr "type")
11013     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014		          (const_int 0))
11015		      (match_operand 0 "register_operand" ""))
11016		 (match_operand 2 "const1_operand" ""))
11017	      (const_string "alu")
11018	   ]
11019	   (const_string "ishift")))
11020   (set_attr "mode" "HI")])
11021
11022;; This pattern can't accept a variable shift count, since shifts by
11023;; zero don't affect the flags.  We assume that shifts by constant
11024;; zero are optimized away.
11025(define_insn "*ashlhi3_cmp"
11026  [(set (reg FLAGS_REG)
11027	(compare
11028	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11029		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11030	  (const_int 0)))
11031   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11032	(ashift:HI (match_dup 1) (match_dup 2)))]
11033  "ix86_match_ccmode (insn, CCGOCmode)
11034   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11035   && (optimize_size
11036       || !TARGET_PARTIAL_FLAG_REG_STALL
11037       || (operands[2] == const1_rtx
11038	   && (TARGET_SHIFT1
11039	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11040{
11041  switch (get_attr_type (insn))
11042    {
11043    case TYPE_ALU:
11044      gcc_assert (operands[2] == const1_rtx);
11045      return "add{w}\t{%0, %0|%0, %0}";
11046
11047    default:
11048      if (REG_P (operands[2]))
11049	return "sal{w}\t{%b2, %0|%0, %b2}";
11050      else if (operands[2] == const1_rtx
11051	       && (TARGET_SHIFT1 || optimize_size))
11052	return "sal{w}\t%0";
11053      else
11054	return "sal{w}\t{%2, %0|%0, %2}";
11055    }
11056}
11057  [(set (attr "type")
11058     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11059		          (const_int 0))
11060		      (match_operand 0 "register_operand" ""))
11061		 (match_operand 2 "const1_operand" ""))
11062	      (const_string "alu")
11063	   ]
11064	   (const_string "ishift")))
11065   (set_attr "mode" "HI")])
11066
11067(define_insn "*ashlhi3_cconly"
11068  [(set (reg FLAGS_REG)
11069	(compare
11070	  (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11071		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11072	  (const_int 0)))
11073   (clobber (match_scratch:HI 0 "=r"))]
11074  "ix86_match_ccmode (insn, CCGOCmode)
11075   && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11076   && (optimize_size
11077       || !TARGET_PARTIAL_FLAG_REG_STALL
11078       || (operands[2] == const1_rtx
11079	   && (TARGET_SHIFT1
11080	       || TARGET_DOUBLE_WITH_ADD)))"
11081{
11082  switch (get_attr_type (insn))
11083    {
11084    case TYPE_ALU:
11085      gcc_assert (operands[2] == const1_rtx);
11086      return "add{w}\t{%0, %0|%0, %0}";
11087
11088    default:
11089      if (REG_P (operands[2]))
11090	return "sal{w}\t{%b2, %0|%0, %b2}";
11091      else if (operands[2] == const1_rtx
11092	       && (TARGET_SHIFT1 || optimize_size))
11093	return "sal{w}\t%0";
11094      else
11095	return "sal{w}\t{%2, %0|%0, %2}";
11096    }
11097}
11098  [(set (attr "type")
11099     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11100		          (const_int 0))
11101		      (match_operand 0 "register_operand" ""))
11102		 (match_operand 2 "const1_operand" ""))
11103	      (const_string "alu")
11104	   ]
11105	   (const_string "ishift")))
11106   (set_attr "mode" "HI")])
11107
11108(define_expand "ashlqi3"
11109  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11110	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11111		   (match_operand:QI 2 "nonmemory_operand" "")))
11112   (clobber (reg:CC FLAGS_REG))]
11113  "TARGET_QIMODE_MATH"
11114  "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11115
11116;; %%% Potential partial reg stall on alternative 2.  What to do?
11117
11118(define_insn "*ashlqi3_1_lea"
11119  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11120	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11121		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11122   (clobber (reg:CC FLAGS_REG))]
11123  "!TARGET_PARTIAL_REG_STALL
11124   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11125{
11126  switch (get_attr_type (insn))
11127    {
11128    case TYPE_LEA:
11129      return "#";
11130    case TYPE_ALU:
11131      gcc_assert (operands[2] == const1_rtx);
11132      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11133        return "add{l}\t{%k0, %k0|%k0, %k0}";
11134      else
11135        return "add{b}\t{%0, %0|%0, %0}";
11136
11137    default:
11138      if (REG_P (operands[2]))
11139	{
11140	  if (get_attr_mode (insn) == MODE_SI)
11141	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11142	  else
11143	    return "sal{b}\t{%b2, %0|%0, %b2}";
11144	}
11145      else if (operands[2] == const1_rtx
11146	       && (TARGET_SHIFT1 || optimize_size))
11147	{
11148	  if (get_attr_mode (insn) == MODE_SI)
11149	    return "sal{l}\t%0";
11150	  else
11151	    return "sal{b}\t%0";
11152	}
11153      else
11154	{
11155	  if (get_attr_mode (insn) == MODE_SI)
11156	    return "sal{l}\t{%2, %k0|%k0, %2}";
11157	  else
11158	    return "sal{b}\t{%2, %0|%0, %2}";
11159	}
11160    }
11161}
11162  [(set (attr "type")
11163     (cond [(eq_attr "alternative" "2")
11164	      (const_string "lea")
11165            (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11166		          (const_int 0))
11167		      (match_operand 0 "register_operand" ""))
11168		 (match_operand 2 "const1_operand" ""))
11169	      (const_string "alu")
11170	   ]
11171	   (const_string "ishift")))
11172   (set_attr "mode" "QI,SI,SI")])
11173
11174(define_insn "*ashlqi3_1"
11175  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11176	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11177		   (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11178   (clobber (reg:CC FLAGS_REG))]
11179  "TARGET_PARTIAL_REG_STALL
11180   && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11181{
11182  switch (get_attr_type (insn))
11183    {
11184    case TYPE_ALU:
11185      gcc_assert (operands[2] == const1_rtx);
11186      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11187        return "add{l}\t{%k0, %k0|%k0, %k0}";
11188      else
11189        return "add{b}\t{%0, %0|%0, %0}";
11190
11191    default:
11192      if (REG_P (operands[2]))
11193	{
11194	  if (get_attr_mode (insn) == MODE_SI)
11195	    return "sal{l}\t{%b2, %k0|%k0, %b2}";
11196	  else
11197	    return "sal{b}\t{%b2, %0|%0, %b2}";
11198	}
11199      else if (operands[2] == const1_rtx
11200	       && (TARGET_SHIFT1 || optimize_size))
11201	{
11202	  if (get_attr_mode (insn) == MODE_SI)
11203	    return "sal{l}\t%0";
11204	  else
11205	    return "sal{b}\t%0";
11206	}
11207      else
11208	{
11209	  if (get_attr_mode (insn) == MODE_SI)
11210	    return "sal{l}\t{%2, %k0|%k0, %2}";
11211	  else
11212	    return "sal{b}\t{%2, %0|%0, %2}";
11213	}
11214    }
11215}
11216  [(set (attr "type")
11217     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11218		          (const_int 0))
11219		      (match_operand 0 "register_operand" ""))
11220		 (match_operand 2 "const1_operand" ""))
11221	      (const_string "alu")
11222	   ]
11223	   (const_string "ishift")))
11224   (set_attr "mode" "QI,SI")])
11225
11226;; This pattern can't accept a variable shift count, since shifts by
11227;; zero don't affect the flags.  We assume that shifts by constant
11228;; zero are optimized away.
11229(define_insn "*ashlqi3_cmp"
11230  [(set (reg FLAGS_REG)
11231	(compare
11232	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11233		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11234	  (const_int 0)))
11235   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11236	(ashift:QI (match_dup 1) (match_dup 2)))]
11237  "ix86_match_ccmode (insn, CCGOCmode)
11238   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11239   && (optimize_size
11240       || !TARGET_PARTIAL_FLAG_REG_STALL
11241       || (operands[2] == const1_rtx
11242	   && (TARGET_SHIFT1
11243	       || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11244{
11245  switch (get_attr_type (insn))
11246    {
11247    case TYPE_ALU:
11248      gcc_assert (operands[2] == const1_rtx);
11249      return "add{b}\t{%0, %0|%0, %0}";
11250
11251    default:
11252      if (REG_P (operands[2]))
11253	return "sal{b}\t{%b2, %0|%0, %b2}";
11254      else if (operands[2] == const1_rtx
11255	       && (TARGET_SHIFT1 || optimize_size))
11256	return "sal{b}\t%0";
11257      else
11258	return "sal{b}\t{%2, %0|%0, %2}";
11259    }
11260}
11261  [(set (attr "type")
11262     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11263		          (const_int 0))
11264		      (match_operand 0 "register_operand" ""))
11265		 (match_operand 2 "const1_operand" ""))
11266	      (const_string "alu")
11267	   ]
11268	   (const_string "ishift")))
11269   (set_attr "mode" "QI")])
11270
11271(define_insn "*ashlqi3_cconly"
11272  [(set (reg FLAGS_REG)
11273	(compare
11274	  (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11275		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
11276	  (const_int 0)))
11277   (clobber (match_scratch:QI 0 "=q"))]
11278  "ix86_match_ccmode (insn, CCGOCmode)
11279   && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11280   && (optimize_size
11281       || !TARGET_PARTIAL_FLAG_REG_STALL
11282       || (operands[2] == const1_rtx
11283	   && (TARGET_SHIFT1
11284	       || TARGET_DOUBLE_WITH_ADD)))"
11285{
11286  switch (get_attr_type (insn))
11287    {
11288    case TYPE_ALU:
11289      gcc_assert (operands[2] == const1_rtx);
11290      return "add{b}\t{%0, %0|%0, %0}";
11291
11292    default:
11293      if (REG_P (operands[2]))
11294	return "sal{b}\t{%b2, %0|%0, %b2}";
11295      else if (operands[2] == const1_rtx
11296	       && (TARGET_SHIFT1 || optimize_size))
11297	return "sal{b}\t%0";
11298      else
11299	return "sal{b}\t{%2, %0|%0, %2}";
11300    }
11301}
11302  [(set (attr "type")
11303     (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11304		          (const_int 0))
11305		      (match_operand 0 "register_operand" ""))
11306		 (match_operand 2 "const1_operand" ""))
11307	      (const_string "alu")
11308	   ]
11309	   (const_string "ishift")))
11310   (set_attr "mode" "QI")])
11311
11312;; See comment above `ashldi3' about how this works.
11313
11314(define_expand "ashrti3"
11315  [(parallel [(set (match_operand:TI 0 "register_operand" "")
11316		   (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11317				(match_operand:QI 2 "nonmemory_operand" "")))
11318	      (clobber (reg:CC FLAGS_REG))])]
11319  "TARGET_64BIT"
11320{
11321  if (! immediate_operand (operands[2], QImode))
11322    {
11323      emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11324      DONE;
11325    }
11326  ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11327  DONE;
11328})
11329
11330(define_insn "ashrti3_1"
11331  [(set (match_operand:TI 0 "register_operand" "=r")
11332	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11333		     (match_operand:QI 2 "register_operand" "c")))
11334   (clobber (match_scratch:DI 3 "=&r"))
11335   (clobber (reg:CC FLAGS_REG))]
11336  "TARGET_64BIT"
11337  "#"
11338  [(set_attr "type" "multi")])
11339
11340(define_insn "*ashrti3_2"
11341  [(set (match_operand:TI 0 "register_operand" "=r")
11342	(ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11343		     (match_operand:QI 2 "immediate_operand" "O")))
11344   (clobber (reg:CC FLAGS_REG))]
11345  "TARGET_64BIT"
11346  "#"
11347  [(set_attr "type" "multi")])
11348
11349(define_split
11350  [(set (match_operand:TI 0 "register_operand" "")
11351	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11352		     (match_operand:QI 2 "register_operand" "")))
11353   (clobber (match_scratch:DI 3 ""))
11354   (clobber (reg:CC FLAGS_REG))]
11355  "TARGET_64BIT && reload_completed"
11356  [(const_int 0)]
11357  "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11358
11359(define_split
11360  [(set (match_operand:TI 0 "register_operand" "")
11361	(ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11362		     (match_operand:QI 2 "immediate_operand" "")))
11363   (clobber (reg:CC FLAGS_REG))]
11364  "TARGET_64BIT && reload_completed"
11365  [(const_int 0)]
11366  "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11367
11368(define_insn "x86_64_shrd"
11369  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11370        (ior:DI (ashiftrt:DI (match_dup 0)
11371		  (match_operand:QI 2 "nonmemory_operand" "J,c"))
11372		(ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11373		  (minus:QI (const_int 64) (match_dup 2)))))
11374   (clobber (reg:CC FLAGS_REG))]
11375  "TARGET_64BIT"
11376  "@
11377   shrd{q}\t{%2, %1, %0|%0, %1, %2}
11378   shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11379  [(set_attr "type" "ishift")
11380   (set_attr "prefix_0f" "1")
11381   (set_attr "mode" "DI")
11382   (set_attr "athlon_decode" "vector")
11383   (set_attr "amdfam10_decode" "vector")])   
11384
11385(define_expand "ashrdi3"
11386  [(set (match_operand:DI 0 "shiftdi_operand" "")
11387	(ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11388		     (match_operand:QI 2 "nonmemory_operand" "")))]
11389  ""
11390  "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11391
11392(define_insn "*ashrdi3_63_rex64"
11393  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11394	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11395		     (match_operand:DI 2 "const_int_operand" "i,i")))
11396   (clobber (reg:CC FLAGS_REG))]
11397  "TARGET_64BIT && INTVAL (operands[2]) == 63
11398   && (TARGET_USE_CLTD || optimize_size)
11399   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11400  "@
11401   {cqto|cqo}
11402   sar{q}\t{%2, %0|%0, %2}"
11403  [(set_attr "type" "imovx,ishift")
11404   (set_attr "prefix_0f" "0,*")
11405   (set_attr "length_immediate" "0,*")
11406   (set_attr "modrm" "0,1")
11407   (set_attr "mode" "DI")])
11408
11409(define_insn "*ashrdi3_1_one_bit_rex64"
11410  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11411	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412		     (match_operand:QI 2 "const1_operand" "")))
11413   (clobber (reg:CC FLAGS_REG))]
11414  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11415   && (TARGET_SHIFT1 || optimize_size)"
11416  "sar{q}\t%0"
11417  [(set_attr "type" "ishift")
11418   (set (attr "length") 
11419     (if_then_else (match_operand:DI 0 "register_operand" "") 
11420	(const_string "2")
11421	(const_string "*")))])
11422
11423(define_insn "*ashrdi3_1_rex64"
11424  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11425	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11426		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
11427   (clobber (reg:CC FLAGS_REG))]
11428  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11429  "@
11430   sar{q}\t{%2, %0|%0, %2}
11431   sar{q}\t{%b2, %0|%0, %b2}"
11432  [(set_attr "type" "ishift")
11433   (set_attr "mode" "DI")])
11434
11435;; This pattern can't accept a variable shift count, since shifts by
11436;; zero don't affect the flags.  We assume that shifts by constant
11437;; zero are optimized away.
11438(define_insn "*ashrdi3_one_bit_cmp_rex64"
11439  [(set (reg FLAGS_REG)
11440	(compare
11441	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11442		       (match_operand:QI 2 "const1_operand" ""))
11443	  (const_int 0)))
11444   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11445	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11446  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11447   && (TARGET_SHIFT1 || optimize_size)
11448   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11449  "sar{q}\t%0"
11450  [(set_attr "type" "ishift")
11451   (set (attr "length") 
11452     (if_then_else (match_operand:DI 0 "register_operand" "") 
11453	(const_string "2")
11454	(const_string "*")))])
11455
11456(define_insn "*ashrdi3_one_bit_cconly_rex64"
11457  [(set (reg FLAGS_REG)
11458	(compare
11459	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11460		       (match_operand:QI 2 "const1_operand" ""))
11461	  (const_int 0)))
11462   (clobber (match_scratch:DI 0 "=r"))]
11463  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11464   && (TARGET_SHIFT1 || optimize_size)
11465   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11466  "sar{q}\t%0"
11467  [(set_attr "type" "ishift")
11468   (set_attr "length" "2")])
11469
11470;; This pattern can't accept a variable shift count, since shifts by
11471;; zero don't affect the flags.  We assume that shifts by constant
11472;; zero are optimized away.
11473(define_insn "*ashrdi3_cmp_rex64"
11474  [(set (reg FLAGS_REG)
11475	(compare
11476	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477		       (match_operand:QI 2 "const_int_operand" "n"))
11478	  (const_int 0)))
11479   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11480	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
11481  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11482   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11483   && (optimize_size
11484       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11485  "sar{q}\t{%2, %0|%0, %2}"
11486  [(set_attr "type" "ishift")
11487   (set_attr "mode" "DI")])
11488
11489(define_insn "*ashrdi3_cconly_rex64"
11490  [(set (reg FLAGS_REG)
11491	(compare
11492	  (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11493		       (match_operand:QI 2 "const_int_operand" "n"))
11494	  (const_int 0)))
11495   (clobber (match_scratch:DI 0 "=r"))]
11496  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11497   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11498   && (optimize_size
11499       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11500  "sar{q}\t{%2, %0|%0, %2}"
11501  [(set_attr "type" "ishift")
11502   (set_attr "mode" "DI")])
11503
11504(define_insn "*ashrdi3_1"
11505  [(set (match_operand:DI 0 "register_operand" "=r")
11506	(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11507		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
11508   (clobber (reg:CC FLAGS_REG))]
11509  "!TARGET_64BIT"
11510  "#"
11511  [(set_attr "type" "multi")])
11512
11513;; By default we don't ask for a scratch register, because when DImode
11514;; values are manipulated, registers are already at a premium.  But if
11515;; we have one handy, we won't turn it away.
11516(define_peephole2
11517  [(match_scratch:SI 3 "r")
11518   (parallel [(set (match_operand:DI 0 "register_operand" "")
11519		   (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11520			        (match_operand:QI 2 "nonmemory_operand" "")))
11521	      (clobber (reg:CC FLAGS_REG))])
11522   (match_dup 3)]
11523  "!TARGET_64BIT && TARGET_CMOVE"
11524  [(const_int 0)]
11525  "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11526
11527(define_split
11528  [(set (match_operand:DI 0 "register_operand" "")
11529	(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11530		     (match_operand:QI 2 "nonmemory_operand" "")))
11531   (clobber (reg:CC FLAGS_REG))]
11532  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11533		     ? flow2_completed : reload_completed)"
11534  [(const_int 0)]
11535  "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11536
11537(define_insn "x86_shrd_1"
11538  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11539        (ior:SI (ashiftrt:SI (match_dup 0)
11540		  (match_operand:QI 2 "nonmemory_operand" "I,c"))
11541		(ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11542		  (minus:QI (const_int 32) (match_dup 2)))))
11543   (clobber (reg:CC FLAGS_REG))]
11544  ""
11545  "@
11546   shrd{l}\t{%2, %1, %0|%0, %1, %2}
11547   shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11548  [(set_attr "type" "ishift")
11549   (set_attr "prefix_0f" "1")
11550   (set_attr "pent_pair" "np")
11551   (set_attr "mode" "SI")])
11552
11553(define_expand "x86_shift_adj_3"
11554  [(use (match_operand:SI 0 "register_operand" ""))
11555   (use (match_operand:SI 1 "register_operand" ""))
11556   (use (match_operand:QI 2 "register_operand" ""))]
11557  ""
11558{
11559  rtx label = gen_label_rtx ();
11560  rtx tmp;
11561
11562  emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11563
11564  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11565  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11566  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11567			      gen_rtx_LABEL_REF (VOIDmode, label),
11568			      pc_rtx);
11569  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11570  JUMP_LABEL (tmp) = label;
11571
11572  emit_move_insn (operands[0], operands[1]);
11573  emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11574
11575  emit_label (label);
11576  LABEL_NUSES (label) = 1;
11577
11578  DONE;
11579})
11580
11581(define_insn "ashrsi3_31"
11582  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11583	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11584		     (match_operand:SI 2 "const_int_operand" "i,i")))
11585   (clobber (reg:CC FLAGS_REG))]
11586  "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11587   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11588  "@
11589   {cltd|cdq}
11590   sar{l}\t{%2, %0|%0, %2}"
11591  [(set_attr "type" "imovx,ishift")
11592   (set_attr "prefix_0f" "0,*")
11593   (set_attr "length_immediate" "0,*")
11594   (set_attr "modrm" "0,1")
11595   (set_attr "mode" "SI")])
11596
11597(define_insn "*ashrsi3_31_zext"
11598  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11599	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11600				     (match_operand:SI 2 "const_int_operand" "i,i"))))
11601   (clobber (reg:CC FLAGS_REG))]
11602  "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11603   && INTVAL (operands[2]) == 31
11604   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11605  "@
11606   {cltd|cdq}
11607   sar{l}\t{%2, %k0|%k0, %2}"
11608  [(set_attr "type" "imovx,ishift")
11609   (set_attr "prefix_0f" "0,*")
11610   (set_attr "length_immediate" "0,*")
11611   (set_attr "modrm" "0,1")
11612   (set_attr "mode" "SI")])
11613
11614(define_expand "ashrsi3"
11615  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11616	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11617		     (match_operand:QI 2 "nonmemory_operand" "")))
11618   (clobber (reg:CC FLAGS_REG))]
11619  ""
11620  "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11621
11622(define_insn "*ashrsi3_1_one_bit"
11623  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11624	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11625		     (match_operand:QI 2 "const1_operand" "")))
11626   (clobber (reg:CC FLAGS_REG))]
11627  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11628   && (TARGET_SHIFT1 || optimize_size)"
11629  "sar{l}\t%0"
11630  [(set_attr "type" "ishift")
11631   (set (attr "length") 
11632     (if_then_else (match_operand:SI 0 "register_operand" "") 
11633	(const_string "2")
11634	(const_string "*")))])
11635
11636(define_insn "*ashrsi3_1_one_bit_zext"
11637  [(set (match_operand:DI 0 "register_operand" "=r")
11638	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11639				     (match_operand:QI 2 "const1_operand" ""))))
11640   (clobber (reg:CC FLAGS_REG))]
11641  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11642   && (TARGET_SHIFT1 || optimize_size)"
11643  "sar{l}\t%k0"
11644  [(set_attr "type" "ishift")
11645   (set_attr "length" "2")])
11646
11647(define_insn "*ashrsi3_1"
11648  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11649	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11650		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11651   (clobber (reg:CC FLAGS_REG))]
11652  "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653  "@
11654   sar{l}\t{%2, %0|%0, %2}
11655   sar{l}\t{%b2, %0|%0, %b2}"
11656  [(set_attr "type" "ishift")
11657   (set_attr "mode" "SI")])
11658
11659(define_insn "*ashrsi3_1_zext"
11660  [(set (match_operand:DI 0 "register_operand" "=r,r")
11661	(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11662				     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11663   (clobber (reg:CC FLAGS_REG))]
11664  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11665  "@
11666   sar{l}\t{%2, %k0|%k0, %2}
11667   sar{l}\t{%b2, %k0|%k0, %b2}"
11668  [(set_attr "type" "ishift")
11669   (set_attr "mode" "SI")])
11670
11671;; This pattern can't accept a variable shift count, since shifts by
11672;; zero don't affect the flags.  We assume that shifts by constant
11673;; zero are optimized away.
11674(define_insn "*ashrsi3_one_bit_cmp"
11675  [(set (reg FLAGS_REG)
11676	(compare
11677	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11678		       (match_operand:QI 2 "const1_operand" ""))
11679	  (const_int 0)))
11680   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11681	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11682  "ix86_match_ccmode (insn, CCGOCmode)
11683   && (TARGET_SHIFT1 || optimize_size)
11684   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11685  "sar{l}\t%0"
11686  [(set_attr "type" "ishift")
11687   (set (attr "length") 
11688     (if_then_else (match_operand:SI 0 "register_operand" "") 
11689	(const_string "2")
11690	(const_string "*")))])
11691
11692(define_insn "*ashrsi3_one_bit_cconly"
11693  [(set (reg FLAGS_REG)
11694	(compare
11695	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11696		       (match_operand:QI 2 "const1_operand" ""))
11697	  (const_int 0)))
11698   (clobber (match_scratch:SI 0 "=r"))]
11699  "ix86_match_ccmode (insn, CCGOCmode)
11700   && (TARGET_SHIFT1 || optimize_size)
11701   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11702  "sar{l}\t%0"
11703  [(set_attr "type" "ishift")
11704   (set_attr "length" "2")])
11705
11706(define_insn "*ashrsi3_one_bit_cmp_zext"
11707  [(set (reg FLAGS_REG)
11708	(compare
11709	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11710		       (match_operand:QI 2 "const1_operand" ""))
11711	  (const_int 0)))
11712   (set (match_operand:DI 0 "register_operand" "=r")
11713	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11714  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11715   && (TARGET_SHIFT1 || optimize_size)
11716   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11717  "sar{l}\t%k0"
11718  [(set_attr "type" "ishift")
11719   (set_attr "length" "2")])
11720
11721;; This pattern can't accept a variable shift count, since shifts by
11722;; zero don't affect the flags.  We assume that shifts by constant
11723;; zero are optimized away.
11724(define_insn "*ashrsi3_cmp"
11725  [(set (reg FLAGS_REG)
11726	(compare
11727	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11729	  (const_int 0)))
11730   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
11732  "ix86_match_ccmode (insn, CCGOCmode)
11733   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11734   && (optimize_size
11735       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11736  "sar{l}\t{%2, %0|%0, %2}"
11737  [(set_attr "type" "ishift")
11738   (set_attr "mode" "SI")])
11739
11740(define_insn "*ashrsi3_cconly"
11741  [(set (reg FLAGS_REG)
11742	(compare
11743	  (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11744		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11745	  (const_int 0)))
11746   (clobber (match_scratch:SI 0 "=r"))]
11747  "ix86_match_ccmode (insn, CCGOCmode)
11748   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11749   && (optimize_size
11750       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11751  "sar{l}\t{%2, %0|%0, %2}"
11752  [(set_attr "type" "ishift")
11753   (set_attr "mode" "SI")])
11754
11755(define_insn "*ashrsi3_cmp_zext"
11756  [(set (reg FLAGS_REG)
11757	(compare
11758	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11759		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11760	  (const_int 0)))
11761   (set (match_operand:DI 0 "register_operand" "=r")
11762	(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11763  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11764   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11765   && (optimize_size
11766       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11767  "sar{l}\t{%2, %k0|%k0, %2}"
11768  [(set_attr "type" "ishift")
11769   (set_attr "mode" "SI")])
11770
11771(define_expand "ashrhi3"
11772  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11773	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11774		     (match_operand:QI 2 "nonmemory_operand" "")))
11775   (clobber (reg:CC FLAGS_REG))]
11776  "TARGET_HIMODE_MATH"
11777  "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11778
11779(define_insn "*ashrhi3_1_one_bit"
11780  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11781	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782		     (match_operand:QI 2 "const1_operand" "")))
11783   (clobber (reg:CC FLAGS_REG))]
11784  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11785   && (TARGET_SHIFT1 || optimize_size)"
11786  "sar{w}\t%0"
11787  [(set_attr "type" "ishift")
11788   (set (attr "length") 
11789     (if_then_else (match_operand 0 "register_operand" "") 
11790	(const_string "2")
11791	(const_string "*")))])
11792
11793(define_insn "*ashrhi3_1"
11794  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11795	(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11796		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11797   (clobber (reg:CC FLAGS_REG))]
11798  "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11799  "@
11800   sar{w}\t{%2, %0|%0, %2}
11801   sar{w}\t{%b2, %0|%0, %b2}"
11802  [(set_attr "type" "ishift")
11803   (set_attr "mode" "HI")])
11804
11805;; This pattern can't accept a variable shift count, since shifts by
11806;; zero don't affect the flags.  We assume that shifts by constant
11807;; zero are optimized away.
11808(define_insn "*ashrhi3_one_bit_cmp"
11809  [(set (reg FLAGS_REG)
11810	(compare
11811	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11812		       (match_operand:QI 2 "const1_operand" ""))
11813	  (const_int 0)))
11814   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11815	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11816  "ix86_match_ccmode (insn, CCGOCmode)
11817   && (TARGET_SHIFT1 || optimize_size)
11818   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11819  "sar{w}\t%0"
11820  [(set_attr "type" "ishift")
11821   (set (attr "length") 
11822     (if_then_else (match_operand 0 "register_operand" "") 
11823	(const_string "2")
11824	(const_string "*")))])
11825
11826(define_insn "*ashrhi3_one_bit_cconly"
11827  [(set (reg FLAGS_REG)
11828	(compare
11829	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11830		       (match_operand:QI 2 "const1_operand" ""))
11831	  (const_int 0)))
11832   (clobber (match_scratch:HI 0 "=r"))]
11833  "ix86_match_ccmode (insn, CCGOCmode)
11834   && (TARGET_SHIFT1 || optimize_size)
11835   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11836  "sar{w}\t%0"
11837  [(set_attr "type" "ishift")
11838   (set_attr "length" "2")])
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 "*ashrhi3_cmp"
11844  [(set (reg FLAGS_REG)
11845	(compare
11846	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11847		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11848	  (const_int 0)))
11849   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11850	(ashiftrt:HI (match_dup 1) (match_dup 2)))]
11851  "ix86_match_ccmode (insn, CCGOCmode)
11852   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11853   && (optimize_size
11854       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11855  "sar{w}\t{%2, %0|%0, %2}"
11856  [(set_attr "type" "ishift")
11857   (set_attr "mode" "HI")])
11858
11859(define_insn "*ashrhi3_cconly"
11860  [(set (reg FLAGS_REG)
11861	(compare
11862	  (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11863		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11864	  (const_int 0)))
11865   (clobber (match_scratch:HI 0 "=r"))]
11866  "ix86_match_ccmode (insn, CCGOCmode)
11867   && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11868   && (optimize_size
11869       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11870  "sar{w}\t{%2, %0|%0, %2}"
11871  [(set_attr "type" "ishift")
11872   (set_attr "mode" "HI")])
11873
11874(define_expand "ashrqi3"
11875  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11876	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11877		     (match_operand:QI 2 "nonmemory_operand" "")))
11878   (clobber (reg:CC FLAGS_REG))]
11879  "TARGET_QIMODE_MATH"
11880  "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11881
11882(define_insn "*ashrqi3_1_one_bit"
11883  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11884	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11885		     (match_operand:QI 2 "const1_operand" "")))
11886   (clobber (reg:CC FLAGS_REG))]
11887  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11888   && (TARGET_SHIFT1 || optimize_size)"
11889  "sar{b}\t%0"
11890  [(set_attr "type" "ishift")
11891   (set (attr "length") 
11892     (if_then_else (match_operand 0 "register_operand" "") 
11893	(const_string "2")
11894	(const_string "*")))])
11895
11896(define_insn "*ashrqi3_1_one_bit_slp"
11897  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11898	(ashiftrt:QI (match_dup 0)
11899		     (match_operand:QI 1 "const1_operand" "")))
11900   (clobber (reg:CC FLAGS_REG))]
11901  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11902   && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11903   && (TARGET_SHIFT1 || optimize_size)"
11904  "sar{b}\t%0"
11905  [(set_attr "type" "ishift1")
11906   (set (attr "length") 
11907     (if_then_else (match_operand 0 "register_operand" "") 
11908	(const_string "2")
11909	(const_string "*")))])
11910
11911(define_insn "*ashrqi3_1"
11912  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11913	(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11914		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
11915   (clobber (reg:CC FLAGS_REG))]
11916  "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11917  "@
11918   sar{b}\t{%2, %0|%0, %2}
11919   sar{b}\t{%b2, %0|%0, %b2}"
11920  [(set_attr "type" "ishift")
11921   (set_attr "mode" "QI")])
11922
11923(define_insn "*ashrqi3_1_slp"
11924  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11925	(ashiftrt:QI (match_dup 0)
11926		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
11927   (clobber (reg:CC FLAGS_REG))]
11928  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11929   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11930  "@
11931   sar{b}\t{%1, %0|%0, %1}
11932   sar{b}\t{%b1, %0|%0, %b1}"
11933  [(set_attr "type" "ishift1")
11934   (set_attr "mode" "QI")])
11935
11936;; This pattern can't accept a variable shift count, since shifts by
11937;; zero don't affect the flags.  We assume that shifts by constant
11938;; zero are optimized away.
11939(define_insn "*ashrqi3_one_bit_cmp"
11940  [(set (reg FLAGS_REG)
11941	(compare
11942	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11943		       (match_operand:QI 2 "const1_operand" "I"))
11944	  (const_int 0)))
11945   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11947  "ix86_match_ccmode (insn, CCGOCmode)
11948   && (TARGET_SHIFT1 || optimize_size)
11949   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11950  "sar{b}\t%0"
11951  [(set_attr "type" "ishift")
11952   (set (attr "length") 
11953     (if_then_else (match_operand 0 "register_operand" "") 
11954	(const_string "2")
11955	(const_string "*")))])
11956
11957(define_insn "*ashrqi3_one_bit_cconly"
11958  [(set (reg FLAGS_REG)
11959	(compare
11960	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11961		       (match_operand:QI 2 "const1_operand" "I"))
11962	  (const_int 0)))
11963   (clobber (match_scratch:QI 0 "=q"))]
11964  "ix86_match_ccmode (insn, CCGOCmode)
11965   && (TARGET_SHIFT1 || optimize_size)
11966   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11967  "sar{b}\t%0"
11968  [(set_attr "type" "ishift")
11969   (set_attr "length" "2")])
11970
11971;; This pattern can't accept a variable shift count, since shifts by
11972;; zero don't affect the flags.  We assume that shifts by constant
11973;; zero are optimized away.
11974(define_insn "*ashrqi3_cmp"
11975  [(set (reg FLAGS_REG)
11976	(compare
11977	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11978		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11979	  (const_int 0)))
11980   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11981	(ashiftrt:QI (match_dup 1) (match_dup 2)))]
11982  "ix86_match_ccmode (insn, CCGOCmode)
11983   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11984   && (optimize_size
11985       || !TARGET_PARTIAL_FLAG_REG_STALL)"
11986  "sar{b}\t{%2, %0|%0, %2}"
11987  [(set_attr "type" "ishift")
11988   (set_attr "mode" "QI")])
11989
11990(define_insn "*ashrqi3_cconly"
11991  [(set (reg FLAGS_REG)
11992	(compare
11993	  (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11994		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
11995	  (const_int 0)))
11996   (clobber (match_scratch:QI 0 "=q"))]
11997  "ix86_match_ccmode (insn, CCGOCmode)
11998   && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11999   && (optimize_size
12000       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12001  "sar{b}\t{%2, %0|%0, %2}"
12002  [(set_attr "type" "ishift")
12003   (set_attr "mode" "QI")])
12004
12005
12006;; Logical shift instructions
12007
12008;; See comment above `ashldi3' about how this works.
12009
12010(define_expand "lshrti3"
12011  [(parallel [(set (match_operand:TI 0 "register_operand" "")
12012		   (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12013			        (match_operand:QI 2 "nonmemory_operand" "")))
12014	      (clobber (reg:CC FLAGS_REG))])]
12015  "TARGET_64BIT"
12016{
12017  if (! immediate_operand (operands[2], QImode))
12018    {
12019      emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12020      DONE;
12021    }
12022  ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12023  DONE;
12024})
12025
12026(define_insn "lshrti3_1"
12027  [(set (match_operand:TI 0 "register_operand" "=r")
12028	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12029		     (match_operand:QI 2 "register_operand" "c")))
12030   (clobber (match_scratch:DI 3 "=&r"))
12031   (clobber (reg:CC FLAGS_REG))]
12032  "TARGET_64BIT"
12033  "#"
12034  [(set_attr "type" "multi")])
12035
12036(define_insn "*lshrti3_2"
12037  [(set (match_operand:TI 0 "register_operand" "=r")
12038	(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12039		     (match_operand:QI 2 "immediate_operand" "O")))
12040   (clobber (reg:CC FLAGS_REG))]
12041  "TARGET_64BIT"
12042  "#"
12043  [(set_attr "type" "multi")])
12044
12045(define_split 
12046  [(set (match_operand:TI 0 "register_operand" "")
12047	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12048		     (match_operand:QI 2 "register_operand" "")))
12049   (clobber (match_scratch:DI 3 ""))
12050   (clobber (reg:CC FLAGS_REG))]
12051  "TARGET_64BIT && reload_completed"
12052  [(const_int 0)]
12053  "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12054
12055(define_split 
12056  [(set (match_operand:TI 0 "register_operand" "")
12057	(lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12058		     (match_operand:QI 2 "immediate_operand" "")))
12059   (clobber (reg:CC FLAGS_REG))]
12060  "TARGET_64BIT && reload_completed"
12061  [(const_int 0)]
12062  "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12063
12064(define_expand "lshrdi3"
12065  [(set (match_operand:DI 0 "shiftdi_operand" "")
12066	(lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12067		     (match_operand:QI 2 "nonmemory_operand" "")))]
12068  ""
12069  "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12070
12071(define_insn "*lshrdi3_1_one_bit_rex64"
12072  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12073	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074		     (match_operand:QI 2 "const1_operand" "")))
12075   (clobber (reg:CC FLAGS_REG))]
12076  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12077   && (TARGET_SHIFT1 || optimize_size)"
12078  "shr{q}\t%0"
12079  [(set_attr "type" "ishift")
12080   (set (attr "length") 
12081     (if_then_else (match_operand:DI 0 "register_operand" "") 
12082	(const_string "2")
12083	(const_string "*")))])
12084
12085(define_insn "*lshrdi3_1_rex64"
12086  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12087	(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12088		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12089   (clobber (reg:CC FLAGS_REG))]
12090  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12091  "@
12092   shr{q}\t{%2, %0|%0, %2}
12093   shr{q}\t{%b2, %0|%0, %b2}"
12094  [(set_attr "type" "ishift")
12095   (set_attr "mode" "DI")])
12096
12097;; This pattern can't accept a variable shift count, since shifts by
12098;; zero don't affect the flags.  We assume that shifts by constant
12099;; zero are optimized away.
12100(define_insn "*lshrdi3_cmp_one_bit_rex64"
12101  [(set (reg FLAGS_REG)
12102	(compare
12103	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12104		       (match_operand:QI 2 "const1_operand" ""))
12105	  (const_int 0)))
12106   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12107	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12108  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12109   && (TARGET_SHIFT1 || optimize_size)
12110   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12111  "shr{q}\t%0"
12112  [(set_attr "type" "ishift")
12113   (set (attr "length") 
12114     (if_then_else (match_operand:DI 0 "register_operand" "") 
12115	(const_string "2")
12116	(const_string "*")))])
12117
12118(define_insn "*lshrdi3_cconly_one_bit_rex64"
12119  [(set (reg FLAGS_REG)
12120	(compare
12121	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12122		       (match_operand:QI 2 "const1_operand" ""))
12123	  (const_int 0)))
12124   (clobber (match_scratch:DI 0 "=r"))]
12125  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12126   && (TARGET_SHIFT1 || optimize_size)
12127   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12128  "shr{q}\t%0"
12129  [(set_attr "type" "ishift")
12130   (set_attr "length" "2")])
12131
12132;; This pattern can't accept a variable shift count, since shifts by
12133;; zero don't affect the flags.  We assume that shifts by constant
12134;; zero are optimized away.
12135(define_insn "*lshrdi3_cmp_rex64"
12136  [(set (reg FLAGS_REG)
12137	(compare
12138	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12139		       (match_operand:QI 2 "const_int_operand" "e"))
12140	  (const_int 0)))
12141   (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12142	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
12143  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12144   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12145   && (optimize_size
12146       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12147  "shr{q}\t{%2, %0|%0, %2}"
12148  [(set_attr "type" "ishift")
12149   (set_attr "mode" "DI")])
12150
12151(define_insn "*lshrdi3_cconly_rex64"
12152  [(set (reg FLAGS_REG)
12153	(compare
12154	  (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12155		       (match_operand:QI 2 "const_int_operand" "e"))
12156	  (const_int 0)))
12157   (clobber (match_scratch:DI 0 "=r"))]
12158  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12159   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12160   && (optimize_size
12161       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12162  "shr{q}\t{%2, %0|%0, %2}"
12163  [(set_attr "type" "ishift")
12164   (set_attr "mode" "DI")])
12165
12166(define_insn "*lshrdi3_1"
12167  [(set (match_operand:DI 0 "register_operand" "=r")
12168	(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12169		     (match_operand:QI 2 "nonmemory_operand" "Jc")))
12170   (clobber (reg:CC FLAGS_REG))]
12171  "!TARGET_64BIT"
12172  "#"
12173  [(set_attr "type" "multi")])
12174
12175;; By default we don't ask for a scratch register, because when DImode
12176;; values are manipulated, registers are already at a premium.  But if
12177;; we have one handy, we won't turn it away.
12178(define_peephole2
12179  [(match_scratch:SI 3 "r")
12180   (parallel [(set (match_operand:DI 0 "register_operand" "")
12181		   (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12182			        (match_operand:QI 2 "nonmemory_operand" "")))
12183	      (clobber (reg:CC FLAGS_REG))])
12184   (match_dup 3)]
12185  "!TARGET_64BIT && TARGET_CMOVE"
12186  [(const_int 0)]
12187  "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12188
12189(define_split 
12190  [(set (match_operand:DI 0 "register_operand" "")
12191	(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12192		     (match_operand:QI 2 "nonmemory_operand" "")))
12193   (clobber (reg:CC FLAGS_REG))]
12194  "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12195		     ? flow2_completed : reload_completed)"
12196  [(const_int 0)]
12197  "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12198
12199(define_expand "lshrsi3"
12200  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12201	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12202		     (match_operand:QI 2 "nonmemory_operand" "")))
12203   (clobber (reg:CC FLAGS_REG))]
12204  ""
12205  "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12206
12207(define_insn "*lshrsi3_1_one_bit"
12208  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12209	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12210		     (match_operand:QI 2 "const1_operand" "")))
12211   (clobber (reg:CC FLAGS_REG))]
12212  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12213   && (TARGET_SHIFT1 || optimize_size)"
12214  "shr{l}\t%0"
12215  [(set_attr "type" "ishift")
12216   (set (attr "length") 
12217     (if_then_else (match_operand:SI 0 "register_operand" "") 
12218	(const_string "2")
12219	(const_string "*")))])
12220
12221(define_insn "*lshrsi3_1_one_bit_zext"
12222  [(set (match_operand:DI 0 "register_operand" "=r")
12223	(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12224		     (match_operand:QI 2 "const1_operand" "")))
12225   (clobber (reg:CC FLAGS_REG))]
12226  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12227   && (TARGET_SHIFT1 || optimize_size)"
12228  "shr{l}\t%k0"
12229  [(set_attr "type" "ishift")
12230   (set_attr "length" "2")])
12231
12232(define_insn "*lshrsi3_1"
12233  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12234	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12235		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12236   (clobber (reg:CC FLAGS_REG))]
12237  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12238  "@
12239   shr{l}\t{%2, %0|%0, %2}
12240   shr{l}\t{%b2, %0|%0, %b2}"
12241  [(set_attr "type" "ishift")
12242   (set_attr "mode" "SI")])
12243
12244(define_insn "*lshrsi3_1_zext"
12245  [(set (match_operand:DI 0 "register_operand" "=r,r")
12246	(zero_extend:DI
12247	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12248		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12249   (clobber (reg:CC FLAGS_REG))]
12250  "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12251  "@
12252   shr{l}\t{%2, %k0|%k0, %2}
12253   shr{l}\t{%b2, %k0|%k0, %b2}"
12254  [(set_attr "type" "ishift")
12255   (set_attr "mode" "SI")])
12256
12257;; This pattern can't accept a variable shift count, since shifts by
12258;; zero don't affect the flags.  We assume that shifts by constant
12259;; zero are optimized away.
12260(define_insn "*lshrsi3_one_bit_cmp"
12261  [(set (reg FLAGS_REG)
12262	(compare
12263	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12264		       (match_operand:QI 2 "const1_operand" ""))
12265	  (const_int 0)))
12266   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12267	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12268  "ix86_match_ccmode (insn, CCGOCmode)
12269   && (TARGET_SHIFT1 || optimize_size)
12270   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12271  "shr{l}\t%0"
12272  [(set_attr "type" "ishift")
12273   (set (attr "length") 
12274     (if_then_else (match_operand:SI 0 "register_operand" "") 
12275	(const_string "2")
12276	(const_string "*")))])
12277
12278(define_insn "*lshrsi3_one_bit_cconly"
12279  [(set (reg FLAGS_REG)
12280	(compare
12281	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282		       (match_operand:QI 2 "const1_operand" ""))
12283	  (const_int 0)))
12284   (clobber (match_scratch:SI 0 "=r"))]
12285  "ix86_match_ccmode (insn, CCGOCmode)
12286   && (TARGET_SHIFT1 || optimize_size)
12287   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12288  "shr{l}\t%0"
12289  [(set_attr "type" "ishift")
12290   (set_attr "length" "2")])
12291
12292(define_insn "*lshrsi3_cmp_one_bit_zext"
12293  [(set (reg FLAGS_REG)
12294	(compare
12295	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296		       (match_operand:QI 2 "const1_operand" ""))
12297	  (const_int 0)))
12298   (set (match_operand:DI 0 "register_operand" "=r")
12299	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12300  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12301   && (TARGET_SHIFT1 || optimize_size)
12302   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12303  "shr{l}\t%k0"
12304  [(set_attr "type" "ishift")
12305   (set_attr "length" "2")])
12306
12307;; This pattern can't accept a variable shift count, since shifts by
12308;; zero don't affect the flags.  We assume that shifts by constant
12309;; zero are optimized away.
12310(define_insn "*lshrsi3_cmp"
12311  [(set (reg FLAGS_REG)
12312	(compare
12313	  (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12315	  (const_int 0)))
12316   (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
12318  "ix86_match_ccmode (insn, CCGOCmode)
12319   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12320   && (optimize_size
12321       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12322  "shr{l}\t{%2, %0|%0, %2}"
12323  [(set_attr "type" "ishift")
12324   (set_attr "mode" "SI")])
12325
12326(define_insn "*lshrsi3_cconly"
12327  [(set (reg FLAGS_REG)
12328      (compare
12329	(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12330		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
12331        (const_int 0)))
12332   (clobber (match_scratch:SI 0 "=r"))]
12333  "ix86_match_ccmode (insn, CCGOCmode)
12334   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12335   && (optimize_size
12336       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12337  "shr{l}\t{%2, %0|%0, %2}"
12338  [(set_attr "type" "ishift")
12339   (set_attr "mode" "SI")])
12340
12341(define_insn "*lshrsi3_cmp_zext"
12342  [(set (reg FLAGS_REG)
12343	(compare
12344	  (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12345		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12346	  (const_int 0)))
12347   (set (match_operand:DI 0 "register_operand" "=r")
12348	(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12349  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12350   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12351   && (optimize_size
12352       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12353  "shr{l}\t{%2, %k0|%k0, %2}"
12354  [(set_attr "type" "ishift")
12355   (set_attr "mode" "SI")])
12356
12357(define_expand "lshrhi3"
12358  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12359	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12360		     (match_operand:QI 2 "nonmemory_operand" "")))
12361   (clobber (reg:CC FLAGS_REG))]
12362  "TARGET_HIMODE_MATH"
12363  "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12364
12365(define_insn "*lshrhi3_1_one_bit"
12366  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12367	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368		     (match_operand:QI 2 "const1_operand" "")))
12369   (clobber (reg:CC FLAGS_REG))]
12370  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12371   && (TARGET_SHIFT1 || optimize_size)"
12372  "shr{w}\t%0"
12373  [(set_attr "type" "ishift")
12374   (set (attr "length") 
12375     (if_then_else (match_operand 0 "register_operand" "") 
12376	(const_string "2")
12377	(const_string "*")))])
12378
12379(define_insn "*lshrhi3_1"
12380  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12381	(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12382		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12383   (clobber (reg:CC FLAGS_REG))]
12384  "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12385  "@
12386   shr{w}\t{%2, %0|%0, %2}
12387   shr{w}\t{%b2, %0|%0, %b2}"
12388  [(set_attr "type" "ishift")
12389   (set_attr "mode" "HI")])
12390
12391;; This pattern can't accept a variable shift count, since shifts by
12392;; zero don't affect the flags.  We assume that shifts by constant
12393;; zero are optimized away.
12394(define_insn "*lshrhi3_one_bit_cmp"
12395  [(set (reg FLAGS_REG)
12396	(compare
12397	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12398		       (match_operand:QI 2 "const1_operand" ""))
12399	  (const_int 0)))
12400   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12401	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12402  "ix86_match_ccmode (insn, CCGOCmode)
12403   && (TARGET_SHIFT1 || optimize_size)
12404   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12405  "shr{w}\t%0"
12406  [(set_attr "type" "ishift")
12407   (set (attr "length") 
12408     (if_then_else (match_operand:SI 0 "register_operand" "") 
12409	(const_string "2")
12410	(const_string "*")))])
12411
12412(define_insn "*lshrhi3_one_bit_cconly"
12413  [(set (reg FLAGS_REG)
12414	(compare
12415	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12416		       (match_operand:QI 2 "const1_operand" ""))
12417	  (const_int 0)))
12418   (clobber (match_scratch:HI 0 "=r"))]
12419  "ix86_match_ccmode (insn, CCGOCmode)
12420   && (TARGET_SHIFT1 || optimize_size)
12421   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12422  "shr{w}\t%0"
12423  [(set_attr "type" "ishift")
12424   (set_attr "length" "2")])
12425
12426;; This pattern can't accept a variable shift count, since shifts by
12427;; zero don't affect the flags.  We assume that shifts by constant
12428;; zero are optimized away.
12429(define_insn "*lshrhi3_cmp"
12430  [(set (reg FLAGS_REG)
12431	(compare
12432	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12433		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12434	  (const_int 0)))
12435   (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12436	(lshiftrt:HI (match_dup 1) (match_dup 2)))]
12437  "ix86_match_ccmode (insn, CCGOCmode)
12438   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12439   && (optimize_size
12440       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12441  "shr{w}\t{%2, %0|%0, %2}"
12442  [(set_attr "type" "ishift")
12443   (set_attr "mode" "HI")])
12444
12445(define_insn "*lshrhi3_cconly"
12446  [(set (reg FLAGS_REG)
12447	(compare
12448	  (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12449		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12450	  (const_int 0)))
12451   (clobber (match_scratch:HI 0 "=r"))]
12452  "ix86_match_ccmode (insn, CCGOCmode)
12453   && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12454   && (optimize_size
12455       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12456  "shr{w}\t{%2, %0|%0, %2}"
12457  [(set_attr "type" "ishift")
12458   (set_attr "mode" "HI")])
12459
12460(define_expand "lshrqi3"
12461  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12462	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12463		     (match_operand:QI 2 "nonmemory_operand" "")))
12464   (clobber (reg:CC FLAGS_REG))]
12465  "TARGET_QIMODE_MATH"
12466  "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12467
12468(define_insn "*lshrqi3_1_one_bit"
12469  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12470	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12471		     (match_operand:QI 2 "const1_operand" "")))
12472   (clobber (reg:CC FLAGS_REG))]
12473  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12474   && (TARGET_SHIFT1 || optimize_size)"
12475  "shr{b}\t%0"
12476  [(set_attr "type" "ishift")
12477   (set (attr "length") 
12478     (if_then_else (match_operand 0 "register_operand" "") 
12479	(const_string "2")
12480	(const_string "*")))])
12481
12482(define_insn "*lshrqi3_1_one_bit_slp"
12483  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12484	(lshiftrt:QI (match_dup 0)
12485		     (match_operand:QI 1 "const1_operand" "")))
12486   (clobber (reg:CC FLAGS_REG))]
12487  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12488   && (TARGET_SHIFT1 || optimize_size)"
12489  "shr{b}\t%0"
12490  [(set_attr "type" "ishift1")
12491   (set (attr "length") 
12492     (if_then_else (match_operand 0 "register_operand" "") 
12493	(const_string "2")
12494	(const_string "*")))])
12495
12496(define_insn "*lshrqi3_1"
12497  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12498	(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12499		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12500   (clobber (reg:CC FLAGS_REG))]
12501  "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12502  "@
12503   shr{b}\t{%2, %0|%0, %2}
12504   shr{b}\t{%b2, %0|%0, %b2}"
12505  [(set_attr "type" "ishift")
12506   (set_attr "mode" "QI")])
12507
12508(define_insn "*lshrqi3_1_slp"
12509  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12510	(lshiftrt:QI (match_dup 0)
12511		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
12512   (clobber (reg:CC FLAGS_REG))]
12513  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12514   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12515  "@
12516   shr{b}\t{%1, %0|%0, %1}
12517   shr{b}\t{%b1, %0|%0, %b1}"
12518  [(set_attr "type" "ishift1")
12519   (set_attr "mode" "QI")])
12520
12521;; This pattern can't accept a variable shift count, since shifts by
12522;; zero don't affect the flags.  We assume that shifts by constant
12523;; zero are optimized away.
12524(define_insn "*lshrqi2_one_bit_cmp"
12525  [(set (reg FLAGS_REG)
12526	(compare
12527	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12528		       (match_operand:QI 2 "const1_operand" ""))
12529	  (const_int 0)))
12530   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12531	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12532  "ix86_match_ccmode (insn, CCGOCmode)
12533   && (TARGET_SHIFT1 || optimize_size)
12534   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12535  "shr{b}\t%0"
12536  [(set_attr "type" "ishift")
12537   (set (attr "length") 
12538     (if_then_else (match_operand:SI 0 "register_operand" "") 
12539	(const_string "2")
12540	(const_string "*")))])
12541
12542(define_insn "*lshrqi2_one_bit_cconly"
12543  [(set (reg FLAGS_REG)
12544	(compare
12545	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12546		       (match_operand:QI 2 "const1_operand" ""))
12547	  (const_int 0)))
12548   (clobber (match_scratch:QI 0 "=q"))]
12549  "ix86_match_ccmode (insn, CCGOCmode)
12550   && (TARGET_SHIFT1 || optimize_size)
12551   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12552  "shr{b}\t%0"
12553  [(set_attr "type" "ishift")
12554   (set_attr "length" "2")])
12555
12556;; This pattern can't accept a variable shift count, since shifts by
12557;; zero don't affect the flags.  We assume that shifts by constant
12558;; zero are optimized away.
12559(define_insn "*lshrqi2_cmp"
12560  [(set (reg FLAGS_REG)
12561	(compare
12562	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12563		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12564	  (const_int 0)))
12565   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12566	(lshiftrt:QI (match_dup 1) (match_dup 2)))]
12567  "ix86_match_ccmode (insn, CCGOCmode)
12568   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12569   && (optimize_size
12570       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12571  "shr{b}\t{%2, %0|%0, %2}"
12572  [(set_attr "type" "ishift")
12573   (set_attr "mode" "QI")])
12574
12575(define_insn "*lshrqi2_cconly"
12576  [(set (reg FLAGS_REG)
12577	(compare
12578	  (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12579		       (match_operand:QI 2 "const_1_to_31_operand" "I"))
12580	  (const_int 0)))
12581   (clobber (match_scratch:QI 0 "=q"))]
12582  "ix86_match_ccmode (insn, CCGOCmode)
12583   && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12584   && (optimize_size
12585       || !TARGET_PARTIAL_FLAG_REG_STALL)"
12586  "shr{b}\t{%2, %0|%0, %2}"
12587  [(set_attr "type" "ishift")
12588   (set_attr "mode" "QI")])
12589
12590;; Rotate instructions
12591
12592(define_expand "rotldi3"
12593  [(set (match_operand:DI 0 "shiftdi_operand" "")
12594	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12595		   (match_operand:QI 2 "nonmemory_operand" "")))
12596   (clobber (reg:CC FLAGS_REG))]
12597 ""
12598{
12599  if (TARGET_64BIT)
12600    {
12601      ix86_expand_binary_operator (ROTATE, DImode, operands);
12602      DONE;
12603    }
12604  if (!const_1_to_31_operand (operands[2], VOIDmode))
12605    FAIL;
12606  emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12607  DONE;
12608})
12609
12610;; Implement rotation using two double-precision shift instructions
12611;; and a scratch register.   
12612(define_insn_and_split "ix86_rotldi3"
12613 [(set (match_operand:DI 0 "register_operand" "=r")
12614       (rotate:DI (match_operand:DI 1 "register_operand" "0")
12615                  (match_operand:QI 2 "const_1_to_31_operand" "I")))
12616  (clobber (reg:CC FLAGS_REG))
12617  (clobber (match_scratch:SI 3 "=&r"))]
12618 "!TARGET_64BIT"
12619 "" 
12620 "&& reload_completed"
12621 [(set (match_dup 3) (match_dup 4))
12622  (parallel
12623   [(set (match_dup 4)
12624         (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12625                 (lshiftrt:SI (match_dup 5)
12626                              (minus:QI (const_int 32) (match_dup 2)))))
12627    (clobber (reg:CC FLAGS_REG))])
12628  (parallel
12629   [(set (match_dup 5)
12630         (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12631                 (lshiftrt:SI (match_dup 3)
12632                              (minus:QI (const_int 32) (match_dup 2)))))
12633    (clobber (reg:CC FLAGS_REG))])]
12634 "split_di (operands, 1, operands + 4, operands + 5);")
12635 
12636(define_insn "*rotlsi3_1_one_bit_rex64"
12637  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12638	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12639		   (match_operand:QI 2 "const1_operand" "")))
12640   (clobber (reg:CC FLAGS_REG))]
12641  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12642   && (TARGET_SHIFT1 || optimize_size)"
12643  "rol{q}\t%0"
12644  [(set_attr "type" "rotate")
12645   (set (attr "length") 
12646     (if_then_else (match_operand:DI 0 "register_operand" "") 
12647	(const_string "2")
12648	(const_string "*")))])
12649
12650(define_insn "*rotldi3_1_rex64"
12651  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12652	(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12653		   (match_operand:QI 2 "nonmemory_operand" "e,c")))
12654   (clobber (reg:CC FLAGS_REG))]
12655  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12656  "@
12657   rol{q}\t{%2, %0|%0, %2}
12658   rol{q}\t{%b2, %0|%0, %b2}"
12659  [(set_attr "type" "rotate")
12660   (set_attr "mode" "DI")])
12661
12662(define_expand "rotlsi3"
12663  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12664	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12665		   (match_operand:QI 2 "nonmemory_operand" "")))
12666   (clobber (reg:CC FLAGS_REG))]
12667  ""
12668  "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12669
12670(define_insn "*rotlsi3_1_one_bit"
12671  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12672	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12673		   (match_operand:QI 2 "const1_operand" "")))
12674   (clobber (reg:CC FLAGS_REG))]
12675  "ix86_binary_operator_ok (ROTATE, SImode, operands)
12676   && (TARGET_SHIFT1 || optimize_size)"
12677  "rol{l}\t%0"
12678  [(set_attr "type" "rotate")
12679   (set (attr "length") 
12680     (if_then_else (match_operand:SI 0 "register_operand" "") 
12681	(const_string "2")
12682	(const_string "*")))])
12683
12684(define_insn "*rotlsi3_1_one_bit_zext"
12685  [(set (match_operand:DI 0 "register_operand" "=r")
12686	(zero_extend:DI
12687	  (rotate:SI (match_operand:SI 1 "register_operand" "0")
12688		     (match_operand:QI 2 "const1_operand" ""))))
12689   (clobber (reg:CC FLAGS_REG))]
12690  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12691   && (TARGET_SHIFT1 || optimize_size)"
12692  "rol{l}\t%k0"
12693  [(set_attr "type" "rotate")
12694   (set_attr "length" "2")])
12695
12696(define_insn "*rotlsi3_1"
12697  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12698	(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12699		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700   (clobber (reg:CC FLAGS_REG))]
12701  "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12702  "@
12703   rol{l}\t{%2, %0|%0, %2}
12704   rol{l}\t{%b2, %0|%0, %b2}"
12705  [(set_attr "type" "rotate")
12706   (set_attr "mode" "SI")])
12707
12708(define_insn "*rotlsi3_1_zext"
12709  [(set (match_operand:DI 0 "register_operand" "=r,r")
12710	(zero_extend:DI
12711	  (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12712		     (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12713   (clobber (reg:CC FLAGS_REG))]
12714  "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12715  "@
12716   rol{l}\t{%2, %k0|%k0, %2}
12717   rol{l}\t{%b2, %k0|%k0, %b2}"
12718  [(set_attr "type" "rotate")
12719   (set_attr "mode" "SI")])
12720
12721(define_expand "rotlhi3"
12722  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12723	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12724		   (match_operand:QI 2 "nonmemory_operand" "")))
12725   (clobber (reg:CC FLAGS_REG))]
12726  "TARGET_HIMODE_MATH"
12727  "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12728
12729(define_insn "*rotlhi3_1_one_bit"
12730  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12731	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12732		   (match_operand:QI 2 "const1_operand" "")))
12733   (clobber (reg:CC FLAGS_REG))]
12734  "ix86_binary_operator_ok (ROTATE, HImode, operands)
12735   && (TARGET_SHIFT1 || optimize_size)"
12736  "rol{w}\t%0"
12737  [(set_attr "type" "rotate")
12738   (set (attr "length") 
12739     (if_then_else (match_operand 0 "register_operand" "") 
12740	(const_string "2")
12741	(const_string "*")))])
12742
12743(define_insn "*rotlhi3_1"
12744  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12745	(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12746		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12747   (clobber (reg:CC FLAGS_REG))]
12748  "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12749  "@
12750   rol{w}\t{%2, %0|%0, %2}
12751   rol{w}\t{%b2, %0|%0, %b2}"
12752  [(set_attr "type" "rotate")
12753   (set_attr "mode" "HI")])
12754
12755(define_expand "rotlqi3"
12756  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12757	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12758		   (match_operand:QI 2 "nonmemory_operand" "")))
12759   (clobber (reg:CC FLAGS_REG))]
12760  "TARGET_QIMODE_MATH"
12761  "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12762
12763(define_insn "*rotlqi3_1_one_bit_slp"
12764  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12765	(rotate:QI (match_dup 0)
12766		   (match_operand:QI 1 "const1_operand" "")))
12767   (clobber (reg:CC FLAGS_REG))]
12768  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12769   && (TARGET_SHIFT1 || optimize_size)"
12770  "rol{b}\t%0"
12771  [(set_attr "type" "rotate1")
12772   (set (attr "length") 
12773     (if_then_else (match_operand 0 "register_operand" "") 
12774	(const_string "2")
12775	(const_string "*")))])
12776
12777(define_insn "*rotlqi3_1_one_bit"
12778  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12779	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12780		   (match_operand:QI 2 "const1_operand" "")))
12781   (clobber (reg:CC FLAGS_REG))]
12782  "ix86_binary_operator_ok (ROTATE, QImode, operands)
12783   && (TARGET_SHIFT1 || optimize_size)"
12784  "rol{b}\t%0"
12785  [(set_attr "type" "rotate")
12786   (set (attr "length") 
12787     (if_then_else (match_operand 0 "register_operand" "") 
12788	(const_string "2")
12789	(const_string "*")))])
12790
12791(define_insn "*rotlqi3_1_slp"
12792  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12793	(rotate:QI (match_dup 0)
12794		   (match_operand:QI 1 "nonmemory_operand" "I,c")))
12795   (clobber (reg:CC FLAGS_REG))]
12796  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12797   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12798  "@
12799   rol{b}\t{%1, %0|%0, %1}
12800   rol{b}\t{%b1, %0|%0, %b1}"
12801  [(set_attr "type" "rotate1")
12802   (set_attr "mode" "QI")])
12803
12804(define_insn "*rotlqi3_1"
12805  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12806	(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12807		   (match_operand:QI 2 "nonmemory_operand" "I,c")))
12808   (clobber (reg:CC FLAGS_REG))]
12809  "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12810  "@
12811   rol{b}\t{%2, %0|%0, %2}
12812   rol{b}\t{%b2, %0|%0, %b2}"
12813  [(set_attr "type" "rotate")
12814   (set_attr "mode" "QI")])
12815
12816(define_expand "rotrdi3"
12817  [(set (match_operand:DI 0 "shiftdi_operand" "")
12818	(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12819		   (match_operand:QI 2 "nonmemory_operand" "")))
12820   (clobber (reg:CC FLAGS_REG))]
12821 ""
12822{
12823  if (TARGET_64BIT)
12824    {
12825      ix86_expand_binary_operator (ROTATERT, DImode, operands);
12826      DONE;
12827    }
12828  if (!const_1_to_31_operand (operands[2], VOIDmode))
12829    FAIL;
12830  emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12831  DONE;
12832})
12833  
12834;; Implement rotation using two double-precision shift instructions
12835;; and a scratch register.   
12836(define_insn_and_split "ix86_rotrdi3"
12837 [(set (match_operand:DI 0 "register_operand" "=r")
12838       (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12839                    (match_operand:QI 2 "const_1_to_31_operand" "I")))
12840  (clobber (reg:CC FLAGS_REG))
12841  (clobber (match_scratch:SI 3 "=&r"))]
12842 "!TARGET_64BIT"
12843 ""
12844 "&& reload_completed"
12845 [(set (match_dup 3) (match_dup 4))
12846  (parallel
12847   [(set (match_dup 4)
12848         (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12849                 (ashift:SI (match_dup 5)
12850                            (minus:QI (const_int 32) (match_dup 2)))))
12851    (clobber (reg:CC FLAGS_REG))])
12852  (parallel
12853   [(set (match_dup 5)
12854         (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12855                 (ashift:SI (match_dup 3)
12856                            (minus:QI (const_int 32) (match_dup 2)))))
12857    (clobber (reg:CC FLAGS_REG))])]
12858 "split_di (operands, 1, operands + 4, operands + 5);")
12859
12860(define_insn "*rotrdi3_1_one_bit_rex64"
12861  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12862	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12863		     (match_operand:QI 2 "const1_operand" "")))
12864   (clobber (reg:CC FLAGS_REG))]
12865  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12866   && (TARGET_SHIFT1 || optimize_size)"
12867  "ror{q}\t%0"
12868  [(set_attr "type" "rotate")
12869   (set (attr "length") 
12870     (if_then_else (match_operand:DI 0 "register_operand" "") 
12871	(const_string "2")
12872	(const_string "*")))])
12873
12874(define_insn "*rotrdi3_1_rex64"
12875  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12876	(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12877		     (match_operand:QI 2 "nonmemory_operand" "J,c")))
12878   (clobber (reg:CC FLAGS_REG))]
12879  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12880  "@
12881   ror{q}\t{%2, %0|%0, %2}
12882   ror{q}\t{%b2, %0|%0, %b2}"
12883  [(set_attr "type" "rotate")
12884   (set_attr "mode" "DI")])
12885
12886(define_expand "rotrsi3"
12887  [(set (match_operand:SI 0 "nonimmediate_operand" "")
12888	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12889		     (match_operand:QI 2 "nonmemory_operand" "")))
12890   (clobber (reg:CC FLAGS_REG))]
12891  ""
12892  "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12893
12894(define_insn "*rotrsi3_1_one_bit"
12895  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12896	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12897		     (match_operand:QI 2 "const1_operand" "")))
12898   (clobber (reg:CC FLAGS_REG))]
12899  "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12900   && (TARGET_SHIFT1 || optimize_size)"
12901  "ror{l}\t%0"
12902  [(set_attr "type" "rotate")
12903   (set (attr "length") 
12904     (if_then_else (match_operand:SI 0 "register_operand" "") 
12905	(const_string "2")
12906	(const_string "*")))])
12907
12908(define_insn "*rotrsi3_1_one_bit_zext"
12909  [(set (match_operand:DI 0 "register_operand" "=r")
12910	(zero_extend:DI
12911	  (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12912		       (match_operand:QI 2 "const1_operand" ""))))
12913   (clobber (reg:CC FLAGS_REG))]
12914  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12915   && (TARGET_SHIFT1 || optimize_size)"
12916  "ror{l}\t%k0"
12917  [(set_attr "type" "rotate")
12918   (set (attr "length") 
12919     (if_then_else (match_operand:SI 0 "register_operand" "") 
12920	(const_string "2")
12921	(const_string "*")))])
12922
12923(define_insn "*rotrsi3_1"
12924  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12925	(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12926		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927   (clobber (reg:CC FLAGS_REG))]
12928  "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12929  "@
12930   ror{l}\t{%2, %0|%0, %2}
12931   ror{l}\t{%b2, %0|%0, %b2}"
12932  [(set_attr "type" "rotate")
12933   (set_attr "mode" "SI")])
12934
12935(define_insn "*rotrsi3_1_zext"
12936  [(set (match_operand:DI 0 "register_operand" "=r,r")
12937	(zero_extend:DI
12938	  (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12939		       (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12940   (clobber (reg:CC FLAGS_REG))]
12941  "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12942  "@
12943   ror{l}\t{%2, %k0|%k0, %2}
12944   ror{l}\t{%b2, %k0|%k0, %b2}"
12945  [(set_attr "type" "rotate")
12946   (set_attr "mode" "SI")])
12947
12948(define_expand "rotrhi3"
12949  [(set (match_operand:HI 0 "nonimmediate_operand" "")
12950	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12951		     (match_operand:QI 2 "nonmemory_operand" "")))
12952   (clobber (reg:CC FLAGS_REG))]
12953  "TARGET_HIMODE_MATH"
12954  "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12955
12956(define_insn "*rotrhi3_one_bit"
12957  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12958	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12959		     (match_operand:QI 2 "const1_operand" "")))
12960   (clobber (reg:CC FLAGS_REG))]
12961  "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12962   && (TARGET_SHIFT1 || optimize_size)"
12963  "ror{w}\t%0"
12964  [(set_attr "type" "rotate")
12965   (set (attr "length") 
12966     (if_then_else (match_operand 0 "register_operand" "") 
12967	(const_string "2")
12968	(const_string "*")))])
12969
12970(define_insn "*rotrhi3"
12971  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12972	(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12973		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
12974   (clobber (reg:CC FLAGS_REG))]
12975  "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12976  "@
12977   ror{w}\t{%2, %0|%0, %2}
12978   ror{w}\t{%b2, %0|%0, %b2}"
12979  [(set_attr "type" "rotate")
12980   (set_attr "mode" "HI")])
12981
12982(define_expand "rotrqi3"
12983  [(set (match_operand:QI 0 "nonimmediate_operand" "")
12984	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12985		     (match_operand:QI 2 "nonmemory_operand" "")))
12986   (clobber (reg:CC FLAGS_REG))]
12987  "TARGET_QIMODE_MATH"
12988  "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12989
12990(define_insn "*rotrqi3_1_one_bit"
12991  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12992	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12993		     (match_operand:QI 2 "const1_operand" "")))
12994   (clobber (reg:CC FLAGS_REG))]
12995  "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12996   && (TARGET_SHIFT1 || optimize_size)"
12997  "ror{b}\t%0"
12998  [(set_attr "type" "rotate")
12999   (set (attr "length") 
13000     (if_then_else (match_operand 0 "register_operand" "") 
13001	(const_string "2")
13002	(const_string "*")))])
13003
13004(define_insn "*rotrqi3_1_one_bit_slp"
13005  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13006	(rotatert:QI (match_dup 0)
13007		     (match_operand:QI 1 "const1_operand" "")))
13008   (clobber (reg:CC FLAGS_REG))]
13009  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13010   && (TARGET_SHIFT1 || optimize_size)"
13011  "ror{b}\t%0"
13012  [(set_attr "type" "rotate1")
13013   (set (attr "length") 
13014     (if_then_else (match_operand 0 "register_operand" "") 
13015	(const_string "2")
13016	(const_string "*")))])
13017
13018(define_insn "*rotrqi3_1"
13019  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13020	(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13021		     (match_operand:QI 2 "nonmemory_operand" "I,c")))
13022   (clobber (reg:CC FLAGS_REG))]
13023  "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13024  "@
13025   ror{b}\t{%2, %0|%0, %2}
13026   ror{b}\t{%b2, %0|%0, %b2}"
13027  [(set_attr "type" "rotate")
13028   (set_attr "mode" "QI")])
13029
13030(define_insn "*rotrqi3_1_slp"
13031  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13032	(rotatert:QI (match_dup 0)
13033		     (match_operand:QI 1 "nonmemory_operand" "I,c")))
13034   (clobber (reg:CC FLAGS_REG))]
13035  "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13036   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13037  "@
13038   ror{b}\t{%1, %0|%0, %1}
13039   ror{b}\t{%b1, %0|%0, %b1}"
13040  [(set_attr "type" "rotate1")
13041   (set_attr "mode" "QI")])
13042
13043;; Bit set / bit test instructions
13044
13045(define_expand "extv"
13046  [(set (match_operand:SI 0 "register_operand" "")
13047	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
13048			 (match_operand:SI 2 "const8_operand" "")
13049			 (match_operand:SI 3 "const8_operand" "")))]
13050  ""
13051{
13052  /* Handle extractions from %ah et al.  */
13053  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13054    FAIL;
13055
13056  /* From mips.md: extract_bit_field doesn't verify that our source
13057     matches the predicate, so check it again here.  */
13058  if (! ext_register_operand (operands[1], VOIDmode))
13059    FAIL;
13060})
13061
13062(define_expand "extzv"
13063  [(set (match_operand:SI 0 "register_operand" "")
13064	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
13065			 (match_operand:SI 2 "const8_operand" "")
13066			 (match_operand:SI 3 "const8_operand" "")))]
13067  ""
13068{
13069  /* Handle extractions from %ah et al.  */
13070  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13071    FAIL;
13072
13073  /* From mips.md: extract_bit_field doesn't verify that our source
13074     matches the predicate, so check it again here.  */
13075  if (! ext_register_operand (operands[1], VOIDmode))
13076    FAIL;
13077})
13078
13079(define_expand "insv"
13080  [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13081		      (match_operand 1 "const8_operand" "")
13082		      (match_operand 2 "const8_operand" ""))
13083        (match_operand 3 "register_operand" ""))]
13084  ""
13085{
13086  /* Handle insertions to %ah et al.  */
13087  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13088    FAIL;
13089
13090  /* From mips.md: insert_bit_field doesn't verify that our source
13091     matches the predicate, so check it again here.  */
13092  if (! ext_register_operand (operands[0], VOIDmode))
13093    FAIL;
13094
13095  if (TARGET_64BIT)
13096    emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13097  else
13098    emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13099
13100  DONE;
13101})
13102
13103;; %%% bts, btr, btc, bt.
13104;; In general these instructions are *slow* when applied to memory,
13105;; since they enforce atomic operation.  When applied to registers,
13106;; it depends on the cpu implementation.  They're never faster than
13107;; the corresponding and/ior/xor operations, so with 32-bit there's
13108;; no point.  But in 64-bit, we can't hold the relevant immediates
13109;; within the instruction itself, so operating on bits in the high
13110;; 32-bits of a register becomes easier.
13111;;
13112;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13113;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13114;; negdf respectively, so they can never be disabled entirely.
13115
13116(define_insn "*btsq"
13117  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13118			 (const_int 1)
13119			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13120	(const_int 1))
13121   (clobber (reg:CC FLAGS_REG))]
13122  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13123  "bts{q} %1,%0"
13124  [(set_attr "type" "alu1")])
13125
13126(define_insn "*btrq"
13127  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13128			 (const_int 1)
13129			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13130	(const_int 0))
13131   (clobber (reg:CC FLAGS_REG))]
13132  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13133  "btr{q} %1,%0"
13134  [(set_attr "type" "alu1")])
13135
13136(define_insn "*btcq"
13137  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13138			 (const_int 1)
13139			 (match_operand:DI 1 "const_0_to_63_operand" ""))
13140	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13141   (clobber (reg:CC FLAGS_REG))]
13142  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13143  "btc{q} %1,%0"
13144  [(set_attr "type" "alu1")])
13145
13146;; Allow Nocona to avoid these instructions if a register is available.
13147
13148(define_peephole2
13149  [(match_scratch:DI 2 "r")
13150   (parallel [(set (zero_extract:DI
13151		     (match_operand:DI 0 "register_operand" "")
13152		     (const_int 1)
13153		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13154		   (const_int 1))
13155	      (clobber (reg:CC FLAGS_REG))])]
13156  "TARGET_64BIT && !TARGET_USE_BT"
13157  [(const_int 0)]
13158{
13159  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13160  rtx op1;
13161
13162  if (HOST_BITS_PER_WIDE_INT >= 64)
13163    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13164  else if (i < HOST_BITS_PER_WIDE_INT)
13165    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166  else
13167    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13168
13169  op1 = immed_double_const (lo, hi, DImode);
13170  if (i >= 31)
13171    {
13172      emit_move_insn (operands[2], op1);
13173      op1 = operands[2];
13174    }
13175
13176  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13177  DONE;
13178})
13179
13180(define_peephole2
13181  [(match_scratch:DI 2 "r")
13182   (parallel [(set (zero_extract:DI
13183		     (match_operand:DI 0 "register_operand" "")
13184		     (const_int 1)
13185		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13186		   (const_int 0))
13187	      (clobber (reg:CC FLAGS_REG))])]
13188  "TARGET_64BIT && !TARGET_USE_BT"
13189  [(const_int 0)]
13190{
13191  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13192  rtx op1;
13193
13194  if (HOST_BITS_PER_WIDE_INT >= 64)
13195    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13196  else if (i < HOST_BITS_PER_WIDE_INT)
13197    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13198  else
13199    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13200
13201  op1 = immed_double_const (~lo, ~hi, DImode);
13202  if (i >= 32)
13203    {
13204      emit_move_insn (operands[2], op1);
13205      op1 = operands[2];
13206    }
13207
13208  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13209  DONE;
13210})
13211
13212(define_peephole2
13213  [(match_scratch:DI 2 "r")
13214   (parallel [(set (zero_extract:DI
13215		     (match_operand:DI 0 "register_operand" "")
13216		     (const_int 1)
13217		     (match_operand:DI 1 "const_0_to_63_operand" ""))
13218	      (not:DI (zero_extract:DI
13219			(match_dup 0) (const_int 1) (match_dup 1))))
13220	      (clobber (reg:CC FLAGS_REG))])]
13221  "TARGET_64BIT && !TARGET_USE_BT"
13222  [(const_int 0)]
13223{
13224  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13225  rtx op1;
13226
13227  if (HOST_BITS_PER_WIDE_INT >= 64)
13228    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13229  else if (i < HOST_BITS_PER_WIDE_INT)
13230    lo = (HOST_WIDE_INT)1 << i, hi = 0;
13231  else
13232    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13233
13234  op1 = immed_double_const (lo, hi, DImode);
13235  if (i >= 31)
13236    {
13237      emit_move_insn (operands[2], op1);
13238      op1 = operands[2];
13239    }
13240
13241  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13242  DONE;
13243})
13244
13245;; Store-flag instructions.
13246
13247;; For all sCOND expanders, also expand the compare or test insn that
13248;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13249
13250;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13251;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13252;; way, which can later delete the movzx if only QImode is needed.
13253
13254(define_expand "seq"
13255  [(set (match_operand:QI 0 "register_operand" "")
13256        (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257  ""
13258  "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13259
13260(define_expand "sne"
13261  [(set (match_operand:QI 0 "register_operand" "")
13262        (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13263  ""
13264  "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13265
13266(define_expand "sgt"
13267  [(set (match_operand:QI 0 "register_operand" "")
13268        (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269  ""
13270  "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13271
13272(define_expand "sgtu"
13273  [(set (match_operand:QI 0 "register_operand" "")
13274        (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13275  ""
13276  "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13277
13278(define_expand "slt"
13279  [(set (match_operand:QI 0 "register_operand" "")
13280        (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13281  ""
13282  "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13283
13284(define_expand "sltu"
13285  [(set (match_operand:QI 0 "register_operand" "")
13286        (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287  ""
13288  "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13289
13290(define_expand "sge"
13291  [(set (match_operand:QI 0 "register_operand" "")
13292        (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13293  ""
13294  "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13295
13296(define_expand "sgeu"
13297  [(set (match_operand:QI 0 "register_operand" "")
13298        (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299  ""
13300  "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13301
13302(define_expand "sle"
13303  [(set (match_operand:QI 0 "register_operand" "")
13304        (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305  ""
13306  "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13307
13308(define_expand "sleu"
13309  [(set (match_operand:QI 0 "register_operand" "")
13310        (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311  ""
13312  "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13313
13314(define_expand "sunordered"
13315  [(set (match_operand:QI 0 "register_operand" "")
13316        (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13317  "TARGET_80387 || TARGET_SSE"
13318  "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13319
13320(define_expand "sordered"
13321  [(set (match_operand:QI 0 "register_operand" "")
13322        (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13323  "TARGET_80387"
13324  "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13325
13326(define_expand "suneq"
13327  [(set (match_operand:QI 0 "register_operand" "")
13328        (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13329  "TARGET_80387 || TARGET_SSE"
13330  "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13331
13332(define_expand "sunge"
13333  [(set (match_operand:QI 0 "register_operand" "")
13334        (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13335  "TARGET_80387 || TARGET_SSE"
13336  "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13337
13338(define_expand "sungt"
13339  [(set (match_operand:QI 0 "register_operand" "")
13340        (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13341  "TARGET_80387 || TARGET_SSE"
13342  "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13343
13344(define_expand "sunle"
13345  [(set (match_operand:QI 0 "register_operand" "")
13346        (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13347  "TARGET_80387 || TARGET_SSE"
13348  "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13349
13350(define_expand "sunlt"
13351  [(set (match_operand:QI 0 "register_operand" "")
13352        (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13353  "TARGET_80387 || TARGET_SSE"
13354  "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13355
13356(define_expand "sltgt"
13357  [(set (match_operand:QI 0 "register_operand" "")
13358        (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13359  "TARGET_80387 || TARGET_SSE"
13360  "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13361
13362(define_insn "*setcc_1"
13363  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13364	(match_operator:QI 1 "ix86_comparison_operator"
13365	  [(reg FLAGS_REG) (const_int 0)]))]
13366  ""
13367  "set%C1\t%0"
13368  [(set_attr "type" "setcc")
13369   (set_attr "mode" "QI")])
13370
13371(define_insn "*setcc_2"
13372  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13373	(match_operator:QI 1 "ix86_comparison_operator"
13374	  [(reg FLAGS_REG) (const_int 0)]))]
13375  ""
13376  "set%C1\t%0"
13377  [(set_attr "type" "setcc")
13378   (set_attr "mode" "QI")])
13379
13380;; In general it is not safe to assume too much about CCmode registers,
13381;; so simplify-rtx stops when it sees a second one.  Under certain 
13382;; conditions this is safe on x86, so help combine not create
13383;;
13384;;	seta	%al
13385;;	testb	%al, %al
13386;;	sete	%al
13387
13388(define_split 
13389  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13390	(ne:QI (match_operator 1 "ix86_comparison_operator"
13391	         [(reg FLAGS_REG) (const_int 0)])
13392	    (const_int 0)))]
13393  ""
13394  [(set (match_dup 0) (match_dup 1))]
13395{
13396  PUT_MODE (operands[1], QImode);
13397})
13398
13399(define_split 
13400  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13401	(ne:QI (match_operator 1 "ix86_comparison_operator"
13402	         [(reg FLAGS_REG) (const_int 0)])
13403	    (const_int 0)))]
13404  ""
13405  [(set (match_dup 0) (match_dup 1))]
13406{
13407  PUT_MODE (operands[1], QImode);
13408})
13409
13410(define_split 
13411  [(set (match_operand:QI 0 "nonimmediate_operand" "")
13412	(eq:QI (match_operator 1 "ix86_comparison_operator"
13413	         [(reg FLAGS_REG) (const_int 0)])
13414	    (const_int 0)))]
13415  ""
13416  [(set (match_dup 0) (match_dup 1))]
13417{
13418  rtx new_op1 = copy_rtx (operands[1]);
13419  operands[1] = new_op1;
13420  PUT_MODE (new_op1, QImode);
13421  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13422					     GET_MODE (XEXP (new_op1, 0))));
13423
13424  /* Make sure that (a) the CCmode we have for the flags is strong
13425     enough for the reversed compare or (b) we have a valid FP compare.  */
13426  if (! ix86_comparison_operator (new_op1, VOIDmode))
13427    FAIL;
13428})
13429
13430(define_split 
13431  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13432	(eq:QI (match_operator 1 "ix86_comparison_operator"
13433	         [(reg FLAGS_REG) (const_int 0)])
13434	    (const_int 0)))]
13435  ""
13436  [(set (match_dup 0) (match_dup 1))]
13437{
13438  rtx new_op1 = copy_rtx (operands[1]);
13439  operands[1] = new_op1;
13440  PUT_MODE (new_op1, QImode);
13441  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13442					     GET_MODE (XEXP (new_op1, 0))));
13443
13444  /* Make sure that (a) the CCmode we have for the flags is strong
13445     enough for the reversed compare or (b) we have a valid FP compare.  */
13446  if (! ix86_comparison_operator (new_op1, VOIDmode))
13447    FAIL;
13448})
13449
13450;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13451;; subsequent logical operations are used to imitate conditional moves.
13452;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13453;; it directly.
13454
13455(define_insn "*sse_setccsf"
13456  [(set (match_operand:SF 0 "register_operand" "=x")
13457	(match_operator:SF 1 "sse_comparison_operator"
13458	  [(match_operand:SF 2 "register_operand" "0")
13459	   (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13460  "TARGET_SSE"
13461  "cmp%D1ss\t{%3, %0|%0, %3}"
13462  [(set_attr "type" "ssecmp")
13463   (set_attr "mode" "SF")])
13464
13465(define_insn "*sse_setccdf"
13466  [(set (match_operand:DF 0 "register_operand" "=Y")
13467	(match_operator:DF 1 "sse_comparison_operator"
13468	  [(match_operand:DF 2 "register_operand" "0")
13469	   (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13470  "TARGET_SSE2"
13471  "cmp%D1sd\t{%3, %0|%0, %3}"
13472  [(set_attr "type" "ssecmp")
13473   (set_attr "mode" "DF")])
13474
13475;; Basic conditional jump instructions.
13476;; We ignore the overflow flag for signed branch instructions.
13477
13478;; For all bCOND expanders, also expand the compare or test insn that
13479;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13480
13481(define_expand "beq"
13482  [(set (pc)
13483	(if_then_else (match_dup 1)
13484		      (label_ref (match_operand 0 "" ""))
13485		      (pc)))]
13486  ""
13487  "ix86_expand_branch (EQ, operands[0]); DONE;")
13488
13489(define_expand "bne"
13490  [(set (pc)
13491	(if_then_else (match_dup 1)
13492		      (label_ref (match_operand 0 "" ""))
13493		      (pc)))]
13494  ""
13495  "ix86_expand_branch (NE, operands[0]); DONE;")
13496
13497(define_expand "bgt"
13498  [(set (pc)
13499	(if_then_else (match_dup 1)
13500		      (label_ref (match_operand 0 "" ""))
13501		      (pc)))]
13502  ""
13503  "ix86_expand_branch (GT, operands[0]); DONE;")
13504
13505(define_expand "bgtu"
13506  [(set (pc)
13507	(if_then_else (match_dup 1)
13508		      (label_ref (match_operand 0 "" ""))
13509		      (pc)))]
13510  ""
13511  "ix86_expand_branch (GTU, operands[0]); DONE;")
13512
13513(define_expand "blt"
13514  [(set (pc)
13515	(if_then_else (match_dup 1)
13516		      (label_ref (match_operand 0 "" ""))
13517		      (pc)))]
13518  ""
13519  "ix86_expand_branch (LT, operands[0]); DONE;")
13520
13521(define_expand "bltu"
13522  [(set (pc)
13523	(if_then_else (match_dup 1)
13524		      (label_ref (match_operand 0 "" ""))
13525		      (pc)))]
13526  ""
13527  "ix86_expand_branch (LTU, operands[0]); DONE;")
13528
13529(define_expand "bge"
13530  [(set (pc)
13531	(if_then_else (match_dup 1)
13532		      (label_ref (match_operand 0 "" ""))
13533		      (pc)))]
13534  ""
13535  "ix86_expand_branch (GE, operands[0]); DONE;")
13536
13537(define_expand "bgeu"
13538  [(set (pc)
13539	(if_then_else (match_dup 1)
13540		      (label_ref (match_operand 0 "" ""))
13541		      (pc)))]
13542  ""
13543  "ix86_expand_branch (GEU, operands[0]); DONE;")
13544
13545(define_expand "ble"
13546  [(set (pc)
13547	(if_then_else (match_dup 1)
13548		      (label_ref (match_operand 0 "" ""))
13549		      (pc)))]
13550  ""
13551  "ix86_expand_branch (LE, operands[0]); DONE;")
13552
13553(define_expand "bleu"
13554  [(set (pc)
13555	(if_then_else (match_dup 1)
13556		      (label_ref (match_operand 0 "" ""))
13557		      (pc)))]
13558  ""
13559  "ix86_expand_branch (LEU, operands[0]); DONE;")
13560
13561(define_expand "bunordered"
13562  [(set (pc)
13563	(if_then_else (match_dup 1)
13564		      (label_ref (match_operand 0 "" ""))
13565		      (pc)))]
13566  "TARGET_80387 || TARGET_SSE_MATH"
13567  "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13568
13569(define_expand "bordered"
13570  [(set (pc)
13571	(if_then_else (match_dup 1)
13572		      (label_ref (match_operand 0 "" ""))
13573		      (pc)))]
13574  "TARGET_80387 || TARGET_SSE_MATH"
13575  "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13576
13577(define_expand "buneq"
13578  [(set (pc)
13579	(if_then_else (match_dup 1)
13580		      (label_ref (match_operand 0 "" ""))
13581		      (pc)))]
13582  "TARGET_80387 || TARGET_SSE_MATH"
13583  "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13584
13585(define_expand "bunge"
13586  [(set (pc)
13587	(if_then_else (match_dup 1)
13588		      (label_ref (match_operand 0 "" ""))
13589		      (pc)))]
13590  "TARGET_80387 || TARGET_SSE_MATH"
13591  "ix86_expand_branch (UNGE, operands[0]); DONE;")
13592
13593(define_expand "bungt"
13594  [(set (pc)
13595	(if_then_else (match_dup 1)
13596		      (label_ref (match_operand 0 "" ""))
13597		      (pc)))]
13598  "TARGET_80387 || TARGET_SSE_MATH"
13599  "ix86_expand_branch (UNGT, operands[0]); DONE;")
13600
13601(define_expand "bunle"
13602  [(set (pc)
13603	(if_then_else (match_dup 1)
13604		      (label_ref (match_operand 0 "" ""))
13605		      (pc)))]
13606  "TARGET_80387 || TARGET_SSE_MATH"
13607  "ix86_expand_branch (UNLE, operands[0]); DONE;")
13608
13609(define_expand "bunlt"
13610  [(set (pc)
13611	(if_then_else (match_dup 1)
13612		      (label_ref (match_operand 0 "" ""))
13613		      (pc)))]
13614  "TARGET_80387 || TARGET_SSE_MATH"
13615  "ix86_expand_branch (UNLT, operands[0]); DONE;")
13616
13617(define_expand "bltgt"
13618  [(set (pc)
13619	(if_then_else (match_dup 1)
13620		      (label_ref (match_operand 0 "" ""))
13621		      (pc)))]
13622  "TARGET_80387 || TARGET_SSE_MATH"
13623  "ix86_expand_branch (LTGT, operands[0]); DONE;")
13624
13625(define_insn "*jcc_1"
13626  [(set (pc)
13627	(if_then_else (match_operator 1 "ix86_comparison_operator"
13628				      [(reg FLAGS_REG) (const_int 0)])
13629		      (label_ref (match_operand 0 "" ""))
13630		      (pc)))]
13631  ""
13632  "%+j%C1\t%l0"
13633  [(set_attr "type" "ibr")
13634   (set_attr "modrm" "0")
13635   (set (attr "length")
13636	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13637				  (const_int -126))
13638			      (lt (minus (match_dup 0) (pc))
13639				  (const_int 128)))
13640	     (const_int 2)
13641	     (const_int 6)))])
13642
13643(define_insn "*jcc_2"
13644  [(set (pc)
13645	(if_then_else (match_operator 1 "ix86_comparison_operator"
13646				      [(reg FLAGS_REG) (const_int 0)])
13647		      (pc)
13648		      (label_ref (match_operand 0 "" ""))))]
13649  ""
13650  "%+j%c1\t%l0"
13651  [(set_attr "type" "ibr")
13652   (set_attr "modrm" "0")
13653   (set (attr "length")
13654	   (if_then_else (and (ge (minus (match_dup 0) (pc))
13655				  (const_int -126))
13656			      (lt (minus (match_dup 0) (pc))
13657				  (const_int 128)))
13658	     (const_int 2)
13659	     (const_int 6)))])
13660
13661;; In general it is not safe to assume too much about CCmode registers,
13662;; so simplify-rtx stops when it sees a second one.  Under certain 
13663;; conditions this is safe on x86, so help combine not create
13664;;
13665;;	seta	%al
13666;;	testb	%al, %al
13667;;	je	Lfoo
13668
13669(define_split 
13670  [(set (pc)
13671	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13672				      [(reg FLAGS_REG) (const_int 0)])
13673			  (const_int 0))
13674		      (label_ref (match_operand 1 "" ""))
13675		      (pc)))]
13676  ""
13677  [(set (pc)
13678	(if_then_else (match_dup 0)
13679		      (label_ref (match_dup 1))
13680		      (pc)))]
13681{
13682  PUT_MODE (operands[0], VOIDmode);
13683})
13684  
13685(define_split 
13686  [(set (pc)
13687	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13688				      [(reg FLAGS_REG) (const_int 0)])
13689			  (const_int 0))
13690		      (label_ref (match_operand 1 "" ""))
13691		      (pc)))]
13692  ""
13693  [(set (pc)
13694	(if_then_else (match_dup 0)
13695		      (label_ref (match_dup 1))
13696		      (pc)))]
13697{
13698  rtx new_op0 = copy_rtx (operands[0]);
13699  operands[0] = new_op0;
13700  PUT_MODE (new_op0, VOIDmode);
13701  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13702					     GET_MODE (XEXP (new_op0, 0))));
13703
13704  /* Make sure that (a) the CCmode we have for the flags is strong
13705     enough for the reversed compare or (b) we have a valid FP compare.  */
13706  if (! ix86_comparison_operator (new_op0, VOIDmode))
13707    FAIL;
13708})
13709
13710;; Define combination compare-and-branch fp compare instructions to use
13711;; during early optimization.  Splitting the operation apart early makes
13712;; for bad code when we want to reverse the operation.
13713
13714(define_insn "*fp_jcc_1_mixed"
13715  [(set (pc)
13716	(if_then_else (match_operator 0 "comparison_operator"
13717			[(match_operand 1 "register_operand" "f,x")
13718			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13719	  (label_ref (match_operand 3 "" ""))
13720	  (pc)))
13721   (clobber (reg:CCFP FPSR_REG))
13722   (clobber (reg:CCFP FLAGS_REG))]
13723  "TARGET_MIX_SSE_I387
13724   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13725   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13726   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13727  "#")
13728
13729(define_insn "*fp_jcc_1_sse"
13730  [(set (pc)
13731	(if_then_else (match_operator 0 "comparison_operator"
13732			[(match_operand 1 "register_operand" "x")
13733			 (match_operand 2 "nonimmediate_operand" "xm")])
13734	  (label_ref (match_operand 3 "" ""))
13735	  (pc)))
13736   (clobber (reg:CCFP FPSR_REG))
13737   (clobber (reg:CCFP FLAGS_REG))]
13738  "TARGET_SSE_MATH
13739   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13740   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13741   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13742  "#")
13743
13744(define_insn "*fp_jcc_1_387"
13745  [(set (pc)
13746	(if_then_else (match_operator 0 "comparison_operator"
13747			[(match_operand 1 "register_operand" "f")
13748			 (match_operand 2 "register_operand" "f")])
13749	  (label_ref (match_operand 3 "" ""))
13750	  (pc)))
13751   (clobber (reg:CCFP FPSR_REG))
13752   (clobber (reg:CCFP FLAGS_REG))]
13753  "TARGET_CMOVE && TARGET_80387
13754   && FLOAT_MODE_P (GET_MODE (operands[1]))
13755   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13756   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13757  "#")
13758
13759(define_insn "*fp_jcc_2_mixed"
13760  [(set (pc)
13761	(if_then_else (match_operator 0 "comparison_operator"
13762			[(match_operand 1 "register_operand" "f,x")
13763			 (match_operand 2 "nonimmediate_operand" "f,xm")])
13764	  (pc)
13765	  (label_ref (match_operand 3 "" ""))))
13766   (clobber (reg:CCFP FPSR_REG))
13767   (clobber (reg:CCFP FLAGS_REG))]
13768  "TARGET_MIX_SSE_I387
13769   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13770   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13772  "#")
13773
13774(define_insn "*fp_jcc_2_sse"
13775  [(set (pc)
13776	(if_then_else (match_operator 0 "comparison_operator"
13777			[(match_operand 1 "register_operand" "x")
13778			 (match_operand 2 "nonimmediate_operand" "xm")])
13779	  (pc)
13780	  (label_ref (match_operand 3 "" ""))))
13781   (clobber (reg:CCFP FPSR_REG))
13782   (clobber (reg:CCFP FLAGS_REG))]
13783  "TARGET_SSE_MATH
13784   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13785   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13786   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13787  "#")
13788
13789(define_insn "*fp_jcc_2_387"
13790  [(set (pc)
13791	(if_then_else (match_operator 0 "comparison_operator"
13792			[(match_operand 1 "register_operand" "f")
13793			 (match_operand 2 "register_operand" "f")])
13794	  (pc)
13795	  (label_ref (match_operand 3 "" ""))))
13796   (clobber (reg:CCFP FPSR_REG))
13797   (clobber (reg:CCFP FLAGS_REG))]
13798  "TARGET_CMOVE && TARGET_80387
13799   && FLOAT_MODE_P (GET_MODE (operands[1]))
13800   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13801   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13802  "#")
13803
13804(define_insn "*fp_jcc_3_387"
13805  [(set (pc)
13806	(if_then_else (match_operator 0 "comparison_operator"
13807			[(match_operand 1 "register_operand" "f")
13808			 (match_operand 2 "nonimmediate_operand" "fm")])
13809	  (label_ref (match_operand 3 "" ""))
13810	  (pc)))
13811   (clobber (reg:CCFP FPSR_REG))
13812   (clobber (reg:CCFP FLAGS_REG))
13813   (clobber (match_scratch:HI 4 "=a"))]
13814  "TARGET_80387
13815   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13816   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13817   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13818   && SELECT_CC_MODE (GET_CODE (operands[0]),
13819		      operands[1], operands[2]) == CCFPmode
13820   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13821  "#")
13822
13823(define_insn "*fp_jcc_4_387"
13824  [(set (pc)
13825	(if_then_else (match_operator 0 "comparison_operator"
13826			[(match_operand 1 "register_operand" "f")
13827			 (match_operand 2 "nonimmediate_operand" "fm")])
13828	  (pc)
13829	  (label_ref (match_operand 3 "" ""))))
13830   (clobber (reg:CCFP FPSR_REG))
13831   (clobber (reg:CCFP FLAGS_REG))
13832   (clobber (match_scratch:HI 4 "=a"))]
13833  "TARGET_80387
13834   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13835   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13836   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13837   && SELECT_CC_MODE (GET_CODE (operands[0]),
13838		      operands[1], operands[2]) == CCFPmode
13839   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13840  "#")
13841
13842(define_insn "*fp_jcc_5_387"
13843  [(set (pc)
13844	(if_then_else (match_operator 0 "comparison_operator"
13845			[(match_operand 1 "register_operand" "f")
13846			 (match_operand 2 "register_operand" "f")])
13847	  (label_ref (match_operand 3 "" ""))
13848	  (pc)))
13849   (clobber (reg:CCFP FPSR_REG))
13850   (clobber (reg:CCFP FLAGS_REG))
13851   (clobber (match_scratch:HI 4 "=a"))]
13852  "TARGET_80387
13853   && FLOAT_MODE_P (GET_MODE (operands[1]))
13854   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13855   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13856  "#")
13857
13858(define_insn "*fp_jcc_6_387"
13859  [(set (pc)
13860	(if_then_else (match_operator 0 "comparison_operator"
13861			[(match_operand 1 "register_operand" "f")
13862			 (match_operand 2 "register_operand" "f")])
13863	  (pc)
13864	  (label_ref (match_operand 3 "" ""))))
13865   (clobber (reg:CCFP FPSR_REG))
13866   (clobber (reg:CCFP FLAGS_REG))
13867   (clobber (match_scratch:HI 4 "=a"))]
13868  "TARGET_80387
13869   && FLOAT_MODE_P (GET_MODE (operands[1]))
13870   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13871   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13872  "#")
13873
13874(define_insn "*fp_jcc_7_387"
13875  [(set (pc)
13876	(if_then_else (match_operator 0 "comparison_operator"
13877			[(match_operand 1 "register_operand" "f")
13878			 (match_operand 2 "const0_operand" "X")])
13879	  (label_ref (match_operand 3 "" ""))
13880	  (pc)))
13881   (clobber (reg:CCFP FPSR_REG))
13882   (clobber (reg:CCFP FLAGS_REG))
13883   (clobber (match_scratch:HI 4 "=a"))]
13884  "TARGET_80387
13885   && FLOAT_MODE_P (GET_MODE (operands[1]))
13886   && GET_MODE (operands[1]) == GET_MODE (operands[2])
13887   && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13888   && SELECT_CC_MODE (GET_CODE (operands[0]),
13889		      operands[1], operands[2]) == CCFPmode
13890   && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13891  "#")
13892
13893;; The order of operands in *fp_jcc_8_387 is forced by combine in
13894;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13895;; with a precedence over other operators and is always put in the first
13896;; place. Swap condition and operands to match ficom instruction.
13897
13898(define_insn "*fp_jcc_8<mode>_387"
13899  [(set (pc)
13900	(if_then_else (match_operator 0 "comparison_operator"
13901			[(match_operator 1 "float_operator"
13902			   [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13903			   (match_operand 3 "register_operand" "f,f")])
13904	  (label_ref (match_operand 4 "" ""))
13905	  (pc)))
13906   (clobber (reg:CCFP FPSR_REG))
13907   (clobber (reg:CCFP FLAGS_REG))
13908   (clobber (match_scratch:HI 5 "=a,a"))]
13909  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13910   && FLOAT_MODE_P (GET_MODE (operands[3]))
13911   && GET_MODE (operands[1]) == GET_MODE (operands[3])
13912   && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13913   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13914   && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13915  "#")
13916
13917(define_split
13918  [(set (pc)
13919	(if_then_else (match_operator 0 "comparison_operator"
13920			[(match_operand 1 "register_operand" "")
13921			 (match_operand 2 "nonimmediate_operand" "")])
13922	  (match_operand 3 "" "")
13923	  (match_operand 4 "" "")))
13924   (clobber (reg:CCFP FPSR_REG))
13925   (clobber (reg:CCFP FLAGS_REG))]
13926  "reload_completed"
13927  [(const_int 0)]
13928{
13929  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13930	                operands[3], operands[4], NULL_RTX, NULL_RTX);
13931  DONE;
13932})
13933
13934(define_split
13935  [(set (pc)
13936	(if_then_else (match_operator 0 "comparison_operator"
13937			[(match_operand 1 "register_operand" "")
13938			 (match_operand 2 "general_operand" "")])
13939	  (match_operand 3 "" "")
13940	  (match_operand 4 "" "")))
13941   (clobber (reg:CCFP FPSR_REG))
13942   (clobber (reg:CCFP FLAGS_REG))
13943   (clobber (match_scratch:HI 5 "=a"))]
13944  "reload_completed"
13945  [(const_int 0)]
13946{
13947  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13948	     		operands[3], operands[4], operands[5], NULL_RTX);
13949  DONE;
13950})
13951
13952(define_split
13953  [(set (pc)
13954	(if_then_else (match_operator 0 "comparison_operator"
13955			[(match_operator 1 "float_operator"
13956			   [(match_operand:X87MODEI12 2 "memory_operand" "")])
13957			   (match_operand 3 "register_operand" "")])
13958	  (match_operand 4 "" "")
13959	  (match_operand 5 "" "")))
13960   (clobber (reg:CCFP FPSR_REG))
13961   (clobber (reg:CCFP FLAGS_REG))
13962   (clobber (match_scratch:HI 6 "=a"))]
13963  "reload_completed"
13964  [(const_int 0)]
13965{
13966  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13967  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13968			operands[3], operands[7],
13969			operands[4], operands[5], operands[6], NULL_RTX);
13970  DONE;
13971})
13972
13973;; %%% Kill this when reload knows how to do it.
13974(define_split
13975  [(set (pc)
13976	(if_then_else (match_operator 0 "comparison_operator"
13977			[(match_operator 1 "float_operator"
13978			   [(match_operand:X87MODEI12 2 "register_operand" "")])
13979			   (match_operand 3 "register_operand" "")])
13980	  (match_operand 4 "" "")
13981	  (match_operand 5 "" "")))
13982   (clobber (reg:CCFP FPSR_REG))
13983   (clobber (reg:CCFP FLAGS_REG))
13984   (clobber (match_scratch:HI 6 "=a"))]
13985  "reload_completed"
13986  [(const_int 0)]
13987{
13988  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13989  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13990  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13991			operands[3], operands[7],
13992			operands[4], operands[5], operands[6], operands[2]);
13993  DONE;
13994})
13995
13996;; Unconditional and other jump instructions
13997
13998(define_insn "jump"
13999  [(set (pc)
14000	(label_ref (match_operand 0 "" "")))]
14001  ""
14002  "jmp\t%l0"
14003  [(set_attr "type" "ibr")
14004   (set (attr "length")
14005	   (if_then_else (and (ge (minus (match_dup 0) (pc))
14006				  (const_int -126))
14007			      (lt (minus (match_dup 0) (pc))
14008				  (const_int 128)))
14009	     (const_int 2)
14010	     (const_int 5)))
14011   (set_attr "modrm" "0")])
14012
14013(define_expand "indirect_jump"
14014  [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14015  ""
14016  "")
14017
14018(define_insn "*indirect_jump"
14019  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14020  "!TARGET_64BIT"
14021  "jmp\t%A0"
14022  [(set_attr "type" "ibr")
14023   (set_attr "length_immediate" "0")])
14024
14025(define_insn "*indirect_jump_rtx64"
14026  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14027  "TARGET_64BIT"
14028  "jmp\t%A0"
14029  [(set_attr "type" "ibr")
14030   (set_attr "length_immediate" "0")])
14031
14032(define_expand "tablejump"
14033  [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14034	      (use (label_ref (match_operand 1 "" "")))])]
14035  ""
14036{
14037  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14038     relative.  Convert the relative address to an absolute address.  */
14039  if (flag_pic)
14040    {
14041      rtx op0, op1;
14042      enum rtx_code code;
14043
14044      if (TARGET_64BIT)
14045	{
14046	  code = PLUS;
14047	  op0 = operands[0];
14048	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14049	}
14050      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14051	{
14052	  code = PLUS;
14053	  op0 = operands[0];
14054	  op1 = pic_offset_table_rtx;
14055	}
14056      else
14057	{
14058	  code = MINUS;
14059	  op0 = pic_offset_table_rtx;
14060	  op1 = operands[0];
14061	}
14062
14063      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14064					 OPTAB_DIRECT);
14065    }
14066})
14067
14068(define_insn "*tablejump_1"
14069  [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14070   (use (label_ref (match_operand 1 "" "")))]
14071  "!TARGET_64BIT"
14072  "jmp\t%A0"
14073  [(set_attr "type" "ibr")
14074   (set_attr "length_immediate" "0")])
14075
14076(define_insn "*tablejump_1_rtx64"
14077  [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14078   (use (label_ref (match_operand 1 "" "")))]
14079  "TARGET_64BIT"
14080  "jmp\t%A0"
14081  [(set_attr "type" "ibr")
14082   (set_attr "length_immediate" "0")])
14083
14084;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14085
14086(define_peephole2
14087  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14088   (set (match_operand:QI 1 "register_operand" "")
14089	(match_operator:QI 2 "ix86_comparison_operator"
14090	  [(reg FLAGS_REG) (const_int 0)]))
14091   (set (match_operand 3 "q_regs_operand" "")
14092	(zero_extend (match_dup 1)))]
14093  "(peep2_reg_dead_p (3, operands[1])
14094    || operands_match_p (operands[1], operands[3]))
14095   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14096  [(set (match_dup 4) (match_dup 0))
14097   (set (strict_low_part (match_dup 5))
14098	(match_dup 2))]
14099{
14100  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14101  operands[5] = gen_lowpart (QImode, operands[3]);
14102  ix86_expand_clear (operands[3]);
14103})
14104
14105;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14106
14107(define_peephole2
14108  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14109   (set (match_operand:QI 1 "register_operand" "")
14110	(match_operator:QI 2 "ix86_comparison_operator"
14111	  [(reg FLAGS_REG) (const_int 0)]))
14112   (parallel [(set (match_operand 3 "q_regs_operand" "")
14113		   (zero_extend (match_dup 1)))
14114	      (clobber (reg:CC FLAGS_REG))])]
14115  "(peep2_reg_dead_p (3, operands[1])
14116    || operands_match_p (operands[1], operands[3]))
14117   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14118  [(set (match_dup 4) (match_dup 0))
14119   (set (strict_low_part (match_dup 5))
14120	(match_dup 2))]
14121{
14122  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14123  operands[5] = gen_lowpart (QImode, operands[3]);
14124  ix86_expand_clear (operands[3]);
14125})
14126
14127;; Call instructions.
14128
14129;; The predicates normally associated with named expanders are not properly
14130;; checked for calls.  This is a bug in the generic code, but it isn't that
14131;; easy to fix.  Ignore it for now and be prepared to fix things up.
14132
14133;; Call subroutine returning no value.
14134
14135(define_expand "call_pop"
14136  [(parallel [(call (match_operand:QI 0 "" "")
14137		    (match_operand:SI 1 "" ""))
14138	      (set (reg:SI SP_REG)
14139		   (plus:SI (reg:SI SP_REG)
14140			    (match_operand:SI 3 "" "")))])]
14141  "!TARGET_64BIT"
14142{
14143  ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14144  DONE;
14145})
14146
14147(define_insn "*call_pop_0"
14148  [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14149	 (match_operand:SI 1 "" ""))
14150   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14151			    (match_operand:SI 2 "immediate_operand" "")))]
14152  "!TARGET_64BIT"
14153{
14154  if (SIBLING_CALL_P (insn))
14155    return "jmp\t%P0";
14156  else
14157    return "call\t%P0";
14158}
14159  [(set_attr "type" "call")])
14160  
14161(define_insn "*call_pop_1"
14162  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14163	 (match_operand:SI 1 "" ""))
14164   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14165			    (match_operand:SI 2 "immediate_operand" "i")))]
14166  "!TARGET_64BIT"
14167{
14168  if (constant_call_address_operand (operands[0], Pmode))
14169    {
14170      if (SIBLING_CALL_P (insn))
14171	return "jmp\t%P0";
14172      else
14173	return "call\t%P0";
14174    }
14175  if (SIBLING_CALL_P (insn))
14176    return "jmp\t%A0";
14177  else
14178    return "call\t%A0";
14179}
14180  [(set_attr "type" "call")])
14181
14182(define_expand "call"
14183  [(call (match_operand:QI 0 "" "")
14184	 (match_operand 1 "" ""))
14185   (use (match_operand 2 "" ""))]
14186  ""
14187{
14188  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14189  DONE;
14190})
14191
14192(define_expand "sibcall"
14193  [(call (match_operand:QI 0 "" "")
14194	 (match_operand 1 "" ""))
14195   (use (match_operand 2 "" ""))]
14196  ""
14197{
14198  ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14199  DONE;
14200})
14201
14202(define_insn "*call_0"
14203  [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14204	 (match_operand 1 "" ""))]
14205  ""
14206{
14207  if (SIBLING_CALL_P (insn))
14208    return "jmp\t%P0";
14209  else
14210    return "call\t%P0";
14211}
14212  [(set_attr "type" "call")])
14213
14214(define_insn "*call_1"
14215  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14216	 (match_operand 1 "" ""))]
14217  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14218{
14219  if (constant_call_address_operand (operands[0], Pmode))
14220    return "call\t%P0";
14221  return "call\t%A0";
14222}
14223  [(set_attr "type" "call")])
14224
14225(define_insn "*sibcall_1"
14226  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14227	 (match_operand 1 "" ""))]
14228  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14229{
14230  if (constant_call_address_operand (operands[0], Pmode))
14231    return "jmp\t%P0";
14232  return "jmp\t%A0";
14233}
14234  [(set_attr "type" "call")])
14235
14236(define_insn "*call_1_rex64"
14237  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14238	 (match_operand 1 "" ""))]
14239  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14240{
14241  if (constant_call_address_operand (operands[0], Pmode))
14242    return "call\t%P0";
14243  return "call\t%A0";
14244}
14245  [(set_attr "type" "call")])
14246
14247(define_insn "*sibcall_1_rex64"
14248  [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14249	 (match_operand 1 "" ""))]
14250  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14251  "jmp\t%P0"
14252  [(set_attr "type" "call")])
14253
14254(define_insn "*sibcall_1_rex64_v"
14255  [(call (mem:QI (reg:DI 40))
14256	 (match_operand 0 "" ""))]
14257  "SIBLING_CALL_P (insn) && TARGET_64BIT"
14258  "jmp\t*%%r11"
14259  [(set_attr "type" "call")])
14260
14261
14262;; Call subroutine, returning value in operand 0
14263
14264(define_expand "call_value_pop"
14265  [(parallel [(set (match_operand 0 "" "")
14266		   (call (match_operand:QI 1 "" "")
14267			 (match_operand:SI 2 "" "")))
14268	      (set (reg:SI SP_REG)
14269		   (plus:SI (reg:SI SP_REG)
14270			    (match_operand:SI 4 "" "")))])]
14271  "!TARGET_64BIT"
14272{
14273  ix86_expand_call (operands[0], operands[1], operands[2],
14274		    operands[3], operands[4], 0);
14275  DONE;
14276})
14277
14278(define_expand "call_value"
14279  [(set (match_operand 0 "" "")
14280	(call (match_operand:QI 1 "" "")
14281	      (match_operand:SI 2 "" "")))
14282   (use (match_operand:SI 3 "" ""))]
14283  ;; Operand 2 not used on the i386.
14284  ""
14285{
14286  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14287  DONE;
14288})
14289
14290(define_expand "sibcall_value"
14291  [(set (match_operand 0 "" "")
14292	(call (match_operand:QI 1 "" "")
14293	      (match_operand:SI 2 "" "")))
14294   (use (match_operand:SI 3 "" ""))]
14295  ;; Operand 2 not used on the i386.
14296  ""
14297{
14298  ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14299  DONE;
14300})
14301
14302;; Call subroutine returning any type.
14303
14304(define_expand "untyped_call"
14305  [(parallel [(call (match_operand 0 "" "")
14306		    (const_int 0))
14307	      (match_operand 1 "" "")
14308	      (match_operand 2 "" "")])]
14309  ""
14310{
14311  int i;
14312
14313  /* In order to give reg-stack an easier job in validating two
14314     coprocessor registers as containing a possible return value,
14315     simply pretend the untyped call returns a complex long double
14316     value.  */
14317
14318  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14319		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14320		    operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14321		    NULL, 0);
14322
14323  for (i = 0; i < XVECLEN (operands[2], 0); i++)
14324    {
14325      rtx set = XVECEXP (operands[2], 0, i);
14326      emit_move_insn (SET_DEST (set), SET_SRC (set));
14327    }
14328
14329  /* The optimizer does not know that the call sets the function value
14330     registers we stored in the result block.  We avoid problems by
14331     claiming that all hard registers are used and clobbered at this
14332     point.  */
14333  emit_insn (gen_blockage (const0_rtx));
14334
14335  DONE;
14336})
14337
14338;; Prologue and epilogue instructions
14339
14340;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14341;; all of memory.  This blocks insns from being moved across this point.
14342
14343(define_insn "blockage"
14344  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14345  ""
14346  ""
14347  [(set_attr "length" "0")])
14348
14349;; Insn emitted into the body of a function to return from a function.
14350;; This is only done if the function's epilogue is known to be simple.
14351;; See comments for ix86_can_use_return_insn_p in i386.c.
14352
14353(define_expand "return"
14354  [(return)]
14355  "ix86_can_use_return_insn_p ()"
14356{
14357  if (current_function_pops_args)
14358    {
14359      rtx popc = GEN_INT (current_function_pops_args);
14360      emit_jump_insn (gen_return_pop_internal (popc));
14361      DONE;
14362    }
14363})
14364
14365(define_insn "return_internal"
14366  [(return)]
14367  "reload_completed"
14368  "ret"
14369  [(set_attr "length" "1")
14370   (set_attr "length_immediate" "0")
14371   (set_attr "modrm" "0")])
14372
14373;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14374;; instruction Athlon and K8 have.
14375
14376(define_insn "return_internal_long"
14377  [(return)
14378   (unspec [(const_int 0)] UNSPEC_REP)]
14379  "reload_completed"
14380  "rep {;} ret"
14381  [(set_attr "length" "1")
14382   (set_attr "length_immediate" "0")
14383   (set_attr "prefix_rep" "1")
14384   (set_attr "modrm" "0")])
14385
14386(define_insn "return_pop_internal"
14387  [(return)
14388   (use (match_operand:SI 0 "const_int_operand" ""))]
14389  "reload_completed"
14390  "ret\t%0"
14391  [(set_attr "length" "3")
14392   (set_attr "length_immediate" "2")
14393   (set_attr "modrm" "0")])
14394
14395(define_insn "return_indirect_internal"
14396  [(return)
14397   (use (match_operand:SI 0 "register_operand" "r"))]
14398  "reload_completed"
14399  "jmp\t%A0"
14400  [(set_attr "type" "ibr")
14401   (set_attr "length_immediate" "0")])
14402
14403(define_insn "nop"
14404  [(const_int 0)]
14405  ""
14406  "nop"
14407  [(set_attr "length" "1")
14408   (set_attr "length_immediate" "0")
14409   (set_attr "modrm" "0")])
14410
14411;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14412;; branch prediction penalty for the third jump in a 16-byte
14413;; block on K8.
14414
14415(define_insn "align"
14416  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14417  ""
14418{
14419#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14420  ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14421#else
14422  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14423     The align insn is used to avoid 3 jump instructions in the row to improve
14424     branch prediction and the benefits hardly outweigh the cost of extra 8
14425     nops on the average inserted by full alignment pseudo operation.  */
14426#endif
14427  return "";
14428}
14429  [(set_attr "length" "16")])
14430
14431(define_expand "prologue"
14432  [(const_int 1)]
14433  ""
14434  "ix86_expand_prologue (); DONE;")
14435
14436(define_insn "set_got"
14437  [(set (match_operand:SI 0 "register_operand" "=r")
14438	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14439   (clobber (reg:CC FLAGS_REG))]
14440  "!TARGET_64BIT"
14441  { return output_set_got (operands[0], NULL_RTX); }
14442  [(set_attr "type" "multi")
14443   (set_attr "length" "12")])
14444
14445(define_insn "set_got_labelled"
14446  [(set (match_operand:SI 0 "register_operand" "=r")
14447	(unspec:SI [(label_ref (match_operand 1 "" ""))]
14448	 UNSPEC_SET_GOT))
14449   (clobber (reg:CC FLAGS_REG))]
14450  "!TARGET_64BIT"
14451  { return output_set_got (operands[0], operands[1]); }
14452  [(set_attr "type" "multi")
14453   (set_attr "length" "12")])
14454
14455(define_insn "set_got_rex64"
14456  [(set (match_operand:DI 0 "register_operand" "=r")
14457	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14458  "TARGET_64BIT"
14459  "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14460  [(set_attr "type" "lea")
14461   (set_attr "length" "6")])
14462
14463(define_expand "epilogue"
14464  [(const_int 1)]
14465  ""
14466  "ix86_expand_epilogue (1); DONE;")
14467
14468(define_expand "sibcall_epilogue"
14469  [(const_int 1)]
14470  ""
14471  "ix86_expand_epilogue (0); DONE;")
14472
14473(define_expand "eh_return"
14474  [(use (match_operand 0 "register_operand" ""))]
14475  ""
14476{
14477  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14478
14479  /* Tricky bit: we write the address of the handler to which we will
14480     be returning into someone else's stack frame, one word below the
14481     stack address we wish to restore.  */
14482  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14483  tmp = plus_constant (tmp, -UNITS_PER_WORD);
14484  tmp = gen_rtx_MEM (Pmode, tmp);
14485  emit_move_insn (tmp, ra);
14486
14487  if (Pmode == SImode)
14488    emit_jump_insn (gen_eh_return_si (sa));
14489  else
14490    emit_jump_insn (gen_eh_return_di (sa));
14491  emit_barrier ();
14492  DONE;
14493})
14494
14495(define_insn_and_split "eh_return_si"
14496  [(set (pc) 
14497        (unspec [(match_operand:SI 0 "register_operand" "c")]
14498	         UNSPEC_EH_RETURN))]
14499  "!TARGET_64BIT"
14500  "#"
14501  "reload_completed"
14502  [(const_int 1)]
14503  "ix86_expand_epilogue (2); DONE;")
14504
14505(define_insn_and_split "eh_return_di"
14506  [(set (pc) 
14507        (unspec [(match_operand:DI 0 "register_operand" "c")]
14508	         UNSPEC_EH_RETURN))]
14509  "TARGET_64BIT"
14510  "#"
14511  "reload_completed"
14512  [(const_int 1)]
14513  "ix86_expand_epilogue (2); DONE;")
14514
14515(define_insn "leave"
14516  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14517   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14518   (clobber (mem:BLK (scratch)))]
14519  "!TARGET_64BIT"
14520  "leave"
14521  [(set_attr "type" "leave")])
14522
14523(define_insn "leave_rex64"
14524  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14525   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14526   (clobber (mem:BLK (scratch)))]
14527  "TARGET_64BIT"
14528  "leave"
14529  [(set_attr "type" "leave")])
14530
14531(define_expand "ffssi2"
14532  [(parallel
14533     [(set (match_operand:SI 0 "register_operand" "") 
14534	   (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14535      (clobber (match_scratch:SI 2 ""))
14536      (clobber (reg:CC FLAGS_REG))])]
14537  ""
14538  "")
14539
14540(define_insn_and_split "*ffs_cmove"
14541  [(set (match_operand:SI 0 "register_operand" "=r") 
14542	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14543   (clobber (match_scratch:SI 2 "=&r"))
14544   (clobber (reg:CC FLAGS_REG))]
14545  "TARGET_CMOVE"
14546  "#"
14547  "&& reload_completed"
14548  [(set (match_dup 2) (const_int -1))
14549   (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14550	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14551   (set (match_dup 0) (if_then_else:SI
14552			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14553			(match_dup 2)
14554			(match_dup 0)))
14555   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14556	      (clobber (reg:CC FLAGS_REG))])]
14557  "")
14558
14559(define_insn_and_split "*ffs_no_cmove"
14560  [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14561	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14562   (clobber (match_scratch:SI 2 "=&q"))
14563   (clobber (reg:CC FLAGS_REG))]
14564  ""
14565  "#"
14566  "reload_completed"
14567  [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14568	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
14569   (set (strict_low_part (match_dup 3))
14570	(eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14571   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14572	      (clobber (reg:CC FLAGS_REG))])
14573   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14574	      (clobber (reg:CC FLAGS_REG))])
14575   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14576	      (clobber (reg:CC FLAGS_REG))])]
14577{
14578  operands[3] = gen_lowpart (QImode, operands[2]);
14579  ix86_expand_clear (operands[2]);
14580})
14581
14582(define_insn "*ffssi_1"
14583  [(set (reg:CCZ FLAGS_REG)
14584	(compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14585		     (const_int 0)))
14586   (set (match_operand:SI 0 "register_operand" "=r")
14587	(ctz:SI (match_dup 1)))]
14588  ""
14589  "bsf{l}\t{%1, %0|%0, %1}"
14590  [(set_attr "prefix_0f" "1")])
14591
14592(define_expand "ffsdi2"
14593  [(parallel
14594     [(set (match_operand:DI 0 "register_operand" "") 
14595	   (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14596      (clobber (match_scratch:DI 2 ""))
14597      (clobber (reg:CC FLAGS_REG))])]
14598  "TARGET_64BIT && TARGET_CMOVE"
14599  "")
14600
14601(define_insn_and_split "*ffs_rex64"
14602  [(set (match_operand:DI 0 "register_operand" "=r") 
14603	(ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14604   (clobber (match_scratch:DI 2 "=&r"))
14605   (clobber (reg:CC FLAGS_REG))]
14606  "TARGET_64BIT && TARGET_CMOVE"
14607  "#"
14608  "&& reload_completed"
14609  [(set (match_dup 2) (const_int -1))
14610   (parallel [(set (reg:CCZ FLAGS_REG)
14611		   (compare:CCZ (match_dup 1) (const_int 0)))
14612	      (set (match_dup 0) (ctz:DI (match_dup 1)))])
14613   (set (match_dup 0) (if_then_else:DI
14614			(eq (reg:CCZ FLAGS_REG) (const_int 0))
14615			(match_dup 2)
14616			(match_dup 0)))
14617   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14618	      (clobber (reg:CC FLAGS_REG))])]
14619  "")
14620
14621(define_insn "*ffsdi_1"
14622  [(set (reg:CCZ FLAGS_REG)
14623	(compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14624		     (const_int 0)))
14625   (set (match_operand:DI 0 "register_operand" "=r")
14626	(ctz:DI (match_dup 1)))]
14627  "TARGET_64BIT"
14628  "bsf{q}\t{%1, %0|%0, %1}"
14629  [(set_attr "prefix_0f" "1")])
14630
14631(define_insn "ctzsi2"
14632  [(set (match_operand:SI 0 "register_operand" "=r")
14633	(ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14634   (clobber (reg:CC FLAGS_REG))]
14635  ""
14636  "bsf{l}\t{%1, %0|%0, %1}"
14637  [(set_attr "prefix_0f" "1")])
14638
14639(define_insn "ctzdi2"
14640  [(set (match_operand:DI 0 "register_operand" "=r")
14641	(ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14642   (clobber (reg:CC FLAGS_REG))]
14643  "TARGET_64BIT"
14644  "bsf{q}\t{%1, %0|%0, %1}"
14645  [(set_attr "prefix_0f" "1")])
14646
14647(define_expand "clzsi2"
14648  [(parallel
14649     [(set (match_operand:SI 0 "register_operand" "")
14650	   (minus:SI (const_int 31)
14651		     (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14652      (clobber (reg:CC FLAGS_REG))])
14653   (parallel
14654     [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14655      (clobber (reg:CC FLAGS_REG))])]
14656  ""
14657{
14658  if (TARGET_ABM)
14659    {
14660      emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14661      DONE;
14662    }
14663})
14664
14665(define_insn "clzsi2_abm"
14666  [(set (match_operand:SI 0 "register_operand" "=r")
14667        (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14668   (clobber (reg:CC FLAGS_REG))]
14669  "TARGET_ABM"
14670  "lzcnt{l}\t{%1, %0|%0, %1}"
14671  [(set_attr "prefix_rep" "1")
14672   (set_attr "type" "bitmanip")
14673   (set_attr "mode" "SI")])
14674
14675(define_insn "*bsr"
14676  [(set (match_operand:SI 0 "register_operand" "=r")
14677	(minus:SI (const_int 31)
14678		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14679   (clobber (reg:CC FLAGS_REG))]
14680  ""
14681  "bsr{l}\t{%1, %0|%0, %1}"
14682  [(set_attr "prefix_0f" "1")
14683   (set_attr "mode" "SI")])
14684
14685(define_insn "popcountsi2"
14686  [(set (match_operand:SI 0 "register_operand" "=r")
14687	(popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14688   (clobber (reg:CC FLAGS_REG))]
14689  "TARGET_POPCNT"
14690  "popcnt{l}\t{%1, %0|%0, %1}"
14691  [(set_attr "prefix_rep" "1")
14692   (set_attr "type" "bitmanip")
14693   (set_attr "mode" "SI")])
14694
14695(define_insn "*popcountsi2_cmp"
14696  [(set (reg FLAGS_REG)
14697	(compare
14698	  (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14699	  (const_int 0)))
14700   (set (match_operand:SI 0 "register_operand" "=r")
14701	(popcount:SI (match_dup 1)))]
14702  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14703  "popcnt{l}\t{%1, %0|%0, %1}"
14704  [(set_attr "prefix_rep" "1")
14705   (set_attr "type" "bitmanip")
14706   (set_attr "mode" "SI")])
14707
14708(define_insn "*popcountsi2_cmp_zext"
14709  [(set (reg FLAGS_REG)
14710        (compare
14711          (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14712          (const_int 0)))
14713   (set (match_operand:DI 0 "register_operand" "=r")
14714        (zero_extend:DI(popcount:SI (match_dup 1))))]
14715  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14716  "popcnt{l}\t{%1, %0|%0, %1}"
14717  [(set_attr "prefix_rep" "1")
14718   (set_attr "type" "bitmanip")
14719   (set_attr "mode" "SI")])
14720
14721(define_expand "clzdi2"
14722  [(parallel
14723     [(set (match_operand:DI 0 "register_operand" "")
14724	   (minus:DI (const_int 63)
14725		     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14726      (clobber (reg:CC FLAGS_REG))])
14727   (parallel
14728     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14729      (clobber (reg:CC FLAGS_REG))])]
14730  "TARGET_64BIT"
14731{
14732  if (TARGET_ABM)
14733    {
14734      emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14735      DONE;
14736    }
14737})
14738
14739(define_insn "clzdi2_abm"
14740  [(set (match_operand:DI 0 "register_operand" "=r")
14741	(clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14742   (clobber (reg:CC FLAGS_REG))]
14743  "TARGET_64BIT && TARGET_ABM"
14744  "lzcnt{q}\t{%1, %0|%0, %1}"
14745  [(set_attr "prefix_rep" "1")
14746   (set_attr "type" "bitmanip")
14747   (set_attr "mode" "DI")])
14748
14749(define_insn "*bsr_rex64"
14750  [(set (match_operand:DI 0 "register_operand" "=r")
14751	(minus:DI (const_int 63)
14752		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14753   (clobber (reg:CC FLAGS_REG))]
14754  "TARGET_64BIT"
14755  "bsr{q}\t{%1, %0|%0, %1}"
14756  [(set_attr "prefix_0f" "1")
14757   (set_attr "mode" "DI")])
14758
14759(define_insn "popcountdi2"
14760  [(set (match_operand:DI 0 "register_operand" "=r")
14761	(popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14762   (clobber (reg:CC FLAGS_REG))]
14763  "TARGET_64BIT && TARGET_POPCNT"
14764  "popcnt{q}\t{%1, %0|%0, %1}"
14765  [(set_attr "prefix_rep" "1")
14766   (set_attr "type" "bitmanip")
14767   (set_attr "mode" "DI")])
14768
14769(define_insn "*popcountdi2_cmp"
14770  [(set (reg FLAGS_REG)
14771	(compare
14772	  (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14773	  (const_int 0)))
14774   (set (match_operand:DI 0 "register_operand" "=r")
14775	(popcount:DI (match_dup 1)))]
14776  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14777  "popcnt{q}\t{%1, %0|%0, %1}"
14778  [(set_attr "prefix_rep" "1")
14779   (set_attr "type" "bitmanip")
14780   (set_attr "mode" "DI")])
14781
14782(define_expand "clzhi2"
14783  [(parallel
14784     [(set (match_operand:HI 0 "register_operand" "")
14785	   (minus:HI (const_int 15)
14786		     (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14787      (clobber (reg:CC FLAGS_REG))])
14788   (parallel
14789     [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14790      (clobber (reg:CC FLAGS_REG))])]
14791  ""
14792{
14793  if (TARGET_ABM)
14794    {
14795      emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14796      DONE;
14797    }
14798})
14799
14800(define_insn "clzhi2_abm"
14801  [(set (match_operand:HI 0 "register_operand" "=r")
14802	(clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14803   (clobber (reg:CC FLAGS_REG))]
14804  "TARGET_ABM"
14805  "lzcnt{w}\t{%1, %0|%0, %1}"
14806  [(set_attr "prefix_rep" "1")
14807   (set_attr "type" "bitmanip")
14808   (set_attr "mode" "HI")])
14809
14810(define_insn "*bsrhi"
14811  [(set (match_operand:HI 0 "register_operand" "=r")
14812	(minus:HI (const_int 15)
14813		  (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14814   (clobber (reg:CC FLAGS_REG))]
14815  ""
14816  "bsr{w}\t{%1, %0|%0, %1}"
14817  [(set_attr "prefix_0f" "1")
14818   (set_attr "mode" "HI")])
14819
14820(define_insn "popcounthi2"
14821  [(set (match_operand:HI 0 "register_operand" "=r")
14822	(popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14823   (clobber (reg:CC FLAGS_REG))]
14824  "TARGET_POPCNT"
14825  "popcnt{w}\t{%1, %0|%0, %1}"
14826  [(set_attr "prefix_rep" "1")
14827   (set_attr "type" "bitmanip")
14828   (set_attr "mode" "HI")])
14829
14830(define_insn "*popcounthi2_cmp"
14831  [(set (reg FLAGS_REG)
14832        (compare
14833          (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14834          (const_int 0)))
14835   (set (match_operand:HI 0 "register_operand" "=r")
14836        (popcount:HI (match_dup 1)))]
14837  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14838  "popcnt{w}\t{%1, %0|%0, %1}"
14839  [(set_attr "prefix_rep" "1")
14840   (set_attr "type" "bitmanip")
14841   (set_attr "mode" "HI")])
14842
14843;; Thread-local storage patterns for ELF.
14844;;
14845;; Note that these code sequences must appear exactly as shown
14846;; in order to allow linker relaxation.
14847
14848(define_insn "*tls_global_dynamic_32_gnu"
14849  [(set (match_operand:SI 0 "register_operand" "=a")
14850	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14851		    (match_operand:SI 2 "tls_symbolic_operand" "")
14852		    (match_operand:SI 3 "call_insn_operand" "")]
14853		    UNSPEC_TLS_GD))
14854   (clobber (match_scratch:SI 4 "=d"))
14855   (clobber (match_scratch:SI 5 "=c"))
14856   (clobber (reg:CC FLAGS_REG))]
14857  "!TARGET_64BIT && TARGET_GNU_TLS"
14858  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14859  [(set_attr "type" "multi")
14860   (set_attr "length" "12")])
14861
14862(define_insn "*tls_global_dynamic_32_sun"
14863  [(set (match_operand:SI 0 "register_operand" "=a")
14864	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14865		    (match_operand:SI 2 "tls_symbolic_operand" "")
14866		    (match_operand:SI 3 "call_insn_operand" "")]
14867		    UNSPEC_TLS_GD))
14868   (clobber (match_scratch:SI 4 "=d"))
14869   (clobber (match_scratch:SI 5 "=c"))
14870   (clobber (reg:CC FLAGS_REG))]
14871  "!TARGET_64BIT && TARGET_SUN_TLS"
14872  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14873	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14874  [(set_attr "type" "multi")
14875   (set_attr "length" "14")])
14876
14877(define_expand "tls_global_dynamic_32"
14878  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14879		   (unspec:SI
14880		    [(match_dup 2)
14881		     (match_operand:SI 1 "tls_symbolic_operand" "")
14882		     (match_dup 3)]
14883		    UNSPEC_TLS_GD))
14884	      (clobber (match_scratch:SI 4 ""))
14885	      (clobber (match_scratch:SI 5 ""))
14886	      (clobber (reg:CC FLAGS_REG))])]
14887  ""
14888{
14889  if (flag_pic)
14890    operands[2] = pic_offset_table_rtx;
14891  else
14892    {
14893      operands[2] = gen_reg_rtx (Pmode);
14894      emit_insn (gen_set_got (operands[2]));
14895    }
14896  if (TARGET_GNU2_TLS)
14897    {
14898       emit_insn (gen_tls_dynamic_gnu2_32
14899		  (operands[0], operands[1], operands[2]));
14900       DONE;
14901    }
14902  operands[3] = ix86_tls_get_addr ();
14903})
14904
14905(define_insn "*tls_global_dynamic_64"
14906  [(set (match_operand:DI 0 "register_operand" "=a")
14907	(call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14908		 (match_operand:DI 3 "" "")))
14909   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14910	      UNSPEC_TLS_GD)]
14911  "TARGET_64BIT"
14912  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14913  [(set_attr "type" "multi")
14914   (set_attr "length" "16")])
14915
14916(define_expand "tls_global_dynamic_64"
14917  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14918		   (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14919	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14920			 UNSPEC_TLS_GD)])]
14921  ""
14922{
14923  if (TARGET_GNU2_TLS)
14924    {
14925       emit_insn (gen_tls_dynamic_gnu2_64
14926		  (operands[0], operands[1]));
14927       DONE;
14928    }
14929  operands[2] = ix86_tls_get_addr ();
14930})
14931
14932(define_insn "*tls_local_dynamic_base_32_gnu"
14933  [(set (match_operand:SI 0 "register_operand" "=a")
14934	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14935                    (match_operand:SI 2 "call_insn_operand" "")]
14936		   UNSPEC_TLS_LD_BASE))
14937   (clobber (match_scratch:SI 3 "=d"))
14938   (clobber (match_scratch:SI 4 "=c"))
14939   (clobber (reg:CC FLAGS_REG))]
14940  "!TARGET_64BIT && TARGET_GNU_TLS"
14941  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14942  [(set_attr "type" "multi")
14943   (set_attr "length" "11")])
14944
14945(define_insn "*tls_local_dynamic_base_32_sun"
14946  [(set (match_operand:SI 0 "register_operand" "=a")
14947	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14948                    (match_operand:SI 2 "call_insn_operand" "")]
14949		   UNSPEC_TLS_LD_BASE))
14950   (clobber (match_scratch:SI 3 "=d"))
14951   (clobber (match_scratch:SI 4 "=c"))
14952   (clobber (reg:CC FLAGS_REG))]
14953  "!TARGET_64BIT && TARGET_SUN_TLS"
14954  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14955	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14956  [(set_attr "type" "multi")
14957   (set_attr "length" "13")])
14958
14959(define_expand "tls_local_dynamic_base_32"
14960  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14961		   (unspec:SI [(match_dup 1) (match_dup 2)]
14962			      UNSPEC_TLS_LD_BASE))
14963	      (clobber (match_scratch:SI 3 ""))
14964	      (clobber (match_scratch:SI 4 ""))
14965	      (clobber (reg:CC FLAGS_REG))])]
14966  ""
14967{
14968  if (flag_pic)
14969    operands[1] = pic_offset_table_rtx;
14970  else
14971    {
14972      operands[1] = gen_reg_rtx (Pmode);
14973      emit_insn (gen_set_got (operands[1]));
14974    }
14975  if (TARGET_GNU2_TLS)
14976    {
14977       emit_insn (gen_tls_dynamic_gnu2_32
14978		  (operands[0], ix86_tls_module_base (), operands[1]));
14979       DONE;
14980    }
14981  operands[2] = ix86_tls_get_addr ();
14982})
14983
14984(define_insn "*tls_local_dynamic_base_64"
14985  [(set (match_operand:DI 0 "register_operand" "=a")
14986	(call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14987		 (match_operand:DI 2 "" "")))
14988   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14989  "TARGET_64BIT"
14990  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14991  [(set_attr "type" "multi")
14992   (set_attr "length" "12")])
14993
14994(define_expand "tls_local_dynamic_base_64"
14995  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14996		   (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14997	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14998  ""
14999{
15000  if (TARGET_GNU2_TLS)
15001    {
15002       emit_insn (gen_tls_dynamic_gnu2_64
15003		  (operands[0], ix86_tls_module_base ()));
15004       DONE;
15005    }
15006  operands[1] = ix86_tls_get_addr ();
15007})
15008
15009;; Local dynamic of a single variable is a lose.  Show combine how
15010;; to convert that back to global dynamic.
15011
15012(define_insn_and_split "*tls_local_dynamic_32_once"
15013  [(set (match_operand:SI 0 "register_operand" "=a")
15014	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15015			     (match_operand:SI 2 "call_insn_operand" "")]
15016			    UNSPEC_TLS_LD_BASE)
15017		 (const:SI (unspec:SI
15018			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
15019			    UNSPEC_DTPOFF))))
15020   (clobber (match_scratch:SI 4 "=d"))
15021   (clobber (match_scratch:SI 5 "=c"))
15022   (clobber (reg:CC FLAGS_REG))]
15023  ""
15024  "#"
15025  ""
15026  [(parallel [(set (match_dup 0)
15027		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15028			      UNSPEC_TLS_GD))
15029	      (clobber (match_dup 4))
15030	      (clobber (match_dup 5))
15031	      (clobber (reg:CC FLAGS_REG))])]
15032  "")
15033
15034;; Load and add the thread base pointer from %gs:0.
15035
15036(define_insn "*load_tp_si"
15037  [(set (match_operand:SI 0 "register_operand" "=r")
15038	(unspec:SI [(const_int 0)] UNSPEC_TP))]
15039  "!TARGET_64BIT"
15040  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15041  [(set_attr "type" "imov")
15042   (set_attr "modrm" "0")
15043   (set_attr "length" "7")
15044   (set_attr "memory" "load")
15045   (set_attr "imm_disp" "false")])
15046
15047(define_insn "*add_tp_si"
15048  [(set (match_operand:SI 0 "register_operand" "=r")
15049	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15050		 (match_operand:SI 1 "register_operand" "0")))
15051   (clobber (reg:CC FLAGS_REG))]
15052  "!TARGET_64BIT"
15053  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15054  [(set_attr "type" "alu")
15055   (set_attr "modrm" "0")
15056   (set_attr "length" "7")
15057   (set_attr "memory" "load")
15058   (set_attr "imm_disp" "false")])
15059
15060(define_insn "*load_tp_di"
15061  [(set (match_operand:DI 0 "register_operand" "=r")
15062	(unspec:DI [(const_int 0)] UNSPEC_TP))]
15063  "TARGET_64BIT"
15064  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15065  [(set_attr "type" "imov")
15066   (set_attr "modrm" "0")
15067   (set_attr "length" "7")
15068   (set_attr "memory" "load")
15069   (set_attr "imm_disp" "false")])
15070
15071(define_insn "*add_tp_di"
15072  [(set (match_operand:DI 0 "register_operand" "=r")
15073	(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15074		 (match_operand:DI 1 "register_operand" "0")))
15075   (clobber (reg:CC FLAGS_REG))]
15076  "TARGET_64BIT"
15077  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15078  [(set_attr "type" "alu")
15079   (set_attr "modrm" "0")
15080   (set_attr "length" "7")
15081   (set_attr "memory" "load")
15082   (set_attr "imm_disp" "false")])
15083
15084;; GNU2 TLS patterns can be split.
15085
15086(define_expand "tls_dynamic_gnu2_32"
15087  [(set (match_dup 3)
15088	(plus:SI (match_operand:SI 2 "register_operand" "")
15089		 (const:SI
15090		  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15091			     UNSPEC_TLSDESC))))
15092   (parallel
15093    [(set (match_operand:SI 0 "register_operand" "")
15094	  (unspec:SI [(match_dup 1) (match_dup 3)
15095		      (match_dup 2) (reg:SI SP_REG)]
15096		      UNSPEC_TLSDESC))
15097     (clobber (reg:CC FLAGS_REG))])]
15098  "!TARGET_64BIT && TARGET_GNU2_TLS"
15099{
15100  operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15101  ix86_tls_descriptor_calls_expanded_in_cfun = true;
15102})
15103
15104(define_insn "*tls_dynamic_lea_32"
15105  [(set (match_operand:SI 0 "register_operand" "=r")
15106	(plus:SI (match_operand:SI 1 "register_operand" "b")
15107		 (const:SI
15108		  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15109			      UNSPEC_TLSDESC))))]
15110  "!TARGET_64BIT && TARGET_GNU2_TLS"
15111  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15112  [(set_attr "type" "lea")
15113   (set_attr "mode" "SI")
15114   (set_attr "length" "6")
15115   (set_attr "length_address" "4")])
15116
15117(define_insn "*tls_dynamic_call_32"
15118  [(set (match_operand:SI 0 "register_operand" "=a")
15119	(unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15120		    (match_operand:SI 2 "register_operand" "0")
15121		    ;; we have to make sure %ebx still points to the GOT
15122		    (match_operand:SI 3 "register_operand" "b")
15123		    (reg:SI SP_REG)]
15124		   UNSPEC_TLSDESC))
15125   (clobber (reg:CC FLAGS_REG))]
15126  "!TARGET_64BIT && TARGET_GNU2_TLS"
15127  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15128  [(set_attr "type" "call")
15129   (set_attr "length" "2")
15130   (set_attr "length_address" "0")])
15131
15132(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15133  [(set (match_operand:SI 0 "register_operand" "=&a")
15134	(plus:SI
15135	 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15136		     (match_operand:SI 4 "" "")
15137		     (match_operand:SI 2 "register_operand" "b")
15138		     (reg:SI SP_REG)]
15139		    UNSPEC_TLSDESC)
15140	 (const:SI (unspec:SI
15141		    [(match_operand:SI 1 "tls_symbolic_operand" "")]
15142		    UNSPEC_DTPOFF))))
15143   (clobber (reg:CC FLAGS_REG))]
15144  "!TARGET_64BIT && TARGET_GNU2_TLS"
15145  "#"
15146  ""
15147  [(set (match_dup 0) (match_dup 5))]
15148{
15149  operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15150  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15151})
15152
15153(define_expand "tls_dynamic_gnu2_64"
15154  [(set (match_dup 2)
15155	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15156		   UNSPEC_TLSDESC))
15157   (parallel
15158    [(set (match_operand:DI 0 "register_operand" "")
15159	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15160		     UNSPEC_TLSDESC))
15161     (clobber (reg:CC FLAGS_REG))])]
15162  "TARGET_64BIT && TARGET_GNU2_TLS"
15163{
15164  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15165  ix86_tls_descriptor_calls_expanded_in_cfun = true;
15166})
15167
15168(define_insn "*tls_dynamic_lea_64"
15169  [(set (match_operand:DI 0 "register_operand" "=r")
15170	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15171		   UNSPEC_TLSDESC))]
15172  "TARGET_64BIT && TARGET_GNU2_TLS"
15173  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15174  [(set_attr "type" "lea")
15175   (set_attr "mode" "DI")
15176   (set_attr "length" "7")
15177   (set_attr "length_address" "4")])
15178
15179(define_insn "*tls_dynamic_call_64"
15180  [(set (match_operand:DI 0 "register_operand" "=a")
15181	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15182		    (match_operand:DI 2 "register_operand" "0")
15183		    (reg:DI SP_REG)]
15184		   UNSPEC_TLSDESC))
15185   (clobber (reg:CC FLAGS_REG))]
15186  "TARGET_64BIT && TARGET_GNU2_TLS"
15187  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15188  [(set_attr "type" "call")
15189   (set_attr "length" "2")
15190   (set_attr "length_address" "0")])
15191
15192(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15193  [(set (match_operand:DI 0 "register_operand" "=&a")
15194	(plus:DI
15195	 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15196		     (match_operand:DI 3 "" "")
15197		     (reg:DI SP_REG)]
15198		    UNSPEC_TLSDESC)
15199	 (const:DI (unspec:DI
15200		    [(match_operand:DI 1 "tls_symbolic_operand" "")]
15201		    UNSPEC_DTPOFF))))
15202   (clobber (reg:CC FLAGS_REG))]
15203  "TARGET_64BIT && TARGET_GNU2_TLS"
15204  "#"
15205  ""
15206  [(set (match_dup 0) (match_dup 4))]
15207{
15208  operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15209  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15210})
15211
15212;;
15213
15214;; These patterns match the binary 387 instructions for addM3, subM3,
15215;; mulM3 and divM3.  There are three patterns for each of DFmode and
15216;; SFmode.  The first is the normal insn, the second the same insn but
15217;; with one operand a conversion, and the third the same insn but with
15218;; the other operand a conversion.  The conversion may be SFmode or
15219;; SImode if the target mode DFmode, but only SImode if the target mode
15220;; is SFmode.
15221
15222;; Gcc is slightly more smart about handling normal two address instructions
15223;; so use special patterns for add and mull.
15224
15225(define_insn "*fop_sf_comm_mixed"
15226  [(set (match_operand:SF 0 "register_operand" "=f,x")
15227	(match_operator:SF 3 "binary_fp_operator"
15228			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15229			 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15230  "TARGET_MIX_SSE_I387
15231   && COMMUTATIVE_ARITH_P (operands[3])
15232   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15233  "* return output_387_binary_op (insn, operands);"
15234  [(set (attr "type") 
15235	(if_then_else (eq_attr "alternative" "1")
15236	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
15237	      (const_string "ssemul")
15238	      (const_string "sseadd"))
15239	   (if_then_else (match_operand:SF 3 "mult_operator" "") 
15240	      (const_string "fmul")
15241	      (const_string "fop"))))
15242   (set_attr "mode" "SF")])
15243
15244(define_insn "*fop_sf_comm_sse"
15245  [(set (match_operand:SF 0 "register_operand" "=x")
15246	(match_operator:SF 3 "binary_fp_operator"
15247			[(match_operand:SF 1 "nonimmediate_operand" "%0")
15248			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15249  "TARGET_SSE_MATH
15250   && COMMUTATIVE_ARITH_P (operands[3])
15251   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15252  "* return output_387_binary_op (insn, operands);"
15253  [(set (attr "type") 
15254        (if_then_else (match_operand:SF 3 "mult_operator" "") 
15255	   (const_string "ssemul")
15256	   (const_string "sseadd")))
15257   (set_attr "mode" "SF")])
15258
15259(define_insn "*fop_sf_comm_i387"
15260  [(set (match_operand:SF 0 "register_operand" "=f")
15261	(match_operator:SF 3 "binary_fp_operator"
15262			[(match_operand:SF 1 "nonimmediate_operand" "%0")
15263			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15264  "TARGET_80387
15265   && COMMUTATIVE_ARITH_P (operands[3])
15266   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15267  "* return output_387_binary_op (insn, operands);"
15268  [(set (attr "type") 
15269	(if_then_else (match_operand:SF 3 "mult_operator" "") 
15270	   (const_string "fmul")
15271	   (const_string "fop")))
15272   (set_attr "mode" "SF")])
15273
15274(define_insn "*fop_sf_1_mixed"
15275  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15276	(match_operator:SF 3 "binary_fp_operator"
15277			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15278			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15279  "TARGET_MIX_SSE_I387
15280   && !COMMUTATIVE_ARITH_P (operands[3])
15281   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15282  "* return output_387_binary_op (insn, operands);"
15283  [(set (attr "type") 
15284        (cond [(and (eq_attr "alternative" "2")
15285	            (match_operand:SF 3 "mult_operator" ""))
15286                 (const_string "ssemul")
15287	       (and (eq_attr "alternative" "2")
15288	            (match_operand:SF 3 "div_operator" ""))
15289                 (const_string "ssediv")
15290	       (eq_attr "alternative" "2")
15291                 (const_string "sseadd")
15292	       (match_operand:SF 3 "mult_operator" "") 
15293                 (const_string "fmul")
15294               (match_operand:SF 3 "div_operator" "") 
15295                 (const_string "fdiv")
15296              ]
15297              (const_string "fop")))
15298   (set_attr "mode" "SF")])
15299
15300(define_insn "*fop_sf_1_sse"
15301  [(set (match_operand:SF 0 "register_operand" "=x")
15302	(match_operator:SF 3 "binary_fp_operator"
15303			[(match_operand:SF 1 "register_operand" "0")
15304			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15305  "TARGET_SSE_MATH
15306   && !COMMUTATIVE_ARITH_P (operands[3])"
15307  "* return output_387_binary_op (insn, operands);"
15308  [(set (attr "type") 
15309        (cond [(match_operand:SF 3 "mult_operator" "")
15310                 (const_string "ssemul")
15311	       (match_operand:SF 3 "div_operator" "")
15312                 (const_string "ssediv")
15313              ]
15314              (const_string "sseadd")))
15315   (set_attr "mode" "SF")])
15316
15317;; This pattern is not fully shadowed by the pattern above.
15318(define_insn "*fop_sf_1_i387"
15319  [(set (match_operand:SF 0 "register_operand" "=f,f")
15320	(match_operator:SF 3 "binary_fp_operator"
15321			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15322			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15323  "TARGET_80387 && !TARGET_SSE_MATH
15324   && !COMMUTATIVE_ARITH_P (operands[3])
15325   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15326  "* return output_387_binary_op (insn, operands);"
15327  [(set (attr "type") 
15328        (cond [(match_operand:SF 3 "mult_operator" "") 
15329                 (const_string "fmul")
15330               (match_operand:SF 3 "div_operator" "") 
15331                 (const_string "fdiv")
15332              ]
15333              (const_string "fop")))
15334   (set_attr "mode" "SF")])
15335
15336;; ??? Add SSE splitters for these!
15337(define_insn "*fop_sf_2<mode>_i387"
15338  [(set (match_operand:SF 0 "register_operand" "=f,f")
15339	(match_operator:SF 3 "binary_fp_operator"
15340	  [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15341	   (match_operand:SF 2 "register_operand" "0,0")]))]
15342  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15343  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15344  [(set (attr "type") 
15345        (cond [(match_operand:SF 3 "mult_operator" "") 
15346                 (const_string "fmul")
15347               (match_operand:SF 3 "div_operator" "") 
15348                 (const_string "fdiv")
15349              ]
15350              (const_string "fop")))
15351   (set_attr "fp_int_src" "true")
15352   (set_attr "mode" "<MODE>")])
15353
15354(define_insn "*fop_sf_3<mode>_i387"
15355  [(set (match_operand:SF 0 "register_operand" "=f,f")
15356	(match_operator:SF 3 "binary_fp_operator"
15357	  [(match_operand:SF 1 "register_operand" "0,0")
15358	   (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15359  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15360  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15361  [(set (attr "type") 
15362        (cond [(match_operand:SF 3 "mult_operator" "") 
15363                 (const_string "fmul")
15364               (match_operand:SF 3 "div_operator" "") 
15365                 (const_string "fdiv")
15366              ]
15367              (const_string "fop")))
15368   (set_attr "fp_int_src" "true")
15369   (set_attr "mode" "<MODE>")])
15370
15371(define_insn "*fop_df_comm_mixed"
15372  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15373	(match_operator:DF 3 "binary_fp_operator"
15374			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15375			 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15376  "TARGET_SSE2 && TARGET_MIX_SSE_I387
15377   && COMMUTATIVE_ARITH_P (operands[3])
15378   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15379  "* return output_387_binary_op (insn, operands);"
15380  [(set (attr "type") 
15381	(if_then_else (eq_attr "alternative" "1")
15382	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15383	      (const_string "ssemul")
15384	      (const_string "sseadd"))
15385	   (if_then_else (match_operand:DF 3 "mult_operator" "") 
15386	      (const_string "fmul")
15387	      (const_string "fop"))))
15388   (set_attr "mode" "DF")])
15389
15390(define_insn "*fop_df_comm_sse"
15391  [(set (match_operand:DF 0 "register_operand" "=Y")
15392	(match_operator:DF 3 "binary_fp_operator"
15393			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15394			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15395  "TARGET_SSE2 && TARGET_SSE_MATH
15396   && COMMUTATIVE_ARITH_P (operands[3])
15397   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15398  "* return output_387_binary_op (insn, operands);"
15399  [(set (attr "type") 
15400        (if_then_else (match_operand:DF 3 "mult_operator" "") 
15401	   (const_string "ssemul")
15402	   (const_string "sseadd")))
15403   (set_attr "mode" "DF")])
15404
15405(define_insn "*fop_df_comm_i387"
15406  [(set (match_operand:DF 0 "register_operand" "=f")
15407	(match_operator:DF 3 "binary_fp_operator"
15408			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15409			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15410  "TARGET_80387
15411   && COMMUTATIVE_ARITH_P (operands[3])
15412   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15413  "* return output_387_binary_op (insn, operands);"
15414  [(set (attr "type") 
15415	(if_then_else (match_operand:DF 3 "mult_operator" "") 
15416	   (const_string "fmul")
15417	   (const_string "fop")))
15418   (set_attr "mode" "DF")])
15419
15420(define_insn "*fop_df_1_mixed"
15421  [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15422	(match_operator:DF 3 "binary_fp_operator"
15423			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15424			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15425  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15426   && !COMMUTATIVE_ARITH_P (operands[3])
15427   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15428  "* return output_387_binary_op (insn, operands);"
15429  [(set (attr "type") 
15430        (cond [(and (eq_attr "alternative" "2")
15431	            (match_operand:DF 3 "mult_operator" ""))
15432                 (const_string "ssemul")
15433	       (and (eq_attr "alternative" "2")
15434	            (match_operand:DF 3 "div_operator" ""))
15435                 (const_string "ssediv")
15436	       (eq_attr "alternative" "2")
15437                 (const_string "sseadd")
15438	       (match_operand:DF 3 "mult_operator" "") 
15439                 (const_string "fmul")
15440               (match_operand:DF 3 "div_operator" "") 
15441                 (const_string "fdiv")
15442              ]
15443              (const_string "fop")))
15444   (set_attr "mode" "DF")])
15445
15446(define_insn "*fop_df_1_sse"
15447  [(set (match_operand:DF 0 "register_operand" "=Y")
15448	(match_operator:DF 3 "binary_fp_operator"
15449			[(match_operand:DF 1 "register_operand" "0")
15450			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15451  "TARGET_SSE2 && TARGET_SSE_MATH
15452   && !COMMUTATIVE_ARITH_P (operands[3])"
15453  "* return output_387_binary_op (insn, operands);"
15454  [(set_attr "mode" "DF")
15455   (set (attr "type") 
15456        (cond [(match_operand:DF 3 "mult_operator" "")
15457                 (const_string "ssemul")
15458	       (match_operand:DF 3 "div_operator" "")
15459                 (const_string "ssediv")
15460              ]
15461              (const_string "sseadd")))])
15462
15463;; This pattern is not fully shadowed by the pattern above.
15464(define_insn "*fop_df_1_i387"
15465  [(set (match_operand:DF 0 "register_operand" "=f,f")
15466	(match_operator:DF 3 "binary_fp_operator"
15467			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15468			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15469  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15470   && !COMMUTATIVE_ARITH_P (operands[3])
15471   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15472  "* return output_387_binary_op (insn, operands);"
15473  [(set (attr "type") 
15474        (cond [(match_operand:DF 3 "mult_operator" "") 
15475                 (const_string "fmul")
15476               (match_operand:DF 3 "div_operator" "")
15477                 (const_string "fdiv")
15478              ]
15479              (const_string "fop")))
15480   (set_attr "mode" "DF")])
15481
15482;; ??? Add SSE splitters for these!
15483(define_insn "*fop_df_2<mode>_i387"
15484  [(set (match_operand:DF 0 "register_operand" "=f,f")
15485	(match_operator:DF 3 "binary_fp_operator"
15486	   [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15487	    (match_operand:DF 2 "register_operand" "0,0")]))]
15488  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15489   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15490  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15491  [(set (attr "type") 
15492        (cond [(match_operand:DF 3 "mult_operator" "") 
15493                 (const_string "fmul")
15494               (match_operand:DF 3 "div_operator" "") 
15495                 (const_string "fdiv")
15496              ]
15497              (const_string "fop")))
15498   (set_attr "fp_int_src" "true")
15499   (set_attr "mode" "<MODE>")])
15500
15501(define_insn "*fop_df_3<mode>_i387"
15502  [(set (match_operand:DF 0 "register_operand" "=f,f")
15503	(match_operator:DF 3 "binary_fp_operator"
15504	   [(match_operand:DF 1 "register_operand" "0,0")
15505	    (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15506  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15507   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15508  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15509  [(set (attr "type") 
15510        (cond [(match_operand:DF 3 "mult_operator" "") 
15511                 (const_string "fmul")
15512               (match_operand:DF 3 "div_operator" "") 
15513                 (const_string "fdiv")
15514              ]
15515              (const_string "fop")))
15516   (set_attr "fp_int_src" "true")
15517   (set_attr "mode" "<MODE>")])
15518
15519(define_insn "*fop_df_4_i387"
15520  [(set (match_operand:DF 0 "register_operand" "=f,f")
15521	(match_operator:DF 3 "binary_fp_operator"
15522	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15523	    (match_operand:DF 2 "register_operand" "0,f")]))]
15524  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15525   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15526  "* return output_387_binary_op (insn, operands);"
15527  [(set (attr "type") 
15528        (cond [(match_operand:DF 3 "mult_operator" "") 
15529                 (const_string "fmul")
15530               (match_operand:DF 3 "div_operator" "") 
15531                 (const_string "fdiv")
15532              ]
15533              (const_string "fop")))
15534   (set_attr "mode" "SF")])
15535
15536(define_insn "*fop_df_5_i387"
15537  [(set (match_operand:DF 0 "register_operand" "=f,f")
15538	(match_operator:DF 3 "binary_fp_operator"
15539	  [(match_operand:DF 1 "register_operand" "0,f")
15540	   (float_extend:DF
15541	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15542  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15543  "* return output_387_binary_op (insn, operands);"
15544  [(set (attr "type") 
15545        (cond [(match_operand:DF 3 "mult_operator" "") 
15546                 (const_string "fmul")
15547               (match_operand:DF 3 "div_operator" "") 
15548                 (const_string "fdiv")
15549              ]
15550              (const_string "fop")))
15551   (set_attr "mode" "SF")])
15552
15553(define_insn "*fop_df_6_i387"
15554  [(set (match_operand:DF 0 "register_operand" "=f,f")
15555	(match_operator:DF 3 "binary_fp_operator"
15556	  [(float_extend:DF
15557	    (match_operand:SF 1 "register_operand" "0,f"))
15558	   (float_extend:DF
15559	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15560  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15561  "* return output_387_binary_op (insn, operands);"
15562  [(set (attr "type") 
15563        (cond [(match_operand:DF 3 "mult_operator" "") 
15564                 (const_string "fmul")
15565               (match_operand:DF 3 "div_operator" "") 
15566                 (const_string "fdiv")
15567              ]
15568              (const_string "fop")))
15569   (set_attr "mode" "SF")])
15570
15571(define_insn "*fop_xf_comm_i387"
15572  [(set (match_operand:XF 0 "register_operand" "=f")
15573	(match_operator:XF 3 "binary_fp_operator"
15574			[(match_operand:XF 1 "register_operand" "%0")
15575			 (match_operand:XF 2 "register_operand" "f")]))]
15576  "TARGET_80387
15577   && COMMUTATIVE_ARITH_P (operands[3])"
15578  "* return output_387_binary_op (insn, operands);"
15579  [(set (attr "type") 
15580        (if_then_else (match_operand:XF 3 "mult_operator" "") 
15581           (const_string "fmul")
15582           (const_string "fop")))
15583   (set_attr "mode" "XF")])
15584
15585(define_insn "*fop_xf_1_i387"
15586  [(set (match_operand:XF 0 "register_operand" "=f,f")
15587	(match_operator:XF 3 "binary_fp_operator"
15588			[(match_operand:XF 1 "register_operand" "0,f")
15589			 (match_operand:XF 2 "register_operand" "f,0")]))]
15590  "TARGET_80387
15591   && !COMMUTATIVE_ARITH_P (operands[3])"
15592  "* return output_387_binary_op (insn, operands);"
15593  [(set (attr "type") 
15594        (cond [(match_operand:XF 3 "mult_operator" "") 
15595                 (const_string "fmul")
15596               (match_operand:XF 3 "div_operator" "") 
15597                 (const_string "fdiv")
15598              ]
15599              (const_string "fop")))
15600   (set_attr "mode" "XF")])
15601
15602(define_insn "*fop_xf_2<mode>_i387"
15603  [(set (match_operand:XF 0 "register_operand" "=f,f")
15604	(match_operator:XF 3 "binary_fp_operator"
15605	   [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15606	    (match_operand:XF 2 "register_operand" "0,0")]))]
15607  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15608  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15609  [(set (attr "type") 
15610        (cond [(match_operand:XF 3 "mult_operator" "") 
15611                 (const_string "fmul")
15612               (match_operand:XF 3 "div_operator" "") 
15613                 (const_string "fdiv")
15614              ]
15615              (const_string "fop")))
15616   (set_attr "fp_int_src" "true")
15617   (set_attr "mode" "<MODE>")])
15618
15619(define_insn "*fop_xf_3<mode>_i387"
15620  [(set (match_operand:XF 0 "register_operand" "=f,f")
15621	(match_operator:XF 3 "binary_fp_operator"
15622	  [(match_operand:XF 1 "register_operand" "0,0")
15623	   (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15624  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15625  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15626  [(set (attr "type") 
15627        (cond [(match_operand:XF 3 "mult_operator" "") 
15628                 (const_string "fmul")
15629               (match_operand:XF 3 "div_operator" "") 
15630                 (const_string "fdiv")
15631              ]
15632              (const_string "fop")))
15633   (set_attr "fp_int_src" "true")
15634   (set_attr "mode" "<MODE>")])
15635
15636(define_insn "*fop_xf_4_i387"
15637  [(set (match_operand:XF 0 "register_operand" "=f,f")
15638	(match_operator:XF 3 "binary_fp_operator"
15639	   [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15640	    (match_operand:XF 2 "register_operand" "0,f")]))]
15641  "TARGET_80387"
15642  "* return output_387_binary_op (insn, operands);"
15643  [(set (attr "type") 
15644        (cond [(match_operand:XF 3 "mult_operator" "") 
15645                 (const_string "fmul")
15646               (match_operand:XF 3 "div_operator" "") 
15647                 (const_string "fdiv")
15648              ]
15649              (const_string "fop")))
15650   (set_attr "mode" "SF")])
15651
15652(define_insn "*fop_xf_5_i387"
15653  [(set (match_operand:XF 0 "register_operand" "=f,f")
15654	(match_operator:XF 3 "binary_fp_operator"
15655	  [(match_operand:XF 1 "register_operand" "0,f")
15656	   (float_extend:XF
15657	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15658  "TARGET_80387"
15659  "* return output_387_binary_op (insn, operands);"
15660  [(set (attr "type") 
15661        (cond [(match_operand:XF 3 "mult_operator" "") 
15662                 (const_string "fmul")
15663               (match_operand:XF 3 "div_operator" "") 
15664                 (const_string "fdiv")
15665              ]
15666              (const_string "fop")))
15667   (set_attr "mode" "SF")])
15668
15669(define_insn "*fop_xf_6_i387"
15670  [(set (match_operand:XF 0 "register_operand" "=f,f")
15671	(match_operator:XF 3 "binary_fp_operator"
15672	  [(float_extend:XF
15673	    (match_operand 1 "register_operand" "0,f"))
15674	   (float_extend:XF
15675	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15676  "TARGET_80387"
15677  "* return output_387_binary_op (insn, operands);"
15678  [(set (attr "type") 
15679        (cond [(match_operand:XF 3 "mult_operator" "") 
15680                 (const_string "fmul")
15681               (match_operand:XF 3 "div_operator" "") 
15682                 (const_string "fdiv")
15683              ]
15684              (const_string "fop")))
15685   (set_attr "mode" "SF")])
15686
15687(define_split
15688  [(set (match_operand 0 "register_operand" "")
15689	(match_operator 3 "binary_fp_operator"
15690	   [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15691	    (match_operand 2 "register_operand" "")]))]
15692  "TARGET_80387 && reload_completed
15693   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15694  [(const_int 0)]
15695{ 
15696  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15697  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15698  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15699			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15700					  GET_MODE (operands[3]),
15701					  operands[4],
15702					  operands[2])));
15703  ix86_free_from_memory (GET_MODE (operands[1]));
15704  DONE;
15705})
15706
15707(define_split
15708  [(set (match_operand 0 "register_operand" "")
15709	(match_operator 3 "binary_fp_operator"
15710	   [(match_operand 1 "register_operand" "")
15711	    (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15712  "TARGET_80387 && reload_completed
15713   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15714  [(const_int 0)]
15715{
15716  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15717  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15718  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15719			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15720					  GET_MODE (operands[3]),
15721					  operands[1],
15722					  operands[4])));
15723  ix86_free_from_memory (GET_MODE (operands[2]));
15724  DONE;
15725})
15726
15727;; FPU special functions.
15728
15729(define_expand "sqrtsf2"
15730  [(set (match_operand:SF 0 "register_operand" "")
15731	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15732  "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15733{
15734  if (!TARGET_SSE_MATH)
15735    operands[1] = force_reg (SFmode, operands[1]);
15736})
15737
15738(define_insn "*sqrtsf2_mixed"
15739  [(set (match_operand:SF 0 "register_operand" "=f,x")
15740	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15741  "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15742  "@
15743   fsqrt
15744   sqrtss\t{%1, %0|%0, %1}"
15745  [(set_attr "type" "fpspc,sse")
15746   (set_attr "mode" "SF,SF")
15747   (set_attr "athlon_decode" "direct,*")
15748   (set_attr "amdfam10_decode" "direct,*")])
15749
15750(define_insn "*sqrtsf2_sse"
15751  [(set (match_operand:SF 0 "register_operand" "=x")
15752	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15753  "TARGET_SSE_MATH"
15754  "sqrtss\t{%1, %0|%0, %1}"
15755  [(set_attr "type" "sse")
15756   (set_attr "mode" "SF")
15757   (set_attr "athlon_decode" "*")
15758   (set_attr "amdfam10_decode" "*")])
15759
15760(define_insn "*sqrtsf2_i387"
15761  [(set (match_operand:SF 0 "register_operand" "=f")
15762	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15763  "TARGET_USE_FANCY_MATH_387"
15764  "fsqrt"
15765  [(set_attr "type" "fpspc")
15766   (set_attr "mode" "SF")
15767   (set_attr "athlon_decode" "direct")
15768   (set_attr "amdfam10_decode" "direct")])
15769
15770(define_expand "sqrtdf2"
15771  [(set (match_operand:DF 0 "register_operand" "")
15772	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15773  "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15774{
15775  if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15776    operands[1] = force_reg (DFmode, operands[1]);
15777})
15778
15779(define_insn "*sqrtdf2_mixed"
15780  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15781	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15782  "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15783  "@
15784   fsqrt
15785   sqrtsd\t{%1, %0|%0, %1}"
15786  [(set_attr "type" "fpspc,sse")
15787   (set_attr "mode" "DF,DF")
15788   (set_attr "athlon_decode" "direct,*")
15789   (set_attr "amdfam10_decode" "direct,*")])
15790
15791(define_insn "*sqrtdf2_sse"
15792  [(set (match_operand:DF 0 "register_operand" "=Y")
15793	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15794  "TARGET_SSE2 && TARGET_SSE_MATH"
15795  "sqrtsd\t{%1, %0|%0, %1}"
15796  [(set_attr "type" "sse")
15797   (set_attr "mode" "DF")
15798   (set_attr "athlon_decode" "*")
15799   (set_attr "amdfam10_decode" "*")])
15800
15801(define_insn "*sqrtdf2_i387"
15802  [(set (match_operand:DF 0 "register_operand" "=f")
15803	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15804  "TARGET_USE_FANCY_MATH_387"
15805  "fsqrt"
15806  [(set_attr "type" "fpspc")
15807   (set_attr "mode" "DF")
15808   (set_attr "athlon_decode" "direct")
15809   (set_attr "amdfam10_decode" "direct")])
15810
15811(define_insn "*sqrtextendsfdf2_i387"
15812  [(set (match_operand:DF 0 "register_operand" "=f")
15813	(sqrt:DF (float_extend:DF
15814		  (match_operand:SF 1 "register_operand" "0"))))]
15815  "TARGET_USE_FANCY_MATH_387
15816   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15817  "fsqrt"
15818  [(set_attr "type" "fpspc")
15819   (set_attr "mode" "DF")
15820   (set_attr "athlon_decode" "direct")
15821   (set_attr "amdfam10_decode" "direct")])
15822
15823(define_insn "sqrtxf2"
15824  [(set (match_operand:XF 0 "register_operand" "=f")
15825	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15826  "TARGET_USE_FANCY_MATH_387"
15827  "fsqrt"
15828  [(set_attr "type" "fpspc")
15829   (set_attr "mode" "XF")
15830   (set_attr "athlon_decode" "direct")
15831   (set_attr "amdfam10_decode" "direct")])
15832
15833(define_insn "*sqrtextendsfxf2_i387"
15834  [(set (match_operand:XF 0 "register_operand" "=f")
15835	(sqrt:XF (float_extend:XF
15836		  (match_operand:SF 1 "register_operand" "0"))))]
15837  "TARGET_USE_FANCY_MATH_387"
15838  "fsqrt"
15839  [(set_attr "type" "fpspc")
15840   (set_attr "mode" "XF")
15841   (set_attr "athlon_decode" "direct")
15842   (set_attr "amdfam10_decode" "direct")])
15843
15844(define_insn "*sqrtextenddfxf2_i387"
15845  [(set (match_operand:XF 0 "register_operand" "=f")
15846	(sqrt:XF (float_extend:XF
15847		  (match_operand:DF 1 "register_operand" "0"))))]
15848  "TARGET_USE_FANCY_MATH_387"
15849  "fsqrt"
15850  [(set_attr "type" "fpspc")
15851   (set_attr "mode" "XF")
15852   (set_attr "athlon_decode" "direct")
15853   (set_attr "amdfam10_decode" "direct")])
15854
15855(define_insn "fpremxf4"
15856  [(set (match_operand:XF 0 "register_operand" "=f")
15857	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15858		    (match_operand:XF 3 "register_operand" "1")]
15859		   UNSPEC_FPREM_F))
15860   (set (match_operand:XF 1 "register_operand" "=u")
15861	(unspec:XF [(match_dup 2) (match_dup 3)]
15862		   UNSPEC_FPREM_U))
15863   (set (reg:CCFP FPSR_REG)
15864	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15865  "TARGET_USE_FANCY_MATH_387
15866   && flag_unsafe_math_optimizations"
15867  "fprem"
15868  [(set_attr "type" "fpspc")
15869   (set_attr "mode" "XF")])
15870
15871(define_expand "fmodsf3"
15872  [(use (match_operand:SF 0 "register_operand" ""))
15873   (use (match_operand:SF 1 "register_operand" ""))
15874   (use (match_operand:SF 2 "register_operand" ""))]
15875  "TARGET_USE_FANCY_MATH_387
15876   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15877   && flag_unsafe_math_optimizations"
15878{
15879  rtx label = gen_label_rtx ();
15880
15881  rtx op1 = gen_reg_rtx (XFmode);
15882  rtx op2 = gen_reg_rtx (XFmode);
15883
15884  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15885  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15886
15887  emit_label (label);
15888
15889  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15890  ix86_emit_fp_unordered_jump (label);
15891
15892  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15893  DONE;
15894})
15895
15896(define_expand "fmoddf3"
15897  [(use (match_operand:DF 0 "register_operand" ""))
15898   (use (match_operand:DF 1 "register_operand" ""))
15899   (use (match_operand:DF 2 "register_operand" ""))]
15900  "TARGET_USE_FANCY_MATH_387
15901   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15902   && flag_unsafe_math_optimizations"
15903{
15904  rtx label = gen_label_rtx ();
15905
15906  rtx op1 = gen_reg_rtx (XFmode);
15907  rtx op2 = gen_reg_rtx (XFmode);
15908
15909  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15910  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15911
15912  emit_label (label);
15913
15914  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15915  ix86_emit_fp_unordered_jump (label);
15916
15917  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15918  DONE;
15919})
15920
15921(define_expand "fmodxf3"
15922  [(use (match_operand:XF 0 "register_operand" ""))
15923   (use (match_operand:XF 1 "register_operand" ""))
15924   (use (match_operand:XF 2 "register_operand" ""))]
15925  "TARGET_USE_FANCY_MATH_387
15926   && flag_unsafe_math_optimizations"
15927{
15928  rtx label = gen_label_rtx ();
15929
15930  emit_label (label);
15931
15932  emit_insn (gen_fpremxf4 (operands[1], operands[2],
15933			   operands[1], operands[2]));
15934  ix86_emit_fp_unordered_jump (label);
15935
15936  emit_move_insn (operands[0], operands[1]);
15937  DONE;
15938})
15939
15940(define_insn "fprem1xf4"
15941  [(set (match_operand:XF 0 "register_operand" "=f")
15942	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15943		    (match_operand:XF 3 "register_operand" "1")]
15944		   UNSPEC_FPREM1_F))
15945   (set (match_operand:XF 1 "register_operand" "=u")
15946	(unspec:XF [(match_dup 2) (match_dup 3)]
15947		   UNSPEC_FPREM1_U))
15948   (set (reg:CCFP FPSR_REG)
15949	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15950  "TARGET_USE_FANCY_MATH_387
15951   && flag_unsafe_math_optimizations"
15952  "fprem1"
15953  [(set_attr "type" "fpspc")
15954   (set_attr "mode" "XF")])
15955
15956(define_expand "dremsf3"
15957  [(use (match_operand:SF 0 "register_operand" ""))
15958   (use (match_operand:SF 1 "register_operand" ""))
15959   (use (match_operand:SF 2 "register_operand" ""))]
15960  "TARGET_USE_FANCY_MATH_387
15961   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15962   && flag_unsafe_math_optimizations"
15963{
15964  rtx label = gen_label_rtx ();
15965
15966  rtx op1 = gen_reg_rtx (XFmode);
15967  rtx op2 = gen_reg_rtx (XFmode);
15968
15969  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15970  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15971
15972  emit_label (label);
15973
15974  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15975  ix86_emit_fp_unordered_jump (label);
15976
15977  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15978  DONE;
15979})
15980
15981(define_expand "dremdf3"
15982  [(use (match_operand:DF 0 "register_operand" ""))
15983   (use (match_operand:DF 1 "register_operand" ""))
15984   (use (match_operand:DF 2 "register_operand" ""))]
15985  "TARGET_USE_FANCY_MATH_387
15986   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15987   && flag_unsafe_math_optimizations"
15988{
15989  rtx label = gen_label_rtx ();
15990
15991  rtx op1 = gen_reg_rtx (XFmode);
15992  rtx op2 = gen_reg_rtx (XFmode);
15993
15994  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15995  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15996
15997  emit_label (label);
15998
15999  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
16000  ix86_emit_fp_unordered_jump (label);
16001
16002  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
16003  DONE;
16004})
16005
16006(define_expand "dremxf3"
16007  [(use (match_operand:XF 0 "register_operand" ""))
16008   (use (match_operand:XF 1 "register_operand" ""))
16009   (use (match_operand:XF 2 "register_operand" ""))]
16010  "TARGET_USE_FANCY_MATH_387
16011   && flag_unsafe_math_optimizations"
16012{
16013  rtx label = gen_label_rtx ();
16014
16015  emit_label (label);
16016
16017  emit_insn (gen_fprem1xf4 (operands[1], operands[2],
16018			    operands[1], operands[2]));
16019  ix86_emit_fp_unordered_jump (label);
16020
16021  emit_move_insn (operands[0], operands[1]);
16022  DONE;
16023})
16024
16025(define_insn "*sindf2"
16026  [(set (match_operand:DF 0 "register_operand" "=f")
16027	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
16028  "TARGET_USE_FANCY_MATH_387
16029   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16030   && flag_unsafe_math_optimizations"
16031  "fsin"
16032  [(set_attr "type" "fpspc")
16033   (set_attr "mode" "DF")])
16034
16035(define_insn "*sinsf2"
16036  [(set (match_operand:SF 0 "register_operand" "=f")
16037	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
16038  "TARGET_USE_FANCY_MATH_387
16039   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16040   && flag_unsafe_math_optimizations"
16041  "fsin"
16042  [(set_attr "type" "fpspc")
16043   (set_attr "mode" "SF")])
16044
16045(define_insn "*sinextendsfdf2"
16046  [(set (match_operand:DF 0 "register_operand" "=f")
16047	(unspec:DF [(float_extend:DF
16048		     (match_operand:SF 1 "register_operand" "0"))]
16049		   UNSPEC_SIN))]
16050  "TARGET_USE_FANCY_MATH_387
16051   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16052   && flag_unsafe_math_optimizations"
16053  "fsin"
16054  [(set_attr "type" "fpspc")
16055   (set_attr "mode" "DF")])
16056
16057(define_insn "*sinxf2"
16058  [(set (match_operand:XF 0 "register_operand" "=f")
16059	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16060  "TARGET_USE_FANCY_MATH_387
16061   && flag_unsafe_math_optimizations"
16062  "fsin"
16063  [(set_attr "type" "fpspc")
16064   (set_attr "mode" "XF")])
16065
16066(define_insn "*cosdf2"
16067  [(set (match_operand:DF 0 "register_operand" "=f")
16068	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
16069  "TARGET_USE_FANCY_MATH_387
16070   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16071   && flag_unsafe_math_optimizations"
16072  "fcos"
16073  [(set_attr "type" "fpspc")
16074   (set_attr "mode" "DF")])
16075
16076(define_insn "*cossf2"
16077  [(set (match_operand:SF 0 "register_operand" "=f")
16078	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
16079  "TARGET_USE_FANCY_MATH_387
16080   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16081   && flag_unsafe_math_optimizations"
16082  "fcos"
16083  [(set_attr "type" "fpspc")
16084   (set_attr "mode" "SF")])
16085
16086(define_insn "*cosextendsfdf2"
16087  [(set (match_operand:DF 0 "register_operand" "=f")
16088	(unspec:DF [(float_extend:DF
16089		     (match_operand:SF 1 "register_operand" "0"))]
16090		   UNSPEC_COS))]
16091  "TARGET_USE_FANCY_MATH_387
16092   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16093   && flag_unsafe_math_optimizations"
16094  "fcos"
16095  [(set_attr "type" "fpspc")
16096   (set_attr "mode" "DF")])
16097
16098(define_insn "*cosxf2"
16099  [(set (match_operand:XF 0 "register_operand" "=f")
16100	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16101  "TARGET_USE_FANCY_MATH_387
16102   && flag_unsafe_math_optimizations"
16103  "fcos"
16104  [(set_attr "type" "fpspc")
16105   (set_attr "mode" "XF")])
16106
16107;; With sincos pattern defined, sin and cos builtin function will be
16108;; expanded to sincos pattern with one of its outputs left unused. 
16109;; Cse pass  will detected, if two sincos patterns can be combined,
16110;; otherwise sincos pattern will be split back to sin or cos pattern,
16111;; depending on the unused output.
16112
16113(define_insn "sincosdf3"
16114  [(set (match_operand:DF 0 "register_operand" "=f")
16115	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16116		   UNSPEC_SINCOS_COS))
16117   (set (match_operand:DF 1 "register_operand" "=u")
16118        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16119  "TARGET_USE_FANCY_MATH_387
16120   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16121   && flag_unsafe_math_optimizations"
16122  "fsincos"
16123  [(set_attr "type" "fpspc")
16124   (set_attr "mode" "DF")])
16125
16126(define_split
16127  [(set (match_operand:DF 0 "register_operand" "")
16128	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
16129		   UNSPEC_SINCOS_COS))
16130   (set (match_operand:DF 1 "register_operand" "")
16131	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16132  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16133   && !reload_completed && !reload_in_progress"
16134  [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
16135  "")
16136
16137(define_split
16138  [(set (match_operand:DF 0 "register_operand" "")
16139	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
16140		   UNSPEC_SINCOS_COS))
16141   (set (match_operand:DF 1 "register_operand" "")
16142	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16143  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16144   && !reload_completed && !reload_in_progress"
16145  [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
16146  "")
16147
16148(define_insn "sincossf3"
16149  [(set (match_operand:SF 0 "register_operand" "=f")
16150	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16151		   UNSPEC_SINCOS_COS))
16152   (set (match_operand:SF 1 "register_operand" "=u")
16153        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16154  "TARGET_USE_FANCY_MATH_387
16155   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16156   && flag_unsafe_math_optimizations"
16157  "fsincos"
16158  [(set_attr "type" "fpspc")
16159   (set_attr "mode" "SF")])
16160
16161(define_split
16162  [(set (match_operand:SF 0 "register_operand" "")
16163	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
16164		   UNSPEC_SINCOS_COS))
16165   (set (match_operand:SF 1 "register_operand" "")
16166	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16167  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16168   && !reload_completed && !reload_in_progress"
16169  [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
16170  "")
16171
16172(define_split
16173  [(set (match_operand:SF 0 "register_operand" "")
16174	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
16175		   UNSPEC_SINCOS_COS))
16176   (set (match_operand:SF 1 "register_operand" "")
16177	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16178  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16179   && !reload_completed && !reload_in_progress"
16180  [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
16181  "")
16182
16183(define_insn "*sincosextendsfdf3"
16184  [(set (match_operand:DF 0 "register_operand" "=f")
16185	(unspec:DF [(float_extend:DF
16186		     (match_operand:SF 2 "register_operand" "0"))]
16187		   UNSPEC_SINCOS_COS))
16188   (set (match_operand:DF 1 "register_operand" "=u")
16189        (unspec:DF [(float_extend:DF
16190		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
16191  "TARGET_USE_FANCY_MATH_387
16192   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16193   && flag_unsafe_math_optimizations"
16194  "fsincos"
16195  [(set_attr "type" "fpspc")
16196   (set_attr "mode" "DF")])
16197
16198(define_split
16199  [(set (match_operand:DF 0 "register_operand" "")
16200	(unspec:DF [(float_extend:DF
16201		     (match_operand:SF 2 "register_operand" ""))]
16202		   UNSPEC_SINCOS_COS))
16203   (set (match_operand:DF 1 "register_operand" "")
16204        (unspec:DF [(float_extend:DF
16205		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
16206  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16207   && !reload_completed && !reload_in_progress"
16208  [(set (match_dup 1) (unspec:DF [(float_extend:DF
16209				   (match_dup 2))] UNSPEC_SIN))]
16210  "")
16211
16212(define_split
16213  [(set (match_operand:DF 0 "register_operand" "")
16214	(unspec:DF [(float_extend:DF
16215		     (match_operand:SF 2 "register_operand" ""))]
16216		   UNSPEC_SINCOS_COS))
16217   (set (match_operand:DF 1 "register_operand" "")
16218        (unspec:DF [(float_extend:DF
16219		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
16220  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16221   && !reload_completed && !reload_in_progress"
16222  [(set (match_dup 0) (unspec:DF [(float_extend:DF
16223				   (match_dup 2))] UNSPEC_COS))]
16224  "")
16225
16226(define_insn "sincosxf3"
16227  [(set (match_operand:XF 0 "register_operand" "=f")
16228	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16229		   UNSPEC_SINCOS_COS))
16230   (set (match_operand:XF 1 "register_operand" "=u")
16231        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16232  "TARGET_USE_FANCY_MATH_387
16233   && flag_unsafe_math_optimizations"
16234  "fsincos"
16235  [(set_attr "type" "fpspc")
16236   (set_attr "mode" "XF")])
16237
16238(define_split
16239  [(set (match_operand:XF 0 "register_operand" "")
16240	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
16241		   UNSPEC_SINCOS_COS))
16242   (set (match_operand:XF 1 "register_operand" "")
16243	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16244  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16245   && !reload_completed && !reload_in_progress"
16246  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16247  "")
16248
16249(define_split
16250  [(set (match_operand:XF 0 "register_operand" "")
16251	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
16252		   UNSPEC_SINCOS_COS))
16253   (set (match_operand:XF 1 "register_operand" "")
16254	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16255  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16256   && !reload_completed && !reload_in_progress"
16257  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16258  "")
16259
16260(define_insn "*tandf3_1"
16261  [(set (match_operand:DF 0 "register_operand" "=f")
16262	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16263		   UNSPEC_TAN_ONE))
16264   (set (match_operand:DF 1 "register_operand" "=u")
16265        (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16266  "TARGET_USE_FANCY_MATH_387
16267   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16268   && flag_unsafe_math_optimizations"
16269  "fptan"
16270  [(set_attr "type" "fpspc")
16271   (set_attr "mode" "DF")])
16272
16273;; optimize sequence: fptan
16274;;		      fstp    %st(0)
16275;;		      fld1
16276;; into fptan insn.
16277
16278(define_peephole2
16279  [(parallel[(set (match_operand:DF 0 "register_operand" "")
16280		  (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16281			     UNSPEC_TAN_ONE))
16282	     (set (match_operand:DF 1 "register_operand" "")
16283		  (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16284   (set (match_dup 0)
16285        (match_operand:DF 3 "immediate_operand" ""))]
16286  "standard_80387_constant_p (operands[3]) == 2"
16287  [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16288   	     (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16289  "")
16290
16291(define_expand "tandf2"
16292  [(parallel [(set (match_dup 2)
16293		   (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16294			      UNSPEC_TAN_ONE))
16295	      (set (match_operand:DF 0 "register_operand" "")
16296		   (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16297  "TARGET_USE_FANCY_MATH_387
16298   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16299   && flag_unsafe_math_optimizations"
16300{
16301  operands[2] = gen_reg_rtx (DFmode);
16302})
16303
16304(define_insn "*tansf3_1"
16305  [(set (match_operand:SF 0 "register_operand" "=f")
16306	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16307		   UNSPEC_TAN_ONE))
16308   (set (match_operand:SF 1 "register_operand" "=u")
16309        (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16310  "TARGET_USE_FANCY_MATH_387
16311   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16312   && flag_unsafe_math_optimizations"
16313  "fptan"
16314  [(set_attr "type" "fpspc")
16315   (set_attr "mode" "SF")])
16316
16317;; optimize sequence: fptan
16318;;		      fstp    %st(0)
16319;;		      fld1
16320;; into fptan insn.
16321
16322(define_peephole2
16323  [(parallel[(set (match_operand:SF 0 "register_operand" "")
16324		  (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16325			     UNSPEC_TAN_ONE))
16326	     (set (match_operand:SF 1 "register_operand" "")
16327		  (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16328   (set (match_dup 0)
16329        (match_operand:SF 3 "immediate_operand" ""))]
16330  "standard_80387_constant_p (operands[3]) == 2"
16331  [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16332   	     (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16333  "")
16334
16335(define_expand "tansf2"
16336  [(parallel [(set (match_dup 2)
16337		   (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16338			      UNSPEC_TAN_ONE))
16339	      (set (match_operand:SF 0 "register_operand" "")
16340		   (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16341  "TARGET_USE_FANCY_MATH_387
16342   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16343   && flag_unsafe_math_optimizations"
16344{
16345  operands[2] = gen_reg_rtx (SFmode);
16346})
16347
16348(define_insn "*tanxf3_1"
16349  [(set (match_operand:XF 0 "register_operand" "=f")
16350	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16351		   UNSPEC_TAN_ONE))
16352   (set (match_operand:XF 1 "register_operand" "=u")
16353        (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16354  "TARGET_USE_FANCY_MATH_387
16355   && flag_unsafe_math_optimizations"
16356  "fptan"
16357  [(set_attr "type" "fpspc")
16358   (set_attr "mode" "XF")])
16359
16360;; optimize sequence: fptan
16361;;		      fstp    %st(0)
16362;;		      fld1
16363;; into fptan insn.
16364
16365(define_peephole2
16366  [(parallel[(set (match_operand:XF 0 "register_operand" "")
16367		  (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16368			     UNSPEC_TAN_ONE))
16369	     (set (match_operand:XF 1 "register_operand" "")
16370		  (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16371   (set (match_dup 0)
16372        (match_operand:XF 3 "immediate_operand" ""))]
16373  "standard_80387_constant_p (operands[3]) == 2"
16374  [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16375   	     (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16376  "")
16377
16378(define_expand "tanxf2"
16379  [(parallel [(set (match_dup 2)
16380		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16381			      UNSPEC_TAN_ONE))
16382	      (set (match_operand:XF 0 "register_operand" "")
16383		   (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16384  "TARGET_USE_FANCY_MATH_387
16385   && flag_unsafe_math_optimizations"
16386{
16387  operands[2] = gen_reg_rtx (XFmode);
16388})
16389
16390(define_insn "atan2df3_1"
16391  [(set (match_operand:DF 0 "register_operand" "=f")
16392	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
16393		    (match_operand:DF 1 "register_operand" "u")]
16394		   UNSPEC_FPATAN))
16395   (clobber (match_scratch:DF 3 "=1"))]
16396  "TARGET_USE_FANCY_MATH_387
16397   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16398   && flag_unsafe_math_optimizations"
16399  "fpatan"
16400  [(set_attr "type" "fpspc")
16401   (set_attr "mode" "DF")])
16402
16403(define_expand "atan2df3"
16404  [(use (match_operand:DF 0 "register_operand" ""))
16405   (use (match_operand:DF 2 "register_operand" ""))
16406   (use (match_operand:DF 1 "register_operand" ""))]
16407  "TARGET_USE_FANCY_MATH_387
16408   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16409   && flag_unsafe_math_optimizations"
16410{
16411  rtx copy = gen_reg_rtx (DFmode);
16412  emit_move_insn (copy, operands[1]);
16413  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16414  DONE;
16415})
16416
16417(define_expand "atandf2"
16418  [(parallel [(set (match_operand:DF 0 "register_operand" "")
16419		   (unspec:DF [(match_dup 2)
16420			       (match_operand:DF 1 "register_operand" "")]
16421		    UNSPEC_FPATAN))
16422	      (clobber (match_scratch:DF 3 ""))])]
16423  "TARGET_USE_FANCY_MATH_387
16424   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16425   && flag_unsafe_math_optimizations"
16426{
16427  operands[2] = gen_reg_rtx (DFmode);
16428  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16429})
16430
16431(define_insn "atan2sf3_1"
16432  [(set (match_operand:SF 0 "register_operand" "=f")
16433        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16434		    (match_operand:SF 1 "register_operand" "u")]
16435		   UNSPEC_FPATAN))
16436   (clobber (match_scratch:SF 3 "=1"))]
16437  "TARGET_USE_FANCY_MATH_387
16438   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16439   && flag_unsafe_math_optimizations"
16440  "fpatan"
16441  [(set_attr "type" "fpspc")
16442   (set_attr "mode" "SF")])
16443
16444(define_expand "atan2sf3"
16445  [(use (match_operand:SF 0 "register_operand" ""))
16446   (use (match_operand:SF 2 "register_operand" ""))
16447   (use (match_operand:SF 1 "register_operand" ""))]
16448  "TARGET_USE_FANCY_MATH_387
16449   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16450   && flag_unsafe_math_optimizations"
16451{
16452  rtx copy = gen_reg_rtx (SFmode);
16453  emit_move_insn (copy, operands[1]);
16454  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16455  DONE;
16456})
16457
16458(define_expand "atansf2"
16459  [(parallel [(set (match_operand:SF 0 "register_operand" "")
16460		   (unspec:SF [(match_dup 2)
16461			       (match_operand:SF 1 "register_operand" "")]
16462		    UNSPEC_FPATAN))
16463	      (clobber (match_scratch:SF 3 ""))])]
16464  "TARGET_USE_FANCY_MATH_387
16465   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16466   && flag_unsafe_math_optimizations"
16467{
16468  operands[2] = gen_reg_rtx (SFmode);
16469  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16470})
16471
16472(define_insn "atan2xf3_1"
16473  [(set (match_operand:XF 0 "register_operand" "=f")
16474        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16475	            (match_operand:XF 1 "register_operand" "u")]
16476	           UNSPEC_FPATAN))
16477   (clobber (match_scratch:XF 3 "=1"))]
16478  "TARGET_USE_FANCY_MATH_387
16479   && flag_unsafe_math_optimizations"
16480  "fpatan"
16481  [(set_attr "type" "fpspc")
16482   (set_attr "mode" "XF")])
16483
16484(define_expand "atan2xf3"
16485  [(use (match_operand:XF 0 "register_operand" ""))
16486   (use (match_operand:XF 2 "register_operand" ""))
16487   (use (match_operand:XF 1 "register_operand" ""))]
16488  "TARGET_USE_FANCY_MATH_387
16489   && flag_unsafe_math_optimizations"
16490{
16491  rtx copy = gen_reg_rtx (XFmode);
16492  emit_move_insn (copy, operands[1]);
16493  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16494  DONE;
16495})
16496
16497(define_expand "atanxf2"
16498  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16499		   (unspec:XF [(match_dup 2)
16500			       (match_operand:XF 1 "register_operand" "")]
16501		    UNSPEC_FPATAN))
16502	      (clobber (match_scratch:XF 3 ""))])]
16503  "TARGET_USE_FANCY_MATH_387
16504   && flag_unsafe_math_optimizations"
16505{
16506  operands[2] = gen_reg_rtx (XFmode);
16507  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16508})
16509
16510(define_expand "asindf2"
16511  [(set (match_dup 2)
16512	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16513   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16514   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16515   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16516   (parallel [(set (match_dup 7)
16517        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16518			      UNSPEC_FPATAN))
16519   	      (clobber (match_scratch:XF 8 ""))])
16520   (set (match_operand:DF 0 "register_operand" "")
16521	(float_truncate:DF (match_dup 7)))]
16522  "TARGET_USE_FANCY_MATH_387
16523   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16524   && flag_unsafe_math_optimizations"
16525{
16526  int i;
16527
16528  for (i=2; i<8; i++)
16529    operands[i] = gen_reg_rtx (XFmode);
16530
16531  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16532})
16533
16534(define_expand "asinsf2"
16535  [(set (match_dup 2)
16536	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16537   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16538   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16539   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16540   (parallel [(set (match_dup 7)
16541        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16542			      UNSPEC_FPATAN))
16543   	      (clobber (match_scratch:XF 8 ""))])
16544   (set (match_operand:SF 0 "register_operand" "")
16545	(float_truncate:SF (match_dup 7)))]
16546  "TARGET_USE_FANCY_MATH_387
16547   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16548   && flag_unsafe_math_optimizations"
16549{
16550  int i;
16551
16552  for (i=2; i<8; i++)
16553    operands[i] = gen_reg_rtx (XFmode);
16554
16555  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16556})
16557
16558(define_expand "asinxf2"
16559  [(set (match_dup 2)
16560	(mult:XF (match_operand:XF 1 "register_operand" "")
16561		 (match_dup 1)))
16562   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16563   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16564   (parallel [(set (match_operand:XF 0 "register_operand" "")
16565        	   (unspec:XF [(match_dup 5) (match_dup 1)]
16566			      UNSPEC_FPATAN))
16567   	      (clobber (match_scratch:XF 6 ""))])]
16568  "TARGET_USE_FANCY_MATH_387
16569   && flag_unsafe_math_optimizations"
16570{
16571  int i;
16572
16573  for (i=2; i<6; i++)
16574    operands[i] = gen_reg_rtx (XFmode);
16575
16576  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16577})
16578
16579(define_expand "acosdf2"
16580  [(set (match_dup 2)
16581	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16582   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16583   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16584   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16585   (parallel [(set (match_dup 7)
16586        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16587			      UNSPEC_FPATAN))
16588   	      (clobber (match_scratch:XF 8 ""))])
16589   (set (match_operand:DF 0 "register_operand" "")
16590	(float_truncate:DF (match_dup 7)))]
16591  "TARGET_USE_FANCY_MATH_387
16592   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16593   && flag_unsafe_math_optimizations"
16594{
16595  int i;
16596
16597  for (i=2; i<8; i++)
16598    operands[i] = gen_reg_rtx (XFmode);
16599
16600  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16601})
16602
16603(define_expand "acossf2"
16604  [(set (match_dup 2)
16605	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16606   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16607   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16608   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16609   (parallel [(set (match_dup 7)
16610        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16611			      UNSPEC_FPATAN))
16612   	      (clobber (match_scratch:XF 8 ""))])
16613   (set (match_operand:SF 0 "register_operand" "")
16614	(float_truncate:SF (match_dup 7)))]
16615  "TARGET_USE_FANCY_MATH_387
16616   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16617   && flag_unsafe_math_optimizations"
16618{
16619  int i;
16620
16621  for (i=2; i<8; i++)
16622    operands[i] = gen_reg_rtx (XFmode);
16623
16624  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16625})
16626
16627(define_expand "acosxf2"
16628  [(set (match_dup 2)
16629	(mult:XF (match_operand:XF 1 "register_operand" "")
16630		 (match_dup 1)))
16631   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16632   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16633   (parallel [(set (match_operand:XF 0 "register_operand" "")
16634        	   (unspec:XF [(match_dup 1) (match_dup 5)]
16635			      UNSPEC_FPATAN))
16636   	      (clobber (match_scratch:XF 6 ""))])]
16637  "TARGET_USE_FANCY_MATH_387
16638   && flag_unsafe_math_optimizations"
16639{
16640  int i;
16641
16642  for (i=2; i<6; i++)
16643    operands[i] = gen_reg_rtx (XFmode);
16644
16645  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16646})
16647
16648(define_insn "fyl2x_xf3"
16649  [(set (match_operand:XF 0 "register_operand" "=f")
16650        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16651		    (match_operand:XF 1 "register_operand" "u")]
16652	           UNSPEC_FYL2X))
16653   (clobber (match_scratch:XF 3 "=1"))]
16654  "TARGET_USE_FANCY_MATH_387
16655   && flag_unsafe_math_optimizations"
16656  "fyl2x"
16657  [(set_attr "type" "fpspc")
16658   (set_attr "mode" "XF")])
16659
16660(define_expand "logsf2"
16661  [(set (match_dup 2)
16662	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16663   (parallel [(set (match_dup 4)
16664		   (unspec:XF [(match_dup 2)
16665			       (match_dup 3)] UNSPEC_FYL2X))
16666	      (clobber (match_scratch:XF 5 ""))])
16667   (set (match_operand:SF 0 "register_operand" "")
16668	(float_truncate:SF (match_dup 4)))]
16669  "TARGET_USE_FANCY_MATH_387
16670   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16671   && flag_unsafe_math_optimizations"
16672{
16673  rtx temp;
16674
16675  operands[2] = gen_reg_rtx (XFmode);
16676  operands[3] = gen_reg_rtx (XFmode);
16677  operands[4] = gen_reg_rtx (XFmode);
16678
16679  temp = standard_80387_constant_rtx (4); /* fldln2 */
16680  emit_move_insn (operands[3], temp);
16681})
16682
16683(define_expand "logdf2"
16684  [(set (match_dup 2)
16685	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16686   (parallel [(set (match_dup 4)
16687		   (unspec:XF [(match_dup 2)
16688			       (match_dup 3)] UNSPEC_FYL2X))
16689	      (clobber (match_scratch:XF 5 ""))])
16690   (set (match_operand:DF 0 "register_operand" "")
16691	(float_truncate:DF (match_dup 4)))]
16692  "TARGET_USE_FANCY_MATH_387
16693   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16694   && flag_unsafe_math_optimizations"
16695{
16696  rtx temp;
16697
16698  operands[2] = gen_reg_rtx (XFmode);
16699  operands[3] = gen_reg_rtx (XFmode);
16700  operands[4] = gen_reg_rtx (XFmode);
16701
16702  temp = standard_80387_constant_rtx (4); /* fldln2 */
16703  emit_move_insn (operands[3], temp);
16704})
16705
16706(define_expand "logxf2"
16707  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16708		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16709			       (match_dup 2)] UNSPEC_FYL2X))
16710	      (clobber (match_scratch:XF 3 ""))])]
16711  "TARGET_USE_FANCY_MATH_387
16712   && flag_unsafe_math_optimizations"
16713{
16714  rtx temp;
16715
16716  operands[2] = gen_reg_rtx (XFmode);
16717  temp = standard_80387_constant_rtx (4); /* fldln2 */
16718  emit_move_insn (operands[2], temp);
16719})
16720
16721(define_expand "log10sf2"
16722  [(set (match_dup 2)
16723	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16724   (parallel [(set (match_dup 4)
16725		   (unspec:XF [(match_dup 2)
16726			       (match_dup 3)] UNSPEC_FYL2X))
16727	      (clobber (match_scratch:XF 5 ""))])
16728   (set (match_operand:SF 0 "register_operand" "")
16729	(float_truncate:SF (match_dup 4)))]
16730  "TARGET_USE_FANCY_MATH_387
16731   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16732   && flag_unsafe_math_optimizations"
16733{
16734  rtx temp;
16735
16736  operands[2] = gen_reg_rtx (XFmode);
16737  operands[3] = gen_reg_rtx (XFmode);
16738  operands[4] = gen_reg_rtx (XFmode);
16739
16740  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16741  emit_move_insn (operands[3], temp);
16742})
16743
16744(define_expand "log10df2"
16745  [(set (match_dup 2)
16746	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16747   (parallel [(set (match_dup 4)
16748		   (unspec:XF [(match_dup 2)
16749			       (match_dup 3)] UNSPEC_FYL2X))
16750	      (clobber (match_scratch:XF 5 ""))])
16751   (set (match_operand:DF 0 "register_operand" "")
16752	(float_truncate:DF (match_dup 4)))]
16753  "TARGET_USE_FANCY_MATH_387
16754   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16755   && flag_unsafe_math_optimizations"
16756{
16757  rtx temp;
16758
16759  operands[2] = gen_reg_rtx (XFmode);
16760  operands[3] = gen_reg_rtx (XFmode);
16761  operands[4] = gen_reg_rtx (XFmode);
16762
16763  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16764  emit_move_insn (operands[3], temp);
16765})
16766
16767(define_expand "log10xf2"
16768  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16769		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16770			       (match_dup 2)] UNSPEC_FYL2X))
16771	      (clobber (match_scratch:XF 3 ""))])]
16772  "TARGET_USE_FANCY_MATH_387
16773   && flag_unsafe_math_optimizations"
16774{
16775  rtx temp;
16776
16777  operands[2] = gen_reg_rtx (XFmode);
16778  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16779  emit_move_insn (operands[2], temp);
16780})
16781
16782(define_expand "log2sf2"
16783  [(set (match_dup 2)
16784	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16785   (parallel [(set (match_dup 4)
16786		   (unspec:XF [(match_dup 2)
16787			       (match_dup 3)] UNSPEC_FYL2X))
16788	      (clobber (match_scratch:XF 5 ""))])
16789   (set (match_operand:SF 0 "register_operand" "")
16790	(float_truncate:SF (match_dup 4)))]
16791  "TARGET_USE_FANCY_MATH_387
16792   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16793   && flag_unsafe_math_optimizations"
16794{
16795  operands[2] = gen_reg_rtx (XFmode);
16796  operands[3] = gen_reg_rtx (XFmode);
16797  operands[4] = gen_reg_rtx (XFmode);
16798
16799  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16800})
16801
16802(define_expand "log2df2"
16803  [(set (match_dup 2)
16804	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16805   (parallel [(set (match_dup 4)
16806		   (unspec:XF [(match_dup 2)
16807			       (match_dup 3)] UNSPEC_FYL2X))
16808	      (clobber (match_scratch:XF 5 ""))])
16809   (set (match_operand:DF 0 "register_operand" "")
16810	(float_truncate:DF (match_dup 4)))]
16811  "TARGET_USE_FANCY_MATH_387
16812   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16813   && flag_unsafe_math_optimizations"
16814{
16815  operands[2] = gen_reg_rtx (XFmode);
16816  operands[3] = gen_reg_rtx (XFmode);
16817  operands[4] = gen_reg_rtx (XFmode);
16818
16819  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16820})
16821
16822(define_expand "log2xf2"
16823  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16824		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16825			       (match_dup 2)] UNSPEC_FYL2X))
16826	      (clobber (match_scratch:XF 3 ""))])]
16827  "TARGET_USE_FANCY_MATH_387
16828   && flag_unsafe_math_optimizations"
16829{
16830  operands[2] = gen_reg_rtx (XFmode);
16831  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16832})
16833
16834(define_insn "fyl2xp1_xf3"
16835  [(set (match_operand:XF 0 "register_operand" "=f")
16836        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16837		    (match_operand:XF 1 "register_operand" "u")]
16838	           UNSPEC_FYL2XP1))
16839   (clobber (match_scratch:XF 3 "=1"))]
16840  "TARGET_USE_FANCY_MATH_387
16841   && flag_unsafe_math_optimizations"
16842  "fyl2xp1"
16843  [(set_attr "type" "fpspc")
16844   (set_attr "mode" "XF")])
16845
16846(define_expand "log1psf2"
16847  [(use (match_operand:SF 0 "register_operand" ""))
16848   (use (match_operand:SF 1 "register_operand" ""))]
16849  "TARGET_USE_FANCY_MATH_387
16850   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16851   && flag_unsafe_math_optimizations"
16852{
16853  rtx op0 = gen_reg_rtx (XFmode);
16854  rtx op1 = gen_reg_rtx (XFmode);
16855
16856  emit_insn (gen_extendsfxf2 (op1, operands[1]));
16857  ix86_emit_i387_log1p (op0, op1);
16858  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16859  DONE;
16860})
16861
16862(define_expand "log1pdf2"
16863  [(use (match_operand:DF 0 "register_operand" ""))
16864   (use (match_operand:DF 1 "register_operand" ""))]
16865  "TARGET_USE_FANCY_MATH_387
16866   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16867   && flag_unsafe_math_optimizations"
16868{
16869  rtx op0 = gen_reg_rtx (XFmode);
16870  rtx op1 = gen_reg_rtx (XFmode);
16871
16872  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16873  ix86_emit_i387_log1p (op0, op1);
16874  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16875  DONE;
16876})
16877
16878(define_expand "log1pxf2"
16879  [(use (match_operand:XF 0 "register_operand" ""))
16880   (use (match_operand:XF 1 "register_operand" ""))]
16881  "TARGET_USE_FANCY_MATH_387
16882   && flag_unsafe_math_optimizations"
16883{
16884  ix86_emit_i387_log1p (operands[0], operands[1]);
16885  DONE;
16886})
16887
16888(define_insn "*fxtractxf3"
16889  [(set (match_operand:XF 0 "register_operand" "=f")
16890	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16891		   UNSPEC_XTRACT_FRACT))
16892   (set (match_operand:XF 1 "register_operand" "=u")
16893        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16894  "TARGET_USE_FANCY_MATH_387
16895   && flag_unsafe_math_optimizations"
16896  "fxtract"
16897  [(set_attr "type" "fpspc")
16898   (set_attr "mode" "XF")])
16899
16900(define_expand "logbsf2"
16901  [(set (match_dup 2)
16902	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16903   (parallel [(set (match_dup 3)
16904		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16905	      (set (match_dup 4)
16906		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16907   (set (match_operand:SF 0 "register_operand" "")
16908	(float_truncate:SF (match_dup 4)))]
16909  "TARGET_USE_FANCY_MATH_387
16910   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16911   && flag_unsafe_math_optimizations"
16912{
16913  operands[2] = gen_reg_rtx (XFmode);
16914  operands[3] = gen_reg_rtx (XFmode);
16915  operands[4] = gen_reg_rtx (XFmode);
16916})
16917
16918(define_expand "logbdf2"
16919  [(set (match_dup 2)
16920	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16921   (parallel [(set (match_dup 3)
16922		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16923	      (set (match_dup 4)
16924		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16925   (set (match_operand:DF 0 "register_operand" "")
16926	(float_truncate:DF (match_dup 4)))]
16927  "TARGET_USE_FANCY_MATH_387
16928   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16929   && flag_unsafe_math_optimizations"
16930{
16931  operands[2] = gen_reg_rtx (XFmode);
16932  operands[3] = gen_reg_rtx (XFmode);
16933  operands[4] = gen_reg_rtx (XFmode);
16934})
16935
16936(define_expand "logbxf2"
16937  [(parallel [(set (match_dup 2)
16938		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16939			      UNSPEC_XTRACT_FRACT))
16940	      (set (match_operand:XF 0 "register_operand" "")
16941		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16942  "TARGET_USE_FANCY_MATH_387
16943   && flag_unsafe_math_optimizations"
16944{
16945  operands[2] = gen_reg_rtx (XFmode);
16946})
16947
16948(define_expand "ilogbsi2"
16949  [(parallel [(set (match_dup 2)
16950		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16951			      UNSPEC_XTRACT_FRACT))
16952	      (set (match_operand:XF 3 "register_operand" "")
16953		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16954   (parallel [(set (match_operand:SI 0 "register_operand" "")
16955	           (fix:SI (match_dup 3)))
16956	      (clobber (reg:CC FLAGS_REG))])]
16957  "TARGET_USE_FANCY_MATH_387
16958   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16959   && flag_unsafe_math_optimizations"
16960{
16961  operands[2] = gen_reg_rtx (XFmode);
16962  operands[3] = gen_reg_rtx (XFmode);
16963})
16964
16965(define_insn "*f2xm1xf2"
16966  [(set (match_operand:XF 0 "register_operand" "=f")
16967	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16968	 UNSPEC_F2XM1))]
16969  "TARGET_USE_FANCY_MATH_387
16970   && flag_unsafe_math_optimizations"
16971  "f2xm1"
16972  [(set_attr "type" "fpspc")
16973   (set_attr "mode" "XF")])
16974
16975(define_insn "*fscalexf4"
16976  [(set (match_operand:XF 0 "register_operand" "=f")
16977	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
16978		    (match_operand:XF 3 "register_operand" "1")]
16979		   UNSPEC_FSCALE_FRACT))
16980   (set (match_operand:XF 1 "register_operand" "=u")
16981	(unspec:XF [(match_dup 2) (match_dup 3)]
16982		   UNSPEC_FSCALE_EXP))]
16983  "TARGET_USE_FANCY_MATH_387
16984   && flag_unsafe_math_optimizations"
16985  "fscale"
16986  [(set_attr "type" "fpspc")
16987   (set_attr "mode" "XF")])
16988
16989(define_expand "expsf2"
16990  [(set (match_dup 2)
16991	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16992   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16993   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16994   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16995   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16996   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16997   (parallel [(set (match_dup 10)
16998		   (unspec:XF [(match_dup 9) (match_dup 5)]
16999			      UNSPEC_FSCALE_FRACT))
17000	      (set (match_dup 11)
17001		   (unspec:XF [(match_dup 9) (match_dup 5)]
17002			      UNSPEC_FSCALE_EXP))])
17003   (set (match_operand:SF 0 "register_operand" "")
17004	(float_truncate:SF (match_dup 10)))]
17005  "TARGET_USE_FANCY_MATH_387
17006   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17007   && flag_unsafe_math_optimizations"
17008{
17009  rtx temp;
17010  int i;
17011
17012  for (i=2; i<12; i++)
17013    operands[i] = gen_reg_rtx (XFmode);
17014  temp = standard_80387_constant_rtx (5); /* fldl2e */
17015  emit_move_insn (operands[3], temp);
17016  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17017})
17018
17019(define_expand "expdf2"
17020  [(set (match_dup 2)
17021	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17022   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17023   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17024   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17025   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17026   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17027   (parallel [(set (match_dup 10)
17028		   (unspec:XF [(match_dup 9) (match_dup 5)]
17029			      UNSPEC_FSCALE_FRACT))
17030	      (set (match_dup 11)
17031		   (unspec:XF [(match_dup 9) (match_dup 5)]
17032			      UNSPEC_FSCALE_EXP))])
17033   (set (match_operand:DF 0 "register_operand" "")
17034	(float_truncate:DF (match_dup 10)))]
17035  "TARGET_USE_FANCY_MATH_387
17036   && (!(TARGET_SSE2 && 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<12; 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[8], CONST1_RTX (XFmode));  /* fld1 */
17047})
17048
17049(define_expand "expxf2"
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   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17056   (parallel [(set (match_operand:XF 0 "register_operand" "")
17057		   (unspec:XF [(match_dup 8) (match_dup 4)]
17058			      UNSPEC_FSCALE_FRACT))
17059	      (set (match_dup 9)
17060		   (unspec:XF [(match_dup 8) (match_dup 4)]
17061			      UNSPEC_FSCALE_EXP))])]
17062  "TARGET_USE_FANCY_MATH_387
17063   && flag_unsafe_math_optimizations"
17064{
17065  rtx temp;
17066  int i;
17067
17068  for (i=2; i<10; i++)
17069    operands[i] = gen_reg_rtx (XFmode);
17070  temp = standard_80387_constant_rtx (5); /* fldl2e */
17071  emit_move_insn (operands[2], temp);
17072  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17073})
17074
17075(define_expand "exp10sf2"
17076  [(set (match_dup 2)
17077	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17078   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17079   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17080   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17081   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17082   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17083   (parallel [(set (match_dup 10)
17084		   (unspec:XF [(match_dup 9) (match_dup 5)]
17085			      UNSPEC_FSCALE_FRACT))
17086	      (set (match_dup 11)
17087		   (unspec:XF [(match_dup 9) (match_dup 5)]
17088			      UNSPEC_FSCALE_EXP))])
17089   (set (match_operand:SF 0 "register_operand" "")
17090	(float_truncate:SF (match_dup 10)))]
17091  "TARGET_USE_FANCY_MATH_387
17092   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17093   && flag_unsafe_math_optimizations"
17094{
17095  rtx temp;
17096  int i;
17097
17098  for (i=2; i<12; i++)
17099    operands[i] = gen_reg_rtx (XFmode);
17100  temp = standard_80387_constant_rtx (6); /* fldl2t */
17101  emit_move_insn (operands[3], temp);
17102  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17103})
17104
17105(define_expand "exp10df2"
17106  [(set (match_dup 2)
17107	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17108   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17109   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17110   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17111   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17112   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17113   (parallel [(set (match_dup 10)
17114		   (unspec:XF [(match_dup 9) (match_dup 5)]
17115			      UNSPEC_FSCALE_FRACT))
17116	      (set (match_dup 11)
17117		   (unspec:XF [(match_dup 9) (match_dup 5)]
17118			      UNSPEC_FSCALE_EXP))])
17119   (set (match_operand:DF 0 "register_operand" "")
17120	(float_truncate:DF (match_dup 10)))]
17121  "TARGET_USE_FANCY_MATH_387
17122   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17123   && flag_unsafe_math_optimizations"
17124{
17125  rtx temp;
17126  int i;
17127
17128  for (i=2; i<12; i++)
17129    operands[i] = gen_reg_rtx (XFmode);
17130  temp = standard_80387_constant_rtx (6); /* fldl2t */
17131  emit_move_insn (operands[3], temp);
17132  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17133})
17134
17135(define_expand "exp10xf2"
17136  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17137			       (match_dup 2)))
17138   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17139   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17140   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17141   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17142   (parallel [(set (match_operand:XF 0 "register_operand" "")
17143		   (unspec:XF [(match_dup 8) (match_dup 4)]
17144			      UNSPEC_FSCALE_FRACT))
17145	      (set (match_dup 9)
17146		   (unspec:XF [(match_dup 8) (match_dup 4)]
17147			      UNSPEC_FSCALE_EXP))])]
17148  "TARGET_USE_FANCY_MATH_387
17149   && flag_unsafe_math_optimizations"
17150{
17151  rtx temp;
17152  int i;
17153
17154  for (i=2; i<10; i++)
17155    operands[i] = gen_reg_rtx (XFmode);
17156  temp = standard_80387_constant_rtx (6); /* fldl2t */
17157  emit_move_insn (operands[2], temp);
17158  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17159})
17160
17161(define_expand "exp2sf2"
17162  [(set (match_dup 2)
17163	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17164   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17165   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17166   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17167   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17168   (parallel [(set (match_dup 8)
17169		   (unspec:XF [(match_dup 7) (match_dup 3)]
17170			      UNSPEC_FSCALE_FRACT))
17171	      (set (match_dup 9)
17172		   (unspec:XF [(match_dup 7) (match_dup 3)]
17173			      UNSPEC_FSCALE_EXP))])
17174   (set (match_operand:SF 0 "register_operand" "")
17175	(float_truncate:SF (match_dup 8)))]
17176  "TARGET_USE_FANCY_MATH_387
17177   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17178   && flag_unsafe_math_optimizations"
17179{
17180  int i;
17181
17182  for (i=2; i<10; i++)
17183    operands[i] = gen_reg_rtx (XFmode);
17184  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17185})
17186
17187(define_expand "exp2df2"
17188  [(set (match_dup 2)
17189	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17190   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17191   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17192   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17193   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17194   (parallel [(set (match_dup 8)
17195		   (unspec:XF [(match_dup 7) (match_dup 3)]
17196			      UNSPEC_FSCALE_FRACT))
17197	      (set (match_dup 9)
17198		   (unspec:XF [(match_dup 7) (match_dup 3)]
17199			      UNSPEC_FSCALE_EXP))])
17200   (set (match_operand:DF 0 "register_operand" "")
17201	(float_truncate:DF (match_dup 8)))]
17202  "TARGET_USE_FANCY_MATH_387
17203   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17204   && flag_unsafe_math_optimizations"
17205{
17206  int i;
17207
17208  for (i=2; i<10; i++)
17209    operands[i] = gen_reg_rtx (XFmode);
17210  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17211})
17212
17213(define_expand "exp2xf2"
17214  [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
17215   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17216   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17217   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17218   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17219   (parallel [(set (match_operand:XF 0 "register_operand" "")
17220		   (unspec:XF [(match_dup 7) (match_dup 3)]
17221			      UNSPEC_FSCALE_FRACT))
17222	      (set (match_dup 8)
17223		   (unspec:XF [(match_dup 7) (match_dup 3)]
17224			      UNSPEC_FSCALE_EXP))])]
17225  "TARGET_USE_FANCY_MATH_387
17226   && flag_unsafe_math_optimizations"
17227{
17228  int i;
17229
17230  for (i=2; i<9; i++)
17231    operands[i] = gen_reg_rtx (XFmode);
17232  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17233})
17234
17235(define_expand "expm1df2"
17236  [(set (match_dup 2)
17237	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17238   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17239   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17240   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17241   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17242   (parallel [(set (match_dup 8)
17243		   (unspec:XF [(match_dup 7) (match_dup 5)]
17244			      UNSPEC_FSCALE_FRACT))
17245		   (set (match_dup 9)
17246		   (unspec:XF [(match_dup 7) (match_dup 5)]
17247			      UNSPEC_FSCALE_EXP))])
17248   (parallel [(set (match_dup 11)
17249		   (unspec:XF [(match_dup 10) (match_dup 9)]
17250			      UNSPEC_FSCALE_FRACT))
17251	      (set (match_dup 12)
17252		   (unspec:XF [(match_dup 10) (match_dup 9)]
17253			      UNSPEC_FSCALE_EXP))])
17254   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17255   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17256   (set (match_operand:DF 0 "register_operand" "")
17257	(float_truncate:DF (match_dup 14)))]
17258  "TARGET_USE_FANCY_MATH_387
17259   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17260   && flag_unsafe_math_optimizations"
17261{
17262  rtx temp;
17263  int i;
17264
17265  for (i=2; i<15; i++)
17266    operands[i] = gen_reg_rtx (XFmode);
17267  temp = standard_80387_constant_rtx (5); /* fldl2e */
17268  emit_move_insn (operands[3], temp);
17269  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17270})
17271
17272(define_expand "expm1sf2"
17273  [(set (match_dup 2)
17274	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17275   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17276   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17277   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17278   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17279   (parallel [(set (match_dup 8)
17280		   (unspec:XF [(match_dup 7) (match_dup 5)]
17281			      UNSPEC_FSCALE_FRACT))
17282		   (set (match_dup 9)
17283		   (unspec:XF [(match_dup 7) (match_dup 5)]
17284			      UNSPEC_FSCALE_EXP))])
17285   (parallel [(set (match_dup 11)
17286		   (unspec:XF [(match_dup 10) (match_dup 9)]
17287			      UNSPEC_FSCALE_FRACT))
17288	      (set (match_dup 12)
17289		   (unspec:XF [(match_dup 10) (match_dup 9)]
17290			      UNSPEC_FSCALE_EXP))])
17291   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17292   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17293   (set (match_operand:SF 0 "register_operand" "")
17294	(float_truncate:SF (match_dup 14)))]
17295  "TARGET_USE_FANCY_MATH_387
17296   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17297   && flag_unsafe_math_optimizations"
17298{
17299  rtx temp;
17300  int i;
17301
17302  for (i=2; i<15; i++)
17303    operands[i] = gen_reg_rtx (XFmode);
17304  temp = standard_80387_constant_rtx (5); /* fldl2e */
17305  emit_move_insn (operands[3], temp);
17306  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17307})
17308
17309(define_expand "expm1xf2"
17310  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17311			       (match_dup 2)))
17312   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17313   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17314   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17315   (parallel [(set (match_dup 7)
17316		   (unspec:XF [(match_dup 6) (match_dup 4)]
17317			      UNSPEC_FSCALE_FRACT))
17318		   (set (match_dup 8)
17319		   (unspec:XF [(match_dup 6) (match_dup 4)]
17320			      UNSPEC_FSCALE_EXP))])
17321   (parallel [(set (match_dup 10)
17322		   (unspec:XF [(match_dup 9) (match_dup 8)]
17323			      UNSPEC_FSCALE_FRACT))
17324	      (set (match_dup 11)
17325		   (unspec:XF [(match_dup 9) (match_dup 8)]
17326			      UNSPEC_FSCALE_EXP))])
17327   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17328   (set (match_operand:XF 0 "register_operand" "")
17329	(plus:XF (match_dup 12) (match_dup 7)))]
17330  "TARGET_USE_FANCY_MATH_387
17331   && flag_unsafe_math_optimizations"
17332{
17333  rtx temp;
17334  int i;
17335
17336  for (i=2; i<13; i++)
17337    operands[i] = gen_reg_rtx (XFmode);
17338  temp = standard_80387_constant_rtx (5); /* fldl2e */
17339  emit_move_insn (operands[2], temp);
17340  emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17341})
17342
17343(define_expand "ldexpdf3"
17344  [(set (match_dup 3)
17345	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17346   (set (match_dup 4)
17347	(float:XF (match_operand:SI 2 "register_operand" "")))
17348   (parallel [(set (match_dup 5)
17349		   (unspec:XF [(match_dup 3) (match_dup 4)]
17350			      UNSPEC_FSCALE_FRACT))
17351	      (set (match_dup 6)
17352		   (unspec:XF [(match_dup 3) (match_dup 4)]
17353			      UNSPEC_FSCALE_EXP))])
17354   (set (match_operand:DF 0 "register_operand" "")
17355	(float_truncate:DF (match_dup 5)))]
17356  "TARGET_USE_FANCY_MATH_387
17357   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17358   && flag_unsafe_math_optimizations"
17359{
17360  int i;
17361
17362  for (i=3; i<7; i++)
17363    operands[i] = gen_reg_rtx (XFmode);
17364})
17365
17366(define_expand "ldexpsf3"
17367  [(set (match_dup 3)
17368	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17369   (set (match_dup 4)
17370	(float:XF (match_operand:SI 2 "register_operand" "")))
17371   (parallel [(set (match_dup 5)
17372		   (unspec:XF [(match_dup 3) (match_dup 4)]
17373			      UNSPEC_FSCALE_FRACT))
17374	      (set (match_dup 6)
17375		   (unspec:XF [(match_dup 3) (match_dup 4)]
17376			      UNSPEC_FSCALE_EXP))])
17377   (set (match_operand:SF 0 "register_operand" "")
17378	(float_truncate:SF (match_dup 5)))]
17379  "TARGET_USE_FANCY_MATH_387
17380   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17381   && flag_unsafe_math_optimizations"
17382{
17383  int i;
17384
17385  for (i=3; i<7; i++)
17386    operands[i] = gen_reg_rtx (XFmode);
17387})
17388
17389(define_expand "ldexpxf3"
17390  [(set (match_dup 3)
17391	(float:XF (match_operand:SI 2 "register_operand" "")))
17392   (parallel [(set (match_operand:XF 0 " register_operand" "")
17393		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
17394			       (match_dup 3)]
17395			      UNSPEC_FSCALE_FRACT))
17396	      (set (match_dup 4)
17397		   (unspec:XF [(match_dup 1) (match_dup 3)]
17398			      UNSPEC_FSCALE_EXP))])]
17399  "TARGET_USE_FANCY_MATH_387
17400   && flag_unsafe_math_optimizations"
17401{
17402  int i;
17403
17404  for (i=3; i<5; i++)
17405    operands[i] = gen_reg_rtx (XFmode);
17406})
17407
17408
17409(define_insn "frndintxf2"
17410  [(set (match_operand:XF 0 "register_operand" "=f")
17411	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17412	 UNSPEC_FRNDINT))]
17413  "TARGET_USE_FANCY_MATH_387
17414   && flag_unsafe_math_optimizations"
17415  "frndint"
17416  [(set_attr "type" "fpspc")
17417   (set_attr "mode" "XF")])
17418
17419(define_expand "rintdf2"
17420  [(use (match_operand:DF 0 "register_operand" ""))
17421   (use (match_operand:DF 1 "register_operand" ""))]
17422  "TARGET_USE_FANCY_MATH_387
17423   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17424   && flag_unsafe_math_optimizations"
17425{
17426  rtx op0 = gen_reg_rtx (XFmode);
17427  rtx op1 = gen_reg_rtx (XFmode);
17428
17429  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17430  emit_insn (gen_frndintxf2 (op0, op1));
17431
17432  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17433  DONE;
17434})
17435
17436(define_expand "rintsf2"
17437  [(use (match_operand:SF 0 "register_operand" ""))
17438   (use (match_operand:SF 1 "register_operand" ""))]
17439  "TARGET_USE_FANCY_MATH_387
17440   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17441   && flag_unsafe_math_optimizations"
17442{
17443  rtx op0 = gen_reg_rtx (XFmode);
17444  rtx op1 = gen_reg_rtx (XFmode);
17445
17446  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17447  emit_insn (gen_frndintxf2 (op0, op1));
17448
17449  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17450  DONE;
17451})
17452
17453(define_expand "rintxf2"
17454  [(use (match_operand:XF 0 "register_operand" ""))
17455   (use (match_operand:XF 1 "register_operand" ""))]
17456  "TARGET_USE_FANCY_MATH_387
17457   && flag_unsafe_math_optimizations"
17458{
17459  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17460  DONE;
17461})
17462
17463(define_insn_and_split "*fistdi2_1"
17464  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17465	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17466	 UNSPEC_FIST))]
17467  "TARGET_USE_FANCY_MATH_387
17468   && flag_unsafe_math_optimizations
17469   && !(reload_completed || reload_in_progress)"
17470  "#"
17471  "&& 1"
17472  [(const_int 0)]
17473{
17474  if (memory_operand (operands[0], VOIDmode))
17475    emit_insn (gen_fistdi2 (operands[0], operands[1]));
17476  else
17477    {
17478      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17479      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17480					 operands[2]));
17481    }
17482  DONE;
17483}
17484  [(set_attr "type" "fpspc")
17485   (set_attr "mode" "DI")])
17486
17487(define_insn "fistdi2"
17488  [(set (match_operand:DI 0 "memory_operand" "=m")
17489	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17490	 UNSPEC_FIST))
17491   (clobber (match_scratch:XF 2 "=&1f"))]
17492  "TARGET_USE_FANCY_MATH_387
17493   && flag_unsafe_math_optimizations"
17494  "* return output_fix_trunc (insn, operands, 0);"
17495  [(set_attr "type" "fpspc")
17496   (set_attr "mode" "DI")])
17497
17498(define_insn "fistdi2_with_temp"
17499  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17500	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17501	 UNSPEC_FIST))
17502   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17503   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17504  "TARGET_USE_FANCY_MATH_387
17505   && flag_unsafe_math_optimizations"
17506  "#"
17507  [(set_attr "type" "fpspc")
17508   (set_attr "mode" "DI")])
17509
17510(define_split 
17511  [(set (match_operand:DI 0 "register_operand" "")
17512	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17513	 UNSPEC_FIST))
17514   (clobber (match_operand:DI 2 "memory_operand" ""))
17515   (clobber (match_scratch 3 ""))]
17516  "reload_completed"
17517  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17518	      (clobber (match_dup 3))])
17519   (set (match_dup 0) (match_dup 2))]
17520  "")
17521
17522(define_split 
17523  [(set (match_operand:DI 0 "memory_operand" "")
17524	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17525	 UNSPEC_FIST))
17526   (clobber (match_operand:DI 2 "memory_operand" ""))
17527   (clobber (match_scratch 3 ""))]
17528  "reload_completed"
17529  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17530	      (clobber (match_dup 3))])]
17531  "")
17532
17533(define_insn_and_split "*fist<mode>2_1"
17534  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17535	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17536	 UNSPEC_FIST))]
17537  "TARGET_USE_FANCY_MATH_387
17538   && flag_unsafe_math_optimizations
17539   && !(reload_completed || reload_in_progress)"
17540  "#"
17541  "&& 1"
17542  [(const_int 0)]
17543{
17544  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17545  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17546					operands[2]));
17547  DONE;
17548}
17549  [(set_attr "type" "fpspc")
17550   (set_attr "mode" "<MODE>")])
17551
17552(define_insn "fist<mode>2"
17553  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17554	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17555	 UNSPEC_FIST))]
17556  "TARGET_USE_FANCY_MATH_387
17557   && flag_unsafe_math_optimizations"
17558  "* return output_fix_trunc (insn, operands, 0);"
17559  [(set_attr "type" "fpspc")
17560   (set_attr "mode" "<MODE>")])
17561
17562(define_insn "fist<mode>2_with_temp"
17563  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17564	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17565	 UNSPEC_FIST))
17566   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17567  "TARGET_USE_FANCY_MATH_387
17568   && flag_unsafe_math_optimizations"
17569  "#"
17570  [(set_attr "type" "fpspc")
17571   (set_attr "mode" "<MODE>")])
17572
17573(define_split 
17574  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17575	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17576	 UNSPEC_FIST))
17577   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17578  "reload_completed"
17579  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17580		       UNSPEC_FIST))
17581   (set (match_dup 0) (match_dup 2))]
17582  "")
17583
17584(define_split 
17585  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17586	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17587	 UNSPEC_FIST))
17588   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17589  "reload_completed"
17590  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17591		       UNSPEC_FIST))]
17592  "")
17593
17594(define_expand "lrint<mode>2"
17595  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17596	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17597	 UNSPEC_FIST))]
17598  "TARGET_USE_FANCY_MATH_387
17599   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17600   && flag_unsafe_math_optimizations"
17601  "")
17602
17603;; Rounding mode control word calculation could clobber FLAGS_REG.
17604(define_insn_and_split "frndintxf2_floor"
17605  [(set (match_operand:XF 0 "register_operand" "=f")
17606	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17607	 UNSPEC_FRNDINT_FLOOR))
17608   (clobber (reg:CC FLAGS_REG))]
17609  "TARGET_USE_FANCY_MATH_387
17610   && flag_unsafe_math_optimizations
17611   && !(reload_completed || reload_in_progress)"
17612  "#"
17613  "&& 1"
17614  [(const_int 0)]
17615{
17616  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17617
17618  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17619  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17620
17621  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17622					operands[2], operands[3]));
17623  DONE;
17624}
17625  [(set_attr "type" "frndint")
17626   (set_attr "i387_cw" "floor")
17627   (set_attr "mode" "XF")])
17628
17629(define_insn "frndintxf2_floor_i387"
17630  [(set (match_operand:XF 0 "register_operand" "=f")
17631	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17632	 UNSPEC_FRNDINT_FLOOR))
17633   (use (match_operand:HI 2 "memory_operand" "m"))
17634   (use (match_operand:HI 3 "memory_operand" "m"))]
17635  "TARGET_USE_FANCY_MATH_387
17636   && flag_unsafe_math_optimizations"
17637  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17638  [(set_attr "type" "frndint")
17639   (set_attr "i387_cw" "floor")
17640   (set_attr "mode" "XF")])
17641
17642(define_expand "floorxf2"
17643  [(use (match_operand:XF 0 "register_operand" ""))
17644   (use (match_operand:XF 1 "register_operand" ""))]
17645  "TARGET_USE_FANCY_MATH_387
17646   && flag_unsafe_math_optimizations"
17647{
17648  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17649  DONE;
17650})
17651
17652(define_expand "floordf2"
17653  [(use (match_operand:DF 0 "register_operand" ""))
17654   (use (match_operand:DF 1 "register_operand" ""))]
17655  "TARGET_USE_FANCY_MATH_387
17656   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17657   && flag_unsafe_math_optimizations"
17658{
17659  rtx op0 = gen_reg_rtx (XFmode);
17660  rtx op1 = gen_reg_rtx (XFmode);
17661
17662  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17663  emit_insn (gen_frndintxf2_floor (op0, op1));
17664
17665  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17666  DONE;
17667})
17668
17669(define_expand "floorsf2"
17670  [(use (match_operand:SF 0 "register_operand" ""))
17671   (use (match_operand:SF 1 "register_operand" ""))]
17672  "TARGET_USE_FANCY_MATH_387
17673   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17674   && flag_unsafe_math_optimizations"
17675{
17676  rtx op0 = gen_reg_rtx (XFmode);
17677  rtx op1 = gen_reg_rtx (XFmode);
17678
17679  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17680  emit_insn (gen_frndintxf2_floor (op0, op1));
17681
17682  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17683  DONE;
17684})
17685
17686(define_insn_and_split "*fist<mode>2_floor_1"
17687  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17688	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17689	 UNSPEC_FIST_FLOOR))
17690   (clobber (reg:CC FLAGS_REG))]
17691  "TARGET_USE_FANCY_MATH_387
17692   && flag_unsafe_math_optimizations
17693   && !(reload_completed || reload_in_progress)"
17694  "#"
17695  "&& 1"
17696  [(const_int 0)]
17697{
17698  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17699
17700  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17701  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17702  if (memory_operand (operands[0], VOIDmode))
17703    emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17704				      operands[2], operands[3]));
17705  else
17706    {
17707      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17708      emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17709						  operands[2], operands[3],
17710						  operands[4]));
17711    }
17712  DONE;
17713}
17714  [(set_attr "type" "fistp")
17715   (set_attr "i387_cw" "floor")
17716   (set_attr "mode" "<MODE>")])
17717
17718(define_insn "fistdi2_floor"
17719  [(set (match_operand:DI 0 "memory_operand" "=m")
17720	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17721	 UNSPEC_FIST_FLOOR))
17722   (use (match_operand:HI 2 "memory_operand" "m"))
17723   (use (match_operand:HI 3 "memory_operand" "m"))
17724   (clobber (match_scratch:XF 4 "=&1f"))]
17725  "TARGET_USE_FANCY_MATH_387
17726   && flag_unsafe_math_optimizations"
17727  "* return output_fix_trunc (insn, operands, 0);"
17728  [(set_attr "type" "fistp")
17729   (set_attr "i387_cw" "floor")
17730   (set_attr "mode" "DI")])
17731
17732(define_insn "fistdi2_floor_with_temp"
17733  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17734	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17735	 UNSPEC_FIST_FLOOR))
17736   (use (match_operand:HI 2 "memory_operand" "m,m"))
17737   (use (match_operand:HI 3 "memory_operand" "m,m"))
17738   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17739   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17740  "TARGET_USE_FANCY_MATH_387
17741   && flag_unsafe_math_optimizations"
17742  "#"
17743  [(set_attr "type" "fistp")
17744   (set_attr "i387_cw" "floor")
17745   (set_attr "mode" "DI")])
17746
17747(define_split 
17748  [(set (match_operand:DI 0 "register_operand" "")
17749	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17750	 UNSPEC_FIST_FLOOR))
17751   (use (match_operand:HI 2 "memory_operand" ""))
17752   (use (match_operand:HI 3 "memory_operand" ""))
17753   (clobber (match_operand:DI 4 "memory_operand" ""))
17754   (clobber (match_scratch 5 ""))]
17755  "reload_completed"
17756  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17757	      (use (match_dup 2))
17758	      (use (match_dup 3))
17759	      (clobber (match_dup 5))])
17760   (set (match_dup 0) (match_dup 4))]
17761  "")
17762
17763(define_split 
17764  [(set (match_operand:DI 0 "memory_operand" "")
17765	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17766	 UNSPEC_FIST_FLOOR))
17767   (use (match_operand:HI 2 "memory_operand" ""))
17768   (use (match_operand:HI 3 "memory_operand" ""))
17769   (clobber (match_operand:DI 4 "memory_operand" ""))
17770   (clobber (match_scratch 5 ""))]
17771  "reload_completed"
17772  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17773	      (use (match_dup 2))
17774	      (use (match_dup 3))
17775	      (clobber (match_dup 5))])]
17776  "")
17777
17778(define_insn "fist<mode>2_floor"
17779  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17780	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17781	 UNSPEC_FIST_FLOOR))
17782   (use (match_operand:HI 2 "memory_operand" "m"))
17783   (use (match_operand:HI 3 "memory_operand" "m"))]
17784  "TARGET_USE_FANCY_MATH_387
17785   && flag_unsafe_math_optimizations"
17786  "* return output_fix_trunc (insn, operands, 0);"
17787  [(set_attr "type" "fistp")
17788   (set_attr "i387_cw" "floor")
17789   (set_attr "mode" "<MODE>")])
17790
17791(define_insn "fist<mode>2_floor_with_temp"
17792  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17793	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17794	 UNSPEC_FIST_FLOOR))
17795   (use (match_operand:HI 2 "memory_operand" "m,m"))
17796   (use (match_operand:HI 3 "memory_operand" "m,m"))
17797   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17798  "TARGET_USE_FANCY_MATH_387
17799   && flag_unsafe_math_optimizations"
17800  "#"
17801  [(set_attr "type" "fistp")
17802   (set_attr "i387_cw" "floor")
17803   (set_attr "mode" "<MODE>")])
17804
17805(define_split 
17806  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17807	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17808	 UNSPEC_FIST_FLOOR))
17809   (use (match_operand:HI 2 "memory_operand" ""))
17810   (use (match_operand:HI 3 "memory_operand" ""))
17811   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17812  "reload_completed"
17813  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17814				  UNSPEC_FIST_FLOOR))
17815	      (use (match_dup 2))
17816	      (use (match_dup 3))])
17817   (set (match_dup 0) (match_dup 4))]
17818  "")
17819
17820(define_split 
17821  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17822	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17823	 UNSPEC_FIST_FLOOR))
17824   (use (match_operand:HI 2 "memory_operand" ""))
17825   (use (match_operand:HI 3 "memory_operand" ""))
17826   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17827  "reload_completed"
17828  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17829				  UNSPEC_FIST_FLOOR))
17830	      (use (match_dup 2))
17831	      (use (match_dup 3))])]
17832  "")
17833
17834(define_expand "lfloor<mode>2"
17835  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17836		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17837		    UNSPEC_FIST_FLOOR))
17838	      (clobber (reg:CC FLAGS_REG))])]
17839  "TARGET_USE_FANCY_MATH_387
17840   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17841   && flag_unsafe_math_optimizations"
17842  "")
17843
17844;; Rounding mode control word calculation could clobber FLAGS_REG.
17845(define_insn_and_split "frndintxf2_ceil"
17846  [(set (match_operand:XF 0 "register_operand" "=f")
17847	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17848	 UNSPEC_FRNDINT_CEIL))
17849   (clobber (reg:CC FLAGS_REG))]
17850  "TARGET_USE_FANCY_MATH_387
17851   && flag_unsafe_math_optimizations
17852   && !(reload_completed || reload_in_progress)"
17853  "#"
17854  "&& 1"
17855  [(const_int 0)]
17856{
17857  ix86_optimize_mode_switching[I387_CEIL] = 1;
17858
17859  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17860  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17861
17862  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17863				       operands[2], operands[3]));
17864  DONE;
17865}
17866  [(set_attr "type" "frndint")
17867   (set_attr "i387_cw" "ceil")
17868   (set_attr "mode" "XF")])
17869
17870(define_insn "frndintxf2_ceil_i387"
17871  [(set (match_operand:XF 0 "register_operand" "=f")
17872	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17873	 UNSPEC_FRNDINT_CEIL))
17874   (use (match_operand:HI 2 "memory_operand" "m"))
17875   (use (match_operand:HI 3 "memory_operand" "m"))]
17876  "TARGET_USE_FANCY_MATH_387
17877   && flag_unsafe_math_optimizations"
17878  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17879  [(set_attr "type" "frndint")
17880   (set_attr "i387_cw" "ceil")
17881   (set_attr "mode" "XF")])
17882
17883(define_expand "ceilxf2"
17884  [(use (match_operand:XF 0 "register_operand" ""))
17885   (use (match_operand:XF 1 "register_operand" ""))]
17886  "TARGET_USE_FANCY_MATH_387
17887   && flag_unsafe_math_optimizations"
17888{
17889  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17890  DONE;
17891})
17892
17893(define_expand "ceildf2"
17894  [(use (match_operand:DF 0 "register_operand" ""))
17895   (use (match_operand:DF 1 "register_operand" ""))]
17896  "TARGET_USE_FANCY_MATH_387
17897   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17898   && flag_unsafe_math_optimizations"
17899{
17900  rtx op0 = gen_reg_rtx (XFmode);
17901  rtx op1 = gen_reg_rtx (XFmode);
17902
17903  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17904  emit_insn (gen_frndintxf2_ceil (op0, op1));
17905
17906  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17907  DONE;
17908})
17909
17910(define_expand "ceilsf2"
17911  [(use (match_operand:SF 0 "register_operand" ""))
17912   (use (match_operand:SF 1 "register_operand" ""))]
17913  "TARGET_USE_FANCY_MATH_387
17914   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17915   && flag_unsafe_math_optimizations"
17916{
17917  rtx op0 = gen_reg_rtx (XFmode);
17918  rtx op1 = gen_reg_rtx (XFmode);
17919
17920  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17921  emit_insn (gen_frndintxf2_ceil (op0, op1));
17922
17923  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17924  DONE;
17925})
17926
17927(define_insn_and_split "*fist<mode>2_ceil_1"
17928  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17929	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17930	 UNSPEC_FIST_CEIL))
17931   (clobber (reg:CC FLAGS_REG))]
17932  "TARGET_USE_FANCY_MATH_387
17933   && flag_unsafe_math_optimizations
17934   && !(reload_completed || reload_in_progress)"
17935  "#"
17936  "&& 1"
17937  [(const_int 0)]
17938{
17939  ix86_optimize_mode_switching[I387_CEIL] = 1;
17940
17941  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17942  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17943  if (memory_operand (operands[0], VOIDmode))
17944    emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17945				     operands[2], operands[3]));
17946  else
17947    {
17948      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17949      emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17950						 operands[2], operands[3],
17951						 operands[4]));
17952    }
17953  DONE;
17954}
17955  [(set_attr "type" "fistp")
17956   (set_attr "i387_cw" "ceil")
17957   (set_attr "mode" "<MODE>")])
17958
17959(define_insn "fistdi2_ceil"
17960  [(set (match_operand:DI 0 "memory_operand" "=m")
17961	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17962	 UNSPEC_FIST_CEIL))
17963   (use (match_operand:HI 2 "memory_operand" "m"))
17964   (use (match_operand:HI 3 "memory_operand" "m"))
17965   (clobber (match_scratch:XF 4 "=&1f"))]
17966  "TARGET_USE_FANCY_MATH_387
17967   && flag_unsafe_math_optimizations"
17968  "* return output_fix_trunc (insn, operands, 0);"
17969  [(set_attr "type" "fistp")
17970   (set_attr "i387_cw" "ceil")
17971   (set_attr "mode" "DI")])
17972
17973(define_insn "fistdi2_ceil_with_temp"
17974  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17975	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17976	 UNSPEC_FIST_CEIL))
17977   (use (match_operand:HI 2 "memory_operand" "m,m"))
17978   (use (match_operand:HI 3 "memory_operand" "m,m"))
17979   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17980   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17981  "TARGET_USE_FANCY_MATH_387
17982   && flag_unsafe_math_optimizations"
17983  "#"
17984  [(set_attr "type" "fistp")
17985   (set_attr "i387_cw" "ceil")
17986   (set_attr "mode" "DI")])
17987
17988(define_split 
17989  [(set (match_operand:DI 0 "register_operand" "")
17990	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17991	 UNSPEC_FIST_CEIL))
17992   (use (match_operand:HI 2 "memory_operand" ""))
17993   (use (match_operand:HI 3 "memory_operand" ""))
17994   (clobber (match_operand:DI 4 "memory_operand" ""))
17995   (clobber (match_scratch 5 ""))]
17996  "reload_completed"
17997  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17998	      (use (match_dup 2))
17999	      (use (match_dup 3))
18000	      (clobber (match_dup 5))])
18001   (set (match_dup 0) (match_dup 4))]
18002  "")
18003
18004(define_split 
18005  [(set (match_operand:DI 0 "memory_operand" "")
18006	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
18007	 UNSPEC_FIST_CEIL))
18008   (use (match_operand:HI 2 "memory_operand" ""))
18009   (use (match_operand:HI 3 "memory_operand" ""))
18010   (clobber (match_operand:DI 4 "memory_operand" ""))
18011   (clobber (match_scratch 5 ""))]
18012  "reload_completed"
18013  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18014	      (use (match_dup 2))
18015	      (use (match_dup 3))
18016	      (clobber (match_dup 5))])]
18017  "")
18018
18019(define_insn "fist<mode>2_ceil"
18020  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18021	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18022	 UNSPEC_FIST_CEIL))
18023   (use (match_operand:HI 2 "memory_operand" "m"))
18024   (use (match_operand:HI 3 "memory_operand" "m"))]
18025  "TARGET_USE_FANCY_MATH_387
18026   && flag_unsafe_math_optimizations"
18027  "* return output_fix_trunc (insn, operands, 0);"
18028  [(set_attr "type" "fistp")
18029   (set_attr "i387_cw" "ceil")
18030   (set_attr "mode" "<MODE>")])
18031
18032(define_insn "fist<mode>2_ceil_with_temp"
18033  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18034	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18035	 UNSPEC_FIST_CEIL))
18036   (use (match_operand:HI 2 "memory_operand" "m,m"))
18037   (use (match_operand:HI 3 "memory_operand" "m,m"))
18038   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18039  "TARGET_USE_FANCY_MATH_387
18040   && flag_unsafe_math_optimizations"
18041  "#"
18042  [(set_attr "type" "fistp")
18043   (set_attr "i387_cw" "ceil")
18044   (set_attr "mode" "<MODE>")])
18045
18046(define_split 
18047  [(set (match_operand:X87MODEI12 0 "register_operand" "")
18048	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18049	 UNSPEC_FIST_CEIL))
18050   (use (match_operand:HI 2 "memory_operand" ""))
18051   (use (match_operand:HI 3 "memory_operand" ""))
18052   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18053  "reload_completed"
18054  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18055				  UNSPEC_FIST_CEIL))
18056	      (use (match_dup 2))
18057	      (use (match_dup 3))])
18058   (set (match_dup 0) (match_dup 4))]
18059  "")
18060
18061(define_split 
18062  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18063	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18064	 UNSPEC_FIST_CEIL))
18065   (use (match_operand:HI 2 "memory_operand" ""))
18066   (use (match_operand:HI 3 "memory_operand" ""))
18067   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18068  "reload_completed"
18069  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18070				  UNSPEC_FIST_CEIL))
18071	      (use (match_dup 2))
18072	      (use (match_dup 3))])]
18073  "")
18074
18075(define_expand "lceil<mode>2"
18076  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18077		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18078		    UNSPEC_FIST_CEIL))
18079	      (clobber (reg:CC FLAGS_REG))])]
18080  "TARGET_USE_FANCY_MATH_387
18081   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18082   && flag_unsafe_math_optimizations"
18083  "")
18084
18085;; Rounding mode control word calculation could clobber FLAGS_REG.
18086(define_insn_and_split "frndintxf2_trunc"
18087  [(set (match_operand:XF 0 "register_operand" "=f")
18088	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18089	 UNSPEC_FRNDINT_TRUNC))
18090   (clobber (reg:CC FLAGS_REG))]
18091  "TARGET_USE_FANCY_MATH_387
18092   && flag_unsafe_math_optimizations
18093   && !(reload_completed || reload_in_progress)"
18094  "#"
18095  "&& 1"
18096  [(const_int 0)]
18097{
18098  ix86_optimize_mode_switching[I387_TRUNC] = 1;
18099
18100  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18101  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18102
18103  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18104					operands[2], operands[3]));
18105  DONE;
18106}
18107  [(set_attr "type" "frndint")
18108   (set_attr "i387_cw" "trunc")
18109   (set_attr "mode" "XF")])
18110
18111(define_insn "frndintxf2_trunc_i387"
18112  [(set (match_operand:XF 0 "register_operand" "=f")
18113	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18114	 UNSPEC_FRNDINT_TRUNC))
18115   (use (match_operand:HI 2 "memory_operand" "m"))
18116   (use (match_operand:HI 3 "memory_operand" "m"))]
18117  "TARGET_USE_FANCY_MATH_387
18118   && flag_unsafe_math_optimizations"
18119  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18120  [(set_attr "type" "frndint")
18121   (set_attr "i387_cw" "trunc")
18122   (set_attr "mode" "XF")])
18123
18124(define_expand "btruncxf2"
18125  [(use (match_operand:XF 0 "register_operand" ""))
18126   (use (match_operand:XF 1 "register_operand" ""))]
18127  "TARGET_USE_FANCY_MATH_387
18128   && flag_unsafe_math_optimizations"
18129{
18130  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18131  DONE;
18132})
18133
18134(define_expand "btruncdf2"
18135  [(use (match_operand:DF 0 "register_operand" ""))
18136   (use (match_operand:DF 1 "register_operand" ""))]
18137  "TARGET_USE_FANCY_MATH_387
18138   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18139   && flag_unsafe_math_optimizations"
18140{
18141  rtx op0 = gen_reg_rtx (XFmode);
18142  rtx op1 = gen_reg_rtx (XFmode);
18143
18144  emit_insn (gen_extenddfxf2 (op1, operands[1]));
18145  emit_insn (gen_frndintxf2_trunc (op0, op1));
18146
18147  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18148  DONE;
18149})
18150
18151(define_expand "btruncsf2"
18152  [(use (match_operand:SF 0 "register_operand" ""))
18153   (use (match_operand:SF 1 "register_operand" ""))]
18154  "TARGET_USE_FANCY_MATH_387
18155   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18156   && flag_unsafe_math_optimizations"
18157{
18158  rtx op0 = gen_reg_rtx (XFmode);
18159  rtx op1 = gen_reg_rtx (XFmode);
18160
18161  emit_insn (gen_extendsfxf2 (op1, operands[1]));
18162  emit_insn (gen_frndintxf2_trunc (op0, op1));
18163
18164  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18165  DONE;
18166})
18167
18168;; Rounding mode control word calculation could clobber FLAGS_REG.
18169(define_insn_and_split "frndintxf2_mask_pm"
18170  [(set (match_operand:XF 0 "register_operand" "=f")
18171	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18172	 UNSPEC_FRNDINT_MASK_PM))
18173   (clobber (reg:CC FLAGS_REG))]
18174  "TARGET_USE_FANCY_MATH_387
18175   && flag_unsafe_math_optimizations
18176   && !(reload_completed || reload_in_progress)"
18177  "#"
18178  "&& 1"
18179  [(const_int 0)]
18180{
18181  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18182
18183  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18184  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18185
18186  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18187					  operands[2], operands[3]));
18188  DONE;
18189}
18190  [(set_attr "type" "frndint")
18191   (set_attr "i387_cw" "mask_pm")
18192   (set_attr "mode" "XF")])
18193
18194(define_insn "frndintxf2_mask_pm_i387"
18195  [(set (match_operand:XF 0 "register_operand" "=f")
18196	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18197	 UNSPEC_FRNDINT_MASK_PM))
18198   (use (match_operand:HI 2 "memory_operand" "m"))
18199   (use (match_operand:HI 3 "memory_operand" "m"))]
18200  "TARGET_USE_FANCY_MATH_387
18201   && flag_unsafe_math_optimizations"
18202  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18203  [(set_attr "type" "frndint")
18204   (set_attr "i387_cw" "mask_pm")
18205   (set_attr "mode" "XF")])
18206
18207(define_expand "nearbyintxf2"
18208  [(use (match_operand:XF 0 "register_operand" ""))
18209   (use (match_operand:XF 1 "register_operand" ""))]
18210  "TARGET_USE_FANCY_MATH_387
18211   && flag_unsafe_math_optimizations"
18212{
18213  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18214
18215  DONE;
18216})
18217
18218(define_expand "nearbyintdf2"
18219  [(use (match_operand:DF 0 "register_operand" ""))
18220   (use (match_operand:DF 1 "register_operand" ""))]
18221  "TARGET_USE_FANCY_MATH_387
18222   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18223   && flag_unsafe_math_optimizations"
18224{
18225  rtx op0 = gen_reg_rtx (XFmode);
18226  rtx op1 = gen_reg_rtx (XFmode);
18227
18228  emit_insn (gen_extenddfxf2 (op1, operands[1]));
18229  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18230
18231  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18232  DONE;
18233})
18234
18235(define_expand "nearbyintsf2"
18236  [(use (match_operand:SF 0 "register_operand" ""))
18237   (use (match_operand:SF 1 "register_operand" ""))]
18238  "TARGET_USE_FANCY_MATH_387
18239   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18240   && flag_unsafe_math_optimizations"
18241{
18242  rtx op0 = gen_reg_rtx (XFmode);
18243  rtx op1 = gen_reg_rtx (XFmode);
18244
18245  emit_insn (gen_extendsfxf2 (op1, operands[1]));
18246  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18247
18248  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18249  DONE;
18250})
18251
18252
18253;; Block operation instructions
18254
18255(define_insn "cld"
18256 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18257 ""
18258 "cld"
18259  [(set_attr "type" "cld")])
18260
18261(define_expand "movmemsi"
18262  [(use (match_operand:BLK 0 "memory_operand" ""))
18263   (use (match_operand:BLK 1 "memory_operand" ""))
18264   (use (match_operand:SI 2 "nonmemory_operand" ""))
18265   (use (match_operand:SI 3 "const_int_operand" ""))]
18266  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18267{
18268 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18269   DONE;
18270 else
18271   FAIL;
18272})
18273
18274(define_expand "movmemdi"
18275  [(use (match_operand:BLK 0 "memory_operand" ""))
18276   (use (match_operand:BLK 1 "memory_operand" ""))
18277   (use (match_operand:DI 2 "nonmemory_operand" ""))
18278   (use (match_operand:DI 3 "const_int_operand" ""))]
18279  "TARGET_64BIT"
18280{
18281 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18282   DONE;
18283 else
18284   FAIL;
18285})
18286
18287;; Most CPUs don't like single string operations
18288;; Handle this case here to simplify previous expander.
18289
18290(define_expand "strmov"
18291  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18292   (set (match_operand 1 "memory_operand" "") (match_dup 4))
18293   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18294	      (clobber (reg:CC FLAGS_REG))])
18295   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18296	      (clobber (reg:CC FLAGS_REG))])]
18297  ""
18298{
18299  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18300
18301  /* If .md ever supports :P for Pmode, these can be directly
18302     in the pattern above.  */
18303  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18304  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18305
18306  if (TARGET_SINGLE_STRINGOP || optimize_size)
18307    {
18308      emit_insn (gen_strmov_singleop (operands[0], operands[1],
18309				      operands[2], operands[3],
18310				      operands[5], operands[6]));
18311      DONE;
18312    }
18313
18314  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18315})
18316
18317(define_expand "strmov_singleop"
18318  [(parallel [(set (match_operand 1 "memory_operand" "")
18319		   (match_operand 3 "memory_operand" ""))
18320	      (set (match_operand 0 "register_operand" "")
18321		   (match_operand 4 "" ""))
18322	      (set (match_operand 2 "register_operand" "")
18323		   (match_operand 5 "" ""))
18324	      (use (reg:SI DIRFLAG_REG))])]
18325  "TARGET_SINGLE_STRINGOP || optimize_size"
18326  "")
18327
18328(define_insn "*strmovdi_rex_1"
18329  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18330	(mem:DI (match_operand:DI 3 "register_operand" "1")))
18331   (set (match_operand:DI 0 "register_operand" "=D")
18332	(plus:DI (match_dup 2)
18333		 (const_int 8)))
18334   (set (match_operand:DI 1 "register_operand" "=S")
18335	(plus:DI (match_dup 3)
18336		 (const_int 8)))
18337   (use (reg:SI DIRFLAG_REG))]
18338  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18339  "movsq"
18340  [(set_attr "type" "str")
18341   (set_attr "mode" "DI")
18342   (set_attr "memory" "both")])
18343
18344(define_insn "*strmovsi_1"
18345  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18346	(mem:SI (match_operand:SI 3 "register_operand" "1")))
18347   (set (match_operand:SI 0 "register_operand" "=D")
18348	(plus:SI (match_dup 2)
18349		 (const_int 4)))
18350   (set (match_operand:SI 1 "register_operand" "=S")
18351	(plus:SI (match_dup 3)
18352		 (const_int 4)))
18353   (use (reg:SI DIRFLAG_REG))]
18354  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18355  "{movsl|movsd}"
18356  [(set_attr "type" "str")
18357   (set_attr "mode" "SI")
18358   (set_attr "memory" "both")])
18359
18360(define_insn "*strmovsi_rex_1"
18361  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18362	(mem:SI (match_operand:DI 3 "register_operand" "1")))
18363   (set (match_operand:DI 0 "register_operand" "=D")
18364	(plus:DI (match_dup 2)
18365		 (const_int 4)))
18366   (set (match_operand:DI 1 "register_operand" "=S")
18367	(plus:DI (match_dup 3)
18368		 (const_int 4)))
18369   (use (reg:SI DIRFLAG_REG))]
18370  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18371  "{movsl|movsd}"
18372  [(set_attr "type" "str")
18373   (set_attr "mode" "SI")
18374   (set_attr "memory" "both")])
18375
18376(define_insn "*strmovhi_1"
18377  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18378	(mem:HI (match_operand:SI 3 "register_operand" "1")))
18379   (set (match_operand:SI 0 "register_operand" "=D")
18380	(plus:SI (match_dup 2)
18381		 (const_int 2)))
18382   (set (match_operand:SI 1 "register_operand" "=S")
18383	(plus:SI (match_dup 3)
18384		 (const_int 2)))
18385   (use (reg:SI DIRFLAG_REG))]
18386  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18387  "movsw"
18388  [(set_attr "type" "str")
18389   (set_attr "memory" "both")
18390   (set_attr "mode" "HI")])
18391
18392(define_insn "*strmovhi_rex_1"
18393  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18394	(mem:HI (match_operand:DI 3 "register_operand" "1")))
18395   (set (match_operand:DI 0 "register_operand" "=D")
18396	(plus:DI (match_dup 2)
18397		 (const_int 2)))
18398   (set (match_operand:DI 1 "register_operand" "=S")
18399	(plus:DI (match_dup 3)
18400		 (const_int 2)))
18401   (use (reg:SI DIRFLAG_REG))]
18402  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18403  "movsw"
18404  [(set_attr "type" "str")
18405   (set_attr "memory" "both")
18406   (set_attr "mode" "HI")])
18407
18408(define_insn "*strmovqi_1"
18409  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18410	(mem:QI (match_operand:SI 3 "register_operand" "1")))
18411   (set (match_operand:SI 0 "register_operand" "=D")
18412	(plus:SI (match_dup 2)
18413		 (const_int 1)))
18414   (set (match_operand:SI 1 "register_operand" "=S")
18415	(plus:SI (match_dup 3)
18416		 (const_int 1)))
18417   (use (reg:SI DIRFLAG_REG))]
18418  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18419  "movsb"
18420  [(set_attr "type" "str")
18421   (set_attr "memory" "both")
18422   (set_attr "mode" "QI")])
18423
18424(define_insn "*strmovqi_rex_1"
18425  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18426	(mem:QI (match_operand:DI 3 "register_operand" "1")))
18427   (set (match_operand:DI 0 "register_operand" "=D")
18428	(plus:DI (match_dup 2)
18429		 (const_int 1)))
18430   (set (match_operand:DI 1 "register_operand" "=S")
18431	(plus:DI (match_dup 3)
18432		 (const_int 1)))
18433   (use (reg:SI DIRFLAG_REG))]
18434  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18435  "movsb"
18436  [(set_attr "type" "str")
18437   (set_attr "memory" "both")
18438   (set_attr "mode" "QI")])
18439
18440(define_expand "rep_mov"
18441  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18442	      (set (match_operand 0 "register_operand" "")
18443		   (match_operand 5 "" ""))
18444	      (set (match_operand 2 "register_operand" "")
18445		   (match_operand 6 "" ""))
18446	      (set (match_operand 1 "memory_operand" "")
18447		   (match_operand 3 "memory_operand" ""))
18448	      (use (match_dup 4))
18449	      (use (reg:SI DIRFLAG_REG))])]
18450  ""
18451  "")
18452
18453(define_insn "*rep_movdi_rex64"
18454  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18455   (set (match_operand:DI 0 "register_operand" "=D") 
18456        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18457			    (const_int 3))
18458		 (match_operand:DI 3 "register_operand" "0")))
18459   (set (match_operand:DI 1 "register_operand" "=S") 
18460        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18461		 (match_operand:DI 4 "register_operand" "1")))
18462   (set (mem:BLK (match_dup 3))
18463	(mem:BLK (match_dup 4)))
18464   (use (match_dup 5))
18465   (use (reg:SI DIRFLAG_REG))]
18466  "TARGET_64BIT"
18467  "{rep\;movsq|rep movsq}"
18468  [(set_attr "type" "str")
18469   (set_attr "prefix_rep" "1")
18470   (set_attr "memory" "both")
18471   (set_attr "mode" "DI")])
18472
18473(define_insn "*rep_movsi"
18474  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18475   (set (match_operand:SI 0 "register_operand" "=D") 
18476        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18477			    (const_int 2))
18478		 (match_operand:SI 3 "register_operand" "0")))
18479   (set (match_operand:SI 1 "register_operand" "=S") 
18480        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18481		 (match_operand:SI 4 "register_operand" "1")))
18482   (set (mem:BLK (match_dup 3))
18483	(mem:BLK (match_dup 4)))
18484   (use (match_dup 5))
18485   (use (reg:SI DIRFLAG_REG))]
18486  "!TARGET_64BIT"
18487  "{rep\;movsl|rep movsd}"
18488  [(set_attr "type" "str")
18489   (set_attr "prefix_rep" "1")
18490   (set_attr "memory" "both")
18491   (set_attr "mode" "SI")])
18492
18493(define_insn "*rep_movsi_rex64"
18494  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18495   (set (match_operand:DI 0 "register_operand" "=D") 
18496        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18497			    (const_int 2))
18498		 (match_operand:DI 3 "register_operand" "0")))
18499   (set (match_operand:DI 1 "register_operand" "=S") 
18500        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18501		 (match_operand:DI 4 "register_operand" "1")))
18502   (set (mem:BLK (match_dup 3))
18503	(mem:BLK (match_dup 4)))
18504   (use (match_dup 5))
18505   (use (reg:SI DIRFLAG_REG))]
18506  "TARGET_64BIT"
18507  "{rep\;movsl|rep movsd}"
18508  [(set_attr "type" "str")
18509   (set_attr "prefix_rep" "1")
18510   (set_attr "memory" "both")
18511   (set_attr "mode" "SI")])
18512
18513(define_insn "*rep_movqi"
18514  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18515   (set (match_operand:SI 0 "register_operand" "=D") 
18516        (plus:SI (match_operand:SI 3 "register_operand" "0")
18517		 (match_operand:SI 5 "register_operand" "2")))
18518   (set (match_operand:SI 1 "register_operand" "=S") 
18519        (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18520   (set (mem:BLK (match_dup 3))
18521	(mem:BLK (match_dup 4)))
18522   (use (match_dup 5))
18523   (use (reg:SI DIRFLAG_REG))]
18524  "!TARGET_64BIT"
18525  "{rep\;movsb|rep movsb}"
18526  [(set_attr "type" "str")
18527   (set_attr "prefix_rep" "1")
18528   (set_attr "memory" "both")
18529   (set_attr "mode" "SI")])
18530
18531(define_insn "*rep_movqi_rex64"
18532  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18533   (set (match_operand:DI 0 "register_operand" "=D") 
18534        (plus:DI (match_operand:DI 3 "register_operand" "0")
18535		 (match_operand:DI 5 "register_operand" "2")))
18536   (set (match_operand:DI 1 "register_operand" "=S") 
18537        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18538   (set (mem:BLK (match_dup 3))
18539	(mem:BLK (match_dup 4)))
18540   (use (match_dup 5))
18541   (use (reg:SI DIRFLAG_REG))]
18542  "TARGET_64BIT"
18543  "{rep\;movsb|rep movsb}"
18544  [(set_attr "type" "str")
18545   (set_attr "prefix_rep" "1")
18546   (set_attr "memory" "both")
18547   (set_attr "mode" "SI")])
18548
18549(define_expand "setmemsi"
18550   [(use (match_operand:BLK 0 "memory_operand" ""))
18551    (use (match_operand:SI 1 "nonmemory_operand" ""))
18552    (use (match_operand 2 "const_int_operand" ""))
18553    (use (match_operand 3 "const_int_operand" ""))]
18554  ""
18555{
18556 /* If value to set is not zero, use the library routine.  */
18557 if (operands[2] != const0_rtx)
18558   FAIL;
18559
18560 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18561   DONE;
18562 else
18563   FAIL;
18564})
18565
18566(define_expand "setmemdi"
18567   [(use (match_operand:BLK 0 "memory_operand" ""))
18568    (use (match_operand:DI 1 "nonmemory_operand" ""))
18569    (use (match_operand 2 "const_int_operand" ""))
18570    (use (match_operand 3 "const_int_operand" ""))]
18571  "TARGET_64BIT"
18572{
18573 /* If value to set is not zero, use the library routine.  */
18574 if (operands[2] != const0_rtx)
18575   FAIL;
18576
18577 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18578   DONE;
18579 else
18580   FAIL;
18581})
18582
18583;; Most CPUs don't like single string operations
18584;; Handle this case here to simplify previous expander.
18585
18586(define_expand "strset"
18587  [(set (match_operand 1 "memory_operand" "")
18588	(match_operand 2 "register_operand" ""))
18589   (parallel [(set (match_operand 0 "register_operand" "")
18590		   (match_dup 3))
18591	      (clobber (reg:CC FLAGS_REG))])]
18592  ""
18593{
18594  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18595    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18596
18597  /* If .md ever supports :P for Pmode, this can be directly
18598     in the pattern above.  */
18599  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18600			      GEN_INT (GET_MODE_SIZE (GET_MODE
18601						      (operands[2]))));
18602  if (TARGET_SINGLE_STRINGOP || optimize_size)
18603    {
18604      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18605				      operands[3]));
18606      DONE;
18607    }
18608})
18609
18610(define_expand "strset_singleop"
18611  [(parallel [(set (match_operand 1 "memory_operand" "")
18612		   (match_operand 2 "register_operand" ""))
18613	      (set (match_operand 0 "register_operand" "")
18614		   (match_operand 3 "" ""))
18615	      (use (reg:SI DIRFLAG_REG))])]
18616  "TARGET_SINGLE_STRINGOP || optimize_size"
18617  "")
18618
18619(define_insn "*strsetdi_rex_1"
18620  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18621	(match_operand:DI 2 "register_operand" "a"))
18622   (set (match_operand:DI 0 "register_operand" "=D")
18623	(plus:DI (match_dup 1)
18624		 (const_int 8)))
18625   (use (reg:SI DIRFLAG_REG))]
18626  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18627  "stosq"
18628  [(set_attr "type" "str")
18629   (set_attr "memory" "store")
18630   (set_attr "mode" "DI")])
18631
18632(define_insn "*strsetsi_1"
18633  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18634	(match_operand:SI 2 "register_operand" "a"))
18635   (set (match_operand:SI 0 "register_operand" "=D")
18636	(plus:SI (match_dup 1)
18637		 (const_int 4)))
18638   (use (reg:SI DIRFLAG_REG))]
18639  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18640  "{stosl|stosd}"
18641  [(set_attr "type" "str")
18642   (set_attr "memory" "store")
18643   (set_attr "mode" "SI")])
18644
18645(define_insn "*strsetsi_rex_1"
18646  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18647	(match_operand:SI 2 "register_operand" "a"))
18648   (set (match_operand:DI 0 "register_operand" "=D")
18649	(plus:DI (match_dup 1)
18650		 (const_int 4)))
18651   (use (reg:SI DIRFLAG_REG))]
18652  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18653  "{stosl|stosd}"
18654  [(set_attr "type" "str")
18655   (set_attr "memory" "store")
18656   (set_attr "mode" "SI")])
18657
18658(define_insn "*strsethi_1"
18659  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18660	(match_operand:HI 2 "register_operand" "a"))
18661   (set (match_operand:SI 0 "register_operand" "=D")
18662	(plus:SI (match_dup 1)
18663		 (const_int 2)))
18664   (use (reg:SI DIRFLAG_REG))]
18665  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18666  "stosw"
18667  [(set_attr "type" "str")
18668   (set_attr "memory" "store")
18669   (set_attr "mode" "HI")])
18670
18671(define_insn "*strsethi_rex_1"
18672  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18673	(match_operand:HI 2 "register_operand" "a"))
18674   (set (match_operand:DI 0 "register_operand" "=D")
18675	(plus:DI (match_dup 1)
18676		 (const_int 2)))
18677   (use (reg:SI DIRFLAG_REG))]
18678  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18679  "stosw"
18680  [(set_attr "type" "str")
18681   (set_attr "memory" "store")
18682   (set_attr "mode" "HI")])
18683
18684(define_insn "*strsetqi_1"
18685  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18686	(match_operand:QI 2 "register_operand" "a"))
18687   (set (match_operand:SI 0 "register_operand" "=D")
18688	(plus:SI (match_dup 1)
18689		 (const_int 1)))
18690   (use (reg:SI DIRFLAG_REG))]
18691  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18692  "stosb"
18693  [(set_attr "type" "str")
18694   (set_attr "memory" "store")
18695   (set_attr "mode" "QI")])
18696
18697(define_insn "*strsetqi_rex_1"
18698  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18699	(match_operand:QI 2 "register_operand" "a"))
18700   (set (match_operand:DI 0 "register_operand" "=D")
18701	(plus:DI (match_dup 1)
18702		 (const_int 1)))
18703   (use (reg:SI DIRFLAG_REG))]
18704  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18705  "stosb"
18706  [(set_attr "type" "str")
18707   (set_attr "memory" "store")
18708   (set_attr "mode" "QI")])
18709
18710(define_expand "rep_stos"
18711  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18712	      (set (match_operand 0 "register_operand" "")
18713		   (match_operand 4 "" ""))
18714	      (set (match_operand 2 "memory_operand" "") (const_int 0))
18715	      (use (match_operand 3 "register_operand" ""))
18716	      (use (match_dup 1))
18717	      (use (reg:SI DIRFLAG_REG))])]
18718  ""
18719  "")
18720
18721(define_insn "*rep_stosdi_rex64"
18722  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18723   (set (match_operand:DI 0 "register_operand" "=D") 
18724        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18725			    (const_int 3))
18726		 (match_operand:DI 3 "register_operand" "0")))
18727   (set (mem:BLK (match_dup 3))
18728	(const_int 0))
18729   (use (match_operand:DI 2 "register_operand" "a"))
18730   (use (match_dup 4))
18731   (use (reg:SI DIRFLAG_REG))]
18732  "TARGET_64BIT"
18733  "{rep\;stosq|rep stosq}"
18734  [(set_attr "type" "str")
18735   (set_attr "prefix_rep" "1")
18736   (set_attr "memory" "store")
18737   (set_attr "mode" "DI")])
18738
18739(define_insn "*rep_stossi"
18740  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18741   (set (match_operand:SI 0 "register_operand" "=D") 
18742        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18743			    (const_int 2))
18744		 (match_operand:SI 3 "register_operand" "0")))
18745   (set (mem:BLK (match_dup 3))
18746	(const_int 0))
18747   (use (match_operand:SI 2 "register_operand" "a"))
18748   (use (match_dup 4))
18749   (use (reg:SI DIRFLAG_REG))]
18750  "!TARGET_64BIT"
18751  "{rep\;stosl|rep stosd}"
18752  [(set_attr "type" "str")
18753   (set_attr "prefix_rep" "1")
18754   (set_attr "memory" "store")
18755   (set_attr "mode" "SI")])
18756
18757(define_insn "*rep_stossi_rex64"
18758  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18759   (set (match_operand:DI 0 "register_operand" "=D") 
18760        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18761			    (const_int 2))
18762		 (match_operand:DI 3 "register_operand" "0")))
18763   (set (mem:BLK (match_dup 3))
18764	(const_int 0))
18765   (use (match_operand:SI 2 "register_operand" "a"))
18766   (use (match_dup 4))
18767   (use (reg:SI DIRFLAG_REG))]
18768  "TARGET_64BIT"
18769  "{rep\;stosl|rep stosd}"
18770  [(set_attr "type" "str")
18771   (set_attr "prefix_rep" "1")
18772   (set_attr "memory" "store")
18773   (set_attr "mode" "SI")])
18774
18775(define_insn "*rep_stosqi"
18776  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18777   (set (match_operand:SI 0 "register_operand" "=D") 
18778        (plus:SI (match_operand:SI 3 "register_operand" "0")
18779		 (match_operand:SI 4 "register_operand" "1")))
18780   (set (mem:BLK (match_dup 3))
18781	(const_int 0))
18782   (use (match_operand:QI 2 "register_operand" "a"))
18783   (use (match_dup 4))
18784   (use (reg:SI DIRFLAG_REG))]
18785  "!TARGET_64BIT"
18786  "{rep\;stosb|rep stosb}"
18787  [(set_attr "type" "str")
18788   (set_attr "prefix_rep" "1")
18789   (set_attr "memory" "store")
18790   (set_attr "mode" "QI")])
18791
18792(define_insn "*rep_stosqi_rex64"
18793  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18794   (set (match_operand:DI 0 "register_operand" "=D") 
18795        (plus:DI (match_operand:DI 3 "register_operand" "0")
18796		 (match_operand:DI 4 "register_operand" "1")))
18797   (set (mem:BLK (match_dup 3))
18798	(const_int 0))
18799   (use (match_operand:QI 2 "register_operand" "a"))
18800   (use (match_dup 4))
18801   (use (reg:SI DIRFLAG_REG))]
18802  "TARGET_64BIT"
18803  "{rep\;stosb|rep stosb}"
18804  [(set_attr "type" "str")
18805   (set_attr "prefix_rep" "1")
18806   (set_attr "memory" "store")
18807   (set_attr "mode" "QI")])
18808
18809(define_expand "cmpstrnsi"
18810  [(set (match_operand:SI 0 "register_operand" "")
18811	(compare:SI (match_operand:BLK 1 "general_operand" "")
18812		    (match_operand:BLK 2 "general_operand" "")))
18813   (use (match_operand 3 "general_operand" ""))
18814   (use (match_operand 4 "immediate_operand" ""))]
18815  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18816{
18817  rtx addr1, addr2, out, outlow, count, countreg, align;
18818
18819  /* Can't use this if the user has appropriated esi or edi.  */
18820  if (global_regs[4] || global_regs[5])
18821    FAIL;
18822
18823  out = operands[0];
18824  if (GET_CODE (out) != REG)
18825    out = gen_reg_rtx (SImode);
18826
18827  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18828  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18829  if (addr1 != XEXP (operands[1], 0))
18830    operands[1] = replace_equiv_address_nv (operands[1], addr1);
18831  if (addr2 != XEXP (operands[2], 0))
18832    operands[2] = replace_equiv_address_nv (operands[2], addr2);
18833
18834  count = operands[3];
18835  countreg = ix86_zero_extend_to_Pmode (count);
18836
18837  /* %%% Iff we are testing strict equality, we can use known alignment
18838     to good advantage.  This may be possible with combine, particularly
18839     once cc0 is dead.  */
18840  align = operands[4];
18841
18842  emit_insn (gen_cld ());
18843  if (GET_CODE (count) == CONST_INT)
18844    {
18845      if (INTVAL (count) == 0)
18846	{
18847	  emit_move_insn (operands[0], const0_rtx);
18848	  DONE;
18849	}
18850      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18851				     operands[1], operands[2]));
18852    }
18853  else
18854    {
18855      if (TARGET_64BIT)
18856	emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18857      else
18858	emit_insn (gen_cmpsi_1 (countreg, countreg));
18859      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18860				  operands[1], operands[2]));
18861    }
18862
18863  outlow = gen_lowpart (QImode, out);
18864  emit_insn (gen_cmpintqi (outlow));
18865  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18866
18867  if (operands[0] != out)
18868    emit_move_insn (operands[0], out);
18869
18870  DONE;
18871})
18872
18873;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18874
18875(define_expand "cmpintqi"
18876  [(set (match_dup 1)
18877	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18878   (set (match_dup 2)
18879	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18880   (parallel [(set (match_operand:QI 0 "register_operand" "")
18881		   (minus:QI (match_dup 1)
18882			     (match_dup 2)))
18883	      (clobber (reg:CC FLAGS_REG))])]
18884  ""
18885  "operands[1] = gen_reg_rtx (QImode);
18886   operands[2] = gen_reg_rtx (QImode);")
18887
18888;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18889;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18890
18891(define_expand "cmpstrnqi_nz_1"
18892  [(parallel [(set (reg:CC FLAGS_REG)
18893		   (compare:CC (match_operand 4 "memory_operand" "")
18894			       (match_operand 5 "memory_operand" "")))
18895	      (use (match_operand 2 "register_operand" ""))
18896	      (use (match_operand:SI 3 "immediate_operand" ""))
18897	      (use (reg:SI DIRFLAG_REG))
18898	      (clobber (match_operand 0 "register_operand" ""))
18899	      (clobber (match_operand 1 "register_operand" ""))
18900	      (clobber (match_dup 2))])]
18901  ""
18902  "")
18903
18904(define_insn "*cmpstrnqi_nz_1"
18905  [(set (reg:CC FLAGS_REG)
18906	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18907		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18908   (use (match_operand:SI 6 "register_operand" "2"))
18909   (use (match_operand:SI 3 "immediate_operand" "i"))
18910   (use (reg:SI DIRFLAG_REG))
18911   (clobber (match_operand:SI 0 "register_operand" "=S"))
18912   (clobber (match_operand:SI 1 "register_operand" "=D"))
18913   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18914  "!TARGET_64BIT"
18915  "repz{\;| }cmpsb"
18916  [(set_attr "type" "str")
18917   (set_attr "mode" "QI")
18918   (set_attr "prefix_rep" "1")])
18919
18920(define_insn "*cmpstrnqi_nz_rex_1"
18921  [(set (reg:CC FLAGS_REG)
18922	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18923		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18924   (use (match_operand:DI 6 "register_operand" "2"))
18925   (use (match_operand:SI 3 "immediate_operand" "i"))
18926   (use (reg:SI DIRFLAG_REG))
18927   (clobber (match_operand:DI 0 "register_operand" "=S"))
18928   (clobber (match_operand:DI 1 "register_operand" "=D"))
18929   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18930  "TARGET_64BIT"
18931  "repz{\;| }cmpsb"
18932  [(set_attr "type" "str")
18933   (set_attr "mode" "QI")
18934   (set_attr "prefix_rep" "1")])
18935
18936;; The same, but the count is not known to not be zero.
18937
18938(define_expand "cmpstrnqi_1"
18939  [(parallel [(set (reg:CC FLAGS_REG)
18940		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
18941				     (const_int 0))
18942		  (compare:CC (match_operand 4 "memory_operand" "")
18943			      (match_operand 5 "memory_operand" ""))
18944		  (const_int 0)))
18945	      (use (match_operand:SI 3 "immediate_operand" ""))
18946	      (use (reg:CC FLAGS_REG))
18947	      (use (reg:SI DIRFLAG_REG))
18948	      (clobber (match_operand 0 "register_operand" ""))
18949	      (clobber (match_operand 1 "register_operand" ""))
18950	      (clobber (match_dup 2))])]
18951  ""
18952  "")
18953
18954(define_insn "*cmpstrnqi_1"
18955  [(set (reg:CC FLAGS_REG)
18956	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18957			     (const_int 0))
18958	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18959		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18960	  (const_int 0)))
18961   (use (match_operand:SI 3 "immediate_operand" "i"))
18962   (use (reg:CC FLAGS_REG))
18963   (use (reg:SI DIRFLAG_REG))
18964   (clobber (match_operand:SI 0 "register_operand" "=S"))
18965   (clobber (match_operand:SI 1 "register_operand" "=D"))
18966   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18967  "!TARGET_64BIT"
18968  "repz{\;| }cmpsb"
18969  [(set_attr "type" "str")
18970   (set_attr "mode" "QI")
18971   (set_attr "prefix_rep" "1")])
18972
18973(define_insn "*cmpstrnqi_rex_1"
18974  [(set (reg:CC FLAGS_REG)
18975	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18976			     (const_int 0))
18977	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18978		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18979	  (const_int 0)))
18980   (use (match_operand:SI 3 "immediate_operand" "i"))
18981   (use (reg:CC FLAGS_REG))
18982   (use (reg:SI DIRFLAG_REG))
18983   (clobber (match_operand:DI 0 "register_operand" "=S"))
18984   (clobber (match_operand:DI 1 "register_operand" "=D"))
18985   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18986  "TARGET_64BIT"
18987  "repz{\;| }cmpsb"
18988  [(set_attr "type" "str")
18989   (set_attr "mode" "QI")
18990   (set_attr "prefix_rep" "1")])
18991
18992(define_expand "strlensi"
18993  [(set (match_operand:SI 0 "register_operand" "")
18994	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
18995		    (match_operand:QI 2 "immediate_operand" "")
18996		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18997  ""
18998{
18999 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19000   DONE;
19001 else
19002   FAIL;
19003})
19004
19005(define_expand "strlendi"
19006  [(set (match_operand:DI 0 "register_operand" "")
19007	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
19008		    (match_operand:QI 2 "immediate_operand" "")
19009		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19010  ""
19011{
19012 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19013   DONE;
19014 else
19015   FAIL;
19016})
19017
19018(define_expand "strlenqi_1"
19019  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19020	      (use (reg:SI DIRFLAG_REG))
19021	      (clobber (match_operand 1 "register_operand" ""))
19022	      (clobber (reg:CC FLAGS_REG))])]
19023  ""
19024  "")
19025
19026(define_insn "*strlenqi_1"
19027  [(set (match_operand:SI 0 "register_operand" "=&c")
19028	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19029		    (match_operand:QI 2 "register_operand" "a")
19030		    (match_operand:SI 3 "immediate_operand" "i")
19031		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19032   (use (reg:SI DIRFLAG_REG))
19033   (clobber (match_operand:SI 1 "register_operand" "=D"))
19034   (clobber (reg:CC FLAGS_REG))]
19035  "!TARGET_64BIT"
19036  "repnz{\;| }scasb"
19037  [(set_attr "type" "str")
19038   (set_attr "mode" "QI")
19039   (set_attr "prefix_rep" "1")])
19040
19041(define_insn "*strlenqi_rex_1"
19042  [(set (match_operand:DI 0 "register_operand" "=&c")
19043	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19044		    (match_operand:QI 2 "register_operand" "a")
19045		    (match_operand:DI 3 "immediate_operand" "i")
19046		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19047   (use (reg:SI DIRFLAG_REG))
19048   (clobber (match_operand:DI 1 "register_operand" "=D"))
19049   (clobber (reg:CC FLAGS_REG))]
19050  "TARGET_64BIT"
19051  "repnz{\;| }scasb"
19052  [(set_attr "type" "str")
19053   (set_attr "mode" "QI")
19054   (set_attr "prefix_rep" "1")])
19055
19056;; Peephole optimizations to clean up after cmpstrn*.  This should be
19057;; handled in combine, but it is not currently up to the task.
19058;; When used for their truth value, the cmpstrn* expanders generate
19059;; code like this:
19060;;
19061;;   repz cmpsb
19062;;   seta 	%al
19063;;   setb 	%dl
19064;;   cmpb 	%al, %dl
19065;;   jcc	label
19066;;
19067;; The intermediate three instructions are unnecessary.
19068
19069;; This one handles cmpstrn*_nz_1...
19070(define_peephole2
19071  [(parallel[
19072     (set (reg:CC FLAGS_REG)
19073	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19074		      (mem:BLK (match_operand 5 "register_operand" ""))))
19075     (use (match_operand 6 "register_operand" ""))
19076     (use (match_operand:SI 3 "immediate_operand" ""))
19077     (use (reg:SI DIRFLAG_REG))
19078     (clobber (match_operand 0 "register_operand" ""))
19079     (clobber (match_operand 1 "register_operand" ""))
19080     (clobber (match_operand 2 "register_operand" ""))])
19081   (set (match_operand:QI 7 "register_operand" "")
19082	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19083   (set (match_operand:QI 8 "register_operand" "")
19084	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19085   (set (reg FLAGS_REG)
19086	(compare (match_dup 7) (match_dup 8)))
19087  ]
19088  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19089  [(parallel[
19090     (set (reg:CC FLAGS_REG)
19091	  (compare:CC (mem:BLK (match_dup 4))
19092		      (mem:BLK (match_dup 5))))
19093     (use (match_dup 6))
19094     (use (match_dup 3))
19095     (use (reg:SI DIRFLAG_REG))
19096     (clobber (match_dup 0))
19097     (clobber (match_dup 1))
19098     (clobber (match_dup 2))])]
19099  "")
19100
19101;; ...and this one handles cmpstrn*_1.
19102(define_peephole2
19103  [(parallel[
19104     (set (reg:CC FLAGS_REG)
19105	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19106			       (const_int 0))
19107	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19108		        (mem:BLK (match_operand 5 "register_operand" "")))
19109	    (const_int 0)))
19110     (use (match_operand:SI 3 "immediate_operand" ""))
19111     (use (reg:CC FLAGS_REG))
19112     (use (reg:SI DIRFLAG_REG))
19113     (clobber (match_operand 0 "register_operand" ""))
19114     (clobber (match_operand 1 "register_operand" ""))
19115     (clobber (match_operand 2 "register_operand" ""))])
19116   (set (match_operand:QI 7 "register_operand" "")
19117	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19118   (set (match_operand:QI 8 "register_operand" "")
19119	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19120   (set (reg FLAGS_REG)
19121	(compare (match_dup 7) (match_dup 8)))
19122  ]
19123  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19124  [(parallel[
19125     (set (reg:CC FLAGS_REG)
19126	  (if_then_else:CC (ne (match_dup 6)
19127			       (const_int 0))
19128	    (compare:CC (mem:BLK (match_dup 4))
19129			(mem:BLK (match_dup 5)))
19130	    (const_int 0)))
19131     (use (match_dup 3))
19132     (use (reg:CC FLAGS_REG))
19133     (use (reg:SI DIRFLAG_REG))
19134     (clobber (match_dup 0))
19135     (clobber (match_dup 1))
19136     (clobber (match_dup 2))])]
19137  "")
19138
19139
19140
19141;; Conditional move instructions.
19142
19143(define_expand "movdicc"
19144  [(set (match_operand:DI 0 "register_operand" "")
19145	(if_then_else:DI (match_operand 1 "comparison_operator" "")
19146			 (match_operand:DI 2 "general_operand" "")
19147			 (match_operand:DI 3 "general_operand" "")))]
19148  "TARGET_64BIT"
19149  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19150
19151(define_insn "x86_movdicc_0_m1_rex64"
19152  [(set (match_operand:DI 0 "register_operand" "=r")
19153	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19154	  (const_int -1)
19155	  (const_int 0)))
19156   (clobber (reg:CC FLAGS_REG))]
19157  "TARGET_64BIT"
19158  "sbb{q}\t%0, %0"
19159  ; Since we don't have the proper number of operands for an alu insn,
19160  ; fill in all the blanks.
19161  [(set_attr "type" "alu")
19162   (set_attr "pent_pair" "pu")
19163   (set_attr "memory" "none")
19164   (set_attr "imm_disp" "false")
19165   (set_attr "mode" "DI")
19166   (set_attr "length_immediate" "0")])
19167
19168(define_insn "*movdicc_c_rex64"
19169  [(set (match_operand:DI 0 "register_operand" "=r,r")
19170	(if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
19171				[(reg FLAGS_REG) (const_int 0)])
19172		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19173		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19174  "TARGET_64BIT && TARGET_CMOVE
19175   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19176  "@
19177   cmov%O2%C1\t{%2, %0|%0, %2}
19178   cmov%O2%c1\t{%3, %0|%0, %3}"
19179  [(set_attr "type" "icmov")
19180   (set_attr "mode" "DI")])
19181
19182(define_expand "movsicc"
19183  [(set (match_operand:SI 0 "register_operand" "")
19184	(if_then_else:SI (match_operand 1 "comparison_operator" "")
19185			 (match_operand:SI 2 "general_operand" "")
19186			 (match_operand:SI 3 "general_operand" "")))]
19187  ""
19188  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19189
19190;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19191;; the register first winds up with `sbbl $0,reg', which is also weird.
19192;; So just document what we're doing explicitly.
19193
19194(define_insn "x86_movsicc_0_m1"
19195  [(set (match_operand:SI 0 "register_operand" "=r")
19196	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19197	  (const_int -1)
19198	  (const_int 0)))
19199   (clobber (reg:CC FLAGS_REG))]
19200  ""
19201  "sbb{l}\t%0, %0"
19202  ; Since we don't have the proper number of operands for an alu insn,
19203  ; fill in all the blanks.
19204  [(set_attr "type" "alu")
19205   (set_attr "pent_pair" "pu")
19206   (set_attr "memory" "none")
19207   (set_attr "imm_disp" "false")
19208   (set_attr "mode" "SI")
19209   (set_attr "length_immediate" "0")])
19210
19211(define_insn "*movsicc_noc"
19212  [(set (match_operand:SI 0 "register_operand" "=r,r")
19213	(if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
19214				[(reg FLAGS_REG) (const_int 0)])
19215		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19216		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19217  "TARGET_CMOVE
19218   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19219  "@
19220   cmov%O2%C1\t{%2, %0|%0, %2}
19221   cmov%O2%c1\t{%3, %0|%0, %3}"
19222  [(set_attr "type" "icmov")
19223   (set_attr "mode" "SI")])
19224
19225(define_expand "movhicc"
19226  [(set (match_operand:HI 0 "register_operand" "")
19227	(if_then_else:HI (match_operand 1 "comparison_operator" "")
19228			 (match_operand:HI 2 "general_operand" "")
19229			 (match_operand:HI 3 "general_operand" "")))]
19230  "TARGET_HIMODE_MATH"
19231  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19232
19233(define_insn "*movhicc_noc"
19234  [(set (match_operand:HI 0 "register_operand" "=r,r")
19235	(if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
19236				[(reg FLAGS_REG) (const_int 0)])
19237		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19238		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19239  "TARGET_CMOVE
19240   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19241  "@
19242   cmov%O2%C1\t{%2, %0|%0, %2}
19243   cmov%O2%c1\t{%3, %0|%0, %3}"
19244  [(set_attr "type" "icmov")
19245   (set_attr "mode" "HI")])
19246
19247(define_expand "movqicc"
19248  [(set (match_operand:QI 0 "register_operand" "")
19249	(if_then_else:QI (match_operand 1 "comparison_operator" "")
19250			 (match_operand:QI 2 "general_operand" "")
19251			 (match_operand:QI 3 "general_operand" "")))]
19252  "TARGET_QIMODE_MATH"
19253  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19254
19255(define_insn_and_split "*movqicc_noc"
19256  [(set (match_operand:QI 0 "register_operand" "=r,r")
19257	(if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
19258				[(match_operand 4 "flags_reg_operand" "")
19259				 (const_int 0)])
19260		      (match_operand:QI 2 "register_operand" "r,0")
19261		      (match_operand:QI 3 "register_operand" "0,r")))]
19262  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19263  "#"
19264  "&& reload_completed"
19265  [(set (match_dup 0)
19266	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19267		      (match_dup 2)
19268		      (match_dup 3)))]
19269  "operands[0] = gen_lowpart (SImode, operands[0]);
19270   operands[2] = gen_lowpart (SImode, operands[2]);
19271   operands[3] = gen_lowpart (SImode, operands[3]);"
19272  [(set_attr "type" "icmov")
19273   (set_attr "mode" "SI")])
19274
19275(define_expand "movsfcc"
19276  [(set (match_operand:SF 0 "register_operand" "")
19277	(if_then_else:SF (match_operand 1 "comparison_operator" "")
19278			 (match_operand:SF 2 "register_operand" "")
19279			 (match_operand:SF 3 "register_operand" "")))]
19280  "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19281  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19282
19283(define_insn "*movsfcc_1_387"
19284  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19285	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
19286				[(reg FLAGS_REG) (const_int 0)])
19287		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19288		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19289  "TARGET_80387 && TARGET_CMOVE
19290   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19291  "@
19292   fcmov%F1\t{%2, %0|%0, %2}
19293   fcmov%f1\t{%3, %0|%0, %3}
19294   cmov%O2%C1\t{%2, %0|%0, %2}
19295   cmov%O2%c1\t{%3, %0|%0, %3}"
19296  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19297   (set_attr "mode" "SF,SF,SI,SI")])
19298
19299(define_expand "movdfcc"
19300  [(set (match_operand:DF 0 "register_operand" "")
19301	(if_then_else:DF (match_operand 1 "comparison_operator" "")
19302			 (match_operand:DF 2 "register_operand" "")
19303			 (match_operand:DF 3 "register_operand" "")))]
19304  "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19305  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19306
19307(define_insn "*movdfcc_1"
19308  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19309	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19310				[(reg FLAGS_REG) (const_int 0)])
19311		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19312		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19313  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19314   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19315  "@
19316   fcmov%F1\t{%2, %0|%0, %2}
19317   fcmov%f1\t{%3, %0|%0, %3}
19318   #
19319   #"
19320  [(set_attr "type" "fcmov,fcmov,multi,multi")
19321   (set_attr "mode" "DF")])
19322
19323(define_insn "*movdfcc_1_rex64"
19324  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19325	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19326				[(reg FLAGS_REG) (const_int 0)])
19327		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19328		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19329  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19330   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19331  "@
19332   fcmov%F1\t{%2, %0|%0, %2}
19333   fcmov%f1\t{%3, %0|%0, %3}
19334   cmov%O2%C1\t{%2, %0|%0, %2}
19335   cmov%O2%c1\t{%3, %0|%0, %3}"
19336  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19337   (set_attr "mode" "DF")])
19338
19339(define_split
19340  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19341	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
19342				[(match_operand 4 "flags_reg_operand" "")
19343				 (const_int 0)])
19344		      (match_operand:DF 2 "nonimmediate_operand" "")
19345		      (match_operand:DF 3 "nonimmediate_operand" "")))]
19346  "!TARGET_64BIT && reload_completed"
19347  [(set (match_dup 2)
19348	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19349		      (match_dup 5)
19350		      (match_dup 7)))
19351   (set (match_dup 3)
19352	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19353		      (match_dup 6)
19354		      (match_dup 8)))]
19355  "split_di (operands+2, 1, operands+5, operands+6);
19356   split_di (operands+3, 1, operands+7, operands+8);
19357   split_di (operands, 1, operands+2, operands+3);")
19358
19359(define_expand "movxfcc"
19360  [(set (match_operand:XF 0 "register_operand" "")
19361	(if_then_else:XF (match_operand 1 "comparison_operator" "")
19362			 (match_operand:XF 2 "register_operand" "")
19363			 (match_operand:XF 3 "register_operand" "")))]
19364  "TARGET_80387 && TARGET_CMOVE"
19365  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19366
19367(define_insn "*movxfcc_1"
19368  [(set (match_operand:XF 0 "register_operand" "=f,f")
19369	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
19370				[(reg FLAGS_REG) (const_int 0)])
19371		      (match_operand:XF 2 "register_operand" "f,0")
19372		      (match_operand:XF 3 "register_operand" "0,f")))]
19373  "TARGET_80387 && TARGET_CMOVE"
19374  "@
19375   fcmov%F1\t{%2, %0|%0, %2}
19376   fcmov%f1\t{%3, %0|%0, %3}"
19377  [(set_attr "type" "fcmov")
19378   (set_attr "mode" "XF")])
19379
19380;; These versions of the min/max patterns are intentionally ignorant of
19381;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19382;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19383;; are undefined in this condition, we're certain this is correct.
19384
19385(define_insn "sminsf3"
19386  [(set (match_operand:SF 0 "register_operand" "=x")
19387	(smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19388		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19389  "TARGET_SSE_MATH"
19390  "minss\t{%2, %0|%0, %2}"
19391  [(set_attr "type" "sseadd")
19392   (set_attr "mode" "SF")])
19393
19394(define_insn "smaxsf3"
19395  [(set (match_operand:SF 0 "register_operand" "=x")
19396	(smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19397		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19398  "TARGET_SSE_MATH"
19399  "maxss\t{%2, %0|%0, %2}"
19400  [(set_attr "type" "sseadd")
19401   (set_attr "mode" "SF")])
19402
19403(define_insn "smindf3"
19404  [(set (match_operand:DF 0 "register_operand" "=x")
19405	(smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19406		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19407  "TARGET_SSE2 && TARGET_SSE_MATH"
19408  "minsd\t{%2, %0|%0, %2}"
19409  [(set_attr "type" "sseadd")
19410   (set_attr "mode" "DF")])
19411
19412(define_insn "smaxdf3"
19413  [(set (match_operand:DF 0 "register_operand" "=x")
19414	(smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19415		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19416  "TARGET_SSE2 && TARGET_SSE_MATH"
19417  "maxsd\t{%2, %0|%0, %2}"
19418  [(set_attr "type" "sseadd")
19419   (set_attr "mode" "DF")])
19420
19421;; These versions of the min/max patterns implement exactly the operations
19422;;   min = (op1 < op2 ? op1 : op2)
19423;;   max = (!(op1 < op2) ? op1 : op2)
19424;; Their operands are not commutative, and thus they may be used in the
19425;; presence of -0.0 and NaN.
19426
19427(define_insn "*ieee_sminsf3"
19428  [(set (match_operand:SF 0 "register_operand" "=x")
19429	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19430		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19431		   UNSPEC_IEEE_MIN))]
19432  "TARGET_SSE_MATH"
19433  "minss\t{%2, %0|%0, %2}"
19434  [(set_attr "type" "sseadd")
19435   (set_attr "mode" "SF")])
19436
19437(define_insn "*ieee_smaxsf3"
19438  [(set (match_operand:SF 0 "register_operand" "=x")
19439	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19440		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19441		   UNSPEC_IEEE_MAX))]
19442  "TARGET_SSE_MATH"
19443  "maxss\t{%2, %0|%0, %2}"
19444  [(set_attr "type" "sseadd")
19445   (set_attr "mode" "SF")])
19446
19447(define_insn "*ieee_smindf3"
19448  [(set (match_operand:DF 0 "register_operand" "=x")
19449	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19450		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19451		   UNSPEC_IEEE_MIN))]
19452  "TARGET_SSE2 && TARGET_SSE_MATH"
19453  "minsd\t{%2, %0|%0, %2}"
19454  [(set_attr "type" "sseadd")
19455   (set_attr "mode" "DF")])
19456
19457(define_insn "*ieee_smaxdf3"
19458  [(set (match_operand:DF 0 "register_operand" "=x")
19459	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19460		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19461		   UNSPEC_IEEE_MAX))]
19462  "TARGET_SSE2 && TARGET_SSE_MATH"
19463  "maxsd\t{%2, %0|%0, %2}"
19464  [(set_attr "type" "sseadd")
19465   (set_attr "mode" "DF")])
19466
19467;; Make two stack loads independent:
19468;;   fld aa              fld aa
19469;;   fld %st(0)     ->   fld bb
19470;;   fmul bb             fmul %st(1), %st
19471;;
19472;; Actually we only match the last two instructions for simplicity.
19473(define_peephole2
19474  [(set (match_operand 0 "fp_register_operand" "")
19475	(match_operand 1 "fp_register_operand" ""))
19476   (set (match_dup 0)
19477	(match_operator 2 "binary_fp_operator"
19478	   [(match_dup 0)
19479	    (match_operand 3 "memory_operand" "")]))]
19480  "REGNO (operands[0]) != REGNO (operands[1])"
19481  [(set (match_dup 0) (match_dup 3))
19482   (set (match_dup 0) (match_dup 4))]
19483
19484  ;; The % modifier is not operational anymore in peephole2's, so we have to
19485  ;; swap the operands manually in the case of addition and multiplication.
19486  "if (COMMUTATIVE_ARITH_P (operands[2]))
19487     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19488				 operands[0], operands[1]);
19489   else
19490     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19491				 operands[1], operands[0]);")
19492
19493;; Conditional addition patterns
19494(define_expand "addqicc"
19495  [(match_operand:QI 0 "register_operand" "")
19496   (match_operand 1 "comparison_operator" "")
19497   (match_operand:QI 2 "register_operand" "")
19498   (match_operand:QI 3 "const_int_operand" "")]
19499  ""
19500  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19501
19502(define_expand "addhicc"
19503  [(match_operand:HI 0 "register_operand" "")
19504   (match_operand 1 "comparison_operator" "")
19505   (match_operand:HI 2 "register_operand" "")
19506   (match_operand:HI 3 "const_int_operand" "")]
19507  ""
19508  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19509
19510(define_expand "addsicc"
19511  [(match_operand:SI 0 "register_operand" "")
19512   (match_operand 1 "comparison_operator" "")
19513   (match_operand:SI 2 "register_operand" "")
19514   (match_operand:SI 3 "const_int_operand" "")]
19515  ""
19516  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19517
19518(define_expand "adddicc"
19519  [(match_operand:DI 0 "register_operand" "")
19520   (match_operand 1 "comparison_operator" "")
19521   (match_operand:DI 2 "register_operand" "")
19522   (match_operand:DI 3 "const_int_operand" "")]
19523  "TARGET_64BIT"
19524  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19525
19526
19527;; Misc patterns (?)
19528
19529;; This pattern exists to put a dependency on all ebp-based memory accesses.
19530;; Otherwise there will be nothing to keep
19531;; 
19532;; [(set (reg ebp) (reg esp))]
19533;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19534;;  (clobber (eflags)]
19535;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19536;;
19537;; in proper program order.
19538(define_insn "pro_epilogue_adjust_stack_1"
19539  [(set (match_operand:SI 0 "register_operand" "=r,r")
19540	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
19541	         (match_operand:SI 2 "immediate_operand" "i,i")))
19542   (clobber (reg:CC FLAGS_REG))
19543   (clobber (mem:BLK (scratch)))]
19544  "!TARGET_64BIT"
19545{
19546  switch (get_attr_type (insn))
19547    {
19548    case TYPE_IMOV:
19549      return "mov{l}\t{%1, %0|%0, %1}";
19550
19551    case TYPE_ALU:
19552      if (GET_CODE (operands[2]) == CONST_INT
19553          && (INTVAL (operands[2]) == 128
19554	      || (INTVAL (operands[2]) < 0
19555	          && INTVAL (operands[2]) != -128)))
19556	{
19557	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19558	  return "sub{l}\t{%2, %0|%0, %2}";
19559	}
19560      return "add{l}\t{%2, %0|%0, %2}";
19561
19562    case TYPE_LEA:
19563      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19564      return "lea{l}\t{%a2, %0|%0, %a2}";
19565
19566    default:
19567      gcc_unreachable ();
19568    }
19569}
19570  [(set (attr "type")
19571	(cond [(eq_attr "alternative" "0")
19572		 (const_string "alu")
19573	       (match_operand:SI 2 "const0_operand" "")
19574		 (const_string "imov")
19575	      ]
19576	      (const_string "lea")))
19577   (set_attr "mode" "SI")])
19578
19579(define_insn "pro_epilogue_adjust_stack_rex64"
19580  [(set (match_operand:DI 0 "register_operand" "=r,r")
19581	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19582		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19583   (clobber (reg:CC FLAGS_REG))
19584   (clobber (mem:BLK (scratch)))]
19585  "TARGET_64BIT"
19586{
19587  switch (get_attr_type (insn))
19588    {
19589    case TYPE_IMOV:
19590      return "mov{q}\t{%1, %0|%0, %1}";
19591
19592    case TYPE_ALU:
19593      if (GET_CODE (operands[2]) == CONST_INT
19594	  /* Avoid overflows.  */
19595	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19596          && (INTVAL (operands[2]) == 128
19597	      || (INTVAL (operands[2]) < 0
19598	          && INTVAL (operands[2]) != -128)))
19599	{
19600	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19601	  return "sub{q}\t{%2, %0|%0, %2}";
19602	}
19603      return "add{q}\t{%2, %0|%0, %2}";
19604
19605    case TYPE_LEA:
19606      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19607      return "lea{q}\t{%a2, %0|%0, %a2}";
19608
19609    default:
19610      gcc_unreachable ();
19611    }
19612}
19613  [(set (attr "type")
19614	(cond [(eq_attr "alternative" "0")
19615		 (const_string "alu")
19616	       (match_operand:DI 2 "const0_operand" "")
19617		 (const_string "imov")
19618	      ]
19619	      (const_string "lea")))
19620   (set_attr "mode" "DI")])
19621
19622(define_insn "pro_epilogue_adjust_stack_rex64_2"
19623  [(set (match_operand:DI 0 "register_operand" "=r,r")
19624	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19625		 (match_operand:DI 3 "immediate_operand" "i,i")))
19626   (use (match_operand:DI 2 "register_operand" "r,r"))
19627   (clobber (reg:CC FLAGS_REG))
19628   (clobber (mem:BLK (scratch)))]
19629  "TARGET_64BIT"
19630{
19631  switch (get_attr_type (insn))
19632    {
19633    case TYPE_ALU:
19634      return "add{q}\t{%2, %0|%0, %2}";
19635
19636    case TYPE_LEA:
19637      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19638      return "lea{q}\t{%a2, %0|%0, %a2}";
19639
19640    default:
19641      gcc_unreachable ();
19642    }
19643}
19644  [(set_attr "type" "alu,lea")
19645   (set_attr "mode" "DI")])
19646
19647(define_expand "allocate_stack_worker"
19648  [(match_operand:SI 0 "register_operand" "")]
19649  "TARGET_STACK_PROBE"
19650{
19651  if (reload_completed)
19652    {
19653      if (TARGET_64BIT)
19654	emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19655      else
19656	emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19657    }
19658  else
19659    {
19660      if (TARGET_64BIT)
19661	emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19662      else
19663	emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19664    }
19665  DONE;
19666})
19667
19668(define_insn "allocate_stack_worker_1"
19669  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19670    UNSPECV_STACK_PROBE)
19671   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19672   (clobber (match_scratch:SI 1 "=0"))
19673   (clobber (reg:CC FLAGS_REG))]
19674  "!TARGET_64BIT && TARGET_STACK_PROBE"
19675  "call\t__alloca"
19676  [(set_attr "type" "multi")
19677   (set_attr "length" "5")])
19678
19679(define_expand "allocate_stack_worker_postreload"
19680  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19681				    UNSPECV_STACK_PROBE)
19682	      (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19683	      (clobber (match_dup 0))
19684	      (clobber (reg:CC FLAGS_REG))])]
19685  ""
19686  "")
19687
19688(define_insn "allocate_stack_worker_rex64"
19689  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19690    UNSPECV_STACK_PROBE)
19691   (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19692   (clobber (match_scratch:DI 1 "=0"))
19693   (clobber (reg:CC FLAGS_REG))]
19694  "TARGET_64BIT && TARGET_STACK_PROBE"
19695  "call\t__alloca"
19696  [(set_attr "type" "multi")
19697   (set_attr "length" "5")])
19698
19699(define_expand "allocate_stack_worker_rex64_postreload"
19700  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19701				    UNSPECV_STACK_PROBE)
19702	      (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19703	      (clobber (match_dup 0))
19704	      (clobber (reg:CC FLAGS_REG))])]
19705  ""
19706  "")
19707
19708(define_expand "allocate_stack"
19709  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19710		   (minus:SI (reg:SI SP_REG)
19711			     (match_operand:SI 1 "general_operand" "")))
19712	      (clobber (reg:CC FLAGS_REG))])
19713   (parallel [(set (reg:SI SP_REG)
19714		   (minus:SI (reg:SI SP_REG) (match_dup 1)))
19715	      (clobber (reg:CC FLAGS_REG))])]
19716  "TARGET_STACK_PROBE"
19717{
19718#ifdef CHECK_STACK_LIMIT
19719  if (GET_CODE (operands[1]) == CONST_INT
19720      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19721    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19722			   operands[1]));
19723  else 
19724#endif
19725    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19726							    operands[1])));
19727
19728  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19729  DONE;
19730})
19731
19732(define_expand "builtin_setjmp_receiver"
19733  [(label_ref (match_operand 0 "" ""))]
19734  "!TARGET_64BIT && flag_pic"
19735{
19736  if (TARGET_MACHO)
19737    {
19738      rtx xops[3];
19739      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19740      rtx label_rtx = gen_label_rtx ();
19741      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19742      xops[0] = xops[1] = picreg;
19743      xops[2] = gen_rtx_CONST (SImode,
19744	          gen_rtx_MINUS (SImode,
19745		    gen_rtx_LABEL_REF (SImode, label_rtx),
19746		    gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19747      ix86_expand_binary_operator (MINUS, SImode, xops);
19748    }
19749  else
19750    emit_insn (gen_set_got (pic_offset_table_rtx));
19751  DONE;
19752})
19753
19754;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19755
19756(define_split
19757  [(set (match_operand 0 "register_operand" "")
19758	(match_operator 3 "promotable_binary_operator"
19759	   [(match_operand 1 "register_operand" "")
19760	    (match_operand 2 "aligned_operand" "")]))
19761   (clobber (reg:CC FLAGS_REG))]
19762  "! TARGET_PARTIAL_REG_STALL && reload_completed
19763   && ((GET_MODE (operands[0]) == HImode 
19764	&& ((!optimize_size && !TARGET_FAST_PREFIX)
19765            /* ??? next two lines just !satisfies_constraint_K (...) */
19766	    || GET_CODE (operands[2]) != CONST_INT
19767	    || satisfies_constraint_K (operands[2])))
19768       || (GET_MODE (operands[0]) == QImode 
19769	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19770  [(parallel [(set (match_dup 0)
19771		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19772	      (clobber (reg:CC FLAGS_REG))])]
19773  "operands[0] = gen_lowpart (SImode, operands[0]);
19774   operands[1] = gen_lowpart (SImode, operands[1]);
19775   if (GET_CODE (operands[3]) != ASHIFT)
19776     operands[2] = gen_lowpart (SImode, operands[2]);
19777   PUT_MODE (operands[3], SImode);")
19778
19779; Promote the QImode tests, as i386 has encoding of the AND
19780; instruction with 32-bit sign-extended immediate and thus the
19781; instruction size is unchanged, except in the %eax case for
19782; which it is increased by one byte, hence the ! optimize_size.
19783(define_split
19784  [(set (match_operand 0 "flags_reg_operand" "")
19785	(match_operator 2 "compare_operator"
19786	  [(and (match_operand 3 "aligned_operand" "")
19787		(match_operand 4 "const_int_operand" ""))
19788	   (const_int 0)]))
19789   (set (match_operand 1 "register_operand" "")
19790	(and (match_dup 3) (match_dup 4)))]
19791  "! TARGET_PARTIAL_REG_STALL && reload_completed
19792   /* Ensure that the operand will remain sign-extended immediate.  */
19793   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19794   && ! optimize_size
19795   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19796       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19797  [(parallel [(set (match_dup 0)
19798		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19799			            (const_int 0)]))
19800	      (set (match_dup 1)
19801		   (and:SI (match_dup 3) (match_dup 4)))])]
19802{
19803  operands[4]
19804    = gen_int_mode (INTVAL (operands[4])
19805		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19806  operands[1] = gen_lowpart (SImode, operands[1]);
19807  operands[3] = gen_lowpart (SImode, operands[3]);
19808})
19809
19810; Don't promote the QImode tests, as i386 doesn't have encoding of
19811; the TEST instruction with 32-bit sign-extended immediate and thus
19812; the instruction size would at least double, which is not what we
19813; want even with ! optimize_size.
19814(define_split
19815  [(set (match_operand 0 "flags_reg_operand" "")
19816	(match_operator 1 "compare_operator"
19817	  [(and (match_operand:HI 2 "aligned_operand" "")
19818		(match_operand:HI 3 "const_int_operand" ""))
19819	   (const_int 0)]))]
19820  "! TARGET_PARTIAL_REG_STALL && reload_completed
19821   /* Ensure that the operand will remain sign-extended immediate.  */
19822   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19823   && ! TARGET_FAST_PREFIX
19824   && ! optimize_size"
19825  [(set (match_dup 0)
19826	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19827		         (const_int 0)]))]
19828{
19829  operands[3]
19830    = gen_int_mode (INTVAL (operands[3])
19831		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19832  operands[2] = gen_lowpart (SImode, operands[2]);
19833})
19834
19835(define_split
19836  [(set (match_operand 0 "register_operand" "")
19837	(neg (match_operand 1 "register_operand" "")))
19838   (clobber (reg:CC FLAGS_REG))]
19839  "! TARGET_PARTIAL_REG_STALL && reload_completed
19840   && (GET_MODE (operands[0]) == HImode
19841       || (GET_MODE (operands[0]) == QImode 
19842	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19843  [(parallel [(set (match_dup 0)
19844		   (neg:SI (match_dup 1)))
19845	      (clobber (reg:CC FLAGS_REG))])]
19846  "operands[0] = gen_lowpart (SImode, operands[0]);
19847   operands[1] = gen_lowpart (SImode, operands[1]);")
19848
19849(define_split
19850  [(set (match_operand 0 "register_operand" "")
19851	(not (match_operand 1 "register_operand" "")))]
19852  "! TARGET_PARTIAL_REG_STALL && reload_completed
19853   && (GET_MODE (operands[0]) == HImode
19854       || (GET_MODE (operands[0]) == QImode 
19855	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19856  [(set (match_dup 0)
19857	(not:SI (match_dup 1)))]
19858  "operands[0] = gen_lowpart (SImode, operands[0]);
19859   operands[1] = gen_lowpart (SImode, operands[1]);")
19860
19861(define_split 
19862  [(set (match_operand 0 "register_operand" "")
19863	(if_then_else (match_operator 1 "comparison_operator" 
19864				[(reg FLAGS_REG) (const_int 0)])
19865		      (match_operand 2 "register_operand" "")
19866		      (match_operand 3 "register_operand" "")))]
19867  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19868   && (GET_MODE (operands[0]) == HImode
19869       || (GET_MODE (operands[0]) == QImode 
19870	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19871  [(set (match_dup 0)
19872	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19873  "operands[0] = gen_lowpart (SImode, operands[0]);
19874   operands[2] = gen_lowpart (SImode, operands[2]);
19875   operands[3] = gen_lowpart (SImode, operands[3]);")
19876			
19877
19878;; RTL Peephole optimizations, run before sched2.  These primarily look to
19879;; transform a complex memory operation into two memory to register operations.
19880
19881;; Don't push memory operands
19882(define_peephole2
19883  [(set (match_operand:SI 0 "push_operand" "")
19884	(match_operand:SI 1 "memory_operand" ""))
19885   (match_scratch:SI 2 "r")]
19886  "!optimize_size && !TARGET_PUSH_MEMORY
19887   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19888  [(set (match_dup 2) (match_dup 1))
19889   (set (match_dup 0) (match_dup 2))]
19890  "")
19891
19892(define_peephole2
19893  [(set (match_operand:DI 0 "push_operand" "")
19894	(match_operand:DI 1 "memory_operand" ""))
19895   (match_scratch:DI 2 "r")]
19896  "!optimize_size && !TARGET_PUSH_MEMORY
19897   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19898  [(set (match_dup 2) (match_dup 1))
19899   (set (match_dup 0) (match_dup 2))]
19900  "")
19901
19902;; We need to handle SFmode only, because DFmode and XFmode is split to
19903;; SImode pushes.
19904(define_peephole2
19905  [(set (match_operand:SF 0 "push_operand" "")
19906	(match_operand:SF 1 "memory_operand" ""))
19907   (match_scratch:SF 2 "r")]
19908  "!optimize_size && !TARGET_PUSH_MEMORY
19909   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19910  [(set (match_dup 2) (match_dup 1))
19911   (set (match_dup 0) (match_dup 2))]
19912  "")
19913
19914(define_peephole2
19915  [(set (match_operand:HI 0 "push_operand" "")
19916	(match_operand:HI 1 "memory_operand" ""))
19917   (match_scratch:HI 2 "r")]
19918  "!optimize_size && !TARGET_PUSH_MEMORY
19919   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920  [(set (match_dup 2) (match_dup 1))
19921   (set (match_dup 0) (match_dup 2))]
19922  "")
19923
19924(define_peephole2
19925  [(set (match_operand:QI 0 "push_operand" "")
19926	(match_operand:QI 1 "memory_operand" ""))
19927   (match_scratch:QI 2 "q")]
19928  "!optimize_size && !TARGET_PUSH_MEMORY
19929   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19930  [(set (match_dup 2) (match_dup 1))
19931   (set (match_dup 0) (match_dup 2))]
19932  "")
19933
19934;; Don't move an immediate directly to memory when the instruction
19935;; gets too big.
19936(define_peephole2
19937  [(match_scratch:SI 1 "r")
19938   (set (match_operand:SI 0 "memory_operand" "")
19939        (const_int 0))]
19940  "! optimize_size
19941   && ! TARGET_USE_MOV0
19942   && TARGET_SPLIT_LONG_MOVES
19943   && get_attr_length (insn) >= ix86_cost->large_insn
19944   && peep2_regno_dead_p (0, FLAGS_REG)"
19945  [(parallel [(set (match_dup 1) (const_int 0))
19946	      (clobber (reg:CC FLAGS_REG))])
19947   (set (match_dup 0) (match_dup 1))]
19948  "")
19949
19950(define_peephole2
19951  [(match_scratch:HI 1 "r")
19952   (set (match_operand:HI 0 "memory_operand" "")
19953        (const_int 0))]
19954  "! optimize_size
19955   && ! TARGET_USE_MOV0
19956   && TARGET_SPLIT_LONG_MOVES
19957   && get_attr_length (insn) >= ix86_cost->large_insn
19958   && peep2_regno_dead_p (0, FLAGS_REG)"
19959  [(parallel [(set (match_dup 2) (const_int 0))
19960	      (clobber (reg:CC FLAGS_REG))])
19961   (set (match_dup 0) (match_dup 1))]
19962  "operands[2] = gen_lowpart (SImode, operands[1]);")
19963
19964(define_peephole2
19965  [(match_scratch:QI 1 "q")
19966   (set (match_operand:QI 0 "memory_operand" "")
19967        (const_int 0))]
19968  "! optimize_size
19969   && ! TARGET_USE_MOV0
19970   && TARGET_SPLIT_LONG_MOVES
19971   && get_attr_length (insn) >= ix86_cost->large_insn
19972   && peep2_regno_dead_p (0, FLAGS_REG)"
19973  [(parallel [(set (match_dup 2) (const_int 0))
19974	      (clobber (reg:CC FLAGS_REG))])
19975   (set (match_dup 0) (match_dup 1))]
19976  "operands[2] = gen_lowpart (SImode, operands[1]);")
19977
19978(define_peephole2
19979  [(match_scratch:SI 2 "r")
19980   (set (match_operand:SI 0 "memory_operand" "")
19981        (match_operand:SI 1 "immediate_operand" ""))]
19982  "! optimize_size
19983   && get_attr_length (insn) >= ix86_cost->large_insn
19984   && TARGET_SPLIT_LONG_MOVES"
19985  [(set (match_dup 2) (match_dup 1))
19986   (set (match_dup 0) (match_dup 2))]
19987  "")
19988
19989(define_peephole2
19990  [(match_scratch:HI 2 "r")
19991   (set (match_operand:HI 0 "memory_operand" "")
19992        (match_operand:HI 1 "immediate_operand" ""))]
19993  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19994  && TARGET_SPLIT_LONG_MOVES"
19995  [(set (match_dup 2) (match_dup 1))
19996   (set (match_dup 0) (match_dup 2))]
19997  "")
19998
19999(define_peephole2
20000  [(match_scratch:QI 2 "q")
20001   (set (match_operand:QI 0 "memory_operand" "")
20002        (match_operand:QI 1 "immediate_operand" ""))]
20003  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20004  && TARGET_SPLIT_LONG_MOVES"
20005  [(set (match_dup 2) (match_dup 1))
20006   (set (match_dup 0) (match_dup 2))]
20007  "")
20008
20009;; Don't compare memory with zero, load and use a test instead.
20010(define_peephole2
20011  [(set (match_operand 0 "flags_reg_operand" "")
20012 	(match_operator 1 "compare_operator"
20013	  [(match_operand:SI 2 "memory_operand" "")
20014	   (const_int 0)]))
20015   (match_scratch:SI 3 "r")]
20016  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20017  [(set (match_dup 3) (match_dup 2))
20018   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20019  "")
20020
20021;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
20022;; Don't split NOTs with a displacement operand, because resulting XOR
20023;; will not be pairable anyway.
20024;;
20025;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20026;; represented using a modRM byte.  The XOR replacement is long decoded,
20027;; so this split helps here as well.
20028;;
20029;; Note: Can't do this as a regular split because we can't get proper
20030;; lifetime information then.
20031
20032(define_peephole2
20033  [(set (match_operand:SI 0 "nonimmediate_operand" "")
20034	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20035  "!optimize_size
20036   && peep2_regno_dead_p (0, FLAGS_REG)
20037   && ((TARGET_PENTIUM 
20038        && (GET_CODE (operands[0]) != MEM
20039            || !memory_displacement_operand (operands[0], SImode)))
20040       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20041  [(parallel [(set (match_dup 0)
20042		   (xor:SI (match_dup 1) (const_int -1)))
20043	      (clobber (reg:CC FLAGS_REG))])]
20044  "")
20045
20046(define_peephole2
20047  [(set (match_operand:HI 0 "nonimmediate_operand" "")
20048	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20049  "!optimize_size
20050   && peep2_regno_dead_p (0, FLAGS_REG)
20051   && ((TARGET_PENTIUM 
20052        && (GET_CODE (operands[0]) != MEM
20053            || !memory_displacement_operand (operands[0], HImode)))
20054       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20055  [(parallel [(set (match_dup 0)
20056		   (xor:HI (match_dup 1) (const_int -1)))
20057	      (clobber (reg:CC FLAGS_REG))])]
20058  "")
20059
20060(define_peephole2
20061  [(set (match_operand:QI 0 "nonimmediate_operand" "")
20062	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20063  "!optimize_size
20064   && peep2_regno_dead_p (0, FLAGS_REG)
20065   && ((TARGET_PENTIUM 
20066        && (GET_CODE (operands[0]) != MEM
20067            || !memory_displacement_operand (operands[0], QImode)))
20068       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20069  [(parallel [(set (match_dup 0)
20070		   (xor:QI (match_dup 1) (const_int -1)))
20071	      (clobber (reg:CC FLAGS_REG))])]
20072  "")
20073
20074;; Non pairable "test imm, reg" instructions can be translated to
20075;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20076;; byte opcode instead of two, have a short form for byte operands),
20077;; so do it for other CPUs as well.  Given that the value was dead,
20078;; this should not create any new dependencies.  Pass on the sub-word
20079;; versions if we're concerned about partial register stalls.
20080
20081(define_peephole2
20082  [(set (match_operand 0 "flags_reg_operand" "")
20083	(match_operator 1 "compare_operator"
20084	  [(and:SI (match_operand:SI 2 "register_operand" "")
20085		   (match_operand:SI 3 "immediate_operand" ""))
20086	   (const_int 0)]))]
20087  "ix86_match_ccmode (insn, CCNOmode)
20088   && (true_regnum (operands[2]) != 0
20089       || satisfies_constraint_K (operands[3]))
20090   && peep2_reg_dead_p (1, operands[2])"
20091  [(parallel
20092     [(set (match_dup 0)
20093	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20094		            (const_int 0)]))
20095      (set (match_dup 2)
20096	   (and:SI (match_dup 2) (match_dup 3)))])]
20097  "")
20098
20099;; We don't need to handle HImode case, because it will be promoted to SImode
20100;; on ! TARGET_PARTIAL_REG_STALL
20101
20102(define_peephole2
20103  [(set (match_operand 0 "flags_reg_operand" "")
20104	(match_operator 1 "compare_operator"
20105	  [(and:QI (match_operand:QI 2 "register_operand" "")
20106		   (match_operand:QI 3 "immediate_operand" ""))
20107	   (const_int 0)]))]
20108  "! TARGET_PARTIAL_REG_STALL
20109   && ix86_match_ccmode (insn, CCNOmode)
20110   && true_regnum (operands[2]) != 0
20111   && peep2_reg_dead_p (1, operands[2])"
20112  [(parallel
20113     [(set (match_dup 0)
20114	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20115		            (const_int 0)]))
20116      (set (match_dup 2)
20117	   (and:QI (match_dup 2) (match_dup 3)))])]
20118  "")
20119
20120(define_peephole2
20121  [(set (match_operand 0 "flags_reg_operand" "")
20122	(match_operator 1 "compare_operator"
20123	  [(and:SI
20124	     (zero_extract:SI
20125	       (match_operand 2 "ext_register_operand" "")
20126	       (const_int 8)
20127	       (const_int 8))
20128	     (match_operand 3 "const_int_operand" ""))
20129	   (const_int 0)]))]
20130  "! TARGET_PARTIAL_REG_STALL
20131   && ix86_match_ccmode (insn, CCNOmode)
20132   && true_regnum (operands[2]) != 0
20133   && peep2_reg_dead_p (1, operands[2])"
20134  [(parallel [(set (match_dup 0)
20135		   (match_op_dup 1
20136		     [(and:SI
20137			(zero_extract:SI
20138			  (match_dup 2)
20139			  (const_int 8)
20140			  (const_int 8))
20141			(match_dup 3))
20142		      (const_int 0)]))
20143	      (set (zero_extract:SI (match_dup 2)
20144				    (const_int 8)
20145				    (const_int 8))
20146		   (and:SI 
20147		     (zero_extract:SI
20148		       (match_dup 2)
20149		       (const_int 8)
20150		       (const_int 8))
20151		     (match_dup 3)))])]
20152  "")
20153
20154;; Don't do logical operations with memory inputs.
20155(define_peephole2
20156  [(match_scratch:SI 2 "r")
20157   (parallel [(set (match_operand:SI 0 "register_operand" "")
20158                   (match_operator:SI 3 "arith_or_logical_operator"
20159                     [(match_dup 0)
20160                      (match_operand:SI 1 "memory_operand" "")]))
20161              (clobber (reg:CC FLAGS_REG))])]
20162  "! optimize_size && ! TARGET_READ_MODIFY"
20163  [(set (match_dup 2) (match_dup 1))
20164   (parallel [(set (match_dup 0)
20165                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20166              (clobber (reg:CC FLAGS_REG))])]
20167  "")
20168
20169(define_peephole2
20170  [(match_scratch:SI 2 "r")
20171   (parallel [(set (match_operand:SI 0 "register_operand" "")
20172                   (match_operator:SI 3 "arith_or_logical_operator"
20173                     [(match_operand:SI 1 "memory_operand" "")
20174                      (match_dup 0)]))
20175              (clobber (reg:CC FLAGS_REG))])]
20176  "! optimize_size && ! TARGET_READ_MODIFY"
20177  [(set (match_dup 2) (match_dup 1))
20178   (parallel [(set (match_dup 0)
20179                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20180              (clobber (reg:CC FLAGS_REG))])]
20181  "")
20182
20183; Don't do logical operations with memory outputs
20184;
20185; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20186; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20187; the same decoder scheduling characteristics as the original.
20188
20189(define_peephole2
20190  [(match_scratch:SI 2 "r")
20191   (parallel [(set (match_operand:SI 0 "memory_operand" "")
20192                   (match_operator:SI 3 "arith_or_logical_operator"
20193                     [(match_dup 0)
20194                      (match_operand:SI 1 "nonmemory_operand" "")]))
20195              (clobber (reg:CC FLAGS_REG))])]
20196  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20197  [(set (match_dup 2) (match_dup 0))
20198   (parallel [(set (match_dup 2)
20199                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20200              (clobber (reg:CC FLAGS_REG))])
20201   (set (match_dup 0) (match_dup 2))]
20202  "")
20203
20204(define_peephole2
20205  [(match_scratch:SI 2 "r")
20206   (parallel [(set (match_operand:SI 0 "memory_operand" "")
20207                   (match_operator:SI 3 "arith_or_logical_operator"
20208                     [(match_operand:SI 1 "nonmemory_operand" "")
20209                      (match_dup 0)]))
20210              (clobber (reg:CC FLAGS_REG))])]
20211  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20212  [(set (match_dup 2) (match_dup 0))
20213   (parallel [(set (match_dup 2)
20214                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20215              (clobber (reg:CC FLAGS_REG))])
20216   (set (match_dup 0) (match_dup 2))]
20217  "")
20218
20219;; Attempt to always use XOR for zeroing registers.
20220(define_peephole2
20221  [(set (match_operand 0 "register_operand" "")
20222	(match_operand 1 "const0_operand" ""))]
20223  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20224   && (! TARGET_USE_MOV0 || optimize_size)
20225   && GENERAL_REG_P (operands[0])
20226   && peep2_regno_dead_p (0, FLAGS_REG)"
20227  [(parallel [(set (match_dup 0) (const_int 0))
20228	      (clobber (reg:CC FLAGS_REG))])]
20229{
20230  operands[0] = gen_lowpart (word_mode, operands[0]);
20231})
20232
20233(define_peephole2
20234  [(set (strict_low_part (match_operand 0 "register_operand" ""))
20235	(const_int 0))]
20236  "(GET_MODE (operands[0]) == QImode
20237    || GET_MODE (operands[0]) == HImode)
20238   && (! TARGET_USE_MOV0 || optimize_size)
20239   && peep2_regno_dead_p (0, FLAGS_REG)"
20240  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20241	      (clobber (reg:CC FLAGS_REG))])])
20242
20243;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20244(define_peephole2
20245  [(set (match_operand 0 "register_operand" "")
20246	(const_int -1))]
20247  "(GET_MODE (operands[0]) == HImode
20248    || GET_MODE (operands[0]) == SImode 
20249    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20250   && (optimize_size || TARGET_PENTIUM)
20251   && peep2_regno_dead_p (0, FLAGS_REG)"
20252  [(parallel [(set (match_dup 0) (const_int -1))
20253	      (clobber (reg:CC FLAGS_REG))])]
20254  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20255			      operands[0]);")
20256
20257;; Attempt to convert simple leas to adds. These can be created by
20258;; move expanders.
20259(define_peephole2
20260  [(set (match_operand:SI 0 "register_operand" "")
20261  	(plus:SI (match_dup 0)
20262		 (match_operand:SI 1 "nonmemory_operand" "")))]
20263  "peep2_regno_dead_p (0, FLAGS_REG)"
20264  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20265	      (clobber (reg:CC FLAGS_REG))])]
20266  "")
20267
20268(define_peephole2
20269  [(set (match_operand:SI 0 "register_operand" "")
20270  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20271			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20272  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20273  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20274	      (clobber (reg:CC FLAGS_REG))])]
20275  "operands[2] = gen_lowpart (SImode, operands[2]);")
20276
20277(define_peephole2
20278  [(set (match_operand:DI 0 "register_operand" "")
20279  	(plus:DI (match_dup 0)
20280		 (match_operand:DI 1 "x86_64_general_operand" "")))]
20281  "peep2_regno_dead_p (0, FLAGS_REG)"
20282  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20283	      (clobber (reg:CC FLAGS_REG))])]
20284  "")
20285
20286(define_peephole2
20287  [(set (match_operand:SI 0 "register_operand" "")
20288  	(mult:SI (match_dup 0)
20289		 (match_operand:SI 1 "const_int_operand" "")))]
20290  "exact_log2 (INTVAL (operands[1])) >= 0
20291   && peep2_regno_dead_p (0, FLAGS_REG)"
20292  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20293	      (clobber (reg:CC FLAGS_REG))])]
20294  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20295
20296(define_peephole2
20297  [(set (match_operand:DI 0 "register_operand" "")
20298  	(mult:DI (match_dup 0)
20299		 (match_operand:DI 1 "const_int_operand" "")))]
20300  "exact_log2 (INTVAL (operands[1])) >= 0
20301   && peep2_regno_dead_p (0, FLAGS_REG)"
20302  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20303	      (clobber (reg:CC FLAGS_REG))])]
20304  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20305
20306(define_peephole2
20307  [(set (match_operand:SI 0 "register_operand" "")
20308  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20309		   (match_operand:DI 2 "const_int_operand" "")) 0))]
20310  "exact_log2 (INTVAL (operands[2])) >= 0
20311   && REGNO (operands[0]) == REGNO (operands[1])
20312   && peep2_regno_dead_p (0, FLAGS_REG)"
20313  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20314	      (clobber (reg:CC FLAGS_REG))])]
20315  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20316
20317;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20318;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20319;; many CPUs it is also faster, since special hardware to avoid esp
20320;; dependencies is present.
20321
20322;; While some of these conversions may be done using splitters, we use peepholes
20323;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20324
20325;; Convert prologue esp subtractions to push.
20326;; We need register to push.  In order to keep verify_flow_info happy we have
20327;; two choices
20328;; - use scratch and clobber it in order to avoid dependencies
20329;; - use already live register
20330;; We can't use the second way right now, since there is no reliable way how to
20331;; verify that given register is live.  First choice will also most likely in
20332;; fewer dependencies.  On the place of esp adjustments it is very likely that
20333;; call clobbered registers are dead.  We may want to use base pointer as an
20334;; alternative when no register is available later.
20335
20336(define_peephole2
20337  [(match_scratch:SI 0 "r")
20338   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20339	      (clobber (reg:CC FLAGS_REG))
20340	      (clobber (mem:BLK (scratch)))])]
20341  "optimize_size || !TARGET_SUB_ESP_4"
20342  [(clobber (match_dup 0))
20343   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20344	      (clobber (mem:BLK (scratch)))])])
20345
20346(define_peephole2
20347  [(match_scratch:SI 0 "r")
20348   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20349	      (clobber (reg:CC FLAGS_REG))
20350	      (clobber (mem:BLK (scratch)))])]
20351  "optimize_size || !TARGET_SUB_ESP_8"
20352  [(clobber (match_dup 0))
20353   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20354   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20355	      (clobber (mem:BLK (scratch)))])])
20356
20357;; Convert esp subtractions to push.
20358(define_peephole2
20359  [(match_scratch:SI 0 "r")
20360   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20361	      (clobber (reg:CC FLAGS_REG))])]
20362  "optimize_size || !TARGET_SUB_ESP_4"
20363  [(clobber (match_dup 0))
20364   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20365
20366(define_peephole2
20367  [(match_scratch:SI 0 "r")
20368   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20369	      (clobber (reg:CC FLAGS_REG))])]
20370  "optimize_size || !TARGET_SUB_ESP_8"
20371  [(clobber (match_dup 0))
20372   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20373   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20374
20375;; Convert epilogue deallocator to pop.
20376(define_peephole2
20377  [(match_scratch:SI 0 "r")
20378   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20379	      (clobber (reg:CC FLAGS_REG))
20380	      (clobber (mem:BLK (scratch)))])]
20381  "optimize_size || !TARGET_ADD_ESP_4"
20382  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20383	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20384	      (clobber (mem:BLK (scratch)))])]
20385  "")
20386
20387;; Two pops case is tricky, since pop causes dependency on destination register.
20388;; We use two registers if available.
20389(define_peephole2
20390  [(match_scratch:SI 0 "r")
20391   (match_scratch:SI 1 "r")
20392   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20393	      (clobber (reg:CC FLAGS_REG))
20394	      (clobber (mem:BLK (scratch)))])]
20395  "optimize_size || !TARGET_ADD_ESP_8"
20396  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20397	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20398	      (clobber (mem:BLK (scratch)))])
20399   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20400	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20401  "")
20402
20403(define_peephole2
20404  [(match_scratch:SI 0 "r")
20405   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20406	      (clobber (reg:CC FLAGS_REG))
20407	      (clobber (mem:BLK (scratch)))])]
20408  "optimize_size"
20409  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20410	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20411	      (clobber (mem:BLK (scratch)))])
20412   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20414  "")
20415
20416;; Convert esp additions to pop.
20417(define_peephole2
20418  [(match_scratch:SI 0 "r")
20419   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20420	      (clobber (reg:CC FLAGS_REG))])]
20421  ""
20422  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20423	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20424  "")
20425
20426;; Two pops case is tricky, since pop causes dependency on destination register.
20427;; We use two registers if available.
20428(define_peephole2
20429  [(match_scratch:SI 0 "r")
20430   (match_scratch:SI 1 "r")
20431   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20432	      (clobber (reg:CC FLAGS_REG))])]
20433  ""
20434  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20435	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20436   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20437	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20438  "")
20439
20440(define_peephole2
20441  [(match_scratch:SI 0 "r")
20442   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20443	      (clobber (reg:CC FLAGS_REG))])]
20444  "optimize_size"
20445  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20446	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20447   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20448	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20449  "")
20450
20451;; Convert compares with 1 to shorter inc/dec operations when CF is not
20452;; required and register dies.  Similarly for 128 to plus -128.
20453(define_peephole2
20454  [(set (match_operand 0 "flags_reg_operand" "")
20455	(match_operator 1 "compare_operator"
20456	  [(match_operand 2 "register_operand" "")
20457	   (match_operand 3 "const_int_operand" "")]))]
20458  "(INTVAL (operands[3]) == -1
20459    || INTVAL (operands[3]) == 1
20460    || INTVAL (operands[3]) == 128)
20461   && ix86_match_ccmode (insn, CCGCmode)
20462   && peep2_reg_dead_p (1, operands[2])"
20463  [(parallel [(set (match_dup 0)
20464		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20465	      (clobber (match_dup 2))])]
20466  "")
20467
20468(define_peephole2
20469  [(match_scratch:DI 0 "r")
20470   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20471	      (clobber (reg:CC FLAGS_REG))
20472	      (clobber (mem:BLK (scratch)))])]
20473  "optimize_size || !TARGET_SUB_ESP_4"
20474  [(clobber (match_dup 0))
20475   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20476	      (clobber (mem:BLK (scratch)))])])
20477
20478(define_peephole2
20479  [(match_scratch:DI 0 "r")
20480   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20481	      (clobber (reg:CC FLAGS_REG))
20482	      (clobber (mem:BLK (scratch)))])]
20483  "optimize_size || !TARGET_SUB_ESP_8"
20484  [(clobber (match_dup 0))
20485   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20486   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20487	      (clobber (mem:BLK (scratch)))])])
20488
20489;; Convert esp subtractions to push.
20490(define_peephole2
20491  [(match_scratch:DI 0 "r")
20492   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20493	      (clobber (reg:CC FLAGS_REG))])]
20494  "optimize_size || !TARGET_SUB_ESP_4"
20495  [(clobber (match_dup 0))
20496   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20497
20498(define_peephole2
20499  [(match_scratch:DI 0 "r")
20500   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20501	      (clobber (reg:CC FLAGS_REG))])]
20502  "optimize_size || !TARGET_SUB_ESP_8"
20503  [(clobber (match_dup 0))
20504   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20505   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20506
20507;; Convert epilogue deallocator to pop.
20508(define_peephole2
20509  [(match_scratch:DI 0 "r")
20510   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20511	      (clobber (reg:CC FLAGS_REG))
20512	      (clobber (mem:BLK (scratch)))])]
20513  "optimize_size || !TARGET_ADD_ESP_4"
20514  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20515	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20516	      (clobber (mem:BLK (scratch)))])]
20517  "")
20518
20519;; Two pops case is tricky, since pop causes dependency on destination register.
20520;; We use two registers if available.
20521(define_peephole2
20522  [(match_scratch:DI 0 "r")
20523   (match_scratch:DI 1 "r")
20524   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20525	      (clobber (reg:CC FLAGS_REG))
20526	      (clobber (mem:BLK (scratch)))])]
20527  "optimize_size || !TARGET_ADD_ESP_8"
20528  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20529	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20530	      (clobber (mem:BLK (scratch)))])
20531   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20532	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20533  "")
20534
20535(define_peephole2
20536  [(match_scratch:DI 0 "r")
20537   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20538	      (clobber (reg:CC FLAGS_REG))
20539	      (clobber (mem:BLK (scratch)))])]
20540  "optimize_size"
20541  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20542	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20543	      (clobber (mem:BLK (scratch)))])
20544   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20546  "")
20547
20548;; Convert esp additions to pop.
20549(define_peephole2
20550  [(match_scratch:DI 0 "r")
20551   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20552	      (clobber (reg:CC FLAGS_REG))])]
20553  ""
20554  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20555	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20556  "")
20557
20558;; Two pops case is tricky, since pop causes dependency on destination register.
20559;; We use two registers if available.
20560(define_peephole2
20561  [(match_scratch:DI 0 "r")
20562   (match_scratch:DI 1 "r")
20563   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20564	      (clobber (reg:CC FLAGS_REG))])]
20565  ""
20566  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20567	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20568   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20569	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20570  "")
20571
20572(define_peephole2
20573  [(match_scratch:DI 0 "r")
20574   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20575	      (clobber (reg:CC FLAGS_REG))])]
20576  "optimize_size"
20577  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20578	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20579   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20580	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20581  "")
20582
20583;; Convert imul by three, five and nine into lea
20584(define_peephole2
20585  [(parallel
20586    [(set (match_operand:SI 0 "register_operand" "")
20587	  (mult:SI (match_operand:SI 1 "register_operand" "")
20588		   (match_operand:SI 2 "const_int_operand" "")))
20589     (clobber (reg:CC FLAGS_REG))])]
20590  "INTVAL (operands[2]) == 3
20591   || INTVAL (operands[2]) == 5
20592   || INTVAL (operands[2]) == 9"
20593  [(set (match_dup 0)
20594        (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20595                 (match_dup 1)))]
20596  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20597
20598(define_peephole2
20599  [(parallel
20600    [(set (match_operand:SI 0 "register_operand" "")
20601          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20602                   (match_operand:SI 2 "const_int_operand" "")))
20603     (clobber (reg:CC FLAGS_REG))])]
20604  "!optimize_size 
20605   && (INTVAL (operands[2]) == 3
20606       || INTVAL (operands[2]) == 5
20607       || INTVAL (operands[2]) == 9)"
20608  [(set (match_dup 0) (match_dup 1))
20609   (set (match_dup 0)
20610        (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20611                 (match_dup 0)))]
20612  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20613
20614(define_peephole2
20615  [(parallel
20616    [(set (match_operand:DI 0 "register_operand" "")
20617	  (mult:DI (match_operand:DI 1 "register_operand" "")
20618		   (match_operand:DI 2 "const_int_operand" "")))
20619     (clobber (reg:CC FLAGS_REG))])]
20620  "TARGET_64BIT
20621   && (INTVAL (operands[2]) == 3
20622       || INTVAL (operands[2]) == 5
20623       || INTVAL (operands[2]) == 9)"
20624  [(set (match_dup 0)
20625        (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20626                 (match_dup 1)))]
20627  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20628
20629(define_peephole2
20630  [(parallel
20631    [(set (match_operand:DI 0 "register_operand" "")
20632          (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20633                   (match_operand:DI 2 "const_int_operand" "")))
20634     (clobber (reg:CC FLAGS_REG))])]
20635  "TARGET_64BIT
20636   && !optimize_size 
20637   && (INTVAL (operands[2]) == 3
20638       || INTVAL (operands[2]) == 5
20639       || INTVAL (operands[2]) == 9)"
20640  [(set (match_dup 0) (match_dup 1))
20641   (set (match_dup 0)
20642        (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20643                 (match_dup 0)))]
20644  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20645
20646;; Imul $32bit_imm, mem, reg is vector decoded, while
20647;; imul $32bit_imm, reg, reg is direct decoded.
20648(define_peephole2
20649  [(match_scratch:DI 3 "r")
20650   (parallel [(set (match_operand:DI 0 "register_operand" "")
20651		   (mult:DI (match_operand:DI 1 "memory_operand" "")
20652			    (match_operand:DI 2 "immediate_operand" "")))
20653	      (clobber (reg:CC FLAGS_REG))])]
20654  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20655   && !satisfies_constraint_K (operands[2])"
20656  [(set (match_dup 3) (match_dup 1))
20657   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20658	      (clobber (reg:CC FLAGS_REG))])]
20659"")
20660
20661(define_peephole2
20662  [(match_scratch:SI 3 "r")
20663   (parallel [(set (match_operand:SI 0 "register_operand" "")
20664		   (mult:SI (match_operand:SI 1 "memory_operand" "")
20665			    (match_operand:SI 2 "immediate_operand" "")))
20666	      (clobber (reg:CC FLAGS_REG))])]
20667  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20668   && !satisfies_constraint_K (operands[2])"
20669  [(set (match_dup 3) (match_dup 1))
20670   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20671	      (clobber (reg:CC FLAGS_REG))])]
20672"")
20673
20674(define_peephole2
20675  [(match_scratch:SI 3 "r")
20676   (parallel [(set (match_operand:DI 0 "register_operand" "")
20677		   (zero_extend:DI
20678		     (mult:SI (match_operand:SI 1 "memory_operand" "")
20679			      (match_operand:SI 2 "immediate_operand" ""))))
20680	      (clobber (reg:CC FLAGS_REG))])]
20681  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20682   && !satisfies_constraint_K (operands[2])"
20683  [(set (match_dup 3) (match_dup 1))
20684   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20685	      (clobber (reg:CC FLAGS_REG))])]
20686"")
20687
20688;; imul $8/16bit_imm, regmem, reg is vector decoded.
20689;; Convert it into imul reg, reg
20690;; It would be better to force assembler to encode instruction using long
20691;; immediate, but there is apparently no way to do so.
20692(define_peephole2
20693  [(parallel [(set (match_operand:DI 0 "register_operand" "")
20694		   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20695			    (match_operand:DI 2 "const_int_operand" "")))
20696	      (clobber (reg:CC FLAGS_REG))])
20697   (match_scratch:DI 3 "r")]
20698  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20699   && satisfies_constraint_K (operands[2])"
20700  [(set (match_dup 3) (match_dup 2))
20701   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20702	      (clobber (reg:CC FLAGS_REG))])]
20703{
20704  if (!rtx_equal_p (operands[0], operands[1]))
20705    emit_move_insn (operands[0], operands[1]);
20706})
20707
20708(define_peephole2
20709  [(parallel [(set (match_operand:SI 0 "register_operand" "")
20710		   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20711			    (match_operand:SI 2 "const_int_operand" "")))
20712	      (clobber (reg:CC FLAGS_REG))])
20713   (match_scratch:SI 3 "r")]
20714  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20715   && satisfies_constraint_K (operands[2])"
20716  [(set (match_dup 3) (match_dup 2))
20717   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20718	      (clobber (reg:CC FLAGS_REG))])]
20719{
20720  if (!rtx_equal_p (operands[0], operands[1]))
20721    emit_move_insn (operands[0], operands[1]);
20722})
20723
20724(define_peephole2
20725  [(parallel [(set (match_operand:HI 0 "register_operand" "")
20726		   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20727			    (match_operand:HI 2 "immediate_operand" "")))
20728	      (clobber (reg:CC FLAGS_REG))])
20729   (match_scratch:HI 3 "r")]
20730  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20731  [(set (match_dup 3) (match_dup 2))
20732   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20733	      (clobber (reg:CC FLAGS_REG))])]
20734{
20735  if (!rtx_equal_p (operands[0], operands[1]))
20736    emit_move_insn (operands[0], operands[1]);
20737})
20738
20739;; After splitting up read-modify operations, array accesses with memory
20740;; operands might end up in form:
20741;;  sall    $2, %eax
20742;;  movl    4(%esp), %edx
20743;;  addl    %edx, %eax
20744;; instead of pre-splitting:
20745;;  sall    $2, %eax
20746;;  addl    4(%esp), %eax
20747;; Turn it into:
20748;;  movl    4(%esp), %edx
20749;;  leal    (%edx,%eax,4), %eax
20750
20751(define_peephole2
20752  [(parallel [(set (match_operand 0 "register_operand" "")
20753		   (ashift (match_operand 1 "register_operand" "")
20754			   (match_operand 2 "const_int_operand" "")))
20755	       (clobber (reg:CC FLAGS_REG))])
20756   (set (match_operand 3 "register_operand")
20757        (match_operand 4 "x86_64_general_operand" ""))
20758   (parallel [(set (match_operand 5 "register_operand" "")
20759		   (plus (match_operand 6 "register_operand" "")
20760			 (match_operand 7 "register_operand" "")))
20761		   (clobber (reg:CC FLAGS_REG))])]
20762  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20763   /* Validate MODE for lea.  */
20764   && ((!TARGET_PARTIAL_REG_STALL
20765	&& (GET_MODE (operands[0]) == QImode
20766	    || GET_MODE (operands[0]) == HImode))
20767       || GET_MODE (operands[0]) == SImode 
20768       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20769   /* We reorder load and the shift.  */
20770   && !rtx_equal_p (operands[1], operands[3])
20771   && !reg_overlap_mentioned_p (operands[0], operands[4])
20772   /* Last PLUS must consist of operand 0 and 3.  */
20773   && !rtx_equal_p (operands[0], operands[3])
20774   && (rtx_equal_p (operands[3], operands[6])
20775       || rtx_equal_p (operands[3], operands[7]))
20776   && (rtx_equal_p (operands[0], operands[6])
20777       || rtx_equal_p (operands[0], operands[7]))
20778   /* The intermediate operand 0 must die or be same as output.  */
20779   && (rtx_equal_p (operands[0], operands[5])
20780       || peep2_reg_dead_p (3, operands[0]))"
20781  [(set (match_dup 3) (match_dup 4))
20782   (set (match_dup 0) (match_dup 1))]
20783{
20784  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20785  int scale = 1 << INTVAL (operands[2]);
20786  rtx index = gen_lowpart (Pmode, operands[1]);
20787  rtx base = gen_lowpart (Pmode, operands[3]);
20788  rtx dest = gen_lowpart (mode, operands[5]);
20789
20790  operands[1] = gen_rtx_PLUS (Pmode, base,
20791  			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20792  if (mode != Pmode)
20793    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20794  operands[0] = dest;
20795})
20796
20797;; Call-value patterns last so that the wildcard operand does not
20798;; disrupt insn-recog's switch tables.
20799
20800(define_insn "*call_value_pop_0"
20801  [(set (match_operand 0 "" "")
20802	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20803	      (match_operand:SI 2 "" "")))
20804   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20805			    (match_operand:SI 3 "immediate_operand" "")))]
20806  "!TARGET_64BIT"
20807{
20808  if (SIBLING_CALL_P (insn))
20809    return "jmp\t%P1";
20810  else
20811    return "call\t%P1";
20812}
20813  [(set_attr "type" "callv")])
20814
20815(define_insn "*call_value_pop_1"
20816  [(set (match_operand 0 "" "")
20817	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20818	      (match_operand:SI 2 "" "")))
20819   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20820			    (match_operand:SI 3 "immediate_operand" "i")))]
20821  "!TARGET_64BIT"
20822{
20823  if (constant_call_address_operand (operands[1], Pmode))
20824    {
20825      if (SIBLING_CALL_P (insn))
20826	return "jmp\t%P1";
20827      else
20828	return "call\t%P1";
20829    }
20830  if (SIBLING_CALL_P (insn))
20831    return "jmp\t%A1";
20832  else
20833    return "call\t%A1";
20834}
20835  [(set_attr "type" "callv")])
20836
20837(define_insn "*call_value_0"
20838  [(set (match_operand 0 "" "")
20839	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20840	      (match_operand:SI 2 "" "")))]
20841  "!TARGET_64BIT"
20842{
20843  if (SIBLING_CALL_P (insn))
20844    return "jmp\t%P1";
20845  else
20846    return "call\t%P1";
20847}
20848  [(set_attr "type" "callv")])
20849
20850(define_insn "*call_value_0_rex64"
20851  [(set (match_operand 0 "" "")
20852	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20853	      (match_operand:DI 2 "const_int_operand" "")))]
20854  "TARGET_64BIT"
20855{
20856  if (SIBLING_CALL_P (insn))
20857    return "jmp\t%P1";
20858  else
20859    return "call\t%P1";
20860}
20861  [(set_attr "type" "callv")])
20862
20863(define_insn "*call_value_1"
20864  [(set (match_operand 0 "" "")
20865	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20866	      (match_operand:SI 2 "" "")))]
20867  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20868{
20869  if (constant_call_address_operand (operands[1], Pmode))
20870    return "call\t%P1";
20871  return "call\t%A1";
20872}
20873  [(set_attr "type" "callv")])
20874
20875(define_insn "*sibcall_value_1"
20876  [(set (match_operand 0 "" "")
20877	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20878	      (match_operand:SI 2 "" "")))]
20879  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20880{
20881  if (constant_call_address_operand (operands[1], Pmode))
20882    return "jmp\t%P1";
20883  return "jmp\t%A1";
20884}
20885  [(set_attr "type" "callv")])
20886
20887(define_insn "*call_value_1_rex64"
20888  [(set (match_operand 0 "" "")
20889	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20890	      (match_operand:DI 2 "" "")))]
20891  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20892{
20893  if (constant_call_address_operand (operands[1], Pmode))
20894    return "call\t%P1";
20895  return "call\t%A1";
20896}
20897  [(set_attr "type" "callv")])
20898
20899(define_insn "*sibcall_value_1_rex64"
20900  [(set (match_operand 0 "" "")
20901	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20902	      (match_operand:DI 2 "" "")))]
20903  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20904  "jmp\t%P1"
20905  [(set_attr "type" "callv")])
20906
20907(define_insn "*sibcall_value_1_rex64_v"
20908  [(set (match_operand 0 "" "")
20909	(call (mem:QI (reg:DI 40))
20910	      (match_operand:DI 1 "" "")))]
20911  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20912  "jmp\t*%%r11"
20913  [(set_attr "type" "callv")])
20914
20915;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20916;; That, however, is usually mapped by the OS to SIGSEGV, which is often 
20917;; caught for use by garbage collectors and the like.  Using an insn that
20918;; maps to SIGILL makes it more likely the program will rightfully die.
20919;; Keeping with tradition, "6" is in honor of #UD.
20920(define_insn "trap"
20921  [(trap_if (const_int 1) (const_int 6))]
20922  ""
20923  { return ASM_SHORT "0x0b0f"; }
20924  [(set_attr "length" "2")])
20925
20926(define_expand "sse_prologue_save"
20927  [(parallel [(set (match_operand:BLK 0 "" "")
20928		   (unspec:BLK [(reg:DI 21)
20929				(reg:DI 22)
20930				(reg:DI 23)
20931				(reg:DI 24)
20932				(reg:DI 25)
20933				(reg:DI 26)
20934				(reg:DI 27)
20935				(reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20936	      (use (match_operand:DI 1 "register_operand" ""))
20937	      (use (match_operand:DI 2 "immediate_operand" ""))
20938	      (use (label_ref:DI (match_operand 3 "" "")))])]
20939  "TARGET_64BIT"
20940  "")
20941
20942(define_insn "*sse_prologue_save_insn"
20943  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20944			  (match_operand:DI 4 "const_int_operand" "n")))
20945	(unspec:BLK [(reg:DI 21)
20946		     (reg:DI 22)
20947		     (reg:DI 23)
20948		     (reg:DI 24)
20949		     (reg:DI 25)
20950		     (reg:DI 26)
20951		     (reg:DI 27)
20952		     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20953   (use (match_operand:DI 1 "register_operand" "r"))
20954   (use (match_operand:DI 2 "const_int_operand" "i"))
20955   (use (label_ref:DI (match_operand 3 "" "X")))]
20956  "TARGET_64BIT
20957   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20958   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20959  "*
20960{
20961  int i;
20962  operands[0] = gen_rtx_MEM (Pmode,
20963			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20964  output_asm_insn (\"jmp\\t%A1\", operands);
20965  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20966    {
20967      operands[4] = adjust_address (operands[0], DImode, i*16);
20968      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20969      PUT_MODE (operands[4], TImode);
20970      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20971        output_asm_insn (\"rex\", operands);
20972      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20973    }
20974  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20975			     CODE_LABEL_NUMBER (operands[3]));
20976  RET;
20977}
20978  "
20979  [(set_attr "type" "other")
20980   (set_attr "length_immediate" "0")
20981   (set_attr "length_address" "0")
20982   (set_attr "length" "135")
20983   (set_attr "memory" "store")
20984   (set_attr "modrm" "0")
20985   (set_attr "mode" "DI")])
20986
20987(define_expand "prefetch"
20988  [(prefetch (match_operand 0 "address_operand" "")
20989	     (match_operand:SI 1 "const_int_operand" "")
20990	     (match_operand:SI 2 "const_int_operand" ""))]
20991  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20992{
20993  int rw = INTVAL (operands[1]);
20994  int locality = INTVAL (operands[2]);
20995
20996  gcc_assert (rw == 0 || rw == 1);
20997  gcc_assert (locality >= 0 && locality <= 3);
20998  gcc_assert (GET_MODE (operands[0]) == Pmode
20999	      || GET_MODE (operands[0]) == VOIDmode);
21000
21001  /* Use 3dNOW prefetch in case we are asking for write prefetch not
21002     supported by SSE counterpart or the SSE prefetch is not available
21003     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21004     of locality.  */
21005  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21006    operands[2] = GEN_INT (3);
21007  else
21008    operands[1] = const0_rtx;
21009})
21010
21011(define_insn "*prefetch_sse"
21012  [(prefetch (match_operand:SI 0 "address_operand" "p")
21013	     (const_int 0)
21014	     (match_operand:SI 1 "const_int_operand" ""))]
21015  "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21016{
21017  static const char * const patterns[4] = {
21018   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21019  };
21020
21021  int locality = INTVAL (operands[1]);
21022  gcc_assert (locality >= 0 && locality <= 3);
21023
21024  return patterns[locality];  
21025}
21026  [(set_attr "type" "sse")
21027   (set_attr "memory" "none")])
21028
21029(define_insn "*prefetch_sse_rex"
21030  [(prefetch (match_operand:DI 0 "address_operand" "p")
21031	     (const_int 0)
21032	     (match_operand:SI 1 "const_int_operand" ""))]
21033  "TARGET_PREFETCH_SSE && TARGET_64BIT"
21034{
21035  static const char * const patterns[4] = {
21036   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21037  };
21038
21039  int locality = INTVAL (operands[1]);
21040  gcc_assert (locality >= 0 && locality <= 3);
21041
21042  return patterns[locality];  
21043}
21044  [(set_attr "type" "sse")
21045   (set_attr "memory" "none")])
21046
21047(define_insn "*prefetch_3dnow"
21048  [(prefetch (match_operand:SI 0 "address_operand" "p")
21049	     (match_operand:SI 1 "const_int_operand" "n")
21050	     (const_int 3))]
21051  "TARGET_3DNOW && !TARGET_64BIT"
21052{
21053  if (INTVAL (operands[1]) == 0)
21054    return "prefetch\t%a0";
21055  else
21056    return "prefetchw\t%a0";
21057}
21058  [(set_attr "type" "mmx")
21059   (set_attr "memory" "none")])
21060
21061(define_insn "*prefetch_3dnow_rex"
21062  [(prefetch (match_operand:DI 0 "address_operand" "p")
21063	     (match_operand:SI 1 "const_int_operand" "n")
21064	     (const_int 3))]
21065  "TARGET_3DNOW && TARGET_64BIT"
21066{
21067  if (INTVAL (operands[1]) == 0)
21068    return "prefetch\t%a0";
21069  else
21070    return "prefetchw\t%a0";
21071}
21072  [(set_attr "type" "mmx")
21073   (set_attr "memory" "none")])
21074
21075(define_expand "stack_protect_set"
21076  [(match_operand 0 "memory_operand" "")
21077   (match_operand 1 "memory_operand" "")]
21078  ""
21079{
21080#ifdef TARGET_THREAD_SSP_OFFSET
21081  if (TARGET_64BIT)
21082    emit_insn (gen_stack_tls_protect_set_di (operands[0],
21083					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21084  else
21085    emit_insn (gen_stack_tls_protect_set_si (operands[0],
21086					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21087#else
21088  if (TARGET_64BIT)
21089    emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21090  else
21091    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21092#endif
21093  DONE;
21094})
21095
21096(define_insn "stack_protect_set_si"
21097  [(set (match_operand:SI 0 "memory_operand" "=m")
21098	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21099   (set (match_scratch:SI 2 "=&r") (const_int 0))
21100   (clobber (reg:CC FLAGS_REG))]
21101  ""
21102  "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21103  [(set_attr "type" "multi")])
21104
21105(define_insn "stack_protect_set_di"
21106  [(set (match_operand:DI 0 "memory_operand" "=m")
21107	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21108   (set (match_scratch:DI 2 "=&r") (const_int 0))
21109   (clobber (reg:CC FLAGS_REG))]
21110  "TARGET_64BIT"
21111  "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21112  [(set_attr "type" "multi")])
21113
21114(define_insn "stack_tls_protect_set_si"
21115  [(set (match_operand:SI 0 "memory_operand" "=m")
21116	(unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21117   (set (match_scratch:SI 2 "=&r") (const_int 0))
21118   (clobber (reg:CC FLAGS_REG))]
21119  ""
21120  "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21121  [(set_attr "type" "multi")])
21122
21123(define_insn "stack_tls_protect_set_di"
21124  [(set (match_operand:DI 0 "memory_operand" "=m")
21125	(unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21126   (set (match_scratch:DI 2 "=&r") (const_int 0))
21127   (clobber (reg:CC FLAGS_REG))]
21128  "TARGET_64BIT"
21129  {
21130     /* The kernel uses a different segment register for performance reasons; a
21131        system call would not have to trash the userspace segment register,
21132        which would be expensive */
21133     if (ix86_cmodel != CM_KERNEL)
21134        return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21135     else
21136        return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21137  }
21138  [(set_attr "type" "multi")])
21139
21140(define_expand "stack_protect_test"
21141  [(match_operand 0 "memory_operand" "")
21142   (match_operand 1 "memory_operand" "")
21143   (match_operand 2 "" "")]
21144  ""
21145{
21146  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21147  ix86_compare_op0 = operands[0];
21148  ix86_compare_op1 = operands[1];
21149  ix86_compare_emitted = flags;
21150
21151#ifdef TARGET_THREAD_SSP_OFFSET
21152  if (TARGET_64BIT)
21153    emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21154					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21155  else
21156    emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21157					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21158#else
21159  if (TARGET_64BIT)
21160    emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21161  else
21162    emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21163#endif
21164  emit_jump_insn (gen_beq (operands[2]));
21165  DONE;
21166})
21167
21168(define_insn "stack_protect_test_si"
21169  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21170	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21171		     (match_operand:SI 2 "memory_operand" "m")]
21172		    UNSPEC_SP_TEST))
21173   (clobber (match_scratch:SI 3 "=&r"))]
21174  ""
21175  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21176  [(set_attr "type" "multi")])
21177
21178(define_insn "stack_protect_test_di"
21179  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21180	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21181		     (match_operand:DI 2 "memory_operand" "m")]
21182		    UNSPEC_SP_TEST))
21183   (clobber (match_scratch:DI 3 "=&r"))]
21184  "TARGET_64BIT"
21185  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21186  [(set_attr "type" "multi")])
21187
21188(define_insn "stack_tls_protect_test_si"
21189  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21190	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21191		     (match_operand:SI 2 "const_int_operand" "i")]
21192		    UNSPEC_SP_TLS_TEST))
21193   (clobber (match_scratch:SI 3 "=r"))]
21194  ""
21195  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21196  [(set_attr "type" "multi")])
21197
21198(define_insn "stack_tls_protect_test_di"
21199  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21200	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21201		     (match_operand:DI 2 "const_int_operand" "i")]
21202		    UNSPEC_SP_TLS_TEST))
21203   (clobber (match_scratch:DI 3 "=r"))]
21204  "TARGET_64BIT"
21205  {
21206     /* The kernel uses a different segment register for performance reasons; a
21207        system call would not have to trash the userspace segment register,
21208        which would be expensive */
21209     if (ix86_cmodel != CM_KERNEL)
21210        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21211     else
21212        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21213  }
21214  [(set_attr "type" "multi")])
21215
21216(include "mmx.md")
21217(include "sse.md")
21218(include "sync.md")
21219