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_insn "bswapsi2"
14722  [(set (match_operand:SI 0 "register_operand" "=r")
14723	(bswap:SI (match_operand:SI 1 "register_operand" "0")))
14724   (clobber (reg:CC FLAGS_REG))]
14725  "TARGET_BSWAP"
14726  "bswap\t%k0"
14727  [(set_attr "prefix_0f" "1")
14728   (set_attr "length" "2")])
14729
14730(define_insn "bswapdi2"
14731  [(set (match_operand:DI 0 "register_operand" "=r")
14732	(bswap:DI (match_operand:DI 1 "register_operand" "0")))
14733   (clobber (reg:CC FLAGS_REG))]
14734  "TARGET_64BIT && TARGET_BSWAP"
14735  "bswap\t%0"
14736  [(set_attr "prefix_0f" "1")
14737   (set_attr "length" "3")])
14738
14739(define_expand "clzdi2"
14740  [(parallel
14741     [(set (match_operand:DI 0 "register_operand" "")
14742	   (minus:DI (const_int 63)
14743		     (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14744      (clobber (reg:CC FLAGS_REG))])
14745   (parallel
14746     [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14747      (clobber (reg:CC FLAGS_REG))])]
14748  "TARGET_64BIT"
14749{
14750  if (TARGET_ABM)
14751    {
14752      emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14753      DONE;
14754    }
14755})
14756
14757(define_insn "clzdi2_abm"
14758  [(set (match_operand:DI 0 "register_operand" "=r")
14759	(clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14760   (clobber (reg:CC FLAGS_REG))]
14761  "TARGET_64BIT && TARGET_ABM"
14762  "lzcnt{q}\t{%1, %0|%0, %1}"
14763  [(set_attr "prefix_rep" "1")
14764   (set_attr "type" "bitmanip")
14765   (set_attr "mode" "DI")])
14766
14767(define_insn "*bsr_rex64"
14768  [(set (match_operand:DI 0 "register_operand" "=r")
14769	(minus:DI (const_int 63)
14770		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14771   (clobber (reg:CC FLAGS_REG))]
14772  "TARGET_64BIT"
14773  "bsr{q}\t{%1, %0|%0, %1}"
14774  [(set_attr "prefix_0f" "1")
14775   (set_attr "mode" "DI")])
14776
14777(define_insn "popcountdi2"
14778  [(set (match_operand:DI 0 "register_operand" "=r")
14779	(popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14780   (clobber (reg:CC FLAGS_REG))]
14781  "TARGET_64BIT && TARGET_POPCNT"
14782  "popcnt{q}\t{%1, %0|%0, %1}"
14783  [(set_attr "prefix_rep" "1")
14784   (set_attr "type" "bitmanip")
14785   (set_attr "mode" "DI")])
14786
14787(define_insn "*popcountdi2_cmp"
14788  [(set (reg FLAGS_REG)
14789	(compare
14790	  (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14791	  (const_int 0)))
14792   (set (match_operand:DI 0 "register_operand" "=r")
14793	(popcount:DI (match_dup 1)))]
14794  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14795  "popcnt{q}\t{%1, %0|%0, %1}"
14796  [(set_attr "prefix_rep" "1")
14797   (set_attr "type" "bitmanip")
14798   (set_attr "mode" "DI")])
14799
14800(define_expand "clzhi2"
14801  [(parallel
14802     [(set (match_operand:HI 0 "register_operand" "")
14803	   (minus:HI (const_int 15)
14804		     (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14805      (clobber (reg:CC FLAGS_REG))])
14806   (parallel
14807     [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14808      (clobber (reg:CC FLAGS_REG))])]
14809  ""
14810{
14811  if (TARGET_ABM)
14812    {
14813      emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14814      DONE;
14815    }
14816})
14817
14818(define_insn "clzhi2_abm"
14819  [(set (match_operand:HI 0 "register_operand" "=r")
14820	(clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14821   (clobber (reg:CC FLAGS_REG))]
14822  "TARGET_ABM"
14823  "lzcnt{w}\t{%1, %0|%0, %1}"
14824  [(set_attr "prefix_rep" "1")
14825   (set_attr "type" "bitmanip")
14826   (set_attr "mode" "HI")])
14827
14828(define_insn "*bsrhi"
14829  [(set (match_operand:HI 0 "register_operand" "=r")
14830	(minus:HI (const_int 15)
14831		  (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14832   (clobber (reg:CC FLAGS_REG))]
14833  ""
14834  "bsr{w}\t{%1, %0|%0, %1}"
14835  [(set_attr "prefix_0f" "1")
14836   (set_attr "mode" "HI")])
14837
14838(define_insn "popcounthi2"
14839  [(set (match_operand:HI 0 "register_operand" "=r")
14840	(popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14841   (clobber (reg:CC FLAGS_REG))]
14842  "TARGET_POPCNT"
14843  "popcnt{w}\t{%1, %0|%0, %1}"
14844  [(set_attr "prefix_rep" "1")
14845   (set_attr "type" "bitmanip")
14846   (set_attr "mode" "HI")])
14847
14848(define_insn "*popcounthi2_cmp"
14849  [(set (reg FLAGS_REG)
14850        (compare
14851          (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14852          (const_int 0)))
14853   (set (match_operand:HI 0 "register_operand" "=r")
14854        (popcount:HI (match_dup 1)))]
14855  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14856  "popcnt{w}\t{%1, %0|%0, %1}"
14857  [(set_attr "prefix_rep" "1")
14858   (set_attr "type" "bitmanip")
14859   (set_attr "mode" "HI")])
14860
14861;; Thread-local storage patterns for ELF.
14862;;
14863;; Note that these code sequences must appear exactly as shown
14864;; in order to allow linker relaxation.
14865
14866(define_insn "*tls_global_dynamic_32_gnu"
14867  [(set (match_operand:SI 0 "register_operand" "=a")
14868	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14869		    (match_operand:SI 2 "tls_symbolic_operand" "")
14870		    (match_operand:SI 3 "call_insn_operand" "")]
14871		    UNSPEC_TLS_GD))
14872   (clobber (match_scratch:SI 4 "=d"))
14873   (clobber (match_scratch:SI 5 "=c"))
14874   (clobber (reg:CC FLAGS_REG))]
14875  "!TARGET_64BIT && TARGET_GNU_TLS"
14876  "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14877  [(set_attr "type" "multi")
14878   (set_attr "length" "12")])
14879
14880(define_insn "*tls_global_dynamic_32_sun"
14881  [(set (match_operand:SI 0 "register_operand" "=a")
14882	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14883		    (match_operand:SI 2 "tls_symbolic_operand" "")
14884		    (match_operand:SI 3 "call_insn_operand" "")]
14885		    UNSPEC_TLS_GD))
14886   (clobber (match_scratch:SI 4 "=d"))
14887   (clobber (match_scratch:SI 5 "=c"))
14888   (clobber (reg:CC FLAGS_REG))]
14889  "!TARGET_64BIT && TARGET_SUN_TLS"
14890  "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14891	push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14892  [(set_attr "type" "multi")
14893   (set_attr "length" "14")])
14894
14895(define_expand "tls_global_dynamic_32"
14896  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14897		   (unspec:SI
14898		    [(match_dup 2)
14899		     (match_operand:SI 1 "tls_symbolic_operand" "")
14900		     (match_dup 3)]
14901		    UNSPEC_TLS_GD))
14902	      (clobber (match_scratch:SI 4 ""))
14903	      (clobber (match_scratch:SI 5 ""))
14904	      (clobber (reg:CC FLAGS_REG))])]
14905  ""
14906{
14907  if (flag_pic)
14908    operands[2] = pic_offset_table_rtx;
14909  else
14910    {
14911      operands[2] = gen_reg_rtx (Pmode);
14912      emit_insn (gen_set_got (operands[2]));
14913    }
14914  if (TARGET_GNU2_TLS)
14915    {
14916       emit_insn (gen_tls_dynamic_gnu2_32
14917		  (operands[0], operands[1], operands[2]));
14918       DONE;
14919    }
14920  operands[3] = ix86_tls_get_addr ();
14921})
14922
14923(define_insn "*tls_global_dynamic_64"
14924  [(set (match_operand:DI 0 "register_operand" "=a")
14925	(call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14926		 (match_operand:DI 3 "" "")))
14927   (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14928	      UNSPEC_TLS_GD)]
14929  "TARGET_64BIT"
14930  ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14931  [(set_attr "type" "multi")
14932   (set_attr "length" "16")])
14933
14934(define_expand "tls_global_dynamic_64"
14935  [(parallel [(set (match_operand:DI 0 "register_operand" "")
14936		   (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14937	      (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14938			 UNSPEC_TLS_GD)])]
14939  ""
14940{
14941  if (TARGET_GNU2_TLS)
14942    {
14943       emit_insn (gen_tls_dynamic_gnu2_64
14944		  (operands[0], operands[1]));
14945       DONE;
14946    }
14947  operands[2] = ix86_tls_get_addr ();
14948})
14949
14950(define_insn "*tls_local_dynamic_base_32_gnu"
14951  [(set (match_operand:SI 0 "register_operand" "=a")
14952	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14953                    (match_operand:SI 2 "call_insn_operand" "")]
14954		   UNSPEC_TLS_LD_BASE))
14955   (clobber (match_scratch:SI 3 "=d"))
14956   (clobber (match_scratch:SI 4 "=c"))
14957   (clobber (reg:CC FLAGS_REG))]
14958  "!TARGET_64BIT && TARGET_GNU_TLS"
14959  "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14960  [(set_attr "type" "multi")
14961   (set_attr "length" "11")])
14962
14963(define_insn "*tls_local_dynamic_base_32_sun"
14964  [(set (match_operand:SI 0 "register_operand" "=a")
14965	(unspec:SI [(match_operand:SI 1 "register_operand" "b")
14966                    (match_operand:SI 2 "call_insn_operand" "")]
14967		   UNSPEC_TLS_LD_BASE))
14968   (clobber (match_scratch:SI 3 "=d"))
14969   (clobber (match_scratch:SI 4 "=c"))
14970   (clobber (reg:CC FLAGS_REG))]
14971  "!TARGET_64BIT && TARGET_SUN_TLS"
14972  "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14973	push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14974  [(set_attr "type" "multi")
14975   (set_attr "length" "13")])
14976
14977(define_expand "tls_local_dynamic_base_32"
14978  [(parallel [(set (match_operand:SI 0 "register_operand" "")
14979		   (unspec:SI [(match_dup 1) (match_dup 2)]
14980			      UNSPEC_TLS_LD_BASE))
14981	      (clobber (match_scratch:SI 3 ""))
14982	      (clobber (match_scratch:SI 4 ""))
14983	      (clobber (reg:CC FLAGS_REG))])]
14984  ""
14985{
14986  if (flag_pic)
14987    operands[1] = pic_offset_table_rtx;
14988  else
14989    {
14990      operands[1] = gen_reg_rtx (Pmode);
14991      emit_insn (gen_set_got (operands[1]));
14992    }
14993  if (TARGET_GNU2_TLS)
14994    {
14995       emit_insn (gen_tls_dynamic_gnu2_32
14996		  (operands[0], ix86_tls_module_base (), operands[1]));
14997       DONE;
14998    }
14999  operands[2] = ix86_tls_get_addr ();
15000})
15001
15002(define_insn "*tls_local_dynamic_base_64"
15003  [(set (match_operand:DI 0 "register_operand" "=a")
15004	(call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15005		 (match_operand:DI 2 "" "")))
15006   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15007  "TARGET_64BIT"
15008  "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15009  [(set_attr "type" "multi")
15010   (set_attr "length" "12")])
15011
15012(define_expand "tls_local_dynamic_base_64"
15013  [(parallel [(set (match_operand:DI 0 "register_operand" "")
15014		   (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15015	      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15016  ""
15017{
15018  if (TARGET_GNU2_TLS)
15019    {
15020       emit_insn (gen_tls_dynamic_gnu2_64
15021		  (operands[0], ix86_tls_module_base ()));
15022       DONE;
15023    }
15024  operands[1] = ix86_tls_get_addr ();
15025})
15026
15027;; Local dynamic of a single variable is a lose.  Show combine how
15028;; to convert that back to global dynamic.
15029
15030(define_insn_and_split "*tls_local_dynamic_32_once"
15031  [(set (match_operand:SI 0 "register_operand" "=a")
15032	(plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15033			     (match_operand:SI 2 "call_insn_operand" "")]
15034			    UNSPEC_TLS_LD_BASE)
15035		 (const:SI (unspec:SI
15036			    [(match_operand:SI 3 "tls_symbolic_operand" "")]
15037			    UNSPEC_DTPOFF))))
15038   (clobber (match_scratch:SI 4 "=d"))
15039   (clobber (match_scratch:SI 5 "=c"))
15040   (clobber (reg:CC FLAGS_REG))]
15041  ""
15042  "#"
15043  ""
15044  [(parallel [(set (match_dup 0)
15045		   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15046			      UNSPEC_TLS_GD))
15047	      (clobber (match_dup 4))
15048	      (clobber (match_dup 5))
15049	      (clobber (reg:CC FLAGS_REG))])]
15050  "")
15051
15052;; Load and add the thread base pointer from %gs:0.
15053
15054(define_insn "*load_tp_si"
15055  [(set (match_operand:SI 0 "register_operand" "=r")
15056	(unspec:SI [(const_int 0)] UNSPEC_TP))]
15057  "!TARGET_64BIT"
15058  "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15059  [(set_attr "type" "imov")
15060   (set_attr "modrm" "0")
15061   (set_attr "length" "7")
15062   (set_attr "memory" "load")
15063   (set_attr "imm_disp" "false")])
15064
15065(define_insn "*add_tp_si"
15066  [(set (match_operand:SI 0 "register_operand" "=r")
15067	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15068		 (match_operand:SI 1 "register_operand" "0")))
15069   (clobber (reg:CC FLAGS_REG))]
15070  "!TARGET_64BIT"
15071  "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15072  [(set_attr "type" "alu")
15073   (set_attr "modrm" "0")
15074   (set_attr "length" "7")
15075   (set_attr "memory" "load")
15076   (set_attr "imm_disp" "false")])
15077
15078(define_insn "*load_tp_di"
15079  [(set (match_operand:DI 0 "register_operand" "=r")
15080	(unspec:DI [(const_int 0)] UNSPEC_TP))]
15081  "TARGET_64BIT"
15082  "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15083  [(set_attr "type" "imov")
15084   (set_attr "modrm" "0")
15085   (set_attr "length" "7")
15086   (set_attr "memory" "load")
15087   (set_attr "imm_disp" "false")])
15088
15089(define_insn "*add_tp_di"
15090  [(set (match_operand:DI 0 "register_operand" "=r")
15091	(plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15092		 (match_operand:DI 1 "register_operand" "0")))
15093   (clobber (reg:CC FLAGS_REG))]
15094  "TARGET_64BIT"
15095  "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15096  [(set_attr "type" "alu")
15097   (set_attr "modrm" "0")
15098   (set_attr "length" "7")
15099   (set_attr "memory" "load")
15100   (set_attr "imm_disp" "false")])
15101
15102;; GNU2 TLS patterns can be split.
15103
15104(define_expand "tls_dynamic_gnu2_32"
15105  [(set (match_dup 3)
15106	(plus:SI (match_operand:SI 2 "register_operand" "")
15107		 (const:SI
15108		  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15109			     UNSPEC_TLSDESC))))
15110   (parallel
15111    [(set (match_operand:SI 0 "register_operand" "")
15112	  (unspec:SI [(match_dup 1) (match_dup 3)
15113		      (match_dup 2) (reg:SI SP_REG)]
15114		      UNSPEC_TLSDESC))
15115     (clobber (reg:CC FLAGS_REG))])]
15116  "!TARGET_64BIT && TARGET_GNU2_TLS"
15117{
15118  operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15119  ix86_tls_descriptor_calls_expanded_in_cfun = true;
15120})
15121
15122(define_insn "*tls_dynamic_lea_32"
15123  [(set (match_operand:SI 0 "register_operand" "=r")
15124	(plus:SI (match_operand:SI 1 "register_operand" "b")
15125		 (const:SI
15126		  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15127			      UNSPEC_TLSDESC))))]
15128  "!TARGET_64BIT && TARGET_GNU2_TLS"
15129  "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15130  [(set_attr "type" "lea")
15131   (set_attr "mode" "SI")
15132   (set_attr "length" "6")
15133   (set_attr "length_address" "4")])
15134
15135(define_insn "*tls_dynamic_call_32"
15136  [(set (match_operand:SI 0 "register_operand" "=a")
15137	(unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15138		    (match_operand:SI 2 "register_operand" "0")
15139		    ;; we have to make sure %ebx still points to the GOT
15140		    (match_operand:SI 3 "register_operand" "b")
15141		    (reg:SI SP_REG)]
15142		   UNSPEC_TLSDESC))
15143   (clobber (reg:CC FLAGS_REG))]
15144  "!TARGET_64BIT && TARGET_GNU2_TLS"
15145  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15146  [(set_attr "type" "call")
15147   (set_attr "length" "2")
15148   (set_attr "length_address" "0")])
15149
15150(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15151  [(set (match_operand:SI 0 "register_operand" "=&a")
15152	(plus:SI
15153	 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15154		     (match_operand:SI 4 "" "")
15155		     (match_operand:SI 2 "register_operand" "b")
15156		     (reg:SI SP_REG)]
15157		    UNSPEC_TLSDESC)
15158	 (const:SI (unspec:SI
15159		    [(match_operand:SI 1 "tls_symbolic_operand" "")]
15160		    UNSPEC_DTPOFF))))
15161   (clobber (reg:CC FLAGS_REG))]
15162  "!TARGET_64BIT && TARGET_GNU2_TLS"
15163  "#"
15164  ""
15165  [(set (match_dup 0) (match_dup 5))]
15166{
15167  operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15168  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15169})
15170
15171(define_expand "tls_dynamic_gnu2_64"
15172  [(set (match_dup 2)
15173	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15174		   UNSPEC_TLSDESC))
15175   (parallel
15176    [(set (match_operand:DI 0 "register_operand" "")
15177	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15178		     UNSPEC_TLSDESC))
15179     (clobber (reg:CC FLAGS_REG))])]
15180  "TARGET_64BIT && TARGET_GNU2_TLS"
15181{
15182  operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15183  ix86_tls_descriptor_calls_expanded_in_cfun = true;
15184})
15185
15186(define_insn "*tls_dynamic_lea_64"
15187  [(set (match_operand:DI 0 "register_operand" "=r")
15188	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15189		   UNSPEC_TLSDESC))]
15190  "TARGET_64BIT && TARGET_GNU2_TLS"
15191  "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15192  [(set_attr "type" "lea")
15193   (set_attr "mode" "DI")
15194   (set_attr "length" "7")
15195   (set_attr "length_address" "4")])
15196
15197(define_insn "*tls_dynamic_call_64"
15198  [(set (match_operand:DI 0 "register_operand" "=a")
15199	(unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15200		    (match_operand:DI 2 "register_operand" "0")
15201		    (reg:DI SP_REG)]
15202		   UNSPEC_TLSDESC))
15203   (clobber (reg:CC FLAGS_REG))]
15204  "TARGET_64BIT && TARGET_GNU2_TLS"
15205  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15206  [(set_attr "type" "call")
15207   (set_attr "length" "2")
15208   (set_attr "length_address" "0")])
15209
15210(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15211  [(set (match_operand:DI 0 "register_operand" "=&a")
15212	(plus:DI
15213	 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15214		     (match_operand:DI 3 "" "")
15215		     (reg:DI SP_REG)]
15216		    UNSPEC_TLSDESC)
15217	 (const:DI (unspec:DI
15218		    [(match_operand:DI 1 "tls_symbolic_operand" "")]
15219		    UNSPEC_DTPOFF))))
15220   (clobber (reg:CC FLAGS_REG))]
15221  "TARGET_64BIT && TARGET_GNU2_TLS"
15222  "#"
15223  ""
15224  [(set (match_dup 0) (match_dup 4))]
15225{
15226  operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15227  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15228})
15229
15230;;
15231
15232;; These patterns match the binary 387 instructions for addM3, subM3,
15233;; mulM3 and divM3.  There are three patterns for each of DFmode and
15234;; SFmode.  The first is the normal insn, the second the same insn but
15235;; with one operand a conversion, and the third the same insn but with
15236;; the other operand a conversion.  The conversion may be SFmode or
15237;; SImode if the target mode DFmode, but only SImode if the target mode
15238;; is SFmode.
15239
15240;; Gcc is slightly more smart about handling normal two address instructions
15241;; so use special patterns for add and mull.
15242
15243(define_insn "*fop_sf_comm_mixed"
15244  [(set (match_operand:SF 0 "register_operand" "=f,x")
15245	(match_operator:SF 3 "binary_fp_operator"
15246			[(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15247			 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15248  "TARGET_MIX_SSE_I387
15249   && COMMUTATIVE_ARITH_P (operands[3])
15250   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15251  "* return output_387_binary_op (insn, operands);"
15252  [(set (attr "type")
15253	(if_then_else (eq_attr "alternative" "1")
15254	   (if_then_else (match_operand:SF 3 "mult_operator" "")
15255	      (const_string "ssemul")
15256	      (const_string "sseadd"))
15257	   (if_then_else (match_operand:SF 3 "mult_operator" "")
15258	      (const_string "fmul")
15259	      (const_string "fop"))))
15260   (set_attr "mode" "SF")])
15261
15262(define_insn "*fop_sf_comm_sse"
15263  [(set (match_operand:SF 0 "register_operand" "=x")
15264	(match_operator:SF 3 "binary_fp_operator"
15265			[(match_operand:SF 1 "nonimmediate_operand" "%0")
15266			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15267  "TARGET_SSE_MATH
15268   && COMMUTATIVE_ARITH_P (operands[3])
15269   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15270  "* return output_387_binary_op (insn, operands);"
15271  [(set (attr "type")
15272        (if_then_else (match_operand:SF 3 "mult_operator" "")
15273	   (const_string "ssemul")
15274	   (const_string "sseadd")))
15275   (set_attr "mode" "SF")])
15276
15277(define_insn "*fop_sf_comm_i387"
15278  [(set (match_operand:SF 0 "register_operand" "=f")
15279	(match_operator:SF 3 "binary_fp_operator"
15280			[(match_operand:SF 1 "nonimmediate_operand" "%0")
15281			 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15282  "TARGET_80387
15283   && COMMUTATIVE_ARITH_P (operands[3])
15284   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15285  "* return output_387_binary_op (insn, operands);"
15286  [(set (attr "type")
15287	(if_then_else (match_operand:SF 3 "mult_operator" "")
15288	   (const_string "fmul")
15289	   (const_string "fop")))
15290   (set_attr "mode" "SF")])
15291
15292(define_insn "*fop_sf_1_mixed"
15293  [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15294	(match_operator:SF 3 "binary_fp_operator"
15295			[(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15296			 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15297  "TARGET_MIX_SSE_I387
15298   && !COMMUTATIVE_ARITH_P (operands[3])
15299   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15300  "* return output_387_binary_op (insn, operands);"
15301  [(set (attr "type")
15302        (cond [(and (eq_attr "alternative" "2")
15303	            (match_operand:SF 3 "mult_operator" ""))
15304                 (const_string "ssemul")
15305	       (and (eq_attr "alternative" "2")
15306	            (match_operand:SF 3 "div_operator" ""))
15307                 (const_string "ssediv")
15308	       (eq_attr "alternative" "2")
15309                 (const_string "sseadd")
15310	       (match_operand:SF 3 "mult_operator" "")
15311                 (const_string "fmul")
15312               (match_operand:SF 3 "div_operator" "")
15313                 (const_string "fdiv")
15314              ]
15315              (const_string "fop")))
15316   (set_attr "mode" "SF")])
15317
15318(define_insn "*fop_sf_1_sse"
15319  [(set (match_operand:SF 0 "register_operand" "=x")
15320	(match_operator:SF 3 "binary_fp_operator"
15321			[(match_operand:SF 1 "register_operand" "0")
15322			 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15323  "TARGET_SSE_MATH
15324   && !COMMUTATIVE_ARITH_P (operands[3])"
15325  "* return output_387_binary_op (insn, operands);"
15326  [(set (attr "type")
15327        (cond [(match_operand:SF 3 "mult_operator" "")
15328                 (const_string "ssemul")
15329	       (match_operand:SF 3 "div_operator" "")
15330                 (const_string "ssediv")
15331              ]
15332              (const_string "sseadd")))
15333   (set_attr "mode" "SF")])
15334
15335;; This pattern is not fully shadowed by the pattern above.
15336(define_insn "*fop_sf_1_i387"
15337  [(set (match_operand:SF 0 "register_operand" "=f,f")
15338	(match_operator:SF 3 "binary_fp_operator"
15339			[(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15340			 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15341  "TARGET_80387 && !TARGET_SSE_MATH
15342   && !COMMUTATIVE_ARITH_P (operands[3])
15343   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15344  "* return output_387_binary_op (insn, operands);"
15345  [(set (attr "type")
15346        (cond [(match_operand:SF 3 "mult_operator" "")
15347                 (const_string "fmul")
15348               (match_operand:SF 3 "div_operator" "")
15349                 (const_string "fdiv")
15350              ]
15351              (const_string "fop")))
15352   (set_attr "mode" "SF")])
15353
15354;; ??? Add SSE splitters for these!
15355(define_insn "*fop_sf_2<mode>_i387"
15356  [(set (match_operand:SF 0 "register_operand" "=f,f")
15357	(match_operator:SF 3 "binary_fp_operator"
15358	  [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15359	   (match_operand:SF 2 "register_operand" "0,0")]))]
15360  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15361  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15362  [(set (attr "type")
15363        (cond [(match_operand:SF 3 "mult_operator" "")
15364                 (const_string "fmul")
15365               (match_operand:SF 3 "div_operator" "")
15366                 (const_string "fdiv")
15367              ]
15368              (const_string "fop")))
15369   (set_attr "fp_int_src" "true")
15370   (set_attr "mode" "<MODE>")])
15371
15372(define_insn "*fop_sf_3<mode>_i387"
15373  [(set (match_operand:SF 0 "register_operand" "=f,f")
15374	(match_operator:SF 3 "binary_fp_operator"
15375	  [(match_operand:SF 1 "register_operand" "0,0")
15376	   (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15377  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15378  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15379  [(set (attr "type")
15380        (cond [(match_operand:SF 3 "mult_operator" "")
15381                 (const_string "fmul")
15382               (match_operand:SF 3 "div_operator" "")
15383                 (const_string "fdiv")
15384              ]
15385              (const_string "fop")))
15386   (set_attr "fp_int_src" "true")
15387   (set_attr "mode" "<MODE>")])
15388
15389(define_insn "*fop_df_comm_mixed"
15390  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15391	(match_operator:DF 3 "binary_fp_operator"
15392			[(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15393			 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15394  "TARGET_SSE2 && TARGET_MIX_SSE_I387
15395   && COMMUTATIVE_ARITH_P (operands[3])
15396   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15397  "* return output_387_binary_op (insn, operands);"
15398  [(set (attr "type")
15399	(if_then_else (eq_attr "alternative" "1")
15400	   (if_then_else (match_operand:DF 3 "mult_operator" "")
15401	      (const_string "ssemul")
15402	      (const_string "sseadd"))
15403	   (if_then_else (match_operand:DF 3 "mult_operator" "")
15404	      (const_string "fmul")
15405	      (const_string "fop"))))
15406   (set_attr "mode" "DF")])
15407
15408(define_insn "*fop_df_comm_sse"
15409  [(set (match_operand:DF 0 "register_operand" "=Y")
15410	(match_operator:DF 3 "binary_fp_operator"
15411			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15412			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15413  "TARGET_SSE2 && TARGET_SSE_MATH
15414   && COMMUTATIVE_ARITH_P (operands[3])
15415   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15416  "* return output_387_binary_op (insn, operands);"
15417  [(set (attr "type")
15418        (if_then_else (match_operand:DF 3 "mult_operator" "")
15419	   (const_string "ssemul")
15420	   (const_string "sseadd")))
15421   (set_attr "mode" "DF")])
15422
15423(define_insn "*fop_df_comm_i387"
15424  [(set (match_operand:DF 0 "register_operand" "=f")
15425	(match_operator:DF 3 "binary_fp_operator"
15426			[(match_operand:DF 1 "nonimmediate_operand" "%0")
15427			 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15428  "TARGET_80387
15429   && COMMUTATIVE_ARITH_P (operands[3])
15430   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15431  "* return output_387_binary_op (insn, operands);"
15432  [(set (attr "type")
15433	(if_then_else (match_operand:DF 3 "mult_operator" "")
15434	   (const_string "fmul")
15435	   (const_string "fop")))
15436   (set_attr "mode" "DF")])
15437
15438(define_insn "*fop_df_1_mixed"
15439  [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15440	(match_operator:DF 3 "binary_fp_operator"
15441			[(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15442			 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15443  "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15444   && !COMMUTATIVE_ARITH_P (operands[3])
15445   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15446  "* return output_387_binary_op (insn, operands);"
15447  [(set (attr "type")
15448        (cond [(and (eq_attr "alternative" "2")
15449	            (match_operand:DF 3 "mult_operator" ""))
15450                 (const_string "ssemul")
15451	       (and (eq_attr "alternative" "2")
15452	            (match_operand:DF 3 "div_operator" ""))
15453                 (const_string "ssediv")
15454	       (eq_attr "alternative" "2")
15455                 (const_string "sseadd")
15456	       (match_operand:DF 3 "mult_operator" "")
15457                 (const_string "fmul")
15458               (match_operand:DF 3 "div_operator" "")
15459                 (const_string "fdiv")
15460              ]
15461              (const_string "fop")))
15462   (set_attr "mode" "DF")])
15463
15464(define_insn "*fop_df_1_sse"
15465  [(set (match_operand:DF 0 "register_operand" "=Y")
15466	(match_operator:DF 3 "binary_fp_operator"
15467			[(match_operand:DF 1 "register_operand" "0")
15468			 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15469  "TARGET_SSE2 && TARGET_SSE_MATH
15470   && !COMMUTATIVE_ARITH_P (operands[3])"
15471  "* return output_387_binary_op (insn, operands);"
15472  [(set_attr "mode" "DF")
15473   (set (attr "type")
15474        (cond [(match_operand:DF 3 "mult_operator" "")
15475                 (const_string "ssemul")
15476	       (match_operand:DF 3 "div_operator" "")
15477                 (const_string "ssediv")
15478              ]
15479              (const_string "sseadd")))])
15480
15481;; This pattern is not fully shadowed by the pattern above.
15482(define_insn "*fop_df_1_i387"
15483  [(set (match_operand:DF 0 "register_operand" "=f,f")
15484	(match_operator:DF 3 "binary_fp_operator"
15485			[(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15486			 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15487  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15488   && !COMMUTATIVE_ARITH_P (operands[3])
15489   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15490  "* return 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 "mode" "DF")])
15499
15500;; ??? Add SSE splitters for these!
15501(define_insn "*fop_df_2<mode>_i387"
15502  [(set (match_operand:DF 0 "register_operand" "=f,f")
15503	(match_operator:DF 3 "binary_fp_operator"
15504	   [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15505	    (match_operand:DF 2 "register_operand" "0,0")]))]
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_3<mode>_i387"
15520  [(set (match_operand:DF 0 "register_operand" "=f,f")
15521	(match_operator:DF 3 "binary_fp_operator"
15522	   [(match_operand:DF 1 "register_operand" "0,0")
15523	    (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15524  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15525   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15526  "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
15535   (set_attr "mode" "<MODE>")])
15536
15537(define_insn "*fop_df_4_i387"
15538  [(set (match_operand:DF 0 "register_operand" "=f,f")
15539	(match_operator:DF 3 "binary_fp_operator"
15540	   [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15541	    (match_operand:DF 2 "register_operand" "0,f")]))]
15542  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15543   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15544  "* return output_387_binary_op (insn, operands);"
15545  [(set (attr "type")
15546        (cond [(match_operand:DF 3 "mult_operator" "")
15547                 (const_string "fmul")
15548               (match_operand:DF 3 "div_operator" "")
15549                 (const_string "fdiv")
15550              ]
15551              (const_string "fop")))
15552   (set_attr "mode" "SF")])
15553
15554(define_insn "*fop_df_5_i387"
15555  [(set (match_operand:DF 0 "register_operand" "=f,f")
15556	(match_operator:DF 3 "binary_fp_operator"
15557	  [(match_operand:DF 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_df_6_i387"
15572  [(set (match_operand:DF 0 "register_operand" "=f,f")
15573	(match_operator:DF 3 "binary_fp_operator"
15574	  [(float_extend:DF
15575	    (match_operand:SF 1 "register_operand" "0,f"))
15576	   (float_extend:DF
15577	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15578  "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15579  "* return output_387_binary_op (insn, operands);"
15580  [(set (attr "type")
15581        (cond [(match_operand:DF 3 "mult_operator" "")
15582                 (const_string "fmul")
15583               (match_operand:DF 3 "div_operator" "")
15584                 (const_string "fdiv")
15585              ]
15586              (const_string "fop")))
15587   (set_attr "mode" "SF")])
15588
15589(define_insn "*fop_xf_comm_i387"
15590  [(set (match_operand:XF 0 "register_operand" "=f")
15591	(match_operator:XF 3 "binary_fp_operator"
15592			[(match_operand:XF 1 "register_operand" "%0")
15593			 (match_operand:XF 2 "register_operand" "f")]))]
15594  "TARGET_80387
15595   && COMMUTATIVE_ARITH_P (operands[3])"
15596  "* return output_387_binary_op (insn, operands);"
15597  [(set (attr "type")
15598        (if_then_else (match_operand:XF 3 "mult_operator" "")
15599           (const_string "fmul")
15600           (const_string "fop")))
15601   (set_attr "mode" "XF")])
15602
15603(define_insn "*fop_xf_1_i387"
15604  [(set (match_operand:XF 0 "register_operand" "=f,f")
15605	(match_operator:XF 3 "binary_fp_operator"
15606			[(match_operand:XF 1 "register_operand" "0,f")
15607			 (match_operand:XF 2 "register_operand" "f,0")]))]
15608  "TARGET_80387
15609   && !COMMUTATIVE_ARITH_P (operands[3])"
15610  "* return output_387_binary_op (insn, operands);"
15611  [(set (attr "type")
15612        (cond [(match_operand:XF 3 "mult_operator" "")
15613                 (const_string "fmul")
15614               (match_operand:XF 3 "div_operator" "")
15615                 (const_string "fdiv")
15616              ]
15617              (const_string "fop")))
15618   (set_attr "mode" "XF")])
15619
15620(define_insn "*fop_xf_2<mode>_i387"
15621  [(set (match_operand:XF 0 "register_operand" "=f,f")
15622	(match_operator:XF 3 "binary_fp_operator"
15623	   [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15624	    (match_operand:XF 2 "register_operand" "0,0")]))]
15625  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15626  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15627  [(set (attr "type")
15628        (cond [(match_operand:XF 3 "mult_operator" "")
15629                 (const_string "fmul")
15630               (match_operand:XF 3 "div_operator" "")
15631                 (const_string "fdiv")
15632              ]
15633              (const_string "fop")))
15634   (set_attr "fp_int_src" "true")
15635   (set_attr "mode" "<MODE>")])
15636
15637(define_insn "*fop_xf_3<mode>_i387"
15638  [(set (match_operand:XF 0 "register_operand" "=f,f")
15639	(match_operator:XF 3 "binary_fp_operator"
15640	  [(match_operand:XF 1 "register_operand" "0,0")
15641	   (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15642  "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15643  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15644  [(set (attr "type")
15645        (cond [(match_operand:XF 3 "mult_operator" "")
15646                 (const_string "fmul")
15647               (match_operand:XF 3 "div_operator" "")
15648                 (const_string "fdiv")
15649              ]
15650              (const_string "fop")))
15651   (set_attr "fp_int_src" "true")
15652   (set_attr "mode" "<MODE>")])
15653
15654(define_insn "*fop_xf_4_i387"
15655  [(set (match_operand:XF 0 "register_operand" "=f,f")
15656	(match_operator:XF 3 "binary_fp_operator"
15657	   [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15658	    (match_operand:XF 2 "register_operand" "0,f")]))]
15659  "TARGET_80387"
15660  "* return output_387_binary_op (insn, operands);"
15661  [(set (attr "type")
15662        (cond [(match_operand:XF 3 "mult_operator" "")
15663                 (const_string "fmul")
15664               (match_operand:XF 3 "div_operator" "")
15665                 (const_string "fdiv")
15666              ]
15667              (const_string "fop")))
15668   (set_attr "mode" "SF")])
15669
15670(define_insn "*fop_xf_5_i387"
15671  [(set (match_operand:XF 0 "register_operand" "=f,f")
15672	(match_operator:XF 3 "binary_fp_operator"
15673	  [(match_operand:XF 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_insn "*fop_xf_6_i387"
15688  [(set (match_operand:XF 0 "register_operand" "=f,f")
15689	(match_operator:XF 3 "binary_fp_operator"
15690	  [(float_extend:XF
15691	    (match_operand 1 "register_operand" "0,f"))
15692	   (float_extend:XF
15693	    (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15694  "TARGET_80387"
15695  "* return output_387_binary_op (insn, operands);"
15696  [(set (attr "type")
15697        (cond [(match_operand:XF 3 "mult_operator" "")
15698                 (const_string "fmul")
15699               (match_operand:XF 3 "div_operator" "")
15700                 (const_string "fdiv")
15701              ]
15702              (const_string "fop")))
15703   (set_attr "mode" "SF")])
15704
15705(define_split
15706  [(set (match_operand 0 "register_operand" "")
15707	(match_operator 3 "binary_fp_operator"
15708	   [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15709	    (match_operand 2 "register_operand" "")]))]
15710  "TARGET_80387 && reload_completed
15711   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15712  [(const_int 0)]
15713{
15714  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15715  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15716  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15717			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15718					  GET_MODE (operands[3]),
15719					  operands[4],
15720					  operands[2])));
15721  ix86_free_from_memory (GET_MODE (operands[1]));
15722  DONE;
15723})
15724
15725(define_split
15726  [(set (match_operand 0 "register_operand" "")
15727	(match_operator 3 "binary_fp_operator"
15728	   [(match_operand 1 "register_operand" "")
15729	    (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15730  "TARGET_80387 && reload_completed
15731   && FLOAT_MODE_P (GET_MODE (operands[0]))"
15732  [(const_int 0)]
15733{
15734  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15735  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15736  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15737			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
15738					  GET_MODE (operands[3]),
15739					  operands[1],
15740					  operands[4])));
15741  ix86_free_from_memory (GET_MODE (operands[2]));
15742  DONE;
15743})
15744
15745;; FPU special functions.
15746
15747(define_expand "sqrtsf2"
15748  [(set (match_operand:SF 0 "register_operand" "")
15749	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15750  "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15751{
15752  if (!TARGET_SSE_MATH)
15753    operands[1] = force_reg (SFmode, operands[1]);
15754})
15755
15756(define_insn "*sqrtsf2_mixed"
15757  [(set (match_operand:SF 0 "register_operand" "=f,x")
15758	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15759  "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15760  "@
15761   fsqrt
15762   sqrtss\t{%1, %0|%0, %1}"
15763  [(set_attr "type" "fpspc,sse")
15764   (set_attr "mode" "SF,SF")
15765   (set_attr "athlon_decode" "direct,*")
15766   (set_attr "amdfam10_decode" "direct,*")])
15767
15768(define_insn "*sqrtsf2_sse"
15769  [(set (match_operand:SF 0 "register_operand" "=x")
15770	(sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15771  "TARGET_SSE_MATH"
15772  "sqrtss\t{%1, %0|%0, %1}"
15773  [(set_attr "type" "sse")
15774   (set_attr "mode" "SF")
15775   (set_attr "athlon_decode" "*")
15776   (set_attr "amdfam10_decode" "*")])
15777
15778(define_insn "*sqrtsf2_i387"
15779  [(set (match_operand:SF 0 "register_operand" "=f")
15780	(sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15781  "TARGET_USE_FANCY_MATH_387"
15782  "fsqrt"
15783  [(set_attr "type" "fpspc")
15784   (set_attr "mode" "SF")
15785   (set_attr "athlon_decode" "direct")
15786   (set_attr "amdfam10_decode" "direct")])
15787
15788(define_expand "sqrtdf2"
15789  [(set (match_operand:DF 0 "register_operand" "")
15790	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15791  "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15792{
15793  if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15794    operands[1] = force_reg (DFmode, operands[1]);
15795})
15796
15797(define_insn "*sqrtdf2_mixed"
15798  [(set (match_operand:DF 0 "register_operand" "=f,Y")
15799	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15800  "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15801  "@
15802   fsqrt
15803   sqrtsd\t{%1, %0|%0, %1}"
15804  [(set_attr "type" "fpspc,sse")
15805   (set_attr "mode" "DF,DF")
15806   (set_attr "athlon_decode" "direct,*")
15807   (set_attr "amdfam10_decode" "direct,*")])
15808
15809(define_insn "*sqrtdf2_sse"
15810  [(set (match_operand:DF 0 "register_operand" "=Y")
15811	(sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15812  "TARGET_SSE2 && TARGET_SSE_MATH"
15813  "sqrtsd\t{%1, %0|%0, %1}"
15814  [(set_attr "type" "sse")
15815   (set_attr "mode" "DF")
15816   (set_attr "athlon_decode" "*")
15817   (set_attr "amdfam10_decode" "*")])
15818
15819(define_insn "*sqrtdf2_i387"
15820  [(set (match_operand:DF 0 "register_operand" "=f")
15821	(sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15822  "TARGET_USE_FANCY_MATH_387"
15823  "fsqrt"
15824  [(set_attr "type" "fpspc")
15825   (set_attr "mode" "DF")
15826   (set_attr "athlon_decode" "direct")
15827   (set_attr "amdfam10_decode" "direct")])
15828
15829(define_insn "*sqrtextendsfdf2_i387"
15830  [(set (match_operand:DF 0 "register_operand" "=f")
15831	(sqrt:DF (float_extend:DF
15832		  (match_operand:SF 1 "register_operand" "0"))))]
15833  "TARGET_USE_FANCY_MATH_387
15834   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15835  "fsqrt"
15836  [(set_attr "type" "fpspc")
15837   (set_attr "mode" "DF")
15838   (set_attr "athlon_decode" "direct")
15839   (set_attr "amdfam10_decode" "direct")])
15840
15841(define_insn "sqrtxf2"
15842  [(set (match_operand:XF 0 "register_operand" "=f")
15843	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15844  "TARGET_USE_FANCY_MATH_387"
15845  "fsqrt"
15846  [(set_attr "type" "fpspc")
15847   (set_attr "mode" "XF")
15848   (set_attr "athlon_decode" "direct")
15849   (set_attr "amdfam10_decode" "direct")])
15850
15851(define_insn "*sqrtextendsfxf2_i387"
15852  [(set (match_operand:XF 0 "register_operand" "=f")
15853	(sqrt:XF (float_extend:XF
15854		  (match_operand:SF 1 "register_operand" "0"))))]
15855  "TARGET_USE_FANCY_MATH_387"
15856  "fsqrt"
15857  [(set_attr "type" "fpspc")
15858   (set_attr "mode" "XF")
15859   (set_attr "athlon_decode" "direct")
15860   (set_attr "amdfam10_decode" "direct")])
15861
15862(define_insn "*sqrtextenddfxf2_i387"
15863  [(set (match_operand:XF 0 "register_operand" "=f")
15864	(sqrt:XF (float_extend:XF
15865		  (match_operand:DF 1 "register_operand" "0"))))]
15866  "TARGET_USE_FANCY_MATH_387"
15867  "fsqrt"
15868  [(set_attr "type" "fpspc")
15869   (set_attr "mode" "XF")
15870   (set_attr "athlon_decode" "direct")
15871   (set_attr "amdfam10_decode" "direct")])
15872
15873(define_insn "fpremxf4"
15874  [(set (match_operand:XF 0 "register_operand" "=f")
15875	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15876		    (match_operand:XF 3 "register_operand" "1")]
15877		   UNSPEC_FPREM_F))
15878   (set (match_operand:XF 1 "register_operand" "=u")
15879	(unspec:XF [(match_dup 2) (match_dup 3)]
15880		   UNSPEC_FPREM_U))
15881   (set (reg:CCFP FPSR_REG)
15882	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15883  "TARGET_USE_FANCY_MATH_387
15884   && flag_unsafe_math_optimizations"
15885  "fprem"
15886  [(set_attr "type" "fpspc")
15887   (set_attr "mode" "XF")])
15888
15889(define_expand "fmodsf3"
15890  [(use (match_operand:SF 0 "register_operand" ""))
15891   (use (match_operand:SF 1 "register_operand" ""))
15892   (use (match_operand:SF 2 "register_operand" ""))]
15893  "TARGET_USE_FANCY_MATH_387
15894   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15895   && flag_unsafe_math_optimizations"
15896{
15897  rtx label = gen_label_rtx ();
15898
15899  rtx op1 = gen_reg_rtx (XFmode);
15900  rtx op2 = gen_reg_rtx (XFmode);
15901
15902  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15903  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15904
15905  emit_label (label);
15906
15907  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15908  ix86_emit_fp_unordered_jump (label);
15909
15910  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15911  DONE;
15912})
15913
15914(define_expand "fmoddf3"
15915  [(use (match_operand:DF 0 "register_operand" ""))
15916   (use (match_operand:DF 1 "register_operand" ""))
15917   (use (match_operand:DF 2 "register_operand" ""))]
15918  "TARGET_USE_FANCY_MATH_387
15919   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15920   && flag_unsafe_math_optimizations"
15921{
15922  rtx label = gen_label_rtx ();
15923
15924  rtx op1 = gen_reg_rtx (XFmode);
15925  rtx op2 = gen_reg_rtx (XFmode);
15926
15927  emit_insn (gen_extenddfxf2 (op1, operands[1]));
15928  emit_insn (gen_extenddfxf2 (op2, operands[2]));
15929
15930  emit_label (label);
15931
15932  emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15933  ix86_emit_fp_unordered_jump (label);
15934
15935  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15936  DONE;
15937})
15938
15939(define_expand "fmodxf3"
15940  [(use (match_operand:XF 0 "register_operand" ""))
15941   (use (match_operand:XF 1 "register_operand" ""))
15942   (use (match_operand:XF 2 "register_operand" ""))]
15943  "TARGET_USE_FANCY_MATH_387
15944   && flag_unsafe_math_optimizations"
15945{
15946  rtx label = gen_label_rtx ();
15947
15948  emit_label (label);
15949
15950  emit_insn (gen_fpremxf4 (operands[1], operands[2],
15951			   operands[1], operands[2]));
15952  ix86_emit_fp_unordered_jump (label);
15953
15954  emit_move_insn (operands[0], operands[1]);
15955  DONE;
15956})
15957
15958(define_insn "fprem1xf4"
15959  [(set (match_operand:XF 0 "register_operand" "=f")
15960	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15961		    (match_operand:XF 3 "register_operand" "1")]
15962		   UNSPEC_FPREM1_F))
15963   (set (match_operand:XF 1 "register_operand" "=u")
15964	(unspec:XF [(match_dup 2) (match_dup 3)]
15965		   UNSPEC_FPREM1_U))
15966   (set (reg:CCFP FPSR_REG)
15967	(unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15968  "TARGET_USE_FANCY_MATH_387
15969   && flag_unsafe_math_optimizations"
15970  "fprem1"
15971  [(set_attr "type" "fpspc")
15972   (set_attr "mode" "XF")])
15973
15974(define_expand "dremsf3"
15975  [(use (match_operand:SF 0 "register_operand" ""))
15976   (use (match_operand:SF 1 "register_operand" ""))
15977   (use (match_operand:SF 2 "register_operand" ""))]
15978  "TARGET_USE_FANCY_MATH_387
15979   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15980   && flag_unsafe_math_optimizations"
15981{
15982  rtx label = gen_label_rtx ();
15983
15984  rtx op1 = gen_reg_rtx (XFmode);
15985  rtx op2 = gen_reg_rtx (XFmode);
15986
15987  emit_insn(gen_extendsfxf2 (op1, operands[1]));
15988  emit_insn(gen_extendsfxf2 (op2, operands[2]));
15989
15990  emit_label (label);
15991
15992  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15993  ix86_emit_fp_unordered_jump (label);
15994
15995  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15996  DONE;
15997})
15998
15999(define_expand "dremdf3"
16000  [(use (match_operand:DF 0 "register_operand" ""))
16001   (use (match_operand:DF 1 "register_operand" ""))
16002   (use (match_operand:DF 2 "register_operand" ""))]
16003  "TARGET_USE_FANCY_MATH_387
16004   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16005   && flag_unsafe_math_optimizations"
16006{
16007  rtx label = gen_label_rtx ();
16008
16009  rtx op1 = gen_reg_rtx (XFmode);
16010  rtx op2 = gen_reg_rtx (XFmode);
16011
16012  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16013  emit_insn (gen_extenddfxf2 (op2, operands[2]));
16014
16015  emit_label (label);
16016
16017  emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
16018  ix86_emit_fp_unordered_jump (label);
16019
16020  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
16021  DONE;
16022})
16023
16024(define_expand "dremxf3"
16025  [(use (match_operand:XF 0 "register_operand" ""))
16026   (use (match_operand:XF 1 "register_operand" ""))
16027   (use (match_operand:XF 2 "register_operand" ""))]
16028  "TARGET_USE_FANCY_MATH_387
16029   && flag_unsafe_math_optimizations"
16030{
16031  rtx label = gen_label_rtx ();
16032
16033  emit_label (label);
16034
16035  emit_insn (gen_fprem1xf4 (operands[1], operands[2],
16036			    operands[1], operands[2]));
16037  ix86_emit_fp_unordered_jump (label);
16038
16039  emit_move_insn (operands[0], operands[1]);
16040  DONE;
16041})
16042
16043(define_insn "*sindf2"
16044  [(set (match_operand:DF 0 "register_operand" "=f")
16045	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
16046  "TARGET_USE_FANCY_MATH_387
16047   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048   && flag_unsafe_math_optimizations"
16049  "fsin"
16050  [(set_attr "type" "fpspc")
16051   (set_attr "mode" "DF")])
16052
16053(define_insn "*sinsf2"
16054  [(set (match_operand:SF 0 "register_operand" "=f")
16055	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
16056  "TARGET_USE_FANCY_MATH_387
16057   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16058   && flag_unsafe_math_optimizations"
16059  "fsin"
16060  [(set_attr "type" "fpspc")
16061   (set_attr "mode" "SF")])
16062
16063(define_insn "*sinextendsfdf2"
16064  [(set (match_operand:DF 0 "register_operand" "=f")
16065	(unspec:DF [(float_extend:DF
16066		     (match_operand:SF 1 "register_operand" "0"))]
16067		   UNSPEC_SIN))]
16068  "TARGET_USE_FANCY_MATH_387
16069   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16070   && flag_unsafe_math_optimizations"
16071  "fsin"
16072  [(set_attr "type" "fpspc")
16073   (set_attr "mode" "DF")])
16074
16075(define_insn "*sinxf2"
16076  [(set (match_operand:XF 0 "register_operand" "=f")
16077	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16078  "TARGET_USE_FANCY_MATH_387
16079   && flag_unsafe_math_optimizations"
16080  "fsin"
16081  [(set_attr "type" "fpspc")
16082   (set_attr "mode" "XF")])
16083
16084(define_insn "*cosdf2"
16085  [(set (match_operand:DF 0 "register_operand" "=f")
16086	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
16087  "TARGET_USE_FANCY_MATH_387
16088   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16089   && flag_unsafe_math_optimizations"
16090  "fcos"
16091  [(set_attr "type" "fpspc")
16092   (set_attr "mode" "DF")])
16093
16094(define_insn "*cossf2"
16095  [(set (match_operand:SF 0 "register_operand" "=f")
16096	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
16097  "TARGET_USE_FANCY_MATH_387
16098   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16099   && flag_unsafe_math_optimizations"
16100  "fcos"
16101  [(set_attr "type" "fpspc")
16102   (set_attr "mode" "SF")])
16103
16104(define_insn "*cosextendsfdf2"
16105  [(set (match_operand:DF 0 "register_operand" "=f")
16106	(unspec:DF [(float_extend:DF
16107		     (match_operand:SF 1 "register_operand" "0"))]
16108		   UNSPEC_COS))]
16109  "TARGET_USE_FANCY_MATH_387
16110   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16111   && flag_unsafe_math_optimizations"
16112  "fcos"
16113  [(set_attr "type" "fpspc")
16114   (set_attr "mode" "DF")])
16115
16116(define_insn "*cosxf2"
16117  [(set (match_operand:XF 0 "register_operand" "=f")
16118	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16119  "TARGET_USE_FANCY_MATH_387
16120   && flag_unsafe_math_optimizations"
16121  "fcos"
16122  [(set_attr "type" "fpspc")
16123   (set_attr "mode" "XF")])
16124
16125;; With sincos pattern defined, sin and cos builtin function will be
16126;; expanded to sincos pattern with one of its outputs left unused.
16127;; Cse pass  will detected, if two sincos patterns can be combined,
16128;; otherwise sincos pattern will be split back to sin or cos pattern,
16129;; depending on the unused output.
16130
16131(define_insn "sincosdf3"
16132  [(set (match_operand:DF 0 "register_operand" "=f")
16133	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16134		   UNSPEC_SINCOS_COS))
16135   (set (match_operand:DF 1 "register_operand" "=u")
16136        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16137  "TARGET_USE_FANCY_MATH_387
16138   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16139   && flag_unsafe_math_optimizations"
16140  "fsincos"
16141  [(set_attr "type" "fpspc")
16142   (set_attr "mode" "DF")])
16143
16144(define_split
16145  [(set (match_operand:DF 0 "register_operand" "")
16146	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
16147		   UNSPEC_SINCOS_COS))
16148   (set (match_operand:DF 1 "register_operand" "")
16149	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16150  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16151   && !reload_completed && !reload_in_progress"
16152  [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
16153  "")
16154
16155(define_split
16156  [(set (match_operand:DF 0 "register_operand" "")
16157	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
16158		   UNSPEC_SINCOS_COS))
16159   (set (match_operand:DF 1 "register_operand" "")
16160	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16161  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16162   && !reload_completed && !reload_in_progress"
16163  [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
16164  "")
16165
16166(define_insn "sincossf3"
16167  [(set (match_operand:SF 0 "register_operand" "=f")
16168	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16169		   UNSPEC_SINCOS_COS))
16170   (set (match_operand:SF 1 "register_operand" "=u")
16171        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16172  "TARGET_USE_FANCY_MATH_387
16173   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16174   && flag_unsafe_math_optimizations"
16175  "fsincos"
16176  [(set_attr "type" "fpspc")
16177   (set_attr "mode" "SF")])
16178
16179(define_split
16180  [(set (match_operand:SF 0 "register_operand" "")
16181	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
16182		   UNSPEC_SINCOS_COS))
16183   (set (match_operand:SF 1 "register_operand" "")
16184	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16185  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16186   && !reload_completed && !reload_in_progress"
16187  [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
16188  "")
16189
16190(define_split
16191  [(set (match_operand:SF 0 "register_operand" "")
16192	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
16193		   UNSPEC_SINCOS_COS))
16194   (set (match_operand:SF 1 "register_operand" "")
16195	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16196  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16197   && !reload_completed && !reload_in_progress"
16198  [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
16199  "")
16200
16201(define_insn "*sincosextendsfdf3"
16202  [(set (match_operand:DF 0 "register_operand" "=f")
16203	(unspec:DF [(float_extend:DF
16204		     (match_operand:SF 2 "register_operand" "0"))]
16205		   UNSPEC_SINCOS_COS))
16206   (set (match_operand:DF 1 "register_operand" "=u")
16207        (unspec:DF [(float_extend:DF
16208		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
16209  "TARGET_USE_FANCY_MATH_387
16210   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16211   && flag_unsafe_math_optimizations"
16212  "fsincos"
16213  [(set_attr "type" "fpspc")
16214   (set_attr "mode" "DF")])
16215
16216(define_split
16217  [(set (match_operand:DF 0 "register_operand" "")
16218	(unspec:DF [(float_extend:DF
16219		     (match_operand:SF 2 "register_operand" ""))]
16220		   UNSPEC_SINCOS_COS))
16221   (set (match_operand:DF 1 "register_operand" "")
16222        (unspec:DF [(float_extend:DF
16223		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
16224  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16225   && !reload_completed && !reload_in_progress"
16226  [(set (match_dup 1) (unspec:DF [(float_extend:DF
16227				   (match_dup 2))] UNSPEC_SIN))]
16228  "")
16229
16230(define_split
16231  [(set (match_operand:DF 0 "register_operand" "")
16232	(unspec:DF [(float_extend:DF
16233		     (match_operand:SF 2 "register_operand" ""))]
16234		   UNSPEC_SINCOS_COS))
16235   (set (match_operand:DF 1 "register_operand" "")
16236        (unspec:DF [(float_extend:DF
16237		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
16238  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16239   && !reload_completed && !reload_in_progress"
16240  [(set (match_dup 0) (unspec:DF [(float_extend:DF
16241				   (match_dup 2))] UNSPEC_COS))]
16242  "")
16243
16244(define_insn "sincosxf3"
16245  [(set (match_operand:XF 0 "register_operand" "=f")
16246	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16247		   UNSPEC_SINCOS_COS))
16248   (set (match_operand:XF 1 "register_operand" "=u")
16249        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16250  "TARGET_USE_FANCY_MATH_387
16251   && flag_unsafe_math_optimizations"
16252  "fsincos"
16253  [(set_attr "type" "fpspc")
16254   (set_attr "mode" "XF")])
16255
16256(define_split
16257  [(set (match_operand:XF 0 "register_operand" "")
16258	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
16259		   UNSPEC_SINCOS_COS))
16260   (set (match_operand:XF 1 "register_operand" "")
16261	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16262  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16263   && !reload_completed && !reload_in_progress"
16264  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16265  "")
16266
16267(define_split
16268  [(set (match_operand:XF 0 "register_operand" "")
16269	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
16270		   UNSPEC_SINCOS_COS))
16271   (set (match_operand:XF 1 "register_operand" "")
16272	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16273  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16274   && !reload_completed && !reload_in_progress"
16275  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16276  "")
16277
16278(define_insn "*tandf3_1"
16279  [(set (match_operand:DF 0 "register_operand" "=f")
16280	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
16281		   UNSPEC_TAN_ONE))
16282   (set (match_operand:DF 1 "register_operand" "=u")
16283        (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16284  "TARGET_USE_FANCY_MATH_387
16285   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16286   && flag_unsafe_math_optimizations"
16287  "fptan"
16288  [(set_attr "type" "fpspc")
16289   (set_attr "mode" "DF")])
16290
16291;; optimize sequence: fptan
16292;;		      fstp    %st(0)
16293;;		      fld1
16294;; into fptan insn.
16295
16296(define_peephole2
16297  [(parallel[(set (match_operand:DF 0 "register_operand" "")
16298		  (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16299			     UNSPEC_TAN_ONE))
16300	     (set (match_operand:DF 1 "register_operand" "")
16301		  (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16302   (set (match_dup 0)
16303        (match_operand:DF 3 "immediate_operand" ""))]
16304  "standard_80387_constant_p (operands[3]) == 2"
16305  [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16306   	     (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16307  "")
16308
16309(define_expand "tandf2"
16310  [(parallel [(set (match_dup 2)
16311		   (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16312			      UNSPEC_TAN_ONE))
16313	      (set (match_operand:DF 0 "register_operand" "")
16314		   (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16315  "TARGET_USE_FANCY_MATH_387
16316   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16317   && flag_unsafe_math_optimizations"
16318{
16319  operands[2] = gen_reg_rtx (DFmode);
16320})
16321
16322(define_insn "*tansf3_1"
16323  [(set (match_operand:SF 0 "register_operand" "=f")
16324	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16325		   UNSPEC_TAN_ONE))
16326   (set (match_operand:SF 1 "register_operand" "=u")
16327        (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16328  "TARGET_USE_FANCY_MATH_387
16329   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16330   && flag_unsafe_math_optimizations"
16331  "fptan"
16332  [(set_attr "type" "fpspc")
16333   (set_attr "mode" "SF")])
16334
16335;; optimize sequence: fptan
16336;;		      fstp    %st(0)
16337;;		      fld1
16338;; into fptan insn.
16339
16340(define_peephole2
16341  [(parallel[(set (match_operand:SF 0 "register_operand" "")
16342		  (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16343			     UNSPEC_TAN_ONE))
16344	     (set (match_operand:SF 1 "register_operand" "")
16345		  (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16346   (set (match_dup 0)
16347        (match_operand:SF 3 "immediate_operand" ""))]
16348  "standard_80387_constant_p (operands[3]) == 2"
16349  [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16350   	     (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16351  "")
16352
16353(define_expand "tansf2"
16354  [(parallel [(set (match_dup 2)
16355		   (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16356			      UNSPEC_TAN_ONE))
16357	      (set (match_operand:SF 0 "register_operand" "")
16358		   (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16359  "TARGET_USE_FANCY_MATH_387
16360   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16361   && flag_unsafe_math_optimizations"
16362{
16363  operands[2] = gen_reg_rtx (SFmode);
16364})
16365
16366(define_insn "*tanxf3_1"
16367  [(set (match_operand:XF 0 "register_operand" "=f")
16368	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16369		   UNSPEC_TAN_ONE))
16370   (set (match_operand:XF 1 "register_operand" "=u")
16371        (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16372  "TARGET_USE_FANCY_MATH_387
16373   && flag_unsafe_math_optimizations"
16374  "fptan"
16375  [(set_attr "type" "fpspc")
16376   (set_attr "mode" "XF")])
16377
16378;; optimize sequence: fptan
16379;;		      fstp    %st(0)
16380;;		      fld1
16381;; into fptan insn.
16382
16383(define_peephole2
16384  [(parallel[(set (match_operand:XF 0 "register_operand" "")
16385		  (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16386			     UNSPEC_TAN_ONE))
16387	     (set (match_operand:XF 1 "register_operand" "")
16388		  (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16389   (set (match_dup 0)
16390        (match_operand:XF 3 "immediate_operand" ""))]
16391  "standard_80387_constant_p (operands[3]) == 2"
16392  [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16393   	     (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16394  "")
16395
16396(define_expand "tanxf2"
16397  [(parallel [(set (match_dup 2)
16398		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16399			      UNSPEC_TAN_ONE))
16400	      (set (match_operand:XF 0 "register_operand" "")
16401		   (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16402  "TARGET_USE_FANCY_MATH_387
16403   && flag_unsafe_math_optimizations"
16404{
16405  operands[2] = gen_reg_rtx (XFmode);
16406})
16407
16408(define_insn "atan2df3_1"
16409  [(set (match_operand:DF 0 "register_operand" "=f")
16410	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
16411		    (match_operand:DF 1 "register_operand" "u")]
16412		   UNSPEC_FPATAN))
16413   (clobber (match_scratch:DF 3 "=1"))]
16414  "TARGET_USE_FANCY_MATH_387
16415   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16416   && flag_unsafe_math_optimizations"
16417  "fpatan"
16418  [(set_attr "type" "fpspc")
16419   (set_attr "mode" "DF")])
16420
16421(define_expand "atan2df3"
16422  [(use (match_operand:DF 0 "register_operand" ""))
16423   (use (match_operand:DF 2 "register_operand" ""))
16424   (use (match_operand:DF 1 "register_operand" ""))]
16425  "TARGET_USE_FANCY_MATH_387
16426   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16427   && flag_unsafe_math_optimizations"
16428{
16429  rtx copy = gen_reg_rtx (DFmode);
16430  emit_move_insn (copy, operands[1]);
16431  emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16432  DONE;
16433})
16434
16435(define_expand "atandf2"
16436  [(parallel [(set (match_operand:DF 0 "register_operand" "")
16437		   (unspec:DF [(match_dup 2)
16438			       (match_operand:DF 1 "register_operand" "")]
16439		    UNSPEC_FPATAN))
16440	      (clobber (match_scratch:DF 3 ""))])]
16441  "TARGET_USE_FANCY_MATH_387
16442   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16443   && flag_unsafe_math_optimizations"
16444{
16445  operands[2] = gen_reg_rtx (DFmode);
16446  emit_move_insn (operands[2], CONST1_RTX (DFmode));  /* fld1 */
16447})
16448
16449(define_insn "atan2sf3_1"
16450  [(set (match_operand:SF 0 "register_operand" "=f")
16451        (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16452		    (match_operand:SF 1 "register_operand" "u")]
16453		   UNSPEC_FPATAN))
16454   (clobber (match_scratch:SF 3 "=1"))]
16455  "TARGET_USE_FANCY_MATH_387
16456   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16457   && flag_unsafe_math_optimizations"
16458  "fpatan"
16459  [(set_attr "type" "fpspc")
16460   (set_attr "mode" "SF")])
16461
16462(define_expand "atan2sf3"
16463  [(use (match_operand:SF 0 "register_operand" ""))
16464   (use (match_operand:SF 2 "register_operand" ""))
16465   (use (match_operand:SF 1 "register_operand" ""))]
16466  "TARGET_USE_FANCY_MATH_387
16467   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16468   && flag_unsafe_math_optimizations"
16469{
16470  rtx copy = gen_reg_rtx (SFmode);
16471  emit_move_insn (copy, operands[1]);
16472  emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16473  DONE;
16474})
16475
16476(define_expand "atansf2"
16477  [(parallel [(set (match_operand:SF 0 "register_operand" "")
16478		   (unspec:SF [(match_dup 2)
16479			       (match_operand:SF 1 "register_operand" "")]
16480		    UNSPEC_FPATAN))
16481	      (clobber (match_scratch:SF 3 ""))])]
16482  "TARGET_USE_FANCY_MATH_387
16483   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16484   && flag_unsafe_math_optimizations"
16485{
16486  operands[2] = gen_reg_rtx (SFmode);
16487  emit_move_insn (operands[2], CONST1_RTX (SFmode));  /* fld1 */
16488})
16489
16490(define_insn "atan2xf3_1"
16491  [(set (match_operand:XF 0 "register_operand" "=f")
16492        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16493	            (match_operand:XF 1 "register_operand" "u")]
16494	           UNSPEC_FPATAN))
16495   (clobber (match_scratch:XF 3 "=1"))]
16496  "TARGET_USE_FANCY_MATH_387
16497   && flag_unsafe_math_optimizations"
16498  "fpatan"
16499  [(set_attr "type" "fpspc")
16500   (set_attr "mode" "XF")])
16501
16502(define_expand "atan2xf3"
16503  [(use (match_operand:XF 0 "register_operand" ""))
16504   (use (match_operand:XF 2 "register_operand" ""))
16505   (use (match_operand:XF 1 "register_operand" ""))]
16506  "TARGET_USE_FANCY_MATH_387
16507   && flag_unsafe_math_optimizations"
16508{
16509  rtx copy = gen_reg_rtx (XFmode);
16510  emit_move_insn (copy, operands[1]);
16511  emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16512  DONE;
16513})
16514
16515(define_expand "atanxf2"
16516  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16517		   (unspec:XF [(match_dup 2)
16518			       (match_operand:XF 1 "register_operand" "")]
16519		    UNSPEC_FPATAN))
16520	      (clobber (match_scratch:XF 3 ""))])]
16521  "TARGET_USE_FANCY_MATH_387
16522   && flag_unsafe_math_optimizations"
16523{
16524  operands[2] = gen_reg_rtx (XFmode);
16525  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16526})
16527
16528(define_expand "asindf2"
16529  [(set (match_dup 2)
16530	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16531   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16532   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16533   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16534   (parallel [(set (match_dup 7)
16535        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16536			      UNSPEC_FPATAN))
16537   	      (clobber (match_scratch:XF 8 ""))])
16538   (set (match_operand:DF 0 "register_operand" "")
16539	(float_truncate:DF (match_dup 7)))]
16540  "TARGET_USE_FANCY_MATH_387
16541   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16542   && flag_unsafe_math_optimizations"
16543{
16544  int i;
16545
16546  for (i=2; i<8; i++)
16547    operands[i] = gen_reg_rtx (XFmode);
16548
16549  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16550})
16551
16552(define_expand "asinsf2"
16553  [(set (match_dup 2)
16554	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16555   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16556   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16557   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16558   (parallel [(set (match_dup 7)
16559        	   (unspec:XF [(match_dup 6) (match_dup 2)]
16560			      UNSPEC_FPATAN))
16561   	      (clobber (match_scratch:XF 8 ""))])
16562   (set (match_operand:SF 0 "register_operand" "")
16563	(float_truncate:SF (match_dup 7)))]
16564  "TARGET_USE_FANCY_MATH_387
16565   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16566   && flag_unsafe_math_optimizations"
16567{
16568  int i;
16569
16570  for (i=2; i<8; i++)
16571    operands[i] = gen_reg_rtx (XFmode);
16572
16573  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16574})
16575
16576(define_expand "asinxf2"
16577  [(set (match_dup 2)
16578	(mult:XF (match_operand:XF 1 "register_operand" "")
16579		 (match_dup 1)))
16580   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16581   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16582   (parallel [(set (match_operand:XF 0 "register_operand" "")
16583        	   (unspec:XF [(match_dup 5) (match_dup 1)]
16584			      UNSPEC_FPATAN))
16585   	      (clobber (match_scratch:XF 6 ""))])]
16586  "TARGET_USE_FANCY_MATH_387
16587   && flag_unsafe_math_optimizations"
16588{
16589  int i;
16590
16591  for (i=2; i<6; i++)
16592    operands[i] = gen_reg_rtx (XFmode);
16593
16594  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16595})
16596
16597(define_expand "acosdf2"
16598  [(set (match_dup 2)
16599	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16600   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16601   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16602   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16603   (parallel [(set (match_dup 7)
16604        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16605			      UNSPEC_FPATAN))
16606   	      (clobber (match_scratch:XF 8 ""))])
16607   (set (match_operand:DF 0 "register_operand" "")
16608	(float_truncate:DF (match_dup 7)))]
16609  "TARGET_USE_FANCY_MATH_387
16610   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16611   && flag_unsafe_math_optimizations"
16612{
16613  int i;
16614
16615  for (i=2; i<8; i++)
16616    operands[i] = gen_reg_rtx (XFmode);
16617
16618  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16619})
16620
16621(define_expand "acossf2"
16622  [(set (match_dup 2)
16623	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16624   (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16625   (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16626   (set (match_dup 6) (sqrt:XF (match_dup 5)))
16627   (parallel [(set (match_dup 7)
16628        	   (unspec:XF [(match_dup 2) (match_dup 6)]
16629			      UNSPEC_FPATAN))
16630   	      (clobber (match_scratch:XF 8 ""))])
16631   (set (match_operand:SF 0 "register_operand" "")
16632	(float_truncate:SF (match_dup 7)))]
16633  "TARGET_USE_FANCY_MATH_387
16634   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16635   && flag_unsafe_math_optimizations"
16636{
16637  int i;
16638
16639  for (i=2; i<8; i++)
16640    operands[i] = gen_reg_rtx (XFmode);
16641
16642  emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16643})
16644
16645(define_expand "acosxf2"
16646  [(set (match_dup 2)
16647	(mult:XF (match_operand:XF 1 "register_operand" "")
16648		 (match_dup 1)))
16649   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16650   (set (match_dup 5) (sqrt:XF (match_dup 4)))
16651   (parallel [(set (match_operand:XF 0 "register_operand" "")
16652        	   (unspec:XF [(match_dup 1) (match_dup 5)]
16653			      UNSPEC_FPATAN))
16654   	      (clobber (match_scratch:XF 6 ""))])]
16655  "TARGET_USE_FANCY_MATH_387
16656   && flag_unsafe_math_optimizations"
16657{
16658  int i;
16659
16660  for (i=2; i<6; i++)
16661    operands[i] = gen_reg_rtx (XFmode);
16662
16663  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16664})
16665
16666(define_insn "fyl2x_xf3"
16667  [(set (match_operand:XF 0 "register_operand" "=f")
16668        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16669		    (match_operand:XF 1 "register_operand" "u")]
16670	           UNSPEC_FYL2X))
16671   (clobber (match_scratch:XF 3 "=1"))]
16672  "TARGET_USE_FANCY_MATH_387
16673   && flag_unsafe_math_optimizations"
16674  "fyl2x"
16675  [(set_attr "type" "fpspc")
16676   (set_attr "mode" "XF")])
16677
16678(define_expand "logsf2"
16679  [(set (match_dup 2)
16680	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16681   (parallel [(set (match_dup 4)
16682		   (unspec:XF [(match_dup 2)
16683			       (match_dup 3)] UNSPEC_FYL2X))
16684	      (clobber (match_scratch:XF 5 ""))])
16685   (set (match_operand:SF 0 "register_operand" "")
16686	(float_truncate:SF (match_dup 4)))]
16687  "TARGET_USE_FANCY_MATH_387
16688   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16689   && flag_unsafe_math_optimizations"
16690{
16691  rtx temp;
16692
16693  operands[2] = gen_reg_rtx (XFmode);
16694  operands[3] = gen_reg_rtx (XFmode);
16695  operands[4] = gen_reg_rtx (XFmode);
16696
16697  temp = standard_80387_constant_rtx (4); /* fldln2 */
16698  emit_move_insn (operands[3], temp);
16699})
16700
16701(define_expand "logdf2"
16702  [(set (match_dup 2)
16703	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16704   (parallel [(set (match_dup 4)
16705		   (unspec:XF [(match_dup 2)
16706			       (match_dup 3)] UNSPEC_FYL2X))
16707	      (clobber (match_scratch:XF 5 ""))])
16708   (set (match_operand:DF 0 "register_operand" "")
16709	(float_truncate:DF (match_dup 4)))]
16710  "TARGET_USE_FANCY_MATH_387
16711   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16712   && flag_unsafe_math_optimizations"
16713{
16714  rtx temp;
16715
16716  operands[2] = gen_reg_rtx (XFmode);
16717  operands[3] = gen_reg_rtx (XFmode);
16718  operands[4] = gen_reg_rtx (XFmode);
16719
16720  temp = standard_80387_constant_rtx (4); /* fldln2 */
16721  emit_move_insn (operands[3], temp);
16722})
16723
16724(define_expand "logxf2"
16725  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16726		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16727			       (match_dup 2)] UNSPEC_FYL2X))
16728	      (clobber (match_scratch:XF 3 ""))])]
16729  "TARGET_USE_FANCY_MATH_387
16730   && flag_unsafe_math_optimizations"
16731{
16732  rtx temp;
16733
16734  operands[2] = gen_reg_rtx (XFmode);
16735  temp = standard_80387_constant_rtx (4); /* fldln2 */
16736  emit_move_insn (operands[2], temp);
16737})
16738
16739(define_expand "log10sf2"
16740  [(set (match_dup 2)
16741	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16742   (parallel [(set (match_dup 4)
16743		   (unspec:XF [(match_dup 2)
16744			       (match_dup 3)] UNSPEC_FYL2X))
16745	      (clobber (match_scratch:XF 5 ""))])
16746   (set (match_operand:SF 0 "register_operand" "")
16747	(float_truncate:SF (match_dup 4)))]
16748  "TARGET_USE_FANCY_MATH_387
16749   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16750   && flag_unsafe_math_optimizations"
16751{
16752  rtx temp;
16753
16754  operands[2] = gen_reg_rtx (XFmode);
16755  operands[3] = gen_reg_rtx (XFmode);
16756  operands[4] = gen_reg_rtx (XFmode);
16757
16758  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16759  emit_move_insn (operands[3], temp);
16760})
16761
16762(define_expand "log10df2"
16763  [(set (match_dup 2)
16764	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16765   (parallel [(set (match_dup 4)
16766		   (unspec:XF [(match_dup 2)
16767			       (match_dup 3)] UNSPEC_FYL2X))
16768	      (clobber (match_scratch:XF 5 ""))])
16769   (set (match_operand:DF 0 "register_operand" "")
16770	(float_truncate:DF (match_dup 4)))]
16771  "TARGET_USE_FANCY_MATH_387
16772   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16773   && flag_unsafe_math_optimizations"
16774{
16775  rtx temp;
16776
16777  operands[2] = gen_reg_rtx (XFmode);
16778  operands[3] = gen_reg_rtx (XFmode);
16779  operands[4] = gen_reg_rtx (XFmode);
16780
16781  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16782  emit_move_insn (operands[3], temp);
16783})
16784
16785(define_expand "log10xf2"
16786  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16787		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16788			       (match_dup 2)] UNSPEC_FYL2X))
16789	      (clobber (match_scratch:XF 3 ""))])]
16790  "TARGET_USE_FANCY_MATH_387
16791   && flag_unsafe_math_optimizations"
16792{
16793  rtx temp;
16794
16795  operands[2] = gen_reg_rtx (XFmode);
16796  temp = standard_80387_constant_rtx (3); /* fldlg2 */
16797  emit_move_insn (operands[2], temp);
16798})
16799
16800(define_expand "log2sf2"
16801  [(set (match_dup 2)
16802	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
16803   (parallel [(set (match_dup 4)
16804		   (unspec:XF [(match_dup 2)
16805			       (match_dup 3)] UNSPEC_FYL2X))
16806	      (clobber (match_scratch:XF 5 ""))])
16807   (set (match_operand:SF 0 "register_operand" "")
16808	(float_truncate:SF (match_dup 4)))]
16809  "TARGET_USE_FANCY_MATH_387
16810   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16811   && flag_unsafe_math_optimizations"
16812{
16813  operands[2] = gen_reg_rtx (XFmode);
16814  operands[3] = gen_reg_rtx (XFmode);
16815  operands[4] = gen_reg_rtx (XFmode);
16816
16817  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16818})
16819
16820(define_expand "log2df2"
16821  [(set (match_dup 2)
16822	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16823   (parallel [(set (match_dup 4)
16824		   (unspec:XF [(match_dup 2)
16825			       (match_dup 3)] UNSPEC_FYL2X))
16826	      (clobber (match_scratch:XF 5 ""))])
16827   (set (match_operand:DF 0 "register_operand" "")
16828	(float_truncate:DF (match_dup 4)))]
16829  "TARGET_USE_FANCY_MATH_387
16830   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16831   && flag_unsafe_math_optimizations"
16832{
16833  operands[2] = gen_reg_rtx (XFmode);
16834  operands[3] = gen_reg_rtx (XFmode);
16835  operands[4] = gen_reg_rtx (XFmode);
16836
16837  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16838})
16839
16840(define_expand "log2xf2"
16841  [(parallel [(set (match_operand:XF 0 "register_operand" "")
16842		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
16843			       (match_dup 2)] UNSPEC_FYL2X))
16844	      (clobber (match_scratch:XF 3 ""))])]
16845  "TARGET_USE_FANCY_MATH_387
16846   && flag_unsafe_math_optimizations"
16847{
16848  operands[2] = gen_reg_rtx (XFmode);
16849  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16850})
16851
16852(define_insn "fyl2xp1_xf3"
16853  [(set (match_operand:XF 0 "register_operand" "=f")
16854        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16855		    (match_operand:XF 1 "register_operand" "u")]
16856	           UNSPEC_FYL2XP1))
16857   (clobber (match_scratch:XF 3 "=1"))]
16858  "TARGET_USE_FANCY_MATH_387
16859   && flag_unsafe_math_optimizations"
16860  "fyl2xp1"
16861  [(set_attr "type" "fpspc")
16862   (set_attr "mode" "XF")])
16863
16864(define_expand "log1psf2"
16865  [(use (match_operand:SF 0 "register_operand" ""))
16866   (use (match_operand:SF 1 "register_operand" ""))]
16867  "TARGET_USE_FANCY_MATH_387
16868   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16869   && flag_unsafe_math_optimizations"
16870{
16871  rtx op0 = gen_reg_rtx (XFmode);
16872  rtx op1 = gen_reg_rtx (XFmode);
16873
16874  emit_insn (gen_extendsfxf2 (op1, operands[1]));
16875  ix86_emit_i387_log1p (op0, op1);
16876  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16877  DONE;
16878})
16879
16880(define_expand "log1pdf2"
16881  [(use (match_operand:DF 0 "register_operand" ""))
16882   (use (match_operand:DF 1 "register_operand" ""))]
16883  "TARGET_USE_FANCY_MATH_387
16884   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16885   && flag_unsafe_math_optimizations"
16886{
16887  rtx op0 = gen_reg_rtx (XFmode);
16888  rtx op1 = gen_reg_rtx (XFmode);
16889
16890  emit_insn (gen_extenddfxf2 (op1, operands[1]));
16891  ix86_emit_i387_log1p (op0, op1);
16892  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16893  DONE;
16894})
16895
16896(define_expand "log1pxf2"
16897  [(use (match_operand:XF 0 "register_operand" ""))
16898   (use (match_operand:XF 1 "register_operand" ""))]
16899  "TARGET_USE_FANCY_MATH_387
16900   && flag_unsafe_math_optimizations"
16901{
16902  ix86_emit_i387_log1p (operands[0], operands[1]);
16903  DONE;
16904})
16905
16906(define_insn "*fxtractxf3"
16907  [(set (match_operand:XF 0 "register_operand" "=f")
16908	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16909		   UNSPEC_XTRACT_FRACT))
16910   (set (match_operand:XF 1 "register_operand" "=u")
16911        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16912  "TARGET_USE_FANCY_MATH_387
16913   && flag_unsafe_math_optimizations"
16914  "fxtract"
16915  [(set_attr "type" "fpspc")
16916   (set_attr "mode" "XF")])
16917
16918(define_expand "logbsf2"
16919  [(set (match_dup 2)
16920	(float_extend:XF (match_operand:SF 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:SF 0 "register_operand" "")
16926	(float_truncate:SF (match_dup 4)))]
16927  "TARGET_USE_FANCY_MATH_387
16928   && (!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 "logbdf2"
16937  [(set (match_dup 2)
16938	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
16939   (parallel [(set (match_dup 3)
16940		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16941	      (set (match_dup 4)
16942		   (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16943   (set (match_operand:DF 0 "register_operand" "")
16944	(float_truncate:DF (match_dup 4)))]
16945  "TARGET_USE_FANCY_MATH_387
16946   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16947   && flag_unsafe_math_optimizations"
16948{
16949  operands[2] = gen_reg_rtx (XFmode);
16950  operands[3] = gen_reg_rtx (XFmode);
16951  operands[4] = gen_reg_rtx (XFmode);
16952})
16953
16954(define_expand "logbxf2"
16955  [(parallel [(set (match_dup 2)
16956		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16957			      UNSPEC_XTRACT_FRACT))
16958	      (set (match_operand:XF 0 "register_operand" "")
16959		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16960  "TARGET_USE_FANCY_MATH_387
16961   && flag_unsafe_math_optimizations"
16962{
16963  operands[2] = gen_reg_rtx (XFmode);
16964})
16965
16966(define_expand "ilogbsi2"
16967  [(parallel [(set (match_dup 2)
16968		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16969			      UNSPEC_XTRACT_FRACT))
16970	      (set (match_operand:XF 3 "register_operand" "")
16971		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16972   (parallel [(set (match_operand:SI 0 "register_operand" "")
16973	           (fix:SI (match_dup 3)))
16974	      (clobber (reg:CC FLAGS_REG))])]
16975  "TARGET_USE_FANCY_MATH_387
16976   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16977   && flag_unsafe_math_optimizations"
16978{
16979  operands[2] = gen_reg_rtx (XFmode);
16980  operands[3] = gen_reg_rtx (XFmode);
16981})
16982
16983(define_insn "*f2xm1xf2"
16984  [(set (match_operand:XF 0 "register_operand" "=f")
16985	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16986	 UNSPEC_F2XM1))]
16987  "TARGET_USE_FANCY_MATH_387
16988   && flag_unsafe_math_optimizations"
16989  "f2xm1"
16990  [(set_attr "type" "fpspc")
16991   (set_attr "mode" "XF")])
16992
16993(define_insn "*fscalexf4"
16994  [(set (match_operand:XF 0 "register_operand" "=f")
16995	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
16996		    (match_operand:XF 3 "register_operand" "1")]
16997		   UNSPEC_FSCALE_FRACT))
16998   (set (match_operand:XF 1 "register_operand" "=u")
16999	(unspec:XF [(match_dup 2) (match_dup 3)]
17000		   UNSPEC_FSCALE_EXP))]
17001  "TARGET_USE_FANCY_MATH_387
17002   && flag_unsafe_math_optimizations"
17003  "fscale"
17004  [(set_attr "type" "fpspc")
17005   (set_attr "mode" "XF")])
17006
17007(define_expand "expsf2"
17008  [(set (match_dup 2)
17009	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17010   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17011   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17012   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17013   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17014   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17015   (parallel [(set (match_dup 10)
17016		   (unspec:XF [(match_dup 9) (match_dup 5)]
17017			      UNSPEC_FSCALE_FRACT))
17018	      (set (match_dup 11)
17019		   (unspec:XF [(match_dup 9) (match_dup 5)]
17020			      UNSPEC_FSCALE_EXP))])
17021   (set (match_operand:SF 0 "register_operand" "")
17022	(float_truncate:SF (match_dup 10)))]
17023  "TARGET_USE_FANCY_MATH_387
17024   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17025   && flag_unsafe_math_optimizations"
17026{
17027  rtx temp;
17028  int i;
17029
17030  for (i=2; i<12; i++)
17031    operands[i] = gen_reg_rtx (XFmode);
17032  temp = standard_80387_constant_rtx (5); /* fldl2e */
17033  emit_move_insn (operands[3], temp);
17034  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17035})
17036
17037(define_expand "expdf2"
17038  [(set (match_dup 2)
17039	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17040   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17041   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17042   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17043   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17044   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17045   (parallel [(set (match_dup 10)
17046		   (unspec:XF [(match_dup 9) (match_dup 5)]
17047			      UNSPEC_FSCALE_FRACT))
17048	      (set (match_dup 11)
17049		   (unspec:XF [(match_dup 9) (match_dup 5)]
17050			      UNSPEC_FSCALE_EXP))])
17051   (set (match_operand:DF 0 "register_operand" "")
17052	(float_truncate:DF (match_dup 10)))]
17053  "TARGET_USE_FANCY_MATH_387
17054   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17055   && flag_unsafe_math_optimizations"
17056{
17057  rtx temp;
17058  int i;
17059
17060  for (i=2; i<12; i++)
17061    operands[i] = gen_reg_rtx (XFmode);
17062  temp = standard_80387_constant_rtx (5); /* fldl2e */
17063  emit_move_insn (operands[3], temp);
17064  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17065})
17066
17067(define_expand "expxf2"
17068  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17069			       (match_dup 2)))
17070   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17071   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17072   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17073   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17074   (parallel [(set (match_operand:XF 0 "register_operand" "")
17075		   (unspec:XF [(match_dup 8) (match_dup 4)]
17076			      UNSPEC_FSCALE_FRACT))
17077	      (set (match_dup 9)
17078		   (unspec:XF [(match_dup 8) (match_dup 4)]
17079			      UNSPEC_FSCALE_EXP))])]
17080  "TARGET_USE_FANCY_MATH_387
17081   && flag_unsafe_math_optimizations"
17082{
17083  rtx temp;
17084  int i;
17085
17086  for (i=2; i<10; i++)
17087    operands[i] = gen_reg_rtx (XFmode);
17088  temp = standard_80387_constant_rtx (5); /* fldl2e */
17089  emit_move_insn (operands[2], temp);
17090  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17091})
17092
17093(define_expand "exp10sf2"
17094  [(set (match_dup 2)
17095	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17096   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17097   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17098   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17099   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17100   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17101   (parallel [(set (match_dup 10)
17102		   (unspec:XF [(match_dup 9) (match_dup 5)]
17103			      UNSPEC_FSCALE_FRACT))
17104	      (set (match_dup 11)
17105		   (unspec:XF [(match_dup 9) (match_dup 5)]
17106			      UNSPEC_FSCALE_EXP))])
17107   (set (match_operand:SF 0 "register_operand" "")
17108	(float_truncate:SF (match_dup 10)))]
17109  "TARGET_USE_FANCY_MATH_387
17110   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17111   && flag_unsafe_math_optimizations"
17112{
17113  rtx temp;
17114  int i;
17115
17116  for (i=2; i<12; i++)
17117    operands[i] = gen_reg_rtx (XFmode);
17118  temp = standard_80387_constant_rtx (6); /* fldl2t */
17119  emit_move_insn (operands[3], temp);
17120  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17121})
17122
17123(define_expand "exp10df2"
17124  [(set (match_dup 2)
17125	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17126   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17127   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17128   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17129   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17130   (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
17131   (parallel [(set (match_dup 10)
17132		   (unspec:XF [(match_dup 9) (match_dup 5)]
17133			      UNSPEC_FSCALE_FRACT))
17134	      (set (match_dup 11)
17135		   (unspec:XF [(match_dup 9) (match_dup 5)]
17136			      UNSPEC_FSCALE_EXP))])
17137   (set (match_operand:DF 0 "register_operand" "")
17138	(float_truncate:DF (match_dup 10)))]
17139  "TARGET_USE_FANCY_MATH_387
17140   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17141   && flag_unsafe_math_optimizations"
17142{
17143  rtx temp;
17144  int i;
17145
17146  for (i=2; i<12; i++)
17147    operands[i] = gen_reg_rtx (XFmode);
17148  temp = standard_80387_constant_rtx (6); /* fldl2t */
17149  emit_move_insn (operands[3], temp);
17150  emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
17151})
17152
17153(define_expand "exp10xf2"
17154  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17155			       (match_dup 2)))
17156   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17157   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17158   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17159   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17160   (parallel [(set (match_operand:XF 0 "register_operand" "")
17161		   (unspec:XF [(match_dup 8) (match_dup 4)]
17162			      UNSPEC_FSCALE_FRACT))
17163	      (set (match_dup 9)
17164		   (unspec:XF [(match_dup 8) (match_dup 4)]
17165			      UNSPEC_FSCALE_EXP))])]
17166  "TARGET_USE_FANCY_MATH_387
17167   && flag_unsafe_math_optimizations"
17168{
17169  rtx temp;
17170  int i;
17171
17172  for (i=2; i<10; i++)
17173    operands[i] = gen_reg_rtx (XFmode);
17174  temp = standard_80387_constant_rtx (6); /* fldl2t */
17175  emit_move_insn (operands[2], temp);
17176  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17177})
17178
17179(define_expand "exp2sf2"
17180  [(set (match_dup 2)
17181	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17182   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17183   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17184   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17185   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17186   (parallel [(set (match_dup 8)
17187		   (unspec:XF [(match_dup 7) (match_dup 3)]
17188			      UNSPEC_FSCALE_FRACT))
17189	      (set (match_dup 9)
17190		   (unspec:XF [(match_dup 7) (match_dup 3)]
17191			      UNSPEC_FSCALE_EXP))])
17192   (set (match_operand:SF 0 "register_operand" "")
17193	(float_truncate:SF (match_dup 8)))]
17194  "TARGET_USE_FANCY_MATH_387
17195   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17196   && flag_unsafe_math_optimizations"
17197{
17198  int i;
17199
17200  for (i=2; i<10; i++)
17201    operands[i] = gen_reg_rtx (XFmode);
17202  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17203})
17204
17205(define_expand "exp2df2"
17206  [(set (match_dup 2)
17207	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17208   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17209   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17210   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17211   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17212   (parallel [(set (match_dup 8)
17213		   (unspec:XF [(match_dup 7) (match_dup 3)]
17214			      UNSPEC_FSCALE_FRACT))
17215	      (set (match_dup 9)
17216		   (unspec:XF [(match_dup 7) (match_dup 3)]
17217			      UNSPEC_FSCALE_EXP))])
17218   (set (match_operand:DF 0 "register_operand" "")
17219	(float_truncate:DF (match_dup 8)))]
17220  "TARGET_USE_FANCY_MATH_387
17221   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17222   && flag_unsafe_math_optimizations"
17223{
17224  int i;
17225
17226  for (i=2; i<10; i++)
17227    operands[i] = gen_reg_rtx (XFmode);
17228  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17229})
17230
17231(define_expand "exp2xf2"
17232  [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
17233   (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
17234   (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
17235   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
17236   (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
17237   (parallel [(set (match_operand:XF 0 "register_operand" "")
17238		   (unspec:XF [(match_dup 7) (match_dup 3)]
17239			      UNSPEC_FSCALE_FRACT))
17240	      (set (match_dup 8)
17241		   (unspec:XF [(match_dup 7) (match_dup 3)]
17242			      UNSPEC_FSCALE_EXP))])]
17243  "TARGET_USE_FANCY_MATH_387
17244   && flag_unsafe_math_optimizations"
17245{
17246  int i;
17247
17248  for (i=2; i<9; i++)
17249    operands[i] = gen_reg_rtx (XFmode);
17250  emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
17251})
17252
17253(define_expand "expm1df2"
17254  [(set (match_dup 2)
17255	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17256   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17257   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17258   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17259   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17260   (parallel [(set (match_dup 8)
17261		   (unspec:XF [(match_dup 7) (match_dup 5)]
17262			      UNSPEC_FSCALE_FRACT))
17263		   (set (match_dup 9)
17264		   (unspec:XF [(match_dup 7) (match_dup 5)]
17265			      UNSPEC_FSCALE_EXP))])
17266   (parallel [(set (match_dup 11)
17267		   (unspec:XF [(match_dup 10) (match_dup 9)]
17268			      UNSPEC_FSCALE_FRACT))
17269	      (set (match_dup 12)
17270		   (unspec:XF [(match_dup 10) (match_dup 9)]
17271			      UNSPEC_FSCALE_EXP))])
17272   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17273   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17274   (set (match_operand:DF 0 "register_operand" "")
17275	(float_truncate:DF (match_dup 14)))]
17276  "TARGET_USE_FANCY_MATH_387
17277   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17278   && flag_unsafe_math_optimizations"
17279{
17280  rtx temp;
17281  int i;
17282
17283  for (i=2; i<15; i++)
17284    operands[i] = gen_reg_rtx (XFmode);
17285  temp = standard_80387_constant_rtx (5); /* fldl2e */
17286  emit_move_insn (operands[3], temp);
17287  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17288})
17289
17290(define_expand "expm1sf2"
17291  [(set (match_dup 2)
17292	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17293   (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17294   (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17295   (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17296   (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17297   (parallel [(set (match_dup 8)
17298		   (unspec:XF [(match_dup 7) (match_dup 5)]
17299			      UNSPEC_FSCALE_FRACT))
17300		   (set (match_dup 9)
17301		   (unspec:XF [(match_dup 7) (match_dup 5)]
17302			      UNSPEC_FSCALE_EXP))])
17303   (parallel [(set (match_dup 11)
17304		   (unspec:XF [(match_dup 10) (match_dup 9)]
17305			      UNSPEC_FSCALE_FRACT))
17306	      (set (match_dup 12)
17307		   (unspec:XF [(match_dup 10) (match_dup 9)]
17308			      UNSPEC_FSCALE_EXP))])
17309   (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17310   (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17311   (set (match_operand:SF 0 "register_operand" "")
17312	(float_truncate:SF (match_dup 14)))]
17313  "TARGET_USE_FANCY_MATH_387
17314   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17315   && flag_unsafe_math_optimizations"
17316{
17317  rtx temp;
17318  int i;
17319
17320  for (i=2; i<15; i++)
17321    operands[i] = gen_reg_rtx (XFmode);
17322  temp = standard_80387_constant_rtx (5); /* fldl2e */
17323  emit_move_insn (operands[3], temp);
17324  emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
17325})
17326
17327(define_expand "expm1xf2"
17328  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17329			       (match_dup 2)))
17330   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17331   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17332   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17333   (parallel [(set (match_dup 7)
17334		   (unspec:XF [(match_dup 6) (match_dup 4)]
17335			      UNSPEC_FSCALE_FRACT))
17336		   (set (match_dup 8)
17337		   (unspec:XF [(match_dup 6) (match_dup 4)]
17338			      UNSPEC_FSCALE_EXP))])
17339   (parallel [(set (match_dup 10)
17340		   (unspec:XF [(match_dup 9) (match_dup 8)]
17341			      UNSPEC_FSCALE_FRACT))
17342	      (set (match_dup 11)
17343		   (unspec:XF [(match_dup 9) (match_dup 8)]
17344			      UNSPEC_FSCALE_EXP))])
17345   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17346   (set (match_operand:XF 0 "register_operand" "")
17347	(plus:XF (match_dup 12) (match_dup 7)))]
17348  "TARGET_USE_FANCY_MATH_387
17349   && flag_unsafe_math_optimizations"
17350{
17351  rtx temp;
17352  int i;
17353
17354  for (i=2; i<13; i++)
17355    operands[i] = gen_reg_rtx (XFmode);
17356  temp = standard_80387_constant_rtx (5); /* fldl2e */
17357  emit_move_insn (operands[2], temp);
17358  emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17359})
17360
17361(define_expand "ldexpdf3"
17362  [(set (match_dup 3)
17363	(float_extend:XF (match_operand:DF 1 "register_operand" "")))
17364   (set (match_dup 4)
17365	(float:XF (match_operand:SI 2 "register_operand" "")))
17366   (parallel [(set (match_dup 5)
17367		   (unspec:XF [(match_dup 3) (match_dup 4)]
17368			      UNSPEC_FSCALE_FRACT))
17369	      (set (match_dup 6)
17370		   (unspec:XF [(match_dup 3) (match_dup 4)]
17371			      UNSPEC_FSCALE_EXP))])
17372   (set (match_operand:DF 0 "register_operand" "")
17373	(float_truncate:DF (match_dup 5)))]
17374  "TARGET_USE_FANCY_MATH_387
17375   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17376   && flag_unsafe_math_optimizations"
17377{
17378  int i;
17379
17380  for (i=3; i<7; i++)
17381    operands[i] = gen_reg_rtx (XFmode);
17382})
17383
17384(define_expand "ldexpsf3"
17385  [(set (match_dup 3)
17386	(float_extend:XF (match_operand:SF 1 "register_operand" "")))
17387   (set (match_dup 4)
17388	(float:XF (match_operand:SI 2 "register_operand" "")))
17389   (parallel [(set (match_dup 5)
17390		   (unspec:XF [(match_dup 3) (match_dup 4)]
17391			      UNSPEC_FSCALE_FRACT))
17392	      (set (match_dup 6)
17393		   (unspec:XF [(match_dup 3) (match_dup 4)]
17394			      UNSPEC_FSCALE_EXP))])
17395   (set (match_operand:SF 0 "register_operand" "")
17396	(float_truncate:SF (match_dup 5)))]
17397  "TARGET_USE_FANCY_MATH_387
17398   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17399   && flag_unsafe_math_optimizations"
17400{
17401  int i;
17402
17403  for (i=3; i<7; i++)
17404    operands[i] = gen_reg_rtx (XFmode);
17405})
17406
17407(define_expand "ldexpxf3"
17408  [(set (match_dup 3)
17409	(float:XF (match_operand:SI 2 "register_operand" "")))
17410   (parallel [(set (match_operand:XF 0 " register_operand" "")
17411		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
17412			       (match_dup 3)]
17413			      UNSPEC_FSCALE_FRACT))
17414	      (set (match_dup 4)
17415		   (unspec:XF [(match_dup 1) (match_dup 3)]
17416			      UNSPEC_FSCALE_EXP))])]
17417  "TARGET_USE_FANCY_MATH_387
17418   && flag_unsafe_math_optimizations"
17419{
17420  int i;
17421
17422  for (i=3; i<5; i++)
17423    operands[i] = gen_reg_rtx (XFmode);
17424})
17425
17426
17427(define_insn "frndintxf2"
17428  [(set (match_operand:XF 0 "register_operand" "=f")
17429	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17430	 UNSPEC_FRNDINT))]
17431  "TARGET_USE_FANCY_MATH_387
17432   && flag_unsafe_math_optimizations"
17433  "frndint"
17434  [(set_attr "type" "fpspc")
17435   (set_attr "mode" "XF")])
17436
17437(define_expand "rintdf2"
17438  [(use (match_operand:DF 0 "register_operand" ""))
17439   (use (match_operand:DF 1 "register_operand" ""))]
17440  "TARGET_USE_FANCY_MATH_387
17441   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17442   && flag_unsafe_math_optimizations"
17443{
17444  rtx op0 = gen_reg_rtx (XFmode);
17445  rtx op1 = gen_reg_rtx (XFmode);
17446
17447  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17448  emit_insn (gen_frndintxf2 (op0, op1));
17449
17450  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17451  DONE;
17452})
17453
17454(define_expand "rintsf2"
17455  [(use (match_operand:SF 0 "register_operand" ""))
17456   (use (match_operand:SF 1 "register_operand" ""))]
17457  "TARGET_USE_FANCY_MATH_387
17458   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17459   && flag_unsafe_math_optimizations"
17460{
17461  rtx op0 = gen_reg_rtx (XFmode);
17462  rtx op1 = gen_reg_rtx (XFmode);
17463
17464  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17465  emit_insn (gen_frndintxf2 (op0, op1));
17466
17467  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17468  DONE;
17469})
17470
17471(define_expand "rintxf2"
17472  [(use (match_operand:XF 0 "register_operand" ""))
17473   (use (match_operand:XF 1 "register_operand" ""))]
17474  "TARGET_USE_FANCY_MATH_387
17475   && flag_unsafe_math_optimizations"
17476{
17477  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17478  DONE;
17479})
17480
17481(define_insn_and_split "*fistdi2_1"
17482  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17483	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17484	 UNSPEC_FIST))]
17485  "TARGET_USE_FANCY_MATH_387
17486   && flag_unsafe_math_optimizations
17487   && !(reload_completed || reload_in_progress)"
17488  "#"
17489  "&& 1"
17490  [(const_int 0)]
17491{
17492  if (memory_operand (operands[0], VOIDmode))
17493    emit_insn (gen_fistdi2 (operands[0], operands[1]));
17494  else
17495    {
17496      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17497      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17498					 operands[2]));
17499    }
17500  DONE;
17501}
17502  [(set_attr "type" "fpspc")
17503   (set_attr "mode" "DI")])
17504
17505(define_insn "fistdi2"
17506  [(set (match_operand:DI 0 "memory_operand" "=m")
17507	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17508	 UNSPEC_FIST))
17509   (clobber (match_scratch:XF 2 "=&1f"))]
17510  "TARGET_USE_FANCY_MATH_387
17511   && flag_unsafe_math_optimizations"
17512  "* return output_fix_trunc (insn, operands, 0);"
17513  [(set_attr "type" "fpspc")
17514   (set_attr "mode" "DI")])
17515
17516(define_insn "fistdi2_with_temp"
17517  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17518	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17519	 UNSPEC_FIST))
17520   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17521   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17522  "TARGET_USE_FANCY_MATH_387
17523   && flag_unsafe_math_optimizations"
17524  "#"
17525  [(set_attr "type" "fpspc")
17526   (set_attr "mode" "DI")])
17527
17528(define_split
17529  [(set (match_operand:DI 0 "register_operand" "")
17530	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17531	 UNSPEC_FIST))
17532   (clobber (match_operand:DI 2 "memory_operand" ""))
17533   (clobber (match_scratch 3 ""))]
17534  "reload_completed"
17535  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17536	      (clobber (match_dup 3))])
17537   (set (match_dup 0) (match_dup 2))]
17538  "")
17539
17540(define_split
17541  [(set (match_operand:DI 0 "memory_operand" "")
17542	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17543	 UNSPEC_FIST))
17544   (clobber (match_operand:DI 2 "memory_operand" ""))
17545   (clobber (match_scratch 3 ""))]
17546  "reload_completed"
17547  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17548	      (clobber (match_dup 3))])]
17549  "")
17550
17551(define_insn_and_split "*fist<mode>2_1"
17552  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17553	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17554	 UNSPEC_FIST))]
17555  "TARGET_USE_FANCY_MATH_387
17556   && flag_unsafe_math_optimizations
17557   && !(reload_completed || reload_in_progress)"
17558  "#"
17559  "&& 1"
17560  [(const_int 0)]
17561{
17562  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17563  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17564					operands[2]));
17565  DONE;
17566}
17567  [(set_attr "type" "fpspc")
17568   (set_attr "mode" "<MODE>")])
17569
17570(define_insn "fist<mode>2"
17571  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17572	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17573	 UNSPEC_FIST))]
17574  "TARGET_USE_FANCY_MATH_387
17575   && flag_unsafe_math_optimizations"
17576  "* return output_fix_trunc (insn, operands, 0);"
17577  [(set_attr "type" "fpspc")
17578   (set_attr "mode" "<MODE>")])
17579
17580(define_insn "fist<mode>2_with_temp"
17581  [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17582	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17583	 UNSPEC_FIST))
17584   (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17585  "TARGET_USE_FANCY_MATH_387
17586   && flag_unsafe_math_optimizations"
17587  "#"
17588  [(set_attr "type" "fpspc")
17589   (set_attr "mode" "<MODE>")])
17590
17591(define_split
17592  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17593	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17594	 UNSPEC_FIST))
17595   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17596  "reload_completed"
17597  [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17598		       UNSPEC_FIST))
17599   (set (match_dup 0) (match_dup 2))]
17600  "")
17601
17602(define_split
17603  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17604	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17605	 UNSPEC_FIST))
17606   (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17607  "reload_completed"
17608  [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17609		       UNSPEC_FIST))]
17610  "")
17611
17612(define_expand "lrint<mode>2"
17613  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17614	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17615	 UNSPEC_FIST))]
17616  "TARGET_USE_FANCY_MATH_387
17617   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17618   && flag_unsafe_math_optimizations"
17619  "")
17620
17621;; Rounding mode control word calculation could clobber FLAGS_REG.
17622(define_insn_and_split "frndintxf2_floor"
17623  [(set (match_operand:XF 0 "register_operand" "=f")
17624	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17625	 UNSPEC_FRNDINT_FLOOR))
17626   (clobber (reg:CC FLAGS_REG))]
17627  "TARGET_USE_FANCY_MATH_387
17628   && flag_unsafe_math_optimizations
17629   && !(reload_completed || reload_in_progress)"
17630  "#"
17631  "&& 1"
17632  [(const_int 0)]
17633{
17634  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17635
17636  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17637  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17638
17639  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17640					operands[2], operands[3]));
17641  DONE;
17642}
17643  [(set_attr "type" "frndint")
17644   (set_attr "i387_cw" "floor")
17645   (set_attr "mode" "XF")])
17646
17647(define_insn "frndintxf2_floor_i387"
17648  [(set (match_operand:XF 0 "register_operand" "=f")
17649	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17650	 UNSPEC_FRNDINT_FLOOR))
17651   (use (match_operand:HI 2 "memory_operand" "m"))
17652   (use (match_operand:HI 3 "memory_operand" "m"))]
17653  "TARGET_USE_FANCY_MATH_387
17654   && flag_unsafe_math_optimizations"
17655  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17656  [(set_attr "type" "frndint")
17657   (set_attr "i387_cw" "floor")
17658   (set_attr "mode" "XF")])
17659
17660(define_expand "floorxf2"
17661  [(use (match_operand:XF 0 "register_operand" ""))
17662   (use (match_operand:XF 1 "register_operand" ""))]
17663  "TARGET_USE_FANCY_MATH_387
17664   && flag_unsafe_math_optimizations"
17665{
17666  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17667  DONE;
17668})
17669
17670(define_expand "floordf2"
17671  [(use (match_operand:DF 0 "register_operand" ""))
17672   (use (match_operand:DF 1 "register_operand" ""))]
17673  "TARGET_USE_FANCY_MATH_387
17674   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17675   && flag_unsafe_math_optimizations"
17676{
17677  rtx op0 = gen_reg_rtx (XFmode);
17678  rtx op1 = gen_reg_rtx (XFmode);
17679
17680  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17681  emit_insn (gen_frndintxf2_floor (op0, op1));
17682
17683  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17684  DONE;
17685})
17686
17687(define_expand "floorsf2"
17688  [(use (match_operand:SF 0 "register_operand" ""))
17689   (use (match_operand:SF 1 "register_operand" ""))]
17690  "TARGET_USE_FANCY_MATH_387
17691   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17692   && flag_unsafe_math_optimizations"
17693{
17694  rtx op0 = gen_reg_rtx (XFmode);
17695  rtx op1 = gen_reg_rtx (XFmode);
17696
17697  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17698  emit_insn (gen_frndintxf2_floor (op0, op1));
17699
17700  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17701  DONE;
17702})
17703
17704(define_insn_and_split "*fist<mode>2_floor_1"
17705  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17706	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17707	 UNSPEC_FIST_FLOOR))
17708   (clobber (reg:CC FLAGS_REG))]
17709  "TARGET_USE_FANCY_MATH_387
17710   && flag_unsafe_math_optimizations
17711   && !(reload_completed || reload_in_progress)"
17712  "#"
17713  "&& 1"
17714  [(const_int 0)]
17715{
17716  ix86_optimize_mode_switching[I387_FLOOR] = 1;
17717
17718  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17719  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17720  if (memory_operand (operands[0], VOIDmode))
17721    emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17722				      operands[2], operands[3]));
17723  else
17724    {
17725      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17726      emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17727						  operands[2], operands[3],
17728						  operands[4]));
17729    }
17730  DONE;
17731}
17732  [(set_attr "type" "fistp")
17733   (set_attr "i387_cw" "floor")
17734   (set_attr "mode" "<MODE>")])
17735
17736(define_insn "fistdi2_floor"
17737  [(set (match_operand:DI 0 "memory_operand" "=m")
17738	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17739	 UNSPEC_FIST_FLOOR))
17740   (use (match_operand:HI 2 "memory_operand" "m"))
17741   (use (match_operand:HI 3 "memory_operand" "m"))
17742   (clobber (match_scratch:XF 4 "=&1f"))]
17743  "TARGET_USE_FANCY_MATH_387
17744   && flag_unsafe_math_optimizations"
17745  "* return output_fix_trunc (insn, operands, 0);"
17746  [(set_attr "type" "fistp")
17747   (set_attr "i387_cw" "floor")
17748   (set_attr "mode" "DI")])
17749
17750(define_insn "fistdi2_floor_with_temp"
17751  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17752	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17753	 UNSPEC_FIST_FLOOR))
17754   (use (match_operand:HI 2 "memory_operand" "m,m"))
17755   (use (match_operand:HI 3 "memory_operand" "m,m"))
17756   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17757   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17758  "TARGET_USE_FANCY_MATH_387
17759   && flag_unsafe_math_optimizations"
17760  "#"
17761  [(set_attr "type" "fistp")
17762   (set_attr "i387_cw" "floor")
17763   (set_attr "mode" "DI")])
17764
17765(define_split
17766  [(set (match_operand:DI 0 "register_operand" "")
17767	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17768	 UNSPEC_FIST_FLOOR))
17769   (use (match_operand:HI 2 "memory_operand" ""))
17770   (use (match_operand:HI 3 "memory_operand" ""))
17771   (clobber (match_operand:DI 4 "memory_operand" ""))
17772   (clobber (match_scratch 5 ""))]
17773  "reload_completed"
17774  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17775	      (use (match_dup 2))
17776	      (use (match_dup 3))
17777	      (clobber (match_dup 5))])
17778   (set (match_dup 0) (match_dup 4))]
17779  "")
17780
17781(define_split
17782  [(set (match_operand:DI 0 "memory_operand" "")
17783	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
17784	 UNSPEC_FIST_FLOOR))
17785   (use (match_operand:HI 2 "memory_operand" ""))
17786   (use (match_operand:HI 3 "memory_operand" ""))
17787   (clobber (match_operand:DI 4 "memory_operand" ""))
17788   (clobber (match_scratch 5 ""))]
17789  "reload_completed"
17790  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17791	      (use (match_dup 2))
17792	      (use (match_dup 3))
17793	      (clobber (match_dup 5))])]
17794  "")
17795
17796(define_insn "fist<mode>2_floor"
17797  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17798	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17799	 UNSPEC_FIST_FLOOR))
17800   (use (match_operand:HI 2 "memory_operand" "m"))
17801   (use (match_operand:HI 3 "memory_operand" "m"))]
17802  "TARGET_USE_FANCY_MATH_387
17803   && flag_unsafe_math_optimizations"
17804  "* return output_fix_trunc (insn, operands, 0);"
17805  [(set_attr "type" "fistp")
17806   (set_attr "i387_cw" "floor")
17807   (set_attr "mode" "<MODE>")])
17808
17809(define_insn "fist<mode>2_floor_with_temp"
17810  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17811	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17812	 UNSPEC_FIST_FLOOR))
17813   (use (match_operand:HI 2 "memory_operand" "m,m"))
17814   (use (match_operand:HI 3 "memory_operand" "m,m"))
17815   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17816  "TARGET_USE_FANCY_MATH_387
17817   && flag_unsafe_math_optimizations"
17818  "#"
17819  [(set_attr "type" "fistp")
17820   (set_attr "i387_cw" "floor")
17821   (set_attr "mode" "<MODE>")])
17822
17823(define_split
17824  [(set (match_operand:X87MODEI12 0 "register_operand" "")
17825	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17826	 UNSPEC_FIST_FLOOR))
17827   (use (match_operand:HI 2 "memory_operand" ""))
17828   (use (match_operand:HI 3 "memory_operand" ""))
17829   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17830  "reload_completed"
17831  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17832				  UNSPEC_FIST_FLOOR))
17833	      (use (match_dup 2))
17834	      (use (match_dup 3))])
17835   (set (match_dup 0) (match_dup 4))]
17836  "")
17837
17838(define_split
17839  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17840	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17841	 UNSPEC_FIST_FLOOR))
17842   (use (match_operand:HI 2 "memory_operand" ""))
17843   (use (match_operand:HI 3 "memory_operand" ""))
17844   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17845  "reload_completed"
17846  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17847				  UNSPEC_FIST_FLOOR))
17848	      (use (match_dup 2))
17849	      (use (match_dup 3))])]
17850  "")
17851
17852(define_expand "lfloor<mode>2"
17853  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17854		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17855		    UNSPEC_FIST_FLOOR))
17856	      (clobber (reg:CC FLAGS_REG))])]
17857  "TARGET_USE_FANCY_MATH_387
17858   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17859   && flag_unsafe_math_optimizations"
17860  "")
17861
17862;; Rounding mode control word calculation could clobber FLAGS_REG.
17863(define_insn_and_split "frndintxf2_ceil"
17864  [(set (match_operand:XF 0 "register_operand" "=f")
17865	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17866	 UNSPEC_FRNDINT_CEIL))
17867   (clobber (reg:CC FLAGS_REG))]
17868  "TARGET_USE_FANCY_MATH_387
17869   && flag_unsafe_math_optimizations
17870   && !(reload_completed || reload_in_progress)"
17871  "#"
17872  "&& 1"
17873  [(const_int 0)]
17874{
17875  ix86_optimize_mode_switching[I387_CEIL] = 1;
17876
17877  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17878  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17879
17880  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17881				       operands[2], operands[3]));
17882  DONE;
17883}
17884  [(set_attr "type" "frndint")
17885   (set_attr "i387_cw" "ceil")
17886   (set_attr "mode" "XF")])
17887
17888(define_insn "frndintxf2_ceil_i387"
17889  [(set (match_operand:XF 0 "register_operand" "=f")
17890	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17891	 UNSPEC_FRNDINT_CEIL))
17892   (use (match_operand:HI 2 "memory_operand" "m"))
17893   (use (match_operand:HI 3 "memory_operand" "m"))]
17894  "TARGET_USE_FANCY_MATH_387
17895   && flag_unsafe_math_optimizations"
17896  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17897  [(set_attr "type" "frndint")
17898   (set_attr "i387_cw" "ceil")
17899   (set_attr "mode" "XF")])
17900
17901(define_expand "ceilxf2"
17902  [(use (match_operand:XF 0 "register_operand" ""))
17903   (use (match_operand:XF 1 "register_operand" ""))]
17904  "TARGET_USE_FANCY_MATH_387
17905   && flag_unsafe_math_optimizations"
17906{
17907  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17908  DONE;
17909})
17910
17911(define_expand "ceildf2"
17912  [(use (match_operand:DF 0 "register_operand" ""))
17913   (use (match_operand:DF 1 "register_operand" ""))]
17914  "TARGET_USE_FANCY_MATH_387
17915   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17916   && flag_unsafe_math_optimizations"
17917{
17918  rtx op0 = gen_reg_rtx (XFmode);
17919  rtx op1 = gen_reg_rtx (XFmode);
17920
17921  emit_insn (gen_extenddfxf2 (op1, operands[1]));
17922  emit_insn (gen_frndintxf2_ceil (op0, op1));
17923
17924  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17925  DONE;
17926})
17927
17928(define_expand "ceilsf2"
17929  [(use (match_operand:SF 0 "register_operand" ""))
17930   (use (match_operand:SF 1 "register_operand" ""))]
17931  "TARGET_USE_FANCY_MATH_387
17932   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17933   && flag_unsafe_math_optimizations"
17934{
17935  rtx op0 = gen_reg_rtx (XFmode);
17936  rtx op1 = gen_reg_rtx (XFmode);
17937
17938  emit_insn (gen_extendsfxf2 (op1, operands[1]));
17939  emit_insn (gen_frndintxf2_ceil (op0, op1));
17940
17941  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17942  DONE;
17943})
17944
17945(define_insn_and_split "*fist<mode>2_ceil_1"
17946  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17947	(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17948	 UNSPEC_FIST_CEIL))
17949   (clobber (reg:CC FLAGS_REG))]
17950  "TARGET_USE_FANCY_MATH_387
17951   && flag_unsafe_math_optimizations
17952   && !(reload_completed || reload_in_progress)"
17953  "#"
17954  "&& 1"
17955  [(const_int 0)]
17956{
17957  ix86_optimize_mode_switching[I387_CEIL] = 1;
17958
17959  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17960  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17961  if (memory_operand (operands[0], VOIDmode))
17962    emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17963				     operands[2], operands[3]));
17964  else
17965    {
17966      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17967      emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17968						 operands[2], operands[3],
17969						 operands[4]));
17970    }
17971  DONE;
17972}
17973  [(set_attr "type" "fistp")
17974   (set_attr "i387_cw" "ceil")
17975   (set_attr "mode" "<MODE>")])
17976
17977(define_insn "fistdi2_ceil"
17978  [(set (match_operand:DI 0 "memory_operand" "=m")
17979	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17980	 UNSPEC_FIST_CEIL))
17981   (use (match_operand:HI 2 "memory_operand" "m"))
17982   (use (match_operand:HI 3 "memory_operand" "m"))
17983   (clobber (match_scratch:XF 4 "=&1f"))]
17984  "TARGET_USE_FANCY_MATH_387
17985   && flag_unsafe_math_optimizations"
17986  "* return output_fix_trunc (insn, operands, 0);"
17987  [(set_attr "type" "fistp")
17988   (set_attr "i387_cw" "ceil")
17989   (set_attr "mode" "DI")])
17990
17991(define_insn "fistdi2_ceil_with_temp"
17992  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17993	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17994	 UNSPEC_FIST_CEIL))
17995   (use (match_operand:HI 2 "memory_operand" "m,m"))
17996   (use (match_operand:HI 3 "memory_operand" "m,m"))
17997   (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17998   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17999  "TARGET_USE_FANCY_MATH_387
18000   && flag_unsafe_math_optimizations"
18001  "#"
18002  [(set_attr "type" "fistp")
18003   (set_attr "i387_cw" "ceil")
18004   (set_attr "mode" "DI")])
18005
18006(define_split
18007  [(set (match_operand:DI 0 "register_operand" "")
18008	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
18009	 UNSPEC_FIST_CEIL))
18010   (use (match_operand:HI 2 "memory_operand" ""))
18011   (use (match_operand:HI 3 "memory_operand" ""))
18012   (clobber (match_operand:DI 4 "memory_operand" ""))
18013   (clobber (match_scratch 5 ""))]
18014  "reload_completed"
18015  [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18016	      (use (match_dup 2))
18017	      (use (match_dup 3))
18018	      (clobber (match_dup 5))])
18019   (set (match_dup 0) (match_dup 4))]
18020  "")
18021
18022(define_split
18023  [(set (match_operand:DI 0 "memory_operand" "")
18024	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
18025	 UNSPEC_FIST_CEIL))
18026   (use (match_operand:HI 2 "memory_operand" ""))
18027   (use (match_operand:HI 3 "memory_operand" ""))
18028   (clobber (match_operand:DI 4 "memory_operand" ""))
18029   (clobber (match_scratch 5 ""))]
18030  "reload_completed"
18031  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18032	      (use (match_dup 2))
18033	      (use (match_dup 3))
18034	      (clobber (match_dup 5))])]
18035  "")
18036
18037(define_insn "fist<mode>2_ceil"
18038  [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18039	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18040	 UNSPEC_FIST_CEIL))
18041   (use (match_operand:HI 2 "memory_operand" "m"))
18042   (use (match_operand:HI 3 "memory_operand" "m"))]
18043  "TARGET_USE_FANCY_MATH_387
18044   && flag_unsafe_math_optimizations"
18045  "* return output_fix_trunc (insn, operands, 0);"
18046  [(set_attr "type" "fistp")
18047   (set_attr "i387_cw" "ceil")
18048   (set_attr "mode" "<MODE>")])
18049
18050(define_insn "fist<mode>2_ceil_with_temp"
18051  [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18052	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18053	 UNSPEC_FIST_CEIL))
18054   (use (match_operand:HI 2 "memory_operand" "m,m"))
18055   (use (match_operand:HI 3 "memory_operand" "m,m"))
18056   (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18057  "TARGET_USE_FANCY_MATH_387
18058   && flag_unsafe_math_optimizations"
18059  "#"
18060  [(set_attr "type" "fistp")
18061   (set_attr "i387_cw" "ceil")
18062   (set_attr "mode" "<MODE>")])
18063
18064(define_split
18065  [(set (match_operand:X87MODEI12 0 "register_operand" "")
18066	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18067	 UNSPEC_FIST_CEIL))
18068   (use (match_operand:HI 2 "memory_operand" ""))
18069   (use (match_operand:HI 3 "memory_operand" ""))
18070   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18071  "reload_completed"
18072  [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18073				  UNSPEC_FIST_CEIL))
18074	      (use (match_dup 2))
18075	      (use (match_dup 3))])
18076   (set (match_dup 0) (match_dup 4))]
18077  "")
18078
18079(define_split
18080  [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18081	(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18082	 UNSPEC_FIST_CEIL))
18083   (use (match_operand:HI 2 "memory_operand" ""))
18084   (use (match_operand:HI 3 "memory_operand" ""))
18085   (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18086  "reload_completed"
18087  [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18088				  UNSPEC_FIST_CEIL))
18089	      (use (match_dup 2))
18090	      (use (match_dup 3))])]
18091  "")
18092
18093(define_expand "lceil<mode>2"
18094  [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18095		   (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18096		    UNSPEC_FIST_CEIL))
18097	      (clobber (reg:CC FLAGS_REG))])]
18098  "TARGET_USE_FANCY_MATH_387
18099   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18100   && flag_unsafe_math_optimizations"
18101  "")
18102
18103;; Rounding mode control word calculation could clobber FLAGS_REG.
18104(define_insn_and_split "frndintxf2_trunc"
18105  [(set (match_operand:XF 0 "register_operand" "=f")
18106	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18107	 UNSPEC_FRNDINT_TRUNC))
18108   (clobber (reg:CC FLAGS_REG))]
18109  "TARGET_USE_FANCY_MATH_387
18110   && flag_unsafe_math_optimizations
18111   && !(reload_completed || reload_in_progress)"
18112  "#"
18113  "&& 1"
18114  [(const_int 0)]
18115{
18116  ix86_optimize_mode_switching[I387_TRUNC] = 1;
18117
18118  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18119  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18120
18121  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18122					operands[2], operands[3]));
18123  DONE;
18124}
18125  [(set_attr "type" "frndint")
18126   (set_attr "i387_cw" "trunc")
18127   (set_attr "mode" "XF")])
18128
18129(define_insn "frndintxf2_trunc_i387"
18130  [(set (match_operand:XF 0 "register_operand" "=f")
18131	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18132	 UNSPEC_FRNDINT_TRUNC))
18133   (use (match_operand:HI 2 "memory_operand" "m"))
18134   (use (match_operand:HI 3 "memory_operand" "m"))]
18135  "TARGET_USE_FANCY_MATH_387
18136   && flag_unsafe_math_optimizations"
18137  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18138  [(set_attr "type" "frndint")
18139   (set_attr "i387_cw" "trunc")
18140   (set_attr "mode" "XF")])
18141
18142(define_expand "btruncxf2"
18143  [(use (match_operand:XF 0 "register_operand" ""))
18144   (use (match_operand:XF 1 "register_operand" ""))]
18145  "TARGET_USE_FANCY_MATH_387
18146   && flag_unsafe_math_optimizations"
18147{
18148  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18149  DONE;
18150})
18151
18152(define_expand "btruncdf2"
18153  [(use (match_operand:DF 0 "register_operand" ""))
18154   (use (match_operand:DF 1 "register_operand" ""))]
18155  "TARGET_USE_FANCY_MATH_387
18156   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18157   && flag_unsafe_math_optimizations"
18158{
18159  rtx op0 = gen_reg_rtx (XFmode);
18160  rtx op1 = gen_reg_rtx (XFmode);
18161
18162  emit_insn (gen_extenddfxf2 (op1, operands[1]));
18163  emit_insn (gen_frndintxf2_trunc (op0, op1));
18164
18165  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18166  DONE;
18167})
18168
18169(define_expand "btruncsf2"
18170  [(use (match_operand:SF 0 "register_operand" ""))
18171   (use (match_operand:SF 1 "register_operand" ""))]
18172  "TARGET_USE_FANCY_MATH_387
18173   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18174   && flag_unsafe_math_optimizations"
18175{
18176  rtx op0 = gen_reg_rtx (XFmode);
18177  rtx op1 = gen_reg_rtx (XFmode);
18178
18179  emit_insn (gen_extendsfxf2 (op1, operands[1]));
18180  emit_insn (gen_frndintxf2_trunc (op0, op1));
18181
18182  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18183  DONE;
18184})
18185
18186;; Rounding mode control word calculation could clobber FLAGS_REG.
18187(define_insn_and_split "frndintxf2_mask_pm"
18188  [(set (match_operand:XF 0 "register_operand" "=f")
18189	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18190	 UNSPEC_FRNDINT_MASK_PM))
18191   (clobber (reg:CC FLAGS_REG))]
18192  "TARGET_USE_FANCY_MATH_387
18193   && flag_unsafe_math_optimizations
18194   && !(reload_completed || reload_in_progress)"
18195  "#"
18196  "&& 1"
18197  [(const_int 0)]
18198{
18199  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18200
18201  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18202  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18203
18204  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18205					  operands[2], operands[3]));
18206  DONE;
18207}
18208  [(set_attr "type" "frndint")
18209   (set_attr "i387_cw" "mask_pm")
18210   (set_attr "mode" "XF")])
18211
18212(define_insn "frndintxf2_mask_pm_i387"
18213  [(set (match_operand:XF 0 "register_operand" "=f")
18214	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18215	 UNSPEC_FRNDINT_MASK_PM))
18216   (use (match_operand:HI 2 "memory_operand" "m"))
18217   (use (match_operand:HI 3 "memory_operand" "m"))]
18218  "TARGET_USE_FANCY_MATH_387
18219   && flag_unsafe_math_optimizations"
18220  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18221  [(set_attr "type" "frndint")
18222   (set_attr "i387_cw" "mask_pm")
18223   (set_attr "mode" "XF")])
18224
18225(define_expand "nearbyintxf2"
18226  [(use (match_operand:XF 0 "register_operand" ""))
18227   (use (match_operand:XF 1 "register_operand" ""))]
18228  "TARGET_USE_FANCY_MATH_387
18229   && flag_unsafe_math_optimizations"
18230{
18231  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18232
18233  DONE;
18234})
18235
18236(define_expand "nearbyintdf2"
18237  [(use (match_operand:DF 0 "register_operand" ""))
18238   (use (match_operand:DF 1 "register_operand" ""))]
18239  "TARGET_USE_FANCY_MATH_387
18240   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18241   && flag_unsafe_math_optimizations"
18242{
18243  rtx op0 = gen_reg_rtx (XFmode);
18244  rtx op1 = gen_reg_rtx (XFmode);
18245
18246  emit_insn (gen_extenddfxf2 (op1, operands[1]));
18247  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18248
18249  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18250  DONE;
18251})
18252
18253(define_expand "nearbyintsf2"
18254  [(use (match_operand:SF 0 "register_operand" ""))
18255   (use (match_operand:SF 1 "register_operand" ""))]
18256  "TARGET_USE_FANCY_MATH_387
18257   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18258   && flag_unsafe_math_optimizations"
18259{
18260  rtx op0 = gen_reg_rtx (XFmode);
18261  rtx op1 = gen_reg_rtx (XFmode);
18262
18263  emit_insn (gen_extendsfxf2 (op1, operands[1]));
18264  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18265
18266  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18267  DONE;
18268})
18269
18270
18271;; Block operation instructions
18272
18273(define_insn "cld"
18274 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18275 ""
18276 "cld"
18277  [(set_attr "type" "cld")])
18278
18279(define_expand "movmemsi"
18280  [(use (match_operand:BLK 0 "memory_operand" ""))
18281   (use (match_operand:BLK 1 "memory_operand" ""))
18282   (use (match_operand:SI 2 "nonmemory_operand" ""))
18283   (use (match_operand:SI 3 "const_int_operand" ""))]
18284  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18285{
18286 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18287   DONE;
18288 else
18289   FAIL;
18290})
18291
18292(define_expand "movmemdi"
18293  [(use (match_operand:BLK 0 "memory_operand" ""))
18294   (use (match_operand:BLK 1 "memory_operand" ""))
18295   (use (match_operand:DI 2 "nonmemory_operand" ""))
18296   (use (match_operand:DI 3 "const_int_operand" ""))]
18297  "TARGET_64BIT"
18298{
18299 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18300   DONE;
18301 else
18302   FAIL;
18303})
18304
18305;; Most CPUs don't like single string operations
18306;; Handle this case here to simplify previous expander.
18307
18308(define_expand "strmov"
18309  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18310   (set (match_operand 1 "memory_operand" "") (match_dup 4))
18311   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18312	      (clobber (reg:CC FLAGS_REG))])
18313   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18314	      (clobber (reg:CC FLAGS_REG))])]
18315  ""
18316{
18317  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18318
18319  /* If .md ever supports :P for Pmode, these can be directly
18320     in the pattern above.  */
18321  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18322  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18323
18324  if (TARGET_SINGLE_STRINGOP || optimize_size)
18325    {
18326      emit_insn (gen_strmov_singleop (operands[0], operands[1],
18327				      operands[2], operands[3],
18328				      operands[5], operands[6]));
18329      DONE;
18330    }
18331
18332  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18333})
18334
18335(define_expand "strmov_singleop"
18336  [(parallel [(set (match_operand 1 "memory_operand" "")
18337		   (match_operand 3 "memory_operand" ""))
18338	      (set (match_operand 0 "register_operand" "")
18339		   (match_operand 4 "" ""))
18340	      (set (match_operand 2 "register_operand" "")
18341		   (match_operand 5 "" ""))
18342	      (use (reg:SI DIRFLAG_REG))])]
18343  "TARGET_SINGLE_STRINGOP || optimize_size"
18344  "")
18345
18346(define_insn "*strmovdi_rex_1"
18347  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18348	(mem:DI (match_operand:DI 3 "register_operand" "1")))
18349   (set (match_operand:DI 0 "register_operand" "=D")
18350	(plus:DI (match_dup 2)
18351		 (const_int 8)))
18352   (set (match_operand:DI 1 "register_operand" "=S")
18353	(plus:DI (match_dup 3)
18354		 (const_int 8)))
18355   (use (reg:SI DIRFLAG_REG))]
18356  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18357  "movsq"
18358  [(set_attr "type" "str")
18359   (set_attr "mode" "DI")
18360   (set_attr "memory" "both")])
18361
18362(define_insn "*strmovsi_1"
18363  [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18364	(mem:SI (match_operand:SI 3 "register_operand" "1")))
18365   (set (match_operand:SI 0 "register_operand" "=D")
18366	(plus:SI (match_dup 2)
18367		 (const_int 4)))
18368   (set (match_operand:SI 1 "register_operand" "=S")
18369	(plus:SI (match_dup 3)
18370		 (const_int 4)))
18371   (use (reg:SI DIRFLAG_REG))]
18372  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18373  "{movsl|movsd}"
18374  [(set_attr "type" "str")
18375   (set_attr "mode" "SI")
18376   (set_attr "memory" "both")])
18377
18378(define_insn "*strmovsi_rex_1"
18379  [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18380	(mem:SI (match_operand:DI 3 "register_operand" "1")))
18381   (set (match_operand:DI 0 "register_operand" "=D")
18382	(plus:DI (match_dup 2)
18383		 (const_int 4)))
18384   (set (match_operand:DI 1 "register_operand" "=S")
18385	(plus:DI (match_dup 3)
18386		 (const_int 4)))
18387   (use (reg:SI DIRFLAG_REG))]
18388  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18389  "{movsl|movsd}"
18390  [(set_attr "type" "str")
18391   (set_attr "mode" "SI")
18392   (set_attr "memory" "both")])
18393
18394(define_insn "*strmovhi_1"
18395  [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18396	(mem:HI (match_operand:SI 3 "register_operand" "1")))
18397   (set (match_operand:SI 0 "register_operand" "=D")
18398	(plus:SI (match_dup 2)
18399		 (const_int 2)))
18400   (set (match_operand:SI 1 "register_operand" "=S")
18401	(plus:SI (match_dup 3)
18402		 (const_int 2)))
18403   (use (reg:SI DIRFLAG_REG))]
18404  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18405  "movsw"
18406  [(set_attr "type" "str")
18407   (set_attr "memory" "both")
18408   (set_attr "mode" "HI")])
18409
18410(define_insn "*strmovhi_rex_1"
18411  [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18412	(mem:HI (match_operand:DI 3 "register_operand" "1")))
18413   (set (match_operand:DI 0 "register_operand" "=D")
18414	(plus:DI (match_dup 2)
18415		 (const_int 2)))
18416   (set (match_operand:DI 1 "register_operand" "=S")
18417	(plus:DI (match_dup 3)
18418		 (const_int 2)))
18419   (use (reg:SI DIRFLAG_REG))]
18420  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18421  "movsw"
18422  [(set_attr "type" "str")
18423   (set_attr "memory" "both")
18424   (set_attr "mode" "HI")])
18425
18426(define_insn "*strmovqi_1"
18427  [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18428	(mem:QI (match_operand:SI 3 "register_operand" "1")))
18429   (set (match_operand:SI 0 "register_operand" "=D")
18430	(plus:SI (match_dup 2)
18431		 (const_int 1)))
18432   (set (match_operand:SI 1 "register_operand" "=S")
18433	(plus:SI (match_dup 3)
18434		 (const_int 1)))
18435   (use (reg:SI DIRFLAG_REG))]
18436  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18437  "movsb"
18438  [(set_attr "type" "str")
18439   (set_attr "memory" "both")
18440   (set_attr "mode" "QI")])
18441
18442(define_insn "*strmovqi_rex_1"
18443  [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18444	(mem:QI (match_operand:DI 3 "register_operand" "1")))
18445   (set (match_operand:DI 0 "register_operand" "=D")
18446	(plus:DI (match_dup 2)
18447		 (const_int 1)))
18448   (set (match_operand:DI 1 "register_operand" "=S")
18449	(plus:DI (match_dup 3)
18450		 (const_int 1)))
18451   (use (reg:SI DIRFLAG_REG))]
18452  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18453  "movsb"
18454  [(set_attr "type" "str")
18455   (set_attr "memory" "both")
18456   (set_attr "mode" "QI")])
18457
18458(define_expand "rep_mov"
18459  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18460	      (set (match_operand 0 "register_operand" "")
18461		   (match_operand 5 "" ""))
18462	      (set (match_operand 2 "register_operand" "")
18463		   (match_operand 6 "" ""))
18464	      (set (match_operand 1 "memory_operand" "")
18465		   (match_operand 3 "memory_operand" ""))
18466	      (use (match_dup 4))
18467	      (use (reg:SI DIRFLAG_REG))])]
18468  ""
18469  "")
18470
18471(define_insn "*rep_movdi_rex64"
18472  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18473   (set (match_operand:DI 0 "register_operand" "=D")
18474        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18475			    (const_int 3))
18476		 (match_operand:DI 3 "register_operand" "0")))
18477   (set (match_operand:DI 1 "register_operand" "=S")
18478        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18479		 (match_operand:DI 4 "register_operand" "1")))
18480   (set (mem:BLK (match_dup 3))
18481	(mem:BLK (match_dup 4)))
18482   (use (match_dup 5))
18483   (use (reg:SI DIRFLAG_REG))]
18484  "TARGET_64BIT"
18485  "{rep\;movsq|rep movsq}"
18486  [(set_attr "type" "str")
18487   (set_attr "prefix_rep" "1")
18488   (set_attr "memory" "both")
18489   (set_attr "mode" "DI")])
18490
18491(define_insn "*rep_movsi"
18492  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18493   (set (match_operand:SI 0 "register_operand" "=D")
18494        (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18495			    (const_int 2))
18496		 (match_operand:SI 3 "register_operand" "0")))
18497   (set (match_operand:SI 1 "register_operand" "=S")
18498        (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18499		 (match_operand:SI 4 "register_operand" "1")))
18500   (set (mem:BLK (match_dup 3))
18501	(mem:BLK (match_dup 4)))
18502   (use (match_dup 5))
18503   (use (reg:SI DIRFLAG_REG))]
18504  "!TARGET_64BIT"
18505  "{rep\;movsl|rep movsd}"
18506  [(set_attr "type" "str")
18507   (set_attr "prefix_rep" "1")
18508   (set_attr "memory" "both")
18509   (set_attr "mode" "SI")])
18510
18511(define_insn "*rep_movsi_rex64"
18512  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18513   (set (match_operand:DI 0 "register_operand" "=D")
18514        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18515			    (const_int 2))
18516		 (match_operand:DI 3 "register_operand" "0")))
18517   (set (match_operand:DI 1 "register_operand" "=S")
18518        (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18519		 (match_operand:DI 4 "register_operand" "1")))
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\;movsl|rep movsd}"
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"
18532  [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18533   (set (match_operand:SI 0 "register_operand" "=D")
18534        (plus:SI (match_operand:SI 3 "register_operand" "0")
18535		 (match_operand:SI 5 "register_operand" "2")))
18536   (set (match_operand:SI 1 "register_operand" "=S")
18537        (plus:SI (match_operand:SI 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_insn "*rep_movqi_rex64"
18550  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18551   (set (match_operand:DI 0 "register_operand" "=D")
18552        (plus:DI (match_operand:DI 3 "register_operand" "0")
18553		 (match_operand:DI 5 "register_operand" "2")))
18554   (set (match_operand:DI 1 "register_operand" "=S")
18555        (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18556   (set (mem:BLK (match_dup 3))
18557	(mem:BLK (match_dup 4)))
18558   (use (match_dup 5))
18559   (use (reg:SI DIRFLAG_REG))]
18560  "TARGET_64BIT"
18561  "{rep\;movsb|rep movsb}"
18562  [(set_attr "type" "str")
18563   (set_attr "prefix_rep" "1")
18564   (set_attr "memory" "both")
18565   (set_attr "mode" "SI")])
18566
18567(define_expand "setmemsi"
18568   [(use (match_operand:BLK 0 "memory_operand" ""))
18569    (use (match_operand:SI 1 "nonmemory_operand" ""))
18570    (use (match_operand 2 "const_int_operand" ""))
18571    (use (match_operand 3 "const_int_operand" ""))]
18572  ""
18573{
18574 /* If value to set is not zero, use the library routine.  */
18575 if (operands[2] != const0_rtx)
18576   FAIL;
18577
18578 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18579   DONE;
18580 else
18581   FAIL;
18582})
18583
18584(define_expand "setmemdi"
18585   [(use (match_operand:BLK 0 "memory_operand" ""))
18586    (use (match_operand:DI 1 "nonmemory_operand" ""))
18587    (use (match_operand 2 "const_int_operand" ""))
18588    (use (match_operand 3 "const_int_operand" ""))]
18589  "TARGET_64BIT"
18590{
18591 /* If value to set is not zero, use the library routine.  */
18592 if (operands[2] != const0_rtx)
18593   FAIL;
18594
18595 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18596   DONE;
18597 else
18598   FAIL;
18599})
18600
18601;; Most CPUs don't like single string operations
18602;; Handle this case here to simplify previous expander.
18603
18604(define_expand "strset"
18605  [(set (match_operand 1 "memory_operand" "")
18606	(match_operand 2 "register_operand" ""))
18607   (parallel [(set (match_operand 0 "register_operand" "")
18608		   (match_dup 3))
18609	      (clobber (reg:CC FLAGS_REG))])]
18610  ""
18611{
18612  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18613    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18614
18615  /* If .md ever supports :P for Pmode, this can be directly
18616     in the pattern above.  */
18617  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18618			      GEN_INT (GET_MODE_SIZE (GET_MODE
18619						      (operands[2]))));
18620  if (TARGET_SINGLE_STRINGOP || optimize_size)
18621    {
18622      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18623				      operands[3]));
18624      DONE;
18625    }
18626})
18627
18628(define_expand "strset_singleop"
18629  [(parallel [(set (match_operand 1 "memory_operand" "")
18630		   (match_operand 2 "register_operand" ""))
18631	      (set (match_operand 0 "register_operand" "")
18632		   (match_operand 3 "" ""))
18633	      (use (reg:SI DIRFLAG_REG))])]
18634  "TARGET_SINGLE_STRINGOP || optimize_size"
18635  "")
18636
18637(define_insn "*strsetdi_rex_1"
18638  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18639	(match_operand:DI 2 "register_operand" "a"))
18640   (set (match_operand:DI 0 "register_operand" "=D")
18641	(plus:DI (match_dup 1)
18642		 (const_int 8)))
18643   (use (reg:SI DIRFLAG_REG))]
18644  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18645  "stosq"
18646  [(set_attr "type" "str")
18647   (set_attr "memory" "store")
18648   (set_attr "mode" "DI")])
18649
18650(define_insn "*strsetsi_1"
18651  [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18652	(match_operand:SI 2 "register_operand" "a"))
18653   (set (match_operand:SI 0 "register_operand" "=D")
18654	(plus:SI (match_dup 1)
18655		 (const_int 4)))
18656   (use (reg:SI DIRFLAG_REG))]
18657  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18658  "{stosl|stosd}"
18659  [(set_attr "type" "str")
18660   (set_attr "memory" "store")
18661   (set_attr "mode" "SI")])
18662
18663(define_insn "*strsetsi_rex_1"
18664  [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18665	(match_operand:SI 2 "register_operand" "a"))
18666   (set (match_operand:DI 0 "register_operand" "=D")
18667	(plus:DI (match_dup 1)
18668		 (const_int 4)))
18669   (use (reg:SI DIRFLAG_REG))]
18670  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18671  "{stosl|stosd}"
18672  [(set_attr "type" "str")
18673   (set_attr "memory" "store")
18674   (set_attr "mode" "SI")])
18675
18676(define_insn "*strsethi_1"
18677  [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18678	(match_operand:HI 2 "register_operand" "a"))
18679   (set (match_operand:SI 0 "register_operand" "=D")
18680	(plus:SI (match_dup 1)
18681		 (const_int 2)))
18682   (use (reg:SI DIRFLAG_REG))]
18683  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18684  "stosw"
18685  [(set_attr "type" "str")
18686   (set_attr "memory" "store")
18687   (set_attr "mode" "HI")])
18688
18689(define_insn "*strsethi_rex_1"
18690  [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18691	(match_operand:HI 2 "register_operand" "a"))
18692   (set (match_operand:DI 0 "register_operand" "=D")
18693	(plus:DI (match_dup 1)
18694		 (const_int 2)))
18695   (use (reg:SI DIRFLAG_REG))]
18696  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18697  "stosw"
18698  [(set_attr "type" "str")
18699   (set_attr "memory" "store")
18700   (set_attr "mode" "HI")])
18701
18702(define_insn "*strsetqi_1"
18703  [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18704	(match_operand:QI 2 "register_operand" "a"))
18705   (set (match_operand:SI 0 "register_operand" "=D")
18706	(plus:SI (match_dup 1)
18707		 (const_int 1)))
18708   (use (reg:SI DIRFLAG_REG))]
18709  "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18710  "stosb"
18711  [(set_attr "type" "str")
18712   (set_attr "memory" "store")
18713   (set_attr "mode" "QI")])
18714
18715(define_insn "*strsetqi_rex_1"
18716  [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18717	(match_operand:QI 2 "register_operand" "a"))
18718   (set (match_operand:DI 0 "register_operand" "=D")
18719	(plus:DI (match_dup 1)
18720		 (const_int 1)))
18721   (use (reg:SI DIRFLAG_REG))]
18722  "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18723  "stosb"
18724  [(set_attr "type" "str")
18725   (set_attr "memory" "store")
18726   (set_attr "mode" "QI")])
18727
18728(define_expand "rep_stos"
18729  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18730	      (set (match_operand 0 "register_operand" "")
18731		   (match_operand 4 "" ""))
18732	      (set (match_operand 2 "memory_operand" "") (const_int 0))
18733	      (use (match_operand 3 "register_operand" ""))
18734	      (use (match_dup 1))
18735	      (use (reg:SI DIRFLAG_REG))])]
18736  ""
18737  "")
18738
18739(define_insn "*rep_stosdi_rex64"
18740  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18741   (set (match_operand:DI 0 "register_operand" "=D")
18742        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18743			    (const_int 3))
18744		 (match_operand:DI 3 "register_operand" "0")))
18745   (set (mem:BLK (match_dup 3))
18746	(const_int 0))
18747   (use (match_operand:DI 2 "register_operand" "a"))
18748   (use (match_dup 4))
18749   (use (reg:SI DIRFLAG_REG))]
18750  "TARGET_64BIT"
18751  "{rep\;stosq|rep stosq}"
18752  [(set_attr "type" "str")
18753   (set_attr "prefix_rep" "1")
18754   (set_attr "memory" "store")
18755   (set_attr "mode" "DI")])
18756
18757(define_insn "*rep_stossi"
18758  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18759   (set (match_operand:SI 0 "register_operand" "=D")
18760        (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18761			    (const_int 2))
18762		 (match_operand:SI 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_stossi_rex64"
18776  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18777   (set (match_operand:DI 0 "register_operand" "=D")
18778        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18779			    (const_int 2))
18780		 (match_operand:DI 3 "register_operand" "0")))
18781   (set (mem:BLK (match_dup 3))
18782	(const_int 0))
18783   (use (match_operand:SI 2 "register_operand" "a"))
18784   (use (match_dup 4))
18785   (use (reg:SI DIRFLAG_REG))]
18786  "TARGET_64BIT"
18787  "{rep\;stosl|rep stosd}"
18788  [(set_attr "type" "str")
18789   (set_attr "prefix_rep" "1")
18790   (set_attr "memory" "store")
18791   (set_attr "mode" "SI")])
18792
18793(define_insn "*rep_stosqi"
18794  [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18795   (set (match_operand:SI 0 "register_operand" "=D")
18796        (plus:SI (match_operand:SI 3 "register_operand" "0")
18797		 (match_operand:SI 4 "register_operand" "1")))
18798   (set (mem:BLK (match_dup 3))
18799	(const_int 0))
18800   (use (match_operand:QI 2 "register_operand" "a"))
18801   (use (match_dup 4))
18802   (use (reg:SI DIRFLAG_REG))]
18803  "!TARGET_64BIT"
18804  "{rep\;stosb|rep stosb}"
18805  [(set_attr "type" "str")
18806   (set_attr "prefix_rep" "1")
18807   (set_attr "memory" "store")
18808   (set_attr "mode" "QI")])
18809
18810(define_insn "*rep_stosqi_rex64"
18811  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18812   (set (match_operand:DI 0 "register_operand" "=D")
18813        (plus:DI (match_operand:DI 3 "register_operand" "0")
18814		 (match_operand:DI 4 "register_operand" "1")))
18815   (set (mem:BLK (match_dup 3))
18816	(const_int 0))
18817   (use (match_operand:QI 2 "register_operand" "a"))
18818   (use (match_dup 4))
18819   (use (reg:SI DIRFLAG_REG))]
18820  "TARGET_64BIT"
18821  "{rep\;stosb|rep stosb}"
18822  [(set_attr "type" "str")
18823   (set_attr "prefix_rep" "1")
18824   (set_attr "memory" "store")
18825   (set_attr "mode" "QI")])
18826
18827(define_expand "cmpstrnsi"
18828  [(set (match_operand:SI 0 "register_operand" "")
18829	(compare:SI (match_operand:BLK 1 "general_operand" "")
18830		    (match_operand:BLK 2 "general_operand" "")))
18831   (use (match_operand 3 "general_operand" ""))
18832   (use (match_operand 4 "immediate_operand" ""))]
18833  "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18834{
18835  rtx addr1, addr2, out, outlow, count, countreg, align;
18836
18837  /* Can't use this if the user has appropriated esi or edi.  */
18838  if (global_regs[4] || global_regs[5])
18839    FAIL;
18840
18841  out = operands[0];
18842  if (GET_CODE (out) != REG)
18843    out = gen_reg_rtx (SImode);
18844
18845  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18846  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18847  if (addr1 != XEXP (operands[1], 0))
18848    operands[1] = replace_equiv_address_nv (operands[1], addr1);
18849  if (addr2 != XEXP (operands[2], 0))
18850    operands[2] = replace_equiv_address_nv (operands[2], addr2);
18851
18852  count = operands[3];
18853  countreg = ix86_zero_extend_to_Pmode (count);
18854
18855  /* %%% Iff we are testing strict equality, we can use known alignment
18856     to good advantage.  This may be possible with combine, particularly
18857     once cc0 is dead.  */
18858  align = operands[4];
18859
18860  emit_insn (gen_cld ());
18861  if (GET_CODE (count) == CONST_INT)
18862    {
18863      if (INTVAL (count) == 0)
18864	{
18865	  emit_move_insn (operands[0], const0_rtx);
18866	  DONE;
18867	}
18868      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18869				     operands[1], operands[2]));
18870    }
18871  else
18872    {
18873      if (TARGET_64BIT)
18874	emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18875      else
18876	emit_insn (gen_cmpsi_1 (countreg, countreg));
18877      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18878				  operands[1], operands[2]));
18879    }
18880
18881  outlow = gen_lowpart (QImode, out);
18882  emit_insn (gen_cmpintqi (outlow));
18883  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18884
18885  if (operands[0] != out)
18886    emit_move_insn (operands[0], out);
18887
18888  DONE;
18889})
18890
18891;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18892
18893(define_expand "cmpintqi"
18894  [(set (match_dup 1)
18895	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18896   (set (match_dup 2)
18897	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18898   (parallel [(set (match_operand:QI 0 "register_operand" "")
18899		   (minus:QI (match_dup 1)
18900			     (match_dup 2)))
18901	      (clobber (reg:CC FLAGS_REG))])]
18902  ""
18903  "operands[1] = gen_reg_rtx (QImode);
18904   operands[2] = gen_reg_rtx (QImode);")
18905
18906;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18907;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18908
18909(define_expand "cmpstrnqi_nz_1"
18910  [(parallel [(set (reg:CC FLAGS_REG)
18911		   (compare:CC (match_operand 4 "memory_operand" "")
18912			       (match_operand 5 "memory_operand" "")))
18913	      (use (match_operand 2 "register_operand" ""))
18914	      (use (match_operand:SI 3 "immediate_operand" ""))
18915	      (use (reg:SI DIRFLAG_REG))
18916	      (clobber (match_operand 0 "register_operand" ""))
18917	      (clobber (match_operand 1 "register_operand" ""))
18918	      (clobber (match_dup 2))])]
18919  ""
18920  "")
18921
18922(define_insn "*cmpstrnqi_nz_1"
18923  [(set (reg:CC FLAGS_REG)
18924	(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18925		    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18926   (use (match_operand:SI 6 "register_operand" "2"))
18927   (use (match_operand:SI 3 "immediate_operand" "i"))
18928   (use (reg:SI DIRFLAG_REG))
18929   (clobber (match_operand:SI 0 "register_operand" "=S"))
18930   (clobber (match_operand:SI 1 "register_operand" "=D"))
18931   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18932  "!TARGET_64BIT"
18933  "repz{\;| }cmpsb"
18934  [(set_attr "type" "str")
18935   (set_attr "mode" "QI")
18936   (set_attr "prefix_rep" "1")])
18937
18938(define_insn "*cmpstrnqi_nz_rex_1"
18939  [(set (reg:CC FLAGS_REG)
18940	(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18941		    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18942   (use (match_operand:DI 6 "register_operand" "2"))
18943   (use (match_operand:SI 3 "immediate_operand" "i"))
18944   (use (reg:SI DIRFLAG_REG))
18945   (clobber (match_operand:DI 0 "register_operand" "=S"))
18946   (clobber (match_operand:DI 1 "register_operand" "=D"))
18947   (clobber (match_operand:DI 2 "register_operand" "=c"))]
18948  "TARGET_64BIT"
18949  "repz{\;| }cmpsb"
18950  [(set_attr "type" "str")
18951   (set_attr "mode" "QI")
18952   (set_attr "prefix_rep" "1")])
18953
18954;; The same, but the count is not known to not be zero.
18955
18956(define_expand "cmpstrnqi_1"
18957  [(parallel [(set (reg:CC FLAGS_REG)
18958		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
18959				     (const_int 0))
18960		  (compare:CC (match_operand 4 "memory_operand" "")
18961			      (match_operand 5 "memory_operand" ""))
18962		  (const_int 0)))
18963	      (use (match_operand:SI 3 "immediate_operand" ""))
18964	      (use (reg:CC FLAGS_REG))
18965	      (use (reg:SI DIRFLAG_REG))
18966	      (clobber (match_operand 0 "register_operand" ""))
18967	      (clobber (match_operand 1 "register_operand" ""))
18968	      (clobber (match_dup 2))])]
18969  ""
18970  "")
18971
18972(define_insn "*cmpstrnqi_1"
18973  [(set (reg:CC FLAGS_REG)
18974	(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18975			     (const_int 0))
18976	  (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18977		      (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18978	  (const_int 0)))
18979   (use (match_operand:SI 3 "immediate_operand" "i"))
18980   (use (reg:CC FLAGS_REG))
18981   (use (reg:SI DIRFLAG_REG))
18982   (clobber (match_operand:SI 0 "register_operand" "=S"))
18983   (clobber (match_operand:SI 1 "register_operand" "=D"))
18984   (clobber (match_operand:SI 2 "register_operand" "=c"))]
18985  "!TARGET_64BIT"
18986  "repz{\;| }cmpsb"
18987  [(set_attr "type" "str")
18988   (set_attr "mode" "QI")
18989   (set_attr "prefix_rep" "1")])
18990
18991(define_insn "*cmpstrnqi_rex_1"
18992  [(set (reg:CC FLAGS_REG)
18993	(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18994			     (const_int 0))
18995	  (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18996		      (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18997	  (const_int 0)))
18998   (use (match_operand:SI 3 "immediate_operand" "i"))
18999   (use (reg:CC FLAGS_REG))
19000   (use (reg:SI DIRFLAG_REG))
19001   (clobber (match_operand:DI 0 "register_operand" "=S"))
19002   (clobber (match_operand:DI 1 "register_operand" "=D"))
19003   (clobber (match_operand:DI 2 "register_operand" "=c"))]
19004  "TARGET_64BIT"
19005  "repz{\;| }cmpsb"
19006  [(set_attr "type" "str")
19007   (set_attr "mode" "QI")
19008   (set_attr "prefix_rep" "1")])
19009
19010(define_expand "strlensi"
19011  [(set (match_operand:SI 0 "register_operand" "")
19012	(unspec:SI [(match_operand:BLK 1 "general_operand" "")
19013		    (match_operand:QI 2 "immediate_operand" "")
19014		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19015  ""
19016{
19017 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19018   DONE;
19019 else
19020   FAIL;
19021})
19022
19023(define_expand "strlendi"
19024  [(set (match_operand:DI 0 "register_operand" "")
19025	(unspec:DI [(match_operand:BLK 1 "general_operand" "")
19026		    (match_operand:QI 2 "immediate_operand" "")
19027		    (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19028  ""
19029{
19030 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19031   DONE;
19032 else
19033   FAIL;
19034})
19035
19036(define_expand "strlenqi_1"
19037  [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19038	      (use (reg:SI DIRFLAG_REG))
19039	      (clobber (match_operand 1 "register_operand" ""))
19040	      (clobber (reg:CC FLAGS_REG))])]
19041  ""
19042  "")
19043
19044(define_insn "*strlenqi_1"
19045  [(set (match_operand:SI 0 "register_operand" "=&c")
19046	(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19047		    (match_operand:QI 2 "register_operand" "a")
19048		    (match_operand:SI 3 "immediate_operand" "i")
19049		    (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19050   (use (reg:SI DIRFLAG_REG))
19051   (clobber (match_operand:SI 1 "register_operand" "=D"))
19052   (clobber (reg:CC FLAGS_REG))]
19053  "!TARGET_64BIT"
19054  "repnz{\;| }scasb"
19055  [(set_attr "type" "str")
19056   (set_attr "mode" "QI")
19057   (set_attr "prefix_rep" "1")])
19058
19059(define_insn "*strlenqi_rex_1"
19060  [(set (match_operand:DI 0 "register_operand" "=&c")
19061	(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19062		    (match_operand:QI 2 "register_operand" "a")
19063		    (match_operand:DI 3 "immediate_operand" "i")
19064		    (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19065   (use (reg:SI DIRFLAG_REG))
19066   (clobber (match_operand:DI 1 "register_operand" "=D"))
19067   (clobber (reg:CC FLAGS_REG))]
19068  "TARGET_64BIT"
19069  "repnz{\;| }scasb"
19070  [(set_attr "type" "str")
19071   (set_attr "mode" "QI")
19072   (set_attr "prefix_rep" "1")])
19073
19074;; Peephole optimizations to clean up after cmpstrn*.  This should be
19075;; handled in combine, but it is not currently up to the task.
19076;; When used for their truth value, the cmpstrn* expanders generate
19077;; code like this:
19078;;
19079;;   repz cmpsb
19080;;   seta 	%al
19081;;   setb 	%dl
19082;;   cmpb 	%al, %dl
19083;;   jcc	label
19084;;
19085;; The intermediate three instructions are unnecessary.
19086
19087;; This one handles cmpstrn*_nz_1...
19088(define_peephole2
19089  [(parallel[
19090     (set (reg:CC FLAGS_REG)
19091	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19092		      (mem:BLK (match_operand 5 "register_operand" ""))))
19093     (use (match_operand 6 "register_operand" ""))
19094     (use (match_operand:SI 3 "immediate_operand" ""))
19095     (use (reg:SI DIRFLAG_REG))
19096     (clobber (match_operand 0 "register_operand" ""))
19097     (clobber (match_operand 1 "register_operand" ""))
19098     (clobber (match_operand 2 "register_operand" ""))])
19099   (set (match_operand:QI 7 "register_operand" "")
19100	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19101   (set (match_operand:QI 8 "register_operand" "")
19102	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19103   (set (reg FLAGS_REG)
19104	(compare (match_dup 7) (match_dup 8)))
19105  ]
19106  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19107  [(parallel[
19108     (set (reg:CC FLAGS_REG)
19109	  (compare:CC (mem:BLK (match_dup 4))
19110		      (mem:BLK (match_dup 5))))
19111     (use (match_dup 6))
19112     (use (match_dup 3))
19113     (use (reg:SI DIRFLAG_REG))
19114     (clobber (match_dup 0))
19115     (clobber (match_dup 1))
19116     (clobber (match_dup 2))])]
19117  "")
19118
19119;; ...and this one handles cmpstrn*_1.
19120(define_peephole2
19121  [(parallel[
19122     (set (reg:CC FLAGS_REG)
19123	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19124			       (const_int 0))
19125	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19126		        (mem:BLK (match_operand 5 "register_operand" "")))
19127	    (const_int 0)))
19128     (use (match_operand:SI 3 "immediate_operand" ""))
19129     (use (reg:CC FLAGS_REG))
19130     (use (reg:SI DIRFLAG_REG))
19131     (clobber (match_operand 0 "register_operand" ""))
19132     (clobber (match_operand 1 "register_operand" ""))
19133     (clobber (match_operand 2 "register_operand" ""))])
19134   (set (match_operand:QI 7 "register_operand" "")
19135	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19136   (set (match_operand:QI 8 "register_operand" "")
19137	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19138   (set (reg FLAGS_REG)
19139	(compare (match_dup 7) (match_dup 8)))
19140  ]
19141  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19142  [(parallel[
19143     (set (reg:CC FLAGS_REG)
19144	  (if_then_else:CC (ne (match_dup 6)
19145			       (const_int 0))
19146	    (compare:CC (mem:BLK (match_dup 4))
19147			(mem:BLK (match_dup 5)))
19148	    (const_int 0)))
19149     (use (match_dup 3))
19150     (use (reg:CC FLAGS_REG))
19151     (use (reg:SI DIRFLAG_REG))
19152     (clobber (match_dup 0))
19153     (clobber (match_dup 1))
19154     (clobber (match_dup 2))])]
19155  "")
19156
19157
19158
19159;; Conditional move instructions.
19160
19161(define_expand "movdicc"
19162  [(set (match_operand:DI 0 "register_operand" "")
19163	(if_then_else:DI (match_operand 1 "comparison_operator" "")
19164			 (match_operand:DI 2 "general_operand" "")
19165			 (match_operand:DI 3 "general_operand" "")))]
19166  "TARGET_64BIT"
19167  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19168
19169(define_insn "x86_movdicc_0_m1_rex64"
19170  [(set (match_operand:DI 0 "register_operand" "=r")
19171	(if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19172	  (const_int -1)
19173	  (const_int 0)))
19174   (clobber (reg:CC FLAGS_REG))]
19175  "TARGET_64BIT"
19176  "sbb{q}\t%0, %0"
19177  ; Since we don't have the proper number of operands for an alu insn,
19178  ; fill in all the blanks.
19179  [(set_attr "type" "alu")
19180   (set_attr "pent_pair" "pu")
19181   (set_attr "memory" "none")
19182   (set_attr "imm_disp" "false")
19183   (set_attr "mode" "DI")
19184   (set_attr "length_immediate" "0")])
19185
19186(define_insn "*movdicc_c_rex64"
19187  [(set (match_operand:DI 0 "register_operand" "=r,r")
19188	(if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19189				[(reg FLAGS_REG) (const_int 0)])
19190		      (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19191		      (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19192  "TARGET_64BIT && TARGET_CMOVE
19193   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19194  "@
19195   cmov%O2%C1\t{%2, %0|%0, %2}
19196   cmov%O2%c1\t{%3, %0|%0, %3}"
19197  [(set_attr "type" "icmov")
19198   (set_attr "mode" "DI")])
19199
19200(define_expand "movsicc"
19201  [(set (match_operand:SI 0 "register_operand" "")
19202	(if_then_else:SI (match_operand 1 "comparison_operator" "")
19203			 (match_operand:SI 2 "general_operand" "")
19204			 (match_operand:SI 3 "general_operand" "")))]
19205  ""
19206  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19207
19208;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19209;; the register first winds up with `sbbl $0,reg', which is also weird.
19210;; So just document what we're doing explicitly.
19211
19212(define_insn "x86_movsicc_0_m1"
19213  [(set (match_operand:SI 0 "register_operand" "=r")
19214	(if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19215	  (const_int -1)
19216	  (const_int 0)))
19217   (clobber (reg:CC FLAGS_REG))]
19218  ""
19219  "sbb{l}\t%0, %0"
19220  ; Since we don't have the proper number of operands for an alu insn,
19221  ; fill in all the blanks.
19222  [(set_attr "type" "alu")
19223   (set_attr "pent_pair" "pu")
19224   (set_attr "memory" "none")
19225   (set_attr "imm_disp" "false")
19226   (set_attr "mode" "SI")
19227   (set_attr "length_immediate" "0")])
19228
19229(define_insn "*movsicc_noc"
19230  [(set (match_operand:SI 0 "register_operand" "=r,r")
19231	(if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19232				[(reg FLAGS_REG) (const_int 0)])
19233		      (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19234		      (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19235  "TARGET_CMOVE
19236   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19237  "@
19238   cmov%O2%C1\t{%2, %0|%0, %2}
19239   cmov%O2%c1\t{%3, %0|%0, %3}"
19240  [(set_attr "type" "icmov")
19241   (set_attr "mode" "SI")])
19242
19243(define_expand "movhicc"
19244  [(set (match_operand:HI 0 "register_operand" "")
19245	(if_then_else:HI (match_operand 1 "comparison_operator" "")
19246			 (match_operand:HI 2 "general_operand" "")
19247			 (match_operand:HI 3 "general_operand" "")))]
19248  "TARGET_HIMODE_MATH"
19249  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19250
19251(define_insn "*movhicc_noc"
19252  [(set (match_operand:HI 0 "register_operand" "=r,r")
19253	(if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19254				[(reg FLAGS_REG) (const_int 0)])
19255		      (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19256		      (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19257  "TARGET_CMOVE
19258   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19259  "@
19260   cmov%O2%C1\t{%2, %0|%0, %2}
19261   cmov%O2%c1\t{%3, %0|%0, %3}"
19262  [(set_attr "type" "icmov")
19263   (set_attr "mode" "HI")])
19264
19265(define_expand "movqicc"
19266  [(set (match_operand:QI 0 "register_operand" "")
19267	(if_then_else:QI (match_operand 1 "comparison_operator" "")
19268			 (match_operand:QI 2 "general_operand" "")
19269			 (match_operand:QI 3 "general_operand" "")))]
19270  "TARGET_QIMODE_MATH"
19271  "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19272
19273(define_insn_and_split "*movqicc_noc"
19274  [(set (match_operand:QI 0 "register_operand" "=r,r")
19275	(if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19276				[(match_operand 4 "flags_reg_operand" "")
19277				 (const_int 0)])
19278		      (match_operand:QI 2 "register_operand" "r,0")
19279		      (match_operand:QI 3 "register_operand" "0,r")))]
19280  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19281  "#"
19282  "&& reload_completed"
19283  [(set (match_dup 0)
19284	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19285		      (match_dup 2)
19286		      (match_dup 3)))]
19287  "operands[0] = gen_lowpart (SImode, operands[0]);
19288   operands[2] = gen_lowpart (SImode, operands[2]);
19289   operands[3] = gen_lowpart (SImode, operands[3]);"
19290  [(set_attr "type" "icmov")
19291   (set_attr "mode" "SI")])
19292
19293(define_expand "movsfcc"
19294  [(set (match_operand:SF 0 "register_operand" "")
19295	(if_then_else:SF (match_operand 1 "comparison_operator" "")
19296			 (match_operand:SF 2 "register_operand" "")
19297			 (match_operand:SF 3 "register_operand" "")))]
19298  "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19299  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19300
19301(define_insn "*movsfcc_1_387"
19302  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19303	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19304				[(reg FLAGS_REG) (const_int 0)])
19305		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19306		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19307  "TARGET_80387 && TARGET_CMOVE
19308   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19309  "@
19310   fcmov%F1\t{%2, %0|%0, %2}
19311   fcmov%f1\t{%3, %0|%0, %3}
19312   cmov%O2%C1\t{%2, %0|%0, %2}
19313   cmov%O2%c1\t{%3, %0|%0, %3}"
19314  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19315   (set_attr "mode" "SF,SF,SI,SI")])
19316
19317(define_expand "movdfcc"
19318  [(set (match_operand:DF 0 "register_operand" "")
19319	(if_then_else:DF (match_operand 1 "comparison_operator" "")
19320			 (match_operand:DF 2 "register_operand" "")
19321			 (match_operand:DF 3 "register_operand" "")))]
19322  "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19323  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19324
19325(define_insn "*movdfcc_1"
19326  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19327	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19328				[(reg FLAGS_REG) (const_int 0)])
19329		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19330		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19331  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19332   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19333  "@
19334   fcmov%F1\t{%2, %0|%0, %2}
19335   fcmov%f1\t{%3, %0|%0, %3}
19336   #
19337   #"
19338  [(set_attr "type" "fcmov,fcmov,multi,multi")
19339   (set_attr "mode" "DF")])
19340
19341(define_insn "*movdfcc_1_rex64"
19342  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19343	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19344				[(reg FLAGS_REG) (const_int 0)])
19345		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19346		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19347  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19348   && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19349  "@
19350   fcmov%F1\t{%2, %0|%0, %2}
19351   fcmov%f1\t{%3, %0|%0, %3}
19352   cmov%O2%C1\t{%2, %0|%0, %2}
19353   cmov%O2%c1\t{%3, %0|%0, %3}"
19354  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19355   (set_attr "mode" "DF")])
19356
19357(define_split
19358  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19359	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19360				[(match_operand 4 "flags_reg_operand" "")
19361				 (const_int 0)])
19362		      (match_operand:DF 2 "nonimmediate_operand" "")
19363		      (match_operand:DF 3 "nonimmediate_operand" "")))]
19364  "!TARGET_64BIT && reload_completed"
19365  [(set (match_dup 2)
19366	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19367		      (match_dup 5)
19368		      (match_dup 7)))
19369   (set (match_dup 3)
19370	(if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19371		      (match_dup 6)
19372		      (match_dup 8)))]
19373  "split_di (operands+2, 1, operands+5, operands+6);
19374   split_di (operands+3, 1, operands+7, operands+8);
19375   split_di (operands, 1, operands+2, operands+3);")
19376
19377(define_expand "movxfcc"
19378  [(set (match_operand:XF 0 "register_operand" "")
19379	(if_then_else:XF (match_operand 1 "comparison_operator" "")
19380			 (match_operand:XF 2 "register_operand" "")
19381			 (match_operand:XF 3 "register_operand" "")))]
19382  "TARGET_80387 && TARGET_CMOVE"
19383  "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19384
19385(define_insn "*movxfcc_1"
19386  [(set (match_operand:XF 0 "register_operand" "=f,f")
19387	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19388				[(reg FLAGS_REG) (const_int 0)])
19389		      (match_operand:XF 2 "register_operand" "f,0")
19390		      (match_operand:XF 3 "register_operand" "0,f")))]
19391  "TARGET_80387 && TARGET_CMOVE"
19392  "@
19393   fcmov%F1\t{%2, %0|%0, %2}
19394   fcmov%f1\t{%3, %0|%0, %3}"
19395  [(set_attr "type" "fcmov")
19396   (set_attr "mode" "XF")])
19397
19398;; These versions of the min/max patterns are intentionally ignorant of
19399;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19400;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19401;; are undefined in this condition, we're certain this is correct.
19402
19403(define_insn "sminsf3"
19404  [(set (match_operand:SF 0 "register_operand" "=x")
19405	(smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19406		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19407  "TARGET_SSE_MATH"
19408  "minss\t{%2, %0|%0, %2}"
19409  [(set_attr "type" "sseadd")
19410   (set_attr "mode" "SF")])
19411
19412(define_insn "smaxsf3"
19413  [(set (match_operand:SF 0 "register_operand" "=x")
19414	(smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19415		 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19416  "TARGET_SSE_MATH"
19417  "maxss\t{%2, %0|%0, %2}"
19418  [(set_attr "type" "sseadd")
19419   (set_attr "mode" "SF")])
19420
19421(define_insn "smindf3"
19422  [(set (match_operand:DF 0 "register_operand" "=x")
19423	(smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19424		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19425  "TARGET_SSE2 && TARGET_SSE_MATH"
19426  "minsd\t{%2, %0|%0, %2}"
19427  [(set_attr "type" "sseadd")
19428   (set_attr "mode" "DF")])
19429
19430(define_insn "smaxdf3"
19431  [(set (match_operand:DF 0 "register_operand" "=x")
19432	(smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19433		 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19434  "TARGET_SSE2 && TARGET_SSE_MATH"
19435  "maxsd\t{%2, %0|%0, %2}"
19436  [(set_attr "type" "sseadd")
19437   (set_attr "mode" "DF")])
19438
19439;; These versions of the min/max patterns implement exactly the operations
19440;;   min = (op1 < op2 ? op1 : op2)
19441;;   max = (!(op1 < op2) ? op1 : op2)
19442;; Their operands are not commutative, and thus they may be used in the
19443;; presence of -0.0 and NaN.
19444
19445(define_insn "*ieee_sminsf3"
19446  [(set (match_operand:SF 0 "register_operand" "=x")
19447	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19448		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19449		   UNSPEC_IEEE_MIN))]
19450  "TARGET_SSE_MATH"
19451  "minss\t{%2, %0|%0, %2}"
19452  [(set_attr "type" "sseadd")
19453   (set_attr "mode" "SF")])
19454
19455(define_insn "*ieee_smaxsf3"
19456  [(set (match_operand:SF 0 "register_operand" "=x")
19457	(unspec:SF [(match_operand:SF 1 "register_operand" "0")
19458		    (match_operand:SF 2 "nonimmediate_operand" "xm")]
19459		   UNSPEC_IEEE_MAX))]
19460  "TARGET_SSE_MATH"
19461  "maxss\t{%2, %0|%0, %2}"
19462  [(set_attr "type" "sseadd")
19463   (set_attr "mode" "SF")])
19464
19465(define_insn "*ieee_smindf3"
19466  [(set (match_operand:DF 0 "register_operand" "=x")
19467	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19468		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19469		   UNSPEC_IEEE_MIN))]
19470  "TARGET_SSE2 && TARGET_SSE_MATH"
19471  "minsd\t{%2, %0|%0, %2}"
19472  [(set_attr "type" "sseadd")
19473   (set_attr "mode" "DF")])
19474
19475(define_insn "*ieee_smaxdf3"
19476  [(set (match_operand:DF 0 "register_operand" "=x")
19477	(unspec:DF [(match_operand:DF 1 "register_operand" "0")
19478		    (match_operand:DF 2 "nonimmediate_operand" "xm")]
19479		   UNSPEC_IEEE_MAX))]
19480  "TARGET_SSE2 && TARGET_SSE_MATH"
19481  "maxsd\t{%2, %0|%0, %2}"
19482  [(set_attr "type" "sseadd")
19483   (set_attr "mode" "DF")])
19484
19485;; Make two stack loads independent:
19486;;   fld aa              fld aa
19487;;   fld %st(0)     ->   fld bb
19488;;   fmul bb             fmul %st(1), %st
19489;;
19490;; Actually we only match the last two instructions for simplicity.
19491(define_peephole2
19492  [(set (match_operand 0 "fp_register_operand" "")
19493	(match_operand 1 "fp_register_operand" ""))
19494   (set (match_dup 0)
19495	(match_operator 2 "binary_fp_operator"
19496	   [(match_dup 0)
19497	    (match_operand 3 "memory_operand" "")]))]
19498  "REGNO (operands[0]) != REGNO (operands[1])"
19499  [(set (match_dup 0) (match_dup 3))
19500   (set (match_dup 0) (match_dup 4))]
19501
19502  ;; The % modifier is not operational anymore in peephole2's, so we have to
19503  ;; swap the operands manually in the case of addition and multiplication.
19504  "if (COMMUTATIVE_ARITH_P (operands[2]))
19505     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19506				 operands[0], operands[1]);
19507   else
19508     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19509				 operands[1], operands[0]);")
19510
19511;; Conditional addition patterns
19512(define_expand "addqicc"
19513  [(match_operand:QI 0 "register_operand" "")
19514   (match_operand 1 "comparison_operator" "")
19515   (match_operand:QI 2 "register_operand" "")
19516   (match_operand:QI 3 "const_int_operand" "")]
19517  ""
19518  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19519
19520(define_expand "addhicc"
19521  [(match_operand:HI 0 "register_operand" "")
19522   (match_operand 1 "comparison_operator" "")
19523   (match_operand:HI 2 "register_operand" "")
19524   (match_operand:HI 3 "const_int_operand" "")]
19525  ""
19526  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19527
19528(define_expand "addsicc"
19529  [(match_operand:SI 0 "register_operand" "")
19530   (match_operand 1 "comparison_operator" "")
19531   (match_operand:SI 2 "register_operand" "")
19532   (match_operand:SI 3 "const_int_operand" "")]
19533  ""
19534  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19535
19536(define_expand "adddicc"
19537  [(match_operand:DI 0 "register_operand" "")
19538   (match_operand 1 "comparison_operator" "")
19539   (match_operand:DI 2 "register_operand" "")
19540   (match_operand:DI 3 "const_int_operand" "")]
19541  "TARGET_64BIT"
19542  "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19543
19544
19545;; Misc patterns (?)
19546
19547;; This pattern exists to put a dependency on all ebp-based memory accesses.
19548;; Otherwise there will be nothing to keep
19549;;
19550;; [(set (reg ebp) (reg esp))]
19551;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19552;;  (clobber (eflags)]
19553;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19554;;
19555;; in proper program order.
19556(define_insn "pro_epilogue_adjust_stack_1"
19557  [(set (match_operand:SI 0 "register_operand" "=r,r")
19558	(plus:SI (match_operand:SI 1 "register_operand" "0,r")
19559	         (match_operand:SI 2 "immediate_operand" "i,i")))
19560   (clobber (reg:CC FLAGS_REG))
19561   (clobber (mem:BLK (scratch)))]
19562  "!TARGET_64BIT"
19563{
19564  switch (get_attr_type (insn))
19565    {
19566    case TYPE_IMOV:
19567      return "mov{l}\t{%1, %0|%0, %1}";
19568
19569    case TYPE_ALU:
19570      if (GET_CODE (operands[2]) == CONST_INT
19571          && (INTVAL (operands[2]) == 128
19572	      || (INTVAL (operands[2]) < 0
19573	          && INTVAL (operands[2]) != -128)))
19574	{
19575	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19576	  return "sub{l}\t{%2, %0|%0, %2}";
19577	}
19578      return "add{l}\t{%2, %0|%0, %2}";
19579
19580    case TYPE_LEA:
19581      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19582      return "lea{l}\t{%a2, %0|%0, %a2}";
19583
19584    default:
19585      gcc_unreachable ();
19586    }
19587}
19588  [(set (attr "type")
19589	(cond [(eq_attr "alternative" "0")
19590		 (const_string "alu")
19591	       (match_operand:SI 2 "const0_operand" "")
19592		 (const_string "imov")
19593	      ]
19594	      (const_string "lea")))
19595   (set_attr "mode" "SI")])
19596
19597(define_insn "pro_epilogue_adjust_stack_rex64"
19598  [(set (match_operand:DI 0 "register_operand" "=r,r")
19599	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19600		 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19601   (clobber (reg:CC FLAGS_REG))
19602   (clobber (mem:BLK (scratch)))]
19603  "TARGET_64BIT"
19604{
19605  switch (get_attr_type (insn))
19606    {
19607    case TYPE_IMOV:
19608      return "mov{q}\t{%1, %0|%0, %1}";
19609
19610    case TYPE_ALU:
19611      if (GET_CODE (operands[2]) == CONST_INT
19612	  /* Avoid overflows.  */
19613	  && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19614          && (INTVAL (operands[2]) == 128
19615	      || (INTVAL (operands[2]) < 0
19616	          && INTVAL (operands[2]) != -128)))
19617	{
19618	  operands[2] = GEN_INT (-INTVAL (operands[2]));
19619	  return "sub{q}\t{%2, %0|%0, %2}";
19620	}
19621      return "add{q}\t{%2, %0|%0, %2}";
19622
19623    case TYPE_LEA:
19624      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19625      return "lea{q}\t{%a2, %0|%0, %a2}";
19626
19627    default:
19628      gcc_unreachable ();
19629    }
19630}
19631  [(set (attr "type")
19632	(cond [(eq_attr "alternative" "0")
19633		 (const_string "alu")
19634	       (match_operand:DI 2 "const0_operand" "")
19635		 (const_string "imov")
19636	      ]
19637	      (const_string "lea")))
19638   (set_attr "mode" "DI")])
19639
19640(define_insn "pro_epilogue_adjust_stack_rex64_2"
19641  [(set (match_operand:DI 0 "register_operand" "=r,r")
19642	(plus:DI (match_operand:DI 1 "register_operand" "0,r")
19643		 (match_operand:DI 3 "immediate_operand" "i,i")))
19644   (use (match_operand:DI 2 "register_operand" "r,r"))
19645   (clobber (reg:CC FLAGS_REG))
19646   (clobber (mem:BLK (scratch)))]
19647  "TARGET_64BIT"
19648{
19649  switch (get_attr_type (insn))
19650    {
19651    case TYPE_ALU:
19652      return "add{q}\t{%2, %0|%0, %2}";
19653
19654    case TYPE_LEA:
19655      operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19656      return "lea{q}\t{%a2, %0|%0, %a2}";
19657
19658    default:
19659      gcc_unreachable ();
19660    }
19661}
19662  [(set_attr "type" "alu,lea")
19663   (set_attr "mode" "DI")])
19664
19665(define_expand "allocate_stack_worker"
19666  [(match_operand:SI 0 "register_operand" "")]
19667  "TARGET_STACK_PROBE"
19668{
19669  if (reload_completed)
19670    {
19671      if (TARGET_64BIT)
19672	emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19673      else
19674	emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19675    }
19676  else
19677    {
19678      if (TARGET_64BIT)
19679	emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19680      else
19681	emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19682    }
19683  DONE;
19684})
19685
19686(define_insn "allocate_stack_worker_1"
19687  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19688    UNSPECV_STACK_PROBE)
19689   (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19690   (clobber (match_scratch:SI 1 "=0"))
19691   (clobber (reg:CC FLAGS_REG))]
19692  "!TARGET_64BIT && TARGET_STACK_PROBE"
19693  "call\t__alloca"
19694  [(set_attr "type" "multi")
19695   (set_attr "length" "5")])
19696
19697(define_expand "allocate_stack_worker_postreload"
19698  [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19699				    UNSPECV_STACK_PROBE)
19700	      (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19701	      (clobber (match_dup 0))
19702	      (clobber (reg:CC FLAGS_REG))])]
19703  ""
19704  "")
19705
19706(define_insn "allocate_stack_worker_rex64"
19707  [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19708    UNSPECV_STACK_PROBE)
19709   (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19710   (clobber (match_scratch:DI 1 "=0"))
19711   (clobber (reg:CC FLAGS_REG))]
19712  "TARGET_64BIT && TARGET_STACK_PROBE"
19713  "call\t__alloca"
19714  [(set_attr "type" "multi")
19715   (set_attr "length" "5")])
19716
19717(define_expand "allocate_stack_worker_rex64_postreload"
19718  [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19719				    UNSPECV_STACK_PROBE)
19720	      (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19721	      (clobber (match_dup 0))
19722	      (clobber (reg:CC FLAGS_REG))])]
19723  ""
19724  "")
19725
19726(define_expand "allocate_stack"
19727  [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19728		   (minus:SI (reg:SI SP_REG)
19729			     (match_operand:SI 1 "general_operand" "")))
19730	      (clobber (reg:CC FLAGS_REG))])
19731   (parallel [(set (reg:SI SP_REG)
19732		   (minus:SI (reg:SI SP_REG) (match_dup 1)))
19733	      (clobber (reg:CC FLAGS_REG))])]
19734  "TARGET_STACK_PROBE"
19735{
19736#ifdef CHECK_STACK_LIMIT
19737  if (GET_CODE (operands[1]) == CONST_INT
19738      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19739    emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19740			   operands[1]));
19741  else
19742#endif
19743    emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19744							    operands[1])));
19745
19746  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19747  DONE;
19748})
19749
19750(define_expand "builtin_setjmp_receiver"
19751  [(label_ref (match_operand 0 "" ""))]
19752  "!TARGET_64BIT && flag_pic"
19753{
19754  if (TARGET_MACHO)
19755    {
19756      rtx xops[3];
19757      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19758      rtx label_rtx = gen_label_rtx ();
19759      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19760      xops[0] = xops[1] = picreg;
19761      xops[2] = gen_rtx_CONST (SImode,
19762	          gen_rtx_MINUS (SImode,
19763		    gen_rtx_LABEL_REF (SImode, label_rtx),
19764		    gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19765      ix86_expand_binary_operator (MINUS, SImode, xops);
19766    }
19767  else
19768    emit_insn (gen_set_got (pic_offset_table_rtx));
19769  DONE;
19770})
19771
19772;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19773
19774(define_split
19775  [(set (match_operand 0 "register_operand" "")
19776	(match_operator 3 "promotable_binary_operator"
19777	   [(match_operand 1 "register_operand" "")
19778	    (match_operand 2 "aligned_operand" "")]))
19779   (clobber (reg:CC FLAGS_REG))]
19780  "! TARGET_PARTIAL_REG_STALL && reload_completed
19781   && ((GET_MODE (operands[0]) == HImode
19782	&& ((!optimize_size && !TARGET_FAST_PREFIX)
19783            /* ??? next two lines just !satisfies_constraint_K (...) */
19784	    || GET_CODE (operands[2]) != CONST_INT
19785	    || satisfies_constraint_K (operands[2])))
19786       || (GET_MODE (operands[0]) == QImode
19787	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19788  [(parallel [(set (match_dup 0)
19789		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19790	      (clobber (reg:CC FLAGS_REG))])]
19791  "operands[0] = gen_lowpart (SImode, operands[0]);
19792   operands[1] = gen_lowpart (SImode, operands[1]);
19793   if (GET_CODE (operands[3]) != ASHIFT)
19794     operands[2] = gen_lowpart (SImode, operands[2]);
19795   PUT_MODE (operands[3], SImode);")
19796
19797; Promote the QImode tests, as i386 has encoding of the AND
19798; instruction with 32-bit sign-extended immediate and thus the
19799; instruction size is unchanged, except in the %eax case for
19800; which it is increased by one byte, hence the ! optimize_size.
19801(define_split
19802  [(set (match_operand 0 "flags_reg_operand" "")
19803	(match_operator 2 "compare_operator"
19804	  [(and (match_operand 3 "aligned_operand" "")
19805		(match_operand 4 "const_int_operand" ""))
19806	   (const_int 0)]))
19807   (set (match_operand 1 "register_operand" "")
19808	(and (match_dup 3) (match_dup 4)))]
19809  "! TARGET_PARTIAL_REG_STALL && reload_completed
19810   /* Ensure that the operand will remain sign-extended immediate.  */
19811   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19812   && ! optimize_size
19813   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19814       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19815  [(parallel [(set (match_dup 0)
19816		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19817			            (const_int 0)]))
19818	      (set (match_dup 1)
19819		   (and:SI (match_dup 3) (match_dup 4)))])]
19820{
19821  operands[4]
19822    = gen_int_mode (INTVAL (operands[4])
19823		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19824  operands[1] = gen_lowpart (SImode, operands[1]);
19825  operands[3] = gen_lowpart (SImode, operands[3]);
19826})
19827
19828; Don't promote the QImode tests, as i386 doesn't have encoding of
19829; the TEST instruction with 32-bit sign-extended immediate and thus
19830; the instruction size would at least double, which is not what we
19831; want even with ! optimize_size.
19832(define_split
19833  [(set (match_operand 0 "flags_reg_operand" "")
19834	(match_operator 1 "compare_operator"
19835	  [(and (match_operand:HI 2 "aligned_operand" "")
19836		(match_operand:HI 3 "const_int_operand" ""))
19837	   (const_int 0)]))]
19838  "! TARGET_PARTIAL_REG_STALL && reload_completed
19839   /* Ensure that the operand will remain sign-extended immediate.  */
19840   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19841   && ! TARGET_FAST_PREFIX
19842   && ! optimize_size"
19843  [(set (match_dup 0)
19844	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19845		         (const_int 0)]))]
19846{
19847  operands[3]
19848    = gen_int_mode (INTVAL (operands[3])
19849		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19850  operands[2] = gen_lowpart (SImode, operands[2]);
19851})
19852
19853(define_split
19854  [(set (match_operand 0 "register_operand" "")
19855	(neg (match_operand 1 "register_operand" "")))
19856   (clobber (reg:CC FLAGS_REG))]
19857  "! TARGET_PARTIAL_REG_STALL && reload_completed
19858   && (GET_MODE (operands[0]) == HImode
19859       || (GET_MODE (operands[0]) == QImode
19860	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19861  [(parallel [(set (match_dup 0)
19862		   (neg:SI (match_dup 1)))
19863	      (clobber (reg:CC FLAGS_REG))])]
19864  "operands[0] = gen_lowpart (SImode, operands[0]);
19865   operands[1] = gen_lowpart (SImode, operands[1]);")
19866
19867(define_split
19868  [(set (match_operand 0 "register_operand" "")
19869	(not (match_operand 1 "register_operand" "")))]
19870  "! TARGET_PARTIAL_REG_STALL && reload_completed
19871   && (GET_MODE (operands[0]) == HImode
19872       || (GET_MODE (operands[0]) == QImode
19873	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19874  [(set (match_dup 0)
19875	(not:SI (match_dup 1)))]
19876  "operands[0] = gen_lowpart (SImode, operands[0]);
19877   operands[1] = gen_lowpart (SImode, operands[1]);")
19878
19879(define_split
19880  [(set (match_operand 0 "register_operand" "")
19881	(if_then_else (match_operator 1 "comparison_operator"
19882				[(reg FLAGS_REG) (const_int 0)])
19883		      (match_operand 2 "register_operand" "")
19884		      (match_operand 3 "register_operand" "")))]
19885  "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19886   && (GET_MODE (operands[0]) == HImode
19887       || (GET_MODE (operands[0]) == QImode
19888	   && (TARGET_PROMOTE_QImode || optimize_size)))"
19889  [(set (match_dup 0)
19890	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19891  "operands[0] = gen_lowpart (SImode, operands[0]);
19892   operands[2] = gen_lowpart (SImode, operands[2]);
19893   operands[3] = gen_lowpart (SImode, operands[3]);")
19894
19895
19896;; RTL Peephole optimizations, run before sched2.  These primarily look to
19897;; transform a complex memory operation into two memory to register operations.
19898
19899;; Don't push memory operands
19900(define_peephole2
19901  [(set (match_operand:SI 0 "push_operand" "")
19902	(match_operand:SI 1 "memory_operand" ""))
19903   (match_scratch:SI 2 "r")]
19904  "!optimize_size && !TARGET_PUSH_MEMORY
19905   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19906  [(set (match_dup 2) (match_dup 1))
19907   (set (match_dup 0) (match_dup 2))]
19908  "")
19909
19910(define_peephole2
19911  [(set (match_operand:DI 0 "push_operand" "")
19912	(match_operand:DI 1 "memory_operand" ""))
19913   (match_scratch:DI 2 "r")]
19914  "!optimize_size && !TARGET_PUSH_MEMORY
19915   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19916  [(set (match_dup 2) (match_dup 1))
19917   (set (match_dup 0) (match_dup 2))]
19918  "")
19919
19920;; We need to handle SFmode only, because DFmode and XFmode is split to
19921;; SImode pushes.
19922(define_peephole2
19923  [(set (match_operand:SF 0 "push_operand" "")
19924	(match_operand:SF 1 "memory_operand" ""))
19925   (match_scratch:SF 2 "r")]
19926  "!optimize_size && !TARGET_PUSH_MEMORY
19927   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19928  [(set (match_dup 2) (match_dup 1))
19929   (set (match_dup 0) (match_dup 2))]
19930  "")
19931
19932(define_peephole2
19933  [(set (match_operand:HI 0 "push_operand" "")
19934	(match_operand:HI 1 "memory_operand" ""))
19935   (match_scratch:HI 2 "r")]
19936  "!optimize_size && !TARGET_PUSH_MEMORY
19937   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19938  [(set (match_dup 2) (match_dup 1))
19939   (set (match_dup 0) (match_dup 2))]
19940  "")
19941
19942(define_peephole2
19943  [(set (match_operand:QI 0 "push_operand" "")
19944	(match_operand:QI 1 "memory_operand" ""))
19945   (match_scratch:QI 2 "q")]
19946  "!optimize_size && !TARGET_PUSH_MEMORY
19947   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19948  [(set (match_dup 2) (match_dup 1))
19949   (set (match_dup 0) (match_dup 2))]
19950  "")
19951
19952;; Don't move an immediate directly to memory when the instruction
19953;; gets too big.
19954(define_peephole2
19955  [(match_scratch:SI 1 "r")
19956   (set (match_operand:SI 0 "memory_operand" "")
19957        (const_int 0))]
19958  "! optimize_size
19959   && ! TARGET_USE_MOV0
19960   && TARGET_SPLIT_LONG_MOVES
19961   && get_attr_length (insn) >= ix86_cost->large_insn
19962   && peep2_regno_dead_p (0, FLAGS_REG)"
19963  [(parallel [(set (match_dup 1) (const_int 0))
19964	      (clobber (reg:CC FLAGS_REG))])
19965   (set (match_dup 0) (match_dup 1))]
19966  "")
19967
19968(define_peephole2
19969  [(match_scratch:HI 1 "r")
19970   (set (match_operand:HI 0 "memory_operand" "")
19971        (const_int 0))]
19972  "! optimize_size
19973   && ! TARGET_USE_MOV0
19974   && TARGET_SPLIT_LONG_MOVES
19975   && get_attr_length (insn) >= ix86_cost->large_insn
19976   && peep2_regno_dead_p (0, FLAGS_REG)"
19977  [(parallel [(set (match_dup 2) (const_int 0))
19978	      (clobber (reg:CC FLAGS_REG))])
19979   (set (match_dup 0) (match_dup 1))]
19980  "operands[2] = gen_lowpart (SImode, operands[1]);")
19981
19982(define_peephole2
19983  [(match_scratch:QI 1 "q")
19984   (set (match_operand:QI 0 "memory_operand" "")
19985        (const_int 0))]
19986  "! optimize_size
19987   && ! TARGET_USE_MOV0
19988   && TARGET_SPLIT_LONG_MOVES
19989   && get_attr_length (insn) >= ix86_cost->large_insn
19990   && peep2_regno_dead_p (0, FLAGS_REG)"
19991  [(parallel [(set (match_dup 2) (const_int 0))
19992	      (clobber (reg:CC FLAGS_REG))])
19993   (set (match_dup 0) (match_dup 1))]
19994  "operands[2] = gen_lowpart (SImode, operands[1]);")
19995
19996(define_peephole2
19997  [(match_scratch:SI 2 "r")
19998   (set (match_operand:SI 0 "memory_operand" "")
19999        (match_operand:SI 1 "immediate_operand" ""))]
20000  "! optimize_size
20001   && get_attr_length (insn) >= ix86_cost->large_insn
20002   && TARGET_SPLIT_LONG_MOVES"
20003  [(set (match_dup 2) (match_dup 1))
20004   (set (match_dup 0) (match_dup 2))]
20005  "")
20006
20007(define_peephole2
20008  [(match_scratch:HI 2 "r")
20009   (set (match_operand:HI 0 "memory_operand" "")
20010        (match_operand:HI 1 "immediate_operand" ""))]
20011  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20012  && TARGET_SPLIT_LONG_MOVES"
20013  [(set (match_dup 2) (match_dup 1))
20014   (set (match_dup 0) (match_dup 2))]
20015  "")
20016
20017(define_peephole2
20018  [(match_scratch:QI 2 "q")
20019   (set (match_operand:QI 0 "memory_operand" "")
20020        (match_operand:QI 1 "immediate_operand" ""))]
20021  "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20022  && TARGET_SPLIT_LONG_MOVES"
20023  [(set (match_dup 2) (match_dup 1))
20024   (set (match_dup 0) (match_dup 2))]
20025  "")
20026
20027;; Don't compare memory with zero, load and use a test instead.
20028(define_peephole2
20029  [(set (match_operand 0 "flags_reg_operand" "")
20030 	(match_operator 1 "compare_operator"
20031	  [(match_operand:SI 2 "memory_operand" "")
20032	   (const_int 0)]))
20033   (match_scratch:SI 3 "r")]
20034  "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20035  [(set (match_dup 3) (match_dup 2))
20036   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20037  "")
20038
20039;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20040;; Don't split NOTs with a displacement operand, because resulting XOR
20041;; will not be pairable anyway.
20042;;
20043;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20044;; represented using a modRM byte.  The XOR replacement is long decoded,
20045;; so this split helps here as well.
20046;;
20047;; Note: Can't do this as a regular split because we can't get proper
20048;; lifetime information then.
20049
20050(define_peephole2
20051  [(set (match_operand:SI 0 "nonimmediate_operand" "")
20052	(not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20053  "!optimize_size
20054   && peep2_regno_dead_p (0, FLAGS_REG)
20055   && ((TARGET_PENTIUM
20056        && (GET_CODE (operands[0]) != MEM
20057            || !memory_displacement_operand (operands[0], SImode)))
20058       || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20059  [(parallel [(set (match_dup 0)
20060		   (xor:SI (match_dup 1) (const_int -1)))
20061	      (clobber (reg:CC FLAGS_REG))])]
20062  "")
20063
20064(define_peephole2
20065  [(set (match_operand:HI 0 "nonimmediate_operand" "")
20066	(not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20067  "!optimize_size
20068   && peep2_regno_dead_p (0, FLAGS_REG)
20069   && ((TARGET_PENTIUM
20070        && (GET_CODE (operands[0]) != MEM
20071            || !memory_displacement_operand (operands[0], HImode)))
20072       || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20073  [(parallel [(set (match_dup 0)
20074		   (xor:HI (match_dup 1) (const_int -1)))
20075	      (clobber (reg:CC FLAGS_REG))])]
20076  "")
20077
20078(define_peephole2
20079  [(set (match_operand:QI 0 "nonimmediate_operand" "")
20080	(not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20081  "!optimize_size
20082   && peep2_regno_dead_p (0, FLAGS_REG)
20083   && ((TARGET_PENTIUM
20084        && (GET_CODE (operands[0]) != MEM
20085            || !memory_displacement_operand (operands[0], QImode)))
20086       || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20087  [(parallel [(set (match_dup 0)
20088		   (xor:QI (match_dup 1) (const_int -1)))
20089	      (clobber (reg:CC FLAGS_REG))])]
20090  "")
20091
20092;; Non pairable "test imm, reg" instructions can be translated to
20093;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20094;; byte opcode instead of two, have a short form for byte operands),
20095;; so do it for other CPUs as well.  Given that the value was dead,
20096;; this should not create any new dependencies.  Pass on the sub-word
20097;; versions if we're concerned about partial register stalls.
20098
20099(define_peephole2
20100  [(set (match_operand 0 "flags_reg_operand" "")
20101	(match_operator 1 "compare_operator"
20102	  [(and:SI (match_operand:SI 2 "register_operand" "")
20103		   (match_operand:SI 3 "immediate_operand" ""))
20104	   (const_int 0)]))]
20105  "ix86_match_ccmode (insn, CCNOmode)
20106   && (true_regnum (operands[2]) != 0
20107       || satisfies_constraint_K (operands[3]))
20108   && peep2_reg_dead_p (1, operands[2])"
20109  [(parallel
20110     [(set (match_dup 0)
20111	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20112		            (const_int 0)]))
20113      (set (match_dup 2)
20114	   (and:SI (match_dup 2) (match_dup 3)))])]
20115  "")
20116
20117;; We don't need to handle HImode case, because it will be promoted to SImode
20118;; on ! TARGET_PARTIAL_REG_STALL
20119
20120(define_peephole2
20121  [(set (match_operand 0 "flags_reg_operand" "")
20122	(match_operator 1 "compare_operator"
20123	  [(and:QI (match_operand:QI 2 "register_operand" "")
20124		   (match_operand:QI 3 "immediate_operand" ""))
20125	   (const_int 0)]))]
20126  "! TARGET_PARTIAL_REG_STALL
20127   && ix86_match_ccmode (insn, CCNOmode)
20128   && true_regnum (operands[2]) != 0
20129   && peep2_reg_dead_p (1, operands[2])"
20130  [(parallel
20131     [(set (match_dup 0)
20132	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20133		            (const_int 0)]))
20134      (set (match_dup 2)
20135	   (and:QI (match_dup 2) (match_dup 3)))])]
20136  "")
20137
20138(define_peephole2
20139  [(set (match_operand 0 "flags_reg_operand" "")
20140	(match_operator 1 "compare_operator"
20141	  [(and:SI
20142	     (zero_extract:SI
20143	       (match_operand 2 "ext_register_operand" "")
20144	       (const_int 8)
20145	       (const_int 8))
20146	     (match_operand 3 "const_int_operand" ""))
20147	   (const_int 0)]))]
20148  "! TARGET_PARTIAL_REG_STALL
20149   && ix86_match_ccmode (insn, CCNOmode)
20150   && true_regnum (operands[2]) != 0
20151   && peep2_reg_dead_p (1, operands[2])"
20152  [(parallel [(set (match_dup 0)
20153		   (match_op_dup 1
20154		     [(and:SI
20155			(zero_extract:SI
20156			  (match_dup 2)
20157			  (const_int 8)
20158			  (const_int 8))
20159			(match_dup 3))
20160		      (const_int 0)]))
20161	      (set (zero_extract:SI (match_dup 2)
20162				    (const_int 8)
20163				    (const_int 8))
20164		   (and:SI
20165		     (zero_extract:SI
20166		       (match_dup 2)
20167		       (const_int 8)
20168		       (const_int 8))
20169		     (match_dup 3)))])]
20170  "")
20171
20172;; Don't do logical operations with memory inputs.
20173(define_peephole2
20174  [(match_scratch:SI 2 "r")
20175   (parallel [(set (match_operand:SI 0 "register_operand" "")
20176                   (match_operator:SI 3 "arith_or_logical_operator"
20177                     [(match_dup 0)
20178                      (match_operand:SI 1 "memory_operand" "")]))
20179              (clobber (reg:CC FLAGS_REG))])]
20180  "! optimize_size && ! TARGET_READ_MODIFY"
20181  [(set (match_dup 2) (match_dup 1))
20182   (parallel [(set (match_dup 0)
20183                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20184              (clobber (reg:CC FLAGS_REG))])]
20185  "")
20186
20187(define_peephole2
20188  [(match_scratch:SI 2 "r")
20189   (parallel [(set (match_operand:SI 0 "register_operand" "")
20190                   (match_operator:SI 3 "arith_or_logical_operator"
20191                     [(match_operand:SI 1 "memory_operand" "")
20192                      (match_dup 0)]))
20193              (clobber (reg:CC FLAGS_REG))])]
20194  "! optimize_size && ! TARGET_READ_MODIFY"
20195  [(set (match_dup 2) (match_dup 1))
20196   (parallel [(set (match_dup 0)
20197                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20198              (clobber (reg:CC FLAGS_REG))])]
20199  "")
20200
20201; Don't do logical operations with memory outputs
20202;
20203; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20204; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20205; the same decoder scheduling characteristics as the original.
20206
20207(define_peephole2
20208  [(match_scratch:SI 2 "r")
20209   (parallel [(set (match_operand:SI 0 "memory_operand" "")
20210                   (match_operator:SI 3 "arith_or_logical_operator"
20211                     [(match_dup 0)
20212                      (match_operand:SI 1 "nonmemory_operand" "")]))
20213              (clobber (reg:CC FLAGS_REG))])]
20214  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20215  [(set (match_dup 2) (match_dup 0))
20216   (parallel [(set (match_dup 2)
20217                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20218              (clobber (reg:CC FLAGS_REG))])
20219   (set (match_dup 0) (match_dup 2))]
20220  "")
20221
20222(define_peephole2
20223  [(match_scratch:SI 2 "r")
20224   (parallel [(set (match_operand:SI 0 "memory_operand" "")
20225                   (match_operator:SI 3 "arith_or_logical_operator"
20226                     [(match_operand:SI 1 "nonmemory_operand" "")
20227                      (match_dup 0)]))
20228              (clobber (reg:CC FLAGS_REG))])]
20229  "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20230  [(set (match_dup 2) (match_dup 0))
20231   (parallel [(set (match_dup 2)
20232                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20233              (clobber (reg:CC FLAGS_REG))])
20234   (set (match_dup 0) (match_dup 2))]
20235  "")
20236
20237;; Attempt to always use XOR for zeroing registers.
20238(define_peephole2
20239  [(set (match_operand 0 "register_operand" "")
20240	(match_operand 1 "const0_operand" ""))]
20241  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20242   && (! TARGET_USE_MOV0 || optimize_size)
20243   && GENERAL_REG_P (operands[0])
20244   && peep2_regno_dead_p (0, FLAGS_REG)"
20245  [(parallel [(set (match_dup 0) (const_int 0))
20246	      (clobber (reg:CC FLAGS_REG))])]
20247{
20248  operands[0] = gen_lowpart (word_mode, operands[0]);
20249})
20250
20251(define_peephole2
20252  [(set (strict_low_part (match_operand 0 "register_operand" ""))
20253	(const_int 0))]
20254  "(GET_MODE (operands[0]) == QImode
20255    || GET_MODE (operands[0]) == HImode)
20256   && (! TARGET_USE_MOV0 || optimize_size)
20257   && peep2_regno_dead_p (0, FLAGS_REG)"
20258  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20259	      (clobber (reg:CC FLAGS_REG))])])
20260
20261;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20262(define_peephole2
20263  [(set (match_operand 0 "register_operand" "")
20264	(const_int -1))]
20265  "(GET_MODE (operands[0]) == HImode
20266    || GET_MODE (operands[0]) == SImode
20267    || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20268   && (optimize_size || TARGET_PENTIUM)
20269   && peep2_regno_dead_p (0, FLAGS_REG)"
20270  [(parallel [(set (match_dup 0) (const_int -1))
20271	      (clobber (reg:CC FLAGS_REG))])]
20272  "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20273			      operands[0]);")
20274
20275;; Attempt to convert simple leas to adds. These can be created by
20276;; move expanders.
20277(define_peephole2
20278  [(set (match_operand:SI 0 "register_operand" "")
20279  	(plus:SI (match_dup 0)
20280		 (match_operand:SI 1 "nonmemory_operand" "")))]
20281  "peep2_regno_dead_p (0, FLAGS_REG)"
20282  [(parallel [(set (match_dup 0) (plus:SI (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  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20289			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20290  "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20291  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20292	      (clobber (reg:CC FLAGS_REG))])]
20293  "operands[2] = gen_lowpart (SImode, operands[2]);")
20294
20295(define_peephole2
20296  [(set (match_operand:DI 0 "register_operand" "")
20297  	(plus:DI (match_dup 0)
20298		 (match_operand:DI 1 "x86_64_general_operand" "")))]
20299  "peep2_regno_dead_p (0, FLAGS_REG)"
20300  [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20301	      (clobber (reg:CC FLAGS_REG))])]
20302  "")
20303
20304(define_peephole2
20305  [(set (match_operand:SI 0 "register_operand" "")
20306  	(mult:SI (match_dup 0)
20307		 (match_operand:SI 1 "const_int_operand" "")))]
20308  "exact_log2 (INTVAL (operands[1])) >= 0
20309   && peep2_regno_dead_p (0, FLAGS_REG)"
20310  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20311	      (clobber (reg:CC FLAGS_REG))])]
20312  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20313
20314(define_peephole2
20315  [(set (match_operand:DI 0 "register_operand" "")
20316  	(mult:DI (match_dup 0)
20317		 (match_operand:DI 1 "const_int_operand" "")))]
20318  "exact_log2 (INTVAL (operands[1])) >= 0
20319   && peep2_regno_dead_p (0, FLAGS_REG)"
20320  [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20321	      (clobber (reg:CC FLAGS_REG))])]
20322  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20323
20324(define_peephole2
20325  [(set (match_operand:SI 0 "register_operand" "")
20326  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20327		   (match_operand:DI 2 "const_int_operand" "")) 0))]
20328  "exact_log2 (INTVAL (operands[2])) >= 0
20329   && REGNO (operands[0]) == REGNO (operands[1])
20330   && peep2_regno_dead_p (0, FLAGS_REG)"
20331  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20332	      (clobber (reg:CC FLAGS_REG))])]
20333  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20334
20335;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20336;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20337;; many CPUs it is also faster, since special hardware to avoid esp
20338;; dependencies is present.
20339
20340;; While some of these conversions may be done using splitters, we use peepholes
20341;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20342
20343;; Convert prologue esp subtractions to push.
20344;; We need register to push.  In order to keep verify_flow_info happy we have
20345;; two choices
20346;; - use scratch and clobber it in order to avoid dependencies
20347;; - use already live register
20348;; We can't use the second way right now, since there is no reliable way how to
20349;; verify that given register is live.  First choice will also most likely in
20350;; fewer dependencies.  On the place of esp adjustments it is very likely that
20351;; call clobbered registers are dead.  We may want to use base pointer as an
20352;; alternative when no register is available later.
20353
20354(define_peephole2
20355  [(match_scratch:SI 0 "r")
20356   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20357	      (clobber (reg:CC FLAGS_REG))
20358	      (clobber (mem:BLK (scratch)))])]
20359  "optimize_size || !TARGET_SUB_ESP_4"
20360  [(clobber (match_dup 0))
20361   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20362	      (clobber (mem:BLK (scratch)))])])
20363
20364(define_peephole2
20365  [(match_scratch:SI 0 "r")
20366   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20367	      (clobber (reg:CC FLAGS_REG))
20368	      (clobber (mem:BLK (scratch)))])]
20369  "optimize_size || !TARGET_SUB_ESP_8"
20370  [(clobber (match_dup 0))
20371   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20372   (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20373	      (clobber (mem:BLK (scratch)))])])
20374
20375;; Convert esp subtractions to push.
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  "optimize_size || !TARGET_SUB_ESP_4"
20381  [(clobber (match_dup 0))
20382   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20383
20384(define_peephole2
20385  [(match_scratch:SI 0 "r")
20386   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20387	      (clobber (reg:CC FLAGS_REG))])]
20388  "optimize_size || !TARGET_SUB_ESP_8"
20389  [(clobber (match_dup 0))
20390   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20391   (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20392
20393;; Convert epilogue deallocator to pop.
20394(define_peephole2
20395  [(match_scratch:SI 0 "r")
20396   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20397	      (clobber (reg:CC FLAGS_REG))
20398	      (clobber (mem:BLK (scratch)))])]
20399  "optimize_size || !TARGET_ADD_ESP_4"
20400  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20401	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20402	      (clobber (mem:BLK (scratch)))])]
20403  "")
20404
20405;; Two pops case is tricky, since pop causes dependency on destination register.
20406;; We use two registers if available.
20407(define_peephole2
20408  [(match_scratch:SI 0 "r")
20409   (match_scratch:SI 1 "r")
20410   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20411	      (clobber (reg:CC FLAGS_REG))
20412	      (clobber (mem:BLK (scratch)))])]
20413  "optimize_size || !TARGET_ADD_ESP_8"
20414  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20415	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20416	      (clobber (mem:BLK (scratch)))])
20417   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20418	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20419  "")
20420
20421(define_peephole2
20422  [(match_scratch:SI 0 "r")
20423   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20424	      (clobber (reg:CC FLAGS_REG))
20425	      (clobber (mem:BLK (scratch)))])]
20426  "optimize_size"
20427  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20428	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20429	      (clobber (mem:BLK (scratch)))])
20430   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20431	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20432  "")
20433
20434;; Convert esp additions to pop.
20435(define_peephole2
20436  [(match_scratch:SI 0 "r")
20437   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20438	      (clobber (reg:CC FLAGS_REG))])]
20439  ""
20440  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20441	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20442  "")
20443
20444;; Two pops case is tricky, since pop causes dependency on destination register.
20445;; We use two registers if available.
20446(define_peephole2
20447  [(match_scratch:SI 0 "r")
20448   (match_scratch:SI 1 "r")
20449   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20450	      (clobber (reg:CC FLAGS_REG))])]
20451  ""
20452  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20453	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20454   (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20455	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20456  "")
20457
20458(define_peephole2
20459  [(match_scratch:SI 0 "r")
20460   (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20461	      (clobber (reg:CC FLAGS_REG))])]
20462  "optimize_size"
20463  [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20464	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20465   (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20466	      (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20467  "")
20468
20469;; Convert compares with 1 to shorter inc/dec operations when CF is not
20470;; required and register dies.  Similarly for 128 to plus -128.
20471(define_peephole2
20472  [(set (match_operand 0 "flags_reg_operand" "")
20473	(match_operator 1 "compare_operator"
20474	  [(match_operand 2 "register_operand" "")
20475	   (match_operand 3 "const_int_operand" "")]))]
20476  "(INTVAL (operands[3]) == -1
20477    || INTVAL (operands[3]) == 1
20478    || INTVAL (operands[3]) == 128)
20479   && ix86_match_ccmode (insn, CCGCmode)
20480   && peep2_reg_dead_p (1, operands[2])"
20481  [(parallel [(set (match_dup 0)
20482		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20483	      (clobber (match_dup 2))])]
20484  "")
20485
20486(define_peephole2
20487  [(match_scratch:DI 0 "r")
20488   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20489	      (clobber (reg:CC FLAGS_REG))
20490	      (clobber (mem:BLK (scratch)))])]
20491  "optimize_size || !TARGET_SUB_ESP_4"
20492  [(clobber (match_dup 0))
20493   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20494	      (clobber (mem:BLK (scratch)))])])
20495
20496(define_peephole2
20497  [(match_scratch:DI 0 "r")
20498   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20499	      (clobber (reg:CC FLAGS_REG))
20500	      (clobber (mem:BLK (scratch)))])]
20501  "optimize_size || !TARGET_SUB_ESP_8"
20502  [(clobber (match_dup 0))
20503   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20504   (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20505	      (clobber (mem:BLK (scratch)))])])
20506
20507;; Convert esp subtractions to push.
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  "optimize_size || !TARGET_SUB_ESP_4"
20513  [(clobber (match_dup 0))
20514   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20515
20516(define_peephole2
20517  [(match_scratch:DI 0 "r")
20518   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20519	      (clobber (reg:CC FLAGS_REG))])]
20520  "optimize_size || !TARGET_SUB_ESP_8"
20521  [(clobber (match_dup 0))
20522   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20523   (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20524
20525;; Convert epilogue deallocator to pop.
20526(define_peephole2
20527  [(match_scratch:DI 0 "r")
20528   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20529	      (clobber (reg:CC FLAGS_REG))
20530	      (clobber (mem:BLK (scratch)))])]
20531  "optimize_size || !TARGET_ADD_ESP_4"
20532  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20533	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20534	      (clobber (mem:BLK (scratch)))])]
20535  "")
20536
20537;; Two pops case is tricky, since pop causes dependency on destination register.
20538;; We use two registers if available.
20539(define_peephole2
20540  [(match_scratch:DI 0 "r")
20541   (match_scratch:DI 1 "r")
20542   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20543	      (clobber (reg:CC FLAGS_REG))
20544	      (clobber (mem:BLK (scratch)))])]
20545  "optimize_size || !TARGET_ADD_ESP_8"
20546  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20547	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20548	      (clobber (mem:BLK (scratch)))])
20549   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20550	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20551  "")
20552
20553(define_peephole2
20554  [(match_scratch:DI 0 "r")
20555   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20556	      (clobber (reg:CC FLAGS_REG))
20557	      (clobber (mem:BLK (scratch)))])]
20558  "optimize_size"
20559  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20560	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20561	      (clobber (mem:BLK (scratch)))])
20562   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20563	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20564  "")
20565
20566;; Convert esp additions to pop.
20567(define_peephole2
20568  [(match_scratch:DI 0 "r")
20569   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20570	      (clobber (reg:CC FLAGS_REG))])]
20571  ""
20572  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20573	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20574  "")
20575
20576;; Two pops case is tricky, since pop causes dependency on destination register.
20577;; We use two registers if available.
20578(define_peephole2
20579  [(match_scratch:DI 0 "r")
20580   (match_scratch:DI 1 "r")
20581   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20582	      (clobber (reg:CC FLAGS_REG))])]
20583  ""
20584  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20585	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20586   (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20587	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20588  "")
20589
20590(define_peephole2
20591  [(match_scratch:DI 0 "r")
20592   (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20593	      (clobber (reg:CC FLAGS_REG))])]
20594  "optimize_size"
20595  [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20596	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20597   (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20598	      (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20599  "")
20600
20601;; Convert imul by three, five and nine into lea
20602(define_peephole2
20603  [(parallel
20604    [(set (match_operand:SI 0 "register_operand" "")
20605	  (mult:SI (match_operand:SI 1 "register_operand" "")
20606		   (match_operand:SI 2 "const_int_operand" "")))
20607     (clobber (reg:CC FLAGS_REG))])]
20608  "INTVAL (operands[2]) == 3
20609   || INTVAL (operands[2]) == 5
20610   || INTVAL (operands[2]) == 9"
20611  [(set (match_dup 0)
20612        (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20613                 (match_dup 1)))]
20614  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20615
20616(define_peephole2
20617  [(parallel
20618    [(set (match_operand:SI 0 "register_operand" "")
20619          (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20620                   (match_operand:SI 2 "const_int_operand" "")))
20621     (clobber (reg:CC FLAGS_REG))])]
20622  "!optimize_size
20623   && (INTVAL (operands[2]) == 3
20624       || INTVAL (operands[2]) == 5
20625       || INTVAL (operands[2]) == 9)"
20626  [(set (match_dup 0) (match_dup 1))
20627   (set (match_dup 0)
20628        (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20629                 (match_dup 0)))]
20630  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20631
20632(define_peephole2
20633  [(parallel
20634    [(set (match_operand:DI 0 "register_operand" "")
20635	  (mult:DI (match_operand:DI 1 "register_operand" "")
20636		   (match_operand:DI 2 "const_int_operand" "")))
20637     (clobber (reg:CC FLAGS_REG))])]
20638  "TARGET_64BIT
20639   && (INTVAL (operands[2]) == 3
20640       || INTVAL (operands[2]) == 5
20641       || INTVAL (operands[2]) == 9)"
20642  [(set (match_dup 0)
20643        (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20644                 (match_dup 1)))]
20645  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20646
20647(define_peephole2
20648  [(parallel
20649    [(set (match_operand:DI 0 "register_operand" "")
20650          (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20651                   (match_operand:DI 2 "const_int_operand" "")))
20652     (clobber (reg:CC FLAGS_REG))])]
20653  "TARGET_64BIT
20654   && !optimize_size
20655   && (INTVAL (operands[2]) == 3
20656       || INTVAL (operands[2]) == 5
20657       || INTVAL (operands[2]) == 9)"
20658  [(set (match_dup 0) (match_dup 1))
20659   (set (match_dup 0)
20660        (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20661                 (match_dup 0)))]
20662  { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20663
20664;; Imul $32bit_imm, mem, reg is vector decoded, while
20665;; imul $32bit_imm, reg, reg is direct decoded.
20666(define_peephole2
20667  [(match_scratch:DI 3 "r")
20668   (parallel [(set (match_operand:DI 0 "register_operand" "")
20669		   (mult:DI (match_operand:DI 1 "memory_operand" "")
20670			    (match_operand:DI 2 "immediate_operand" "")))
20671	      (clobber (reg:CC FLAGS_REG))])]
20672  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20673   && !satisfies_constraint_K (operands[2])"
20674  [(set (match_dup 3) (match_dup 1))
20675   (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20676	      (clobber (reg:CC FLAGS_REG))])]
20677"")
20678
20679(define_peephole2
20680  [(match_scratch:SI 3 "r")
20681   (parallel [(set (match_operand:SI 0 "register_operand" "")
20682		   (mult:SI (match_operand:SI 1 "memory_operand" "")
20683			    (match_operand:SI 2 "immediate_operand" "")))
20684	      (clobber (reg:CC FLAGS_REG))])]
20685  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20686   && !satisfies_constraint_K (operands[2])"
20687  [(set (match_dup 3) (match_dup 1))
20688   (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20689	      (clobber (reg:CC FLAGS_REG))])]
20690"")
20691
20692(define_peephole2
20693  [(match_scratch:SI 3 "r")
20694   (parallel [(set (match_operand:DI 0 "register_operand" "")
20695		   (zero_extend:DI
20696		     (mult:SI (match_operand:SI 1 "memory_operand" "")
20697			      (match_operand:SI 2 "immediate_operand" ""))))
20698	      (clobber (reg:CC FLAGS_REG))])]
20699  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20700   && !satisfies_constraint_K (operands[2])"
20701  [(set (match_dup 3) (match_dup 1))
20702   (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20703	      (clobber (reg:CC FLAGS_REG))])]
20704"")
20705
20706;; imul $8/16bit_imm, regmem, reg is vector decoded.
20707;; Convert it into imul reg, reg
20708;; It would be better to force assembler to encode instruction using long
20709;; immediate, but there is apparently no way to do so.
20710(define_peephole2
20711  [(parallel [(set (match_operand:DI 0 "register_operand" "")
20712		   (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20713			    (match_operand:DI 2 "const_int_operand" "")))
20714	      (clobber (reg:CC FLAGS_REG))])
20715   (match_scratch:DI 3 "r")]
20716  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20717   && satisfies_constraint_K (operands[2])"
20718  [(set (match_dup 3) (match_dup 2))
20719   (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20720	      (clobber (reg:CC FLAGS_REG))])]
20721{
20722  if (!rtx_equal_p (operands[0], operands[1]))
20723    emit_move_insn (operands[0], operands[1]);
20724})
20725
20726(define_peephole2
20727  [(parallel [(set (match_operand:SI 0 "register_operand" "")
20728		   (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20729			    (match_operand:SI 2 "const_int_operand" "")))
20730	      (clobber (reg:CC FLAGS_REG))])
20731   (match_scratch:SI 3 "r")]
20732  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20733   && satisfies_constraint_K (operands[2])"
20734  [(set (match_dup 3) (match_dup 2))
20735   (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20736	      (clobber (reg:CC FLAGS_REG))])]
20737{
20738  if (!rtx_equal_p (operands[0], operands[1]))
20739    emit_move_insn (operands[0], operands[1]);
20740})
20741
20742(define_peephole2
20743  [(parallel [(set (match_operand:HI 0 "register_operand" "")
20744		   (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20745			    (match_operand:HI 2 "immediate_operand" "")))
20746	      (clobber (reg:CC FLAGS_REG))])
20747   (match_scratch:HI 3 "r")]
20748  "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20749  [(set (match_dup 3) (match_dup 2))
20750   (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20751	      (clobber (reg:CC FLAGS_REG))])]
20752{
20753  if (!rtx_equal_p (operands[0], operands[1]))
20754    emit_move_insn (operands[0], operands[1]);
20755})
20756
20757;; After splitting up read-modify operations, array accesses with memory
20758;; operands might end up in form:
20759;;  sall    $2, %eax
20760;;  movl    4(%esp), %edx
20761;;  addl    %edx, %eax
20762;; instead of pre-splitting:
20763;;  sall    $2, %eax
20764;;  addl    4(%esp), %eax
20765;; Turn it into:
20766;;  movl    4(%esp), %edx
20767;;  leal    (%edx,%eax,4), %eax
20768
20769(define_peephole2
20770  [(parallel [(set (match_operand 0 "register_operand" "")
20771		   (ashift (match_operand 1 "register_operand" "")
20772			   (match_operand 2 "const_int_operand" "")))
20773	       (clobber (reg:CC FLAGS_REG))])
20774   (set (match_operand 3 "register_operand")
20775        (match_operand 4 "x86_64_general_operand" ""))
20776   (parallel [(set (match_operand 5 "register_operand" "")
20777		   (plus (match_operand 6 "register_operand" "")
20778			 (match_operand 7 "register_operand" "")))
20779		   (clobber (reg:CC FLAGS_REG))])]
20780  "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20781   /* Validate MODE for lea.  */
20782   && ((!TARGET_PARTIAL_REG_STALL
20783	&& (GET_MODE (operands[0]) == QImode
20784	    || GET_MODE (operands[0]) == HImode))
20785       || GET_MODE (operands[0]) == SImode
20786       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20787   /* We reorder load and the shift.  */
20788   && !rtx_equal_p (operands[1], operands[3])
20789   && !reg_overlap_mentioned_p (operands[0], operands[4])
20790   /* Last PLUS must consist of operand 0 and 3.  */
20791   && !rtx_equal_p (operands[0], operands[3])
20792   && (rtx_equal_p (operands[3], operands[6])
20793       || rtx_equal_p (operands[3], operands[7]))
20794   && (rtx_equal_p (operands[0], operands[6])
20795       || rtx_equal_p (operands[0], operands[7]))
20796   /* The intermediate operand 0 must die or be same as output.  */
20797   && (rtx_equal_p (operands[0], operands[5])
20798       || peep2_reg_dead_p (3, operands[0]))"
20799  [(set (match_dup 3) (match_dup 4))
20800   (set (match_dup 0) (match_dup 1))]
20801{
20802  enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20803  int scale = 1 << INTVAL (operands[2]);
20804  rtx index = gen_lowpart (Pmode, operands[1]);
20805  rtx base = gen_lowpart (Pmode, operands[3]);
20806  rtx dest = gen_lowpart (mode, operands[5]);
20807
20808  operands[1] = gen_rtx_PLUS (Pmode, base,
20809  			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20810  if (mode != Pmode)
20811    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20812  operands[0] = dest;
20813})
20814
20815;; Call-value patterns last so that the wildcard operand does not
20816;; disrupt insn-recog's switch tables.
20817
20818(define_insn "*call_value_pop_0"
20819  [(set (match_operand 0 "" "")
20820	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20821	      (match_operand:SI 2 "" "")))
20822   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20823			    (match_operand:SI 3 "immediate_operand" "")))]
20824  "!TARGET_64BIT"
20825{
20826  if (SIBLING_CALL_P (insn))
20827    return "jmp\t%P1";
20828  else
20829    return "call\t%P1";
20830}
20831  [(set_attr "type" "callv")])
20832
20833(define_insn "*call_value_pop_1"
20834  [(set (match_operand 0 "" "")
20835	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20836	      (match_operand:SI 2 "" "")))
20837   (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20838			    (match_operand:SI 3 "immediate_operand" "i")))]
20839  "!TARGET_64BIT"
20840{
20841  if (constant_call_address_operand (operands[1], Pmode))
20842    {
20843      if (SIBLING_CALL_P (insn))
20844	return "jmp\t%P1";
20845      else
20846	return "call\t%P1";
20847    }
20848  if (SIBLING_CALL_P (insn))
20849    return "jmp\t%A1";
20850  else
20851    return "call\t%A1";
20852}
20853  [(set_attr "type" "callv")])
20854
20855(define_insn "*call_value_0"
20856  [(set (match_operand 0 "" "")
20857	(call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20858	      (match_operand:SI 2 "" "")))]
20859  "!TARGET_64BIT"
20860{
20861  if (SIBLING_CALL_P (insn))
20862    return "jmp\t%P1";
20863  else
20864    return "call\t%P1";
20865}
20866  [(set_attr "type" "callv")])
20867
20868(define_insn "*call_value_0_rex64"
20869  [(set (match_operand 0 "" "")
20870	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20871	      (match_operand:DI 2 "const_int_operand" "")))]
20872  "TARGET_64BIT"
20873{
20874  if (SIBLING_CALL_P (insn))
20875    return "jmp\t%P1";
20876  else
20877    return "call\t%P1";
20878}
20879  [(set_attr "type" "callv")])
20880
20881(define_insn "*call_value_1"
20882  [(set (match_operand 0 "" "")
20883	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20884	      (match_operand:SI 2 "" "")))]
20885  "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20886{
20887  if (constant_call_address_operand (operands[1], Pmode))
20888    return "call\t%P1";
20889  return "call\t%A1";
20890}
20891  [(set_attr "type" "callv")])
20892
20893(define_insn "*sibcall_value_1"
20894  [(set (match_operand 0 "" "")
20895	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20896	      (match_operand:SI 2 "" "")))]
20897  "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20898{
20899  if (constant_call_address_operand (operands[1], Pmode))
20900    return "jmp\t%P1";
20901  return "jmp\t%A1";
20902}
20903  [(set_attr "type" "callv")])
20904
20905(define_insn "*call_value_1_rex64"
20906  [(set (match_operand 0 "" "")
20907	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20908	      (match_operand:DI 2 "" "")))]
20909  "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20910{
20911  if (constant_call_address_operand (operands[1], Pmode))
20912    return "call\t%P1";
20913  return "call\t%A1";
20914}
20915  [(set_attr "type" "callv")])
20916
20917(define_insn "*sibcall_value_1_rex64"
20918  [(set (match_operand 0 "" "")
20919	(call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20920	      (match_operand:DI 2 "" "")))]
20921  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20922  "jmp\t%P1"
20923  [(set_attr "type" "callv")])
20924
20925(define_insn "*sibcall_value_1_rex64_v"
20926  [(set (match_operand 0 "" "")
20927	(call (mem:QI (reg:DI 40))
20928	      (match_operand:DI 1 "" "")))]
20929  "SIBLING_CALL_P (insn) && TARGET_64BIT"
20930  "jmp\t*%%r11"
20931  [(set_attr "type" "callv")])
20932
20933;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20934;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20935;; caught for use by garbage collectors and the like.  Using an insn that
20936;; maps to SIGILL makes it more likely the program will rightfully die.
20937;; Keeping with tradition, "6" is in honor of #UD.
20938(define_insn "trap"
20939  [(trap_if (const_int 1) (const_int 6))]
20940  ""
20941  { return ASM_SHORT "0x0b0f"; }
20942  [(set_attr "length" "2")])
20943
20944(define_expand "sse_prologue_save"
20945  [(parallel [(set (match_operand:BLK 0 "" "")
20946		   (unspec:BLK [(reg:DI 21)
20947				(reg:DI 22)
20948				(reg:DI 23)
20949				(reg:DI 24)
20950				(reg:DI 25)
20951				(reg:DI 26)
20952				(reg:DI 27)
20953				(reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20954	      (use (match_operand:DI 1 "register_operand" ""))
20955	      (use (match_operand:DI 2 "immediate_operand" ""))
20956	      (use (label_ref:DI (match_operand 3 "" "")))])]
20957  "TARGET_64BIT"
20958  "")
20959
20960(define_insn "*sse_prologue_save_insn"
20961  [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20962			  (match_operand:DI 4 "const_int_operand" "n")))
20963	(unspec:BLK [(reg:DI 21)
20964		     (reg:DI 22)
20965		     (reg:DI 23)
20966		     (reg:DI 24)
20967		     (reg:DI 25)
20968		     (reg:DI 26)
20969		     (reg:DI 27)
20970		     (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20971   (use (match_operand:DI 1 "register_operand" "r"))
20972   (use (match_operand:DI 2 "const_int_operand" "i"))
20973   (use (label_ref:DI (match_operand 3 "" "X")))]
20974  "TARGET_64BIT
20975   && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20976   && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20977  "*
20978{
20979  int i;
20980  operands[0] = gen_rtx_MEM (Pmode,
20981			     gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20982  output_asm_insn (\"jmp\\t%A1\", operands);
20983  for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20984    {
20985      operands[4] = adjust_address (operands[0], DImode, i*16);
20986      operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20987      PUT_MODE (operands[4], TImode);
20988      if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20989        output_asm_insn (\"rex\", operands);
20990      output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20991    }
20992  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20993			     CODE_LABEL_NUMBER (operands[3]));
20994  RET;
20995}
20996  "
20997  [(set_attr "type" "other")
20998   (set_attr "length_immediate" "0")
20999   (set_attr "length_address" "0")
21000   (set_attr "length" "135")
21001   (set_attr "memory" "store")
21002   (set_attr "modrm" "0")
21003   (set_attr "mode" "DI")])
21004
21005(define_expand "prefetch"
21006  [(prefetch (match_operand 0 "address_operand" "")
21007	     (match_operand:SI 1 "const_int_operand" "")
21008	     (match_operand:SI 2 "const_int_operand" ""))]
21009  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21010{
21011  int rw = INTVAL (operands[1]);
21012  int locality = INTVAL (operands[2]);
21013
21014  gcc_assert (rw == 0 || rw == 1);
21015  gcc_assert (locality >= 0 && locality <= 3);
21016  gcc_assert (GET_MODE (operands[0]) == Pmode
21017	      || GET_MODE (operands[0]) == VOIDmode);
21018
21019  /* Use 3dNOW prefetch in case we are asking for write prefetch not
21020     supported by SSE counterpart or the SSE prefetch is not available
21021     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21022     of locality.  */
21023  if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21024    operands[2] = GEN_INT (3);
21025  else
21026    operands[1] = const0_rtx;
21027})
21028
21029(define_insn "*prefetch_sse"
21030  [(prefetch (match_operand:SI 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_sse_rex"
21048  [(prefetch (match_operand:DI 0 "address_operand" "p")
21049	     (const_int 0)
21050	     (match_operand:SI 1 "const_int_operand" ""))]
21051  "TARGET_PREFETCH_SSE && TARGET_64BIT"
21052{
21053  static const char * const patterns[4] = {
21054   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21055  };
21056
21057  int locality = INTVAL (operands[1]);
21058  gcc_assert (locality >= 0 && locality <= 3);
21059
21060  return patterns[locality];
21061}
21062  [(set_attr "type" "sse")
21063   (set_attr "memory" "none")])
21064
21065(define_insn "*prefetch_3dnow"
21066  [(prefetch (match_operand:SI 0 "address_operand" "p")
21067	     (match_operand:SI 1 "const_int_operand" "n")
21068	     (const_int 3))]
21069  "TARGET_3DNOW && !TARGET_64BIT"
21070{
21071  if (INTVAL (operands[1]) == 0)
21072    return "prefetch\t%a0";
21073  else
21074    return "prefetchw\t%a0";
21075}
21076  [(set_attr "type" "mmx")
21077   (set_attr "memory" "none")])
21078
21079(define_insn "*prefetch_3dnow_rex"
21080  [(prefetch (match_operand:DI 0 "address_operand" "p")
21081	     (match_operand:SI 1 "const_int_operand" "n")
21082	     (const_int 3))]
21083  "TARGET_3DNOW && TARGET_64BIT"
21084{
21085  if (INTVAL (operands[1]) == 0)
21086    return "prefetch\t%a0";
21087  else
21088    return "prefetchw\t%a0";
21089}
21090  [(set_attr "type" "mmx")
21091   (set_attr "memory" "none")])
21092
21093(define_expand "stack_protect_set"
21094  [(match_operand 0 "memory_operand" "")
21095   (match_operand 1 "memory_operand" "")]
21096  ""
21097{
21098#ifdef TARGET_THREAD_SSP_OFFSET
21099  if (TARGET_64BIT)
21100    emit_insn (gen_stack_tls_protect_set_di (operands[0],
21101					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21102  else
21103    emit_insn (gen_stack_tls_protect_set_si (operands[0],
21104					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21105#else
21106  if (TARGET_64BIT)
21107    emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21108  else
21109    emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21110#endif
21111  DONE;
21112})
21113
21114(define_insn "stack_protect_set_si"
21115  [(set (match_operand:SI 0 "memory_operand" "=m")
21116	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21117   (set (match_scratch:SI 2 "=&r") (const_int 0))
21118   (clobber (reg:CC FLAGS_REG))]
21119  ""
21120  "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21121  [(set_attr "type" "multi")])
21122
21123(define_insn "stack_protect_set_di"
21124  [(set (match_operand:DI 0 "memory_operand" "=m")
21125	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21126   (set (match_scratch:DI 2 "=&r") (const_int 0))
21127   (clobber (reg:CC FLAGS_REG))]
21128  "TARGET_64BIT"
21129  "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21130  [(set_attr "type" "multi")])
21131
21132(define_insn "stack_tls_protect_set_si"
21133  [(set (match_operand:SI 0 "memory_operand" "=m")
21134	(unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21135   (set (match_scratch:SI 2 "=&r") (const_int 0))
21136   (clobber (reg:CC FLAGS_REG))]
21137  ""
21138  "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21139  [(set_attr "type" "multi")])
21140
21141(define_insn "stack_tls_protect_set_di"
21142  [(set (match_operand:DI 0 "memory_operand" "=m")
21143	(unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21144   (set (match_scratch:DI 2 "=&r") (const_int 0))
21145   (clobber (reg:CC FLAGS_REG))]
21146  "TARGET_64BIT"
21147  {
21148     /* The kernel uses a different segment register for performance reasons; a
21149        system call would not have to trash the userspace segment register,
21150        which would be expensive */
21151     if (ix86_cmodel != CM_KERNEL)
21152        return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21153     else
21154        return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21155  }
21156  [(set_attr "type" "multi")])
21157
21158(define_expand "stack_protect_test"
21159  [(match_operand 0 "memory_operand" "")
21160   (match_operand 1 "memory_operand" "")
21161   (match_operand 2 "" "")]
21162  ""
21163{
21164  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21165  ix86_compare_op0 = operands[0];
21166  ix86_compare_op1 = operands[1];
21167  ix86_compare_emitted = flags;
21168
21169#ifdef TARGET_THREAD_SSP_OFFSET
21170  if (TARGET_64BIT)
21171    emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21172					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21173  else
21174    emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21175					GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21176#else
21177  if (TARGET_64BIT)
21178    emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21179  else
21180    emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21181#endif
21182  emit_jump_insn (gen_beq (operands[2]));
21183  DONE;
21184})
21185
21186(define_insn "stack_protect_test_si"
21187  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21188	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21189		     (match_operand:SI 2 "memory_operand" "m")]
21190		    UNSPEC_SP_TEST))
21191   (clobber (match_scratch:SI 3 "=&r"))]
21192  ""
21193  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21194  [(set_attr "type" "multi")])
21195
21196(define_insn "stack_protect_test_di"
21197  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21198	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21199		     (match_operand:DI 2 "memory_operand" "m")]
21200		    UNSPEC_SP_TEST))
21201   (clobber (match_scratch:DI 3 "=&r"))]
21202  "TARGET_64BIT"
21203  "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21204  [(set_attr "type" "multi")])
21205
21206(define_insn "stack_tls_protect_test_si"
21207  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21208	(unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21209		     (match_operand:SI 2 "const_int_operand" "i")]
21210		    UNSPEC_SP_TLS_TEST))
21211   (clobber (match_scratch:SI 3 "=r"))]
21212  ""
21213  "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21214  [(set_attr "type" "multi")])
21215
21216(define_insn "stack_tls_protect_test_di"
21217  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21218	(unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21219		     (match_operand:DI 2 "const_int_operand" "i")]
21220		    UNSPEC_SP_TLS_TEST))
21221   (clobber (match_scratch:DI 3 "=r"))]
21222  "TARGET_64BIT"
21223  {
21224     /* The kernel uses a different segment register for performance reasons; a
21225        system call would not have to trash the userspace segment register,
21226        which would be expensive */
21227     if (ix86_cmodel != CM_KERNEL)
21228        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21229     else
21230        return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21231  }
21232  [(set_attr "type" "multi")])
21233
21234(include "mmx.md")
21235(include "sse.md")
21236(include "sync.md")
21237