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, 2007, 2008, 2009, 2010, 2011, 2012
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 3, 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 COPYING3.  If not see
22;; <http://www.gnu.org/licenses/>.  */
23;;
24;; The original PO technology requires these to be ordered by speed,
25;; so that assigner will pick the fastest.
26;;
27;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
28;;
29;; The special asm out single letter directives following a '%' are:
30;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31;; C -- print opcode suffix for set/cmov insn.
32;; c -- like C, but print reversed condition
33;; F,f -- likewise, but for floating-point.
34;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35;;      otherwise nothing
36;; R -- print the prefix for register names.
37;; z -- print the opcode suffix for the size of the current operand.
38;; Z -- likewise, with special suffixes for x87 instructions.
39;; * -- print a star (in certain assembler syntax)
40;; A -- print an absolute memory reference.
41;; E -- print address with DImode register names if TARGET_64BIT.
42;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43;; s -- print a shift double count, followed by the assemblers argument
44;;	delimiter.
45;; b -- print the QImode name of the register for the indicated operand.
46;;	%b0 would print %al if operands[0] is reg 0.
47;; w --  likewise, print the HImode name of the register.
48;; k --  likewise, print the SImode name of the register.
49;; q --  likewise, print the DImode name of the register.
50;; x --  likewise, print the V4SFmode name of the register.
51;; t --  likewise, print the V8SFmode name of the register.
52;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53;; y -- print "st(0)" instead of "st" as a register.
54;; d -- print duplicated register operand for AVX instruction.
55;; D -- print condition for SSE cmp instruction.
56;; P -- if PIC, print an @PLT suffix.
57;; p -- print raw symbol name.
58;; X -- don't print any sort of PIC '@' suffix for a symbol.
59;; & -- print some in-use local-dynamic symbol name.
60;; H -- print a memory address offset by 8; used for sse high-parts
61;; Y -- print condition for XOP pcom* instruction.
62;; + -- print a branch hint as 'cs' or 'ds' prefix
63;; ; -- print a semicolon (after prefixes due to bug in older gas).
64;; @ -- print a segment register of thread base pointer load
65
66(define_c_enum "unspec" [
67  ;; Relocation specifiers
68  UNSPEC_GOT
69  UNSPEC_GOTOFF
70  UNSPEC_GOTPCREL
71  UNSPEC_GOTTPOFF
72  UNSPEC_TPOFF
73  UNSPEC_NTPOFF
74  UNSPEC_DTPOFF
75  UNSPEC_GOTNTPOFF
76  UNSPEC_INDNTPOFF
77  UNSPEC_PLTOFF
78  UNSPEC_MACHOPIC_OFFSET
79  UNSPEC_PCREL
80
81  ;; Prologue support
82  UNSPEC_STACK_ALLOC
83  UNSPEC_SET_GOT
84  UNSPEC_SET_RIP
85  UNSPEC_SET_GOT_OFFSET
86  UNSPEC_MEMORY_BLOCKAGE
87  UNSPEC_STACK_CHECK
88
89  ;; TLS support
90  UNSPEC_TP
91  UNSPEC_TLS_GD
92  UNSPEC_TLS_LD_BASE
93  UNSPEC_TLSDESC
94  UNSPEC_TLS_IE_SUN
95
96  ;; Other random patterns
97  UNSPEC_SCAS
98  UNSPEC_FNSTSW
99  UNSPEC_SAHF
100  UNSPEC_PARITY
101  UNSPEC_FSTCW
102  UNSPEC_ADD_CARRY
103  UNSPEC_FLDCW
104  UNSPEC_REP
105  UNSPEC_LD_MPIC	; load_macho_picbase
106  UNSPEC_TRUNC_NOOP
107  UNSPEC_DIV_ALREADY_SPLIT
108  UNSPEC_MS_TO_SYSV_CALL
109  UNSPEC_CALL_NEEDS_VZEROUPPER
110  UNSPEC_PAUSE
111  UNSPEC_LEA_ADDR
112
113  ;; For SSE/MMX support:
114  UNSPEC_FIX_NOTRUNC
115  UNSPEC_MASKMOV
116  UNSPEC_MOVMSK
117  UNSPEC_RCP
118  UNSPEC_RSQRT
119  UNSPEC_PSADBW
120
121  ;; Generic math support
122  UNSPEC_COPYSIGN
123  UNSPEC_IEEE_MIN	; not commutative
124  UNSPEC_IEEE_MAX	; not commutative
125
126  ;; x87 Floating point
127  UNSPEC_SIN
128  UNSPEC_COS
129  UNSPEC_FPATAN
130  UNSPEC_FYL2X
131  UNSPEC_FYL2XP1
132  UNSPEC_FRNDINT
133  UNSPEC_FIST
134  UNSPEC_F2XM1
135  UNSPEC_TAN
136  UNSPEC_FXAM
137
138  ;; x87 Rounding
139  UNSPEC_FRNDINT_FLOOR
140  UNSPEC_FRNDINT_CEIL
141  UNSPEC_FRNDINT_TRUNC
142  UNSPEC_FRNDINT_MASK_PM
143  UNSPEC_FIST_FLOOR
144  UNSPEC_FIST_CEIL
145
146  ;; x87 Double output FP
147  UNSPEC_SINCOS_COS
148  UNSPEC_SINCOS_SIN
149  UNSPEC_XTRACT_FRACT
150  UNSPEC_XTRACT_EXP
151  UNSPEC_FSCALE_FRACT
152  UNSPEC_FSCALE_EXP
153  UNSPEC_FPREM_F
154  UNSPEC_FPREM_U
155  UNSPEC_FPREM1_F
156  UNSPEC_FPREM1_U
157
158  UNSPEC_C2_FLAG
159  UNSPEC_FXAM_MEM
160
161  ;; SSP patterns
162  UNSPEC_SP_SET
163  UNSPEC_SP_TEST
164  UNSPEC_SP_TLS_SET
165  UNSPEC_SP_TLS_TEST
166
167  ;; For ROUND support
168  UNSPEC_ROUND
169
170  ;; For CRC32 support
171  UNSPEC_CRC32
172
173  ;; For BMI support
174  UNSPEC_BEXTR
175
176  ;; For BMI2 support
177  UNSPEC_PDEP
178  UNSPEC_PEXT
179])
180
181(define_c_enum "unspecv" [
182  UNSPECV_BLOCKAGE
183  UNSPECV_STACK_PROBE
184  UNSPECV_PROBE_STACK_RANGE
185  UNSPECV_ALIGN
186  UNSPECV_PROLOGUE_USE
187  UNSPECV_SPLIT_STACK_RETURN
188  UNSPECV_CLD
189  UNSPECV_NOPS
190  UNSPECV_RDTSC
191  UNSPECV_RDTSCP
192  UNSPECV_RDPMC
193  UNSPECV_LLWP_INTRINSIC
194  UNSPECV_SLWP_INTRINSIC
195  UNSPECV_LWPVAL_INTRINSIC
196  UNSPECV_LWPINS_INTRINSIC
197  UNSPECV_RDFSBASE
198  UNSPECV_RDGSBASE
199  UNSPECV_WRFSBASE
200  UNSPECV_WRGSBASE
201
202  ;; For RDRAND support
203  UNSPECV_RDRAND
204])
205
206;; Constants to represent rounding modes in the ROUND instruction
207(define_constants
208  [(ROUND_FLOOR			0x1)
209   (ROUND_CEIL			0x2)
210   (ROUND_TRUNC			0x3)
211   (ROUND_MXCSR			0x4)
212   (ROUND_NO_EXC		0x8)
213  ])
214
215;; Constants to represent pcomtrue/pcomfalse variants
216(define_constants
217  [(PCOM_FALSE			0)
218   (PCOM_TRUE			1)
219   (COM_FALSE_S			2)
220   (COM_FALSE_P			3)
221   (COM_TRUE_S			4)
222   (COM_TRUE_P			5)
223  ])
224
225;; Constants used in the XOP pperm instruction
226(define_constants
227  [(PPERM_SRC			0x00)	/* copy source */
228   (PPERM_INVERT		0x20)	/* invert source */
229   (PPERM_REVERSE		0x40)	/* bit reverse source */
230   (PPERM_REV_INV		0x60)	/* bit reverse & invert src */
231   (PPERM_ZERO			0x80)	/* all 0's */
232   (PPERM_ONES			0xa0)	/* all 1's */
233   (PPERM_SIGN			0xc0)	/* propagate sign bit */
234   (PPERM_INV_SIGN		0xe0)	/* invert & propagate sign */
235   (PPERM_SRC1			0x00)	/* use first source byte */
236   (PPERM_SRC2			0x10)	/* use second source byte */
237   ])
238
239;; Registers by name.
240(define_constants
241  [(AX_REG			 0)
242   (DX_REG			 1)
243   (CX_REG			 2)
244   (BX_REG			 3)
245   (SI_REG			 4)
246   (DI_REG			 5)
247   (BP_REG			 6)
248   (SP_REG			 7)
249   (ST0_REG			 8)
250   (ST1_REG			 9)
251   (ST2_REG			10)
252   (ST3_REG			11)
253   (ST4_REG			12)
254   (ST5_REG			13)
255   (ST6_REG			14)
256   (ST7_REG			15)
257   (FLAGS_REG			17)
258   (FPSR_REG			18)
259   (FPCR_REG			19)
260   (XMM0_REG			21)
261   (XMM1_REG			22)
262   (XMM2_REG			23)
263   (XMM3_REG			24)
264   (XMM4_REG			25)
265   (XMM5_REG			26)
266   (XMM6_REG			27)
267   (XMM7_REG			28)
268   (MM0_REG			29)
269   (MM1_REG			30)
270   (MM2_REG			31)
271   (MM3_REG			32)
272   (MM4_REG			33)
273   (MM5_REG			34)
274   (MM6_REG			35)
275   (MM7_REG			36)
276   (R8_REG			37)
277   (R9_REG			38)
278   (R10_REG			39)
279   (R11_REG			40)
280   (R12_REG			41)
281   (R13_REG			42)
282   (XMM8_REG			45)
283   (XMM9_REG			46)
284   (XMM10_REG			47)
285   (XMM11_REG			48)
286   (XMM12_REG			49)
287   (XMM13_REG			50)
288   (XMM14_REG			51)
289   (XMM15_REG			52)
290  ])
291
292;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
293;; from i386.c.
294
295;; In C guard expressions, put expressions which may be compile-time
296;; constants first.  This allows for better optimization.  For
297;; example, write "TARGET_64BIT && reload_completed", not
298;; "reload_completed && TARGET_64BIT".
299
300
301;; Processor type.
302(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
303		    atom,generic64,amdfam10,bdver1,bdver2,btver1"
304  (const (symbol_ref "ix86_schedule")))
305
306;; A basic instruction type.  Refinements due to arguments to be
307;; provided in other attributes.
308(define_attr "type"
309  "other,multi,
310   alu,alu1,negnot,imov,imovx,lea,
311   incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
312   icmp,test,ibr,setcc,icmov,
313   push,pop,call,callv,leave,
314   str,bitmanip,
315   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
316   sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
317   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
318   ssemuladd,sse4arg,lwp,
319   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
320  (const_string "other"))
321
322;; Main data type used by the insn
323(define_attr "mode"
324  "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
325  (const_string "unknown"))
326
327;; The CPU unit operations uses.
328(define_attr "unit" "integer,i387,sse,mmx,unknown"
329  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
330	   (const_string "i387")
331	 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
332			  sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
333			  ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
334	   (const_string "sse")
335	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
336	   (const_string "mmx")
337	 (eq_attr "type" "other")
338	   (const_string "unknown")]
339	 (const_string "integer")))
340
341;; The (bounding maximum) length of an instruction immediate.
342(define_attr "length_immediate" ""
343  (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
344                          bitmanip,imulx")
345	   (const_int 0)
346	 (eq_attr "unit" "i387,sse,mmx")
347	   (const_int 0)
348	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
349			  rotate,rotatex,rotate1,imul,icmp,push,pop")
350	   (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
351	 (eq_attr "type" "imov,test")
352	   (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
353	 (eq_attr "type" "call")
354	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
355	     (const_int 4)
356	     (const_int 0))
357	 (eq_attr "type" "callv")
358	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
359	     (const_int 4)
360	     (const_int 0))
361	 ;; We don't know the size before shorten_branches.  Expect
362	 ;; the instruction to fit for better scheduling.
363	 (eq_attr "type" "ibr")
364	   (const_int 1)
365	 ]
366	 (symbol_ref "/* Update immediate_length and other attributes! */
367		      gcc_unreachable (),1")))
368
369;; The (bounding maximum) length of an instruction address.
370(define_attr "length_address" ""
371  (cond [(eq_attr "type" "str,other,multi,fxch")
372	   (const_int 0)
373	 (and (eq_attr "type" "call")
374	      (match_operand 0 "constant_call_address_operand" ""))
375	     (const_int 0)
376	 (and (eq_attr "type" "callv")
377	      (match_operand 1 "constant_call_address_operand" ""))
378	     (const_int 0)
379	 ]
380	 (symbol_ref "ix86_attr_length_address_default (insn)")))
381
382;; Set when length prefix is used.
383(define_attr "prefix_data16" ""
384  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
385	   (const_int 0)
386	 (eq_attr "mode" "HI")
387	   (const_int 1)
388	 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
389	   (const_int 1)
390	]
391	(const_int 0)))
392
393;; Set when string REP prefix is used.
394(define_attr "prefix_rep" ""
395  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
396	   (const_int 0)
397	 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
398	   (const_int 1)
399	]
400	(const_int 0)))
401
402;; Set when 0f opcode prefix is used.
403(define_attr "prefix_0f" ""
404  (if_then_else
405    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
406	 (eq_attr "unit" "sse,mmx"))
407    (const_int 1)
408    (const_int 0)))
409
410;; Set when REX opcode prefix is used.
411(define_attr "prefix_rex" ""
412  (cond [(not (match_test "TARGET_64BIT"))
413	   (const_int 0)
414	 (and (eq_attr "mode" "DI")
415	      (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
416		   (eq_attr "unit" "!mmx")))
417	   (const_int 1)
418	 (and (eq_attr "mode" "QI")
419	      (match_test "x86_extended_QIreg_mentioned_p (insn)"))
420	   (const_int 1)
421	 (match_test "x86_extended_reg_mentioned_p (insn)")
422	   (const_int 1)
423	 (and (eq_attr "type" "imovx")
424	      (match_operand:QI 1 "ext_QIreg_operand" ""))
425	   (const_int 1)
426	]
427	(const_int 0)))
428
429;; There are also additional prefixes in 3DNOW, SSSE3.
430;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
431;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
432;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
433(define_attr "prefix_extra" ""
434  (cond [(eq_attr "type" "ssemuladd,sse4arg")
435	   (const_int 2)
436	 (eq_attr "type" "sseiadd1,ssecvt1")
437	   (const_int 1)
438	]
439	(const_int 0)))
440
441;; Prefix used: original, VEX or maybe VEX.
442(define_attr "prefix" "orig,vex,maybe_vex"
443  (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
444    (const_string "vex")
445    (const_string "orig")))
446
447;; VEX W bit is used.
448(define_attr "prefix_vex_w" "" (const_int 0))
449
450;; The length of VEX prefix
451;; Only instructions with 0f prefix can have 2 byte VEX prefix,
452;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
453;; still prefix_0f 1, with prefix_extra 1.
454(define_attr "length_vex" ""
455  (if_then_else (and (eq_attr "prefix_0f" "1")
456		     (eq_attr "prefix_extra" "0"))
457    (if_then_else (eq_attr "prefix_vex_w" "1")
458      (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
459      (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
460    (if_then_else (eq_attr "prefix_vex_w" "1")
461      (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
462      (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
463
464;; Set when modrm byte is used.
465(define_attr "modrm" ""
466  (cond [(eq_attr "type" "str,leave")
467	   (const_int 0)
468	 (eq_attr "unit" "i387")
469	   (const_int 0)
470         (and (eq_attr "type" "incdec")
471	      (and (not (match_test "TARGET_64BIT"))
472		   (ior (match_operand:SI 1 "register_operand" "")
473			(match_operand:HI 1 "register_operand" ""))))
474	   (const_int 0)
475	 (and (eq_attr "type" "push")
476	      (not (match_operand 1 "memory_operand" "")))
477	   (const_int 0)
478	 (and (eq_attr "type" "pop")
479	      (not (match_operand 0 "memory_operand" "")))
480	   (const_int 0)
481	 (and (eq_attr "type" "imov")
482	      (and (not (eq_attr "mode" "DI"))
483		   (ior (and (match_operand 0 "register_operand" "")
484			     (match_operand 1 "immediate_operand" ""))
485		        (ior (and (match_operand 0 "ax_reg_operand" "")
486				  (match_operand 1 "memory_displacement_only_operand" ""))
487			     (and (match_operand 0 "memory_displacement_only_operand" "")
488				  (match_operand 1 "ax_reg_operand" ""))))))
489	   (const_int 0)
490	 (and (eq_attr "type" "call")
491	      (match_operand 0 "constant_call_address_operand" ""))
492	     (const_int 0)
493	 (and (eq_attr "type" "callv")
494	      (match_operand 1 "constant_call_address_operand" ""))
495	     (const_int 0)
496	 (and (eq_attr "type" "alu,alu1,icmp,test")
497	      (match_operand 0 "ax_reg_operand" ""))
498	     (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
499	 ]
500	 (const_int 1)))
501
502;; The (bounding maximum) length of an instruction in bytes.
503;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
504;; Later we may want to split them and compute proper length as for
505;; other insns.
506(define_attr "length" ""
507  (cond [(eq_attr "type" "other,multi,fistp,frndint")
508	   (const_int 16)
509	 (eq_attr "type" "fcmp")
510	   (const_int 4)
511	 (eq_attr "unit" "i387")
512	   (plus (const_int 2)
513		 (plus (attr "prefix_data16")
514		       (attr "length_address")))
515	 (ior (eq_attr "prefix" "vex")
516	      (and (eq_attr "prefix" "maybe_vex")
517		   (match_test "TARGET_AVX")))
518	   (plus (attr "length_vex")
519		 (plus (attr "length_immediate")
520		       (plus (attr "modrm")
521			     (attr "length_address"))))]
522	 (plus (plus (attr "modrm")
523		     (plus (attr "prefix_0f")
524			   (plus (attr "prefix_rex")
525				 (plus (attr "prefix_extra")
526				       (const_int 1)))))
527	       (plus (attr "prefix_rep")
528		     (plus (attr "prefix_data16")
529			   (plus (attr "length_immediate")
530				 (attr "length_address")))))))
531
532;; The `memory' attribute is `none' if no memory is referenced, `load' or
533;; `store' if there is a simple memory reference therein, or `unknown'
534;; if the instruction is complex.
535
536(define_attr "memory" "none,load,store,both,unknown"
537  (cond [(eq_attr "type" "other,multi,str,lwp")
538	   (const_string "unknown")
539	 (eq_attr "type" "lea,fcmov,fpspc")
540	   (const_string "none")
541	 (eq_attr "type" "fistp,leave")
542	   (const_string "both")
543	 (eq_attr "type" "frndint")
544	   (const_string "load")
545	 (eq_attr "type" "push")
546	   (if_then_else (match_operand 1 "memory_operand" "")
547	     (const_string "both")
548	     (const_string "store"))
549	 (eq_attr "type" "pop")
550	   (if_then_else (match_operand 0 "memory_operand" "")
551	     (const_string "both")
552	     (const_string "load"))
553	 (eq_attr "type" "setcc")
554	   (if_then_else (match_operand 0 "memory_operand" "")
555	     (const_string "store")
556	     (const_string "none"))
557	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
558	   (if_then_else (ior (match_operand 0 "memory_operand" "")
559			      (match_operand 1 "memory_operand" ""))
560	     (const_string "load")
561	     (const_string "none"))
562	 (eq_attr "type" "ibr")
563	   (if_then_else (match_operand 0 "memory_operand" "")
564	     (const_string "load")
565	     (const_string "none"))
566	 (eq_attr "type" "call")
567	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
568	     (const_string "none")
569	     (const_string "load"))
570	 (eq_attr "type" "callv")
571	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
572	     (const_string "none")
573	     (const_string "load"))
574	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
575	      (match_operand 1 "memory_operand" ""))
576	   (const_string "both")
577	 (and (match_operand 0 "memory_operand" "")
578	      (match_operand 1 "memory_operand" ""))
579	   (const_string "both")
580	 (match_operand 0 "memory_operand" "")
581	   (const_string "store")
582	 (match_operand 1 "memory_operand" "")
583	   (const_string "load")
584	 (and (eq_attr "type"
585		 "!alu1,negnot,ishift1,
586		   imov,imovx,icmp,test,bitmanip,
587		   fmov,fcmp,fsgn,
588		   sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
589		   sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
590	      (match_operand 2 "memory_operand" ""))
591	   (const_string "load")
592	 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
593	      (match_operand 3 "memory_operand" ""))
594	   (const_string "load")
595	]
596	(const_string "none")))
597
598;; Indicates if an instruction has both an immediate and a displacement.
599
600(define_attr "imm_disp" "false,true,unknown"
601  (cond [(eq_attr "type" "other,multi")
602	   (const_string "unknown")
603	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
604	      (and (match_operand 0 "memory_displacement_operand" "")
605		   (match_operand 1 "immediate_operand" "")))
606	   (const_string "true")
607	 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
608	      (and (match_operand 0 "memory_displacement_operand" "")
609		   (match_operand 2 "immediate_operand" "")))
610	   (const_string "true")
611	]
612	(const_string "false")))
613
614;; Indicates if an FP operation has an integer source.
615
616(define_attr "fp_int_src" "false,true"
617  (const_string "false"))
618
619;; Defines rounding mode of an FP operation.
620
621(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
622  (const_string "any"))
623
624;; Define attribute to classify add/sub insns that consumes carry flag (CF)
625(define_attr "use_carry" "0,1" (const_string "0"))
626
627;; Define attribute to indicate unaligned ssemov insns
628(define_attr "movu" "0,1" (const_string "0"))
629
630;; Used to control the "enabled" attribute on a per-instruction basis.
631(define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
632		    bmi2,fma4,fma"
633  (const_string "base"))
634
635(define_attr "enabled" ""
636  (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
637	 (eq_attr "isa" "sse2_noavx")
638	   (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
639	 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
640	 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
641	 (eq_attr "isa" "sse4_noavx")
642	   (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
643	 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
644	 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
645	 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
646	 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
647	 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
648	]
649	(const_int 1)))
650
651;; Describe a user's asm statement.
652(define_asm_attributes
653  [(set_attr "length" "128")
654   (set_attr "type" "multi")])
655
656(define_code_iterator plusminus [plus minus])
657
658(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
659
660;; Base name for define_insn
661(define_code_attr plusminus_insn
662  [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
663   (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
664
665;; Base name for insn mnemonic.
666(define_code_attr plusminus_mnemonic
667  [(plus "add") (ss_plus "adds") (us_plus "addus")
668   (minus "sub") (ss_minus "subs") (us_minus "subus")])
669(define_code_attr plusminus_carry_mnemonic
670  [(plus "adc") (minus "sbb")])
671
672;; Mark commutative operators as such in constraints.
673(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
674			(minus "") (ss_minus "") (us_minus "")])
675
676;; Mapping of max and min
677(define_code_iterator maxmin [smax smin umax umin])
678
679;; Mapping of signed max and min
680(define_code_iterator smaxmin [smax smin])
681
682;; Mapping of unsigned max and min
683(define_code_iterator umaxmin [umax umin])
684
685;; Base name for integer and FP insn mnemonic
686(define_code_attr maxmin_int [(smax "maxs") (smin "mins")
687			      (umax "maxu") (umin "minu")])
688(define_code_attr maxmin_float [(smax "max") (smin "min")])
689
690;; Mapping of logic operators
691(define_code_iterator any_logic [and ior xor])
692(define_code_iterator any_or [ior xor])
693
694;; Base name for insn mnemonic.
695(define_code_attr logic [(and "and") (ior "or") (xor "xor")])
696
697;; Mapping of logic-shift operators
698(define_code_iterator any_lshift [ashift lshiftrt])
699
700;; Mapping of shift-right operators
701(define_code_iterator any_shiftrt [lshiftrt ashiftrt])
702
703;; Base name for define_insn
704(define_code_attr shift_insn
705  [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
706
707;; Base name for insn mnemonic.
708(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
709(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
710
711;; Mapping of rotate operators
712(define_code_iterator any_rotate [rotate rotatert])
713
714;; Base name for define_insn
715(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
716
717;; Base name for insn mnemonic.
718(define_code_attr rotate [(rotate "rol") (rotatert "ror")])
719
720;; Mapping of abs neg operators
721(define_code_iterator absneg [abs neg])
722
723;; Base name for x87 insn mnemonic.
724(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
725
726;; Used in signed and unsigned widening multiplications.
727(define_code_iterator any_extend [sign_extend zero_extend])
728
729;; Prefix for insn menmonic.
730(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
731
732;; Prefix for define_insn
733(define_code_attr u [(sign_extend "") (zero_extend "u")])
734(define_code_attr s [(sign_extend "s") (zero_extend "u")])
735
736;; All integer modes.
737(define_mode_iterator SWI1248x [QI HI SI DI])
738
739;; All integer modes without QImode.
740(define_mode_iterator SWI248x [HI SI DI])
741
742;; All integer modes without QImode and HImode.
743(define_mode_iterator SWI48x [SI DI])
744
745;; All integer modes without SImode and DImode.
746(define_mode_iterator SWI12 [QI HI])
747
748;; All integer modes without DImode.
749(define_mode_iterator SWI124 [QI HI SI])
750
751;; All integer modes without QImode and DImode.
752(define_mode_iterator SWI24 [HI SI])
753
754;; Single word integer modes.
755(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
756
757;; Single word integer modes without QImode.
758(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
759
760;; Single word integer modes without QImode and HImode.
761(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
762
763;; All math-dependant single and double word integer modes.
764(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
765			     (HI "TARGET_HIMODE_MATH")
766			     SI DI (TI "TARGET_64BIT")])
767
768;; Math-dependant single word integer modes.
769(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
770			    (HI "TARGET_HIMODE_MATH")
771			    SI (DI "TARGET_64BIT")])
772
773;; Math-dependant integer modes without DImode.
774(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
775			       (HI "TARGET_HIMODE_MATH")
776			       SI])
777
778;; Math-dependant single word integer modes without QImode.
779(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
780		      	       SI (DI "TARGET_64BIT")])
781
782;; Double word integer modes.
783(define_mode_iterator DWI [(DI "!TARGET_64BIT")
784			   (TI "TARGET_64BIT")])
785
786;; Double word integer modes as mode attribute.
787(define_mode_attr DWI [(SI "DI") (DI "TI")])
788(define_mode_attr dwi [(SI "di") (DI "ti")])
789
790;; Half mode for double word integer modes.
791(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
792			    (DI "TARGET_64BIT")])
793
794;; Instruction suffix for integer modes.
795(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
796
797;; Pointer size prefix for integer modes (Intel asm dialect)
798(define_mode_attr iptrsize [(QI "BYTE")
799			    (HI "WORD")
800			    (SI "DWORD")
801			    (DI "QWORD")])
802
803;; Register class for integer modes.
804(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
805
806;; Immediate operand constraint for integer modes.
807(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
808
809;; General operand constraint for word modes.
810(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
811
812;; Immediate operand constraint for double integer modes.
813(define_mode_attr di [(SI "nF") (DI "e")])
814
815;; Immediate operand constraint for shifts.
816(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
817
818;; General operand predicate for integer modes.
819(define_mode_attr general_operand
820	[(QI "general_operand")
821	 (HI "general_operand")
822	 (SI "x86_64_general_operand")
823	 (DI "x86_64_general_operand")
824	 (TI "x86_64_general_operand")])
825
826;; General sign/zero extend operand predicate for integer modes.
827(define_mode_attr general_szext_operand
828	[(QI "general_operand")
829	 (HI "general_operand")
830	 (SI "x86_64_szext_general_operand")
831	 (DI "x86_64_szext_general_operand")])
832
833;; Immediate operand predicate for integer modes.
834(define_mode_attr immediate_operand
835	[(QI "immediate_operand")
836	 (HI "immediate_operand")
837	 (SI "x86_64_immediate_operand")
838	 (DI "x86_64_immediate_operand")])
839
840;; Nonmemory operand predicate for integer modes.
841(define_mode_attr nonmemory_operand
842	[(QI "nonmemory_operand")
843	 (HI "nonmemory_operand")
844	 (SI "x86_64_nonmemory_operand")
845	 (DI "x86_64_nonmemory_operand")])
846
847;; Operand predicate for shifts.
848(define_mode_attr shift_operand
849	[(QI "nonimmediate_operand")
850	 (HI "nonimmediate_operand")
851	 (SI "nonimmediate_operand")
852	 (DI "shiftdi_operand")
853	 (TI "register_operand")])
854
855;; Operand predicate for shift argument.
856(define_mode_attr shift_immediate_operand
857	[(QI "const_1_to_31_operand")
858	 (HI "const_1_to_31_operand")
859	 (SI "const_1_to_31_operand")
860	 (DI "const_1_to_63_operand")])
861
862;; Input operand predicate for arithmetic left shifts.
863(define_mode_attr ashl_input_operand
864	[(QI "nonimmediate_operand")
865	 (HI "nonimmediate_operand")
866	 (SI "nonimmediate_operand")
867	 (DI "ashldi_input_operand")
868	 (TI "reg_or_pm1_operand")])
869
870;; SSE and x87 SFmode and DFmode floating point modes
871(define_mode_iterator MODEF [SF DF])
872
873;; All x87 floating point modes
874(define_mode_iterator X87MODEF [SF DF XF])
875
876;; SSE instruction suffix for various modes
877(define_mode_attr ssemodesuffix
878  [(SF "ss") (DF "sd")
879   (V8SF "ps") (V4DF "pd")
880   (V4SF "ps") (V2DF "pd")
881   (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
882   (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
883
884;; SSE vector suffix for floating point modes
885(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
886
887;; SSE vector mode corresponding to a scalar mode
888(define_mode_attr ssevecmode
889  [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
890
891;; Instruction suffix for REX 64bit operators.
892(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
893
894;; This mode iterator allows :P to be used for patterns that operate on
895;; pointer-sized quantities.  Exactly one of the two alternatives will match.
896(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
897
898;; This mode iterator allows :PTR to be used for patterns that operate on
899;; ptr_mode sized quantities.
900(define_mode_iterator PTR
901  [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
902
903;; Scheduling descriptions
904
905(include "pentium.md")
906(include "ppro.md")
907(include "k6.md")
908(include "athlon.md")
909(include "bdver1.md")
910(include "geode.md")
911(include "atom.md")
912(include "core2.md")
913
914
915;; Operand and operator predicates and constraints
916
917(include "predicates.md")
918(include "constraints.md")
919
920
921;; Compare and branch/compare and store instructions.
922
923(define_expand "cbranch<mode>4"
924  [(set (reg:CC FLAGS_REG)
925	(compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
926		    (match_operand:SDWIM 2 "<general_operand>" "")))
927   (set (pc) (if_then_else
928	       (match_operator 0 "ordered_comparison_operator"
929		[(reg:CC FLAGS_REG) (const_int 0)])
930	       (label_ref (match_operand 3 "" ""))
931	       (pc)))]
932  ""
933{
934  if (MEM_P (operands[1]) && MEM_P (operands[2]))
935    operands[1] = force_reg (<MODE>mode, operands[1]);
936  ix86_expand_branch (GET_CODE (operands[0]),
937		      operands[1], operands[2], operands[3]);
938  DONE;
939})
940
941(define_expand "cstore<mode>4"
942  [(set (reg:CC FLAGS_REG)
943	(compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
944		    (match_operand:SWIM 3 "<general_operand>" "")))
945   (set (match_operand:QI 0 "register_operand" "")
946	(match_operator 1 "ordered_comparison_operator"
947	  [(reg:CC FLAGS_REG) (const_int 0)]))]
948  ""
949{
950  if (MEM_P (operands[2]) && MEM_P (operands[3]))
951    operands[2] = force_reg (<MODE>mode, operands[2]);
952  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
953		     operands[2], operands[3]);
954  DONE;
955})
956
957(define_expand "cmp<mode>_1"
958  [(set (reg:CC FLAGS_REG)
959	(compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
960		    (match_operand:SWI48 1 "<general_operand>" "")))])
961
962(define_insn "*cmp<mode>_ccno_1"
963  [(set (reg FLAGS_REG)
964	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
965		 (match_operand:SWI 1 "const0_operand" "")))]
966  "ix86_match_ccmode (insn, CCNOmode)"
967  "@
968   test{<imodesuffix>}\t%0, %0
969   cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
970  [(set_attr "type" "test,icmp")
971   (set_attr "length_immediate" "0,1")
972   (set_attr "mode" "<MODE>")])
973
974(define_insn "*cmp<mode>_1"
975  [(set (reg FLAGS_REG)
976	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
977		 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
978  "ix86_match_ccmode (insn, CCmode)"
979  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
980  [(set_attr "type" "icmp")
981   (set_attr "mode" "<MODE>")])
982
983(define_insn "*cmp<mode>_minus_1"
984  [(set (reg FLAGS_REG)
985	(compare
986	  (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
987		     (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
988	  (const_int 0)))]
989  "ix86_match_ccmode (insn, CCGOCmode)"
990  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
991  [(set_attr "type" "icmp")
992   (set_attr "mode" "<MODE>")])
993
994(define_insn "*cmpqi_ext_1"
995  [(set (reg FLAGS_REG)
996	(compare
997	  (match_operand:QI 0 "general_operand" "Qm")
998	  (subreg:QI
999	    (zero_extract:SI
1000	      (match_operand 1 "ext_register_operand" "Q")
1001	      (const_int 8)
1002	      (const_int 8)) 0)))]
1003  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1004  "cmp{b}\t{%h1, %0|%0, %h1}"
1005  [(set_attr "type" "icmp")
1006   (set_attr "mode" "QI")])
1007
1008(define_insn "*cmpqi_ext_1_rex64"
1009  [(set (reg FLAGS_REG)
1010	(compare
1011	  (match_operand:QI 0 "register_operand" "Q")
1012	  (subreg:QI
1013	    (zero_extract:SI
1014	      (match_operand 1 "ext_register_operand" "Q")
1015	      (const_int 8)
1016	      (const_int 8)) 0)))]
1017  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1018  "cmp{b}\t{%h1, %0|%0, %h1}"
1019  [(set_attr "type" "icmp")
1020   (set_attr "mode" "QI")])
1021
1022(define_insn "*cmpqi_ext_2"
1023  [(set (reg FLAGS_REG)
1024	(compare
1025	  (subreg:QI
1026	    (zero_extract:SI
1027	      (match_operand 0 "ext_register_operand" "Q")
1028	      (const_int 8)
1029	      (const_int 8)) 0)
1030	  (match_operand:QI 1 "const0_operand" "")))]
1031  "ix86_match_ccmode (insn, CCNOmode)"
1032  "test{b}\t%h0, %h0"
1033  [(set_attr "type" "test")
1034   (set_attr "length_immediate" "0")
1035   (set_attr "mode" "QI")])
1036
1037(define_expand "cmpqi_ext_3"
1038  [(set (reg:CC FLAGS_REG)
1039	(compare:CC
1040	  (subreg:QI
1041	    (zero_extract:SI
1042	      (match_operand 0 "ext_register_operand" "")
1043	      (const_int 8)
1044	      (const_int 8)) 0)
1045	  (match_operand:QI 1 "immediate_operand" "")))])
1046
1047(define_insn "*cmpqi_ext_3_insn"
1048  [(set (reg FLAGS_REG)
1049	(compare
1050	  (subreg:QI
1051	    (zero_extract:SI
1052	      (match_operand 0 "ext_register_operand" "Q")
1053	      (const_int 8)
1054	      (const_int 8)) 0)
1055	  (match_operand:QI 1 "general_operand" "Qmn")))]
1056  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1057  "cmp{b}\t{%1, %h0|%h0, %1}"
1058  [(set_attr "type" "icmp")
1059   (set_attr "modrm" "1")
1060   (set_attr "mode" "QI")])
1061
1062(define_insn "*cmpqi_ext_3_insn_rex64"
1063  [(set (reg FLAGS_REG)
1064	(compare
1065	  (subreg:QI
1066	    (zero_extract:SI
1067	      (match_operand 0 "ext_register_operand" "Q")
1068	      (const_int 8)
1069	      (const_int 8)) 0)
1070	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1071  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1072  "cmp{b}\t{%1, %h0|%h0, %1}"
1073  [(set_attr "type" "icmp")
1074   (set_attr "modrm" "1")
1075   (set_attr "mode" "QI")])
1076
1077(define_insn "*cmpqi_ext_4"
1078  [(set (reg FLAGS_REG)
1079	(compare
1080	  (subreg:QI
1081	    (zero_extract:SI
1082	      (match_operand 0 "ext_register_operand" "Q")
1083	      (const_int 8)
1084	      (const_int 8)) 0)
1085	  (subreg:QI
1086	    (zero_extract:SI
1087	      (match_operand 1 "ext_register_operand" "Q")
1088	      (const_int 8)
1089	      (const_int 8)) 0)))]
1090  "ix86_match_ccmode (insn, CCmode)"
1091  "cmp{b}\t{%h1, %h0|%h0, %h1}"
1092  [(set_attr "type" "icmp")
1093   (set_attr "mode" "QI")])
1094
1095;; These implement float point compares.
1096;; %%% See if we can get away with VOIDmode operands on the actual insns,
1097;; which would allow mix and match FP modes on the compares.  Which is what
1098;; the old patterns did, but with many more of them.
1099
1100(define_expand "cbranchxf4"
1101  [(set (reg:CC FLAGS_REG)
1102	(compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1103		    (match_operand:XF 2 "nonmemory_operand" "")))
1104   (set (pc) (if_then_else
1105              (match_operator 0 "ix86_fp_comparison_operator"
1106               [(reg:CC FLAGS_REG)
1107                (const_int 0)])
1108              (label_ref (match_operand 3 "" ""))
1109              (pc)))]
1110  "TARGET_80387"
1111{
1112  ix86_expand_branch (GET_CODE (operands[0]),
1113		      operands[1], operands[2], operands[3]);
1114  DONE;
1115})
1116
1117(define_expand "cstorexf4"
1118  [(set (reg:CC FLAGS_REG)
1119	(compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1120		    (match_operand:XF 3 "nonmemory_operand" "")))
1121   (set (match_operand:QI 0 "register_operand" "")
1122              (match_operator 1 "ix86_fp_comparison_operator"
1123               [(reg:CC FLAGS_REG)
1124                (const_int 0)]))]
1125  "TARGET_80387"
1126{
1127  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1128		     operands[2], operands[3]);
1129  DONE;
1130})
1131
1132(define_expand "cbranch<mode>4"
1133  [(set (reg:CC FLAGS_REG)
1134	(compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1135		    (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1136   (set (pc) (if_then_else
1137              (match_operator 0 "ix86_fp_comparison_operator"
1138               [(reg:CC FLAGS_REG)
1139                (const_int 0)])
1140              (label_ref (match_operand 3 "" ""))
1141              (pc)))]
1142  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1143{
1144  ix86_expand_branch (GET_CODE (operands[0]),
1145		      operands[1], operands[2], operands[3]);
1146  DONE;
1147})
1148
1149(define_expand "cstore<mode>4"
1150  [(set (reg:CC FLAGS_REG)
1151	(compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1152		    (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1153   (set (match_operand:QI 0 "register_operand" "")
1154              (match_operator 1 "ix86_fp_comparison_operator"
1155               [(reg:CC FLAGS_REG)
1156                (const_int 0)]))]
1157  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1158{
1159  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1160		     operands[2], operands[3]);
1161  DONE;
1162})
1163
1164(define_expand "cbranchcc4"
1165  [(set (pc) (if_then_else
1166              (match_operator 0 "comparison_operator"
1167               [(match_operand 1 "flags_reg_operand" "")
1168                (match_operand 2 "const0_operand" "")])
1169              (label_ref (match_operand 3 "" ""))
1170              (pc)))]
1171  ""
1172{
1173  ix86_expand_branch (GET_CODE (operands[0]),
1174		      operands[1], operands[2], operands[3]);
1175  DONE;
1176})
1177
1178(define_expand "cstorecc4"
1179  [(set (match_operand:QI 0 "register_operand" "")
1180              (match_operator 1 "comparison_operator"
1181               [(match_operand 2 "flags_reg_operand" "")
1182                (match_operand 3 "const0_operand" "")]))]
1183  ""
1184{
1185  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1186		     operands[2], operands[3]);
1187  DONE;
1188})
1189
1190
1191;; FP compares, step 1:
1192;; Set the FP condition codes.
1193;;
1194;; CCFPmode	compare with exceptions
1195;; CCFPUmode	compare with no exceptions
1196
1197;; We may not use "#" to split and emit these, since the REG_DEAD notes
1198;; used to manage the reg stack popping would not be preserved.
1199
1200(define_insn "*cmpfp_0"
1201  [(set (match_operand:HI 0 "register_operand" "=a")
1202	(unspec:HI
1203	  [(compare:CCFP
1204	     (match_operand 1 "register_operand" "f")
1205	     (match_operand 2 "const0_operand" ""))]
1206	UNSPEC_FNSTSW))]
1207  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1208   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1209  "* return output_fp_compare (insn, operands, false, false);"
1210  [(set_attr "type" "multi")
1211   (set_attr "unit" "i387")
1212   (set (attr "mode")
1213     (cond [(match_operand:SF 1 "" "")
1214	      (const_string "SF")
1215	    (match_operand:DF 1 "" "")
1216	      (const_string "DF")
1217	   ]
1218	   (const_string "XF")))])
1219
1220(define_insn_and_split "*cmpfp_0_cc"
1221  [(set (reg:CCFP FLAGS_REG)
1222	(compare:CCFP
1223	  (match_operand 1 "register_operand" "f")
1224	  (match_operand 2 "const0_operand" "")))
1225   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1226  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227   && TARGET_SAHF && !TARGET_CMOVE
1228   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1229  "#"
1230  "&& reload_completed"
1231  [(set (match_dup 0)
1232	(unspec:HI
1233	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1234	UNSPEC_FNSTSW))
1235   (set (reg:CC FLAGS_REG)
1236	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1237  ""
1238  [(set_attr "type" "multi")
1239   (set_attr "unit" "i387")
1240   (set (attr "mode")
1241     (cond [(match_operand:SF 1 "" "")
1242	      (const_string "SF")
1243	    (match_operand:DF 1 "" "")
1244	      (const_string "DF")
1245	   ]
1246	   (const_string "XF")))])
1247
1248(define_insn "*cmpfp_xf"
1249  [(set (match_operand:HI 0 "register_operand" "=a")
1250	(unspec:HI
1251	  [(compare:CCFP
1252	     (match_operand:XF 1 "register_operand" "f")
1253	     (match_operand:XF 2 "register_operand" "f"))]
1254	  UNSPEC_FNSTSW))]
1255  "TARGET_80387"
1256  "* return output_fp_compare (insn, operands, false, false);"
1257  [(set_attr "type" "multi")
1258   (set_attr "unit" "i387")
1259   (set_attr "mode" "XF")])
1260
1261(define_insn_and_split "*cmpfp_xf_cc"
1262  [(set (reg:CCFP FLAGS_REG)
1263	(compare:CCFP
1264	  (match_operand:XF 1 "register_operand" "f")
1265	  (match_operand:XF 2 "register_operand" "f")))
1266   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1267  "TARGET_80387
1268   && TARGET_SAHF && !TARGET_CMOVE"
1269  "#"
1270  "&& reload_completed"
1271  [(set (match_dup 0)
1272	(unspec:HI
1273	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1274	UNSPEC_FNSTSW))
1275   (set (reg:CC FLAGS_REG)
1276	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1277  ""
1278  [(set_attr "type" "multi")
1279   (set_attr "unit" "i387")
1280   (set_attr "mode" "XF")])
1281
1282(define_insn "*cmpfp_<mode>"
1283  [(set (match_operand:HI 0 "register_operand" "=a")
1284	(unspec:HI
1285	  [(compare:CCFP
1286	     (match_operand:MODEF 1 "register_operand" "f")
1287	     (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1288	  UNSPEC_FNSTSW))]
1289  "TARGET_80387"
1290  "* return output_fp_compare (insn, operands, false, false);"
1291  [(set_attr "type" "multi")
1292   (set_attr "unit" "i387")
1293   (set_attr "mode" "<MODE>")])
1294
1295(define_insn_and_split "*cmpfp_<mode>_cc"
1296  [(set (reg:CCFP FLAGS_REG)
1297	(compare:CCFP
1298	  (match_operand:MODEF 1 "register_operand" "f")
1299	  (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1300   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1301  "TARGET_80387
1302   && TARGET_SAHF && !TARGET_CMOVE"
1303  "#"
1304  "&& reload_completed"
1305  [(set (match_dup 0)
1306	(unspec:HI
1307	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1308	UNSPEC_FNSTSW))
1309   (set (reg:CC FLAGS_REG)
1310	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1311  ""
1312  [(set_attr "type" "multi")
1313   (set_attr "unit" "i387")
1314   (set_attr "mode" "<MODE>")])
1315
1316(define_insn "*cmpfp_u"
1317  [(set (match_operand:HI 0 "register_operand" "=a")
1318	(unspec:HI
1319	  [(compare:CCFPU
1320	     (match_operand 1 "register_operand" "f")
1321	     (match_operand 2 "register_operand" "f"))]
1322	  UNSPEC_FNSTSW))]
1323  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1324   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1325  "* return output_fp_compare (insn, operands, false, true);"
1326  [(set_attr "type" "multi")
1327   (set_attr "unit" "i387")
1328   (set (attr "mode")
1329     (cond [(match_operand:SF 1 "" "")
1330	      (const_string "SF")
1331	    (match_operand:DF 1 "" "")
1332	      (const_string "DF")
1333	   ]
1334	   (const_string "XF")))])
1335
1336(define_insn_and_split "*cmpfp_u_cc"
1337  [(set (reg:CCFPU FLAGS_REG)
1338	(compare:CCFPU
1339	  (match_operand 1 "register_operand" "f")
1340	  (match_operand 2 "register_operand" "f")))
1341   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1342  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343   && TARGET_SAHF && !TARGET_CMOVE
1344   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1345  "#"
1346  "&& reload_completed"
1347  [(set (match_dup 0)
1348	(unspec:HI
1349	  [(compare:CCFPU (match_dup 1)(match_dup 2))]
1350	UNSPEC_FNSTSW))
1351   (set (reg:CC FLAGS_REG)
1352	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1353  ""
1354  [(set_attr "type" "multi")
1355   (set_attr "unit" "i387")
1356   (set (attr "mode")
1357     (cond [(match_operand:SF 1 "" "")
1358	      (const_string "SF")
1359	    (match_operand:DF 1 "" "")
1360	      (const_string "DF")
1361	   ]
1362	   (const_string "XF")))])
1363
1364(define_insn "*cmpfp_<mode>"
1365  [(set (match_operand:HI 0 "register_operand" "=a")
1366	(unspec:HI
1367	  [(compare:CCFP
1368	     (match_operand 1 "register_operand" "f")
1369	     (match_operator 3 "float_operator"
1370	       [(match_operand:SWI24 2 "memory_operand" "m")]))]
1371	  UNSPEC_FNSTSW))]
1372  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1373   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1374   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1375  "* return output_fp_compare (insn, operands, false, false);"
1376  [(set_attr "type" "multi")
1377   (set_attr "unit" "i387")
1378   (set_attr "fp_int_src" "true")
1379   (set_attr "mode" "<MODE>")])
1380
1381(define_insn_and_split "*cmpfp_<mode>_cc"
1382  [(set (reg:CCFP FLAGS_REG)
1383	(compare:CCFP
1384	  (match_operand 1 "register_operand" "f")
1385	  (match_operator 3 "float_operator"
1386	    [(match_operand:SWI24 2 "memory_operand" "m")])))
1387   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1388  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1389   && TARGET_SAHF && !TARGET_CMOVE
1390   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1391   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1392  "#"
1393  "&& reload_completed"
1394  [(set (match_dup 0)
1395	(unspec:HI
1396	  [(compare:CCFP
1397	     (match_dup 1)
1398	     (match_op_dup 3 [(match_dup 2)]))]
1399	UNSPEC_FNSTSW))
1400   (set (reg:CC FLAGS_REG)
1401	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1402  ""
1403  [(set_attr "type" "multi")
1404   (set_attr "unit" "i387")
1405   (set_attr "fp_int_src" "true")
1406   (set_attr "mode" "<MODE>")])
1407
1408;; FP compares, step 2
1409;; Move the fpsw to ax.
1410
1411(define_insn "x86_fnstsw_1"
1412  [(set (match_operand:HI 0 "register_operand" "=a")
1413	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1414  "TARGET_80387"
1415  "fnstsw\t%0"
1416  [(set (attr "length")
1417	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1418   (set_attr "mode" "SI")
1419   (set_attr "unit" "i387")])
1420
1421;; FP compares, step 3
1422;; Get ax into flags, general case.
1423
1424(define_insn "x86_sahf_1"
1425  [(set (reg:CC FLAGS_REG)
1426	(unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1427		   UNSPEC_SAHF))]
1428  "TARGET_SAHF"
1429{
1430#ifndef HAVE_AS_IX86_SAHF
1431  if (TARGET_64BIT)
1432    return ASM_BYTE "0x9e";
1433  else
1434#endif
1435  return "sahf";
1436}
1437  [(set_attr "length" "1")
1438   (set_attr "athlon_decode" "vector")
1439   (set_attr "amdfam10_decode" "direct")
1440   (set_attr "bdver1_decode" "direct")
1441   (set_attr "mode" "SI")])
1442
1443;; Pentium Pro can do steps 1 through 3 in one go.
1444;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1445;; (these i387 instructions set flags directly)
1446(define_insn "*cmpfp_i_mixed"
1447  [(set (reg:CCFP FLAGS_REG)
1448	(compare:CCFP (match_operand 0 "register_operand" "f,x")
1449		      (match_operand 1 "nonimmediate_operand" "f,xm")))]
1450  "TARGET_MIX_SSE_I387
1451   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1452   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1453  "* return output_fp_compare (insn, operands, true, false);"
1454  [(set_attr "type" "fcmp,ssecomi")
1455   (set_attr "prefix" "orig,maybe_vex")
1456   (set (attr "mode")
1457     (if_then_else (match_operand:SF 1 "" "")
1458        (const_string "SF")
1459        (const_string "DF")))
1460   (set (attr "prefix_rep")
1461	(if_then_else (eq_attr "type" "ssecomi")
1462		      (const_string "0")
1463		      (const_string "*")))
1464   (set (attr "prefix_data16")
1465	(cond [(eq_attr "type" "fcmp")
1466		 (const_string "*")
1467	       (eq_attr "mode" "DF")
1468		 (const_string "1")
1469	      ]
1470	      (const_string "0")))
1471   (set_attr "athlon_decode" "vector")
1472   (set_attr "amdfam10_decode" "direct")
1473   (set_attr "bdver1_decode" "double")])
1474
1475(define_insn "*cmpfp_i_sse"
1476  [(set (reg:CCFP FLAGS_REG)
1477	(compare:CCFP (match_operand 0 "register_operand" "x")
1478		      (match_operand 1 "nonimmediate_operand" "xm")))]
1479  "TARGET_SSE_MATH
1480   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1481   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1482  "* return output_fp_compare (insn, operands, true, false);"
1483  [(set_attr "type" "ssecomi")
1484   (set_attr "prefix" "maybe_vex")
1485   (set (attr "mode")
1486     (if_then_else (match_operand:SF 1 "" "")
1487        (const_string "SF")
1488        (const_string "DF")))
1489   (set_attr "prefix_rep" "0")
1490   (set (attr "prefix_data16")
1491	(if_then_else (eq_attr "mode" "DF")
1492		      (const_string "1")
1493		      (const_string "0")))
1494   (set_attr "athlon_decode" "vector")
1495   (set_attr "amdfam10_decode" "direct")
1496   (set_attr "bdver1_decode" "double")])
1497
1498(define_insn "*cmpfp_i_i387"
1499  [(set (reg:CCFP FLAGS_REG)
1500	(compare:CCFP (match_operand 0 "register_operand" "f")
1501		      (match_operand 1 "register_operand" "f")))]
1502  "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1503   && TARGET_CMOVE
1504   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1505   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1506  "* return output_fp_compare (insn, operands, true, false);"
1507  [(set_attr "type" "fcmp")
1508   (set (attr "mode")
1509     (cond [(match_operand:SF 1 "" "")
1510	      (const_string "SF")
1511	    (match_operand:DF 1 "" "")
1512	      (const_string "DF")
1513	   ]
1514	   (const_string "XF")))
1515   (set_attr "athlon_decode" "vector")
1516   (set_attr "amdfam10_decode" "direct")
1517   (set_attr "bdver1_decode" "double")])
1518
1519(define_insn "*cmpfp_iu_mixed"
1520  [(set (reg:CCFPU FLAGS_REG)
1521	(compare:CCFPU (match_operand 0 "register_operand" "f,x")
1522		       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1523  "TARGET_MIX_SSE_I387
1524   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1525   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526  "* return output_fp_compare (insn, operands, true, true);"
1527  [(set_attr "type" "fcmp,ssecomi")
1528   (set_attr "prefix" "orig,maybe_vex")
1529   (set (attr "mode")
1530     (if_then_else (match_operand:SF 1 "" "")
1531        (const_string "SF")
1532        (const_string "DF")))
1533   (set (attr "prefix_rep")
1534	(if_then_else (eq_attr "type" "ssecomi")
1535		      (const_string "0")
1536		      (const_string "*")))
1537   (set (attr "prefix_data16")
1538	(cond [(eq_attr "type" "fcmp")
1539		 (const_string "*")
1540	       (eq_attr "mode" "DF")
1541		 (const_string "1")
1542	      ]
1543	      (const_string "0")))
1544   (set_attr "athlon_decode" "vector")
1545   (set_attr "amdfam10_decode" "direct")
1546   (set_attr "bdver1_decode" "double")])
1547
1548(define_insn "*cmpfp_iu_sse"
1549  [(set (reg:CCFPU FLAGS_REG)
1550	(compare:CCFPU (match_operand 0 "register_operand" "x")
1551		       (match_operand 1 "nonimmediate_operand" "xm")))]
1552  "TARGET_SSE_MATH
1553   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1554   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1555  "* return output_fp_compare (insn, operands, true, true);"
1556  [(set_attr "type" "ssecomi")
1557   (set_attr "prefix" "maybe_vex")
1558   (set (attr "mode")
1559     (if_then_else (match_operand:SF 1 "" "")
1560        (const_string "SF")
1561        (const_string "DF")))
1562   (set_attr "prefix_rep" "0")
1563   (set (attr "prefix_data16")
1564	(if_then_else (eq_attr "mode" "DF")
1565		      (const_string "1")
1566		      (const_string "0")))
1567   (set_attr "athlon_decode" "vector")
1568   (set_attr "amdfam10_decode" "direct")
1569   (set_attr "bdver1_decode" "double")])
1570
1571(define_insn "*cmpfp_iu_387"
1572  [(set (reg:CCFPU FLAGS_REG)
1573	(compare:CCFPU (match_operand 0 "register_operand" "f")
1574		       (match_operand 1 "register_operand" "f")))]
1575  "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1576   && TARGET_CMOVE
1577   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1578   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1579  "* return output_fp_compare (insn, operands, true, true);"
1580  [(set_attr "type" "fcmp")
1581   (set (attr "mode")
1582     (cond [(match_operand:SF 1 "" "")
1583	      (const_string "SF")
1584	    (match_operand:DF 1 "" "")
1585	      (const_string "DF")
1586	   ]
1587	   (const_string "XF")))
1588   (set_attr "athlon_decode" "vector")
1589   (set_attr "amdfam10_decode" "direct")
1590   (set_attr "bdver1_decode" "direct")])
1591
1592;; Push/pop instructions.
1593
1594(define_insn "*push<mode>2"
1595  [(set (match_operand:DWI 0 "push_operand" "=<")
1596	(match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1597  ""
1598  "#"
1599  [(set_attr "type" "multi")
1600   (set_attr "mode" "<MODE>")])
1601
1602(define_split
1603  [(set (match_operand:TI 0 "push_operand" "")
1604        (match_operand:TI 1 "general_operand" ""))]
1605  "TARGET_64BIT && reload_completed
1606   && !SSE_REG_P (operands[1])"
1607  [(const_int 0)]
1608  "ix86_split_long_move (operands); DONE;")
1609
1610(define_insn "*pushdi2_rex64"
1611  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1612	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1613  "TARGET_64BIT"
1614  "@
1615   push{q}\t%1
1616   #"
1617  [(set_attr "type" "push,multi")
1618   (set_attr "mode" "DI")])
1619
1620;; Convert impossible pushes of immediate to existing instructions.
1621;; First try to get scratch register and go through it.  In case this
1622;; fails, push sign extended lower part first and then overwrite
1623;; upper part by 32bit move.
1624(define_peephole2
1625  [(match_scratch:DI 2 "r")
1626   (set (match_operand:DI 0 "push_operand" "")
1627        (match_operand:DI 1 "immediate_operand" ""))]
1628  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1629   && !x86_64_immediate_operand (operands[1], DImode)"
1630  [(set (match_dup 2) (match_dup 1))
1631   (set (match_dup 0) (match_dup 2))])
1632
1633;; We need to define this as both peepholer and splitter for case
1634;; peephole2 pass is not run.
1635;; "&& 1" is needed to keep it from matching the previous pattern.
1636(define_peephole2
1637  [(set (match_operand:DI 0 "push_operand" "")
1638        (match_operand:DI 1 "immediate_operand" ""))]
1639  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1640   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1641  [(set (match_dup 0) (match_dup 1))
1642   (set (match_dup 2) (match_dup 3))]
1643{
1644  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1645
1646  operands[1] = gen_lowpart (DImode, operands[2]);
1647  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1648						   GEN_INT (4)));
1649})
1650
1651(define_split
1652  [(set (match_operand:DI 0 "push_operand" "")
1653        (match_operand:DI 1 "immediate_operand" ""))]
1654  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1655		    ? epilogue_completed : reload_completed)
1656   && !symbolic_operand (operands[1], DImode)
1657   && !x86_64_immediate_operand (operands[1], DImode)"
1658  [(set (match_dup 0) (match_dup 1))
1659   (set (match_dup 2) (match_dup 3))]
1660{
1661  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1662
1663  operands[1] = gen_lowpart (DImode, operands[2]);
1664  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665						   GEN_INT (4)));
1666})
1667
1668(define_split
1669  [(set (match_operand:DI 0 "push_operand" "")
1670        (match_operand:DI 1 "general_operand" ""))]
1671  "!TARGET_64BIT && reload_completed
1672   && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1673  [(const_int 0)]
1674  "ix86_split_long_move (operands); DONE;")
1675
1676(define_insn "*pushsi2"
1677  [(set (match_operand:SI 0 "push_operand" "=<")
1678	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1679  "!TARGET_64BIT"
1680  "push{l}\t%1"
1681  [(set_attr "type" "push")
1682   (set_attr "mode" "SI")])
1683
1684;; emit_push_insn when it calls move_by_pieces requires an insn to
1685;; "push a byte/word".  But actually we use pushl, which has the effect
1686;; of rounding the amount pushed up to a word.
1687
1688;; For TARGET_64BIT we always round up to 8 bytes.
1689(define_insn "*push<mode>2_rex64"
1690  [(set (match_operand:SWI124 0 "push_operand" "=X")
1691	(match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1692  "TARGET_64BIT"
1693  "push{q}\t%q1"
1694  [(set_attr "type" "push")
1695   (set_attr "mode" "DI")])
1696
1697(define_insn "*push<mode>2"
1698  [(set (match_operand:SWI12 0 "push_operand" "=X")
1699	(match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1700  "!TARGET_64BIT"
1701  "push{l}\t%k1"
1702  [(set_attr "type" "push")
1703   (set_attr "mode" "SI")])
1704
1705(define_insn "*push<mode>2_prologue"
1706  [(set (match_operand:P 0 "push_operand" "=<")
1707	(match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1708   (clobber (mem:BLK (scratch)))]
1709  ""
1710  "push{<imodesuffix>}\t%1"
1711  [(set_attr "type" "push")
1712   (set_attr "mode" "<MODE>")])
1713
1714(define_insn "*pop<mode>1"
1715  [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1716	(match_operand:P 1 "pop_operand" ">"))]
1717  ""
1718  "pop{<imodesuffix>}\t%0"
1719  [(set_attr "type" "pop")
1720   (set_attr "mode" "<MODE>")])
1721
1722(define_insn "*pop<mode>1_epilogue"
1723  [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1724	(match_operand:P 1 "pop_operand" ">"))
1725   (clobber (mem:BLK (scratch)))]
1726  ""
1727  "pop{<imodesuffix>}\t%0"
1728  [(set_attr "type" "pop")
1729   (set_attr "mode" "<MODE>")])
1730
1731;; Move instructions.
1732
1733(define_expand "movoi"
1734  [(set (match_operand:OI 0 "nonimmediate_operand" "")
1735	(match_operand:OI 1 "general_operand" ""))]
1736  "TARGET_AVX"
1737  "ix86_expand_move (OImode, operands); DONE;")
1738
1739(define_expand "movti"
1740  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1741	(match_operand:TI 1 "nonimmediate_operand" ""))]
1742  "TARGET_64BIT || TARGET_SSE"
1743{
1744  if (TARGET_64BIT)
1745    ix86_expand_move (TImode, operands);
1746  else if (push_operand (operands[0], TImode))
1747    ix86_expand_push (TImode, operands[1]);
1748  else
1749    ix86_expand_vector_move (TImode, operands);
1750  DONE;
1751})
1752
1753;; This expands to what emit_move_complex would generate if we didn't
1754;; have a movti pattern.  Having this avoids problems with reload on
1755;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1756;; to have around all the time.
1757(define_expand "movcdi"
1758  [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1759	(match_operand:CDI 1 "general_operand" ""))]
1760  ""
1761{
1762  if (push_operand (operands[0], CDImode))
1763    emit_move_complex_push (CDImode, operands[0], operands[1]);
1764  else
1765    emit_move_complex_parts (operands[0], operands[1]);
1766  DONE;
1767})
1768
1769(define_expand "mov<mode>"
1770  [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1771	(match_operand:SWI1248x 1 "general_operand" ""))]
1772  ""
1773  "ix86_expand_move (<MODE>mode, operands); DONE;")
1774
1775(define_insn "*mov<mode>_xor"
1776  [(set (match_operand:SWI48 0 "register_operand" "=r")
1777	(match_operand:SWI48 1 "const0_operand" ""))
1778   (clobber (reg:CC FLAGS_REG))]
1779  "reload_completed"
1780  "xor{l}\t%k0, %k0"
1781  [(set_attr "type" "alu1")
1782   (set_attr "mode" "SI")
1783   (set_attr "length_immediate" "0")])
1784
1785(define_insn "*mov<mode>_or"
1786  [(set (match_operand:SWI48 0 "register_operand" "=r")
1787	(match_operand:SWI48 1 "const_int_operand" ""))
1788   (clobber (reg:CC FLAGS_REG))]
1789  "reload_completed
1790   && operands[1] == constm1_rtx"
1791  "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1792  [(set_attr "type" "alu1")
1793   (set_attr "mode" "<MODE>")
1794   (set_attr "length_immediate" "1")])
1795
1796(define_insn "*movoi_internal_avx"
1797  [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1798	(match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1799  "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1800{
1801  switch (which_alternative)
1802    {
1803    case 0:
1804      return standard_sse_constant_opcode (insn, operands[1]);
1805    case 1:
1806    case 2:
1807      if (misaligned_operand (operands[0], OImode)
1808	  || misaligned_operand (operands[1], OImode))
1809	return "vmovdqu\t{%1, %0|%0, %1}";
1810      else
1811	return "vmovdqa\t{%1, %0|%0, %1}";
1812    default:
1813      gcc_unreachable ();
1814    }
1815}
1816  [(set_attr "type" "sselog1,ssemov,ssemov")
1817   (set_attr "prefix" "vex")
1818   (set_attr "mode" "OI")])
1819
1820(define_insn "*movti_internal_rex64"
1821  [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1822	(match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1823  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1824{
1825  switch (which_alternative)
1826    {
1827    case 0:
1828    case 1:
1829      return "#";
1830    case 2:
1831      return standard_sse_constant_opcode (insn, operands[1]);
1832    case 3:
1833    case 4:
1834      /* TDmode values are passed as TImode on the stack.  Moving them
1835	 to stack may result in unaligned memory access.  */
1836      if (misaligned_operand (operands[0], TImode)
1837	  || misaligned_operand (operands[1], TImode))
1838	{
1839	  if (get_attr_mode (insn) == MODE_V4SF)
1840	    return "%vmovups\t{%1, %0|%0, %1}";
1841	  else
1842	    return "%vmovdqu\t{%1, %0|%0, %1}";
1843	}
1844      else
1845	{
1846	  if (get_attr_mode (insn) == MODE_V4SF)
1847	    return "%vmovaps\t{%1, %0|%0, %1}";
1848	  else
1849	    return "%vmovdqa\t{%1, %0|%0, %1}";
1850	}
1851    default:
1852      gcc_unreachable ();
1853    }
1854}
1855  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1856   (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1857   (set (attr "mode")
1858   	(cond [(eq_attr "alternative" "2,3")
1859		 (if_then_else
1860		   (match_test "optimize_function_for_size_p (cfun)")
1861		   (const_string "V4SF")
1862		   (const_string "TI"))
1863	       (eq_attr "alternative" "4")
1864		 (if_then_else
1865		   (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1866			(match_test "optimize_function_for_size_p (cfun)"))
1867		   (const_string "V4SF")
1868		   (const_string "TI"))]
1869	       (const_string "DI")))])
1870
1871(define_split
1872  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1873	(match_operand:TI 1 "general_operand" ""))]
1874  "reload_completed
1875   && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1876  [(const_int 0)]
1877  "ix86_split_long_move (operands); DONE;")
1878
1879(define_insn "*movti_internal_sse"
1880  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1881	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1882  "TARGET_SSE && !TARGET_64BIT
1883   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1884{
1885  switch (which_alternative)
1886    {
1887    case 0:
1888      return standard_sse_constant_opcode (insn, operands[1]);
1889    case 1:
1890    case 2:
1891      /* TDmode values are passed as TImode on the stack.  Moving them
1892	 to stack may result in unaligned memory access.  */
1893      if (misaligned_operand (operands[0], TImode)
1894	  || misaligned_operand (operands[1], TImode))
1895	{
1896	  if (get_attr_mode (insn) == MODE_V4SF)
1897	    return "%vmovups\t{%1, %0|%0, %1}";
1898	  else
1899	    return "%vmovdqu\t{%1, %0|%0, %1}";
1900	}
1901      else
1902	{
1903	  if (get_attr_mode (insn) == MODE_V4SF)
1904	    return "%vmovaps\t{%1, %0|%0, %1}";
1905	  else
1906	    return "%vmovdqa\t{%1, %0|%0, %1}";
1907	}
1908    default:
1909      gcc_unreachable ();
1910    }
1911}
1912  [(set_attr "type" "sselog1,ssemov,ssemov")
1913   (set_attr "prefix" "maybe_vex")
1914   (set (attr "mode")
1915	(cond [(ior (not (match_test "TARGET_SSE2"))
1916		    (match_test "optimize_function_for_size_p (cfun)"))
1917		 (const_string "V4SF")
1918	       (and (eq_attr "alternative" "2")
1919		    (match_test "TARGET_SSE_TYPELESS_STORES"))
1920		 (const_string "V4SF")]
1921	      (const_string "TI")))])
1922
1923(define_insn "*movdi_internal_rex64"
1924  [(set (match_operand:DI 0 "nonimmediate_operand"
1925	  "=r,r  ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1926	(match_operand:DI 1 "general_operand"
1927	  "Z ,rem,i,re,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1928  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1929{
1930  switch (get_attr_type (insn))
1931    {
1932    case TYPE_SSECVT:
1933      if (SSE_REG_P (operands[0]))
1934	return "movq2dq\t{%1, %0|%0, %1}";
1935      else
1936	return "movdq2q\t{%1, %0|%0, %1}";
1937
1938    case TYPE_SSEMOV:
1939      if (get_attr_mode (insn) == MODE_TI)
1940	return "%vmovdqa\t{%1, %0|%0, %1}";
1941      /* Handle broken assemblers that require movd instead of movq.  */
1942      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1943	return "%vmovd\t{%1, %0|%0, %1}";
1944      else
1945	return "%vmovq\t{%1, %0|%0, %1}";
1946
1947    case TYPE_MMXMOV:
1948      /* Handle broken assemblers that require movd instead of movq.  */
1949      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1950	return "movd\t{%1, %0|%0, %1}";
1951      else
1952	return "movq\t{%1, %0|%0, %1}";
1953
1954    case TYPE_SSELOG1:
1955      return standard_sse_constant_opcode (insn, operands[1]);
1956
1957    case TYPE_MMX:
1958      return "pxor\t%0, %0";
1959
1960    case TYPE_LEA:
1961      return "lea{q}\t{%E1, %0|%0, %E1}";
1962
1963    default:
1964      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1965      if (get_attr_mode (insn) == MODE_SI)
1966	return "mov{l}\t{%k1, %k0|%k0, %k1}";
1967      else if (which_alternative == 2)
1968	return "movabs{q}\t{%1, %0|%0, %1}";
1969      else if (ix86_use_lea_for_mov (insn, operands))
1970	return "lea{q}\t{%E1, %0|%0, %E1}";
1971      else
1972	return "mov{q}\t{%1, %0|%0, %1}";
1973    }
1974}
1975  [(set (attr "type")
1976     (cond [(eq_attr "alternative" "4")
1977	      (const_string "mmx")
1978	    (eq_attr "alternative" "5,6,7,8")
1979	      (const_string "mmxmov")
1980	    (eq_attr "alternative" "9")
1981	      (const_string "sselog1")
1982	    (eq_attr "alternative" "10,11,12,13,14")
1983	      (const_string "ssemov")
1984	    (eq_attr "alternative" "15,16")
1985	      (const_string "ssecvt")
1986 	    (match_operand 1 "pic_32bit_operand" "")
1987	      (const_string "lea")
1988	   ]
1989	   (const_string "imov")))
1990   (set (attr "modrm")
1991     (if_then_else
1992       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1993	 (const_string "0")
1994	 (const_string "*")))
1995   (set (attr "length_immediate")
1996     (if_then_else
1997       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1998	 (const_string "8")
1999	 (const_string "*")))
2000   (set (attr "prefix_rex")
2001     (if_then_else (eq_attr "alternative" "7,8")
2002       (const_string "1")
2003       (const_string "*")))
2004   (set (attr "prefix_data16")
2005     (if_then_else (eq_attr "alternative" "10")
2006       (const_string "1")
2007       (const_string "*")))
2008   (set (attr "prefix")
2009     (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2010       (const_string "maybe_vex")
2011       (const_string "orig")))
2012   (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2013
2014;; Reload patterns to support multi-word load/store
2015;; with non-offsetable address.
2016(define_expand "reload_noff_store"
2017  [(parallel [(match_operand 0 "memory_operand" "=m")
2018              (match_operand 1 "register_operand" "r")
2019              (match_operand:DI 2 "register_operand" "=&r")])]
2020  "TARGET_64BIT"
2021{
2022  rtx mem = operands[0];
2023  rtx addr = XEXP (mem, 0);
2024
2025  emit_move_insn (operands[2], addr);
2026  mem = replace_equiv_address_nv (mem, operands[2]);
2027
2028  emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2029  DONE;
2030})
2031
2032(define_expand "reload_noff_load"
2033  [(parallel [(match_operand 0 "register_operand" "=r")
2034              (match_operand 1 "memory_operand" "m")
2035              (match_operand:DI 2 "register_operand" "=r")])]
2036  "TARGET_64BIT"
2037{
2038  rtx mem = operands[1];
2039  rtx addr = XEXP (mem, 0);
2040
2041  emit_move_insn (operands[2], addr);
2042  mem = replace_equiv_address_nv (mem, operands[2]);
2043
2044  emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2045  DONE;
2046})
2047
2048(define_insn "*movdi_internal"
2049  [(set (match_operand:DI 0 "nonimmediate_operand"
2050	  "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2051	(match_operand:DI 1 "general_operand"
2052	  "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2053  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2054{
2055  switch (get_attr_type (insn))
2056    {
2057    case TYPE_SSECVT:
2058      if (SSE_REG_P (operands[0]))
2059	return "movq2dq\t{%1, %0|%0, %1}";
2060      else
2061	return "movdq2q\t{%1, %0|%0, %1}";
2062
2063    case TYPE_SSEMOV:
2064      switch (get_attr_mode (insn))
2065	{
2066	case MODE_TI:
2067	  return "%vmovdqa\t{%1, %0|%0, %1}";
2068	case MODE_DI:
2069	   return "%vmovq\t{%1, %0|%0, %1}";
2070	case MODE_V4SF:
2071	  return "movaps\t{%1, %0|%0, %1}";
2072	case MODE_V2SF:
2073	  return "movlps\t{%1, %0|%0, %1}";
2074	default:
2075	  gcc_unreachable ();
2076	}
2077
2078    case TYPE_MMXMOV:
2079      return "movq\t{%1, %0|%0, %1}";
2080
2081    case TYPE_SSELOG1:
2082      return standard_sse_constant_opcode (insn, operands[1]);
2083
2084    case TYPE_MMX:
2085      return "pxor\t%0, %0";
2086
2087    case TYPE_MULTI:
2088      return "#";
2089
2090    default:
2091      gcc_unreachable ();
2092    }
2093}
2094  [(set (attr "isa")
2095     (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2096	      (const_string "sse2")
2097	    (eq_attr "alternative" "9,10,11,12")
2098	      (const_string "noavx")
2099	   ]
2100           (const_string "*")))
2101   (set (attr "type")
2102     (cond [(eq_attr "alternative" "0,1")
2103	      (const_string "multi")
2104	    (eq_attr "alternative" "2")
2105	      (const_string "mmx")
2106	    (eq_attr "alternative" "3,4")
2107	      (const_string "mmxmov")
2108	    (eq_attr "alternative" "5,9")
2109	      (const_string "sselog1")
2110	    (eq_attr "alternative" "13,14")
2111	      (const_string "ssecvt")
2112	   ]
2113	   (const_string "ssemov")))
2114   (set (attr "prefix")
2115     (if_then_else (eq_attr "alternative" "5,6,7,8")
2116       (const_string "maybe_vex")
2117       (const_string "orig")))
2118   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2119
2120(define_split
2121  [(set (match_operand:DI 0 "nonimmediate_operand" "")
2122        (match_operand:DI 1 "general_operand" ""))]
2123  "!TARGET_64BIT && reload_completed
2124   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2125   && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2126  [(const_int 0)]
2127  "ix86_split_long_move (operands); DONE;")
2128
2129(define_insn "*movsi_internal"
2130  [(set (match_operand:SI 0 "nonimmediate_operand"
2131			"=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2132	(match_operand:SI 1 "general_operand"
2133			"g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2134  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2135{
2136  switch (get_attr_type (insn))
2137    {
2138    case TYPE_SSELOG1:
2139      return standard_sse_constant_opcode (insn, operands[1]);
2140
2141    case TYPE_SSEMOV:
2142      switch (get_attr_mode (insn))
2143	{
2144	case MODE_TI:
2145	  return "%vmovdqa\t{%1, %0|%0, %1}";
2146	case MODE_V4SF:
2147	  return "%vmovaps\t{%1, %0|%0, %1}";
2148	case MODE_SI:
2149          return "%vmovd\t{%1, %0|%0, %1}";
2150	case MODE_SF:
2151          return "%vmovss\t{%1, %0|%0, %1}";
2152	default:
2153	  gcc_unreachable ();
2154	}
2155
2156    case TYPE_MMX:
2157      return "pxor\t%0, %0";
2158
2159    case TYPE_MMXMOV:
2160      if (get_attr_mode (insn) == MODE_DI)
2161	return "movq\t{%1, %0|%0, %1}";
2162      return "movd\t{%1, %0|%0, %1}";
2163
2164    case TYPE_LEA:
2165      return "lea{l}\t{%E1, %0|%0, %E1}";
2166
2167    default:
2168      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2169      if (ix86_use_lea_for_mov (insn, operands))
2170	return "lea{l}\t{%E1, %0|%0, %E1}";
2171      else
2172	return "mov{l}\t{%1, %0|%0, %1}";
2173    }
2174}
2175  [(set (attr "type")
2176     (cond [(eq_attr "alternative" "2")
2177	      (const_string "mmx")
2178	    (eq_attr "alternative" "3,4,5")
2179	      (const_string "mmxmov")
2180	    (eq_attr "alternative" "6")
2181	      (const_string "sselog1")
2182	    (eq_attr "alternative" "7,8,9,10,11")
2183	      (const_string "ssemov")
2184 	    (match_operand 1 "pic_32bit_operand" "")
2185	      (const_string "lea")
2186	   ]
2187	   (const_string "imov")))
2188   (set (attr "prefix")
2189     (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2190       (const_string "orig")
2191       (const_string "maybe_vex")))
2192   (set (attr "prefix_data16")
2193     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2194       (const_string "1")
2195       (const_string "*")))
2196   (set (attr "mode")
2197     (cond [(eq_attr "alternative" "2,3")
2198	      (const_string "DI")
2199	    (eq_attr "alternative" "6,7")
2200	      (if_then_else
2201	        (not (match_test "TARGET_SSE2"))
2202	        (const_string "V4SF")
2203	        (const_string "TI"))
2204	    (and (eq_attr "alternative" "8,9,10,11")
2205	         (not (match_test "TARGET_SSE2")))
2206	      (const_string "SF")
2207	   ]
2208	   (const_string "SI")))])
2209
2210(define_insn "*movhi_internal"
2211  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2212	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2213  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2214{
2215  switch (get_attr_type (insn))
2216    {
2217    case TYPE_IMOVX:
2218      /* movzwl is faster than movw on p2 due to partial word stalls,
2219	 though not as fast as an aligned movl.  */
2220      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2221    default:
2222      if (get_attr_mode (insn) == MODE_SI)
2223        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2224      else
2225        return "mov{w}\t{%1, %0|%0, %1}";
2226    }
2227}
2228  [(set (attr "type")
2229     (cond [(match_test "optimize_function_for_size_p (cfun)")
2230	      (const_string "imov")
2231	    (and (eq_attr "alternative" "0")
2232		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2233		      (not (match_test "TARGET_HIMODE_MATH"))))
2234	      (const_string "imov")
2235	    (and (eq_attr "alternative" "1,2")
2236		 (match_operand:HI 1 "aligned_operand" ""))
2237	      (const_string "imov")
2238	    (and (match_test "TARGET_MOVX")
2239		 (eq_attr "alternative" "0,2"))
2240	      (const_string "imovx")
2241	   ]
2242	   (const_string "imov")))
2243    (set (attr "mode")
2244      (cond [(eq_attr "type" "imovx")
2245	       (const_string "SI")
2246	     (and (eq_attr "alternative" "1,2")
2247		  (match_operand:HI 1 "aligned_operand" ""))
2248	       (const_string "SI")
2249	     (and (eq_attr "alternative" "0")
2250		  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2251		       (not (match_test "TARGET_HIMODE_MATH"))))
2252	       (const_string "SI")
2253	    ]
2254	    (const_string "HI")))])
2255
2256;; Situation is quite tricky about when to choose full sized (SImode) move
2257;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2258;; partial register dependency machines (such as AMD Athlon), where QImode
2259;; moves issue extra dependency and for partial register stalls machines
2260;; that don't use QImode patterns (and QImode move cause stall on the next
2261;; instruction).
2262;;
2263;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2264;; register stall machines with, where we use QImode instructions, since
2265;; partial register stall can be caused there.  Then we use movzx.
2266(define_insn "*movqi_internal"
2267  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2268	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2269  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2270{
2271  switch (get_attr_type (insn))
2272    {
2273    case TYPE_IMOVX:
2274      gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2275      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2276    default:
2277      if (get_attr_mode (insn) == MODE_SI)
2278        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2279      else
2280        return "mov{b}\t{%1, %0|%0, %1}";
2281    }
2282}
2283  [(set (attr "type")
2284     (cond [(and (eq_attr "alternative" "5")
2285		 (not (match_operand:QI 1 "aligned_operand" "")))
2286	      (const_string "imovx")
2287	    (match_test "optimize_function_for_size_p (cfun)")
2288	      (const_string "imov")
2289	    (and (eq_attr "alternative" "3")
2290		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2291		      (not (match_test "TARGET_QIMODE_MATH"))))
2292	      (const_string "imov")
2293	    (eq_attr "alternative" "3,5")
2294	      (const_string "imovx")
2295	    (and (match_test "TARGET_MOVX")
2296		 (eq_attr "alternative" "2"))
2297	      (const_string "imovx")
2298	   ]
2299	   (const_string "imov")))
2300   (set (attr "mode")
2301      (cond [(eq_attr "alternative" "3,4,5")
2302	       (const_string "SI")
2303	     (eq_attr "alternative" "6")
2304	       (const_string "QI")
2305	     (eq_attr "type" "imovx")
2306	       (const_string "SI")
2307	     (and (eq_attr "type" "imov")
2308		  (and (eq_attr "alternative" "0,1")
2309		       (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2310			    (and (not (match_test "optimize_function_for_size_p (cfun)"))
2311				 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2312	       (const_string "SI")
2313	     ;; Avoid partial register stalls when not using QImode arithmetic
2314	     (and (eq_attr "type" "imov")
2315		  (and (eq_attr "alternative" "0,1")
2316		       (and (match_test "TARGET_PARTIAL_REG_STALL")
2317			    (not (match_test "TARGET_QIMODE_MATH")))))
2318	       (const_string "SI")
2319	   ]
2320	   (const_string "QI")))])
2321
2322;; Stores and loads of ax to arbitrary constant address.
2323;; We fake an second form of instruction to force reload to load address
2324;; into register when rax is not available
2325(define_insn "*movabs<mode>_1"
2326  [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2327	(match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2328  "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2329  "@
2330   movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2331   mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2332  [(set_attr "type" "imov")
2333   (set_attr "modrm" "0,*")
2334   (set_attr "length_address" "8,0")
2335   (set_attr "length_immediate" "0,*")
2336   (set_attr "memory" "store")
2337   (set_attr "mode" "<MODE>")])
2338
2339(define_insn "*movabs<mode>_2"
2340  [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2341        (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2342  "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2343  "@
2344   movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2345   mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2346  [(set_attr "type" "imov")
2347   (set_attr "modrm" "0,*")
2348   (set_attr "length_address" "8,0")
2349   (set_attr "length_immediate" "0")
2350   (set_attr "memory" "load")
2351   (set_attr "mode" "<MODE>")])
2352
2353(define_insn "*swap<mode>"
2354  [(set (match_operand:SWI48 0 "register_operand" "+r")
2355	(match_operand:SWI48 1 "register_operand" "+r"))
2356   (set (match_dup 1)
2357	(match_dup 0))]
2358  ""
2359  "xchg{<imodesuffix>}\t%1, %0"
2360  [(set_attr "type" "imov")
2361   (set_attr "mode" "<MODE>")
2362   (set_attr "pent_pair" "np")
2363   (set_attr "athlon_decode" "vector")
2364   (set_attr "amdfam10_decode" "double")
2365   (set_attr "bdver1_decode" "double")])
2366
2367(define_insn "*swap<mode>_1"
2368  [(set (match_operand:SWI12 0 "register_operand" "+r")
2369	(match_operand:SWI12 1 "register_operand" "+r"))
2370   (set (match_dup 1)
2371	(match_dup 0))]
2372  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2373  "xchg{l}\t%k1, %k0"
2374  [(set_attr "type" "imov")
2375   (set_attr "mode" "SI")
2376   (set_attr "pent_pair" "np")
2377   (set_attr "athlon_decode" "vector")
2378   (set_attr "amdfam10_decode" "double")
2379   (set_attr "bdver1_decode" "double")])
2380
2381;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2382;; is disabled for AMDFAM10
2383(define_insn "*swap<mode>_2"
2384  [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2385	(match_operand:SWI12 1 "register_operand" "+<r>"))
2386   (set (match_dup 1)
2387	(match_dup 0))]
2388  "TARGET_PARTIAL_REG_STALL"
2389  "xchg{<imodesuffix>}\t%1, %0"
2390  [(set_attr "type" "imov")
2391   (set_attr "mode" "<MODE>")
2392   (set_attr "pent_pair" "np")
2393   (set_attr "athlon_decode" "vector")])
2394
2395(define_expand "movstrict<mode>"
2396  [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2397	(match_operand:SWI12 1 "general_operand" ""))]
2398  ""
2399{
2400  if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2401    FAIL;
2402  if (GET_CODE (operands[0]) == SUBREG
2403      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2404    FAIL;
2405  /* Don't generate memory->memory moves, go through a register */
2406  if (MEM_P (operands[0]) && MEM_P (operands[1]))
2407    operands[1] = force_reg (<MODE>mode, operands[1]);
2408})
2409
2410(define_insn "*movstrict<mode>_1"
2411  [(set (strict_low_part
2412	  (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2413	(match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2414  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2415   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2416  "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2417  [(set_attr "type" "imov")
2418   (set_attr "mode" "<MODE>")])
2419
2420(define_insn "*movstrict<mode>_xor"
2421  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2422	(match_operand:SWI12 1 "const0_operand" ""))
2423   (clobber (reg:CC FLAGS_REG))]
2424  "reload_completed"
2425  "xor{<imodesuffix>}\t%0, %0"
2426  [(set_attr "type" "alu1")
2427   (set_attr "mode" "<MODE>")
2428   (set_attr "length_immediate" "0")])
2429
2430(define_insn "*mov<mode>_extv_1"
2431  [(set (match_operand:SWI24 0 "register_operand" "=R")
2432	(sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2433			    (const_int 8)
2434			    (const_int 8)))]
2435  ""
2436  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2437  [(set_attr "type" "imovx")
2438   (set_attr "mode" "SI")])
2439
2440(define_insn "*movqi_extv_1_rex64"
2441  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2442        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2443                         (const_int 8)
2444                         (const_int 8)))]
2445  "TARGET_64BIT"
2446{
2447  switch (get_attr_type (insn))
2448    {
2449    case TYPE_IMOVX:
2450      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2451    default:
2452      return "mov{b}\t{%h1, %0|%0, %h1}";
2453    }
2454}
2455  [(set (attr "type")
2456     (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2457			(match_test "TARGET_MOVX"))
2458	(const_string "imovx")
2459	(const_string "imov")))
2460   (set (attr "mode")
2461     (if_then_else (eq_attr "type" "imovx")
2462	(const_string "SI")
2463	(const_string "QI")))])
2464
2465(define_insn "*movqi_extv_1"
2466  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2467        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2468                         (const_int 8)
2469                         (const_int 8)))]
2470  "!TARGET_64BIT"
2471{
2472  switch (get_attr_type (insn))
2473    {
2474    case TYPE_IMOVX:
2475      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2476    default:
2477      return "mov{b}\t{%h1, %0|%0, %h1}";
2478    }
2479}
2480  [(set (attr "type")
2481     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2482			(ior (not (match_operand:QI 0 "QIreg_operand" ""))
2483			     (match_test "TARGET_MOVX")))
2484	(const_string "imovx")
2485	(const_string "imov")))
2486   (set (attr "mode")
2487     (if_then_else (eq_attr "type" "imovx")
2488	(const_string "SI")
2489	(const_string "QI")))])
2490
2491(define_insn "*mov<mode>_extzv_1"
2492  [(set (match_operand:SWI48 0 "register_operand" "=R")
2493	(zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2494			    (const_int 8)
2495			    (const_int 8)))]
2496  ""
2497  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2498  [(set_attr "type" "imovx")
2499   (set_attr "mode" "SI")])
2500
2501(define_insn "*movqi_extzv_2_rex64"
2502  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2503        (subreg:QI
2504	  (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2505			   (const_int 8)
2506			   (const_int 8)) 0))]
2507  "TARGET_64BIT"
2508{
2509  switch (get_attr_type (insn))
2510    {
2511    case TYPE_IMOVX:
2512      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2513    default:
2514      return "mov{b}\t{%h1, %0|%0, %h1}";
2515    }
2516}
2517  [(set (attr "type")
2518     (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2519			(match_test "TARGET_MOVX"))
2520	(const_string "imovx")
2521	(const_string "imov")))
2522   (set (attr "mode")
2523     (if_then_else (eq_attr "type" "imovx")
2524	(const_string "SI")
2525	(const_string "QI")))])
2526
2527(define_insn "*movqi_extzv_2"
2528  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2529        (subreg:QI
2530	  (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2531			   (const_int 8)
2532			   (const_int 8)) 0))]
2533  "!TARGET_64BIT"
2534{
2535  switch (get_attr_type (insn))
2536    {
2537    case TYPE_IMOVX:
2538      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2539    default:
2540      return "mov{b}\t{%h1, %0|%0, %h1}";
2541    }
2542}
2543  [(set (attr "type")
2544     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2545			(ior (not (match_operand:QI 0 "QIreg_operand" ""))
2546			     (match_test "TARGET_MOVX")))
2547	(const_string "imovx")
2548	(const_string "imov")))
2549   (set (attr "mode")
2550     (if_then_else (eq_attr "type" "imovx")
2551	(const_string "SI")
2552	(const_string "QI")))])
2553
2554(define_expand "mov<mode>_insv_1"
2555  [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2556			    (const_int 8)
2557			    (const_int 8))
2558	(match_operand:SWI48 1 "nonmemory_operand" ""))])
2559
2560(define_insn "*mov<mode>_insv_1_rex64"
2561  [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2562			     (const_int 8)
2563			     (const_int 8))
2564	(match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2565  "TARGET_64BIT"
2566{
2567  if (CONST_INT_P (operands[1]))
2568    operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2569  return "mov{b}\t{%b1, %h0|%h0, %b1}";
2570}
2571  [(set_attr "type" "imov")
2572   (set_attr "mode" "QI")])
2573
2574(define_insn "*movsi_insv_1"
2575  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2576			 (const_int 8)
2577			 (const_int 8))
2578	(match_operand:SI 1 "general_operand" "Qmn"))]
2579  "!TARGET_64BIT"
2580{
2581  if (CONST_INT_P (operands[1]))
2582    operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2583  return "mov{b}\t{%b1, %h0|%h0, %b1}";
2584}
2585  [(set_attr "type" "imov")
2586   (set_attr "mode" "QI")])
2587
2588(define_insn "*movqi_insv_2"
2589  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2590			 (const_int 8)
2591			 (const_int 8))
2592	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2593		     (const_int 8)))]
2594  ""
2595  "mov{b}\t{%h1, %h0|%h0, %h1}"
2596  [(set_attr "type" "imov")
2597   (set_attr "mode" "QI")])
2598
2599;; Floating point push instructions.
2600
2601(define_insn "*pushtf"
2602  [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2603	(match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2604  "TARGET_SSE2"
2605{
2606  /* This insn should be already split before reg-stack.  */
2607  gcc_unreachable ();
2608}
2609  [(set_attr "type" "multi")
2610   (set_attr "unit" "sse,*,*")
2611   (set_attr "mode" "TF,SI,SI")])
2612
2613;; %%% Kill this when call knows how to work this out.
2614(define_split
2615  [(set (match_operand:TF 0 "push_operand" "")
2616	(match_operand:TF 1 "sse_reg_operand" ""))]
2617  "TARGET_SSE2 && reload_completed"
2618  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2619   (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2620
2621(define_insn "*pushxf"
2622  [(set (match_operand:XF 0 "push_operand" "=<,<")
2623	(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2624  "optimize_function_for_speed_p (cfun)"
2625{
2626  /* This insn should be already split before reg-stack.  */
2627  gcc_unreachable ();
2628}
2629  [(set_attr "type" "multi")
2630   (set_attr "unit" "i387,*")
2631   (set_attr "mode" "XF,SI")])
2632
2633;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2634;; Size of pushxf using integer instructions is 3+3*memory operand size
2635;; Pushing using integer instructions is longer except for constants
2636;; and direct memory references (assuming that any given constant is pushed
2637;; only once, but this ought to be handled elsewhere).
2638
2639(define_insn "*pushxf_nointeger"
2640  [(set (match_operand:XF 0 "push_operand" "=<,<")
2641	(match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2642  "optimize_function_for_size_p (cfun)"
2643{
2644  /* This insn should be already split before reg-stack.  */
2645  gcc_unreachable ();
2646}
2647  [(set_attr "type" "multi")
2648   (set_attr "unit" "i387,*")
2649   (set_attr "mode" "XF,SI")])
2650
2651;; %%% Kill this when call knows how to work this out.
2652(define_split
2653  [(set (match_operand:XF 0 "push_operand" "")
2654	(match_operand:XF 1 "fp_register_operand" ""))]
2655  "reload_completed"
2656  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2657   (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2658  "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2659
2660(define_insn "*pushdf_rex64"
2661  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2662	(match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2663  "TARGET_64BIT"
2664{
2665  /* This insn should be already split before reg-stack.  */
2666  gcc_unreachable ();
2667}
2668  [(set_attr "type" "multi")
2669   (set_attr "unit" "i387,*,*")
2670   (set_attr "mode" "DF,DI,DF")])
2671
2672;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2673;; Size of pushdf using integer instructions is 2+2*memory operand size
2674;; On the average, pushdf using integers can be still shorter.
2675
2676(define_insn "*pushdf"
2677  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2678	(match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2679  "!TARGET_64BIT"
2680{
2681  /* This insn should be already split before reg-stack.  */
2682  gcc_unreachable ();
2683}
2684  [(set_attr "isa" "*,*,sse2")
2685   (set_attr "type" "multi")
2686   (set_attr "unit" "i387,*,*")
2687   (set_attr "mode" "DF,DI,DF")])
2688
2689;; %%% Kill this when call knows how to work this out.
2690(define_split
2691  [(set (match_operand:DF 0 "push_operand" "")
2692	(match_operand:DF 1 "any_fp_register_operand" ""))]
2693  "reload_completed"
2694  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2695   (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2696
2697(define_insn "*pushsf_rex64"
2698  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2699	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2700  "TARGET_64BIT"
2701{
2702  /* Anything else should be already split before reg-stack.  */
2703  gcc_assert (which_alternative == 1);
2704  return "push{q}\t%q1";
2705}
2706  [(set_attr "type" "multi,push,multi")
2707   (set_attr "unit" "i387,*,*")
2708   (set_attr "mode" "SF,DI,SF")])
2709
2710(define_insn "*pushsf"
2711  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2712	(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2713  "!TARGET_64BIT"
2714{
2715  /* Anything else should be already split before reg-stack.  */
2716  gcc_assert (which_alternative == 1);
2717  return "push{l}\t%1";
2718}
2719  [(set_attr "type" "multi,push,multi")
2720   (set_attr "unit" "i387,*,*")
2721   (set_attr "mode" "SF,SI,SF")])
2722
2723;; %%% Kill this when call knows how to work this out.
2724(define_split
2725  [(set (match_operand:SF 0 "push_operand" "")
2726	(match_operand:SF 1 "any_fp_register_operand" ""))]
2727  "reload_completed"
2728  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2729   (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2730  "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2731
2732(define_split
2733  [(set (match_operand:SF 0 "push_operand" "")
2734	(match_operand:SF 1 "memory_operand" ""))]
2735  "reload_completed
2736   && (operands[2] = find_constant_src (insn))"
2737  [(set (match_dup 0) (match_dup 2))])
2738
2739(define_split
2740  [(set (match_operand 0 "push_operand" "")
2741	(match_operand 1 "general_operand" ""))]
2742  "reload_completed
2743   && (GET_MODE (operands[0]) == TFmode
2744       || GET_MODE (operands[0]) == XFmode
2745       || GET_MODE (operands[0]) == DFmode)
2746   && !ANY_FP_REG_P (operands[1])"
2747  [(const_int 0)]
2748  "ix86_split_long_move (operands); DONE;")
2749
2750;; Floating point move instructions.
2751
2752(define_expand "movtf"
2753  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2754	(match_operand:TF 1 "nonimmediate_operand" ""))]
2755  "TARGET_64BIT || TARGET_SSE2"
2756{
2757  ix86_expand_move (TFmode, operands);
2758  DONE;
2759})
2760
2761(define_expand "mov<mode>"
2762  [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2763	(match_operand:X87MODEF 1 "general_operand" ""))]
2764  ""
2765  "ix86_expand_move (<MODE>mode, operands); DONE;")
2766
2767(define_insn "*movtf_internal_rex64"
2768  [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2769	(match_operand:TF 1 "general_operand"	   "xm,x,C,*roF,*r"))]
2770  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2771   && (!can_create_pseudo_p ()
2772       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2773       || GET_CODE (operands[1]) != CONST_DOUBLE
2774       || (optimize_function_for_size_p (cfun)
2775	   && standard_sse_constant_p (operands[1])
2776	   && !memory_operand (operands[0], TFmode))
2777       || (!TARGET_MEMORY_MISMATCH_STALL
2778	   && memory_operand (operands[0], TFmode)))"
2779{
2780  switch (which_alternative)
2781    {
2782    case 0:
2783    case 1:
2784      /* Handle misaligned load/store since we
2785         don't have movmisaligntf pattern. */
2786      if (misaligned_operand (operands[0], TFmode)
2787	  || misaligned_operand (operands[1], TFmode))
2788	{
2789	  if (get_attr_mode (insn) == MODE_V4SF)
2790	    return "%vmovups\t{%1, %0|%0, %1}";
2791	  else
2792	    return "%vmovdqu\t{%1, %0|%0, %1}";
2793	}
2794      else
2795	{
2796	  if (get_attr_mode (insn) == MODE_V4SF)
2797	    return "%vmovaps\t{%1, %0|%0, %1}";
2798	  else
2799	    return "%vmovdqa\t{%1, %0|%0, %1}";
2800	}
2801
2802    case 2:
2803      return standard_sse_constant_opcode (insn, operands[1]);
2804
2805    case 3:
2806    case 4:
2807	return "#";
2808
2809    default:
2810      gcc_unreachable ();
2811    }
2812}
2813  [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2814   (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2815   (set (attr "mode")
2816        (cond [(eq_attr "alternative" "0,2")
2817		 (if_then_else
2818		   (match_test "optimize_function_for_size_p (cfun)")
2819		   (const_string "V4SF")
2820		   (const_string "TI"))
2821	       (eq_attr "alternative" "1")
2822		 (if_then_else
2823		   (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2824			(match_test "optimize_function_for_size_p (cfun)"))
2825		   (const_string "V4SF")
2826		   (const_string "TI"))]
2827	       (const_string "DI")))])
2828
2829(define_insn "*movtf_internal_sse2"
2830  [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2831	(match_operand:TF 1 "general_operand"  	   "xm,x,C"))]
2832  "TARGET_SSE2 && !TARGET_64BIT
2833   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2834   && (!can_create_pseudo_p ()
2835       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2836       || GET_CODE (operands[1]) != CONST_DOUBLE
2837       || (optimize_function_for_size_p (cfun)
2838	   && standard_sse_constant_p (operands[1])
2839	   && !memory_operand (operands[0], TFmode))
2840       || (!TARGET_MEMORY_MISMATCH_STALL
2841	   && memory_operand (operands[0], TFmode)))"
2842{
2843  switch (which_alternative)
2844    {
2845    case 0:
2846    case 1:
2847      /* Handle misaligned load/store since we
2848         don't have movmisaligntf pattern. */
2849      if (misaligned_operand (operands[0], TFmode)
2850	  || misaligned_operand (operands[1], TFmode))
2851	{
2852	  if (get_attr_mode (insn) == MODE_V4SF)
2853	    return "%vmovups\t{%1, %0|%0, %1}";
2854	  else
2855	    return "%vmovdqu\t{%1, %0|%0, %1}";
2856	}
2857      else
2858	{
2859	  if (get_attr_mode (insn) == MODE_V4SF)
2860	    return "%vmovaps\t{%1, %0|%0, %1}";
2861	  else
2862	    return "%vmovdqa\t{%1, %0|%0, %1}";
2863	}
2864
2865    case 2:
2866      return standard_sse_constant_opcode (insn, operands[1]);
2867
2868    default:
2869      gcc_unreachable ();
2870    }
2871}
2872  [(set_attr "type" "ssemov,ssemov,sselog1")
2873   (set_attr "prefix" "maybe_vex")
2874   (set (attr "mode")
2875        (cond [(eq_attr "alternative" "0,2")
2876		 (if_then_else
2877		   (match_test "optimize_function_for_size_p (cfun)")
2878		   (const_string "V4SF")
2879		   (const_string "TI"))
2880	       (eq_attr "alternative" "1")
2881		 (if_then_else
2882		   (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2883			(match_test "optimize_function_for_size_p (cfun)"))
2884		   (const_string "V4SF")
2885		   (const_string "TI"))]
2886	       (const_string "DI")))])
2887
2888(define_insn "*movxf_internal_rex64"
2889  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2890	(match_operand:XF 1 "general_operand"	   "fm,f,G,Yx*roF,Yx*rC"))]
2891  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2892   && (!can_create_pseudo_p ()
2893       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2894       || GET_CODE (operands[1]) != CONST_DOUBLE
2895       || (optimize_function_for_size_p (cfun)
2896	   && standard_80387_constant_p (operands[1]) > 0
2897	   && !memory_operand (operands[0], XFmode))
2898       || (!TARGET_MEMORY_MISMATCH_STALL
2899	   && memory_operand (operands[0], XFmode)))"
2900{
2901  switch (which_alternative)
2902    {
2903    case 0:
2904    case 1:
2905      return output_387_reg_move (insn, operands);
2906
2907    case 2:
2908      return standard_80387_constant_opcode (operands[1]);
2909
2910    case 3:
2911    case 4:
2912      return "#";
2913
2914    default:
2915      gcc_unreachable ();
2916    }
2917}
2918  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2919   (set_attr "mode" "XF,XF,XF,SI,SI")])
2920
2921;; Possible store forwarding (partial memory) stall in alternative 4.
2922(define_insn "*movxf_internal"
2923  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2924	(match_operand:XF 1 "general_operand"	   "fm,f,G,Yx*roF,Yx*rF"))]
2925  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2926   && (!can_create_pseudo_p ()
2927       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2928       || GET_CODE (operands[1]) != CONST_DOUBLE
2929       || (optimize_function_for_size_p (cfun)
2930	   && standard_80387_constant_p (operands[1]) > 0
2931	   && !memory_operand (operands[0], XFmode))
2932       || (!TARGET_MEMORY_MISMATCH_STALL
2933	   && memory_operand (operands[0], XFmode)))"
2934{
2935  switch (which_alternative)
2936    {
2937    case 0:
2938    case 1:
2939      return output_387_reg_move (insn, operands);
2940
2941    case 2:
2942      return standard_80387_constant_opcode (operands[1]);
2943
2944    case 3:
2945    case 4:
2946      return "#";
2947
2948    default:
2949      gcc_unreachable ();
2950    }
2951}
2952  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2953   (set_attr "mode" "XF,XF,XF,SI,SI")])
2954
2955(define_insn "*movdf_internal_rex64"
2956  [(set (match_operand:DF 0 "nonimmediate_operand"
2957		"=?Yf*f,?m   ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2958	(match_operand:DF 1 "general_operand"
2959		"Yf*fm ,Yf*f ,G    ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2960  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2961   && (!can_create_pseudo_p ()
2962       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2963       || GET_CODE (operands[1]) != CONST_DOUBLE
2964       || (optimize_function_for_size_p (cfun)
2965	   && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2966		&& standard_80387_constant_p (operands[1]) > 0)
2967	       || (TARGET_SSE2 && TARGET_SSE_MATH
2968		   && standard_sse_constant_p (operands[1]))))
2969       || memory_operand (operands[0], DFmode))"
2970{
2971  switch (which_alternative)
2972    {
2973    case 0:
2974    case 1:
2975      return output_387_reg_move (insn, operands);
2976
2977    case 2:
2978      return standard_80387_constant_opcode (operands[1]);
2979
2980    case 3:
2981    case 4:
2982      return "mov{q}\t{%1, %0|%0, %1}";
2983
2984    case 5:
2985      return "mov{l}\t{%1, %k0|%k0, %1}";
2986
2987    case 6:
2988      return "movabs{q}\t{%1, %0|%0, %1}";
2989
2990    case 7:
2991      return standard_sse_constant_opcode (insn, operands[1]);
2992
2993    case 8:
2994    case 9:
2995    case 10:
2996      switch (get_attr_mode (insn))
2997	{
2998	case MODE_V2DF:
2999	  if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3000	    return "%vmovapd\t{%1, %0|%0, %1}";
3001	case MODE_V4SF:
3002	  return "%vmovaps\t{%1, %0|%0, %1}";
3003
3004	case MODE_DI:
3005	  return "%vmovq\t{%1, %0|%0, %1}";
3006	case MODE_DF:
3007	  if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3008	    return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3009	  return "%vmovsd\t{%1, %0|%0, %1}";
3010	case MODE_V1DF:
3011	  return "%vmovlpd\t{%1, %d0|%d0, %1}";
3012	case MODE_V2SF:
3013	  return "%vmovlps\t{%1, %d0|%d0, %1}";
3014	default:
3015	  gcc_unreachable ();
3016	}
3017
3018    case 11:
3019    case 12:
3020      /* Handle broken assemblers that require movd instead of movq.  */
3021      return "%vmovd\t{%1, %0|%0, %1}";
3022
3023    default:
3024      gcc_unreachable();
3025    }
3026}
3027  [(set (attr "type")
3028	(cond [(eq_attr "alternative" "0,1,2")
3029		 (const_string "fmov")
3030	       (eq_attr "alternative" "3,4,5,6")
3031		 (const_string "imov")
3032	       (eq_attr "alternative" "7")
3033		 (const_string "sselog1")
3034	      ]
3035	      (const_string "ssemov")))
3036   (set (attr "modrm")
3037     (if_then_else
3038       (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3039	 (const_string "0")
3040	 (const_string "*")))
3041   (set (attr "length_immediate")
3042     (if_then_else
3043       (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3044	 (const_string "8")
3045	 (const_string "*")))
3046   (set (attr "prefix")
3047     (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3048       (const_string "orig")
3049       (const_string "maybe_vex")))
3050   (set (attr "prefix_data16")
3051     (if_then_else (eq_attr "mode" "V1DF")
3052       (const_string "1")
3053       (const_string "*")))
3054   (set (attr "mode")
3055        (cond [(eq_attr "alternative" "0,1,2")
3056		 (const_string "DF")
3057	       (eq_attr "alternative" "3,4,6,11,12")
3058		 (const_string "DI")
3059	       (eq_attr "alternative" "5")
3060		 (const_string "SI")
3061
3062	       /* xorps is one byte shorter.  */
3063	       (eq_attr "alternative" "7")
3064		 (cond [(match_test "optimize_function_for_size_p (cfun)")
3065			  (const_string "V4SF")
3066			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3067			  (const_string "TI")
3068		       ]
3069		       (const_string "V2DF"))
3070
3071	       /* For architectures resolving dependencies on
3072		  whole SSE registers use APD move to break dependency
3073		  chains, otherwise use short move to avoid extra work.
3074
3075		  movaps encodes one byte shorter.  */
3076	       (eq_attr "alternative" "8")
3077		 (cond
3078		   [(match_test "optimize_function_for_size_p (cfun)")
3079		      (const_string "V4SF")
3080		    (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3081		      (const_string "V2DF")
3082		   ]
3083		   (const_string "DF"))
3084	       /* For architectures resolving dependencies on register
3085		  parts we may avoid extra work to zero out upper part
3086		  of register.  */
3087	       (eq_attr "alternative" "9")
3088		 (if_then_else
3089		   (match_test "TARGET_SSE_SPLIT_REGS")
3090		   (const_string "V1DF")
3091		   (const_string "DF"))
3092	      ]
3093	      (const_string "DF")))])
3094
3095;; Possible store forwarding (partial memory) stall in alternative 4.
3096(define_insn "*movdf_internal"
3097  [(set (match_operand:DF 0 "nonimmediate_operand"
3098		"=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3099	(match_operand:DF 1 "general_operand"
3100		"Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3101  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3102   && (!can_create_pseudo_p ()
3103       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3104       || GET_CODE (operands[1]) != CONST_DOUBLE
3105       || (optimize_function_for_size_p (cfun)
3106	   && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3107		&& standard_80387_constant_p (operands[1]) > 0)
3108	       || (TARGET_SSE2 && TARGET_SSE_MATH
3109		   && standard_sse_constant_p (operands[1])))
3110	   && !memory_operand (operands[0], DFmode))
3111       || (!TARGET_MEMORY_MISMATCH_STALL
3112	   && memory_operand (operands[0], DFmode)))"
3113{
3114  switch (which_alternative)
3115    {
3116    case 0:
3117    case 1:
3118      return output_387_reg_move (insn, operands);
3119
3120    case 2:
3121      return standard_80387_constant_opcode (operands[1]);
3122
3123    case 3:
3124    case 4:
3125      return "#";
3126
3127    case 5:
3128    case 9:
3129      return standard_sse_constant_opcode (insn, operands[1]);
3130
3131    case 6:
3132    case 7:
3133    case 8:
3134    case 10:
3135    case 11:
3136    case 12:
3137      switch (get_attr_mode (insn))
3138	{
3139	case MODE_V2DF:
3140	  if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3141	    return "%vmovapd\t{%1, %0|%0, %1}";
3142	case MODE_V4SF:
3143	  return "%vmovaps\t{%1, %0|%0, %1}";
3144
3145	case MODE_DI:
3146	  return "%vmovq\t{%1, %0|%0, %1}";
3147	case MODE_DF:
3148	  if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3149	    return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3150	  return "%vmovsd\t{%1, %0|%0, %1}";
3151	case MODE_V1DF:
3152	  return "%vmovlpd\t{%1, %d0|%d0, %1}";
3153	case MODE_V2SF:
3154	  return "%vmovlps\t{%1, %d0|%d0, %1}";
3155	default:
3156	  gcc_unreachable ();
3157	}
3158
3159    default:
3160      gcc_unreachable ();
3161    }
3162}
3163  [(set (attr "isa")
3164     (if_then_else (eq_attr "alternative" "5,6,7,8")
3165       (const_string "sse2")
3166       (const_string "*")))
3167   (set (attr "type")
3168	(cond [(eq_attr "alternative" "0,1,2")
3169		 (const_string "fmov")
3170	       (eq_attr "alternative" "3,4")
3171		 (const_string "multi")
3172	       (eq_attr "alternative" "5,9")
3173		 (const_string "sselog1")
3174	      ]
3175	      (const_string "ssemov")))
3176   (set (attr "prefix")
3177     (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3178       (const_string "orig")
3179       (const_string "maybe_vex")))
3180   (set (attr "prefix_data16")
3181     (if_then_else (eq_attr "mode" "V1DF")
3182       (const_string "1")
3183       (const_string "*")))
3184   (set (attr "mode")
3185        (cond [(eq_attr "alternative" "0,1,2")
3186		 (const_string "DF")
3187	       (eq_attr "alternative" "3,4")
3188		 (const_string "SI")
3189
3190	       /* For SSE1, we have many fewer alternatives.  */
3191	       (not (match_test "TARGET_SSE2"))
3192		 (if_then_else
3193		   (eq_attr "alternative" "5,6,9,10")
3194		   (const_string "V4SF")
3195		   (const_string "V2SF"))
3196
3197	       /* xorps is one byte shorter.  */
3198	       (eq_attr "alternative" "5,9")
3199		 (cond [(match_test "optimize_function_for_size_p (cfun)")
3200			  (const_string "V4SF")
3201			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3202			  (const_string "TI")
3203		       ]
3204		       (const_string "V2DF"))
3205
3206	       /* For architectures resolving dependencies on
3207		  whole SSE registers use APD move to break dependency
3208		  chains, otherwise use short move to avoid extra work.
3209
3210		  movaps encodes one byte shorter.  */
3211	       (eq_attr "alternative" "6,10")
3212		 (cond
3213		   [(match_test "optimize_function_for_size_p (cfun)")
3214		      (const_string "V4SF")
3215		    (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3216		      (const_string "V2DF")
3217		   ]
3218		   (const_string "DF"))
3219	       /* For architectures resolving dependencies on register
3220		  parts we may avoid extra work to zero out upper part
3221		  of register.  */
3222	       (eq_attr "alternative" "7,11")
3223		 (if_then_else
3224		   (match_test "TARGET_SSE_SPLIT_REGS")
3225		   (const_string "V1DF")
3226		   (const_string "DF"))
3227	      ]
3228	      (const_string "DF")))])
3229
3230(define_insn "*movsf_internal"
3231  [(set (match_operand:SF 0 "nonimmediate_operand"
3232	  "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3233	(match_operand:SF 1 "general_operand"
3234	  "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3235  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3236   && (!can_create_pseudo_p ()
3237       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3238       || GET_CODE (operands[1]) != CONST_DOUBLE
3239       || (optimize_function_for_size_p (cfun)
3240	   && ((!TARGET_SSE_MATH
3241		&& standard_80387_constant_p (operands[1]) > 0)
3242	       || (TARGET_SSE_MATH
3243		   && standard_sse_constant_p (operands[1]))))
3244       || memory_operand (operands[0], SFmode))"
3245{
3246  switch (which_alternative)
3247    {
3248    case 0:
3249    case 1:
3250      return output_387_reg_move (insn, operands);
3251
3252    case 2:
3253      return standard_80387_constant_opcode (operands[1]);
3254
3255    case 3:
3256    case 4:
3257      return "mov{l}\t{%1, %0|%0, %1}";
3258
3259    case 5:
3260      return standard_sse_constant_opcode (insn, operands[1]);
3261
3262    case 6:
3263      if (get_attr_mode (insn) == MODE_V4SF)
3264	return "%vmovaps\t{%1, %0|%0, %1}";
3265      if (TARGET_AVX)
3266	return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3267
3268    case 7:
3269    case 8:
3270      return "%vmovss\t{%1, %0|%0, %1}";
3271
3272    case 9:
3273    case 10:
3274    case 14:
3275    case 15:
3276      return "movd\t{%1, %0|%0, %1}";
3277
3278    case 11:
3279      return "movq\t{%1, %0|%0, %1}";
3280
3281    case 12:
3282    case 13:
3283      return "%vmovd\t{%1, %0|%0, %1}";
3284
3285    default:
3286      gcc_unreachable ();
3287    }
3288}
3289  [(set (attr "type")
3290	(cond [(eq_attr "alternative" "0,1,2")
3291		 (const_string "fmov")
3292	       (eq_attr "alternative" "3,4")
3293		 (const_string "imov")
3294	       (eq_attr "alternative" "5")
3295		 (const_string "sselog1")
3296	       (eq_attr "alternative" "9,10,11,14,15")
3297		 (const_string "mmxmov")
3298	      ]
3299	      (const_string "ssemov")))
3300   (set (attr "prefix")
3301     (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3302       (const_string "maybe_vex")
3303       (const_string "orig")))
3304   (set (attr "mode")
3305        (cond [(eq_attr "alternative" "3,4,9,10")
3306		 (const_string "SI")
3307	       (eq_attr "alternative" "5")
3308		 (if_then_else
3309		   (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3310			     (match_test "TARGET_SSE2"))
3311			(not (match_test "optimize_function_for_size_p (cfun)")))
3312		   (const_string "TI")
3313		   (const_string "V4SF"))
3314	       /* For architectures resolving dependencies on
3315		  whole SSE registers use APS move to break dependency
3316		  chains, otherwise use short move to avoid extra work.
3317
3318		  Do the same for architectures resolving dependencies on
3319		  the parts.  While in DF mode it is better to always handle
3320		  just register parts, the SF mode is different due to lack
3321		  of instructions to load just part of the register.  It is
3322		  better to maintain the whole registers in single format
3323		  to avoid problems on using packed logical operations.  */
3324	       (eq_attr "alternative" "6")
3325		 (if_then_else
3326		   (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3327			(match_test "TARGET_SSE_SPLIT_REGS"))
3328		   (const_string "V4SF")
3329		   (const_string "SF"))
3330	       (eq_attr "alternative" "11")
3331		 (const_string "DI")]
3332	       (const_string "SF")))])
3333
3334(define_split
3335  [(set (match_operand 0 "any_fp_register_operand" "")
3336	(match_operand 1 "memory_operand" ""))]
3337  "reload_completed
3338   && (GET_MODE (operands[0]) == TFmode
3339       || GET_MODE (operands[0]) == XFmode
3340       || GET_MODE (operands[0]) == DFmode
3341       || GET_MODE (operands[0]) == SFmode)
3342   && (operands[2] = find_constant_src (insn))"
3343  [(set (match_dup 0) (match_dup 2))]
3344{
3345  rtx c = operands[2];
3346  int r = REGNO (operands[0]);
3347
3348  if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3349      || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3350    FAIL;
3351})
3352
3353(define_split
3354  [(set (match_operand 0 "any_fp_register_operand" "")
3355	(float_extend (match_operand 1 "memory_operand" "")))]
3356  "reload_completed
3357   && (GET_MODE (operands[0]) == TFmode
3358       || GET_MODE (operands[0]) == XFmode
3359       || GET_MODE (operands[0]) == DFmode)
3360   && (operands[2] = find_constant_src (insn))"
3361  [(set (match_dup 0) (match_dup 2))]
3362{
3363  rtx c = operands[2];
3364  int r = REGNO (operands[0]);
3365
3366  if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3367      || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3368    FAIL;
3369})
3370
3371;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3372(define_split
3373  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3374	(match_operand:X87MODEF 1 "immediate_operand" ""))]
3375  "reload_completed
3376   && (standard_80387_constant_p (operands[1]) == 8
3377       || standard_80387_constant_p (operands[1]) == 9)"
3378  [(set (match_dup 0)(match_dup 1))
3379   (set (match_dup 0)
3380	(neg:X87MODEF (match_dup 0)))]
3381{
3382  REAL_VALUE_TYPE r;
3383
3384  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3385  if (real_isnegzero (&r))
3386    operands[1] = CONST0_RTX (<MODE>mode);
3387  else
3388    operands[1] = CONST1_RTX (<MODE>mode);
3389})
3390
3391(define_split
3392  [(set (match_operand 0 "nonimmediate_operand" "")
3393        (match_operand 1 "general_operand" ""))]
3394  "reload_completed
3395   && (GET_MODE (operands[0]) == TFmode
3396       || GET_MODE (operands[0]) == XFmode
3397       || GET_MODE (operands[0]) == DFmode)
3398   && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3399  [(const_int 0)]
3400  "ix86_split_long_move (operands); DONE;")
3401
3402(define_insn "swapxf"
3403  [(set (match_operand:XF 0 "register_operand" "+f")
3404	(match_operand:XF 1 "register_operand" "+f"))
3405   (set (match_dup 1)
3406	(match_dup 0))]
3407  "TARGET_80387"
3408{
3409  if (STACK_TOP_P (operands[0]))
3410    return "fxch\t%1";
3411  else
3412    return "fxch\t%0";
3413}
3414  [(set_attr "type" "fxch")
3415   (set_attr "mode" "XF")])
3416
3417(define_insn "*swap<mode>"
3418  [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3419	(match_operand:MODEF 1 "fp_register_operand" "+f"))
3420   (set (match_dup 1)
3421	(match_dup 0))]
3422  "TARGET_80387 || reload_completed"
3423{
3424  if (STACK_TOP_P (operands[0]))
3425    return "fxch\t%1";
3426  else
3427    return "fxch\t%0";
3428}
3429  [(set_attr "type" "fxch")
3430   (set_attr "mode" "<MODE>")])
3431
3432;; Zero extension instructions
3433
3434(define_expand "zero_extendsidi2"
3435  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3436	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3437  ""
3438{
3439  if (!TARGET_64BIT)
3440    {
3441      emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3442      DONE;
3443    }
3444})
3445
3446(define_insn "*zero_extendsidi2_rex64"
3447  [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?*y,?*Yi,*x")
3448	(zero_extend:DI
3449	 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m  ,r   ,m")))]
3450  "TARGET_64BIT"
3451  "@
3452   mov{l}\t{%1, %k0|%k0, %1}
3453   #
3454   movd\t{%1, %0|%0, %1}
3455   movd\t{%1, %0|%0, %1}
3456   %vmovd\t{%1, %0|%0, %1}
3457   %vmovd\t{%1, %0|%0, %1}"
3458  [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3459   (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3460   (set_attr "prefix_0f" "0,*,*,*,*,*")
3461   (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3462
3463(define_split
3464  [(set (match_operand:DI 0 "memory_operand" "")
3465     	(zero_extend:DI (match_dup 0)))]
3466  "TARGET_64BIT"
3467  [(set (match_dup 4) (const_int 0))]
3468  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3469
3470;; %%% Kill me once multi-word ops are sane.
3471(define_insn "zero_extendsidi2_1"
3472  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3473	(zero_extend:DI
3474	 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3475   (clobber (reg:CC FLAGS_REG))]
3476  "!TARGET_64BIT"
3477  "@
3478   #
3479   #
3480   #
3481   movd\t{%1, %0|%0, %1}
3482   movd\t{%1, %0|%0, %1}
3483   %vmovd\t{%1, %0|%0, %1}
3484   %vmovd\t{%1, %0|%0, %1}"
3485  [(set_attr "isa" "*,*,*,*,*,*,sse2")
3486   (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3487   (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3488   (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3489
3490(define_split
3491  [(set (match_operand:DI 0 "register_operand" "")
3492	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3493   (clobber (reg:CC FLAGS_REG))]
3494  "!TARGET_64BIT && reload_completed
3495   && true_regnum (operands[0]) == true_regnum (operands[1])"
3496  [(set (match_dup 4) (const_int 0))]
3497  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3498
3499(define_split
3500  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3501	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3502   (clobber (reg:CC FLAGS_REG))]
3503  "!TARGET_64BIT && reload_completed
3504   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3505  [(set (match_dup 3) (match_dup 1))
3506   (set (match_dup 4) (const_int 0))]
3507  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3508
3509(define_insn "zero_extend<mode>di2"
3510  [(set (match_operand:DI 0 "register_operand" "=r")
3511	(zero_extend:DI
3512	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3513  "TARGET_64BIT"
3514  "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3515  [(set_attr "type" "imovx")
3516   (set_attr "mode" "SI")])
3517
3518(define_expand "zero_extendhisi2"
3519  [(set (match_operand:SI 0 "register_operand" "")
3520	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3521  ""
3522{
3523  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3524    {
3525      operands[1] = force_reg (HImode, operands[1]);
3526      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3527      DONE;
3528    }
3529})
3530
3531(define_insn_and_split "zero_extendhisi2_and"
3532  [(set (match_operand:SI 0 "register_operand" "=r")
3533	(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3534   (clobber (reg:CC FLAGS_REG))]
3535  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3536  "#"
3537  "&& reload_completed"
3538  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3539	      (clobber (reg:CC FLAGS_REG))])]
3540  ""
3541  [(set_attr "type" "alu1")
3542   (set_attr "mode" "SI")])
3543
3544(define_insn "*zero_extendhisi2_movzwl"
3545  [(set (match_operand:SI 0 "register_operand" "=r")
3546	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3547  "!TARGET_ZERO_EXTEND_WITH_AND
3548   || optimize_function_for_size_p (cfun)"
3549  "movz{wl|x}\t{%1, %0|%0, %1}"
3550  [(set_attr "type" "imovx")
3551   (set_attr "mode" "SI")])
3552
3553(define_expand "zero_extendqi<mode>2"
3554  [(parallel
3555    [(set (match_operand:SWI24 0 "register_operand" "")
3556	  (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3557     (clobber (reg:CC FLAGS_REG))])])
3558
3559(define_insn "*zero_extendqi<mode>2_and"
3560  [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3561	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3562   (clobber (reg:CC FLAGS_REG))]
3563  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3564  "#"
3565  [(set_attr "type" "alu1")
3566   (set_attr "mode" "<MODE>")])
3567
3568;; When source and destination does not overlap, clear destination
3569;; first and then do the movb
3570(define_split
3571  [(set (match_operand:SWI24 0 "register_operand" "")
3572	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3573   (clobber (reg:CC FLAGS_REG))]
3574  "reload_completed
3575   && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3576   && ANY_QI_REG_P (operands[0])
3577   && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3578   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3579  [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3580{
3581  operands[2] = gen_lowpart (QImode, operands[0]);
3582  ix86_expand_clear (operands[0]);
3583})
3584
3585(define_insn "*zero_extendqi<mode>2_movzbl_and"
3586  [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3587	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3588   (clobber (reg:CC FLAGS_REG))]
3589  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3590  "#"
3591  [(set_attr "type" "imovx,alu1")
3592   (set_attr "mode" "<MODE>")])
3593
3594;; For the movzbl case strip only the clobber
3595(define_split
3596  [(set (match_operand:SWI24 0 "register_operand" "")
3597	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3598   (clobber (reg:CC FLAGS_REG))]
3599  "reload_completed
3600   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3601   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3602  [(set (match_dup 0)
3603	(zero_extend:SWI24 (match_dup 1)))])
3604
3605; zero extend to SImode to avoid partial register stalls
3606(define_insn "*zero_extendqi<mode>2_movzbl"
3607  [(set (match_operand:SWI24 0 "register_operand" "=r")
3608	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3609  "reload_completed
3610   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3611  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3612  [(set_attr "type" "imovx")
3613   (set_attr "mode" "SI")])
3614
3615;; Rest is handled by single and.
3616(define_split
3617  [(set (match_operand:SWI24 0 "register_operand" "")
3618	(zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3619   (clobber (reg:CC FLAGS_REG))]
3620  "reload_completed
3621   && true_regnum (operands[0]) == true_regnum (operands[1])"
3622  [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3623	      (clobber (reg:CC FLAGS_REG))])])
3624
3625;; Sign extension instructions
3626
3627(define_expand "extendsidi2"
3628  [(set (match_operand:DI 0 "register_operand" "")
3629	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3630  ""
3631{
3632  if (!TARGET_64BIT)
3633    {
3634      emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3635      DONE;
3636    }
3637})
3638
3639(define_insn "*extendsidi2_rex64"
3640  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3641	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3642  "TARGET_64BIT"
3643  "@
3644   {cltq|cdqe}
3645   movs{lq|x}\t{%1, %0|%0, %1}"
3646  [(set_attr "type" "imovx")
3647   (set_attr "mode" "DI")
3648   (set_attr "prefix_0f" "0")
3649   (set_attr "modrm" "0,1")])
3650
3651(define_insn "extendsidi2_1"
3652  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3653	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3654   (clobber (reg:CC FLAGS_REG))
3655   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3656  "!TARGET_64BIT"
3657  "#")
3658
3659;; Extend to memory case when source register does die.
3660(define_split
3661  [(set (match_operand:DI 0 "memory_operand" "")
3662	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3663   (clobber (reg:CC FLAGS_REG))
3664   (clobber (match_operand:SI 2 "register_operand" ""))]
3665  "(reload_completed
3666    && dead_or_set_p (insn, operands[1])
3667    && !reg_mentioned_p (operands[1], operands[0]))"
3668  [(set (match_dup 3) (match_dup 1))
3669   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3670	      (clobber (reg:CC FLAGS_REG))])
3671   (set (match_dup 4) (match_dup 1))]
3672  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3673
3674;; Extend to memory case when source register does not die.
3675(define_split
3676  [(set (match_operand:DI 0 "memory_operand" "")
3677	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3678   (clobber (reg:CC FLAGS_REG))
3679   (clobber (match_operand:SI 2 "register_operand" ""))]
3680  "reload_completed"
3681  [(const_int 0)]
3682{
3683  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3684
3685  emit_move_insn (operands[3], operands[1]);
3686
3687  /* Generate a cltd if possible and doing so it profitable.  */
3688  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3689      && true_regnum (operands[1]) == AX_REG
3690      && true_regnum (operands[2]) == DX_REG)
3691    {
3692      emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3693    }
3694  else
3695    {
3696      emit_move_insn (operands[2], operands[1]);
3697      emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3698    }
3699  emit_move_insn (operands[4], operands[2]);
3700  DONE;
3701})
3702
3703;; Extend to register case.  Optimize case where source and destination
3704;; registers match and cases where we can use cltd.
3705(define_split
3706  [(set (match_operand:DI 0 "register_operand" "")
3707	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3708   (clobber (reg:CC FLAGS_REG))
3709   (clobber (match_scratch:SI 2 ""))]
3710  "reload_completed"
3711  [(const_int 0)]
3712{
3713  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3714
3715  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3716    emit_move_insn (operands[3], operands[1]);
3717
3718  /* Generate a cltd if possible and doing so it profitable.  */
3719  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3720      && true_regnum (operands[3]) == AX_REG
3721      && true_regnum (operands[4]) == DX_REG)
3722    {
3723      emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3724      DONE;
3725    }
3726
3727  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3728    emit_move_insn (operands[4], operands[1]);
3729
3730  emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3731  DONE;
3732})
3733
3734(define_insn "extend<mode>di2"
3735  [(set (match_operand:DI 0 "register_operand" "=r")
3736	(sign_extend:DI
3737	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3738  "TARGET_64BIT"
3739  "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3740  [(set_attr "type" "imovx")
3741   (set_attr "mode" "DI")])
3742
3743(define_insn "extendhisi2"
3744  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3745	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3746  ""
3747{
3748  switch (get_attr_prefix_0f (insn))
3749    {
3750    case 0:
3751      return "{cwtl|cwde}";
3752    default:
3753      return "movs{wl|x}\t{%1, %0|%0, %1}";
3754    }
3755}
3756  [(set_attr "type" "imovx")
3757   (set_attr "mode" "SI")
3758   (set (attr "prefix_0f")
3759     ;; movsx is short decodable while cwtl is vector decoded.
3760     (if_then_else (and (eq_attr "cpu" "!k6")
3761			(eq_attr "alternative" "0"))
3762	(const_string "0")
3763	(const_string "1")))
3764   (set (attr "modrm")
3765     (if_then_else (eq_attr "prefix_0f" "0")
3766	(const_string "0")
3767	(const_string "1")))])
3768
3769(define_insn "*extendhisi2_zext"
3770  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3771	(zero_extend:DI
3772	 (sign_extend:SI
3773	  (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3774  "TARGET_64BIT"
3775{
3776  switch (get_attr_prefix_0f (insn))
3777    {
3778    case 0:
3779      return "{cwtl|cwde}";
3780    default:
3781      return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3782    }
3783}
3784  [(set_attr "type" "imovx")
3785   (set_attr "mode" "SI")
3786   (set (attr "prefix_0f")
3787     ;; movsx is short decodable while cwtl is vector decoded.
3788     (if_then_else (and (eq_attr "cpu" "!k6")
3789			(eq_attr "alternative" "0"))
3790	(const_string "0")
3791	(const_string "1")))
3792   (set (attr "modrm")
3793     (if_then_else (eq_attr "prefix_0f" "0")
3794	(const_string "0")
3795	(const_string "1")))])
3796
3797(define_insn "extendqisi2"
3798  [(set (match_operand:SI 0 "register_operand" "=r")
3799	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3800  ""
3801  "movs{bl|x}\t{%1, %0|%0, %1}"
3802   [(set_attr "type" "imovx")
3803    (set_attr "mode" "SI")])
3804
3805(define_insn "*extendqisi2_zext"
3806  [(set (match_operand:DI 0 "register_operand" "=r")
3807	(zero_extend:DI
3808	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3809  "TARGET_64BIT"
3810  "movs{bl|x}\t{%1, %k0|%k0, %1}"
3811   [(set_attr "type" "imovx")
3812    (set_attr "mode" "SI")])
3813
3814(define_insn "extendqihi2"
3815  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3816	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3817  ""
3818{
3819  switch (get_attr_prefix_0f (insn))
3820    {
3821    case 0:
3822      return "{cbtw|cbw}";
3823    default:
3824      return "movs{bw|x}\t{%1, %0|%0, %1}";
3825    }
3826}
3827  [(set_attr "type" "imovx")
3828   (set_attr "mode" "HI")
3829   (set (attr "prefix_0f")
3830     ;; movsx is short decodable while cwtl is vector decoded.
3831     (if_then_else (and (eq_attr "cpu" "!k6")
3832			(eq_attr "alternative" "0"))
3833	(const_string "0")
3834	(const_string "1")))
3835   (set (attr "modrm")
3836     (if_then_else (eq_attr "prefix_0f" "0")
3837	(const_string "0")
3838	(const_string "1")))])
3839
3840;; Conversions between float and double.
3841
3842;; These are all no-ops in the model used for the 80387.
3843;; So just emit moves.
3844
3845;; %%% Kill these when call knows how to work out a DFmode push earlier.
3846(define_split
3847  [(set (match_operand:DF 0 "push_operand" "")
3848	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3849  "reload_completed"
3850  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3851   (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3852
3853(define_split
3854  [(set (match_operand:XF 0 "push_operand" "")
3855	(float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3856  "reload_completed"
3857  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3858   (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3859  "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3860
3861(define_expand "extendsfdf2"
3862  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3863        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3864  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3865{
3866  /* ??? Needed for compress_float_constant since all fp constants
3867     are TARGET_LEGITIMATE_CONSTANT_P.  */
3868  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3869    {
3870      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3871	  && standard_80387_constant_p (operands[1]) > 0)
3872	{
3873	  operands[1] = simplify_const_unary_operation
3874	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3875	  emit_move_insn_1 (operands[0], operands[1]);
3876	  DONE;
3877	}
3878      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3879    }
3880})
3881
3882/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3883   cvtss2sd:
3884      unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3885      cvtps2pd xmm2,xmm1
3886   We do the conversion post reload to avoid producing of 128bit spills
3887   that might lead to ICE on 32bit target.  The sequence unlikely combine
3888   anyway.  */
3889(define_split
3890  [(set (match_operand:DF 0 "register_operand" "")
3891        (float_extend:DF
3892	  (match_operand:SF 1 "nonimmediate_operand" "")))]
3893  "TARGET_USE_VECTOR_FP_CONVERTS
3894   && optimize_insn_for_speed_p ()
3895   && reload_completed && SSE_REG_P (operands[0])"
3896   [(set (match_dup 2)
3897	 (float_extend:V2DF
3898	   (vec_select:V2SF
3899	     (match_dup 3)
3900	     (parallel [(const_int 0) (const_int 1)]))))]
3901{
3902  operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3903  operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3904  /* Use movss for loading from memory, unpcklps reg, reg for registers.
3905     Try to avoid move when unpacking can be done in source.  */
3906  if (REG_P (operands[1]))
3907    {
3908      /* If it is unsafe to overwrite upper half of source, we need
3909	 to move to destination and unpack there.  */
3910      if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3911	   || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3912	  && true_regnum (operands[0]) != true_regnum (operands[1]))
3913	{
3914	  rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3915	  emit_move_insn (tmp, operands[1]);
3916	}
3917      else
3918	operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3919      emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3920      		 			     operands[3]));
3921    }
3922  else
3923    emit_insn (gen_vec_setv4sf_0 (operands[3],
3924				  CONST0_RTX (V4SFmode), operands[1]));
3925})
3926
3927(define_insn "*extendsfdf2_mixed"
3928  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3929        (float_extend:DF
3930	  (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3931  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3932{
3933  switch (which_alternative)
3934    {
3935    case 0:
3936    case 1:
3937      return output_387_reg_move (insn, operands);
3938
3939    case 2:
3940      return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3941
3942    default:
3943      gcc_unreachable ();
3944    }
3945}
3946  [(set_attr "type" "fmov,fmov,ssecvt")
3947   (set_attr "prefix" "orig,orig,maybe_vex")
3948   (set_attr "mode" "SF,XF,DF")])
3949
3950(define_insn "*extendsfdf2_sse"
3951  [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3952        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3953  "TARGET_SSE2 && TARGET_SSE_MATH"
3954  "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3955  [(set_attr "type" "ssecvt")
3956   (set_attr "prefix" "maybe_vex")
3957   (set_attr "mode" "DF")])
3958
3959(define_insn "*extendsfdf2_i387"
3960  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3961        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3962  "TARGET_80387"
3963  "* return output_387_reg_move (insn, operands);"
3964  [(set_attr "type" "fmov")
3965   (set_attr "mode" "SF,XF")])
3966
3967(define_expand "extend<mode>xf2"
3968  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3969        (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3970  "TARGET_80387"
3971{
3972  /* ??? Needed for compress_float_constant since all fp constants
3973     are TARGET_LEGITIMATE_CONSTANT_P.  */
3974  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3975    {
3976      if (standard_80387_constant_p (operands[1]) > 0)
3977	{
3978	  operands[1] = simplify_const_unary_operation
3979	    (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3980	  emit_move_insn_1 (operands[0], operands[1]);
3981	  DONE;
3982	}
3983      operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3984    }
3985})
3986
3987(define_insn "*extend<mode>xf2_i387"
3988  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3989        (float_extend:XF
3990	  (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3991  "TARGET_80387"
3992  "* return output_387_reg_move (insn, operands);"
3993  [(set_attr "type" "fmov")
3994   (set_attr "mode" "<MODE>,XF")])
3995
3996;; %%% This seems bad bad news.
3997;; This cannot output into an f-reg because there is no way to be sure
3998;; of truncating in that case.  Otherwise this is just like a simple move
3999;; insn.  So we pretend we can output to a reg in order to get better
4000;; register preferencing, but we really use a stack slot.
4001
4002;; Conversion from DFmode to SFmode.
4003
4004(define_expand "truncdfsf2"
4005  [(set (match_operand:SF 0 "nonimmediate_operand" "")
4006	(float_truncate:SF
4007	  (match_operand:DF 1 "nonimmediate_operand" "")))]
4008  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4009{
4010  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4011    ;
4012  else if (flag_unsafe_math_optimizations)
4013    ;
4014  else
4015    {
4016      rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4017      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4018      DONE;
4019    }
4020})
4021
4022/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4023   cvtsd2ss:
4024      unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4025      cvtpd2ps xmm2,xmm1
4026   We do the conversion post reload to avoid producing of 128bit spills
4027   that might lead to ICE on 32bit target.  The sequence unlikely combine
4028   anyway.  */
4029(define_split
4030  [(set (match_operand:SF 0 "register_operand" "")
4031        (float_truncate:SF
4032	  (match_operand:DF 1 "nonimmediate_operand" "")))]
4033  "TARGET_USE_VECTOR_FP_CONVERTS
4034   && optimize_insn_for_speed_p ()
4035   && reload_completed && SSE_REG_P (operands[0])"
4036   [(set (match_dup 2)
4037	 (vec_concat:V4SF
4038	   (float_truncate:V2SF
4039	     (match_dup 4))
4040	   (match_dup 3)))]
4041{
4042  operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4043  operands[3] = CONST0_RTX (V2SFmode);
4044  operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4045  /* Use movsd for loading from memory, unpcklpd for registers.
4046     Try to avoid move when unpacking can be done in source, or SSE3
4047     movddup is available.  */
4048  if (REG_P (operands[1]))
4049    {
4050      if (!TARGET_SSE3
4051	  && true_regnum (operands[0]) != true_regnum (operands[1])
4052	  && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4053	      || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4054	{
4055	  rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4056	  emit_move_insn (tmp, operands[1]);
4057	  operands[1] = tmp;
4058	}
4059      else if (!TARGET_SSE3)
4060	operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4061      emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4062    }
4063  else
4064    emit_insn (gen_sse2_loadlpd (operands[4],
4065				 CONST0_RTX (V2DFmode), operands[1]));
4066})
4067
4068(define_expand "truncdfsf2_with_temp"
4069  [(parallel [(set (match_operand:SF 0 "" "")
4070		   (float_truncate:SF (match_operand:DF 1 "" "")))
4071	      (clobber (match_operand:SF 2 "" ""))])])
4072
4073(define_insn "*truncdfsf_fast_mixed"
4074  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4075        (float_truncate:SF
4076          (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4077  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4078{
4079  switch (which_alternative)
4080    {
4081    case 0:
4082      return output_387_reg_move (insn, operands);
4083    case 1:
4084      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4085    default:
4086      gcc_unreachable ();
4087    }
4088}
4089  [(set_attr "type" "fmov,ssecvt")
4090   (set_attr "prefix" "orig,maybe_vex")
4091   (set_attr "mode" "SF")])
4092
4093;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4094;; because nothing we do here is unsafe.
4095(define_insn "*truncdfsf_fast_sse"
4096  [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4097        (float_truncate:SF
4098          (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4099  "TARGET_SSE2 && TARGET_SSE_MATH"
4100  "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4101  [(set_attr "type" "ssecvt")
4102   (set_attr "prefix" "maybe_vex")
4103   (set_attr "mode" "SF")])
4104
4105(define_insn "*truncdfsf_fast_i387"
4106  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4107        (float_truncate:SF
4108          (match_operand:DF 1 "nonimmediate_operand" "f")))]
4109  "TARGET_80387 && flag_unsafe_math_optimizations"
4110  "* return output_387_reg_move (insn, operands);"
4111  [(set_attr "type" "fmov")
4112   (set_attr "mode" "SF")])
4113
4114(define_insn "*truncdfsf_mixed"
4115  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4116	(float_truncate:SF
4117	  (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4118   (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4119  "TARGET_MIX_SSE_I387"
4120{
4121  switch (which_alternative)
4122    {
4123    case 0:
4124      return output_387_reg_move (insn, operands);
4125    case 1:
4126      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4127
4128    default:
4129      return "#";
4130    }
4131}
4132  [(set_attr "isa" "*,sse2,*,*,*")
4133   (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4134   (set_attr "unit" "*,*,i387,i387,i387")
4135   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4136   (set_attr "mode" "SF")])
4137
4138(define_insn "*truncdfsf_i387"
4139  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4140	(float_truncate:SF
4141	  (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4142   (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4143  "TARGET_80387"
4144{
4145  switch (which_alternative)
4146    {
4147    case 0:
4148      return output_387_reg_move (insn, operands);
4149
4150    default:
4151      return "#";
4152    }
4153}
4154  [(set_attr "type" "fmov,multi,multi,multi")
4155   (set_attr "unit" "*,i387,i387,i387")
4156   (set_attr "mode" "SF")])
4157
4158(define_insn "*truncdfsf2_i387_1"
4159  [(set (match_operand:SF 0 "memory_operand" "=m")
4160	(float_truncate:SF
4161	  (match_operand:DF 1 "register_operand" "f")))]
4162  "TARGET_80387
4163   && !(TARGET_SSE2 && TARGET_SSE_MATH)
4164   && !TARGET_MIX_SSE_I387"
4165  "* return output_387_reg_move (insn, operands);"
4166  [(set_attr "type" "fmov")
4167   (set_attr "mode" "SF")])
4168
4169(define_split
4170  [(set (match_operand:SF 0 "register_operand" "")
4171	(float_truncate:SF
4172	 (match_operand:DF 1 "fp_register_operand" "")))
4173   (clobber (match_operand 2 "" ""))]
4174  "reload_completed"
4175  [(set (match_dup 2) (match_dup 1))
4176   (set (match_dup 0) (match_dup 2))]
4177  "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4178
4179;; Conversion from XFmode to {SF,DF}mode
4180
4181(define_expand "truncxf<mode>2"
4182  [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4183		   (float_truncate:MODEF
4184		     (match_operand:XF 1 "register_operand" "")))
4185	      (clobber (match_dup 2))])]
4186  "TARGET_80387"
4187{
4188  if (flag_unsafe_math_optimizations)
4189    {
4190      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4191      emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4192      if (reg != operands[0])
4193	emit_move_insn (operands[0], reg);
4194      DONE;
4195    }
4196  else
4197    operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4198})
4199
4200(define_insn "*truncxfsf2_mixed"
4201  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4202	(float_truncate:SF
4203	  (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4204   (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4205  "TARGET_80387"
4206{
4207  gcc_assert (!which_alternative);
4208  return output_387_reg_move (insn, operands);
4209}
4210  [(set_attr "type" "fmov,multi,multi,multi")
4211   (set_attr "unit" "*,i387,i387,i387")
4212   (set_attr "mode" "SF")])
4213
4214(define_insn "*truncxfdf2_mixed"
4215  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4216	(float_truncate:DF
4217	  (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4218   (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4219  "TARGET_80387"
4220{
4221  gcc_assert (!which_alternative);
4222  return output_387_reg_move (insn, operands);
4223}
4224  [(set_attr "isa" "*,*,sse2,*")
4225   (set_attr "type" "fmov,multi,multi,multi")
4226   (set_attr "unit" "*,i387,i387,i387")
4227   (set_attr "mode" "DF")])
4228
4229(define_insn "truncxf<mode>2_i387_noop"
4230  [(set (match_operand:MODEF 0 "register_operand" "=f")
4231	(float_truncate:MODEF
4232	  (match_operand:XF 1 "register_operand" "f")))]
4233  "TARGET_80387 && flag_unsafe_math_optimizations"
4234  "* return output_387_reg_move (insn, operands);"
4235  [(set_attr "type" "fmov")
4236   (set_attr "mode" "<MODE>")])
4237
4238(define_insn "*truncxf<mode>2_i387"
4239  [(set (match_operand:MODEF 0 "memory_operand" "=m")
4240	(float_truncate:MODEF
4241	  (match_operand:XF 1 "register_operand" "f")))]
4242  "TARGET_80387"
4243  "* return output_387_reg_move (insn, operands);"
4244  [(set_attr "type" "fmov")
4245   (set_attr "mode" "<MODE>")])
4246
4247(define_split
4248  [(set (match_operand:MODEF 0 "register_operand" "")
4249	(float_truncate:MODEF
4250	  (match_operand:XF 1 "register_operand" "")))
4251   (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4252  "TARGET_80387 && reload_completed"
4253  [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4254   (set (match_dup 0) (match_dup 2))])
4255
4256(define_split
4257  [(set (match_operand:MODEF 0 "memory_operand" "")
4258	(float_truncate:MODEF
4259	  (match_operand:XF 1 "register_operand" "")))
4260   (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4261  "TARGET_80387"
4262  [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4263
4264;; Signed conversion to DImode.
4265
4266(define_expand "fix_truncxfdi2"
4267  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4268                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4269	      (clobber (reg:CC FLAGS_REG))])]
4270  "TARGET_80387"
4271{
4272  if (TARGET_FISTTP)
4273   {
4274     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4275     DONE;
4276   }
4277})
4278
4279(define_expand "fix_trunc<mode>di2"
4280  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4281                   (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4282              (clobber (reg:CC FLAGS_REG))])]
4283  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4284{
4285  if (TARGET_FISTTP
4286      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4287   {
4288     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4289     DONE;
4290   }
4291  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4292   {
4293     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4294     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4295     if (out != operands[0])
4296	emit_move_insn (operands[0], out);
4297     DONE;
4298   }
4299})
4300
4301;; Signed conversion to SImode.
4302
4303(define_expand "fix_truncxfsi2"
4304  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4305                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4306	      (clobber (reg:CC FLAGS_REG))])]
4307  "TARGET_80387"
4308{
4309  if (TARGET_FISTTP)
4310   {
4311     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4312     DONE;
4313   }
4314})
4315
4316(define_expand "fix_trunc<mode>si2"
4317  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4318	           (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4319	      (clobber (reg:CC FLAGS_REG))])]
4320  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4321{
4322  if (TARGET_FISTTP
4323      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4324   {
4325     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4326     DONE;
4327   }
4328  if (SSE_FLOAT_MODE_P (<MODE>mode))
4329   {
4330     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4331     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4332     if (out != operands[0])
4333	emit_move_insn (operands[0], out);
4334     DONE;
4335   }
4336})
4337
4338;; Signed conversion to HImode.
4339
4340(define_expand "fix_trunc<mode>hi2"
4341  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4342	           (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4343              (clobber (reg:CC FLAGS_REG))])]
4344  "TARGET_80387
4345   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4346{
4347  if (TARGET_FISTTP)
4348   {
4349     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4350     DONE;
4351   }
4352})
4353
4354;; Unsigned conversion to SImode.
4355
4356(define_expand "fixuns_trunc<mode>si2"
4357  [(parallel
4358    [(set (match_operand:SI 0 "register_operand" "")
4359	  (unsigned_fix:SI
4360	    (match_operand:MODEF 1 "nonimmediate_operand" "")))
4361     (use (match_dup 2))
4362     (clobber (match_scratch:<ssevecmode> 3 ""))
4363     (clobber (match_scratch:<ssevecmode> 4 ""))])]
4364  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4365{
4366  enum machine_mode mode = <MODE>mode;
4367  enum machine_mode vecmode = <ssevecmode>mode;
4368  REAL_VALUE_TYPE TWO31r;
4369  rtx two31;
4370
4371  if (optimize_insn_for_size_p ())
4372    FAIL;
4373
4374  real_ldexp (&TWO31r, &dconst1, 31);
4375  two31 = const_double_from_real_value (TWO31r, mode);
4376  two31 = ix86_build_const_vector (vecmode, true, two31);
4377  operands[2] = force_reg (vecmode, two31);
4378})
4379
4380(define_insn_and_split "*fixuns_trunc<mode>_1"
4381  [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4382	(unsigned_fix:SI
4383	  (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4384   (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4385   (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4386   (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4387  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4388   && optimize_function_for_speed_p (cfun)"
4389  "#"
4390  "&& reload_completed"
4391  [(const_int 0)]
4392{
4393  ix86_split_convert_uns_si_sse (operands);
4394  DONE;
4395})
4396
4397;; Unsigned conversion to HImode.
4398;; Without these patterns, we'll try the unsigned SI conversion which
4399;; is complex for SSE, rather than the signed SI conversion, which isn't.
4400
4401(define_expand "fixuns_trunc<mode>hi2"
4402  [(set (match_dup 2)
4403	(fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4404   (set (match_operand:HI 0 "nonimmediate_operand" "")
4405	(subreg:HI (match_dup 2) 0))]
4406  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4407  "operands[2] = gen_reg_rtx (SImode);")
4408
4409;; When SSE is available, it is always faster to use it!
4410(define_insn "fix_trunc<mode>di_sse"
4411  [(set (match_operand:DI 0 "register_operand" "=r,r")
4412	(fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4413  "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4414   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4415  "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4416  [(set_attr "type" "sseicvt")
4417   (set_attr "prefix" "maybe_vex")
4418   (set_attr "prefix_rex" "1")
4419   (set_attr "mode" "<MODE>")
4420   (set_attr "athlon_decode" "double,vector")
4421   (set_attr "amdfam10_decode" "double,double")
4422   (set_attr "bdver1_decode" "double,double")])
4423
4424(define_insn "fix_trunc<mode>si_sse"
4425  [(set (match_operand:SI 0 "register_operand" "=r,r")
4426	(fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4427  "SSE_FLOAT_MODE_P (<MODE>mode)
4428   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4429  "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4430  [(set_attr "type" "sseicvt")
4431   (set_attr "prefix" "maybe_vex")
4432   (set_attr "mode" "<MODE>")
4433   (set_attr "athlon_decode" "double,vector")
4434   (set_attr "amdfam10_decode" "double,double")
4435   (set_attr "bdver1_decode" "double,double")])
4436
4437;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4438(define_peephole2
4439  [(set (match_operand:MODEF 0 "register_operand" "")
4440	(match_operand:MODEF 1 "memory_operand" ""))
4441   (set (match_operand:SWI48x 2 "register_operand" "")
4442	(fix:SWI48x (match_dup 0)))]
4443  "TARGET_SHORTEN_X87_SSE
4444   && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4445   && peep2_reg_dead_p (2, operands[0])"
4446  [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4447
4448;; Avoid vector decoded forms of the instruction.
4449(define_peephole2
4450  [(match_scratch:DF 2 "x")
4451   (set (match_operand:SWI48x 0 "register_operand" "")
4452	(fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4453  "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4454  [(set (match_dup 2) (match_dup 1))
4455   (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4456
4457(define_peephole2
4458  [(match_scratch:SF 2 "x")
4459   (set (match_operand:SWI48x 0 "register_operand" "")
4460	(fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4461  "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4462  [(set (match_dup 2) (match_dup 1))
4463   (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4464
4465(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4466  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4467	(fix:SWI248x (match_operand 1 "register_operand" "")))]
4468  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4469   && TARGET_FISTTP
4470   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4471	 && (TARGET_64BIT || <MODE>mode != DImode))
4472	&& TARGET_SSE_MATH)
4473   && can_create_pseudo_p ()"
4474  "#"
4475  "&& 1"
4476  [(const_int 0)]
4477{
4478  if (memory_operand (operands[0], VOIDmode))
4479    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4480  else
4481    {
4482      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4483      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4484							    operands[1],
4485							    operands[2]));
4486    }
4487  DONE;
4488}
4489  [(set_attr "type" "fisttp")
4490   (set_attr "mode" "<MODE>")])
4491
4492(define_insn "fix_trunc<mode>_i387_fisttp"
4493  [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4494	(fix:SWI248x (match_operand 1 "register_operand" "f")))
4495   (clobber (match_scratch:XF 2 "=&1f"))]
4496  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4497   && TARGET_FISTTP
4498   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4499	 && (TARGET_64BIT || <MODE>mode != DImode))
4500	&& TARGET_SSE_MATH)"
4501  "* return output_fix_trunc (insn, operands, true);"
4502  [(set_attr "type" "fisttp")
4503   (set_attr "mode" "<MODE>")])
4504
4505(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4506  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4507	(fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4508   (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4509   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4510  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4511   && TARGET_FISTTP
4512   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4513	&& (TARGET_64BIT || <MODE>mode != DImode))
4514	&& TARGET_SSE_MATH)"
4515  "#"
4516  [(set_attr "type" "fisttp")
4517   (set_attr "mode" "<MODE>")])
4518
4519(define_split
4520  [(set (match_operand:SWI248x 0 "register_operand" "")
4521	(fix:SWI248x (match_operand 1 "register_operand" "")))
4522   (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4523   (clobber (match_scratch 3 ""))]
4524  "reload_completed"
4525  [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4526	      (clobber (match_dup 3))])
4527   (set (match_dup 0) (match_dup 2))])
4528
4529(define_split
4530  [(set (match_operand:SWI248x 0 "memory_operand" "")
4531	(fix:SWI248x (match_operand 1 "register_operand" "")))
4532   (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4533   (clobber (match_scratch 3 ""))]
4534  "reload_completed"
4535  [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4536	      (clobber (match_dup 3))])])
4537
4538;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4539;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4540;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4541;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4542;; function in i386.c.
4543(define_insn_and_split "*fix_trunc<mode>_i387_1"
4544  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4545	(fix:SWI248x (match_operand 1 "register_operand" "")))
4546   (clobber (reg:CC FLAGS_REG))]
4547  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4548   && !TARGET_FISTTP
4549   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4550	 && (TARGET_64BIT || <MODE>mode != DImode))
4551   && can_create_pseudo_p ()"
4552  "#"
4553  "&& 1"
4554  [(const_int 0)]
4555{
4556  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4557
4558  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4559  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4560  if (memory_operand (operands[0], VOIDmode))
4561    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4562					 operands[2], operands[3]));
4563  else
4564    {
4565      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4566      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4567						     operands[2], operands[3],
4568						     operands[4]));
4569    }
4570  DONE;
4571}
4572  [(set_attr "type" "fistp")
4573   (set_attr "i387_cw" "trunc")
4574   (set_attr "mode" "<MODE>")])
4575
4576(define_insn "fix_truncdi_i387"
4577  [(set (match_operand:DI 0 "memory_operand" "=m")
4578	(fix:DI (match_operand 1 "register_operand" "f")))
4579   (use (match_operand:HI 2 "memory_operand" "m"))
4580   (use (match_operand:HI 3 "memory_operand" "m"))
4581   (clobber (match_scratch:XF 4 "=&1f"))]
4582  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583   && !TARGET_FISTTP
4584   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4585  "* return output_fix_trunc (insn, operands, false);"
4586  [(set_attr "type" "fistp")
4587   (set_attr "i387_cw" "trunc")
4588   (set_attr "mode" "DI")])
4589
4590(define_insn "fix_truncdi_i387_with_temp"
4591  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4592	(fix:DI (match_operand 1 "register_operand" "f,f")))
4593   (use (match_operand:HI 2 "memory_operand" "m,m"))
4594   (use (match_operand:HI 3 "memory_operand" "m,m"))
4595   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4596   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4597  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598   && !TARGET_FISTTP
4599   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4600  "#"
4601  [(set_attr "type" "fistp")
4602   (set_attr "i387_cw" "trunc")
4603   (set_attr "mode" "DI")])
4604
4605(define_split
4606  [(set (match_operand:DI 0 "register_operand" "")
4607	(fix:DI (match_operand 1 "register_operand" "")))
4608   (use (match_operand:HI 2 "memory_operand" ""))
4609   (use (match_operand:HI 3 "memory_operand" ""))
4610   (clobber (match_operand:DI 4 "memory_operand" ""))
4611   (clobber (match_scratch 5 ""))]
4612  "reload_completed"
4613  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4614	      (use (match_dup 2))
4615	      (use (match_dup 3))
4616	      (clobber (match_dup 5))])
4617   (set (match_dup 0) (match_dup 4))])
4618
4619(define_split
4620  [(set (match_operand:DI 0 "memory_operand" "")
4621	(fix:DI (match_operand 1 "register_operand" "")))
4622   (use (match_operand:HI 2 "memory_operand" ""))
4623   (use (match_operand:HI 3 "memory_operand" ""))
4624   (clobber (match_operand:DI 4 "memory_operand" ""))
4625   (clobber (match_scratch 5 ""))]
4626  "reload_completed"
4627  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4628	      (use (match_dup 2))
4629	      (use (match_dup 3))
4630	      (clobber (match_dup 5))])])
4631
4632(define_insn "fix_trunc<mode>_i387"
4633  [(set (match_operand:SWI24 0 "memory_operand" "=m")
4634	(fix:SWI24 (match_operand 1 "register_operand" "f")))
4635   (use (match_operand:HI 2 "memory_operand" "m"))
4636   (use (match_operand:HI 3 "memory_operand" "m"))]
4637  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4638   && !TARGET_FISTTP
4639   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4640  "* return output_fix_trunc (insn, operands, false);"
4641  [(set_attr "type" "fistp")
4642   (set_attr "i387_cw" "trunc")
4643   (set_attr "mode" "<MODE>")])
4644
4645(define_insn "fix_trunc<mode>_i387_with_temp"
4646  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4647	(fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4648   (use (match_operand:HI 2 "memory_operand" "m,m"))
4649   (use (match_operand:HI 3 "memory_operand" "m,m"))
4650   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4651  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4652   && !TARGET_FISTTP
4653   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654  "#"
4655  [(set_attr "type" "fistp")
4656   (set_attr "i387_cw" "trunc")
4657   (set_attr "mode" "<MODE>")])
4658
4659(define_split
4660  [(set (match_operand:SWI24 0 "register_operand" "")
4661	(fix:SWI24 (match_operand 1 "register_operand" "")))
4662   (use (match_operand:HI 2 "memory_operand" ""))
4663   (use (match_operand:HI 3 "memory_operand" ""))
4664   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4665  "reload_completed"
4666  [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4667	      (use (match_dup 2))
4668	      (use (match_dup 3))])
4669   (set (match_dup 0) (match_dup 4))])
4670
4671(define_split
4672  [(set (match_operand:SWI24 0 "memory_operand" "")
4673	(fix:SWI24 (match_operand 1 "register_operand" "")))
4674   (use (match_operand:HI 2 "memory_operand" ""))
4675   (use (match_operand:HI 3 "memory_operand" ""))
4676   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4677  "reload_completed"
4678  [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4679	      (use (match_dup 2))
4680	      (use (match_dup 3))])])
4681
4682(define_insn "x86_fnstcw_1"
4683  [(set (match_operand:HI 0 "memory_operand" "=m")
4684	(unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4685  "TARGET_80387"
4686  "fnstcw\t%0"
4687  [(set (attr "length")
4688	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4689   (set_attr "mode" "HI")
4690   (set_attr "unit" "i387")
4691   (set_attr "bdver1_decode" "vector")])
4692
4693(define_insn "x86_fldcw_1"
4694  [(set (reg:HI FPCR_REG)
4695	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4696  "TARGET_80387"
4697  "fldcw\t%0"
4698  [(set (attr "length")
4699	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4700   (set_attr "mode" "HI")
4701   (set_attr "unit" "i387")
4702   (set_attr "athlon_decode" "vector")
4703   (set_attr "amdfam10_decode" "vector")
4704   (set_attr "bdver1_decode" "vector")])
4705
4706;; Conversion between fixed point and floating point.
4707
4708;; Even though we only accept memory inputs, the backend _really_
4709;; wants to be able to do this between registers.
4710
4711(define_expand "floathi<mode>2"
4712  [(set (match_operand:X87MODEF 0 "register_operand" "")
4713	(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4714  "TARGET_80387
4715   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4716       || TARGET_MIX_SSE_I387)")
4717
4718;; Pre-reload splitter to add memory clobber to the pattern.
4719(define_insn_and_split "*floathi<mode>2_1"
4720  [(set (match_operand:X87MODEF 0 "register_operand" "")
4721	(float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4722  "TARGET_80387
4723   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4724       || TARGET_MIX_SSE_I387)
4725   && can_create_pseudo_p ()"
4726  "#"
4727  "&& 1"
4728  [(parallel [(set (match_dup 0)
4729	      (float:X87MODEF (match_dup 1)))
4730   (clobber (match_dup 2))])]
4731  "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4732
4733(define_insn "*floathi<mode>2_i387_with_temp"
4734  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4735	(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4736  (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4737  "TARGET_80387
4738   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4739       || TARGET_MIX_SSE_I387)"
4740  "#"
4741  [(set_attr "type" "fmov,multi")
4742   (set_attr "mode" "<MODE>")
4743   (set_attr "unit" "*,i387")
4744   (set_attr "fp_int_src" "true")])
4745
4746(define_insn "*floathi<mode>2_i387"
4747  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4748	(float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4749  "TARGET_80387
4750   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4751       || TARGET_MIX_SSE_I387)"
4752  "fild%Z1\t%1"
4753  [(set_attr "type" "fmov")
4754   (set_attr "mode" "<MODE>")
4755   (set_attr "fp_int_src" "true")])
4756
4757(define_split
4758  [(set (match_operand:X87MODEF 0 "register_operand" "")
4759	(float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4760   (clobber (match_operand:HI 2 "memory_operand" ""))]
4761  "TARGET_80387
4762   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4763       || TARGET_MIX_SSE_I387)
4764   && reload_completed"
4765  [(set (match_dup 2) (match_dup 1))
4766   (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4767
4768(define_split
4769  [(set (match_operand:X87MODEF 0 "register_operand" "")
4770	(float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4771   (clobber (match_operand:HI 2 "memory_operand" ""))]
4772   "TARGET_80387
4773    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4774        || TARGET_MIX_SSE_I387)
4775    && reload_completed"
4776  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4777
4778(define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4779  [(set (match_operand:X87MODEF 0 "register_operand" "")
4780	(float:X87MODEF
4781	  (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4782  "TARGET_80387
4783   || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4784       && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4785{
4786  if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4787	&& SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4788      && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4789    {
4790      rtx reg = gen_reg_rtx (XFmode);
4791      rtx (*insn)(rtx, rtx);
4792
4793      emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4794
4795      if (<X87MODEF:MODE>mode == SFmode)
4796	insn = gen_truncxfsf2;
4797      else if (<X87MODEF:MODE>mode == DFmode)
4798	insn = gen_truncxfdf2;
4799      else
4800	gcc_unreachable ();
4801
4802      emit_insn (insn (operands[0], reg));
4803      DONE;
4804    }
4805})
4806
4807;; Pre-reload splitter to add memory clobber to the pattern.
4808(define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4809  [(set (match_operand:X87MODEF 0 "register_operand" "")
4810	(float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4811  "((TARGET_80387
4812     && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4813     && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4814	   && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4815	 || TARGET_MIX_SSE_I387))
4816    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4817	&& SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4818	&& ((<SWI48x:MODE>mode == SImode
4819	     && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4820	     && optimize_function_for_speed_p (cfun)
4821	     && flag_trapping_math)
4822	    || !(TARGET_INTER_UNIT_CONVERSIONS
4823	         || optimize_function_for_size_p (cfun)))))
4824   && can_create_pseudo_p ()"
4825  "#"
4826  "&& 1"
4827  [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4828	      (clobber (match_dup 2))])]
4829{
4830  operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4831
4832  /* Avoid store forwarding (partial memory) stall penalty
4833     by passing DImode value through XMM registers.  */
4834  if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4835      && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4836      && optimize_function_for_speed_p (cfun))
4837    {
4838      emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4839							    operands[1],
4840							    operands[2]));
4841      DONE;
4842    }
4843})
4844
4845(define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4846  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4847	(float:MODEF
4848	  (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4849   (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4850  "TARGET_SSE2 && TARGET_MIX_SSE_I387
4851   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4852  "#"
4853  [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4854   (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4855   (set_attr "unit" "*,i387,*,*,*")
4856   (set_attr "athlon_decode" "*,*,double,direct,double")
4857   (set_attr "amdfam10_decode" "*,*,vector,double,double")
4858   (set_attr "bdver1_decode" "*,*,double,direct,double")
4859   (set_attr "fp_int_src" "true")])
4860
4861(define_insn "*floatsi<mode>2_vector_mixed"
4862  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4863	(float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4864  "TARGET_SSE2 && TARGET_MIX_SSE_I387
4865   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4866  "@
4867   fild%Z1\t%1
4868   #"
4869  [(set_attr "type" "fmov,sseicvt")
4870   (set_attr "mode" "<MODE>,<ssevecmode>")
4871   (set_attr "unit" "i387,*")
4872   (set_attr "athlon_decode" "*,direct")
4873   (set_attr "amdfam10_decode" "*,double")
4874   (set_attr "bdver1_decode" "*,direct")
4875   (set_attr "fp_int_src" "true")])
4876
4877(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4878  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4879	(float:MODEF
4880	  (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4881   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4882  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4883   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4884  "#"
4885  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4886   (set_attr "mode" "<MODEF:MODE>")
4887   (set_attr "unit" "*,i387,*,*")
4888   (set_attr "athlon_decode" "*,*,double,direct")
4889   (set_attr "amdfam10_decode" "*,*,vector,double")
4890   (set_attr "bdver1_decode" "*,*,double,direct")
4891   (set_attr "fp_int_src" "true")])
4892
4893(define_split
4894  [(set (match_operand:MODEF 0 "register_operand" "")
4895	(float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4896   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4897  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4898   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4899   && TARGET_INTER_UNIT_CONVERSIONS
4900   && reload_completed
4901   && (SSE_REG_P (operands[0])
4902       || (GET_CODE (operands[0]) == SUBREG
4903	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
4904  [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4905
4906(define_split
4907  [(set (match_operand:MODEF 0 "register_operand" "")
4908	(float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4909   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4910  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4911   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4912   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4913   && reload_completed
4914   && (SSE_REG_P (operands[0])
4915       || (GET_CODE (operands[0]) == SUBREG
4916	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
4917  [(set (match_dup 2) (match_dup 1))
4918   (set (match_dup 0) (float:MODEF (match_dup 2)))])
4919
4920(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4921  [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4922	(float:MODEF
4923	  (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4924  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4925   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4926   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4927  "@
4928   fild%Z1\t%1
4929   %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4930   %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4931  [(set_attr "type" "fmov,sseicvt,sseicvt")
4932   (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4933   (set_attr "mode" "<MODEF:MODE>")
4934   (set (attr "prefix_rex")
4935     (if_then_else
4936       (and (eq_attr "prefix" "maybe_vex")
4937	    (match_test "<SWI48x:MODE>mode == DImode"))
4938       (const_string "1")
4939       (const_string "*")))
4940   (set_attr "unit" "i387,*,*")
4941   (set_attr "athlon_decode" "*,double,direct")
4942   (set_attr "amdfam10_decode" "*,vector,double")
4943   (set_attr "bdver1_decode" "*,double,direct")
4944   (set_attr "fp_int_src" "true")])
4945
4946(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4947  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4948	(float:MODEF
4949	  (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4950  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4951   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4952   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4953  "@
4954   fild%Z1\t%1
4955   %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4956  [(set_attr "type" "fmov,sseicvt")
4957   (set_attr "prefix" "orig,maybe_vex")
4958   (set_attr "mode" "<MODEF:MODE>")
4959   (set (attr "prefix_rex")
4960     (if_then_else
4961       (and (eq_attr "prefix" "maybe_vex")
4962	    (match_test "<SWI48x:MODE>mode == DImode"))
4963       (const_string "1")
4964       (const_string "*")))
4965   (set_attr "athlon_decode" "*,direct")
4966   (set_attr "amdfam10_decode" "*,double")
4967   (set_attr "bdver1_decode" "*,direct")
4968   (set_attr "fp_int_src" "true")])
4969
4970(define_insn "*floatsi<mode>2_vector_sse_with_temp"
4971  [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4972	(float:MODEF
4973	  (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4974   (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4975  "TARGET_SSE2 && TARGET_SSE_MATH
4976   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4977  "#"
4978  [(set_attr "type" "sseicvt")
4979   (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4980   (set_attr "athlon_decode" "double,direct,double")
4981   (set_attr "amdfam10_decode" "vector,double,double")
4982   (set_attr "bdver1_decode" "double,direct,double")
4983   (set_attr "fp_int_src" "true")])
4984
4985(define_insn "*floatsi<mode>2_vector_sse"
4986  [(set (match_operand:MODEF 0 "register_operand" "=x")
4987	(float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4988  "TARGET_SSE2 && TARGET_SSE_MATH
4989   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4990  "#"
4991  [(set_attr "type" "sseicvt")
4992   (set_attr "mode" "<MODE>")
4993   (set_attr "athlon_decode" "direct")
4994   (set_attr "amdfam10_decode" "double")
4995   (set_attr "bdver1_decode" "direct")
4996   (set_attr "fp_int_src" "true")])
4997
4998(define_split
4999  [(set (match_operand:MODEF 0 "register_operand" "")
5000	(float:MODEF (match_operand:SI 1 "register_operand" "")))
5001   (clobber (match_operand:SI 2 "memory_operand" ""))]
5002  "TARGET_SSE2 && TARGET_SSE_MATH
5003   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5004   && reload_completed
5005   && (SSE_REG_P (operands[0])
5006       || (GET_CODE (operands[0]) == SUBREG
5007	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5008  [(const_int 0)]
5009{
5010  rtx op1 = operands[1];
5011
5012  operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5013				     <MODE>mode, 0);
5014  if (GET_CODE (op1) == SUBREG)
5015    op1 = SUBREG_REG (op1);
5016
5017  if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5018    {
5019      operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5020      emit_insn (gen_sse2_loadld (operands[4],
5021				  CONST0_RTX (V4SImode), operands[1]));
5022    }
5023  /* We can ignore possible trapping value in the
5024     high part of SSE register for non-trapping math. */
5025  else if (SSE_REG_P (op1) && !flag_trapping_math)
5026    operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5027  else
5028    {
5029      operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5030      emit_move_insn (operands[2], operands[1]);
5031      emit_insn (gen_sse2_loadld (operands[4],
5032				  CONST0_RTX (V4SImode), operands[2]));
5033    }
5034  if (<ssevecmode>mode == V4SFmode)
5035    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5036  else
5037    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5038  DONE;
5039})
5040
5041(define_split
5042  [(set (match_operand:MODEF 0 "register_operand" "")
5043	(float:MODEF (match_operand:SI 1 "memory_operand" "")))
5044   (clobber (match_operand:SI 2 "memory_operand" ""))]
5045  "TARGET_SSE2 && TARGET_SSE_MATH
5046   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5047   && reload_completed
5048   && (SSE_REG_P (operands[0])
5049       || (GET_CODE (operands[0]) == SUBREG
5050	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5051  [(const_int 0)]
5052{
5053  operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5054				     <MODE>mode, 0);
5055  operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5056
5057  emit_insn (gen_sse2_loadld (operands[4],
5058			      CONST0_RTX (V4SImode), operands[1]));
5059  if (<ssevecmode>mode == V4SFmode)
5060    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5061  else
5062    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5063  DONE;
5064})
5065
5066(define_split
5067  [(set (match_operand:MODEF 0 "register_operand" "")
5068	(float:MODEF (match_operand:SI 1 "register_operand" "")))]
5069  "TARGET_SSE2 && TARGET_SSE_MATH
5070   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5071   && reload_completed
5072   && (SSE_REG_P (operands[0])
5073       || (GET_CODE (operands[0]) == SUBREG
5074	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5075  [(const_int 0)]
5076{
5077  rtx op1 = operands[1];
5078
5079  operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5080				     <MODE>mode, 0);
5081  if (GET_CODE (op1) == SUBREG)
5082    op1 = SUBREG_REG (op1);
5083
5084  if (GENERAL_REG_P (op1))
5085    {
5086      operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5087      if (TARGET_INTER_UNIT_MOVES)
5088	emit_insn (gen_sse2_loadld (operands[4],
5089				    CONST0_RTX (V4SImode), operands[1]));
5090      else
5091	{
5092	  operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5093					      operands[1]);
5094	  emit_insn (gen_sse2_loadld (operands[4],
5095				      CONST0_RTX (V4SImode), operands[5]));
5096	  ix86_free_from_memory (GET_MODE (operands[1]));
5097	}
5098    }
5099  /* We can ignore possible trapping value in the
5100     high part of SSE register for non-trapping math. */
5101  else if (SSE_REG_P (op1) && !flag_trapping_math)
5102    operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5103  else
5104    gcc_unreachable ();
5105  if (<ssevecmode>mode == V4SFmode)
5106    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5107  else
5108    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5109  DONE;
5110})
5111
5112(define_split
5113  [(set (match_operand:MODEF 0 "register_operand" "")
5114	(float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5115  "TARGET_SSE2 && TARGET_SSE_MATH
5116   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5117   && reload_completed
5118   && (SSE_REG_P (operands[0])
5119       || (GET_CODE (operands[0]) == SUBREG
5120	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5121  [(const_int 0)]
5122{
5123  operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5124				     <MODE>mode, 0);
5125  operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5126
5127  emit_insn (gen_sse2_loadld (operands[4],
5128			      CONST0_RTX (V4SImode), operands[1]));
5129  if (<ssevecmode>mode == V4SFmode)
5130    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5131  else
5132    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5133  DONE;
5134})
5135
5136(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5137  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5138	(float:MODEF
5139	  (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5140  (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5141  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5142   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5143  "#"
5144  [(set_attr "type" "sseicvt")
5145   (set_attr "mode" "<MODEF:MODE>")
5146   (set_attr "athlon_decode" "double,direct")
5147   (set_attr "amdfam10_decode" "vector,double")
5148   (set_attr "bdver1_decode" "double,direct")
5149   (set_attr "fp_int_src" "true")])
5150
5151(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5152  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5153	(float:MODEF
5154	  (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5155  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5156   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5157   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5158  "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5159  [(set_attr "type" "sseicvt")
5160   (set_attr "prefix" "maybe_vex")
5161   (set_attr "mode" "<MODEF:MODE>")
5162   (set (attr "prefix_rex")
5163     (if_then_else
5164       (and (eq_attr "prefix" "maybe_vex")
5165	    (match_test "<SWI48x:MODE>mode == DImode"))
5166       (const_string "1")
5167       (const_string "*")))
5168   (set_attr "athlon_decode" "double,direct")
5169   (set_attr "amdfam10_decode" "vector,double")
5170   (set_attr "bdver1_decode" "double,direct")
5171   (set_attr "fp_int_src" "true")])
5172
5173(define_split
5174  [(set (match_operand:MODEF 0 "register_operand" "")
5175	(float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5176   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5177  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5178   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5179   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5180   && reload_completed
5181   && (SSE_REG_P (operands[0])
5182       || (GET_CODE (operands[0]) == SUBREG
5183	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5184  [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5185
5186(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5187  [(set (match_operand:MODEF 0 "register_operand" "=x")
5188	(float:MODEF
5189	  (match_operand:SWI48x 1 "memory_operand" "m")))]
5190  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5191   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5192   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5193  "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5194  [(set_attr "type" "sseicvt")
5195   (set_attr "prefix" "maybe_vex")
5196   (set_attr "mode" "<MODEF:MODE>")
5197   (set (attr "prefix_rex")
5198     (if_then_else
5199       (and (eq_attr "prefix" "maybe_vex")
5200	    (match_test "<SWI48x:MODE>mode == DImode"))
5201       (const_string "1")
5202       (const_string "*")))
5203   (set_attr "athlon_decode" "direct")
5204   (set_attr "amdfam10_decode" "double")
5205   (set_attr "bdver1_decode" "direct")
5206   (set_attr "fp_int_src" "true")])
5207
5208(define_split
5209  [(set (match_operand:MODEF 0 "register_operand" "")
5210	(float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5211   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5212  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5213   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5214   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5215   && reload_completed
5216   && (SSE_REG_P (operands[0])
5217       || (GET_CODE (operands[0]) == SUBREG
5218	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5219  [(set (match_dup 2) (match_dup 1))
5220   (set (match_dup 0) (float:MODEF (match_dup 2)))])
5221
5222(define_split
5223  [(set (match_operand:MODEF 0 "register_operand" "")
5224	(float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5225   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5226  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5227   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5228   && reload_completed
5229   && (SSE_REG_P (operands[0])
5230       || (GET_CODE (operands[0]) == SUBREG
5231	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5232  [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5233
5234(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5235  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5236	(float:X87MODEF
5237	  (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5238  (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5239  "TARGET_80387
5240   && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5241  "@
5242   fild%Z1\t%1
5243   #"
5244  [(set_attr "type" "fmov,multi")
5245   (set_attr "mode" "<X87MODEF:MODE>")
5246   (set_attr "unit" "*,i387")
5247   (set_attr "fp_int_src" "true")])
5248
5249(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5250  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5251	(float:X87MODEF
5252	  (match_operand:SWI48x 1 "memory_operand" "m")))]
5253  "TARGET_80387
5254   && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5255  "fild%Z1\t%1"
5256  [(set_attr "type" "fmov")
5257   (set_attr "mode" "<X87MODEF:MODE>")
5258   (set_attr "fp_int_src" "true")])
5259
5260(define_split
5261  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5262	(float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5263   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5264  "TARGET_80387
5265   && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5266   && reload_completed"
5267  [(set (match_dup 2) (match_dup 1))
5268   (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5269
5270(define_split
5271  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5272	(float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5273   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5274  "TARGET_80387
5275   && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5276   && reload_completed"
5277  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5278
5279;; Avoid store forwarding (partial memory) stall penalty
5280;; by passing DImode value through XMM registers.  */
5281
5282(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5283  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5284	(float:X87MODEF
5285	  (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5286   (clobber (match_scratch:V4SI 3 "=X,x"))
5287   (clobber (match_scratch:V4SI 4 "=X,x"))
5288   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5289  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5290   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5291   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5292  "#"
5293  [(set_attr "type" "multi")
5294   (set_attr "mode" "<X87MODEF:MODE>")
5295   (set_attr "unit" "i387")
5296   (set_attr "fp_int_src" "true")])
5297
5298(define_split
5299  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5300	(float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5301   (clobber (match_scratch:V4SI 3 ""))
5302   (clobber (match_scratch:V4SI 4 ""))
5303   (clobber (match_operand:DI 2 "memory_operand" ""))]
5304  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5306   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5307   && reload_completed"
5308  [(set (match_dup 2) (match_dup 3))
5309   (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5310{
5311  /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5312     Assemble the 64-bit DImode value in an xmm register.  */
5313  emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5314			      gen_rtx_SUBREG (SImode, operands[1], 0)));
5315  emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5316			      gen_rtx_SUBREG (SImode, operands[1], 4)));
5317  emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5318  	    				 operands[4]));
5319
5320  operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5321})
5322
5323(define_split
5324  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5325	(float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5326   (clobber (match_scratch:V4SI 3 ""))
5327   (clobber (match_scratch:V4SI 4 ""))
5328   (clobber (match_operand:DI 2 "memory_operand" ""))]
5329  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5330   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5331   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5332   && reload_completed"
5333  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5334
5335;; Avoid store forwarding (partial memory) stall penalty by extending
5336;; SImode value to DImode through XMM register instead of pushing two
5337;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5338;; targets benefit from this optimization. Also note that fild
5339;; loads from memory only.
5340
5341(define_insn "*floatunssi<mode>2_1"
5342  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5343	(unsigned_float:X87MODEF
5344	  (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5345   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5346   (clobber (match_scratch:SI 3 "=X,x"))]
5347  "!TARGET_64BIT
5348   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5349   && TARGET_SSE"
5350  "#"
5351  [(set_attr "type" "multi")
5352   (set_attr "mode" "<MODE>")])
5353
5354(define_split
5355  [(set (match_operand:X87MODEF 0 "register_operand" "")
5356	(unsigned_float:X87MODEF
5357	  (match_operand:SI 1 "register_operand" "")))
5358   (clobber (match_operand:DI 2 "memory_operand" ""))
5359   (clobber (match_scratch:SI 3 ""))]
5360  "!TARGET_64BIT
5361   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5362   && TARGET_SSE
5363   && reload_completed"
5364  [(set (match_dup 2) (match_dup 1))
5365   (set (match_dup 0)
5366	(float:X87MODEF (match_dup 2)))]
5367  "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5368
5369(define_split
5370  [(set (match_operand:X87MODEF 0 "register_operand" "")
5371	(unsigned_float:X87MODEF
5372	  (match_operand:SI 1 "memory_operand" "")))
5373   (clobber (match_operand:DI 2 "memory_operand" ""))
5374   (clobber (match_scratch:SI 3 ""))]
5375  "!TARGET_64BIT
5376   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5377   && TARGET_SSE
5378   && reload_completed"
5379  [(set (match_dup 2) (match_dup 3))
5380   (set (match_dup 0)
5381	(float:X87MODEF (match_dup 2)))]
5382{
5383  emit_move_insn (operands[3], operands[1]);
5384  operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5385})
5386
5387(define_expand "floatunssi<mode>2"
5388  [(parallel
5389     [(set (match_operand:X87MODEF 0 "register_operand" "")
5390	   (unsigned_float:X87MODEF
5391	     (match_operand:SI 1 "nonimmediate_operand" "")))
5392      (clobber (match_dup 2))
5393      (clobber (match_scratch:SI 3 ""))])]
5394  "!TARGET_64BIT
5395   && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5396	&& TARGET_SSE)
5397       || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5398{
5399  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5400    {
5401      ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5402      DONE;
5403    }
5404  else
5405    operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5406})
5407
5408(define_expand "floatunsdisf2"
5409  [(use (match_operand:SF 0 "register_operand" ""))
5410   (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5411  "TARGET_64BIT && TARGET_SSE_MATH"
5412  "x86_emit_floatuns (operands); DONE;")
5413
5414(define_expand "floatunsdidf2"
5415  [(use (match_operand:DF 0 "register_operand" ""))
5416   (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5417  "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5418   && TARGET_SSE2 && TARGET_SSE_MATH"
5419{
5420  if (TARGET_64BIT)
5421    x86_emit_floatuns (operands);
5422  else
5423    ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5424  DONE;
5425})
5426
5427;; Load effective address instructions
5428
5429(define_insn_and_split "*lea<mode>"
5430  [(set (match_operand:SWI48 0 "register_operand" "=r")
5431	(match_operand:SWI48 1 "lea_address_operand" "p"))]
5432  ""
5433{
5434  rtx addr = operands[1];
5435
5436  if (SImode_address_operand (addr, VOIDmode))
5437    {
5438      gcc_assert (TARGET_64BIT);
5439      return "lea{l}\t{%E1, %k0|%k0, %E1}";
5440    }
5441  else
5442    return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5443}
5444  "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5445  [(const_int 0)]
5446{
5447  ix86_split_lea_for_addr (operands, <MODE>mode);
5448  DONE;
5449}
5450  [(set_attr "type" "lea")
5451   (set (attr "mode")
5452     (if_then_else
5453       (match_operand 1 "SImode_address_operand")
5454       (const_string "SI")
5455       (const_string "<MODE>")))])
5456
5457;; Add instructions
5458
5459(define_expand "add<mode>3"
5460  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5461	(plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5462		    (match_operand:SDWIM 2 "<general_operand>" "")))]
5463  ""
5464  "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5465
5466(define_insn_and_split "*add<dwi>3_doubleword"
5467  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5468	(plus:<DWI>
5469	  (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5470	  (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5471   (clobber (reg:CC FLAGS_REG))]
5472  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5473  "#"
5474  "reload_completed"
5475  [(parallel [(set (reg:CC FLAGS_REG)
5476		   (unspec:CC [(match_dup 1) (match_dup 2)]
5477			      UNSPEC_ADD_CARRY))
5478	      (set (match_dup 0)
5479		   (plus:DWIH (match_dup 1) (match_dup 2)))])
5480   (parallel [(set (match_dup 3)
5481		   (plus:DWIH
5482		     (match_dup 4)
5483		     (plus:DWIH
5484		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5485		       (match_dup 5))))
5486	      (clobber (reg:CC FLAGS_REG))])]
5487  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5488
5489(define_insn "*add<mode>3_cc"
5490  [(set (reg:CC FLAGS_REG)
5491	(unspec:CC
5492	  [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5493	   (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5494	  UNSPEC_ADD_CARRY))
5495   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5496	(plus:SWI48 (match_dup 1) (match_dup 2)))]
5497  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5498  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5499  [(set_attr "type" "alu")
5500   (set_attr "mode" "<MODE>")])
5501
5502(define_insn "addqi3_cc"
5503  [(set (reg:CC FLAGS_REG)
5504	(unspec:CC
5505	  [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5506	   (match_operand:QI 2 "general_operand" "qn,qm")]
5507	  UNSPEC_ADD_CARRY))
5508   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5509	(plus:QI (match_dup 1) (match_dup 2)))]
5510  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5511  "add{b}\t{%2, %0|%0, %2}"
5512  [(set_attr "type" "alu")
5513   (set_attr "mode" "QI")])
5514
5515(define_insn "*add<mode>_1"
5516  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5517	(plus:SWI48
5518	  (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5519	  (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5520   (clobber (reg:CC FLAGS_REG))]
5521  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5522{
5523  switch (get_attr_type (insn))
5524    {
5525    case TYPE_LEA:
5526      return "#";
5527
5528    case TYPE_INCDEC:
5529      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530      if (operands[2] == const1_rtx)
5531        return "inc{<imodesuffix>}\t%0";
5532      else
5533        {
5534	  gcc_assert (operands[2] == constm1_rtx);
5535          return "dec{<imodesuffix>}\t%0";
5536	}
5537
5538    default:
5539      /* For most processors, ADD is faster than LEA.  This alternative
5540	 was added to use ADD as much as possible.  */
5541      if (which_alternative == 2)
5542	{
5543	  rtx tmp;
5544	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5545	}
5546
5547      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5548      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5549        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5550
5551      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5552    }
5553}
5554  [(set (attr "type")
5555     (cond [(eq_attr "alternative" "3")
5556              (const_string "lea")
5557	    (match_operand:SWI48 2 "incdec_operand" "")
5558	      (const_string "incdec")
5559	   ]
5560	   (const_string "alu")))
5561   (set (attr "length_immediate")
5562      (if_then_else
5563	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5564	(const_string "1")
5565	(const_string "*")))
5566   (set_attr "mode" "<MODE>")])
5567
5568;; It may seem that nonimmediate operand is proper one for operand 1.
5569;; The addsi_1 pattern allows nonimmediate operand at that place and
5570;; we take care in ix86_binary_operator_ok to not allow two memory
5571;; operands so proper swapping will be done in reload.  This allow
5572;; patterns constructed from addsi_1 to match.
5573
5574(define_insn "addsi_1_zext"
5575  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5576	(zero_extend:DI
5577	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5578		   (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5579   (clobber (reg:CC FLAGS_REG))]
5580  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5581{
5582  switch (get_attr_type (insn))
5583    {
5584    case TYPE_LEA:
5585      return "#";
5586
5587    case TYPE_INCDEC:
5588      if (operands[2] == const1_rtx)
5589        return "inc{l}\t%k0";
5590      else
5591        {
5592	  gcc_assert (operands[2] == constm1_rtx);
5593          return "dec{l}\t%k0";
5594	}
5595
5596    default:
5597      /* For most processors, ADD is faster than LEA.  This alternative
5598	 was added to use ADD as much as possible.  */
5599      if (which_alternative == 1)
5600	{
5601	  rtx tmp;
5602	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5603	}
5604
5605      if (x86_maybe_negate_const_int (&operands[2], SImode))
5606        return "sub{l}\t{%2, %k0|%k0, %2}";
5607
5608      return "add{l}\t{%2, %k0|%k0, %2}";
5609    }
5610}
5611  [(set (attr "type")
5612     (cond [(eq_attr "alternative" "2")
5613	      (const_string "lea")
5614	    (match_operand:SI 2 "incdec_operand" "")
5615	      (const_string "incdec")
5616	   ]
5617	   (const_string "alu")))
5618   (set (attr "length_immediate")
5619      (if_then_else
5620	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5621	(const_string "1")
5622	(const_string "*")))
5623   (set_attr "mode" "SI")])
5624
5625(define_insn "*addhi_1"
5626  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5627	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5628		 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5629   (clobber (reg:CC FLAGS_REG))]
5630  "ix86_binary_operator_ok (PLUS, HImode, operands)"
5631{
5632  switch (get_attr_type (insn))
5633    {
5634    case TYPE_LEA:
5635      return "#";
5636
5637    case TYPE_INCDEC:
5638      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639      if (operands[2] == const1_rtx)
5640	return "inc{w}\t%0";
5641      else
5642	{
5643	  gcc_assert (operands[2] == constm1_rtx);
5644	  return "dec{w}\t%0";
5645	}
5646
5647    default:
5648      /* For most processors, ADD is faster than LEA.  This alternative
5649	 was added to use ADD as much as possible.  */
5650      if (which_alternative == 2)
5651	{
5652	  rtx tmp;
5653	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5654	}
5655
5656      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5657      if (x86_maybe_negate_const_int (&operands[2], HImode))
5658	return "sub{w}\t{%2, %0|%0, %2}";
5659
5660      return "add{w}\t{%2, %0|%0, %2}";
5661    }
5662}
5663  [(set (attr "type")
5664     (cond [(eq_attr "alternative" "3")
5665              (const_string "lea")
5666	    (match_operand:HI 2 "incdec_operand" "")
5667	      (const_string "incdec")
5668	   ]
5669	   (const_string "alu")))
5670   (set (attr "length_immediate")
5671      (if_then_else
5672	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5673	(const_string "1")
5674	(const_string "*")))
5675   (set_attr "mode" "HI,HI,HI,SI")])
5676
5677;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5678(define_insn "*addqi_1"
5679  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5680	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5681		 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5682   (clobber (reg:CC FLAGS_REG))]
5683  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5684{
5685  bool widen = (which_alternative == 3 || which_alternative == 4);
5686
5687  switch (get_attr_type (insn))
5688    {
5689    case TYPE_LEA:
5690      return "#";
5691
5692    case TYPE_INCDEC:
5693      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5694      if (operands[2] == const1_rtx)
5695	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5696      else
5697	{
5698	  gcc_assert (operands[2] == constm1_rtx);
5699	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5700	}
5701
5702    default:
5703      /* For most processors, ADD is faster than LEA.  These alternatives
5704	 were added to use ADD as much as possible.  */
5705      if (which_alternative == 2 || which_alternative == 4)
5706	{
5707	  rtx tmp;
5708	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5709	}
5710
5711      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5712      if (x86_maybe_negate_const_int (&operands[2], QImode))
5713	{
5714	  if (widen)
5715	    return "sub{l}\t{%2, %k0|%k0, %2}";
5716	  else
5717	    return "sub{b}\t{%2, %0|%0, %2}";
5718	}
5719      if (widen)
5720        return "add{l}\t{%k2, %k0|%k0, %k2}";
5721      else
5722        return "add{b}\t{%2, %0|%0, %2}";
5723    }
5724}
5725  [(set (attr "type")
5726     (cond [(eq_attr "alternative" "5")
5727              (const_string "lea")
5728	    (match_operand:QI 2 "incdec_operand" "")
5729	      (const_string "incdec")
5730	   ]
5731	   (const_string "alu")))
5732   (set (attr "length_immediate")
5733      (if_then_else
5734	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5735	(const_string "1")
5736	(const_string "*")))
5737   (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5738
5739(define_insn "*addqi_1_slp"
5740  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5741	(plus:QI (match_dup 0)
5742		 (match_operand:QI 1 "general_operand" "qn,qm")))
5743   (clobber (reg:CC FLAGS_REG))]
5744  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5745   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5746{
5747  switch (get_attr_type (insn))
5748    {
5749    case TYPE_INCDEC:
5750      if (operands[1] == const1_rtx)
5751	return "inc{b}\t%0";
5752      else
5753	{
5754	  gcc_assert (operands[1] == constm1_rtx);
5755	  return "dec{b}\t%0";
5756	}
5757
5758    default:
5759      if (x86_maybe_negate_const_int (&operands[1], QImode))
5760	return "sub{b}\t{%1, %0|%0, %1}";
5761
5762      return "add{b}\t{%1, %0|%0, %1}";
5763    }
5764}
5765  [(set (attr "type")
5766     (if_then_else (match_operand:QI 1 "incdec_operand" "")
5767	(const_string "incdec")
5768	(const_string "alu1")))
5769   (set (attr "memory")
5770     (if_then_else (match_operand 1 "memory_operand" "")
5771        (const_string "load")
5772        (const_string "none")))
5773   (set_attr "mode" "QI")])
5774
5775;; Split non destructive adds if we cannot use lea.
5776(define_split
5777  [(set (match_operand:SWI48 0 "register_operand" "")
5778	(plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5779              (match_operand:SWI48 2 "nonmemory_operand" "")))
5780   (clobber (reg:CC FLAGS_REG))]
5781  "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5782  [(set (match_dup 0) (match_dup 1))
5783   (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5784	      (clobber (reg:CC FLAGS_REG))])])
5785
5786;; Convert add to the lea pattern to avoid flags dependency.
5787(define_split
5788  [(set (match_operand:SWI 0 "register_operand" "")
5789	(plus:SWI (match_operand:SWI 1 "register_operand" "")
5790		  (match_operand:SWI 2 "<nonmemory_operand>" "")))
5791   (clobber (reg:CC FLAGS_REG))]
5792  "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5793  [(const_int 0)]
5794{
5795  enum machine_mode mode = <MODE>mode;
5796  rtx pat;
5797
5798  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5799    {
5800      mode = SImode;
5801      operands[0] = gen_lowpart (mode, operands[0]);
5802      operands[1] = gen_lowpart (mode, operands[1]);
5803      operands[2] = gen_lowpart (mode, operands[2]);
5804    }
5805
5806  pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5807
5808  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5809  DONE;
5810})
5811
5812;; Convert add to the lea pattern to avoid flags dependency.
5813(define_split
5814  [(set (match_operand:DI 0 "register_operand" "")
5815	(zero_extend:DI
5816	  (plus:SI (match_operand:SI 1 "register_operand" "")
5817		   (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5818   (clobber (reg:CC FLAGS_REG))]
5819  "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5820  [(set (match_dup 0)
5821	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5822
5823(define_insn "*add<mode>_2"
5824  [(set (reg FLAGS_REG)
5825	(compare
5826	  (plus:SWI
5827	    (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5828	    (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5829	  (const_int 0)))
5830   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5831	(plus:SWI (match_dup 1) (match_dup 2)))]
5832  "ix86_match_ccmode (insn, CCGOCmode)
5833   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5834{
5835  switch (get_attr_type (insn))
5836    {
5837    case TYPE_INCDEC:
5838      if (operands[2] == const1_rtx)
5839        return "inc{<imodesuffix>}\t%0";
5840      else
5841        {
5842	  gcc_assert (operands[2] == constm1_rtx);
5843          return "dec{<imodesuffix>}\t%0";
5844	}
5845
5846    default:
5847      if (which_alternative == 2)
5848	{
5849	  rtx tmp;
5850	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5851	}
5852
5853      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5854      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5855        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5856
5857      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5858    }
5859}
5860  [(set (attr "type")
5861     (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5862	(const_string "incdec")
5863	(const_string "alu")))
5864   (set (attr "length_immediate")
5865      (if_then_else
5866	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5867	(const_string "1")
5868	(const_string "*")))
5869   (set_attr "mode" "<MODE>")])
5870
5871;; See comment for addsi_1_zext why we do use nonimmediate_operand
5872(define_insn "*addsi_2_zext"
5873  [(set (reg FLAGS_REG)
5874	(compare
5875	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5876		   (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5877	  (const_int 0)))
5878   (set (match_operand:DI 0 "register_operand" "=r,r")
5879	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5880  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5881   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5882{
5883  switch (get_attr_type (insn))
5884    {
5885    case TYPE_INCDEC:
5886      if (operands[2] == const1_rtx)
5887        return "inc{l}\t%k0";
5888      else
5889	{
5890	  gcc_assert (operands[2] == constm1_rtx);
5891          return "dec{l}\t%k0";
5892	}
5893
5894    default:
5895      if (which_alternative == 1)
5896	{
5897	  rtx tmp;
5898	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5899	}
5900
5901      if (x86_maybe_negate_const_int (&operands[2], SImode))
5902        return "sub{l}\t{%2, %k0|%k0, %2}";
5903
5904      return "add{l}\t{%2, %k0|%k0, %2}";
5905    }
5906}
5907  [(set (attr "type")
5908     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5909	(const_string "incdec")
5910	(const_string "alu")))
5911   (set (attr "length_immediate")
5912      (if_then_else
5913	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5914	(const_string "1")
5915	(const_string "*")))
5916   (set_attr "mode" "SI")])
5917
5918(define_insn "*add<mode>_3"
5919  [(set (reg FLAGS_REG)
5920	(compare
5921	  (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5922	  (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5923   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5924  "ix86_match_ccmode (insn, CCZmode)
5925   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5926{
5927  switch (get_attr_type (insn))
5928    {
5929    case TYPE_INCDEC:
5930      if (operands[2] == const1_rtx)
5931        return "inc{<imodesuffix>}\t%0";
5932      else
5933        {
5934	  gcc_assert (operands[2] == constm1_rtx);
5935          return "dec{<imodesuffix>}\t%0";
5936	}
5937
5938    default:
5939      if (which_alternative == 1)
5940	{
5941	  rtx tmp;
5942	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5943	}
5944
5945      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5946      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5947        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5948
5949      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5950    }
5951}
5952  [(set (attr "type")
5953     (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5954	(const_string "incdec")
5955	(const_string "alu")))
5956   (set (attr "length_immediate")
5957      (if_then_else
5958	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5959	(const_string "1")
5960	(const_string "*")))
5961   (set_attr "mode" "<MODE>")])
5962
5963;; See comment for addsi_1_zext why we do use nonimmediate_operand
5964(define_insn "*addsi_3_zext"
5965  [(set (reg FLAGS_REG)
5966	(compare
5967	  (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5968	  (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5969   (set (match_operand:DI 0 "register_operand" "=r,r")
5970	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5971  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5972   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5973{
5974  switch (get_attr_type (insn))
5975    {
5976    case TYPE_INCDEC:
5977      if (operands[2] == const1_rtx)
5978        return "inc{l}\t%k0";
5979      else
5980        {
5981	  gcc_assert (operands[2] == constm1_rtx);
5982          return "dec{l}\t%k0";
5983	}
5984
5985    default:
5986      if (which_alternative == 1)
5987	{
5988	  rtx tmp;
5989	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5990	}
5991
5992      if (x86_maybe_negate_const_int (&operands[2], SImode))
5993        return "sub{l}\t{%2, %k0|%k0, %2}";
5994
5995      return "add{l}\t{%2, %k0|%k0, %2}";
5996    }
5997}
5998  [(set (attr "type")
5999     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6000	(const_string "incdec")
6001	(const_string "alu")))
6002   (set (attr "length_immediate")
6003      (if_then_else
6004	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6005	(const_string "1")
6006	(const_string "*")))
6007   (set_attr "mode" "SI")])
6008
6009; For comparisons against 1, -1 and 128, we may generate better code
6010; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6011; is matched then.  We can't accept general immediate, because for
6012; case of overflows,  the result is messed up.
6013; Also carry flag is reversed compared to cmp, so this conversion is valid
6014; only for comparisons not depending on it.
6015
6016(define_insn "*adddi_4"
6017  [(set (reg FLAGS_REG)
6018	(compare
6019	  (match_operand:DI 1 "nonimmediate_operand" "0")
6020	  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6021   (clobber (match_scratch:DI 0 "=rm"))]
6022  "TARGET_64BIT
6023   && ix86_match_ccmode (insn, CCGCmode)"
6024{
6025  switch (get_attr_type (insn))
6026    {
6027    case TYPE_INCDEC:
6028      if (operands[2] == constm1_rtx)
6029        return "inc{q}\t%0";
6030      else
6031        {
6032	  gcc_assert (operands[2] == const1_rtx);
6033          return "dec{q}\t%0";
6034	}
6035
6036    default:
6037      if (x86_maybe_negate_const_int (&operands[2], DImode))
6038	return "add{q}\t{%2, %0|%0, %2}";
6039
6040      return "sub{q}\t{%2, %0|%0, %2}";
6041    }
6042}
6043  [(set (attr "type")
6044     (if_then_else (match_operand:DI 2 "incdec_operand" "")
6045	(const_string "incdec")
6046	(const_string "alu")))
6047   (set (attr "length_immediate")
6048      (if_then_else
6049	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6050	(const_string "1")
6051	(const_string "*")))
6052   (set_attr "mode" "DI")])
6053
6054; For comparisons against 1, -1 and 128, we may generate better code
6055; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6056; is matched then.  We can't accept general immediate, because for
6057; case of overflows,  the result is messed up.
6058; Also carry flag is reversed compared to cmp, so this conversion is valid
6059; only for comparisons not depending on it.
6060
6061(define_insn "*add<mode>_4"
6062  [(set (reg FLAGS_REG)
6063	(compare
6064	  (match_operand:SWI124 1 "nonimmediate_operand" "0")
6065	  (match_operand:SWI124 2 "const_int_operand" "n")))
6066   (clobber (match_scratch:SWI124 0 "=<r>m"))]
6067  "ix86_match_ccmode (insn, CCGCmode)"
6068{
6069  switch (get_attr_type (insn))
6070    {
6071    case TYPE_INCDEC:
6072      if (operands[2] == constm1_rtx)
6073        return "inc{<imodesuffix>}\t%0";
6074      else
6075        {
6076	  gcc_assert (operands[2] == const1_rtx);
6077          return "dec{<imodesuffix>}\t%0";
6078	}
6079
6080    default:
6081      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6082	return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6083
6084      return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6085    }
6086}
6087  [(set (attr "type")
6088     (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6089	(const_string "incdec")
6090	(const_string "alu")))
6091   (set (attr "length_immediate")
6092      (if_then_else
6093	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6094	(const_string "1")
6095	(const_string "*")))
6096   (set_attr "mode" "<MODE>")])
6097
6098(define_insn "*add<mode>_5"
6099  [(set (reg FLAGS_REG)
6100	(compare
6101	  (plus:SWI
6102	    (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6103	    (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6104	  (const_int 0)))
6105   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6106  "ix86_match_ccmode (insn, CCGOCmode)
6107   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6108{
6109  switch (get_attr_type (insn))
6110    {
6111    case TYPE_INCDEC:
6112      if (operands[2] == const1_rtx)
6113        return "inc{<imodesuffix>}\t%0";
6114      else
6115        {
6116          gcc_assert (operands[2] == constm1_rtx);
6117          return "dec{<imodesuffix>}\t%0";
6118	}
6119
6120    default:
6121      if (which_alternative == 1)
6122	{
6123	  rtx tmp;
6124	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6125	}
6126
6127      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6128      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6129        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6130
6131      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6132    }
6133}
6134  [(set (attr "type")
6135     (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6136	(const_string "incdec")
6137	(const_string "alu")))
6138   (set (attr "length_immediate")
6139      (if_then_else
6140	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6141	(const_string "1")
6142	(const_string "*")))
6143   (set_attr "mode" "<MODE>")])
6144
6145(define_insn "*addqi_ext_1_rex64"
6146  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6147			 (const_int 8)
6148			 (const_int 8))
6149	(plus:SI
6150	  (zero_extract:SI
6151	    (match_operand 1 "ext_register_operand" "0")
6152	    (const_int 8)
6153	    (const_int 8))
6154	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6155   (clobber (reg:CC FLAGS_REG))]
6156  "TARGET_64BIT"
6157{
6158  switch (get_attr_type (insn))
6159    {
6160    case TYPE_INCDEC:
6161      if (operands[2] == const1_rtx)
6162	return "inc{b}\t%h0";
6163      else
6164        {
6165	  gcc_assert (operands[2] == constm1_rtx);
6166          return "dec{b}\t%h0";
6167        }
6168
6169    default:
6170      return "add{b}\t{%2, %h0|%h0, %2}";
6171    }
6172}
6173  [(set (attr "type")
6174     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6175	(const_string "incdec")
6176	(const_string "alu")))
6177   (set_attr "modrm" "1")
6178   (set_attr "mode" "QI")])
6179
6180(define_insn "addqi_ext_1"
6181  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6182			 (const_int 8)
6183			 (const_int 8))
6184	(plus:SI
6185	  (zero_extract:SI
6186	    (match_operand 1 "ext_register_operand" "0")
6187	    (const_int 8)
6188	    (const_int 8))
6189	  (match_operand:QI 2 "general_operand" "Qmn")))
6190   (clobber (reg:CC FLAGS_REG))]
6191  "!TARGET_64BIT"
6192{
6193  switch (get_attr_type (insn))
6194    {
6195    case TYPE_INCDEC:
6196      if (operands[2] == const1_rtx)
6197	return "inc{b}\t%h0";
6198      else
6199        {
6200	  gcc_assert (operands[2] == constm1_rtx);
6201          return "dec{b}\t%h0";
6202	}
6203
6204    default:
6205      return "add{b}\t{%2, %h0|%h0, %2}";
6206    }
6207}
6208  [(set (attr "type")
6209     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6210	(const_string "incdec")
6211	(const_string "alu")))
6212   (set_attr "modrm" "1")
6213   (set_attr "mode" "QI")])
6214
6215(define_insn "*addqi_ext_2"
6216  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6217			 (const_int 8)
6218			 (const_int 8))
6219	(plus:SI
6220	  (zero_extract:SI
6221	    (match_operand 1 "ext_register_operand" "%0")
6222	    (const_int 8)
6223	    (const_int 8))
6224	  (zero_extract:SI
6225	    (match_operand 2 "ext_register_operand" "Q")
6226	    (const_int 8)
6227	    (const_int 8))))
6228   (clobber (reg:CC FLAGS_REG))]
6229  ""
6230  "add{b}\t{%h2, %h0|%h0, %h2}"
6231  [(set_attr "type" "alu")
6232   (set_attr "mode" "QI")])
6233
6234;; The lea patterns for modes less than 32 bits need to be matched by
6235;; several insns converted to real lea by splitters.
6236
6237(define_insn_and_split "*lea_general_1"
6238  [(set (match_operand 0 "register_operand" "=r")
6239	(plus (plus (match_operand 1 "index_register_operand" "l")
6240		    (match_operand 2 "register_operand" "r"))
6241	      (match_operand 3 "immediate_operand" "i")))]
6242  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6243   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6244   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6245   && GET_MODE (operands[0]) == GET_MODE (operands[2])
6246   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6247       || GET_MODE (operands[3]) == VOIDmode)"
6248  "#"
6249  "&& reload_completed"
6250  [(const_int 0)]
6251{
6252  enum machine_mode mode = SImode;
6253  rtx pat;
6254
6255  operands[0] = gen_lowpart (mode, operands[0]);
6256  operands[1] = gen_lowpart (mode, operands[1]);
6257  operands[2] = gen_lowpart (mode, operands[2]);
6258  operands[3] = gen_lowpart (mode, operands[3]);
6259
6260  pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6261  		      operands[3]);
6262
6263  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6264  DONE;
6265}
6266  [(set_attr "type" "lea")
6267   (set_attr "mode" "SI")])
6268
6269(define_insn_and_split "*lea_general_2"
6270  [(set (match_operand 0 "register_operand" "=r")
6271	(plus (mult (match_operand 1 "index_register_operand" "l")
6272		    (match_operand 2 "const248_operand" "n"))
6273	      (match_operand 3 "nonmemory_operand" "ri")))]
6274  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6275   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6276   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6277   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6278       || GET_MODE (operands[3]) == VOIDmode)"
6279  "#"
6280  "&& reload_completed"
6281  [(const_int 0)]
6282{
6283  enum machine_mode mode = SImode;
6284  rtx pat;
6285
6286  operands[0] = gen_lowpart (mode, operands[0]);
6287  operands[1] = gen_lowpart (mode, operands[1]);
6288  operands[3] = gen_lowpart (mode, operands[3]);
6289
6290  pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6291		      operands[3]);
6292
6293  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6294  DONE;
6295}
6296  [(set_attr "type" "lea")
6297   (set_attr "mode" "SI")])
6298
6299(define_insn_and_split "*lea_general_3"
6300  [(set (match_operand 0 "register_operand" "=r")
6301	(plus (plus (mult (match_operand 1 "index_register_operand" "l")
6302			  (match_operand 2 "const248_operand" "n"))
6303		    (match_operand 3 "register_operand" "r"))
6304	      (match_operand 4 "immediate_operand" "i")))]
6305  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6306   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6307   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6308   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6309  "#"
6310  "&& reload_completed"
6311  [(const_int 0)]
6312{
6313  enum machine_mode mode = SImode;
6314  rtx pat;
6315
6316  operands[0] = gen_lowpart (mode, operands[0]);
6317  operands[1] = gen_lowpart (mode, operands[1]);
6318  operands[3] = gen_lowpart (mode, operands[3]);
6319  operands[4] = gen_lowpart (mode, operands[4]);
6320
6321  pat = gen_rtx_PLUS (mode,
6322  		      gen_rtx_PLUS (mode,
6323				    gen_rtx_MULT (mode, operands[1],
6324		      					operands[2]),
6325				    operands[3]),
6326  		      operands[4]);
6327
6328  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6329  DONE;
6330}
6331  [(set_attr "type" "lea")
6332   (set_attr "mode" "SI")])
6333
6334(define_insn_and_split "*lea_general_4"
6335  [(set (match_operand 0 "register_operand" "=r")
6336	(any_or (ashift
6337		  (match_operand 1 "index_register_operand" "l")
6338		  (match_operand 2 "const_int_operand" "n"))
6339		(match_operand 3 "const_int_operand" "n")))]
6340  "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6341      && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6342    || GET_MODE (operands[0]) == SImode
6343    || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6344   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6345   && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6346   && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6347       < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6348  "#"
6349  "&& reload_completed"
6350  [(const_int 0)]
6351{
6352  enum machine_mode mode = GET_MODE (operands[0]);
6353  rtx pat;
6354
6355  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6356    {
6357      mode = SImode;
6358      operands[0] = gen_lowpart (mode, operands[0]);
6359      operands[1] = gen_lowpart (mode, operands[1]);
6360    }
6361
6362  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6363
6364  pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6365		       INTVAL (operands[3]));
6366
6367  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6368  DONE;
6369}
6370  [(set_attr "type" "lea")
6371   (set (attr "mode")
6372      (if_then_else (match_operand:DI 0 "" "")
6373	(const_string "DI")
6374	(const_string "SI")))])
6375
6376;; Subtract instructions
6377
6378(define_expand "sub<mode>3"
6379  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6380	(minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6381		     (match_operand:SDWIM 2 "<general_operand>" "")))]
6382  ""
6383  "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6384
6385(define_insn_and_split "*sub<dwi>3_doubleword"
6386  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6387	(minus:<DWI>
6388	  (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6389	  (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6390   (clobber (reg:CC FLAGS_REG))]
6391  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6392  "#"
6393  "reload_completed"
6394  [(parallel [(set (reg:CC FLAGS_REG)
6395		   (compare:CC (match_dup 1) (match_dup 2)))
6396	      (set (match_dup 0)
6397		   (minus:DWIH (match_dup 1) (match_dup 2)))])
6398   (parallel [(set (match_dup 3)
6399		   (minus:DWIH
6400		     (match_dup 4)
6401		     (plus:DWIH
6402		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6403		       (match_dup 5))))
6404	      (clobber (reg:CC FLAGS_REG))])]
6405  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6406
6407(define_insn "*sub<mode>_1"
6408  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6409	(minus:SWI
6410	  (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6411	  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6412   (clobber (reg:CC FLAGS_REG))]
6413  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6414  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6415  [(set_attr "type" "alu")
6416   (set_attr "mode" "<MODE>")])
6417
6418(define_insn "*subsi_1_zext"
6419  [(set (match_operand:DI 0 "register_operand" "=r")
6420	(zero_extend:DI
6421	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6422		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6423   (clobber (reg:CC FLAGS_REG))]
6424  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6425  "sub{l}\t{%2, %k0|%k0, %2}"
6426  [(set_attr "type" "alu")
6427   (set_attr "mode" "SI")])
6428
6429(define_insn "*subqi_1_slp"
6430  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6431	(minus:QI (match_dup 0)
6432		  (match_operand:QI 1 "general_operand" "qn,qm")))
6433   (clobber (reg:CC FLAGS_REG))]
6434  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6435   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6436  "sub{b}\t{%1, %0|%0, %1}"
6437  [(set_attr "type" "alu1")
6438   (set_attr "mode" "QI")])
6439
6440(define_insn "*sub<mode>_2"
6441  [(set (reg FLAGS_REG)
6442	(compare
6443	  (minus:SWI
6444	    (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6445	    (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6446	  (const_int 0)))
6447   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6448	(minus:SWI (match_dup 1) (match_dup 2)))]
6449  "ix86_match_ccmode (insn, CCGOCmode)
6450   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6451  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6452  [(set_attr "type" "alu")
6453   (set_attr "mode" "<MODE>")])
6454
6455(define_insn "*subsi_2_zext"
6456  [(set (reg FLAGS_REG)
6457	(compare
6458	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6459		    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6460	  (const_int 0)))
6461   (set (match_operand:DI 0 "register_operand" "=r")
6462	(zero_extend:DI
6463	  (minus:SI (match_dup 1)
6464		    (match_dup 2))))]
6465  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6466   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6467  "sub{l}\t{%2, %k0|%k0, %2}"
6468  [(set_attr "type" "alu")
6469   (set_attr "mode" "SI")])
6470
6471(define_insn "*sub<mode>_3"
6472  [(set (reg FLAGS_REG)
6473	(compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6474		 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6475   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6476	(minus:SWI (match_dup 1) (match_dup 2)))]
6477  "ix86_match_ccmode (insn, CCmode)
6478   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6479  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6480  [(set_attr "type" "alu")
6481   (set_attr "mode" "<MODE>")])
6482
6483(define_insn "*subsi_3_zext"
6484  [(set (reg FLAGS_REG)
6485	(compare (match_operand:SI 1 "register_operand" "0")
6486		 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6487   (set (match_operand:DI 0 "register_operand" "=r")
6488	(zero_extend:DI
6489	  (minus:SI (match_dup 1)
6490		    (match_dup 2))))]
6491  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6492   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6493  "sub{l}\t{%2, %1|%1, %2}"
6494  [(set_attr "type" "alu")
6495   (set_attr "mode" "SI")])
6496
6497;; Add with carry and subtract with borrow
6498
6499(define_expand "<plusminus_insn><mode>3_carry"
6500  [(parallel
6501    [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6502	  (plusminus:SWI
6503	    (match_operand:SWI 1 "nonimmediate_operand" "")
6504	    (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6505		       [(match_operand 3 "flags_reg_operand" "")
6506			(const_int 0)])
6507		      (match_operand:SWI 2 "<general_operand>" ""))))
6508     (clobber (reg:CC FLAGS_REG))])]
6509  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6510
6511(define_insn "*<plusminus_insn><mode>3_carry"
6512  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6513	(plusminus:SWI
6514	  (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6515	  (plus:SWI
6516	    (match_operator 3 "ix86_carry_flag_operator"
6517	     [(reg FLAGS_REG) (const_int 0)])
6518	    (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6519   (clobber (reg:CC FLAGS_REG))]
6520  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6521  "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6522  [(set_attr "type" "alu")
6523   (set_attr "use_carry" "1")
6524   (set_attr "pent_pair" "pu")
6525   (set_attr "mode" "<MODE>")])
6526
6527(define_insn "*addsi3_carry_zext"
6528  [(set (match_operand:DI 0 "register_operand" "=r")
6529	(zero_extend:DI
6530	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6531		   (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6532			     [(reg FLAGS_REG) (const_int 0)])
6533			    (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6534   (clobber (reg:CC FLAGS_REG))]
6535  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6536  "adc{l}\t{%2, %k0|%k0, %2}"
6537  [(set_attr "type" "alu")
6538   (set_attr "use_carry" "1")
6539   (set_attr "pent_pair" "pu")
6540   (set_attr "mode" "SI")])
6541
6542(define_insn "*subsi3_carry_zext"
6543  [(set (match_operand:DI 0 "register_operand" "=r")
6544	(zero_extend:DI
6545	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6546		    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6547			      [(reg FLAGS_REG) (const_int 0)])
6548			     (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6549   (clobber (reg:CC FLAGS_REG))]
6550  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6551  "sbb{l}\t{%2, %k0|%k0, %2}"
6552  [(set_attr "type" "alu")
6553   (set_attr "pent_pair" "pu")
6554   (set_attr "mode" "SI")])
6555
6556;; Overflow setting add and subtract instructions
6557
6558(define_insn "*add<mode>3_cconly_overflow"
6559  [(set (reg:CCC FLAGS_REG)
6560	(compare:CCC
6561	  (plus:SWI
6562	    (match_operand:SWI 1 "nonimmediate_operand" "%0")
6563	    (match_operand:SWI 2 "<general_operand>" "<g>"))
6564	  (match_dup 1)))
6565   (clobber (match_scratch:SWI 0 "=<r>"))]
6566  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6567  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6568  [(set_attr "type" "alu")
6569   (set_attr "mode" "<MODE>")])
6570
6571(define_insn "*sub<mode>3_cconly_overflow"
6572  [(set (reg:CCC FLAGS_REG)
6573	(compare:CCC
6574	  (minus:SWI
6575	    (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6576	    (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6577	  (match_dup 0)))]
6578  ""
6579  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6580  [(set_attr "type" "icmp")
6581   (set_attr "mode" "<MODE>")])
6582
6583(define_insn "*<plusminus_insn><mode>3_cc_overflow"
6584  [(set (reg:CCC FLAGS_REG)
6585	(compare:CCC
6586	    (plusminus:SWI
6587		(match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6588		(match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6589	    (match_dup 1)))
6590   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6591	(plusminus:SWI (match_dup 1) (match_dup 2)))]
6592  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6593  "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6594  [(set_attr "type" "alu")
6595   (set_attr "mode" "<MODE>")])
6596
6597(define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6598  [(set (reg:CCC FLAGS_REG)
6599	(compare:CCC
6600	  (plusminus:SI
6601	    (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6602	    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6603	  (match_dup 1)))
6604   (set (match_operand:DI 0 "register_operand" "=r")
6605	(zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6606  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6607  "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6608  [(set_attr "type" "alu")
6609   (set_attr "mode" "SI")])
6610
6611;; The patterns that match these are at the end of this file.
6612
6613(define_expand "<plusminus_insn>xf3"
6614  [(set (match_operand:XF 0 "register_operand" "")
6615	(plusminus:XF
6616	  (match_operand:XF 1 "register_operand" "")
6617	  (match_operand:XF 2 "register_operand" "")))]
6618  "TARGET_80387")
6619
6620(define_expand "<plusminus_insn><mode>3"
6621  [(set (match_operand:MODEF 0 "register_operand" "")
6622	(plusminus:MODEF
6623	  (match_operand:MODEF 1 "register_operand" "")
6624	  (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6625  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6626    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6627
6628;; Multiply instructions
6629
6630(define_expand "mul<mode>3"
6631  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6632		   (mult:SWIM248
6633		     (match_operand:SWIM248 1 "register_operand" "")
6634		     (match_operand:SWIM248 2 "<general_operand>" "")))
6635	      (clobber (reg:CC FLAGS_REG))])])
6636
6637(define_expand "mulqi3"
6638  [(parallel [(set (match_operand:QI 0 "register_operand" "")
6639		   (mult:QI
6640		     (match_operand:QI 1 "register_operand" "")
6641		     (match_operand:QI 2 "nonimmediate_operand" "")))
6642	      (clobber (reg:CC FLAGS_REG))])]
6643  "TARGET_QIMODE_MATH")
6644
6645;; On AMDFAM10
6646;; IMUL reg32/64, reg32/64, imm8 	Direct
6647;; IMUL reg32/64, mem32/64, imm8 	VectorPath
6648;; IMUL reg32/64, reg32/64, imm32 	Direct
6649;; IMUL reg32/64, mem32/64, imm32 	VectorPath
6650;; IMUL reg32/64, reg32/64 		Direct
6651;; IMUL reg32/64, mem32/64 		Direct
6652;;
6653;; On BDVER1, all above IMULs use DirectPath
6654
6655(define_insn "*mul<mode>3_1"
6656  [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6657	(mult:SWI48
6658	  (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6659	  (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6660   (clobber (reg:CC FLAGS_REG))]
6661  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6662  "@
6663   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6664   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6665   imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6666  [(set_attr "type" "imul")
6667   (set_attr "prefix_0f" "0,0,1")
6668   (set (attr "athlon_decode")
6669	(cond [(eq_attr "cpu" "athlon")
6670		  (const_string "vector")
6671	       (eq_attr "alternative" "1")
6672		  (const_string "vector")
6673	       (and (eq_attr "alternative" "2")
6674		    (match_operand 1 "memory_operand" ""))
6675		  (const_string "vector")]
6676	      (const_string "direct")))
6677   (set (attr "amdfam10_decode")
6678	(cond [(and (eq_attr "alternative" "0,1")
6679		    (match_operand 1 "memory_operand" ""))
6680		  (const_string "vector")]
6681	      (const_string "direct")))
6682   (set_attr "bdver1_decode" "direct")
6683   (set_attr "mode" "<MODE>")])
6684
6685(define_insn "*mulsi3_1_zext"
6686  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6687	(zero_extend:DI
6688	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6689		   (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6690   (clobber (reg:CC FLAGS_REG))]
6691  "TARGET_64BIT
6692   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6693  "@
6694   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6695   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6696   imul{l}\t{%2, %k0|%k0, %2}"
6697  [(set_attr "type" "imul")
6698   (set_attr "prefix_0f" "0,0,1")
6699   (set (attr "athlon_decode")
6700	(cond [(eq_attr "cpu" "athlon")
6701		  (const_string "vector")
6702	       (eq_attr "alternative" "1")
6703		  (const_string "vector")
6704	       (and (eq_attr "alternative" "2")
6705		    (match_operand 1 "memory_operand" ""))
6706		  (const_string "vector")]
6707	      (const_string "direct")))
6708   (set (attr "amdfam10_decode")
6709	(cond [(and (eq_attr "alternative" "0,1")
6710		    (match_operand 1 "memory_operand" ""))
6711		  (const_string "vector")]
6712	      (const_string "direct")))
6713   (set_attr "bdver1_decode" "direct")
6714   (set_attr "mode" "SI")])
6715
6716;; On AMDFAM10
6717;; IMUL reg16, reg16, imm8 	VectorPath
6718;; IMUL reg16, mem16, imm8 	VectorPath
6719;; IMUL reg16, reg16, imm16 	VectorPath
6720;; IMUL reg16, mem16, imm16 	VectorPath
6721;; IMUL reg16, reg16 		Direct
6722;; IMUL reg16, mem16 		Direct
6723;;
6724;; On BDVER1, all HI MULs use DoublePath
6725
6726(define_insn "*mulhi3_1"
6727  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6728	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6729		 (match_operand:HI 2 "general_operand" "K,n,mr")))
6730   (clobber (reg:CC FLAGS_REG))]
6731  "TARGET_HIMODE_MATH
6732   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6733  "@
6734   imul{w}\t{%2, %1, %0|%0, %1, %2}
6735   imul{w}\t{%2, %1, %0|%0, %1, %2}
6736   imul{w}\t{%2, %0|%0, %2}"
6737  [(set_attr "type" "imul")
6738   (set_attr "prefix_0f" "0,0,1")
6739   (set (attr "athlon_decode")
6740	(cond [(eq_attr "cpu" "athlon")
6741		  (const_string "vector")
6742	       (eq_attr "alternative" "1,2")
6743		  (const_string "vector")]
6744	      (const_string "direct")))
6745   (set (attr "amdfam10_decode")
6746	(cond [(eq_attr "alternative" "0,1")
6747		  (const_string "vector")]
6748	      (const_string "direct")))
6749   (set_attr "bdver1_decode" "double")
6750   (set_attr "mode" "HI")])
6751
6752;;On AMDFAM10 and BDVER1
6753;; MUL reg8 	Direct
6754;; MUL mem8 	Direct
6755
6756(define_insn "*mulqi3_1"
6757  [(set (match_operand:QI 0 "register_operand" "=a")
6758	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6759		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6760   (clobber (reg:CC FLAGS_REG))]
6761  "TARGET_QIMODE_MATH
6762   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763  "mul{b}\t%2"
6764  [(set_attr "type" "imul")
6765   (set_attr "length_immediate" "0")
6766   (set (attr "athlon_decode")
6767     (if_then_else (eq_attr "cpu" "athlon")
6768        (const_string "vector")
6769        (const_string "direct")))
6770   (set_attr "amdfam10_decode" "direct")
6771   (set_attr "bdver1_decode" "direct")
6772   (set_attr "mode" "QI")])
6773
6774(define_expand "<u>mul<mode><dwi>3"
6775  [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6776		   (mult:<DWI>
6777		     (any_extend:<DWI>
6778		       (match_operand:DWIH 1 "nonimmediate_operand" ""))
6779		     (any_extend:<DWI>
6780		       (match_operand:DWIH 2 "register_operand" ""))))
6781	      (clobber (reg:CC FLAGS_REG))])])
6782
6783(define_expand "<u>mulqihi3"
6784  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6785		   (mult:HI
6786		     (any_extend:HI
6787		       (match_operand:QI 1 "nonimmediate_operand" ""))
6788		     (any_extend:HI
6789		       (match_operand:QI 2 "register_operand" ""))))
6790	      (clobber (reg:CC FLAGS_REG))])]
6791  "TARGET_QIMODE_MATH")
6792
6793(define_insn "*bmi2_umulditi3_1"
6794  [(set (match_operand:DI 0 "register_operand" "=r")
6795	(mult:DI
6796	  (match_operand:DI 2 "nonimmediate_operand" "%d")
6797	  (match_operand:DI 3 "nonimmediate_operand" "rm")))
6798   (set (match_operand:DI 1 "register_operand" "=r")
6799	(truncate:DI
6800	  (lshiftrt:TI
6801	    (mult:TI (zero_extend:TI (match_dup 2))
6802		     (zero_extend:TI (match_dup 3)))
6803	    (const_int 64))))]
6804  "TARGET_64BIT && TARGET_BMI2
6805   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6806  "mulx\t{%3, %0, %1|%1, %0, %3}"
6807  [(set_attr "type" "imulx")
6808   (set_attr "prefix" "vex")
6809   (set_attr "mode" "DI")])
6810
6811(define_insn "*bmi2_umulsidi3_1"
6812  [(set (match_operand:SI 0 "register_operand" "=r")
6813	(mult:SI
6814	  (match_operand:SI 2 "nonimmediate_operand" "%d")
6815	  (match_operand:SI 3 "nonimmediate_operand" "rm")))
6816   (set (match_operand:SI 1 "register_operand" "=r")
6817	(truncate:SI
6818	  (lshiftrt:DI
6819	    (mult:DI (zero_extend:DI (match_dup 2))
6820		     (zero_extend:DI (match_dup 3)))
6821	    (const_int 32))))]
6822  "!TARGET_64BIT && TARGET_BMI2
6823   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6824  "mulx\t{%3, %0, %1|%1, %0, %3}"
6825  [(set_attr "type" "imulx")
6826   (set_attr "prefix" "vex")
6827   (set_attr "mode" "SI")])
6828
6829(define_insn "*umul<mode><dwi>3_1"
6830  [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6831	(mult:<DWI>
6832	  (zero_extend:<DWI>
6833	    (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6834	  (zero_extend:<DWI>
6835	    (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6836   (clobber (reg:CC FLAGS_REG))]
6837  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6838  "@
6839   mul{<imodesuffix>}\t%2
6840   #"
6841  [(set_attr "isa" "*,bmi2")
6842   (set_attr "type" "imul,imulx")
6843   (set_attr "length_immediate" "0,*")
6844   (set (attr "athlon_decode")
6845	(cond [(eq_attr "alternative" "0")
6846		 (if_then_else (eq_attr "cpu" "athlon")
6847		   (const_string "vector")
6848		   (const_string "double"))]
6849	      (const_string "*")))
6850   (set_attr "amdfam10_decode" "double,*")
6851   (set_attr "bdver1_decode" "direct,*")
6852   (set_attr "prefix" "orig,vex")
6853   (set_attr "mode" "<MODE>")])
6854
6855;; Convert mul to the mulx pattern to avoid flags dependency.
6856(define_split
6857 [(set (match_operand:<DWI> 0 "register_operand" "")
6858       (mult:<DWI>
6859	 (zero_extend:<DWI>
6860	   (match_operand:DWIH 1 "register_operand" ""))
6861	 (zero_extend:<DWI>
6862	   (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6863  (clobber (reg:CC FLAGS_REG))]
6864 "TARGET_BMI2 && reload_completed
6865  && true_regnum (operands[1]) == DX_REG"
6866  [(parallel [(set (match_dup 3)
6867		   (mult:DWIH (match_dup 1) (match_dup 2)))
6868	      (set (match_dup 4)
6869		   (truncate:DWIH
6870		     (lshiftrt:<DWI>
6871		       (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6872				   (zero_extend:<DWI> (match_dup 2)))
6873		       (match_dup 5))))])]
6874{
6875  split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6876
6877  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6878})
6879
6880(define_insn "*mul<mode><dwi>3_1"
6881  [(set (match_operand:<DWI> 0 "register_operand" "=A")
6882	(mult:<DWI>
6883	  (sign_extend:<DWI>
6884	    (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6885	  (sign_extend:<DWI>
6886	    (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6887   (clobber (reg:CC FLAGS_REG))]
6888  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889  "imul{<imodesuffix>}\t%2"
6890  [(set_attr "type" "imul")
6891   (set_attr "length_immediate" "0")
6892   (set (attr "athlon_decode")
6893     (if_then_else (eq_attr "cpu" "athlon")
6894        (const_string "vector")
6895        (const_string "double")))
6896   (set_attr "amdfam10_decode" "double")
6897   (set_attr "bdver1_decode" "direct")
6898   (set_attr "mode" "<MODE>")])
6899
6900(define_insn "*<u>mulqihi3_1"
6901  [(set (match_operand:HI 0 "register_operand" "=a")
6902	(mult:HI
6903	  (any_extend:HI
6904	    (match_operand:QI 1 "nonimmediate_operand" "%0"))
6905	  (any_extend:HI
6906	    (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6907   (clobber (reg:CC FLAGS_REG))]
6908  "TARGET_QIMODE_MATH
6909   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6910  "<sgnprefix>mul{b}\t%2"
6911  [(set_attr "type" "imul")
6912   (set_attr "length_immediate" "0")
6913   (set (attr "athlon_decode")
6914     (if_then_else (eq_attr "cpu" "athlon")
6915        (const_string "vector")
6916        (const_string "direct")))
6917   (set_attr "amdfam10_decode" "direct")
6918   (set_attr "bdver1_decode" "direct")
6919   (set_attr "mode" "QI")])
6920
6921(define_expand "<s>mul<mode>3_highpart"
6922  [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6923		   (truncate:SWI48
6924		     (lshiftrt:<DWI>
6925		       (mult:<DWI>
6926			 (any_extend:<DWI>
6927			   (match_operand:SWI48 1 "nonimmediate_operand" ""))
6928			 (any_extend:<DWI>
6929			   (match_operand:SWI48 2 "register_operand" "")))
6930		       (match_dup 4))))
6931	      (clobber (match_scratch:SWI48 3 ""))
6932	      (clobber (reg:CC FLAGS_REG))])]
6933  ""
6934  "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6935
6936(define_insn "*<s>muldi3_highpart_1"
6937  [(set (match_operand:DI 0 "register_operand" "=d")
6938	(truncate:DI
6939	  (lshiftrt:TI
6940	    (mult:TI
6941	      (any_extend:TI
6942		(match_operand:DI 1 "nonimmediate_operand" "%a"))
6943	      (any_extend:TI
6944		(match_operand:DI 2 "nonimmediate_operand" "rm")))
6945	    (const_int 64))))
6946   (clobber (match_scratch:DI 3 "=1"))
6947   (clobber (reg:CC FLAGS_REG))]
6948  "TARGET_64BIT
6949   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950  "<sgnprefix>mul{q}\t%2"
6951  [(set_attr "type" "imul")
6952   (set_attr "length_immediate" "0")
6953   (set (attr "athlon_decode")
6954     (if_then_else (eq_attr "cpu" "athlon")
6955        (const_string "vector")
6956        (const_string "double")))
6957   (set_attr "amdfam10_decode" "double")
6958   (set_attr "bdver1_decode" "direct")
6959   (set_attr "mode" "DI")])
6960
6961(define_insn "*<s>mulsi3_highpart_1"
6962  [(set (match_operand:SI 0 "register_operand" "=d")
6963	(truncate:SI
6964	  (lshiftrt:DI
6965	    (mult:DI
6966	      (any_extend:DI
6967		(match_operand:SI 1 "nonimmediate_operand" "%a"))
6968	      (any_extend:DI
6969		(match_operand:SI 2 "nonimmediate_operand" "rm")))
6970	    (const_int 32))))
6971   (clobber (match_scratch:SI 3 "=1"))
6972   (clobber (reg:CC FLAGS_REG))]
6973  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6974  "<sgnprefix>mul{l}\t%2"
6975  [(set_attr "type" "imul")
6976   (set_attr "length_immediate" "0")
6977   (set (attr "athlon_decode")
6978     (if_then_else (eq_attr "cpu" "athlon")
6979        (const_string "vector")
6980        (const_string "double")))
6981   (set_attr "amdfam10_decode" "double")
6982   (set_attr "bdver1_decode" "direct")
6983   (set_attr "mode" "SI")])
6984
6985(define_insn "*<s>mulsi3_highpart_zext"
6986  [(set (match_operand:DI 0 "register_operand" "=d")
6987	(zero_extend:DI (truncate:SI
6988	  (lshiftrt:DI
6989	    (mult:DI (any_extend:DI
6990		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
6991		     (any_extend:DI
6992		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
6993	    (const_int 32)))))
6994   (clobber (match_scratch:SI 3 "=1"))
6995   (clobber (reg:CC FLAGS_REG))]
6996  "TARGET_64BIT
6997   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6998  "<sgnprefix>mul{l}\t%2"
6999  [(set_attr "type" "imul")
7000   (set_attr "length_immediate" "0")
7001   (set (attr "athlon_decode")
7002     (if_then_else (eq_attr "cpu" "athlon")
7003        (const_string "vector")
7004        (const_string "double")))
7005   (set_attr "amdfam10_decode" "double")
7006   (set_attr "bdver1_decode" "direct")
7007   (set_attr "mode" "SI")])
7008
7009;; The patterns that match these are at the end of this file.
7010
7011(define_expand "mulxf3"
7012  [(set (match_operand:XF 0 "register_operand" "")
7013	(mult:XF (match_operand:XF 1 "register_operand" "")
7014		 (match_operand:XF 2 "register_operand" "")))]
7015  "TARGET_80387")
7016
7017(define_expand "mul<mode>3"
7018  [(set (match_operand:MODEF 0 "register_operand" "")
7019	(mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7020		    (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7021  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7022    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7023
7024;; Divide instructions
7025
7026;; The patterns that match these are at the end of this file.
7027
7028(define_expand "divxf3"
7029  [(set (match_operand:XF 0 "register_operand" "")
7030	(div:XF (match_operand:XF 1 "register_operand" "")
7031		(match_operand:XF 2 "register_operand" "")))]
7032  "TARGET_80387")
7033
7034(define_expand "divdf3"
7035  [(set (match_operand:DF 0 "register_operand" "")
7036 	(div:DF (match_operand:DF 1 "register_operand" "")
7037 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7038   "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7039    || (TARGET_SSE2 && TARGET_SSE_MATH)")
7040
7041(define_expand "divsf3"
7042  [(set (match_operand:SF 0 "register_operand" "")
7043	(div:SF (match_operand:SF 1 "register_operand" "")
7044		(match_operand:SF 2 "nonimmediate_operand" "")))]
7045  "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7046    || TARGET_SSE_MATH"
7047{
7048  if (TARGET_SSE_MATH
7049      && TARGET_RECIP_DIV
7050      && optimize_insn_for_speed_p ()
7051      && flag_finite_math_only && !flag_trapping_math
7052      && flag_unsafe_math_optimizations)
7053    {
7054      ix86_emit_swdivsf (operands[0], operands[1],
7055			 operands[2], SFmode);
7056      DONE;
7057    }
7058})
7059
7060;; Divmod instructions.
7061
7062(define_expand "divmod<mode>4"
7063  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7064		   (div:SWIM248
7065		     (match_operand:SWIM248 1 "register_operand" "")
7066		     (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7067	      (set (match_operand:SWIM248 3 "register_operand" "")
7068		   (mod:SWIM248 (match_dup 1) (match_dup 2)))
7069	      (clobber (reg:CC FLAGS_REG))])])
7070
7071;; Split with 8bit unsigned divide:
7072;; 	if (dividend an divisor are in [0-255])
7073;;	   use 8bit unsigned integer divide
7074;;	 else
7075;;	   use original integer divide
7076(define_split
7077  [(set (match_operand:SWI48 0 "register_operand" "")
7078	(div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7079		    (match_operand:SWI48 3 "nonimmediate_operand" "")))
7080   (set (match_operand:SWI48 1 "register_operand" "")
7081	(mod:SWI48 (match_dup 2) (match_dup 3)))
7082   (clobber (reg:CC FLAGS_REG))]
7083  "TARGET_USE_8BIT_IDIV
7084   && TARGET_QIMODE_MATH
7085   && can_create_pseudo_p ()
7086   && !optimize_insn_for_size_p ()"
7087  [(const_int 0)]
7088  "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7089
7090(define_insn_and_split "divmod<mode>4_1"
7091  [(set (match_operand:SWI48 0 "register_operand" "=a")
7092	(div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7093		   (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7094   (set (match_operand:SWI48 1 "register_operand" "=&d")
7095	(mod:SWI48 (match_dup 2) (match_dup 3)))
7096   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7097   (clobber (reg:CC FLAGS_REG))]
7098  ""
7099  "#"
7100  "reload_completed"
7101  [(parallel [(set (match_dup 1)
7102		   (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7103	      (clobber (reg:CC FLAGS_REG))])
7104   (parallel [(set (match_dup 0)
7105	           (div:SWI48 (match_dup 2) (match_dup 3)))
7106	      (set (match_dup 1)
7107		   (mod:SWI48 (match_dup 2) (match_dup 3)))
7108	      (use (match_dup 1))
7109	      (clobber (reg:CC FLAGS_REG))])]
7110{
7111  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7112
7113  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7114    operands[4] = operands[2];
7115  else
7116    {
7117      /* Avoid use of cltd in favor of a mov+shift.  */
7118      emit_move_insn (operands[1], operands[2]);
7119      operands[4] = operands[1];
7120    }
7121}
7122  [(set_attr "type" "multi")
7123   (set_attr "mode" "<MODE>")])
7124
7125(define_insn_and_split "*divmod<mode>4"
7126  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7127	(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7128		    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7129   (set (match_operand:SWIM248 1 "register_operand" "=&d")
7130	(mod:SWIM248 (match_dup 2) (match_dup 3)))
7131   (clobber (reg:CC FLAGS_REG))]
7132  ""
7133  "#"
7134  "reload_completed"
7135  [(parallel [(set (match_dup 1)
7136		   (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7137	      (clobber (reg:CC FLAGS_REG))])
7138   (parallel [(set (match_dup 0)
7139	           (div:SWIM248 (match_dup 2) (match_dup 3)))
7140	      (set (match_dup 1)
7141		   (mod:SWIM248 (match_dup 2) (match_dup 3)))
7142	      (use (match_dup 1))
7143	      (clobber (reg:CC FLAGS_REG))])]
7144{
7145  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7146
7147  if (<MODE>mode != HImode
7148      && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7149    operands[4] = operands[2];
7150  else
7151    {
7152      /* Avoid use of cltd in favor of a mov+shift.  */
7153      emit_move_insn (operands[1], operands[2]);
7154      operands[4] = operands[1];
7155    }
7156}
7157  [(set_attr "type" "multi")
7158   (set_attr "mode" "<MODE>")])
7159
7160(define_insn "*divmod<mode>4_noext"
7161  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7162	(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7163		    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7164   (set (match_operand:SWIM248 1 "register_operand" "=d")
7165	(mod:SWIM248 (match_dup 2) (match_dup 3)))
7166   (use (match_operand:SWIM248 4 "register_operand" "1"))
7167   (clobber (reg:CC FLAGS_REG))]
7168  ""
7169  "idiv{<imodesuffix>}\t%3"
7170  [(set_attr "type" "idiv")
7171   (set_attr "mode" "<MODE>")])
7172
7173(define_expand "divmodqi4"
7174  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7175		   (div:QI
7176		     (match_operand:QI 1 "register_operand" "")
7177		     (match_operand:QI 2 "nonimmediate_operand" "")))
7178	      (set (match_operand:QI 3 "register_operand" "")
7179		   (mod:QI (match_dup 1) (match_dup 2)))
7180	      (clobber (reg:CC FLAGS_REG))])]
7181  "TARGET_QIMODE_MATH"
7182{
7183  rtx div, mod, insn;
7184  rtx tmp0, tmp1;
7185
7186  tmp0 = gen_reg_rtx (HImode);
7187  tmp1 = gen_reg_rtx (HImode);
7188
7189  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7190     in AX.  */
7191  emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7192  emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7193
7194  /* Extract remainder from AH.  */
7195  tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7196  insn = emit_move_insn (operands[3], tmp1);
7197
7198  mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7199  set_unique_reg_note (insn, REG_EQUAL, mod);
7200
7201  /* Extract quotient from AL.  */
7202  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7203
7204  div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7205  set_unique_reg_note (insn, REG_EQUAL, div);
7206
7207  DONE;
7208})
7209
7210;; Divide AX by r/m8, with result stored in
7211;; AL <- Quotient
7212;; AH <- Remainder
7213;; Change div/mod to HImode and extend the second argument to HImode
7214;; so that mode of div/mod matches with mode of arguments.  Otherwise
7215;; combine may fail.
7216(define_insn "divmodhiqi3"
7217  [(set (match_operand:HI 0 "register_operand" "=a")
7218	(ior:HI
7219	  (ashift:HI
7220	    (zero_extend:HI
7221	      (truncate:QI
7222		(mod:HI (match_operand:HI 1 "register_operand" "0")
7223			(sign_extend:HI
7224			  (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7225	    (const_int 8))
7226	  (zero_extend:HI
7227	    (truncate:QI
7228	      (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7229   (clobber (reg:CC FLAGS_REG))]
7230  "TARGET_QIMODE_MATH"
7231  "idiv{b}\t%2"
7232  [(set_attr "type" "idiv")
7233   (set_attr "mode" "QI")])
7234
7235(define_expand "udivmod<mode>4"
7236  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7237		   (udiv:SWIM248
7238		     (match_operand:SWIM248 1 "register_operand" "")
7239		     (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7240	      (set (match_operand:SWIM248 3 "register_operand" "")
7241		   (umod:SWIM248 (match_dup 1) (match_dup 2)))
7242	      (clobber (reg:CC FLAGS_REG))])])
7243
7244;; Split with 8bit unsigned divide:
7245;; 	if (dividend an divisor are in [0-255])
7246;;	   use 8bit unsigned integer divide
7247;;	 else
7248;;	   use original integer divide
7249(define_split
7250  [(set (match_operand:SWI48 0 "register_operand" "")
7251	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7252		    (match_operand:SWI48 3 "nonimmediate_operand" "")))
7253   (set (match_operand:SWI48 1 "register_operand" "")
7254	(umod:SWI48 (match_dup 2) (match_dup 3)))
7255   (clobber (reg:CC FLAGS_REG))]
7256  "TARGET_USE_8BIT_IDIV
7257   && TARGET_QIMODE_MATH
7258   && can_create_pseudo_p ()
7259   && !optimize_insn_for_size_p ()"
7260  [(const_int 0)]
7261  "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7262
7263(define_insn_and_split "udivmod<mode>4_1"
7264  [(set (match_operand:SWI48 0 "register_operand" "=a")
7265	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7266		    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7267   (set (match_operand:SWI48 1 "register_operand" "=&d")
7268	(umod:SWI48 (match_dup 2) (match_dup 3)))
7269   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7270   (clobber (reg:CC FLAGS_REG))]
7271  ""
7272  "#"
7273  "reload_completed"
7274  [(set (match_dup 1) (const_int 0))
7275   (parallel [(set (match_dup 0)
7276		   (udiv:SWI48 (match_dup 2) (match_dup 3)))
7277	      (set (match_dup 1)
7278		   (umod:SWI48 (match_dup 2) (match_dup 3)))
7279	      (use (match_dup 1))
7280	      (clobber (reg:CC FLAGS_REG))])]
7281  ""
7282  [(set_attr "type" "multi")
7283   (set_attr "mode" "<MODE>")])
7284
7285(define_insn_and_split "*udivmod<mode>4"
7286  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7287	(udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7288		      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7289   (set (match_operand:SWIM248 1 "register_operand" "=&d")
7290	(umod:SWIM248 (match_dup 2) (match_dup 3)))
7291   (clobber (reg:CC FLAGS_REG))]
7292  ""
7293  "#"
7294  "reload_completed"
7295  [(set (match_dup 1) (const_int 0))
7296   (parallel [(set (match_dup 0)
7297		   (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7298	      (set (match_dup 1)
7299		   (umod:SWIM248 (match_dup 2) (match_dup 3)))
7300	      (use (match_dup 1))
7301	      (clobber (reg:CC FLAGS_REG))])]
7302  ""
7303  [(set_attr "type" "multi")
7304   (set_attr "mode" "<MODE>")])
7305
7306(define_insn "*udivmod<mode>4_noext"
7307  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7308	(udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7309		      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7310   (set (match_operand:SWIM248 1 "register_operand" "=d")
7311	(umod:SWIM248 (match_dup 2) (match_dup 3)))
7312   (use (match_operand:SWIM248 4 "register_operand" "1"))
7313   (clobber (reg:CC FLAGS_REG))]
7314  ""
7315  "div{<imodesuffix>}\t%3"
7316  [(set_attr "type" "idiv")
7317   (set_attr "mode" "<MODE>")])
7318
7319(define_expand "udivmodqi4"
7320  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7321		   (udiv:QI
7322		     (match_operand:QI 1 "register_operand" "")
7323		     (match_operand:QI 2 "nonimmediate_operand" "")))
7324	      (set (match_operand:QI 3 "register_operand" "")
7325		   (umod:QI (match_dup 1) (match_dup 2)))
7326	      (clobber (reg:CC FLAGS_REG))])]
7327  "TARGET_QIMODE_MATH"
7328{
7329  rtx div, mod, insn;
7330  rtx tmp0, tmp1;
7331
7332  tmp0 = gen_reg_rtx (HImode);
7333  tmp1 = gen_reg_rtx (HImode);
7334
7335  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7336     in AX.  */
7337  emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7338  emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7339
7340  /* Extract remainder from AH.  */
7341  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7342  tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7343  insn = emit_move_insn (operands[3], tmp1);
7344
7345  mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7346  set_unique_reg_note (insn, REG_EQUAL, mod);
7347
7348  /* Extract quotient from AL.  */
7349  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7350
7351  div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7352  set_unique_reg_note (insn, REG_EQUAL, div);
7353
7354  DONE;
7355})
7356
7357(define_insn "udivmodhiqi3"
7358  [(set (match_operand:HI 0 "register_operand" "=a")
7359	(ior:HI
7360	  (ashift:HI
7361	    (zero_extend:HI
7362	      (truncate:QI
7363		(mod:HI (match_operand:HI 1 "register_operand" "0")
7364			(zero_extend:HI
7365			  (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7366	    (const_int 8))
7367	  (zero_extend:HI
7368	    (truncate:QI
7369	      (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7370   (clobber (reg:CC FLAGS_REG))]
7371  "TARGET_QIMODE_MATH"
7372  "div{b}\t%2"
7373  [(set_attr "type" "idiv")
7374   (set_attr "mode" "QI")])
7375
7376;; We cannot use div/idiv for double division, because it causes
7377;; "division by zero" on the overflow and that's not what we expect
7378;; from truncate.  Because true (non truncating) double division is
7379;; never generated, we can't create this insn anyway.
7380;
7381;(define_insn ""
7382;  [(set (match_operand:SI 0 "register_operand" "=a")
7383;	(truncate:SI
7384;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7385;		   (zero_extend:DI
7386;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7387;   (set (match_operand:SI 3 "register_operand" "=d")
7388;	(truncate:SI
7389;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7390;   (clobber (reg:CC FLAGS_REG))]
7391;  ""
7392;  "div{l}\t{%2, %0|%0, %2}"
7393;  [(set_attr "type" "idiv")])
7394
7395;;- Logical AND instructions
7396
7397;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7398;; Note that this excludes ah.
7399
7400(define_expand "testsi_ccno_1"
7401  [(set (reg:CCNO FLAGS_REG)
7402	(compare:CCNO
7403	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7404		  (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7405	  (const_int 0)))])
7406
7407(define_expand "testqi_ccz_1"
7408  [(set (reg:CCZ FLAGS_REG)
7409        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7410			     (match_operand:QI 1 "nonmemory_operand" ""))
7411		 (const_int 0)))])
7412
7413(define_expand "testdi_ccno_1"
7414  [(set (reg:CCNO FLAGS_REG)
7415	(compare:CCNO
7416	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7417		  (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7418	  (const_int 0)))]
7419  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7420
7421(define_insn "*testdi_1"
7422  [(set (reg FLAGS_REG)
7423	(compare
7424	 (and:DI
7425	  (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7426	  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7427	 (const_int 0)))]
7428  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7429   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7430  "@
7431   test{l}\t{%k1, %k0|%k0, %k1}
7432   test{l}\t{%k1, %k0|%k0, %k1}
7433   test{q}\t{%1, %0|%0, %1}
7434   test{q}\t{%1, %0|%0, %1}
7435   test{q}\t{%1, %0|%0, %1}"
7436  [(set_attr "type" "test")
7437   (set_attr "modrm" "0,1,0,1,1")
7438   (set_attr "mode" "SI,SI,DI,DI,DI")])
7439
7440(define_insn "*testqi_1_maybe_si"
7441  [(set (reg FLAGS_REG)
7442        (compare
7443	  (and:QI
7444	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7445	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7446	  (const_int 0)))]
7447   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7448    && ix86_match_ccmode (insn,
7449 			 CONST_INT_P (operands[1])
7450 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7451{
7452  if (which_alternative == 3)
7453    {
7454      if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7455	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7456      return "test{l}\t{%1, %k0|%k0, %1}";
7457    }
7458  return "test{b}\t{%1, %0|%0, %1}";
7459}
7460  [(set_attr "type" "test")
7461   (set_attr "modrm" "0,1,1,1")
7462   (set_attr "mode" "QI,QI,QI,SI")
7463   (set_attr "pent_pair" "uv,np,uv,np")])
7464
7465(define_insn "*test<mode>_1"
7466  [(set (reg FLAGS_REG)
7467	(compare
7468	 (and:SWI124
7469	  (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7470	  (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7471	 (const_int 0)))]
7472  "ix86_match_ccmode (insn, CCNOmode)
7473   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7474  "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7475  [(set_attr "type" "test")
7476   (set_attr "modrm" "0,1,1")
7477   (set_attr "mode" "<MODE>")
7478   (set_attr "pent_pair" "uv,np,uv")])
7479
7480(define_expand "testqi_ext_ccno_0"
7481  [(set (reg:CCNO FLAGS_REG)
7482	(compare:CCNO
7483	  (and:SI
7484	    (zero_extract:SI
7485	      (match_operand 0 "ext_register_operand" "")
7486	      (const_int 8)
7487	      (const_int 8))
7488	    (match_operand 1 "const_int_operand" ""))
7489	  (const_int 0)))])
7490
7491(define_insn "*testqi_ext_0"
7492  [(set (reg FLAGS_REG)
7493	(compare
7494	  (and:SI
7495	    (zero_extract:SI
7496	      (match_operand 0 "ext_register_operand" "Q")
7497	      (const_int 8)
7498	      (const_int 8))
7499	    (match_operand 1 "const_int_operand" "n"))
7500	  (const_int 0)))]
7501  "ix86_match_ccmode (insn, CCNOmode)"
7502  "test{b}\t{%1, %h0|%h0, %1}"
7503  [(set_attr "type" "test")
7504   (set_attr "mode" "QI")
7505   (set_attr "length_immediate" "1")
7506   (set_attr "modrm" "1")
7507   (set_attr "pent_pair" "np")])
7508
7509(define_insn "*testqi_ext_1_rex64"
7510  [(set (reg FLAGS_REG)
7511	(compare
7512	  (and:SI
7513	    (zero_extract:SI
7514	      (match_operand 0 "ext_register_operand" "Q")
7515	      (const_int 8)
7516	      (const_int 8))
7517	    (zero_extend:SI
7518	      (match_operand:QI 1 "register_operand" "Q")))
7519	  (const_int 0)))]
7520  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7521  "test{b}\t{%1, %h0|%h0, %1}"
7522  [(set_attr "type" "test")
7523   (set_attr "mode" "QI")])
7524
7525(define_insn "*testqi_ext_1"
7526  [(set (reg FLAGS_REG)
7527	(compare
7528	  (and:SI
7529	    (zero_extract:SI
7530	      (match_operand 0 "ext_register_operand" "Q")
7531	      (const_int 8)
7532	      (const_int 8))
7533	    (zero_extend:SI
7534	      (match_operand:QI 1 "general_operand" "Qm")))
7535	  (const_int 0)))]
7536  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7537  "test{b}\t{%1, %h0|%h0, %1}"
7538  [(set_attr "type" "test")
7539   (set_attr "mode" "QI")])
7540
7541(define_insn "*testqi_ext_2"
7542  [(set (reg FLAGS_REG)
7543	(compare
7544	  (and:SI
7545	    (zero_extract:SI
7546	      (match_operand 0 "ext_register_operand" "Q")
7547	      (const_int 8)
7548	      (const_int 8))
7549	    (zero_extract:SI
7550	      (match_operand 1 "ext_register_operand" "Q")
7551	      (const_int 8)
7552	      (const_int 8)))
7553	  (const_int 0)))]
7554  "ix86_match_ccmode (insn, CCNOmode)"
7555  "test{b}\t{%h1, %h0|%h0, %h1}"
7556  [(set_attr "type" "test")
7557   (set_attr "mode" "QI")])
7558
7559(define_insn "*testqi_ext_3_rex64"
7560  [(set (reg FLAGS_REG)
7561        (compare (zero_extract:DI
7562		   (match_operand 0 "nonimmediate_operand" "rm")
7563		   (match_operand:DI 1 "const_int_operand" "")
7564		   (match_operand:DI 2 "const_int_operand" ""))
7565		 (const_int 0)))]
7566  "TARGET_64BIT
7567   && ix86_match_ccmode (insn, CCNOmode)
7568   && INTVAL (operands[1]) > 0
7569   && INTVAL (operands[2]) >= 0
7570   /* Ensure that resulting mask is zero or sign extended operand.  */
7571   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7572       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7573	   && INTVAL (operands[1]) > 32))
7574   && (GET_MODE (operands[0]) == SImode
7575       || GET_MODE (operands[0]) == DImode
7576       || GET_MODE (operands[0]) == HImode
7577       || GET_MODE (operands[0]) == QImode)"
7578  "#")
7579
7580;; Combine likes to form bit extractions for some tests.  Humor it.
7581(define_insn "*testqi_ext_3"
7582  [(set (reg FLAGS_REG)
7583        (compare (zero_extract:SI
7584		   (match_operand 0 "nonimmediate_operand" "rm")
7585		   (match_operand:SI 1 "const_int_operand" "")
7586		   (match_operand:SI 2 "const_int_operand" ""))
7587		 (const_int 0)))]
7588  "ix86_match_ccmode (insn, CCNOmode)
7589   && INTVAL (operands[1]) > 0
7590   && INTVAL (operands[2]) >= 0
7591   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7592   && (GET_MODE (operands[0]) == SImode
7593       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7594       || GET_MODE (operands[0]) == HImode
7595       || GET_MODE (operands[0]) == QImode)"
7596  "#")
7597
7598(define_split
7599  [(set (match_operand 0 "flags_reg_operand" "")
7600        (match_operator 1 "compare_operator"
7601	  [(zero_extract
7602	     (match_operand 2 "nonimmediate_operand" "")
7603	     (match_operand 3 "const_int_operand" "")
7604	     (match_operand 4 "const_int_operand" ""))
7605	   (const_int 0)]))]
7606  "ix86_match_ccmode (insn, CCNOmode)"
7607  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7608{
7609  rtx val = operands[2];
7610  HOST_WIDE_INT len = INTVAL (operands[3]);
7611  HOST_WIDE_INT pos = INTVAL (operands[4]);
7612  HOST_WIDE_INT mask;
7613  enum machine_mode mode, submode;
7614
7615  mode = GET_MODE (val);
7616  if (MEM_P (val))
7617    {
7618      /* ??? Combine likes to put non-volatile mem extractions in QImode
7619	 no matter the size of the test.  So find a mode that works.  */
7620      if (! MEM_VOLATILE_P (val))
7621	{
7622	  mode = smallest_mode_for_size (pos + len, MODE_INT);
7623	  val = adjust_address (val, mode, 0);
7624	}
7625    }
7626  else if (GET_CODE (val) == SUBREG
7627	   && (submode = GET_MODE (SUBREG_REG (val)),
7628	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7629	   && pos + len <= GET_MODE_BITSIZE (submode)
7630	   && GET_MODE_CLASS (submode) == MODE_INT)
7631    {
7632      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7633      mode = submode;
7634      val = SUBREG_REG (val);
7635    }
7636  else if (mode == HImode && pos + len <= 8)
7637    {
7638      /* Small HImode tests can be converted to QImode.  */
7639      mode = QImode;
7640      val = gen_lowpart (QImode, val);
7641    }
7642
7643  if (len == HOST_BITS_PER_WIDE_INT)
7644    mask = -1;
7645  else
7646    mask = ((HOST_WIDE_INT)1 << len) - 1;
7647  mask <<= pos;
7648
7649  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7650})
7651
7652;; Convert HImode/SImode test instructions with immediate to QImode ones.
7653;; i386 does not allow to encode test with 8bit sign extended immediate, so
7654;; this is relatively important trick.
7655;; Do the conversion only post-reload to avoid limiting of the register class
7656;; to QI regs.
7657(define_split
7658  [(set (match_operand 0 "flags_reg_operand" "")
7659	(match_operator 1 "compare_operator"
7660	  [(and (match_operand 2 "register_operand" "")
7661	        (match_operand 3 "const_int_operand" ""))
7662	   (const_int 0)]))]
7663   "reload_completed
7664    && QI_REG_P (operands[2])
7665    && GET_MODE (operands[2]) != QImode
7666    && ((ix86_match_ccmode (insn, CCZmode)
7667    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
7668	|| (ix86_match_ccmode (insn, CCNOmode)
7669	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
7670  [(set (match_dup 0)
7671	(match_op_dup 1
7672	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7673		   (match_dup 3))
7674	   (const_int 0)]))]
7675{
7676  operands[2] = gen_lowpart (SImode, operands[2]);
7677  operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7678})
7679
7680(define_split
7681  [(set (match_operand 0 "flags_reg_operand" "")
7682	(match_operator 1 "compare_operator"
7683	  [(and (match_operand 2 "nonimmediate_operand" "")
7684	        (match_operand 3 "const_int_operand" ""))
7685	   (const_int 0)]))]
7686   "reload_completed
7687    && GET_MODE (operands[2]) != QImode
7688    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7689    && ((ix86_match_ccmode (insn, CCZmode)
7690	 && !(INTVAL (operands[3]) & ~255))
7691	|| (ix86_match_ccmode (insn, CCNOmode)
7692	    && !(INTVAL (operands[3]) & ~127)))"
7693  [(set (match_dup 0)
7694	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7695			 (const_int 0)]))]
7696{
7697  operands[2] = gen_lowpart (QImode, operands[2]);
7698  operands[3] = gen_lowpart (QImode, operands[3]);
7699})
7700
7701;; %%% This used to optimize known byte-wide and operations to memory,
7702;; and sometimes to QImode registers.  If this is considered useful,
7703;; it should be done with splitters.
7704
7705(define_expand "and<mode>3"
7706  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7707	(and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7708		  (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7709  ""
7710{
7711  if (<MODE>mode == DImode
7712      && GET_CODE (operands[2]) == CONST_INT
7713      && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7714      && REG_P (operands[1]))
7715    emit_insn (gen_zero_extendsidi2 (operands[0],
7716				     gen_lowpart (SImode, operands[1])));
7717  else
7718    ix86_expand_binary_operator (AND, <MODE>mode, operands);
7719  DONE;
7720})
7721
7722(define_insn "*anddi_1"
7723  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7724	(and:DI
7725	 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7726	 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7727   (clobber (reg:CC FLAGS_REG))]
7728  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7729{
7730  switch (get_attr_type (insn))
7731    {
7732    case TYPE_IMOVX:
7733      {
7734	enum machine_mode mode;
7735
7736	gcc_assert (CONST_INT_P (operands[2]));
7737	if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7738	  mode = SImode;
7739	else if (INTVAL (operands[2]) == 0xffff)
7740	  mode = HImode;
7741	else
7742	  {
7743	    gcc_assert (INTVAL (operands[2]) == 0xff);
7744	    mode = QImode;
7745	  }
7746
7747	operands[1] = gen_lowpart (mode, operands[1]);
7748	if (mode == SImode)
7749	  return "mov{l}\t{%1, %k0|%k0, %1}";
7750	else if (mode == HImode)
7751	  return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7752	else
7753	  return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7754      }
7755
7756    default:
7757      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7758      if (get_attr_mode (insn) == MODE_SI)
7759	return "and{l}\t{%k2, %k0|%k0, %k2}";
7760      else
7761	return "and{q}\t{%2, %0|%0, %2}";
7762    }
7763}
7764  [(set_attr "type" "alu,alu,alu,imovx")
7765   (set_attr "length_immediate" "*,*,*,0")
7766   (set (attr "prefix_rex")
7767     (if_then_else
7768       (and (eq_attr "type" "imovx")
7769	    (and (match_test "INTVAL (operands[2]) == 0xff")
7770		 (match_operand 1 "ext_QIreg_operand" "")))
7771       (const_string "1")
7772       (const_string "*")))
7773   (set_attr "mode" "SI,DI,DI,SI")])
7774
7775(define_insn "*andsi_1"
7776  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7777	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7778		(match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7779   (clobber (reg:CC FLAGS_REG))]
7780  "ix86_binary_operator_ok (AND, SImode, operands)"
7781{
7782  switch (get_attr_type (insn))
7783    {
7784    case TYPE_IMOVX:
7785      {
7786	enum machine_mode mode;
7787
7788	gcc_assert (CONST_INT_P (operands[2]));
7789        if (INTVAL (operands[2]) == 0xffff)
7790	  mode = HImode;
7791	else
7792	  {
7793	    gcc_assert (INTVAL (operands[2]) == 0xff);
7794	    mode = QImode;
7795	  }
7796
7797	operands[1] = gen_lowpart (mode, operands[1]);
7798	if (mode == HImode)
7799	  return "movz{wl|x}\t{%1, %0|%0, %1}";
7800	else
7801	  return "movz{bl|x}\t{%1, %0|%0, %1}";
7802      }
7803
7804    default:
7805      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7806      return "and{l}\t{%2, %0|%0, %2}";
7807    }
7808}
7809  [(set_attr "type" "alu,alu,imovx")
7810   (set (attr "prefix_rex")
7811     (if_then_else
7812       (and (eq_attr "type" "imovx")
7813	    (and (match_test "INTVAL (operands[2]) == 0xff")
7814		 (match_operand 1 "ext_QIreg_operand" "")))
7815       (const_string "1")
7816       (const_string "*")))
7817   (set_attr "length_immediate" "*,*,0")
7818   (set_attr "mode" "SI")])
7819
7820;; See comment for addsi_1_zext why we do use nonimmediate_operand
7821(define_insn "*andsi_1_zext"
7822  [(set (match_operand:DI 0 "register_operand" "=r")
7823	(zero_extend:DI
7824	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7825		  (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7826   (clobber (reg:CC FLAGS_REG))]
7827  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7828  "and{l}\t{%2, %k0|%k0, %2}"
7829  [(set_attr "type" "alu")
7830   (set_attr "mode" "SI")])
7831
7832(define_insn "*andhi_1"
7833  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7834	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7835		(match_operand:HI 2 "general_operand" "rn,rm,L")))
7836   (clobber (reg:CC FLAGS_REG))]
7837  "ix86_binary_operator_ok (AND, HImode, operands)"
7838{
7839  switch (get_attr_type (insn))
7840    {
7841    case TYPE_IMOVX:
7842      gcc_assert (CONST_INT_P (operands[2]));
7843      gcc_assert (INTVAL (operands[2]) == 0xff);
7844      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7845
7846    default:
7847      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7848
7849      return "and{w}\t{%2, %0|%0, %2}";
7850    }
7851}
7852  [(set_attr "type" "alu,alu,imovx")
7853   (set_attr "length_immediate" "*,*,0")
7854   (set (attr "prefix_rex")
7855     (if_then_else
7856       (and (eq_attr "type" "imovx")
7857	    (match_operand 1 "ext_QIreg_operand" ""))
7858       (const_string "1")
7859       (const_string "*")))
7860   (set_attr "mode" "HI,HI,SI")])
7861
7862;; %%% Potential partial reg stall on alternative 2.  What to do?
7863(define_insn "*andqi_1"
7864  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7865	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7866		(match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7867   (clobber (reg:CC FLAGS_REG))]
7868  "ix86_binary_operator_ok (AND, QImode, operands)"
7869  "@
7870   and{b}\t{%2, %0|%0, %2}
7871   and{b}\t{%2, %0|%0, %2}
7872   and{l}\t{%k2, %k0|%k0, %k2}"
7873  [(set_attr "type" "alu")
7874   (set_attr "mode" "QI,QI,SI")])
7875
7876(define_insn "*andqi_1_slp"
7877  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7878	(and:QI (match_dup 0)
7879		(match_operand:QI 1 "general_operand" "qn,qmn")))
7880   (clobber (reg:CC FLAGS_REG))]
7881  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7882   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7883  "and{b}\t{%1, %0|%0, %1}"
7884  [(set_attr "type" "alu1")
7885   (set_attr "mode" "QI")])
7886
7887(define_split
7888  [(set (match_operand 0 "register_operand" "")
7889	(and (match_dup 0)
7890	     (const_int -65536)))
7891   (clobber (reg:CC FLAGS_REG))]
7892  "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7893    || optimize_function_for_size_p (cfun)"
7894  [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895  "operands[1] = gen_lowpart (HImode, operands[0]);")
7896
7897(define_split
7898  [(set (match_operand 0 "ext_register_operand" "")
7899	(and (match_dup 0)
7900	     (const_int -256)))
7901   (clobber (reg:CC FLAGS_REG))]
7902  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903   && reload_completed"
7904  [(set (strict_low_part (match_dup 1)) (const_int 0))]
7905  "operands[1] = gen_lowpart (QImode, operands[0]);")
7906
7907(define_split
7908  [(set (match_operand 0 "ext_register_operand" "")
7909	(and (match_dup 0)
7910	     (const_int -65281)))
7911   (clobber (reg:CC FLAGS_REG))]
7912  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7913   && reload_completed"
7914  [(parallel [(set (zero_extract:SI (match_dup 0)
7915				    (const_int 8)
7916				    (const_int 8))
7917		   (xor:SI
7918		     (zero_extract:SI (match_dup 0)
7919				      (const_int 8)
7920				      (const_int 8))
7921		     (zero_extract:SI (match_dup 0)
7922				      (const_int 8)
7923				      (const_int 8))))
7924	      (clobber (reg:CC FLAGS_REG))])]
7925  "operands[0] = gen_lowpart (SImode, operands[0]);")
7926
7927(define_insn "*anddi_2"
7928  [(set (reg FLAGS_REG)
7929	(compare
7930	 (and:DI
7931	  (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7932	  (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7933	 (const_int 0)))
7934   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7935	(and:DI (match_dup 1) (match_dup 2)))]
7936  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7937   && ix86_binary_operator_ok (AND, DImode, operands)"
7938  "@
7939   and{l}\t{%k2, %k0|%k0, %k2}
7940   and{q}\t{%2, %0|%0, %2}
7941   and{q}\t{%2, %0|%0, %2}"
7942  [(set_attr "type" "alu")
7943   (set_attr "mode" "SI,DI,DI")])
7944
7945(define_insn "*andqi_2_maybe_si"
7946  [(set (reg FLAGS_REG)
7947	(compare (and:QI
7948		  (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7949		  (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7950		 (const_int 0)))
7951   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7952	(and:QI (match_dup 1) (match_dup 2)))]
7953  "ix86_binary_operator_ok (AND, QImode, operands)
7954   && ix86_match_ccmode (insn,
7955			 CONST_INT_P (operands[2])
7956			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7957{
7958  if (which_alternative == 2)
7959    {
7960      if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7961        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7962      return "and{l}\t{%2, %k0|%k0, %2}";
7963    }
7964  return "and{b}\t{%2, %0|%0, %2}";
7965}
7966  [(set_attr "type" "alu")
7967   (set_attr "mode" "QI,QI,SI")])
7968
7969(define_insn "*and<mode>_2"
7970  [(set (reg FLAGS_REG)
7971	(compare (and:SWI124
7972		  (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7973		  (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7974		 (const_int 0)))
7975   (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7976	(and:SWI124 (match_dup 1) (match_dup 2)))]
7977  "ix86_match_ccmode (insn, CCNOmode)
7978   && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7979  "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7980  [(set_attr "type" "alu")
7981   (set_attr "mode" "<MODE>")])
7982
7983;; See comment for addsi_1_zext why we do use nonimmediate_operand
7984(define_insn "*andsi_2_zext"
7985  [(set (reg FLAGS_REG)
7986	(compare (and:SI
7987		  (match_operand:SI 1 "nonimmediate_operand" "%0")
7988		  (match_operand:SI 2 "x86_64_general_operand" "rme"))
7989		 (const_int 0)))
7990   (set (match_operand:DI 0 "register_operand" "=r")
7991	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7992  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7993   && ix86_binary_operator_ok (AND, SImode, operands)"
7994  "and{l}\t{%2, %k0|%k0, %2}"
7995  [(set_attr "type" "alu")
7996   (set_attr "mode" "SI")])
7997
7998(define_insn "*andqi_2_slp"
7999  [(set (reg FLAGS_REG)
8000	(compare (and:QI
8001		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8002		   (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8003		 (const_int 0)))
8004   (set (strict_low_part (match_dup 0))
8005	(and:QI (match_dup 0) (match_dup 1)))]
8006  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007   && ix86_match_ccmode (insn, CCNOmode)
8008   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8009  "and{b}\t{%1, %0|%0, %1}"
8010  [(set_attr "type" "alu1")
8011   (set_attr "mode" "QI")])
8012
8013;; ??? A bug in recog prevents it from recognizing a const_int as an
8014;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8015;; for a QImode operand, which of course failed.
8016(define_insn "andqi_ext_0"
8017  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8018			 (const_int 8)
8019			 (const_int 8))
8020	(and:SI
8021	  (zero_extract:SI
8022	    (match_operand 1 "ext_register_operand" "0")
8023	    (const_int 8)
8024	    (const_int 8))
8025	  (match_operand 2 "const_int_operand" "n")))
8026   (clobber (reg:CC FLAGS_REG))]
8027  ""
8028  "and{b}\t{%2, %h0|%h0, %2}"
8029  [(set_attr "type" "alu")
8030   (set_attr "length_immediate" "1")
8031   (set_attr "modrm" "1")
8032   (set_attr "mode" "QI")])
8033
8034;; Generated by peephole translating test to and.  This shows up
8035;; often in fp comparisons.
8036(define_insn "*andqi_ext_0_cc"
8037  [(set (reg FLAGS_REG)
8038	(compare
8039	  (and:SI
8040	    (zero_extract:SI
8041	      (match_operand 1 "ext_register_operand" "0")
8042	      (const_int 8)
8043	      (const_int 8))
8044	    (match_operand 2 "const_int_operand" "n"))
8045	  (const_int 0)))
8046   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8047			 (const_int 8)
8048			 (const_int 8))
8049	(and:SI
8050	  (zero_extract:SI
8051	    (match_dup 1)
8052	    (const_int 8)
8053	    (const_int 8))
8054	  (match_dup 2)))]
8055  "ix86_match_ccmode (insn, CCNOmode)"
8056  "and{b}\t{%2, %h0|%h0, %2}"
8057  [(set_attr "type" "alu")
8058   (set_attr "length_immediate" "1")
8059   (set_attr "modrm" "1")
8060   (set_attr "mode" "QI")])
8061
8062(define_insn "*andqi_ext_1_rex64"
8063  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8064			 (const_int 8)
8065			 (const_int 8))
8066	(and:SI
8067	  (zero_extract:SI
8068	    (match_operand 1 "ext_register_operand" "0")
8069	    (const_int 8)
8070	    (const_int 8))
8071	  (zero_extend:SI
8072	    (match_operand 2 "ext_register_operand" "Q"))))
8073   (clobber (reg:CC FLAGS_REG))]
8074  "TARGET_64BIT"
8075  "and{b}\t{%2, %h0|%h0, %2}"
8076  [(set_attr "type" "alu")
8077   (set_attr "length_immediate" "0")
8078   (set_attr "mode" "QI")])
8079
8080(define_insn "*andqi_ext_1"
8081  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8082			 (const_int 8)
8083			 (const_int 8))
8084	(and:SI
8085	  (zero_extract:SI
8086	    (match_operand 1 "ext_register_operand" "0")
8087	    (const_int 8)
8088	    (const_int 8))
8089	  (zero_extend:SI
8090	    (match_operand:QI 2 "general_operand" "Qm"))))
8091   (clobber (reg:CC FLAGS_REG))]
8092  "!TARGET_64BIT"
8093  "and{b}\t{%2, %h0|%h0, %2}"
8094  [(set_attr "type" "alu")
8095   (set_attr "length_immediate" "0")
8096   (set_attr "mode" "QI")])
8097
8098(define_insn "*andqi_ext_2"
8099  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8100			 (const_int 8)
8101			 (const_int 8))
8102	(and:SI
8103	  (zero_extract:SI
8104	    (match_operand 1 "ext_register_operand" "%0")
8105	    (const_int 8)
8106	    (const_int 8))
8107	  (zero_extract:SI
8108	    (match_operand 2 "ext_register_operand" "Q")
8109	    (const_int 8)
8110	    (const_int 8))))
8111   (clobber (reg:CC FLAGS_REG))]
8112  ""
8113  "and{b}\t{%h2, %h0|%h0, %h2}"
8114  [(set_attr "type" "alu")
8115   (set_attr "length_immediate" "0")
8116   (set_attr "mode" "QI")])
8117
8118;; Convert wide AND instructions with immediate operand to shorter QImode
8119;; equivalents when possible.
8120;; Don't do the splitting with memory operands, since it introduces risk
8121;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8122;; for size, but that can (should?) be handled by generic code instead.
8123(define_split
8124  [(set (match_operand 0 "register_operand" "")
8125	(and (match_operand 1 "register_operand" "")
8126	     (match_operand 2 "const_int_operand" "")))
8127   (clobber (reg:CC FLAGS_REG))]
8128   "reload_completed
8129    && QI_REG_P (operands[0])
8130    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8131    && !(~INTVAL (operands[2]) & ~(255 << 8))
8132    && GET_MODE (operands[0]) != QImode"
8133  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8134		   (and:SI (zero_extract:SI (match_dup 1)
8135					    (const_int 8) (const_int 8))
8136			   (match_dup 2)))
8137	      (clobber (reg:CC FLAGS_REG))])]
8138{
8139  operands[0] = gen_lowpart (SImode, operands[0]);
8140  operands[1] = gen_lowpart (SImode, operands[1]);
8141  operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8142})
8143
8144;; Since AND can be encoded with sign extended immediate, this is only
8145;; profitable when 7th bit is not set.
8146(define_split
8147  [(set (match_operand 0 "register_operand" "")
8148	(and (match_operand 1 "general_operand" "")
8149	     (match_operand 2 "const_int_operand" "")))
8150   (clobber (reg:CC FLAGS_REG))]
8151   "reload_completed
8152    && ANY_QI_REG_P (operands[0])
8153    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8154    && !(~INTVAL (operands[2]) & ~255)
8155    && !(INTVAL (operands[2]) & 128)
8156    && GET_MODE (operands[0]) != QImode"
8157  [(parallel [(set (strict_low_part (match_dup 0))
8158		   (and:QI (match_dup 1)
8159			   (match_dup 2)))
8160	      (clobber (reg:CC FLAGS_REG))])]
8161{
8162  operands[0] = gen_lowpart (QImode, operands[0]);
8163  operands[1] = gen_lowpart (QImode, operands[1]);
8164  operands[2] = gen_lowpart (QImode, operands[2]);
8165})
8166
8167;; Logical inclusive and exclusive OR instructions
8168
8169;; %%% This used to optimize known byte-wide and operations to memory.
8170;; If this is considered useful, it should be done with splitters.
8171
8172(define_expand "<code><mode>3"
8173  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8174	(any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8175		     (match_operand:SWIM 2 "<general_operand>" "")))]
8176  ""
8177  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8178
8179(define_insn "*<code><mode>_1"
8180  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8181	(any_or:SWI248
8182	 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8183	 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8184   (clobber (reg:CC FLAGS_REG))]
8185  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8186  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8187  [(set_attr "type" "alu")
8188   (set_attr "mode" "<MODE>")])
8189
8190;; %%% Potential partial reg stall on alternative 2.  What to do?
8191(define_insn "*<code>qi_1"
8192  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8193	(any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8194		   (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8195   (clobber (reg:CC FLAGS_REG))]
8196  "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8197  "@
8198   <logic>{b}\t{%2, %0|%0, %2}
8199   <logic>{b}\t{%2, %0|%0, %2}
8200   <logic>{l}\t{%k2, %k0|%k0, %k2}"
8201  [(set_attr "type" "alu")
8202   (set_attr "mode" "QI,QI,SI")])
8203
8204;; See comment for addsi_1_zext why we do use nonimmediate_operand
8205(define_insn "*<code>si_1_zext"
8206  [(set (match_operand:DI 0 "register_operand" "=r")
8207	(zero_extend:DI
8208	 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8209		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8210   (clobber (reg:CC FLAGS_REG))]
8211  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8212  "<logic>{l}\t{%2, %k0|%k0, %2}"
8213  [(set_attr "type" "alu")
8214   (set_attr "mode" "SI")])
8215
8216(define_insn "*<code>si_1_zext_imm"
8217  [(set (match_operand:DI 0 "register_operand" "=r")
8218	(any_or:DI
8219	 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8220	 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8221   (clobber (reg:CC FLAGS_REG))]
8222  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8223  "<logic>{l}\t{%2, %k0|%k0, %2}"
8224  [(set_attr "type" "alu")
8225   (set_attr "mode" "SI")])
8226
8227(define_insn "*<code>qi_1_slp"
8228  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8229	(any_or:QI (match_dup 0)
8230		   (match_operand:QI 1 "general_operand" "qmn,qn")))
8231   (clobber (reg:CC FLAGS_REG))]
8232  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8233   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8234  "<logic>{b}\t{%1, %0|%0, %1}"
8235  [(set_attr "type" "alu1")
8236   (set_attr "mode" "QI")])
8237
8238(define_insn "*<code><mode>_2"
8239  [(set (reg FLAGS_REG)
8240	(compare (any_or:SWI
8241		  (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8242		  (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8243		 (const_int 0)))
8244   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8245	(any_or:SWI (match_dup 1) (match_dup 2)))]
8246  "ix86_match_ccmode (insn, CCNOmode)
8247   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8248  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8249  [(set_attr "type" "alu")
8250   (set_attr "mode" "<MODE>")])
8251
8252;; See comment for addsi_1_zext why we do use nonimmediate_operand
8253;; ??? Special case for immediate operand is missing - it is tricky.
8254(define_insn "*<code>si_2_zext"
8255  [(set (reg FLAGS_REG)
8256	(compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8257			    (match_operand:SI 2 "x86_64_general_operand" "rme"))
8258		 (const_int 0)))
8259   (set (match_operand:DI 0 "register_operand" "=r")
8260	(zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8261  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8262   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8263  "<logic>{l}\t{%2, %k0|%k0, %2}"
8264  [(set_attr "type" "alu")
8265   (set_attr "mode" "SI")])
8266
8267(define_insn "*<code>si_2_zext_imm"
8268  [(set (reg FLAGS_REG)
8269	(compare (any_or:SI
8270		  (match_operand:SI 1 "nonimmediate_operand" "%0")
8271		  (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8272		 (const_int 0)))
8273   (set (match_operand:DI 0 "register_operand" "=r")
8274	(any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8275  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8276   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8277  "<logic>{l}\t{%2, %k0|%k0, %2}"
8278  [(set_attr "type" "alu")
8279   (set_attr "mode" "SI")])
8280
8281(define_insn "*<code>qi_2_slp"
8282  [(set (reg FLAGS_REG)
8283	(compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8284			    (match_operand:QI 1 "general_operand" "qmn,qn"))
8285		 (const_int 0)))
8286   (set (strict_low_part (match_dup 0))
8287	(any_or:QI (match_dup 0) (match_dup 1)))]
8288  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8289   && ix86_match_ccmode (insn, CCNOmode)
8290   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8291  "<logic>{b}\t{%1, %0|%0, %1}"
8292  [(set_attr "type" "alu1")
8293   (set_attr "mode" "QI")])
8294
8295(define_insn "*<code><mode>_3"
8296  [(set (reg FLAGS_REG)
8297	(compare (any_or:SWI
8298		  (match_operand:SWI 1 "nonimmediate_operand" "%0")
8299		  (match_operand:SWI 2 "<general_operand>" "<g>"))
8300		 (const_int 0)))
8301   (clobber (match_scratch:SWI 0 "=<r>"))]
8302  "ix86_match_ccmode (insn, CCNOmode)
8303   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8304  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8305  [(set_attr "type" "alu")
8306   (set_attr "mode" "<MODE>")])
8307
8308(define_insn "*<code>qi_ext_0"
8309  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8310			 (const_int 8)
8311			 (const_int 8))
8312	(any_or:SI
8313	  (zero_extract:SI
8314	    (match_operand 1 "ext_register_operand" "0")
8315	    (const_int 8)
8316	    (const_int 8))
8317	  (match_operand 2 "const_int_operand" "n")))
8318   (clobber (reg:CC FLAGS_REG))]
8319  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8320  "<logic>{b}\t{%2, %h0|%h0, %2}"
8321  [(set_attr "type" "alu")
8322   (set_attr "length_immediate" "1")
8323   (set_attr "modrm" "1")
8324   (set_attr "mode" "QI")])
8325
8326(define_insn "*<code>qi_ext_1_rex64"
8327  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8328			 (const_int 8)
8329			 (const_int 8))
8330	(any_or:SI
8331	  (zero_extract:SI
8332	    (match_operand 1 "ext_register_operand" "0")
8333	    (const_int 8)
8334	    (const_int 8))
8335	  (zero_extend:SI
8336	    (match_operand 2 "ext_register_operand" "Q"))))
8337   (clobber (reg:CC FLAGS_REG))]
8338  "TARGET_64BIT
8339   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8340  "<logic>{b}\t{%2, %h0|%h0, %2}"
8341  [(set_attr "type" "alu")
8342   (set_attr "length_immediate" "0")
8343   (set_attr "mode" "QI")])
8344
8345(define_insn "*<code>qi_ext_1"
8346  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8347			 (const_int 8)
8348			 (const_int 8))
8349	(any_or:SI
8350	  (zero_extract:SI
8351	    (match_operand 1 "ext_register_operand" "0")
8352	    (const_int 8)
8353	    (const_int 8))
8354	  (zero_extend:SI
8355	    (match_operand:QI 2 "general_operand" "Qm"))))
8356   (clobber (reg:CC FLAGS_REG))]
8357  "!TARGET_64BIT
8358   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8359  "<logic>{b}\t{%2, %h0|%h0, %2}"
8360  [(set_attr "type" "alu")
8361   (set_attr "length_immediate" "0")
8362   (set_attr "mode" "QI")])
8363
8364(define_insn "*<code>qi_ext_2"
8365  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366			 (const_int 8)
8367			 (const_int 8))
8368	(any_or:SI
8369	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8370	  		   (const_int 8)
8371			   (const_int 8))
8372	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8373	  		   (const_int 8)
8374			   (const_int 8))))
8375   (clobber (reg:CC FLAGS_REG))]
8376  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8377  "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8378  [(set_attr "type" "alu")
8379   (set_attr "length_immediate" "0")
8380   (set_attr "mode" "QI")])
8381
8382(define_split
8383  [(set (match_operand 0 "register_operand" "")
8384	(any_or (match_operand 1 "register_operand" "")
8385		(match_operand 2 "const_int_operand" "")))
8386   (clobber (reg:CC FLAGS_REG))]
8387   "reload_completed
8388    && QI_REG_P (operands[0])
8389    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8390    && !(INTVAL (operands[2]) & ~(255 << 8))
8391    && GET_MODE (operands[0]) != QImode"
8392  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8393		   (any_or:SI (zero_extract:SI (match_dup 1)
8394					       (const_int 8) (const_int 8))
8395			      (match_dup 2)))
8396	      (clobber (reg:CC FLAGS_REG))])]
8397{
8398  operands[0] = gen_lowpart (SImode, operands[0]);
8399  operands[1] = gen_lowpart (SImode, operands[1]);
8400  operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8401})
8402
8403;; Since OR can be encoded with sign extended immediate, this is only
8404;; profitable when 7th bit is set.
8405(define_split
8406  [(set (match_operand 0 "register_operand" "")
8407	(any_or (match_operand 1 "general_operand" "")
8408		(match_operand 2 "const_int_operand" "")))
8409   (clobber (reg:CC FLAGS_REG))]
8410   "reload_completed
8411    && ANY_QI_REG_P (operands[0])
8412    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413    && !(INTVAL (operands[2]) & ~255)
8414    && (INTVAL (operands[2]) & 128)
8415    && GET_MODE (operands[0]) != QImode"
8416  [(parallel [(set (strict_low_part (match_dup 0))
8417		   (any_or:QI (match_dup 1)
8418			      (match_dup 2)))
8419	      (clobber (reg:CC FLAGS_REG))])]
8420{
8421  operands[0] = gen_lowpart (QImode, operands[0]);
8422  operands[1] = gen_lowpart (QImode, operands[1]);
8423  operands[2] = gen_lowpart (QImode, operands[2]);
8424})
8425
8426(define_expand "xorqi_cc_ext_1"
8427  [(parallel [
8428     (set (reg:CCNO FLAGS_REG)
8429	  (compare:CCNO
8430	    (xor:SI
8431	      (zero_extract:SI
8432		(match_operand 1 "ext_register_operand" "")
8433		(const_int 8)
8434		(const_int 8))
8435	      (match_operand:QI 2 "general_operand" ""))
8436	    (const_int 0)))
8437     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8438			   (const_int 8)
8439			   (const_int 8))
8440	  (xor:SI
8441	    (zero_extract:SI
8442	     (match_dup 1)
8443	     (const_int 8)
8444	     (const_int 8))
8445	    (match_dup 2)))])])
8446
8447(define_insn "*xorqi_cc_ext_1_rex64"
8448  [(set (reg FLAGS_REG)
8449	(compare
8450	  (xor:SI
8451	    (zero_extract:SI
8452	      (match_operand 1 "ext_register_operand" "0")
8453	      (const_int 8)
8454	      (const_int 8))
8455	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
8456	  (const_int 0)))
8457   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8458			 (const_int 8)
8459			 (const_int 8))
8460	(xor:SI
8461	  (zero_extract:SI
8462	   (match_dup 1)
8463	   (const_int 8)
8464	   (const_int 8))
8465	  (match_dup 2)))]
8466  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8467  "xor{b}\t{%2, %h0|%h0, %2}"
8468  [(set_attr "type" "alu")
8469   (set_attr "modrm" "1")
8470   (set_attr "mode" "QI")])
8471
8472(define_insn "*xorqi_cc_ext_1"
8473  [(set (reg FLAGS_REG)
8474	(compare
8475	  (xor:SI
8476	    (zero_extract:SI
8477	      (match_operand 1 "ext_register_operand" "0")
8478	      (const_int 8)
8479	      (const_int 8))
8480	    (match_operand:QI 2 "general_operand" "qmn"))
8481	  (const_int 0)))
8482   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8483			 (const_int 8)
8484			 (const_int 8))
8485	(xor:SI
8486	  (zero_extract:SI
8487	   (match_dup 1)
8488	   (const_int 8)
8489	   (const_int 8))
8490	  (match_dup 2)))]
8491  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8492  "xor{b}\t{%2, %h0|%h0, %2}"
8493  [(set_attr "type" "alu")
8494   (set_attr "modrm" "1")
8495   (set_attr "mode" "QI")])
8496
8497;; Negation instructions
8498
8499(define_expand "neg<mode>2"
8500  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8501	(neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8502  ""
8503  "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8504
8505(define_insn_and_split "*neg<dwi>2_doubleword"
8506  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8507	(neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8508   (clobber (reg:CC FLAGS_REG))]
8509  "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8510  "#"
8511  "reload_completed"
8512  [(parallel
8513    [(set (reg:CCZ FLAGS_REG)
8514	  (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8515     (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8516   (parallel
8517    [(set (match_dup 2)
8518	  (plus:DWIH (match_dup 3)
8519		     (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8520				(const_int 0))))
8521     (clobber (reg:CC FLAGS_REG))])
8522   (parallel
8523    [(set (match_dup 2)
8524	  (neg:DWIH (match_dup 2)))
8525     (clobber (reg:CC FLAGS_REG))])]
8526  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8527
8528(define_insn "*neg<mode>2_1"
8529  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8530	(neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8531   (clobber (reg:CC FLAGS_REG))]
8532  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8533  "neg{<imodesuffix>}\t%0"
8534  [(set_attr "type" "negnot")
8535   (set_attr "mode" "<MODE>")])
8536
8537;; Combine is quite creative about this pattern.
8538(define_insn "*negsi2_1_zext"
8539  [(set (match_operand:DI 0 "register_operand" "=r")
8540	(lshiftrt:DI
8541	  (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8542			     (const_int 32)))
8543	(const_int 32)))
8544   (clobber (reg:CC FLAGS_REG))]
8545  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8546  "neg{l}\t%k0"
8547  [(set_attr "type" "negnot")
8548   (set_attr "mode" "SI")])
8549
8550;; The problem with neg is that it does not perform (compare x 0),
8551;; it really performs (compare 0 x), which leaves us with the zero
8552;; flag being the only useful item.
8553
8554(define_insn "*neg<mode>2_cmpz"
8555  [(set (reg:CCZ FLAGS_REG)
8556	(compare:CCZ
8557	  (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8558		   (const_int 0)))
8559   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8560	(neg:SWI (match_dup 1)))]
8561  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8562  "neg{<imodesuffix>}\t%0"
8563  [(set_attr "type" "negnot")
8564   (set_attr "mode" "<MODE>")])
8565
8566(define_insn "*negsi2_cmpz_zext"
8567  [(set (reg:CCZ FLAGS_REG)
8568	(compare:CCZ
8569	  (lshiftrt:DI
8570	    (neg:DI (ashift:DI
8571		      (match_operand:DI 1 "register_operand" "0")
8572		      (const_int 32)))
8573	    (const_int 32))
8574	  (const_int 0)))
8575   (set (match_operand:DI 0 "register_operand" "=r")
8576	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8577					(const_int 32)))
8578		     (const_int 32)))]
8579  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8580  "neg{l}\t%k0"
8581  [(set_attr "type" "negnot")
8582   (set_attr "mode" "SI")])
8583
8584;; Changing of sign for FP values is doable using integer unit too.
8585
8586(define_expand "<code><mode>2"
8587  [(set (match_operand:X87MODEF 0 "register_operand" "")
8588	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8589  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8590  "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8591
8592(define_insn "*absneg<mode>2_mixed"
8593  [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8594	(match_operator:MODEF 3 "absneg_operator"
8595	  [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8596   (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8597   (clobber (reg:CC FLAGS_REG))]
8598  "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8599  "#")
8600
8601(define_insn "*absneg<mode>2_sse"
8602  [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8603	(match_operator:MODEF 3 "absneg_operator"
8604	  [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8605   (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8606   (clobber (reg:CC FLAGS_REG))]
8607  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8608  "#")
8609
8610(define_insn "*absneg<mode>2_i387"
8611  [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8612	(match_operator:X87MODEF 3 "absneg_operator"
8613	  [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8614   (use (match_operand 2 "" ""))
8615   (clobber (reg:CC FLAGS_REG))]
8616  "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8617  "#")
8618
8619(define_expand "<code>tf2"
8620  [(set (match_operand:TF 0 "register_operand" "")
8621	(absneg:TF (match_operand:TF 1 "register_operand" "")))]
8622  "TARGET_SSE2"
8623  "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8624
8625(define_insn "*absnegtf2_sse"
8626  [(set (match_operand:TF 0 "register_operand" "=x,x")
8627	(match_operator:TF 3 "absneg_operator"
8628	  [(match_operand:TF 1 "register_operand" "0,x")]))
8629   (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8630   (clobber (reg:CC FLAGS_REG))]
8631  "TARGET_SSE2"
8632  "#")
8633
8634;; Splitters for fp abs and neg.
8635
8636(define_split
8637  [(set (match_operand 0 "fp_register_operand" "")
8638	(match_operator 1 "absneg_operator" [(match_dup 0)]))
8639   (use (match_operand 2 "" ""))
8640   (clobber (reg:CC FLAGS_REG))]
8641  "reload_completed"
8642  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8643
8644(define_split
8645  [(set (match_operand 0 "register_operand" "")
8646	(match_operator 3 "absneg_operator"
8647	  [(match_operand 1 "register_operand" "")]))
8648   (use (match_operand 2 "nonimmediate_operand" ""))
8649   (clobber (reg:CC FLAGS_REG))]
8650  "reload_completed && SSE_REG_P (operands[0])"
8651  [(set (match_dup 0) (match_dup 3))]
8652{
8653  enum machine_mode mode = GET_MODE (operands[0]);
8654  enum machine_mode vmode = GET_MODE (operands[2]);
8655  rtx tmp;
8656
8657  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8658  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8659  if (operands_match_p (operands[0], operands[2]))
8660    {
8661      tmp = operands[1];
8662      operands[1] = operands[2];
8663      operands[2] = tmp;
8664    }
8665  if (GET_CODE (operands[3]) == ABS)
8666    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8667  else
8668    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8669  operands[3] = tmp;
8670})
8671
8672(define_split
8673  [(set (match_operand:SF 0 "register_operand" "")
8674	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8675   (use (match_operand:V4SF 2 "" ""))
8676   (clobber (reg:CC FLAGS_REG))]
8677  "reload_completed"
8678  [(parallel [(set (match_dup 0) (match_dup 1))
8679	      (clobber (reg:CC FLAGS_REG))])]
8680{
8681  rtx tmp;
8682  operands[0] = gen_lowpart (SImode, operands[0]);
8683  if (GET_CODE (operands[1]) == ABS)
8684    {
8685      tmp = gen_int_mode (0x7fffffff, SImode);
8686      tmp = gen_rtx_AND (SImode, operands[0], tmp);
8687    }
8688  else
8689    {
8690      tmp = gen_int_mode (0x80000000, SImode);
8691      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8692    }
8693  operands[1] = tmp;
8694})
8695
8696(define_split
8697  [(set (match_operand:DF 0 "register_operand" "")
8698	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8699   (use (match_operand 2 "" ""))
8700   (clobber (reg:CC FLAGS_REG))]
8701  "reload_completed"
8702  [(parallel [(set (match_dup 0) (match_dup 1))
8703	      (clobber (reg:CC FLAGS_REG))])]
8704{
8705  rtx tmp;
8706  if (TARGET_64BIT)
8707    {
8708      tmp = gen_lowpart (DImode, operands[0]);
8709      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8710      operands[0] = tmp;
8711
8712      if (GET_CODE (operands[1]) == ABS)
8713	tmp = const0_rtx;
8714      else
8715	tmp = gen_rtx_NOT (DImode, tmp);
8716    }
8717  else
8718    {
8719      operands[0] = gen_highpart (SImode, operands[0]);
8720      if (GET_CODE (operands[1]) == ABS)
8721	{
8722	  tmp = gen_int_mode (0x7fffffff, SImode);
8723	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
8724	}
8725      else
8726	{
8727	  tmp = gen_int_mode (0x80000000, SImode);
8728	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8729	}
8730    }
8731  operands[1] = tmp;
8732})
8733
8734(define_split
8735  [(set (match_operand:XF 0 "register_operand" "")
8736	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8737   (use (match_operand 2 "" ""))
8738   (clobber (reg:CC FLAGS_REG))]
8739  "reload_completed"
8740  [(parallel [(set (match_dup 0) (match_dup 1))
8741	      (clobber (reg:CC FLAGS_REG))])]
8742{
8743  rtx tmp;
8744  operands[0] = gen_rtx_REG (SImode,
8745			     true_regnum (operands[0])
8746			     + (TARGET_64BIT ? 1 : 2));
8747  if (GET_CODE (operands[1]) == ABS)
8748    {
8749      tmp = GEN_INT (0x7fff);
8750      tmp = gen_rtx_AND (SImode, operands[0], tmp);
8751    }
8752  else
8753    {
8754      tmp = GEN_INT (0x8000);
8755      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8756    }
8757  operands[1] = tmp;
8758})
8759
8760;; Conditionalize these after reload. If they match before reload, we
8761;; lose the clobber and ability to use integer instructions.
8762
8763(define_insn "*<code><mode>2_1"
8764  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8765	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8766  "TARGET_80387
8767   && (reload_completed
8768       || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8769  "f<absneg_mnemonic>"
8770  [(set_attr "type" "fsgn")
8771   (set_attr "mode" "<MODE>")])
8772
8773(define_insn "*<code>extendsfdf2"
8774  [(set (match_operand:DF 0 "register_operand" "=f")
8775	(absneg:DF (float_extend:DF
8776		     (match_operand:SF 1 "register_operand" "0"))))]
8777  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8778  "f<absneg_mnemonic>"
8779  [(set_attr "type" "fsgn")
8780   (set_attr "mode" "DF")])
8781
8782(define_insn "*<code>extendsfxf2"
8783  [(set (match_operand:XF 0 "register_operand" "=f")
8784	(absneg:XF (float_extend:XF
8785		     (match_operand:SF 1 "register_operand" "0"))))]
8786  "TARGET_80387"
8787  "f<absneg_mnemonic>"
8788  [(set_attr "type" "fsgn")
8789   (set_attr "mode" "XF")])
8790
8791(define_insn "*<code>extenddfxf2"
8792  [(set (match_operand:XF 0 "register_operand" "=f")
8793	(absneg:XF (float_extend:XF
8794		     (match_operand:DF 1 "register_operand" "0"))))]
8795  "TARGET_80387"
8796  "f<absneg_mnemonic>"
8797  [(set_attr "type" "fsgn")
8798   (set_attr "mode" "XF")])
8799
8800;; Copysign instructions
8801
8802(define_mode_iterator CSGNMODE [SF DF TF])
8803(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8804
8805(define_expand "copysign<mode>3"
8806  [(match_operand:CSGNMODE 0 "register_operand" "")
8807   (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8808   (match_operand:CSGNMODE 2 "register_operand" "")]
8809  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8811  "ix86_expand_copysign (operands); DONE;")
8812
8813(define_insn_and_split "copysign<mode>3_const"
8814  [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8815	(unspec:CSGNMODE
8816	  [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8817	   (match_operand:CSGNMODE 2 "register_operand" "0")
8818	   (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8819	  UNSPEC_COPYSIGN))]
8820  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8821   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8822  "#"
8823  "&& reload_completed"
8824  [(const_int 0)]
8825  "ix86_split_copysign_const (operands); DONE;")
8826
8827(define_insn "copysign<mode>3_var"
8828  [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8829	(unspec:CSGNMODE
8830	  [(match_operand:CSGNMODE 2 "register_operand"	"x,0,0,x,x")
8831	   (match_operand:CSGNMODE 3 "register_operand"	"1,1,x,1,x")
8832	   (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8833	   (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8834	  UNSPEC_COPYSIGN))
8835   (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8836  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8837   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8838  "#")
8839
8840(define_split
8841  [(set (match_operand:CSGNMODE 0 "register_operand" "")
8842	(unspec:CSGNMODE
8843	  [(match_operand:CSGNMODE 2 "register_operand" "")
8844	   (match_operand:CSGNMODE 3 "register_operand" "")
8845	   (match_operand:<CSGNVMODE> 4 "" "")
8846	   (match_operand:<CSGNVMODE> 5 "" "")]
8847	  UNSPEC_COPYSIGN))
8848   (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8849  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8850    || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8851   && reload_completed"
8852  [(const_int 0)]
8853  "ix86_split_copysign_var (operands); DONE;")
8854
8855;; One complement instructions
8856
8857(define_expand "one_cmpl<mode>2"
8858  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8859	(not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8860  ""
8861  "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8862
8863(define_insn "*one_cmpl<mode>2_1"
8864  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8865	(not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8866  "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8867  "not{<imodesuffix>}\t%0"
8868  [(set_attr "type" "negnot")
8869   (set_attr "mode" "<MODE>")])
8870
8871;; %%% Potential partial reg stall on alternative 1.  What to do?
8872(define_insn "*one_cmplqi2_1"
8873  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8874	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8875  "ix86_unary_operator_ok (NOT, QImode, operands)"
8876  "@
8877   not{b}\t%0
8878   not{l}\t%k0"
8879  [(set_attr "type" "negnot")
8880   (set_attr "mode" "QI,SI")])
8881
8882;; ??? Currently never generated - xor is used instead.
8883(define_insn "*one_cmplsi2_1_zext"
8884  [(set (match_operand:DI 0 "register_operand" "=r")
8885	(zero_extend:DI
8886	  (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8887  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8888  "not{l}\t%k0"
8889  [(set_attr "type" "negnot")
8890   (set_attr "mode" "SI")])
8891
8892(define_insn "*one_cmpl<mode>2_2"
8893  [(set (reg FLAGS_REG)
8894	(compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8895		 (const_int 0)))
8896   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8897	(not:SWI (match_dup 1)))]
8898  "ix86_match_ccmode (insn, CCNOmode)
8899   && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8900  "#"
8901  [(set_attr "type" "alu1")
8902   (set_attr "mode" "<MODE>")])
8903
8904(define_split
8905  [(set (match_operand 0 "flags_reg_operand" "")
8906	(match_operator 2 "compare_operator"
8907	  [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8908	   (const_int 0)]))
8909   (set (match_operand:SWI 1 "nonimmediate_operand" "")
8910	(not:SWI (match_dup 3)))]
8911  "ix86_match_ccmode (insn, CCNOmode)"
8912  [(parallel [(set (match_dup 0)
8913		   (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8914				    (const_int 0)]))
8915	      (set (match_dup 1)
8916		   (xor:SWI (match_dup 3) (const_int -1)))])])
8917
8918;; ??? Currently never generated - xor is used instead.
8919(define_insn "*one_cmplsi2_2_zext"
8920  [(set (reg FLAGS_REG)
8921	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8922		 (const_int 0)))
8923   (set (match_operand:DI 0 "register_operand" "=r")
8924	(zero_extend:DI (not:SI (match_dup 1))))]
8925  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8926   && ix86_unary_operator_ok (NOT, SImode, operands)"
8927  "#"
8928  [(set_attr "type" "alu1")
8929   (set_attr "mode" "SI")])
8930
8931(define_split
8932  [(set (match_operand 0 "flags_reg_operand" "")
8933	(match_operator 2 "compare_operator"
8934	  [(not:SI (match_operand:SI 3 "register_operand" ""))
8935	   (const_int 0)]))
8936   (set (match_operand:DI 1 "register_operand" "")
8937	(zero_extend:DI (not:SI (match_dup 3))))]
8938  "ix86_match_ccmode (insn, CCNOmode)"
8939  [(parallel [(set (match_dup 0)
8940		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8941				    (const_int 0)]))
8942	      (set (match_dup 1)
8943		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8944
8945;; Shift instructions
8946
8947;; DImode shifts are implemented using the i386 "shift double" opcode,
8948;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8949;; is variable, then the count is in %cl and the "imm" operand is dropped
8950;; from the assembler input.
8951;;
8952;; This instruction shifts the target reg/mem as usual, but instead of
8953;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8954;; is a left shift double, bits are taken from the high order bits of
8955;; reg, else if the insn is a shift right double, bits are taken from the
8956;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8957;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8958;;
8959;; Since sh[lr]d does not change the `reg' operand, that is done
8960;; separately, making all shifts emit pairs of shift double and normal
8961;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8962;; support a 63 bit shift, each shift where the count is in a reg expands
8963;; to a pair of shifts, a branch, a shift by 32 and a label.
8964;;
8965;; If the shift count is a constant, we need never emit more than one
8966;; shift pair, instead using moves and sign extension for counts greater
8967;; than 31.
8968
8969(define_expand "ashl<mode>3"
8970  [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8971	(ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8972		      (match_operand:QI 2 "nonmemory_operand" "")))]
8973  ""
8974  "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8975
8976(define_insn "*ashl<mode>3_doubleword"
8977  [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8978	(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8979		    (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8980   (clobber (reg:CC FLAGS_REG))]
8981  ""
8982  "#"
8983  [(set_attr "type" "multi")])
8984
8985(define_split
8986  [(set (match_operand:DWI 0 "register_operand" "")
8987	(ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8988		    (match_operand:QI 2 "nonmemory_operand" "")))
8989   (clobber (reg:CC FLAGS_REG))]
8990  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8991  [(const_int 0)]
8992  "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8993
8994;; By default we don't ask for a scratch register, because when DWImode
8995;; values are manipulated, registers are already at a premium.  But if
8996;; we have one handy, we won't turn it away.
8997
8998(define_peephole2
8999  [(match_scratch:DWIH 3 "r")
9000   (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9001		   (ashift:<DWI>
9002		     (match_operand:<DWI> 1 "nonmemory_operand" "")
9003		     (match_operand:QI 2 "nonmemory_operand" "")))
9004	      (clobber (reg:CC FLAGS_REG))])
9005   (match_dup 3)]
9006  "TARGET_CMOVE"
9007  [(const_int 0)]
9008  "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9009
9010(define_insn "x86_64_shld"
9011  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9012        (ior:DI (ashift:DI (match_dup 0)
9013		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
9014		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9015		  (minus:QI (const_int 64) (match_dup 2)))))
9016   (clobber (reg:CC FLAGS_REG))]
9017  "TARGET_64BIT"
9018  "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9019  [(set_attr "type" "ishift")
9020   (set_attr "prefix_0f" "1")
9021   (set_attr "mode" "DI")
9022   (set_attr "athlon_decode" "vector")
9023   (set_attr "amdfam10_decode" "vector")
9024   (set_attr "bdver1_decode" "vector")])
9025
9026(define_insn "x86_shld"
9027  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9028        (ior:SI (ashift:SI (match_dup 0)
9029		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
9030		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9031		  (minus:QI (const_int 32) (match_dup 2)))))
9032   (clobber (reg:CC FLAGS_REG))]
9033  ""
9034  "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9035  [(set_attr "type" "ishift")
9036   (set_attr "prefix_0f" "1")
9037   (set_attr "mode" "SI")
9038   (set_attr "pent_pair" "np")
9039   (set_attr "athlon_decode" "vector")
9040   (set_attr "amdfam10_decode" "vector")
9041   (set_attr "bdver1_decode" "vector")])
9042
9043(define_expand "x86_shift<mode>_adj_1"
9044  [(set (reg:CCZ FLAGS_REG)
9045	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9046			     (match_dup 4))
9047		     (const_int 0)))
9048   (set (match_operand:SWI48 0 "register_operand" "")
9049        (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9050			    (match_operand:SWI48 1 "register_operand" "")
9051			    (match_dup 0)))
9052   (set (match_dup 1)
9053	(if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9054			    (match_operand:SWI48 3 "register_operand" "")
9055			    (match_dup 1)))]
9056  "TARGET_CMOVE"
9057  "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9058
9059(define_expand "x86_shift<mode>_adj_2"
9060  [(use (match_operand:SWI48 0 "register_operand" ""))
9061   (use (match_operand:SWI48 1 "register_operand" ""))
9062   (use (match_operand:QI 2 "register_operand" ""))]
9063  ""
9064{
9065  rtx label = gen_label_rtx ();
9066  rtx tmp;
9067
9068  emit_insn (gen_testqi_ccz_1 (operands[2],
9069			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9070
9071  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9072  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9073  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9074			      gen_rtx_LABEL_REF (VOIDmode, label),
9075			      pc_rtx);
9076  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9077  JUMP_LABEL (tmp) = label;
9078
9079  emit_move_insn (operands[0], operands[1]);
9080  ix86_expand_clear (operands[1]);
9081
9082  emit_label (label);
9083  LABEL_NUSES (label) = 1;
9084
9085  DONE;
9086})
9087
9088;; Avoid useless masking of count operand.
9089(define_insn "*ashl<mode>3_mask"
9090  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9091	(ashift:SWI48
9092	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
9093	  (subreg:QI
9094	    (and:SI
9095	      (match_operand:SI 2 "register_operand" "c")
9096	      (match_operand:SI 3 "const_int_operand" "n")) 0)))
9097   (clobber (reg:CC FLAGS_REG))]
9098  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9099   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9100      == GET_MODE_BITSIZE (<MODE>mode)-1"
9101{
9102  return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9103}
9104  [(set_attr "type" "ishift")
9105   (set_attr "mode" "<MODE>")])
9106
9107(define_insn "*bmi2_ashl<mode>3_1"
9108  [(set (match_operand:SWI48 0 "register_operand" "=r")
9109	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9110		      (match_operand:SWI48 2 "register_operand" "r")))]
9111  "TARGET_BMI2"
9112  "shlx\t{%2, %1, %0|%0, %1, %2}"
9113  [(set_attr "type" "ishiftx")
9114   (set_attr "mode" "<MODE>")])
9115
9116(define_insn "*ashl<mode>3_1"
9117  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9118	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9119		      (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9120   (clobber (reg:CC FLAGS_REG))]
9121  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9122{
9123  switch (get_attr_type (insn))
9124    {
9125    case TYPE_LEA:
9126    case TYPE_ISHIFTX:
9127      return "#";
9128
9129    case TYPE_ALU:
9130      gcc_assert (operands[2] == const1_rtx);
9131      gcc_assert (rtx_equal_p (operands[0], operands[1]));
9132      return "add{<imodesuffix>}\t%0, %0";
9133
9134    default:
9135      if (operands[2] == const1_rtx
9136	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9137	return "sal{<imodesuffix>}\t%0";
9138      else
9139	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9140    }
9141}
9142  [(set_attr "isa" "*,*,bmi2")
9143   (set (attr "type")
9144     (cond [(eq_attr "alternative" "1")
9145	      (const_string "lea")
9146	    (eq_attr "alternative" "2")
9147	      (const_string "ishiftx")
9148            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9149		      (match_operand 0 "register_operand" ""))
9150		 (match_operand 2 "const1_operand" ""))
9151	      (const_string "alu")
9152	   ]
9153	   (const_string "ishift")))
9154   (set (attr "length_immediate")
9155     (if_then_else
9156       (ior (eq_attr "type" "alu")
9157	    (and (eq_attr "type" "ishift")
9158		 (and (match_operand 2 "const1_operand" "")
9159		      (ior (match_test "TARGET_SHIFT1")
9160			   (match_test "optimize_function_for_size_p (cfun)")))))
9161       (const_string "0")
9162       (const_string "*")))
9163   (set_attr "mode" "<MODE>")])
9164
9165;; Convert shift to the shiftx pattern to avoid flags dependency.
9166(define_split
9167  [(set (match_operand:SWI48 0 "register_operand" "")
9168	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9169		      (match_operand:QI 2 "register_operand" "")))
9170   (clobber (reg:CC FLAGS_REG))]
9171  "TARGET_BMI2 && reload_completed"
9172  [(set (match_dup 0)
9173	(ashift:SWI48 (match_dup 1) (match_dup 2)))]
9174  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9175
9176(define_insn "*bmi2_ashlsi3_1_zext"
9177  [(set (match_operand:DI 0 "register_operand" "=r")
9178	(zero_extend:DI
9179	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9180		     (match_operand:SI 2 "register_operand" "r"))))]
9181  "TARGET_64BIT && TARGET_BMI2"
9182  "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9183  [(set_attr "type" "ishiftx")
9184   (set_attr "mode" "SI")])
9185
9186(define_insn "*ashlsi3_1_zext"
9187  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9188	(zero_extend:DI
9189	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9190		     (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9191   (clobber (reg:CC FLAGS_REG))]
9192  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9193{
9194  switch (get_attr_type (insn))
9195    {
9196    case TYPE_LEA:
9197    case TYPE_ISHIFTX:
9198      return "#";
9199
9200    case TYPE_ALU:
9201      gcc_assert (operands[2] == const1_rtx);
9202      return "add{l}\t%k0, %k0";
9203
9204    default:
9205      if (operands[2] == const1_rtx
9206	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9207	return "sal{l}\t%k0";
9208      else
9209	return "sal{l}\t{%2, %k0|%k0, %2}";
9210    }
9211}
9212  [(set_attr "isa" "*,*,bmi2")
9213   (set (attr "type")
9214     (cond [(eq_attr "alternative" "1")
9215	      (const_string "lea")
9216	    (eq_attr "alternative" "2")
9217	      (const_string "ishiftx")
9218            (and (match_test "TARGET_DOUBLE_WITH_ADD")
9219		 (match_operand 2 "const1_operand" ""))
9220	      (const_string "alu")
9221	   ]
9222	   (const_string "ishift")))
9223   (set (attr "length_immediate")
9224     (if_then_else
9225       (ior (eq_attr "type" "alu")
9226	    (and (eq_attr "type" "ishift")
9227		 (and (match_operand 2 "const1_operand" "")
9228		      (ior (match_test "TARGET_SHIFT1")
9229			   (match_test "optimize_function_for_size_p (cfun)")))))
9230       (const_string "0")
9231       (const_string "*")))
9232   (set_attr "mode" "SI")])
9233
9234;; Convert shift to the shiftx pattern to avoid flags dependency.
9235(define_split
9236  [(set (match_operand:DI 0 "register_operand" "")
9237	(zero_extend:DI
9238	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9239		     (match_operand:QI 2 "register_operand" ""))))
9240   (clobber (reg:CC FLAGS_REG))]
9241  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9242  [(set (match_dup 0)
9243	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9244  "operands[2] = gen_lowpart (SImode, operands[2]);")
9245
9246(define_insn "*ashlhi3_1"
9247  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9248	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9249		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9250   (clobber (reg:CC FLAGS_REG))]
9251  "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9252{
9253  switch (get_attr_type (insn))
9254    {
9255    case TYPE_LEA:
9256      return "#";
9257
9258    case TYPE_ALU:
9259      gcc_assert (operands[2] == const1_rtx);
9260      return "add{w}\t%0, %0";
9261
9262    default:
9263      if (operands[2] == const1_rtx
9264	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265	return "sal{w}\t%0";
9266      else
9267	return "sal{w}\t{%2, %0|%0, %2}";
9268    }
9269}
9270  [(set (attr "type")
9271     (cond [(eq_attr "alternative" "1")
9272	      (const_string "lea")
9273            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9274		      (match_operand 0 "register_operand" ""))
9275		 (match_operand 2 "const1_operand" ""))
9276	      (const_string "alu")
9277	   ]
9278	   (const_string "ishift")))
9279   (set (attr "length_immediate")
9280     (if_then_else
9281       (ior (eq_attr "type" "alu")
9282	    (and (eq_attr "type" "ishift")
9283		 (and (match_operand 2 "const1_operand" "")
9284		      (ior (match_test "TARGET_SHIFT1")
9285			   (match_test "optimize_function_for_size_p (cfun)")))))
9286       (const_string "0")
9287       (const_string "*")))
9288   (set_attr "mode" "HI,SI")])
9289
9290;; %%% Potential partial reg stall on alternative 1.  What to do?
9291(define_insn "*ashlqi3_1"
9292  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9293	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9294		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9295   (clobber (reg:CC FLAGS_REG))]
9296  "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9297{
9298  switch (get_attr_type (insn))
9299    {
9300    case TYPE_LEA:
9301      return "#";
9302
9303    case TYPE_ALU:
9304      gcc_assert (operands[2] == const1_rtx);
9305      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9306        return "add{l}\t%k0, %k0";
9307      else
9308        return "add{b}\t%0, %0";
9309
9310    default:
9311      if (operands[2] == const1_rtx
9312	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9313	{
9314	  if (get_attr_mode (insn) == MODE_SI)
9315	    return "sal{l}\t%k0";
9316	  else
9317	    return "sal{b}\t%0";
9318	}
9319      else
9320	{
9321	  if (get_attr_mode (insn) == MODE_SI)
9322	    return "sal{l}\t{%2, %k0|%k0, %2}";
9323	  else
9324	    return "sal{b}\t{%2, %0|%0, %2}";
9325	}
9326    }
9327}
9328  [(set (attr "type")
9329     (cond [(eq_attr "alternative" "2")
9330	      (const_string "lea")
9331            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9332		      (match_operand 0 "register_operand" ""))
9333		 (match_operand 2 "const1_operand" ""))
9334	      (const_string "alu")
9335	   ]
9336	   (const_string "ishift")))
9337   (set (attr "length_immediate")
9338     (if_then_else
9339       (ior (eq_attr "type" "alu")
9340	    (and (eq_attr "type" "ishift")
9341		 (and (match_operand 2 "const1_operand" "")
9342		      (ior (match_test "TARGET_SHIFT1")
9343			   (match_test "optimize_function_for_size_p (cfun)")))))
9344       (const_string "0")
9345       (const_string "*")))
9346   (set_attr "mode" "QI,SI,SI")])
9347
9348(define_insn "*ashlqi3_1_slp"
9349  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9350	(ashift:QI (match_dup 0)
9351		   (match_operand:QI 1 "nonmemory_operand" "cI")))
9352   (clobber (reg:CC FLAGS_REG))]
9353  "(optimize_function_for_size_p (cfun)
9354    || !TARGET_PARTIAL_FLAG_REG_STALL
9355    || (operands[1] == const1_rtx
9356	&& (TARGET_SHIFT1
9357	    || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9358{
9359  switch (get_attr_type (insn))
9360    {
9361    case TYPE_ALU:
9362      gcc_assert (operands[1] == const1_rtx);
9363      return "add{b}\t%0, %0";
9364
9365    default:
9366      if (operands[1] == const1_rtx
9367	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9368	return "sal{b}\t%0";
9369      else
9370	return "sal{b}\t{%1, %0|%0, %1}";
9371    }
9372}
9373  [(set (attr "type")
9374     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9375		      (match_operand 0 "register_operand" ""))
9376		 (match_operand 1 "const1_operand" ""))
9377	      (const_string "alu")
9378	   ]
9379	   (const_string "ishift1")))
9380   (set (attr "length_immediate")
9381     (if_then_else
9382       (ior (eq_attr "type" "alu")
9383	    (and (eq_attr "type" "ishift1")
9384		 (and (match_operand 1 "const1_operand" "")
9385		      (ior (match_test "TARGET_SHIFT1")
9386			   (match_test "optimize_function_for_size_p (cfun)")))))
9387       (const_string "0")
9388       (const_string "*")))
9389   (set_attr "mode" "QI")])
9390
9391;; Convert ashift to the lea pattern to avoid flags dependency.
9392(define_split
9393  [(set (match_operand 0 "register_operand" "")
9394	(ashift (match_operand 1 "index_register_operand" "")
9395                (match_operand:QI 2 "const_int_operand" "")))
9396   (clobber (reg:CC FLAGS_REG))]
9397  "GET_MODE (operands[0]) == GET_MODE (operands[1])
9398   && reload_completed
9399   && true_regnum (operands[0]) != true_regnum (operands[1])"
9400  [(const_int 0)]
9401{
9402  enum machine_mode mode = GET_MODE (operands[0]);
9403  rtx pat;
9404
9405  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9406    {
9407      mode = SImode;
9408      operands[0] = gen_lowpart (mode, operands[0]);
9409      operands[1] = gen_lowpart (mode, operands[1]);
9410    }
9411
9412  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9413
9414  pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9415
9416  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9417  DONE;
9418})
9419
9420;; Convert ashift to the lea pattern to avoid flags dependency.
9421(define_split
9422  [(set (match_operand:DI 0 "register_operand" "")
9423	(zero_extend:DI
9424	  (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9425		     (match_operand:QI 2 "const_int_operand" ""))))
9426   (clobber (reg:CC FLAGS_REG))]
9427  "TARGET_64BIT && reload_completed
9428   && true_regnum (operands[0]) != true_regnum (operands[1])"
9429  [(set (match_dup 0)
9430	(zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9431{
9432  operands[1] = gen_lowpart (DImode, operands[1]);
9433  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9434})
9435
9436;; This pattern can't accept a variable shift count, since shifts by
9437;; zero don't affect the flags.  We assume that shifts by constant
9438;; zero are optimized away.
9439(define_insn "*ashl<mode>3_cmp"
9440  [(set (reg FLAGS_REG)
9441	(compare
9442	  (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9443		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9444	  (const_int 0)))
9445   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9446	(ashift:SWI (match_dup 1) (match_dup 2)))]
9447  "(optimize_function_for_size_p (cfun)
9448    || !TARGET_PARTIAL_FLAG_REG_STALL
9449    || (operands[2] == const1_rtx
9450	&& (TARGET_SHIFT1
9451	    || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9452   && ix86_match_ccmode (insn, CCGOCmode)
9453   && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9454{
9455  switch (get_attr_type (insn))
9456    {
9457    case TYPE_ALU:
9458      gcc_assert (operands[2] == const1_rtx);
9459      return "add{<imodesuffix>}\t%0, %0";
9460
9461    default:
9462      if (operands[2] == const1_rtx
9463	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9464	return "sal{<imodesuffix>}\t%0";
9465      else
9466	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9467    }
9468}
9469  [(set (attr "type")
9470     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9471		      (match_operand 0 "register_operand" ""))
9472		 (match_operand 2 "const1_operand" ""))
9473	      (const_string "alu")
9474	   ]
9475	   (const_string "ishift")))
9476   (set (attr "length_immediate")
9477     (if_then_else
9478       (ior (eq_attr "type" "alu")
9479	    (and (eq_attr "type" "ishift")
9480		 (and (match_operand 2 "const1_operand" "")
9481		      (ior (match_test "TARGET_SHIFT1")
9482			   (match_test "optimize_function_for_size_p (cfun)")))))
9483       (const_string "0")
9484       (const_string "*")))
9485   (set_attr "mode" "<MODE>")])
9486
9487(define_insn "*ashlsi3_cmp_zext"
9488  [(set (reg FLAGS_REG)
9489	(compare
9490	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
9491		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
9492	  (const_int 0)))
9493   (set (match_operand:DI 0 "register_operand" "=r")
9494	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9495  "TARGET_64BIT
9496   && (optimize_function_for_size_p (cfun)
9497       || !TARGET_PARTIAL_FLAG_REG_STALL
9498       || (operands[2] == const1_rtx
9499	   && (TARGET_SHIFT1
9500	       || TARGET_DOUBLE_WITH_ADD)))
9501   && ix86_match_ccmode (insn, CCGOCmode)
9502   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9503{
9504  switch (get_attr_type (insn))
9505    {
9506    case TYPE_ALU:
9507      gcc_assert (operands[2] == const1_rtx);
9508      return "add{l}\t%k0, %k0";
9509
9510    default:
9511      if (operands[2] == const1_rtx
9512	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9513	return "sal{l}\t%k0";
9514      else
9515	return "sal{l}\t{%2, %k0|%k0, %2}";
9516    }
9517}
9518  [(set (attr "type")
9519     (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9520		 (match_operand 2 "const1_operand" ""))
9521	      (const_string "alu")
9522	   ]
9523	   (const_string "ishift")))
9524   (set (attr "length_immediate")
9525     (if_then_else
9526       (ior (eq_attr "type" "alu")
9527	    (and (eq_attr "type" "ishift")
9528		 (and (match_operand 2 "const1_operand" "")
9529		      (ior (match_test "TARGET_SHIFT1")
9530			   (match_test "optimize_function_for_size_p (cfun)")))))
9531       (const_string "0")
9532       (const_string "*")))
9533   (set_attr "mode" "SI")])
9534
9535(define_insn "*ashl<mode>3_cconly"
9536  [(set (reg FLAGS_REG)
9537	(compare
9538	  (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9539		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9540	  (const_int 0)))
9541   (clobber (match_scratch:SWI 0 "=<r>"))]
9542  "(optimize_function_for_size_p (cfun)
9543    || !TARGET_PARTIAL_FLAG_REG_STALL
9544    || (operands[2] == const1_rtx
9545	&& (TARGET_SHIFT1
9546	    || TARGET_DOUBLE_WITH_ADD)))
9547   && ix86_match_ccmode (insn, CCGOCmode)"
9548{
9549  switch (get_attr_type (insn))
9550    {
9551    case TYPE_ALU:
9552      gcc_assert (operands[2] == const1_rtx);
9553      return "add{<imodesuffix>}\t%0, %0";
9554
9555    default:
9556      if (operands[2] == const1_rtx
9557	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9558	return "sal{<imodesuffix>}\t%0";
9559      else
9560	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9561    }
9562}
9563  [(set (attr "type")
9564     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9565		      (match_operand 0 "register_operand" ""))
9566		 (match_operand 2 "const1_operand" ""))
9567	      (const_string "alu")
9568	   ]
9569	   (const_string "ishift")))
9570   (set (attr "length_immediate")
9571     (if_then_else
9572       (ior (eq_attr "type" "alu")
9573	    (and (eq_attr "type" "ishift")
9574		 (and (match_operand 2 "const1_operand" "")
9575		      (ior (match_test "TARGET_SHIFT1")
9576			   (match_test "optimize_function_for_size_p (cfun)")))))
9577       (const_string "0")
9578       (const_string "*")))
9579   (set_attr "mode" "<MODE>")])
9580
9581;; See comment above `ashl<mode>3' about how this works.
9582
9583(define_expand "<shift_insn><mode>3"
9584  [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9585	(any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9586			   (match_operand:QI 2 "nonmemory_operand" "")))]
9587  ""
9588  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9589
9590;; Avoid useless masking of count operand.
9591(define_insn "*<shift_insn><mode>3_mask"
9592  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9593	(any_shiftrt:SWI48
9594	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
9595	  (subreg:QI
9596	    (and:SI
9597	      (match_operand:SI 2 "register_operand" "c")
9598	      (match_operand:SI 3 "const_int_operand" "n")) 0)))
9599   (clobber (reg:CC FLAGS_REG))]
9600  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9601   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9602      == GET_MODE_BITSIZE (<MODE>mode)-1"
9603{
9604  return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9605}
9606  [(set_attr "type" "ishift")
9607   (set_attr "mode" "<MODE>")])
9608
9609(define_insn_and_split "*<shift_insn><mode>3_doubleword"
9610  [(set (match_operand:DWI 0 "register_operand" "=r")
9611	(any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9612			 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9613   (clobber (reg:CC FLAGS_REG))]
9614  ""
9615  "#"
9616  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9617  [(const_int 0)]
9618  "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9619  [(set_attr "type" "multi")])
9620
9621;; By default we don't ask for a scratch register, because when DWImode
9622;; values are manipulated, registers are already at a premium.  But if
9623;; we have one handy, we won't turn it away.
9624
9625(define_peephole2
9626  [(match_scratch:DWIH 3 "r")
9627   (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9628		   (any_shiftrt:<DWI>
9629		     (match_operand:<DWI> 1 "register_operand" "")
9630		     (match_operand:QI 2 "nonmemory_operand" "")))
9631	      (clobber (reg:CC FLAGS_REG))])
9632   (match_dup 3)]
9633  "TARGET_CMOVE"
9634  [(const_int 0)]
9635  "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9636
9637(define_insn "x86_64_shrd"
9638  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9639        (ior:DI (ashiftrt:DI (match_dup 0)
9640		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
9641		(ashift:DI (match_operand:DI 1 "register_operand" "r")
9642		  (minus:QI (const_int 64) (match_dup 2)))))
9643   (clobber (reg:CC FLAGS_REG))]
9644  "TARGET_64BIT"
9645  "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9646  [(set_attr "type" "ishift")
9647   (set_attr "prefix_0f" "1")
9648   (set_attr "mode" "DI")
9649   (set_attr "athlon_decode" "vector")
9650   (set_attr "amdfam10_decode" "vector")
9651   (set_attr "bdver1_decode" "vector")])
9652
9653(define_insn "x86_shrd"
9654  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9655        (ior:SI (ashiftrt:SI (match_dup 0)
9656		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
9657		(ashift:SI (match_operand:SI 1 "register_operand" "r")
9658		  (minus:QI (const_int 32) (match_dup 2)))))
9659   (clobber (reg:CC FLAGS_REG))]
9660  ""
9661  "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9662  [(set_attr "type" "ishift")
9663   (set_attr "prefix_0f" "1")
9664   (set_attr "mode" "SI")
9665   (set_attr "pent_pair" "np")
9666   (set_attr "athlon_decode" "vector")
9667   (set_attr "amdfam10_decode" "vector")
9668   (set_attr "bdver1_decode" "vector")])
9669
9670(define_insn "ashrdi3_cvt"
9671  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9672	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9673		     (match_operand:QI 2 "const_int_operand" "")))
9674   (clobber (reg:CC FLAGS_REG))]
9675  "TARGET_64BIT && INTVAL (operands[2]) == 63
9676   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9677   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9678  "@
9679   {cqto|cqo}
9680   sar{q}\t{%2, %0|%0, %2}"
9681  [(set_attr "type" "imovx,ishift")
9682   (set_attr "prefix_0f" "0,*")
9683   (set_attr "length_immediate" "0,*")
9684   (set_attr "modrm" "0,1")
9685   (set_attr "mode" "DI")])
9686
9687(define_insn "ashrsi3_cvt"
9688  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9689	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9690		     (match_operand:QI 2 "const_int_operand" "")))
9691   (clobber (reg:CC FLAGS_REG))]
9692  "INTVAL (operands[2]) == 31
9693   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9694   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9695  "@
9696   {cltd|cdq}
9697   sar{l}\t{%2, %0|%0, %2}"
9698  [(set_attr "type" "imovx,ishift")
9699   (set_attr "prefix_0f" "0,*")
9700   (set_attr "length_immediate" "0,*")
9701   (set_attr "modrm" "0,1")
9702   (set_attr "mode" "SI")])
9703
9704(define_insn "*ashrsi3_cvt_zext"
9705  [(set (match_operand:DI 0 "register_operand" "=*d,r")
9706	(zero_extend:DI
9707	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9708		       (match_operand:QI 2 "const_int_operand" ""))))
9709   (clobber (reg:CC FLAGS_REG))]
9710  "TARGET_64BIT && INTVAL (operands[2]) == 31
9711   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9712   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9713  "@
9714   {cltd|cdq}
9715   sar{l}\t{%2, %k0|%k0, %2}"
9716  [(set_attr "type" "imovx,ishift")
9717   (set_attr "prefix_0f" "0,*")
9718   (set_attr "length_immediate" "0,*")
9719   (set_attr "modrm" "0,1")
9720   (set_attr "mode" "SI")])
9721
9722(define_expand "x86_shift<mode>_adj_3"
9723  [(use (match_operand:SWI48 0 "register_operand" ""))
9724   (use (match_operand:SWI48 1 "register_operand" ""))
9725   (use (match_operand:QI 2 "register_operand" ""))]
9726  ""
9727{
9728  rtx label = gen_label_rtx ();
9729  rtx tmp;
9730
9731  emit_insn (gen_testqi_ccz_1 (operands[2],
9732			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9733
9734  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9735  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9736  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9737			      gen_rtx_LABEL_REF (VOIDmode, label),
9738			      pc_rtx);
9739  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9740  JUMP_LABEL (tmp) = label;
9741
9742  emit_move_insn (operands[0], operands[1]);
9743  emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9744				  GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9745  emit_label (label);
9746  LABEL_NUSES (label) = 1;
9747
9748  DONE;
9749})
9750
9751(define_insn "*bmi2_<shift_insn><mode>3_1"
9752  [(set (match_operand:SWI48 0 "register_operand" "=r")
9753	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9754			   (match_operand:SWI48 2 "register_operand" "r")))]
9755  "TARGET_BMI2"
9756  "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9757  [(set_attr "type" "ishiftx")
9758   (set_attr "mode" "<MODE>")])
9759
9760(define_insn "*<shift_insn><mode>3_1"
9761  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9762	(any_shiftrt:SWI48
9763	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9764	  (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9765   (clobber (reg:CC FLAGS_REG))]
9766  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9767{
9768  switch (get_attr_type (insn))
9769    {
9770    case TYPE_ISHIFTX:
9771      return "#";
9772
9773    default:
9774      if (operands[2] == const1_rtx
9775	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9776	return "<shift>{<imodesuffix>}\t%0";
9777      else
9778	return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9779    }
9780}
9781  [(set_attr "isa" "*,bmi2")
9782   (set_attr "type" "ishift,ishiftx")
9783   (set (attr "length_immediate")
9784     (if_then_else
9785       (and (match_operand 2 "const1_operand" "")
9786	    (ior (match_test "TARGET_SHIFT1")
9787		 (match_test "optimize_function_for_size_p (cfun)")))
9788       (const_string "0")
9789       (const_string "*")))
9790   (set_attr "mode" "<MODE>")])
9791
9792;; Convert shift to the shiftx pattern to avoid flags dependency.
9793(define_split
9794  [(set (match_operand:SWI48 0 "register_operand" "")
9795	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9796			   (match_operand:QI 2 "register_operand" "")))
9797   (clobber (reg:CC FLAGS_REG))]
9798  "TARGET_BMI2 && reload_completed"
9799  [(set (match_dup 0)
9800	(any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9801  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9802
9803(define_insn "*bmi2_<shift_insn>si3_1_zext"
9804  [(set (match_operand:DI 0 "register_operand" "=r")
9805	(zero_extend:DI
9806	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9807			  (match_operand:SI 2 "register_operand" "r"))))]
9808  "TARGET_64BIT && TARGET_BMI2"
9809  "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9810  [(set_attr "type" "ishiftx")
9811   (set_attr "mode" "SI")])
9812
9813(define_insn "*<shift_insn>si3_1_zext"
9814  [(set (match_operand:DI 0 "register_operand" "=r,r")
9815	(zero_extend:DI
9816	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9817			  (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9818   (clobber (reg:CC FLAGS_REG))]
9819  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9820{
9821  switch (get_attr_type (insn))
9822    {
9823    case TYPE_ISHIFTX:
9824      return "#";
9825
9826    default:
9827      if (operands[2] == const1_rtx
9828	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9829	return "<shift>{l}\t%k0";
9830      else
9831	return "<shift>{l}\t{%2, %k0|%k0, %2}";
9832    }
9833}
9834  [(set_attr "isa" "*,bmi2")
9835   (set_attr "type" "ishift,ishiftx")
9836   (set (attr "length_immediate")
9837     (if_then_else
9838       (and (match_operand 2 "const1_operand" "")
9839	    (ior (match_test "TARGET_SHIFT1")
9840		 (match_test "optimize_function_for_size_p (cfun)")))
9841       (const_string "0")
9842       (const_string "*")))
9843   (set_attr "mode" "SI")])
9844
9845;; Convert shift to the shiftx pattern to avoid flags dependency.
9846(define_split
9847  [(set (match_operand:DI 0 "register_operand" "")
9848	(zero_extend:DI
9849	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9850			  (match_operand:QI 2 "register_operand" ""))))
9851   (clobber (reg:CC FLAGS_REG))]
9852  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9853  [(set (match_dup 0)
9854	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9855  "operands[2] = gen_lowpart (SImode, operands[2]);")
9856
9857(define_insn "*<shift_insn><mode>3_1"
9858  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9859	(any_shiftrt:SWI12
9860	  (match_operand:SWI12 1 "nonimmediate_operand" "0")
9861	  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9862   (clobber (reg:CC FLAGS_REG))]
9863  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9864{
9865  if (operands[2] == const1_rtx
9866      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9867    return "<shift>{<imodesuffix>}\t%0";
9868  else
9869    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9870}
9871  [(set_attr "type" "ishift")
9872   (set (attr "length_immediate")
9873     (if_then_else
9874       (and (match_operand 2 "const1_operand" "")
9875	    (ior (match_test "TARGET_SHIFT1")
9876		 (match_test "optimize_function_for_size_p (cfun)")))
9877       (const_string "0")
9878       (const_string "*")))
9879   (set_attr "mode" "<MODE>")])
9880
9881(define_insn "*<shift_insn>qi3_1_slp"
9882  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9883	(any_shiftrt:QI (match_dup 0)
9884			(match_operand:QI 1 "nonmemory_operand" "cI")))
9885   (clobber (reg:CC FLAGS_REG))]
9886  "(optimize_function_for_size_p (cfun)
9887    || !TARGET_PARTIAL_REG_STALL
9888    || (operands[1] == const1_rtx
9889	&& TARGET_SHIFT1))"
9890{
9891  if (operands[1] == const1_rtx
9892      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9893    return "<shift>{b}\t%0";
9894  else
9895    return "<shift>{b}\t{%1, %0|%0, %1}";
9896}
9897  [(set_attr "type" "ishift1")
9898   (set (attr "length_immediate")
9899     (if_then_else
9900       (and (match_operand 1 "const1_operand" "")
9901	    (ior (match_test "TARGET_SHIFT1")
9902		 (match_test "optimize_function_for_size_p (cfun)")))
9903       (const_string "0")
9904       (const_string "*")))
9905   (set_attr "mode" "QI")])
9906
9907;; This pattern can't accept a variable shift count, since shifts by
9908;; zero don't affect the flags.  We assume that shifts by constant
9909;; zero are optimized away.
9910(define_insn "*<shift_insn><mode>3_cmp"
9911  [(set (reg FLAGS_REG)
9912	(compare
9913	  (any_shiftrt:SWI
9914	    (match_operand:SWI 1 "nonimmediate_operand" "0")
9915	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9916	  (const_int 0)))
9917   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9918	(any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9919  "(optimize_function_for_size_p (cfun)
9920    || !TARGET_PARTIAL_FLAG_REG_STALL
9921    || (operands[2] == const1_rtx
9922	&& TARGET_SHIFT1))
9923   && ix86_match_ccmode (insn, CCGOCmode)
9924   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9925{
9926  if (operands[2] == const1_rtx
9927      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9928    return "<shift>{<imodesuffix>}\t%0";
9929  else
9930    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9931}
9932  [(set_attr "type" "ishift")
9933   (set (attr "length_immediate")
9934     (if_then_else
9935       (and (match_operand 2 "const1_operand" "")
9936	    (ior (match_test "TARGET_SHIFT1")
9937		 (match_test "optimize_function_for_size_p (cfun)")))
9938       (const_string "0")
9939       (const_string "*")))
9940   (set_attr "mode" "<MODE>")])
9941
9942(define_insn "*<shift_insn>si3_cmp_zext"
9943  [(set (reg FLAGS_REG)
9944	(compare
9945	  (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9946			  (match_operand:QI 2 "const_1_to_31_operand" "I"))
9947	  (const_int 0)))
9948   (set (match_operand:DI 0 "register_operand" "=r")
9949	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9950  "TARGET_64BIT
9951   && (optimize_function_for_size_p (cfun)
9952       || !TARGET_PARTIAL_FLAG_REG_STALL
9953       || (operands[2] == const1_rtx
9954	   && TARGET_SHIFT1))
9955   && ix86_match_ccmode (insn, CCGOCmode)
9956   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9957{
9958  if (operands[2] == const1_rtx
9959      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9960    return "<shift>{l}\t%k0";
9961  else
9962    return "<shift>{l}\t{%2, %k0|%k0, %2}";
9963}
9964  [(set_attr "type" "ishift")
9965   (set (attr "length_immediate")
9966     (if_then_else
9967       (and (match_operand 2 "const1_operand" "")
9968	    (ior (match_test "TARGET_SHIFT1")
9969		 (match_test "optimize_function_for_size_p (cfun)")))
9970       (const_string "0")
9971       (const_string "*")))
9972   (set_attr "mode" "SI")])
9973
9974(define_insn "*<shift_insn><mode>3_cconly"
9975  [(set (reg FLAGS_REG)
9976	(compare
9977	  (any_shiftrt:SWI
9978	    (match_operand:SWI 1 "register_operand" "0")
9979	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9980	  (const_int 0)))
9981   (clobber (match_scratch:SWI 0 "=<r>"))]
9982  "(optimize_function_for_size_p (cfun)
9983    || !TARGET_PARTIAL_FLAG_REG_STALL
9984    || (operands[2] == const1_rtx
9985	&& TARGET_SHIFT1))
9986   && ix86_match_ccmode (insn, CCGOCmode)"
9987{
9988  if (operands[2] == const1_rtx
9989      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9990    return "<shift>{<imodesuffix>}\t%0";
9991  else
9992    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9993}
9994  [(set_attr "type" "ishift")
9995   (set (attr "length_immediate")
9996     (if_then_else
9997       (and (match_operand 2 "const1_operand" "")
9998	    (ior (match_test "TARGET_SHIFT1")
9999		 (match_test "optimize_function_for_size_p (cfun)")))
10000       (const_string "0")
10001       (const_string "*")))
10002   (set_attr "mode" "<MODE>")])
10003
10004;; Rotate instructions
10005
10006(define_expand "<rotate_insn>ti3"
10007  [(set (match_operand:TI 0 "register_operand" "")
10008	(any_rotate:TI (match_operand:TI 1 "register_operand" "")
10009		       (match_operand:QI 2 "nonmemory_operand" "")))]
10010  "TARGET_64BIT"
10011{
10012  if (const_1_to_63_operand (operands[2], VOIDmode))
10013    emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10014		(operands[0], operands[1], operands[2]));
10015  else
10016    FAIL;
10017
10018  DONE;
10019})
10020
10021(define_expand "<rotate_insn>di3"
10022  [(set (match_operand:DI 0 "shiftdi_operand" "")
10023	(any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10024		       (match_operand:QI 2 "nonmemory_operand" "")))]
10025 ""
10026{
10027  if (TARGET_64BIT)
10028    ix86_expand_binary_operator (<CODE>, DImode, operands);
10029  else if (const_1_to_31_operand (operands[2], VOIDmode))
10030    emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10031		(operands[0], operands[1], operands[2]));
10032  else
10033    FAIL;
10034
10035  DONE;
10036})
10037
10038(define_expand "<rotate_insn><mode>3"
10039  [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10040	(any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10041			    (match_operand:QI 2 "nonmemory_operand" "")))]
10042  ""
10043  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10044
10045;; Avoid useless masking of count operand.
10046(define_insn "*<rotate_insn><mode>3_mask"
10047  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10048	(any_rotate:SWI48
10049	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
10050	  (subreg:QI
10051	    (and:SI
10052	      (match_operand:SI 2 "register_operand" "c")
10053	      (match_operand:SI 3 "const_int_operand" "n")) 0)))
10054   (clobber (reg:CC FLAGS_REG))]
10055  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10056   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10057      == GET_MODE_BITSIZE (<MODE>mode)-1"
10058{
10059  return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10060}
10061  [(set_attr "type" "rotate")
10062   (set_attr "mode" "<MODE>")])
10063
10064;; Implement rotation using two double-precision
10065;; shift instructions and a scratch register.
10066
10067(define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10068 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10069       (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10070		     (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10071  (clobber (reg:CC FLAGS_REG))
10072  (clobber (match_scratch:DWIH 3 "=&r"))]
10073 ""
10074 "#"
10075 "reload_completed"
10076 [(set (match_dup 3) (match_dup 4))
10077  (parallel
10078   [(set (match_dup 4)
10079	 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10080		   (lshiftrt:DWIH (match_dup 5)
10081				  (minus:QI (match_dup 6) (match_dup 2)))))
10082    (clobber (reg:CC FLAGS_REG))])
10083  (parallel
10084   [(set (match_dup 5)
10085	 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10086		   (lshiftrt:DWIH (match_dup 3)
10087				  (minus:QI (match_dup 6) (match_dup 2)))))
10088    (clobber (reg:CC FLAGS_REG))])]
10089{
10090  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10091
10092  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10093})
10094
10095(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10096 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10097       (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10098		       (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10099  (clobber (reg:CC FLAGS_REG))
10100  (clobber (match_scratch:DWIH 3 "=&r"))]
10101 ""
10102 "#"
10103 "reload_completed"
10104 [(set (match_dup 3) (match_dup 4))
10105  (parallel
10106   [(set (match_dup 4)
10107	 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10108		   (ashift:DWIH (match_dup 5)
10109				(minus:QI (match_dup 6) (match_dup 2)))))
10110    (clobber (reg:CC FLAGS_REG))])
10111  (parallel
10112   [(set (match_dup 5)
10113	 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10114		   (ashift:DWIH (match_dup 3)
10115				(minus:QI (match_dup 6) (match_dup 2)))))
10116    (clobber (reg:CC FLAGS_REG))])]
10117{
10118  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10119
10120  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10121})
10122
10123(define_insn "*bmi2_rorx<mode>3_1"
10124  [(set (match_operand:SWI48 0 "register_operand" "=r")
10125	(rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10126			(match_operand:QI 2 "immediate_operand" "<S>")))]
10127  "TARGET_BMI2"
10128  "rorx\t{%2, %1, %0|%0, %1, %2}"
10129  [(set_attr "type" "rotatex")
10130   (set_attr "mode" "<MODE>")])
10131
10132(define_insn "*<rotate_insn><mode>3_1"
10133  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10134	(any_rotate:SWI48
10135	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10136	  (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10137   (clobber (reg:CC FLAGS_REG))]
10138  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10139{
10140  switch (get_attr_type (insn))
10141    {
10142    case TYPE_ROTATEX:
10143      return "#";
10144
10145    default:
10146      if (operands[2] == const1_rtx
10147	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10148	return "<rotate>{<imodesuffix>}\t%0";
10149      else
10150	return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10151    }
10152}
10153  [(set_attr "isa" "*,bmi2")
10154   (set_attr "type" "rotate,rotatex")
10155   (set (attr "length_immediate")
10156     (if_then_else
10157       (and (eq_attr "type" "rotate")
10158	    (and (match_operand 2 "const1_operand" "")
10159		 (ior (match_test "TARGET_SHIFT1")
10160		      (match_test "optimize_function_for_size_p (cfun)"))))
10161       (const_string "0")
10162       (const_string "*")))
10163   (set_attr "mode" "<MODE>")])
10164
10165;; Convert rotate to the rotatex pattern to avoid flags dependency.
10166(define_split
10167  [(set (match_operand:SWI48 0 "register_operand" "")
10168	(rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10169		      (match_operand:QI 2 "immediate_operand" "")))
10170   (clobber (reg:CC FLAGS_REG))]
10171  "TARGET_BMI2 && reload_completed"
10172  [(set (match_dup 0)
10173	(rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10174{
10175  operands[2]
10176    = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10177})
10178
10179(define_split
10180  [(set (match_operand:SWI48 0 "register_operand" "")
10181	(rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10182			(match_operand:QI 2 "immediate_operand" "")))
10183   (clobber (reg:CC FLAGS_REG))]
10184  "TARGET_BMI2 && reload_completed"
10185  [(set (match_dup 0)
10186	(rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10187
10188(define_insn "*bmi2_rorxsi3_1_zext"
10189  [(set (match_operand:DI 0 "register_operand" "=r")
10190	(zero_extend:DI
10191	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10192		       (match_operand:QI 2 "immediate_operand" "I"))))]
10193  "TARGET_64BIT && TARGET_BMI2"
10194  "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10195  [(set_attr "type" "rotatex")
10196   (set_attr "mode" "SI")])
10197
10198(define_insn "*<rotate_insn>si3_1_zext"
10199  [(set (match_operand:DI 0 "register_operand" "=r,r")
10200	(zero_extend:DI
10201	  (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10202			 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10203   (clobber (reg:CC FLAGS_REG))]
10204  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10205{
10206  switch (get_attr_type (insn))
10207    {
10208    case TYPE_ROTATEX:
10209      return "#";
10210
10211    default:
10212      if (operands[2] == const1_rtx
10213	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10214	return "<rotate>{l}\t%k0";
10215      else
10216	return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10217    }
10218}
10219  [(set_attr "isa" "*,bmi2")
10220   (set_attr "type" "rotate,rotatex")
10221   (set (attr "length_immediate")
10222     (if_then_else
10223       (and (eq_attr "type" "rotate")
10224	    (and (match_operand 2 "const1_operand" "")
10225		 (ior (match_test "TARGET_SHIFT1")
10226		      (match_test "optimize_function_for_size_p (cfun)"))))
10227       (const_string "0")
10228       (const_string "*")))
10229   (set_attr "mode" "SI")])
10230
10231;; Convert rotate to the rotatex pattern to avoid flags dependency.
10232(define_split
10233  [(set (match_operand:DI 0 "register_operand" "")
10234	(zero_extend:DI
10235	  (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10236		     (match_operand:QI 2 "immediate_operand" ""))))
10237   (clobber (reg:CC FLAGS_REG))]
10238  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10239  [(set (match_dup 0)
10240	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10241{
10242  operands[2]
10243    = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10244})
10245
10246(define_split
10247  [(set (match_operand:DI 0 "register_operand" "")
10248	(zero_extend:DI
10249	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10250		       (match_operand:QI 2 "immediate_operand" ""))))
10251   (clobber (reg:CC FLAGS_REG))]
10252  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10253  [(set (match_dup 0)
10254	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10255
10256(define_insn "*<rotate_insn><mode>3_1"
10257  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10258	(any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10259			  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10260   (clobber (reg:CC FLAGS_REG))]
10261  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10262{
10263  if (operands[2] == const1_rtx
10264      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10265    return "<rotate>{<imodesuffix>}\t%0";
10266  else
10267    return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10268}
10269  [(set_attr "type" "rotate")
10270   (set (attr "length_immediate")
10271     (if_then_else
10272       (and (match_operand 2 "const1_operand" "")
10273	    (ior (match_test "TARGET_SHIFT1")
10274		 (match_test "optimize_function_for_size_p (cfun)")))
10275       (const_string "0")
10276       (const_string "*")))
10277   (set_attr "mode" "<MODE>")])
10278
10279(define_insn "*<rotate_insn>qi3_1_slp"
10280  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10281	(any_rotate:QI (match_dup 0)
10282		       (match_operand:QI 1 "nonmemory_operand" "cI")))
10283   (clobber (reg:CC FLAGS_REG))]
10284  "(optimize_function_for_size_p (cfun)
10285    || !TARGET_PARTIAL_REG_STALL
10286    || (operands[1] == const1_rtx
10287	&& TARGET_SHIFT1))"
10288{
10289  if (operands[1] == const1_rtx
10290      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10291    return "<rotate>{b}\t%0";
10292  else
10293    return "<rotate>{b}\t{%1, %0|%0, %1}";
10294}
10295  [(set_attr "type" "rotate1")
10296   (set (attr "length_immediate")
10297     (if_then_else
10298       (and (match_operand 1 "const1_operand" "")
10299	    (ior (match_test "TARGET_SHIFT1")
10300		 (match_test "optimize_function_for_size_p (cfun)")))
10301       (const_string "0")
10302       (const_string "*")))
10303   (set_attr "mode" "QI")])
10304
10305(define_split
10306 [(set (match_operand:HI 0 "register_operand" "")
10307       (any_rotate:HI (match_dup 0) (const_int 8)))
10308  (clobber (reg:CC FLAGS_REG))]
10309 "reload_completed
10310  && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10311 [(parallel [(set (strict_low_part (match_dup 0))
10312		  (bswap:HI (match_dup 0)))
10313	     (clobber (reg:CC FLAGS_REG))])])
10314
10315;; Bit set / bit test instructions
10316
10317(define_expand "extv"
10318  [(set (match_operand:SI 0 "register_operand" "")
10319	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
10320			 (match_operand:SI 2 "const8_operand" "")
10321			 (match_operand:SI 3 "const8_operand" "")))]
10322  ""
10323{
10324  /* Handle extractions from %ah et al.  */
10325  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10326    FAIL;
10327
10328  /* From mips.md: extract_bit_field doesn't verify that our source
10329     matches the predicate, so check it again here.  */
10330  if (! ext_register_operand (operands[1], VOIDmode))
10331    FAIL;
10332})
10333
10334(define_expand "extzv"
10335  [(set (match_operand:SI 0 "register_operand" "")
10336	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
10337			 (match_operand:SI 2 "const8_operand" "")
10338			 (match_operand:SI 3 "const8_operand" "")))]
10339  ""
10340{
10341  /* Handle extractions from %ah et al.  */
10342  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10343    FAIL;
10344
10345  /* From mips.md: extract_bit_field doesn't verify that our source
10346     matches the predicate, so check it again here.  */
10347  if (! ext_register_operand (operands[1], VOIDmode))
10348    FAIL;
10349})
10350
10351(define_expand "insv"
10352  [(set (zero_extract (match_operand 0 "register_operand" "")
10353		      (match_operand 1 "const_int_operand" "")
10354		      (match_operand 2 "const_int_operand" ""))
10355        (match_operand 3 "register_operand" ""))]
10356  ""
10357{
10358  rtx (*gen_mov_insv_1) (rtx, rtx);
10359
10360  if (ix86_expand_pinsr (operands))
10361    DONE;
10362
10363  /* Handle insertions to %ah et al.  */
10364  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10365    FAIL;
10366
10367  /* From mips.md: insert_bit_field doesn't verify that our source
10368     matches the predicate, so check it again here.  */
10369  if (! ext_register_operand (operands[0], VOIDmode))
10370    FAIL;
10371
10372  gen_mov_insv_1 = (TARGET_64BIT
10373		    ? gen_movdi_insv_1 : gen_movsi_insv_1);
10374
10375  emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10376  DONE;
10377})
10378
10379;; %%% bts, btr, btc, bt.
10380;; In general these instructions are *slow* when applied to memory,
10381;; since they enforce atomic operation.  When applied to registers,
10382;; it depends on the cpu implementation.  They're never faster than
10383;; the corresponding and/ior/xor operations, so with 32-bit there's
10384;; no point.  But in 64-bit, we can't hold the relevant immediates
10385;; within the instruction itself, so operating on bits in the high
10386;; 32-bits of a register becomes easier.
10387;;
10388;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10389;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10390;; negdf respectively, so they can never be disabled entirely.
10391
10392(define_insn "*btsq"
10393  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10394			 (const_int 1)
10395			 (match_operand:DI 1 "const_0_to_63_operand" ""))
10396	(const_int 1))
10397   (clobber (reg:CC FLAGS_REG))]
10398  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10399  "bts{q}\t{%1, %0|%0, %1}"
10400  [(set_attr "type" "alu1")
10401   (set_attr "prefix_0f" "1")
10402   (set_attr "mode" "DI")])
10403
10404(define_insn "*btrq"
10405  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10406			 (const_int 1)
10407			 (match_operand:DI 1 "const_0_to_63_operand" ""))
10408	(const_int 0))
10409   (clobber (reg:CC FLAGS_REG))]
10410  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10411  "btr{q}\t{%1, %0|%0, %1}"
10412  [(set_attr "type" "alu1")
10413   (set_attr "prefix_0f" "1")
10414   (set_attr "mode" "DI")])
10415
10416(define_insn "*btcq"
10417  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10418			 (const_int 1)
10419			 (match_operand:DI 1 "const_0_to_63_operand" ""))
10420	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10421   (clobber (reg:CC FLAGS_REG))]
10422  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10423  "btc{q}\t{%1, %0|%0, %1}"
10424  [(set_attr "type" "alu1")
10425   (set_attr "prefix_0f" "1")
10426   (set_attr "mode" "DI")])
10427
10428;; Allow Nocona to avoid these instructions if a register is available.
10429
10430(define_peephole2
10431  [(match_scratch:DI 2 "r")
10432   (parallel [(set (zero_extract:DI
10433		     (match_operand:DI 0 "register_operand" "")
10434		     (const_int 1)
10435		     (match_operand:DI 1 "const_0_to_63_operand" ""))
10436		   (const_int 1))
10437	      (clobber (reg:CC FLAGS_REG))])]
10438  "TARGET_64BIT && !TARGET_USE_BT"
10439  [(const_int 0)]
10440{
10441  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10442  rtx op1;
10443
10444  if (HOST_BITS_PER_WIDE_INT >= 64)
10445    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446  else if (i < HOST_BITS_PER_WIDE_INT)
10447    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10448  else
10449    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10450
10451  op1 = immed_double_const (lo, hi, DImode);
10452  if (i >= 31)
10453    {
10454      emit_move_insn (operands[2], op1);
10455      op1 = operands[2];
10456    }
10457
10458  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10459  DONE;
10460})
10461
10462(define_peephole2
10463  [(match_scratch:DI 2 "r")
10464   (parallel [(set (zero_extract:DI
10465		     (match_operand:DI 0 "register_operand" "")
10466		     (const_int 1)
10467		     (match_operand:DI 1 "const_0_to_63_operand" ""))
10468		   (const_int 0))
10469	      (clobber (reg:CC FLAGS_REG))])]
10470  "TARGET_64BIT && !TARGET_USE_BT"
10471  [(const_int 0)]
10472{
10473  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10474  rtx op1;
10475
10476  if (HOST_BITS_PER_WIDE_INT >= 64)
10477    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10478  else if (i < HOST_BITS_PER_WIDE_INT)
10479    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10480  else
10481    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10482
10483  op1 = immed_double_const (~lo, ~hi, DImode);
10484  if (i >= 32)
10485    {
10486      emit_move_insn (operands[2], op1);
10487      op1 = operands[2];
10488    }
10489
10490  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10491  DONE;
10492})
10493
10494(define_peephole2
10495  [(match_scratch:DI 2 "r")
10496   (parallel [(set (zero_extract:DI
10497		     (match_operand:DI 0 "register_operand" "")
10498		     (const_int 1)
10499		     (match_operand:DI 1 "const_0_to_63_operand" ""))
10500	      (not:DI (zero_extract:DI
10501			(match_dup 0) (const_int 1) (match_dup 1))))
10502	      (clobber (reg:CC FLAGS_REG))])]
10503  "TARGET_64BIT && !TARGET_USE_BT"
10504  [(const_int 0)]
10505{
10506  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10507  rtx op1;
10508
10509  if (HOST_BITS_PER_WIDE_INT >= 64)
10510    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10511  else if (i < HOST_BITS_PER_WIDE_INT)
10512    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10513  else
10514    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10515
10516  op1 = immed_double_const (lo, hi, DImode);
10517  if (i >= 31)
10518    {
10519      emit_move_insn (operands[2], op1);
10520      op1 = operands[2];
10521    }
10522
10523  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10524  DONE;
10525})
10526
10527(define_insn "*bt<mode>"
10528  [(set (reg:CCC FLAGS_REG)
10529	(compare:CCC
10530	  (zero_extract:SWI48
10531	    (match_operand:SWI48 0 "register_operand" "r")
10532	    (const_int 1)
10533	    (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10534	  (const_int 0)))]
10535  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10536  "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10537  [(set_attr "type" "alu1")
10538   (set_attr "prefix_0f" "1")
10539   (set_attr "mode" "<MODE>")])
10540
10541;; Store-flag instructions.
10542
10543;; For all sCOND expanders, also expand the compare or test insn that
10544;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10545
10546(define_insn_and_split "*setcc_di_1"
10547  [(set (match_operand:DI 0 "register_operand" "=q")
10548	(match_operator:DI 1 "ix86_comparison_operator"
10549	  [(reg FLAGS_REG) (const_int 0)]))]
10550  "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10551  "#"
10552  "&& reload_completed"
10553  [(set (match_dup 2) (match_dup 1))
10554   (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10555{
10556  PUT_MODE (operands[1], QImode);
10557  operands[2] = gen_lowpart (QImode, operands[0]);
10558})
10559
10560(define_insn_and_split "*setcc_si_1_and"
10561  [(set (match_operand:SI 0 "register_operand" "=q")
10562	(match_operator:SI 1 "ix86_comparison_operator"
10563	  [(reg FLAGS_REG) (const_int 0)]))
10564   (clobber (reg:CC FLAGS_REG))]
10565  "!TARGET_PARTIAL_REG_STALL
10566   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10567  "#"
10568  "&& reload_completed"
10569  [(set (match_dup 2) (match_dup 1))
10570   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10571	      (clobber (reg:CC FLAGS_REG))])]
10572{
10573  PUT_MODE (operands[1], QImode);
10574  operands[2] = gen_lowpart (QImode, operands[0]);
10575})
10576
10577(define_insn_and_split "*setcc_si_1_movzbl"
10578  [(set (match_operand:SI 0 "register_operand" "=q")
10579	(match_operator:SI 1 "ix86_comparison_operator"
10580	  [(reg FLAGS_REG) (const_int 0)]))]
10581  "!TARGET_PARTIAL_REG_STALL
10582   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10583  "#"
10584  "&& reload_completed"
10585  [(set (match_dup 2) (match_dup 1))
10586   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10587{
10588  PUT_MODE (operands[1], QImode);
10589  operands[2] = gen_lowpart (QImode, operands[0]);
10590})
10591
10592(define_insn "*setcc_qi"
10593  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10594	(match_operator:QI 1 "ix86_comparison_operator"
10595	  [(reg FLAGS_REG) (const_int 0)]))]
10596  ""
10597  "set%C1\t%0"
10598  [(set_attr "type" "setcc")
10599   (set_attr "mode" "QI")])
10600
10601(define_insn "*setcc_qi_slp"
10602  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10603	(match_operator:QI 1 "ix86_comparison_operator"
10604	  [(reg FLAGS_REG) (const_int 0)]))]
10605  ""
10606  "set%C1\t%0"
10607  [(set_attr "type" "setcc")
10608   (set_attr "mode" "QI")])
10609
10610;; In general it is not safe to assume too much about CCmode registers,
10611;; so simplify-rtx stops when it sees a second one.  Under certain
10612;; conditions this is safe on x86, so help combine not create
10613;;
10614;;	seta	%al
10615;;	testb	%al, %al
10616;;	sete	%al
10617
10618(define_split
10619  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10620	(ne:QI (match_operator 1 "ix86_comparison_operator"
10621	         [(reg FLAGS_REG) (const_int 0)])
10622	    (const_int 0)))]
10623  ""
10624  [(set (match_dup 0) (match_dup 1))]
10625  "PUT_MODE (operands[1], QImode);")
10626
10627(define_split
10628  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10629	(ne:QI (match_operator 1 "ix86_comparison_operator"
10630	         [(reg FLAGS_REG) (const_int 0)])
10631	    (const_int 0)))]
10632  ""
10633  [(set (match_dup 0) (match_dup 1))]
10634  "PUT_MODE (operands[1], QImode);")
10635
10636(define_split
10637  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10638	(eq:QI (match_operator 1 "ix86_comparison_operator"
10639	         [(reg FLAGS_REG) (const_int 0)])
10640	    (const_int 0)))]
10641  ""
10642  [(set (match_dup 0) (match_dup 1))]
10643{
10644  rtx new_op1 = copy_rtx (operands[1]);
10645  operands[1] = new_op1;
10646  PUT_MODE (new_op1, QImode);
10647  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10648					     GET_MODE (XEXP (new_op1, 0))));
10649
10650  /* Make sure that (a) the CCmode we have for the flags is strong
10651     enough for the reversed compare or (b) we have a valid FP compare.  */
10652  if (! ix86_comparison_operator (new_op1, VOIDmode))
10653    FAIL;
10654})
10655
10656(define_split
10657  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10658	(eq:QI (match_operator 1 "ix86_comparison_operator"
10659	         [(reg FLAGS_REG) (const_int 0)])
10660	    (const_int 0)))]
10661  ""
10662  [(set (match_dup 0) (match_dup 1))]
10663{
10664  rtx new_op1 = copy_rtx (operands[1]);
10665  operands[1] = new_op1;
10666  PUT_MODE (new_op1, QImode);
10667  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10668					     GET_MODE (XEXP (new_op1, 0))));
10669
10670  /* Make sure that (a) the CCmode we have for the flags is strong
10671     enough for the reversed compare or (b) we have a valid FP compare.  */
10672  if (! ix86_comparison_operator (new_op1, VOIDmode))
10673    FAIL;
10674})
10675
10676;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10677;; subsequent logical operations are used to imitate conditional moves.
10678;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10679;; it directly.
10680
10681(define_insn "setcc_<mode>_sse"
10682  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10683	(match_operator:MODEF 3 "sse_comparison_operator"
10684	  [(match_operand:MODEF 1 "register_operand" "0,x")
10685	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10686  "SSE_FLOAT_MODE_P (<MODE>mode)"
10687  "@
10688   cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10689   vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10690  [(set_attr "isa" "noavx,avx")
10691   (set_attr "type" "ssecmp")
10692   (set_attr "length_immediate" "1")
10693   (set_attr "prefix" "orig,vex")
10694   (set_attr "mode" "<MODE>")])
10695
10696;; Basic conditional jump instructions.
10697;; We ignore the overflow flag for signed branch instructions.
10698
10699(define_insn "*jcc_1"
10700  [(set (pc)
10701	(if_then_else (match_operator 1 "ix86_comparison_operator"
10702				      [(reg FLAGS_REG) (const_int 0)])
10703		      (label_ref (match_operand 0 "" ""))
10704		      (pc)))]
10705  ""
10706  "%+j%C1\t%l0"
10707  [(set_attr "type" "ibr")
10708   (set_attr "modrm" "0")
10709   (set (attr "length")
10710	   (if_then_else (and (ge (minus (match_dup 0) (pc))
10711				  (const_int -126))
10712			      (lt (minus (match_dup 0) (pc))
10713				  (const_int 128)))
10714	     (const_int 2)
10715	     (const_int 6)))])
10716
10717(define_insn "*jcc_2"
10718  [(set (pc)
10719	(if_then_else (match_operator 1 "ix86_comparison_operator"
10720				      [(reg FLAGS_REG) (const_int 0)])
10721		      (pc)
10722		      (label_ref (match_operand 0 "" ""))))]
10723  ""
10724  "%+j%c1\t%l0"
10725  [(set_attr "type" "ibr")
10726   (set_attr "modrm" "0")
10727   (set (attr "length")
10728	   (if_then_else (and (ge (minus (match_dup 0) (pc))
10729				  (const_int -126))
10730			      (lt (minus (match_dup 0) (pc))
10731				  (const_int 128)))
10732	     (const_int 2)
10733	     (const_int 6)))])
10734
10735;; In general it is not safe to assume too much about CCmode registers,
10736;; so simplify-rtx stops when it sees a second one.  Under certain
10737;; conditions this is safe on x86, so help combine not create
10738;;
10739;;	seta	%al
10740;;	testb	%al, %al
10741;;	je	Lfoo
10742
10743(define_split
10744  [(set (pc)
10745	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10746				      [(reg FLAGS_REG) (const_int 0)])
10747			  (const_int 0))
10748		      (label_ref (match_operand 1 "" ""))
10749		      (pc)))]
10750  ""
10751  [(set (pc)
10752	(if_then_else (match_dup 0)
10753		      (label_ref (match_dup 1))
10754		      (pc)))]
10755  "PUT_MODE (operands[0], VOIDmode);")
10756
10757(define_split
10758  [(set (pc)
10759	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10760				      [(reg FLAGS_REG) (const_int 0)])
10761			  (const_int 0))
10762		      (label_ref (match_operand 1 "" ""))
10763		      (pc)))]
10764  ""
10765  [(set (pc)
10766	(if_then_else (match_dup 0)
10767		      (label_ref (match_dup 1))
10768		      (pc)))]
10769{
10770  rtx new_op0 = copy_rtx (operands[0]);
10771  operands[0] = new_op0;
10772  PUT_MODE (new_op0, VOIDmode);
10773  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10774					     GET_MODE (XEXP (new_op0, 0))));
10775
10776  /* Make sure that (a) the CCmode we have for the flags is strong
10777     enough for the reversed compare or (b) we have a valid FP compare.  */
10778  if (! ix86_comparison_operator (new_op0, VOIDmode))
10779    FAIL;
10780})
10781
10782;; zero_extend in SImode is correct also for DImode, since this is what combine
10783;; pass generates from shift insn with QImode operand.  Actually, the mode
10784;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10785;; appropriate modulo of the bit offset value.
10786
10787(define_insn_and_split "*jcc_bt<mode>"
10788  [(set (pc)
10789  	(if_then_else (match_operator 0 "bt_comparison_operator"
10790			[(zero_extract:SWI48
10791			   (match_operand:SWI48 1 "register_operand" "r")
10792			   (const_int 1)
10793			   (zero_extend:SI
10794			     (match_operand:QI 2 "register_operand" "r")))
10795			 (const_int 0)])
10796		      (label_ref (match_operand 3 "" ""))
10797		      (pc)))
10798   (clobber (reg:CC FLAGS_REG))]
10799  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10800  "#"
10801  "&& 1"
10802  [(set (reg:CCC FLAGS_REG)
10803	(compare:CCC
10804	  (zero_extract:SWI48
10805	    (match_dup 1)
10806	    (const_int 1)
10807	    (match_dup 2))
10808	  (const_int 0)))
10809   (set (pc)
10810	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10811		      (label_ref (match_dup 3))
10812		      (pc)))]
10813{
10814  operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10815
10816  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10817})
10818
10819;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10820;; also for DImode, this is what combine produces.
10821(define_insn_and_split "*jcc_bt<mode>_mask"
10822  [(set (pc)
10823  	(if_then_else (match_operator 0 "bt_comparison_operator"
10824			[(zero_extract:SWI48
10825			   (match_operand:SWI48 1 "register_operand" "r")
10826			   (const_int 1)
10827			   (and:SI
10828			     (match_operand:SI 2 "register_operand" "r")
10829			     (match_operand:SI 3 "const_int_operand" "n")))])
10830		      (label_ref (match_operand 4 "" ""))
10831		      (pc)))
10832   (clobber (reg:CC FLAGS_REG))]
10833  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10834   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10835      == GET_MODE_BITSIZE (<MODE>mode)-1"
10836  "#"
10837  "&& 1"
10838  [(set (reg:CCC FLAGS_REG)
10839	(compare:CCC
10840	  (zero_extract:SWI48
10841	    (match_dup 1)
10842	    (const_int 1)
10843	    (match_dup 2))
10844	  (const_int 0)))
10845   (set (pc)
10846	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10847		      (label_ref (match_dup 4))
10848		      (pc)))]
10849{
10850  operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10851
10852  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10853})
10854
10855(define_insn_and_split "*jcc_btsi_1"
10856  [(set (pc)
10857  	(if_then_else (match_operator 0 "bt_comparison_operator"
10858			[(and:SI
10859			   (lshiftrt:SI
10860			     (match_operand:SI 1 "register_operand" "r")
10861			     (match_operand:QI 2 "register_operand" "r"))
10862			   (const_int 1))
10863			 (const_int 0)])
10864		      (label_ref (match_operand 3 "" ""))
10865		      (pc)))
10866   (clobber (reg:CC FLAGS_REG))]
10867  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10868  "#"
10869  "&& 1"
10870  [(set (reg:CCC FLAGS_REG)
10871	(compare:CCC
10872	  (zero_extract:SI
10873	    (match_dup 1)
10874	    (const_int 1)
10875	    (match_dup 2))
10876	  (const_int 0)))
10877   (set (pc)
10878	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10879		      (label_ref (match_dup 3))
10880		      (pc)))]
10881{
10882  operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10883
10884  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10885})
10886
10887;; avoid useless masking of bit offset operand
10888(define_insn_and_split "*jcc_btsi_mask_1"
10889  [(set (pc)
10890  	(if_then_else
10891	  (match_operator 0 "bt_comparison_operator"
10892	    [(and:SI
10893	       (lshiftrt:SI
10894		 (match_operand:SI 1 "register_operand" "r")
10895		 (subreg:QI
10896		   (and:SI
10897		     (match_operand:SI 2 "register_operand" "r")
10898		     (match_operand:SI 3 "const_int_operand" "n")) 0))
10899	       (const_int 1))
10900	     (const_int 0)])
10901	  (label_ref (match_operand 4 "" ""))
10902	  (pc)))
10903   (clobber (reg:CC FLAGS_REG))]
10904  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10905   && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10906  "#"
10907  "&& 1"
10908  [(set (reg:CCC FLAGS_REG)
10909	(compare:CCC
10910	  (zero_extract:SI
10911	    (match_dup 1)
10912	    (const_int 1)
10913	    (match_dup 2))
10914	  (const_int 0)))
10915   (set (pc)
10916	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10917		      (label_ref (match_dup 4))
10918		      (pc)))]
10919  "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10920
10921;; Define combination compare-and-branch fp compare instructions to help
10922;; combine.
10923
10924(define_insn "*fp_jcc_1_387"
10925  [(set (pc)
10926	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10927			[(match_operand 1 "register_operand" "f")
10928			 (match_operand 2 "nonimmediate_operand" "fm")])
10929	  (label_ref (match_operand 3 "" ""))
10930	  (pc)))
10931   (clobber (reg:CCFP FPSR_REG))
10932   (clobber (reg:CCFP FLAGS_REG))
10933   (clobber (match_scratch:HI 4 "=a"))]
10934  "TARGET_80387
10935   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10936   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10937   && SELECT_CC_MODE (GET_CODE (operands[0]),
10938		      operands[1], operands[2]) == CCFPmode
10939   && !TARGET_CMOVE"
10940  "#")
10941
10942(define_insn "*fp_jcc_1r_387"
10943  [(set (pc)
10944	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10945			[(match_operand 1 "register_operand" "f")
10946			 (match_operand 2 "nonimmediate_operand" "fm")])
10947	  (pc)
10948	  (label_ref (match_operand 3 "" ""))))
10949   (clobber (reg:CCFP FPSR_REG))
10950   (clobber (reg:CCFP FLAGS_REG))
10951   (clobber (match_scratch:HI 4 "=a"))]
10952  "TARGET_80387
10953   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10954   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10955   && SELECT_CC_MODE (GET_CODE (operands[0]),
10956		      operands[1], operands[2]) == CCFPmode
10957   && !TARGET_CMOVE"
10958  "#")
10959
10960(define_insn "*fp_jcc_2_387"
10961  [(set (pc)
10962	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10963			[(match_operand 1 "register_operand" "f")
10964			 (match_operand 2 "register_operand" "f")])
10965	  (label_ref (match_operand 3 "" ""))
10966	  (pc)))
10967   (clobber (reg:CCFP FPSR_REG))
10968   (clobber (reg:CCFP FLAGS_REG))
10969   (clobber (match_scratch:HI 4 "=a"))]
10970  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10971   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10972   && !TARGET_CMOVE"
10973  "#")
10974
10975(define_insn "*fp_jcc_2r_387"
10976  [(set (pc)
10977	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10978			[(match_operand 1 "register_operand" "f")
10979			 (match_operand 2 "register_operand" "f")])
10980	  (pc)
10981	  (label_ref (match_operand 3 "" ""))))
10982   (clobber (reg:CCFP FPSR_REG))
10983   (clobber (reg:CCFP FLAGS_REG))
10984   (clobber (match_scratch:HI 4 "=a"))]
10985  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10986   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10987   && !TARGET_CMOVE"
10988  "#")
10989
10990(define_insn "*fp_jcc_3_387"
10991  [(set (pc)
10992	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10993			[(match_operand 1 "register_operand" "f")
10994			 (match_operand 2 "const0_operand" "")])
10995	  (label_ref (match_operand 3 "" ""))
10996	  (pc)))
10997   (clobber (reg:CCFP FPSR_REG))
10998   (clobber (reg:CCFP FLAGS_REG))
10999   (clobber (match_scratch:HI 4 "=a"))]
11000  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11001   && GET_MODE (operands[1]) == GET_MODE (operands[2])
11002   && SELECT_CC_MODE (GET_CODE (operands[0]),
11003		      operands[1], operands[2]) == CCFPmode
11004   && !TARGET_CMOVE"
11005  "#")
11006
11007(define_split
11008  [(set (pc)
11009	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11010			[(match_operand 1 "register_operand" "")
11011			 (match_operand 2 "nonimmediate_operand" "")])
11012	  (match_operand 3 "" "")
11013	  (match_operand 4 "" "")))
11014   (clobber (reg:CCFP FPSR_REG))
11015   (clobber (reg:CCFP FLAGS_REG))]
11016  "reload_completed"
11017  [(const_int 0)]
11018{
11019  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11020	                operands[3], operands[4], NULL_RTX, NULL_RTX);
11021  DONE;
11022})
11023
11024(define_split
11025  [(set (pc)
11026	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11027			[(match_operand 1 "register_operand" "")
11028			 (match_operand 2 "general_operand" "")])
11029	  (match_operand 3 "" "")
11030	  (match_operand 4 "" "")))
11031   (clobber (reg:CCFP FPSR_REG))
11032   (clobber (reg:CCFP FLAGS_REG))
11033   (clobber (match_scratch:HI 5 "=a"))]
11034  "reload_completed"
11035  [(const_int 0)]
11036{
11037  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11038	     		operands[3], operands[4], operands[5], NULL_RTX);
11039  DONE;
11040})
11041
11042;; The order of operands in *fp_jcc_4_387 is forced by combine in
11043;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11044;; with a precedence over other operators and is always put in the first
11045;; place. Swap condition and operands to match ficom instruction.
11046
11047(define_insn "*fp_jcc_4_<mode>_387"
11048  [(set (pc)
11049	(if_then_else
11050	  (match_operator 0 "ix86_swapped_fp_comparison_operator"
11051	    [(match_operator 1 "float_operator"
11052	      [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11053	     (match_operand 3 "register_operand" "f,f")])
11054	  (label_ref (match_operand 4 "" ""))
11055	  (pc)))
11056   (clobber (reg:CCFP FPSR_REG))
11057   (clobber (reg:CCFP FLAGS_REG))
11058   (clobber (match_scratch:HI 5 "=a,a"))]
11059  "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11060   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11061   && GET_MODE (operands[1]) == GET_MODE (operands[3])
11062   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11063   && !TARGET_CMOVE"
11064  "#")
11065
11066(define_split
11067  [(set (pc)
11068	(if_then_else
11069	  (match_operator 0 "ix86_swapped_fp_comparison_operator"
11070	    [(match_operator 1 "float_operator"
11071	      [(match_operand:SWI24 2 "memory_operand" "")])
11072	     (match_operand 3 "register_operand" "")])
11073	  (match_operand 4 "" "")
11074	  (match_operand 5 "" "")))
11075   (clobber (reg:CCFP FPSR_REG))
11076   (clobber (reg:CCFP FLAGS_REG))
11077   (clobber (match_scratch:HI 6 "=a"))]
11078  "reload_completed"
11079  [(const_int 0)]
11080{
11081  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11082
11083  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11084			operands[3], operands[7],
11085			operands[4], operands[5], operands[6], NULL_RTX);
11086  DONE;
11087})
11088
11089;; %%% Kill this when reload knows how to do it.
11090(define_split
11091  [(set (pc)
11092	(if_then_else
11093	  (match_operator 0 "ix86_swapped_fp_comparison_operator"
11094	    [(match_operator 1 "float_operator"
11095	      [(match_operand:SWI24 2 "register_operand" "")])
11096	     (match_operand 3 "register_operand" "")])
11097	  (match_operand 4 "" "")
11098	  (match_operand 5 "" "")))
11099   (clobber (reg:CCFP FPSR_REG))
11100   (clobber (reg:CCFP FLAGS_REG))
11101   (clobber (match_scratch:HI 6 "=a"))]
11102  "reload_completed"
11103  [(const_int 0)]
11104{
11105  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11106  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11107
11108  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11109			operands[3], operands[7],
11110			operands[4], operands[5], operands[6], operands[2]);
11111  DONE;
11112})
11113
11114;; Unconditional and other jump instructions
11115
11116(define_insn "jump"
11117  [(set (pc)
11118	(label_ref (match_operand 0 "" "")))]
11119  ""
11120  "jmp\t%l0"
11121  [(set_attr "type" "ibr")
11122   (set (attr "length")
11123	   (if_then_else (and (ge (minus (match_dup 0) (pc))
11124				  (const_int -126))
11125			      (lt (minus (match_dup 0) (pc))
11126				  (const_int 128)))
11127	     (const_int 2)
11128	     (const_int 5)))
11129   (set_attr "modrm" "0")])
11130
11131(define_expand "indirect_jump"
11132  [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11133
11134(define_insn "*indirect_jump"
11135  [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11136  ""
11137  "jmp\t%A0"
11138  [(set_attr "type" "ibr")
11139   (set_attr "length_immediate" "0")])
11140
11141(define_expand "tablejump"
11142  [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11143	      (use (label_ref (match_operand 1 "" "")))])]
11144  ""
11145{
11146  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11147     relative.  Convert the relative address to an absolute address.  */
11148  if (flag_pic)
11149    {
11150      rtx op0, op1;
11151      enum rtx_code code;
11152
11153      /* We can't use @GOTOFF for text labels on VxWorks;
11154	 see gotoff_operand.  */
11155      if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11156	{
11157	  code = PLUS;
11158	  op0 = operands[0];
11159	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11160	}
11161      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11162	{
11163	  code = PLUS;
11164	  op0 = operands[0];
11165	  op1 = pic_offset_table_rtx;
11166	}
11167      else
11168	{
11169	  code = MINUS;
11170	  op0 = pic_offset_table_rtx;
11171	  op1 = operands[0];
11172	}
11173
11174      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11175					 OPTAB_DIRECT);
11176    }
11177  else if (TARGET_X32)
11178    operands[0] = convert_memory_address (Pmode, operands[0]);
11179})
11180
11181(define_insn "*tablejump_1"
11182  [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11183   (use (label_ref (match_operand 1 "" "")))]
11184  ""
11185  "jmp\t%A0"
11186  [(set_attr "type" "ibr")
11187   (set_attr "length_immediate" "0")])
11188
11189;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11190
11191(define_peephole2
11192  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11193   (set (match_operand:QI 1 "register_operand" "")
11194	(match_operator:QI 2 "ix86_comparison_operator"
11195	  [(reg FLAGS_REG) (const_int 0)]))
11196   (set (match_operand 3 "q_regs_operand" "")
11197	(zero_extend (match_dup 1)))]
11198  "(peep2_reg_dead_p (3, operands[1])
11199    || operands_match_p (operands[1], operands[3]))
11200   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11201  [(set (match_dup 4) (match_dup 0))
11202   (set (strict_low_part (match_dup 5))
11203	(match_dup 2))]
11204{
11205  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11206  operands[5] = gen_lowpart (QImode, operands[3]);
11207  ix86_expand_clear (operands[3]);
11208})
11209
11210;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11211
11212(define_peephole2
11213  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11214   (set (match_operand:QI 1 "register_operand" "")
11215	(match_operator:QI 2 "ix86_comparison_operator"
11216	  [(reg FLAGS_REG) (const_int 0)]))
11217   (parallel [(set (match_operand 3 "q_regs_operand" "")
11218		   (zero_extend (match_dup 1)))
11219	      (clobber (reg:CC FLAGS_REG))])]
11220  "(peep2_reg_dead_p (3, operands[1])
11221    || operands_match_p (operands[1], operands[3]))
11222   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11223  [(set (match_dup 4) (match_dup 0))
11224   (set (strict_low_part (match_dup 5))
11225	(match_dup 2))]
11226{
11227  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11228  operands[5] = gen_lowpart (QImode, operands[3]);
11229  ix86_expand_clear (operands[3]);
11230})
11231
11232;; Call instructions.
11233
11234;; The predicates normally associated with named expanders are not properly
11235;; checked for calls.  This is a bug in the generic code, but it isn't that
11236;; easy to fix.  Ignore it for now and be prepared to fix things up.
11237
11238;; P6 processors will jump to the address after the decrement when %esp
11239;; is used as a call operand, so they will execute return address as a code.
11240;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11241
11242;; Register constraint for call instruction.
11243(define_mode_attr c [(SI "l") (DI "r")])
11244
11245;; Call subroutine returning no value.
11246
11247(define_expand "call"
11248  [(call (match_operand:QI 0 "" "")
11249	 (match_operand 1 "" ""))
11250   (use (match_operand 2 "" ""))]
11251  ""
11252{
11253  ix86_expand_call (NULL, operands[0], operands[1],
11254		    operands[2], NULL, false);
11255  DONE;
11256})
11257
11258(define_expand "sibcall"
11259  [(call (match_operand:QI 0 "" "")
11260	 (match_operand 1 "" ""))
11261   (use (match_operand 2 "" ""))]
11262  ""
11263{
11264  ix86_expand_call (NULL, operands[0], operands[1],
11265		    operands[2], NULL, true);
11266  DONE;
11267})
11268
11269(define_insn_and_split "*call_vzeroupper"
11270  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11271	 (match_operand 1 "" ""))
11272   (unspec [(match_operand 2 "const_int_operand" "")]
11273   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11274  "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11275  "#"
11276  "&& reload_completed"
11277  [(const_int 0)]
11278  "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11279  [(set_attr "type" "call")])
11280
11281(define_insn "*call"
11282  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11283	 (match_operand 1 "" ""))]
11284  "!SIBLING_CALL_P (insn)"
11285  "* return ix86_output_call_insn (insn, operands[0]);"
11286  [(set_attr "type" "call")])
11287
11288(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11289  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11290	 (match_operand 1 "" ""))
11291   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11292   (clobber (reg:TI XMM6_REG))
11293   (clobber (reg:TI XMM7_REG))
11294   (clobber (reg:TI XMM8_REG))
11295   (clobber (reg:TI XMM9_REG))
11296   (clobber (reg:TI XMM10_REG))
11297   (clobber (reg:TI XMM11_REG))
11298   (clobber (reg:TI XMM12_REG))
11299   (clobber (reg:TI XMM13_REG))
11300   (clobber (reg:TI XMM14_REG))
11301   (clobber (reg:TI XMM15_REG))
11302   (clobber (reg:DI SI_REG))
11303   (clobber (reg:DI DI_REG))
11304   (unspec [(match_operand 2 "const_int_operand" "")]
11305   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11306  "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11307  "#"
11308  "&& reload_completed"
11309  [(const_int 0)]
11310  "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11311  [(set_attr "type" "call")])
11312
11313(define_insn "*call_rex64_ms_sysv"
11314  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11315	 (match_operand 1 "" ""))
11316   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11317   (clobber (reg:TI XMM6_REG))
11318   (clobber (reg:TI XMM7_REG))
11319   (clobber (reg:TI XMM8_REG))
11320   (clobber (reg:TI XMM9_REG))
11321   (clobber (reg:TI XMM10_REG))
11322   (clobber (reg:TI XMM11_REG))
11323   (clobber (reg:TI XMM12_REG))
11324   (clobber (reg:TI XMM13_REG))
11325   (clobber (reg:TI XMM14_REG))
11326   (clobber (reg:TI XMM15_REG))
11327   (clobber (reg:DI SI_REG))
11328   (clobber (reg:DI DI_REG))]
11329  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11330  "* return ix86_output_call_insn (insn, operands[0]);"
11331  [(set_attr "type" "call")])
11332
11333(define_insn_and_split "*sibcall_vzeroupper"
11334  [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11335	 (match_operand 1 "" ""))
11336   (unspec [(match_operand 2 "const_int_operand" "")]
11337   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11338  "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11339  "#"
11340  "&& reload_completed"
11341  [(const_int 0)]
11342  "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11343  [(set_attr "type" "call")])
11344
11345(define_insn "*sibcall"
11346  [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11347	 (match_operand 1 "" ""))]
11348  "SIBLING_CALL_P (insn)"
11349  "* return ix86_output_call_insn (insn, operands[0]);"
11350  [(set_attr "type" "call")])
11351
11352(define_expand "call_pop"
11353  [(parallel [(call (match_operand:QI 0 "" "")
11354		    (match_operand:SI 1 "" ""))
11355	      (set (reg:SI SP_REG)
11356		   (plus:SI (reg:SI SP_REG)
11357			    (match_operand:SI 3 "" "")))])]
11358  "!TARGET_64BIT"
11359{
11360  ix86_expand_call (NULL, operands[0], operands[1],
11361		    operands[2], operands[3], false);
11362  DONE;
11363})
11364
11365(define_insn_and_split "*call_pop_vzeroupper"
11366  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11367	 (match_operand:SI 1 "" ""))
11368   (set (reg:SI SP_REG)
11369	(plus:SI (reg:SI SP_REG)
11370		 (match_operand:SI 2 "immediate_operand" "i")))
11371   (unspec [(match_operand 3 "const_int_operand" "")]
11372   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11373  "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11374  "#"
11375  "&& reload_completed"
11376  [(const_int 0)]
11377  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11378  [(set_attr "type" "call")])
11379
11380(define_insn "*call_pop"
11381  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11382	 (match_operand 1 "" ""))
11383   (set (reg:SI SP_REG)
11384	(plus:SI (reg:SI SP_REG)
11385		 (match_operand:SI 2 "immediate_operand" "i")))]
11386  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11387  "* return ix86_output_call_insn (insn, operands[0]);"
11388  [(set_attr "type" "call")])
11389
11390(define_insn_and_split "*sibcall_pop_vzeroupper"
11391  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11392	 (match_operand 1 "" ""))
11393   (set (reg:SI SP_REG)
11394	(plus:SI (reg:SI SP_REG)
11395		 (match_operand:SI 2 "immediate_operand" "i")))
11396   (unspec [(match_operand 3 "const_int_operand" "")]
11397   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11398  "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11399  "#"
11400  "&& reload_completed"
11401  [(const_int 0)]
11402  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11403  [(set_attr "type" "call")])
11404
11405(define_insn "*sibcall_pop"
11406  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11407	 (match_operand 1 "" ""))
11408   (set (reg:SI SP_REG)
11409	(plus:SI (reg:SI SP_REG)
11410		 (match_operand:SI 2 "immediate_operand" "i")))]
11411  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11412  "* return ix86_output_call_insn (insn, operands[0]);"
11413  [(set_attr "type" "call")])
11414
11415;; Call subroutine, returning value in operand 0
11416
11417(define_expand "call_value"
11418  [(set (match_operand 0 "" "")
11419	(call (match_operand:QI 1 "" "")
11420	      (match_operand 2 "" "")))
11421   (use (match_operand 3 "" ""))]
11422  ""
11423{
11424  ix86_expand_call (operands[0], operands[1], operands[2],
11425		    operands[3], NULL, false);
11426  DONE;
11427})
11428
11429(define_expand "sibcall_value"
11430  [(set (match_operand 0 "" "")
11431	(call (match_operand:QI 1 "" "")
11432	      (match_operand 2 "" "")))
11433   (use (match_operand 3 "" ""))]
11434  ""
11435{
11436  ix86_expand_call (operands[0], operands[1], operands[2],
11437		    operands[3], NULL, true);
11438  DONE;
11439})
11440
11441(define_insn_and_split "*call_value_vzeroupper"
11442  [(set (match_operand 0 "" "")
11443	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11444	      (match_operand 2 "" "")))
11445   (unspec [(match_operand 3 "const_int_operand" "")]
11446   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11447  "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11448  "#"
11449  "&& reload_completed"
11450  [(const_int 0)]
11451  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11452  [(set_attr "type" "callv")])
11453
11454(define_insn "*call_value"
11455  [(set (match_operand 0 "" "")
11456	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11457	      (match_operand 2 "" "")))]
11458  "!SIBLING_CALL_P (insn)"
11459  "* return ix86_output_call_insn (insn, operands[1]);"
11460  [(set_attr "type" "callv")])
11461
11462(define_insn_and_split "*sibcall_value_vzeroupper"
11463  [(set (match_operand 0 "" "")
11464	(call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11465	      (match_operand 2 "" "")))
11466   (unspec [(match_operand 3 "const_int_operand" "")]
11467   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11468  "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11469  "#"
11470  "&& reload_completed"
11471  [(const_int 0)]
11472  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11473  [(set_attr "type" "callv")])
11474
11475(define_insn "*sibcall_value"
11476  [(set (match_operand 0 "" "")
11477	(call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11478	      (match_operand 2 "" "")))]
11479  "SIBLING_CALL_P (insn)"
11480  "* return ix86_output_call_insn (insn, operands[1]);"
11481  [(set_attr "type" "callv")])
11482
11483(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11484  [(set (match_operand 0 "" "")
11485	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11486	      (match_operand 2 "" "")))
11487   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11488   (clobber (reg:TI XMM6_REG))
11489   (clobber (reg:TI XMM7_REG))
11490   (clobber (reg:TI XMM8_REG))
11491   (clobber (reg:TI XMM9_REG))
11492   (clobber (reg:TI XMM10_REG))
11493   (clobber (reg:TI XMM11_REG))
11494   (clobber (reg:TI XMM12_REG))
11495   (clobber (reg:TI XMM13_REG))
11496   (clobber (reg:TI XMM14_REG))
11497   (clobber (reg:TI XMM15_REG))
11498   (clobber (reg:DI SI_REG))
11499   (clobber (reg:DI DI_REG))
11500   (unspec [(match_operand 3 "const_int_operand" "")]
11501   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11502  "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11503  "#"
11504  "&& reload_completed"
11505  [(const_int 0)]
11506  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11507  [(set_attr "type" "callv")])
11508
11509(define_insn "*call_value_rex64_ms_sysv"
11510  [(set (match_operand 0 "" "")
11511	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11512	      (match_operand 2 "" "")))
11513   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11514   (clobber (reg:TI XMM6_REG))
11515   (clobber (reg:TI XMM7_REG))
11516   (clobber (reg:TI XMM8_REG))
11517   (clobber (reg:TI XMM9_REG))
11518   (clobber (reg:TI XMM10_REG))
11519   (clobber (reg:TI XMM11_REG))
11520   (clobber (reg:TI XMM12_REG))
11521   (clobber (reg:TI XMM13_REG))
11522   (clobber (reg:TI XMM14_REG))
11523   (clobber (reg:TI XMM15_REG))
11524   (clobber (reg:DI SI_REG))
11525   (clobber (reg:DI DI_REG))]
11526  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11527  "* return ix86_output_call_insn (insn, operands[1]);"
11528  [(set_attr "type" "callv")])
11529
11530(define_expand "call_value_pop"
11531  [(parallel [(set (match_operand 0 "" "")
11532		   (call (match_operand:QI 1 "" "")
11533			 (match_operand:SI 2 "" "")))
11534	      (set (reg:SI SP_REG)
11535		   (plus:SI (reg:SI SP_REG)
11536			    (match_operand:SI 4 "" "")))])]
11537  "!TARGET_64BIT"
11538{
11539  ix86_expand_call (operands[0], operands[1], operands[2],
11540		    operands[3], operands[4], false);
11541  DONE;
11542})
11543
11544(define_insn_and_split "*call_value_pop_vzeroupper"
11545  [(set (match_operand 0 "" "")
11546	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11547	      (match_operand 2 "" "")))
11548   (set (reg:SI SP_REG)
11549	(plus:SI (reg:SI SP_REG)
11550		 (match_operand:SI 3 "immediate_operand" "i")))
11551   (unspec [(match_operand 4 "const_int_operand" "")]
11552   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11553  "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11554  "#"
11555  "&& reload_completed"
11556  [(const_int 0)]
11557  "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11558  [(set_attr "type" "callv")])
11559
11560(define_insn "*call_value_pop"
11561  [(set (match_operand 0 "" "")
11562	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11563	      (match_operand 2 "" "")))
11564   (set (reg:SI SP_REG)
11565	(plus:SI (reg:SI SP_REG)
11566		 (match_operand:SI 3 "immediate_operand" "i")))]
11567  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11568  "* return ix86_output_call_insn (insn, operands[1]);"
11569  [(set_attr "type" "callv")])
11570
11571(define_insn_and_split "*sibcall_value_pop_vzeroupper"
11572  [(set (match_operand 0 "" "")
11573	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11574	      (match_operand 2 "" "")))
11575   (set (reg:SI SP_REG)
11576	(plus:SI (reg:SI SP_REG)
11577		 (match_operand:SI 3 "immediate_operand" "i")))
11578   (unspec [(match_operand 4 "const_int_operand" "")]
11579   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11580  "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11581  "#"
11582  "&& reload_completed"
11583  [(const_int 0)]
11584  "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11585  [(set_attr "type" "callv")])
11586
11587(define_insn "*sibcall_value_pop"
11588  [(set (match_operand 0 "" "")
11589	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11590	      (match_operand 2 "" "")))
11591   (set (reg:SI SP_REG)
11592	(plus:SI (reg:SI SP_REG)
11593		 (match_operand:SI 3 "immediate_operand" "i")))]
11594  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11595  "* return ix86_output_call_insn (insn, operands[1]);"
11596  [(set_attr "type" "callv")])
11597
11598;; Call subroutine returning any type.
11599
11600(define_expand "untyped_call"
11601  [(parallel [(call (match_operand 0 "" "")
11602		    (const_int 0))
11603	      (match_operand 1 "" "")
11604	      (match_operand 2 "" "")])]
11605  ""
11606{
11607  int i;
11608
11609  /* In order to give reg-stack an easier job in validating two
11610     coprocessor registers as containing a possible return value,
11611     simply pretend the untyped call returns a complex long double
11612     value.
11613
11614     We can't use SSE_REGPARM_MAX here since callee is unprototyped
11615     and should have the default ABI.  */
11616
11617  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11618		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11619		    operands[0], const0_rtx,
11620		    GEN_INT ((TARGET_64BIT
11621			      ? (ix86_abi == SYSV_ABI
11622				 ? X86_64_SSE_REGPARM_MAX
11623				 : X86_64_MS_SSE_REGPARM_MAX)
11624			      : X86_32_SSE_REGPARM_MAX)
11625		    	     - 1),
11626		    NULL, false);
11627
11628  for (i = 0; i < XVECLEN (operands[2], 0); i++)
11629    {
11630      rtx set = XVECEXP (operands[2], 0, i);
11631      emit_move_insn (SET_DEST (set), SET_SRC (set));
11632    }
11633
11634  /* The optimizer does not know that the call sets the function value
11635     registers we stored in the result block.  We avoid problems by
11636     claiming that all hard registers are used and clobbered at this
11637     point.  */
11638  emit_insn (gen_blockage ());
11639
11640  DONE;
11641})
11642
11643;; Prologue and epilogue instructions
11644
11645;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11646;; all of memory.  This blocks insns from being moved across this point.
11647
11648(define_insn "blockage"
11649  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11650  ""
11651  ""
11652  [(set_attr "length" "0")])
11653
11654;; Do not schedule instructions accessing memory across this point.
11655
11656(define_expand "memory_blockage"
11657  [(set (match_dup 0)
11658	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11659  ""
11660{
11661  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11662  MEM_VOLATILE_P (operands[0]) = 1;
11663})
11664
11665(define_insn "*memory_blockage"
11666  [(set (match_operand:BLK 0 "" "")
11667	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11668  ""
11669  ""
11670  [(set_attr "length" "0")])
11671
11672;; As USE insns aren't meaningful after reload, this is used instead
11673;; to prevent deleting instructions setting registers for PIC code
11674(define_insn "prologue_use"
11675  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11676  ""
11677  ""
11678  [(set_attr "length" "0")])
11679
11680;; Insn emitted into the body of a function to return from a function.
11681;; This is only done if the function's epilogue is known to be simple.
11682;; See comments for ix86_can_use_return_insn_p in i386.c.
11683
11684(define_expand "return"
11685  [(simple_return)]
11686  "ix86_can_use_return_insn_p ()"
11687{
11688  ix86_maybe_emit_epilogue_vzeroupper ();
11689  if (crtl->args.pops_args)
11690    {
11691      rtx popc = GEN_INT (crtl->args.pops_args);
11692      emit_jump_insn (gen_simple_return_pop_internal (popc));
11693      DONE;
11694    }
11695})
11696
11697;; We need to disable this for TARGET_SEH, as otherwise
11698;; shrink-wrapped prologue gets enabled too.  This might exceed
11699;; the maximum size of prologue in unwind information.
11700
11701(define_expand "simple_return"
11702  [(simple_return)]
11703  "!TARGET_SEH"
11704{
11705  ix86_maybe_emit_epilogue_vzeroupper ();
11706  if (crtl->args.pops_args)
11707    {
11708      rtx popc = GEN_INT (crtl->args.pops_args);
11709      emit_jump_insn (gen_simple_return_pop_internal (popc));
11710      DONE;
11711    }
11712})
11713
11714(define_insn "simple_return_internal"
11715  [(simple_return)]
11716  "reload_completed"
11717  "ret"
11718  [(set_attr "length" "1")
11719   (set_attr "atom_unit" "jeu")
11720   (set_attr "length_immediate" "0")
11721   (set_attr "modrm" "0")])
11722
11723;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11724;; instruction Athlon and K8 have.
11725
11726(define_insn "simple_return_internal_long"
11727  [(simple_return)
11728   (unspec [(const_int 0)] UNSPEC_REP)]
11729  "reload_completed"
11730  "rep\;ret"
11731  [(set_attr "length" "2")
11732   (set_attr "atom_unit" "jeu")
11733   (set_attr "length_immediate" "0")
11734   (set_attr "prefix_rep" "1")
11735   (set_attr "modrm" "0")])
11736
11737(define_insn "simple_return_pop_internal"
11738  [(simple_return)
11739   (use (match_operand:SI 0 "const_int_operand" ""))]
11740  "reload_completed"
11741  "ret\t%0"
11742  [(set_attr "length" "3")
11743   (set_attr "atom_unit" "jeu")
11744   (set_attr "length_immediate" "2")
11745   (set_attr "modrm" "0")])
11746
11747(define_insn "simple_return_indirect_internal"
11748  [(simple_return)
11749   (use (match_operand:SI 0 "register_operand" "r"))]
11750  "reload_completed"
11751  "jmp\t%A0"
11752  [(set_attr "type" "ibr")
11753   (set_attr "length_immediate" "0")])
11754
11755(define_insn "nop"
11756  [(const_int 0)]
11757  ""
11758  "nop"
11759  [(set_attr "length" "1")
11760   (set_attr "length_immediate" "0")
11761   (set_attr "modrm" "0")])
11762
11763;; Generate nops.  Operand 0 is the number of nops, up to 8.
11764(define_insn "nops"
11765  [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11766		    UNSPECV_NOPS)]
11767  "reload_completed"
11768{
11769  int num = INTVAL (operands[0]);
11770
11771  gcc_assert (num >= 1 && num <= 8);
11772
11773  while (num--)
11774    fputs ("\tnop\n", asm_out_file);
11775
11776  return "";
11777}
11778  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11779   (set_attr "length_immediate" "0")
11780   (set_attr "modrm" "0")])
11781
11782;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11783;; branch prediction penalty for the third jump in a 16-byte
11784;; block on K8.
11785
11786(define_insn "pad"
11787  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11788  ""
11789{
11790#ifdef ASM_OUTPUT_MAX_SKIP_PAD
11791  ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11792#else
11793  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11794     The align insn is used to avoid 3 jump instructions in the row to improve
11795     branch prediction and the benefits hardly outweigh the cost of extra 8
11796     nops on the average inserted by full alignment pseudo operation.  */
11797#endif
11798  return "";
11799}
11800  [(set_attr "length" "16")])
11801
11802(define_expand "prologue"
11803  [(const_int 0)]
11804  ""
11805  "ix86_expand_prologue (); DONE;")
11806
11807(define_insn "set_got"
11808  [(set (match_operand:SI 0 "register_operand" "=r")
11809	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11810   (clobber (reg:CC FLAGS_REG))]
11811  "!TARGET_64BIT"
11812  "* return output_set_got (operands[0], NULL_RTX);"
11813  [(set_attr "type" "multi")
11814   (set_attr "length" "12")])
11815
11816(define_insn "set_got_labelled"
11817  [(set (match_operand:SI 0 "register_operand" "=r")
11818	(unspec:SI [(label_ref (match_operand 1 "" ""))]
11819	 UNSPEC_SET_GOT))
11820   (clobber (reg:CC FLAGS_REG))]
11821  "!TARGET_64BIT"
11822  "* return output_set_got (operands[0], operands[1]);"
11823  [(set_attr "type" "multi")
11824   (set_attr "length" "12")])
11825
11826(define_insn "set_got_rex64"
11827  [(set (match_operand:DI 0 "register_operand" "=r")
11828	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11829  "TARGET_64BIT"
11830  "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11831  [(set_attr "type" "lea")
11832   (set_attr "length_address" "4")
11833   (set_attr "mode" "DI")])
11834
11835(define_insn "set_rip_rex64"
11836  [(set (match_operand:DI 0 "register_operand" "=r")
11837	(unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11838  "TARGET_64BIT"
11839  "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11840  [(set_attr "type" "lea")
11841   (set_attr "length_address" "4")
11842   (set_attr "mode" "DI")])
11843
11844(define_insn "set_got_offset_rex64"
11845  [(set (match_operand:DI 0 "register_operand" "=r")
11846	(unspec:DI
11847	  [(label_ref (match_operand 1 "" ""))]
11848	  UNSPEC_SET_GOT_OFFSET))]
11849  "TARGET_LP64"
11850  "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11851  [(set_attr "type" "imov")
11852   (set_attr "length_immediate" "0")
11853   (set_attr "length_address" "8")
11854   (set_attr "mode" "DI")])
11855
11856(define_expand "epilogue"
11857  [(const_int 0)]
11858  ""
11859  "ix86_expand_epilogue (1); DONE;")
11860
11861(define_expand "sibcall_epilogue"
11862  [(const_int 0)]
11863  ""
11864  "ix86_expand_epilogue (0); DONE;")
11865
11866(define_expand "eh_return"
11867  [(use (match_operand 0 "register_operand" ""))]
11868  ""
11869{
11870  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11871
11872  /* Tricky bit: we write the address of the handler to which we will
11873     be returning into someone else's stack frame, one word below the
11874     stack address we wish to restore.  */
11875  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11876  tmp = plus_constant (tmp, -UNITS_PER_WORD);
11877  tmp = gen_rtx_MEM (Pmode, tmp);
11878  emit_move_insn (tmp, ra);
11879
11880  emit_jump_insn (gen_eh_return_internal ());
11881  emit_barrier ();
11882  DONE;
11883})
11884
11885(define_insn_and_split "eh_return_internal"
11886  [(eh_return)]
11887  ""
11888  "#"
11889  "epilogue_completed"
11890  [(const_int 0)]
11891  "ix86_expand_epilogue (2); DONE;")
11892
11893(define_insn "leave"
11894  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11895   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11896   (clobber (mem:BLK (scratch)))]
11897  "!TARGET_64BIT"
11898  "leave"
11899  [(set_attr "type" "leave")])
11900
11901(define_insn "leave_rex64"
11902  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11903   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11904   (clobber (mem:BLK (scratch)))]
11905  "TARGET_64BIT"
11906  "leave"
11907  [(set_attr "type" "leave")])
11908
11909;; Handle -fsplit-stack.
11910
11911(define_expand "split_stack_prologue"
11912  [(const_int 0)]
11913  ""
11914{
11915  ix86_expand_split_stack_prologue ();
11916  DONE;
11917})
11918
11919;; In order to support the call/return predictor, we use a return
11920;; instruction which the middle-end doesn't see.
11921(define_insn "split_stack_return"
11922  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11923		     UNSPECV_SPLIT_STACK_RETURN)]
11924  ""
11925{
11926  if (operands[0] == const0_rtx)
11927    return "ret";
11928  else
11929    return "ret\t%0";
11930}
11931  [(set_attr "atom_unit" "jeu")
11932   (set_attr "modrm" "0")
11933   (set (attr "length")
11934	(if_then_else (match_operand:SI 0 "const0_operand" "")
11935		      (const_int 1)
11936		      (const_int 3)))
11937   (set (attr "length_immediate")
11938	(if_then_else (match_operand:SI 0 "const0_operand" "")
11939		      (const_int 0)
11940		      (const_int 2)))])
11941
11942;; If there are operand 0 bytes available on the stack, jump to
11943;; operand 1.
11944
11945(define_expand "split_stack_space_check"
11946  [(set (pc) (if_then_else
11947	      (ltu (minus (reg SP_REG)
11948			  (match_operand 0 "register_operand" ""))
11949		   (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11950	      (label_ref (match_operand 1 "" ""))
11951	      (pc)))]
11952  ""
11953{
11954  rtx reg, size, limit;
11955
11956  reg = gen_reg_rtx (Pmode);
11957  size = force_reg (Pmode, operands[0]);
11958  emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11959  limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11960			  UNSPEC_STACK_CHECK);
11961  limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11962  ix86_expand_branch (GEU, reg, limit, operands[1]);
11963
11964  DONE;
11965})
11966
11967;; Bit manipulation instructions.
11968
11969(define_expand "ffs<mode>2"
11970  [(set (match_dup 2) (const_int -1))
11971   (parallel [(set (reg:CCZ FLAGS_REG)
11972		   (compare:CCZ
11973		     (match_operand:SWI48 1 "nonimmediate_operand" "")
11974		     (const_int 0)))
11975	      (set (match_operand:SWI48 0 "register_operand" "")
11976		   (ctz:SWI48 (match_dup 1)))])
11977   (set (match_dup 0) (if_then_else:SWI48
11978			(eq (reg:CCZ FLAGS_REG) (const_int 0))
11979			(match_dup 2)
11980			(match_dup 0)))
11981   (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11982	      (clobber (reg:CC FLAGS_REG))])]
11983  ""
11984{
11985  if (<MODE>mode == SImode && !TARGET_CMOVE)
11986    {
11987      emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11988      DONE;
11989    }
11990  operands[2] = gen_reg_rtx (<MODE>mode);
11991})
11992
11993(define_insn_and_split "ffssi2_no_cmove"
11994  [(set (match_operand:SI 0 "register_operand" "=r")
11995	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11996   (clobber (match_scratch:SI 2 "=&q"))
11997   (clobber (reg:CC FLAGS_REG))]
11998  "!TARGET_CMOVE"
11999  "#"
12000  "&& reload_completed"
12001  [(parallel [(set (reg:CCZ FLAGS_REG)
12002		   (compare:CCZ (match_dup 1) (const_int 0)))
12003	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
12004   (set (strict_low_part (match_dup 3))
12005	(eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12006   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12007	      (clobber (reg:CC FLAGS_REG))])
12008   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12009	      (clobber (reg:CC FLAGS_REG))])
12010   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12011	      (clobber (reg:CC FLAGS_REG))])]
12012{
12013  operands[3] = gen_lowpart (QImode, operands[2]);
12014  ix86_expand_clear (operands[2]);
12015})
12016
12017(define_insn "*ffs<mode>_1"
12018  [(set (reg:CCZ FLAGS_REG)
12019	(compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12020		     (const_int 0)))
12021   (set (match_operand:SWI48 0 "register_operand" "=r")
12022	(ctz:SWI48 (match_dup 1)))]
12023  ""
12024  "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12025  [(set_attr "type" "alu1")
12026   (set_attr "prefix_0f" "1")
12027   (set_attr "mode" "<MODE>")])
12028
12029(define_insn "ctz<mode>2"
12030  [(set (match_operand:SWI248 0 "register_operand" "=r")
12031	(ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12032   (clobber (reg:CC FLAGS_REG))]
12033  ""
12034{
12035  if (TARGET_BMI)
12036    return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12037  else
12038    return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12039}
12040  [(set_attr "type" "alu1")
12041   (set_attr "prefix_0f" "1")
12042   (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12043   (set_attr "mode" "<MODE>")])
12044
12045(define_expand "clz<mode>2"
12046  [(parallel
12047     [(set (match_operand:SWI248 0 "register_operand" "")
12048	   (minus:SWI248
12049	     (match_dup 2)
12050	     (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12051      (clobber (reg:CC FLAGS_REG))])
12052   (parallel
12053     [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12054      (clobber (reg:CC FLAGS_REG))])]
12055  ""
12056{
12057  if (TARGET_LZCNT)
12058    {
12059      emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12060      DONE;
12061    }
12062  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12063})
12064
12065(define_insn "clz<mode>2_lzcnt"
12066  [(set (match_operand:SWI248 0 "register_operand" "=r")
12067	(clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12068   (clobber (reg:CC FLAGS_REG))]
12069  "TARGET_LZCNT"
12070  "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12071  [(set_attr "prefix_rep" "1")
12072   (set_attr "type" "bitmanip")
12073   (set_attr "mode" "<MODE>")])
12074
12075;; BMI instructions.
12076(define_insn "*bmi_andn_<mode>"
12077  [(set (match_operand:SWI48 0 "register_operand" "=r")
12078        (and:SWI48
12079          (not:SWI48
12080            (match_operand:SWI48 1 "register_operand" "r"))
12081            (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12082   (clobber (reg:CC FLAGS_REG))]
12083  "TARGET_BMI"
12084  "andn\t{%2, %1, %0|%0, %1, %2}"
12085  [(set_attr "type" "bitmanip")
12086   (set_attr "mode" "<MODE>")])
12087
12088(define_insn "bmi_bextr_<mode>"
12089  [(set (match_operand:SWI48 0 "register_operand" "=r")
12090        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12091                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12092                       UNSPEC_BEXTR))
12093   (clobber (reg:CC FLAGS_REG))]
12094  "TARGET_BMI"
12095  "bextr\t{%2, %1, %0|%0, %1, %2}"
12096  [(set_attr "type" "bitmanip")
12097   (set_attr "mode" "<MODE>")])
12098
12099(define_insn "*bmi_blsi_<mode>"
12100  [(set (match_operand:SWI48 0 "register_operand" "=r")
12101        (and:SWI48
12102          (neg:SWI48
12103            (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12104          (match_dup 1)))
12105   (clobber (reg:CC FLAGS_REG))]
12106  "TARGET_BMI"
12107  "blsi\t{%1, %0|%0, %1}"
12108  [(set_attr "type" "bitmanip")
12109   (set_attr "mode" "<MODE>")])
12110
12111(define_insn "*bmi_blsmsk_<mode>"
12112  [(set (match_operand:SWI48 0 "register_operand" "=r")
12113        (xor:SWI48
12114          (plus:SWI48
12115            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12116            (const_int -1))
12117          (match_dup 1)))
12118   (clobber (reg:CC FLAGS_REG))]
12119  "TARGET_BMI"
12120  "blsmsk\t{%1, %0|%0, %1}"
12121  [(set_attr "type" "bitmanip")
12122   (set_attr "mode" "<MODE>")])
12123
12124(define_insn "*bmi_blsr_<mode>"
12125  [(set (match_operand:SWI48 0 "register_operand" "=r")
12126        (and:SWI48
12127          (plus:SWI48
12128            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12129            (const_int -1))
12130          (match_dup 1)))
12131   (clobber (reg:CC FLAGS_REG))]
12132   "TARGET_BMI"
12133   "blsr\t{%1, %0|%0, %1}"
12134  [(set_attr "type" "bitmanip")
12135   (set_attr "mode" "<MODE>")])
12136
12137;; BMI2 instructions.
12138(define_insn "bmi2_bzhi_<mode>3"
12139  [(set (match_operand:SWI48 0 "register_operand" "=r")
12140	(and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12141		   (lshiftrt:SWI48 (const_int -1)
12142				   (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12143   (clobber (reg:CC FLAGS_REG))]
12144  "TARGET_BMI2"
12145  "bzhi\t{%2, %1, %0|%0, %1, %2}"
12146  [(set_attr "type" "bitmanip")
12147   (set_attr "prefix" "vex")
12148   (set_attr "mode" "<MODE>")])
12149
12150(define_insn "bmi2_pdep_<mode>3"
12151  [(set (match_operand:SWI48 0 "register_operand" "=r")
12152        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12153                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12154                       UNSPEC_PDEP))]
12155  "TARGET_BMI2"
12156  "pdep\t{%2, %1, %0|%0, %1, %2}"
12157  [(set_attr "type" "bitmanip")
12158   (set_attr "prefix" "vex")
12159   (set_attr "mode" "<MODE>")])
12160
12161(define_insn "bmi2_pext_<mode>3"
12162  [(set (match_operand:SWI48 0 "register_operand" "=r")
12163        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12164                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12165                       UNSPEC_PEXT))]
12166  "TARGET_BMI2"
12167  "pext\t{%2, %1, %0|%0, %1, %2}"
12168  [(set_attr "type" "bitmanip")
12169   (set_attr "prefix" "vex")
12170   (set_attr "mode" "<MODE>")])
12171
12172;; TBM instructions.
12173(define_insn "tbm_bextri_<mode>"
12174  [(set (match_operand:SWI48 0 "register_operand" "=r")
12175        (zero_extract:SWI48
12176          (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12177          (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12178          (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12179   (clobber (reg:CC FLAGS_REG))]
12180   "TARGET_TBM"
12181{
12182  operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12183  return "bextr\t{%2, %1, %0|%0, %1, %2}";
12184}
12185  [(set_attr "type" "bitmanip")
12186   (set_attr "mode" "<MODE>")])
12187
12188(define_insn "*tbm_blcfill_<mode>"
12189  [(set (match_operand:SWI48 0 "register_operand" "=r")
12190        (and:SWI48
12191          (plus:SWI48
12192            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12193            (const_int 1))
12194          (match_dup 1)))
12195   (clobber (reg:CC FLAGS_REG))]
12196   "TARGET_TBM"
12197   "blcfill\t{%1, %0|%0, %1}"
12198  [(set_attr "type" "bitmanip")
12199   (set_attr "mode" "<MODE>")])
12200
12201(define_insn "*tbm_blci_<mode>"
12202  [(set (match_operand:SWI48 0 "register_operand" "=r")
12203        (ior:SWI48
12204          (not:SWI48
12205            (plus:SWI48
12206              (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12207              (const_int 1)))
12208          (match_dup 1)))
12209   (clobber (reg:CC FLAGS_REG))]
12210   "TARGET_TBM"
12211   "blci\t{%1, %0|%0, %1}"
12212  [(set_attr "type" "bitmanip")
12213   (set_attr "mode" "<MODE>")])
12214
12215(define_insn "*tbm_blcic_<mode>"
12216  [(set (match_operand:SWI48 0 "register_operand" "=r")
12217        (and:SWI48
12218          (plus:SWI48
12219            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12220            (const_int 1))
12221          (not:SWI48
12222            (match_dup 1))))
12223   (clobber (reg:CC FLAGS_REG))]
12224   "TARGET_TBM"
12225   "blcic\t{%1, %0|%0, %1}"
12226  [(set_attr "type" "bitmanip")
12227   (set_attr "mode" "<MODE>")])
12228
12229(define_insn "*tbm_blcmsk_<mode>"
12230  [(set (match_operand:SWI48 0 "register_operand" "=r")
12231        (xor:SWI48
12232          (plus:SWI48
12233            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12234            (const_int 1))
12235          (match_dup 1)))
12236   (clobber (reg:CC FLAGS_REG))]
12237   "TARGET_TBM"
12238   "blcmsk\t{%1, %0|%0, %1}"
12239  [(set_attr "type" "bitmanip")
12240   (set_attr "mode" "<MODE>")])
12241
12242(define_insn "*tbm_blcs_<mode>"
12243  [(set (match_operand:SWI48 0 "register_operand" "=r")
12244        (ior:SWI48
12245          (plus:SWI48
12246            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12247            (const_int 1))
12248          (match_dup 1)))
12249   (clobber (reg:CC FLAGS_REG))]
12250   "TARGET_TBM"
12251   "blcs\t{%1, %0|%0, %1}"
12252  [(set_attr "type" "bitmanip")
12253   (set_attr "mode" "<MODE>")])
12254
12255(define_insn "*tbm_blsfill_<mode>"
12256  [(set (match_operand:SWI48 0 "register_operand" "=r")
12257        (ior:SWI48
12258          (plus:SWI48
12259            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12260            (const_int -1))
12261          (match_dup 1)))
12262   (clobber (reg:CC FLAGS_REG))]
12263   "TARGET_TBM"
12264   "blsfill\t{%1, %0|%0, %1}"
12265  [(set_attr "type" "bitmanip")
12266   (set_attr "mode" "<MODE>")])
12267
12268(define_insn "*tbm_blsic_<mode>"
12269  [(set (match_operand:SWI48 0 "register_operand" "=r")
12270        (ior:SWI48
12271          (plus:SWI48
12272            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12273            (const_int -1))
12274          (not:SWI48
12275            (match_dup 1))))
12276   (clobber (reg:CC FLAGS_REG))]
12277   "TARGET_TBM"
12278   "blsic\t{%1, %0|%0, %1}"
12279  [(set_attr "type" "bitmanip")
12280   (set_attr "mode" "<MODE>")])
12281
12282(define_insn "*tbm_t1mskc_<mode>"
12283  [(set (match_operand:SWI48 0 "register_operand" "=r")
12284        (ior:SWI48
12285          (plus:SWI48
12286            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12287            (const_int 1))
12288          (not:SWI48
12289            (match_dup 1))))
12290   (clobber (reg:CC FLAGS_REG))]
12291   "TARGET_TBM"
12292   "t1mskc\t{%1, %0|%0, %1}"
12293  [(set_attr "type" "bitmanip")
12294   (set_attr "mode" "<MODE>")])
12295
12296(define_insn "*tbm_tzmsk_<mode>"
12297  [(set (match_operand:SWI48 0 "register_operand" "=r")
12298        (and:SWI48
12299          (plus:SWI48
12300            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12301            (const_int -1))
12302          (not:SWI48
12303            (match_dup 1))))
12304   (clobber (reg:CC FLAGS_REG))]
12305   "TARGET_TBM"
12306   "tzmsk\t{%1, %0|%0, %1}"
12307  [(set_attr "type" "bitmanip")
12308   (set_attr "mode" "<MODE>")])
12309
12310(define_insn "bsr_rex64"
12311  [(set (match_operand:DI 0 "register_operand" "=r")
12312	(minus:DI (const_int 63)
12313		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12314   (clobber (reg:CC FLAGS_REG))]
12315  "TARGET_64BIT"
12316  "bsr{q}\t{%1, %0|%0, %1}"
12317  [(set_attr "type" "alu1")
12318   (set_attr "prefix_0f" "1")
12319   (set_attr "mode" "DI")])
12320
12321(define_insn "bsr"
12322  [(set (match_operand:SI 0 "register_operand" "=r")
12323	(minus:SI (const_int 31)
12324		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12325   (clobber (reg:CC FLAGS_REG))]
12326  ""
12327  "bsr{l}\t{%1, %0|%0, %1}"
12328  [(set_attr "type" "alu1")
12329   (set_attr "prefix_0f" "1")
12330   (set_attr "mode" "SI")])
12331
12332(define_insn "*bsrhi"
12333  [(set (match_operand:HI 0 "register_operand" "=r")
12334	(minus:HI (const_int 15)
12335		  (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12336   (clobber (reg:CC FLAGS_REG))]
12337  ""
12338  "bsr{w}\t{%1, %0|%0, %1}"
12339  [(set_attr "type" "alu1")
12340   (set_attr "prefix_0f" "1")
12341   (set_attr "mode" "HI")])
12342
12343(define_insn "popcount<mode>2"
12344  [(set (match_operand:SWI248 0 "register_operand" "=r")
12345	(popcount:SWI248
12346	  (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12347   (clobber (reg:CC FLAGS_REG))]
12348  "TARGET_POPCNT"
12349{
12350#if TARGET_MACHO
12351  return "popcnt\t{%1, %0|%0, %1}";
12352#else
12353  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12354#endif
12355}
12356  [(set_attr "prefix_rep" "1")
12357   (set_attr "type" "bitmanip")
12358   (set_attr "mode" "<MODE>")])
12359
12360(define_insn "*popcount<mode>2_cmp"
12361  [(set (reg FLAGS_REG)
12362	(compare
12363	  (popcount:SWI248
12364	    (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12365	  (const_int 0)))
12366   (set (match_operand:SWI248 0 "register_operand" "=r")
12367	(popcount:SWI248 (match_dup 1)))]
12368  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12369{
12370#if TARGET_MACHO
12371  return "popcnt\t{%1, %0|%0, %1}";
12372#else
12373  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12374#endif
12375}
12376  [(set_attr "prefix_rep" "1")
12377   (set_attr "type" "bitmanip")
12378   (set_attr "mode" "<MODE>")])
12379
12380(define_insn "*popcountsi2_cmp_zext"
12381  [(set (reg FLAGS_REG)
12382        (compare
12383          (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12384          (const_int 0)))
12385   (set (match_operand:DI 0 "register_operand" "=r")
12386        (zero_extend:DI(popcount:SI (match_dup 1))))]
12387  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12388{
12389#if TARGET_MACHO
12390  return "popcnt\t{%1, %0|%0, %1}";
12391#else
12392  return "popcnt{l}\t{%1, %0|%0, %1}";
12393#endif
12394}
12395  [(set_attr "prefix_rep" "1")
12396   (set_attr "type" "bitmanip")
12397   (set_attr "mode" "SI")])
12398
12399(define_expand "bswap<mode>2"
12400  [(set (match_operand:SWI48 0 "register_operand" "")
12401	(bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12402  ""
12403{
12404  if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12405    {
12406      rtx x = operands[0];
12407
12408      emit_move_insn (x, operands[1]);
12409      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12410      emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12411      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12412      DONE;
12413    }
12414})
12415
12416(define_insn "*bswap<mode>2_movbe"
12417  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12418	(bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12419  "TARGET_MOVBE
12420   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12421  "@
12422    bswap\t%0
12423    movbe\t{%1, %0|%0, %1}
12424    movbe\t{%1, %0|%0, %1}"
12425  [(set_attr "type" "bitmanip,imov,imov")
12426   (set_attr "modrm" "0,1,1")
12427   (set_attr "prefix_0f" "*,1,1")
12428   (set_attr "prefix_extra" "*,1,1")
12429   (set_attr "mode" "<MODE>")])
12430
12431(define_insn "*bswap<mode>2_1"
12432  [(set (match_operand:SWI48 0 "register_operand" "=r")
12433	(bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12434  "TARGET_BSWAP"
12435  "bswap\t%0"
12436  [(set_attr "type" "bitmanip")
12437   (set_attr "modrm" "0")
12438   (set_attr "mode" "<MODE>")])
12439
12440(define_insn "*bswaphi_lowpart_1"
12441  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12442	(bswap:HI (match_dup 0)))
12443   (clobber (reg:CC FLAGS_REG))]
12444  "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12445  "@
12446    xchg{b}\t{%h0, %b0|%b0, %h0}
12447    rol{w}\t{$8, %0|%0, 8}"
12448  [(set_attr "length" "2,4")
12449   (set_attr "mode" "QI,HI")])
12450
12451(define_insn "bswaphi_lowpart"
12452  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12453	(bswap:HI (match_dup 0)))
12454   (clobber (reg:CC FLAGS_REG))]
12455  ""
12456  "rol{w}\t{$8, %0|%0, 8}"
12457  [(set_attr "length" "4")
12458   (set_attr "mode" "HI")])
12459
12460(define_expand "paritydi2"
12461  [(set (match_operand:DI 0 "register_operand" "")
12462	(parity:DI (match_operand:DI 1 "register_operand" "")))]
12463  "! TARGET_POPCNT"
12464{
12465  rtx scratch = gen_reg_rtx (QImode);
12466  rtx cond;
12467
12468  emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12469				NULL_RTX, operands[1]));
12470
12471  cond = gen_rtx_fmt_ee (ORDERED, QImode,
12472			 gen_rtx_REG (CCmode, FLAGS_REG),
12473			 const0_rtx);
12474  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12475
12476  if (TARGET_64BIT)
12477    emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12478  else
12479    {
12480      rtx tmp = gen_reg_rtx (SImode);
12481
12482      emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12483      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12484    }
12485  DONE;
12486})
12487
12488(define_expand "paritysi2"
12489  [(set (match_operand:SI 0 "register_operand" "")
12490	(parity:SI (match_operand:SI 1 "register_operand" "")))]
12491  "! TARGET_POPCNT"
12492{
12493  rtx scratch = gen_reg_rtx (QImode);
12494  rtx cond;
12495
12496  emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12497
12498  cond = gen_rtx_fmt_ee (ORDERED, QImode,
12499			 gen_rtx_REG (CCmode, FLAGS_REG),
12500			 const0_rtx);
12501  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12502
12503  emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12504  DONE;
12505})
12506
12507(define_insn_and_split "paritydi2_cmp"
12508  [(set (reg:CC FLAGS_REG)
12509	(unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12510		   UNSPEC_PARITY))
12511   (clobber (match_scratch:DI 0 "=r"))
12512   (clobber (match_scratch:SI 1 "=&r"))
12513   (clobber (match_scratch:HI 2 "=Q"))]
12514  "! TARGET_POPCNT"
12515  "#"
12516  "&& reload_completed"
12517  [(parallel
12518     [(set (match_dup 1)
12519	   (xor:SI (match_dup 1) (match_dup 4)))
12520      (clobber (reg:CC FLAGS_REG))])
12521   (parallel
12522     [(set (reg:CC FLAGS_REG)
12523	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12524      (clobber (match_dup 1))
12525      (clobber (match_dup 2))])]
12526{
12527  operands[4] = gen_lowpart (SImode, operands[3]);
12528
12529  if (TARGET_64BIT)
12530    {
12531      emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12532      emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12533    }
12534  else
12535    operands[1] = gen_highpart (SImode, operands[3]);
12536})
12537
12538(define_insn_and_split "paritysi2_cmp"
12539  [(set (reg:CC FLAGS_REG)
12540	(unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12541		   UNSPEC_PARITY))
12542   (clobber (match_scratch:SI 0 "=r"))
12543   (clobber (match_scratch:HI 1 "=&Q"))]
12544  "! TARGET_POPCNT"
12545  "#"
12546  "&& reload_completed"
12547  [(parallel
12548     [(set (match_dup 1)
12549	   (xor:HI (match_dup 1) (match_dup 3)))
12550      (clobber (reg:CC FLAGS_REG))])
12551   (parallel
12552     [(set (reg:CC FLAGS_REG)
12553	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12554      (clobber (match_dup 1))])]
12555{
12556  operands[3] = gen_lowpart (HImode, operands[2]);
12557
12558  emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12559  emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12560})
12561
12562(define_insn "*parityhi2_cmp"
12563  [(set (reg:CC FLAGS_REG)
12564	(unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12565		   UNSPEC_PARITY))
12566   (clobber (match_scratch:HI 0 "=Q"))]
12567  "! TARGET_POPCNT"
12568  "xor{b}\t{%h0, %b0|%b0, %h0}"
12569  [(set_attr "length" "2")
12570   (set_attr "mode" "HI")])
12571
12572
12573;; Thread-local storage patterns for ELF.
12574;;
12575;; Note that these code sequences must appear exactly as shown
12576;; in order to allow linker relaxation.
12577
12578(define_insn "*tls_global_dynamic_32_gnu"
12579  [(set (match_operand:SI 0 "register_operand" "=a")
12580	(unspec:SI
12581	 [(match_operand:SI 1 "register_operand" "b")
12582	  (match_operand:SI 2 "tls_symbolic_operand" "")
12583	  (match_operand:SI 3 "constant_call_address_operand" "z")]
12584	 UNSPEC_TLS_GD))
12585   (clobber (match_scratch:SI 4 "=d"))
12586   (clobber (match_scratch:SI 5 "=c"))
12587   (clobber (reg:CC FLAGS_REG))]
12588  "!TARGET_64BIT && TARGET_GNU_TLS"
12589{
12590  output_asm_insn
12591    ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12592  if (TARGET_SUN_TLS)
12593#ifdef HAVE_AS_IX86_TLSGDPLT
12594    return "call\t%a2@tlsgdplt";
12595#else
12596    return "call\t%p3@plt";
12597#endif
12598  return "call\t%P3";
12599}
12600  [(set_attr "type" "multi")
12601   (set_attr "length" "12")])
12602
12603(define_expand "tls_global_dynamic_32"
12604  [(parallel
12605    [(set (match_operand:SI 0 "register_operand" "")
12606	  (unspec:SI [(match_operand:SI 2 "register_operand" "")
12607		      (match_operand:SI 1 "tls_symbolic_operand" "")
12608		      (match_operand:SI 3 "constant_call_address_operand" "")]
12609		     UNSPEC_TLS_GD))
12610     (clobber (match_scratch:SI 4 ""))
12611     (clobber (match_scratch:SI 5 ""))
12612     (clobber (reg:CC FLAGS_REG))])])
12613
12614(define_insn "*tls_global_dynamic_64"
12615  [(set (match_operand:DI 0 "register_operand" "=a")
12616	(call:DI
12617	 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12618	 (match_operand:DI 3 "" "")))
12619   (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12620	      UNSPEC_TLS_GD)]
12621  "TARGET_64BIT"
12622{
12623  if (!TARGET_X32)
12624    fputs (ASM_BYTE "0x66\n", asm_out_file);
12625  output_asm_insn
12626    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12627  fputs (ASM_SHORT "0x6666\n", asm_out_file);
12628  fputs ("\trex64\n", asm_out_file);
12629  if (TARGET_SUN_TLS)
12630    return "call\t%p2@plt";
12631  return "call\t%P2";
12632}
12633  [(set_attr "type" "multi")
12634   (set (attr "length")
12635	(symbol_ref "TARGET_X32 ? 15 : 16"))])
12636
12637(define_expand "tls_global_dynamic_64"
12638  [(parallel
12639    [(set (match_operand:DI 0 "register_operand" "")
12640	  (call:DI
12641	   (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12642	   (const_int 0)))
12643     (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12644		UNSPEC_TLS_GD)])])
12645
12646(define_insn "*tls_local_dynamic_base_32_gnu"
12647  [(set (match_operand:SI 0 "register_operand" "=a")
12648	(unspec:SI
12649	 [(match_operand:SI 1 "register_operand" "b")
12650	  (match_operand:SI 2 "constant_call_address_operand" "z")]
12651	 UNSPEC_TLS_LD_BASE))
12652   (clobber (match_scratch:SI 3 "=d"))
12653   (clobber (match_scratch:SI 4 "=c"))
12654   (clobber (reg:CC FLAGS_REG))]
12655  "!TARGET_64BIT && TARGET_GNU_TLS"
12656{
12657  output_asm_insn
12658    ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12659  if (TARGET_SUN_TLS)
12660#ifdef HAVE_AS_IX86_TLSLDMPLT
12661    return "call\t%&@tlsldmplt";
12662#else
12663    return "call\t%p2@plt";
12664#endif
12665  return "call\t%P2";
12666}
12667  [(set_attr "type" "multi")
12668   (set_attr "length" "11")])
12669
12670(define_expand "tls_local_dynamic_base_32"
12671  [(parallel
12672     [(set (match_operand:SI 0 "register_operand" "")
12673	   (unspec:SI
12674	    [(match_operand:SI 1 "register_operand" "")
12675	     (match_operand:SI 2 "constant_call_address_operand" "")]
12676	    UNSPEC_TLS_LD_BASE))
12677      (clobber (match_scratch:SI 3 ""))
12678      (clobber (match_scratch:SI 4 ""))
12679      (clobber (reg:CC FLAGS_REG))])])
12680
12681(define_insn "*tls_local_dynamic_base_64"
12682  [(set (match_operand:DI 0 "register_operand" "=a")
12683	(call:DI
12684	 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12685	 (match_operand:DI 2 "" "")))
12686   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12687  "TARGET_64BIT"
12688{
12689  output_asm_insn
12690    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12691  if (TARGET_SUN_TLS)
12692    return "call\t%p1@plt";
12693  return "call\t%P1";
12694}
12695  [(set_attr "type" "multi")
12696   (set_attr "length" "12")])
12697
12698(define_expand "tls_local_dynamic_base_64"
12699  [(parallel
12700     [(set (match_operand:DI 0 "register_operand" "")
12701	   (call:DI
12702	    (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12703	    (const_int 0)))
12704      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12705
12706;; Local dynamic of a single variable is a lose.  Show combine how
12707;; to convert that back to global dynamic.
12708
12709(define_insn_and_split "*tls_local_dynamic_32_once"
12710  [(set (match_operand:SI 0 "register_operand" "=a")
12711	(plus:SI
12712	 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12713		     (match_operand:SI 2 "constant_call_address_operand" "z")]
12714		    UNSPEC_TLS_LD_BASE)
12715	 (const:SI (unspec:SI
12716		    [(match_operand:SI 3 "tls_symbolic_operand" "")]
12717		    UNSPEC_DTPOFF))))
12718   (clobber (match_scratch:SI 4 "=d"))
12719   (clobber (match_scratch:SI 5 "=c"))
12720   (clobber (reg:CC FLAGS_REG))]
12721  ""
12722  "#"
12723  ""
12724  [(parallel
12725     [(set (match_dup 0)
12726	   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12727		      UNSPEC_TLS_GD))
12728      (clobber (match_dup 4))
12729      (clobber (match_dup 5))
12730      (clobber (reg:CC FLAGS_REG))])])
12731
12732;; Segment register for the thread base ptr load
12733(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12734
12735;; Load and add the thread base pointer from %<tp_seg>:0.
12736(define_insn "*load_tp_x32"
12737  [(set (match_operand:SI 0 "register_operand" "=r")
12738	(unspec:SI [(const_int 0)] UNSPEC_TP))]
12739  "TARGET_X32"
12740  "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12741  [(set_attr "type" "imov")
12742   (set_attr "modrm" "0")
12743   (set_attr "length" "7")
12744   (set_attr "memory" "load")
12745   (set_attr "imm_disp" "false")])
12746
12747(define_insn "*load_tp_x32_zext"
12748  [(set (match_operand:DI 0 "register_operand" "=r")
12749	(zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12750  "TARGET_X32"
12751  "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12752  [(set_attr "type" "imov")
12753   (set_attr "modrm" "0")
12754   (set_attr "length" "7")
12755   (set_attr "memory" "load")
12756   (set_attr "imm_disp" "false")])
12757
12758(define_insn "*load_tp_<mode>"
12759  [(set (match_operand:P 0 "register_operand" "=r")
12760	(unspec:P [(const_int 0)] UNSPEC_TP))]
12761  "!TARGET_X32"
12762  "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12763  [(set_attr "type" "imov")
12764   (set_attr "modrm" "0")
12765   (set_attr "length" "7")
12766   (set_attr "memory" "load")
12767   (set_attr "imm_disp" "false")])
12768
12769(define_insn "*add_tp_x32"
12770  [(set (match_operand:SI 0 "register_operand" "=r")
12771	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12772		 (match_operand:SI 1 "register_operand" "0")))
12773   (clobber (reg:CC FLAGS_REG))]
12774  "TARGET_X32"
12775  "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12776  [(set_attr "type" "alu")
12777   (set_attr "modrm" "0")
12778   (set_attr "length" "7")
12779   (set_attr "memory" "load")
12780   (set_attr "imm_disp" "false")])
12781
12782(define_insn "*add_tp_x32_zext"
12783  [(set (match_operand:DI 0 "register_operand" "=r")
12784	(zero_extend:DI
12785	  (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12786		   (match_operand:SI 1 "register_operand" "0"))))
12787   (clobber (reg:CC FLAGS_REG))]
12788  "TARGET_X32"
12789  "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12790  [(set_attr "type" "alu")
12791   (set_attr "modrm" "0")
12792   (set_attr "length" "7")
12793   (set_attr "memory" "load")
12794   (set_attr "imm_disp" "false")])
12795
12796(define_insn "*add_tp_<mode>"
12797  [(set (match_operand:P 0 "register_operand" "=r")
12798	(plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12799		(match_operand:P 1 "register_operand" "0")))
12800   (clobber (reg:CC FLAGS_REG))]
12801  "!TARGET_X32"
12802  "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12803  [(set_attr "type" "alu")
12804   (set_attr "modrm" "0")
12805   (set_attr "length" "7")
12806   (set_attr "memory" "load")
12807   (set_attr "imm_disp" "false")])
12808
12809;; The Sun linker took the AMD64 TLS spec literally and can only handle
12810;; %rax as destination of the initial executable code sequence.
12811(define_insn "tls_initial_exec_64_sun"
12812  [(set (match_operand:DI 0 "register_operand" "=a")
12813	(unspec:DI
12814	 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12815	 UNSPEC_TLS_IE_SUN))
12816   (clobber (reg:CC FLAGS_REG))]
12817  "TARGET_64BIT && TARGET_SUN_TLS"
12818{
12819  output_asm_insn
12820    ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12821  return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12822}
12823  [(set_attr "type" "multi")])
12824
12825;; GNU2 TLS patterns can be split.
12826
12827(define_expand "tls_dynamic_gnu2_32"
12828  [(set (match_dup 3)
12829	(plus:SI (match_operand:SI 2 "register_operand" "")
12830		 (const:SI
12831		  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12832			     UNSPEC_TLSDESC))))
12833   (parallel
12834    [(set (match_operand:SI 0 "register_operand" "")
12835	  (unspec:SI [(match_dup 1) (match_dup 3)
12836		      (match_dup 2) (reg:SI SP_REG)]
12837		      UNSPEC_TLSDESC))
12838     (clobber (reg:CC FLAGS_REG))])]
12839  "!TARGET_64BIT && TARGET_GNU2_TLS"
12840{
12841  operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12842  ix86_tls_descriptor_calls_expanded_in_cfun = true;
12843})
12844
12845(define_insn "*tls_dynamic_gnu2_lea_32"
12846  [(set (match_operand:SI 0 "register_operand" "=r")
12847	(plus:SI (match_operand:SI 1 "register_operand" "b")
12848		 (const:SI
12849		  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12850			      UNSPEC_TLSDESC))))]
12851  "!TARGET_64BIT && TARGET_GNU2_TLS"
12852  "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12853  [(set_attr "type" "lea")
12854   (set_attr "mode" "SI")
12855   (set_attr "length" "6")
12856   (set_attr "length_address" "4")])
12857
12858(define_insn "*tls_dynamic_gnu2_call_32"
12859  [(set (match_operand:SI 0 "register_operand" "=a")
12860	(unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12861		    (match_operand:SI 2 "register_operand" "0")
12862		    ;; we have to make sure %ebx still points to the GOT
12863		    (match_operand:SI 3 "register_operand" "b")
12864		    (reg:SI SP_REG)]
12865		   UNSPEC_TLSDESC))
12866   (clobber (reg:CC FLAGS_REG))]
12867  "!TARGET_64BIT && TARGET_GNU2_TLS"
12868  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12869  [(set_attr "type" "call")
12870   (set_attr "length" "2")
12871   (set_attr "length_address" "0")])
12872
12873(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12874  [(set (match_operand:SI 0 "register_operand" "=&a")
12875	(plus:SI
12876	 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12877		     (match_operand:SI 4 "" "")
12878		     (match_operand:SI 2 "register_operand" "b")
12879		     (reg:SI SP_REG)]
12880		    UNSPEC_TLSDESC)
12881	 (const:SI (unspec:SI
12882		    [(match_operand:SI 1 "tls_symbolic_operand" "")]
12883		    UNSPEC_DTPOFF))))
12884   (clobber (reg:CC FLAGS_REG))]
12885  "!TARGET_64BIT && TARGET_GNU2_TLS"
12886  "#"
12887  ""
12888  [(set (match_dup 0) (match_dup 5))]
12889{
12890  operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12891  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12892})
12893
12894(define_expand "tls_dynamic_gnu2_64"
12895  [(set (match_dup 2)
12896	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12897		   UNSPEC_TLSDESC))
12898   (parallel
12899    [(set (match_operand:DI 0 "register_operand" "")
12900	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12901		     UNSPEC_TLSDESC))
12902     (clobber (reg:CC FLAGS_REG))])]
12903  "TARGET_64BIT && TARGET_GNU2_TLS"
12904{
12905  operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12906  ix86_tls_descriptor_calls_expanded_in_cfun = true;
12907})
12908
12909(define_insn "*tls_dynamic_gnu2_lea_64"
12910  [(set (match_operand:DI 0 "register_operand" "=r")
12911	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12912		   UNSPEC_TLSDESC))]
12913  "TARGET_64BIT && TARGET_GNU2_TLS"
12914  "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12915  [(set_attr "type" "lea")
12916   (set_attr "mode" "DI")
12917   (set_attr "length" "7")
12918   (set_attr "length_address" "4")])
12919
12920(define_insn "*tls_dynamic_gnu2_call_64"
12921  [(set (match_operand:DI 0 "register_operand" "=a")
12922	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12923		    (match_operand:DI 2 "register_operand" "0")
12924		    (reg:DI SP_REG)]
12925		   UNSPEC_TLSDESC))
12926   (clobber (reg:CC FLAGS_REG))]
12927  "TARGET_64BIT && TARGET_GNU2_TLS"
12928  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12929  [(set_attr "type" "call")
12930   (set_attr "length" "2")
12931   (set_attr "length_address" "0")])
12932
12933(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12934  [(set (match_operand:DI 0 "register_operand" "=&a")
12935	(plus:DI
12936	 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12937		     (match_operand:DI 3 "" "")
12938		     (reg:DI SP_REG)]
12939		    UNSPEC_TLSDESC)
12940	 (const:DI (unspec:DI
12941		    [(match_operand 1 "tls_symbolic_operand" "")]
12942		    UNSPEC_DTPOFF))))
12943   (clobber (reg:CC FLAGS_REG))]
12944  "TARGET_64BIT && TARGET_GNU2_TLS"
12945  "#"
12946  ""
12947  [(set (match_dup 0) (match_dup 4))]
12948{
12949  operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12950  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12951})
12952
12953;; These patterns match the binary 387 instructions for addM3, subM3,
12954;; mulM3 and divM3.  There are three patterns for each of DFmode and
12955;; SFmode.  The first is the normal insn, the second the same insn but
12956;; with one operand a conversion, and the third the same insn but with
12957;; the other operand a conversion.  The conversion may be SFmode or
12958;; SImode if the target mode DFmode, but only SImode if the target mode
12959;; is SFmode.
12960
12961;; Gcc is slightly more smart about handling normal two address instructions
12962;; so use special patterns for add and mull.
12963
12964(define_insn "*fop_<mode>_comm_mixed"
12965  [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12966	(match_operator:MODEF 3 "binary_fp_operator"
12967	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12968	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12969  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12970   && COMMUTATIVE_ARITH_P (operands[3])
12971   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12972  "* return output_387_binary_op (insn, operands);"
12973  [(set (attr "type")
12974	(if_then_else (eq_attr "alternative" "1,2")
12975	   (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12976	      (const_string "ssemul")
12977	      (const_string "sseadd"))
12978	   (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12979	      (const_string "fmul")
12980	      (const_string "fop"))))
12981   (set_attr "isa" "*,noavx,avx")
12982   (set_attr "prefix" "orig,orig,vex")
12983   (set_attr "mode" "<MODE>")])
12984
12985(define_insn "*fop_<mode>_comm_sse"
12986  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12987	(match_operator:MODEF 3 "binary_fp_operator"
12988	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12989	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12990  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12991   && COMMUTATIVE_ARITH_P (operands[3])
12992   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12993  "* return output_387_binary_op (insn, operands);"
12994  [(set (attr "type")
12995        (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12996	   (const_string "ssemul")
12997	   (const_string "sseadd")))
12998   (set_attr "isa" "noavx,avx")
12999   (set_attr "prefix" "orig,vex")
13000   (set_attr "mode" "<MODE>")])
13001
13002(define_insn "*fop_<mode>_comm_i387"
13003  [(set (match_operand:MODEF 0 "register_operand" "=f")
13004	(match_operator:MODEF 3 "binary_fp_operator"
13005	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13006	   (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13007  "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13008   && COMMUTATIVE_ARITH_P (operands[3])
13009   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13010  "* return output_387_binary_op (insn, operands);"
13011  [(set (attr "type")
13012	(if_then_else (match_operand:MODEF 3 "mult_operator" "")
13013	   (const_string "fmul")
13014	   (const_string "fop")))
13015   (set_attr "mode" "<MODE>")])
13016
13017(define_insn "*fop_<mode>_1_mixed"
13018  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13019	(match_operator:MODEF 3 "binary_fp_operator"
13020	  [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13021	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13022  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13023   && !COMMUTATIVE_ARITH_P (operands[3])
13024   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13025  "* return output_387_binary_op (insn, operands);"
13026  [(set (attr "type")
13027        (cond [(and (eq_attr "alternative" "2,3")
13028	            (match_operand:MODEF 3 "mult_operator" ""))
13029                 (const_string "ssemul")
13030	       (and (eq_attr "alternative" "2,3")
13031	            (match_operand:MODEF 3 "div_operator" ""))
13032                 (const_string "ssediv")
13033	       (eq_attr "alternative" "2,3")
13034                 (const_string "sseadd")
13035	       (match_operand:MODEF 3 "mult_operator" "")
13036                 (const_string "fmul")
13037               (match_operand:MODEF 3 "div_operator" "")
13038                 (const_string "fdiv")
13039              ]
13040              (const_string "fop")))
13041   (set_attr "isa" "*,*,noavx,avx")
13042   (set_attr "prefix" "orig,orig,orig,vex")
13043   (set_attr "mode" "<MODE>")])
13044
13045(define_insn "*rcpsf2_sse"
13046  [(set (match_operand:SF 0 "register_operand" "=x")
13047	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13048		   UNSPEC_RCP))]
13049  "TARGET_SSE_MATH"
13050  "%vrcpss\t{%1, %d0|%d0, %1}"
13051  [(set_attr "type" "sse")
13052   (set_attr "atom_sse_attr" "rcp")
13053   (set_attr "prefix" "maybe_vex")
13054   (set_attr "mode" "SF")])
13055
13056(define_insn "*fop_<mode>_1_sse"
13057  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13058	(match_operator:MODEF 3 "binary_fp_operator"
13059	  [(match_operand:MODEF 1 "register_operand" "0,x")
13060	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13061  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13062   && !COMMUTATIVE_ARITH_P (operands[3])"
13063  "* return output_387_binary_op (insn, operands);"
13064  [(set (attr "type")
13065        (cond [(match_operand:MODEF 3 "mult_operator" "")
13066                 (const_string "ssemul")
13067	       (match_operand:MODEF 3 "div_operator" "")
13068                 (const_string "ssediv")
13069              ]
13070              (const_string "sseadd")))
13071   (set_attr "isa" "noavx,avx")
13072   (set_attr "prefix" "orig,vex")
13073   (set_attr "mode" "<MODE>")])
13074
13075;; This pattern is not fully shadowed by the pattern above.
13076(define_insn "*fop_<mode>_1_i387"
13077  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13078	(match_operator:MODEF 3 "binary_fp_operator"
13079	  [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13080	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13081  "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13082   && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13083   && !COMMUTATIVE_ARITH_P (operands[3])
13084   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13085  "* return output_387_binary_op (insn, operands);"
13086  [(set (attr "type")
13087        (cond [(match_operand:MODEF 3 "mult_operator" "")
13088                 (const_string "fmul")
13089               (match_operand:MODEF 3 "div_operator" "")
13090                 (const_string "fdiv")
13091              ]
13092              (const_string "fop")))
13093   (set_attr "mode" "<MODE>")])
13094
13095;; ??? Add SSE splitters for these!
13096(define_insn "*fop_<MODEF:mode>_2_i387"
13097  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13098	(match_operator:MODEF 3 "binary_fp_operator"
13099	  [(float:MODEF
13100	     (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13101	   (match_operand:MODEF 2 "register_operand" "0,0")]))]
13102  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13103   && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13104   && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13105  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13106  [(set (attr "type")
13107        (cond [(match_operand:MODEF 3 "mult_operator" "")
13108                 (const_string "fmul")
13109               (match_operand:MODEF 3 "div_operator" "")
13110                 (const_string "fdiv")
13111              ]
13112              (const_string "fop")))
13113   (set_attr "fp_int_src" "true")
13114   (set_attr "mode" "<SWI24:MODE>")])
13115
13116(define_insn "*fop_<MODEF:mode>_3_i387"
13117  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13118	(match_operator:MODEF 3 "binary_fp_operator"
13119	  [(match_operand:MODEF 1 "register_operand" "0,0")
13120	   (float:MODEF
13121	     (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13122  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13123   && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13124   && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13125  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13126  [(set (attr "type")
13127        (cond [(match_operand:MODEF 3 "mult_operator" "")
13128                 (const_string "fmul")
13129               (match_operand:MODEF 3 "div_operator" "")
13130                 (const_string "fdiv")
13131              ]
13132              (const_string "fop")))
13133   (set_attr "fp_int_src" "true")
13134   (set_attr "mode" "<MODE>")])
13135
13136(define_insn "*fop_df_4_i387"
13137  [(set (match_operand:DF 0 "register_operand" "=f,f")
13138	(match_operator:DF 3 "binary_fp_operator"
13139	   [(float_extend:DF
13140	     (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13141	    (match_operand:DF 2 "register_operand" "0,f")]))]
13142  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13143   && !(TARGET_SSE2 && TARGET_SSE_MATH)
13144   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13145  "* return output_387_binary_op (insn, operands);"
13146  [(set (attr "type")
13147        (cond [(match_operand:DF 3 "mult_operator" "")
13148                 (const_string "fmul")
13149               (match_operand:DF 3 "div_operator" "")
13150                 (const_string "fdiv")
13151              ]
13152              (const_string "fop")))
13153   (set_attr "mode" "SF")])
13154
13155(define_insn "*fop_df_5_i387"
13156  [(set (match_operand:DF 0 "register_operand" "=f,f")
13157	(match_operator:DF 3 "binary_fp_operator"
13158	  [(match_operand:DF 1 "register_operand" "0,f")
13159	   (float_extend:DF
13160	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13161  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13162   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13163  "* return output_387_binary_op (insn, operands);"
13164  [(set (attr "type")
13165        (cond [(match_operand:DF 3 "mult_operator" "")
13166                 (const_string "fmul")
13167               (match_operand:DF 3 "div_operator" "")
13168                 (const_string "fdiv")
13169              ]
13170              (const_string "fop")))
13171   (set_attr "mode" "SF")])
13172
13173(define_insn "*fop_df_6_i387"
13174  [(set (match_operand:DF 0 "register_operand" "=f,f")
13175	(match_operator:DF 3 "binary_fp_operator"
13176	  [(float_extend:DF
13177	    (match_operand:SF 1 "register_operand" "0,f"))
13178	   (float_extend:DF
13179	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13180  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13181   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13182  "* return output_387_binary_op (insn, operands);"
13183  [(set (attr "type")
13184        (cond [(match_operand:DF 3 "mult_operator" "")
13185                 (const_string "fmul")
13186               (match_operand:DF 3 "div_operator" "")
13187                 (const_string "fdiv")
13188              ]
13189              (const_string "fop")))
13190   (set_attr "mode" "SF")])
13191
13192(define_insn "*fop_xf_comm_i387"
13193  [(set (match_operand:XF 0 "register_operand" "=f")
13194	(match_operator:XF 3 "binary_fp_operator"
13195			[(match_operand:XF 1 "register_operand" "%0")
13196			 (match_operand:XF 2 "register_operand" "f")]))]
13197  "TARGET_80387
13198   && COMMUTATIVE_ARITH_P (operands[3])"
13199  "* return output_387_binary_op (insn, operands);"
13200  [(set (attr "type")
13201        (if_then_else (match_operand:XF 3 "mult_operator" "")
13202           (const_string "fmul")
13203           (const_string "fop")))
13204   (set_attr "mode" "XF")])
13205
13206(define_insn "*fop_xf_1_i387"
13207  [(set (match_operand:XF 0 "register_operand" "=f,f")
13208	(match_operator:XF 3 "binary_fp_operator"
13209			[(match_operand:XF 1 "register_operand" "0,f")
13210			 (match_operand:XF 2 "register_operand" "f,0")]))]
13211  "TARGET_80387
13212   && !COMMUTATIVE_ARITH_P (operands[3])"
13213  "* return output_387_binary_op (insn, operands);"
13214  [(set (attr "type")
13215        (cond [(match_operand:XF 3 "mult_operator" "")
13216                 (const_string "fmul")
13217               (match_operand:XF 3 "div_operator" "")
13218                 (const_string "fdiv")
13219              ]
13220              (const_string "fop")))
13221   (set_attr "mode" "XF")])
13222
13223(define_insn "*fop_xf_2_i387"
13224  [(set (match_operand:XF 0 "register_operand" "=f,f")
13225	(match_operator:XF 3 "binary_fp_operator"
13226	  [(float:XF
13227	     (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13228	   (match_operand:XF 2 "register_operand" "0,0")]))]
13229  "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13230  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13231  [(set (attr "type")
13232        (cond [(match_operand:XF 3 "mult_operator" "")
13233                 (const_string "fmul")
13234               (match_operand:XF 3 "div_operator" "")
13235                 (const_string "fdiv")
13236              ]
13237              (const_string "fop")))
13238   (set_attr "fp_int_src" "true")
13239   (set_attr "mode" "<MODE>")])
13240
13241(define_insn "*fop_xf_3_i387"
13242  [(set (match_operand:XF 0 "register_operand" "=f,f")
13243	(match_operator:XF 3 "binary_fp_operator"
13244	  [(match_operand:XF 1 "register_operand" "0,0")
13245	   (float:XF
13246	     (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13247  "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13248  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13249  [(set (attr "type")
13250        (cond [(match_operand:XF 3 "mult_operator" "")
13251                 (const_string "fmul")
13252               (match_operand:XF 3 "div_operator" "")
13253                 (const_string "fdiv")
13254              ]
13255              (const_string "fop")))
13256   (set_attr "fp_int_src" "true")
13257   (set_attr "mode" "<MODE>")])
13258
13259(define_insn "*fop_xf_4_i387"
13260  [(set (match_operand:XF 0 "register_operand" "=f,f")
13261	(match_operator:XF 3 "binary_fp_operator"
13262	   [(float_extend:XF
13263	      (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13264	    (match_operand:XF 2 "register_operand" "0,f")]))]
13265  "TARGET_80387"
13266  "* return output_387_binary_op (insn, operands);"
13267  [(set (attr "type")
13268        (cond [(match_operand:XF 3 "mult_operator" "")
13269                 (const_string "fmul")
13270               (match_operand:XF 3 "div_operator" "")
13271                 (const_string "fdiv")
13272              ]
13273              (const_string "fop")))
13274   (set_attr "mode" "<MODE>")])
13275
13276(define_insn "*fop_xf_5_i387"
13277  [(set (match_operand:XF 0 "register_operand" "=f,f")
13278	(match_operator:XF 3 "binary_fp_operator"
13279	  [(match_operand:XF 1 "register_operand" "0,f")
13280	   (float_extend:XF
13281	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13282  "TARGET_80387"
13283  "* return output_387_binary_op (insn, operands);"
13284  [(set (attr "type")
13285        (cond [(match_operand:XF 3 "mult_operator" "")
13286                 (const_string "fmul")
13287               (match_operand:XF 3 "div_operator" "")
13288                 (const_string "fdiv")
13289              ]
13290              (const_string "fop")))
13291   (set_attr "mode" "<MODE>")])
13292
13293(define_insn "*fop_xf_6_i387"
13294  [(set (match_operand:XF 0 "register_operand" "=f,f")
13295	(match_operator:XF 3 "binary_fp_operator"
13296	  [(float_extend:XF
13297	     (match_operand:MODEF 1 "register_operand" "0,f"))
13298	   (float_extend:XF
13299	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13300  "TARGET_80387"
13301  "* return output_387_binary_op (insn, operands);"
13302  [(set (attr "type")
13303        (cond [(match_operand:XF 3 "mult_operator" "")
13304                 (const_string "fmul")
13305               (match_operand:XF 3 "div_operator" "")
13306                 (const_string "fdiv")
13307              ]
13308              (const_string "fop")))
13309   (set_attr "mode" "<MODE>")])
13310
13311(define_split
13312  [(set (match_operand 0 "register_operand" "")
13313	(match_operator 3 "binary_fp_operator"
13314	   [(float (match_operand:SWI24 1 "register_operand" ""))
13315	    (match_operand 2 "register_operand" "")]))]
13316  "reload_completed
13317   && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13318   && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13319  [(const_int 0)]
13320{
13321  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13322  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13323  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13324			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
13325					  GET_MODE (operands[3]),
13326					  operands[4],
13327					  operands[2])));
13328  ix86_free_from_memory (GET_MODE (operands[1]));
13329  DONE;
13330})
13331
13332(define_split
13333  [(set (match_operand 0 "register_operand" "")
13334	(match_operator 3 "binary_fp_operator"
13335	   [(match_operand 1 "register_operand" "")
13336	    (float (match_operand:SWI24 2 "register_operand" ""))]))]
13337  "reload_completed
13338   && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13339   && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13340  [(const_int 0)]
13341{
13342  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13343  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13344  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13345			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
13346					  GET_MODE (operands[3]),
13347					  operands[1],
13348					  operands[4])));
13349  ix86_free_from_memory (GET_MODE (operands[2]));
13350  DONE;
13351})
13352
13353;; FPU special functions.
13354
13355;; This pattern implements a no-op XFmode truncation for
13356;; all fancy i386 XFmode math functions.
13357
13358(define_insn "truncxf<mode>2_i387_noop_unspec"
13359  [(set (match_operand:MODEF 0 "register_operand" "=f")
13360	(unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13361	UNSPEC_TRUNC_NOOP))]
13362  "TARGET_USE_FANCY_MATH_387"
13363  "* return output_387_reg_move (insn, operands);"
13364  [(set_attr "type" "fmov")
13365   (set_attr "mode" "<MODE>")])
13366
13367(define_insn "sqrtxf2"
13368  [(set (match_operand:XF 0 "register_operand" "=f")
13369	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13370  "TARGET_USE_FANCY_MATH_387"
13371  "fsqrt"
13372  [(set_attr "type" "fpspc")
13373   (set_attr "mode" "XF")
13374   (set_attr "athlon_decode" "direct")
13375   (set_attr "amdfam10_decode" "direct")
13376   (set_attr "bdver1_decode" "direct")])
13377
13378(define_insn "sqrt_extend<mode>xf2_i387"
13379  [(set (match_operand:XF 0 "register_operand" "=f")
13380	(sqrt:XF
13381	  (float_extend:XF
13382	    (match_operand:MODEF 1 "register_operand" "0"))))]
13383  "TARGET_USE_FANCY_MATH_387"
13384  "fsqrt"
13385  [(set_attr "type" "fpspc")
13386   (set_attr "mode" "XF")
13387   (set_attr "athlon_decode" "direct")
13388   (set_attr "amdfam10_decode" "direct")
13389   (set_attr "bdver1_decode" "direct")])
13390
13391(define_insn "*rsqrtsf2_sse"
13392  [(set (match_operand:SF 0 "register_operand" "=x")
13393	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13394		   UNSPEC_RSQRT))]
13395  "TARGET_SSE_MATH"
13396  "%vrsqrtss\t{%1, %d0|%d0, %1}"
13397  [(set_attr "type" "sse")
13398   (set_attr "atom_sse_attr" "rcp")
13399   (set_attr "prefix" "maybe_vex")
13400   (set_attr "mode" "SF")])
13401
13402(define_expand "rsqrtsf2"
13403  [(set (match_operand:SF 0 "register_operand" "")
13404	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13405		   UNSPEC_RSQRT))]
13406  "TARGET_SSE_MATH"
13407{
13408  ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13409  DONE;
13410})
13411
13412(define_insn "*sqrt<mode>2_sse"
13413  [(set (match_operand:MODEF 0 "register_operand" "=x")
13414	(sqrt:MODEF
13415	  (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13416  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13417  "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13418  [(set_attr "type" "sse")
13419   (set_attr "atom_sse_attr" "sqrt")
13420   (set_attr "prefix" "maybe_vex")
13421   (set_attr "mode" "<MODE>")
13422   (set_attr "athlon_decode" "*")
13423   (set_attr "amdfam10_decode" "*")
13424   (set_attr "bdver1_decode" "*")])
13425
13426(define_expand "sqrt<mode>2"
13427  [(set (match_operand:MODEF 0 "register_operand" "")
13428	(sqrt:MODEF
13429	  (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13430  "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13431   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13432{
13433  if (<MODE>mode == SFmode
13434      && TARGET_SSE_MATH
13435      && TARGET_RECIP_SQRT
13436      && !optimize_function_for_size_p (cfun)
13437      && flag_finite_math_only && !flag_trapping_math
13438      && flag_unsafe_math_optimizations)
13439    {
13440      ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13441      DONE;
13442    }
13443
13444  if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13445    {
13446      rtx op0 = gen_reg_rtx (XFmode);
13447      rtx op1 = force_reg (<MODE>mode, operands[1]);
13448
13449      emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13450      emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13451      DONE;
13452   }
13453})
13454
13455(define_insn "fpremxf4_i387"
13456  [(set (match_operand:XF 0 "register_operand" "=f")
13457	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
13458		    (match_operand:XF 3 "register_operand" "1")]
13459		   UNSPEC_FPREM_F))
13460   (set (match_operand:XF 1 "register_operand" "=u")
13461	(unspec:XF [(match_dup 2) (match_dup 3)]
13462		   UNSPEC_FPREM_U))
13463   (set (reg:CCFP FPSR_REG)
13464	(unspec:CCFP [(match_dup 2) (match_dup 3)]
13465		     UNSPEC_C2_FLAG))]
13466  "TARGET_USE_FANCY_MATH_387"
13467  "fprem"
13468  [(set_attr "type" "fpspc")
13469   (set_attr "mode" "XF")])
13470
13471(define_expand "fmodxf3"
13472  [(use (match_operand:XF 0 "register_operand" ""))
13473   (use (match_operand:XF 1 "general_operand" ""))
13474   (use (match_operand:XF 2 "general_operand" ""))]
13475  "TARGET_USE_FANCY_MATH_387"
13476{
13477  rtx label = gen_label_rtx ();
13478
13479  rtx op1 = gen_reg_rtx (XFmode);
13480  rtx op2 = gen_reg_rtx (XFmode);
13481
13482  emit_move_insn (op2, operands[2]);
13483  emit_move_insn (op1, operands[1]);
13484
13485  emit_label (label);
13486  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13487  ix86_emit_fp_unordered_jump (label);
13488  LABEL_NUSES (label) = 1;
13489
13490  emit_move_insn (operands[0], op1);
13491  DONE;
13492})
13493
13494(define_expand "fmod<mode>3"
13495  [(use (match_operand:MODEF 0 "register_operand" ""))
13496   (use (match_operand:MODEF 1 "general_operand" ""))
13497   (use (match_operand:MODEF 2 "general_operand" ""))]
13498  "TARGET_USE_FANCY_MATH_387"
13499{
13500  rtx (*gen_truncxf) (rtx, rtx);
13501
13502  rtx label = gen_label_rtx ();
13503
13504  rtx op1 = gen_reg_rtx (XFmode);
13505  rtx op2 = gen_reg_rtx (XFmode);
13506
13507  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13508  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13509
13510  emit_label (label);
13511  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13512  ix86_emit_fp_unordered_jump (label);
13513  LABEL_NUSES (label) = 1;
13514
13515  /* Truncate the result properly for strict SSE math.  */
13516  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13517      && !TARGET_MIX_SSE_I387)
13518    gen_truncxf = gen_truncxf<mode>2;
13519  else
13520    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13521
13522  emit_insn (gen_truncxf (operands[0], op1));
13523  DONE;
13524})
13525
13526(define_insn "fprem1xf4_i387"
13527  [(set (match_operand:XF 0 "register_operand" "=f")
13528	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
13529		    (match_operand:XF 3 "register_operand" "1")]
13530		   UNSPEC_FPREM1_F))
13531   (set (match_operand:XF 1 "register_operand" "=u")
13532	(unspec:XF [(match_dup 2) (match_dup 3)]
13533		   UNSPEC_FPREM1_U))
13534   (set (reg:CCFP FPSR_REG)
13535	(unspec:CCFP [(match_dup 2) (match_dup 3)]
13536		     UNSPEC_C2_FLAG))]
13537  "TARGET_USE_FANCY_MATH_387"
13538  "fprem1"
13539  [(set_attr "type" "fpspc")
13540   (set_attr "mode" "XF")])
13541
13542(define_expand "remainderxf3"
13543  [(use (match_operand:XF 0 "register_operand" ""))
13544   (use (match_operand:XF 1 "general_operand" ""))
13545   (use (match_operand:XF 2 "general_operand" ""))]
13546  "TARGET_USE_FANCY_MATH_387"
13547{
13548  rtx label = gen_label_rtx ();
13549
13550  rtx op1 = gen_reg_rtx (XFmode);
13551  rtx op2 = gen_reg_rtx (XFmode);
13552
13553  emit_move_insn (op2, operands[2]);
13554  emit_move_insn (op1, operands[1]);
13555
13556  emit_label (label);
13557  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13558  ix86_emit_fp_unordered_jump (label);
13559  LABEL_NUSES (label) = 1;
13560
13561  emit_move_insn (operands[0], op1);
13562  DONE;
13563})
13564
13565(define_expand "remainder<mode>3"
13566  [(use (match_operand:MODEF 0 "register_operand" ""))
13567   (use (match_operand:MODEF 1 "general_operand" ""))
13568   (use (match_operand:MODEF 2 "general_operand" ""))]
13569  "TARGET_USE_FANCY_MATH_387"
13570{
13571  rtx (*gen_truncxf) (rtx, rtx);
13572
13573  rtx label = gen_label_rtx ();
13574
13575  rtx op1 = gen_reg_rtx (XFmode);
13576  rtx op2 = gen_reg_rtx (XFmode);
13577
13578  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13579  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13580
13581  emit_label (label);
13582
13583  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13584  ix86_emit_fp_unordered_jump (label);
13585  LABEL_NUSES (label) = 1;
13586
13587  /* Truncate the result properly for strict SSE math.  */
13588  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13589      && !TARGET_MIX_SSE_I387)
13590    gen_truncxf = gen_truncxf<mode>2;
13591  else
13592    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13593
13594  emit_insn (gen_truncxf (operands[0], op1));
13595  DONE;
13596})
13597
13598(define_insn "*sinxf2_i387"
13599  [(set (match_operand:XF 0 "register_operand" "=f")
13600	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13601  "TARGET_USE_FANCY_MATH_387
13602   && flag_unsafe_math_optimizations"
13603  "fsin"
13604  [(set_attr "type" "fpspc")
13605   (set_attr "mode" "XF")])
13606
13607(define_insn "*sin_extend<mode>xf2_i387"
13608  [(set (match_operand:XF 0 "register_operand" "=f")
13609	(unspec:XF [(float_extend:XF
13610		      (match_operand:MODEF 1 "register_operand" "0"))]
13611		   UNSPEC_SIN))]
13612  "TARGET_USE_FANCY_MATH_387
13613   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13614       || TARGET_MIX_SSE_I387)
13615   && flag_unsafe_math_optimizations"
13616  "fsin"
13617  [(set_attr "type" "fpspc")
13618   (set_attr "mode" "XF")])
13619
13620(define_insn "*cosxf2_i387"
13621  [(set (match_operand:XF 0 "register_operand" "=f")
13622	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13623  "TARGET_USE_FANCY_MATH_387
13624   && flag_unsafe_math_optimizations"
13625  "fcos"
13626  [(set_attr "type" "fpspc")
13627   (set_attr "mode" "XF")])
13628
13629(define_insn "*cos_extend<mode>xf2_i387"
13630  [(set (match_operand:XF 0 "register_operand" "=f")
13631	(unspec:XF [(float_extend:XF
13632		      (match_operand:MODEF 1 "register_operand" "0"))]
13633		   UNSPEC_COS))]
13634  "TARGET_USE_FANCY_MATH_387
13635   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13636       || TARGET_MIX_SSE_I387)
13637   && flag_unsafe_math_optimizations"
13638  "fcos"
13639  [(set_attr "type" "fpspc")
13640   (set_attr "mode" "XF")])
13641
13642;; When sincos pattern is defined, sin and cos builtin functions will be
13643;; expanded to sincos pattern with one of its outputs left unused.
13644;; CSE pass will figure out if two sincos patterns can be combined,
13645;; otherwise sincos pattern will be split back to sin or cos pattern,
13646;; depending on the unused output.
13647
13648(define_insn "sincosxf3"
13649  [(set (match_operand:XF 0 "register_operand" "=f")
13650	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13651		   UNSPEC_SINCOS_COS))
13652   (set (match_operand:XF 1 "register_operand" "=u")
13653        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13654  "TARGET_USE_FANCY_MATH_387
13655   && flag_unsafe_math_optimizations"
13656  "fsincos"
13657  [(set_attr "type" "fpspc")
13658   (set_attr "mode" "XF")])
13659
13660(define_split
13661  [(set (match_operand:XF 0 "register_operand" "")
13662	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
13663		   UNSPEC_SINCOS_COS))
13664   (set (match_operand:XF 1 "register_operand" "")
13665	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13666  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13667   && can_create_pseudo_p ()"
13668  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13669
13670(define_split
13671  [(set (match_operand:XF 0 "register_operand" "")
13672	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
13673		   UNSPEC_SINCOS_COS))
13674   (set (match_operand:XF 1 "register_operand" "")
13675	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13676  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13677   && can_create_pseudo_p ()"
13678  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13679
13680(define_insn "sincos_extend<mode>xf3_i387"
13681  [(set (match_operand:XF 0 "register_operand" "=f")
13682	(unspec:XF [(float_extend:XF
13683		      (match_operand:MODEF 2 "register_operand" "0"))]
13684		   UNSPEC_SINCOS_COS))
13685   (set (match_operand:XF 1 "register_operand" "=u")
13686        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13687  "TARGET_USE_FANCY_MATH_387
13688   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13689       || TARGET_MIX_SSE_I387)
13690   && flag_unsafe_math_optimizations"
13691  "fsincos"
13692  [(set_attr "type" "fpspc")
13693   (set_attr "mode" "XF")])
13694
13695(define_split
13696  [(set (match_operand:XF 0 "register_operand" "")
13697	(unspec:XF [(float_extend:XF
13698		      (match_operand:MODEF 2 "register_operand" ""))]
13699		   UNSPEC_SINCOS_COS))
13700   (set (match_operand:XF 1 "register_operand" "")
13701	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13702  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13703   && can_create_pseudo_p ()"
13704  [(set (match_dup 1)
13705	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13706
13707(define_split
13708  [(set (match_operand:XF 0 "register_operand" "")
13709	(unspec:XF [(float_extend:XF
13710		      (match_operand:MODEF 2 "register_operand" ""))]
13711		   UNSPEC_SINCOS_COS))
13712   (set (match_operand:XF 1 "register_operand" "")
13713	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13714  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13715   && can_create_pseudo_p ()"
13716  [(set (match_dup 0)
13717	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13718
13719(define_expand "sincos<mode>3"
13720  [(use (match_operand:MODEF 0 "register_operand" ""))
13721   (use (match_operand:MODEF 1 "register_operand" ""))
13722   (use (match_operand:MODEF 2 "register_operand" ""))]
13723  "TARGET_USE_FANCY_MATH_387
13724   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13725       || TARGET_MIX_SSE_I387)
13726   && flag_unsafe_math_optimizations"
13727{
13728  rtx op0 = gen_reg_rtx (XFmode);
13729  rtx op1 = gen_reg_rtx (XFmode);
13730
13731  emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13732  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13733  emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13734  DONE;
13735})
13736
13737(define_insn "fptanxf4_i387"
13738  [(set (match_operand:XF 0 "register_operand" "=f")
13739	(match_operand:XF 3 "const_double_operand" "F"))
13740   (set (match_operand:XF 1 "register_operand" "=u")
13741        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13742		   UNSPEC_TAN))]
13743  "TARGET_USE_FANCY_MATH_387
13744   && flag_unsafe_math_optimizations
13745   && standard_80387_constant_p (operands[3]) == 2"
13746  "fptan"
13747  [(set_attr "type" "fpspc")
13748   (set_attr "mode" "XF")])
13749
13750(define_insn "fptan_extend<mode>xf4_i387"
13751  [(set (match_operand:MODEF 0 "register_operand" "=f")
13752	(match_operand:MODEF 3 "const_double_operand" "F"))
13753   (set (match_operand:XF 1 "register_operand" "=u")
13754        (unspec:XF [(float_extend:XF
13755		      (match_operand:MODEF 2 "register_operand" "0"))]
13756		   UNSPEC_TAN))]
13757  "TARGET_USE_FANCY_MATH_387
13758   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13759       || TARGET_MIX_SSE_I387)
13760   && flag_unsafe_math_optimizations
13761   && standard_80387_constant_p (operands[3]) == 2"
13762  "fptan"
13763  [(set_attr "type" "fpspc")
13764   (set_attr "mode" "XF")])
13765
13766(define_expand "tanxf2"
13767  [(use (match_operand:XF 0 "register_operand" ""))
13768   (use (match_operand:XF 1 "register_operand" ""))]
13769  "TARGET_USE_FANCY_MATH_387
13770   && flag_unsafe_math_optimizations"
13771{
13772  rtx one = gen_reg_rtx (XFmode);
13773  rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13774
13775  emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13776  DONE;
13777})
13778
13779(define_expand "tan<mode>2"
13780  [(use (match_operand:MODEF 0 "register_operand" ""))
13781   (use (match_operand:MODEF 1 "register_operand" ""))]
13782  "TARGET_USE_FANCY_MATH_387
13783   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13784       || TARGET_MIX_SSE_I387)
13785   && flag_unsafe_math_optimizations"
13786{
13787  rtx op0 = gen_reg_rtx (XFmode);
13788
13789  rtx one = gen_reg_rtx (<MODE>mode);
13790  rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13791
13792  emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13793					     operands[1], op2));
13794  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13795  DONE;
13796})
13797
13798(define_insn "*fpatanxf3_i387"
13799  [(set (match_operand:XF 0 "register_operand" "=f")
13800        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13801	            (match_operand:XF 2 "register_operand" "u")]
13802	           UNSPEC_FPATAN))
13803   (clobber (match_scratch:XF 3 "=2"))]
13804  "TARGET_USE_FANCY_MATH_387
13805   && flag_unsafe_math_optimizations"
13806  "fpatan"
13807  [(set_attr "type" "fpspc")
13808   (set_attr "mode" "XF")])
13809
13810(define_insn "fpatan_extend<mode>xf3_i387"
13811  [(set (match_operand:XF 0 "register_operand" "=f")
13812        (unspec:XF [(float_extend:XF
13813		      (match_operand:MODEF 1 "register_operand" "0"))
13814		    (float_extend:XF
13815		      (match_operand:MODEF 2 "register_operand" "u"))]
13816	           UNSPEC_FPATAN))
13817   (clobber (match_scratch:XF 3 "=2"))]
13818  "TARGET_USE_FANCY_MATH_387
13819   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13820       || TARGET_MIX_SSE_I387)
13821   && flag_unsafe_math_optimizations"
13822  "fpatan"
13823  [(set_attr "type" "fpspc")
13824   (set_attr "mode" "XF")])
13825
13826(define_expand "atan2xf3"
13827  [(parallel [(set (match_operand:XF 0 "register_operand" "")
13828		   (unspec:XF [(match_operand:XF 2 "register_operand" "")
13829			       (match_operand:XF 1 "register_operand" "")]
13830			      UNSPEC_FPATAN))
13831	      (clobber (match_scratch:XF 3 ""))])]
13832  "TARGET_USE_FANCY_MATH_387
13833   && flag_unsafe_math_optimizations")
13834
13835(define_expand "atan2<mode>3"
13836  [(use (match_operand:MODEF 0 "register_operand" ""))
13837   (use (match_operand:MODEF 1 "register_operand" ""))
13838   (use (match_operand:MODEF 2 "register_operand" ""))]
13839  "TARGET_USE_FANCY_MATH_387
13840   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13841       || TARGET_MIX_SSE_I387)
13842   && flag_unsafe_math_optimizations"
13843{
13844  rtx op0 = gen_reg_rtx (XFmode);
13845
13846  emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13847  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13848  DONE;
13849})
13850
13851(define_expand "atanxf2"
13852  [(parallel [(set (match_operand:XF 0 "register_operand" "")
13853		   (unspec:XF [(match_dup 2)
13854			       (match_operand:XF 1 "register_operand" "")]
13855			      UNSPEC_FPATAN))
13856	      (clobber (match_scratch:XF 3 ""))])]
13857  "TARGET_USE_FANCY_MATH_387
13858   && flag_unsafe_math_optimizations"
13859{
13860  operands[2] = gen_reg_rtx (XFmode);
13861  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13862})
13863
13864(define_expand "atan<mode>2"
13865  [(use (match_operand:MODEF 0 "register_operand" ""))
13866   (use (match_operand:MODEF 1 "register_operand" ""))]
13867  "TARGET_USE_FANCY_MATH_387
13868   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13869       || TARGET_MIX_SSE_I387)
13870   && flag_unsafe_math_optimizations"
13871{
13872  rtx op0 = gen_reg_rtx (XFmode);
13873
13874  rtx op2 = gen_reg_rtx (<MODE>mode);
13875  emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13876
13877  emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13878  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13879  DONE;
13880})
13881
13882(define_expand "asinxf2"
13883  [(set (match_dup 2)
13884	(mult:XF (match_operand:XF 1 "register_operand" "")
13885		 (match_dup 1)))
13886   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13887   (set (match_dup 5) (sqrt:XF (match_dup 4)))
13888   (parallel [(set (match_operand:XF 0 "register_operand" "")
13889        	   (unspec:XF [(match_dup 5) (match_dup 1)]
13890			      UNSPEC_FPATAN))
13891   	      (clobber (match_scratch:XF 6 ""))])]
13892  "TARGET_USE_FANCY_MATH_387
13893   && flag_unsafe_math_optimizations"
13894{
13895  int i;
13896
13897  if (optimize_insn_for_size_p ())
13898    FAIL;
13899
13900  for (i = 2; i < 6; i++)
13901    operands[i] = gen_reg_rtx (XFmode);
13902
13903  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13904})
13905
13906(define_expand "asin<mode>2"
13907  [(use (match_operand:MODEF 0 "register_operand" ""))
13908   (use (match_operand:MODEF 1 "general_operand" ""))]
13909 "TARGET_USE_FANCY_MATH_387
13910   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13911       || TARGET_MIX_SSE_I387)
13912   && flag_unsafe_math_optimizations"
13913{
13914  rtx op0 = gen_reg_rtx (XFmode);
13915  rtx op1 = gen_reg_rtx (XFmode);
13916
13917  if (optimize_insn_for_size_p ())
13918    FAIL;
13919
13920  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13921  emit_insn (gen_asinxf2 (op0, op1));
13922  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13923  DONE;
13924})
13925
13926(define_expand "acosxf2"
13927  [(set (match_dup 2)
13928	(mult:XF (match_operand:XF 1 "register_operand" "")
13929		 (match_dup 1)))
13930   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13931   (set (match_dup 5) (sqrt:XF (match_dup 4)))
13932   (parallel [(set (match_operand:XF 0 "register_operand" "")
13933        	   (unspec:XF [(match_dup 1) (match_dup 5)]
13934			      UNSPEC_FPATAN))
13935   	      (clobber (match_scratch:XF 6 ""))])]
13936  "TARGET_USE_FANCY_MATH_387
13937   && flag_unsafe_math_optimizations"
13938{
13939  int i;
13940
13941  if (optimize_insn_for_size_p ())
13942    FAIL;
13943
13944  for (i = 2; i < 6; i++)
13945    operands[i] = gen_reg_rtx (XFmode);
13946
13947  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13948})
13949
13950(define_expand "acos<mode>2"
13951  [(use (match_operand:MODEF 0 "register_operand" ""))
13952   (use (match_operand:MODEF 1 "general_operand" ""))]
13953 "TARGET_USE_FANCY_MATH_387
13954   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13955       || TARGET_MIX_SSE_I387)
13956   && flag_unsafe_math_optimizations"
13957{
13958  rtx op0 = gen_reg_rtx (XFmode);
13959  rtx op1 = gen_reg_rtx (XFmode);
13960
13961  if (optimize_insn_for_size_p ())
13962    FAIL;
13963
13964  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13965  emit_insn (gen_acosxf2 (op0, op1));
13966  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13967  DONE;
13968})
13969
13970(define_insn "fyl2xxf3_i387"
13971  [(set (match_operand:XF 0 "register_operand" "=f")
13972        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13973		    (match_operand:XF 2 "register_operand" "u")]
13974	           UNSPEC_FYL2X))
13975   (clobber (match_scratch:XF 3 "=2"))]
13976  "TARGET_USE_FANCY_MATH_387
13977   && flag_unsafe_math_optimizations"
13978  "fyl2x"
13979  [(set_attr "type" "fpspc")
13980   (set_attr "mode" "XF")])
13981
13982(define_insn "fyl2x_extend<mode>xf3_i387"
13983  [(set (match_operand:XF 0 "register_operand" "=f")
13984        (unspec:XF [(float_extend:XF
13985		      (match_operand:MODEF 1 "register_operand" "0"))
13986		    (match_operand:XF 2 "register_operand" "u")]
13987	           UNSPEC_FYL2X))
13988   (clobber (match_scratch:XF 3 "=2"))]
13989  "TARGET_USE_FANCY_MATH_387
13990   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13991       || TARGET_MIX_SSE_I387)
13992   && flag_unsafe_math_optimizations"
13993  "fyl2x"
13994  [(set_attr "type" "fpspc")
13995   (set_attr "mode" "XF")])
13996
13997(define_expand "logxf2"
13998  [(parallel [(set (match_operand:XF 0 "register_operand" "")
13999		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14000			       (match_dup 2)] UNSPEC_FYL2X))
14001	      (clobber (match_scratch:XF 3 ""))])]
14002  "TARGET_USE_FANCY_MATH_387
14003   && flag_unsafe_math_optimizations"
14004{
14005  operands[2] = gen_reg_rtx (XFmode);
14006  emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14007})
14008
14009(define_expand "log<mode>2"
14010  [(use (match_operand:MODEF 0 "register_operand" ""))
14011   (use (match_operand:MODEF 1 "register_operand" ""))]
14012  "TARGET_USE_FANCY_MATH_387
14013   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14014       || TARGET_MIX_SSE_I387)
14015   && flag_unsafe_math_optimizations"
14016{
14017  rtx op0 = gen_reg_rtx (XFmode);
14018
14019  rtx op2 = gen_reg_rtx (XFmode);
14020  emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14021
14022  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14023  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14024  DONE;
14025})
14026
14027(define_expand "log10xf2"
14028  [(parallel [(set (match_operand:XF 0 "register_operand" "")
14029		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14030			       (match_dup 2)] UNSPEC_FYL2X))
14031	      (clobber (match_scratch:XF 3 ""))])]
14032  "TARGET_USE_FANCY_MATH_387
14033   && flag_unsafe_math_optimizations"
14034{
14035  operands[2] = gen_reg_rtx (XFmode);
14036  emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14037})
14038
14039(define_expand "log10<mode>2"
14040  [(use (match_operand:MODEF 0 "register_operand" ""))
14041   (use (match_operand:MODEF 1 "register_operand" ""))]
14042  "TARGET_USE_FANCY_MATH_387
14043   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14044       || TARGET_MIX_SSE_I387)
14045   && flag_unsafe_math_optimizations"
14046{
14047  rtx op0 = gen_reg_rtx (XFmode);
14048
14049  rtx op2 = gen_reg_rtx (XFmode);
14050  emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14051
14052  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14053  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14054  DONE;
14055})
14056
14057(define_expand "log2xf2"
14058  [(parallel [(set (match_operand:XF 0 "register_operand" "")
14059		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14060			       (match_dup 2)] UNSPEC_FYL2X))
14061	      (clobber (match_scratch:XF 3 ""))])]
14062  "TARGET_USE_FANCY_MATH_387
14063   && flag_unsafe_math_optimizations"
14064{
14065  operands[2] = gen_reg_rtx (XFmode);
14066  emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14067})
14068
14069(define_expand "log2<mode>2"
14070  [(use (match_operand:MODEF 0 "register_operand" ""))
14071   (use (match_operand:MODEF 1 "register_operand" ""))]
14072  "TARGET_USE_FANCY_MATH_387
14073   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14074       || TARGET_MIX_SSE_I387)
14075   && flag_unsafe_math_optimizations"
14076{
14077  rtx op0 = gen_reg_rtx (XFmode);
14078
14079  rtx op2 = gen_reg_rtx (XFmode);
14080  emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14081
14082  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14083  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14084  DONE;
14085})
14086
14087(define_insn "fyl2xp1xf3_i387"
14088  [(set (match_operand:XF 0 "register_operand" "=f")
14089        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14090		    (match_operand:XF 2 "register_operand" "u")]
14091	           UNSPEC_FYL2XP1))
14092   (clobber (match_scratch:XF 3 "=2"))]
14093  "TARGET_USE_FANCY_MATH_387
14094   && flag_unsafe_math_optimizations"
14095  "fyl2xp1"
14096  [(set_attr "type" "fpspc")
14097   (set_attr "mode" "XF")])
14098
14099(define_insn "fyl2xp1_extend<mode>xf3_i387"
14100  [(set (match_operand:XF 0 "register_operand" "=f")
14101        (unspec:XF [(float_extend:XF
14102		      (match_operand:MODEF 1 "register_operand" "0"))
14103		    (match_operand:XF 2 "register_operand" "u")]
14104	           UNSPEC_FYL2XP1))
14105   (clobber (match_scratch:XF 3 "=2"))]
14106  "TARGET_USE_FANCY_MATH_387
14107   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14108       || TARGET_MIX_SSE_I387)
14109   && flag_unsafe_math_optimizations"
14110  "fyl2xp1"
14111  [(set_attr "type" "fpspc")
14112   (set_attr "mode" "XF")])
14113
14114(define_expand "log1pxf2"
14115  [(use (match_operand:XF 0 "register_operand" ""))
14116   (use (match_operand:XF 1 "register_operand" ""))]
14117  "TARGET_USE_FANCY_MATH_387
14118   && flag_unsafe_math_optimizations"
14119{
14120  if (optimize_insn_for_size_p ())
14121    FAIL;
14122
14123  ix86_emit_i387_log1p (operands[0], operands[1]);
14124  DONE;
14125})
14126
14127(define_expand "log1p<mode>2"
14128  [(use (match_operand:MODEF 0 "register_operand" ""))
14129   (use (match_operand:MODEF 1 "register_operand" ""))]
14130  "TARGET_USE_FANCY_MATH_387
14131   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14132       || TARGET_MIX_SSE_I387)
14133   && flag_unsafe_math_optimizations"
14134{
14135  rtx op0;
14136
14137  if (optimize_insn_for_size_p ())
14138    FAIL;
14139
14140  op0 = gen_reg_rtx (XFmode);
14141
14142  operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14143
14144  ix86_emit_i387_log1p (op0, operands[1]);
14145  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14146  DONE;
14147})
14148
14149(define_insn "fxtractxf3_i387"
14150  [(set (match_operand:XF 0 "register_operand" "=f")
14151	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14152		   UNSPEC_XTRACT_FRACT))
14153   (set (match_operand:XF 1 "register_operand" "=u")
14154        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14155  "TARGET_USE_FANCY_MATH_387
14156   && flag_unsafe_math_optimizations"
14157  "fxtract"
14158  [(set_attr "type" "fpspc")
14159   (set_attr "mode" "XF")])
14160
14161(define_insn "fxtract_extend<mode>xf3_i387"
14162  [(set (match_operand:XF 0 "register_operand" "=f")
14163	(unspec:XF [(float_extend:XF
14164		      (match_operand:MODEF 2 "register_operand" "0"))]
14165		   UNSPEC_XTRACT_FRACT))
14166   (set (match_operand:XF 1 "register_operand" "=u")
14167        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14168  "TARGET_USE_FANCY_MATH_387
14169   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14170       || TARGET_MIX_SSE_I387)
14171   && flag_unsafe_math_optimizations"
14172  "fxtract"
14173  [(set_attr "type" "fpspc")
14174   (set_attr "mode" "XF")])
14175
14176(define_expand "logbxf2"
14177  [(parallel [(set (match_dup 2)
14178		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14179			      UNSPEC_XTRACT_FRACT))
14180	      (set (match_operand:XF 0 "register_operand" "")
14181		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14182  "TARGET_USE_FANCY_MATH_387
14183   && flag_unsafe_math_optimizations"
14184  "operands[2] = gen_reg_rtx (XFmode);")
14185
14186(define_expand "logb<mode>2"
14187  [(use (match_operand:MODEF 0 "register_operand" ""))
14188   (use (match_operand:MODEF 1 "register_operand" ""))]
14189  "TARGET_USE_FANCY_MATH_387
14190   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14191       || TARGET_MIX_SSE_I387)
14192   && flag_unsafe_math_optimizations"
14193{
14194  rtx op0 = gen_reg_rtx (XFmode);
14195  rtx op1 = gen_reg_rtx (XFmode);
14196
14197  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14198  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14199  DONE;
14200})
14201
14202(define_expand "ilogbxf2"
14203  [(use (match_operand:SI 0 "register_operand" ""))
14204   (use (match_operand:XF 1 "register_operand" ""))]
14205  "TARGET_USE_FANCY_MATH_387
14206   && flag_unsafe_math_optimizations"
14207{
14208  rtx op0, op1;
14209
14210  if (optimize_insn_for_size_p ())
14211    FAIL;
14212
14213  op0 = gen_reg_rtx (XFmode);
14214  op1 = gen_reg_rtx (XFmode);
14215
14216  emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14217  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14218  DONE;
14219})
14220
14221(define_expand "ilogb<mode>2"
14222  [(use (match_operand:SI 0 "register_operand" ""))
14223   (use (match_operand:MODEF 1 "register_operand" ""))]
14224  "TARGET_USE_FANCY_MATH_387
14225   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14226       || TARGET_MIX_SSE_I387)
14227   && flag_unsafe_math_optimizations"
14228{
14229  rtx op0, op1;
14230
14231  if (optimize_insn_for_size_p ())
14232    FAIL;
14233
14234  op0 = gen_reg_rtx (XFmode);
14235  op1 = gen_reg_rtx (XFmode);
14236
14237  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14238  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14239  DONE;
14240})
14241
14242(define_insn "*f2xm1xf2_i387"
14243  [(set (match_operand:XF 0 "register_operand" "=f")
14244	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14245		   UNSPEC_F2XM1))]
14246  "TARGET_USE_FANCY_MATH_387
14247   && flag_unsafe_math_optimizations"
14248  "f2xm1"
14249  [(set_attr "type" "fpspc")
14250   (set_attr "mode" "XF")])
14251
14252(define_insn "*fscalexf4_i387"
14253  [(set (match_operand:XF 0 "register_operand" "=f")
14254	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
14255		    (match_operand:XF 3 "register_operand" "1")]
14256		   UNSPEC_FSCALE_FRACT))
14257   (set (match_operand:XF 1 "register_operand" "=u")
14258	(unspec:XF [(match_dup 2) (match_dup 3)]
14259		   UNSPEC_FSCALE_EXP))]
14260  "TARGET_USE_FANCY_MATH_387
14261   && flag_unsafe_math_optimizations"
14262  "fscale"
14263  [(set_attr "type" "fpspc")
14264   (set_attr "mode" "XF")])
14265
14266(define_expand "expNcorexf3"
14267  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14268			       (match_operand:XF 2 "register_operand" "")))
14269   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14270   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14271   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14272   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14273   (parallel [(set (match_operand:XF 0 "register_operand" "")
14274		   (unspec:XF [(match_dup 8) (match_dup 4)]
14275			      UNSPEC_FSCALE_FRACT))
14276	      (set (match_dup 9)
14277		   (unspec:XF [(match_dup 8) (match_dup 4)]
14278			      UNSPEC_FSCALE_EXP))])]
14279  "TARGET_USE_FANCY_MATH_387
14280   && flag_unsafe_math_optimizations"
14281{
14282  int i;
14283
14284  if (optimize_insn_for_size_p ())
14285    FAIL;
14286
14287  for (i = 3; i < 10; i++)
14288    operands[i] = gen_reg_rtx (XFmode);
14289
14290  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14291})
14292
14293(define_expand "expxf2"
14294  [(use (match_operand:XF 0 "register_operand" ""))
14295   (use (match_operand:XF 1 "register_operand" ""))]
14296  "TARGET_USE_FANCY_MATH_387
14297   && flag_unsafe_math_optimizations"
14298{
14299  rtx op2;
14300
14301  if (optimize_insn_for_size_p ())
14302    FAIL;
14303
14304  op2 = gen_reg_rtx (XFmode);
14305  emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14306
14307  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14308  DONE;
14309})
14310
14311(define_expand "exp<mode>2"
14312  [(use (match_operand:MODEF 0 "register_operand" ""))
14313   (use (match_operand:MODEF 1 "general_operand" ""))]
14314 "TARGET_USE_FANCY_MATH_387
14315   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14316       || TARGET_MIX_SSE_I387)
14317   && flag_unsafe_math_optimizations"
14318{
14319  rtx op0, op1;
14320
14321  if (optimize_insn_for_size_p ())
14322    FAIL;
14323
14324  op0 = gen_reg_rtx (XFmode);
14325  op1 = gen_reg_rtx (XFmode);
14326
14327  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14328  emit_insn (gen_expxf2 (op0, op1));
14329  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14330  DONE;
14331})
14332
14333(define_expand "exp10xf2"
14334  [(use (match_operand:XF 0 "register_operand" ""))
14335   (use (match_operand:XF 1 "register_operand" ""))]
14336  "TARGET_USE_FANCY_MATH_387
14337   && flag_unsafe_math_optimizations"
14338{
14339  rtx op2;
14340
14341  if (optimize_insn_for_size_p ())
14342    FAIL;
14343
14344  op2 = gen_reg_rtx (XFmode);
14345  emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14346
14347  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14348  DONE;
14349})
14350
14351(define_expand "exp10<mode>2"
14352  [(use (match_operand:MODEF 0 "register_operand" ""))
14353   (use (match_operand:MODEF 1 "general_operand" ""))]
14354 "TARGET_USE_FANCY_MATH_387
14355   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14356       || TARGET_MIX_SSE_I387)
14357   && flag_unsafe_math_optimizations"
14358{
14359  rtx op0, op1;
14360
14361  if (optimize_insn_for_size_p ())
14362    FAIL;
14363
14364  op0 = gen_reg_rtx (XFmode);
14365  op1 = gen_reg_rtx (XFmode);
14366
14367  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14368  emit_insn (gen_exp10xf2 (op0, op1));
14369  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14370  DONE;
14371})
14372
14373(define_expand "exp2xf2"
14374  [(use (match_operand:XF 0 "register_operand" ""))
14375   (use (match_operand:XF 1 "register_operand" ""))]
14376  "TARGET_USE_FANCY_MATH_387
14377   && flag_unsafe_math_optimizations"
14378{
14379  rtx op2;
14380
14381  if (optimize_insn_for_size_p ())
14382    FAIL;
14383
14384  op2 = gen_reg_rtx (XFmode);
14385  emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14386
14387  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14388  DONE;
14389})
14390
14391(define_expand "exp2<mode>2"
14392  [(use (match_operand:MODEF 0 "register_operand" ""))
14393   (use (match_operand:MODEF 1 "general_operand" ""))]
14394 "TARGET_USE_FANCY_MATH_387
14395   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14396       || TARGET_MIX_SSE_I387)
14397   && flag_unsafe_math_optimizations"
14398{
14399  rtx op0, op1;
14400
14401  if (optimize_insn_for_size_p ())
14402    FAIL;
14403
14404  op0 = gen_reg_rtx (XFmode);
14405  op1 = gen_reg_rtx (XFmode);
14406
14407  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14408  emit_insn (gen_exp2xf2 (op0, op1));
14409  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14410  DONE;
14411})
14412
14413(define_expand "expm1xf2"
14414  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14415			       (match_dup 2)))
14416   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14417   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14418   (set (match_dup 9) (float_extend:XF (match_dup 13)))
14419   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14420   (parallel [(set (match_dup 7)
14421		   (unspec:XF [(match_dup 6) (match_dup 4)]
14422			      UNSPEC_FSCALE_FRACT))
14423	      (set (match_dup 8)
14424		   (unspec:XF [(match_dup 6) (match_dup 4)]
14425			      UNSPEC_FSCALE_EXP))])
14426   (parallel [(set (match_dup 10)
14427		   (unspec:XF [(match_dup 9) (match_dup 8)]
14428			      UNSPEC_FSCALE_FRACT))
14429	      (set (match_dup 11)
14430		   (unspec:XF [(match_dup 9) (match_dup 8)]
14431			      UNSPEC_FSCALE_EXP))])
14432   (set (match_dup 12) (minus:XF (match_dup 10)
14433				 (float_extend:XF (match_dup 13))))
14434   (set (match_operand:XF 0 "register_operand" "")
14435	(plus:XF (match_dup 12) (match_dup 7)))]
14436  "TARGET_USE_FANCY_MATH_387
14437   && flag_unsafe_math_optimizations"
14438{
14439  int i;
14440
14441  if (optimize_insn_for_size_p ())
14442    FAIL;
14443
14444  for (i = 2; i < 13; i++)
14445    operands[i] = gen_reg_rtx (XFmode);
14446
14447  operands[13]
14448    = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14449
14450  emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14451})
14452
14453(define_expand "expm1<mode>2"
14454  [(use (match_operand:MODEF 0 "register_operand" ""))
14455   (use (match_operand:MODEF 1 "general_operand" ""))]
14456 "TARGET_USE_FANCY_MATH_387
14457   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14458       || TARGET_MIX_SSE_I387)
14459   && flag_unsafe_math_optimizations"
14460{
14461  rtx op0, op1;
14462
14463  if (optimize_insn_for_size_p ())
14464    FAIL;
14465
14466  op0 = gen_reg_rtx (XFmode);
14467  op1 = gen_reg_rtx (XFmode);
14468
14469  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14470  emit_insn (gen_expm1xf2 (op0, op1));
14471  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14472  DONE;
14473})
14474
14475(define_expand "ldexpxf3"
14476  [(set (match_dup 3)
14477	(float:XF (match_operand:SI 2 "register_operand" "")))
14478   (parallel [(set (match_operand:XF 0 " register_operand" "")
14479		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14480			       (match_dup 3)]
14481			      UNSPEC_FSCALE_FRACT))
14482	      (set (match_dup 4)
14483		   (unspec:XF [(match_dup 1) (match_dup 3)]
14484			      UNSPEC_FSCALE_EXP))])]
14485  "TARGET_USE_FANCY_MATH_387
14486   && flag_unsafe_math_optimizations"
14487{
14488  if (optimize_insn_for_size_p ())
14489    FAIL;
14490
14491  operands[3] = gen_reg_rtx (XFmode);
14492  operands[4] = gen_reg_rtx (XFmode);
14493})
14494
14495(define_expand "ldexp<mode>3"
14496  [(use (match_operand:MODEF 0 "register_operand" ""))
14497   (use (match_operand:MODEF 1 "general_operand" ""))
14498   (use (match_operand:SI 2 "register_operand" ""))]
14499 "TARGET_USE_FANCY_MATH_387
14500   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14501       || TARGET_MIX_SSE_I387)
14502   && flag_unsafe_math_optimizations"
14503{
14504  rtx op0, op1;
14505
14506  if (optimize_insn_for_size_p ())
14507    FAIL;
14508
14509  op0 = gen_reg_rtx (XFmode);
14510  op1 = gen_reg_rtx (XFmode);
14511
14512  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14513  emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14514  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14515  DONE;
14516})
14517
14518(define_expand "scalbxf3"
14519  [(parallel [(set (match_operand:XF 0 " register_operand" "")
14520		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14521			       (match_operand:XF 2 "register_operand" "")]
14522			      UNSPEC_FSCALE_FRACT))
14523	      (set (match_dup 3)
14524		   (unspec:XF [(match_dup 1) (match_dup 2)]
14525			      UNSPEC_FSCALE_EXP))])]
14526  "TARGET_USE_FANCY_MATH_387
14527   && flag_unsafe_math_optimizations"
14528{
14529  if (optimize_insn_for_size_p ())
14530    FAIL;
14531
14532  operands[3] = gen_reg_rtx (XFmode);
14533})
14534
14535(define_expand "scalb<mode>3"
14536  [(use (match_operand:MODEF 0 "register_operand" ""))
14537   (use (match_operand:MODEF 1 "general_operand" ""))
14538   (use (match_operand:MODEF 2 "general_operand" ""))]
14539 "TARGET_USE_FANCY_MATH_387
14540   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14541       || TARGET_MIX_SSE_I387)
14542   && flag_unsafe_math_optimizations"
14543{
14544  rtx op0, op1, op2;
14545
14546  if (optimize_insn_for_size_p ())
14547    FAIL;
14548
14549  op0 = gen_reg_rtx (XFmode);
14550  op1 = gen_reg_rtx (XFmode);
14551  op2 = gen_reg_rtx (XFmode);
14552
14553  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14554  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14555  emit_insn (gen_scalbxf3 (op0, op1, op2));
14556  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14557  DONE;
14558})
14559
14560(define_expand "significandxf2"
14561  [(parallel [(set (match_operand:XF 0 "register_operand" "")
14562		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14563			      UNSPEC_XTRACT_FRACT))
14564	      (set (match_dup 2)
14565		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14566  "TARGET_USE_FANCY_MATH_387
14567   && flag_unsafe_math_optimizations"
14568  "operands[2] = gen_reg_rtx (XFmode);")
14569
14570(define_expand "significand<mode>2"
14571  [(use (match_operand:MODEF 0 "register_operand" ""))
14572   (use (match_operand:MODEF 1 "register_operand" ""))]
14573  "TARGET_USE_FANCY_MATH_387
14574   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14575       || TARGET_MIX_SSE_I387)
14576   && flag_unsafe_math_optimizations"
14577{
14578  rtx op0 = gen_reg_rtx (XFmode);
14579  rtx op1 = gen_reg_rtx (XFmode);
14580
14581  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14582  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14583  DONE;
14584})
14585
14586
14587(define_insn "sse4_1_round<mode>2"
14588  [(set (match_operand:MODEF 0 "register_operand" "=x")
14589	(unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14590		       (match_operand:SI 2 "const_0_to_15_operand" "n")]
14591		      UNSPEC_ROUND))]
14592  "TARGET_ROUND"
14593  "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14594  [(set_attr "type" "ssecvt")
14595   (set_attr "prefix_extra" "1")
14596   (set_attr "prefix" "maybe_vex")
14597   (set_attr "mode" "<MODE>")])
14598
14599(define_insn "rintxf2"
14600  [(set (match_operand:XF 0 "register_operand" "=f")
14601	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14602		   UNSPEC_FRNDINT))]
14603  "TARGET_USE_FANCY_MATH_387
14604   && flag_unsafe_math_optimizations"
14605  "frndint"
14606  [(set_attr "type" "fpspc")
14607   (set_attr "mode" "XF")])
14608
14609(define_expand "rint<mode>2"
14610  [(use (match_operand:MODEF 0 "register_operand" ""))
14611   (use (match_operand:MODEF 1 "register_operand" ""))]
14612  "(TARGET_USE_FANCY_MATH_387
14613    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14614	|| TARGET_MIX_SSE_I387)
14615    && flag_unsafe_math_optimizations)
14616   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14617       && !flag_trapping_math)"
14618{
14619  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14620      && !flag_trapping_math)
14621    {
14622      if (TARGET_ROUND)
14623	emit_insn (gen_sse4_1_round<mode>2
14624		   (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14625      else if (optimize_insn_for_size_p ())
14626        FAIL;
14627      else
14628	ix86_expand_rint (operands[0], operands[1]);
14629    }
14630  else
14631    {
14632      rtx op0 = gen_reg_rtx (XFmode);
14633      rtx op1 = gen_reg_rtx (XFmode);
14634
14635      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14636      emit_insn (gen_rintxf2 (op0, op1));
14637
14638      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14639    }
14640  DONE;
14641})
14642
14643(define_expand "round<mode>2"
14644  [(match_operand:X87MODEF 0 "register_operand" "")
14645   (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14646  "(TARGET_USE_FANCY_MATH_387
14647    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14648	|| TARGET_MIX_SSE_I387)
14649    && flag_unsafe_math_optimizations)
14650   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14651       && !flag_trapping_math && !flag_rounding_math)"
14652{
14653  if (optimize_insn_for_size_p ())
14654    FAIL;
14655
14656  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14657      && !flag_trapping_math && !flag_rounding_math)
14658    {
14659      if (TARGET_ROUND)
14660        {
14661	  operands[1] = force_reg (<MODE>mode, operands[1]);
14662	  ix86_expand_round_sse4 (operands[0], operands[1]);
14663	}
14664      else if (TARGET_64BIT || (<MODE>mode != DFmode))
14665	ix86_expand_round (operands[0], operands[1]);
14666      else
14667	ix86_expand_rounddf_32 (operands[0], operands[1]);
14668    }
14669  else
14670    {
14671      operands[1] = force_reg (<MODE>mode, operands[1]);
14672      ix86_emit_i387_round (operands[0], operands[1]);
14673    }
14674  DONE;
14675})
14676
14677(define_insn_and_split "*fistdi2_1"
14678  [(set (match_operand:DI 0 "nonimmediate_operand" "")
14679	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
14680		   UNSPEC_FIST))]
14681  "TARGET_USE_FANCY_MATH_387
14682   && can_create_pseudo_p ()"
14683  "#"
14684  "&& 1"
14685  [(const_int 0)]
14686{
14687  if (memory_operand (operands[0], VOIDmode))
14688    emit_insn (gen_fistdi2 (operands[0], operands[1]));
14689  else
14690    {
14691      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14692      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14693					 operands[2]));
14694    }
14695  DONE;
14696}
14697  [(set_attr "type" "fpspc")
14698   (set_attr "mode" "DI")])
14699
14700(define_insn "fistdi2"
14701  [(set (match_operand:DI 0 "memory_operand" "=m")
14702	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14703		   UNSPEC_FIST))
14704   (clobber (match_scratch:XF 2 "=&1f"))]
14705  "TARGET_USE_FANCY_MATH_387"
14706  "* return output_fix_trunc (insn, operands, false);"
14707  [(set_attr "type" "fpspc")
14708   (set_attr "mode" "DI")])
14709
14710(define_insn "fistdi2_with_temp"
14711  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14712	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14713		   UNSPEC_FIST))
14714   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14715   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14716  "TARGET_USE_FANCY_MATH_387"
14717  "#"
14718  [(set_attr "type" "fpspc")
14719   (set_attr "mode" "DI")])
14720
14721(define_split
14722  [(set (match_operand:DI 0 "register_operand" "")
14723	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
14724		   UNSPEC_FIST))
14725   (clobber (match_operand:DI 2 "memory_operand" ""))
14726   (clobber (match_scratch 3 ""))]
14727  "reload_completed"
14728  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14729	      (clobber (match_dup 3))])
14730   (set (match_dup 0) (match_dup 2))])
14731
14732(define_split
14733  [(set (match_operand:DI 0 "memory_operand" "")
14734	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
14735		   UNSPEC_FIST))
14736   (clobber (match_operand:DI 2 "memory_operand" ""))
14737   (clobber (match_scratch 3 ""))]
14738  "reload_completed"
14739  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14740	      (clobber (match_dup 3))])])
14741
14742(define_insn_and_split "*fist<mode>2_1"
14743  [(set (match_operand:SWI24 0 "register_operand" "")
14744	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14745		      UNSPEC_FIST))]
14746  "TARGET_USE_FANCY_MATH_387
14747   && can_create_pseudo_p ()"
14748  "#"
14749  "&& 1"
14750  [(const_int 0)]
14751{
14752  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14753  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14754					operands[2]));
14755  DONE;
14756}
14757  [(set_attr "type" "fpspc")
14758   (set_attr "mode" "<MODE>")])
14759
14760(define_insn "fist<mode>2"
14761  [(set (match_operand:SWI24 0 "memory_operand" "=m")
14762	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14763		      UNSPEC_FIST))]
14764  "TARGET_USE_FANCY_MATH_387"
14765  "* return output_fix_trunc (insn, operands, false);"
14766  [(set_attr "type" "fpspc")
14767   (set_attr "mode" "<MODE>")])
14768
14769(define_insn "fist<mode>2_with_temp"
14770  [(set (match_operand:SWI24 0 "register_operand" "=r")
14771	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14772		      UNSPEC_FIST))
14773   (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14774  "TARGET_USE_FANCY_MATH_387"
14775  "#"
14776  [(set_attr "type" "fpspc")
14777   (set_attr "mode" "<MODE>")])
14778
14779(define_split
14780  [(set (match_operand:SWI24 0 "register_operand" "")
14781	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14782		      UNSPEC_FIST))
14783   (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14784  "reload_completed"
14785  [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14786   (set (match_dup 0) (match_dup 2))])
14787
14788(define_split
14789  [(set (match_operand:SWI24 0 "memory_operand" "")
14790	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14791		      UNSPEC_FIST))
14792   (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14793  "reload_completed"
14794  [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14795
14796(define_expand "lrintxf<mode>2"
14797  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14798     (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14799		     UNSPEC_FIST))]
14800  "TARGET_USE_FANCY_MATH_387")
14801
14802(define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14803  [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14804     (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14805			UNSPEC_FIX_NOTRUNC))]
14806  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14807   && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14808
14809(define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14810  [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14811   (match_operand:X87MODEF 1 "register_operand" "")]
14812  "(TARGET_USE_FANCY_MATH_387
14813    && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14814	|| TARGET_MIX_SSE_I387)
14815    && flag_unsafe_math_optimizations)
14816   || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14817       && <SWI248x:MODE>mode != HImode
14818       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14819       && !flag_trapping_math && !flag_rounding_math)"
14820{
14821  if (optimize_insn_for_size_p ())
14822    FAIL;
14823
14824  if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14825      && <SWI248x:MODE>mode != HImode
14826      && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14827      && !flag_trapping_math && !flag_rounding_math)
14828    ix86_expand_lround (operands[0], operands[1]);
14829  else
14830    ix86_emit_i387_round (operands[0], operands[1]);
14831  DONE;
14832})
14833
14834;; Rounding mode control word calculation could clobber FLAGS_REG.
14835(define_insn_and_split "frndintxf2_floor"
14836  [(set (match_operand:XF 0 "register_operand" "")
14837	(unspec:XF [(match_operand:XF 1 "register_operand" "")]
14838	 UNSPEC_FRNDINT_FLOOR))
14839   (clobber (reg:CC FLAGS_REG))]
14840  "TARGET_USE_FANCY_MATH_387
14841   && flag_unsafe_math_optimizations
14842   && can_create_pseudo_p ()"
14843  "#"
14844  "&& 1"
14845  [(const_int 0)]
14846{
14847  ix86_optimize_mode_switching[I387_FLOOR] = 1;
14848
14849  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14850  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14851
14852  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14853					operands[2], operands[3]));
14854  DONE;
14855}
14856  [(set_attr "type" "frndint")
14857   (set_attr "i387_cw" "floor")
14858   (set_attr "mode" "XF")])
14859
14860(define_insn "frndintxf2_floor_i387"
14861  [(set (match_operand:XF 0 "register_operand" "=f")
14862	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14863	 UNSPEC_FRNDINT_FLOOR))
14864   (use (match_operand:HI 2 "memory_operand" "m"))
14865   (use (match_operand:HI 3 "memory_operand" "m"))]
14866  "TARGET_USE_FANCY_MATH_387
14867   && flag_unsafe_math_optimizations"
14868  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14869  [(set_attr "type" "frndint")
14870   (set_attr "i387_cw" "floor")
14871   (set_attr "mode" "XF")])
14872
14873(define_expand "floorxf2"
14874  [(use (match_operand:XF 0 "register_operand" ""))
14875   (use (match_operand:XF 1 "register_operand" ""))]
14876  "TARGET_USE_FANCY_MATH_387
14877   && flag_unsafe_math_optimizations"
14878{
14879  if (optimize_insn_for_size_p ())
14880    FAIL;
14881  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14882  DONE;
14883})
14884
14885(define_expand "floor<mode>2"
14886  [(use (match_operand:MODEF 0 "register_operand" ""))
14887   (use (match_operand:MODEF 1 "register_operand" ""))]
14888  "(TARGET_USE_FANCY_MATH_387
14889    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14890	|| TARGET_MIX_SSE_I387)
14891    && flag_unsafe_math_optimizations)
14892   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14893       && !flag_trapping_math)"
14894{
14895  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14896      && !flag_trapping_math)
14897    {
14898      if (TARGET_ROUND)
14899	emit_insn (gen_sse4_1_round<mode>2
14900		   (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14901      else if (optimize_insn_for_size_p ())
14902        FAIL;
14903      else if (TARGET_64BIT || (<MODE>mode != DFmode))
14904	ix86_expand_floorceil (operands[0], operands[1], true);
14905      else
14906	ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14907    }
14908  else
14909    {
14910      rtx op0, op1;
14911
14912      if (optimize_insn_for_size_p ())
14913	FAIL;
14914
14915      op0 = gen_reg_rtx (XFmode);
14916      op1 = gen_reg_rtx (XFmode);
14917      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14918      emit_insn (gen_frndintxf2_floor (op0, op1));
14919
14920      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14921    }
14922  DONE;
14923})
14924
14925(define_insn_and_split "*fist<mode>2_floor_1"
14926  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14927	(unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14928			UNSPEC_FIST_FLOOR))
14929   (clobber (reg:CC FLAGS_REG))]
14930  "TARGET_USE_FANCY_MATH_387
14931   && flag_unsafe_math_optimizations
14932   && can_create_pseudo_p ()"
14933  "#"
14934  "&& 1"
14935  [(const_int 0)]
14936{
14937  ix86_optimize_mode_switching[I387_FLOOR] = 1;
14938
14939  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14940  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14941  if (memory_operand (operands[0], VOIDmode))
14942    emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14943				      operands[2], operands[3]));
14944  else
14945    {
14946      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14947      emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14948						  operands[2], operands[3],
14949						  operands[4]));
14950    }
14951  DONE;
14952}
14953  [(set_attr "type" "fistp")
14954   (set_attr "i387_cw" "floor")
14955   (set_attr "mode" "<MODE>")])
14956
14957(define_insn "fistdi2_floor"
14958  [(set (match_operand:DI 0 "memory_operand" "=m")
14959	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14960		   UNSPEC_FIST_FLOOR))
14961   (use (match_operand:HI 2 "memory_operand" "m"))
14962   (use (match_operand:HI 3 "memory_operand" "m"))
14963   (clobber (match_scratch:XF 4 "=&1f"))]
14964  "TARGET_USE_FANCY_MATH_387
14965   && flag_unsafe_math_optimizations"
14966  "* return output_fix_trunc (insn, operands, false);"
14967  [(set_attr "type" "fistp")
14968   (set_attr "i387_cw" "floor")
14969   (set_attr "mode" "DI")])
14970
14971(define_insn "fistdi2_floor_with_temp"
14972  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14973	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14974		   UNSPEC_FIST_FLOOR))
14975   (use (match_operand:HI 2 "memory_operand" "m,m"))
14976   (use (match_operand:HI 3 "memory_operand" "m,m"))
14977   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14978   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14979  "TARGET_USE_FANCY_MATH_387
14980   && flag_unsafe_math_optimizations"
14981  "#"
14982  [(set_attr "type" "fistp")
14983   (set_attr "i387_cw" "floor")
14984   (set_attr "mode" "DI")])
14985
14986(define_split
14987  [(set (match_operand:DI 0 "register_operand" "")
14988	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
14989		   UNSPEC_FIST_FLOOR))
14990   (use (match_operand:HI 2 "memory_operand" ""))
14991   (use (match_operand:HI 3 "memory_operand" ""))
14992   (clobber (match_operand:DI 4 "memory_operand" ""))
14993   (clobber (match_scratch 5 ""))]
14994  "reload_completed"
14995  [(parallel [(set (match_dup 4)
14996		   (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14997	      (use (match_dup 2))
14998	      (use (match_dup 3))
14999	      (clobber (match_dup 5))])
15000   (set (match_dup 0) (match_dup 4))])
15001
15002(define_split
15003  [(set (match_operand:DI 0 "memory_operand" "")
15004	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
15005		   UNSPEC_FIST_FLOOR))
15006   (use (match_operand:HI 2 "memory_operand" ""))
15007   (use (match_operand:HI 3 "memory_operand" ""))
15008   (clobber (match_operand:DI 4 "memory_operand" ""))
15009   (clobber (match_scratch 5 ""))]
15010  "reload_completed"
15011  [(parallel [(set (match_dup 0)
15012		   (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15013	      (use (match_dup 2))
15014	      (use (match_dup 3))
15015	      (clobber (match_dup 5))])])
15016
15017(define_insn "fist<mode>2_floor"
15018  [(set (match_operand:SWI24 0 "memory_operand" "=m")
15019	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15020		      UNSPEC_FIST_FLOOR))
15021   (use (match_operand:HI 2 "memory_operand" "m"))
15022   (use (match_operand:HI 3 "memory_operand" "m"))]
15023  "TARGET_USE_FANCY_MATH_387
15024   && flag_unsafe_math_optimizations"
15025  "* return output_fix_trunc (insn, operands, false);"
15026  [(set_attr "type" "fistp")
15027   (set_attr "i387_cw" "floor")
15028   (set_attr "mode" "<MODE>")])
15029
15030(define_insn "fist<mode>2_floor_with_temp"
15031  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15032	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15033		      UNSPEC_FIST_FLOOR))
15034   (use (match_operand:HI 2 "memory_operand" "m,m"))
15035   (use (match_operand:HI 3 "memory_operand" "m,m"))
15036   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15037  "TARGET_USE_FANCY_MATH_387
15038   && flag_unsafe_math_optimizations"
15039  "#"
15040  [(set_attr "type" "fistp")
15041   (set_attr "i387_cw" "floor")
15042   (set_attr "mode" "<MODE>")])
15043
15044(define_split
15045  [(set (match_operand:SWI24 0 "register_operand" "")
15046	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15047		      UNSPEC_FIST_FLOOR))
15048   (use (match_operand:HI 2 "memory_operand" ""))
15049   (use (match_operand:HI 3 "memory_operand" ""))
15050   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15051  "reload_completed"
15052  [(parallel [(set (match_dup 4)
15053		   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15054	      (use (match_dup 2))
15055	      (use (match_dup 3))])
15056   (set (match_dup 0) (match_dup 4))])
15057
15058(define_split
15059  [(set (match_operand:SWI24 0 "memory_operand" "")
15060	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15061		      UNSPEC_FIST_FLOOR))
15062   (use (match_operand:HI 2 "memory_operand" ""))
15063   (use (match_operand:HI 3 "memory_operand" ""))
15064   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15065  "reload_completed"
15066  [(parallel [(set (match_dup 0)
15067		   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15068	      (use (match_dup 2))
15069	      (use (match_dup 3))])])
15070
15071(define_expand "lfloorxf<mode>2"
15072  [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15073		   (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15074				   UNSPEC_FIST_FLOOR))
15075	      (clobber (reg:CC FLAGS_REG))])]
15076  "TARGET_USE_FANCY_MATH_387
15077   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15078   && flag_unsafe_math_optimizations")
15079
15080(define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15081  [(match_operand:SWI48 0 "nonimmediate_operand" "")
15082   (match_operand:MODEF 1 "register_operand" "")]
15083  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15084   && !flag_trapping_math"
15085{
15086  if (TARGET_64BIT && optimize_insn_for_size_p ())
15087    FAIL;
15088  ix86_expand_lfloorceil (operands[0], operands[1], true);
15089  DONE;
15090})
15091
15092;; Rounding mode control word calculation could clobber FLAGS_REG.
15093(define_insn_and_split "frndintxf2_ceil"
15094  [(set (match_operand:XF 0 "register_operand" "")
15095	(unspec:XF [(match_operand:XF 1 "register_operand" "")]
15096	 UNSPEC_FRNDINT_CEIL))
15097   (clobber (reg:CC FLAGS_REG))]
15098  "TARGET_USE_FANCY_MATH_387
15099   && flag_unsafe_math_optimizations
15100   && can_create_pseudo_p ()"
15101  "#"
15102  "&& 1"
15103  [(const_int 0)]
15104{
15105  ix86_optimize_mode_switching[I387_CEIL] = 1;
15106
15107  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15108  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15109
15110  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15111				       operands[2], operands[3]));
15112  DONE;
15113}
15114  [(set_attr "type" "frndint")
15115   (set_attr "i387_cw" "ceil")
15116   (set_attr "mode" "XF")])
15117
15118(define_insn "frndintxf2_ceil_i387"
15119  [(set (match_operand:XF 0 "register_operand" "=f")
15120	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15121	 UNSPEC_FRNDINT_CEIL))
15122   (use (match_operand:HI 2 "memory_operand" "m"))
15123   (use (match_operand:HI 3 "memory_operand" "m"))]
15124  "TARGET_USE_FANCY_MATH_387
15125   && flag_unsafe_math_optimizations"
15126  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15127  [(set_attr "type" "frndint")
15128   (set_attr "i387_cw" "ceil")
15129   (set_attr "mode" "XF")])
15130
15131(define_expand "ceilxf2"
15132  [(use (match_operand:XF 0 "register_operand" ""))
15133   (use (match_operand:XF 1 "register_operand" ""))]
15134  "TARGET_USE_FANCY_MATH_387
15135   && flag_unsafe_math_optimizations"
15136{
15137  if (optimize_insn_for_size_p ())
15138    FAIL;
15139  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15140  DONE;
15141})
15142
15143(define_expand "ceil<mode>2"
15144  [(use (match_operand:MODEF 0 "register_operand" ""))
15145   (use (match_operand:MODEF 1 "register_operand" ""))]
15146  "(TARGET_USE_FANCY_MATH_387
15147    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15148	|| TARGET_MIX_SSE_I387)
15149    && flag_unsafe_math_optimizations)
15150   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15151       && !flag_trapping_math)"
15152{
15153  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15154      && !flag_trapping_math)
15155    {
15156      if (TARGET_ROUND)
15157	emit_insn (gen_sse4_1_round<mode>2
15158		   (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15159      else if (optimize_insn_for_size_p ())
15160	FAIL;
15161      else if (TARGET_64BIT || (<MODE>mode != DFmode))
15162	ix86_expand_floorceil (operands[0], operands[1], false);
15163      else
15164	ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15165    }
15166  else
15167    {
15168      rtx op0, op1;
15169
15170      if (optimize_insn_for_size_p ())
15171	FAIL;
15172
15173      op0 = gen_reg_rtx (XFmode);
15174      op1 = gen_reg_rtx (XFmode);
15175      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15176      emit_insn (gen_frndintxf2_ceil (op0, op1));
15177
15178      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15179    }
15180  DONE;
15181})
15182
15183(define_insn_and_split "*fist<mode>2_ceil_1"
15184  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15185	(unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15186			UNSPEC_FIST_CEIL))
15187   (clobber (reg:CC FLAGS_REG))]
15188  "TARGET_USE_FANCY_MATH_387
15189   && flag_unsafe_math_optimizations
15190   && can_create_pseudo_p ()"
15191  "#"
15192  "&& 1"
15193  [(const_int 0)]
15194{
15195  ix86_optimize_mode_switching[I387_CEIL] = 1;
15196
15197  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15198  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15199  if (memory_operand (operands[0], VOIDmode))
15200    emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15201				     operands[2], operands[3]));
15202  else
15203    {
15204      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15205      emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15206						 operands[2], operands[3],
15207						 operands[4]));
15208    }
15209  DONE;
15210}
15211  [(set_attr "type" "fistp")
15212   (set_attr "i387_cw" "ceil")
15213   (set_attr "mode" "<MODE>")])
15214
15215(define_insn "fistdi2_ceil"
15216  [(set (match_operand:DI 0 "memory_operand" "=m")
15217	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15218		   UNSPEC_FIST_CEIL))
15219   (use (match_operand:HI 2 "memory_operand" "m"))
15220   (use (match_operand:HI 3 "memory_operand" "m"))
15221   (clobber (match_scratch:XF 4 "=&1f"))]
15222  "TARGET_USE_FANCY_MATH_387
15223   && flag_unsafe_math_optimizations"
15224  "* return output_fix_trunc (insn, operands, false);"
15225  [(set_attr "type" "fistp")
15226   (set_attr "i387_cw" "ceil")
15227   (set_attr "mode" "DI")])
15228
15229(define_insn "fistdi2_ceil_with_temp"
15230  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15231	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15232		   UNSPEC_FIST_CEIL))
15233   (use (match_operand:HI 2 "memory_operand" "m,m"))
15234   (use (match_operand:HI 3 "memory_operand" "m,m"))
15235   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15236   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15237  "TARGET_USE_FANCY_MATH_387
15238   && flag_unsafe_math_optimizations"
15239  "#"
15240  [(set_attr "type" "fistp")
15241   (set_attr "i387_cw" "ceil")
15242   (set_attr "mode" "DI")])
15243
15244(define_split
15245  [(set (match_operand:DI 0 "register_operand" "")
15246	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
15247		   UNSPEC_FIST_CEIL))
15248   (use (match_operand:HI 2 "memory_operand" ""))
15249   (use (match_operand:HI 3 "memory_operand" ""))
15250   (clobber (match_operand:DI 4 "memory_operand" ""))
15251   (clobber (match_scratch 5 ""))]
15252  "reload_completed"
15253  [(parallel [(set (match_dup 4)
15254		   (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15255	      (use (match_dup 2))
15256	      (use (match_dup 3))
15257	      (clobber (match_dup 5))])
15258   (set (match_dup 0) (match_dup 4))])
15259
15260(define_split
15261  [(set (match_operand:DI 0 "memory_operand" "")
15262	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
15263		   UNSPEC_FIST_CEIL))
15264   (use (match_operand:HI 2 "memory_operand" ""))
15265   (use (match_operand:HI 3 "memory_operand" ""))
15266   (clobber (match_operand:DI 4 "memory_operand" ""))
15267   (clobber (match_scratch 5 ""))]
15268  "reload_completed"
15269  [(parallel [(set (match_dup 0)
15270		   (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15271	      (use (match_dup 2))
15272	      (use (match_dup 3))
15273	      (clobber (match_dup 5))])])
15274
15275(define_insn "fist<mode>2_ceil"
15276  [(set (match_operand:SWI24 0 "memory_operand" "=m")
15277	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15278		      UNSPEC_FIST_CEIL))
15279   (use (match_operand:HI 2 "memory_operand" "m"))
15280   (use (match_operand:HI 3 "memory_operand" "m"))]
15281  "TARGET_USE_FANCY_MATH_387
15282   && flag_unsafe_math_optimizations"
15283  "* return output_fix_trunc (insn, operands, false);"
15284  [(set_attr "type" "fistp")
15285   (set_attr "i387_cw" "ceil")
15286   (set_attr "mode" "<MODE>")])
15287
15288(define_insn "fist<mode>2_ceil_with_temp"
15289  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15290	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15291		      UNSPEC_FIST_CEIL))
15292   (use (match_operand:HI 2 "memory_operand" "m,m"))
15293   (use (match_operand:HI 3 "memory_operand" "m,m"))
15294   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15295  "TARGET_USE_FANCY_MATH_387
15296   && flag_unsafe_math_optimizations"
15297  "#"
15298  [(set_attr "type" "fistp")
15299   (set_attr "i387_cw" "ceil")
15300   (set_attr "mode" "<MODE>")])
15301
15302(define_split
15303  [(set (match_operand:SWI24 0 "register_operand" "")
15304	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15305		      UNSPEC_FIST_CEIL))
15306   (use (match_operand:HI 2 "memory_operand" ""))
15307   (use (match_operand:HI 3 "memory_operand" ""))
15308   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15309  "reload_completed"
15310  [(parallel [(set (match_dup 4)
15311		   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15312	      (use (match_dup 2))
15313	      (use (match_dup 3))])
15314   (set (match_dup 0) (match_dup 4))])
15315
15316(define_split
15317  [(set (match_operand:SWI24 0 "memory_operand" "")
15318	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15319		      UNSPEC_FIST_CEIL))
15320   (use (match_operand:HI 2 "memory_operand" ""))
15321   (use (match_operand:HI 3 "memory_operand" ""))
15322   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15323  "reload_completed"
15324  [(parallel [(set (match_dup 0)
15325		   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15326	      (use (match_dup 2))
15327	      (use (match_dup 3))])])
15328
15329(define_expand "lceilxf<mode>2"
15330  [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15331		   (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15332				   UNSPEC_FIST_CEIL))
15333	      (clobber (reg:CC FLAGS_REG))])]
15334  "TARGET_USE_FANCY_MATH_387
15335   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15336   && flag_unsafe_math_optimizations")
15337
15338(define_expand "lceil<MODEF:mode><SWI48:mode>2"
15339  [(match_operand:SWI48 0 "nonimmediate_operand" "")
15340   (match_operand:MODEF 1 "register_operand" "")]
15341  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15342   && !flag_trapping_math"
15343{
15344  ix86_expand_lfloorceil (operands[0], operands[1], false);
15345  DONE;
15346})
15347
15348;; Rounding mode control word calculation could clobber FLAGS_REG.
15349(define_insn_and_split "frndintxf2_trunc"
15350  [(set (match_operand:XF 0 "register_operand" "")
15351	(unspec:XF [(match_operand:XF 1 "register_operand" "")]
15352	 UNSPEC_FRNDINT_TRUNC))
15353   (clobber (reg:CC FLAGS_REG))]
15354  "TARGET_USE_FANCY_MATH_387
15355   && flag_unsafe_math_optimizations
15356   && can_create_pseudo_p ()"
15357  "#"
15358  "&& 1"
15359  [(const_int 0)]
15360{
15361  ix86_optimize_mode_switching[I387_TRUNC] = 1;
15362
15363  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15364  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15365
15366  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15367					operands[2], operands[3]));
15368  DONE;
15369}
15370  [(set_attr "type" "frndint")
15371   (set_attr "i387_cw" "trunc")
15372   (set_attr "mode" "XF")])
15373
15374(define_insn "frndintxf2_trunc_i387"
15375  [(set (match_operand:XF 0 "register_operand" "=f")
15376	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15377	 UNSPEC_FRNDINT_TRUNC))
15378   (use (match_operand:HI 2 "memory_operand" "m"))
15379   (use (match_operand:HI 3 "memory_operand" "m"))]
15380  "TARGET_USE_FANCY_MATH_387
15381   && flag_unsafe_math_optimizations"
15382  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15383  [(set_attr "type" "frndint")
15384   (set_attr "i387_cw" "trunc")
15385   (set_attr "mode" "XF")])
15386
15387(define_expand "btruncxf2"
15388  [(use (match_operand:XF 0 "register_operand" ""))
15389   (use (match_operand:XF 1 "register_operand" ""))]
15390  "TARGET_USE_FANCY_MATH_387
15391   && flag_unsafe_math_optimizations"
15392{
15393  if (optimize_insn_for_size_p ())
15394    FAIL;
15395  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15396  DONE;
15397})
15398
15399(define_expand "btrunc<mode>2"
15400  [(use (match_operand:MODEF 0 "register_operand" ""))
15401   (use (match_operand:MODEF 1 "register_operand" ""))]
15402  "(TARGET_USE_FANCY_MATH_387
15403    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15404	|| TARGET_MIX_SSE_I387)
15405    && flag_unsafe_math_optimizations)
15406   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15407       && !flag_trapping_math)"
15408{
15409  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15410      && !flag_trapping_math)
15411    {
15412      if (TARGET_ROUND)
15413	emit_insn (gen_sse4_1_round<mode>2
15414		   (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15415      else if (optimize_insn_for_size_p ())
15416	FAIL;
15417      else if (TARGET_64BIT || (<MODE>mode != DFmode))
15418	ix86_expand_trunc (operands[0], operands[1]);
15419      else
15420	ix86_expand_truncdf_32 (operands[0], operands[1]);
15421    }
15422  else
15423    {
15424      rtx op0, op1;
15425
15426      if (optimize_insn_for_size_p ())
15427	FAIL;
15428
15429      op0 = gen_reg_rtx (XFmode);
15430      op1 = gen_reg_rtx (XFmode);
15431      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15432      emit_insn (gen_frndintxf2_trunc (op0, op1));
15433
15434      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15435    }
15436  DONE;
15437})
15438
15439;; Rounding mode control word calculation could clobber FLAGS_REG.
15440(define_insn_and_split "frndintxf2_mask_pm"
15441  [(set (match_operand:XF 0 "register_operand" "")
15442	(unspec:XF [(match_operand:XF 1 "register_operand" "")]
15443	 UNSPEC_FRNDINT_MASK_PM))
15444   (clobber (reg:CC FLAGS_REG))]
15445  "TARGET_USE_FANCY_MATH_387
15446   && flag_unsafe_math_optimizations
15447   && can_create_pseudo_p ()"
15448  "#"
15449  "&& 1"
15450  [(const_int 0)]
15451{
15452  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15453
15454  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15455  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15456
15457  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15458					  operands[2], operands[3]));
15459  DONE;
15460}
15461  [(set_attr "type" "frndint")
15462   (set_attr "i387_cw" "mask_pm")
15463   (set_attr "mode" "XF")])
15464
15465(define_insn "frndintxf2_mask_pm_i387"
15466  [(set (match_operand:XF 0 "register_operand" "=f")
15467	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15468	 UNSPEC_FRNDINT_MASK_PM))
15469   (use (match_operand:HI 2 "memory_operand" "m"))
15470   (use (match_operand:HI 3 "memory_operand" "m"))]
15471  "TARGET_USE_FANCY_MATH_387
15472   && flag_unsafe_math_optimizations"
15473  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15474  [(set_attr "type" "frndint")
15475   (set_attr "i387_cw" "mask_pm")
15476   (set_attr "mode" "XF")])
15477
15478(define_expand "nearbyintxf2"
15479  [(use (match_operand:XF 0 "register_operand" ""))
15480   (use (match_operand:XF 1 "register_operand" ""))]
15481  "TARGET_USE_FANCY_MATH_387
15482   && flag_unsafe_math_optimizations"
15483{
15484  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15485  DONE;
15486})
15487
15488(define_expand "nearbyint<mode>2"
15489  [(use (match_operand:MODEF 0 "register_operand" ""))
15490   (use (match_operand:MODEF 1 "register_operand" ""))]
15491  "TARGET_USE_FANCY_MATH_387
15492   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15493       || TARGET_MIX_SSE_I387)
15494   && flag_unsafe_math_optimizations"
15495{
15496  rtx op0 = gen_reg_rtx (XFmode);
15497  rtx op1 = gen_reg_rtx (XFmode);
15498
15499  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15500  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15501
15502  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15503  DONE;
15504})
15505
15506(define_insn "fxam<mode>2_i387"
15507  [(set (match_operand:HI 0 "register_operand" "=a")
15508	(unspec:HI
15509	  [(match_operand:X87MODEF 1 "register_operand" "f")]
15510	  UNSPEC_FXAM))]
15511  "TARGET_USE_FANCY_MATH_387"
15512  "fxam\n\tfnstsw\t%0"
15513  [(set_attr "type" "multi")
15514   (set_attr "length" "4")
15515   (set_attr "unit" "i387")
15516   (set_attr "mode" "<MODE>")])
15517
15518(define_insn_and_split "fxam<mode>2_i387_with_temp"
15519  [(set (match_operand:HI 0 "register_operand" "")
15520	(unspec:HI
15521	  [(match_operand:MODEF 1 "memory_operand" "")]
15522	  UNSPEC_FXAM_MEM))]
15523  "TARGET_USE_FANCY_MATH_387
15524   && can_create_pseudo_p ()"
15525  "#"
15526  "&& 1"
15527  [(set (match_dup 2)(match_dup 1))
15528   (set (match_dup 0)
15529	(unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15530{
15531  operands[2] = gen_reg_rtx (<MODE>mode);
15532
15533  MEM_VOLATILE_P (operands[1]) = 1;
15534}
15535  [(set_attr "type" "multi")
15536   (set_attr "unit" "i387")
15537   (set_attr "mode" "<MODE>")])
15538
15539(define_expand "isinfxf2"
15540  [(use (match_operand:SI 0 "register_operand" ""))
15541   (use (match_operand:XF 1 "register_operand" ""))]
15542  "TARGET_USE_FANCY_MATH_387
15543   && TARGET_C99_FUNCTIONS"
15544{
15545  rtx mask = GEN_INT (0x45);
15546  rtx val = GEN_INT (0x05);
15547
15548  rtx cond;
15549
15550  rtx scratch = gen_reg_rtx (HImode);
15551  rtx res = gen_reg_rtx (QImode);
15552
15553  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15554
15555  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15556  emit_insn (gen_cmpqi_ext_3 (scratch, val));
15557  cond = gen_rtx_fmt_ee (EQ, QImode,
15558			 gen_rtx_REG (CCmode, FLAGS_REG),
15559			 const0_rtx);
15560  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15561  emit_insn (gen_zero_extendqisi2 (operands[0], res));
15562  DONE;
15563})
15564
15565(define_expand "isinf<mode>2"
15566  [(use (match_operand:SI 0 "register_operand" ""))
15567   (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15568  "TARGET_USE_FANCY_MATH_387
15569   && TARGET_C99_FUNCTIONS
15570   && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15571{
15572  rtx mask = GEN_INT (0x45);
15573  rtx val = GEN_INT (0x05);
15574
15575  rtx cond;
15576
15577  rtx scratch = gen_reg_rtx (HImode);
15578  rtx res = gen_reg_rtx (QImode);
15579
15580  /* Remove excess precision by forcing value through memory. */
15581  if (memory_operand (operands[1], VOIDmode))
15582    emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15583  else
15584    {
15585      rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15586
15587      emit_move_insn (temp, operands[1]);
15588      emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15589    }
15590
15591  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15592  emit_insn (gen_cmpqi_ext_3 (scratch, val));
15593  cond = gen_rtx_fmt_ee (EQ, QImode,
15594			 gen_rtx_REG (CCmode, FLAGS_REG),
15595			 const0_rtx);
15596  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15597  emit_insn (gen_zero_extendqisi2 (operands[0], res));
15598  DONE;
15599})
15600
15601(define_expand "signbitxf2"
15602  [(use (match_operand:SI 0 "register_operand" ""))
15603   (use (match_operand:XF 1 "register_operand" ""))]
15604  "TARGET_USE_FANCY_MATH_387"
15605{
15606  rtx scratch = gen_reg_rtx (HImode);
15607
15608  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15609  emit_insn (gen_andsi3 (operands[0],
15610	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15611  DONE;
15612})
15613
15614(define_insn "movmsk_df"
15615  [(set (match_operand:SI 0 "register_operand" "=r")
15616	(unspec:SI
15617	  [(match_operand:DF 1 "register_operand" "x")]
15618	  UNSPEC_MOVMSK))]
15619  "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15620  "%vmovmskpd\t{%1, %0|%0, %1}"
15621  [(set_attr "type" "ssemov")
15622   (set_attr "prefix" "maybe_vex")
15623   (set_attr "mode" "DF")])
15624
15625;; Use movmskpd in SSE mode to avoid store forwarding stall
15626;; for 32bit targets and movq+shrq sequence for 64bit targets.
15627(define_expand "signbitdf2"
15628  [(use (match_operand:SI 0 "register_operand" ""))
15629   (use (match_operand:DF 1 "register_operand" ""))]
15630  "TARGET_USE_FANCY_MATH_387
15631   || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15632{
15633  if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15634    {
15635      emit_insn (gen_movmsk_df (operands[0], operands[1]));
15636      emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15637    }
15638  else
15639    {
15640      rtx scratch = gen_reg_rtx (HImode);
15641
15642      emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15643      emit_insn (gen_andsi3 (operands[0],
15644		 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15645    }
15646  DONE;
15647})
15648
15649(define_expand "signbitsf2"
15650  [(use (match_operand:SI 0 "register_operand" ""))
15651   (use (match_operand:SF 1 "register_operand" ""))]
15652  "TARGET_USE_FANCY_MATH_387
15653   && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15654{
15655  rtx scratch = gen_reg_rtx (HImode);
15656
15657  emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15658  emit_insn (gen_andsi3 (operands[0],
15659	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15660  DONE;
15661})
15662
15663;; Block operation instructions
15664
15665(define_insn "cld"
15666  [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15667  ""
15668  "cld"
15669  [(set_attr "length" "1")
15670   (set_attr "length_immediate" "0")
15671   (set_attr "modrm" "0")])
15672
15673(define_expand "movmem<mode>"
15674  [(use (match_operand:BLK 0 "memory_operand" ""))
15675   (use (match_operand:BLK 1 "memory_operand" ""))
15676   (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15677   (use (match_operand:SWI48 3 "const_int_operand" ""))
15678   (use (match_operand:SI 4 "const_int_operand" ""))
15679   (use (match_operand:SI 5 "const_int_operand" ""))]
15680  ""
15681{
15682 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15683			 operands[4], operands[5]))
15684   DONE;
15685 else
15686   FAIL;
15687})
15688
15689;; Most CPUs don't like single string operations
15690;; Handle this case here to simplify previous expander.
15691
15692(define_expand "strmov"
15693  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15694   (set (match_operand 1 "memory_operand" "") (match_dup 4))
15695   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15696	      (clobber (reg:CC FLAGS_REG))])
15697   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15698	      (clobber (reg:CC FLAGS_REG))])]
15699  ""
15700{
15701  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15702
15703  /* If .md ever supports :P for Pmode, these can be directly
15704     in the pattern above.  */
15705  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15706  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15707
15708  /* Can't use this if the user has appropriated esi or edi.  */
15709  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15710      && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15711    {
15712      emit_insn (gen_strmov_singleop (operands[0], operands[1],
15713				      operands[2], operands[3],
15714				      operands[5], operands[6]));
15715      DONE;
15716    }
15717
15718  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15719})
15720
15721(define_expand "strmov_singleop"
15722  [(parallel [(set (match_operand 1 "memory_operand" "")
15723		   (match_operand 3 "memory_operand" ""))
15724	      (set (match_operand 0 "register_operand" "")
15725		   (match_operand 4 "" ""))
15726	      (set (match_operand 2 "register_operand" "")
15727		   (match_operand 5 "" ""))])]
15728  ""
15729  "ix86_current_function_needs_cld = 1;")
15730
15731(define_insn "*strmovdi_rex_1"
15732  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15733	(mem:DI (match_operand:DI 3 "register_operand" "1")))
15734   (set (match_operand:DI 0 "register_operand" "=D")
15735	(plus:DI (match_dup 2)
15736		 (const_int 8)))
15737   (set (match_operand:DI 1 "register_operand" "=S")
15738	(plus:DI (match_dup 3)
15739		 (const_int 8)))]
15740  "TARGET_64BIT
15741   && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15742  "movsq"
15743  [(set_attr "type" "str")
15744   (set_attr "memory" "both")
15745   (set_attr "mode" "DI")])
15746
15747(define_insn "*strmovsi_1"
15748  [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15749	(mem:SI (match_operand:P 3 "register_operand" "1")))
15750   (set (match_operand:P 0 "register_operand" "=D")
15751	(plus:P (match_dup 2)
15752		(const_int 4)))
15753   (set (match_operand:P 1 "register_operand" "=S")
15754	(plus:P (match_dup 3)
15755		(const_int 4)))]
15756  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15757  "movs{l|d}"
15758  [(set_attr "type" "str")
15759   (set_attr "memory" "both")
15760   (set_attr "mode" "SI")])
15761
15762(define_insn "*strmovhi_1"
15763  [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15764	(mem:HI (match_operand:P 3 "register_operand" "1")))
15765   (set (match_operand:P 0 "register_operand" "=D")
15766	(plus:P (match_dup 2)
15767		(const_int 2)))
15768   (set (match_operand:P 1 "register_operand" "=S")
15769	(plus:P (match_dup 3)
15770		(const_int 2)))]
15771  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15772  "movsw"
15773  [(set_attr "type" "str")
15774   (set_attr "memory" "both")
15775   (set_attr "mode" "HI")])
15776
15777(define_insn "*strmovqi_1"
15778  [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15779	(mem:QI (match_operand:P 3 "register_operand" "1")))
15780   (set (match_operand:P 0 "register_operand" "=D")
15781	(plus:P (match_dup 2)
15782		(const_int 1)))
15783   (set (match_operand:P 1 "register_operand" "=S")
15784	(plus:P (match_dup 3)
15785		(const_int 1)))]
15786  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15787  "movsb"
15788  [(set_attr "type" "str")
15789   (set_attr "memory" "both")
15790   (set (attr "prefix_rex")
15791	(if_then_else
15792	  (match_test "<P:MODE>mode == DImode")
15793	  (const_string "0")
15794	  (const_string "*")))
15795   (set_attr "mode" "QI")])
15796
15797(define_expand "rep_mov"
15798  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15799	      (set (match_operand 0 "register_operand" "")
15800		   (match_operand 5 "" ""))
15801	      (set (match_operand 2 "register_operand" "")
15802		   (match_operand 6 "" ""))
15803	      (set (match_operand 1 "memory_operand" "")
15804		   (match_operand 3 "memory_operand" ""))
15805	      (use (match_dup 4))])]
15806  ""
15807  "ix86_current_function_needs_cld = 1;")
15808
15809(define_insn "*rep_movdi_rex64"
15810  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15811   (set (match_operand:DI 0 "register_operand" "=D")
15812        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15813			    (const_int 3))
15814		 (match_operand:DI 3 "register_operand" "0")))
15815   (set (match_operand:DI 1 "register_operand" "=S")
15816        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15817		 (match_operand:DI 4 "register_operand" "1")))
15818   (set (mem:BLK (match_dup 3))
15819	(mem:BLK (match_dup 4)))
15820   (use (match_dup 5))]
15821  "TARGET_64BIT
15822   && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15823  "rep{%;} movsq"
15824  [(set_attr "type" "str")
15825   (set_attr "prefix_rep" "1")
15826   (set_attr "memory" "both")
15827   (set_attr "mode" "DI")])
15828
15829(define_insn "*rep_movsi"
15830  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15831   (set (match_operand:P 0 "register_operand" "=D")
15832        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15833			  (const_int 2))
15834		 (match_operand:P 3 "register_operand" "0")))
15835   (set (match_operand:P 1 "register_operand" "=S")
15836        (plus:P (ashift:P (match_dup 5) (const_int 2))
15837		(match_operand:P 4 "register_operand" "1")))
15838   (set (mem:BLK (match_dup 3))
15839	(mem:BLK (match_dup 4)))
15840   (use (match_dup 5))]
15841  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15842  "rep{%;} movs{l|d}"
15843  [(set_attr "type" "str")
15844   (set_attr "prefix_rep" "1")
15845   (set_attr "memory" "both")
15846   (set_attr "mode" "SI")])
15847
15848(define_insn "*rep_movqi"
15849  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15850   (set (match_operand:P 0 "register_operand" "=D")
15851        (plus:P (match_operand:P 3 "register_operand" "0")
15852		(match_operand:P 5 "register_operand" "2")))
15853   (set (match_operand:P 1 "register_operand" "=S")
15854        (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15855   (set (mem:BLK (match_dup 3))
15856	(mem:BLK (match_dup 4)))
15857   (use (match_dup 5))]
15858  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15859  "rep{%;} movsb"
15860  [(set_attr "type" "str")
15861   (set_attr "prefix_rep" "1")
15862   (set_attr "memory" "both")
15863   (set_attr "mode" "QI")])
15864
15865(define_expand "setmem<mode>"
15866   [(use (match_operand:BLK 0 "memory_operand" ""))
15867    (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15868    (use (match_operand:QI 2 "nonmemory_operand" ""))
15869    (use (match_operand 3 "const_int_operand" ""))
15870    (use (match_operand:SI 4 "const_int_operand" ""))
15871    (use (match_operand:SI 5 "const_int_operand" ""))]
15872  ""
15873{
15874 if (ix86_expand_setmem (operands[0], operands[1],
15875			 operands[2], operands[3],
15876			 operands[4], operands[5]))
15877   DONE;
15878 else
15879   FAIL;
15880})
15881
15882;; Most CPUs don't like single string operations
15883;; Handle this case here to simplify previous expander.
15884
15885(define_expand "strset"
15886  [(set (match_operand 1 "memory_operand" "")
15887	(match_operand 2 "register_operand" ""))
15888   (parallel [(set (match_operand 0 "register_operand" "")
15889		   (match_dup 3))
15890	      (clobber (reg:CC FLAGS_REG))])]
15891  ""
15892{
15893  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15894    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15895
15896  /* If .md ever supports :P for Pmode, this can be directly
15897     in the pattern above.  */
15898  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15899			      GEN_INT (GET_MODE_SIZE (GET_MODE
15900						      (operands[2]))));
15901  /* Can't use this if the user has appropriated eax or edi.  */
15902  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15903      && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15904    {
15905      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15906				      operands[3]));
15907      DONE;
15908    }
15909})
15910
15911(define_expand "strset_singleop"
15912  [(parallel [(set (match_operand 1 "memory_operand" "")
15913		   (match_operand 2 "register_operand" ""))
15914	      (set (match_operand 0 "register_operand" "")
15915		   (match_operand 3 "" ""))])]
15916  ""
15917  "ix86_current_function_needs_cld = 1;")
15918
15919(define_insn "*strsetdi_rex_1"
15920  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15921	(match_operand:DI 2 "register_operand" "a"))
15922   (set (match_operand:DI 0 "register_operand" "=D")
15923	(plus:DI (match_dup 1)
15924		 (const_int 8)))]
15925  "TARGET_64BIT
15926   && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15927  "stosq"
15928  [(set_attr "type" "str")
15929   (set_attr "memory" "store")
15930   (set_attr "mode" "DI")])
15931
15932(define_insn "*strsetsi_1"
15933  [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15934	(match_operand:SI 2 "register_operand" "a"))
15935   (set (match_operand:P 0 "register_operand" "=D")
15936	(plus:P (match_dup 1)
15937		(const_int 4)))]
15938  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15939  "stos{l|d}"
15940  [(set_attr "type" "str")
15941   (set_attr "memory" "store")
15942   (set_attr "mode" "SI")])
15943
15944(define_insn "*strsethi_1"
15945  [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15946	(match_operand:HI 2 "register_operand" "a"))
15947   (set (match_operand:P 0 "register_operand" "=D")
15948	(plus:P (match_dup 1)
15949		(const_int 2)))]
15950  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15951  "stosw"
15952  [(set_attr "type" "str")
15953   (set_attr "memory" "store")
15954   (set_attr "mode" "HI")])
15955
15956(define_insn "*strsetqi_1"
15957  [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15958	(match_operand:QI 2 "register_operand" "a"))
15959   (set (match_operand:P 0 "register_operand" "=D")
15960	(plus:P (match_dup 1)
15961		(const_int 1)))]
15962  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15963  "stosb"
15964  [(set_attr "type" "str")
15965   (set_attr "memory" "store")
15966   (set (attr "prefix_rex")
15967	(if_then_else
15968	  (match_test "<P:MODE>mode == DImode")
15969	  (const_string "0")
15970	  (const_string "*")))
15971   (set_attr "mode" "QI")])
15972
15973(define_expand "rep_stos"
15974  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15975	      (set (match_operand 0 "register_operand" "")
15976		   (match_operand 4 "" ""))
15977	      (set (match_operand 2 "memory_operand" "") (const_int 0))
15978	      (use (match_operand 3 "register_operand" ""))
15979	      (use (match_dup 1))])]
15980  ""
15981  "ix86_current_function_needs_cld = 1;")
15982
15983(define_insn "*rep_stosdi_rex64"
15984  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15985   (set (match_operand:DI 0 "register_operand" "=D")
15986        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15987			    (const_int 3))
15988		 (match_operand:DI 3 "register_operand" "0")))
15989   (set (mem:BLK (match_dup 3))
15990	(const_int 0))
15991   (use (match_operand:DI 2 "register_operand" "a"))
15992   (use (match_dup 4))]
15993  "TARGET_64BIT
15994   && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15995  "rep{%;} stosq"
15996  [(set_attr "type" "str")
15997   (set_attr "prefix_rep" "1")
15998   (set_attr "memory" "store")
15999   (set_attr "mode" "DI")])
16000
16001(define_insn "*rep_stossi"
16002  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16003   (set (match_operand:P 0 "register_operand" "=D")
16004        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16005			  (const_int 2))
16006		 (match_operand:P 3 "register_operand" "0")))
16007   (set (mem:BLK (match_dup 3))
16008	(const_int 0))
16009   (use (match_operand:SI 2 "register_operand" "a"))
16010   (use (match_dup 4))]
16011  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012  "rep{%;} stos{l|d}"
16013  [(set_attr "type" "str")
16014   (set_attr "prefix_rep" "1")
16015   (set_attr "memory" "store")
16016   (set_attr "mode" "SI")])
16017
16018(define_insn "*rep_stosqi"
16019  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16020   (set (match_operand:P 0 "register_operand" "=D")
16021        (plus:P (match_operand:P 3 "register_operand" "0")
16022		(match_operand:P 4 "register_operand" "1")))
16023   (set (mem:BLK (match_dup 3))
16024	(const_int 0))
16025   (use (match_operand:QI 2 "register_operand" "a"))
16026   (use (match_dup 4))]
16027  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16028  "rep{%;} stosb"
16029  [(set_attr "type" "str")
16030   (set_attr "prefix_rep" "1")
16031   (set_attr "memory" "store")
16032   (set (attr "prefix_rex")
16033	(if_then_else
16034	  (match_test "<P:MODE>mode == DImode")
16035	  (const_string "0")
16036	  (const_string "*")))
16037   (set_attr "mode" "QI")])
16038
16039(define_expand "cmpstrnsi"
16040  [(set (match_operand:SI 0 "register_operand" "")
16041	(compare:SI (match_operand:BLK 1 "general_operand" "")
16042		    (match_operand:BLK 2 "general_operand" "")))
16043   (use (match_operand 3 "general_operand" ""))
16044   (use (match_operand 4 "immediate_operand" ""))]
16045  ""
16046{
16047  rtx addr1, addr2, out, outlow, count, countreg, align;
16048
16049  if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16050    FAIL;
16051
16052  /* Can't use this if the user has appropriated ecx, esi or edi.  */
16053  if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16054    FAIL;
16055
16056  out = operands[0];
16057  if (!REG_P (out))
16058    out = gen_reg_rtx (SImode);
16059
16060  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16061  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16062  if (addr1 != XEXP (operands[1], 0))
16063    operands[1] = replace_equiv_address_nv (operands[1], addr1);
16064  if (addr2 != XEXP (operands[2], 0))
16065    operands[2] = replace_equiv_address_nv (operands[2], addr2);
16066
16067  count = operands[3];
16068  countreg = ix86_zero_extend_to_Pmode (count);
16069
16070  /* %%% Iff we are testing strict equality, we can use known alignment
16071     to good advantage.  This may be possible with combine, particularly
16072     once cc0 is dead.  */
16073  align = operands[4];
16074
16075  if (CONST_INT_P (count))
16076    {
16077      if (INTVAL (count) == 0)
16078	{
16079	  emit_move_insn (operands[0], const0_rtx);
16080	  DONE;
16081	}
16082      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16083				     operands[1], operands[2]));
16084    }
16085  else
16086    {
16087      rtx (*gen_cmp) (rtx, rtx);
16088
16089      gen_cmp = (TARGET_64BIT
16090		 ? gen_cmpdi_1 : gen_cmpsi_1);
16091
16092      emit_insn (gen_cmp (countreg, countreg));
16093      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16094				  operands[1], operands[2]));
16095    }
16096
16097  outlow = gen_lowpart (QImode, out);
16098  emit_insn (gen_cmpintqi (outlow));
16099  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16100
16101  if (operands[0] != out)
16102    emit_move_insn (operands[0], out);
16103
16104  DONE;
16105})
16106
16107;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16108
16109(define_expand "cmpintqi"
16110  [(set (match_dup 1)
16111	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16112   (set (match_dup 2)
16113	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16114   (parallel [(set (match_operand:QI 0 "register_operand" "")
16115		   (minus:QI (match_dup 1)
16116			     (match_dup 2)))
16117	      (clobber (reg:CC FLAGS_REG))])]
16118  ""
16119{
16120  operands[1] = gen_reg_rtx (QImode);
16121  operands[2] = gen_reg_rtx (QImode);
16122})
16123
16124;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16125;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16126
16127(define_expand "cmpstrnqi_nz_1"
16128  [(parallel [(set (reg:CC FLAGS_REG)
16129		   (compare:CC (match_operand 4 "memory_operand" "")
16130			       (match_operand 5 "memory_operand" "")))
16131	      (use (match_operand 2 "register_operand" ""))
16132	      (use (match_operand:SI 3 "immediate_operand" ""))
16133	      (clobber (match_operand 0 "register_operand" ""))
16134	      (clobber (match_operand 1 "register_operand" ""))
16135	      (clobber (match_dup 2))])]
16136  ""
16137  "ix86_current_function_needs_cld = 1;")
16138
16139(define_insn "*cmpstrnqi_nz_1"
16140  [(set (reg:CC FLAGS_REG)
16141	(compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16142		    (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16143   (use (match_operand:P 6 "register_operand" "2"))
16144   (use (match_operand:SI 3 "immediate_operand" "i"))
16145   (clobber (match_operand:P 0 "register_operand" "=S"))
16146   (clobber (match_operand:P 1 "register_operand" "=D"))
16147   (clobber (match_operand:P 2 "register_operand" "=c"))]
16148  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16149  "repz{%;} cmpsb"
16150  [(set_attr "type" "str")
16151   (set_attr "mode" "QI")
16152   (set (attr "prefix_rex")
16153	(if_then_else
16154	  (match_test "<P:MODE>mode == DImode")
16155	  (const_string "0")
16156	  (const_string "*")))
16157   (set_attr "prefix_rep" "1")])
16158
16159;; The same, but the count is not known to not be zero.
16160
16161(define_expand "cmpstrnqi_1"
16162  [(parallel [(set (reg:CC FLAGS_REG)
16163		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
16164				     (const_int 0))
16165		  (compare:CC (match_operand 4 "memory_operand" "")
16166			      (match_operand 5 "memory_operand" ""))
16167		  (const_int 0)))
16168	      (use (match_operand:SI 3 "immediate_operand" ""))
16169	      (use (reg:CC FLAGS_REG))
16170	      (clobber (match_operand 0 "register_operand" ""))
16171	      (clobber (match_operand 1 "register_operand" ""))
16172	      (clobber (match_dup 2))])]
16173  ""
16174  "ix86_current_function_needs_cld = 1;")
16175
16176(define_insn "*cmpstrnqi_1"
16177  [(set (reg:CC FLAGS_REG)
16178	(if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16179			     (const_int 0))
16180	  (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16181		      (mem:BLK (match_operand:P 5 "register_operand" "1")))
16182	  (const_int 0)))
16183   (use (match_operand:SI 3 "immediate_operand" "i"))
16184   (use (reg:CC FLAGS_REG))
16185   (clobber (match_operand:P 0 "register_operand" "=S"))
16186   (clobber (match_operand:P 1 "register_operand" "=D"))
16187   (clobber (match_operand:P 2 "register_operand" "=c"))]
16188  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16189  "repz{%;} cmpsb"
16190  [(set_attr "type" "str")
16191   (set_attr "mode" "QI")
16192   (set (attr "prefix_rex")
16193	(if_then_else
16194	  (match_test "<P:MODE>mode == DImode")
16195	  (const_string "0")
16196	  (const_string "*")))
16197   (set_attr "prefix_rep" "1")])
16198
16199(define_expand "strlen<mode>"
16200  [(set (match_operand:P 0 "register_operand" "")
16201	(unspec:P [(match_operand:BLK 1 "general_operand" "")
16202		   (match_operand:QI 2 "immediate_operand" "")
16203		   (match_operand 3 "immediate_operand" "")]
16204		  UNSPEC_SCAS))]
16205  ""
16206{
16207 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16208   DONE;
16209 else
16210   FAIL;
16211})
16212
16213(define_expand "strlenqi_1"
16214  [(parallel [(set (match_operand 0 "register_operand" "")
16215		   (match_operand 2 "" ""))
16216	      (clobber (match_operand 1 "register_operand" ""))
16217	      (clobber (reg:CC FLAGS_REG))])]
16218  ""
16219  "ix86_current_function_needs_cld = 1;")
16220
16221(define_insn "*strlenqi_1"
16222  [(set (match_operand:P 0 "register_operand" "=&c")
16223	(unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16224		   (match_operand:QI 2 "register_operand" "a")
16225		   (match_operand:P 3 "immediate_operand" "i")
16226		   (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16227   (clobber (match_operand:P 1 "register_operand" "=D"))
16228   (clobber (reg:CC FLAGS_REG))]
16229  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16230  "repnz{%;} scasb"
16231  [(set_attr "type" "str")
16232   (set_attr "mode" "QI")
16233   (set (attr "prefix_rex")
16234	(if_then_else
16235	  (match_test "<P:MODE>mode == DImode")
16236	  (const_string "0")
16237	  (const_string "*")))
16238   (set_attr "prefix_rep" "1")])
16239
16240;; Peephole optimizations to clean up after cmpstrn*.  This should be
16241;; handled in combine, but it is not currently up to the task.
16242;; When used for their truth value, the cmpstrn* expanders generate
16243;; code like this:
16244;;
16245;;   repz cmpsb
16246;;   seta 	%al
16247;;   setb 	%dl
16248;;   cmpb 	%al, %dl
16249;;   jcc	label
16250;;
16251;; The intermediate three instructions are unnecessary.
16252
16253;; This one handles cmpstrn*_nz_1...
16254(define_peephole2
16255  [(parallel[
16256     (set (reg:CC FLAGS_REG)
16257	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16258		      (mem:BLK (match_operand 5 "register_operand" ""))))
16259     (use (match_operand 6 "register_operand" ""))
16260     (use (match_operand:SI 3 "immediate_operand" ""))
16261     (clobber (match_operand 0 "register_operand" ""))
16262     (clobber (match_operand 1 "register_operand" ""))
16263     (clobber (match_operand 2 "register_operand" ""))])
16264   (set (match_operand:QI 7 "register_operand" "")
16265	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16266   (set (match_operand:QI 8 "register_operand" "")
16267	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16268   (set (reg FLAGS_REG)
16269	(compare (match_dup 7) (match_dup 8)))
16270  ]
16271  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16272  [(parallel[
16273     (set (reg:CC FLAGS_REG)
16274	  (compare:CC (mem:BLK (match_dup 4))
16275		      (mem:BLK (match_dup 5))))
16276     (use (match_dup 6))
16277     (use (match_dup 3))
16278     (clobber (match_dup 0))
16279     (clobber (match_dup 1))
16280     (clobber (match_dup 2))])])
16281
16282;; ...and this one handles cmpstrn*_1.
16283(define_peephole2
16284  [(parallel[
16285     (set (reg:CC FLAGS_REG)
16286	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16287			       (const_int 0))
16288	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16289		        (mem:BLK (match_operand 5 "register_operand" "")))
16290	    (const_int 0)))
16291     (use (match_operand:SI 3 "immediate_operand" ""))
16292     (use (reg:CC FLAGS_REG))
16293     (clobber (match_operand 0 "register_operand" ""))
16294     (clobber (match_operand 1 "register_operand" ""))
16295     (clobber (match_operand 2 "register_operand" ""))])
16296   (set (match_operand:QI 7 "register_operand" "")
16297	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16298   (set (match_operand:QI 8 "register_operand" "")
16299	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16300   (set (reg FLAGS_REG)
16301	(compare (match_dup 7) (match_dup 8)))
16302  ]
16303  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16304  [(parallel[
16305     (set (reg:CC FLAGS_REG)
16306	  (if_then_else:CC (ne (match_dup 6)
16307			       (const_int 0))
16308	    (compare:CC (mem:BLK (match_dup 4))
16309			(mem:BLK (match_dup 5)))
16310	    (const_int 0)))
16311     (use (match_dup 3))
16312     (use (reg:CC FLAGS_REG))
16313     (clobber (match_dup 0))
16314     (clobber (match_dup 1))
16315     (clobber (match_dup 2))])])
16316
16317;; Conditional move instructions.
16318
16319(define_expand "mov<mode>cc"
16320  [(set (match_operand:SWIM 0 "register_operand" "")
16321	(if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16322			   (match_operand:SWIM 2 "<general_operand>" "")
16323			   (match_operand:SWIM 3 "<general_operand>" "")))]
16324  ""
16325  "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16326
16327;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16328;; the register first winds up with `sbbl $0,reg', which is also weird.
16329;; So just document what we're doing explicitly.
16330
16331(define_expand "x86_mov<mode>cc_0_m1"
16332  [(parallel
16333    [(set (match_operand:SWI48 0 "register_operand" "")
16334	  (if_then_else:SWI48
16335	    (match_operator:SWI48 2 "ix86_carry_flag_operator"
16336	     [(match_operand 1 "flags_reg_operand" "")
16337	      (const_int 0)])
16338	    (const_int -1)
16339	    (const_int 0)))
16340     (clobber (reg:CC FLAGS_REG))])])
16341
16342(define_insn "*x86_mov<mode>cc_0_m1"
16343  [(set (match_operand:SWI48 0 "register_operand" "=r")
16344	(if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16345			     [(reg FLAGS_REG) (const_int 0)])
16346	  (const_int -1)
16347	  (const_int 0)))
16348   (clobber (reg:CC FLAGS_REG))]
16349  ""
16350  "sbb{<imodesuffix>}\t%0, %0"
16351  ; Since we don't have the proper number of operands for an alu insn,
16352  ; fill in all the blanks.
16353  [(set_attr "type" "alu")
16354   (set_attr "use_carry" "1")
16355   (set_attr "pent_pair" "pu")
16356   (set_attr "memory" "none")
16357   (set_attr "imm_disp" "false")
16358   (set_attr "mode" "<MODE>")
16359   (set_attr "length_immediate" "0")])
16360
16361(define_insn "*x86_mov<mode>cc_0_m1_se"
16362  [(set (match_operand:SWI48 0 "register_operand" "=r")
16363	(sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16364			     [(reg FLAGS_REG) (const_int 0)])
16365			    (const_int 1)
16366			    (const_int 0)))
16367   (clobber (reg:CC FLAGS_REG))]
16368  ""
16369  "sbb{<imodesuffix>}\t%0, %0"
16370  [(set_attr "type" "alu")
16371   (set_attr "use_carry" "1")
16372   (set_attr "pent_pair" "pu")
16373   (set_attr "memory" "none")
16374   (set_attr "imm_disp" "false")
16375   (set_attr "mode" "<MODE>")
16376   (set_attr "length_immediate" "0")])
16377
16378(define_insn "*x86_mov<mode>cc_0_m1_neg"
16379  [(set (match_operand:SWI48 0 "register_operand" "=r")
16380	(neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16381		    [(reg FLAGS_REG) (const_int 0)])))
16382   (clobber (reg:CC FLAGS_REG))]
16383  ""
16384  "sbb{<imodesuffix>}\t%0, %0"
16385  [(set_attr "type" "alu")
16386   (set_attr "use_carry" "1")
16387   (set_attr "pent_pair" "pu")
16388   (set_attr "memory" "none")
16389   (set_attr "imm_disp" "false")
16390   (set_attr "mode" "<MODE>")
16391   (set_attr "length_immediate" "0")])
16392
16393(define_insn "*mov<mode>cc_noc"
16394  [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16395	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16396			       [(reg FLAGS_REG) (const_int 0)])
16397	  (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16398	  (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16399  "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16400  "@
16401   cmov%O2%C1\t{%2, %0|%0, %2}
16402   cmov%O2%c1\t{%3, %0|%0, %3}"
16403  [(set_attr "type" "icmov")
16404   (set_attr "mode" "<MODE>")])
16405
16406(define_insn "*movqicc_noc"
16407  [(set (match_operand:QI 0 "register_operand" "=r,r")
16408	(if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16409			   [(reg FLAGS_REG) (const_int 0)])
16410		      (match_operand:QI 2 "register_operand" "r,0")
16411		      (match_operand:QI 3 "register_operand" "0,r")))]
16412  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16413  "#"
16414  [(set_attr "type" "icmov")
16415   (set_attr "mode" "QI")])
16416
16417(define_split
16418  [(set (match_operand 0 "register_operand")
16419	(if_then_else (match_operator 1 "ix86_comparison_operator"
16420			[(reg FLAGS_REG) (const_int 0)])
16421		      (match_operand 2 "register_operand")
16422		      (match_operand 3 "register_operand")))]
16423  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16424   && (GET_MODE (operands[0]) == QImode
16425       || GET_MODE (operands[0]) == HImode)
16426   && reload_completed"
16427  [(set (match_dup 0)
16428	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16429{
16430  operands[0] = gen_lowpart (SImode, operands[0]);
16431  operands[2] = gen_lowpart (SImode, operands[2]);
16432  operands[3] = gen_lowpart (SImode, operands[3]);
16433})
16434
16435(define_expand "mov<mode>cc"
16436  [(set (match_operand:X87MODEF 0 "register_operand" "")
16437	(if_then_else:X87MODEF
16438	  (match_operand 1 "ix86_fp_comparison_operator" "")
16439	  (match_operand:X87MODEF 2 "register_operand" "")
16440	  (match_operand:X87MODEF 3 "register_operand" "")))]
16441  "(TARGET_80387 && TARGET_CMOVE)
16442   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16443  "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16444
16445(define_insn "*movxfcc_1"
16446  [(set (match_operand:XF 0 "register_operand" "=f,f")
16447	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16448				[(reg FLAGS_REG) (const_int 0)])
16449		      (match_operand:XF 2 "register_operand" "f,0")
16450		      (match_operand:XF 3 "register_operand" "0,f")))]
16451  "TARGET_80387 && TARGET_CMOVE"
16452  "@
16453   fcmov%F1\t{%2, %0|%0, %2}
16454   fcmov%f1\t{%3, %0|%0, %3}"
16455  [(set_attr "type" "fcmov")
16456   (set_attr "mode" "XF")])
16457
16458(define_insn "*movdfcc_1_rex64"
16459  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16460	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16461				[(reg FLAGS_REG) (const_int 0)])
16462		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16463		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16464  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16465   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16466  "@
16467   fcmov%F1\t{%2, %0|%0, %2}
16468   fcmov%f1\t{%3, %0|%0, %3}
16469   cmov%O2%C1\t{%2, %0|%0, %2}
16470   cmov%O2%c1\t{%3, %0|%0, %3}"
16471  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16472   (set_attr "mode" "DF,DF,DI,DI")])
16473
16474(define_insn "*movdfcc_1"
16475  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16476	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16477				[(reg FLAGS_REG) (const_int 0)])
16478		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16479		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16480  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16481   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16482  "@
16483   fcmov%F1\t{%2, %0|%0, %2}
16484   fcmov%f1\t{%3, %0|%0, %3}
16485   #
16486   #"
16487  [(set_attr "type" "fcmov,fcmov,multi,multi")
16488   (set_attr "mode" "DF,DF,DI,DI")])
16489
16490(define_split
16491  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16492	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16493				[(reg FLAGS_REG) (const_int 0)])
16494		      (match_operand:DF 2 "nonimmediate_operand")
16495		      (match_operand:DF 3 "nonimmediate_operand")))]
16496  "!TARGET_64BIT && reload_completed"
16497  [(set (match_dup 2)
16498	(if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16499   (set (match_dup 3)
16500	(if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16501{
16502  split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16503  split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16504})
16505
16506(define_insn "*movsfcc_1_387"
16507  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16508	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16509				[(reg FLAGS_REG) (const_int 0)])
16510		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16511		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16512  "TARGET_80387 && TARGET_CMOVE
16513   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16514  "@
16515   fcmov%F1\t{%2, %0|%0, %2}
16516   fcmov%f1\t{%3, %0|%0, %3}
16517   cmov%O2%C1\t{%2, %0|%0, %2}
16518   cmov%O2%c1\t{%3, %0|%0, %3}"
16519  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16520   (set_attr "mode" "SF,SF,SI,SI")])
16521
16522;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16523;; the scalar versions to have only XMM registers as operands.
16524
16525;; XOP conditional move
16526(define_insn "*xop_pcmov_<mode>"
16527  [(set (match_operand:MODEF 0 "register_operand" "=x")
16528	(if_then_else:MODEF
16529	  (match_operand:MODEF 1 "register_operand" "x")
16530	  (match_operand:MODEF 2 "register_operand" "x")
16531	  (match_operand:MODEF 3 "register_operand" "x")))]
16532  "TARGET_XOP"
16533  "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16534  [(set_attr "type" "sse4arg")])
16535
16536;; These versions of the min/max patterns are intentionally ignorant of
16537;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16538;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16539;; are undefined in this condition, we're certain this is correct.
16540
16541(define_insn "<code><mode>3"
16542  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16543	(smaxmin:MODEF
16544	  (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16545	  (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16546  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16547  "@
16548   <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16549   v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16550  [(set_attr "isa" "noavx,avx")
16551   (set_attr "prefix" "orig,vex")
16552   (set_attr "type" "sseadd")
16553   (set_attr "mode" "<MODE>")])
16554
16555;; These versions of the min/max patterns implement exactly the operations
16556;;   min = (op1 < op2 ? op1 : op2)
16557;;   max = (!(op1 < op2) ? op1 : op2)
16558;; Their operands are not commutative, and thus they may be used in the
16559;; presence of -0.0 and NaN.
16560
16561(define_insn "*ieee_smin<mode>3"
16562  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16563	(unspec:MODEF
16564	  [(match_operand:MODEF 1 "register_operand" "0,x")
16565	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16566	 UNSPEC_IEEE_MIN))]
16567  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16568  "@
16569   min<ssemodesuffix>\t{%2, %0|%0, %2}
16570   vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16571  [(set_attr "isa" "noavx,avx")
16572   (set_attr "prefix" "orig,vex")
16573   (set_attr "type" "sseadd")
16574   (set_attr "mode" "<MODE>")])
16575
16576(define_insn "*ieee_smax<mode>3"
16577  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16578	(unspec:MODEF
16579	  [(match_operand:MODEF 1 "register_operand" "0,x")
16580	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16581	 UNSPEC_IEEE_MAX))]
16582  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16583  "@
16584   max<ssemodesuffix>\t{%2, %0|%0, %2}
16585   vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16586  [(set_attr "isa" "noavx,avx")
16587   (set_attr "prefix" "orig,vex")
16588   (set_attr "type" "sseadd")
16589   (set_attr "mode" "<MODE>")])
16590
16591;; Make two stack loads independent:
16592;;   fld aa              fld aa
16593;;   fld %st(0)     ->   fld bb
16594;;   fmul bb             fmul %st(1), %st
16595;;
16596;; Actually we only match the last two instructions for simplicity.
16597(define_peephole2
16598  [(set (match_operand 0 "fp_register_operand" "")
16599	(match_operand 1 "fp_register_operand" ""))
16600   (set (match_dup 0)
16601	(match_operator 2 "binary_fp_operator"
16602	   [(match_dup 0)
16603	    (match_operand 3 "memory_operand" "")]))]
16604  "REGNO (operands[0]) != REGNO (operands[1])"
16605  [(set (match_dup 0) (match_dup 3))
16606   (set (match_dup 0) (match_dup 4))]
16607
16608  ;; The % modifier is not operational anymore in peephole2's, so we have to
16609  ;; swap the operands manually in the case of addition and multiplication.
16610{
16611  rtx op0, op1;
16612
16613  if (COMMUTATIVE_ARITH_P (operands[2]))
16614    op0 = operands[0], op1 = operands[1];
16615  else
16616    op0 = operands[1], op1 = operands[0];
16617
16618  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16619				GET_MODE (operands[2]),
16620				op0, op1);
16621})
16622
16623;; Conditional addition patterns
16624(define_expand "add<mode>cc"
16625  [(match_operand:SWI 0 "register_operand" "")
16626   (match_operand 1 "ordered_comparison_operator" "")
16627   (match_operand:SWI 2 "register_operand" "")
16628   (match_operand:SWI 3 "const_int_operand" "")]
16629  ""
16630  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16631
16632;; Misc patterns (?)
16633
16634;; This pattern exists to put a dependency on all ebp-based memory accesses.
16635;; Otherwise there will be nothing to keep
16636;;
16637;; [(set (reg ebp) (reg esp))]
16638;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16639;;  (clobber (eflags)]
16640;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16641;;
16642;; in proper program order.
16643
16644(define_insn "pro_epilogue_adjust_stack_<mode>_add"
16645  [(set (match_operand:P 0 "register_operand" "=r,r")
16646	(plus:P (match_operand:P 1 "register_operand" "0,r")
16647	        (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16648   (clobber (reg:CC FLAGS_REG))
16649   (clobber (mem:BLK (scratch)))]
16650  ""
16651{
16652  switch (get_attr_type (insn))
16653    {
16654    case TYPE_IMOV:
16655      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16656
16657    case TYPE_ALU:
16658      gcc_assert (rtx_equal_p (operands[0], operands[1]));
16659      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16660	return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16661
16662      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16663
16664    default:
16665      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16666      return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16667    }
16668}
16669  [(set (attr "type")
16670	(cond [(and (eq_attr "alternative" "0")
16671		    (not (match_test "TARGET_OPT_AGU")))
16672		 (const_string "alu")
16673	       (match_operand:<MODE> 2 "const0_operand" "")
16674		 (const_string "imov")
16675	      ]
16676	      (const_string "lea")))
16677   (set (attr "length_immediate")
16678	(cond [(eq_attr "type" "imov")
16679		 (const_string "0")
16680	       (and (eq_attr "type" "alu")
16681		    (match_operand 2 "const128_operand" ""))
16682		 (const_string "1")
16683	      ]
16684	      (const_string "*")))
16685   (set_attr "mode" "<MODE>")])
16686
16687(define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16688  [(set (match_operand:P 0 "register_operand" "=r")
16689	(minus:P (match_operand:P 1 "register_operand" "0")
16690		 (match_operand:P 2 "register_operand" "r")))
16691   (clobber (reg:CC FLAGS_REG))
16692   (clobber (mem:BLK (scratch)))]
16693  ""
16694  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16695  [(set_attr "type" "alu")
16696   (set_attr "mode" "<MODE>")])
16697
16698(define_insn "allocate_stack_worker_probe_<mode>"
16699  [(set (match_operand:P 0 "register_operand" "=a")
16700	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16701			    UNSPECV_STACK_PROBE))
16702   (clobber (reg:CC FLAGS_REG))]
16703  "ix86_target_stack_probe ()"
16704  "call\t___chkstk_ms"
16705  [(set_attr "type" "multi")
16706   (set_attr "length" "5")])
16707
16708(define_expand "allocate_stack"
16709  [(match_operand 0 "register_operand" "")
16710   (match_operand 1 "general_operand" "")]
16711  "ix86_target_stack_probe ()"
16712{
16713  rtx x;
16714
16715#ifndef CHECK_STACK_LIMIT
16716#define CHECK_STACK_LIMIT 0
16717#endif
16718
16719  if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16720      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16721    {
16722      x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16723			       stack_pointer_rtx, 0, OPTAB_DIRECT);
16724      if (x != stack_pointer_rtx)
16725	emit_move_insn (stack_pointer_rtx, x);
16726    }
16727  else
16728    {
16729      x = copy_to_mode_reg (Pmode, operands[1]);
16730      if (TARGET_64BIT)
16731        emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16732      else
16733        emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16734      x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16735			       stack_pointer_rtx, 0, OPTAB_DIRECT);
16736      if (x != stack_pointer_rtx)
16737	emit_move_insn (stack_pointer_rtx, x);
16738    }
16739
16740  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16741  DONE;
16742})
16743
16744;; Use IOR for stack probes, this is shorter.
16745(define_expand "probe_stack"
16746  [(match_operand 0 "memory_operand" "")]
16747  ""
16748{
16749  rtx (*gen_ior3) (rtx, rtx, rtx);
16750
16751  gen_ior3 = (GET_MODE (operands[0]) == DImode
16752	      ? gen_iordi3 : gen_iorsi3);
16753
16754  emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16755  DONE;
16756})
16757
16758(define_insn "adjust_stack_and_probe<mode>"
16759  [(set (match_operand:P 0 "register_operand" "=r")
16760	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16761			    UNSPECV_PROBE_STACK_RANGE))
16762   (set (reg:P SP_REG)
16763        (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16764   (clobber (reg:CC FLAGS_REG))
16765   (clobber (mem:BLK (scratch)))]
16766  ""
16767  "* return output_adjust_stack_and_probe (operands[0]);"
16768  [(set_attr "type" "multi")])
16769
16770(define_insn "probe_stack_range<mode>"
16771  [(set (match_operand:P 0 "register_operand" "=r")
16772	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16773			    (match_operand:P 2 "const_int_operand" "n")]
16774			    UNSPECV_PROBE_STACK_RANGE))
16775   (clobber (reg:CC FLAGS_REG))]
16776  ""
16777  "* return output_probe_stack_range (operands[0], operands[2]);"
16778  [(set_attr "type" "multi")])
16779
16780(define_expand "builtin_setjmp_receiver"
16781  [(label_ref (match_operand 0 "" ""))]
16782  "!TARGET_64BIT && flag_pic"
16783{
16784#if TARGET_MACHO
16785  if (TARGET_MACHO)
16786    {
16787      rtx xops[3];
16788      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16789      rtx label_rtx = gen_label_rtx ();
16790      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16791      xops[0] = xops[1] = picreg;
16792      xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16793      ix86_expand_binary_operator (MINUS, SImode, xops);
16794    }
16795  else
16796#endif
16797    emit_insn (gen_set_got (pic_offset_table_rtx));
16798  DONE;
16799})
16800
16801;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16802
16803(define_split
16804  [(set (match_operand 0 "register_operand" "")
16805	(match_operator 3 "promotable_binary_operator"
16806	   [(match_operand 1 "register_operand" "")
16807	    (match_operand 2 "aligned_operand" "")]))
16808   (clobber (reg:CC FLAGS_REG))]
16809  "! TARGET_PARTIAL_REG_STALL && reload_completed
16810   && ((GET_MODE (operands[0]) == HImode
16811	&& ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16812            /* ??? next two lines just !satisfies_constraint_K (...) */
16813	    || !CONST_INT_P (operands[2])
16814	    || satisfies_constraint_K (operands[2])))
16815       || (GET_MODE (operands[0]) == QImode
16816	   && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16817  [(parallel [(set (match_dup 0)
16818		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16819	      (clobber (reg:CC FLAGS_REG))])]
16820{
16821  operands[0] = gen_lowpart (SImode, operands[0]);
16822  operands[1] = gen_lowpart (SImode, operands[1]);
16823  if (GET_CODE (operands[3]) != ASHIFT)
16824    operands[2] = gen_lowpart (SImode, operands[2]);
16825  PUT_MODE (operands[3], SImode);
16826})
16827
16828; Promote the QImode tests, as i386 has encoding of the AND
16829; instruction with 32-bit sign-extended immediate and thus the
16830; instruction size is unchanged, except in the %eax case for
16831; which it is increased by one byte, hence the ! optimize_size.
16832(define_split
16833  [(set (match_operand 0 "flags_reg_operand" "")
16834	(match_operator 2 "compare_operator"
16835	  [(and (match_operand 3 "aligned_operand" "")
16836		(match_operand 4 "const_int_operand" ""))
16837	   (const_int 0)]))
16838   (set (match_operand 1 "register_operand" "")
16839	(and (match_dup 3) (match_dup 4)))]
16840  "! TARGET_PARTIAL_REG_STALL && reload_completed
16841   && optimize_insn_for_speed_p ()
16842   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16843       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16844   /* Ensure that the operand will remain sign-extended immediate.  */
16845   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16846  [(parallel [(set (match_dup 0)
16847		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16848			            (const_int 0)]))
16849	      (set (match_dup 1)
16850		   (and:SI (match_dup 3) (match_dup 4)))])]
16851{
16852  operands[4]
16853    = gen_int_mode (INTVAL (operands[4])
16854		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16855  operands[1] = gen_lowpart (SImode, operands[1]);
16856  operands[3] = gen_lowpart (SImode, operands[3]);
16857})
16858
16859; Don't promote the QImode tests, as i386 doesn't have encoding of
16860; the TEST instruction with 32-bit sign-extended immediate and thus
16861; the instruction size would at least double, which is not what we
16862; want even with ! optimize_size.
16863(define_split
16864  [(set (match_operand 0 "flags_reg_operand" "")
16865	(match_operator 1 "compare_operator"
16866	  [(and (match_operand:HI 2 "aligned_operand" "")
16867		(match_operand:HI 3 "const_int_operand" ""))
16868	   (const_int 0)]))]
16869  "! TARGET_PARTIAL_REG_STALL && reload_completed
16870   && ! TARGET_FAST_PREFIX
16871   && optimize_insn_for_speed_p ()
16872   /* Ensure that the operand will remain sign-extended immediate.  */
16873   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16874  [(set (match_dup 0)
16875	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16876		         (const_int 0)]))]
16877{
16878  operands[3]
16879    = gen_int_mode (INTVAL (operands[3])
16880		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16881  operands[2] = gen_lowpart (SImode, operands[2]);
16882})
16883
16884(define_split
16885  [(set (match_operand 0 "register_operand" "")
16886	(neg (match_operand 1 "register_operand" "")))
16887   (clobber (reg:CC FLAGS_REG))]
16888  "! TARGET_PARTIAL_REG_STALL && reload_completed
16889   && (GET_MODE (operands[0]) == HImode
16890       || (GET_MODE (operands[0]) == QImode
16891	   && (TARGET_PROMOTE_QImode
16892	       || optimize_insn_for_size_p ())))"
16893  [(parallel [(set (match_dup 0)
16894		   (neg:SI (match_dup 1)))
16895	      (clobber (reg:CC FLAGS_REG))])]
16896{
16897  operands[0] = gen_lowpart (SImode, operands[0]);
16898  operands[1] = gen_lowpart (SImode, operands[1]);
16899})
16900
16901(define_split
16902  [(set (match_operand 0 "register_operand" "")
16903	(not (match_operand 1 "register_operand" "")))]
16904  "! TARGET_PARTIAL_REG_STALL && reload_completed
16905   && (GET_MODE (operands[0]) == HImode
16906       || (GET_MODE (operands[0]) == QImode
16907	   && (TARGET_PROMOTE_QImode
16908	       || optimize_insn_for_size_p ())))"
16909  [(set (match_dup 0)
16910	(not:SI (match_dup 1)))]
16911{
16912  operands[0] = gen_lowpart (SImode, operands[0]);
16913  operands[1] = gen_lowpart (SImode, operands[1]);
16914})
16915
16916;; RTL Peephole optimizations, run before sched2.  These primarily look to
16917;; transform a complex memory operation into two memory to register operations.
16918
16919;; Don't push memory operands
16920(define_peephole2
16921  [(set (match_operand:SWI 0 "push_operand" "")
16922	(match_operand:SWI 1 "memory_operand" ""))
16923   (match_scratch:SWI 2 "<r>")]
16924  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16925   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16926  [(set (match_dup 2) (match_dup 1))
16927   (set (match_dup 0) (match_dup 2))])
16928
16929;; We need to handle SFmode only, because DFmode and XFmode are split to
16930;; SImode pushes.
16931(define_peephole2
16932  [(set (match_operand:SF 0 "push_operand" "")
16933	(match_operand:SF 1 "memory_operand" ""))
16934   (match_scratch:SF 2 "r")]
16935  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16936   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16937  [(set (match_dup 2) (match_dup 1))
16938   (set (match_dup 0) (match_dup 2))])
16939
16940;; Don't move an immediate directly to memory when the instruction
16941;; gets too big.
16942(define_peephole2
16943  [(match_scratch:SWI124 1 "<r>")
16944   (set (match_operand:SWI124 0 "memory_operand" "")
16945        (const_int 0))]
16946  "optimize_insn_for_speed_p ()
16947   && !TARGET_USE_MOV0
16948   && TARGET_SPLIT_LONG_MOVES
16949   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16950   && peep2_regno_dead_p (0, FLAGS_REG)"
16951  [(parallel [(set (match_dup 2) (const_int 0))
16952	      (clobber (reg:CC FLAGS_REG))])
16953   (set (match_dup 0) (match_dup 1))]
16954  "operands[2] = gen_lowpart (SImode, operands[1]);")
16955
16956(define_peephole2
16957  [(match_scratch:SWI124 2 "<r>")
16958   (set (match_operand:SWI124 0 "memory_operand" "")
16959        (match_operand:SWI124 1 "immediate_operand" ""))]
16960  "optimize_insn_for_speed_p ()
16961   && TARGET_SPLIT_LONG_MOVES
16962   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16963  [(set (match_dup 2) (match_dup 1))
16964   (set (match_dup 0) (match_dup 2))])
16965
16966;; Don't compare memory with zero, load and use a test instead.
16967(define_peephole2
16968  [(set (match_operand 0 "flags_reg_operand" "")
16969 	(match_operator 1 "compare_operator"
16970	  [(match_operand:SI 2 "memory_operand" "")
16971	   (const_int 0)]))
16972   (match_scratch:SI 3 "r")]
16973  "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16974  [(set (match_dup 3) (match_dup 2))
16975   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16976
16977;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16978;; Don't split NOTs with a displacement operand, because resulting XOR
16979;; will not be pairable anyway.
16980;;
16981;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16982;; represented using a modRM byte.  The XOR replacement is long decoded,
16983;; so this split helps here as well.
16984;;
16985;; Note: Can't do this as a regular split because we can't get proper
16986;; lifetime information then.
16987
16988(define_peephole2
16989  [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16990	(not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16991  "optimize_insn_for_speed_p ()
16992   && ((TARGET_NOT_UNPAIRABLE
16993	&& (!MEM_P (operands[0])
16994	    || !memory_displacement_operand (operands[0], <MODE>mode)))
16995       || (TARGET_NOT_VECTORMODE
16996	   && long_memory_operand (operands[0], <MODE>mode)))
16997   && peep2_regno_dead_p (0, FLAGS_REG)"
16998  [(parallel [(set (match_dup 0)
16999		   (xor:SWI124 (match_dup 1) (const_int -1)))
17000	      (clobber (reg:CC FLAGS_REG))])])
17001
17002;; Non pairable "test imm, reg" instructions can be translated to
17003;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17004;; byte opcode instead of two, have a short form for byte operands),
17005;; so do it for other CPUs as well.  Given that the value was dead,
17006;; this should not create any new dependencies.  Pass on the sub-word
17007;; versions if we're concerned about partial register stalls.
17008
17009(define_peephole2
17010  [(set (match_operand 0 "flags_reg_operand" "")
17011	(match_operator 1 "compare_operator"
17012	  [(and:SI (match_operand:SI 2 "register_operand" "")
17013		   (match_operand:SI 3 "immediate_operand" ""))
17014	   (const_int 0)]))]
17015  "ix86_match_ccmode (insn, CCNOmode)
17016   && (true_regnum (operands[2]) != AX_REG
17017       || satisfies_constraint_K (operands[3]))
17018   && peep2_reg_dead_p (1, operands[2])"
17019  [(parallel
17020     [(set (match_dup 0)
17021	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17022		            (const_int 0)]))
17023      (set (match_dup 2)
17024	   (and:SI (match_dup 2) (match_dup 3)))])])
17025
17026;; We don't need to handle HImode case, because it will be promoted to SImode
17027;; on ! TARGET_PARTIAL_REG_STALL
17028
17029(define_peephole2
17030  [(set (match_operand 0 "flags_reg_operand" "")
17031	(match_operator 1 "compare_operator"
17032	  [(and:QI (match_operand:QI 2 "register_operand" "")
17033		   (match_operand:QI 3 "immediate_operand" ""))
17034	   (const_int 0)]))]
17035  "! TARGET_PARTIAL_REG_STALL
17036   && ix86_match_ccmode (insn, CCNOmode)
17037   && true_regnum (operands[2]) != AX_REG
17038   && peep2_reg_dead_p (1, operands[2])"
17039  [(parallel
17040     [(set (match_dup 0)
17041	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17042		            (const_int 0)]))
17043      (set (match_dup 2)
17044	   (and:QI (match_dup 2) (match_dup 3)))])])
17045
17046(define_peephole2
17047  [(set (match_operand 0 "flags_reg_operand" "")
17048	(match_operator 1 "compare_operator"
17049	  [(and:SI
17050	     (zero_extract:SI
17051	       (match_operand 2 "ext_register_operand" "")
17052	       (const_int 8)
17053	       (const_int 8))
17054	     (match_operand 3 "const_int_operand" ""))
17055	   (const_int 0)]))]
17056  "! TARGET_PARTIAL_REG_STALL
17057   && ix86_match_ccmode (insn, CCNOmode)
17058   && true_regnum (operands[2]) != AX_REG
17059   && peep2_reg_dead_p (1, operands[2])"
17060  [(parallel [(set (match_dup 0)
17061		   (match_op_dup 1
17062		     [(and:SI
17063			(zero_extract:SI
17064			  (match_dup 2)
17065			  (const_int 8)
17066			  (const_int 8))
17067			(match_dup 3))
17068		      (const_int 0)]))
17069	      (set (zero_extract:SI (match_dup 2)
17070				    (const_int 8)
17071				    (const_int 8))
17072		   (and:SI
17073		     (zero_extract:SI
17074		       (match_dup 2)
17075		       (const_int 8)
17076		       (const_int 8))
17077		     (match_dup 3)))])])
17078
17079;; Don't do logical operations with memory inputs.
17080(define_peephole2
17081  [(match_scratch:SI 2 "r")
17082   (parallel [(set (match_operand:SI 0 "register_operand" "")
17083                   (match_operator:SI 3 "arith_or_logical_operator"
17084                     [(match_dup 0)
17085                      (match_operand:SI 1 "memory_operand" "")]))
17086              (clobber (reg:CC FLAGS_REG))])]
17087  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17088  [(set (match_dup 2) (match_dup 1))
17089   (parallel [(set (match_dup 0)
17090                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17091              (clobber (reg:CC FLAGS_REG))])])
17092
17093(define_peephole2
17094  [(match_scratch:SI 2 "r")
17095   (parallel [(set (match_operand:SI 0 "register_operand" "")
17096                   (match_operator:SI 3 "arith_or_logical_operator"
17097                     [(match_operand:SI 1 "memory_operand" "")
17098                      (match_dup 0)]))
17099              (clobber (reg:CC FLAGS_REG))])]
17100  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17101  [(set (match_dup 2) (match_dup 1))
17102   (parallel [(set (match_dup 0)
17103                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17104              (clobber (reg:CC FLAGS_REG))])])
17105
17106;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17107;; refers to the destination of the load!
17108
17109(define_peephole2
17110  [(set (match_operand:SI 0 "register_operand" "")
17111        (match_operand:SI 1 "register_operand" ""))
17112   (parallel [(set (match_dup 0)
17113                   (match_operator:SI 3 "commutative_operator"
17114                     [(match_dup 0)
17115                      (match_operand:SI 2 "memory_operand" "")]))
17116              (clobber (reg:CC FLAGS_REG))])]
17117  "REGNO (operands[0]) != REGNO (operands[1])
17118   && GENERAL_REGNO_P (REGNO (operands[0]))
17119   && GENERAL_REGNO_P (REGNO (operands[1]))"
17120  [(set (match_dup 0) (match_dup 4))
17121   (parallel [(set (match_dup 0)
17122                   (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17123              (clobber (reg:CC FLAGS_REG))])]
17124  "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17125
17126(define_peephole2
17127  [(set (match_operand 0 "register_operand" "")
17128        (match_operand 1 "register_operand" ""))
17129   (set (match_dup 0)
17130                   (match_operator 3 "commutative_operator"
17131                     [(match_dup 0)
17132                      (match_operand 2 "memory_operand" "")]))]
17133  "REGNO (operands[0]) != REGNO (operands[1])
17134   && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17135       || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17136  [(set (match_dup 0) (match_dup 2))
17137   (set (match_dup 0)
17138        (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17139
17140; Don't do logical operations with memory outputs
17141;
17142; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17143; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17144; the same decoder scheduling characteristics as the original.
17145
17146(define_peephole2
17147  [(match_scratch:SI 2 "r")
17148   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17149                   (match_operator:SI 3 "arith_or_logical_operator"
17150                     [(match_dup 0)
17151                      (match_operand:SI 1 "nonmemory_operand" "")]))
17152              (clobber (reg:CC FLAGS_REG))])]
17153  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17154   /* Do not split stack checking probes.  */
17155   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17156  [(set (match_dup 2) (match_dup 0))
17157   (parallel [(set (match_dup 2)
17158                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17159              (clobber (reg:CC FLAGS_REG))])
17160   (set (match_dup 0) (match_dup 2))])
17161
17162(define_peephole2
17163  [(match_scratch:SI 2 "r")
17164   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17165                   (match_operator:SI 3 "arith_or_logical_operator"
17166                     [(match_operand:SI 1 "nonmemory_operand" "")
17167                      (match_dup 0)]))
17168              (clobber (reg:CC FLAGS_REG))])]
17169  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17170   /* Do not split stack checking probes.  */
17171   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17172  [(set (match_dup 2) (match_dup 0))
17173   (parallel [(set (match_dup 2)
17174                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17175              (clobber (reg:CC FLAGS_REG))])
17176   (set (match_dup 0) (match_dup 2))])
17177
17178;; Attempt to use arith or logical operations with memory outputs with
17179;; setting of flags.
17180(define_peephole2
17181  [(set (match_operand:SWI 0 "register_operand" "")
17182	(match_operand:SWI 1 "memory_operand" ""))
17183   (parallel [(set (match_dup 0)
17184		   (match_operator:SWI 3 "plusminuslogic_operator"
17185		     [(match_dup 0)
17186		      (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17187	      (clobber (reg:CC FLAGS_REG))])
17188   (set (match_dup 1) (match_dup 0))
17189   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17190  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17191   && peep2_reg_dead_p (4, operands[0])
17192   && !reg_overlap_mentioned_p (operands[0], operands[1])
17193   && (<MODE>mode != QImode
17194       || immediate_operand (operands[2], QImode)
17195       || q_regs_operand (operands[2], QImode))
17196   && ix86_match_ccmode (peep2_next_insn (3),
17197			 (GET_CODE (operands[3]) == PLUS
17198			  || GET_CODE (operands[3]) == MINUS)
17199			 ? CCGOCmode : CCNOmode)"
17200  [(parallel [(set (match_dup 4) (match_dup 5))
17201	      (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17202						  (match_dup 2)]))])]
17203{
17204  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17205  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17206				copy_rtx (operands[1]),
17207				copy_rtx (operands[2]));
17208  operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17209				 operands[5], const0_rtx);
17210})
17211
17212(define_peephole2
17213  [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17214		   (match_operator:SWI 2 "plusminuslogic_operator"
17215		     [(match_dup 0)
17216		      (match_operand:SWI 1 "memory_operand" "")]))
17217	      (clobber (reg:CC FLAGS_REG))])
17218   (set (match_dup 1) (match_dup 0))
17219   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17220  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17221   && GET_CODE (operands[2]) != MINUS
17222   && peep2_reg_dead_p (3, operands[0])
17223   && !reg_overlap_mentioned_p (operands[0], operands[1])
17224   && ix86_match_ccmode (peep2_next_insn (2),
17225			 GET_CODE (operands[2]) == PLUS
17226			 ? CCGOCmode : CCNOmode)"
17227  [(parallel [(set (match_dup 3) (match_dup 4))
17228	      (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17229						  (match_dup 0)]))])]
17230{
17231  operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17232  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17233				copy_rtx (operands[1]),
17234				copy_rtx (operands[0]));
17235  operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17236				 operands[4], const0_rtx);
17237})
17238
17239(define_peephole2
17240  [(set (match_operand:SWI12 0 "register_operand" "")
17241	(match_operand:SWI12 1 "memory_operand" ""))
17242   (parallel [(set (match_operand:SI 4 "register_operand" "")
17243		   (match_operator:SI 3 "plusminuslogic_operator"
17244		     [(match_dup 4)
17245		      (match_operand:SI 2 "nonmemory_operand" "")]))
17246	      (clobber (reg:CC FLAGS_REG))])
17247   (set (match_dup 1) (match_dup 0))
17248   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17249  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17250   && REG_P (operands[0]) && REG_P (operands[4])
17251   && REGNO (operands[0]) == REGNO (operands[4])
17252   && peep2_reg_dead_p (4, operands[0])
17253   && (<MODE>mode != QImode
17254       || immediate_operand (operands[2], SImode)
17255       || q_regs_operand (operands[2], SImode))
17256   && !reg_overlap_mentioned_p (operands[0], operands[1])
17257   && ix86_match_ccmode (peep2_next_insn (3),
17258			 (GET_CODE (operands[3]) == PLUS
17259			  || GET_CODE (operands[3]) == MINUS)
17260			 ? CCGOCmode : CCNOmode)"
17261  [(parallel [(set (match_dup 4) (match_dup 5))
17262	      (set (match_dup 1) (match_dup 6))])]
17263{
17264  operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17265  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17266  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17267				copy_rtx (operands[1]), operands[2]);
17268  operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17269				 operands[5], const0_rtx);
17270  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17271				copy_rtx (operands[1]),
17272				copy_rtx (operands[2]));
17273})
17274
17275;; Attempt to always use XOR for zeroing registers.
17276(define_peephole2
17277  [(set (match_operand 0 "register_operand" "")
17278	(match_operand 1 "const0_operand" ""))]
17279  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17280   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17281   && GENERAL_REG_P (operands[0])
17282   && peep2_regno_dead_p (0, FLAGS_REG)"
17283  [(parallel [(set (match_dup 0) (const_int 0))
17284	      (clobber (reg:CC FLAGS_REG))])]
17285  "operands[0] = gen_lowpart (word_mode, operands[0]);")
17286
17287(define_peephole2
17288  [(set (strict_low_part (match_operand 0 "register_operand" ""))
17289	(const_int 0))]
17290  "(GET_MODE (operands[0]) == QImode
17291    || GET_MODE (operands[0]) == HImode)
17292   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17293   && peep2_regno_dead_p (0, FLAGS_REG)"
17294  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17295	      (clobber (reg:CC FLAGS_REG))])])
17296
17297;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17298(define_peephole2
17299  [(set (match_operand:SWI248 0 "register_operand" "")
17300	(const_int -1))]
17301  "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17302   && peep2_regno_dead_p (0, FLAGS_REG)"
17303  [(parallel [(set (match_dup 0) (const_int -1))
17304	      (clobber (reg:CC FLAGS_REG))])]
17305{
17306  if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17307    operands[0] = gen_lowpart (SImode, operands[0]);
17308})
17309
17310;; Attempt to convert simple lea to add/shift.
17311;; These can be created by move expanders.
17312
17313(define_peephole2
17314  [(set (match_operand:SWI48 0 "register_operand" "")
17315  	(plus:SWI48 (match_dup 0)
17316		    (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17317  "peep2_regno_dead_p (0, FLAGS_REG)"
17318  [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17319	      (clobber (reg:CC FLAGS_REG))])])
17320
17321(define_peephole2
17322  [(set (match_operand:SI 0 "register_operand" "")
17323  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17324			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17325  "TARGET_64BIT
17326   && peep2_regno_dead_p (0, FLAGS_REG)
17327   && REGNO (operands[0]) == REGNO (operands[1])"
17328  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17329	      (clobber (reg:CC FLAGS_REG))])]
17330  "operands[2] = gen_lowpart (SImode, operands[2]);")
17331
17332(define_peephole2
17333  [(set (match_operand:SWI48 0 "register_operand" "")
17334  	(mult:SWI48 (match_dup 0)
17335		    (match_operand:SWI48 1 "const_int_operand" "")))]
17336  "exact_log2 (INTVAL (operands[1])) >= 0
17337   && peep2_regno_dead_p (0, FLAGS_REG)"
17338  [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17339	      (clobber (reg:CC FLAGS_REG))])]
17340  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17341
17342(define_peephole2
17343  [(set (match_operand:SI 0 "register_operand" "")
17344  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17345		   (match_operand:DI 2 "const_int_operand" "")) 0))]
17346  "TARGET_64BIT
17347   && exact_log2 (INTVAL (operands[2])) >= 0
17348   && REGNO (operands[0]) == REGNO (operands[1])
17349   && peep2_regno_dead_p (0, FLAGS_REG)"
17350  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17351	      (clobber (reg:CC FLAGS_REG))])]
17352  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17353
17354;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17355;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17356;; On many CPUs it is also faster, since special hardware to avoid esp
17357;; dependencies is present.
17358
17359;; While some of these conversions may be done using splitters, we use
17360;; peepholes in order to allow combine_stack_adjustments pass to see
17361;; nonobfuscated RTL.
17362
17363;; Convert prologue esp subtractions to push.
17364;; We need register to push.  In order to keep verify_flow_info happy we have
17365;; two choices
17366;; - use scratch and clobber it in order to avoid dependencies
17367;; - use already live register
17368;; We can't use the second way right now, since there is no reliable way how to
17369;; verify that given register is live.  First choice will also most likely in
17370;; fewer dependencies.  On the place of esp adjustments it is very likely that
17371;; call clobbered registers are dead.  We may want to use base pointer as an
17372;; alternative when no register is available later.
17373
17374(define_peephole2
17375  [(match_scratch:P 1 "r")
17376   (parallel [(set (reg:P SP_REG)
17377		   (plus:P (reg:P SP_REG)
17378			   (match_operand:P 0 "const_int_operand" "")))
17379	      (clobber (reg:CC FLAGS_REG))
17380	      (clobber (mem:BLK (scratch)))])]
17381  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17382   && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17383  [(clobber (match_dup 1))
17384   (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17385	      (clobber (mem:BLK (scratch)))])])
17386
17387(define_peephole2
17388  [(match_scratch:P 1 "r")
17389   (parallel [(set (reg:P SP_REG)
17390		   (plus:P (reg:P SP_REG)
17391			   (match_operand:P 0 "const_int_operand" "")))
17392	      (clobber (reg:CC FLAGS_REG))
17393	      (clobber (mem:BLK (scratch)))])]
17394  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17395   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17396  [(clobber (match_dup 1))
17397   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17398   (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17399	      (clobber (mem:BLK (scratch)))])])
17400
17401;; Convert esp subtractions to push.
17402(define_peephole2
17403  [(match_scratch:P 1 "r")
17404   (parallel [(set (reg:P SP_REG)
17405		   (plus:P (reg:P SP_REG)
17406			   (match_operand:P 0 "const_int_operand" "")))
17407	      (clobber (reg:CC FLAGS_REG))])]
17408  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17409   && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17410  [(clobber (match_dup 1))
17411   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17412
17413(define_peephole2
17414  [(match_scratch:P 1 "r")
17415   (parallel [(set (reg:P SP_REG)
17416		   (plus:P (reg:P SP_REG)
17417			   (match_operand:P 0 "const_int_operand" "")))
17418	      (clobber (reg:CC FLAGS_REG))])]
17419  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17420   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17421  [(clobber (match_dup 1))
17422   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17423   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17424
17425;; Convert epilogue deallocator to pop.
17426(define_peephole2
17427  [(match_scratch:P 1 "r")
17428   (parallel [(set (reg:P SP_REG)
17429		   (plus:P (reg:P SP_REG)
17430			   (match_operand:P 0 "const_int_operand" "")))
17431	      (clobber (reg:CC FLAGS_REG))
17432	      (clobber (mem:BLK (scratch)))])]
17433  "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17434   && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17435  [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17436	      (clobber (mem:BLK (scratch)))])])
17437
17438;; Two pops case is tricky, since pop causes dependency
17439;; on destination register.  We use two registers if available.
17440(define_peephole2
17441  [(match_scratch:P 1 "r")
17442   (match_scratch:P 2 "r")
17443   (parallel [(set (reg:P SP_REG)
17444		   (plus:P (reg:P SP_REG)
17445			   (match_operand:P 0 "const_int_operand" "")))
17446	      (clobber (reg:CC FLAGS_REG))
17447	      (clobber (mem:BLK (scratch)))])]
17448  "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17449   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17450  [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17451	      (clobber (mem:BLK (scratch)))])
17452   (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17453
17454(define_peephole2
17455  [(match_scratch:P 1 "r")
17456   (parallel [(set (reg:P SP_REG)
17457		   (plus:P (reg:P SP_REG)
17458			   (match_operand:P 0 "const_int_operand" "")))
17459	      (clobber (reg:CC FLAGS_REG))
17460	      (clobber (mem:BLK (scratch)))])]
17461  "optimize_insn_for_size_p ()
17462   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17463  [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17464	      (clobber (mem:BLK (scratch)))])
17465   (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17466
17467;; Convert esp additions to pop.
17468(define_peephole2
17469  [(match_scratch:P 1 "r")
17470   (parallel [(set (reg:P SP_REG)
17471		   (plus:P (reg:P SP_REG)
17472			   (match_operand:P 0 "const_int_operand" "")))
17473	      (clobber (reg:CC FLAGS_REG))])]
17474  "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17475  [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17476
17477;; Two pops case is tricky, since pop causes dependency
17478;; on destination register.  We use two registers if available.
17479(define_peephole2
17480  [(match_scratch:P 1 "r")
17481   (match_scratch:P 2 "r")
17482   (parallel [(set (reg:P SP_REG)
17483		   (plus:P (reg:P SP_REG)
17484			   (match_operand:P 0 "const_int_operand" "")))
17485	      (clobber (reg:CC FLAGS_REG))])]
17486  "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17487  [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17488   (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17489
17490(define_peephole2
17491  [(match_scratch:P 1 "r")
17492   (parallel [(set (reg:P SP_REG)
17493		   (plus:P (reg:P SP_REG)
17494			   (match_operand:P 0 "const_int_operand" "")))
17495	      (clobber (reg:CC FLAGS_REG))])]
17496  "optimize_insn_for_size_p ()
17497   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17498  [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17499   (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17500
17501;; Convert compares with 1 to shorter inc/dec operations when CF is not
17502;; required and register dies.  Similarly for 128 to -128.
17503(define_peephole2
17504  [(set (match_operand 0 "flags_reg_operand" "")
17505	(match_operator 1 "compare_operator"
17506	  [(match_operand 2 "register_operand" "")
17507	   (match_operand 3 "const_int_operand" "")]))]
17508  "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17509     && incdec_operand (operands[3], GET_MODE (operands[3])))
17510    || (!TARGET_FUSE_CMP_AND_BRANCH
17511	&& INTVAL (operands[3]) == 128))
17512   && ix86_match_ccmode (insn, CCGCmode)
17513   && peep2_reg_dead_p (1, operands[2])"
17514  [(parallel [(set (match_dup 0)
17515		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17516	      (clobber (match_dup 2))])])
17517
17518;; Convert imul by three, five and nine into lea
17519(define_peephole2
17520  [(parallel
17521    [(set (match_operand:SWI48 0 "register_operand" "")
17522	  (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17523		      (match_operand:SWI48 2 "const359_operand" "")))
17524     (clobber (reg:CC FLAGS_REG))])]
17525  "!TARGET_PARTIAL_REG_STALL
17526   || <MODE>mode == SImode
17527   || optimize_function_for_size_p (cfun)"
17528  [(set (match_dup 0)
17529	(plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17530		    (match_dup 1)))]
17531  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17532
17533(define_peephole2
17534  [(parallel
17535    [(set (match_operand:SWI48 0 "register_operand" "")
17536	  (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17537		      (match_operand:SWI48 2 "const359_operand" "")))
17538     (clobber (reg:CC FLAGS_REG))])]
17539  "optimize_insn_for_speed_p ()
17540   && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17541  [(set (match_dup 0) (match_dup 1))
17542   (set (match_dup 0)
17543	(plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17544		    (match_dup 0)))]
17545  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17546
17547;; imul $32bit_imm, mem, reg is vector decoded, while
17548;; imul $32bit_imm, reg, reg is direct decoded.
17549(define_peephole2
17550  [(match_scratch:SWI48 3 "r")
17551   (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17552		   (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17553			       (match_operand:SWI48 2 "immediate_operand" "")))
17554	      (clobber (reg:CC FLAGS_REG))])]
17555  "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17556   && !satisfies_constraint_K (operands[2])"
17557  [(set (match_dup 3) (match_dup 1))
17558   (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17559	      (clobber (reg:CC FLAGS_REG))])])
17560
17561(define_peephole2
17562  [(match_scratch:SI 3 "r")
17563   (parallel [(set (match_operand:DI 0 "register_operand" "")
17564		   (zero_extend:DI
17565		     (mult:SI (match_operand:SI 1 "memory_operand" "")
17566			      (match_operand:SI 2 "immediate_operand" ""))))
17567	      (clobber (reg:CC FLAGS_REG))])]
17568  "TARGET_64BIT
17569   && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17570   && !satisfies_constraint_K (operands[2])"
17571  [(set (match_dup 3) (match_dup 1))
17572   (parallel [(set (match_dup 0)
17573		   (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17574	      (clobber (reg:CC FLAGS_REG))])])
17575
17576;; imul $8/16bit_imm, regmem, reg is vector decoded.
17577;; Convert it into imul reg, reg
17578;; It would be better to force assembler to encode instruction using long
17579;; immediate, but there is apparently no way to do so.
17580(define_peephole2
17581  [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17582		   (mult:SWI248
17583		    (match_operand:SWI248 1 "nonimmediate_operand" "")
17584		    (match_operand:SWI248 2 "const_int_operand" "")))
17585	      (clobber (reg:CC FLAGS_REG))])
17586   (match_scratch:SWI248 3 "r")]
17587  "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17588   && satisfies_constraint_K (operands[2])"
17589  [(set (match_dup 3) (match_dup 2))
17590   (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17591	      (clobber (reg:CC FLAGS_REG))])]
17592{
17593  if (!rtx_equal_p (operands[0], operands[1]))
17594    emit_move_insn (operands[0], operands[1]);
17595})
17596
17597;; After splitting up read-modify operations, array accesses with memory
17598;; operands might end up in form:
17599;;  sall    $2, %eax
17600;;  movl    4(%esp), %edx
17601;;  addl    %edx, %eax
17602;; instead of pre-splitting:
17603;;  sall    $2, %eax
17604;;  addl    4(%esp), %eax
17605;; Turn it into:
17606;;  movl    4(%esp), %edx
17607;;  leal    (%edx,%eax,4), %eax
17608
17609(define_peephole2
17610  [(match_scratch:P 5 "r")
17611   (parallel [(set (match_operand 0 "register_operand" "")
17612		   (ashift (match_operand 1 "register_operand" "")
17613			   (match_operand 2 "const_int_operand" "")))
17614	       (clobber (reg:CC FLAGS_REG))])
17615   (parallel [(set (match_operand 3 "register_operand" "")
17616		   (plus (match_dup 0)
17617			 (match_operand 4 "x86_64_general_operand" "")))
17618		   (clobber (reg:CC FLAGS_REG))])]
17619  "IN_RANGE (INTVAL (operands[2]), 1, 3)
17620   /* Validate MODE for lea.  */
17621   && ((!TARGET_PARTIAL_REG_STALL
17622	&& (GET_MODE (operands[0]) == QImode
17623	    || GET_MODE (operands[0]) == HImode))
17624       || GET_MODE (operands[0]) == SImode
17625       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17626   && (rtx_equal_p (operands[0], operands[3])
17627       || peep2_reg_dead_p (2, operands[0]))
17628   /* We reorder load and the shift.  */
17629   && !reg_overlap_mentioned_p (operands[0], operands[4])"
17630  [(set (match_dup 5) (match_dup 4))
17631   (set (match_dup 0) (match_dup 1))]
17632{
17633  enum machine_mode op1mode = GET_MODE (operands[1]);
17634  enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17635  int scale = 1 << INTVAL (operands[2]);
17636  rtx index = gen_lowpart (Pmode, operands[1]);
17637  rtx base = gen_lowpart (Pmode, operands[5]);
17638  rtx dest = gen_lowpart (mode, operands[3]);
17639
17640  operands[1] = gen_rtx_PLUS (Pmode, base,
17641  			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17642  operands[5] = base;
17643  if (mode != Pmode)
17644    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17645  if (op1mode != Pmode)
17646    operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17647  operands[0] = dest;
17648})
17649
17650;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17651;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17652;; caught for use by garbage collectors and the like.  Using an insn that
17653;; maps to SIGILL makes it more likely the program will rightfully die.
17654;; Keeping with tradition, "6" is in honor of #UD.
17655(define_insn "trap"
17656  [(trap_if (const_int 1) (const_int 6))]
17657  ""
17658  { return ASM_SHORT "0x0b0f"; }
17659  [(set_attr "length" "2")])
17660
17661(define_expand "prefetch"
17662  [(prefetch (match_operand 0 "address_operand" "")
17663	     (match_operand:SI 1 "const_int_operand" "")
17664	     (match_operand:SI 2 "const_int_operand" ""))]
17665  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17666{
17667  int rw = INTVAL (operands[1]);
17668  int locality = INTVAL (operands[2]);
17669
17670  gcc_assert (rw == 0 || rw == 1);
17671  gcc_assert (IN_RANGE (locality, 0, 3));
17672
17673  if (TARGET_PREFETCHW && rw)
17674    operands[2] = GEN_INT (3);
17675  /* Use 3dNOW prefetch in case we are asking for write prefetch not
17676     supported by SSE counterpart or the SSE prefetch is not available
17677     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17678     of locality.  */
17679  else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17680    operands[2] = GEN_INT (3);
17681  else
17682    operands[1] = const0_rtx;
17683})
17684
17685(define_insn "*prefetch_sse"
17686  [(prefetch (match_operand 0 "address_operand" "p")
17687	     (const_int 0)
17688	     (match_operand:SI 1 "const_int_operand" ""))]
17689  "TARGET_PREFETCH_SSE"
17690{
17691  static const char * const patterns[4] = {
17692   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17693  };
17694
17695  int locality = INTVAL (operands[1]);
17696  gcc_assert (IN_RANGE (locality, 0, 3));
17697
17698  return patterns[locality];
17699}
17700  [(set_attr "type" "sse")
17701   (set_attr "atom_sse_attr" "prefetch")
17702   (set (attr "length_address")
17703	(symbol_ref "memory_address_length (operands[0], false)"))
17704   (set_attr "memory" "none")])
17705
17706(define_insn "*prefetch_3dnow"
17707  [(prefetch (match_operand 0 "address_operand" "p")
17708	     (match_operand:SI 1 "const_int_operand" "n")
17709	     (const_int 3))]
17710  "TARGET_3DNOW || TARGET_PREFETCHW"
17711{
17712  if (INTVAL (operands[1]) == 0)
17713    return "prefetch\t%a0";
17714  else
17715    return "prefetchw\t%a0";
17716}
17717  [(set_attr "type" "mmx")
17718   (set (attr "length_address")
17719	(symbol_ref "memory_address_length (operands[0], false)"))
17720   (set_attr "memory" "none")])
17721
17722(define_expand "stack_protect_set"
17723  [(match_operand 0 "memory_operand" "")
17724   (match_operand 1 "memory_operand" "")]
17725  "!TARGET_HAS_BIONIC"
17726{
17727  rtx (*insn)(rtx, rtx);
17728
17729#ifdef TARGET_THREAD_SSP_OFFSET
17730  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17731  insn = (TARGET_LP64
17732	  ? gen_stack_tls_protect_set_di
17733	  : gen_stack_tls_protect_set_si);
17734#else
17735  insn = (TARGET_LP64
17736	  ? gen_stack_protect_set_di
17737	  : gen_stack_protect_set_si);
17738#endif
17739
17740  emit_insn (insn (operands[0], operands[1]));
17741  DONE;
17742})
17743
17744(define_insn "stack_protect_set_<mode>"
17745  [(set (match_operand:PTR 0 "memory_operand" "=m")
17746	(unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17747		    UNSPEC_SP_SET))
17748   (set (match_scratch:PTR 2 "=&r") (const_int 0))
17749   (clobber (reg:CC FLAGS_REG))]
17750  "!TARGET_HAS_BIONIC"
17751  "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17752  [(set_attr "type" "multi")])
17753
17754(define_insn "stack_tls_protect_set_<mode>"
17755  [(set (match_operand:PTR 0 "memory_operand" "=m")
17756	(unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17757		    UNSPEC_SP_TLS_SET))
17758   (set (match_scratch:PTR 2 "=&r") (const_int 0))
17759   (clobber (reg:CC FLAGS_REG))]
17760  ""
17761  "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17762  [(set_attr "type" "multi")])
17763
17764(define_expand "stack_protect_test"
17765  [(match_operand 0 "memory_operand" "")
17766   (match_operand 1 "memory_operand" "")
17767   (match_operand 2 "" "")]
17768  "!TARGET_HAS_BIONIC"
17769{
17770  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17771
17772  rtx (*insn)(rtx, rtx, rtx);
17773
17774#ifdef TARGET_THREAD_SSP_OFFSET
17775  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17776  insn = (TARGET_LP64
17777	  ? gen_stack_tls_protect_test_di
17778	  : gen_stack_tls_protect_test_si);
17779#else
17780  insn = (TARGET_LP64
17781	  ? gen_stack_protect_test_di
17782	  : gen_stack_protect_test_si);
17783#endif
17784
17785  emit_insn (insn (flags, operands[0], operands[1]));
17786
17787  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17788				  flags, const0_rtx, operands[2]));
17789  DONE;
17790})
17791
17792(define_insn "stack_protect_test_<mode>"
17793  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17794	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17795		     (match_operand:PTR 2 "memory_operand" "m")]
17796		    UNSPEC_SP_TEST))
17797   (clobber (match_scratch:PTR 3 "=&r"))]
17798  "!TARGET_HAS_BIONIC"
17799  "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17800  [(set_attr "type" "multi")])
17801
17802(define_insn "stack_tls_protect_test_<mode>"
17803  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17804	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17805		     (match_operand:PTR 2 "const_int_operand" "i")]
17806		    UNSPEC_SP_TLS_TEST))
17807   (clobber (match_scratch:PTR 3 "=r"))]
17808  ""
17809  "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17810  [(set_attr "type" "multi")])
17811
17812(define_insn "sse4_2_crc32<mode>"
17813  [(set (match_operand:SI 0 "register_operand" "=r")
17814	(unspec:SI
17815	  [(match_operand:SI 1 "register_operand" "0")
17816	   (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17817	  UNSPEC_CRC32))]
17818  "TARGET_SSE4_2 || TARGET_CRC32"
17819  "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17820  [(set_attr "type" "sselog1")
17821   (set_attr "prefix_rep" "1")
17822   (set_attr "prefix_extra" "1")
17823   (set (attr "prefix_data16")
17824     (if_then_else (match_operand:HI 2 "" "")
17825       (const_string "1")
17826       (const_string "*")))
17827   (set (attr "prefix_rex")
17828     (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17829       (const_string "1")
17830       (const_string "*")))
17831   (set_attr "mode" "SI")])
17832
17833(define_insn "sse4_2_crc32di"
17834  [(set (match_operand:DI 0 "register_operand" "=r")
17835	(unspec:DI
17836	  [(match_operand:DI 1 "register_operand" "0")
17837	   (match_operand:DI 2 "nonimmediate_operand" "rm")]
17838	  UNSPEC_CRC32))]
17839  "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17840  "crc32{q}\t{%2, %0|%0, %2}"
17841  [(set_attr "type" "sselog1")
17842   (set_attr "prefix_rep" "1")
17843   (set_attr "prefix_extra" "1")
17844   (set_attr "mode" "DI")])
17845
17846(define_expand "rdpmc"
17847  [(match_operand:DI 0 "register_operand" "")
17848   (match_operand:SI 1 "register_operand" "")]
17849  ""
17850{
17851  rtx reg = gen_reg_rtx (DImode);
17852  rtx si;
17853
17854  /* Force operand 1 into ECX.  */
17855  rtx ecx = gen_rtx_REG (SImode, CX_REG);
17856  emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17857  si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17858				UNSPECV_RDPMC);
17859
17860  if (TARGET_64BIT)
17861    {
17862      rtvec vec = rtvec_alloc (2);
17863      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17864      rtx upper = gen_reg_rtx (DImode);
17865      rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17866					gen_rtvec (1, const0_rtx),
17867					UNSPECV_RDPMC);
17868      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17869      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17870      emit_insn (load);
17871      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17872				   NULL, 1, OPTAB_DIRECT);
17873      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17874				 OPTAB_DIRECT);
17875    }
17876  else
17877    emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17878  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17879  DONE;
17880})
17881
17882(define_insn "*rdpmc"
17883  [(set (match_operand:DI 0 "register_operand" "=A")
17884  	(unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17885			    UNSPECV_RDPMC))]
17886  "!TARGET_64BIT"
17887  "rdpmc"
17888  [(set_attr "type" "other")
17889   (set_attr "length" "2")])
17890
17891(define_insn "*rdpmc_rex64"
17892  [(set (match_operand:DI 0 "register_operand" "=a")
17893  	(unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17894			    UNSPECV_RDPMC))
17895  (set (match_operand:DI 1 "register_operand" "=d")
17896       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17897  "TARGET_64BIT"
17898  "rdpmc"
17899  [(set_attr "type" "other")
17900   (set_attr "length" "2")])
17901
17902(define_expand "rdtsc"
17903  [(set (match_operand:DI 0 "register_operand" "")
17904	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17905  ""
17906{
17907  if (TARGET_64BIT)
17908    {
17909      rtvec vec = rtvec_alloc (2);
17910      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17911      rtx upper = gen_reg_rtx (DImode);
17912      rtx lower = gen_reg_rtx (DImode);
17913      rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17914					 gen_rtvec (1, const0_rtx),
17915					 UNSPECV_RDTSC);
17916      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17917      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17918      emit_insn (load);
17919      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17920				   NULL, 1, OPTAB_DIRECT);
17921      lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17922				   OPTAB_DIRECT);
17923      emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17924      DONE;
17925    }
17926})
17927
17928(define_insn "*rdtsc"
17929  [(set (match_operand:DI 0 "register_operand" "=A")
17930	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17931  "!TARGET_64BIT"
17932  "rdtsc"
17933  [(set_attr "type" "other")
17934   (set_attr "length" "2")])
17935
17936(define_insn "*rdtsc_rex64"
17937  [(set (match_operand:DI 0 "register_operand" "=a")
17938	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17939   (set (match_operand:DI 1 "register_operand" "=d")
17940	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17941  "TARGET_64BIT"
17942  "rdtsc"
17943  [(set_attr "type" "other")
17944   (set_attr "length" "2")])
17945
17946(define_expand "rdtscp"
17947  [(match_operand:DI 0 "register_operand" "")
17948   (match_operand:SI 1 "memory_operand" "")]
17949  ""
17950{
17951  rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17952				    gen_rtvec (1, const0_rtx),
17953				    UNSPECV_RDTSCP);
17954  rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17955				    gen_rtvec (1, const0_rtx),
17956				    UNSPECV_RDTSCP);
17957  rtx reg = gen_reg_rtx (DImode);
17958  rtx tmp = gen_reg_rtx (SImode);
17959
17960  if (TARGET_64BIT)
17961    {
17962      rtvec vec = rtvec_alloc (3);
17963      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17964      rtx upper = gen_reg_rtx (DImode);
17965      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17966      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17967      RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17968      emit_insn (load);
17969      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17970				   NULL, 1, OPTAB_DIRECT);
17971      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17972				 OPTAB_DIRECT);
17973    }
17974  else
17975    {
17976      rtvec vec = rtvec_alloc (2);
17977      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17978      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17979      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17980      emit_insn (load);
17981    }
17982  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17983  emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17984  DONE;
17985})
17986
17987(define_insn "*rdtscp"
17988  [(set (match_operand:DI 0 "register_operand" "=A")
17989	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17990   (set (match_operand:SI 1 "register_operand" "=c")
17991	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17992  "!TARGET_64BIT"
17993  "rdtscp"
17994  [(set_attr "type" "other")
17995   (set_attr "length" "3")])
17996
17997(define_insn "*rdtscp_rex64"
17998  [(set (match_operand:DI 0 "register_operand" "=a")
17999	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18000   (set (match_operand:DI 1 "register_operand" "=d")
18001        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18002   (set (match_operand:SI 2 "register_operand" "=c")
18003	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18004  "TARGET_64BIT"
18005  "rdtscp"
18006  [(set_attr "type" "other")
18007   (set_attr "length" "3")])
18008
18009;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18010;;
18011;; LWP instructions
18012;;
18013;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18014
18015(define_expand "lwp_llwpcb"
18016  [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18017		    UNSPECV_LLWP_INTRINSIC)]
18018  "TARGET_LWP")
18019
18020(define_insn "*lwp_llwpcb<mode>1"
18021  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18022		    UNSPECV_LLWP_INTRINSIC)]
18023  "TARGET_LWP"
18024  "llwpcb\t%0"
18025  [(set_attr "type" "lwp")
18026   (set_attr "mode" "<MODE>")
18027   (set_attr "length" "5")])
18028
18029(define_expand "lwp_slwpcb"
18030  [(set (match_operand 0 "register_operand" "=r")
18031	(unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18032  "TARGET_LWP"
18033{
18034  rtx (*insn)(rtx);
18035
18036  insn = (TARGET_64BIT
18037	  ? gen_lwp_slwpcbdi
18038	  : gen_lwp_slwpcbsi);
18039
18040  emit_insn (insn (operands[0]));
18041  DONE;
18042})
18043
18044(define_insn "lwp_slwpcb<mode>"
18045  [(set (match_operand:P 0 "register_operand" "=r")
18046	(unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18047  "TARGET_LWP"
18048  "slwpcb\t%0"
18049  [(set_attr "type" "lwp")
18050   (set_attr "mode" "<MODE>")
18051   (set_attr "length" "5")])
18052
18053(define_expand "lwp_lwpval<mode>3"
18054  [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18055    	    	     (match_operand:SI 2 "nonimmediate_operand" "rm")
18056		     (match_operand:SI 3 "const_int_operand" "i")]
18057		    UNSPECV_LWPVAL_INTRINSIC)]
18058  "TARGET_LWP"
18059  ;; Avoid unused variable warning.
18060  "(void) operands[0];")
18061
18062(define_insn "*lwp_lwpval<mode>3_1"
18063  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18064    	    	     (match_operand:SI 1 "nonimmediate_operand" "rm")
18065		     (match_operand:SI 2 "const_int_operand" "i")]
18066		    UNSPECV_LWPVAL_INTRINSIC)]
18067  "TARGET_LWP"
18068  "lwpval\t{%2, %1, %0|%0, %1, %2}"
18069  [(set_attr "type" "lwp")
18070   (set_attr "mode" "<MODE>")
18071   (set (attr "length")
18072        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18073
18074(define_expand "lwp_lwpins<mode>3"
18075  [(set (reg:CCC FLAGS_REG)
18076	(unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18077			      (match_operand:SI 2 "nonimmediate_operand" "rm")
18078			      (match_operand:SI 3 "const_int_operand" "i")]
18079			     UNSPECV_LWPINS_INTRINSIC))
18080   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18081	(eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18082  "TARGET_LWP")
18083
18084(define_insn "*lwp_lwpins<mode>3_1"
18085  [(set (reg:CCC FLAGS_REG)
18086	(unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18087			      (match_operand:SI 1 "nonimmediate_operand" "rm")
18088			      (match_operand:SI 2 "const_int_operand" "i")]
18089			     UNSPECV_LWPINS_INTRINSIC))]
18090  "TARGET_LWP"
18091  "lwpins\t{%2, %1, %0|%0, %1, %2}"
18092  [(set_attr "type" "lwp")
18093   (set_attr "mode" "<MODE>")
18094   (set (attr "length")
18095        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18096
18097(define_insn "rdfsbase<mode>"
18098  [(set (match_operand:SWI48 0 "register_operand" "=r")
18099	(unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18100  "TARGET_64BIT && TARGET_FSGSBASE"
18101  "rdfsbase %0"
18102  [(set_attr "type" "other")
18103   (set_attr "prefix_extra" "2")])
18104
18105(define_insn "rdgsbase<mode>"
18106  [(set (match_operand:SWI48 0 "register_operand" "=r")
18107	(unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18108  "TARGET_64BIT && TARGET_FSGSBASE"
18109  "rdgsbase %0"
18110  [(set_attr "type" "other")
18111   (set_attr "prefix_extra" "2")])
18112
18113(define_insn "wrfsbase<mode>"
18114  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18115		    UNSPECV_WRFSBASE)]
18116  "TARGET_64BIT && TARGET_FSGSBASE"
18117  "wrfsbase %0"
18118  [(set_attr "type" "other")
18119   (set_attr "prefix_extra" "2")])
18120
18121(define_insn "wrgsbase<mode>"
18122  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18123		    UNSPECV_WRGSBASE)]
18124  "TARGET_64BIT && TARGET_FSGSBASE"
18125  "wrgsbase %0"
18126  [(set_attr "type" "other")
18127   (set_attr "prefix_extra" "2")])
18128
18129(define_insn "rdrand<mode>_1"
18130  [(set (match_operand:SWI248 0 "register_operand" "=r")
18131	(unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18132   (set (reg:CCC FLAGS_REG)
18133	(unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18134  "TARGET_RDRND"
18135  "rdrand\t%0"
18136  [(set_attr "type" "other")
18137   (set_attr "prefix_extra" "1")])
18138
18139(define_expand "pause"
18140  [(set (match_dup 0)
18141	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18142  ""
18143{
18144  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18145  MEM_VOLATILE_P (operands[0]) = 1;
18146})
18147
18148;; Use "rep; nop", instead of "pause", to support older assemblers.
18149;; They have the same encoding.
18150(define_insn "*pause"
18151  [(set (match_operand:BLK 0 "" "")
18152	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18153  ""
18154  "rep; nop"
18155  [(set_attr "length" "2")
18156   (set_attr "memory" "unknown")])
18157
18158(include "mmx.md")
18159(include "sse.md")
18160(include "sync.md")
18161