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  UNSPEC_STOS
113
114  ;; For SSE/MMX support:
115  UNSPEC_FIX_NOTRUNC
116  UNSPEC_MASKMOV
117  UNSPEC_MOVMSK
118  UNSPEC_RCP
119  UNSPEC_RSQRT
120  UNSPEC_PSADBW
121
122  ;; Generic math support
123  UNSPEC_COPYSIGN
124  UNSPEC_IEEE_MIN	; not commutative
125  UNSPEC_IEEE_MAX	; not commutative
126
127  ;; x87 Floating point
128  UNSPEC_SIN
129  UNSPEC_COS
130  UNSPEC_FPATAN
131  UNSPEC_FYL2X
132  UNSPEC_FYL2XP1
133  UNSPEC_FRNDINT
134  UNSPEC_FIST
135  UNSPEC_F2XM1
136  UNSPEC_TAN
137  UNSPEC_FXAM
138
139  ;; x87 Rounding
140  UNSPEC_FRNDINT_FLOOR
141  UNSPEC_FRNDINT_CEIL
142  UNSPEC_FRNDINT_TRUNC
143  UNSPEC_FRNDINT_MASK_PM
144  UNSPEC_FIST_FLOOR
145  UNSPEC_FIST_CEIL
146
147  ;; x87 Double output FP
148  UNSPEC_SINCOS_COS
149  UNSPEC_SINCOS_SIN
150  UNSPEC_XTRACT_FRACT
151  UNSPEC_XTRACT_EXP
152  UNSPEC_FSCALE_FRACT
153  UNSPEC_FSCALE_EXP
154  UNSPEC_FPREM_F
155  UNSPEC_FPREM_U
156  UNSPEC_FPREM1_F
157  UNSPEC_FPREM1_U
158
159  UNSPEC_C2_FLAG
160  UNSPEC_FXAM_MEM
161
162  ;; SSP patterns
163  UNSPEC_SP_SET
164  UNSPEC_SP_TEST
165  UNSPEC_SP_TLS_SET
166  UNSPEC_SP_TLS_TEST
167
168  ;; For ROUND support
169  UNSPEC_ROUND
170
171  ;; For CRC32 support
172  UNSPEC_CRC32
173
174  ;; For BMI support
175  UNSPEC_BEXTR
176
177  ;; For BMI2 support
178  UNSPEC_PDEP
179  UNSPEC_PEXT
180])
181
182(define_c_enum "unspecv" [
183  UNSPECV_BLOCKAGE
184  UNSPECV_STACK_PROBE
185  UNSPECV_PROBE_STACK_RANGE
186  UNSPECV_ALIGN
187  UNSPECV_PROLOGUE_USE
188  UNSPECV_SPLIT_STACK_RETURN
189  UNSPECV_CLD
190  UNSPECV_NOPS
191  UNSPECV_RDTSC
192  UNSPECV_RDTSCP
193  UNSPECV_RDPMC
194  UNSPECV_LLWP_INTRINSIC
195  UNSPECV_SLWP_INTRINSIC
196  UNSPECV_LWPVAL_INTRINSIC
197  UNSPECV_LWPINS_INTRINSIC
198  UNSPECV_RDFSBASE
199  UNSPECV_RDGSBASE
200  UNSPECV_WRFSBASE
201  UNSPECV_WRGSBASE
202
203  ;; For RDRAND support
204  UNSPECV_RDRAND
205
206  ;; Non-local goto.
207  UNSPECV_NLGR
208 ])
209
210;; Constants to represent rounding modes in the ROUND instruction
211(define_constants
212  [(ROUND_FLOOR			0x1)
213   (ROUND_CEIL			0x2)
214   (ROUND_TRUNC			0x3)
215   (ROUND_MXCSR			0x4)
216   (ROUND_NO_EXC		0x8)
217  ])
218
219;; Constants to represent pcomtrue/pcomfalse variants
220(define_constants
221  [(PCOM_FALSE			0)
222   (PCOM_TRUE			1)
223   (COM_FALSE_S			2)
224   (COM_FALSE_P			3)
225   (COM_TRUE_S			4)
226   (COM_TRUE_P			5)
227  ])
228
229;; Constants used in the XOP pperm instruction
230(define_constants
231  [(PPERM_SRC			0x00)	/* copy source */
232   (PPERM_INVERT		0x20)	/* invert source */
233   (PPERM_REVERSE		0x40)	/* bit reverse source */
234   (PPERM_REV_INV		0x60)	/* bit reverse & invert src */
235   (PPERM_ZERO			0x80)	/* all 0's */
236   (PPERM_ONES			0xa0)	/* all 1's */
237   (PPERM_SIGN			0xc0)	/* propagate sign bit */
238   (PPERM_INV_SIGN		0xe0)	/* invert & propagate sign */
239   (PPERM_SRC1			0x00)	/* use first source byte */
240   (PPERM_SRC2			0x10)	/* use second source byte */
241   ])
242
243;; Registers by name.
244(define_constants
245  [(AX_REG			 0)
246   (DX_REG			 1)
247   (CX_REG			 2)
248   (BX_REG			 3)
249   (SI_REG			 4)
250   (DI_REG			 5)
251   (BP_REG			 6)
252   (SP_REG			 7)
253   (ST0_REG			 8)
254   (ST1_REG			 9)
255   (ST2_REG			10)
256   (ST3_REG			11)
257   (ST4_REG			12)
258   (ST5_REG			13)
259   (ST6_REG			14)
260   (ST7_REG			15)
261   (FLAGS_REG			17)
262   (FPSR_REG			18)
263   (FPCR_REG			19)
264   (XMM0_REG			21)
265   (XMM1_REG			22)
266   (XMM2_REG			23)
267   (XMM3_REG			24)
268   (XMM4_REG			25)
269   (XMM5_REG			26)
270   (XMM6_REG			27)
271   (XMM7_REG			28)
272   (MM0_REG			29)
273   (MM1_REG			30)
274   (MM2_REG			31)
275   (MM3_REG			32)
276   (MM4_REG			33)
277   (MM5_REG			34)
278   (MM6_REG			35)
279   (MM7_REG			36)
280   (R8_REG			37)
281   (R9_REG			38)
282   (R10_REG			39)
283   (R11_REG			40)
284   (R12_REG			41)
285   (R13_REG			42)
286   (XMM8_REG			45)
287   (XMM9_REG			46)
288   (XMM10_REG			47)
289   (XMM11_REG			48)
290   (XMM12_REG			49)
291   (XMM13_REG			50)
292   (XMM14_REG			51)
293   (XMM15_REG			52)
294  ])
295
296;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
297;; from i386.c.
298
299;; In C guard expressions, put expressions which may be compile-time
300;; constants first.  This allows for better optimization.  For
301;; example, write "TARGET_64BIT && reload_completed", not
302;; "reload_completed && TARGET_64BIT".
303
304
305;; Processor type.
306(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
307		    atom,generic64,amdfam10,bdver1,bdver2,btver1"
308  (const (symbol_ref "ix86_schedule")))
309
310;; A basic instruction type.  Refinements due to arguments to be
311;; provided in other attributes.
312(define_attr "type"
313  "other,multi,
314   alu,alu1,negnot,imov,imovx,lea,
315   incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
316   icmp,test,ibr,setcc,icmov,
317   push,pop,call,callv,leave,
318   str,bitmanip,
319   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
320   sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
321   sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
322   ssemuladd,sse4arg,lwp,
323   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
324  (const_string "other"))
325
326;; Main data type used by the insn
327(define_attr "mode"
328  "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
329  (const_string "unknown"))
330
331;; The CPU unit operations uses.
332(define_attr "unit" "integer,i387,sse,mmx,unknown"
333  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
334	   (const_string "i387")
335	 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
336			  sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
337			  ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
338	   (const_string "sse")
339	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
340	   (const_string "mmx")
341	 (eq_attr "type" "other")
342	   (const_string "unknown")]
343	 (const_string "integer")))
344
345;; The (bounding maximum) length of an instruction immediate.
346(define_attr "length_immediate" ""
347  (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
348                          bitmanip,imulx")
349	   (const_int 0)
350	 (eq_attr "unit" "i387,sse,mmx")
351	   (const_int 0)
352	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
353			  rotate,rotatex,rotate1,imul,icmp,push,pop")
354	   (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
355	 (eq_attr "type" "imov,test")
356	   (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
357	 (eq_attr "type" "call")
358	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
359	     (const_int 4)
360	     (const_int 0))
361	 (eq_attr "type" "callv")
362	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
363	     (const_int 4)
364	     (const_int 0))
365	 ;; We don't know the size before shorten_branches.  Expect
366	 ;; the instruction to fit for better scheduling.
367	 (eq_attr "type" "ibr")
368	   (const_int 1)
369	 ]
370	 (symbol_ref "/* Update immediate_length and other attributes! */
371		      gcc_unreachable (),1")))
372
373;; The (bounding maximum) length of an instruction address.
374(define_attr "length_address" ""
375  (cond [(eq_attr "type" "str,other,multi,fxch")
376	   (const_int 0)
377	 (and (eq_attr "type" "call")
378	      (match_operand 0 "constant_call_address_operand" ""))
379	     (const_int 0)
380	 (and (eq_attr "type" "callv")
381	      (match_operand 1 "constant_call_address_operand" ""))
382	     (const_int 0)
383	 ]
384	 (symbol_ref "ix86_attr_length_address_default (insn)")))
385
386;; Set when length prefix is used.
387(define_attr "prefix_data16" ""
388  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
389	   (const_int 0)
390	 (eq_attr "mode" "HI")
391	   (const_int 1)
392	 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
393	   (const_int 1)
394	]
395	(const_int 0)))
396
397;; Set when string REP prefix is used.
398(define_attr "prefix_rep" ""
399  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
400	   (const_int 0)
401	 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
402	   (const_int 1)
403	]
404	(const_int 0)))
405
406;; Set when 0f opcode prefix is used.
407(define_attr "prefix_0f" ""
408  (if_then_else
409    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
410	 (eq_attr "unit" "sse,mmx"))
411    (const_int 1)
412    (const_int 0)))
413
414;; Set when REX opcode prefix is used.
415(define_attr "prefix_rex" ""
416  (cond [(not (match_test "TARGET_64BIT"))
417	   (const_int 0)
418	 (and (eq_attr "mode" "DI")
419	      (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
420		   (eq_attr "unit" "!mmx")))
421	   (const_int 1)
422	 (and (eq_attr "mode" "QI")
423	      (match_test "x86_extended_QIreg_mentioned_p (insn)"))
424	   (const_int 1)
425	 (match_test "x86_extended_reg_mentioned_p (insn)")
426	   (const_int 1)
427	 (and (eq_attr "type" "imovx")
428	      (match_operand:QI 1 "ext_QIreg_operand" ""))
429	   (const_int 1)
430	]
431	(const_int 0)))
432
433;; There are also additional prefixes in 3DNOW, SSSE3.
434;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
435;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
436;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
437(define_attr "prefix_extra" ""
438  (cond [(eq_attr "type" "ssemuladd,sse4arg")
439	   (const_int 2)
440	 (eq_attr "type" "sseiadd1,ssecvt1")
441	   (const_int 1)
442	]
443	(const_int 0)))
444
445;; Prefix used: original, VEX or maybe VEX.
446(define_attr "prefix" "orig,vex,maybe_vex"
447  (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
448    (const_string "vex")
449    (const_string "orig")))
450
451;; VEX W bit is used.
452(define_attr "prefix_vex_w" "" (const_int 0))
453
454;; The length of VEX prefix
455;; Only instructions with 0f prefix can have 2 byte VEX prefix,
456;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
457;; still prefix_0f 1, with prefix_extra 1.
458(define_attr "length_vex" ""
459  (if_then_else (and (eq_attr "prefix_0f" "1")
460		     (eq_attr "prefix_extra" "0"))
461    (if_then_else (eq_attr "prefix_vex_w" "1")
462      (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
463      (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
464    (if_then_else (eq_attr "prefix_vex_w" "1")
465      (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
466      (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
467
468;; Set when modrm byte is used.
469(define_attr "modrm" ""
470  (cond [(eq_attr "type" "str,leave")
471	   (const_int 0)
472	 (eq_attr "unit" "i387")
473	   (const_int 0)
474         (and (eq_attr "type" "incdec")
475	      (and (not (match_test "TARGET_64BIT"))
476		   (ior (match_operand:SI 1 "register_operand" "")
477			(match_operand:HI 1 "register_operand" ""))))
478	   (const_int 0)
479	 (and (eq_attr "type" "push")
480	      (not (match_operand 1 "memory_operand" "")))
481	   (const_int 0)
482	 (and (eq_attr "type" "pop")
483	      (not (match_operand 0 "memory_operand" "")))
484	   (const_int 0)
485	 (and (eq_attr "type" "imov")
486	      (and (not (eq_attr "mode" "DI"))
487		   (ior (and (match_operand 0 "register_operand" "")
488			     (match_operand 1 "immediate_operand" ""))
489		        (ior (and (match_operand 0 "ax_reg_operand" "")
490				  (match_operand 1 "memory_displacement_only_operand" ""))
491			     (and (match_operand 0 "memory_displacement_only_operand" "")
492				  (match_operand 1 "ax_reg_operand" ""))))))
493	   (const_int 0)
494	 (and (eq_attr "type" "call")
495	      (match_operand 0 "constant_call_address_operand" ""))
496	     (const_int 0)
497	 (and (eq_attr "type" "callv")
498	      (match_operand 1 "constant_call_address_operand" ""))
499	     (const_int 0)
500	 (and (eq_attr "type" "alu,alu1,icmp,test")
501	      (match_operand 0 "ax_reg_operand" ""))
502	     (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
503	 ]
504	 (const_int 1)))
505
506;; The (bounding maximum) length of an instruction in bytes.
507;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
508;; Later we may want to split them and compute proper length as for
509;; other insns.
510(define_attr "length" ""
511  (cond [(eq_attr "type" "other,multi,fistp,frndint")
512	   (const_int 16)
513	 (eq_attr "type" "fcmp")
514	   (const_int 4)
515	 (eq_attr "unit" "i387")
516	   (plus (const_int 2)
517		 (plus (attr "prefix_data16")
518		       (attr "length_address")))
519	 (ior (eq_attr "prefix" "vex")
520	      (and (eq_attr "prefix" "maybe_vex")
521		   (match_test "TARGET_AVX")))
522	   (plus (attr "length_vex")
523		 (plus (attr "length_immediate")
524		       (plus (attr "modrm")
525			     (attr "length_address"))))]
526	 (plus (plus (attr "modrm")
527		     (plus (attr "prefix_0f")
528			   (plus (attr "prefix_rex")
529				 (plus (attr "prefix_extra")
530				       (const_int 1)))))
531	       (plus (attr "prefix_rep")
532		     (plus (attr "prefix_data16")
533			   (plus (attr "length_immediate")
534				 (attr "length_address")))))))
535
536;; The `memory' attribute is `none' if no memory is referenced, `load' or
537;; `store' if there is a simple memory reference therein, or `unknown'
538;; if the instruction is complex.
539
540(define_attr "memory" "none,load,store,both,unknown"
541  (cond [(eq_attr "type" "other,multi,str,lwp")
542	   (const_string "unknown")
543	 (eq_attr "type" "lea,fcmov,fpspc")
544	   (const_string "none")
545	 (eq_attr "type" "fistp,leave")
546	   (const_string "both")
547	 (eq_attr "type" "frndint")
548	   (const_string "load")
549	 (eq_attr "type" "push")
550	   (if_then_else (match_operand 1 "memory_operand" "")
551	     (const_string "both")
552	     (const_string "store"))
553	 (eq_attr "type" "pop")
554	   (if_then_else (match_operand 0 "memory_operand" "")
555	     (const_string "both")
556	     (const_string "load"))
557	 (eq_attr "type" "setcc")
558	   (if_then_else (match_operand 0 "memory_operand" "")
559	     (const_string "store")
560	     (const_string "none"))
561	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
562	   (if_then_else (ior (match_operand 0 "memory_operand" "")
563			      (match_operand 1 "memory_operand" ""))
564	     (const_string "load")
565	     (const_string "none"))
566	 (eq_attr "type" "ibr")
567	   (if_then_else (match_operand 0 "memory_operand" "")
568	     (const_string "load")
569	     (const_string "none"))
570	 (eq_attr "type" "call")
571	   (if_then_else (match_operand 0 "constant_call_address_operand" "")
572	     (const_string "none")
573	     (const_string "load"))
574	 (eq_attr "type" "callv")
575	   (if_then_else (match_operand 1 "constant_call_address_operand" "")
576	     (const_string "none")
577	     (const_string "load"))
578	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
579	      (match_operand 1 "memory_operand" ""))
580	   (const_string "both")
581	 (and (match_operand 0 "memory_operand" "")
582	      (match_operand 1 "memory_operand" ""))
583	   (const_string "both")
584	 (match_operand 0 "memory_operand" "")
585	   (const_string "store")
586	 (match_operand 1 "memory_operand" "")
587	   (const_string "load")
588	 (and (eq_attr "type"
589		 "!alu1,negnot,ishift1,
590		   imov,imovx,icmp,test,bitmanip,
591		   fmov,fcmp,fsgn,
592		   sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
593		   sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
594	      (match_operand 2 "memory_operand" ""))
595	   (const_string "load")
596	 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
597	      (match_operand 3 "memory_operand" ""))
598	   (const_string "load")
599	]
600	(const_string "none")))
601
602;; Indicates if an instruction has both an immediate and a displacement.
603
604(define_attr "imm_disp" "false,true,unknown"
605  (cond [(eq_attr "type" "other,multi")
606	   (const_string "unknown")
607	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
608	      (and (match_operand 0 "memory_displacement_operand" "")
609		   (match_operand 1 "immediate_operand" "")))
610	   (const_string "true")
611	 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
612	      (and (match_operand 0 "memory_displacement_operand" "")
613		   (match_operand 2 "immediate_operand" "")))
614	   (const_string "true")
615	]
616	(const_string "false")))
617
618;; Indicates if an FP operation has an integer source.
619
620(define_attr "fp_int_src" "false,true"
621  (const_string "false"))
622
623;; Defines rounding mode of an FP operation.
624
625(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
626  (const_string "any"))
627
628;; Define attribute to classify add/sub insns that consumes carry flag (CF)
629(define_attr "use_carry" "0,1" (const_string "0"))
630
631;; Define attribute to indicate unaligned ssemov insns
632(define_attr "movu" "0,1" (const_string "0"))
633
634;; Used to control the "enabled" attribute on a per-instruction basis.
635(define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
636		    bmi2,fma4,fma"
637  (const_string "base"))
638
639(define_attr "enabled" ""
640  (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
641	 (eq_attr "isa" "sse2_noavx")
642	   (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
643	 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
644	 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
645	 (eq_attr "isa" "sse4_noavx")
646	   (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
647	 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
648	 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
649	 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
650	 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
651	 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
652	]
653	(const_int 1)))
654
655;; Describe a user's asm statement.
656(define_asm_attributes
657  [(set_attr "length" "128")
658   (set_attr "type" "multi")])
659
660(define_code_iterator plusminus [plus minus])
661
662(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
663
664;; Base name for define_insn
665(define_code_attr plusminus_insn
666  [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
667   (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
668
669;; Base name for insn mnemonic.
670(define_code_attr plusminus_mnemonic
671  [(plus "add") (ss_plus "adds") (us_plus "addus")
672   (minus "sub") (ss_minus "subs") (us_minus "subus")])
673(define_code_attr plusminus_carry_mnemonic
674  [(plus "adc") (minus "sbb")])
675
676;; Mark commutative operators as such in constraints.
677(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
678			(minus "") (ss_minus "") (us_minus "")])
679
680;; Mapping of max and min
681(define_code_iterator maxmin [smax smin umax umin])
682
683;; Mapping of signed max and min
684(define_code_iterator smaxmin [smax smin])
685
686;; Mapping of unsigned max and min
687(define_code_iterator umaxmin [umax umin])
688
689;; Base name for integer and FP insn mnemonic
690(define_code_attr maxmin_int [(smax "maxs") (smin "mins")
691			      (umax "maxu") (umin "minu")])
692(define_code_attr maxmin_float [(smax "max") (smin "min")])
693
694;; Mapping of logic operators
695(define_code_iterator any_logic [and ior xor])
696(define_code_iterator any_or [ior xor])
697
698;; Base name for insn mnemonic.
699(define_code_attr logic [(and "and") (ior "or") (xor "xor")])
700
701;; Mapping of logic-shift operators
702(define_code_iterator any_lshift [ashift lshiftrt])
703
704;; Mapping of shift-right operators
705(define_code_iterator any_shiftrt [lshiftrt ashiftrt])
706
707;; Base name for define_insn
708(define_code_attr shift_insn
709  [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
710
711;; Base name for insn mnemonic.
712(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
713(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
714
715;; Mapping of rotate operators
716(define_code_iterator any_rotate [rotate rotatert])
717
718;; Base name for define_insn
719(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
720
721;; Base name for insn mnemonic.
722(define_code_attr rotate [(rotate "rol") (rotatert "ror")])
723
724;; Mapping of abs neg operators
725(define_code_iterator absneg [abs neg])
726
727;; Base name for x87 insn mnemonic.
728(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
729
730;; Used in signed and unsigned widening multiplications.
731(define_code_iterator any_extend [sign_extend zero_extend])
732
733;; Prefix for insn menmonic.
734(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
735
736;; Prefix for define_insn
737(define_code_attr u [(sign_extend "") (zero_extend "u")])
738(define_code_attr s [(sign_extend "s") (zero_extend "u")])
739
740;; All integer modes.
741(define_mode_iterator SWI1248x [QI HI SI DI])
742
743;; All integer modes without QImode.
744(define_mode_iterator SWI248x [HI SI DI])
745
746;; All integer modes without QImode and HImode.
747(define_mode_iterator SWI48x [SI DI])
748
749;; All integer modes without SImode and DImode.
750(define_mode_iterator SWI12 [QI HI])
751
752;; All integer modes without DImode.
753(define_mode_iterator SWI124 [QI HI SI])
754
755;; All integer modes without QImode and DImode.
756(define_mode_iterator SWI24 [HI SI])
757
758;; Single word integer modes.
759(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
760
761;; Single word integer modes without QImode.
762(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
763
764;; Single word integer modes without QImode and HImode.
765(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
766
767;; All math-dependant single and double word integer modes.
768(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
769			     (HI "TARGET_HIMODE_MATH")
770			     SI DI (TI "TARGET_64BIT")])
771
772;; Math-dependant single word integer modes.
773(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
774			    (HI "TARGET_HIMODE_MATH")
775			    SI (DI "TARGET_64BIT")])
776
777;; Math-dependant integer modes without DImode.
778(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
779			       (HI "TARGET_HIMODE_MATH")
780			       SI])
781
782;; Math-dependant single word integer modes without QImode.
783(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
784		      	       SI (DI "TARGET_64BIT")])
785
786;; Double word integer modes.
787(define_mode_iterator DWI [(DI "!TARGET_64BIT")
788			   (TI "TARGET_64BIT")])
789
790;; Double word integer modes as mode attribute.
791(define_mode_attr DWI [(SI "DI") (DI "TI")])
792(define_mode_attr dwi [(SI "di") (DI "ti")])
793
794;; Half mode for double word integer modes.
795(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
796			    (DI "TARGET_64BIT")])
797
798;; Instruction suffix for integer modes.
799(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
800
801;; Pointer size prefix for integer modes (Intel asm dialect)
802(define_mode_attr iptrsize [(QI "BYTE")
803			    (HI "WORD")
804			    (SI "DWORD")
805			    (DI "QWORD")])
806
807;; Register class for integer modes.
808(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
809
810;; Immediate operand constraint for integer modes.
811(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
812
813;; General operand constraint for word modes.
814(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
815
816;; Immediate operand constraint for double integer modes.
817(define_mode_attr di [(SI "nF") (DI "e")])
818
819;; Immediate operand constraint for shifts.
820(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
821
822;; General operand predicate for integer modes.
823(define_mode_attr general_operand
824	[(QI "general_operand")
825	 (HI "general_operand")
826	 (SI "x86_64_general_operand")
827	 (DI "x86_64_general_operand")
828	 (TI "x86_64_general_operand")])
829
830;; General sign/zero extend operand predicate for integer modes.
831(define_mode_attr general_szext_operand
832	[(QI "general_operand")
833	 (HI "general_operand")
834	 (SI "x86_64_szext_general_operand")
835	 (DI "x86_64_szext_general_operand")])
836
837;; Immediate operand predicate for integer modes.
838(define_mode_attr immediate_operand
839	[(QI "immediate_operand")
840	 (HI "immediate_operand")
841	 (SI "x86_64_immediate_operand")
842	 (DI "x86_64_immediate_operand")])
843
844;; Nonmemory operand predicate for integer modes.
845(define_mode_attr nonmemory_operand
846	[(QI "nonmemory_operand")
847	 (HI "nonmemory_operand")
848	 (SI "x86_64_nonmemory_operand")
849	 (DI "x86_64_nonmemory_operand")])
850
851;; Operand predicate for shifts.
852(define_mode_attr shift_operand
853	[(QI "nonimmediate_operand")
854	 (HI "nonimmediate_operand")
855	 (SI "nonimmediate_operand")
856	 (DI "shiftdi_operand")
857	 (TI "register_operand")])
858
859;; Operand predicate for shift argument.
860(define_mode_attr shift_immediate_operand
861	[(QI "const_1_to_31_operand")
862	 (HI "const_1_to_31_operand")
863	 (SI "const_1_to_31_operand")
864	 (DI "const_1_to_63_operand")])
865
866;; Input operand predicate for arithmetic left shifts.
867(define_mode_attr ashl_input_operand
868	[(QI "nonimmediate_operand")
869	 (HI "nonimmediate_operand")
870	 (SI "nonimmediate_operand")
871	 (DI "ashldi_input_operand")
872	 (TI "reg_or_pm1_operand")])
873
874;; SSE and x87 SFmode and DFmode floating point modes
875(define_mode_iterator MODEF [SF DF])
876
877;; All x87 floating point modes
878(define_mode_iterator X87MODEF [SF DF XF])
879
880;; SSE instruction suffix for various modes
881(define_mode_attr ssemodesuffix
882  [(SF "ss") (DF "sd")
883   (V8SF "ps") (V4DF "pd")
884   (V4SF "ps") (V2DF "pd")
885   (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
886   (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
887
888;; SSE vector suffix for floating point modes
889(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
890
891;; SSE vector mode corresponding to a scalar mode
892(define_mode_attr ssevecmode
893  [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
894
895;; Instruction suffix for REX 64bit operators.
896(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
897
898;; This mode iterator allows :P to be used for patterns that operate on
899;; pointer-sized quantities.  Exactly one of the two alternatives will match.
900(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
901
902;; This mode iterator allows :PTR to be used for patterns that operate on
903;; ptr_mode sized quantities.
904(define_mode_iterator PTR
905  [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
906
907;; Scheduling descriptions
908
909(include "pentium.md")
910(include "ppro.md")
911(include "k6.md")
912(include "athlon.md")
913(include "bdver1.md")
914(include "geode.md")
915(include "atom.md")
916(include "core2.md")
917
918
919;; Operand and operator predicates and constraints
920
921(include "predicates.md")
922(include "constraints.md")
923
924
925;; Compare and branch/compare and store instructions.
926
927(define_expand "cbranch<mode>4"
928  [(set (reg:CC FLAGS_REG)
929	(compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
930		    (match_operand:SDWIM 2 "<general_operand>" "")))
931   (set (pc) (if_then_else
932	       (match_operator 0 "ordered_comparison_operator"
933		[(reg:CC FLAGS_REG) (const_int 0)])
934	       (label_ref (match_operand 3 "" ""))
935	       (pc)))]
936  ""
937{
938  if (MEM_P (operands[1]) && MEM_P (operands[2]))
939    operands[1] = force_reg (<MODE>mode, operands[1]);
940  ix86_expand_branch (GET_CODE (operands[0]),
941		      operands[1], operands[2], operands[3]);
942  DONE;
943})
944
945(define_expand "cstore<mode>4"
946  [(set (reg:CC FLAGS_REG)
947	(compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
948		    (match_operand:SWIM 3 "<general_operand>" "")))
949   (set (match_operand:QI 0 "register_operand" "")
950	(match_operator 1 "ordered_comparison_operator"
951	  [(reg:CC FLAGS_REG) (const_int 0)]))]
952  ""
953{
954  if (MEM_P (operands[2]) && MEM_P (operands[3]))
955    operands[2] = force_reg (<MODE>mode, operands[2]);
956  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
957		     operands[2], operands[3]);
958  DONE;
959})
960
961(define_expand "cmp<mode>_1"
962  [(set (reg:CC FLAGS_REG)
963	(compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
964		    (match_operand:SWI48 1 "<general_operand>" "")))])
965
966(define_insn "*cmp<mode>_ccno_1"
967  [(set (reg FLAGS_REG)
968	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
969		 (match_operand:SWI 1 "const0_operand" "")))]
970  "ix86_match_ccmode (insn, CCNOmode)"
971  "@
972   test{<imodesuffix>}\t%0, %0
973   cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
974  [(set_attr "type" "test,icmp")
975   (set_attr "length_immediate" "0,1")
976   (set_attr "mode" "<MODE>")])
977
978(define_insn "*cmp<mode>_1"
979  [(set (reg FLAGS_REG)
980	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
981		 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
982  "ix86_match_ccmode (insn, CCmode)"
983  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
984  [(set_attr "type" "icmp")
985   (set_attr "mode" "<MODE>")])
986
987(define_insn "*cmp<mode>_minus_1"
988  [(set (reg FLAGS_REG)
989	(compare
990	  (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
991		     (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
992	  (const_int 0)))]
993  "ix86_match_ccmode (insn, CCGOCmode)"
994  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
995  [(set_attr "type" "icmp")
996   (set_attr "mode" "<MODE>")])
997
998(define_insn "*cmpqi_ext_1"
999  [(set (reg FLAGS_REG)
1000	(compare
1001	  (match_operand:QI 0 "general_operand" "Qm")
1002	  (subreg:QI
1003	    (zero_extract:SI
1004	      (match_operand 1 "ext_register_operand" "Q")
1005	      (const_int 8)
1006	      (const_int 8)) 0)))]
1007  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1008  "cmp{b}\t{%h1, %0|%0, %h1}"
1009  [(set_attr "type" "icmp")
1010   (set_attr "mode" "QI")])
1011
1012(define_insn "*cmpqi_ext_1_rex64"
1013  [(set (reg FLAGS_REG)
1014	(compare
1015	  (match_operand:QI 0 "register_operand" "Q")
1016	  (subreg:QI
1017	    (zero_extract:SI
1018	      (match_operand 1 "ext_register_operand" "Q")
1019	      (const_int 8)
1020	      (const_int 8)) 0)))]
1021  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1022  "cmp{b}\t{%h1, %0|%0, %h1}"
1023  [(set_attr "type" "icmp")
1024   (set_attr "mode" "QI")])
1025
1026(define_insn "*cmpqi_ext_2"
1027  [(set (reg FLAGS_REG)
1028	(compare
1029	  (subreg:QI
1030	    (zero_extract:SI
1031	      (match_operand 0 "ext_register_operand" "Q")
1032	      (const_int 8)
1033	      (const_int 8)) 0)
1034	  (match_operand:QI 1 "const0_operand" "")))]
1035  "ix86_match_ccmode (insn, CCNOmode)"
1036  "test{b}\t%h0, %h0"
1037  [(set_attr "type" "test")
1038   (set_attr "length_immediate" "0")
1039   (set_attr "mode" "QI")])
1040
1041(define_expand "cmpqi_ext_3"
1042  [(set (reg:CC FLAGS_REG)
1043	(compare:CC
1044	  (subreg:QI
1045	    (zero_extract:SI
1046	      (match_operand 0 "ext_register_operand" "")
1047	      (const_int 8)
1048	      (const_int 8)) 0)
1049	  (match_operand:QI 1 "immediate_operand" "")))])
1050
1051(define_insn "*cmpqi_ext_3_insn"
1052  [(set (reg FLAGS_REG)
1053	(compare
1054	  (subreg:QI
1055	    (zero_extract:SI
1056	      (match_operand 0 "ext_register_operand" "Q")
1057	      (const_int 8)
1058	      (const_int 8)) 0)
1059	  (match_operand:QI 1 "general_operand" "Qmn")))]
1060  "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1061  "cmp{b}\t{%1, %h0|%h0, %1}"
1062  [(set_attr "type" "icmp")
1063   (set_attr "modrm" "1")
1064   (set_attr "mode" "QI")])
1065
1066(define_insn "*cmpqi_ext_3_insn_rex64"
1067  [(set (reg FLAGS_REG)
1068	(compare
1069	  (subreg:QI
1070	    (zero_extract:SI
1071	      (match_operand 0 "ext_register_operand" "Q")
1072	      (const_int 8)
1073	      (const_int 8)) 0)
1074	  (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1075  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076  "cmp{b}\t{%1, %h0|%h0, %1}"
1077  [(set_attr "type" "icmp")
1078   (set_attr "modrm" "1")
1079   (set_attr "mode" "QI")])
1080
1081(define_insn "*cmpqi_ext_4"
1082  [(set (reg FLAGS_REG)
1083	(compare
1084	  (subreg:QI
1085	    (zero_extract:SI
1086	      (match_operand 0 "ext_register_operand" "Q")
1087	      (const_int 8)
1088	      (const_int 8)) 0)
1089	  (subreg:QI
1090	    (zero_extract:SI
1091	      (match_operand 1 "ext_register_operand" "Q")
1092	      (const_int 8)
1093	      (const_int 8)) 0)))]
1094  "ix86_match_ccmode (insn, CCmode)"
1095  "cmp{b}\t{%h1, %h0|%h0, %h1}"
1096  [(set_attr "type" "icmp")
1097   (set_attr "mode" "QI")])
1098
1099;; These implement float point compares.
1100;; %%% See if we can get away with VOIDmode operands on the actual insns,
1101;; which would allow mix and match FP modes on the compares.  Which is what
1102;; the old patterns did, but with many more of them.
1103
1104(define_expand "cbranchxf4"
1105  [(set (reg:CC FLAGS_REG)
1106	(compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1107		    (match_operand:XF 2 "nonmemory_operand" "")))
1108   (set (pc) (if_then_else
1109              (match_operator 0 "ix86_fp_comparison_operator"
1110               [(reg:CC FLAGS_REG)
1111                (const_int 0)])
1112              (label_ref (match_operand 3 "" ""))
1113              (pc)))]
1114  "TARGET_80387"
1115{
1116  ix86_expand_branch (GET_CODE (operands[0]),
1117		      operands[1], operands[2], operands[3]);
1118  DONE;
1119})
1120
1121(define_expand "cstorexf4"
1122  [(set (reg:CC FLAGS_REG)
1123	(compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1124		    (match_operand:XF 3 "nonmemory_operand" "")))
1125   (set (match_operand:QI 0 "register_operand" "")
1126              (match_operator 1 "ix86_fp_comparison_operator"
1127               [(reg:CC FLAGS_REG)
1128                (const_int 0)]))]
1129  "TARGET_80387"
1130{
1131  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1132		     operands[2], operands[3]);
1133  DONE;
1134})
1135
1136(define_expand "cbranch<mode>4"
1137  [(set (reg:CC FLAGS_REG)
1138	(compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1139		    (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1140   (set (pc) (if_then_else
1141              (match_operator 0 "ix86_fp_comparison_operator"
1142               [(reg:CC FLAGS_REG)
1143                (const_int 0)])
1144              (label_ref (match_operand 3 "" ""))
1145              (pc)))]
1146  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1147{
1148  ix86_expand_branch (GET_CODE (operands[0]),
1149		      operands[1], operands[2], operands[3]);
1150  DONE;
1151})
1152
1153(define_expand "cstore<mode>4"
1154  [(set (reg:CC FLAGS_REG)
1155	(compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1156		    (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1157   (set (match_operand:QI 0 "register_operand" "")
1158              (match_operator 1 "ix86_fp_comparison_operator"
1159               [(reg:CC FLAGS_REG)
1160                (const_int 0)]))]
1161  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1162{
1163  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1164		     operands[2], operands[3]);
1165  DONE;
1166})
1167
1168(define_expand "cbranchcc4"
1169  [(set (pc) (if_then_else
1170              (match_operator 0 "comparison_operator"
1171               [(match_operand 1 "flags_reg_operand" "")
1172                (match_operand 2 "const0_operand" "")])
1173              (label_ref (match_operand 3 "" ""))
1174              (pc)))]
1175  ""
1176{
1177  ix86_expand_branch (GET_CODE (operands[0]),
1178		      operands[1], operands[2], operands[3]);
1179  DONE;
1180})
1181
1182(define_expand "cstorecc4"
1183  [(set (match_operand:QI 0 "register_operand" "")
1184              (match_operator 1 "comparison_operator"
1185               [(match_operand 2 "flags_reg_operand" "")
1186                (match_operand 3 "const0_operand" "")]))]
1187  ""
1188{
1189  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1190		     operands[2], operands[3]);
1191  DONE;
1192})
1193
1194
1195;; FP compares, step 1:
1196;; Set the FP condition codes.
1197;;
1198;; CCFPmode	compare with exceptions
1199;; CCFPUmode	compare with no exceptions
1200
1201;; We may not use "#" to split and emit these, since the REG_DEAD notes
1202;; used to manage the reg stack popping would not be preserved.
1203
1204(define_insn "*cmpfp_0"
1205  [(set (match_operand:HI 0 "register_operand" "=a")
1206	(unspec:HI
1207	  [(compare:CCFP
1208	     (match_operand 1 "register_operand" "f")
1209	     (match_operand 2 "const0_operand" ""))]
1210	UNSPEC_FNSTSW))]
1211  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213  "* return output_fp_compare (insn, operands, false, false);"
1214  [(set_attr "type" "multi")
1215   (set_attr "unit" "i387")
1216   (set (attr "mode")
1217     (cond [(match_operand:SF 1 "" "")
1218	      (const_string "SF")
1219	    (match_operand:DF 1 "" "")
1220	      (const_string "DF")
1221	   ]
1222	   (const_string "XF")))])
1223
1224(define_insn_and_split "*cmpfp_0_cc"
1225  [(set (reg:CCFP FLAGS_REG)
1226	(compare:CCFP
1227	  (match_operand 1 "register_operand" "f")
1228	  (match_operand 2 "const0_operand" "")))
1229   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231   && TARGET_SAHF && !TARGET_CMOVE
1232   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1233  "#"
1234  "&& reload_completed"
1235  [(set (match_dup 0)
1236	(unspec:HI
1237	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1238	UNSPEC_FNSTSW))
1239   (set (reg:CC FLAGS_REG)
1240	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1241  ""
1242  [(set_attr "type" "multi")
1243   (set_attr "unit" "i387")
1244   (set (attr "mode")
1245     (cond [(match_operand:SF 1 "" "")
1246	      (const_string "SF")
1247	    (match_operand:DF 1 "" "")
1248	      (const_string "DF")
1249	   ]
1250	   (const_string "XF")))])
1251
1252(define_insn "*cmpfp_xf"
1253  [(set (match_operand:HI 0 "register_operand" "=a")
1254	(unspec:HI
1255	  [(compare:CCFP
1256	     (match_operand:XF 1 "register_operand" "f")
1257	     (match_operand:XF 2 "register_operand" "f"))]
1258	  UNSPEC_FNSTSW))]
1259  "TARGET_80387"
1260  "* return output_fp_compare (insn, operands, false, false);"
1261  [(set_attr "type" "multi")
1262   (set_attr "unit" "i387")
1263   (set_attr "mode" "XF")])
1264
1265(define_insn_and_split "*cmpfp_xf_cc"
1266  [(set (reg:CCFP FLAGS_REG)
1267	(compare:CCFP
1268	  (match_operand:XF 1 "register_operand" "f")
1269	  (match_operand:XF 2 "register_operand" "f")))
1270   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1271  "TARGET_80387
1272   && TARGET_SAHF && !TARGET_CMOVE"
1273  "#"
1274  "&& reload_completed"
1275  [(set (match_dup 0)
1276	(unspec:HI
1277	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1278	UNSPEC_FNSTSW))
1279   (set (reg:CC FLAGS_REG)
1280	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1281  ""
1282  [(set_attr "type" "multi")
1283   (set_attr "unit" "i387")
1284   (set_attr "mode" "XF")])
1285
1286(define_insn "*cmpfp_<mode>"
1287  [(set (match_operand:HI 0 "register_operand" "=a")
1288	(unspec:HI
1289	  [(compare:CCFP
1290	     (match_operand:MODEF 1 "register_operand" "f")
1291	     (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1292	  UNSPEC_FNSTSW))]
1293  "TARGET_80387"
1294  "* return output_fp_compare (insn, operands, false, false);"
1295  [(set_attr "type" "multi")
1296   (set_attr "unit" "i387")
1297   (set_attr "mode" "<MODE>")])
1298
1299(define_insn_and_split "*cmpfp_<mode>_cc"
1300  [(set (reg:CCFP FLAGS_REG)
1301	(compare:CCFP
1302	  (match_operand:MODEF 1 "register_operand" "f")
1303	  (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1304   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1305  "TARGET_80387
1306   && TARGET_SAHF && !TARGET_CMOVE"
1307  "#"
1308  "&& reload_completed"
1309  [(set (match_dup 0)
1310	(unspec:HI
1311	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1312	UNSPEC_FNSTSW))
1313   (set (reg:CC FLAGS_REG)
1314	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1315  ""
1316  [(set_attr "type" "multi")
1317   (set_attr "unit" "i387")
1318   (set_attr "mode" "<MODE>")])
1319
1320(define_insn "*cmpfp_u"
1321  [(set (match_operand:HI 0 "register_operand" "=a")
1322	(unspec:HI
1323	  [(compare:CCFPU
1324	     (match_operand 1 "register_operand" "f")
1325	     (match_operand 2 "register_operand" "f"))]
1326	  UNSPEC_FNSTSW))]
1327  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1328   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1329  "* return output_fp_compare (insn, operands, false, true);"
1330  [(set_attr "type" "multi")
1331   (set_attr "unit" "i387")
1332   (set (attr "mode")
1333     (cond [(match_operand:SF 1 "" "")
1334	      (const_string "SF")
1335	    (match_operand:DF 1 "" "")
1336	      (const_string "DF")
1337	   ]
1338	   (const_string "XF")))])
1339
1340(define_insn_and_split "*cmpfp_u_cc"
1341  [(set (reg:CCFPU FLAGS_REG)
1342	(compare:CCFPU
1343	  (match_operand 1 "register_operand" "f")
1344	  (match_operand 2 "register_operand" "f")))
1345   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1346  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1347   && TARGET_SAHF && !TARGET_CMOVE
1348   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1349  "#"
1350  "&& reload_completed"
1351  [(set (match_dup 0)
1352	(unspec:HI
1353	  [(compare:CCFPU (match_dup 1)(match_dup 2))]
1354	UNSPEC_FNSTSW))
1355   (set (reg:CC FLAGS_REG)
1356	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1357  ""
1358  [(set_attr "type" "multi")
1359   (set_attr "unit" "i387")
1360   (set (attr "mode")
1361     (cond [(match_operand:SF 1 "" "")
1362	      (const_string "SF")
1363	    (match_operand:DF 1 "" "")
1364	      (const_string "DF")
1365	   ]
1366	   (const_string "XF")))])
1367
1368(define_insn "*cmpfp_<mode>"
1369  [(set (match_operand:HI 0 "register_operand" "=a")
1370	(unspec:HI
1371	  [(compare:CCFP
1372	     (match_operand 1 "register_operand" "f")
1373	     (match_operator 3 "float_operator"
1374	       [(match_operand:SWI24 2 "memory_operand" "m")]))]
1375	  UNSPEC_FNSTSW))]
1376  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1377   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1378   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1379  "* return output_fp_compare (insn, operands, false, false);"
1380  [(set_attr "type" "multi")
1381   (set_attr "unit" "i387")
1382   (set_attr "fp_int_src" "true")
1383   (set_attr "mode" "<MODE>")])
1384
1385(define_insn_and_split "*cmpfp_<mode>_cc"
1386  [(set (reg:CCFP FLAGS_REG)
1387	(compare:CCFP
1388	  (match_operand 1 "register_operand" "f")
1389	  (match_operator 3 "float_operator"
1390	    [(match_operand:SWI24 2 "memory_operand" "m")])))
1391   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1392  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1393   && TARGET_SAHF && !TARGET_CMOVE
1394   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1395   && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1396  "#"
1397  "&& reload_completed"
1398  [(set (match_dup 0)
1399	(unspec:HI
1400	  [(compare:CCFP
1401	     (match_dup 1)
1402	     (match_op_dup 3 [(match_dup 2)]))]
1403	UNSPEC_FNSTSW))
1404   (set (reg:CC FLAGS_REG)
1405	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1406  ""
1407  [(set_attr "type" "multi")
1408   (set_attr "unit" "i387")
1409   (set_attr "fp_int_src" "true")
1410   (set_attr "mode" "<MODE>")])
1411
1412;; FP compares, step 2
1413;; Move the fpsw to ax.
1414
1415(define_insn "x86_fnstsw_1"
1416  [(set (match_operand:HI 0 "register_operand" "=a")
1417	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1418  "TARGET_80387"
1419  "fnstsw\t%0"
1420  [(set (attr "length")
1421	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1422   (set_attr "mode" "SI")
1423   (set_attr "unit" "i387")])
1424
1425;; FP compares, step 3
1426;; Get ax into flags, general case.
1427
1428(define_insn "x86_sahf_1"
1429  [(set (reg:CC FLAGS_REG)
1430	(unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1431		   UNSPEC_SAHF))]
1432  "TARGET_SAHF"
1433{
1434#ifndef HAVE_AS_IX86_SAHF
1435  if (TARGET_64BIT)
1436    return ASM_BYTE "0x9e";
1437  else
1438#endif
1439  return "sahf";
1440}
1441  [(set_attr "length" "1")
1442   (set_attr "athlon_decode" "vector")
1443   (set_attr "amdfam10_decode" "direct")
1444   (set_attr "bdver1_decode" "direct")
1445   (set_attr "mode" "SI")])
1446
1447;; Pentium Pro can do steps 1 through 3 in one go.
1448;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1449;; (these i387 instructions set flags directly)
1450(define_insn "*cmpfp_i_mixed"
1451  [(set (reg:CCFP FLAGS_REG)
1452	(compare:CCFP (match_operand 0 "register_operand" "f,x")
1453		      (match_operand 1 "nonimmediate_operand" "f,xm")))]
1454  "TARGET_MIX_SSE_I387
1455   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1456   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1457  "* return output_fp_compare (insn, operands, true, false);"
1458  [(set_attr "type" "fcmp,ssecomi")
1459   (set_attr "prefix" "orig,maybe_vex")
1460   (set (attr "mode")
1461     (if_then_else (match_operand:SF 1 "" "")
1462        (const_string "SF")
1463        (const_string "DF")))
1464   (set (attr "prefix_rep")
1465	(if_then_else (eq_attr "type" "ssecomi")
1466		      (const_string "0")
1467		      (const_string "*")))
1468   (set (attr "prefix_data16")
1469	(cond [(eq_attr "type" "fcmp")
1470		 (const_string "*")
1471	       (eq_attr "mode" "DF")
1472		 (const_string "1")
1473	      ]
1474	      (const_string "0")))
1475   (set_attr "athlon_decode" "vector")
1476   (set_attr "amdfam10_decode" "direct")
1477   (set_attr "bdver1_decode" "double")])
1478
1479(define_insn "*cmpfp_i_sse"
1480  [(set (reg:CCFP FLAGS_REG)
1481	(compare:CCFP (match_operand 0 "register_operand" "x")
1482		      (match_operand 1 "nonimmediate_operand" "xm")))]
1483  "TARGET_SSE_MATH
1484   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1485   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1486  "* return output_fp_compare (insn, operands, true, false);"
1487  [(set_attr "type" "ssecomi")
1488   (set_attr "prefix" "maybe_vex")
1489   (set (attr "mode")
1490     (if_then_else (match_operand:SF 1 "" "")
1491        (const_string "SF")
1492        (const_string "DF")))
1493   (set_attr "prefix_rep" "0")
1494   (set (attr "prefix_data16")
1495	(if_then_else (eq_attr "mode" "DF")
1496		      (const_string "1")
1497		      (const_string "0")))
1498   (set_attr "athlon_decode" "vector")
1499   (set_attr "amdfam10_decode" "direct")
1500   (set_attr "bdver1_decode" "double")])
1501
1502(define_insn "*cmpfp_i_i387"
1503  [(set (reg:CCFP FLAGS_REG)
1504	(compare:CCFP (match_operand 0 "register_operand" "f")
1505		      (match_operand 1 "register_operand" "f")))]
1506  "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1507   && TARGET_CMOVE
1508   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1509   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510  "* return output_fp_compare (insn, operands, true, false);"
1511  [(set_attr "type" "fcmp")
1512   (set (attr "mode")
1513     (cond [(match_operand:SF 1 "" "")
1514	      (const_string "SF")
1515	    (match_operand:DF 1 "" "")
1516	      (const_string "DF")
1517	   ]
1518	   (const_string "XF")))
1519   (set_attr "athlon_decode" "vector")
1520   (set_attr "amdfam10_decode" "direct")
1521   (set_attr "bdver1_decode" "double")])
1522
1523(define_insn "*cmpfp_iu_mixed"
1524  [(set (reg:CCFPU FLAGS_REG)
1525	(compare:CCFPU (match_operand 0 "register_operand" "f,x")
1526		       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1527  "TARGET_MIX_SSE_I387
1528   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1529   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1530  "* return output_fp_compare (insn, operands, true, true);"
1531  [(set_attr "type" "fcmp,ssecomi")
1532   (set_attr "prefix" "orig,maybe_vex")
1533   (set (attr "mode")
1534     (if_then_else (match_operand:SF 1 "" "")
1535        (const_string "SF")
1536        (const_string "DF")))
1537   (set (attr "prefix_rep")
1538	(if_then_else (eq_attr "type" "ssecomi")
1539		      (const_string "0")
1540		      (const_string "*")))
1541   (set (attr "prefix_data16")
1542	(cond [(eq_attr "type" "fcmp")
1543		 (const_string "*")
1544	       (eq_attr "mode" "DF")
1545		 (const_string "1")
1546	      ]
1547	      (const_string "0")))
1548   (set_attr "athlon_decode" "vector")
1549   (set_attr "amdfam10_decode" "direct")
1550   (set_attr "bdver1_decode" "double")])
1551
1552(define_insn "*cmpfp_iu_sse"
1553  [(set (reg:CCFPU FLAGS_REG)
1554	(compare:CCFPU (match_operand 0 "register_operand" "x")
1555		       (match_operand 1 "nonimmediate_operand" "xm")))]
1556  "TARGET_SSE_MATH
1557   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1558   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1559  "* return output_fp_compare (insn, operands, true, true);"
1560  [(set_attr "type" "ssecomi")
1561   (set_attr "prefix" "maybe_vex")
1562   (set (attr "mode")
1563     (if_then_else (match_operand:SF 1 "" "")
1564        (const_string "SF")
1565        (const_string "DF")))
1566   (set_attr "prefix_rep" "0")
1567   (set (attr "prefix_data16")
1568	(if_then_else (eq_attr "mode" "DF")
1569		      (const_string "1")
1570		      (const_string "0")))
1571   (set_attr "athlon_decode" "vector")
1572   (set_attr "amdfam10_decode" "direct")
1573   (set_attr "bdver1_decode" "double")])
1574
1575(define_insn "*cmpfp_iu_387"
1576  [(set (reg:CCFPU FLAGS_REG)
1577	(compare:CCFPU (match_operand 0 "register_operand" "f")
1578		       (match_operand 1 "register_operand" "f")))]
1579  "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1580   && TARGET_CMOVE
1581   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1582   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583  "* return output_fp_compare (insn, operands, true, true);"
1584  [(set_attr "type" "fcmp")
1585   (set (attr "mode")
1586     (cond [(match_operand:SF 1 "" "")
1587	      (const_string "SF")
1588	    (match_operand:DF 1 "" "")
1589	      (const_string "DF")
1590	   ]
1591	   (const_string "XF")))
1592   (set_attr "athlon_decode" "vector")
1593   (set_attr "amdfam10_decode" "direct")
1594   (set_attr "bdver1_decode" "direct")])
1595
1596;; Push/pop instructions.
1597
1598(define_insn "*push<mode>2"
1599  [(set (match_operand:DWI 0 "push_operand" "=<")
1600	(match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1601  ""
1602  "#"
1603  [(set_attr "type" "multi")
1604   (set_attr "mode" "<MODE>")])
1605
1606(define_split
1607  [(set (match_operand:TI 0 "push_operand" "")
1608        (match_operand:TI 1 "general_operand" ""))]
1609  "TARGET_64BIT && reload_completed
1610   && !SSE_REG_P (operands[1])"
1611  [(const_int 0)]
1612  "ix86_split_long_move (operands); DONE;")
1613
1614(define_insn "*pushdi2_rex64"
1615  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1616	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1617  "TARGET_64BIT"
1618  "@
1619   push{q}\t%1
1620   #"
1621  [(set_attr "type" "push,multi")
1622   (set_attr "mode" "DI")])
1623
1624;; Convert impossible pushes of immediate to existing instructions.
1625;; First try to get scratch register and go through it.  In case this
1626;; fails, push sign extended lower part first and then overwrite
1627;; upper part by 32bit move.
1628(define_peephole2
1629  [(match_scratch:DI 2 "r")
1630   (set (match_operand:DI 0 "push_operand" "")
1631        (match_operand:DI 1 "immediate_operand" ""))]
1632  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1633   && !x86_64_immediate_operand (operands[1], DImode)"
1634  [(set (match_dup 2) (match_dup 1))
1635   (set (match_dup 0) (match_dup 2))])
1636
1637;; We need to define this as both peepholer and splitter for case
1638;; peephole2 pass is not run.
1639;; "&& 1" is needed to keep it from matching the previous pattern.
1640(define_peephole2
1641  [(set (match_operand:DI 0 "push_operand" "")
1642        (match_operand:DI 1 "immediate_operand" ""))]
1643  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1644   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1645  [(set (match_dup 0) (match_dup 1))
1646   (set (match_dup 2) (match_dup 3))]
1647{
1648  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1649
1650  operands[1] = gen_lowpart (DImode, operands[2]);
1651  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1652						   GEN_INT (4)));
1653})
1654
1655(define_split
1656  [(set (match_operand:DI 0 "push_operand" "")
1657        (match_operand:DI 1 "immediate_operand" ""))]
1658  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1659		    ? epilogue_completed : reload_completed)
1660   && !symbolic_operand (operands[1], DImode)
1661   && !x86_64_immediate_operand (operands[1], DImode)"
1662  [(set (match_dup 0) (match_dup 1))
1663   (set (match_dup 2) (match_dup 3))]
1664{
1665  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1666
1667  operands[1] = gen_lowpart (DImode, operands[2]);
1668  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1669						   GEN_INT (4)));
1670})
1671
1672(define_split
1673  [(set (match_operand:DI 0 "push_operand" "")
1674        (match_operand:DI 1 "general_operand" ""))]
1675  "!TARGET_64BIT && reload_completed
1676   && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1677  [(const_int 0)]
1678  "ix86_split_long_move (operands); DONE;")
1679
1680(define_insn "*pushsi2"
1681  [(set (match_operand:SI 0 "push_operand" "=<")
1682	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1683  "!TARGET_64BIT"
1684  "push{l}\t%1"
1685  [(set_attr "type" "push")
1686   (set_attr "mode" "SI")])
1687
1688;; emit_push_insn when it calls move_by_pieces requires an insn to
1689;; "push a byte/word".  But actually we use pushl, which has the effect
1690;; of rounding the amount pushed up to a word.
1691
1692;; For TARGET_64BIT we always round up to 8 bytes.
1693(define_insn "*push<mode>2_rex64"
1694  [(set (match_operand:SWI124 0 "push_operand" "=X")
1695	(match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1696  "TARGET_64BIT"
1697  "push{q}\t%q1"
1698  [(set_attr "type" "push")
1699   (set_attr "mode" "DI")])
1700
1701(define_insn "*push<mode>2"
1702  [(set (match_operand:SWI12 0 "push_operand" "=X")
1703	(match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1704  "!TARGET_64BIT"
1705  "push{l}\t%k1"
1706  [(set_attr "type" "push")
1707   (set_attr "mode" "SI")])
1708
1709(define_insn "*push<mode>2_prologue"
1710  [(set (match_operand:P 0 "push_operand" "=<")
1711	(match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1712   (clobber (mem:BLK (scratch)))]
1713  ""
1714  "push{<imodesuffix>}\t%1"
1715  [(set_attr "type" "push")
1716   (set_attr "mode" "<MODE>")])
1717
1718(define_insn "*pop<mode>1"
1719  [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1720	(match_operand:P 1 "pop_operand" ">"))]
1721  ""
1722  "pop{<imodesuffix>}\t%0"
1723  [(set_attr "type" "pop")
1724   (set_attr "mode" "<MODE>")])
1725
1726(define_insn "*pop<mode>1_epilogue"
1727  [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1728	(match_operand:P 1 "pop_operand" ">"))
1729   (clobber (mem:BLK (scratch)))]
1730  ""
1731  "pop{<imodesuffix>}\t%0"
1732  [(set_attr "type" "pop")
1733   (set_attr "mode" "<MODE>")])
1734
1735;; Move instructions.
1736
1737(define_expand "movoi"
1738  [(set (match_operand:OI 0 "nonimmediate_operand" "")
1739	(match_operand:OI 1 "general_operand" ""))]
1740  "TARGET_AVX"
1741  "ix86_expand_move (OImode, operands); DONE;")
1742
1743(define_expand "movti"
1744  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1745	(match_operand:TI 1 "nonimmediate_operand" ""))]
1746  "TARGET_64BIT || TARGET_SSE"
1747{
1748  if (TARGET_64BIT)
1749    ix86_expand_move (TImode, operands);
1750  else if (push_operand (operands[0], TImode))
1751    ix86_expand_push (TImode, operands[1]);
1752  else
1753    ix86_expand_vector_move (TImode, operands);
1754  DONE;
1755})
1756
1757;; This expands to what emit_move_complex would generate if we didn't
1758;; have a movti pattern.  Having this avoids problems with reload on
1759;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1760;; to have around all the time.
1761(define_expand "movcdi"
1762  [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1763	(match_operand:CDI 1 "general_operand" ""))]
1764  ""
1765{
1766  if (push_operand (operands[0], CDImode))
1767    emit_move_complex_push (CDImode, operands[0], operands[1]);
1768  else
1769    emit_move_complex_parts (operands[0], operands[1]);
1770  DONE;
1771})
1772
1773(define_expand "mov<mode>"
1774  [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1775	(match_operand:SWI1248x 1 "general_operand" ""))]
1776  ""
1777  "ix86_expand_move (<MODE>mode, operands); DONE;")
1778
1779(define_insn "*mov<mode>_xor"
1780  [(set (match_operand:SWI48 0 "register_operand" "=r")
1781	(match_operand:SWI48 1 "const0_operand" ""))
1782   (clobber (reg:CC FLAGS_REG))]
1783  "reload_completed"
1784  "xor{l}\t%k0, %k0"
1785  [(set_attr "type" "alu1")
1786   (set_attr "mode" "SI")
1787   (set_attr "length_immediate" "0")])
1788
1789(define_insn "*mov<mode>_or"
1790  [(set (match_operand:SWI48 0 "register_operand" "=r")
1791	(match_operand:SWI48 1 "const_int_operand" ""))
1792   (clobber (reg:CC FLAGS_REG))]
1793  "reload_completed
1794   && operands[1] == constm1_rtx"
1795  "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1796  [(set_attr "type" "alu1")
1797   (set_attr "mode" "<MODE>")
1798   (set_attr "length_immediate" "1")])
1799
1800(define_insn "*movoi_internal_avx"
1801  [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1802	(match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1803  "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1804{
1805  switch (which_alternative)
1806    {
1807    case 0:
1808      return standard_sse_constant_opcode (insn, operands[1]);
1809    case 1:
1810    case 2:
1811      if (misaligned_operand (operands[0], OImode)
1812	  || misaligned_operand (operands[1], OImode))
1813	return "vmovdqu\t{%1, %0|%0, %1}";
1814      else
1815	return "vmovdqa\t{%1, %0|%0, %1}";
1816    default:
1817      gcc_unreachable ();
1818    }
1819}
1820  [(set_attr "type" "sselog1,ssemov,ssemov")
1821   (set_attr "prefix" "vex")
1822   (set_attr "mode" "OI")])
1823
1824(define_insn "*movti_internal_rex64"
1825  [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1826	(match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1827  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1828{
1829  switch (which_alternative)
1830    {
1831    case 0:
1832    case 1:
1833      return "#";
1834    case 2:
1835      return standard_sse_constant_opcode (insn, operands[1]);
1836    case 3:
1837    case 4:
1838      /* TDmode values are passed as TImode on the stack.  Moving them
1839	 to stack may result in unaligned memory access.  */
1840      if (misaligned_operand (operands[0], TImode)
1841	  || misaligned_operand (operands[1], TImode))
1842	{
1843	  if (get_attr_mode (insn) == MODE_V4SF)
1844	    return "%vmovups\t{%1, %0|%0, %1}";
1845	  else
1846	    return "%vmovdqu\t{%1, %0|%0, %1}";
1847	}
1848      else
1849	{
1850	  if (get_attr_mode (insn) == MODE_V4SF)
1851	    return "%vmovaps\t{%1, %0|%0, %1}";
1852	  else
1853	    return "%vmovdqa\t{%1, %0|%0, %1}";
1854	}
1855    default:
1856      gcc_unreachable ();
1857    }
1858}
1859  [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1860   (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1861   (set (attr "mode")
1862   	(cond [(eq_attr "alternative" "0,1")
1863		 (const_string "DI")
1864	       (ior (not (match_test "TARGET_SSE2"))
1865		    (match_test "optimize_function_for_size_p (cfun)"))
1866	         (const_string "V4SF")
1867	       (and (eq_attr "alternative" "4")
1868		    (match_test "TARGET_SSE_TYPELESS_STORES"))
1869		 (const_string "V4SF")
1870	       ]
1871	       (const_string "TI")))])
1872
1873(define_split
1874  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1875	(match_operand:TI 1 "general_operand" ""))]
1876  "reload_completed
1877   && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1878  [(const_int 0)]
1879  "ix86_split_long_move (operands); DONE;")
1880
1881(define_insn "*movti_internal_sse"
1882  [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1883	(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1884  "TARGET_SSE && !TARGET_64BIT
1885   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1886{
1887  switch (which_alternative)
1888    {
1889    case 0:
1890      return standard_sse_constant_opcode (insn, operands[1]);
1891    case 1:
1892    case 2:
1893      /* TDmode values are passed as TImode on the stack.  Moving them
1894	 to stack may result in unaligned memory access.  */
1895      if (misaligned_operand (operands[0], TImode)
1896	  || misaligned_operand (operands[1], TImode))
1897	{
1898	  if (get_attr_mode (insn) == MODE_V4SF)
1899	    return "%vmovups\t{%1, %0|%0, %1}";
1900	  else
1901	    return "%vmovdqu\t{%1, %0|%0, %1}";
1902	}
1903      else
1904	{
1905	  if (get_attr_mode (insn) == MODE_V4SF)
1906	    return "%vmovaps\t{%1, %0|%0, %1}";
1907	  else
1908	    return "%vmovdqa\t{%1, %0|%0, %1}";
1909	}
1910    default:
1911      gcc_unreachable ();
1912    }
1913}
1914  [(set_attr "type" "sselog1,ssemov,ssemov")
1915   (set_attr "prefix" "maybe_vex")
1916   (set (attr "mode")
1917	(cond [(ior (not (match_test "TARGET_SSE2"))
1918		    (match_test "optimize_function_for_size_p (cfun)"))
1919		 (const_string "V4SF")
1920	       (and (eq_attr "alternative" "2")
1921		    (match_test "TARGET_SSE_TYPELESS_STORES"))
1922		 (const_string "V4SF")]
1923	      (const_string "TI")))])
1924
1925(define_insn "*movdi_internal_rex64"
1926  [(set (match_operand:DI 0 "nonimmediate_operand"
1927	  "=r,r  ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1928	(match_operand:DI 1 "general_operand"
1929	  "Z ,rem,i,re,C ,*y ,m  ,*Ym,r   ,C ,*x,*x,m ,*Yi,r   ,*Ym,*x"))]
1930  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1931{
1932  switch (get_attr_type (insn))
1933    {
1934    case TYPE_SSECVT:
1935      if (SSE_REG_P (operands[0]))
1936	return "movq2dq\t{%1, %0|%0, %1}";
1937      else
1938	return "movdq2q\t{%1, %0|%0, %1}";
1939
1940    case TYPE_SSEMOV:
1941      if (get_attr_mode (insn) == MODE_TI)
1942	return "%vmovdqa\t{%1, %0|%0, %1}";
1943      /* Handle broken assemblers that require movd instead of movq.  */
1944      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1945	return "%vmovd\t{%1, %0|%0, %1}";
1946      else
1947	return "%vmovq\t{%1, %0|%0, %1}";
1948
1949    case TYPE_MMXMOV:
1950      /* Handle broken assemblers that require movd instead of movq.  */
1951      if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1952	return "movd\t{%1, %0|%0, %1}";
1953      else
1954	return "movq\t{%1, %0|%0, %1}";
1955
1956    case TYPE_SSELOG1:
1957      return standard_sse_constant_opcode (insn, operands[1]);
1958
1959    case TYPE_MMX:
1960      return "pxor\t%0, %0";
1961
1962    case TYPE_LEA:
1963      return "lea{q}\t{%E1, %0|%0, %E1}";
1964
1965    default:
1966      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1967      if (get_attr_mode (insn) == MODE_SI)
1968	return "mov{l}\t{%k1, %k0|%k0, %k1}";
1969      else if (which_alternative == 2)
1970	return "movabs{q}\t{%1, %0|%0, %1}";
1971      else if (ix86_use_lea_for_mov (insn, operands))
1972	return "lea{q}\t{%E1, %0|%0, %E1}";
1973      else
1974	return "mov{q}\t{%1, %0|%0, %1}";
1975    }
1976}
1977  [(set (attr "type")
1978     (cond [(eq_attr "alternative" "4")
1979	      (const_string "mmx")
1980	    (eq_attr "alternative" "5,6,7,8")
1981	      (const_string "mmxmov")
1982	    (eq_attr "alternative" "9")
1983	      (const_string "sselog1")
1984	    (eq_attr "alternative" "10,11,12,13,14")
1985	      (const_string "ssemov")
1986	    (eq_attr "alternative" "15,16")
1987	      (const_string "ssecvt")
1988 	    (match_operand 1 "pic_32bit_operand" "")
1989	      (const_string "lea")
1990	   ]
1991	   (const_string "imov")))
1992   (set (attr "modrm")
1993     (if_then_else
1994       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1995	 (const_string "0")
1996	 (const_string "*")))
1997   (set (attr "length_immediate")
1998     (if_then_else
1999       (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2000	 (const_string "8")
2001	 (const_string "*")))
2002   (set (attr "prefix_rex")
2003     (if_then_else (eq_attr "alternative" "7,8")
2004       (const_string "1")
2005       (const_string "*")))
2006   (set (attr "prefix_data16")
2007     (if_then_else (eq_attr "alternative" "10")
2008       (const_string "1")
2009       (const_string "*")))
2010   (set (attr "prefix")
2011     (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2012       (const_string "maybe_vex")
2013       (const_string "orig")))
2014   (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2015
2016;; Reload patterns to support multi-word load/store
2017;; with non-offsetable address.
2018(define_expand "reload_noff_store"
2019  [(parallel [(match_operand 0 "memory_operand" "=m")
2020              (match_operand 1 "register_operand" "r")
2021              (match_operand:DI 2 "register_operand" "=&r")])]
2022  "TARGET_64BIT"
2023{
2024  rtx mem = operands[0];
2025  rtx addr = XEXP (mem, 0);
2026
2027  emit_move_insn (operands[2], addr);
2028  mem = replace_equiv_address_nv (mem, operands[2]);
2029
2030  emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2031  DONE;
2032})
2033
2034(define_expand "reload_noff_load"
2035  [(parallel [(match_operand 0 "register_operand" "=r")
2036              (match_operand 1 "memory_operand" "m")
2037              (match_operand:DI 2 "register_operand" "=r")])]
2038  "TARGET_64BIT"
2039{
2040  rtx mem = operands[1];
2041  rtx addr = XEXP (mem, 0);
2042
2043  emit_move_insn (operands[2], addr);
2044  mem = replace_equiv_address_nv (mem, operands[2]);
2045
2046  emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2047  DONE;
2048})
2049
2050(define_insn "*movdi_internal"
2051  [(set (match_operand:DI 0 "nonimmediate_operand"
2052	  "=r  ,o  ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2053	(match_operand:DI 1 "general_operand"
2054	  "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2055  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2056{
2057  switch (get_attr_type (insn))
2058    {
2059    case TYPE_SSECVT:
2060      if (SSE_REG_P (operands[0]))
2061	return "movq2dq\t{%1, %0|%0, %1}";
2062      else
2063	return "movdq2q\t{%1, %0|%0, %1}";
2064
2065    case TYPE_SSEMOV:
2066      switch (get_attr_mode (insn))
2067	{
2068	case MODE_TI:
2069	  return "%vmovdqa\t{%1, %0|%0, %1}";
2070	case MODE_DI:
2071	   return "%vmovq\t{%1, %0|%0, %1}";
2072	case MODE_V4SF:
2073	  return "movaps\t{%1, %0|%0, %1}";
2074	case MODE_V2SF:
2075	  return "movlps\t{%1, %0|%0, %1}";
2076	default:
2077	  gcc_unreachable ();
2078	}
2079
2080    case TYPE_MMXMOV:
2081      return "movq\t{%1, %0|%0, %1}";
2082
2083    case TYPE_SSELOG1:
2084      return standard_sse_constant_opcode (insn, operands[1]);
2085
2086    case TYPE_MMX:
2087      return "pxor\t%0, %0";
2088
2089    case TYPE_MULTI:
2090      return "#";
2091
2092    default:
2093      gcc_unreachable ();
2094    }
2095}
2096  [(set (attr "isa")
2097     (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2098	      (const_string "sse2")
2099	    (eq_attr "alternative" "9,10,11,12")
2100	      (const_string "noavx")
2101	   ]
2102           (const_string "*")))
2103   (set (attr "type")
2104     (cond [(eq_attr "alternative" "0,1")
2105	      (const_string "multi")
2106	    (eq_attr "alternative" "2")
2107	      (const_string "mmx")
2108	    (eq_attr "alternative" "3,4")
2109	      (const_string "mmxmov")
2110	    (eq_attr "alternative" "5,9")
2111	      (const_string "sselog1")
2112	    (eq_attr "alternative" "13,14")
2113	      (const_string "ssecvt")
2114	   ]
2115	   (const_string "ssemov")))
2116   (set (attr "prefix")
2117     (if_then_else (eq_attr "alternative" "5,6,7,8")
2118       (const_string "maybe_vex")
2119       (const_string "orig")))
2120   (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2121
2122(define_split
2123  [(set (match_operand:DI 0 "nonimmediate_operand" "")
2124        (match_operand:DI 1 "general_operand" ""))]
2125  "!TARGET_64BIT && reload_completed
2126   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2127   && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2128  [(const_int 0)]
2129  "ix86_split_long_move (operands); DONE;")
2130
2131(define_insn "*movsi_internal"
2132  [(set (match_operand:SI 0 "nonimmediate_operand"
2133			"=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2134	(match_operand:SI 1 "general_operand"
2135			"g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
2136  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2137{
2138  switch (get_attr_type (insn))
2139    {
2140    case TYPE_SSELOG1:
2141      return standard_sse_constant_opcode (insn, operands[1]);
2142
2143    case TYPE_SSEMOV:
2144      switch (get_attr_mode (insn))
2145	{
2146	case MODE_TI:
2147	  return "%vmovdqa\t{%1, %0|%0, %1}";
2148	case MODE_V4SF:
2149	  return "%vmovaps\t{%1, %0|%0, %1}";
2150	case MODE_SI:
2151          return "%vmovd\t{%1, %0|%0, %1}";
2152	case MODE_SF:
2153          return "%vmovss\t{%1, %0|%0, %1}";
2154	default:
2155	  gcc_unreachable ();
2156	}
2157
2158    case TYPE_MMX:
2159      return "pxor\t%0, %0";
2160
2161    case TYPE_MMXMOV:
2162      if (get_attr_mode (insn) == MODE_DI)
2163	return "movq\t{%1, %0|%0, %1}";
2164      return "movd\t{%1, %0|%0, %1}";
2165
2166    case TYPE_LEA:
2167      return "lea{l}\t{%E1, %0|%0, %E1}";
2168
2169    default:
2170      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2171      if (ix86_use_lea_for_mov (insn, operands))
2172	return "lea{l}\t{%E1, %0|%0, %E1}";
2173      else
2174	return "mov{l}\t{%1, %0|%0, %1}";
2175    }
2176}
2177  [(set (attr "type")
2178     (cond [(eq_attr "alternative" "2")
2179	      (const_string "mmx")
2180	    (eq_attr "alternative" "3,4,5")
2181	      (const_string "mmxmov")
2182	    (eq_attr "alternative" "6")
2183	      (const_string "sselog1")
2184	    (eq_attr "alternative" "7,8,9,10,11")
2185	      (const_string "ssemov")
2186 	    (match_operand 1 "pic_32bit_operand" "")
2187	      (const_string "lea")
2188	   ]
2189	   (const_string "imov")))
2190   (set (attr "prefix")
2191     (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2192       (const_string "orig")
2193       (const_string "maybe_vex")))
2194   (set (attr "prefix_data16")
2195     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2196       (const_string "1")
2197       (const_string "*")))
2198   (set (attr "mode")
2199     (cond [(eq_attr "alternative" "2,3")
2200	      (const_string "DI")
2201	    (eq_attr "alternative" "6,7")
2202	      (if_then_else
2203	        (not (match_test "TARGET_SSE2"))
2204	        (const_string "V4SF")
2205	        (const_string "TI"))
2206	    (and (eq_attr "alternative" "8,9,10,11")
2207	         (not (match_test "TARGET_SSE2")))
2208	      (const_string "SF")
2209	   ]
2210	   (const_string "SI")))])
2211
2212(define_insn "*movhi_internal"
2213  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2214	(match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2215  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2216{
2217  switch (get_attr_type (insn))
2218    {
2219    case TYPE_IMOVX:
2220      /* movzwl is faster than movw on p2 due to partial word stalls,
2221	 though not as fast as an aligned movl.  */
2222      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2223    default:
2224      if (get_attr_mode (insn) == MODE_SI)
2225        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2226      else
2227        return "mov{w}\t{%1, %0|%0, %1}";
2228    }
2229}
2230  [(set (attr "type")
2231     (cond [(match_test "optimize_function_for_size_p (cfun)")
2232	      (const_string "imov")
2233	    (and (eq_attr "alternative" "0")
2234		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2235		      (not (match_test "TARGET_HIMODE_MATH"))))
2236	      (const_string "imov")
2237	    (and (eq_attr "alternative" "1,2")
2238		 (match_operand:HI 1 "aligned_operand" ""))
2239	      (const_string "imov")
2240	    (and (match_test "TARGET_MOVX")
2241		 (eq_attr "alternative" "0,2"))
2242	      (const_string "imovx")
2243	   ]
2244	   (const_string "imov")))
2245    (set (attr "mode")
2246      (cond [(eq_attr "type" "imovx")
2247	       (const_string "SI")
2248	     (and (eq_attr "alternative" "1,2")
2249		  (match_operand:HI 1 "aligned_operand" ""))
2250	       (const_string "SI")
2251	     (and (eq_attr "alternative" "0")
2252		  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2253		       (not (match_test "TARGET_HIMODE_MATH"))))
2254	       (const_string "SI")
2255	    ]
2256	    (const_string "HI")))])
2257
2258;; Situation is quite tricky about when to choose full sized (SImode) move
2259;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2260;; partial register dependency machines (such as AMD Athlon), where QImode
2261;; moves issue extra dependency and for partial register stalls machines
2262;; that don't use QImode patterns (and QImode move cause stall on the next
2263;; instruction).
2264;;
2265;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2266;; register stall machines with, where we use QImode instructions, since
2267;; partial register stall can be caused there.  Then we use movzx.
2268(define_insn "*movqi_internal"
2269  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2270	(match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2271  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2272{
2273  switch (get_attr_type (insn))
2274    {
2275    case TYPE_IMOVX:
2276      gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2277      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2278    default:
2279      if (get_attr_mode (insn) == MODE_SI)
2280        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2281      else
2282        return "mov{b}\t{%1, %0|%0, %1}";
2283    }
2284}
2285  [(set (attr "type")
2286     (cond [(and (eq_attr "alternative" "5")
2287		 (not (match_operand:QI 1 "aligned_operand" "")))
2288	      (const_string "imovx")
2289	    (match_test "optimize_function_for_size_p (cfun)")
2290	      (const_string "imov")
2291	    (and (eq_attr "alternative" "3")
2292		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2293		      (not (match_test "TARGET_QIMODE_MATH"))))
2294	      (const_string "imov")
2295	    (eq_attr "alternative" "3,5")
2296	      (const_string "imovx")
2297	    (and (match_test "TARGET_MOVX")
2298		 (eq_attr "alternative" "2"))
2299	      (const_string "imovx")
2300	   ]
2301	   (const_string "imov")))
2302   (set (attr "mode")
2303      (cond [(eq_attr "alternative" "3,4,5")
2304	       (const_string "SI")
2305	     (eq_attr "alternative" "6")
2306	       (const_string "QI")
2307	     (eq_attr "type" "imovx")
2308	       (const_string "SI")
2309	     (and (eq_attr "type" "imov")
2310		  (and (eq_attr "alternative" "0,1")
2311		       (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2312			    (and (not (match_test "optimize_function_for_size_p (cfun)"))
2313				 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2314	       (const_string "SI")
2315	     ;; Avoid partial register stalls when not using QImode arithmetic
2316	     (and (eq_attr "type" "imov")
2317		  (and (eq_attr "alternative" "0,1")
2318		       (and (match_test "TARGET_PARTIAL_REG_STALL")
2319			    (not (match_test "TARGET_QIMODE_MATH")))))
2320	       (const_string "SI")
2321	   ]
2322	   (const_string "QI")))])
2323
2324;; Stores and loads of ax to arbitrary constant address.
2325;; We fake an second form of instruction to force reload to load address
2326;; into register when rax is not available
2327(define_insn "*movabs<mode>_1"
2328  [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2329	(match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2330  "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2331  "@
2332   movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2333   mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2334  [(set_attr "type" "imov")
2335   (set_attr "modrm" "0,*")
2336   (set_attr "length_address" "8,0")
2337   (set_attr "length_immediate" "0,*")
2338   (set_attr "memory" "store")
2339   (set_attr "mode" "<MODE>")])
2340
2341(define_insn "*movabs<mode>_2"
2342  [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2343        (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2344  "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2345  "@
2346   movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2347   mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2348  [(set_attr "type" "imov")
2349   (set_attr "modrm" "0,*")
2350   (set_attr "length_address" "8,0")
2351   (set_attr "length_immediate" "0")
2352   (set_attr "memory" "load")
2353   (set_attr "mode" "<MODE>")])
2354
2355(define_insn "*swap<mode>"
2356  [(set (match_operand:SWI48 0 "register_operand" "+r")
2357	(match_operand:SWI48 1 "register_operand" "+r"))
2358   (set (match_dup 1)
2359	(match_dup 0))]
2360  ""
2361  "xchg{<imodesuffix>}\t%1, %0"
2362  [(set_attr "type" "imov")
2363   (set_attr "mode" "<MODE>")
2364   (set_attr "pent_pair" "np")
2365   (set_attr "athlon_decode" "vector")
2366   (set_attr "amdfam10_decode" "double")
2367   (set_attr "bdver1_decode" "double")])
2368
2369(define_insn "*swap<mode>_1"
2370  [(set (match_operand:SWI12 0 "register_operand" "+r")
2371	(match_operand:SWI12 1 "register_operand" "+r"))
2372   (set (match_dup 1)
2373	(match_dup 0))]
2374  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2375  "xchg{l}\t%k1, %k0"
2376  [(set_attr "type" "imov")
2377   (set_attr "mode" "SI")
2378   (set_attr "pent_pair" "np")
2379   (set_attr "athlon_decode" "vector")
2380   (set_attr "amdfam10_decode" "double")
2381   (set_attr "bdver1_decode" "double")])
2382
2383;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2384;; is disabled for AMDFAM10
2385(define_insn "*swap<mode>_2"
2386  [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2387	(match_operand:SWI12 1 "register_operand" "+<r>"))
2388   (set (match_dup 1)
2389	(match_dup 0))]
2390  "TARGET_PARTIAL_REG_STALL"
2391  "xchg{<imodesuffix>}\t%1, %0"
2392  [(set_attr "type" "imov")
2393   (set_attr "mode" "<MODE>")
2394   (set_attr "pent_pair" "np")
2395   (set_attr "athlon_decode" "vector")])
2396
2397(define_expand "movstrict<mode>"
2398  [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2399	(match_operand:SWI12 1 "general_operand" ""))]
2400  ""
2401{
2402  if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2403    FAIL;
2404  if (GET_CODE (operands[0]) == SUBREG
2405      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2406    FAIL;
2407  /* Don't generate memory->memory moves, go through a register */
2408  if (MEM_P (operands[0]) && MEM_P (operands[1]))
2409    operands[1] = force_reg (<MODE>mode, operands[1]);
2410})
2411
2412(define_insn "*movstrict<mode>_1"
2413  [(set (strict_low_part
2414	  (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2415	(match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2416  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2417   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2418  "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2419  [(set_attr "type" "imov")
2420   (set_attr "mode" "<MODE>")])
2421
2422(define_insn "*movstrict<mode>_xor"
2423  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2424	(match_operand:SWI12 1 "const0_operand" ""))
2425   (clobber (reg:CC FLAGS_REG))]
2426  "reload_completed"
2427  "xor{<imodesuffix>}\t%0, %0"
2428  [(set_attr "type" "alu1")
2429   (set_attr "mode" "<MODE>")
2430   (set_attr "length_immediate" "0")])
2431
2432(define_insn "*mov<mode>_extv_1"
2433  [(set (match_operand:SWI24 0 "register_operand" "=R")
2434	(sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2435			    (const_int 8)
2436			    (const_int 8)))]
2437  ""
2438  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2439  [(set_attr "type" "imovx")
2440   (set_attr "mode" "SI")])
2441
2442(define_insn "*movqi_extv_1_rex64"
2443  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2444        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2445                         (const_int 8)
2446                         (const_int 8)))]
2447  "TARGET_64BIT"
2448{
2449  switch (get_attr_type (insn))
2450    {
2451    case TYPE_IMOVX:
2452      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2453    default:
2454      return "mov{b}\t{%h1, %0|%0, %h1}";
2455    }
2456}
2457  [(set (attr "type")
2458     (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2459			(match_test "TARGET_MOVX"))
2460	(const_string "imovx")
2461	(const_string "imov")))
2462   (set (attr "mode")
2463     (if_then_else (eq_attr "type" "imovx")
2464	(const_string "SI")
2465	(const_string "QI")))])
2466
2467(define_insn "*movqi_extv_1"
2468  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2469        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2470                         (const_int 8)
2471                         (const_int 8)))]
2472  "!TARGET_64BIT"
2473{
2474  switch (get_attr_type (insn))
2475    {
2476    case TYPE_IMOVX:
2477      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2478    default:
2479      return "mov{b}\t{%h1, %0|%0, %h1}";
2480    }
2481}
2482  [(set (attr "type")
2483     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2484			(ior (not (match_operand:QI 0 "QIreg_operand" ""))
2485			     (match_test "TARGET_MOVX")))
2486	(const_string "imovx")
2487	(const_string "imov")))
2488   (set (attr "mode")
2489     (if_then_else (eq_attr "type" "imovx")
2490	(const_string "SI")
2491	(const_string "QI")))])
2492
2493(define_insn "*mov<mode>_extzv_1"
2494  [(set (match_operand:SWI48 0 "register_operand" "=R")
2495	(zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2496			    (const_int 8)
2497			    (const_int 8)))]
2498  ""
2499  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2500  [(set_attr "type" "imovx")
2501   (set_attr "mode" "SI")])
2502
2503(define_insn "*movqi_extzv_2_rex64"
2504  [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2505        (subreg:QI
2506	  (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2507			   (const_int 8)
2508			   (const_int 8)) 0))]
2509  "TARGET_64BIT"
2510{
2511  switch (get_attr_type (insn))
2512    {
2513    case TYPE_IMOVX:
2514      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2515    default:
2516      return "mov{b}\t{%h1, %0|%0, %h1}";
2517    }
2518}
2519  [(set (attr "type")
2520     (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2521			(match_test "TARGET_MOVX"))
2522	(const_string "imovx")
2523	(const_string "imov")))
2524   (set (attr "mode")
2525     (if_then_else (eq_attr "type" "imovx")
2526	(const_string "SI")
2527	(const_string "QI")))])
2528
2529(define_insn "*movqi_extzv_2"
2530  [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2531        (subreg:QI
2532	  (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2533			   (const_int 8)
2534			   (const_int 8)) 0))]
2535  "!TARGET_64BIT"
2536{
2537  switch (get_attr_type (insn))
2538    {
2539    case TYPE_IMOVX:
2540      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2541    default:
2542      return "mov{b}\t{%h1, %0|%0, %h1}";
2543    }
2544}
2545  [(set (attr "type")
2546     (if_then_else (and (match_operand:QI 0 "register_operand" "")
2547			(ior (not (match_operand:QI 0 "QIreg_operand" ""))
2548			     (match_test "TARGET_MOVX")))
2549	(const_string "imovx")
2550	(const_string "imov")))
2551   (set (attr "mode")
2552     (if_then_else (eq_attr "type" "imovx")
2553	(const_string "SI")
2554	(const_string "QI")))])
2555
2556(define_expand "mov<mode>_insv_1"
2557  [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2558			    (const_int 8)
2559			    (const_int 8))
2560	(match_operand:SWI48 1 "nonmemory_operand" ""))])
2561
2562(define_insn "*mov<mode>_insv_1_rex64"
2563  [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2564			     (const_int 8)
2565			     (const_int 8))
2566	(match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2567  "TARGET_64BIT"
2568{
2569  if (CONST_INT_P (operands[1]))
2570    operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2571  return "mov{b}\t{%b1, %h0|%h0, %b1}";
2572}
2573  [(set_attr "type" "imov")
2574   (set_attr "mode" "QI")])
2575
2576(define_insn "*movsi_insv_1"
2577  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2578			 (const_int 8)
2579			 (const_int 8))
2580	(match_operand:SI 1 "general_operand" "Qmn"))]
2581  "!TARGET_64BIT"
2582{
2583  if (CONST_INT_P (operands[1]))
2584    operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2585  return "mov{b}\t{%b1, %h0|%h0, %b1}";
2586}
2587  [(set_attr "type" "imov")
2588   (set_attr "mode" "QI")])
2589
2590(define_insn "*movqi_insv_2"
2591  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2592			 (const_int 8)
2593			 (const_int 8))
2594	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2595		     (const_int 8)))]
2596  ""
2597  "mov{b}\t{%h1, %h0|%h0, %h1}"
2598  [(set_attr "type" "imov")
2599   (set_attr "mode" "QI")])
2600
2601;; Floating point push instructions.
2602
2603(define_insn "*pushtf"
2604  [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2605	(match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2606  "TARGET_SSE2"
2607{
2608  /* This insn should be already split before reg-stack.  */
2609  gcc_unreachable ();
2610}
2611  [(set_attr "type" "multi")
2612   (set_attr "unit" "sse,*,*")
2613   (set_attr "mode" "TF,SI,SI")])
2614
2615;; %%% Kill this when call knows how to work this out.
2616(define_split
2617  [(set (match_operand:TF 0 "push_operand" "")
2618	(match_operand:TF 1 "sse_reg_operand" ""))]
2619  "TARGET_SSE2 && reload_completed"
2620  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2621   (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2622
2623(define_insn "*pushxf"
2624  [(set (match_operand:XF 0 "push_operand" "=<,<")
2625	(match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2626  "optimize_function_for_speed_p (cfun)"
2627{
2628  /* This insn should be already split before reg-stack.  */
2629  gcc_unreachable ();
2630}
2631  [(set_attr "type" "multi")
2632   (set_attr "unit" "i387,*")
2633   (set_attr "mode" "XF,SI")])
2634
2635;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2636;; Size of pushxf using integer instructions is 3+3*memory operand size
2637;; Pushing using integer instructions is longer except for constants
2638;; and direct memory references (assuming that any given constant is pushed
2639;; only once, but this ought to be handled elsewhere).
2640
2641(define_insn "*pushxf_nointeger"
2642  [(set (match_operand:XF 0 "push_operand" "=<,<")
2643	(match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2644  "optimize_function_for_size_p (cfun)"
2645{
2646  /* This insn should be already split before reg-stack.  */
2647  gcc_unreachable ();
2648}
2649  [(set_attr "type" "multi")
2650   (set_attr "unit" "i387,*")
2651   (set_attr "mode" "XF,SI")])
2652
2653;; %%% Kill this when call knows how to work this out.
2654(define_split
2655  [(set (match_operand:XF 0 "push_operand" "")
2656	(match_operand:XF 1 "fp_register_operand" ""))]
2657  "reload_completed"
2658  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2659   (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2660  "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2661
2662(define_insn "*pushdf_rex64"
2663  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2664	(match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2665  "TARGET_64BIT"
2666{
2667  /* This insn should be already split before reg-stack.  */
2668  gcc_unreachable ();
2669}
2670  [(set_attr "type" "multi")
2671   (set_attr "unit" "i387,*,*")
2672   (set_attr "mode" "DF,DI,DF")])
2673
2674;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2675;; Size of pushdf using integer instructions is 2+2*memory operand size
2676;; On the average, pushdf using integers can be still shorter.
2677
2678(define_insn "*pushdf"
2679  [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2680	(match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2681  "!TARGET_64BIT"
2682{
2683  /* This insn should be already split before reg-stack.  */
2684  gcc_unreachable ();
2685}
2686  [(set_attr "isa" "*,*,sse2")
2687   (set_attr "type" "multi")
2688   (set_attr "unit" "i387,*,*")
2689   (set_attr "mode" "DF,DI,DF")])
2690
2691;; %%% Kill this when call knows how to work this out.
2692(define_split
2693  [(set (match_operand:DF 0 "push_operand" "")
2694	(match_operand:DF 1 "any_fp_register_operand" ""))]
2695  "reload_completed"
2696  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2697   (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2698
2699(define_insn "*pushsf_rex64"
2700  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2701	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2702  "TARGET_64BIT"
2703{
2704  /* Anything else should be already split before reg-stack.  */
2705  gcc_assert (which_alternative == 1);
2706  return "push{q}\t%q1";
2707}
2708  [(set_attr "type" "multi,push,multi")
2709   (set_attr "unit" "i387,*,*")
2710   (set_attr "mode" "SF,DI,SF")])
2711
2712(define_insn "*pushsf"
2713  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2714	(match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2715  "!TARGET_64BIT"
2716{
2717  /* Anything else should be already split before reg-stack.  */
2718  gcc_assert (which_alternative == 1);
2719  return "push{l}\t%1";
2720}
2721  [(set_attr "type" "multi,push,multi")
2722   (set_attr "unit" "i387,*,*")
2723   (set_attr "mode" "SF,SI,SF")])
2724
2725;; %%% Kill this when call knows how to work this out.
2726(define_split
2727  [(set (match_operand:SF 0 "push_operand" "")
2728	(match_operand:SF 1 "any_fp_register_operand" ""))]
2729  "reload_completed"
2730  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2731   (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2732  "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2733
2734(define_split
2735  [(set (match_operand:SF 0 "push_operand" "")
2736	(match_operand:SF 1 "memory_operand" ""))]
2737  "reload_completed
2738   && (operands[2] = find_constant_src (insn))"
2739  [(set (match_dup 0) (match_dup 2))])
2740
2741(define_split
2742  [(set (match_operand 0 "push_operand" "")
2743	(match_operand 1 "general_operand" ""))]
2744  "reload_completed
2745   && (GET_MODE (operands[0]) == TFmode
2746       || GET_MODE (operands[0]) == XFmode
2747       || GET_MODE (operands[0]) == DFmode)
2748   && !ANY_FP_REG_P (operands[1])"
2749  [(const_int 0)]
2750  "ix86_split_long_move (operands); DONE;")
2751
2752;; Floating point move instructions.
2753
2754(define_expand "movtf"
2755  [(set (match_operand:TF 0 "nonimmediate_operand" "")
2756	(match_operand:TF 1 "nonimmediate_operand" ""))]
2757  "TARGET_64BIT || TARGET_SSE2"
2758{
2759  ix86_expand_move (TFmode, operands);
2760  DONE;
2761})
2762
2763(define_expand "mov<mode>"
2764  [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2765	(match_operand:X87MODEF 1 "general_operand" ""))]
2766  ""
2767  "ix86_expand_move (<MODE>mode, operands); DONE;")
2768
2769(define_insn "*movtf_internal_rex64"
2770  [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2771	(match_operand:TF 1 "general_operand"	   "xm,x,C,*roF,*r"))]
2772  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2773   && (!can_create_pseudo_p ()
2774       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2775       || GET_CODE (operands[1]) != CONST_DOUBLE
2776       || (optimize_function_for_size_p (cfun)
2777	   && standard_sse_constant_p (operands[1])
2778	   && !memory_operand (operands[0], TFmode))
2779       || (!TARGET_MEMORY_MISMATCH_STALL
2780	   && memory_operand (operands[0], TFmode)))"
2781{
2782  switch (which_alternative)
2783    {
2784    case 0:
2785    case 1:
2786      /* Handle misaligned load/store since we
2787         don't have movmisaligntf pattern. */
2788      if (misaligned_operand (operands[0], TFmode)
2789	  || misaligned_operand (operands[1], TFmode))
2790	{
2791	  if (get_attr_mode (insn) == MODE_V4SF)
2792	    return "%vmovups\t{%1, %0|%0, %1}";
2793	  else
2794	    return "%vmovdqu\t{%1, %0|%0, %1}";
2795	}
2796      else
2797	{
2798	  if (get_attr_mode (insn) == MODE_V4SF)
2799	    return "%vmovaps\t{%1, %0|%0, %1}";
2800	  else
2801	    return "%vmovdqa\t{%1, %0|%0, %1}";
2802	}
2803
2804    case 2:
2805      return standard_sse_constant_opcode (insn, operands[1]);
2806
2807    case 3:
2808    case 4:
2809	return "#";
2810
2811    default:
2812      gcc_unreachable ();
2813    }
2814}
2815  [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2816   (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2817   (set (attr "mode")
2818        (cond [(eq_attr "alternative" "0,2")
2819		 (if_then_else
2820		   (match_test "optimize_function_for_size_p (cfun)")
2821		   (const_string "V4SF")
2822		   (const_string "TI"))
2823	       (eq_attr "alternative" "1")
2824		 (if_then_else
2825		   (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2826			(match_test "optimize_function_for_size_p (cfun)"))
2827		   (const_string "V4SF")
2828		   (const_string "TI"))]
2829	       (const_string "DI")))])
2830
2831(define_insn "*movtf_internal_sse2"
2832  [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2833	(match_operand:TF 1 "general_operand"  	   "xm,x,C"))]
2834  "TARGET_SSE2 && !TARGET_64BIT
2835   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2836   && (!can_create_pseudo_p ()
2837       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2838       || GET_CODE (operands[1]) != CONST_DOUBLE
2839       || (optimize_function_for_size_p (cfun)
2840	   && standard_sse_constant_p (operands[1])
2841	   && !memory_operand (operands[0], TFmode))
2842       || (!TARGET_MEMORY_MISMATCH_STALL
2843	   && memory_operand (operands[0], TFmode)))"
2844{
2845  switch (which_alternative)
2846    {
2847    case 0:
2848    case 1:
2849      /* Handle misaligned load/store since we
2850         don't have movmisaligntf pattern. */
2851      if (misaligned_operand (operands[0], TFmode)
2852	  || misaligned_operand (operands[1], TFmode))
2853	{
2854	  if (get_attr_mode (insn) == MODE_V4SF)
2855	    return "%vmovups\t{%1, %0|%0, %1}";
2856	  else
2857	    return "%vmovdqu\t{%1, %0|%0, %1}";
2858	}
2859      else
2860	{
2861	  if (get_attr_mode (insn) == MODE_V4SF)
2862	    return "%vmovaps\t{%1, %0|%0, %1}";
2863	  else
2864	    return "%vmovdqa\t{%1, %0|%0, %1}";
2865	}
2866
2867    case 2:
2868      return standard_sse_constant_opcode (insn, operands[1]);
2869
2870    default:
2871      gcc_unreachable ();
2872    }
2873}
2874  [(set_attr "type" "ssemov,ssemov,sselog1")
2875   (set_attr "prefix" "maybe_vex")
2876   (set (attr "mode")
2877        (cond [(eq_attr "alternative" "0,2")
2878		 (if_then_else
2879		   (match_test "optimize_function_for_size_p (cfun)")
2880		   (const_string "V4SF")
2881		   (const_string "TI"))
2882	       (eq_attr "alternative" "1")
2883		 (if_then_else
2884		   (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2885			(match_test "optimize_function_for_size_p (cfun)"))
2886		   (const_string "V4SF")
2887		   (const_string "TI"))]
2888	       (const_string "DI")))])
2889
2890(define_insn "*movxf_internal_rex64"
2891  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2892	(match_operand:XF 1 "general_operand"	   "fm,f,G,Yx*roF,Yx*rC"))]
2893  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2894   && (!can_create_pseudo_p ()
2895       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2896       || GET_CODE (operands[1]) != CONST_DOUBLE
2897       || (optimize_function_for_size_p (cfun)
2898	   && standard_80387_constant_p (operands[1]) > 0
2899	   && !memory_operand (operands[0], XFmode))
2900       || (!TARGET_MEMORY_MISMATCH_STALL
2901	   && memory_operand (operands[0], XFmode)))"
2902{
2903  switch (which_alternative)
2904    {
2905    case 0:
2906    case 1:
2907      return output_387_reg_move (insn, operands);
2908
2909    case 2:
2910      return standard_80387_constant_opcode (operands[1]);
2911
2912    case 3:
2913    case 4:
2914      return "#";
2915
2916    default:
2917      gcc_unreachable ();
2918    }
2919}
2920  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2921   (set_attr "mode" "XF,XF,XF,SI,SI")])
2922
2923;; Possible store forwarding (partial memory) stall in alternative 4.
2924(define_insn "*movxf_internal"
2925  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2926	(match_operand:XF 1 "general_operand"	   "fm,f,G,Yx*roF,Yx*rF"))]
2927  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2928   && (!can_create_pseudo_p ()
2929       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2930       || GET_CODE (operands[1]) != CONST_DOUBLE
2931       || (optimize_function_for_size_p (cfun)
2932	   && standard_80387_constant_p (operands[1]) > 0
2933	   && !memory_operand (operands[0], XFmode))
2934       || (!TARGET_MEMORY_MISMATCH_STALL
2935	   && memory_operand (operands[0], XFmode)))"
2936{
2937  switch (which_alternative)
2938    {
2939    case 0:
2940    case 1:
2941      return output_387_reg_move (insn, operands);
2942
2943    case 2:
2944      return standard_80387_constant_opcode (operands[1]);
2945
2946    case 3:
2947    case 4:
2948      return "#";
2949
2950    default:
2951      gcc_unreachable ();
2952    }
2953}
2954  [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2955   (set_attr "mode" "XF,XF,XF,SI,SI")])
2956
2957(define_insn "*movdf_internal_rex64"
2958  [(set (match_operand:DF 0 "nonimmediate_operand"
2959		"=?Yf*f,?m   ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2960	(match_operand:DF 1 "general_operand"
2961		"Yf*fm ,Yf*f ,G    ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2962  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2963   && (!can_create_pseudo_p ()
2964       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2965       || GET_CODE (operands[1]) != CONST_DOUBLE
2966       || (optimize_function_for_size_p (cfun)
2967	   && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2968		&& standard_80387_constant_p (operands[1]) > 0)
2969	       || (TARGET_SSE2 && TARGET_SSE_MATH
2970		   && standard_sse_constant_p (operands[1]))))
2971       || memory_operand (operands[0], DFmode))"
2972{
2973  switch (which_alternative)
2974    {
2975    case 0:
2976    case 1:
2977      return output_387_reg_move (insn, operands);
2978
2979    case 2:
2980      return standard_80387_constant_opcode (operands[1]);
2981
2982    case 3:
2983    case 4:
2984      return "mov{q}\t{%1, %0|%0, %1}";
2985
2986    case 5:
2987      return "mov{l}\t{%1, %k0|%k0, %1}";
2988
2989    case 6:
2990      return "movabs{q}\t{%1, %0|%0, %1}";
2991
2992    case 7:
2993      return standard_sse_constant_opcode (insn, operands[1]);
2994
2995    case 8:
2996    case 9:
2997    case 10:
2998      switch (get_attr_mode (insn))
2999	{
3000	case MODE_V2DF:
3001	  if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3002	    return "%vmovapd\t{%1, %0|%0, %1}";
3003	case MODE_V4SF:
3004	  return "%vmovaps\t{%1, %0|%0, %1}";
3005
3006	case MODE_DI:
3007	  return "%vmovq\t{%1, %0|%0, %1}";
3008	case MODE_DF:
3009	  if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3010	    return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3011	  return "%vmovsd\t{%1, %0|%0, %1}";
3012	case MODE_V1DF:
3013	  return "%vmovlpd\t{%1, %d0|%d0, %1}";
3014	case MODE_V2SF:
3015	  return "%vmovlps\t{%1, %d0|%d0, %1}";
3016	default:
3017	  gcc_unreachable ();
3018	}
3019
3020    case 11:
3021    case 12:
3022      /* Handle broken assemblers that require movd instead of movq.  */
3023      return "%vmovd\t{%1, %0|%0, %1}";
3024
3025    default:
3026      gcc_unreachable();
3027    }
3028}
3029  [(set (attr "type")
3030	(cond [(eq_attr "alternative" "0,1,2")
3031		 (const_string "fmov")
3032	       (eq_attr "alternative" "3,4,5,6")
3033		 (const_string "imov")
3034	       (eq_attr "alternative" "7")
3035		 (const_string "sselog1")
3036	      ]
3037	      (const_string "ssemov")))
3038   (set (attr "modrm")
3039     (if_then_else
3040       (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3041	 (const_string "0")
3042	 (const_string "*")))
3043   (set (attr "length_immediate")
3044     (if_then_else
3045       (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3046	 (const_string "8")
3047	 (const_string "*")))
3048   (set (attr "prefix")
3049     (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3050       (const_string "orig")
3051       (const_string "maybe_vex")))
3052   (set (attr "prefix_data16")
3053     (if_then_else (eq_attr "mode" "V1DF")
3054       (const_string "1")
3055       (const_string "*")))
3056   (set (attr "mode")
3057        (cond [(eq_attr "alternative" "0,1,2")
3058		 (const_string "DF")
3059	       (eq_attr "alternative" "3,4,6,11,12")
3060		 (const_string "DI")
3061	       (eq_attr "alternative" "5")
3062		 (const_string "SI")
3063
3064	       /* xorps is one byte shorter.  */
3065	       (eq_attr "alternative" "7")
3066		 (cond [(match_test "optimize_function_for_size_p (cfun)")
3067			  (const_string "V4SF")
3068			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3069			  (const_string "TI")
3070		       ]
3071		       (const_string "V2DF"))
3072
3073	       /* For architectures resolving dependencies on
3074		  whole SSE registers use APD move to break dependency
3075		  chains, otherwise use short move to avoid extra work.
3076
3077		  movaps encodes one byte shorter.  */
3078	       (eq_attr "alternative" "8")
3079		 (cond
3080		   [(match_test "optimize_function_for_size_p (cfun)")
3081		      (const_string "V4SF")
3082		    (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3083		      (const_string "V2DF")
3084		   ]
3085		   (const_string "DF"))
3086	       /* For architectures resolving dependencies on register
3087		  parts we may avoid extra work to zero out upper part
3088		  of register.  */
3089	       (eq_attr "alternative" "9")
3090		 (if_then_else
3091		   (match_test "TARGET_SSE_SPLIT_REGS")
3092		   (const_string "V1DF")
3093		   (const_string "DF"))
3094	      ]
3095	      (const_string "DF")))])
3096
3097;; Possible store forwarding (partial memory) stall in alternative 4.
3098(define_insn "*movdf_internal"
3099  [(set (match_operand:DF 0 "nonimmediate_operand"
3100		"=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,x,x,x,m,*x,*x,*x,m")
3101	(match_operand:DF 1 "general_operand"
3102		"Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3103  "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3104   && (!can_create_pseudo_p ()
3105       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3106       || GET_CODE (operands[1]) != CONST_DOUBLE
3107       || (optimize_function_for_size_p (cfun)
3108	   && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3109		&& standard_80387_constant_p (operands[1]) > 0)
3110	       || (TARGET_SSE2 && TARGET_SSE_MATH
3111		   && standard_sse_constant_p (operands[1])))
3112	   && !memory_operand (operands[0], DFmode))
3113       || (!TARGET_MEMORY_MISMATCH_STALL
3114	   && memory_operand (operands[0], DFmode)))"
3115{
3116  switch (which_alternative)
3117    {
3118    case 0:
3119    case 1:
3120      return output_387_reg_move (insn, operands);
3121
3122    case 2:
3123      return standard_80387_constant_opcode (operands[1]);
3124
3125    case 3:
3126    case 4:
3127      return "#";
3128
3129    case 5:
3130    case 9:
3131      return standard_sse_constant_opcode (insn, operands[1]);
3132
3133    case 6:
3134    case 7:
3135    case 8:
3136    case 10:
3137    case 11:
3138    case 12:
3139      switch (get_attr_mode (insn))
3140	{
3141	case MODE_V2DF:
3142	  if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3143	    return "%vmovapd\t{%1, %0|%0, %1}";
3144	case MODE_V4SF:
3145	  return "%vmovaps\t{%1, %0|%0, %1}";
3146
3147	case MODE_DI:
3148	  return "%vmovq\t{%1, %0|%0, %1}";
3149	case MODE_DF:
3150	  if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3151	    return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3152	  return "%vmovsd\t{%1, %0|%0, %1}";
3153	case MODE_V1DF:
3154	  return "%vmovlpd\t{%1, %d0|%d0, %1}";
3155	case MODE_V2SF:
3156	  return "%vmovlps\t{%1, %d0|%d0, %1}";
3157	default:
3158	  gcc_unreachable ();
3159	}
3160
3161    default:
3162      gcc_unreachable ();
3163    }
3164}
3165  [(set (attr "isa")
3166     (if_then_else (eq_attr "alternative" "5,6,7,8")
3167       (const_string "sse2")
3168       (const_string "*")))
3169   (set (attr "type")
3170	(cond [(eq_attr "alternative" "0,1,2")
3171		 (const_string "fmov")
3172	       (eq_attr "alternative" "3,4")
3173		 (const_string "multi")
3174	       (eq_attr "alternative" "5,9")
3175		 (const_string "sselog1")
3176	      ]
3177	      (const_string "ssemov")))
3178   (set (attr "prefix")
3179     (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3180       (const_string "orig")
3181       (const_string "maybe_vex")))
3182   (set (attr "prefix_data16")
3183     (if_then_else (eq_attr "mode" "V1DF")
3184       (const_string "1")
3185       (const_string "*")))
3186   (set (attr "mode")
3187        (cond [(eq_attr "alternative" "0,1,2")
3188		 (const_string "DF")
3189	       (eq_attr "alternative" "3,4")
3190		 (const_string "SI")
3191
3192	       /* For SSE1, we have many fewer alternatives.  */
3193	       (not (match_test "TARGET_SSE2"))
3194		 (if_then_else
3195		   (eq_attr "alternative" "5,6,9,10")
3196		   (const_string "V4SF")
3197		   (const_string "V2SF"))
3198
3199	       /* xorps is one byte shorter.  */
3200	       (eq_attr "alternative" "5,9")
3201		 (cond [(match_test "optimize_function_for_size_p (cfun)")
3202			  (const_string "V4SF")
3203			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3204			  (const_string "TI")
3205		       ]
3206		       (const_string "V2DF"))
3207
3208	       /* For architectures resolving dependencies on
3209		  whole SSE registers use APD move to break dependency
3210		  chains, otherwise use short move to avoid extra work.
3211
3212		  movaps encodes one byte shorter.  */
3213	       (eq_attr "alternative" "6,10")
3214		 (cond
3215		   [(match_test "optimize_function_for_size_p (cfun)")
3216		      (const_string "V4SF")
3217		    (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3218		      (const_string "V2DF")
3219		   ]
3220		   (const_string "DF"))
3221	       /* For architectures resolving dependencies on register
3222		  parts we may avoid extra work to zero out upper part
3223		  of register.  */
3224	       (eq_attr "alternative" "7,11")
3225		 (if_then_else
3226		   (match_test "TARGET_SSE_SPLIT_REGS")
3227		   (const_string "V1DF")
3228		   (const_string "DF"))
3229	      ]
3230	      (const_string "DF")))])
3231
3232(define_insn "*movsf_internal"
3233  [(set (match_operand:SF 0 "nonimmediate_operand"
3234	  "=Yf*f,m   ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3235	(match_operand:SF 1 "general_operand"
3236	  "Yf*fm,Yf*f,G   ,rmF,rF,C,x,m,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3237  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3238   && (!can_create_pseudo_p ()
3239       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3240       || GET_CODE (operands[1]) != CONST_DOUBLE
3241       || (optimize_function_for_size_p (cfun)
3242	   && ((!TARGET_SSE_MATH
3243		&& standard_80387_constant_p (operands[1]) > 0)
3244	       || (TARGET_SSE_MATH
3245		   && standard_sse_constant_p (operands[1]))))
3246       || memory_operand (operands[0], SFmode))"
3247{
3248  switch (which_alternative)
3249    {
3250    case 0:
3251    case 1:
3252      return output_387_reg_move (insn, operands);
3253
3254    case 2:
3255      return standard_80387_constant_opcode (operands[1]);
3256
3257    case 3:
3258    case 4:
3259      return "mov{l}\t{%1, %0|%0, %1}";
3260
3261    case 5:
3262      return standard_sse_constant_opcode (insn, operands[1]);
3263
3264    case 6:
3265      if (get_attr_mode (insn) == MODE_V4SF)
3266	return "%vmovaps\t{%1, %0|%0, %1}";
3267      if (TARGET_AVX)
3268	return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3269
3270    case 7:
3271    case 8:
3272      return "%vmovss\t{%1, %0|%0, %1}";
3273
3274    case 9:
3275    case 10:
3276    case 14:
3277    case 15:
3278      return "movd\t{%1, %0|%0, %1}";
3279
3280    case 11:
3281      return "movq\t{%1, %0|%0, %1}";
3282
3283    case 12:
3284    case 13:
3285      return "%vmovd\t{%1, %0|%0, %1}";
3286
3287    default:
3288      gcc_unreachable ();
3289    }
3290}
3291  [(set (attr "type")
3292	(cond [(eq_attr "alternative" "0,1,2")
3293		 (const_string "fmov")
3294	       (eq_attr "alternative" "3,4")
3295		 (const_string "imov")
3296	       (eq_attr "alternative" "5")
3297		 (const_string "sselog1")
3298	       (eq_attr "alternative" "9,10,11,14,15")
3299		 (const_string "mmxmov")
3300	      ]
3301	      (const_string "ssemov")))
3302   (set (attr "prefix")
3303     (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3304       (const_string "maybe_vex")
3305       (const_string "orig")))
3306   (set (attr "mode")
3307        (cond [(eq_attr "alternative" "3,4,9,10")
3308		 (const_string "SI")
3309	       (eq_attr "alternative" "5")
3310		 (if_then_else
3311		   (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3312			     (match_test "TARGET_SSE2"))
3313			(not (match_test "optimize_function_for_size_p (cfun)")))
3314		   (const_string "TI")
3315		   (const_string "V4SF"))
3316	       /* For architectures resolving dependencies on
3317		  whole SSE registers use APS move to break dependency
3318		  chains, otherwise use short move to avoid extra work.
3319
3320		  Do the same for architectures resolving dependencies on
3321		  the parts.  While in DF mode it is better to always handle
3322		  just register parts, the SF mode is different due to lack
3323		  of instructions to load just part of the register.  It is
3324		  better to maintain the whole registers in single format
3325		  to avoid problems on using packed logical operations.  */
3326	       (eq_attr "alternative" "6")
3327		 (if_then_else
3328		   (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3329			(match_test "TARGET_SSE_SPLIT_REGS"))
3330		   (const_string "V4SF")
3331		   (const_string "SF"))
3332	       (eq_attr "alternative" "11")
3333		 (const_string "DI")]
3334	       (const_string "SF")))])
3335
3336(define_split
3337  [(set (match_operand 0 "any_fp_register_operand" "")
3338	(match_operand 1 "memory_operand" ""))]
3339  "reload_completed
3340   && (GET_MODE (operands[0]) == TFmode
3341       || GET_MODE (operands[0]) == XFmode
3342       || GET_MODE (operands[0]) == DFmode
3343       || GET_MODE (operands[0]) == SFmode)
3344   && (operands[2] = find_constant_src (insn))"
3345  [(set (match_dup 0) (match_dup 2))]
3346{
3347  rtx c = operands[2];
3348  int r = REGNO (operands[0]);
3349
3350  if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3351      || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3352    FAIL;
3353})
3354
3355(define_split
3356  [(set (match_operand 0 "any_fp_register_operand" "")
3357	(float_extend (match_operand 1 "memory_operand" "")))]
3358  "reload_completed
3359   && (GET_MODE (operands[0]) == TFmode
3360       || GET_MODE (operands[0]) == XFmode
3361       || GET_MODE (operands[0]) == DFmode)
3362   && (operands[2] = find_constant_src (insn))"
3363  [(set (match_dup 0) (match_dup 2))]
3364{
3365  rtx c = operands[2];
3366  int r = REGNO (operands[0]);
3367
3368  if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3369      || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3370    FAIL;
3371})
3372
3373;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3374(define_split
3375  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3376	(match_operand:X87MODEF 1 "immediate_operand" ""))]
3377  "reload_completed
3378   && (standard_80387_constant_p (operands[1]) == 8
3379       || standard_80387_constant_p (operands[1]) == 9)"
3380  [(set (match_dup 0)(match_dup 1))
3381   (set (match_dup 0)
3382	(neg:X87MODEF (match_dup 0)))]
3383{
3384  REAL_VALUE_TYPE r;
3385
3386  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3387  if (real_isnegzero (&r))
3388    operands[1] = CONST0_RTX (<MODE>mode);
3389  else
3390    operands[1] = CONST1_RTX (<MODE>mode);
3391})
3392
3393(define_split
3394  [(set (match_operand 0 "nonimmediate_operand" "")
3395        (match_operand 1 "general_operand" ""))]
3396  "reload_completed
3397   && (GET_MODE (operands[0]) == TFmode
3398       || GET_MODE (operands[0]) == XFmode
3399       || GET_MODE (operands[0]) == DFmode)
3400   && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3401  [(const_int 0)]
3402  "ix86_split_long_move (operands); DONE;")
3403
3404(define_insn "swapxf"
3405  [(set (match_operand:XF 0 "register_operand" "+f")
3406	(match_operand:XF 1 "register_operand" "+f"))
3407   (set (match_dup 1)
3408	(match_dup 0))]
3409  "TARGET_80387"
3410{
3411  if (STACK_TOP_P (operands[0]))
3412    return "fxch\t%1";
3413  else
3414    return "fxch\t%0";
3415}
3416  [(set_attr "type" "fxch")
3417   (set_attr "mode" "XF")])
3418
3419(define_insn "*swap<mode>"
3420  [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3421	(match_operand:MODEF 1 "fp_register_operand" "+f"))
3422   (set (match_dup 1)
3423	(match_dup 0))]
3424  "TARGET_80387 || reload_completed"
3425{
3426  if (STACK_TOP_P (operands[0]))
3427    return "fxch\t%1";
3428  else
3429    return "fxch\t%0";
3430}
3431  [(set_attr "type" "fxch")
3432   (set_attr "mode" "<MODE>")])
3433
3434;; Zero extension instructions
3435
3436(define_expand "zero_extendsidi2"
3437  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3438	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3439  ""
3440{
3441  if (!TARGET_64BIT)
3442    {
3443      emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3444      DONE;
3445    }
3446})
3447
3448(define_insn "*zero_extendsidi2_rex64"
3449  [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,o,?*Ym,?!*y,?*Yi,*x")
3450	(zero_extend:DI
3451	 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r   ,m   ,r   ,m")))]
3452  "TARGET_64BIT"
3453  "@
3454   mov{l}\t{%1, %k0|%k0, %1}
3455   #
3456   movd\t{%1, %0|%0, %1}
3457   movd\t{%1, %0|%0, %1}
3458   %vmovd\t{%1, %0|%0, %1}
3459   %vmovd\t{%1, %0|%0, %1}"
3460  [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3461   (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3462   (set_attr "prefix_0f" "0,*,*,*,*,*")
3463   (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3464
3465(define_split
3466  [(set (match_operand:DI 0 "memory_operand" "")
3467     	(zero_extend:DI (match_dup 0)))]
3468  "TARGET_64BIT"
3469  [(set (match_dup 4) (const_int 0))]
3470  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3471
3472;; %%% Kill me once multi-word ops are sane.
3473(define_insn "zero_extendsidi2_1"
3474  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?!*y,?*Yi,*x")
3475	(zero_extend:DI
3476	 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m   ,r   ,m")))
3477   (clobber (reg:CC FLAGS_REG))]
3478  "!TARGET_64BIT"
3479  "@
3480   #
3481   #
3482   #
3483   movd\t{%1, %0|%0, %1}
3484   movd\t{%1, %0|%0, %1}
3485   %vmovd\t{%1, %0|%0, %1}
3486   %vmovd\t{%1, %0|%0, %1}"
3487  [(set_attr "isa" "*,*,*,*,*,*,sse2")
3488   (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3489   (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3490   (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3491
3492(define_split
3493  [(set (match_operand:DI 0 "register_operand" "")
3494	(zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3495   (clobber (reg:CC FLAGS_REG))]
3496  "!TARGET_64BIT && reload_completed
3497   && true_regnum (operands[0]) == true_regnum (operands[1])"
3498  [(set (match_dup 4) (const_int 0))]
3499  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3500
3501(define_split
3502  [(set (match_operand:DI 0 "nonimmediate_operand" "")
3503	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3504   (clobber (reg:CC FLAGS_REG))]
3505  "!TARGET_64BIT && reload_completed
3506   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3507  [(set (match_dup 3) (match_dup 1))
3508   (set (match_dup 4) (const_int 0))]
3509  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3510
3511(define_insn "zero_extend<mode>di2"
3512  [(set (match_operand:DI 0 "register_operand" "=r")
3513	(zero_extend:DI
3514	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3515  "TARGET_64BIT"
3516  "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3517  [(set_attr "type" "imovx")
3518   (set_attr "mode" "SI")])
3519
3520(define_expand "zero_extendhisi2"
3521  [(set (match_operand:SI 0 "register_operand" "")
3522	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3523  ""
3524{
3525  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3526    {
3527      operands[1] = force_reg (HImode, operands[1]);
3528      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3529      DONE;
3530    }
3531})
3532
3533(define_insn_and_split "zero_extendhisi2_and"
3534  [(set (match_operand:SI 0 "register_operand" "=r")
3535	(zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3536   (clobber (reg:CC FLAGS_REG))]
3537  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3538  "#"
3539  "&& reload_completed"
3540  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3541	      (clobber (reg:CC FLAGS_REG))])]
3542  ""
3543  [(set_attr "type" "alu1")
3544   (set_attr "mode" "SI")])
3545
3546(define_insn "*zero_extendhisi2_movzwl"
3547  [(set (match_operand:SI 0 "register_operand" "=r")
3548	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3549  "!TARGET_ZERO_EXTEND_WITH_AND
3550   || optimize_function_for_size_p (cfun)"
3551  "movz{wl|x}\t{%1, %0|%0, %1}"
3552  [(set_attr "type" "imovx")
3553   (set_attr "mode" "SI")])
3554
3555(define_expand "zero_extendqi<mode>2"
3556  [(parallel
3557    [(set (match_operand:SWI24 0 "register_operand" "")
3558	  (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3559     (clobber (reg:CC FLAGS_REG))])])
3560
3561(define_insn "*zero_extendqi<mode>2_and"
3562  [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3563	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3564   (clobber (reg:CC FLAGS_REG))]
3565  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3566  "#"
3567  [(set_attr "type" "alu1")
3568   (set_attr "mode" "<MODE>")])
3569
3570;; When source and destination does not overlap, clear destination
3571;; first and then do the movb
3572(define_split
3573  [(set (match_operand:SWI24 0 "register_operand" "")
3574	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3575   (clobber (reg:CC FLAGS_REG))]
3576  "reload_completed
3577   && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3578   && ANY_QI_REG_P (operands[0])
3579   && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3580   && !reg_overlap_mentioned_p (operands[0], operands[1])"
3581  [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3582{
3583  operands[2] = gen_lowpart (QImode, operands[0]);
3584  ix86_expand_clear (operands[0]);
3585})
3586
3587(define_insn "*zero_extendqi<mode>2_movzbl_and"
3588  [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3589	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3590   (clobber (reg:CC FLAGS_REG))]
3591  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3592  "#"
3593  [(set_attr "type" "imovx,alu1")
3594   (set_attr "mode" "<MODE>")])
3595
3596;; For the movzbl case strip only the clobber
3597(define_split
3598  [(set (match_operand:SWI24 0 "register_operand" "")
3599	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3600   (clobber (reg:CC FLAGS_REG))]
3601  "reload_completed
3602   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3603   && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3604  [(set (match_dup 0)
3605	(zero_extend:SWI24 (match_dup 1)))])
3606
3607; zero extend to SImode to avoid partial register stalls
3608(define_insn "*zero_extendqi<mode>2_movzbl"
3609  [(set (match_operand:SWI24 0 "register_operand" "=r")
3610	(zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3611  "reload_completed
3612   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3613  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3614  [(set_attr "type" "imovx")
3615   (set_attr "mode" "SI")])
3616
3617;; Rest is handled by single and.
3618(define_split
3619  [(set (match_operand:SWI24 0 "register_operand" "")
3620	(zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3621   (clobber (reg:CC FLAGS_REG))]
3622  "reload_completed
3623   && true_regnum (operands[0]) == true_regnum (operands[1])"
3624  [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3625	      (clobber (reg:CC FLAGS_REG))])])
3626
3627;; Sign extension instructions
3628
3629(define_expand "extendsidi2"
3630  [(set (match_operand:DI 0 "register_operand" "")
3631	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3632  ""
3633{
3634  if (!TARGET_64BIT)
3635    {
3636      emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3637      DONE;
3638    }
3639})
3640
3641(define_insn "*extendsidi2_rex64"
3642  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3643	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3644  "TARGET_64BIT"
3645  "@
3646   {cltq|cdqe}
3647   movs{lq|x}\t{%1, %0|%0, %1}"
3648  [(set_attr "type" "imovx")
3649   (set_attr "mode" "DI")
3650   (set_attr "prefix_0f" "0")
3651   (set_attr "modrm" "0,1")])
3652
3653(define_insn "extendsidi2_1"
3654  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3655	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3656   (clobber (reg:CC FLAGS_REG))
3657   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3658  "!TARGET_64BIT"
3659  "#")
3660
3661;; Extend to memory case when source register does die.
3662(define_split
3663  [(set (match_operand:DI 0 "memory_operand" "")
3664	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3665   (clobber (reg:CC FLAGS_REG))
3666   (clobber (match_operand:SI 2 "register_operand" ""))]
3667  "(reload_completed
3668    && dead_or_set_p (insn, operands[1])
3669    && !reg_mentioned_p (operands[1], operands[0]))"
3670  [(set (match_dup 3) (match_dup 1))
3671   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3672	      (clobber (reg:CC FLAGS_REG))])
3673   (set (match_dup 4) (match_dup 1))]
3674  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3675
3676;; Extend to memory case when source register does not die.
3677(define_split
3678  [(set (match_operand:DI 0 "memory_operand" "")
3679	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3680   (clobber (reg:CC FLAGS_REG))
3681   (clobber (match_operand:SI 2 "register_operand" ""))]
3682  "reload_completed"
3683  [(const_int 0)]
3684{
3685  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3686
3687  emit_move_insn (operands[3], operands[1]);
3688
3689  /* Generate a cltd if possible and doing so it profitable.  */
3690  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3691      && true_regnum (operands[1]) == AX_REG
3692      && true_regnum (operands[2]) == DX_REG)
3693    {
3694      emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3695    }
3696  else
3697    {
3698      emit_move_insn (operands[2], operands[1]);
3699      emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3700    }
3701  emit_move_insn (operands[4], operands[2]);
3702  DONE;
3703})
3704
3705;; Extend to register case.  Optimize case where source and destination
3706;; registers match and cases where we can use cltd.
3707(define_split
3708  [(set (match_operand:DI 0 "register_operand" "")
3709	(sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3710   (clobber (reg:CC FLAGS_REG))
3711   (clobber (match_scratch:SI 2 ""))]
3712  "reload_completed"
3713  [(const_int 0)]
3714{
3715  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3716
3717  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3718    emit_move_insn (operands[3], operands[1]);
3719
3720  /* Generate a cltd if possible and doing so it profitable.  */
3721  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3722      && true_regnum (operands[3]) == AX_REG
3723      && true_regnum (operands[4]) == DX_REG)
3724    {
3725      emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3726      DONE;
3727    }
3728
3729  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3730    emit_move_insn (operands[4], operands[1]);
3731
3732  emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3733  DONE;
3734})
3735
3736(define_insn "extend<mode>di2"
3737  [(set (match_operand:DI 0 "register_operand" "=r")
3738	(sign_extend:DI
3739	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3740  "TARGET_64BIT"
3741  "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3742  [(set_attr "type" "imovx")
3743   (set_attr "mode" "DI")])
3744
3745(define_insn "extendhisi2"
3746  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3747	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3748  ""
3749{
3750  switch (get_attr_prefix_0f (insn))
3751    {
3752    case 0:
3753      return "{cwtl|cwde}";
3754    default:
3755      return "movs{wl|x}\t{%1, %0|%0, %1}";
3756    }
3757}
3758  [(set_attr "type" "imovx")
3759   (set_attr "mode" "SI")
3760   (set (attr "prefix_0f")
3761     ;; movsx is short decodable while cwtl is vector decoded.
3762     (if_then_else (and (eq_attr "cpu" "!k6")
3763			(eq_attr "alternative" "0"))
3764	(const_string "0")
3765	(const_string "1")))
3766   (set (attr "modrm")
3767     (if_then_else (eq_attr "prefix_0f" "0")
3768	(const_string "0")
3769	(const_string "1")))])
3770
3771(define_insn "*extendhisi2_zext"
3772  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3773	(zero_extend:DI
3774	 (sign_extend:SI
3775	  (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3776  "TARGET_64BIT"
3777{
3778  switch (get_attr_prefix_0f (insn))
3779    {
3780    case 0:
3781      return "{cwtl|cwde}";
3782    default:
3783      return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3784    }
3785}
3786  [(set_attr "type" "imovx")
3787   (set_attr "mode" "SI")
3788   (set (attr "prefix_0f")
3789     ;; movsx is short decodable while cwtl is vector decoded.
3790     (if_then_else (and (eq_attr "cpu" "!k6")
3791			(eq_attr "alternative" "0"))
3792	(const_string "0")
3793	(const_string "1")))
3794   (set (attr "modrm")
3795     (if_then_else (eq_attr "prefix_0f" "0")
3796	(const_string "0")
3797	(const_string "1")))])
3798
3799(define_insn "extendqisi2"
3800  [(set (match_operand:SI 0 "register_operand" "=r")
3801	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3802  ""
3803  "movs{bl|x}\t{%1, %0|%0, %1}"
3804   [(set_attr "type" "imovx")
3805    (set_attr "mode" "SI")])
3806
3807(define_insn "*extendqisi2_zext"
3808  [(set (match_operand:DI 0 "register_operand" "=r")
3809	(zero_extend:DI
3810	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3811  "TARGET_64BIT"
3812  "movs{bl|x}\t{%1, %k0|%k0, %1}"
3813   [(set_attr "type" "imovx")
3814    (set_attr "mode" "SI")])
3815
3816(define_insn "extendqihi2"
3817  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3818	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3819  ""
3820{
3821  switch (get_attr_prefix_0f (insn))
3822    {
3823    case 0:
3824      return "{cbtw|cbw}";
3825    default:
3826      return "movs{bw|x}\t{%1, %0|%0, %1}";
3827    }
3828}
3829  [(set_attr "type" "imovx")
3830   (set_attr "mode" "HI")
3831   (set (attr "prefix_0f")
3832     ;; movsx is short decodable while cwtl is vector decoded.
3833     (if_then_else (and (eq_attr "cpu" "!k6")
3834			(eq_attr "alternative" "0"))
3835	(const_string "0")
3836	(const_string "1")))
3837   (set (attr "modrm")
3838     (if_then_else (eq_attr "prefix_0f" "0")
3839	(const_string "0")
3840	(const_string "1")))])
3841
3842;; Conversions between float and double.
3843
3844;; These are all no-ops in the model used for the 80387.
3845;; So just emit moves.
3846
3847;; %%% Kill these when call knows how to work out a DFmode push earlier.
3848(define_split
3849  [(set (match_operand:DF 0 "push_operand" "")
3850	(float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3851  "reload_completed"
3852  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3853   (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3854
3855(define_split
3856  [(set (match_operand:XF 0 "push_operand" "")
3857	(float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3858  "reload_completed"
3859  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3860   (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3861  "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3862
3863(define_expand "extendsfdf2"
3864  [(set (match_operand:DF 0 "nonimmediate_operand" "")
3865        (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3866  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3867{
3868  /* ??? Needed for compress_float_constant since all fp constants
3869     are TARGET_LEGITIMATE_CONSTANT_P.  */
3870  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3871    {
3872      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3873	  && standard_80387_constant_p (operands[1]) > 0)
3874	{
3875	  operands[1] = simplify_const_unary_operation
3876	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3877	  emit_move_insn_1 (operands[0], operands[1]);
3878	  DONE;
3879	}
3880      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3881    }
3882})
3883
3884/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3885   cvtss2sd:
3886      unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3887      cvtps2pd xmm2,xmm1
3888   We do the conversion post reload to avoid producing of 128bit spills
3889   that might lead to ICE on 32bit target.  The sequence unlikely combine
3890   anyway.  */
3891(define_split
3892  [(set (match_operand:DF 0 "register_operand" "")
3893        (float_extend:DF
3894	  (match_operand:SF 1 "nonimmediate_operand" "")))]
3895  "TARGET_USE_VECTOR_FP_CONVERTS
3896   && optimize_insn_for_speed_p ()
3897   && reload_completed && SSE_REG_P (operands[0])"
3898   [(set (match_dup 2)
3899	 (float_extend:V2DF
3900	   (vec_select:V2SF
3901	     (match_dup 3)
3902	     (parallel [(const_int 0) (const_int 1)]))))]
3903{
3904  operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3905  operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3906  /* Use movss for loading from memory, unpcklps reg, reg for registers.
3907     Try to avoid move when unpacking can be done in source.  */
3908  if (REG_P (operands[1]))
3909    {
3910      /* If it is unsafe to overwrite upper half of source, we need
3911	 to move to destination and unpack there.  */
3912      if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3913	   || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3914	  && true_regnum (operands[0]) != true_regnum (operands[1]))
3915	{
3916	  rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3917	  emit_move_insn (tmp, operands[1]);
3918	}
3919      else
3920	operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3921      emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3922      		 			     operands[3]));
3923    }
3924  else
3925    emit_insn (gen_vec_setv4sf_0 (operands[3],
3926				  CONST0_RTX (V4SFmode), operands[1]));
3927})
3928
3929(define_insn "*extendsfdf2_mixed"
3930  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3931        (float_extend:DF
3932	  (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3933  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3934{
3935  switch (which_alternative)
3936    {
3937    case 0:
3938    case 1:
3939      return output_387_reg_move (insn, operands);
3940
3941    case 2:
3942      return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3943
3944    default:
3945      gcc_unreachable ();
3946    }
3947}
3948  [(set_attr "type" "fmov,fmov,ssecvt")
3949   (set_attr "prefix" "orig,orig,maybe_vex")
3950   (set_attr "mode" "SF,XF,DF")])
3951
3952(define_insn "*extendsfdf2_sse"
3953  [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3954        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3955  "TARGET_SSE2 && TARGET_SSE_MATH"
3956  "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3957  [(set_attr "type" "ssecvt")
3958   (set_attr "prefix" "maybe_vex")
3959   (set_attr "mode" "DF")])
3960
3961(define_insn "*extendsfdf2_i387"
3962  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3963        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3964  "TARGET_80387"
3965  "* return output_387_reg_move (insn, operands);"
3966  [(set_attr "type" "fmov")
3967   (set_attr "mode" "SF,XF")])
3968
3969(define_expand "extend<mode>xf2"
3970  [(set (match_operand:XF 0 "nonimmediate_operand" "")
3971        (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3972  "TARGET_80387"
3973{
3974  /* ??? Needed for compress_float_constant since all fp constants
3975     are TARGET_LEGITIMATE_CONSTANT_P.  */
3976  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3977    {
3978      if (standard_80387_constant_p (operands[1]) > 0)
3979	{
3980	  operands[1] = simplify_const_unary_operation
3981	    (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3982	  emit_move_insn_1 (operands[0], operands[1]);
3983	  DONE;
3984	}
3985      operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3986    }
3987})
3988
3989(define_insn "*extend<mode>xf2_i387"
3990  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3991        (float_extend:XF
3992	  (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3993  "TARGET_80387"
3994  "* return output_387_reg_move (insn, operands);"
3995  [(set_attr "type" "fmov")
3996   (set_attr "mode" "<MODE>,XF")])
3997
3998;; %%% This seems bad bad news.
3999;; This cannot output into an f-reg because there is no way to be sure
4000;; of truncating in that case.  Otherwise this is just like a simple move
4001;; insn.  So we pretend we can output to a reg in order to get better
4002;; register preferencing, but we really use a stack slot.
4003
4004;; Conversion from DFmode to SFmode.
4005
4006(define_expand "truncdfsf2"
4007  [(set (match_operand:SF 0 "nonimmediate_operand" "")
4008	(float_truncate:SF
4009	  (match_operand:DF 1 "nonimmediate_operand" "")))]
4010  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4011{
4012  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4013    ;
4014  else if (flag_unsafe_math_optimizations)
4015    ;
4016  else
4017    {
4018      rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4019      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4020      DONE;
4021    }
4022})
4023
4024/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4025   cvtsd2ss:
4026      unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4027      cvtpd2ps xmm2,xmm1
4028   We do the conversion post reload to avoid producing of 128bit spills
4029   that might lead to ICE on 32bit target.  The sequence unlikely combine
4030   anyway.  */
4031(define_split
4032  [(set (match_operand:SF 0 "register_operand" "")
4033        (float_truncate:SF
4034	  (match_operand:DF 1 "nonimmediate_operand" "")))]
4035  "TARGET_USE_VECTOR_FP_CONVERTS
4036   && optimize_insn_for_speed_p ()
4037   && reload_completed && SSE_REG_P (operands[0])"
4038   [(set (match_dup 2)
4039	 (vec_concat:V4SF
4040	   (float_truncate:V2SF
4041	     (match_dup 4))
4042	   (match_dup 3)))]
4043{
4044  operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4045  operands[3] = CONST0_RTX (V2SFmode);
4046  operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4047  /* Use movsd for loading from memory, unpcklpd for registers.
4048     Try to avoid move when unpacking can be done in source, or SSE3
4049     movddup is available.  */
4050  if (REG_P (operands[1]))
4051    {
4052      if (!TARGET_SSE3
4053	  && true_regnum (operands[0]) != true_regnum (operands[1])
4054	  && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4055	      || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4056	{
4057	  rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4058	  emit_move_insn (tmp, operands[1]);
4059	  operands[1] = tmp;
4060	}
4061      else if (!TARGET_SSE3)
4062	operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4063      emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4064    }
4065  else
4066    emit_insn (gen_sse2_loadlpd (operands[4],
4067				 CONST0_RTX (V2DFmode), operands[1]));
4068})
4069
4070(define_expand "truncdfsf2_with_temp"
4071  [(parallel [(set (match_operand:SF 0 "" "")
4072		   (float_truncate:SF (match_operand:DF 1 "" "")))
4073	      (clobber (match_operand:SF 2 "" ""))])])
4074
4075(define_insn "*truncdfsf_fast_mixed"
4076  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4077        (float_truncate:SF
4078          (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4079  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4080{
4081  switch (which_alternative)
4082    {
4083    case 0:
4084      return output_387_reg_move (insn, operands);
4085    case 1:
4086      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4087    default:
4088      gcc_unreachable ();
4089    }
4090}
4091  [(set_attr "type" "fmov,ssecvt")
4092   (set_attr "prefix" "orig,maybe_vex")
4093   (set_attr "mode" "SF")])
4094
4095;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4096;; because nothing we do here is unsafe.
4097(define_insn "*truncdfsf_fast_sse"
4098  [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4099        (float_truncate:SF
4100          (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4101  "TARGET_SSE2 && TARGET_SSE_MATH"
4102  "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4103  [(set_attr "type" "ssecvt")
4104   (set_attr "prefix" "maybe_vex")
4105   (set_attr "mode" "SF")])
4106
4107(define_insn "*truncdfsf_fast_i387"
4108  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4109        (float_truncate:SF
4110          (match_operand:DF 1 "nonimmediate_operand" "f")))]
4111  "TARGET_80387 && flag_unsafe_math_optimizations"
4112  "* return output_387_reg_move (insn, operands);"
4113  [(set_attr "type" "fmov")
4114   (set_attr "mode" "SF")])
4115
4116(define_insn "*truncdfsf_mixed"
4117  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4118	(float_truncate:SF
4119	  (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4120   (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4121  "TARGET_MIX_SSE_I387"
4122{
4123  switch (which_alternative)
4124    {
4125    case 0:
4126      return output_387_reg_move (insn, operands);
4127    case 1:
4128      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4129
4130    default:
4131      return "#";
4132    }
4133}
4134  [(set_attr "isa" "*,sse2,*,*,*")
4135   (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4136   (set_attr "unit" "*,*,i387,i387,i387")
4137   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4138   (set_attr "mode" "SF")])
4139
4140(define_insn "*truncdfsf_i387"
4141  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4142	(float_truncate:SF
4143	  (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4144   (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4145  "TARGET_80387"
4146{
4147  switch (which_alternative)
4148    {
4149    case 0:
4150      return output_387_reg_move (insn, operands);
4151
4152    default:
4153      return "#";
4154    }
4155}
4156  [(set_attr "type" "fmov,multi,multi,multi")
4157   (set_attr "unit" "*,i387,i387,i387")
4158   (set_attr "mode" "SF")])
4159
4160(define_insn "*truncdfsf2_i387_1"
4161  [(set (match_operand:SF 0 "memory_operand" "=m")
4162	(float_truncate:SF
4163	  (match_operand:DF 1 "register_operand" "f")))]
4164  "TARGET_80387
4165   && !(TARGET_SSE2 && TARGET_SSE_MATH)
4166   && !TARGET_MIX_SSE_I387"
4167  "* return output_387_reg_move (insn, operands);"
4168  [(set_attr "type" "fmov")
4169   (set_attr "mode" "SF")])
4170
4171(define_split
4172  [(set (match_operand:SF 0 "register_operand" "")
4173	(float_truncate:SF
4174	 (match_operand:DF 1 "fp_register_operand" "")))
4175   (clobber (match_operand 2 "" ""))]
4176  "reload_completed"
4177  [(set (match_dup 2) (match_dup 1))
4178   (set (match_dup 0) (match_dup 2))]
4179  "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4180
4181;; Conversion from XFmode to {SF,DF}mode
4182
4183(define_expand "truncxf<mode>2"
4184  [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4185		   (float_truncate:MODEF
4186		     (match_operand:XF 1 "register_operand" "")))
4187	      (clobber (match_dup 2))])]
4188  "TARGET_80387"
4189{
4190  if (flag_unsafe_math_optimizations)
4191    {
4192      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4193      emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4194      if (reg != operands[0])
4195	emit_move_insn (operands[0], reg);
4196      DONE;
4197    }
4198  else
4199    operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4200})
4201
4202(define_insn "*truncxfsf2_mixed"
4203  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4204	(float_truncate:SF
4205	  (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4206   (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4207  "TARGET_80387"
4208{
4209  gcc_assert (!which_alternative);
4210  return output_387_reg_move (insn, operands);
4211}
4212  [(set_attr "type" "fmov,multi,multi,multi")
4213   (set_attr "unit" "*,i387,i387,i387")
4214   (set_attr "mode" "SF")])
4215
4216(define_insn "*truncxfdf2_mixed"
4217  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4218	(float_truncate:DF
4219	  (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4220   (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4221  "TARGET_80387"
4222{
4223  gcc_assert (!which_alternative);
4224  return output_387_reg_move (insn, operands);
4225}
4226  [(set_attr "isa" "*,*,sse2,*")
4227   (set_attr "type" "fmov,multi,multi,multi")
4228   (set_attr "unit" "*,i387,i387,i387")
4229   (set_attr "mode" "DF")])
4230
4231(define_insn "truncxf<mode>2_i387_noop"
4232  [(set (match_operand:MODEF 0 "register_operand" "=f")
4233	(float_truncate:MODEF
4234	  (match_operand:XF 1 "register_operand" "f")))]
4235  "TARGET_80387 && flag_unsafe_math_optimizations"
4236  "* return output_387_reg_move (insn, operands);"
4237  [(set_attr "type" "fmov")
4238   (set_attr "mode" "<MODE>")])
4239
4240(define_insn "*truncxf<mode>2_i387"
4241  [(set (match_operand:MODEF 0 "memory_operand" "=m")
4242	(float_truncate:MODEF
4243	  (match_operand:XF 1 "register_operand" "f")))]
4244  "TARGET_80387"
4245  "* return output_387_reg_move (insn, operands);"
4246  [(set_attr "type" "fmov")
4247   (set_attr "mode" "<MODE>")])
4248
4249(define_split
4250  [(set (match_operand:MODEF 0 "register_operand" "")
4251	(float_truncate:MODEF
4252	  (match_operand:XF 1 "register_operand" "")))
4253   (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4254  "TARGET_80387 && reload_completed"
4255  [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4256   (set (match_dup 0) (match_dup 2))])
4257
4258(define_split
4259  [(set (match_operand:MODEF 0 "memory_operand" "")
4260	(float_truncate:MODEF
4261	  (match_operand:XF 1 "register_operand" "")))
4262   (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4263  "TARGET_80387"
4264  [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4265
4266;; Signed conversion to DImode.
4267
4268(define_expand "fix_truncxfdi2"
4269  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4270                   (fix:DI (match_operand:XF 1 "register_operand" "")))
4271	      (clobber (reg:CC FLAGS_REG))])]
4272  "TARGET_80387"
4273{
4274  if (TARGET_FISTTP)
4275   {
4276     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4277     DONE;
4278   }
4279})
4280
4281(define_expand "fix_trunc<mode>di2"
4282  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4283                   (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4284              (clobber (reg:CC FLAGS_REG))])]
4285  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4286{
4287  if (TARGET_FISTTP
4288      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4289   {
4290     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4291     DONE;
4292   }
4293  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4294   {
4295     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4296     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4297     if (out != operands[0])
4298	emit_move_insn (operands[0], out);
4299     DONE;
4300   }
4301})
4302
4303;; Signed conversion to SImode.
4304
4305(define_expand "fix_truncxfsi2"
4306  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4307                   (fix:SI (match_operand:XF 1 "register_operand" "")))
4308	      (clobber (reg:CC FLAGS_REG))])]
4309  "TARGET_80387"
4310{
4311  if (TARGET_FISTTP)
4312   {
4313     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4314     DONE;
4315   }
4316})
4317
4318(define_expand "fix_trunc<mode>si2"
4319  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4320	           (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4321	      (clobber (reg:CC FLAGS_REG))])]
4322  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4323{
4324  if (TARGET_FISTTP
4325      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4326   {
4327     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4328     DONE;
4329   }
4330  if (SSE_FLOAT_MODE_P (<MODE>mode))
4331   {
4332     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4333     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4334     if (out != operands[0])
4335	emit_move_insn (operands[0], out);
4336     DONE;
4337   }
4338})
4339
4340;; Signed conversion to HImode.
4341
4342(define_expand "fix_trunc<mode>hi2"
4343  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4344	           (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4345              (clobber (reg:CC FLAGS_REG))])]
4346  "TARGET_80387
4347   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4348{
4349  if (TARGET_FISTTP)
4350   {
4351     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4352     DONE;
4353   }
4354})
4355
4356;; Unsigned conversion to SImode.
4357
4358(define_expand "fixuns_trunc<mode>si2"
4359  [(parallel
4360    [(set (match_operand:SI 0 "register_operand" "")
4361	  (unsigned_fix:SI
4362	    (match_operand:MODEF 1 "nonimmediate_operand" "")))
4363     (use (match_dup 2))
4364     (clobber (match_scratch:<ssevecmode> 3 ""))
4365     (clobber (match_scratch:<ssevecmode> 4 ""))])]
4366  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4367{
4368  enum machine_mode mode = <MODE>mode;
4369  enum machine_mode vecmode = <ssevecmode>mode;
4370  REAL_VALUE_TYPE TWO31r;
4371  rtx two31;
4372
4373  if (optimize_insn_for_size_p ())
4374    FAIL;
4375
4376  real_ldexp (&TWO31r, &dconst1, 31);
4377  two31 = const_double_from_real_value (TWO31r, mode);
4378  two31 = ix86_build_const_vector (vecmode, true, two31);
4379  operands[2] = force_reg (vecmode, two31);
4380})
4381
4382(define_insn_and_split "*fixuns_trunc<mode>_1"
4383  [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4384	(unsigned_fix:SI
4385	  (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4386   (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4387   (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4388   (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4389  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4390   && optimize_function_for_speed_p (cfun)"
4391  "#"
4392  "&& reload_completed"
4393  [(const_int 0)]
4394{
4395  ix86_split_convert_uns_si_sse (operands);
4396  DONE;
4397})
4398
4399;; Unsigned conversion to HImode.
4400;; Without these patterns, we'll try the unsigned SI conversion which
4401;; is complex for SSE, rather than the signed SI conversion, which isn't.
4402
4403(define_expand "fixuns_trunc<mode>hi2"
4404  [(set (match_dup 2)
4405	(fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4406   (set (match_operand:HI 0 "nonimmediate_operand" "")
4407	(subreg:HI (match_dup 2) 0))]
4408  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4409  "operands[2] = gen_reg_rtx (SImode);")
4410
4411;; When SSE is available, it is always faster to use it!
4412(define_insn "fix_trunc<mode>di_sse"
4413  [(set (match_operand:DI 0 "register_operand" "=r,r")
4414	(fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4415  "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4416   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4417  "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4418  [(set_attr "type" "sseicvt")
4419   (set_attr "prefix" "maybe_vex")
4420   (set_attr "prefix_rex" "1")
4421   (set_attr "mode" "<MODE>")
4422   (set_attr "athlon_decode" "double,vector")
4423   (set_attr "amdfam10_decode" "double,double")
4424   (set_attr "bdver1_decode" "double,double")])
4425
4426(define_insn "fix_trunc<mode>si_sse"
4427  [(set (match_operand:SI 0 "register_operand" "=r,r")
4428	(fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4429  "SSE_FLOAT_MODE_P (<MODE>mode)
4430   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4431  "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4432  [(set_attr "type" "sseicvt")
4433   (set_attr "prefix" "maybe_vex")
4434   (set_attr "mode" "<MODE>")
4435   (set_attr "athlon_decode" "double,vector")
4436   (set_attr "amdfam10_decode" "double,double")
4437   (set_attr "bdver1_decode" "double,double")])
4438
4439;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4440(define_peephole2
4441  [(set (match_operand:MODEF 0 "register_operand" "")
4442	(match_operand:MODEF 1 "memory_operand" ""))
4443   (set (match_operand:SWI48x 2 "register_operand" "")
4444	(fix:SWI48x (match_dup 0)))]
4445  "TARGET_SHORTEN_X87_SSE
4446   && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4447   && peep2_reg_dead_p (2, operands[0])"
4448  [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4449
4450;; Avoid vector decoded forms of the instruction.
4451(define_peephole2
4452  [(match_scratch:DF 2 "x")
4453   (set (match_operand:SWI48x 0 "register_operand" "")
4454	(fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4455  "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4456  [(set (match_dup 2) (match_dup 1))
4457   (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4458
4459(define_peephole2
4460  [(match_scratch:SF 2 "x")
4461   (set (match_operand:SWI48x 0 "register_operand" "")
4462	(fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4463  "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4464  [(set (match_dup 2) (match_dup 1))
4465   (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4466
4467(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4468  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4469	(fix:SWI248x (match_operand 1 "register_operand" "")))]
4470  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4471   && TARGET_FISTTP
4472   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4473	 && (TARGET_64BIT || <MODE>mode != DImode))
4474	&& TARGET_SSE_MATH)
4475   && can_create_pseudo_p ()"
4476  "#"
4477  "&& 1"
4478  [(const_int 0)]
4479{
4480  if (memory_operand (operands[0], VOIDmode))
4481    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4482  else
4483    {
4484      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4485      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4486							    operands[1],
4487							    operands[2]));
4488    }
4489  DONE;
4490}
4491  [(set_attr "type" "fisttp")
4492   (set_attr "mode" "<MODE>")])
4493
4494(define_insn "fix_trunc<mode>_i387_fisttp"
4495  [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4496	(fix:SWI248x (match_operand 1 "register_operand" "f")))
4497   (clobber (match_scratch:XF 2 "=&1f"))]
4498  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4499   && TARGET_FISTTP
4500   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4501	 && (TARGET_64BIT || <MODE>mode != DImode))
4502	&& TARGET_SSE_MATH)"
4503  "* return output_fix_trunc (insn, operands, true);"
4504  [(set_attr "type" "fisttp")
4505   (set_attr "mode" "<MODE>")])
4506
4507(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4508  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4509	(fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4510   (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4511   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4512  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4513   && TARGET_FISTTP
4514   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4515	&& (TARGET_64BIT || <MODE>mode != DImode))
4516	&& TARGET_SSE_MATH)"
4517  "#"
4518  [(set_attr "type" "fisttp")
4519   (set_attr "mode" "<MODE>")])
4520
4521(define_split
4522  [(set (match_operand:SWI248x 0 "register_operand" "")
4523	(fix:SWI248x (match_operand 1 "register_operand" "")))
4524   (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4525   (clobber (match_scratch 3 ""))]
4526  "reload_completed"
4527  [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4528	      (clobber (match_dup 3))])
4529   (set (match_dup 0) (match_dup 2))])
4530
4531(define_split
4532  [(set (match_operand:SWI248x 0 "memory_operand" "")
4533	(fix:SWI248x (match_operand 1 "register_operand" "")))
4534   (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4535   (clobber (match_scratch 3 ""))]
4536  "reload_completed"
4537  [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4538	      (clobber (match_dup 3))])])
4539
4540;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4541;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4542;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4543;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4544;; function in i386.c.
4545(define_insn_and_split "*fix_trunc<mode>_i387_1"
4546  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4547	(fix:SWI248x (match_operand 1 "register_operand" "")))
4548   (clobber (reg:CC FLAGS_REG))]
4549  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4550   && !TARGET_FISTTP
4551   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4552	 && (TARGET_64BIT || <MODE>mode != DImode))
4553   && can_create_pseudo_p ()"
4554  "#"
4555  "&& 1"
4556  [(const_int 0)]
4557{
4558  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4559
4560  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4561  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4562  if (memory_operand (operands[0], VOIDmode))
4563    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4564					 operands[2], operands[3]));
4565  else
4566    {
4567      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4568      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4569						     operands[2], operands[3],
4570						     operands[4]));
4571    }
4572  DONE;
4573}
4574  [(set_attr "type" "fistp")
4575   (set_attr "i387_cw" "trunc")
4576   (set_attr "mode" "<MODE>")])
4577
4578(define_insn "fix_truncdi_i387"
4579  [(set (match_operand:DI 0 "memory_operand" "=m")
4580	(fix:DI (match_operand 1 "register_operand" "f")))
4581   (use (match_operand:HI 2 "memory_operand" "m"))
4582   (use (match_operand:HI 3 "memory_operand" "m"))
4583   (clobber (match_scratch:XF 4 "=&1f"))]
4584  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585   && !TARGET_FISTTP
4586   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4587  "* return output_fix_trunc (insn, operands, false);"
4588  [(set_attr "type" "fistp")
4589   (set_attr "i387_cw" "trunc")
4590   (set_attr "mode" "DI")])
4591
4592(define_insn "fix_truncdi_i387_with_temp"
4593  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4594	(fix:DI (match_operand 1 "register_operand" "f,f")))
4595   (use (match_operand:HI 2 "memory_operand" "m,m"))
4596   (use (match_operand:HI 3 "memory_operand" "m,m"))
4597   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4598   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4599  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4600   && !TARGET_FISTTP
4601   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4602  "#"
4603  [(set_attr "type" "fistp")
4604   (set_attr "i387_cw" "trunc")
4605   (set_attr "mode" "DI")])
4606
4607(define_split
4608  [(set (match_operand:DI 0 "register_operand" "")
4609	(fix:DI (match_operand 1 "register_operand" "")))
4610   (use (match_operand:HI 2 "memory_operand" ""))
4611   (use (match_operand:HI 3 "memory_operand" ""))
4612   (clobber (match_operand:DI 4 "memory_operand" ""))
4613   (clobber (match_scratch 5 ""))]
4614  "reload_completed"
4615  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4616	      (use (match_dup 2))
4617	      (use (match_dup 3))
4618	      (clobber (match_dup 5))])
4619   (set (match_dup 0) (match_dup 4))])
4620
4621(define_split
4622  [(set (match_operand:DI 0 "memory_operand" "")
4623	(fix:DI (match_operand 1 "register_operand" "")))
4624   (use (match_operand:HI 2 "memory_operand" ""))
4625   (use (match_operand:HI 3 "memory_operand" ""))
4626   (clobber (match_operand:DI 4 "memory_operand" ""))
4627   (clobber (match_scratch 5 ""))]
4628  "reload_completed"
4629  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4630	      (use (match_dup 2))
4631	      (use (match_dup 3))
4632	      (clobber (match_dup 5))])])
4633
4634(define_insn "fix_trunc<mode>_i387"
4635  [(set (match_operand:SWI24 0 "memory_operand" "=m")
4636	(fix:SWI24 (match_operand 1 "register_operand" "f")))
4637   (use (match_operand:HI 2 "memory_operand" "m"))
4638   (use (match_operand:HI 3 "memory_operand" "m"))]
4639  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4640   && !TARGET_FISTTP
4641   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4642  "* return output_fix_trunc (insn, operands, false);"
4643  [(set_attr "type" "fistp")
4644   (set_attr "i387_cw" "trunc")
4645   (set_attr "mode" "<MODE>")])
4646
4647(define_insn "fix_trunc<mode>_i387_with_temp"
4648  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4649	(fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4650   (use (match_operand:HI 2 "memory_operand" "m,m"))
4651   (use (match_operand:HI 3 "memory_operand" "m,m"))
4652   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4653  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4654   && !TARGET_FISTTP
4655   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4656  "#"
4657  [(set_attr "type" "fistp")
4658   (set_attr "i387_cw" "trunc")
4659   (set_attr "mode" "<MODE>")])
4660
4661(define_split
4662  [(set (match_operand:SWI24 0 "register_operand" "")
4663	(fix:SWI24 (match_operand 1 "register_operand" "")))
4664   (use (match_operand:HI 2 "memory_operand" ""))
4665   (use (match_operand:HI 3 "memory_operand" ""))
4666   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4667  "reload_completed"
4668  [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4669	      (use (match_dup 2))
4670	      (use (match_dup 3))])
4671   (set (match_dup 0) (match_dup 4))])
4672
4673(define_split
4674  [(set (match_operand:SWI24 0 "memory_operand" "")
4675	(fix:SWI24 (match_operand 1 "register_operand" "")))
4676   (use (match_operand:HI 2 "memory_operand" ""))
4677   (use (match_operand:HI 3 "memory_operand" ""))
4678   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4679  "reload_completed"
4680  [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4681	      (use (match_dup 2))
4682	      (use (match_dup 3))])])
4683
4684(define_insn "x86_fnstcw_1"
4685  [(set (match_operand:HI 0 "memory_operand" "=m")
4686	(unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4687  "TARGET_80387"
4688  "fnstcw\t%0"
4689  [(set (attr "length")
4690	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4691   (set_attr "mode" "HI")
4692   (set_attr "unit" "i387")
4693   (set_attr "bdver1_decode" "vector")])
4694
4695(define_insn "x86_fldcw_1"
4696  [(set (reg:HI FPCR_REG)
4697	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4698  "TARGET_80387"
4699  "fldcw\t%0"
4700  [(set (attr "length")
4701	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4702   (set_attr "mode" "HI")
4703   (set_attr "unit" "i387")
4704   (set_attr "athlon_decode" "vector")
4705   (set_attr "amdfam10_decode" "vector")
4706   (set_attr "bdver1_decode" "vector")])
4707
4708;; Conversion between fixed point and floating point.
4709
4710;; Even though we only accept memory inputs, the backend _really_
4711;; wants to be able to do this between registers.
4712
4713(define_expand "floathi<mode>2"
4714  [(set (match_operand:X87MODEF 0 "register_operand" "")
4715	(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4716  "TARGET_80387
4717   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4718       || TARGET_MIX_SSE_I387)")
4719
4720;; Pre-reload splitter to add memory clobber to the pattern.
4721(define_insn_and_split "*floathi<mode>2_1"
4722  [(set (match_operand:X87MODEF 0 "register_operand" "")
4723	(float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4724  "TARGET_80387
4725   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4726       || TARGET_MIX_SSE_I387)
4727   && can_create_pseudo_p ()"
4728  "#"
4729  "&& 1"
4730  [(parallel [(set (match_dup 0)
4731	      (float:X87MODEF (match_dup 1)))
4732   (clobber (match_dup 2))])]
4733  "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4734
4735(define_insn "*floathi<mode>2_i387_with_temp"
4736  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4737	(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4738  (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4739  "TARGET_80387
4740   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4741       || TARGET_MIX_SSE_I387)"
4742  "#"
4743  [(set_attr "type" "fmov,multi")
4744   (set_attr "mode" "<MODE>")
4745   (set_attr "unit" "*,i387")
4746   (set_attr "fp_int_src" "true")])
4747
4748(define_insn "*floathi<mode>2_i387"
4749  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4750	(float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4751  "TARGET_80387
4752   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4753       || TARGET_MIX_SSE_I387)"
4754  "fild%Z1\t%1"
4755  [(set_attr "type" "fmov")
4756   (set_attr "mode" "<MODE>")
4757   (set_attr "fp_int_src" "true")])
4758
4759(define_split
4760  [(set (match_operand:X87MODEF 0 "register_operand" "")
4761	(float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4762   (clobber (match_operand:HI 2 "memory_operand" ""))]
4763  "TARGET_80387
4764   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4765       || TARGET_MIX_SSE_I387)
4766   && reload_completed"
4767  [(set (match_dup 2) (match_dup 1))
4768   (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4769
4770(define_split
4771  [(set (match_operand:X87MODEF 0 "register_operand" "")
4772	(float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4773   (clobber (match_operand:HI 2 "memory_operand" ""))]
4774   "TARGET_80387
4775    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4776        || TARGET_MIX_SSE_I387)
4777    && reload_completed"
4778  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4779
4780(define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4781  [(set (match_operand:X87MODEF 0 "register_operand" "")
4782	(float:X87MODEF
4783	  (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4784  "TARGET_80387
4785   || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4786       && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4787{
4788  if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4789	&& SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4790      && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4791    {
4792      rtx reg = gen_reg_rtx (XFmode);
4793      rtx (*insn)(rtx, rtx);
4794
4795      emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4796
4797      if (<X87MODEF:MODE>mode == SFmode)
4798	insn = gen_truncxfsf2;
4799      else if (<X87MODEF:MODE>mode == DFmode)
4800	insn = gen_truncxfdf2;
4801      else
4802	gcc_unreachable ();
4803
4804      emit_insn (insn (operands[0], reg));
4805      DONE;
4806    }
4807})
4808
4809;; Pre-reload splitter to add memory clobber to the pattern.
4810(define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4811  [(set (match_operand:X87MODEF 0 "register_operand" "")
4812	(float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4813  "((TARGET_80387
4814     && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4815     && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4816	   && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4817	 || TARGET_MIX_SSE_I387))
4818    || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4819	&& SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4820	&& ((<SWI48x:MODE>mode == SImode
4821	     && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4822	     && optimize_function_for_speed_p (cfun)
4823	     && flag_trapping_math)
4824	    || !(TARGET_INTER_UNIT_CONVERSIONS
4825	         || optimize_function_for_size_p (cfun)))))
4826   && can_create_pseudo_p ()"
4827  "#"
4828  "&& 1"
4829  [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4830	      (clobber (match_dup 2))])]
4831{
4832  operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4833
4834  /* Avoid store forwarding (partial memory) stall penalty
4835     by passing DImode value through XMM registers.  */
4836  if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4837      && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4838      && optimize_function_for_speed_p (cfun))
4839    {
4840      emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4841							    operands[1],
4842							    operands[2]));
4843      DONE;
4844    }
4845})
4846
4847(define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4848  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4849	(float:MODEF
4850	  (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4851   (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4852  "TARGET_SSE2 && TARGET_MIX_SSE_I387
4853   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4854  "#"
4855  [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4856   (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4857   (set_attr "unit" "*,i387,*,*,*")
4858   (set_attr "athlon_decode" "*,*,double,direct,double")
4859   (set_attr "amdfam10_decode" "*,*,vector,double,double")
4860   (set_attr "bdver1_decode" "*,*,double,direct,double")
4861   (set_attr "fp_int_src" "true")])
4862
4863(define_insn "*floatsi<mode>2_vector_mixed"
4864  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4865	(float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4866  "TARGET_SSE2 && TARGET_MIX_SSE_I387
4867   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4868  "@
4869   fild%Z1\t%1
4870   #"
4871  [(set_attr "type" "fmov,sseicvt")
4872   (set_attr "mode" "<MODE>,<ssevecmode>")
4873   (set_attr "unit" "i387,*")
4874   (set_attr "athlon_decode" "*,direct")
4875   (set_attr "amdfam10_decode" "*,double")
4876   (set_attr "bdver1_decode" "*,direct")
4877   (set_attr "fp_int_src" "true")])
4878
4879(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4880  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4881	(float:MODEF
4882	  (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4883   (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4884  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4885   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4886  "#"
4887  [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4888   (set_attr "mode" "<MODEF:MODE>")
4889   (set_attr "unit" "*,i387,*,*")
4890   (set_attr "athlon_decode" "*,*,double,direct")
4891   (set_attr "amdfam10_decode" "*,*,vector,double")
4892   (set_attr "bdver1_decode" "*,*,double,direct")
4893   (set_attr "fp_int_src" "true")])
4894
4895(define_split
4896  [(set (match_operand:MODEF 0 "register_operand" "")
4897	(float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4898   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4899  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4900   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4901   && TARGET_INTER_UNIT_CONVERSIONS
4902   && reload_completed
4903   && (SSE_REG_P (operands[0])
4904       || (GET_CODE (operands[0]) == SUBREG
4905	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
4906  [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4907
4908(define_split
4909  [(set (match_operand:MODEF 0 "register_operand" "")
4910	(float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4911   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4912  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4913   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4914   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4915   && reload_completed
4916   && (SSE_REG_P (operands[0])
4917       || (GET_CODE (operands[0]) == SUBREG
4918	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
4919  [(set (match_dup 2) (match_dup 1))
4920   (set (match_dup 0) (float:MODEF (match_dup 2)))])
4921
4922(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4923  [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4924	(float:MODEF
4925	  (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4926  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4927   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4928   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4929  "@
4930   fild%Z1\t%1
4931   %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4932   %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4933  [(set_attr "type" "fmov,sseicvt,sseicvt")
4934   (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4935   (set_attr "mode" "<MODEF:MODE>")
4936   (set (attr "prefix_rex")
4937     (if_then_else
4938       (and (eq_attr "prefix" "maybe_vex")
4939	    (match_test "<SWI48x:MODE>mode == DImode"))
4940       (const_string "1")
4941       (const_string "*")))
4942   (set_attr "unit" "i387,*,*")
4943   (set_attr "athlon_decode" "*,double,direct")
4944   (set_attr "amdfam10_decode" "*,vector,double")
4945   (set_attr "bdver1_decode" "*,double,direct")
4946   (set_attr "fp_int_src" "true")])
4947
4948(define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4949  [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4950	(float:MODEF
4951	  (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4952  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4953   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4954   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4955  "@
4956   fild%Z1\t%1
4957   %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4958  [(set_attr "type" "fmov,sseicvt")
4959   (set_attr "prefix" "orig,maybe_vex")
4960   (set_attr "mode" "<MODEF:MODE>")
4961   (set (attr "prefix_rex")
4962     (if_then_else
4963       (and (eq_attr "prefix" "maybe_vex")
4964	    (match_test "<SWI48x:MODE>mode == DImode"))
4965       (const_string "1")
4966       (const_string "*")))
4967   (set_attr "athlon_decode" "*,direct")
4968   (set_attr "amdfam10_decode" "*,double")
4969   (set_attr "bdver1_decode" "*,direct")
4970   (set_attr "fp_int_src" "true")])
4971
4972(define_insn "*floatsi<mode>2_vector_sse_with_temp"
4973  [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4974	(float:MODEF
4975	  (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4976   (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4977  "TARGET_SSE2 && TARGET_SSE_MATH
4978   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4979  "#"
4980  [(set_attr "type" "sseicvt")
4981   (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4982   (set_attr "athlon_decode" "double,direct,double")
4983   (set_attr "amdfam10_decode" "vector,double,double")
4984   (set_attr "bdver1_decode" "double,direct,double")
4985   (set_attr "fp_int_src" "true")])
4986
4987(define_insn "*floatsi<mode>2_vector_sse"
4988  [(set (match_operand:MODEF 0 "register_operand" "=x")
4989	(float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4990  "TARGET_SSE2 && TARGET_SSE_MATH
4991   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4992  "#"
4993  [(set_attr "type" "sseicvt")
4994   (set_attr "mode" "<MODE>")
4995   (set_attr "athlon_decode" "direct")
4996   (set_attr "amdfam10_decode" "double")
4997   (set_attr "bdver1_decode" "direct")
4998   (set_attr "fp_int_src" "true")])
4999
5000(define_split
5001  [(set (match_operand:MODEF 0 "register_operand" "")
5002	(float:MODEF (match_operand:SI 1 "register_operand" "")))
5003   (clobber (match_operand:SI 2 "memory_operand" ""))]
5004  "TARGET_SSE2 && TARGET_SSE_MATH
5005   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5006   && reload_completed
5007   && (SSE_REG_P (operands[0])
5008       || (GET_CODE (operands[0]) == SUBREG
5009	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5010  [(const_int 0)]
5011{
5012  rtx op1 = operands[1];
5013
5014  operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5015				     <MODE>mode, 0);
5016  if (GET_CODE (op1) == SUBREG)
5017    op1 = SUBREG_REG (op1);
5018
5019  if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5020    {
5021      operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5022      emit_insn (gen_sse2_loadld (operands[4],
5023				  CONST0_RTX (V4SImode), operands[1]));
5024    }
5025  /* We can ignore possible trapping value in the
5026     high part of SSE register for non-trapping math. */
5027  else if (SSE_REG_P (op1) && !flag_trapping_math)
5028    operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5029  else
5030    {
5031      operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5032      emit_move_insn (operands[2], operands[1]);
5033      emit_insn (gen_sse2_loadld (operands[4],
5034				  CONST0_RTX (V4SImode), operands[2]));
5035    }
5036  if (<ssevecmode>mode == V4SFmode)
5037    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5038  else
5039    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5040  DONE;
5041})
5042
5043(define_split
5044  [(set (match_operand:MODEF 0 "register_operand" "")
5045	(float:MODEF (match_operand:SI 1 "memory_operand" "")))
5046   (clobber (match_operand:SI 2 "memory_operand" ""))]
5047  "TARGET_SSE2 && TARGET_SSE_MATH
5048   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5049   && reload_completed
5050   && (SSE_REG_P (operands[0])
5051       || (GET_CODE (operands[0]) == SUBREG
5052	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5053  [(const_int 0)]
5054{
5055  operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5056				     <MODE>mode, 0);
5057  operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5058
5059  emit_insn (gen_sse2_loadld (operands[4],
5060			      CONST0_RTX (V4SImode), operands[1]));
5061  if (<ssevecmode>mode == V4SFmode)
5062    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5063  else
5064    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5065  DONE;
5066})
5067
5068(define_split
5069  [(set (match_operand:MODEF 0 "register_operand" "")
5070	(float:MODEF (match_operand:SI 1 "register_operand" "")))]
5071  "TARGET_SSE2 && TARGET_SSE_MATH
5072   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5073   && reload_completed
5074   && (SSE_REG_P (operands[0])
5075       || (GET_CODE (operands[0]) == SUBREG
5076	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5077  [(const_int 0)]
5078{
5079  rtx op1 = operands[1];
5080
5081  operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5082				     <MODE>mode, 0);
5083  if (GET_CODE (op1) == SUBREG)
5084    op1 = SUBREG_REG (op1);
5085
5086  if (GENERAL_REG_P (op1))
5087    {
5088      operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5089      if (TARGET_INTER_UNIT_MOVES)
5090	emit_insn (gen_sse2_loadld (operands[4],
5091				    CONST0_RTX (V4SImode), operands[1]));
5092      else
5093	{
5094	  operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5095					      operands[1]);
5096	  emit_insn (gen_sse2_loadld (operands[4],
5097				      CONST0_RTX (V4SImode), operands[5]));
5098	  ix86_free_from_memory (GET_MODE (operands[1]));
5099	}
5100    }
5101  /* We can ignore possible trapping value in the
5102     high part of SSE register for non-trapping math. */
5103  else if (SSE_REG_P (op1) && !flag_trapping_math)
5104    operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5105  else
5106    gcc_unreachable ();
5107  if (<ssevecmode>mode == V4SFmode)
5108    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5109  else
5110    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5111  DONE;
5112})
5113
5114(define_split
5115  [(set (match_operand:MODEF 0 "register_operand" "")
5116	(float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5117  "TARGET_SSE2 && TARGET_SSE_MATH
5118   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5119   && reload_completed
5120   && (SSE_REG_P (operands[0])
5121       || (GET_CODE (operands[0]) == SUBREG
5122	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5123  [(const_int 0)]
5124{
5125  operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5126				     <MODE>mode, 0);
5127  operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5128
5129  emit_insn (gen_sse2_loadld (operands[4],
5130			      CONST0_RTX (V4SImode), operands[1]));
5131  if (<ssevecmode>mode == V4SFmode)
5132    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5133  else
5134    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5135  DONE;
5136})
5137
5138(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5139  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5140	(float:MODEF
5141	  (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5142  (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5143  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5144   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5145  "#"
5146  [(set_attr "type" "sseicvt")
5147   (set_attr "mode" "<MODEF:MODE>")
5148   (set_attr "athlon_decode" "double,direct")
5149   (set_attr "amdfam10_decode" "vector,double")
5150   (set_attr "bdver1_decode" "double,direct")
5151   (set_attr "fp_int_src" "true")])
5152
5153(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5154  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5155	(float:MODEF
5156	  (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5157  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5158   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5159   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5160  "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5161  [(set_attr "type" "sseicvt")
5162   (set_attr "prefix" "maybe_vex")
5163   (set_attr "mode" "<MODEF:MODE>")
5164   (set (attr "prefix_rex")
5165     (if_then_else
5166       (and (eq_attr "prefix" "maybe_vex")
5167	    (match_test "<SWI48x:MODE>mode == DImode"))
5168       (const_string "1")
5169       (const_string "*")))
5170   (set_attr "athlon_decode" "double,direct")
5171   (set_attr "amdfam10_decode" "vector,double")
5172   (set_attr "bdver1_decode" "double,direct")
5173   (set_attr "fp_int_src" "true")])
5174
5175(define_split
5176  [(set (match_operand:MODEF 0 "register_operand" "")
5177	(float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5178   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5179  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5180   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5181   && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5182   && reload_completed
5183   && (SSE_REG_P (operands[0])
5184       || (GET_CODE (operands[0]) == SUBREG
5185	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5186  [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5187
5188(define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5189  [(set (match_operand:MODEF 0 "register_operand" "=x")
5190	(float:MODEF
5191	  (match_operand:SWI48x 1 "memory_operand" "m")))]
5192  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5193   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5194   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5195  "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5196  [(set_attr "type" "sseicvt")
5197   (set_attr "prefix" "maybe_vex")
5198   (set_attr "mode" "<MODEF:MODE>")
5199   (set (attr "prefix_rex")
5200     (if_then_else
5201       (and (eq_attr "prefix" "maybe_vex")
5202	    (match_test "<SWI48x:MODE>mode == DImode"))
5203       (const_string "1")
5204       (const_string "*")))
5205   (set_attr "athlon_decode" "direct")
5206   (set_attr "amdfam10_decode" "double")
5207   (set_attr "bdver1_decode" "direct")
5208   (set_attr "fp_int_src" "true")])
5209
5210(define_split
5211  [(set (match_operand:MODEF 0 "register_operand" "")
5212	(float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5213   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5214  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5215   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5216   && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5217   && reload_completed
5218   && (SSE_REG_P (operands[0])
5219       || (GET_CODE (operands[0]) == SUBREG
5220	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5221  [(set (match_dup 2) (match_dup 1))
5222   (set (match_dup 0) (float:MODEF (match_dup 2)))])
5223
5224(define_split
5225  [(set (match_operand:MODEF 0 "register_operand" "")
5226	(float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5227   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5228  "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5229   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5230   && reload_completed
5231   && (SSE_REG_P (operands[0])
5232       || (GET_CODE (operands[0]) == SUBREG
5233	   && SSE_REG_P (SUBREG_REG (operands[0]))))"
5234  [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5235
5236(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5237  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5238	(float:X87MODEF
5239	  (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5240  (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5241  "TARGET_80387
5242   && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5243  "@
5244   fild%Z1\t%1
5245   #"
5246  [(set_attr "type" "fmov,multi")
5247   (set_attr "mode" "<X87MODEF:MODE>")
5248   (set_attr "unit" "*,i387")
5249   (set_attr "fp_int_src" "true")])
5250
5251(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5252  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5253	(float:X87MODEF
5254	  (match_operand:SWI48x 1 "memory_operand" "m")))]
5255  "TARGET_80387
5256   && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5257  "fild%Z1\t%1"
5258  [(set_attr "type" "fmov")
5259   (set_attr "mode" "<X87MODEF:MODE>")
5260   (set_attr "fp_int_src" "true")])
5261
5262(define_split
5263  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5264	(float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5265   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5266  "TARGET_80387
5267   && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5268   && reload_completed"
5269  [(set (match_dup 2) (match_dup 1))
5270   (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5271
5272(define_split
5273  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5274	(float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5275   (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5276  "TARGET_80387
5277   && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5278   && reload_completed"
5279  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5280
5281;; Avoid store forwarding (partial memory) stall penalty
5282;; by passing DImode value through XMM registers.  */
5283
5284(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5285  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5286	(float:X87MODEF
5287	  (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5288   (clobber (match_scratch:V4SI 3 "=X,x"))
5289   (clobber (match_scratch:V4SI 4 "=X,x"))
5290   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5291  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5292   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5293   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5294  "#"
5295  [(set_attr "type" "multi")
5296   (set_attr "mode" "<X87MODEF:MODE>")
5297   (set_attr "unit" "i387")
5298   (set_attr "fp_int_src" "true")])
5299
5300(define_split
5301  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5302	(float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5303   (clobber (match_scratch:V4SI 3 ""))
5304   (clobber (match_scratch:V4SI 4 ""))
5305   (clobber (match_operand:DI 2 "memory_operand" ""))]
5306  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5308   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5309   && reload_completed"
5310  [(set (match_dup 2) (match_dup 3))
5311   (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5312{
5313  /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5314     Assemble the 64-bit DImode value in an xmm register.  */
5315  emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5316			      gen_rtx_SUBREG (SImode, operands[1], 0)));
5317  emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5318			      gen_rtx_SUBREG (SImode, operands[1], 4)));
5319  emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5320  	    				 operands[4]));
5321
5322  operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5323})
5324
5325(define_split
5326  [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5327	(float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5328   (clobber (match_scratch:V4SI 3 ""))
5329   (clobber (match_scratch:V4SI 4 ""))
5330   (clobber (match_operand:DI 2 "memory_operand" ""))]
5331  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5333   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5334   && reload_completed"
5335  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5336
5337;; Avoid store forwarding (partial memory) stall penalty by extending
5338;; SImode value to DImode through XMM register instead of pushing two
5339;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5340;; targets benefit from this optimization. Also note that fild
5341;; loads from memory only.
5342
5343(define_insn "*floatunssi<mode>2_1"
5344  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5345	(unsigned_float:X87MODEF
5346	  (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5347   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5348   (clobber (match_scratch:SI 3 "=X,x"))]
5349  "!TARGET_64BIT
5350   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351   && TARGET_SSE"
5352  "#"
5353  [(set_attr "type" "multi")
5354   (set_attr "mode" "<MODE>")])
5355
5356(define_split
5357  [(set (match_operand:X87MODEF 0 "register_operand" "")
5358	(unsigned_float:X87MODEF
5359	  (match_operand:SI 1 "register_operand" "")))
5360   (clobber (match_operand:DI 2 "memory_operand" ""))
5361   (clobber (match_scratch:SI 3 ""))]
5362  "!TARGET_64BIT
5363   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5364   && TARGET_SSE
5365   && reload_completed"
5366  [(set (match_dup 2) (match_dup 1))
5367   (set (match_dup 0)
5368	(float:X87MODEF (match_dup 2)))]
5369  "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5370
5371(define_split
5372  [(set (match_operand:X87MODEF 0 "register_operand" "")
5373	(unsigned_float:X87MODEF
5374	  (match_operand:SI 1 "memory_operand" "")))
5375   (clobber (match_operand:DI 2 "memory_operand" ""))
5376   (clobber (match_scratch:SI 3 ""))]
5377  "!TARGET_64BIT
5378   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5379   && TARGET_SSE
5380   && reload_completed"
5381  [(set (match_dup 2) (match_dup 3))
5382   (set (match_dup 0)
5383	(float:X87MODEF (match_dup 2)))]
5384{
5385  emit_move_insn (operands[3], operands[1]);
5386  operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5387})
5388
5389(define_expand "floatunssi<mode>2"
5390  [(parallel
5391     [(set (match_operand:X87MODEF 0 "register_operand" "")
5392	   (unsigned_float:X87MODEF
5393	     (match_operand:SI 1 "nonimmediate_operand" "")))
5394      (clobber (match_dup 2))
5395      (clobber (match_scratch:SI 3 ""))])]
5396  "!TARGET_64BIT
5397   && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5398	&& TARGET_SSE)
5399       || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5400{
5401  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5402    {
5403      ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5404      DONE;
5405    }
5406  else
5407    operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5408})
5409
5410(define_expand "floatunsdisf2"
5411  [(use (match_operand:SF 0 "register_operand" ""))
5412   (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5413  "TARGET_64BIT && TARGET_SSE_MATH"
5414  "x86_emit_floatuns (operands); DONE;")
5415
5416(define_expand "floatunsdidf2"
5417  [(use (match_operand:DF 0 "register_operand" ""))
5418   (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5419  "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5420   && TARGET_SSE2 && TARGET_SSE_MATH"
5421{
5422  if (TARGET_64BIT)
5423    x86_emit_floatuns (operands);
5424  else
5425    ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5426  DONE;
5427})
5428
5429;; Load effective address instructions
5430
5431(define_insn_and_split "*lea<mode>"
5432  [(set (match_operand:SWI48 0 "register_operand" "=r")
5433	(match_operand:SWI48 1 "lea_address_operand" "p"))]
5434  ""
5435{
5436  rtx addr = operands[1];
5437
5438  if (SImode_address_operand (addr, VOIDmode))
5439    {
5440      gcc_assert (TARGET_64BIT);
5441      return "lea{l}\t{%E1, %k0|%k0, %E1}";
5442    }
5443  else
5444    return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5445}
5446  "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5447  [(const_int 0)]
5448{
5449  ix86_split_lea_for_addr (operands, <MODE>mode);
5450  DONE;
5451}
5452  [(set_attr "type" "lea")
5453   (set (attr "mode")
5454     (if_then_else
5455       (match_operand 1 "SImode_address_operand")
5456       (const_string "SI")
5457       (const_string "<MODE>")))])
5458
5459;; Add instructions
5460
5461(define_expand "add<mode>3"
5462  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5463	(plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5464		    (match_operand:SDWIM 2 "<general_operand>" "")))]
5465  ""
5466  "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5467
5468(define_insn_and_split "*add<dwi>3_doubleword"
5469  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5470	(plus:<DWI>
5471	  (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5472	  (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5473   (clobber (reg:CC FLAGS_REG))]
5474  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5475  "#"
5476  "reload_completed"
5477  [(parallel [(set (reg:CC FLAGS_REG)
5478		   (unspec:CC [(match_dup 1) (match_dup 2)]
5479			      UNSPEC_ADD_CARRY))
5480	      (set (match_dup 0)
5481		   (plus:DWIH (match_dup 1) (match_dup 2)))])
5482   (parallel [(set (match_dup 3)
5483		   (plus:DWIH
5484		     (match_dup 4)
5485		     (plus:DWIH
5486		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5487		       (match_dup 5))))
5488	      (clobber (reg:CC FLAGS_REG))])]
5489  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5490
5491(define_insn "*add<mode>3_cc"
5492  [(set (reg:CC FLAGS_REG)
5493	(unspec:CC
5494	  [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5495	   (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5496	  UNSPEC_ADD_CARRY))
5497   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5498	(plus:SWI48 (match_dup 1) (match_dup 2)))]
5499  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5500  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5501  [(set_attr "type" "alu")
5502   (set_attr "mode" "<MODE>")])
5503
5504(define_insn "addqi3_cc"
5505  [(set (reg:CC FLAGS_REG)
5506	(unspec:CC
5507	  [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5508	   (match_operand:QI 2 "general_operand" "qn,qm")]
5509	  UNSPEC_ADD_CARRY))
5510   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5511	(plus:QI (match_dup 1) (match_dup 2)))]
5512  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5513  "add{b}\t{%2, %0|%0, %2}"
5514  [(set_attr "type" "alu")
5515   (set_attr "mode" "QI")])
5516
5517(define_insn "*add<mode>_1"
5518  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5519	(plus:SWI48
5520	  (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5521	  (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5522   (clobber (reg:CC FLAGS_REG))]
5523  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5524{
5525  switch (get_attr_type (insn))
5526    {
5527    case TYPE_LEA:
5528      return "#";
5529
5530    case TYPE_INCDEC:
5531      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5532      if (operands[2] == const1_rtx)
5533        return "inc{<imodesuffix>}\t%0";
5534      else
5535        {
5536	  gcc_assert (operands[2] == constm1_rtx);
5537          return "dec{<imodesuffix>}\t%0";
5538	}
5539
5540    default:
5541      /* For most processors, ADD is faster than LEA.  This alternative
5542	 was added to use ADD as much as possible.  */
5543      if (which_alternative == 2)
5544	{
5545	  rtx tmp;
5546	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5547	}
5548
5549      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5550      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5551        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5552
5553      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5554    }
5555}
5556  [(set (attr "type")
5557     (cond [(eq_attr "alternative" "3")
5558              (const_string "lea")
5559	    (match_operand:SWI48 2 "incdec_operand" "")
5560	      (const_string "incdec")
5561	   ]
5562	   (const_string "alu")))
5563   (set (attr "length_immediate")
5564      (if_then_else
5565	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5566	(const_string "1")
5567	(const_string "*")))
5568   (set_attr "mode" "<MODE>")])
5569
5570;; It may seem that nonimmediate operand is proper one for operand 1.
5571;; The addsi_1 pattern allows nonimmediate operand at that place and
5572;; we take care in ix86_binary_operator_ok to not allow two memory
5573;; operands so proper swapping will be done in reload.  This allow
5574;; patterns constructed from addsi_1 to match.
5575
5576(define_insn "addsi_1_zext"
5577  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5578	(zero_extend:DI
5579	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5580		   (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5581   (clobber (reg:CC FLAGS_REG))]
5582  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5583{
5584  switch (get_attr_type (insn))
5585    {
5586    case TYPE_LEA:
5587      return "#";
5588
5589    case TYPE_INCDEC:
5590      if (operands[2] == const1_rtx)
5591        return "inc{l}\t%k0";
5592      else
5593        {
5594	  gcc_assert (operands[2] == constm1_rtx);
5595          return "dec{l}\t%k0";
5596	}
5597
5598    default:
5599      /* For most processors, ADD is faster than LEA.  This alternative
5600	 was added to use ADD as much as possible.  */
5601      if (which_alternative == 1)
5602	{
5603	  rtx tmp;
5604	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5605	}
5606
5607      if (x86_maybe_negate_const_int (&operands[2], SImode))
5608        return "sub{l}\t{%2, %k0|%k0, %2}";
5609
5610      return "add{l}\t{%2, %k0|%k0, %2}";
5611    }
5612}
5613  [(set (attr "type")
5614     (cond [(eq_attr "alternative" "2")
5615	      (const_string "lea")
5616	    (match_operand:SI 2 "incdec_operand" "")
5617	      (const_string "incdec")
5618	   ]
5619	   (const_string "alu")))
5620   (set (attr "length_immediate")
5621      (if_then_else
5622	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5623	(const_string "1")
5624	(const_string "*")))
5625   (set_attr "mode" "SI")])
5626
5627(define_insn "*addhi_1"
5628  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5629	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5630		 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5631   (clobber (reg:CC FLAGS_REG))]
5632  "ix86_binary_operator_ok (PLUS, HImode, operands)"
5633{
5634  switch (get_attr_type (insn))
5635    {
5636    case TYPE_LEA:
5637      return "#";
5638
5639    case TYPE_INCDEC:
5640      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641      if (operands[2] == const1_rtx)
5642	return "inc{w}\t%0";
5643      else
5644	{
5645	  gcc_assert (operands[2] == constm1_rtx);
5646	  return "dec{w}\t%0";
5647	}
5648
5649    default:
5650      /* For most processors, ADD is faster than LEA.  This alternative
5651	 was added to use ADD as much as possible.  */
5652      if (which_alternative == 2)
5653	{
5654	  rtx tmp;
5655	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5656	}
5657
5658      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5659      if (x86_maybe_negate_const_int (&operands[2], HImode))
5660	return "sub{w}\t{%2, %0|%0, %2}";
5661
5662      return "add{w}\t{%2, %0|%0, %2}";
5663    }
5664}
5665  [(set (attr "type")
5666     (cond [(eq_attr "alternative" "3")
5667              (const_string "lea")
5668	    (match_operand:HI 2 "incdec_operand" "")
5669	      (const_string "incdec")
5670	   ]
5671	   (const_string "alu")))
5672   (set (attr "length_immediate")
5673      (if_then_else
5674	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5675	(const_string "1")
5676	(const_string "*")))
5677   (set_attr "mode" "HI,HI,HI,SI")])
5678
5679;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5680(define_insn "*addqi_1"
5681  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5682	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5683		 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5684   (clobber (reg:CC FLAGS_REG))]
5685  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5686{
5687  bool widen = (which_alternative == 3 || which_alternative == 4);
5688
5689  switch (get_attr_type (insn))
5690    {
5691    case TYPE_LEA:
5692      return "#";
5693
5694    case TYPE_INCDEC:
5695      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5696      if (operands[2] == const1_rtx)
5697	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5698      else
5699	{
5700	  gcc_assert (operands[2] == constm1_rtx);
5701	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5702	}
5703
5704    default:
5705      /* For most processors, ADD is faster than LEA.  These alternatives
5706	 were added to use ADD as much as possible.  */
5707      if (which_alternative == 2 || which_alternative == 4)
5708	{
5709	  rtx tmp;
5710	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5711	}
5712
5713      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5714      if (x86_maybe_negate_const_int (&operands[2], QImode))
5715	{
5716	  if (widen)
5717	    return "sub{l}\t{%2, %k0|%k0, %2}";
5718	  else
5719	    return "sub{b}\t{%2, %0|%0, %2}";
5720	}
5721      if (widen)
5722        return "add{l}\t{%k2, %k0|%k0, %k2}";
5723      else
5724        return "add{b}\t{%2, %0|%0, %2}";
5725    }
5726}
5727  [(set (attr "type")
5728     (cond [(eq_attr "alternative" "5")
5729              (const_string "lea")
5730	    (match_operand:QI 2 "incdec_operand" "")
5731	      (const_string "incdec")
5732	   ]
5733	   (const_string "alu")))
5734   (set (attr "length_immediate")
5735      (if_then_else
5736	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5737	(const_string "1")
5738	(const_string "*")))
5739   (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5740
5741(define_insn "*addqi_1_slp"
5742  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5743	(plus:QI (match_dup 0)
5744		 (match_operand:QI 1 "general_operand" "qn,qm")))
5745   (clobber (reg:CC FLAGS_REG))]
5746  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5747   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5748{
5749  switch (get_attr_type (insn))
5750    {
5751    case TYPE_INCDEC:
5752      if (operands[1] == const1_rtx)
5753	return "inc{b}\t%0";
5754      else
5755	{
5756	  gcc_assert (operands[1] == constm1_rtx);
5757	  return "dec{b}\t%0";
5758	}
5759
5760    default:
5761      if (x86_maybe_negate_const_int (&operands[1], QImode))
5762	return "sub{b}\t{%1, %0|%0, %1}";
5763
5764      return "add{b}\t{%1, %0|%0, %1}";
5765    }
5766}
5767  [(set (attr "type")
5768     (if_then_else (match_operand:QI 1 "incdec_operand" "")
5769	(const_string "incdec")
5770	(const_string "alu1")))
5771   (set (attr "memory")
5772     (if_then_else (match_operand 1 "memory_operand" "")
5773        (const_string "load")
5774        (const_string "none")))
5775   (set_attr "mode" "QI")])
5776
5777;; Split non destructive adds if we cannot use lea.
5778(define_split
5779  [(set (match_operand:SWI48 0 "register_operand" "")
5780	(plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5781              (match_operand:SWI48 2 "nonmemory_operand" "")))
5782   (clobber (reg:CC FLAGS_REG))]
5783  "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5784  [(set (match_dup 0) (match_dup 1))
5785   (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5786	      (clobber (reg:CC FLAGS_REG))])])
5787
5788;; Convert add to the lea pattern to avoid flags dependency.
5789(define_split
5790  [(set (match_operand:SWI 0 "register_operand" "")
5791	(plus:SWI (match_operand:SWI 1 "register_operand" "")
5792		  (match_operand:SWI 2 "<nonmemory_operand>" "")))
5793   (clobber (reg:CC FLAGS_REG))]
5794  "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5795  [(const_int 0)]
5796{
5797  enum machine_mode mode = <MODE>mode;
5798  rtx pat;
5799
5800  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5801    {
5802      mode = SImode;
5803      operands[0] = gen_lowpart (mode, operands[0]);
5804      operands[1] = gen_lowpart (mode, operands[1]);
5805      operands[2] = gen_lowpart (mode, operands[2]);
5806    }
5807
5808  pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5809
5810  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5811  DONE;
5812})
5813
5814;; Convert add to the lea pattern to avoid flags dependency.
5815(define_split
5816  [(set (match_operand:DI 0 "register_operand" "")
5817	(zero_extend:DI
5818	  (plus:SI (match_operand:SI 1 "register_operand" "")
5819		   (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5820   (clobber (reg:CC FLAGS_REG))]
5821  "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5822  [(set (match_dup 0)
5823	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5824
5825(define_insn "*add<mode>_2"
5826  [(set (reg FLAGS_REG)
5827	(compare
5828	  (plus:SWI
5829	    (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5830	    (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5831	  (const_int 0)))
5832   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5833	(plus:SWI (match_dup 1) (match_dup 2)))]
5834  "ix86_match_ccmode (insn, CCGOCmode)
5835   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5836{
5837  switch (get_attr_type (insn))
5838    {
5839    case TYPE_INCDEC:
5840      if (operands[2] == const1_rtx)
5841        return "inc{<imodesuffix>}\t%0";
5842      else
5843        {
5844	  gcc_assert (operands[2] == constm1_rtx);
5845          return "dec{<imodesuffix>}\t%0";
5846	}
5847
5848    default:
5849      if (which_alternative == 2)
5850	{
5851	  rtx tmp;
5852	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5853	}
5854
5855      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5856      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5857        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5858
5859      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5860    }
5861}
5862  [(set (attr "type")
5863     (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5864	(const_string "incdec")
5865	(const_string "alu")))
5866   (set (attr "length_immediate")
5867      (if_then_else
5868	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5869	(const_string "1")
5870	(const_string "*")))
5871   (set_attr "mode" "<MODE>")])
5872
5873;; See comment for addsi_1_zext why we do use nonimmediate_operand
5874(define_insn "*addsi_2_zext"
5875  [(set (reg FLAGS_REG)
5876	(compare
5877	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5878		   (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5879	  (const_int 0)))
5880   (set (match_operand:DI 0 "register_operand" "=r,r")
5881	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5882  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5883   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5884{
5885  switch (get_attr_type (insn))
5886    {
5887    case TYPE_INCDEC:
5888      if (operands[2] == const1_rtx)
5889        return "inc{l}\t%k0";
5890      else
5891	{
5892	  gcc_assert (operands[2] == constm1_rtx);
5893          return "dec{l}\t%k0";
5894	}
5895
5896    default:
5897      if (which_alternative == 1)
5898	{
5899	  rtx tmp;
5900	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5901	}
5902
5903      if (x86_maybe_negate_const_int (&operands[2], SImode))
5904        return "sub{l}\t{%2, %k0|%k0, %2}";
5905
5906      return "add{l}\t{%2, %k0|%k0, %2}";
5907    }
5908}
5909  [(set (attr "type")
5910     (if_then_else (match_operand:SI 2 "incdec_operand" "")
5911	(const_string "incdec")
5912	(const_string "alu")))
5913   (set (attr "length_immediate")
5914      (if_then_else
5915	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5916	(const_string "1")
5917	(const_string "*")))
5918   (set_attr "mode" "SI")])
5919
5920(define_insn "*add<mode>_3"
5921  [(set (reg FLAGS_REG)
5922	(compare
5923	  (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5924	  (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5925   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5926  "ix86_match_ccmode (insn, CCZmode)
5927   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5928{
5929  switch (get_attr_type (insn))
5930    {
5931    case TYPE_INCDEC:
5932      if (operands[2] == const1_rtx)
5933        return "inc{<imodesuffix>}\t%0";
5934      else
5935        {
5936	  gcc_assert (operands[2] == constm1_rtx);
5937          return "dec{<imodesuffix>}\t%0";
5938	}
5939
5940    default:
5941      if (which_alternative == 1)
5942	{
5943	  rtx tmp;
5944	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5945	}
5946
5947      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5948      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5949        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5950
5951      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5952    }
5953}
5954  [(set (attr "type")
5955     (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5956	(const_string "incdec")
5957	(const_string "alu")))
5958   (set (attr "length_immediate")
5959      (if_then_else
5960	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5961	(const_string "1")
5962	(const_string "*")))
5963   (set_attr "mode" "<MODE>")])
5964
5965;; See comment for addsi_1_zext why we do use nonimmediate_operand
5966(define_insn "*addsi_3_zext"
5967  [(set (reg FLAGS_REG)
5968	(compare
5969	  (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5970	  (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5971   (set (match_operand:DI 0 "register_operand" "=r,r")
5972	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5973  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5974   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5975{
5976  switch (get_attr_type (insn))
5977    {
5978    case TYPE_INCDEC:
5979      if (operands[2] == const1_rtx)
5980        return "inc{l}\t%k0";
5981      else
5982        {
5983	  gcc_assert (operands[2] == constm1_rtx);
5984          return "dec{l}\t%k0";
5985	}
5986
5987    default:
5988      if (which_alternative == 1)
5989	{
5990	  rtx tmp;
5991	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5992	}
5993
5994      if (x86_maybe_negate_const_int (&operands[2], SImode))
5995        return "sub{l}\t{%2, %k0|%k0, %2}";
5996
5997      return "add{l}\t{%2, %k0|%k0, %2}";
5998    }
5999}
6000  [(set (attr "type")
6001     (if_then_else (match_operand:SI 2 "incdec_operand" "")
6002	(const_string "incdec")
6003	(const_string "alu")))
6004   (set (attr "length_immediate")
6005      (if_then_else
6006	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6007	(const_string "1")
6008	(const_string "*")))
6009   (set_attr "mode" "SI")])
6010
6011; For comparisons against 1, -1 and 128, we may generate better code
6012; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6013; is matched then.  We can't accept general immediate, because for
6014; case of overflows,  the result is messed up.
6015; Also carry flag is reversed compared to cmp, so this conversion is valid
6016; only for comparisons not depending on it.
6017
6018(define_insn "*adddi_4"
6019  [(set (reg FLAGS_REG)
6020	(compare
6021	  (match_operand:DI 1 "nonimmediate_operand" "0")
6022	  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6023   (clobber (match_scratch:DI 0 "=rm"))]
6024  "TARGET_64BIT
6025   && ix86_match_ccmode (insn, CCGCmode)"
6026{
6027  switch (get_attr_type (insn))
6028    {
6029    case TYPE_INCDEC:
6030      if (operands[2] == constm1_rtx)
6031        return "inc{q}\t%0";
6032      else
6033        {
6034	  gcc_assert (operands[2] == const1_rtx);
6035          return "dec{q}\t%0";
6036	}
6037
6038    default:
6039      if (x86_maybe_negate_const_int (&operands[2], DImode))
6040	return "add{q}\t{%2, %0|%0, %2}";
6041
6042      return "sub{q}\t{%2, %0|%0, %2}";
6043    }
6044}
6045  [(set (attr "type")
6046     (if_then_else (match_operand:DI 2 "incdec_operand" "")
6047	(const_string "incdec")
6048	(const_string "alu")))
6049   (set (attr "length_immediate")
6050      (if_then_else
6051	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6052	(const_string "1")
6053	(const_string "*")))
6054   (set_attr "mode" "DI")])
6055
6056; For comparisons against 1, -1 and 128, we may generate better code
6057; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6058; is matched then.  We can't accept general immediate, because for
6059; case of overflows,  the result is messed up.
6060; Also carry flag is reversed compared to cmp, so this conversion is valid
6061; only for comparisons not depending on it.
6062
6063(define_insn "*add<mode>_4"
6064  [(set (reg FLAGS_REG)
6065	(compare
6066	  (match_operand:SWI124 1 "nonimmediate_operand" "0")
6067	  (match_operand:SWI124 2 "const_int_operand" "n")))
6068   (clobber (match_scratch:SWI124 0 "=<r>m"))]
6069  "ix86_match_ccmode (insn, CCGCmode)"
6070{
6071  switch (get_attr_type (insn))
6072    {
6073    case TYPE_INCDEC:
6074      if (operands[2] == constm1_rtx)
6075        return "inc{<imodesuffix>}\t%0";
6076      else
6077        {
6078	  gcc_assert (operands[2] == const1_rtx);
6079          return "dec{<imodesuffix>}\t%0";
6080	}
6081
6082    default:
6083      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6084	return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6085
6086      return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6087    }
6088}
6089  [(set (attr "type")
6090     (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6091	(const_string "incdec")
6092	(const_string "alu")))
6093   (set (attr "length_immediate")
6094      (if_then_else
6095	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6096	(const_string "1")
6097	(const_string "*")))
6098   (set_attr "mode" "<MODE>")])
6099
6100(define_insn "*add<mode>_5"
6101  [(set (reg FLAGS_REG)
6102	(compare
6103	  (plus:SWI
6104	    (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6105	    (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6106	  (const_int 0)))
6107   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6108  "ix86_match_ccmode (insn, CCGOCmode)
6109   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6110{
6111  switch (get_attr_type (insn))
6112    {
6113    case TYPE_INCDEC:
6114      if (operands[2] == const1_rtx)
6115        return "inc{<imodesuffix>}\t%0";
6116      else
6117        {
6118          gcc_assert (operands[2] == constm1_rtx);
6119          return "dec{<imodesuffix>}\t%0";
6120	}
6121
6122    default:
6123      if (which_alternative == 1)
6124	{
6125	  rtx tmp;
6126	  tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6127	}
6128
6129      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6130      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6131        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6132
6133      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6134    }
6135}
6136  [(set (attr "type")
6137     (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6138	(const_string "incdec")
6139	(const_string "alu")))
6140   (set (attr "length_immediate")
6141      (if_then_else
6142	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6143	(const_string "1")
6144	(const_string "*")))
6145   (set_attr "mode" "<MODE>")])
6146
6147(define_insn "*addqi_ext_1_rex64"
6148  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6149			 (const_int 8)
6150			 (const_int 8))
6151	(plus:SI
6152	  (zero_extract:SI
6153	    (match_operand 1 "ext_register_operand" "0")
6154	    (const_int 8)
6155	    (const_int 8))
6156	  (match_operand:QI 2 "nonmemory_operand" "Qn")))
6157   (clobber (reg:CC FLAGS_REG))]
6158  "TARGET_64BIT"
6159{
6160  switch (get_attr_type (insn))
6161    {
6162    case TYPE_INCDEC:
6163      if (operands[2] == const1_rtx)
6164	return "inc{b}\t%h0";
6165      else
6166        {
6167	  gcc_assert (operands[2] == constm1_rtx);
6168          return "dec{b}\t%h0";
6169        }
6170
6171    default:
6172      return "add{b}\t{%2, %h0|%h0, %2}";
6173    }
6174}
6175  [(set (attr "type")
6176     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6177	(const_string "incdec")
6178	(const_string "alu")))
6179   (set_attr "modrm" "1")
6180   (set_attr "mode" "QI")])
6181
6182(define_insn "addqi_ext_1"
6183  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6184			 (const_int 8)
6185			 (const_int 8))
6186	(plus:SI
6187	  (zero_extract:SI
6188	    (match_operand 1 "ext_register_operand" "0")
6189	    (const_int 8)
6190	    (const_int 8))
6191	  (match_operand:QI 2 "general_operand" "Qmn")))
6192   (clobber (reg:CC FLAGS_REG))]
6193  "!TARGET_64BIT"
6194{
6195  switch (get_attr_type (insn))
6196    {
6197    case TYPE_INCDEC:
6198      if (operands[2] == const1_rtx)
6199	return "inc{b}\t%h0";
6200      else
6201        {
6202	  gcc_assert (operands[2] == constm1_rtx);
6203          return "dec{b}\t%h0";
6204	}
6205
6206    default:
6207      return "add{b}\t{%2, %h0|%h0, %2}";
6208    }
6209}
6210  [(set (attr "type")
6211     (if_then_else (match_operand:QI 2 "incdec_operand" "")
6212	(const_string "incdec")
6213	(const_string "alu")))
6214   (set_attr "modrm" "1")
6215   (set_attr "mode" "QI")])
6216
6217(define_insn "*addqi_ext_2"
6218  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6219			 (const_int 8)
6220			 (const_int 8))
6221	(plus:SI
6222	  (zero_extract:SI
6223	    (match_operand 1 "ext_register_operand" "%0")
6224	    (const_int 8)
6225	    (const_int 8))
6226	  (zero_extract:SI
6227	    (match_operand 2 "ext_register_operand" "Q")
6228	    (const_int 8)
6229	    (const_int 8))))
6230   (clobber (reg:CC FLAGS_REG))]
6231  ""
6232  "add{b}\t{%h2, %h0|%h0, %h2}"
6233  [(set_attr "type" "alu")
6234   (set_attr "mode" "QI")])
6235
6236;; The lea patterns for modes less than 32 bits need to be matched by
6237;; several insns converted to real lea by splitters.
6238
6239(define_insn_and_split "*lea_general_1"
6240  [(set (match_operand 0 "register_operand" "=r")
6241	(plus (plus (match_operand 1 "index_register_operand" "l")
6242		    (match_operand 2 "register_operand" "r"))
6243	      (match_operand 3 "immediate_operand" "i")))]
6244  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6245   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6246   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6247   && GET_MODE (operands[0]) == GET_MODE (operands[2])
6248   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6249       || GET_MODE (operands[3]) == VOIDmode)"
6250  "#"
6251  "&& reload_completed"
6252  [(const_int 0)]
6253{
6254  enum machine_mode mode = SImode;
6255  rtx pat;
6256
6257  operands[0] = gen_lowpart (mode, operands[0]);
6258  operands[1] = gen_lowpart (mode, operands[1]);
6259  operands[2] = gen_lowpart (mode, operands[2]);
6260  operands[3] = gen_lowpart (mode, operands[3]);
6261
6262  pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6263  		      operands[3]);
6264
6265  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6266  DONE;
6267}
6268  [(set_attr "type" "lea")
6269   (set_attr "mode" "SI")])
6270
6271(define_insn_and_split "*lea_general_2"
6272  [(set (match_operand 0 "register_operand" "=r")
6273	(plus (mult (match_operand 1 "index_register_operand" "l")
6274		    (match_operand 2 "const248_operand" "n"))
6275	      (match_operand 3 "nonmemory_operand" "ri")))]
6276  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6277   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6278   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6279   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6280       || GET_MODE (operands[3]) == VOIDmode)"
6281  "#"
6282  "&& reload_completed"
6283  [(const_int 0)]
6284{
6285  enum machine_mode mode = SImode;
6286  rtx pat;
6287
6288  operands[0] = gen_lowpart (mode, operands[0]);
6289  operands[1] = gen_lowpart (mode, operands[1]);
6290  operands[3] = gen_lowpart (mode, operands[3]);
6291
6292  pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6293		      operands[3]);
6294
6295  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6296  DONE;
6297}
6298  [(set_attr "type" "lea")
6299   (set_attr "mode" "SI")])
6300
6301(define_insn_and_split "*lea_general_3"
6302  [(set (match_operand 0 "register_operand" "=r")
6303	(plus (plus (mult (match_operand 1 "index_register_operand" "l")
6304			  (match_operand 2 "const248_operand" "n"))
6305		    (match_operand 3 "register_operand" "r"))
6306	      (match_operand 4 "immediate_operand" "i")))]
6307  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6308   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6309   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6310   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6311  "#"
6312  "&& reload_completed"
6313  [(const_int 0)]
6314{
6315  enum machine_mode mode = SImode;
6316  rtx pat;
6317
6318  operands[0] = gen_lowpart (mode, operands[0]);
6319  operands[1] = gen_lowpart (mode, operands[1]);
6320  operands[3] = gen_lowpart (mode, operands[3]);
6321  operands[4] = gen_lowpart (mode, operands[4]);
6322
6323  pat = gen_rtx_PLUS (mode,
6324  		      gen_rtx_PLUS (mode,
6325				    gen_rtx_MULT (mode, operands[1],
6326		      					operands[2]),
6327				    operands[3]),
6328  		      operands[4]);
6329
6330  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6331  DONE;
6332}
6333  [(set_attr "type" "lea")
6334   (set_attr "mode" "SI")])
6335
6336(define_insn_and_split "*lea_general_4"
6337  [(set (match_operand 0 "register_operand" "=r")
6338	(any_or (ashift
6339		  (match_operand 1 "index_register_operand" "l")
6340		  (match_operand 2 "const_int_operand" "n"))
6341		(match_operand 3 "const_int_operand" "n")))]
6342  "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6343      && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6344    || GET_MODE (operands[0]) == SImode
6345    || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6346   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6347   && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6348   && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6349       < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6350  "#"
6351  "&& reload_completed"
6352  [(const_int 0)]
6353{
6354  enum machine_mode mode = GET_MODE (operands[0]);
6355  rtx pat;
6356
6357  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6358    {
6359      mode = SImode;
6360      operands[0] = gen_lowpart (mode, operands[0]);
6361      operands[1] = gen_lowpart (mode, operands[1]);
6362    }
6363
6364  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6365
6366  pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6367		       INTVAL (operands[3]));
6368
6369  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6370  DONE;
6371}
6372  [(set_attr "type" "lea")
6373   (set (attr "mode")
6374      (if_then_else (match_operand:DI 0 "" "")
6375	(const_string "DI")
6376	(const_string "SI")))])
6377
6378;; Subtract instructions
6379
6380(define_expand "sub<mode>3"
6381  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6382	(minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6383		     (match_operand:SDWIM 2 "<general_operand>" "")))]
6384  ""
6385  "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6386
6387(define_insn_and_split "*sub<dwi>3_doubleword"
6388  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6389	(minus:<DWI>
6390	  (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6391	  (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6392   (clobber (reg:CC FLAGS_REG))]
6393  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6394  "#"
6395  "reload_completed"
6396  [(parallel [(set (reg:CC FLAGS_REG)
6397		   (compare:CC (match_dup 1) (match_dup 2)))
6398	      (set (match_dup 0)
6399		   (minus:DWIH (match_dup 1) (match_dup 2)))])
6400   (parallel [(set (match_dup 3)
6401		   (minus:DWIH
6402		     (match_dup 4)
6403		     (plus:DWIH
6404		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6405		       (match_dup 5))))
6406	      (clobber (reg:CC FLAGS_REG))])]
6407  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6408
6409(define_insn "*sub<mode>_1"
6410  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6411	(minus:SWI
6412	  (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6413	  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6414   (clobber (reg:CC FLAGS_REG))]
6415  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6416  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6417  [(set_attr "type" "alu")
6418   (set_attr "mode" "<MODE>")])
6419
6420(define_insn "*subsi_1_zext"
6421  [(set (match_operand:DI 0 "register_operand" "=r")
6422	(zero_extend:DI
6423	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6424		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6425   (clobber (reg:CC FLAGS_REG))]
6426  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6427  "sub{l}\t{%2, %k0|%k0, %2}"
6428  [(set_attr "type" "alu")
6429   (set_attr "mode" "SI")])
6430
6431(define_insn "*subqi_1_slp"
6432  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6433	(minus:QI (match_dup 0)
6434		  (match_operand:QI 1 "general_operand" "qn,qm")))
6435   (clobber (reg:CC FLAGS_REG))]
6436  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6437   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6438  "sub{b}\t{%1, %0|%0, %1}"
6439  [(set_attr "type" "alu1")
6440   (set_attr "mode" "QI")])
6441
6442(define_insn "*sub<mode>_2"
6443  [(set (reg FLAGS_REG)
6444	(compare
6445	  (minus:SWI
6446	    (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6447	    (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6448	  (const_int 0)))
6449   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6450	(minus:SWI (match_dup 1) (match_dup 2)))]
6451  "ix86_match_ccmode (insn, CCGOCmode)
6452   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6453  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6454  [(set_attr "type" "alu")
6455   (set_attr "mode" "<MODE>")])
6456
6457(define_insn "*subsi_2_zext"
6458  [(set (reg FLAGS_REG)
6459	(compare
6460	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6461		    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6462	  (const_int 0)))
6463   (set (match_operand:DI 0 "register_operand" "=r")
6464	(zero_extend:DI
6465	  (minus:SI (match_dup 1)
6466		    (match_dup 2))))]
6467  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6468   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6469  "sub{l}\t{%2, %k0|%k0, %2}"
6470  [(set_attr "type" "alu")
6471   (set_attr "mode" "SI")])
6472
6473(define_insn "*sub<mode>_3"
6474  [(set (reg FLAGS_REG)
6475	(compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6476		 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6477   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6478	(minus:SWI (match_dup 1) (match_dup 2)))]
6479  "ix86_match_ccmode (insn, CCmode)
6480   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6481  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6482  [(set_attr "type" "alu")
6483   (set_attr "mode" "<MODE>")])
6484
6485(define_insn "*subsi_3_zext"
6486  [(set (reg FLAGS_REG)
6487	(compare (match_operand:SI 1 "register_operand" "0")
6488		 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6489   (set (match_operand:DI 0 "register_operand" "=r")
6490	(zero_extend:DI
6491	  (minus:SI (match_dup 1)
6492		    (match_dup 2))))]
6493  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6494   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6495  "sub{l}\t{%2, %1|%1, %2}"
6496  [(set_attr "type" "alu")
6497   (set_attr "mode" "SI")])
6498
6499;; Add with carry and subtract with borrow
6500
6501(define_expand "<plusminus_insn><mode>3_carry"
6502  [(parallel
6503    [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6504	  (plusminus:SWI
6505	    (match_operand:SWI 1 "nonimmediate_operand" "")
6506	    (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6507		       [(match_operand 3 "flags_reg_operand" "")
6508			(const_int 0)])
6509		      (match_operand:SWI 2 "<general_operand>" ""))))
6510     (clobber (reg:CC FLAGS_REG))])]
6511  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6512
6513(define_insn "*<plusminus_insn><mode>3_carry"
6514  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6515	(plusminus:SWI
6516	  (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6517	  (plus:SWI
6518	    (match_operator 3 "ix86_carry_flag_operator"
6519	     [(reg FLAGS_REG) (const_int 0)])
6520	    (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6521   (clobber (reg:CC FLAGS_REG))]
6522  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6523  "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6524  [(set_attr "type" "alu")
6525   (set_attr "use_carry" "1")
6526   (set_attr "pent_pair" "pu")
6527   (set_attr "mode" "<MODE>")])
6528
6529(define_insn "*addsi3_carry_zext"
6530  [(set (match_operand:DI 0 "register_operand" "=r")
6531	(zero_extend:DI
6532	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6533		   (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6534			     [(reg FLAGS_REG) (const_int 0)])
6535			    (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6536   (clobber (reg:CC FLAGS_REG))]
6537  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6538  "adc{l}\t{%2, %k0|%k0, %2}"
6539  [(set_attr "type" "alu")
6540   (set_attr "use_carry" "1")
6541   (set_attr "pent_pair" "pu")
6542   (set_attr "mode" "SI")])
6543
6544(define_insn "*subsi3_carry_zext"
6545  [(set (match_operand:DI 0 "register_operand" "=r")
6546	(zero_extend:DI
6547	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6548		    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6549			      [(reg FLAGS_REG) (const_int 0)])
6550			     (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6551   (clobber (reg:CC FLAGS_REG))]
6552  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6553  "sbb{l}\t{%2, %k0|%k0, %2}"
6554  [(set_attr "type" "alu")
6555   (set_attr "pent_pair" "pu")
6556   (set_attr "mode" "SI")])
6557
6558;; Overflow setting add instructions
6559
6560(define_insn "*add<mode>3_cconly_overflow"
6561  [(set (reg:CCC FLAGS_REG)
6562	(compare:CCC
6563	  (plus:SWI
6564	    (match_operand:SWI 1 "nonimmediate_operand" "%0")
6565	    (match_operand:SWI 2 "<general_operand>" "<g>"))
6566	  (match_dup 1)))
6567   (clobber (match_scratch:SWI 0 "=<r>"))]
6568  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6569  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6570  [(set_attr "type" "alu")
6571   (set_attr "mode" "<MODE>")])
6572
6573(define_insn "*add<mode>3_cc_overflow"
6574  [(set (reg:CCC FLAGS_REG)
6575	(compare:CCC
6576	    (plus:SWI
6577		(match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6578		(match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6579	    (match_dup 1)))
6580   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6581	(plus:SWI (match_dup 1) (match_dup 2)))]
6582  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6583  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6584  [(set_attr "type" "alu")
6585   (set_attr "mode" "<MODE>")])
6586
6587(define_insn "*addsi3_zext_cc_overflow"
6588  [(set (reg:CCC FLAGS_REG)
6589	(compare:CCC
6590	  (plus:SI
6591	    (match_operand:SI 1 "nonimmediate_operand" "%0")
6592	    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6593	  (match_dup 1)))
6594   (set (match_operand:DI 0 "register_operand" "=r")
6595	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6596  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6597  "add{l}\t{%2, %k0|%k0, %2}"
6598  [(set_attr "type" "alu")
6599   (set_attr "mode" "SI")])
6600
6601;; The patterns that match these are at the end of this file.
6602
6603(define_expand "<plusminus_insn>xf3"
6604  [(set (match_operand:XF 0 "register_operand" "")
6605	(plusminus:XF
6606	  (match_operand:XF 1 "register_operand" "")
6607	  (match_operand:XF 2 "register_operand" "")))]
6608  "TARGET_80387")
6609
6610(define_expand "<plusminus_insn><mode>3"
6611  [(set (match_operand:MODEF 0 "register_operand" "")
6612	(plusminus:MODEF
6613	  (match_operand:MODEF 1 "register_operand" "")
6614	  (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6615  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6616    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6617
6618;; Multiply instructions
6619
6620(define_expand "mul<mode>3"
6621  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6622		   (mult:SWIM248
6623		     (match_operand:SWIM248 1 "register_operand" "")
6624		     (match_operand:SWIM248 2 "<general_operand>" "")))
6625	      (clobber (reg:CC FLAGS_REG))])])
6626
6627(define_expand "mulqi3"
6628  [(parallel [(set (match_operand:QI 0 "register_operand" "")
6629		   (mult:QI
6630		     (match_operand:QI 1 "register_operand" "")
6631		     (match_operand:QI 2 "nonimmediate_operand" "")))
6632	      (clobber (reg:CC FLAGS_REG))])]
6633  "TARGET_QIMODE_MATH")
6634
6635;; On AMDFAM10
6636;; IMUL reg32/64, reg32/64, imm8 	Direct
6637;; IMUL reg32/64, mem32/64, imm8 	VectorPath
6638;; IMUL reg32/64, reg32/64, imm32 	Direct
6639;; IMUL reg32/64, mem32/64, imm32 	VectorPath
6640;; IMUL reg32/64, reg32/64 		Direct
6641;; IMUL reg32/64, mem32/64 		Direct
6642;;
6643;; On BDVER1, all above IMULs use DirectPath
6644
6645(define_insn "*mul<mode>3_1"
6646  [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6647	(mult:SWI48
6648	  (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6649	  (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6650   (clobber (reg:CC FLAGS_REG))]
6651  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6652  "@
6653   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6654   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6655   imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6656  [(set_attr "type" "imul")
6657   (set_attr "prefix_0f" "0,0,1")
6658   (set (attr "athlon_decode")
6659	(cond [(eq_attr "cpu" "athlon")
6660		  (const_string "vector")
6661	       (eq_attr "alternative" "1")
6662		  (const_string "vector")
6663	       (and (eq_attr "alternative" "2")
6664		    (match_operand 1 "memory_operand" ""))
6665		  (const_string "vector")]
6666	      (const_string "direct")))
6667   (set (attr "amdfam10_decode")
6668	(cond [(and (eq_attr "alternative" "0,1")
6669		    (match_operand 1 "memory_operand" ""))
6670		  (const_string "vector")]
6671	      (const_string "direct")))
6672   (set_attr "bdver1_decode" "direct")
6673   (set_attr "mode" "<MODE>")])
6674
6675(define_insn "*mulsi3_1_zext"
6676  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6677	(zero_extend:DI
6678	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6679		   (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6680   (clobber (reg:CC FLAGS_REG))]
6681  "TARGET_64BIT
6682   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6683  "@
6684   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6685   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6686   imul{l}\t{%2, %k0|%k0, %2}"
6687  [(set_attr "type" "imul")
6688   (set_attr "prefix_0f" "0,0,1")
6689   (set (attr "athlon_decode")
6690	(cond [(eq_attr "cpu" "athlon")
6691		  (const_string "vector")
6692	       (eq_attr "alternative" "1")
6693		  (const_string "vector")
6694	       (and (eq_attr "alternative" "2")
6695		    (match_operand 1 "memory_operand" ""))
6696		  (const_string "vector")]
6697	      (const_string "direct")))
6698   (set (attr "amdfam10_decode")
6699	(cond [(and (eq_attr "alternative" "0,1")
6700		    (match_operand 1 "memory_operand" ""))
6701		  (const_string "vector")]
6702	      (const_string "direct")))
6703   (set_attr "bdver1_decode" "direct")
6704   (set_attr "mode" "SI")])
6705
6706;; On AMDFAM10
6707;; IMUL reg16, reg16, imm8 	VectorPath
6708;; IMUL reg16, mem16, imm8 	VectorPath
6709;; IMUL reg16, reg16, imm16 	VectorPath
6710;; IMUL reg16, mem16, imm16 	VectorPath
6711;; IMUL reg16, reg16 		Direct
6712;; IMUL reg16, mem16 		Direct
6713;;
6714;; On BDVER1, all HI MULs use DoublePath
6715
6716(define_insn "*mulhi3_1"
6717  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6718	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6719		 (match_operand:HI 2 "general_operand" "K,n,mr")))
6720   (clobber (reg:CC FLAGS_REG))]
6721  "TARGET_HIMODE_MATH
6722   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6723  "@
6724   imul{w}\t{%2, %1, %0|%0, %1, %2}
6725   imul{w}\t{%2, %1, %0|%0, %1, %2}
6726   imul{w}\t{%2, %0|%0, %2}"
6727  [(set_attr "type" "imul")
6728   (set_attr "prefix_0f" "0,0,1")
6729   (set (attr "athlon_decode")
6730	(cond [(eq_attr "cpu" "athlon")
6731		  (const_string "vector")
6732	       (eq_attr "alternative" "1,2")
6733		  (const_string "vector")]
6734	      (const_string "direct")))
6735   (set (attr "amdfam10_decode")
6736	(cond [(eq_attr "alternative" "0,1")
6737		  (const_string "vector")]
6738	      (const_string "direct")))
6739   (set_attr "bdver1_decode" "double")
6740   (set_attr "mode" "HI")])
6741
6742;;On AMDFAM10 and BDVER1
6743;; MUL reg8 	Direct
6744;; MUL mem8 	Direct
6745
6746(define_insn "*mulqi3_1"
6747  [(set (match_operand:QI 0 "register_operand" "=a")
6748	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6749		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6750   (clobber (reg:CC FLAGS_REG))]
6751  "TARGET_QIMODE_MATH
6752   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6753  "mul{b}\t%2"
6754  [(set_attr "type" "imul")
6755   (set_attr "length_immediate" "0")
6756   (set (attr "athlon_decode")
6757     (if_then_else (eq_attr "cpu" "athlon")
6758        (const_string "vector")
6759        (const_string "direct")))
6760   (set_attr "amdfam10_decode" "direct")
6761   (set_attr "bdver1_decode" "direct")
6762   (set_attr "mode" "QI")])
6763
6764(define_expand "<u>mul<mode><dwi>3"
6765  [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6766		   (mult:<DWI>
6767		     (any_extend:<DWI>
6768		       (match_operand:DWIH 1 "nonimmediate_operand" ""))
6769		     (any_extend:<DWI>
6770		       (match_operand:DWIH 2 "register_operand" ""))))
6771	      (clobber (reg:CC FLAGS_REG))])])
6772
6773(define_expand "<u>mulqihi3"
6774  [(parallel [(set (match_operand:HI 0 "register_operand" "")
6775		   (mult:HI
6776		     (any_extend:HI
6777		       (match_operand:QI 1 "nonimmediate_operand" ""))
6778		     (any_extend:HI
6779		       (match_operand:QI 2 "register_operand" ""))))
6780	      (clobber (reg:CC FLAGS_REG))])]
6781  "TARGET_QIMODE_MATH")
6782
6783(define_insn "*bmi2_umulditi3_1"
6784  [(set (match_operand:DI 0 "register_operand" "=r")
6785	(mult:DI
6786	  (match_operand:DI 2 "nonimmediate_operand" "%d")
6787	  (match_operand:DI 3 "nonimmediate_operand" "rm")))
6788   (set (match_operand:DI 1 "register_operand" "=r")
6789	(truncate:DI
6790	  (lshiftrt:TI
6791	    (mult:TI (zero_extend:TI (match_dup 2))
6792		     (zero_extend:TI (match_dup 3)))
6793	    (const_int 64))))]
6794  "TARGET_64BIT && TARGET_BMI2
6795   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796  "mulx\t{%3, %0, %1|%1, %0, %3}"
6797  [(set_attr "type" "imulx")
6798   (set_attr "prefix" "vex")
6799   (set_attr "mode" "DI")])
6800
6801(define_insn "*bmi2_umulsidi3_1"
6802  [(set (match_operand:SI 0 "register_operand" "=r")
6803	(mult:SI
6804	  (match_operand:SI 2 "nonimmediate_operand" "%d")
6805	  (match_operand:SI 3 "nonimmediate_operand" "rm")))
6806   (set (match_operand:SI 1 "register_operand" "=r")
6807	(truncate:SI
6808	  (lshiftrt:DI
6809	    (mult:DI (zero_extend:DI (match_dup 2))
6810		     (zero_extend:DI (match_dup 3)))
6811	    (const_int 32))))]
6812  "!TARGET_64BIT && TARGET_BMI2
6813   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6814  "mulx\t{%3, %0, %1|%1, %0, %3}"
6815  [(set_attr "type" "imulx")
6816   (set_attr "prefix" "vex")
6817   (set_attr "mode" "SI")])
6818
6819(define_insn "*umul<mode><dwi>3_1"
6820  [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6821	(mult:<DWI>
6822	  (zero_extend:<DWI>
6823	    (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6824	  (zero_extend:<DWI>
6825	    (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6826   (clobber (reg:CC FLAGS_REG))]
6827  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6828  "@
6829   mul{<imodesuffix>}\t%2
6830   #"
6831  [(set_attr "isa" "*,bmi2")
6832   (set_attr "type" "imul,imulx")
6833   (set_attr "length_immediate" "0,*")
6834   (set (attr "athlon_decode")
6835	(cond [(eq_attr "alternative" "0")
6836		 (if_then_else (eq_attr "cpu" "athlon")
6837		   (const_string "vector")
6838		   (const_string "double"))]
6839	      (const_string "*")))
6840   (set_attr "amdfam10_decode" "double,*")
6841   (set_attr "bdver1_decode" "direct,*")
6842   (set_attr "prefix" "orig,vex")
6843   (set_attr "mode" "<MODE>")])
6844
6845;; Convert mul to the mulx pattern to avoid flags dependency.
6846(define_split
6847 [(set (match_operand:<DWI> 0 "register_operand" "")
6848       (mult:<DWI>
6849	 (zero_extend:<DWI>
6850	   (match_operand:DWIH 1 "register_operand" ""))
6851	 (zero_extend:<DWI>
6852	   (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6853  (clobber (reg:CC FLAGS_REG))]
6854 "TARGET_BMI2 && reload_completed
6855  && true_regnum (operands[1]) == DX_REG"
6856  [(parallel [(set (match_dup 3)
6857		   (mult:DWIH (match_dup 1) (match_dup 2)))
6858	      (set (match_dup 4)
6859		   (truncate:DWIH
6860		     (lshiftrt:<DWI>
6861		       (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6862				   (zero_extend:<DWI> (match_dup 2)))
6863		       (match_dup 5))))])]
6864{
6865  split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6866
6867  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6868})
6869
6870(define_insn "*mul<mode><dwi>3_1"
6871  [(set (match_operand:<DWI> 0 "register_operand" "=A")
6872	(mult:<DWI>
6873	  (sign_extend:<DWI>
6874	    (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6875	  (sign_extend:<DWI>
6876	    (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6877   (clobber (reg:CC FLAGS_REG))]
6878  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6879  "imul{<imodesuffix>}\t%2"
6880  [(set_attr "type" "imul")
6881   (set_attr "length_immediate" "0")
6882   (set (attr "athlon_decode")
6883     (if_then_else (eq_attr "cpu" "athlon")
6884        (const_string "vector")
6885        (const_string "double")))
6886   (set_attr "amdfam10_decode" "double")
6887   (set_attr "bdver1_decode" "direct")
6888   (set_attr "mode" "<MODE>")])
6889
6890(define_insn "*<u>mulqihi3_1"
6891  [(set (match_operand:HI 0 "register_operand" "=a")
6892	(mult:HI
6893	  (any_extend:HI
6894	    (match_operand:QI 1 "nonimmediate_operand" "%0"))
6895	  (any_extend:HI
6896	    (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6897   (clobber (reg:CC FLAGS_REG))]
6898  "TARGET_QIMODE_MATH
6899   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6900  "<sgnprefix>mul{b}\t%2"
6901  [(set_attr "type" "imul")
6902   (set_attr "length_immediate" "0")
6903   (set (attr "athlon_decode")
6904     (if_then_else (eq_attr "cpu" "athlon")
6905        (const_string "vector")
6906        (const_string "direct")))
6907   (set_attr "amdfam10_decode" "direct")
6908   (set_attr "bdver1_decode" "direct")
6909   (set_attr "mode" "QI")])
6910
6911(define_expand "<s>mul<mode>3_highpart"
6912  [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6913		   (truncate:SWI48
6914		     (lshiftrt:<DWI>
6915		       (mult:<DWI>
6916			 (any_extend:<DWI>
6917			   (match_operand:SWI48 1 "nonimmediate_operand" ""))
6918			 (any_extend:<DWI>
6919			   (match_operand:SWI48 2 "register_operand" "")))
6920		       (match_dup 4))))
6921	      (clobber (match_scratch:SWI48 3 ""))
6922	      (clobber (reg:CC FLAGS_REG))])]
6923  ""
6924  "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6925
6926(define_insn "*<s>muldi3_highpart_1"
6927  [(set (match_operand:DI 0 "register_operand" "=d")
6928	(truncate:DI
6929	  (lshiftrt:TI
6930	    (mult:TI
6931	      (any_extend:TI
6932		(match_operand:DI 1 "nonimmediate_operand" "%a"))
6933	      (any_extend:TI
6934		(match_operand:DI 2 "nonimmediate_operand" "rm")))
6935	    (const_int 64))))
6936   (clobber (match_scratch:DI 3 "=1"))
6937   (clobber (reg:CC FLAGS_REG))]
6938  "TARGET_64BIT
6939   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940  "<sgnprefix>mul{q}\t%2"
6941  [(set_attr "type" "imul")
6942   (set_attr "length_immediate" "0")
6943   (set (attr "athlon_decode")
6944     (if_then_else (eq_attr "cpu" "athlon")
6945        (const_string "vector")
6946        (const_string "double")))
6947   (set_attr "amdfam10_decode" "double")
6948   (set_attr "bdver1_decode" "direct")
6949   (set_attr "mode" "DI")])
6950
6951(define_insn "*<s>mulsi3_highpart_1"
6952  [(set (match_operand:SI 0 "register_operand" "=d")
6953	(truncate:SI
6954	  (lshiftrt:DI
6955	    (mult:DI
6956	      (any_extend:DI
6957		(match_operand:SI 1 "nonimmediate_operand" "%a"))
6958	      (any_extend:DI
6959		(match_operand:SI 2 "nonimmediate_operand" "rm")))
6960	    (const_int 32))))
6961   (clobber (match_scratch:SI 3 "=1"))
6962   (clobber (reg:CC FLAGS_REG))]
6963  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6964  "<sgnprefix>mul{l}\t%2"
6965  [(set_attr "type" "imul")
6966   (set_attr "length_immediate" "0")
6967   (set (attr "athlon_decode")
6968     (if_then_else (eq_attr "cpu" "athlon")
6969        (const_string "vector")
6970        (const_string "double")))
6971   (set_attr "amdfam10_decode" "double")
6972   (set_attr "bdver1_decode" "direct")
6973   (set_attr "mode" "SI")])
6974
6975(define_insn "*<s>mulsi3_highpart_zext"
6976  [(set (match_operand:DI 0 "register_operand" "=d")
6977	(zero_extend:DI (truncate:SI
6978	  (lshiftrt:DI
6979	    (mult:DI (any_extend:DI
6980		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
6981		     (any_extend:DI
6982		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
6983	    (const_int 32)))))
6984   (clobber (match_scratch:SI 3 "=1"))
6985   (clobber (reg:CC FLAGS_REG))]
6986  "TARGET_64BIT
6987   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6988  "<sgnprefix>mul{l}\t%2"
6989  [(set_attr "type" "imul")
6990   (set_attr "length_immediate" "0")
6991   (set (attr "athlon_decode")
6992     (if_then_else (eq_attr "cpu" "athlon")
6993        (const_string "vector")
6994        (const_string "double")))
6995   (set_attr "amdfam10_decode" "double")
6996   (set_attr "bdver1_decode" "direct")
6997   (set_attr "mode" "SI")])
6998
6999;; The patterns that match these are at the end of this file.
7000
7001(define_expand "mulxf3"
7002  [(set (match_operand:XF 0 "register_operand" "")
7003	(mult:XF (match_operand:XF 1 "register_operand" "")
7004		 (match_operand:XF 2 "register_operand" "")))]
7005  "TARGET_80387")
7006
7007(define_expand "mul<mode>3"
7008  [(set (match_operand:MODEF 0 "register_operand" "")
7009	(mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7010		    (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7011  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7012    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7013
7014;; Divide instructions
7015
7016;; The patterns that match these are at the end of this file.
7017
7018(define_expand "divxf3"
7019  [(set (match_operand:XF 0 "register_operand" "")
7020	(div:XF (match_operand:XF 1 "register_operand" "")
7021		(match_operand:XF 2 "register_operand" "")))]
7022  "TARGET_80387")
7023
7024(define_expand "divdf3"
7025  [(set (match_operand:DF 0 "register_operand" "")
7026 	(div:DF (match_operand:DF 1 "register_operand" "")
7027 		(match_operand:DF 2 "nonimmediate_operand" "")))]
7028   "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7029    || (TARGET_SSE2 && TARGET_SSE_MATH)")
7030
7031(define_expand "divsf3"
7032  [(set (match_operand:SF 0 "register_operand" "")
7033	(div:SF (match_operand:SF 1 "register_operand" "")
7034		(match_operand:SF 2 "nonimmediate_operand" "")))]
7035  "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7036    || TARGET_SSE_MATH"
7037{
7038  if (TARGET_SSE_MATH
7039      && TARGET_RECIP_DIV
7040      && optimize_insn_for_speed_p ()
7041      && flag_finite_math_only && !flag_trapping_math
7042      && flag_unsafe_math_optimizations)
7043    {
7044      ix86_emit_swdivsf (operands[0], operands[1],
7045			 operands[2], SFmode);
7046      DONE;
7047    }
7048})
7049
7050;; Divmod instructions.
7051
7052(define_expand "divmod<mode>4"
7053  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7054		   (div:SWIM248
7055		     (match_operand:SWIM248 1 "register_operand" "")
7056		     (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7057	      (set (match_operand:SWIM248 3 "register_operand" "")
7058		   (mod:SWIM248 (match_dup 1) (match_dup 2)))
7059	      (clobber (reg:CC FLAGS_REG))])])
7060
7061;; Split with 8bit unsigned divide:
7062;; 	if (dividend an divisor are in [0-255])
7063;;	   use 8bit unsigned integer divide
7064;;	 else
7065;;	   use original integer divide
7066(define_split
7067  [(set (match_operand:SWI48 0 "register_operand" "")
7068	(div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7069		    (match_operand:SWI48 3 "nonimmediate_operand" "")))
7070   (set (match_operand:SWI48 1 "register_operand" "")
7071	(mod:SWI48 (match_dup 2) (match_dup 3)))
7072   (clobber (reg:CC FLAGS_REG))]
7073  "TARGET_USE_8BIT_IDIV
7074   && TARGET_QIMODE_MATH
7075   && can_create_pseudo_p ()
7076   && !optimize_insn_for_size_p ()"
7077  [(const_int 0)]
7078  "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7079
7080(define_insn_and_split "divmod<mode>4_1"
7081  [(set (match_operand:SWI48 0 "register_operand" "=a")
7082	(div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7083		   (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7084   (set (match_operand:SWI48 1 "register_operand" "=&d")
7085	(mod:SWI48 (match_dup 2) (match_dup 3)))
7086   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7087   (clobber (reg:CC FLAGS_REG))]
7088  ""
7089  "#"
7090  "reload_completed"
7091  [(parallel [(set (match_dup 1)
7092		   (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7093	      (clobber (reg:CC FLAGS_REG))])
7094   (parallel [(set (match_dup 0)
7095	           (div:SWI48 (match_dup 2) (match_dup 3)))
7096	      (set (match_dup 1)
7097		   (mod:SWI48 (match_dup 2) (match_dup 3)))
7098	      (use (match_dup 1))
7099	      (clobber (reg:CC FLAGS_REG))])]
7100{
7101  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7102
7103  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7104    operands[4] = operands[2];
7105  else
7106    {
7107      /* Avoid use of cltd in favor of a mov+shift.  */
7108      emit_move_insn (operands[1], operands[2]);
7109      operands[4] = operands[1];
7110    }
7111}
7112  [(set_attr "type" "multi")
7113   (set_attr "mode" "<MODE>")])
7114
7115(define_insn_and_split "*divmod<mode>4"
7116  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7117	(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7118		    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7119   (set (match_operand:SWIM248 1 "register_operand" "=&d")
7120	(mod:SWIM248 (match_dup 2) (match_dup 3)))
7121   (clobber (reg:CC FLAGS_REG))]
7122  ""
7123  "#"
7124  "reload_completed"
7125  [(parallel [(set (match_dup 1)
7126		   (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7127	      (clobber (reg:CC FLAGS_REG))])
7128   (parallel [(set (match_dup 0)
7129	           (div:SWIM248 (match_dup 2) (match_dup 3)))
7130	      (set (match_dup 1)
7131		   (mod:SWIM248 (match_dup 2) (match_dup 3)))
7132	      (use (match_dup 1))
7133	      (clobber (reg:CC FLAGS_REG))])]
7134{
7135  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7136
7137  if (<MODE>mode != HImode
7138      && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7139    operands[4] = operands[2];
7140  else
7141    {
7142      /* Avoid use of cltd in favor of a mov+shift.  */
7143      emit_move_insn (operands[1], operands[2]);
7144      operands[4] = operands[1];
7145    }
7146}
7147  [(set_attr "type" "multi")
7148   (set_attr "mode" "<MODE>")])
7149
7150(define_insn "*divmod<mode>4_noext"
7151  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7152	(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7153		    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7154   (set (match_operand:SWIM248 1 "register_operand" "=d")
7155	(mod:SWIM248 (match_dup 2) (match_dup 3)))
7156   (use (match_operand:SWIM248 4 "register_operand" "1"))
7157   (clobber (reg:CC FLAGS_REG))]
7158  ""
7159  "idiv{<imodesuffix>}\t%3"
7160  [(set_attr "type" "idiv")
7161   (set_attr "mode" "<MODE>")])
7162
7163(define_expand "divmodqi4"
7164  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7165		   (div:QI
7166		     (match_operand:QI 1 "register_operand" "")
7167		     (match_operand:QI 2 "nonimmediate_operand" "")))
7168	      (set (match_operand:QI 3 "register_operand" "")
7169		   (mod:QI (match_dup 1) (match_dup 2)))
7170	      (clobber (reg:CC FLAGS_REG))])]
7171  "TARGET_QIMODE_MATH"
7172{
7173  rtx div, mod, insn;
7174  rtx tmp0, tmp1;
7175
7176  tmp0 = gen_reg_rtx (HImode);
7177  tmp1 = gen_reg_rtx (HImode);
7178
7179  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7180     in AX.  */
7181  emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7182  emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7183
7184  /* Extract remainder from AH.  */
7185  tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7186  insn = emit_move_insn (operands[3], tmp1);
7187
7188  mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7189  set_unique_reg_note (insn, REG_EQUAL, mod);
7190
7191  /* Extract quotient from AL.  */
7192  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7193
7194  div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7195  set_unique_reg_note (insn, REG_EQUAL, div);
7196
7197  DONE;
7198})
7199
7200;; Divide AX by r/m8, with result stored in
7201;; AL <- Quotient
7202;; AH <- Remainder
7203;; Change div/mod to HImode and extend the second argument to HImode
7204;; so that mode of div/mod matches with mode of arguments.  Otherwise
7205;; combine may fail.
7206(define_insn "divmodhiqi3"
7207  [(set (match_operand:HI 0 "register_operand" "=a")
7208	(ior:HI
7209	  (ashift:HI
7210	    (zero_extend:HI
7211	      (truncate:QI
7212		(mod:HI (match_operand:HI 1 "register_operand" "0")
7213			(sign_extend:HI
7214			  (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7215	    (const_int 8))
7216	  (zero_extend:HI
7217	    (truncate:QI
7218	      (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7219   (clobber (reg:CC FLAGS_REG))]
7220  "TARGET_QIMODE_MATH"
7221  "idiv{b}\t%2"
7222  [(set_attr "type" "idiv")
7223   (set_attr "mode" "QI")])
7224
7225(define_expand "udivmod<mode>4"
7226  [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7227		   (udiv:SWIM248
7228		     (match_operand:SWIM248 1 "register_operand" "")
7229		     (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7230	      (set (match_operand:SWIM248 3 "register_operand" "")
7231		   (umod:SWIM248 (match_dup 1) (match_dup 2)))
7232	      (clobber (reg:CC FLAGS_REG))])])
7233
7234;; Split with 8bit unsigned divide:
7235;; 	if (dividend an divisor are in [0-255])
7236;;	   use 8bit unsigned integer divide
7237;;	 else
7238;;	   use original integer divide
7239(define_split
7240  [(set (match_operand:SWI48 0 "register_operand" "")
7241	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7242		    (match_operand:SWI48 3 "nonimmediate_operand" "")))
7243   (set (match_operand:SWI48 1 "register_operand" "")
7244	(umod:SWI48 (match_dup 2) (match_dup 3)))
7245   (clobber (reg:CC FLAGS_REG))]
7246  "TARGET_USE_8BIT_IDIV
7247   && TARGET_QIMODE_MATH
7248   && can_create_pseudo_p ()
7249   && !optimize_insn_for_size_p ()"
7250  [(const_int 0)]
7251  "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7252
7253(define_insn_and_split "udivmod<mode>4_1"
7254  [(set (match_operand:SWI48 0 "register_operand" "=a")
7255	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7256		    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7257   (set (match_operand:SWI48 1 "register_operand" "=&d")
7258	(umod:SWI48 (match_dup 2) (match_dup 3)))
7259   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7260   (clobber (reg:CC FLAGS_REG))]
7261  ""
7262  "#"
7263  "reload_completed"
7264  [(set (match_dup 1) (const_int 0))
7265   (parallel [(set (match_dup 0)
7266		   (udiv:SWI48 (match_dup 2) (match_dup 3)))
7267	      (set (match_dup 1)
7268		   (umod:SWI48 (match_dup 2) (match_dup 3)))
7269	      (use (match_dup 1))
7270	      (clobber (reg:CC FLAGS_REG))])]
7271  ""
7272  [(set_attr "type" "multi")
7273   (set_attr "mode" "<MODE>")])
7274
7275(define_insn_and_split "*udivmod<mode>4"
7276  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7277	(udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7278		      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7279   (set (match_operand:SWIM248 1 "register_operand" "=&d")
7280	(umod:SWIM248 (match_dup 2) (match_dup 3)))
7281   (clobber (reg:CC FLAGS_REG))]
7282  ""
7283  "#"
7284  "reload_completed"
7285  [(set (match_dup 1) (const_int 0))
7286   (parallel [(set (match_dup 0)
7287		   (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7288	      (set (match_dup 1)
7289		   (umod:SWIM248 (match_dup 2) (match_dup 3)))
7290	      (use (match_dup 1))
7291	      (clobber (reg:CC FLAGS_REG))])]
7292  ""
7293  [(set_attr "type" "multi")
7294   (set_attr "mode" "<MODE>")])
7295
7296(define_insn "*udivmod<mode>4_noext"
7297  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7298	(udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7299		      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7300   (set (match_operand:SWIM248 1 "register_operand" "=d")
7301	(umod:SWIM248 (match_dup 2) (match_dup 3)))
7302   (use (match_operand:SWIM248 4 "register_operand" "1"))
7303   (clobber (reg:CC FLAGS_REG))]
7304  ""
7305  "div{<imodesuffix>}\t%3"
7306  [(set_attr "type" "idiv")
7307   (set_attr "mode" "<MODE>")])
7308
7309(define_expand "udivmodqi4"
7310  [(parallel [(set (match_operand:QI 0 "register_operand" "")
7311		   (udiv:QI
7312		     (match_operand:QI 1 "register_operand" "")
7313		     (match_operand:QI 2 "nonimmediate_operand" "")))
7314	      (set (match_operand:QI 3 "register_operand" "")
7315		   (umod:QI (match_dup 1) (match_dup 2)))
7316	      (clobber (reg:CC FLAGS_REG))])]
7317  "TARGET_QIMODE_MATH"
7318{
7319  rtx div, mod, insn;
7320  rtx tmp0, tmp1;
7321
7322  tmp0 = gen_reg_rtx (HImode);
7323  tmp1 = gen_reg_rtx (HImode);
7324
7325  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7326     in AX.  */
7327  emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7328  emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7329
7330  /* Extract remainder from AH.  */
7331  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7332  tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7333  insn = emit_move_insn (operands[3], tmp1);
7334
7335  mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7336  set_unique_reg_note (insn, REG_EQUAL, mod);
7337
7338  /* Extract quotient from AL.  */
7339  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7340
7341  div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7342  set_unique_reg_note (insn, REG_EQUAL, div);
7343
7344  DONE;
7345})
7346
7347(define_insn "udivmodhiqi3"
7348  [(set (match_operand:HI 0 "register_operand" "=a")
7349	(ior:HI
7350	  (ashift:HI
7351	    (zero_extend:HI
7352	      (truncate:QI
7353		(mod:HI (match_operand:HI 1 "register_operand" "0")
7354			(zero_extend:HI
7355			  (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7356	    (const_int 8))
7357	  (zero_extend:HI
7358	    (truncate:QI
7359	      (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7360   (clobber (reg:CC FLAGS_REG))]
7361  "TARGET_QIMODE_MATH"
7362  "div{b}\t%2"
7363  [(set_attr "type" "idiv")
7364   (set_attr "mode" "QI")])
7365
7366;; We cannot use div/idiv for double division, because it causes
7367;; "division by zero" on the overflow and that's not what we expect
7368;; from truncate.  Because true (non truncating) double division is
7369;; never generated, we can't create this insn anyway.
7370;
7371;(define_insn ""
7372;  [(set (match_operand:SI 0 "register_operand" "=a")
7373;	(truncate:SI
7374;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7375;		   (zero_extend:DI
7376;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7377;   (set (match_operand:SI 3 "register_operand" "=d")
7378;	(truncate:SI
7379;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7380;   (clobber (reg:CC FLAGS_REG))]
7381;  ""
7382;  "div{l}\t{%2, %0|%0, %2}"
7383;  [(set_attr "type" "idiv")])
7384
7385;;- Logical AND instructions
7386
7387;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7388;; Note that this excludes ah.
7389
7390(define_expand "testsi_ccno_1"
7391  [(set (reg:CCNO FLAGS_REG)
7392	(compare:CCNO
7393	  (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7394		  (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7395	  (const_int 0)))])
7396
7397(define_expand "testqi_ccz_1"
7398  [(set (reg:CCZ FLAGS_REG)
7399        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7400			     (match_operand:QI 1 "nonmemory_operand" ""))
7401		 (const_int 0)))])
7402
7403(define_expand "testdi_ccno_1"
7404  [(set (reg:CCNO FLAGS_REG)
7405	(compare:CCNO
7406	  (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7407		  (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7408	  (const_int 0)))]
7409  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7410
7411(define_insn "*testdi_1"
7412  [(set (reg FLAGS_REG)
7413	(compare
7414	 (and:DI
7415	  (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7416	  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7417	 (const_int 0)))]
7418  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7419   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7420  "@
7421   test{l}\t{%k1, %k0|%k0, %k1}
7422   test{l}\t{%k1, %k0|%k0, %k1}
7423   test{q}\t{%1, %0|%0, %1}
7424   test{q}\t{%1, %0|%0, %1}
7425   test{q}\t{%1, %0|%0, %1}"
7426  [(set_attr "type" "test")
7427   (set_attr "modrm" "0,1,0,1,1")
7428   (set_attr "mode" "SI,SI,DI,DI,DI")])
7429
7430(define_insn "*testqi_1_maybe_si"
7431  [(set (reg FLAGS_REG)
7432        (compare
7433	  (and:QI
7434	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7435	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7436	  (const_int 0)))]
7437   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7438    && ix86_match_ccmode (insn,
7439 			 CONST_INT_P (operands[1])
7440 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7441{
7442  if (which_alternative == 3)
7443    {
7444      if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7445	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7446      return "test{l}\t{%1, %k0|%k0, %1}";
7447    }
7448  return "test{b}\t{%1, %0|%0, %1}";
7449}
7450  [(set_attr "type" "test")
7451   (set_attr "modrm" "0,1,1,1")
7452   (set_attr "mode" "QI,QI,QI,SI")
7453   (set_attr "pent_pair" "uv,np,uv,np")])
7454
7455(define_insn "*test<mode>_1"
7456  [(set (reg FLAGS_REG)
7457	(compare
7458	 (and:SWI124
7459	  (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7460	  (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7461	 (const_int 0)))]
7462  "ix86_match_ccmode (insn, CCNOmode)
7463   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7464  "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7465  [(set_attr "type" "test")
7466   (set_attr "modrm" "0,1,1")
7467   (set_attr "mode" "<MODE>")
7468   (set_attr "pent_pair" "uv,np,uv")])
7469
7470(define_expand "testqi_ext_ccno_0"
7471  [(set (reg:CCNO FLAGS_REG)
7472	(compare:CCNO
7473	  (and:SI
7474	    (zero_extract:SI
7475	      (match_operand 0 "ext_register_operand" "")
7476	      (const_int 8)
7477	      (const_int 8))
7478	    (match_operand 1 "const_int_operand" ""))
7479	  (const_int 0)))])
7480
7481(define_insn "*testqi_ext_0"
7482  [(set (reg FLAGS_REG)
7483	(compare
7484	  (and:SI
7485	    (zero_extract:SI
7486	      (match_operand 0 "ext_register_operand" "Q")
7487	      (const_int 8)
7488	      (const_int 8))
7489	    (match_operand 1 "const_int_operand" "n"))
7490	  (const_int 0)))]
7491  "ix86_match_ccmode (insn, CCNOmode)"
7492  "test{b}\t{%1, %h0|%h0, %1}"
7493  [(set_attr "type" "test")
7494   (set_attr "mode" "QI")
7495   (set_attr "length_immediate" "1")
7496   (set_attr "modrm" "1")
7497   (set_attr "pent_pair" "np")])
7498
7499(define_insn "*testqi_ext_1_rex64"
7500  [(set (reg FLAGS_REG)
7501	(compare
7502	  (and:SI
7503	    (zero_extract:SI
7504	      (match_operand 0 "ext_register_operand" "Q")
7505	      (const_int 8)
7506	      (const_int 8))
7507	    (zero_extend:SI
7508	      (match_operand:QI 1 "register_operand" "Q")))
7509	  (const_int 0)))]
7510  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7511  "test{b}\t{%1, %h0|%h0, %1}"
7512  [(set_attr "type" "test")
7513   (set_attr "mode" "QI")])
7514
7515(define_insn "*testqi_ext_1"
7516  [(set (reg FLAGS_REG)
7517	(compare
7518	  (and:SI
7519	    (zero_extract:SI
7520	      (match_operand 0 "ext_register_operand" "Q")
7521	      (const_int 8)
7522	      (const_int 8))
7523	    (zero_extend:SI
7524	      (match_operand:QI 1 "general_operand" "Qm")))
7525	  (const_int 0)))]
7526  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7527  "test{b}\t{%1, %h0|%h0, %1}"
7528  [(set_attr "type" "test")
7529   (set_attr "mode" "QI")])
7530
7531(define_insn "*testqi_ext_2"
7532  [(set (reg FLAGS_REG)
7533	(compare
7534	  (and:SI
7535	    (zero_extract:SI
7536	      (match_operand 0 "ext_register_operand" "Q")
7537	      (const_int 8)
7538	      (const_int 8))
7539	    (zero_extract:SI
7540	      (match_operand 1 "ext_register_operand" "Q")
7541	      (const_int 8)
7542	      (const_int 8)))
7543	  (const_int 0)))]
7544  "ix86_match_ccmode (insn, CCNOmode)"
7545  "test{b}\t{%h1, %h0|%h0, %h1}"
7546  [(set_attr "type" "test")
7547   (set_attr "mode" "QI")])
7548
7549(define_insn "*testqi_ext_3_rex64"
7550  [(set (reg FLAGS_REG)
7551        (compare (zero_extract:DI
7552		   (match_operand 0 "nonimmediate_operand" "rm")
7553		   (match_operand:DI 1 "const_int_operand" "")
7554		   (match_operand:DI 2 "const_int_operand" ""))
7555		 (const_int 0)))]
7556  "TARGET_64BIT
7557   && ix86_match_ccmode (insn, CCNOmode)
7558   && INTVAL (operands[1]) > 0
7559   && INTVAL (operands[2]) >= 0
7560   /* Ensure that resulting mask is zero or sign extended operand.  */
7561   && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7562       || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7563	   && INTVAL (operands[1]) > 32))
7564   && (GET_MODE (operands[0]) == SImode
7565       || GET_MODE (operands[0]) == DImode
7566       || GET_MODE (operands[0]) == HImode
7567       || GET_MODE (operands[0]) == QImode)"
7568  "#")
7569
7570;; Combine likes to form bit extractions for some tests.  Humor it.
7571(define_insn "*testqi_ext_3"
7572  [(set (reg FLAGS_REG)
7573        (compare (zero_extract:SI
7574		   (match_operand 0 "nonimmediate_operand" "rm")
7575		   (match_operand:SI 1 "const_int_operand" "")
7576		   (match_operand:SI 2 "const_int_operand" ""))
7577		 (const_int 0)))]
7578  "ix86_match_ccmode (insn, CCNOmode)
7579   && INTVAL (operands[1]) > 0
7580   && INTVAL (operands[2]) >= 0
7581   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7582   && (GET_MODE (operands[0]) == SImode
7583       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7584       || GET_MODE (operands[0]) == HImode
7585       || GET_MODE (operands[0]) == QImode)"
7586  "#")
7587
7588(define_split
7589  [(set (match_operand 0 "flags_reg_operand" "")
7590        (match_operator 1 "compare_operator"
7591	  [(zero_extract
7592	     (match_operand 2 "nonimmediate_operand" "")
7593	     (match_operand 3 "const_int_operand" "")
7594	     (match_operand 4 "const_int_operand" ""))
7595	   (const_int 0)]))]
7596  "ix86_match_ccmode (insn, CCNOmode)"
7597  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7598{
7599  rtx val = operands[2];
7600  HOST_WIDE_INT len = INTVAL (operands[3]);
7601  HOST_WIDE_INT pos = INTVAL (operands[4]);
7602  HOST_WIDE_INT mask;
7603  enum machine_mode mode, submode;
7604
7605  mode = GET_MODE (val);
7606  if (MEM_P (val))
7607    {
7608      /* ??? Combine likes to put non-volatile mem extractions in QImode
7609	 no matter the size of the test.  So find a mode that works.  */
7610      if (! MEM_VOLATILE_P (val))
7611	{
7612	  mode = smallest_mode_for_size (pos + len, MODE_INT);
7613	  val = adjust_address (val, mode, 0);
7614	}
7615    }
7616  else if (GET_CODE (val) == SUBREG
7617	   && (submode = GET_MODE (SUBREG_REG (val)),
7618	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7619	   && pos + len <= GET_MODE_BITSIZE (submode)
7620	   && GET_MODE_CLASS (submode) == MODE_INT)
7621    {
7622      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7623      mode = submode;
7624      val = SUBREG_REG (val);
7625    }
7626  else if (mode == HImode && pos + len <= 8)
7627    {
7628      /* Small HImode tests can be converted to QImode.  */
7629      mode = QImode;
7630      val = gen_lowpart (QImode, val);
7631    }
7632
7633  if (len == HOST_BITS_PER_WIDE_INT)
7634    mask = -1;
7635  else
7636    mask = ((HOST_WIDE_INT)1 << len) - 1;
7637  mask <<= pos;
7638
7639  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7640})
7641
7642;; Convert HImode/SImode test instructions with immediate to QImode ones.
7643;; i386 does not allow to encode test with 8bit sign extended immediate, so
7644;; this is relatively important trick.
7645;; Do the conversion only post-reload to avoid limiting of the register class
7646;; to QI regs.
7647(define_split
7648  [(set (match_operand 0 "flags_reg_operand" "")
7649	(match_operator 1 "compare_operator"
7650	  [(and (match_operand 2 "register_operand" "")
7651	        (match_operand 3 "const_int_operand" ""))
7652	   (const_int 0)]))]
7653   "reload_completed
7654    && QI_REG_P (operands[2])
7655    && GET_MODE (operands[2]) != QImode
7656    && ((ix86_match_ccmode (insn, CCZmode)
7657    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
7658	|| (ix86_match_ccmode (insn, CCNOmode)
7659	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
7660  [(set (match_dup 0)
7661	(match_op_dup 1
7662	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7663		   (match_dup 3))
7664	   (const_int 0)]))]
7665{
7666  operands[2] = gen_lowpart (SImode, operands[2]);
7667  operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7668})
7669
7670(define_split
7671  [(set (match_operand 0 "flags_reg_operand" "")
7672	(match_operator 1 "compare_operator"
7673	  [(and (match_operand 2 "nonimmediate_operand" "")
7674	        (match_operand 3 "const_int_operand" ""))
7675	   (const_int 0)]))]
7676   "reload_completed
7677    && GET_MODE (operands[2]) != QImode
7678    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7679    && ((ix86_match_ccmode (insn, CCZmode)
7680	 && !(INTVAL (operands[3]) & ~255))
7681	|| (ix86_match_ccmode (insn, CCNOmode)
7682	    && !(INTVAL (operands[3]) & ~127)))"
7683  [(set (match_dup 0)
7684	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7685			 (const_int 0)]))]
7686{
7687  operands[2] = gen_lowpart (QImode, operands[2]);
7688  operands[3] = gen_lowpart (QImode, operands[3]);
7689})
7690
7691;; %%% This used to optimize known byte-wide and operations to memory,
7692;; and sometimes to QImode registers.  If this is considered useful,
7693;; it should be done with splitters.
7694
7695(define_expand "and<mode>3"
7696  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7697	(and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7698		  (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7699  ""
7700{
7701  if (<MODE>mode == DImode
7702      && GET_CODE (operands[2]) == CONST_INT
7703      && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7704      && REG_P (operands[1]))
7705    emit_insn (gen_zero_extendsidi2 (operands[0],
7706				     gen_lowpart (SImode, operands[1])));
7707  else
7708    ix86_expand_binary_operator (AND, <MODE>mode, operands);
7709  DONE;
7710})
7711
7712(define_insn "*anddi_1"
7713  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7714	(and:DI
7715	 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7716	 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7717   (clobber (reg:CC FLAGS_REG))]
7718  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7719{
7720  switch (get_attr_type (insn))
7721    {
7722    case TYPE_IMOVX:
7723      {
7724	enum machine_mode mode;
7725
7726	gcc_assert (CONST_INT_P (operands[2]));
7727	if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7728	  mode = SImode;
7729	else if (INTVAL (operands[2]) == 0xffff)
7730	  mode = HImode;
7731	else
7732	  {
7733	    gcc_assert (INTVAL (operands[2]) == 0xff);
7734	    mode = QImode;
7735	  }
7736
7737	operands[1] = gen_lowpart (mode, operands[1]);
7738	if (mode == SImode)
7739	  return "mov{l}\t{%1, %k0|%k0, %1}";
7740	else if (mode == HImode)
7741	  return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7742	else
7743	  return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7744      }
7745
7746    default:
7747      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7748      if (get_attr_mode (insn) == MODE_SI)
7749	return "and{l}\t{%k2, %k0|%k0, %k2}";
7750      else
7751	return "and{q}\t{%2, %0|%0, %2}";
7752    }
7753}
7754  [(set_attr "type" "alu,alu,alu,imovx")
7755   (set_attr "length_immediate" "*,*,*,0")
7756   (set (attr "prefix_rex")
7757     (if_then_else
7758       (and (eq_attr "type" "imovx")
7759	    (and (match_test "INTVAL (operands[2]) == 0xff")
7760		 (match_operand 1 "ext_QIreg_operand" "")))
7761       (const_string "1")
7762       (const_string "*")))
7763   (set_attr "mode" "SI,DI,DI,SI")])
7764
7765(define_insn "*andsi_1"
7766  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7767	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7768		(match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7769   (clobber (reg:CC FLAGS_REG))]
7770  "ix86_binary_operator_ok (AND, SImode, operands)"
7771{
7772  switch (get_attr_type (insn))
7773    {
7774    case TYPE_IMOVX:
7775      {
7776	enum machine_mode mode;
7777
7778	gcc_assert (CONST_INT_P (operands[2]));
7779        if (INTVAL (operands[2]) == 0xffff)
7780	  mode = HImode;
7781	else
7782	  {
7783	    gcc_assert (INTVAL (operands[2]) == 0xff);
7784	    mode = QImode;
7785	  }
7786
7787	operands[1] = gen_lowpart (mode, operands[1]);
7788	if (mode == HImode)
7789	  return "movz{wl|x}\t{%1, %0|%0, %1}";
7790	else
7791	  return "movz{bl|x}\t{%1, %0|%0, %1}";
7792      }
7793
7794    default:
7795      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7796      return "and{l}\t{%2, %0|%0, %2}";
7797    }
7798}
7799  [(set_attr "type" "alu,alu,imovx")
7800   (set (attr "prefix_rex")
7801     (if_then_else
7802       (and (eq_attr "type" "imovx")
7803	    (and (match_test "INTVAL (operands[2]) == 0xff")
7804		 (match_operand 1 "ext_QIreg_operand" "")))
7805       (const_string "1")
7806       (const_string "*")))
7807   (set_attr "length_immediate" "*,*,0")
7808   (set_attr "mode" "SI")])
7809
7810;; See comment for addsi_1_zext why we do use nonimmediate_operand
7811(define_insn "*andsi_1_zext"
7812  [(set (match_operand:DI 0 "register_operand" "=r")
7813	(zero_extend:DI
7814	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7815		  (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7816   (clobber (reg:CC FLAGS_REG))]
7817  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7818  "and{l}\t{%2, %k0|%k0, %2}"
7819  [(set_attr "type" "alu")
7820   (set_attr "mode" "SI")])
7821
7822(define_insn "*andhi_1"
7823  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7824	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7825		(match_operand:HI 2 "general_operand" "rn,rm,L")))
7826   (clobber (reg:CC FLAGS_REG))]
7827  "ix86_binary_operator_ok (AND, HImode, operands)"
7828{
7829  switch (get_attr_type (insn))
7830    {
7831    case TYPE_IMOVX:
7832      gcc_assert (CONST_INT_P (operands[2]));
7833      gcc_assert (INTVAL (operands[2]) == 0xff);
7834      return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7835
7836    default:
7837      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7838
7839      return "and{w}\t{%2, %0|%0, %2}";
7840    }
7841}
7842  [(set_attr "type" "alu,alu,imovx")
7843   (set_attr "length_immediate" "*,*,0")
7844   (set (attr "prefix_rex")
7845     (if_then_else
7846       (and (eq_attr "type" "imovx")
7847	    (match_operand 1 "ext_QIreg_operand" ""))
7848       (const_string "1")
7849       (const_string "*")))
7850   (set_attr "mode" "HI,HI,SI")])
7851
7852;; %%% Potential partial reg stall on alternative 2.  What to do?
7853(define_insn "*andqi_1"
7854  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7855	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7856		(match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7857   (clobber (reg:CC FLAGS_REG))]
7858  "ix86_binary_operator_ok (AND, QImode, operands)"
7859  "@
7860   and{b}\t{%2, %0|%0, %2}
7861   and{b}\t{%2, %0|%0, %2}
7862   and{l}\t{%k2, %k0|%k0, %k2}"
7863  [(set_attr "type" "alu")
7864   (set_attr "mode" "QI,QI,SI")])
7865
7866(define_insn "*andqi_1_slp"
7867  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7868	(and:QI (match_dup 0)
7869		(match_operand:QI 1 "general_operand" "qn,qmn")))
7870   (clobber (reg:CC FLAGS_REG))]
7871  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7872   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7873  "and{b}\t{%1, %0|%0, %1}"
7874  [(set_attr "type" "alu1")
7875   (set_attr "mode" "QI")])
7876
7877(define_split
7878  [(set (match_operand 0 "register_operand" "")
7879	(and (match_dup 0)
7880	     (const_int -65536)))
7881   (clobber (reg:CC FLAGS_REG))]
7882  "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7883    || optimize_function_for_size_p (cfun)"
7884  [(set (strict_low_part (match_dup 1)) (const_int 0))]
7885  "operands[1] = gen_lowpart (HImode, operands[0]);")
7886
7887(define_split
7888  [(set (match_operand 0 "ext_register_operand" "")
7889	(and (match_dup 0)
7890	     (const_int -256)))
7891   (clobber (reg:CC FLAGS_REG))]
7892  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7893   && reload_completed"
7894  [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895  "operands[1] = gen_lowpart (QImode, operands[0]);")
7896
7897(define_split
7898  [(set (match_operand 0 "ext_register_operand" "")
7899	(and (match_dup 0)
7900	     (const_int -65281)))
7901   (clobber (reg:CC FLAGS_REG))]
7902  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903   && reload_completed"
7904  [(parallel [(set (zero_extract:SI (match_dup 0)
7905				    (const_int 8)
7906				    (const_int 8))
7907		   (xor:SI
7908		     (zero_extract:SI (match_dup 0)
7909				      (const_int 8)
7910				      (const_int 8))
7911		     (zero_extract:SI (match_dup 0)
7912				      (const_int 8)
7913				      (const_int 8))))
7914	      (clobber (reg:CC FLAGS_REG))])]
7915  "operands[0] = gen_lowpart (SImode, operands[0]);")
7916
7917(define_insn "*anddi_2"
7918  [(set (reg FLAGS_REG)
7919	(compare
7920	 (and:DI
7921	  (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7922	  (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7923	 (const_int 0)))
7924   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7925	(and:DI (match_dup 1) (match_dup 2)))]
7926  "TARGET_64BIT
7927   && ix86_match_ccmode
7928	(insn,
7929	 /* If we are going to emit andl instead of andq, and the operands[2]
7930	    constant might have the SImode sign bit set, make sure the sign
7931	    flag isn't tested, because the instruction will set the sign flag
7932	    based on bit 31 rather than bit 63.  If it isn't CONST_INT,
7933	    conservatively assume it might have bit 31 set.  */
7934	 (satisfies_constraint_Z (operands[2])
7935	  && (!CONST_INT_P (operands[2])
7936	      || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7937	 ? CCZmode : CCNOmode)
7938   && ix86_binary_operator_ok (AND, DImode, operands)"
7939  "@
7940   and{l}\t{%k2, %k0|%k0, %k2}
7941   and{q}\t{%2, %0|%0, %2}
7942   and{q}\t{%2, %0|%0, %2}"
7943  [(set_attr "type" "alu")
7944   (set_attr "mode" "SI,DI,DI")])
7945
7946(define_insn "*andqi_2_maybe_si"
7947  [(set (reg FLAGS_REG)
7948	(compare (and:QI
7949		  (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7950		  (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7951		 (const_int 0)))
7952   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7953	(and:QI (match_dup 1) (match_dup 2)))]
7954  "ix86_binary_operator_ok (AND, QImode, operands)
7955   && ix86_match_ccmode (insn,
7956			 CONST_INT_P (operands[2])
7957			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7958{
7959  if (which_alternative == 2)
7960    {
7961      if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7962        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7963      return "and{l}\t{%2, %k0|%k0, %2}";
7964    }
7965  return "and{b}\t{%2, %0|%0, %2}";
7966}
7967  [(set_attr "type" "alu")
7968   (set_attr "mode" "QI,QI,SI")])
7969
7970(define_insn "*and<mode>_2"
7971  [(set (reg FLAGS_REG)
7972	(compare (and:SWI124
7973		  (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7974		  (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7975		 (const_int 0)))
7976   (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7977	(and:SWI124 (match_dup 1) (match_dup 2)))]
7978  "ix86_match_ccmode (insn, CCNOmode)
7979   && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7980  "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7981  [(set_attr "type" "alu")
7982   (set_attr "mode" "<MODE>")])
7983
7984;; See comment for addsi_1_zext why we do use nonimmediate_operand
7985(define_insn "*andsi_2_zext"
7986  [(set (reg FLAGS_REG)
7987	(compare (and:SI
7988		  (match_operand:SI 1 "nonimmediate_operand" "%0")
7989		  (match_operand:SI 2 "x86_64_general_operand" "rme"))
7990		 (const_int 0)))
7991   (set (match_operand:DI 0 "register_operand" "=r")
7992	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7993  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7994   && ix86_binary_operator_ok (AND, SImode, operands)"
7995  "and{l}\t{%2, %k0|%k0, %2}"
7996  [(set_attr "type" "alu")
7997   (set_attr "mode" "SI")])
7998
7999(define_insn "*andqi_2_slp"
8000  [(set (reg FLAGS_REG)
8001	(compare (and:QI
8002		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8003		   (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8004		 (const_int 0)))
8005   (set (strict_low_part (match_dup 0))
8006	(and:QI (match_dup 0) (match_dup 1)))]
8007  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8008   && ix86_match_ccmode (insn, CCNOmode)
8009   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8010  "and{b}\t{%1, %0|%0, %1}"
8011  [(set_attr "type" "alu1")
8012   (set_attr "mode" "QI")])
8013
8014;; ??? A bug in recog prevents it from recognizing a const_int as an
8015;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8016;; for a QImode operand, which of course failed.
8017(define_insn "andqi_ext_0"
8018  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8019			 (const_int 8)
8020			 (const_int 8))
8021	(and:SI
8022	  (zero_extract:SI
8023	    (match_operand 1 "ext_register_operand" "0")
8024	    (const_int 8)
8025	    (const_int 8))
8026	  (match_operand 2 "const_int_operand" "n")))
8027   (clobber (reg:CC FLAGS_REG))]
8028  ""
8029  "and{b}\t{%2, %h0|%h0, %2}"
8030  [(set_attr "type" "alu")
8031   (set_attr "length_immediate" "1")
8032   (set_attr "modrm" "1")
8033   (set_attr "mode" "QI")])
8034
8035;; Generated by peephole translating test to and.  This shows up
8036;; often in fp comparisons.
8037(define_insn "*andqi_ext_0_cc"
8038  [(set (reg FLAGS_REG)
8039	(compare
8040	  (and:SI
8041	    (zero_extract:SI
8042	      (match_operand 1 "ext_register_operand" "0")
8043	      (const_int 8)
8044	      (const_int 8))
8045	    (match_operand 2 "const_int_operand" "n"))
8046	  (const_int 0)))
8047   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8048			 (const_int 8)
8049			 (const_int 8))
8050	(and:SI
8051	  (zero_extract:SI
8052	    (match_dup 1)
8053	    (const_int 8)
8054	    (const_int 8))
8055	  (match_dup 2)))]
8056  "ix86_match_ccmode (insn, CCNOmode)"
8057  "and{b}\t{%2, %h0|%h0, %2}"
8058  [(set_attr "type" "alu")
8059   (set_attr "length_immediate" "1")
8060   (set_attr "modrm" "1")
8061   (set_attr "mode" "QI")])
8062
8063(define_insn "*andqi_ext_1_rex64"
8064  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8065			 (const_int 8)
8066			 (const_int 8))
8067	(and:SI
8068	  (zero_extract:SI
8069	    (match_operand 1 "ext_register_operand" "0")
8070	    (const_int 8)
8071	    (const_int 8))
8072	  (zero_extend:SI
8073	    (match_operand 2 "ext_register_operand" "Q"))))
8074   (clobber (reg:CC FLAGS_REG))]
8075  "TARGET_64BIT"
8076  "and{b}\t{%2, %h0|%h0, %2}"
8077  [(set_attr "type" "alu")
8078   (set_attr "length_immediate" "0")
8079   (set_attr "mode" "QI")])
8080
8081(define_insn "*andqi_ext_1"
8082  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8083			 (const_int 8)
8084			 (const_int 8))
8085	(and:SI
8086	  (zero_extract:SI
8087	    (match_operand 1 "ext_register_operand" "0")
8088	    (const_int 8)
8089	    (const_int 8))
8090	  (zero_extend:SI
8091	    (match_operand:QI 2 "general_operand" "Qm"))))
8092   (clobber (reg:CC FLAGS_REG))]
8093  "!TARGET_64BIT"
8094  "and{b}\t{%2, %h0|%h0, %2}"
8095  [(set_attr "type" "alu")
8096   (set_attr "length_immediate" "0")
8097   (set_attr "mode" "QI")])
8098
8099(define_insn "*andqi_ext_2"
8100  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8101			 (const_int 8)
8102			 (const_int 8))
8103	(and:SI
8104	  (zero_extract:SI
8105	    (match_operand 1 "ext_register_operand" "%0")
8106	    (const_int 8)
8107	    (const_int 8))
8108	  (zero_extract:SI
8109	    (match_operand 2 "ext_register_operand" "Q")
8110	    (const_int 8)
8111	    (const_int 8))))
8112   (clobber (reg:CC FLAGS_REG))]
8113  ""
8114  "and{b}\t{%h2, %h0|%h0, %h2}"
8115  [(set_attr "type" "alu")
8116   (set_attr "length_immediate" "0")
8117   (set_attr "mode" "QI")])
8118
8119;; Convert wide AND instructions with immediate operand to shorter QImode
8120;; equivalents when possible.
8121;; Don't do the splitting with memory operands, since it introduces risk
8122;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8123;; for size, but that can (should?) be handled by generic code instead.
8124(define_split
8125  [(set (match_operand 0 "register_operand" "")
8126	(and (match_operand 1 "register_operand" "")
8127	     (match_operand 2 "const_int_operand" "")))
8128   (clobber (reg:CC FLAGS_REG))]
8129   "reload_completed
8130    && QI_REG_P (operands[0])
8131    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8132    && !(~INTVAL (operands[2]) & ~(255 << 8))
8133    && GET_MODE (operands[0]) != QImode"
8134  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8135		   (and:SI (zero_extract:SI (match_dup 1)
8136					    (const_int 8) (const_int 8))
8137			   (match_dup 2)))
8138	      (clobber (reg:CC FLAGS_REG))])]
8139{
8140  operands[0] = gen_lowpart (SImode, operands[0]);
8141  operands[1] = gen_lowpart (SImode, operands[1]);
8142  operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8143})
8144
8145;; Since AND can be encoded with sign extended immediate, this is only
8146;; profitable when 7th bit is not set.
8147(define_split
8148  [(set (match_operand 0 "register_operand" "")
8149	(and (match_operand 1 "general_operand" "")
8150	     (match_operand 2 "const_int_operand" "")))
8151   (clobber (reg:CC FLAGS_REG))]
8152   "reload_completed
8153    && ANY_QI_REG_P (operands[0])
8154    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8155    && !(~INTVAL (operands[2]) & ~255)
8156    && !(INTVAL (operands[2]) & 128)
8157    && GET_MODE (operands[0]) != QImode"
8158  [(parallel [(set (strict_low_part (match_dup 0))
8159		   (and:QI (match_dup 1)
8160			   (match_dup 2)))
8161	      (clobber (reg:CC FLAGS_REG))])]
8162{
8163  operands[0] = gen_lowpart (QImode, operands[0]);
8164  operands[1] = gen_lowpart (QImode, operands[1]);
8165  operands[2] = gen_lowpart (QImode, operands[2]);
8166})
8167
8168;; Logical inclusive and exclusive OR instructions
8169
8170;; %%% This used to optimize known byte-wide and operations to memory.
8171;; If this is considered useful, it should be done with splitters.
8172
8173(define_expand "<code><mode>3"
8174  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8175	(any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8176		     (match_operand:SWIM 2 "<general_operand>" "")))]
8177  ""
8178  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8179
8180(define_insn "*<code><mode>_1"
8181  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8182	(any_or:SWI248
8183	 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8184	 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8185   (clobber (reg:CC FLAGS_REG))]
8186  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8187  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8188  [(set_attr "type" "alu")
8189   (set_attr "mode" "<MODE>")])
8190
8191;; %%% Potential partial reg stall on alternative 2.  What to do?
8192(define_insn "*<code>qi_1"
8193  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8194	(any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8195		   (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8196   (clobber (reg:CC FLAGS_REG))]
8197  "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8198  "@
8199   <logic>{b}\t{%2, %0|%0, %2}
8200   <logic>{b}\t{%2, %0|%0, %2}
8201   <logic>{l}\t{%k2, %k0|%k0, %k2}"
8202  [(set_attr "type" "alu")
8203   (set_attr "mode" "QI,QI,SI")])
8204
8205;; See comment for addsi_1_zext why we do use nonimmediate_operand
8206(define_insn "*<code>si_1_zext"
8207  [(set (match_operand:DI 0 "register_operand" "=r")
8208	(zero_extend:DI
8209	 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8210		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8211   (clobber (reg:CC FLAGS_REG))]
8212  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8213  "<logic>{l}\t{%2, %k0|%k0, %2}"
8214  [(set_attr "type" "alu")
8215   (set_attr "mode" "SI")])
8216
8217(define_insn "*<code>si_1_zext_imm"
8218  [(set (match_operand:DI 0 "register_operand" "=r")
8219	(any_or:DI
8220	 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8221	 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8222   (clobber (reg:CC FLAGS_REG))]
8223  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8224  "<logic>{l}\t{%2, %k0|%k0, %2}"
8225  [(set_attr "type" "alu")
8226   (set_attr "mode" "SI")])
8227
8228(define_insn "*<code>qi_1_slp"
8229  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8230	(any_or:QI (match_dup 0)
8231		   (match_operand:QI 1 "general_operand" "qmn,qn")))
8232   (clobber (reg:CC FLAGS_REG))]
8233  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8234   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8235  "<logic>{b}\t{%1, %0|%0, %1}"
8236  [(set_attr "type" "alu1")
8237   (set_attr "mode" "QI")])
8238
8239(define_insn "*<code><mode>_2"
8240  [(set (reg FLAGS_REG)
8241	(compare (any_or:SWI
8242		  (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8243		  (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8244		 (const_int 0)))
8245   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8246	(any_or:SWI (match_dup 1) (match_dup 2)))]
8247  "ix86_match_ccmode (insn, CCNOmode)
8248   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8249  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8250  [(set_attr "type" "alu")
8251   (set_attr "mode" "<MODE>")])
8252
8253;; See comment for addsi_1_zext why we do use nonimmediate_operand
8254;; ??? Special case for immediate operand is missing - it is tricky.
8255(define_insn "*<code>si_2_zext"
8256  [(set (reg FLAGS_REG)
8257	(compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8258			    (match_operand:SI 2 "x86_64_general_operand" "rme"))
8259		 (const_int 0)))
8260   (set (match_operand:DI 0 "register_operand" "=r")
8261	(zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8262  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8263   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8264  "<logic>{l}\t{%2, %k0|%k0, %2}"
8265  [(set_attr "type" "alu")
8266   (set_attr "mode" "SI")])
8267
8268(define_insn "*<code>si_2_zext_imm"
8269  [(set (reg FLAGS_REG)
8270	(compare (any_or:SI
8271		  (match_operand:SI 1 "nonimmediate_operand" "%0")
8272		  (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8273		 (const_int 0)))
8274   (set (match_operand:DI 0 "register_operand" "=r")
8275	(any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8276  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8277   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8278  "<logic>{l}\t{%2, %k0|%k0, %2}"
8279  [(set_attr "type" "alu")
8280   (set_attr "mode" "SI")])
8281
8282(define_insn "*<code>qi_2_slp"
8283  [(set (reg FLAGS_REG)
8284	(compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8285			    (match_operand:QI 1 "general_operand" "qmn,qn"))
8286		 (const_int 0)))
8287   (set (strict_low_part (match_dup 0))
8288	(any_or:QI (match_dup 0) (match_dup 1)))]
8289  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8290   && ix86_match_ccmode (insn, CCNOmode)
8291   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8292  "<logic>{b}\t{%1, %0|%0, %1}"
8293  [(set_attr "type" "alu1")
8294   (set_attr "mode" "QI")])
8295
8296(define_insn "*<code><mode>_3"
8297  [(set (reg FLAGS_REG)
8298	(compare (any_or:SWI
8299		  (match_operand:SWI 1 "nonimmediate_operand" "%0")
8300		  (match_operand:SWI 2 "<general_operand>" "<g>"))
8301		 (const_int 0)))
8302   (clobber (match_scratch:SWI 0 "=<r>"))]
8303  "ix86_match_ccmode (insn, CCNOmode)
8304   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8305  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8306  [(set_attr "type" "alu")
8307   (set_attr "mode" "<MODE>")])
8308
8309(define_insn "*<code>qi_ext_0"
8310  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8311			 (const_int 8)
8312			 (const_int 8))
8313	(any_or:SI
8314	  (zero_extract:SI
8315	    (match_operand 1 "ext_register_operand" "0")
8316	    (const_int 8)
8317	    (const_int 8))
8318	  (match_operand 2 "const_int_operand" "n")))
8319   (clobber (reg:CC FLAGS_REG))]
8320  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8321  "<logic>{b}\t{%2, %h0|%h0, %2}"
8322  [(set_attr "type" "alu")
8323   (set_attr "length_immediate" "1")
8324   (set_attr "modrm" "1")
8325   (set_attr "mode" "QI")])
8326
8327(define_insn "*<code>qi_ext_1_rex64"
8328  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8329			 (const_int 8)
8330			 (const_int 8))
8331	(any_or:SI
8332	  (zero_extract:SI
8333	    (match_operand 1 "ext_register_operand" "0")
8334	    (const_int 8)
8335	    (const_int 8))
8336	  (zero_extend:SI
8337	    (match_operand 2 "ext_register_operand" "Q"))))
8338   (clobber (reg:CC FLAGS_REG))]
8339  "TARGET_64BIT
8340   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8341  "<logic>{b}\t{%2, %h0|%h0, %2}"
8342  [(set_attr "type" "alu")
8343   (set_attr "length_immediate" "0")
8344   (set_attr "mode" "QI")])
8345
8346(define_insn "*<code>qi_ext_1"
8347  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8348			 (const_int 8)
8349			 (const_int 8))
8350	(any_or:SI
8351	  (zero_extract:SI
8352	    (match_operand 1 "ext_register_operand" "0")
8353	    (const_int 8)
8354	    (const_int 8))
8355	  (zero_extend:SI
8356	    (match_operand:QI 2 "general_operand" "Qm"))))
8357   (clobber (reg:CC FLAGS_REG))]
8358  "!TARGET_64BIT
8359   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8360  "<logic>{b}\t{%2, %h0|%h0, %2}"
8361  [(set_attr "type" "alu")
8362   (set_attr "length_immediate" "0")
8363   (set_attr "mode" "QI")])
8364
8365(define_insn "*<code>qi_ext_2"
8366  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8367			 (const_int 8)
8368			 (const_int 8))
8369	(any_or:SI
8370	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8371	  		   (const_int 8)
8372			   (const_int 8))
8373	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8374	  		   (const_int 8)
8375			   (const_int 8))))
8376   (clobber (reg:CC FLAGS_REG))]
8377  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8378  "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8379  [(set_attr "type" "alu")
8380   (set_attr "length_immediate" "0")
8381   (set_attr "mode" "QI")])
8382
8383(define_split
8384  [(set (match_operand 0 "register_operand" "")
8385	(any_or (match_operand 1 "register_operand" "")
8386		(match_operand 2 "const_int_operand" "")))
8387   (clobber (reg:CC FLAGS_REG))]
8388   "reload_completed
8389    && QI_REG_P (operands[0])
8390    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8391    && !(INTVAL (operands[2]) & ~(255 << 8))
8392    && GET_MODE (operands[0]) != QImode"
8393  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8394		   (any_or:SI (zero_extract:SI (match_dup 1)
8395					       (const_int 8) (const_int 8))
8396			      (match_dup 2)))
8397	      (clobber (reg:CC FLAGS_REG))])]
8398{
8399  operands[0] = gen_lowpart (SImode, operands[0]);
8400  operands[1] = gen_lowpart (SImode, operands[1]);
8401  operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8402})
8403
8404;; Since OR can be encoded with sign extended immediate, this is only
8405;; profitable when 7th bit is set.
8406(define_split
8407  [(set (match_operand 0 "register_operand" "")
8408	(any_or (match_operand 1 "general_operand" "")
8409		(match_operand 2 "const_int_operand" "")))
8410   (clobber (reg:CC FLAGS_REG))]
8411   "reload_completed
8412    && ANY_QI_REG_P (operands[0])
8413    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8414    && !(INTVAL (operands[2]) & ~255)
8415    && (INTVAL (operands[2]) & 128)
8416    && GET_MODE (operands[0]) != QImode"
8417  [(parallel [(set (strict_low_part (match_dup 0))
8418		   (any_or:QI (match_dup 1)
8419			      (match_dup 2)))
8420	      (clobber (reg:CC FLAGS_REG))])]
8421{
8422  operands[0] = gen_lowpart (QImode, operands[0]);
8423  operands[1] = gen_lowpart (QImode, operands[1]);
8424  operands[2] = gen_lowpart (QImode, operands[2]);
8425})
8426
8427(define_expand "xorqi_cc_ext_1"
8428  [(parallel [
8429     (set (reg:CCNO FLAGS_REG)
8430	  (compare:CCNO
8431	    (xor:SI
8432	      (zero_extract:SI
8433		(match_operand 1 "ext_register_operand" "")
8434		(const_int 8)
8435		(const_int 8))
8436	      (match_operand:QI 2 "general_operand" ""))
8437	    (const_int 0)))
8438     (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8439			   (const_int 8)
8440			   (const_int 8))
8441	  (xor:SI
8442	    (zero_extract:SI
8443	     (match_dup 1)
8444	     (const_int 8)
8445	     (const_int 8))
8446	    (match_dup 2)))])])
8447
8448(define_insn "*xorqi_cc_ext_1_rex64"
8449  [(set (reg FLAGS_REG)
8450	(compare
8451	  (xor:SI
8452	    (zero_extract:SI
8453	      (match_operand 1 "ext_register_operand" "0")
8454	      (const_int 8)
8455	      (const_int 8))
8456	    (match_operand:QI 2 "nonmemory_operand" "Qn"))
8457	  (const_int 0)))
8458   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8459			 (const_int 8)
8460			 (const_int 8))
8461	(xor:SI
8462	  (zero_extract:SI
8463	   (match_dup 1)
8464	   (const_int 8)
8465	   (const_int 8))
8466	  (match_dup 2)))]
8467  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8468  "xor{b}\t{%2, %h0|%h0, %2}"
8469  [(set_attr "type" "alu")
8470   (set_attr "modrm" "1")
8471   (set_attr "mode" "QI")])
8472
8473(define_insn "*xorqi_cc_ext_1"
8474  [(set (reg FLAGS_REG)
8475	(compare
8476	  (xor:SI
8477	    (zero_extract:SI
8478	      (match_operand 1 "ext_register_operand" "0")
8479	      (const_int 8)
8480	      (const_int 8))
8481	    (match_operand:QI 2 "general_operand" "qmn"))
8482	  (const_int 0)))
8483   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8484			 (const_int 8)
8485			 (const_int 8))
8486	(xor:SI
8487	  (zero_extract:SI
8488	   (match_dup 1)
8489	   (const_int 8)
8490	   (const_int 8))
8491	  (match_dup 2)))]
8492  "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8493  "xor{b}\t{%2, %h0|%h0, %2}"
8494  [(set_attr "type" "alu")
8495   (set_attr "modrm" "1")
8496   (set_attr "mode" "QI")])
8497
8498;; Negation instructions
8499
8500(define_expand "neg<mode>2"
8501  [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8502	(neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8503  ""
8504  "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8505
8506(define_insn_and_split "*neg<dwi>2_doubleword"
8507  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8508	(neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8509   (clobber (reg:CC FLAGS_REG))]
8510  "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8511  "#"
8512  "reload_completed"
8513  [(parallel
8514    [(set (reg:CCZ FLAGS_REG)
8515	  (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8516     (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8517   (parallel
8518    [(set (match_dup 2)
8519	  (plus:DWIH (match_dup 3)
8520		     (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8521				(const_int 0))))
8522     (clobber (reg:CC FLAGS_REG))])
8523   (parallel
8524    [(set (match_dup 2)
8525	  (neg:DWIH (match_dup 2)))
8526     (clobber (reg:CC FLAGS_REG))])]
8527  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8528
8529(define_insn "*neg<mode>2_1"
8530  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8531	(neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8532   (clobber (reg:CC FLAGS_REG))]
8533  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8534  "neg{<imodesuffix>}\t%0"
8535  [(set_attr "type" "negnot")
8536   (set_attr "mode" "<MODE>")])
8537
8538;; Combine is quite creative about this pattern.
8539(define_insn "*negsi2_1_zext"
8540  [(set (match_operand:DI 0 "register_operand" "=r")
8541	(lshiftrt:DI
8542	  (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8543			     (const_int 32)))
8544	(const_int 32)))
8545   (clobber (reg:CC FLAGS_REG))]
8546  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8547  "neg{l}\t%k0"
8548  [(set_attr "type" "negnot")
8549   (set_attr "mode" "SI")])
8550
8551;; The problem with neg is that it does not perform (compare x 0),
8552;; it really performs (compare 0 x), which leaves us with the zero
8553;; flag being the only useful item.
8554
8555(define_insn "*neg<mode>2_cmpz"
8556  [(set (reg:CCZ FLAGS_REG)
8557	(compare:CCZ
8558	  (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8559		   (const_int 0)))
8560   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8561	(neg:SWI (match_dup 1)))]
8562  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8563  "neg{<imodesuffix>}\t%0"
8564  [(set_attr "type" "negnot")
8565   (set_attr "mode" "<MODE>")])
8566
8567(define_insn "*negsi2_cmpz_zext"
8568  [(set (reg:CCZ FLAGS_REG)
8569	(compare:CCZ
8570	  (lshiftrt:DI
8571	    (neg:DI (ashift:DI
8572		      (match_operand:DI 1 "register_operand" "0")
8573		      (const_int 32)))
8574	    (const_int 32))
8575	  (const_int 0)))
8576   (set (match_operand:DI 0 "register_operand" "=r")
8577	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8578					(const_int 32)))
8579		     (const_int 32)))]
8580  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8581  "neg{l}\t%k0"
8582  [(set_attr "type" "negnot")
8583   (set_attr "mode" "SI")])
8584
8585;; Changing of sign for FP values is doable using integer unit too.
8586
8587(define_expand "<code><mode>2"
8588  [(set (match_operand:X87MODEF 0 "register_operand" "")
8589	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8590  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8591  "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8592
8593(define_insn "*absneg<mode>2_mixed"
8594  [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8595	(match_operator:MODEF 3 "absneg_operator"
8596	  [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8597   (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8598   (clobber (reg:CC FLAGS_REG))]
8599  "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8600  "#")
8601
8602(define_insn "*absneg<mode>2_sse"
8603  [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8604	(match_operator:MODEF 3 "absneg_operator"
8605	  [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8606   (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8607   (clobber (reg:CC FLAGS_REG))]
8608  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8609  "#")
8610
8611(define_insn "*absneg<mode>2_i387"
8612  [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8613	(match_operator:X87MODEF 3 "absneg_operator"
8614	  [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8615   (use (match_operand 2 "" ""))
8616   (clobber (reg:CC FLAGS_REG))]
8617  "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8618  "#")
8619
8620(define_expand "<code>tf2"
8621  [(set (match_operand:TF 0 "register_operand" "")
8622	(absneg:TF (match_operand:TF 1 "register_operand" "")))]
8623  "TARGET_SSE2"
8624  "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8625
8626(define_insn "*absnegtf2_sse"
8627  [(set (match_operand:TF 0 "register_operand" "=x,x")
8628	(match_operator:TF 3 "absneg_operator"
8629	  [(match_operand:TF 1 "register_operand" "0,x")]))
8630   (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8631   (clobber (reg:CC FLAGS_REG))]
8632  "TARGET_SSE2"
8633  "#")
8634
8635;; Splitters for fp abs and neg.
8636
8637(define_split
8638  [(set (match_operand 0 "fp_register_operand" "")
8639	(match_operator 1 "absneg_operator" [(match_dup 0)]))
8640   (use (match_operand 2 "" ""))
8641   (clobber (reg:CC FLAGS_REG))]
8642  "reload_completed"
8643  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8644
8645(define_split
8646  [(set (match_operand 0 "register_operand" "")
8647	(match_operator 3 "absneg_operator"
8648	  [(match_operand 1 "register_operand" "")]))
8649   (use (match_operand 2 "nonimmediate_operand" ""))
8650   (clobber (reg:CC FLAGS_REG))]
8651  "reload_completed && SSE_REG_P (operands[0])"
8652  [(set (match_dup 0) (match_dup 3))]
8653{
8654  enum machine_mode mode = GET_MODE (operands[0]);
8655  enum machine_mode vmode = GET_MODE (operands[2]);
8656  rtx tmp;
8657
8658  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8659  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8660  if (operands_match_p (operands[0], operands[2]))
8661    {
8662      tmp = operands[1];
8663      operands[1] = operands[2];
8664      operands[2] = tmp;
8665    }
8666  if (GET_CODE (operands[3]) == ABS)
8667    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8668  else
8669    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8670  operands[3] = tmp;
8671})
8672
8673(define_split
8674  [(set (match_operand:SF 0 "register_operand" "")
8675	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8676   (use (match_operand:V4SF 2 "" ""))
8677   (clobber (reg:CC FLAGS_REG))]
8678  "reload_completed"
8679  [(parallel [(set (match_dup 0) (match_dup 1))
8680	      (clobber (reg:CC FLAGS_REG))])]
8681{
8682  rtx tmp;
8683  operands[0] = gen_lowpart (SImode, operands[0]);
8684  if (GET_CODE (operands[1]) == ABS)
8685    {
8686      tmp = gen_int_mode (0x7fffffff, SImode);
8687      tmp = gen_rtx_AND (SImode, operands[0], tmp);
8688    }
8689  else
8690    {
8691      tmp = gen_int_mode (0x80000000, SImode);
8692      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8693    }
8694  operands[1] = tmp;
8695})
8696
8697(define_split
8698  [(set (match_operand:DF 0 "register_operand" "")
8699	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8700   (use (match_operand 2 "" ""))
8701   (clobber (reg:CC FLAGS_REG))]
8702  "reload_completed"
8703  [(parallel [(set (match_dup 0) (match_dup 1))
8704	      (clobber (reg:CC FLAGS_REG))])]
8705{
8706  rtx tmp;
8707  if (TARGET_64BIT)
8708    {
8709      tmp = gen_lowpart (DImode, operands[0]);
8710      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8711      operands[0] = tmp;
8712
8713      if (GET_CODE (operands[1]) == ABS)
8714	tmp = const0_rtx;
8715      else
8716	tmp = gen_rtx_NOT (DImode, tmp);
8717    }
8718  else
8719    {
8720      operands[0] = gen_highpart (SImode, operands[0]);
8721      if (GET_CODE (operands[1]) == ABS)
8722	{
8723	  tmp = gen_int_mode (0x7fffffff, SImode);
8724	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
8725	}
8726      else
8727	{
8728	  tmp = gen_int_mode (0x80000000, SImode);
8729	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8730	}
8731    }
8732  operands[1] = tmp;
8733})
8734
8735(define_split
8736  [(set (match_operand:XF 0 "register_operand" "")
8737	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8738   (use (match_operand 2 "" ""))
8739   (clobber (reg:CC FLAGS_REG))]
8740  "reload_completed"
8741  [(parallel [(set (match_dup 0) (match_dup 1))
8742	      (clobber (reg:CC FLAGS_REG))])]
8743{
8744  rtx tmp;
8745  operands[0] = gen_rtx_REG (SImode,
8746			     true_regnum (operands[0])
8747			     + (TARGET_64BIT ? 1 : 2));
8748  if (GET_CODE (operands[1]) == ABS)
8749    {
8750      tmp = GEN_INT (0x7fff);
8751      tmp = gen_rtx_AND (SImode, operands[0], tmp);
8752    }
8753  else
8754    {
8755      tmp = GEN_INT (0x8000);
8756      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8757    }
8758  operands[1] = tmp;
8759})
8760
8761;; Conditionalize these after reload. If they match before reload, we
8762;; lose the clobber and ability to use integer instructions.
8763
8764(define_insn "*<code><mode>2_1"
8765  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8766	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8767  "TARGET_80387
8768   && (reload_completed
8769       || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8770  "f<absneg_mnemonic>"
8771  [(set_attr "type" "fsgn")
8772   (set_attr "mode" "<MODE>")])
8773
8774(define_insn "*<code>extendsfdf2"
8775  [(set (match_operand:DF 0 "register_operand" "=f")
8776	(absneg:DF (float_extend:DF
8777		     (match_operand:SF 1 "register_operand" "0"))))]
8778  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8779  "f<absneg_mnemonic>"
8780  [(set_attr "type" "fsgn")
8781   (set_attr "mode" "DF")])
8782
8783(define_insn "*<code>extendsfxf2"
8784  [(set (match_operand:XF 0 "register_operand" "=f")
8785	(absneg:XF (float_extend:XF
8786		     (match_operand:SF 1 "register_operand" "0"))))]
8787  "TARGET_80387"
8788  "f<absneg_mnemonic>"
8789  [(set_attr "type" "fsgn")
8790   (set_attr "mode" "XF")])
8791
8792(define_insn "*<code>extenddfxf2"
8793  [(set (match_operand:XF 0 "register_operand" "=f")
8794	(absneg:XF (float_extend:XF
8795		     (match_operand:DF 1 "register_operand" "0"))))]
8796  "TARGET_80387"
8797  "f<absneg_mnemonic>"
8798  [(set_attr "type" "fsgn")
8799   (set_attr "mode" "XF")])
8800
8801;; Copysign instructions
8802
8803(define_mode_iterator CSGNMODE [SF DF TF])
8804(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8805
8806(define_expand "copysign<mode>3"
8807  [(match_operand:CSGNMODE 0 "register_operand" "")
8808   (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8809   (match_operand:CSGNMODE 2 "register_operand" "")]
8810  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8811   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8812  "ix86_expand_copysign (operands); DONE;")
8813
8814(define_insn_and_split "copysign<mode>3_const"
8815  [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8816	(unspec:CSGNMODE
8817	  [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8818	   (match_operand:CSGNMODE 2 "register_operand" "0")
8819	   (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8820	  UNSPEC_COPYSIGN))]
8821  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8822   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8823  "#"
8824  "&& reload_completed"
8825  [(const_int 0)]
8826  "ix86_split_copysign_const (operands); DONE;")
8827
8828(define_insn "copysign<mode>3_var"
8829  [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8830	(unspec:CSGNMODE
8831	  [(match_operand:CSGNMODE 2 "register_operand"	"x,0,0,x,x")
8832	   (match_operand:CSGNMODE 3 "register_operand"	"1,1,x,1,x")
8833	   (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8834	   (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8835	  UNSPEC_COPYSIGN))
8836   (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8837  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8838   || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8839  "#")
8840
8841(define_split
8842  [(set (match_operand:CSGNMODE 0 "register_operand" "")
8843	(unspec:CSGNMODE
8844	  [(match_operand:CSGNMODE 2 "register_operand" "")
8845	   (match_operand:CSGNMODE 3 "register_operand" "")
8846	   (match_operand:<CSGNVMODE> 4 "" "")
8847	   (match_operand:<CSGNVMODE> 5 "" "")]
8848	  UNSPEC_COPYSIGN))
8849   (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8850  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8851    || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8852   && reload_completed"
8853  [(const_int 0)]
8854  "ix86_split_copysign_var (operands); DONE;")
8855
8856;; One complement instructions
8857
8858(define_expand "one_cmpl<mode>2"
8859  [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8860	(not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8861  ""
8862  "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8863
8864(define_insn "*one_cmpl<mode>2_1"
8865  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8866	(not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8867  "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8868  "not{<imodesuffix>}\t%0"
8869  [(set_attr "type" "negnot")
8870   (set_attr "mode" "<MODE>")])
8871
8872;; %%% Potential partial reg stall on alternative 1.  What to do?
8873(define_insn "*one_cmplqi2_1"
8874  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8875	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8876  "ix86_unary_operator_ok (NOT, QImode, operands)"
8877  "@
8878   not{b}\t%0
8879   not{l}\t%k0"
8880  [(set_attr "type" "negnot")
8881   (set_attr "mode" "QI,SI")])
8882
8883;; ??? Currently never generated - xor is used instead.
8884(define_insn "*one_cmplsi2_1_zext"
8885  [(set (match_operand:DI 0 "register_operand" "=r")
8886	(zero_extend:DI
8887	  (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8888  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8889  "not{l}\t%k0"
8890  [(set_attr "type" "negnot")
8891   (set_attr "mode" "SI")])
8892
8893(define_insn "*one_cmpl<mode>2_2"
8894  [(set (reg FLAGS_REG)
8895	(compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8896		 (const_int 0)))
8897   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8898	(not:SWI (match_dup 1)))]
8899  "ix86_match_ccmode (insn, CCNOmode)
8900   && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8901  "#"
8902  [(set_attr "type" "alu1")
8903   (set_attr "mode" "<MODE>")])
8904
8905(define_split
8906  [(set (match_operand 0 "flags_reg_operand" "")
8907	(match_operator 2 "compare_operator"
8908	  [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8909	   (const_int 0)]))
8910   (set (match_operand:SWI 1 "nonimmediate_operand" "")
8911	(not:SWI (match_dup 3)))]
8912  "ix86_match_ccmode (insn, CCNOmode)"
8913  [(parallel [(set (match_dup 0)
8914		   (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8915				    (const_int 0)]))
8916	      (set (match_dup 1)
8917		   (xor:SWI (match_dup 3) (const_int -1)))])])
8918
8919;; ??? Currently never generated - xor is used instead.
8920(define_insn "*one_cmplsi2_2_zext"
8921  [(set (reg FLAGS_REG)
8922	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8923		 (const_int 0)))
8924   (set (match_operand:DI 0 "register_operand" "=r")
8925	(zero_extend:DI (not:SI (match_dup 1))))]
8926  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8927   && ix86_unary_operator_ok (NOT, SImode, operands)"
8928  "#"
8929  [(set_attr "type" "alu1")
8930   (set_attr "mode" "SI")])
8931
8932(define_split
8933  [(set (match_operand 0 "flags_reg_operand" "")
8934	(match_operator 2 "compare_operator"
8935	  [(not:SI (match_operand:SI 3 "register_operand" ""))
8936	   (const_int 0)]))
8937   (set (match_operand:DI 1 "register_operand" "")
8938	(zero_extend:DI (not:SI (match_dup 3))))]
8939  "ix86_match_ccmode (insn, CCNOmode)"
8940  [(parallel [(set (match_dup 0)
8941		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8942				    (const_int 0)]))
8943	      (set (match_dup 1)
8944		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8945
8946;; Shift instructions
8947
8948;; DImode shifts are implemented using the i386 "shift double" opcode,
8949;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
8950;; is variable, then the count is in %cl and the "imm" operand is dropped
8951;; from the assembler input.
8952;;
8953;; This instruction shifts the target reg/mem as usual, but instead of
8954;; shifting in zeros, bits are shifted in from reg operand.  If the insn
8955;; is a left shift double, bits are taken from the high order bits of
8956;; reg, else if the insn is a shift right double, bits are taken from the
8957;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
8958;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8959;;
8960;; Since sh[lr]d does not change the `reg' operand, that is done
8961;; separately, making all shifts emit pairs of shift double and normal
8962;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
8963;; support a 63 bit shift, each shift where the count is in a reg expands
8964;; to a pair of shifts, a branch, a shift by 32 and a label.
8965;;
8966;; If the shift count is a constant, we need never emit more than one
8967;; shift pair, instead using moves and sign extension for counts greater
8968;; than 31.
8969
8970(define_expand "ashl<mode>3"
8971  [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8972	(ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8973		      (match_operand:QI 2 "nonmemory_operand" "")))]
8974  ""
8975  "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8976
8977(define_insn "*ashl<mode>3_doubleword"
8978  [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8979	(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8980		    (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8981   (clobber (reg:CC FLAGS_REG))]
8982  ""
8983  "#"
8984  [(set_attr "type" "multi")])
8985
8986(define_split
8987  [(set (match_operand:DWI 0 "register_operand" "")
8988	(ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8989		    (match_operand:QI 2 "nonmemory_operand" "")))
8990   (clobber (reg:CC FLAGS_REG))]
8991  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8992  [(const_int 0)]
8993  "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8994
8995;; By default we don't ask for a scratch register, because when DWImode
8996;; values are manipulated, registers are already at a premium.  But if
8997;; we have one handy, we won't turn it away.
8998
8999(define_peephole2
9000  [(match_scratch:DWIH 3 "r")
9001   (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9002		   (ashift:<DWI>
9003		     (match_operand:<DWI> 1 "nonmemory_operand" "")
9004		     (match_operand:QI 2 "nonmemory_operand" "")))
9005	      (clobber (reg:CC FLAGS_REG))])
9006   (match_dup 3)]
9007  "TARGET_CMOVE"
9008  [(const_int 0)]
9009  "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9010
9011(define_insn "x86_64_shld"
9012  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9013        (ior:DI (ashift:DI (match_dup 0)
9014		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
9015		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9016		  (minus:QI (const_int 64) (match_dup 2)))))
9017   (clobber (reg:CC FLAGS_REG))]
9018  "TARGET_64BIT"
9019  "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9020  [(set_attr "type" "ishift")
9021   (set_attr "prefix_0f" "1")
9022   (set_attr "mode" "DI")
9023   (set_attr "athlon_decode" "vector")
9024   (set_attr "amdfam10_decode" "vector")
9025   (set_attr "bdver1_decode" "vector")])
9026
9027(define_insn "x86_shld"
9028  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9029        (ior:SI (ashift:SI (match_dup 0)
9030		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
9031		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9032		  (minus:QI (const_int 32) (match_dup 2)))))
9033   (clobber (reg:CC FLAGS_REG))]
9034  ""
9035  "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9036  [(set_attr "type" "ishift")
9037   (set_attr "prefix_0f" "1")
9038   (set_attr "mode" "SI")
9039   (set_attr "pent_pair" "np")
9040   (set_attr "athlon_decode" "vector")
9041   (set_attr "amdfam10_decode" "vector")
9042   (set_attr "bdver1_decode" "vector")])
9043
9044(define_expand "x86_shift<mode>_adj_1"
9045  [(set (reg:CCZ FLAGS_REG)
9046	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9047			     (match_dup 4))
9048		     (const_int 0)))
9049   (set (match_operand:SWI48 0 "register_operand" "")
9050        (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9051			    (match_operand:SWI48 1 "register_operand" "")
9052			    (match_dup 0)))
9053   (set (match_dup 1)
9054	(if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9055			    (match_operand:SWI48 3 "register_operand" "")
9056			    (match_dup 1)))]
9057  "TARGET_CMOVE"
9058  "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9059
9060(define_expand "x86_shift<mode>_adj_2"
9061  [(use (match_operand:SWI48 0 "register_operand" ""))
9062   (use (match_operand:SWI48 1 "register_operand" ""))
9063   (use (match_operand:QI 2 "register_operand" ""))]
9064  ""
9065{
9066  rtx label = gen_label_rtx ();
9067  rtx tmp;
9068
9069  emit_insn (gen_testqi_ccz_1 (operands[2],
9070			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9071
9072  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9073  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9074  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9075			      gen_rtx_LABEL_REF (VOIDmode, label),
9076			      pc_rtx);
9077  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9078  JUMP_LABEL (tmp) = label;
9079
9080  emit_move_insn (operands[0], operands[1]);
9081  ix86_expand_clear (operands[1]);
9082
9083  emit_label (label);
9084  LABEL_NUSES (label) = 1;
9085
9086  DONE;
9087})
9088
9089;; Avoid useless masking of count operand.
9090(define_insn "*ashl<mode>3_mask"
9091  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9092	(ashift:SWI48
9093	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
9094	  (subreg:QI
9095	    (and:SI
9096	      (match_operand:SI 2 "register_operand" "c")
9097	      (match_operand:SI 3 "const_int_operand" "n")) 0)))
9098   (clobber (reg:CC FLAGS_REG))]
9099  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9100   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9101      == GET_MODE_BITSIZE (<MODE>mode)-1"
9102{
9103  return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9104}
9105  [(set_attr "type" "ishift")
9106   (set_attr "mode" "<MODE>")])
9107
9108(define_insn "*bmi2_ashl<mode>3_1"
9109  [(set (match_operand:SWI48 0 "register_operand" "=r")
9110	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9111		      (match_operand:SWI48 2 "register_operand" "r")))]
9112  "TARGET_BMI2"
9113  "shlx\t{%2, %1, %0|%0, %1, %2}"
9114  [(set_attr "type" "ishiftx")
9115   (set_attr "mode" "<MODE>")])
9116
9117(define_insn "*ashl<mode>3_1"
9118  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9119	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9120		      (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9121   (clobber (reg:CC FLAGS_REG))]
9122  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9123{
9124  switch (get_attr_type (insn))
9125    {
9126    case TYPE_LEA:
9127    case TYPE_ISHIFTX:
9128      return "#";
9129
9130    case TYPE_ALU:
9131      gcc_assert (operands[2] == const1_rtx);
9132      gcc_assert (rtx_equal_p (operands[0], operands[1]));
9133      return "add{<imodesuffix>}\t%0, %0";
9134
9135    default:
9136      if (operands[2] == const1_rtx
9137	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9138	return "sal{<imodesuffix>}\t%0";
9139      else
9140	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9141    }
9142}
9143  [(set_attr "isa" "*,*,bmi2")
9144   (set (attr "type")
9145     (cond [(eq_attr "alternative" "1")
9146	      (const_string "lea")
9147	    (eq_attr "alternative" "2")
9148	      (const_string "ishiftx")
9149            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9150		      (match_operand 0 "register_operand" ""))
9151		 (match_operand 2 "const1_operand" ""))
9152	      (const_string "alu")
9153	   ]
9154	   (const_string "ishift")))
9155   (set (attr "length_immediate")
9156     (if_then_else
9157       (ior (eq_attr "type" "alu")
9158	    (and (eq_attr "type" "ishift")
9159		 (and (match_operand 2 "const1_operand" "")
9160		      (ior (match_test "TARGET_SHIFT1")
9161			   (match_test "optimize_function_for_size_p (cfun)")))))
9162       (const_string "0")
9163       (const_string "*")))
9164   (set_attr "mode" "<MODE>")])
9165
9166;; Convert shift to the shiftx pattern to avoid flags dependency.
9167(define_split
9168  [(set (match_operand:SWI48 0 "register_operand" "")
9169	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9170		      (match_operand:QI 2 "register_operand" "")))
9171   (clobber (reg:CC FLAGS_REG))]
9172  "TARGET_BMI2 && reload_completed"
9173  [(set (match_dup 0)
9174	(ashift:SWI48 (match_dup 1) (match_dup 2)))]
9175  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9176
9177(define_insn "*bmi2_ashlsi3_1_zext"
9178  [(set (match_operand:DI 0 "register_operand" "=r")
9179	(zero_extend:DI
9180	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9181		     (match_operand:SI 2 "register_operand" "r"))))]
9182  "TARGET_64BIT && TARGET_BMI2"
9183  "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9184  [(set_attr "type" "ishiftx")
9185   (set_attr "mode" "SI")])
9186
9187(define_insn "*ashlsi3_1_zext"
9188  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9189	(zero_extend:DI
9190	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9191		     (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9192   (clobber (reg:CC FLAGS_REG))]
9193  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9194{
9195  switch (get_attr_type (insn))
9196    {
9197    case TYPE_LEA:
9198    case TYPE_ISHIFTX:
9199      return "#";
9200
9201    case TYPE_ALU:
9202      gcc_assert (operands[2] == const1_rtx);
9203      return "add{l}\t%k0, %k0";
9204
9205    default:
9206      if (operands[2] == const1_rtx
9207	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9208	return "sal{l}\t%k0";
9209      else
9210	return "sal{l}\t{%2, %k0|%k0, %2}";
9211    }
9212}
9213  [(set_attr "isa" "*,*,bmi2")
9214   (set (attr "type")
9215     (cond [(eq_attr "alternative" "1")
9216	      (const_string "lea")
9217	    (eq_attr "alternative" "2")
9218	      (const_string "ishiftx")
9219            (and (match_test "TARGET_DOUBLE_WITH_ADD")
9220		 (match_operand 2 "const1_operand" ""))
9221	      (const_string "alu")
9222	   ]
9223	   (const_string "ishift")))
9224   (set (attr "length_immediate")
9225     (if_then_else
9226       (ior (eq_attr "type" "alu")
9227	    (and (eq_attr "type" "ishift")
9228		 (and (match_operand 2 "const1_operand" "")
9229		      (ior (match_test "TARGET_SHIFT1")
9230			   (match_test "optimize_function_for_size_p (cfun)")))))
9231       (const_string "0")
9232       (const_string "*")))
9233   (set_attr "mode" "SI")])
9234
9235;; Convert shift to the shiftx pattern to avoid flags dependency.
9236(define_split
9237  [(set (match_operand:DI 0 "register_operand" "")
9238	(zero_extend:DI
9239	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9240		     (match_operand:QI 2 "register_operand" ""))))
9241   (clobber (reg:CC FLAGS_REG))]
9242  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9243  [(set (match_dup 0)
9244	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9245  "operands[2] = gen_lowpart (SImode, operands[2]);")
9246
9247(define_insn "*ashlhi3_1"
9248  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9249	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9250		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9251   (clobber (reg:CC FLAGS_REG))]
9252  "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9253{
9254  switch (get_attr_type (insn))
9255    {
9256    case TYPE_LEA:
9257      return "#";
9258
9259    case TYPE_ALU:
9260      gcc_assert (operands[2] == const1_rtx);
9261      return "add{w}\t%0, %0";
9262
9263    default:
9264      if (operands[2] == const1_rtx
9265	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9266	return "sal{w}\t%0";
9267      else
9268	return "sal{w}\t{%2, %0|%0, %2}";
9269    }
9270}
9271  [(set (attr "type")
9272     (cond [(eq_attr "alternative" "1")
9273	      (const_string "lea")
9274            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9275		      (match_operand 0 "register_operand" ""))
9276		 (match_operand 2 "const1_operand" ""))
9277	      (const_string "alu")
9278	   ]
9279	   (const_string "ishift")))
9280   (set (attr "length_immediate")
9281     (if_then_else
9282       (ior (eq_attr "type" "alu")
9283	    (and (eq_attr "type" "ishift")
9284		 (and (match_operand 2 "const1_operand" "")
9285		      (ior (match_test "TARGET_SHIFT1")
9286			   (match_test "optimize_function_for_size_p (cfun)")))))
9287       (const_string "0")
9288       (const_string "*")))
9289   (set_attr "mode" "HI,SI")])
9290
9291;; %%% Potential partial reg stall on alternative 1.  What to do?
9292(define_insn "*ashlqi3_1"
9293  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9294	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9295		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9296   (clobber (reg:CC FLAGS_REG))]
9297  "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9298{
9299  switch (get_attr_type (insn))
9300    {
9301    case TYPE_LEA:
9302      return "#";
9303
9304    case TYPE_ALU:
9305      gcc_assert (operands[2] == const1_rtx);
9306      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9307        return "add{l}\t%k0, %k0";
9308      else
9309        return "add{b}\t%0, %0";
9310
9311    default:
9312      if (operands[2] == const1_rtx
9313	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9314	{
9315	  if (get_attr_mode (insn) == MODE_SI)
9316	    return "sal{l}\t%k0";
9317	  else
9318	    return "sal{b}\t%0";
9319	}
9320      else
9321	{
9322	  if (get_attr_mode (insn) == MODE_SI)
9323	    return "sal{l}\t{%2, %k0|%k0, %2}";
9324	  else
9325	    return "sal{b}\t{%2, %0|%0, %2}";
9326	}
9327    }
9328}
9329  [(set (attr "type")
9330     (cond [(eq_attr "alternative" "2")
9331	      (const_string "lea")
9332            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9333		      (match_operand 0 "register_operand" ""))
9334		 (match_operand 2 "const1_operand" ""))
9335	      (const_string "alu")
9336	   ]
9337	   (const_string "ishift")))
9338   (set (attr "length_immediate")
9339     (if_then_else
9340       (ior (eq_attr "type" "alu")
9341	    (and (eq_attr "type" "ishift")
9342		 (and (match_operand 2 "const1_operand" "")
9343		      (ior (match_test "TARGET_SHIFT1")
9344			   (match_test "optimize_function_for_size_p (cfun)")))))
9345       (const_string "0")
9346       (const_string "*")))
9347   (set_attr "mode" "QI,SI,SI")])
9348
9349(define_insn "*ashlqi3_1_slp"
9350  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9351	(ashift:QI (match_dup 0)
9352		   (match_operand:QI 1 "nonmemory_operand" "cI")))
9353   (clobber (reg:CC FLAGS_REG))]
9354  "(optimize_function_for_size_p (cfun)
9355    || !TARGET_PARTIAL_FLAG_REG_STALL
9356    || (operands[1] == const1_rtx
9357	&& (TARGET_SHIFT1
9358	    || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9359{
9360  switch (get_attr_type (insn))
9361    {
9362    case TYPE_ALU:
9363      gcc_assert (operands[1] == const1_rtx);
9364      return "add{b}\t%0, %0";
9365
9366    default:
9367      if (operands[1] == const1_rtx
9368	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9369	return "sal{b}\t%0";
9370      else
9371	return "sal{b}\t{%1, %0|%0, %1}";
9372    }
9373}
9374  [(set (attr "type")
9375     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9376		      (match_operand 0 "register_operand" ""))
9377		 (match_operand 1 "const1_operand" ""))
9378	      (const_string "alu")
9379	   ]
9380	   (const_string "ishift1")))
9381   (set (attr "length_immediate")
9382     (if_then_else
9383       (ior (eq_attr "type" "alu")
9384	    (and (eq_attr "type" "ishift1")
9385		 (and (match_operand 1 "const1_operand" "")
9386		      (ior (match_test "TARGET_SHIFT1")
9387			   (match_test "optimize_function_for_size_p (cfun)")))))
9388       (const_string "0")
9389       (const_string "*")))
9390   (set_attr "mode" "QI")])
9391
9392;; Convert ashift to the lea pattern to avoid flags dependency.
9393(define_split
9394  [(set (match_operand 0 "register_operand" "")
9395	(ashift (match_operand 1 "index_register_operand" "")
9396                (match_operand:QI 2 "const_int_operand" "")))
9397   (clobber (reg:CC FLAGS_REG))]
9398  "GET_MODE (operands[0]) == GET_MODE (operands[1])
9399   && reload_completed
9400   && true_regnum (operands[0]) != true_regnum (operands[1])"
9401  [(const_int 0)]
9402{
9403  enum machine_mode mode = GET_MODE (operands[0]);
9404  rtx pat;
9405
9406  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9407    {
9408      mode = SImode;
9409      operands[0] = gen_lowpart (mode, operands[0]);
9410      operands[1] = gen_lowpart (mode, operands[1]);
9411    }
9412
9413  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9414
9415  pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9416
9417  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9418  DONE;
9419})
9420
9421;; Convert ashift to the lea pattern to avoid flags dependency.
9422(define_split
9423  [(set (match_operand:DI 0 "register_operand" "")
9424	(zero_extend:DI
9425	  (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9426		     (match_operand:QI 2 "const_int_operand" ""))))
9427   (clobber (reg:CC FLAGS_REG))]
9428  "TARGET_64BIT && reload_completed
9429   && true_regnum (operands[0]) != true_regnum (operands[1])"
9430  [(set (match_dup 0)
9431	(zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9432{
9433  operands[1] = gen_lowpart (DImode, operands[1]);
9434  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9435})
9436
9437;; This pattern can't accept a variable shift count, since shifts by
9438;; zero don't affect the flags.  We assume that shifts by constant
9439;; zero are optimized away.
9440(define_insn "*ashl<mode>3_cmp"
9441  [(set (reg FLAGS_REG)
9442	(compare
9443	  (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9444		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9445	  (const_int 0)))
9446   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9447	(ashift:SWI (match_dup 1) (match_dup 2)))]
9448  "(optimize_function_for_size_p (cfun)
9449    || !TARGET_PARTIAL_FLAG_REG_STALL
9450    || (operands[2] == const1_rtx
9451	&& (TARGET_SHIFT1
9452	    || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9453   && ix86_match_ccmode (insn, CCGOCmode)
9454   && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9455{
9456  switch (get_attr_type (insn))
9457    {
9458    case TYPE_ALU:
9459      gcc_assert (operands[2] == const1_rtx);
9460      return "add{<imodesuffix>}\t%0, %0";
9461
9462    default:
9463      if (operands[2] == const1_rtx
9464	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465	return "sal{<imodesuffix>}\t%0";
9466      else
9467	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9468    }
9469}
9470  [(set (attr "type")
9471     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9472		      (match_operand 0 "register_operand" ""))
9473		 (match_operand 2 "const1_operand" ""))
9474	      (const_string "alu")
9475	   ]
9476	   (const_string "ishift")))
9477   (set (attr "length_immediate")
9478     (if_then_else
9479       (ior (eq_attr "type" "alu")
9480	    (and (eq_attr "type" "ishift")
9481		 (and (match_operand 2 "const1_operand" "")
9482		      (ior (match_test "TARGET_SHIFT1")
9483			   (match_test "optimize_function_for_size_p (cfun)")))))
9484       (const_string "0")
9485       (const_string "*")))
9486   (set_attr "mode" "<MODE>")])
9487
9488(define_insn "*ashlsi3_cmp_zext"
9489  [(set (reg FLAGS_REG)
9490	(compare
9491	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
9492		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
9493	  (const_int 0)))
9494   (set (match_operand:DI 0 "register_operand" "=r")
9495	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9496  "TARGET_64BIT
9497   && (optimize_function_for_size_p (cfun)
9498       || !TARGET_PARTIAL_FLAG_REG_STALL
9499       || (operands[2] == const1_rtx
9500	   && (TARGET_SHIFT1
9501	       || TARGET_DOUBLE_WITH_ADD)))
9502   && ix86_match_ccmode (insn, CCGOCmode)
9503   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9504{
9505  switch (get_attr_type (insn))
9506    {
9507    case TYPE_ALU:
9508      gcc_assert (operands[2] == const1_rtx);
9509      return "add{l}\t%k0, %k0";
9510
9511    default:
9512      if (operands[2] == const1_rtx
9513	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9514	return "sal{l}\t%k0";
9515      else
9516	return "sal{l}\t{%2, %k0|%k0, %2}";
9517    }
9518}
9519  [(set (attr "type")
9520     (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9521		 (match_operand 2 "const1_operand" ""))
9522	      (const_string "alu")
9523	   ]
9524	   (const_string "ishift")))
9525   (set (attr "length_immediate")
9526     (if_then_else
9527       (ior (eq_attr "type" "alu")
9528	    (and (eq_attr "type" "ishift")
9529		 (and (match_operand 2 "const1_operand" "")
9530		      (ior (match_test "TARGET_SHIFT1")
9531			   (match_test "optimize_function_for_size_p (cfun)")))))
9532       (const_string "0")
9533       (const_string "*")))
9534   (set_attr "mode" "SI")])
9535
9536(define_insn "*ashl<mode>3_cconly"
9537  [(set (reg FLAGS_REG)
9538	(compare
9539	  (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9540		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9541	  (const_int 0)))
9542   (clobber (match_scratch:SWI 0 "=<r>"))]
9543  "(optimize_function_for_size_p (cfun)
9544    || !TARGET_PARTIAL_FLAG_REG_STALL
9545    || (operands[2] == const1_rtx
9546	&& (TARGET_SHIFT1
9547	    || TARGET_DOUBLE_WITH_ADD)))
9548   && ix86_match_ccmode (insn, CCGOCmode)"
9549{
9550  switch (get_attr_type (insn))
9551    {
9552    case TYPE_ALU:
9553      gcc_assert (operands[2] == const1_rtx);
9554      return "add{<imodesuffix>}\t%0, %0";
9555
9556    default:
9557      if (operands[2] == const1_rtx
9558	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9559	return "sal{<imodesuffix>}\t%0";
9560      else
9561	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9562    }
9563}
9564  [(set (attr "type")
9565     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9566		      (match_operand 0 "register_operand" ""))
9567		 (match_operand 2 "const1_operand" ""))
9568	      (const_string "alu")
9569	   ]
9570	   (const_string "ishift")))
9571   (set (attr "length_immediate")
9572     (if_then_else
9573       (ior (eq_attr "type" "alu")
9574	    (and (eq_attr "type" "ishift")
9575		 (and (match_operand 2 "const1_operand" "")
9576		      (ior (match_test "TARGET_SHIFT1")
9577			   (match_test "optimize_function_for_size_p (cfun)")))))
9578       (const_string "0")
9579       (const_string "*")))
9580   (set_attr "mode" "<MODE>")])
9581
9582;; See comment above `ashl<mode>3' about how this works.
9583
9584(define_expand "<shift_insn><mode>3"
9585  [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9586	(any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9587			   (match_operand:QI 2 "nonmemory_operand" "")))]
9588  ""
9589  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9590
9591;; Avoid useless masking of count operand.
9592(define_insn "*<shift_insn><mode>3_mask"
9593  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9594	(any_shiftrt:SWI48
9595	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
9596	  (subreg:QI
9597	    (and:SI
9598	      (match_operand:SI 2 "register_operand" "c")
9599	      (match_operand:SI 3 "const_int_operand" "n")) 0)))
9600   (clobber (reg:CC FLAGS_REG))]
9601  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9602   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9603      == GET_MODE_BITSIZE (<MODE>mode)-1"
9604{
9605  return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9606}
9607  [(set_attr "type" "ishift")
9608   (set_attr "mode" "<MODE>")])
9609
9610(define_insn_and_split "*<shift_insn><mode>3_doubleword"
9611  [(set (match_operand:DWI 0 "register_operand" "=r")
9612	(any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9613			 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9614   (clobber (reg:CC FLAGS_REG))]
9615  ""
9616  "#"
9617  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9618  [(const_int 0)]
9619  "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9620  [(set_attr "type" "multi")])
9621
9622;; By default we don't ask for a scratch register, because when DWImode
9623;; values are manipulated, registers are already at a premium.  But if
9624;; we have one handy, we won't turn it away.
9625
9626(define_peephole2
9627  [(match_scratch:DWIH 3 "r")
9628   (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9629		   (any_shiftrt:<DWI>
9630		     (match_operand:<DWI> 1 "register_operand" "")
9631		     (match_operand:QI 2 "nonmemory_operand" "")))
9632	      (clobber (reg:CC FLAGS_REG))])
9633   (match_dup 3)]
9634  "TARGET_CMOVE"
9635  [(const_int 0)]
9636  "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9637
9638(define_insn "x86_64_shrd"
9639  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9640        (ior:DI (ashiftrt:DI (match_dup 0)
9641		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
9642		(ashift:DI (match_operand:DI 1 "register_operand" "r")
9643		  (minus:QI (const_int 64) (match_dup 2)))))
9644   (clobber (reg:CC FLAGS_REG))]
9645  "TARGET_64BIT"
9646  "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9647  [(set_attr "type" "ishift")
9648   (set_attr "prefix_0f" "1")
9649   (set_attr "mode" "DI")
9650   (set_attr "athlon_decode" "vector")
9651   (set_attr "amdfam10_decode" "vector")
9652   (set_attr "bdver1_decode" "vector")])
9653
9654(define_insn "x86_shrd"
9655  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9656        (ior:SI (ashiftrt:SI (match_dup 0)
9657		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
9658		(ashift:SI (match_operand:SI 1 "register_operand" "r")
9659		  (minus:QI (const_int 32) (match_dup 2)))))
9660   (clobber (reg:CC FLAGS_REG))]
9661  ""
9662  "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9663  [(set_attr "type" "ishift")
9664   (set_attr "prefix_0f" "1")
9665   (set_attr "mode" "SI")
9666   (set_attr "pent_pair" "np")
9667   (set_attr "athlon_decode" "vector")
9668   (set_attr "amdfam10_decode" "vector")
9669   (set_attr "bdver1_decode" "vector")])
9670
9671(define_insn "ashrdi3_cvt"
9672  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9673	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9674		     (match_operand:QI 2 "const_int_operand" "")))
9675   (clobber (reg:CC FLAGS_REG))]
9676  "TARGET_64BIT && INTVAL (operands[2]) == 63
9677   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9678   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9679  "@
9680   {cqto|cqo}
9681   sar{q}\t{%2, %0|%0, %2}"
9682  [(set_attr "type" "imovx,ishift")
9683   (set_attr "prefix_0f" "0,*")
9684   (set_attr "length_immediate" "0,*")
9685   (set_attr "modrm" "0,1")
9686   (set_attr "mode" "DI")])
9687
9688(define_insn "ashrsi3_cvt"
9689  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9690	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9691		     (match_operand:QI 2 "const_int_operand" "")))
9692   (clobber (reg:CC FLAGS_REG))]
9693  "INTVAL (operands[2]) == 31
9694   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9695   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9696  "@
9697   {cltd|cdq}
9698   sar{l}\t{%2, %0|%0, %2}"
9699  [(set_attr "type" "imovx,ishift")
9700   (set_attr "prefix_0f" "0,*")
9701   (set_attr "length_immediate" "0,*")
9702   (set_attr "modrm" "0,1")
9703   (set_attr "mode" "SI")])
9704
9705(define_insn "*ashrsi3_cvt_zext"
9706  [(set (match_operand:DI 0 "register_operand" "=*d,r")
9707	(zero_extend:DI
9708	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9709		       (match_operand:QI 2 "const_int_operand" ""))))
9710   (clobber (reg:CC FLAGS_REG))]
9711  "TARGET_64BIT && INTVAL (operands[2]) == 31
9712   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9713   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9714  "@
9715   {cltd|cdq}
9716   sar{l}\t{%2, %k0|%k0, %2}"
9717  [(set_attr "type" "imovx,ishift")
9718   (set_attr "prefix_0f" "0,*")
9719   (set_attr "length_immediate" "0,*")
9720   (set_attr "modrm" "0,1")
9721   (set_attr "mode" "SI")])
9722
9723(define_expand "x86_shift<mode>_adj_3"
9724  [(use (match_operand:SWI48 0 "register_operand" ""))
9725   (use (match_operand:SWI48 1 "register_operand" ""))
9726   (use (match_operand:QI 2 "register_operand" ""))]
9727  ""
9728{
9729  rtx label = gen_label_rtx ();
9730  rtx tmp;
9731
9732  emit_insn (gen_testqi_ccz_1 (operands[2],
9733			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9734
9735  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9736  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9737  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9738			      gen_rtx_LABEL_REF (VOIDmode, label),
9739			      pc_rtx);
9740  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9741  JUMP_LABEL (tmp) = label;
9742
9743  emit_move_insn (operands[0], operands[1]);
9744  emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9745				  GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9746  emit_label (label);
9747  LABEL_NUSES (label) = 1;
9748
9749  DONE;
9750})
9751
9752(define_insn "*bmi2_<shift_insn><mode>3_1"
9753  [(set (match_operand:SWI48 0 "register_operand" "=r")
9754	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9755			   (match_operand:SWI48 2 "register_operand" "r")))]
9756  "TARGET_BMI2"
9757  "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9758  [(set_attr "type" "ishiftx")
9759   (set_attr "mode" "<MODE>")])
9760
9761(define_insn "*<shift_insn><mode>3_1"
9762  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9763	(any_shiftrt:SWI48
9764	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9765	  (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9766   (clobber (reg:CC FLAGS_REG))]
9767  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9768{
9769  switch (get_attr_type (insn))
9770    {
9771    case TYPE_ISHIFTX:
9772      return "#";
9773
9774    default:
9775      if (operands[2] == const1_rtx
9776	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9777	return "<shift>{<imodesuffix>}\t%0";
9778      else
9779	return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9780    }
9781}
9782  [(set_attr "isa" "*,bmi2")
9783   (set_attr "type" "ishift,ishiftx")
9784   (set (attr "length_immediate")
9785     (if_then_else
9786       (and (match_operand 2 "const1_operand" "")
9787	    (ior (match_test "TARGET_SHIFT1")
9788		 (match_test "optimize_function_for_size_p (cfun)")))
9789       (const_string "0")
9790       (const_string "*")))
9791   (set_attr "mode" "<MODE>")])
9792
9793;; Convert shift to the shiftx pattern to avoid flags dependency.
9794(define_split
9795  [(set (match_operand:SWI48 0 "register_operand" "")
9796	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9797			   (match_operand:QI 2 "register_operand" "")))
9798   (clobber (reg:CC FLAGS_REG))]
9799  "TARGET_BMI2 && reload_completed"
9800  [(set (match_dup 0)
9801	(any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9802  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9803
9804(define_insn "*bmi2_<shift_insn>si3_1_zext"
9805  [(set (match_operand:DI 0 "register_operand" "=r")
9806	(zero_extend:DI
9807	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9808			  (match_operand:SI 2 "register_operand" "r"))))]
9809  "TARGET_64BIT && TARGET_BMI2"
9810  "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9811  [(set_attr "type" "ishiftx")
9812   (set_attr "mode" "SI")])
9813
9814(define_insn "*<shift_insn>si3_1_zext"
9815  [(set (match_operand:DI 0 "register_operand" "=r,r")
9816	(zero_extend:DI
9817	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9818			  (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9819   (clobber (reg:CC FLAGS_REG))]
9820  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9821{
9822  switch (get_attr_type (insn))
9823    {
9824    case TYPE_ISHIFTX:
9825      return "#";
9826
9827    default:
9828      if (operands[2] == const1_rtx
9829	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9830	return "<shift>{l}\t%k0";
9831      else
9832	return "<shift>{l}\t{%2, %k0|%k0, %2}";
9833    }
9834}
9835  [(set_attr "isa" "*,bmi2")
9836   (set_attr "type" "ishift,ishiftx")
9837   (set (attr "length_immediate")
9838     (if_then_else
9839       (and (match_operand 2 "const1_operand" "")
9840	    (ior (match_test "TARGET_SHIFT1")
9841		 (match_test "optimize_function_for_size_p (cfun)")))
9842       (const_string "0")
9843       (const_string "*")))
9844   (set_attr "mode" "SI")])
9845
9846;; Convert shift to the shiftx pattern to avoid flags dependency.
9847(define_split
9848  [(set (match_operand:DI 0 "register_operand" "")
9849	(zero_extend:DI
9850	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9851			  (match_operand:QI 2 "register_operand" ""))))
9852   (clobber (reg:CC FLAGS_REG))]
9853  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9854  [(set (match_dup 0)
9855	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9856  "operands[2] = gen_lowpart (SImode, operands[2]);")
9857
9858(define_insn "*<shift_insn><mode>3_1"
9859  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9860	(any_shiftrt:SWI12
9861	  (match_operand:SWI12 1 "nonimmediate_operand" "0")
9862	  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9863   (clobber (reg:CC FLAGS_REG))]
9864  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9865{
9866  if (operands[2] == const1_rtx
9867      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9868    return "<shift>{<imodesuffix>}\t%0";
9869  else
9870    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9871}
9872  [(set_attr "type" "ishift")
9873   (set (attr "length_immediate")
9874     (if_then_else
9875       (and (match_operand 2 "const1_operand" "")
9876	    (ior (match_test "TARGET_SHIFT1")
9877		 (match_test "optimize_function_for_size_p (cfun)")))
9878       (const_string "0")
9879       (const_string "*")))
9880   (set_attr "mode" "<MODE>")])
9881
9882(define_insn "*<shift_insn>qi3_1_slp"
9883  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9884	(any_shiftrt:QI (match_dup 0)
9885			(match_operand:QI 1 "nonmemory_operand" "cI")))
9886   (clobber (reg:CC FLAGS_REG))]
9887  "(optimize_function_for_size_p (cfun)
9888    || !TARGET_PARTIAL_REG_STALL
9889    || (operands[1] == const1_rtx
9890	&& TARGET_SHIFT1))"
9891{
9892  if (operands[1] == const1_rtx
9893      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9894    return "<shift>{b}\t%0";
9895  else
9896    return "<shift>{b}\t{%1, %0|%0, %1}";
9897}
9898  [(set_attr "type" "ishift1")
9899   (set (attr "length_immediate")
9900     (if_then_else
9901       (and (match_operand 1 "const1_operand" "")
9902	    (ior (match_test "TARGET_SHIFT1")
9903		 (match_test "optimize_function_for_size_p (cfun)")))
9904       (const_string "0")
9905       (const_string "*")))
9906   (set_attr "mode" "QI")])
9907
9908;; This pattern can't accept a variable shift count, since shifts by
9909;; zero don't affect the flags.  We assume that shifts by constant
9910;; zero are optimized away.
9911(define_insn "*<shift_insn><mode>3_cmp"
9912  [(set (reg FLAGS_REG)
9913	(compare
9914	  (any_shiftrt:SWI
9915	    (match_operand:SWI 1 "nonimmediate_operand" "0")
9916	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9917	  (const_int 0)))
9918   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9919	(any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9920  "(optimize_function_for_size_p (cfun)
9921    || !TARGET_PARTIAL_FLAG_REG_STALL
9922    || (operands[2] == const1_rtx
9923	&& TARGET_SHIFT1))
9924   && ix86_match_ccmode (insn, CCGOCmode)
9925   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9926{
9927  if (operands[2] == const1_rtx
9928      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9929    return "<shift>{<imodesuffix>}\t%0";
9930  else
9931    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9932}
9933  [(set_attr "type" "ishift")
9934   (set (attr "length_immediate")
9935     (if_then_else
9936       (and (match_operand 2 "const1_operand" "")
9937	    (ior (match_test "TARGET_SHIFT1")
9938		 (match_test "optimize_function_for_size_p (cfun)")))
9939       (const_string "0")
9940       (const_string "*")))
9941   (set_attr "mode" "<MODE>")])
9942
9943(define_insn "*<shift_insn>si3_cmp_zext"
9944  [(set (reg FLAGS_REG)
9945	(compare
9946	  (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9947			  (match_operand:QI 2 "const_1_to_31_operand" "I"))
9948	  (const_int 0)))
9949   (set (match_operand:DI 0 "register_operand" "=r")
9950	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9951  "TARGET_64BIT
9952   && (optimize_function_for_size_p (cfun)
9953       || !TARGET_PARTIAL_FLAG_REG_STALL
9954       || (operands[2] == const1_rtx
9955	   && TARGET_SHIFT1))
9956   && ix86_match_ccmode (insn, CCGOCmode)
9957   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9958{
9959  if (operands[2] == const1_rtx
9960      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9961    return "<shift>{l}\t%k0";
9962  else
9963    return "<shift>{l}\t{%2, %k0|%k0, %2}";
9964}
9965  [(set_attr "type" "ishift")
9966   (set (attr "length_immediate")
9967     (if_then_else
9968       (and (match_operand 2 "const1_operand" "")
9969	    (ior (match_test "TARGET_SHIFT1")
9970		 (match_test "optimize_function_for_size_p (cfun)")))
9971       (const_string "0")
9972       (const_string "*")))
9973   (set_attr "mode" "SI")])
9974
9975(define_insn "*<shift_insn><mode>3_cconly"
9976  [(set (reg FLAGS_REG)
9977	(compare
9978	  (any_shiftrt:SWI
9979	    (match_operand:SWI 1 "register_operand" "0")
9980	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9981	  (const_int 0)))
9982   (clobber (match_scratch:SWI 0 "=<r>"))]
9983  "(optimize_function_for_size_p (cfun)
9984    || !TARGET_PARTIAL_FLAG_REG_STALL
9985    || (operands[2] == const1_rtx
9986	&& TARGET_SHIFT1))
9987   && ix86_match_ccmode (insn, CCGOCmode)"
9988{
9989  if (operands[2] == const1_rtx
9990      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9991    return "<shift>{<imodesuffix>}\t%0";
9992  else
9993    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9994}
9995  [(set_attr "type" "ishift")
9996   (set (attr "length_immediate")
9997     (if_then_else
9998       (and (match_operand 2 "const1_operand" "")
9999	    (ior (match_test "TARGET_SHIFT1")
10000		 (match_test "optimize_function_for_size_p (cfun)")))
10001       (const_string "0")
10002       (const_string "*")))
10003   (set_attr "mode" "<MODE>")])
10004
10005;; Rotate instructions
10006
10007(define_expand "<rotate_insn>ti3"
10008  [(set (match_operand:TI 0 "register_operand" "")
10009	(any_rotate:TI (match_operand:TI 1 "register_operand" "")
10010		       (match_operand:QI 2 "nonmemory_operand" "")))]
10011  "TARGET_64BIT"
10012{
10013  if (const_1_to_63_operand (operands[2], VOIDmode))
10014    emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10015		(operands[0], operands[1], operands[2]));
10016  else
10017    FAIL;
10018
10019  DONE;
10020})
10021
10022(define_expand "<rotate_insn>di3"
10023  [(set (match_operand:DI 0 "shiftdi_operand" "")
10024	(any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10025		       (match_operand:QI 2 "nonmemory_operand" "")))]
10026 ""
10027{
10028  if (TARGET_64BIT)
10029    ix86_expand_binary_operator (<CODE>, DImode, operands);
10030  else if (const_1_to_31_operand (operands[2], VOIDmode))
10031    emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10032		(operands[0], operands[1], operands[2]));
10033  else
10034    FAIL;
10035
10036  DONE;
10037})
10038
10039(define_expand "<rotate_insn><mode>3"
10040  [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10041	(any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10042			    (match_operand:QI 2 "nonmemory_operand" "")))]
10043  ""
10044  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10045
10046;; Avoid useless masking of count operand.
10047(define_insn "*<rotate_insn><mode>3_mask"
10048  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10049	(any_rotate:SWI48
10050	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
10051	  (subreg:QI
10052	    (and:SI
10053	      (match_operand:SI 2 "register_operand" "c")
10054	      (match_operand:SI 3 "const_int_operand" "n")) 0)))
10055   (clobber (reg:CC FLAGS_REG))]
10056  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10057   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10058      == GET_MODE_BITSIZE (<MODE>mode)-1"
10059{
10060  return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10061}
10062  [(set_attr "type" "rotate")
10063   (set_attr "mode" "<MODE>")])
10064
10065;; Implement rotation using two double-precision
10066;; shift instructions and a scratch register.
10067
10068(define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10069 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10070       (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10071		     (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10072  (clobber (reg:CC FLAGS_REG))
10073  (clobber (match_scratch:DWIH 3 "=&r"))]
10074 ""
10075 "#"
10076 "reload_completed"
10077 [(set (match_dup 3) (match_dup 4))
10078  (parallel
10079   [(set (match_dup 4)
10080	 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10081		   (lshiftrt:DWIH (match_dup 5)
10082				  (minus:QI (match_dup 6) (match_dup 2)))))
10083    (clobber (reg:CC FLAGS_REG))])
10084  (parallel
10085   [(set (match_dup 5)
10086	 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10087		   (lshiftrt:DWIH (match_dup 3)
10088				  (minus:QI (match_dup 6) (match_dup 2)))))
10089    (clobber (reg:CC FLAGS_REG))])]
10090{
10091  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10092
10093  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10094})
10095
10096(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10097 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10098       (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10099		       (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10100  (clobber (reg:CC FLAGS_REG))
10101  (clobber (match_scratch:DWIH 3 "=&r"))]
10102 ""
10103 "#"
10104 "reload_completed"
10105 [(set (match_dup 3) (match_dup 4))
10106  (parallel
10107   [(set (match_dup 4)
10108	 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10109		   (ashift:DWIH (match_dup 5)
10110				(minus:QI (match_dup 6) (match_dup 2)))))
10111    (clobber (reg:CC FLAGS_REG))])
10112  (parallel
10113   [(set (match_dup 5)
10114	 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10115		   (ashift:DWIH (match_dup 3)
10116				(minus:QI (match_dup 6) (match_dup 2)))))
10117    (clobber (reg:CC FLAGS_REG))])]
10118{
10119  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10120
10121  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10122})
10123
10124(define_insn "*bmi2_rorx<mode>3_1"
10125  [(set (match_operand:SWI48 0 "register_operand" "=r")
10126	(rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10127			(match_operand:QI 2 "immediate_operand" "<S>")))]
10128  "TARGET_BMI2"
10129  "rorx\t{%2, %1, %0|%0, %1, %2}"
10130  [(set_attr "type" "rotatex")
10131   (set_attr "mode" "<MODE>")])
10132
10133(define_insn "*<rotate_insn><mode>3_1"
10134  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10135	(any_rotate:SWI48
10136	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10137	  (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10138   (clobber (reg:CC FLAGS_REG))]
10139  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10140{
10141  switch (get_attr_type (insn))
10142    {
10143    case TYPE_ROTATEX:
10144      return "#";
10145
10146    default:
10147      if (operands[2] == const1_rtx
10148	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10149	return "<rotate>{<imodesuffix>}\t%0";
10150      else
10151	return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10152    }
10153}
10154  [(set_attr "isa" "*,bmi2")
10155   (set_attr "type" "rotate,rotatex")
10156   (set (attr "length_immediate")
10157     (if_then_else
10158       (and (eq_attr "type" "rotate")
10159	    (and (match_operand 2 "const1_operand" "")
10160		 (ior (match_test "TARGET_SHIFT1")
10161		      (match_test "optimize_function_for_size_p (cfun)"))))
10162       (const_string "0")
10163       (const_string "*")))
10164   (set_attr "mode" "<MODE>")])
10165
10166;; Convert rotate to the rotatex pattern to avoid flags dependency.
10167(define_split
10168  [(set (match_operand:SWI48 0 "register_operand" "")
10169	(rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10170		      (match_operand:QI 2 "immediate_operand" "")))
10171   (clobber (reg:CC FLAGS_REG))]
10172  "TARGET_BMI2 && reload_completed"
10173  [(set (match_dup 0)
10174	(rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10175{
10176  operands[2]
10177    = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10178})
10179
10180(define_split
10181  [(set (match_operand:SWI48 0 "register_operand" "")
10182	(rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10183			(match_operand:QI 2 "immediate_operand" "")))
10184   (clobber (reg:CC FLAGS_REG))]
10185  "TARGET_BMI2 && reload_completed"
10186  [(set (match_dup 0)
10187	(rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10188
10189(define_insn "*bmi2_rorxsi3_1_zext"
10190  [(set (match_operand:DI 0 "register_operand" "=r")
10191	(zero_extend:DI
10192	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10193		       (match_operand:QI 2 "immediate_operand" "I"))))]
10194  "TARGET_64BIT && TARGET_BMI2"
10195  "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10196  [(set_attr "type" "rotatex")
10197   (set_attr "mode" "SI")])
10198
10199(define_insn "*<rotate_insn>si3_1_zext"
10200  [(set (match_operand:DI 0 "register_operand" "=r,r")
10201	(zero_extend:DI
10202	  (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10203			 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10204   (clobber (reg:CC FLAGS_REG))]
10205  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10206{
10207  switch (get_attr_type (insn))
10208    {
10209    case TYPE_ROTATEX:
10210      return "#";
10211
10212    default:
10213      if (operands[2] == const1_rtx
10214	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10215	return "<rotate>{l}\t%k0";
10216      else
10217	return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10218    }
10219}
10220  [(set_attr "isa" "*,bmi2")
10221   (set_attr "type" "rotate,rotatex")
10222   (set (attr "length_immediate")
10223     (if_then_else
10224       (and (eq_attr "type" "rotate")
10225	    (and (match_operand 2 "const1_operand" "")
10226		 (ior (match_test "TARGET_SHIFT1")
10227		      (match_test "optimize_function_for_size_p (cfun)"))))
10228       (const_string "0")
10229       (const_string "*")))
10230   (set_attr "mode" "SI")])
10231
10232;; Convert rotate to the rotatex pattern to avoid flags dependency.
10233(define_split
10234  [(set (match_operand:DI 0 "register_operand" "")
10235	(zero_extend:DI
10236	  (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10237		     (match_operand:QI 2 "immediate_operand" ""))))
10238   (clobber (reg:CC FLAGS_REG))]
10239  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10240  [(set (match_dup 0)
10241	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10242{
10243  operands[2]
10244    = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10245})
10246
10247(define_split
10248  [(set (match_operand:DI 0 "register_operand" "")
10249	(zero_extend:DI
10250	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10251		       (match_operand:QI 2 "immediate_operand" ""))))
10252   (clobber (reg:CC FLAGS_REG))]
10253  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10254  [(set (match_dup 0)
10255	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10256
10257(define_insn "*<rotate_insn><mode>3_1"
10258  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10259	(any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10260			  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10261   (clobber (reg:CC FLAGS_REG))]
10262  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10263{
10264  if (operands[2] == const1_rtx
10265      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10266    return "<rotate>{<imodesuffix>}\t%0";
10267  else
10268    return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10269}
10270  [(set_attr "type" "rotate")
10271   (set (attr "length_immediate")
10272     (if_then_else
10273       (and (match_operand 2 "const1_operand" "")
10274	    (ior (match_test "TARGET_SHIFT1")
10275		 (match_test "optimize_function_for_size_p (cfun)")))
10276       (const_string "0")
10277       (const_string "*")))
10278   (set_attr "mode" "<MODE>")])
10279
10280(define_insn "*<rotate_insn>qi3_1_slp"
10281  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10282	(any_rotate:QI (match_dup 0)
10283		       (match_operand:QI 1 "nonmemory_operand" "cI")))
10284   (clobber (reg:CC FLAGS_REG))]
10285  "(optimize_function_for_size_p (cfun)
10286    || !TARGET_PARTIAL_REG_STALL
10287    || (operands[1] == const1_rtx
10288	&& TARGET_SHIFT1))"
10289{
10290  if (operands[1] == const1_rtx
10291      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10292    return "<rotate>{b}\t%0";
10293  else
10294    return "<rotate>{b}\t{%1, %0|%0, %1}";
10295}
10296  [(set_attr "type" "rotate1")
10297   (set (attr "length_immediate")
10298     (if_then_else
10299       (and (match_operand 1 "const1_operand" "")
10300	    (ior (match_test "TARGET_SHIFT1")
10301		 (match_test "optimize_function_for_size_p (cfun)")))
10302       (const_string "0")
10303       (const_string "*")))
10304   (set_attr "mode" "QI")])
10305
10306(define_split
10307 [(set (match_operand:HI 0 "register_operand" "")
10308       (any_rotate:HI (match_dup 0) (const_int 8)))
10309  (clobber (reg:CC FLAGS_REG))]
10310 "reload_completed
10311  && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10312 [(parallel [(set (strict_low_part (match_dup 0))
10313		  (bswap:HI (match_dup 0)))
10314	     (clobber (reg:CC FLAGS_REG))])])
10315
10316;; Bit set / bit test instructions
10317
10318(define_expand "extv"
10319  [(set (match_operand:SI 0 "register_operand" "")
10320	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
10321			 (match_operand:SI 2 "const8_operand" "")
10322			 (match_operand:SI 3 "const8_operand" "")))]
10323  ""
10324{
10325  /* Handle extractions from %ah et al.  */
10326  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10327    FAIL;
10328
10329  /* From mips.md: extract_bit_field doesn't verify that our source
10330     matches the predicate, so check it again here.  */
10331  if (! ext_register_operand (operands[1], VOIDmode))
10332    FAIL;
10333})
10334
10335(define_expand "extzv"
10336  [(set (match_operand:SI 0 "register_operand" "")
10337	(zero_extract:SI (match_operand 1 "ext_register_operand" "")
10338			 (match_operand:SI 2 "const8_operand" "")
10339			 (match_operand:SI 3 "const8_operand" "")))]
10340  ""
10341{
10342  /* Handle extractions from %ah et al.  */
10343  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10344    FAIL;
10345
10346  /* From mips.md: extract_bit_field doesn't verify that our source
10347     matches the predicate, so check it again here.  */
10348  if (! ext_register_operand (operands[1], VOIDmode))
10349    FAIL;
10350})
10351
10352(define_expand "insv"
10353  [(set (zero_extract (match_operand 0 "register_operand" "")
10354		      (match_operand 1 "const_int_operand" "")
10355		      (match_operand 2 "const_int_operand" ""))
10356        (match_operand 3 "register_operand" ""))]
10357  ""
10358{
10359  rtx (*gen_mov_insv_1) (rtx, rtx);
10360
10361  if (ix86_expand_pinsr (operands))
10362    DONE;
10363
10364  /* Handle insertions to %ah et al.  */
10365  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10366    FAIL;
10367
10368  /* From mips.md: insert_bit_field doesn't verify that our source
10369     matches the predicate, so check it again here.  */
10370  if (! ext_register_operand (operands[0], VOIDmode))
10371    FAIL;
10372
10373  gen_mov_insv_1 = (TARGET_64BIT
10374		    ? gen_movdi_insv_1 : gen_movsi_insv_1);
10375
10376  emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10377  DONE;
10378})
10379
10380;; %%% bts, btr, btc, bt.
10381;; In general these instructions are *slow* when applied to memory,
10382;; since they enforce atomic operation.  When applied to registers,
10383;; it depends on the cpu implementation.  They're never faster than
10384;; the corresponding and/ior/xor operations, so with 32-bit there's
10385;; no point.  But in 64-bit, we can't hold the relevant immediates
10386;; within the instruction itself, so operating on bits in the high
10387;; 32-bits of a register becomes easier.
10388;;
10389;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10390;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10391;; negdf respectively, so they can never be disabled entirely.
10392
10393(define_insn "*btsq"
10394  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10395			 (const_int 1)
10396			 (match_operand:DI 1 "const_0_to_63_operand" ""))
10397	(const_int 1))
10398   (clobber (reg:CC FLAGS_REG))]
10399  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10400  "bts{q}\t{%1, %0|%0, %1}"
10401  [(set_attr "type" "alu1")
10402   (set_attr "prefix_0f" "1")
10403   (set_attr "mode" "DI")])
10404
10405(define_insn "*btrq"
10406  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10407			 (const_int 1)
10408			 (match_operand:DI 1 "const_0_to_63_operand" ""))
10409	(const_int 0))
10410   (clobber (reg:CC FLAGS_REG))]
10411  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10412  "btr{q}\t{%1, %0|%0, %1}"
10413  [(set_attr "type" "alu1")
10414   (set_attr "prefix_0f" "1")
10415   (set_attr "mode" "DI")])
10416
10417(define_insn "*btcq"
10418  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10419			 (const_int 1)
10420			 (match_operand:DI 1 "const_0_to_63_operand" ""))
10421	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10422   (clobber (reg:CC FLAGS_REG))]
10423  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10424  "btc{q}\t{%1, %0|%0, %1}"
10425  [(set_attr "type" "alu1")
10426   (set_attr "prefix_0f" "1")
10427   (set_attr "mode" "DI")])
10428
10429;; Allow Nocona to avoid these instructions if a register is available.
10430
10431(define_peephole2
10432  [(match_scratch:DI 2 "r")
10433   (parallel [(set (zero_extract:DI
10434		     (match_operand:DI 0 "register_operand" "")
10435		     (const_int 1)
10436		     (match_operand:DI 1 "const_0_to_63_operand" ""))
10437		   (const_int 1))
10438	      (clobber (reg:CC FLAGS_REG))])]
10439  "TARGET_64BIT && !TARGET_USE_BT"
10440  [(const_int 0)]
10441{
10442  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10443  rtx op1;
10444
10445  if (HOST_BITS_PER_WIDE_INT >= 64)
10446    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10447  else if (i < HOST_BITS_PER_WIDE_INT)
10448    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10449  else
10450    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10451
10452  op1 = immed_double_const (lo, hi, DImode);
10453  if (i >= 31)
10454    {
10455      emit_move_insn (operands[2], op1);
10456      op1 = operands[2];
10457    }
10458
10459  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10460  DONE;
10461})
10462
10463(define_peephole2
10464  [(match_scratch:DI 2 "r")
10465   (parallel [(set (zero_extract:DI
10466		     (match_operand:DI 0 "register_operand" "")
10467		     (const_int 1)
10468		     (match_operand:DI 1 "const_0_to_63_operand" ""))
10469		   (const_int 0))
10470	      (clobber (reg:CC FLAGS_REG))])]
10471  "TARGET_64BIT && !TARGET_USE_BT"
10472  [(const_int 0)]
10473{
10474  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10475  rtx op1;
10476
10477  if (HOST_BITS_PER_WIDE_INT >= 64)
10478    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479  else if (i < HOST_BITS_PER_WIDE_INT)
10480    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10481  else
10482    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10483
10484  op1 = immed_double_const (~lo, ~hi, DImode);
10485  if (i >= 32)
10486    {
10487      emit_move_insn (operands[2], op1);
10488      op1 = operands[2];
10489    }
10490
10491  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10492  DONE;
10493})
10494
10495(define_peephole2
10496  [(match_scratch:DI 2 "r")
10497   (parallel [(set (zero_extract:DI
10498		     (match_operand:DI 0 "register_operand" "")
10499		     (const_int 1)
10500		     (match_operand:DI 1 "const_0_to_63_operand" ""))
10501	      (not:DI (zero_extract:DI
10502			(match_dup 0) (const_int 1) (match_dup 1))))
10503	      (clobber (reg:CC FLAGS_REG))])]
10504  "TARGET_64BIT && !TARGET_USE_BT"
10505  [(const_int 0)]
10506{
10507  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10508  rtx op1;
10509
10510  if (HOST_BITS_PER_WIDE_INT >= 64)
10511    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10512  else if (i < HOST_BITS_PER_WIDE_INT)
10513    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10514  else
10515    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10516
10517  op1 = immed_double_const (lo, hi, DImode);
10518  if (i >= 31)
10519    {
10520      emit_move_insn (operands[2], op1);
10521      op1 = operands[2];
10522    }
10523
10524  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10525  DONE;
10526})
10527
10528(define_insn "*bt<mode>"
10529  [(set (reg:CCC FLAGS_REG)
10530	(compare:CCC
10531	  (zero_extract:SWI48
10532	    (match_operand:SWI48 0 "register_operand" "r")
10533	    (const_int 1)
10534	    (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10535	  (const_int 0)))]
10536  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10537  "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10538  [(set_attr "type" "alu1")
10539   (set_attr "prefix_0f" "1")
10540   (set_attr "mode" "<MODE>")])
10541
10542;; Store-flag instructions.
10543
10544;; For all sCOND expanders, also expand the compare or test insn that
10545;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10546
10547(define_insn_and_split "*setcc_di_1"
10548  [(set (match_operand:DI 0 "register_operand" "=q")
10549	(match_operator:DI 1 "ix86_comparison_operator"
10550	  [(reg FLAGS_REG) (const_int 0)]))]
10551  "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10552  "#"
10553  "&& reload_completed"
10554  [(set (match_dup 2) (match_dup 1))
10555   (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10556{
10557  PUT_MODE (operands[1], QImode);
10558  operands[2] = gen_lowpart (QImode, operands[0]);
10559})
10560
10561(define_insn_and_split "*setcc_si_1_and"
10562  [(set (match_operand:SI 0 "register_operand" "=q")
10563	(match_operator:SI 1 "ix86_comparison_operator"
10564	  [(reg FLAGS_REG) (const_int 0)]))
10565   (clobber (reg:CC FLAGS_REG))]
10566  "!TARGET_PARTIAL_REG_STALL
10567   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10568  "#"
10569  "&& reload_completed"
10570  [(set (match_dup 2) (match_dup 1))
10571   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10572	      (clobber (reg:CC FLAGS_REG))])]
10573{
10574  PUT_MODE (operands[1], QImode);
10575  operands[2] = gen_lowpart (QImode, operands[0]);
10576})
10577
10578(define_insn_and_split "*setcc_si_1_movzbl"
10579  [(set (match_operand:SI 0 "register_operand" "=q")
10580	(match_operator:SI 1 "ix86_comparison_operator"
10581	  [(reg FLAGS_REG) (const_int 0)]))]
10582  "!TARGET_PARTIAL_REG_STALL
10583   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10584  "#"
10585  "&& reload_completed"
10586  [(set (match_dup 2) (match_dup 1))
10587   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10588{
10589  PUT_MODE (operands[1], QImode);
10590  operands[2] = gen_lowpart (QImode, operands[0]);
10591})
10592
10593(define_insn "*setcc_qi"
10594  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10595	(match_operator:QI 1 "ix86_comparison_operator"
10596	  [(reg FLAGS_REG) (const_int 0)]))]
10597  ""
10598  "set%C1\t%0"
10599  [(set_attr "type" "setcc")
10600   (set_attr "mode" "QI")])
10601
10602(define_insn "*setcc_qi_slp"
10603  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10604	(match_operator:QI 1 "ix86_comparison_operator"
10605	  [(reg FLAGS_REG) (const_int 0)]))]
10606  ""
10607  "set%C1\t%0"
10608  [(set_attr "type" "setcc")
10609   (set_attr "mode" "QI")])
10610
10611;; In general it is not safe to assume too much about CCmode registers,
10612;; so simplify-rtx stops when it sees a second one.  Under certain
10613;; conditions this is safe on x86, so help combine not create
10614;;
10615;;	seta	%al
10616;;	testb	%al, %al
10617;;	sete	%al
10618
10619(define_split
10620  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10621	(ne:QI (match_operator 1 "ix86_comparison_operator"
10622	         [(reg FLAGS_REG) (const_int 0)])
10623	    (const_int 0)))]
10624  ""
10625  [(set (match_dup 0) (match_dup 1))]
10626  "PUT_MODE (operands[1], QImode);")
10627
10628(define_split
10629  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10630	(ne:QI (match_operator 1 "ix86_comparison_operator"
10631	         [(reg FLAGS_REG) (const_int 0)])
10632	    (const_int 0)))]
10633  ""
10634  [(set (match_dup 0) (match_dup 1))]
10635  "PUT_MODE (operands[1], QImode);")
10636
10637(define_split
10638  [(set (match_operand:QI 0 "nonimmediate_operand" "")
10639	(eq:QI (match_operator 1 "ix86_comparison_operator"
10640	         [(reg FLAGS_REG) (const_int 0)])
10641	    (const_int 0)))]
10642  ""
10643  [(set (match_dup 0) (match_dup 1))]
10644{
10645  rtx new_op1 = copy_rtx (operands[1]);
10646  operands[1] = new_op1;
10647  PUT_MODE (new_op1, QImode);
10648  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10649					     GET_MODE (XEXP (new_op1, 0))));
10650
10651  /* Make sure that (a) the CCmode we have for the flags is strong
10652     enough for the reversed compare or (b) we have a valid FP compare.  */
10653  if (! ix86_comparison_operator (new_op1, VOIDmode))
10654    FAIL;
10655})
10656
10657(define_split
10658  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10659	(eq:QI (match_operator 1 "ix86_comparison_operator"
10660	         [(reg FLAGS_REG) (const_int 0)])
10661	    (const_int 0)))]
10662  ""
10663  [(set (match_dup 0) (match_dup 1))]
10664{
10665  rtx new_op1 = copy_rtx (operands[1]);
10666  operands[1] = new_op1;
10667  PUT_MODE (new_op1, QImode);
10668  PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10669					     GET_MODE (XEXP (new_op1, 0))));
10670
10671  /* Make sure that (a) the CCmode we have for the flags is strong
10672     enough for the reversed compare or (b) we have a valid FP compare.  */
10673  if (! ix86_comparison_operator (new_op1, VOIDmode))
10674    FAIL;
10675})
10676
10677;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10678;; subsequent logical operations are used to imitate conditional moves.
10679;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10680;; it directly.
10681
10682(define_insn "setcc_<mode>_sse"
10683  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10684	(match_operator:MODEF 3 "sse_comparison_operator"
10685	  [(match_operand:MODEF 1 "register_operand" "0,x")
10686	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10687  "SSE_FLOAT_MODE_P (<MODE>mode)"
10688  "@
10689   cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10690   vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10691  [(set_attr "isa" "noavx,avx")
10692   (set_attr "type" "ssecmp")
10693   (set_attr "length_immediate" "1")
10694   (set_attr "prefix" "orig,vex")
10695   (set_attr "mode" "<MODE>")])
10696
10697;; Basic conditional jump instructions.
10698;; We ignore the overflow flag for signed branch instructions.
10699
10700(define_insn "*jcc_1"
10701  [(set (pc)
10702	(if_then_else (match_operator 1 "ix86_comparison_operator"
10703				      [(reg FLAGS_REG) (const_int 0)])
10704		      (label_ref (match_operand 0 "" ""))
10705		      (pc)))]
10706  ""
10707  "%+j%C1\t%l0"
10708  [(set_attr "type" "ibr")
10709   (set_attr "modrm" "0")
10710   (set (attr "length")
10711	   (if_then_else (and (ge (minus (match_dup 0) (pc))
10712				  (const_int -126))
10713			      (lt (minus (match_dup 0) (pc))
10714				  (const_int 128)))
10715	     (const_int 2)
10716	     (const_int 6)))])
10717
10718(define_insn "*jcc_2"
10719  [(set (pc)
10720	(if_then_else (match_operator 1 "ix86_comparison_operator"
10721				      [(reg FLAGS_REG) (const_int 0)])
10722		      (pc)
10723		      (label_ref (match_operand 0 "" ""))))]
10724  ""
10725  "%+j%c1\t%l0"
10726  [(set_attr "type" "ibr")
10727   (set_attr "modrm" "0")
10728   (set (attr "length")
10729	   (if_then_else (and (ge (minus (match_dup 0) (pc))
10730				  (const_int -126))
10731			      (lt (minus (match_dup 0) (pc))
10732				  (const_int 128)))
10733	     (const_int 2)
10734	     (const_int 6)))])
10735
10736;; In general it is not safe to assume too much about CCmode registers,
10737;; so simplify-rtx stops when it sees a second one.  Under certain
10738;; conditions this is safe on x86, so help combine not create
10739;;
10740;;	seta	%al
10741;;	testb	%al, %al
10742;;	je	Lfoo
10743
10744(define_split
10745  [(set (pc)
10746	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10747				      [(reg FLAGS_REG) (const_int 0)])
10748			  (const_int 0))
10749		      (label_ref (match_operand 1 "" ""))
10750		      (pc)))]
10751  ""
10752  [(set (pc)
10753	(if_then_else (match_dup 0)
10754		      (label_ref (match_dup 1))
10755		      (pc)))]
10756  "PUT_MODE (operands[0], VOIDmode);")
10757
10758(define_split
10759  [(set (pc)
10760	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10761				      [(reg FLAGS_REG) (const_int 0)])
10762			  (const_int 0))
10763		      (label_ref (match_operand 1 "" ""))
10764		      (pc)))]
10765  ""
10766  [(set (pc)
10767	(if_then_else (match_dup 0)
10768		      (label_ref (match_dup 1))
10769		      (pc)))]
10770{
10771  rtx new_op0 = copy_rtx (operands[0]);
10772  operands[0] = new_op0;
10773  PUT_MODE (new_op0, VOIDmode);
10774  PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10775					     GET_MODE (XEXP (new_op0, 0))));
10776
10777  /* Make sure that (a) the CCmode we have for the flags is strong
10778     enough for the reversed compare or (b) we have a valid FP compare.  */
10779  if (! ix86_comparison_operator (new_op0, VOIDmode))
10780    FAIL;
10781})
10782
10783;; zero_extend in SImode is correct also for DImode, since this is what combine
10784;; pass generates from shift insn with QImode operand.  Actually, the mode
10785;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10786;; appropriate modulo of the bit offset value.
10787
10788(define_insn_and_split "*jcc_bt<mode>"
10789  [(set (pc)
10790  	(if_then_else (match_operator 0 "bt_comparison_operator"
10791			[(zero_extract:SWI48
10792			   (match_operand:SWI48 1 "register_operand" "r")
10793			   (const_int 1)
10794			   (zero_extend:SI
10795			     (match_operand:QI 2 "register_operand" "r")))
10796			 (const_int 0)])
10797		      (label_ref (match_operand 3 "" ""))
10798		      (pc)))
10799   (clobber (reg:CC FLAGS_REG))]
10800  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10801  "#"
10802  "&& 1"
10803  [(set (reg:CCC FLAGS_REG)
10804	(compare:CCC
10805	  (zero_extract:SWI48
10806	    (match_dup 1)
10807	    (const_int 1)
10808	    (match_dup 2))
10809	  (const_int 0)))
10810   (set (pc)
10811	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10812		      (label_ref (match_dup 3))
10813		      (pc)))]
10814{
10815  operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10816
10817  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10818})
10819
10820;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10821;; also for DImode, this is what combine produces.
10822(define_insn_and_split "*jcc_bt<mode>_mask"
10823  [(set (pc)
10824  	(if_then_else (match_operator 0 "bt_comparison_operator"
10825			[(zero_extract:SWI48
10826			   (match_operand:SWI48 1 "register_operand" "r")
10827			   (const_int 1)
10828			   (and:SI
10829			     (match_operand:SI 2 "register_operand" "r")
10830			     (match_operand:SI 3 "const_int_operand" "n")))])
10831		      (label_ref (match_operand 4 "" ""))
10832		      (pc)))
10833   (clobber (reg:CC FLAGS_REG))]
10834  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10835   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10836      == GET_MODE_BITSIZE (<MODE>mode)-1"
10837  "#"
10838  "&& 1"
10839  [(set (reg:CCC FLAGS_REG)
10840	(compare:CCC
10841	  (zero_extract:SWI48
10842	    (match_dup 1)
10843	    (const_int 1)
10844	    (match_dup 2))
10845	  (const_int 0)))
10846   (set (pc)
10847	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10848		      (label_ref (match_dup 4))
10849		      (pc)))]
10850{
10851  operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10852
10853  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10854})
10855
10856(define_insn_and_split "*jcc_btsi_1"
10857  [(set (pc)
10858  	(if_then_else (match_operator 0 "bt_comparison_operator"
10859			[(and:SI
10860			   (lshiftrt:SI
10861			     (match_operand:SI 1 "register_operand" "r")
10862			     (match_operand:QI 2 "register_operand" "r"))
10863			   (const_int 1))
10864			 (const_int 0)])
10865		      (label_ref (match_operand 3 "" ""))
10866		      (pc)))
10867   (clobber (reg:CC FLAGS_REG))]
10868  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10869  "#"
10870  "&& 1"
10871  [(set (reg:CCC FLAGS_REG)
10872	(compare:CCC
10873	  (zero_extract:SI
10874	    (match_dup 1)
10875	    (const_int 1)
10876	    (match_dup 2))
10877	  (const_int 0)))
10878   (set (pc)
10879	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10880		      (label_ref (match_dup 3))
10881		      (pc)))]
10882{
10883  operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10884
10885  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10886})
10887
10888;; avoid useless masking of bit offset operand
10889(define_insn_and_split "*jcc_btsi_mask_1"
10890  [(set (pc)
10891  	(if_then_else
10892	  (match_operator 0 "bt_comparison_operator"
10893	    [(and:SI
10894	       (lshiftrt:SI
10895		 (match_operand:SI 1 "register_operand" "r")
10896		 (subreg:QI
10897		   (and:SI
10898		     (match_operand:SI 2 "register_operand" "r")
10899		     (match_operand:SI 3 "const_int_operand" "n")) 0))
10900	       (const_int 1))
10901	     (const_int 0)])
10902	  (label_ref (match_operand 4 "" ""))
10903	  (pc)))
10904   (clobber (reg:CC FLAGS_REG))]
10905  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10906   && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10907  "#"
10908  "&& 1"
10909  [(set (reg:CCC FLAGS_REG)
10910	(compare:CCC
10911	  (zero_extract:SI
10912	    (match_dup 1)
10913	    (const_int 1)
10914	    (match_dup 2))
10915	  (const_int 0)))
10916   (set (pc)
10917	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10918		      (label_ref (match_dup 4))
10919		      (pc)))]
10920  "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10921
10922;; Define combination compare-and-branch fp compare instructions to help
10923;; combine.
10924
10925(define_insn "*fp_jcc_1_387"
10926  [(set (pc)
10927	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10928			[(match_operand 1 "register_operand" "f")
10929			 (match_operand 2 "nonimmediate_operand" "fm")])
10930	  (label_ref (match_operand 3 "" ""))
10931	  (pc)))
10932   (clobber (reg:CCFP FPSR_REG))
10933   (clobber (reg:CCFP FLAGS_REG))
10934   (clobber (match_scratch:HI 4 "=a"))]
10935  "TARGET_80387
10936   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10937   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10938   && SELECT_CC_MODE (GET_CODE (operands[0]),
10939		      operands[1], operands[2]) == CCFPmode
10940   && !TARGET_CMOVE"
10941  "#")
10942
10943(define_insn "*fp_jcc_1r_387"
10944  [(set (pc)
10945	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10946			[(match_operand 1 "register_operand" "f")
10947			 (match_operand 2 "nonimmediate_operand" "fm")])
10948	  (pc)
10949	  (label_ref (match_operand 3 "" ""))))
10950   (clobber (reg:CCFP FPSR_REG))
10951   (clobber (reg:CCFP FLAGS_REG))
10952   (clobber (match_scratch:HI 4 "=a"))]
10953  "TARGET_80387
10954   && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10955   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10956   && SELECT_CC_MODE (GET_CODE (operands[0]),
10957		      operands[1], operands[2]) == CCFPmode
10958   && !TARGET_CMOVE"
10959  "#")
10960
10961(define_insn "*fp_jcc_2_387"
10962  [(set (pc)
10963	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10964			[(match_operand 1 "register_operand" "f")
10965			 (match_operand 2 "register_operand" "f")])
10966	  (label_ref (match_operand 3 "" ""))
10967	  (pc)))
10968   (clobber (reg:CCFP FPSR_REG))
10969   (clobber (reg:CCFP FLAGS_REG))
10970   (clobber (match_scratch:HI 4 "=a"))]
10971  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10972   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10973   && !TARGET_CMOVE"
10974  "#")
10975
10976(define_insn "*fp_jcc_2r_387"
10977  [(set (pc)
10978	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10979			[(match_operand 1 "register_operand" "f")
10980			 (match_operand 2 "register_operand" "f")])
10981	  (pc)
10982	  (label_ref (match_operand 3 "" ""))))
10983   (clobber (reg:CCFP FPSR_REG))
10984   (clobber (reg:CCFP FLAGS_REG))
10985   (clobber (match_scratch:HI 4 "=a"))]
10986  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10987   && GET_MODE (operands[1]) == GET_MODE (operands[2])
10988   && !TARGET_CMOVE"
10989  "#")
10990
10991(define_insn "*fp_jcc_3_387"
10992  [(set (pc)
10993	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10994			[(match_operand 1 "register_operand" "f")
10995			 (match_operand 2 "const0_operand" "")])
10996	  (label_ref (match_operand 3 "" ""))
10997	  (pc)))
10998   (clobber (reg:CCFP FPSR_REG))
10999   (clobber (reg:CCFP FLAGS_REG))
11000   (clobber (match_scratch:HI 4 "=a"))]
11001  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11002   && GET_MODE (operands[1]) == GET_MODE (operands[2])
11003   && SELECT_CC_MODE (GET_CODE (operands[0]),
11004		      operands[1], operands[2]) == CCFPmode
11005   && !TARGET_CMOVE"
11006  "#")
11007
11008(define_split
11009  [(set (pc)
11010	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11011			[(match_operand 1 "register_operand" "")
11012			 (match_operand 2 "nonimmediate_operand" "")])
11013	  (match_operand 3 "" "")
11014	  (match_operand 4 "" "")))
11015   (clobber (reg:CCFP FPSR_REG))
11016   (clobber (reg:CCFP FLAGS_REG))]
11017  "reload_completed"
11018  [(const_int 0)]
11019{
11020  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11021	                operands[3], operands[4], NULL_RTX, NULL_RTX);
11022  DONE;
11023})
11024
11025(define_split
11026  [(set (pc)
11027	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11028			[(match_operand 1 "register_operand" "")
11029			 (match_operand 2 "general_operand" "")])
11030	  (match_operand 3 "" "")
11031	  (match_operand 4 "" "")))
11032   (clobber (reg:CCFP FPSR_REG))
11033   (clobber (reg:CCFP FLAGS_REG))
11034   (clobber (match_scratch:HI 5 "=a"))]
11035  "reload_completed"
11036  [(const_int 0)]
11037{
11038  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11039	     		operands[3], operands[4], operands[5], NULL_RTX);
11040  DONE;
11041})
11042
11043;; The order of operands in *fp_jcc_4_387 is forced by combine in
11044;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11045;; with a precedence over other operators and is always put in the first
11046;; place. Swap condition and operands to match ficom instruction.
11047
11048(define_insn "*fp_jcc_4_<mode>_387"
11049  [(set (pc)
11050	(if_then_else
11051	  (match_operator 0 "ix86_swapped_fp_comparison_operator"
11052	    [(match_operator 1 "float_operator"
11053	      [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11054	     (match_operand 3 "register_operand" "f,f")])
11055	  (label_ref (match_operand 4 "" ""))
11056	  (pc)))
11057   (clobber (reg:CCFP FPSR_REG))
11058   (clobber (reg:CCFP FLAGS_REG))
11059   (clobber (match_scratch:HI 5 "=a,a"))]
11060  "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11061   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11062   && GET_MODE (operands[1]) == GET_MODE (operands[3])
11063   && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11064   && !TARGET_CMOVE"
11065  "#")
11066
11067(define_split
11068  [(set (pc)
11069	(if_then_else
11070	  (match_operator 0 "ix86_swapped_fp_comparison_operator"
11071	    [(match_operator 1 "float_operator"
11072	      [(match_operand:SWI24 2 "memory_operand" "")])
11073	     (match_operand 3 "register_operand" "")])
11074	  (match_operand 4 "" "")
11075	  (match_operand 5 "" "")))
11076   (clobber (reg:CCFP FPSR_REG))
11077   (clobber (reg:CCFP FLAGS_REG))
11078   (clobber (match_scratch:HI 6 "=a"))]
11079  "reload_completed"
11080  [(const_int 0)]
11081{
11082  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11083
11084  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11085			operands[3], operands[7],
11086			operands[4], operands[5], operands[6], NULL_RTX);
11087  DONE;
11088})
11089
11090;; %%% Kill this when reload knows how to do it.
11091(define_split
11092  [(set (pc)
11093	(if_then_else
11094	  (match_operator 0 "ix86_swapped_fp_comparison_operator"
11095	    [(match_operator 1 "float_operator"
11096	      [(match_operand:SWI24 2 "register_operand" "")])
11097	     (match_operand 3 "register_operand" "")])
11098	  (match_operand 4 "" "")
11099	  (match_operand 5 "" "")))
11100   (clobber (reg:CCFP FPSR_REG))
11101   (clobber (reg:CCFP FLAGS_REG))
11102   (clobber (match_scratch:HI 6 "=a"))]
11103  "reload_completed"
11104  [(const_int 0)]
11105{
11106  operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11107  operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11108
11109  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11110			operands[3], operands[7],
11111			operands[4], operands[5], operands[6], operands[2]);
11112  DONE;
11113})
11114
11115;; Unconditional and other jump instructions
11116
11117(define_insn "jump"
11118  [(set (pc)
11119	(label_ref (match_operand 0 "" "")))]
11120  ""
11121  "jmp\t%l0"
11122  [(set_attr "type" "ibr")
11123   (set (attr "length")
11124	   (if_then_else (and (ge (minus (match_dup 0) (pc))
11125				  (const_int -126))
11126			      (lt (minus (match_dup 0) (pc))
11127				  (const_int 128)))
11128	     (const_int 2)
11129	     (const_int 5)))
11130   (set_attr "modrm" "0")])
11131
11132(define_expand "indirect_jump"
11133  [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11134
11135(define_insn "*indirect_jump"
11136  [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11137  ""
11138  "jmp\t%A0"
11139  [(set_attr "type" "ibr")
11140   (set_attr "length_immediate" "0")])
11141
11142(define_expand "tablejump"
11143  [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11144	      (use (label_ref (match_operand 1 "" "")))])]
11145  ""
11146{
11147  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11148     relative.  Convert the relative address to an absolute address.  */
11149  if (flag_pic)
11150    {
11151      rtx op0, op1;
11152      enum rtx_code code;
11153
11154      /* We can't use @GOTOFF for text labels on VxWorks;
11155	 see gotoff_operand.  */
11156      if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11157	{
11158	  code = PLUS;
11159	  op0 = operands[0];
11160	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11161	}
11162      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11163	{
11164	  code = PLUS;
11165	  op0 = operands[0];
11166	  op1 = pic_offset_table_rtx;
11167	}
11168      else
11169	{
11170	  code = MINUS;
11171	  op0 = pic_offset_table_rtx;
11172	  op1 = operands[0];
11173	}
11174
11175      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11176					 OPTAB_DIRECT);
11177    }
11178  else if (TARGET_X32)
11179    operands[0] = convert_memory_address (Pmode, operands[0]);
11180})
11181
11182(define_insn "*tablejump_1"
11183  [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11184   (use (label_ref (match_operand 1 "" "")))]
11185  ""
11186  "jmp\t%A0"
11187  [(set_attr "type" "ibr")
11188   (set_attr "length_immediate" "0")])
11189
11190;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11191
11192(define_peephole2
11193  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11194   (set (match_operand:QI 1 "register_operand" "")
11195	(match_operator:QI 2 "ix86_comparison_operator"
11196	  [(reg FLAGS_REG) (const_int 0)]))
11197   (set (match_operand 3 "q_regs_operand" "")
11198	(zero_extend (match_dup 1)))]
11199  "(peep2_reg_dead_p (3, operands[1])
11200    || operands_match_p (operands[1], operands[3]))
11201   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11202  [(set (match_dup 4) (match_dup 0))
11203   (set (strict_low_part (match_dup 5))
11204	(match_dup 2))]
11205{
11206  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11207  operands[5] = gen_lowpart (QImode, operands[3]);
11208  ix86_expand_clear (operands[3]);
11209})
11210
11211;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11212
11213(define_peephole2
11214  [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11215   (set (match_operand:QI 1 "register_operand" "")
11216	(match_operator:QI 2 "ix86_comparison_operator"
11217	  [(reg FLAGS_REG) (const_int 0)]))
11218   (parallel [(set (match_operand 3 "q_regs_operand" "")
11219		   (zero_extend (match_dup 1)))
11220	      (clobber (reg:CC FLAGS_REG))])]
11221  "(peep2_reg_dead_p (3, operands[1])
11222    || operands_match_p (operands[1], operands[3]))
11223   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11224  [(set (match_dup 4) (match_dup 0))
11225   (set (strict_low_part (match_dup 5))
11226	(match_dup 2))]
11227{
11228  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11229  operands[5] = gen_lowpart (QImode, operands[3]);
11230  ix86_expand_clear (operands[3]);
11231})
11232
11233;; Call instructions.
11234
11235;; The predicates normally associated with named expanders are not properly
11236;; checked for calls.  This is a bug in the generic code, but it isn't that
11237;; easy to fix.  Ignore it for now and be prepared to fix things up.
11238
11239;; P6 processors will jump to the address after the decrement when %esp
11240;; is used as a call operand, so they will execute return address as a code.
11241;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11242
11243;; Register constraint for call instruction.
11244(define_mode_attr c [(SI "l") (DI "r")])
11245
11246;; Call subroutine returning no value.
11247
11248(define_expand "call"
11249  [(call (match_operand:QI 0 "" "")
11250	 (match_operand 1 "" ""))
11251   (use (match_operand 2 "" ""))]
11252  ""
11253{
11254  ix86_expand_call (NULL, operands[0], operands[1],
11255		    operands[2], NULL, false);
11256  DONE;
11257})
11258
11259(define_expand "sibcall"
11260  [(call (match_operand:QI 0 "" "")
11261	 (match_operand 1 "" ""))
11262   (use (match_operand 2 "" ""))]
11263  ""
11264{
11265  ix86_expand_call (NULL, operands[0], operands[1],
11266		    operands[2], NULL, true);
11267  DONE;
11268})
11269
11270(define_insn_and_split "*call_vzeroupper"
11271  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11272	 (match_operand 1 "" ""))
11273   (unspec [(match_operand 2 "const_int_operand" "")]
11274   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11275  "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11276  "#"
11277  "&& reload_completed"
11278  [(const_int 0)]
11279  "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11280  [(set_attr "type" "call")])
11281
11282(define_insn "*call"
11283  [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11284	 (match_operand 1 "" ""))]
11285  "!SIBLING_CALL_P (insn)"
11286  "* return ix86_output_call_insn (insn, operands[0]);"
11287  [(set_attr "type" "call")])
11288
11289(define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11290  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11291	 (match_operand 1 "" ""))
11292   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11293   (clobber (reg:TI XMM6_REG))
11294   (clobber (reg:TI XMM7_REG))
11295   (clobber (reg:TI XMM8_REG))
11296   (clobber (reg:TI XMM9_REG))
11297   (clobber (reg:TI XMM10_REG))
11298   (clobber (reg:TI XMM11_REG))
11299   (clobber (reg:TI XMM12_REG))
11300   (clobber (reg:TI XMM13_REG))
11301   (clobber (reg:TI XMM14_REG))
11302   (clobber (reg:TI XMM15_REG))
11303   (clobber (reg:DI SI_REG))
11304   (clobber (reg:DI DI_REG))
11305   (unspec [(match_operand 2 "const_int_operand" "")]
11306   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11307  "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11308  "#"
11309  "&& reload_completed"
11310  [(const_int 0)]
11311  "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11312  [(set_attr "type" "call")])
11313
11314(define_insn "*call_rex64_ms_sysv"
11315  [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11316	 (match_operand 1 "" ""))
11317   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11318   (clobber (reg:TI XMM6_REG))
11319   (clobber (reg:TI XMM7_REG))
11320   (clobber (reg:TI XMM8_REG))
11321   (clobber (reg:TI XMM9_REG))
11322   (clobber (reg:TI XMM10_REG))
11323   (clobber (reg:TI XMM11_REG))
11324   (clobber (reg:TI XMM12_REG))
11325   (clobber (reg:TI XMM13_REG))
11326   (clobber (reg:TI XMM14_REG))
11327   (clobber (reg:TI XMM15_REG))
11328   (clobber (reg:DI SI_REG))
11329   (clobber (reg:DI DI_REG))]
11330  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11331  "* return ix86_output_call_insn (insn, operands[0]);"
11332  [(set_attr "type" "call")])
11333
11334(define_insn_and_split "*sibcall_vzeroupper"
11335  [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11336	 (match_operand 1 "" ""))
11337   (unspec [(match_operand 2 "const_int_operand" "")]
11338   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11339  "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11340  "#"
11341  "&& reload_completed"
11342  [(const_int 0)]
11343  "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11344  [(set_attr "type" "call")])
11345
11346(define_insn "*sibcall"
11347  [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11348	 (match_operand 1 "" ""))]
11349  "SIBLING_CALL_P (insn)"
11350  "* return ix86_output_call_insn (insn, operands[0]);"
11351  [(set_attr "type" "call")])
11352
11353(define_expand "call_pop"
11354  [(parallel [(call (match_operand:QI 0 "" "")
11355		    (match_operand:SI 1 "" ""))
11356	      (set (reg:SI SP_REG)
11357		   (plus:SI (reg:SI SP_REG)
11358			    (match_operand:SI 3 "" "")))])]
11359  "!TARGET_64BIT"
11360{
11361  ix86_expand_call (NULL, operands[0], operands[1],
11362		    operands[2], operands[3], false);
11363  DONE;
11364})
11365
11366(define_insn_and_split "*call_pop_vzeroupper"
11367  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11368	 (match_operand:SI 1 "" ""))
11369   (set (reg:SI SP_REG)
11370	(plus:SI (reg:SI SP_REG)
11371		 (match_operand:SI 2 "immediate_operand" "i")))
11372   (unspec [(match_operand 3 "const_int_operand" "")]
11373   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11374  "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11375  "#"
11376  "&& reload_completed"
11377  [(const_int 0)]
11378  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11379  [(set_attr "type" "call")])
11380
11381(define_insn "*call_pop"
11382  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11383	 (match_operand 1 "" ""))
11384   (set (reg:SI SP_REG)
11385	(plus:SI (reg:SI SP_REG)
11386		 (match_operand:SI 2 "immediate_operand" "i")))]
11387  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11388  "* return ix86_output_call_insn (insn, operands[0]);"
11389  [(set_attr "type" "call")])
11390
11391(define_insn_and_split "*sibcall_pop_vzeroupper"
11392  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11393	 (match_operand 1 "" ""))
11394   (set (reg:SI SP_REG)
11395	(plus:SI (reg:SI SP_REG)
11396		 (match_operand:SI 2 "immediate_operand" "i")))
11397   (unspec [(match_operand 3 "const_int_operand" "")]
11398   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11399  "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11400  "#"
11401  "&& reload_completed"
11402  [(const_int 0)]
11403  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11404  [(set_attr "type" "call")])
11405
11406(define_insn "*sibcall_pop"
11407  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11408	 (match_operand 1 "" ""))
11409   (set (reg:SI SP_REG)
11410	(plus:SI (reg:SI SP_REG)
11411		 (match_operand:SI 2 "immediate_operand" "i")))]
11412  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11413  "* return ix86_output_call_insn (insn, operands[0]);"
11414  [(set_attr "type" "call")])
11415
11416;; Call subroutine, returning value in operand 0
11417
11418(define_expand "call_value"
11419  [(set (match_operand 0 "" "")
11420	(call (match_operand:QI 1 "" "")
11421	      (match_operand 2 "" "")))
11422   (use (match_operand 3 "" ""))]
11423  ""
11424{
11425  ix86_expand_call (operands[0], operands[1], operands[2],
11426		    operands[3], NULL, false);
11427  DONE;
11428})
11429
11430(define_expand "sibcall_value"
11431  [(set (match_operand 0 "" "")
11432	(call (match_operand:QI 1 "" "")
11433	      (match_operand 2 "" "")))
11434   (use (match_operand 3 "" ""))]
11435  ""
11436{
11437  ix86_expand_call (operands[0], operands[1], operands[2],
11438		    operands[3], NULL, true);
11439  DONE;
11440})
11441
11442(define_insn_and_split "*call_value_vzeroupper"
11443  [(set (match_operand 0 "" "")
11444	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11445	      (match_operand 2 "" "")))
11446   (unspec [(match_operand 3 "const_int_operand" "")]
11447   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11448  "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11449  "#"
11450  "&& reload_completed"
11451  [(const_int 0)]
11452  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11453  [(set_attr "type" "callv")])
11454
11455(define_insn "*call_value"
11456  [(set (match_operand 0 "" "")
11457	(call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11458	      (match_operand 2 "" "")))]
11459  "!SIBLING_CALL_P (insn)"
11460  "* return ix86_output_call_insn (insn, operands[1]);"
11461  [(set_attr "type" "callv")])
11462
11463(define_insn_and_split "*sibcall_value_vzeroupper"
11464  [(set (match_operand 0 "" "")
11465	(call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11466	      (match_operand 2 "" "")))
11467   (unspec [(match_operand 3 "const_int_operand" "")]
11468   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11469  "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11470  "#"
11471  "&& reload_completed"
11472  [(const_int 0)]
11473  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11474  [(set_attr "type" "callv")])
11475
11476(define_insn "*sibcall_value"
11477  [(set (match_operand 0 "" "")
11478	(call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11479	      (match_operand 2 "" "")))]
11480  "SIBLING_CALL_P (insn)"
11481  "* return ix86_output_call_insn (insn, operands[1]);"
11482  [(set_attr "type" "callv")])
11483
11484(define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11485  [(set (match_operand 0 "" "")
11486	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11487	      (match_operand 2 "" "")))
11488   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11489   (clobber (reg:TI XMM6_REG))
11490   (clobber (reg:TI XMM7_REG))
11491   (clobber (reg:TI XMM8_REG))
11492   (clobber (reg:TI XMM9_REG))
11493   (clobber (reg:TI XMM10_REG))
11494   (clobber (reg:TI XMM11_REG))
11495   (clobber (reg:TI XMM12_REG))
11496   (clobber (reg:TI XMM13_REG))
11497   (clobber (reg:TI XMM14_REG))
11498   (clobber (reg:TI XMM15_REG))
11499   (clobber (reg:DI SI_REG))
11500   (clobber (reg:DI DI_REG))
11501   (unspec [(match_operand 3 "const_int_operand" "")]
11502   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11503  "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11504  "#"
11505  "&& reload_completed"
11506  [(const_int 0)]
11507  "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11508  [(set_attr "type" "callv")])
11509
11510(define_insn "*call_value_rex64_ms_sysv"
11511  [(set (match_operand 0 "" "")
11512	(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11513	      (match_operand 2 "" "")))
11514   (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11515   (clobber (reg:TI XMM6_REG))
11516   (clobber (reg:TI XMM7_REG))
11517   (clobber (reg:TI XMM8_REG))
11518   (clobber (reg:TI XMM9_REG))
11519   (clobber (reg:TI XMM10_REG))
11520   (clobber (reg:TI XMM11_REG))
11521   (clobber (reg:TI XMM12_REG))
11522   (clobber (reg:TI XMM13_REG))
11523   (clobber (reg:TI XMM14_REG))
11524   (clobber (reg:TI XMM15_REG))
11525   (clobber (reg:DI SI_REG))
11526   (clobber (reg:DI DI_REG))]
11527  "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11528  "* return ix86_output_call_insn (insn, operands[1]);"
11529  [(set_attr "type" "callv")])
11530
11531(define_expand "call_value_pop"
11532  [(parallel [(set (match_operand 0 "" "")
11533		   (call (match_operand:QI 1 "" "")
11534			 (match_operand:SI 2 "" "")))
11535	      (set (reg:SI SP_REG)
11536		   (plus:SI (reg:SI SP_REG)
11537			    (match_operand:SI 4 "" "")))])]
11538  "!TARGET_64BIT"
11539{
11540  ix86_expand_call (operands[0], operands[1], operands[2],
11541		    operands[3], operands[4], false);
11542  DONE;
11543})
11544
11545(define_insn_and_split "*call_value_pop_vzeroupper"
11546  [(set (match_operand 0 "" "")
11547	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11548	      (match_operand 2 "" "")))
11549   (set (reg:SI SP_REG)
11550	(plus:SI (reg:SI SP_REG)
11551		 (match_operand:SI 3 "immediate_operand" "i")))
11552   (unspec [(match_operand 4 "const_int_operand" "")]
11553   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11554  "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11555  "#"
11556  "&& reload_completed"
11557  [(const_int 0)]
11558  "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11559  [(set_attr "type" "callv")])
11560
11561(define_insn "*call_value_pop"
11562  [(set (match_operand 0 "" "")
11563	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11564	      (match_operand 2 "" "")))
11565   (set (reg:SI SP_REG)
11566	(plus:SI (reg:SI SP_REG)
11567		 (match_operand:SI 3 "immediate_operand" "i")))]
11568  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11569  "* return ix86_output_call_insn (insn, operands[1]);"
11570  [(set_attr "type" "callv")])
11571
11572(define_insn_and_split "*sibcall_value_pop_vzeroupper"
11573  [(set (match_operand 0 "" "")
11574	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11575	      (match_operand 2 "" "")))
11576   (set (reg:SI SP_REG)
11577	(plus:SI (reg:SI SP_REG)
11578		 (match_operand:SI 3 "immediate_operand" "i")))
11579   (unspec [(match_operand 4 "const_int_operand" "")]
11580   	   UNSPEC_CALL_NEEDS_VZEROUPPER)]
11581  "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11582  "#"
11583  "&& reload_completed"
11584  [(const_int 0)]
11585  "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11586  [(set_attr "type" "callv")])
11587
11588(define_insn "*sibcall_value_pop"
11589  [(set (match_operand 0 "" "")
11590	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11591	      (match_operand 2 "" "")))
11592   (set (reg:SI SP_REG)
11593	(plus:SI (reg:SI SP_REG)
11594		 (match_operand:SI 3 "immediate_operand" "i")))]
11595  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11596  "* return ix86_output_call_insn (insn, operands[1]);"
11597  [(set_attr "type" "callv")])
11598
11599;; Call subroutine returning any type.
11600
11601(define_expand "untyped_call"
11602  [(parallel [(call (match_operand 0 "" "")
11603		    (const_int 0))
11604	      (match_operand 1 "" "")
11605	      (match_operand 2 "" "")])]
11606  ""
11607{
11608  int i;
11609
11610  /* In order to give reg-stack an easier job in validating two
11611     coprocessor registers as containing a possible return value,
11612     simply pretend the untyped call returns a complex long double
11613     value.
11614
11615     We can't use SSE_REGPARM_MAX here since callee is unprototyped
11616     and should have the default ABI.  */
11617
11618  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11619		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11620		    operands[0], const0_rtx,
11621		    GEN_INT ((TARGET_64BIT
11622			      ? (ix86_abi == SYSV_ABI
11623				 ? X86_64_SSE_REGPARM_MAX
11624				 : X86_64_MS_SSE_REGPARM_MAX)
11625			      : X86_32_SSE_REGPARM_MAX)
11626		    	     - 1),
11627		    NULL, false);
11628
11629  for (i = 0; i < XVECLEN (operands[2], 0); i++)
11630    {
11631      rtx set = XVECEXP (operands[2], 0, i);
11632      emit_move_insn (SET_DEST (set), SET_SRC (set));
11633    }
11634
11635  /* The optimizer does not know that the call sets the function value
11636     registers we stored in the result block.  We avoid problems by
11637     claiming that all hard registers are used and clobbered at this
11638     point.  */
11639  emit_insn (gen_blockage ());
11640
11641  DONE;
11642})
11643
11644;; Prologue and epilogue instructions
11645
11646;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11647;; all of memory.  This blocks insns from being moved across this point.
11648
11649(define_insn "blockage"
11650  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11651  ""
11652  ""
11653  [(set_attr "length" "0")])
11654
11655;; Do not schedule instructions accessing memory across this point.
11656
11657(define_expand "memory_blockage"
11658  [(set (match_dup 0)
11659	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11660  ""
11661{
11662  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11663  MEM_VOLATILE_P (operands[0]) = 1;
11664})
11665
11666(define_insn "*memory_blockage"
11667  [(set (match_operand:BLK 0 "" "")
11668	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11669  ""
11670  ""
11671  [(set_attr "length" "0")])
11672
11673;; As USE insns aren't meaningful after reload, this is used instead
11674;; to prevent deleting instructions setting registers for PIC code
11675(define_insn "prologue_use"
11676  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11677  ""
11678  ""
11679  [(set_attr "length" "0")])
11680
11681;; Insn emitted into the body of a function to return from a function.
11682;; This is only done if the function's epilogue is known to be simple.
11683;; See comments for ix86_can_use_return_insn_p in i386.c.
11684
11685(define_expand "return"
11686  [(simple_return)]
11687  "ix86_can_use_return_insn_p ()"
11688{
11689  ix86_maybe_emit_epilogue_vzeroupper ();
11690  if (crtl->args.pops_args)
11691    {
11692      rtx popc = GEN_INT (crtl->args.pops_args);
11693      emit_jump_insn (gen_simple_return_pop_internal (popc));
11694      DONE;
11695    }
11696})
11697
11698;; We need to disable this for TARGET_SEH, as otherwise
11699;; shrink-wrapped prologue gets enabled too.  This might exceed
11700;; the maximum size of prologue in unwind information.
11701
11702(define_expand "simple_return"
11703  [(simple_return)]
11704  "!TARGET_SEH"
11705{
11706  ix86_maybe_emit_epilogue_vzeroupper ();
11707  if (crtl->args.pops_args)
11708    {
11709      rtx popc = GEN_INT (crtl->args.pops_args);
11710      emit_jump_insn (gen_simple_return_pop_internal (popc));
11711      DONE;
11712    }
11713})
11714
11715(define_insn "simple_return_internal"
11716  [(simple_return)]
11717  "reload_completed"
11718  "ret"
11719  [(set_attr "length" "1")
11720   (set_attr "atom_unit" "jeu")
11721   (set_attr "length_immediate" "0")
11722   (set_attr "modrm" "0")])
11723
11724;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11725;; instruction Athlon and K8 have.
11726
11727(define_insn "simple_return_internal_long"
11728  [(simple_return)
11729   (unspec [(const_int 0)] UNSPEC_REP)]
11730  "reload_completed"
11731  "rep\;ret"
11732  [(set_attr "length" "2")
11733   (set_attr "atom_unit" "jeu")
11734   (set_attr "length_immediate" "0")
11735   (set_attr "prefix_rep" "1")
11736   (set_attr "modrm" "0")])
11737
11738(define_insn "simple_return_pop_internal"
11739  [(simple_return)
11740   (use (match_operand:SI 0 "const_int_operand" ""))]
11741  "reload_completed"
11742  "ret\t%0"
11743  [(set_attr "length" "3")
11744   (set_attr "atom_unit" "jeu")
11745   (set_attr "length_immediate" "2")
11746   (set_attr "modrm" "0")])
11747
11748(define_insn "simple_return_indirect_internal"
11749  [(simple_return)
11750   (use (match_operand:SI 0 "register_operand" "r"))]
11751  "reload_completed"
11752  "jmp\t%A0"
11753  [(set_attr "type" "ibr")
11754   (set_attr "length_immediate" "0")])
11755
11756(define_insn "nop"
11757  [(const_int 0)]
11758  ""
11759  "nop"
11760  [(set_attr "length" "1")
11761   (set_attr "length_immediate" "0")
11762   (set_attr "modrm" "0")])
11763
11764;; Generate nops.  Operand 0 is the number of nops, up to 8.
11765(define_insn "nops"
11766  [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11767		    UNSPECV_NOPS)]
11768  "reload_completed"
11769{
11770  int num = INTVAL (operands[0]);
11771
11772  gcc_assert (num >= 1 && num <= 8);
11773
11774  while (num--)
11775    fputs ("\tnop\n", asm_out_file);
11776
11777  return "";
11778}
11779  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11780   (set_attr "length_immediate" "0")
11781   (set_attr "modrm" "0")])
11782
11783;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11784;; branch prediction penalty for the third jump in a 16-byte
11785;; block on K8.
11786
11787(define_insn "pad"
11788  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11789  ""
11790{
11791#ifdef ASM_OUTPUT_MAX_SKIP_PAD
11792  ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11793#else
11794  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11795     The align insn is used to avoid 3 jump instructions in the row to improve
11796     branch prediction and the benefits hardly outweigh the cost of extra 8
11797     nops on the average inserted by full alignment pseudo operation.  */
11798#endif
11799  return "";
11800}
11801  [(set_attr "length" "16")])
11802
11803(define_expand "prologue"
11804  [(const_int 0)]
11805  ""
11806  "ix86_expand_prologue (); DONE;")
11807
11808(define_insn "set_got"
11809  [(set (match_operand:SI 0 "register_operand" "=r")
11810	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11811   (clobber (reg:CC FLAGS_REG))]
11812  "!TARGET_64BIT"
11813  "* return output_set_got (operands[0], NULL_RTX);"
11814  [(set_attr "type" "multi")
11815   (set_attr "length" "12")])
11816
11817(define_insn "set_got_labelled"
11818  [(set (match_operand:SI 0 "register_operand" "=r")
11819	(unspec:SI [(label_ref (match_operand 1 "" ""))]
11820	 UNSPEC_SET_GOT))
11821   (clobber (reg:CC FLAGS_REG))]
11822  "!TARGET_64BIT"
11823  "* return output_set_got (operands[0], operands[1]);"
11824  [(set_attr "type" "multi")
11825   (set_attr "length" "12")])
11826
11827(define_insn "set_got_rex64"
11828  [(set (match_operand:DI 0 "register_operand" "=r")
11829	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11830  "TARGET_64BIT"
11831  "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11832  [(set_attr "type" "lea")
11833   (set_attr "length_address" "4")
11834   (set_attr "mode" "DI")])
11835
11836(define_insn "set_rip_rex64"
11837  [(set (match_operand:DI 0 "register_operand" "=r")
11838	(unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11839  "TARGET_64BIT"
11840  "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11841  [(set_attr "type" "lea")
11842   (set_attr "length_address" "4")
11843   (set_attr "mode" "DI")])
11844
11845(define_insn "set_got_offset_rex64"
11846  [(set (match_operand:DI 0 "register_operand" "=r")
11847	(unspec:DI
11848	  [(label_ref (match_operand 1 "" ""))]
11849	  UNSPEC_SET_GOT_OFFSET))]
11850  "TARGET_LP64"
11851  "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11852  [(set_attr "type" "imov")
11853   (set_attr "length_immediate" "0")
11854   (set_attr "length_address" "8")
11855   (set_attr "mode" "DI")])
11856
11857(define_expand "epilogue"
11858  [(const_int 0)]
11859  ""
11860  "ix86_expand_epilogue (1); DONE;")
11861
11862(define_expand "sibcall_epilogue"
11863  [(const_int 0)]
11864  ""
11865  "ix86_expand_epilogue (0); DONE;")
11866
11867(define_expand "eh_return"
11868  [(use (match_operand 0 "register_operand" ""))]
11869  ""
11870{
11871  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11872
11873  /* Tricky bit: we write the address of the handler to which we will
11874     be returning into someone else's stack frame, one word below the
11875     stack address we wish to restore.  */
11876  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11877  tmp = plus_constant (tmp, -UNITS_PER_WORD);
11878  tmp = gen_rtx_MEM (Pmode, tmp);
11879  emit_move_insn (tmp, ra);
11880
11881  emit_jump_insn (gen_eh_return_internal ());
11882  emit_barrier ();
11883  DONE;
11884})
11885
11886(define_insn_and_split "eh_return_internal"
11887  [(eh_return)]
11888  ""
11889  "#"
11890  "epilogue_completed"
11891  [(const_int 0)]
11892  "ix86_expand_epilogue (2); DONE;")
11893
11894(define_insn "leave"
11895  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11896   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11897   (clobber (mem:BLK (scratch)))]
11898  "!TARGET_64BIT"
11899  "leave"
11900  [(set_attr "type" "leave")])
11901
11902(define_insn "leave_rex64"
11903  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11904   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11905   (clobber (mem:BLK (scratch)))]
11906  "TARGET_64BIT"
11907  "leave"
11908  [(set_attr "type" "leave")])
11909
11910;; Handle -fsplit-stack.
11911
11912(define_expand "split_stack_prologue"
11913  [(const_int 0)]
11914  ""
11915{
11916  ix86_expand_split_stack_prologue ();
11917  DONE;
11918})
11919
11920;; In order to support the call/return predictor, we use a return
11921;; instruction which the middle-end doesn't see.
11922(define_insn "split_stack_return"
11923  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11924		     UNSPECV_SPLIT_STACK_RETURN)]
11925  ""
11926{
11927  if (operands[0] == const0_rtx)
11928    return "ret";
11929  else
11930    return "ret\t%0";
11931}
11932  [(set_attr "atom_unit" "jeu")
11933   (set_attr "modrm" "0")
11934   (set (attr "length")
11935	(if_then_else (match_operand:SI 0 "const0_operand" "")
11936		      (const_int 1)
11937		      (const_int 3)))
11938   (set (attr "length_immediate")
11939	(if_then_else (match_operand:SI 0 "const0_operand" "")
11940		      (const_int 0)
11941		      (const_int 2)))])
11942
11943;; If there are operand 0 bytes available on the stack, jump to
11944;; operand 1.
11945
11946(define_expand "split_stack_space_check"
11947  [(set (pc) (if_then_else
11948	      (ltu (minus (reg SP_REG)
11949			  (match_operand 0 "register_operand" ""))
11950		   (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11951	      (label_ref (match_operand 1 "" ""))
11952	      (pc)))]
11953  ""
11954{
11955  rtx reg, size, limit;
11956
11957  reg = gen_reg_rtx (Pmode);
11958  size = force_reg (Pmode, operands[0]);
11959  emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11960  limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11961			  UNSPEC_STACK_CHECK);
11962  limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11963  ix86_expand_branch (GEU, reg, limit, operands[1]);
11964
11965  DONE;
11966})
11967
11968;; Bit manipulation instructions.
11969
11970(define_expand "ffs<mode>2"
11971  [(set (match_dup 2) (const_int -1))
11972   (parallel [(set (reg:CCZ FLAGS_REG)
11973		   (compare:CCZ
11974		     (match_operand:SWI48 1 "nonimmediate_operand" "")
11975		     (const_int 0)))
11976	      (set (match_operand:SWI48 0 "register_operand" "")
11977		   (ctz:SWI48 (match_dup 1)))])
11978   (set (match_dup 0) (if_then_else:SWI48
11979			(eq (reg:CCZ FLAGS_REG) (const_int 0))
11980			(match_dup 2)
11981			(match_dup 0)))
11982   (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11983	      (clobber (reg:CC FLAGS_REG))])]
11984  ""
11985{
11986  if (<MODE>mode == SImode && !TARGET_CMOVE)
11987    {
11988      emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11989      DONE;
11990    }
11991  operands[2] = gen_reg_rtx (<MODE>mode);
11992})
11993
11994(define_insn_and_split "ffssi2_no_cmove"
11995  [(set (match_operand:SI 0 "register_operand" "=r")
11996	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11997   (clobber (match_scratch:SI 2 "=&q"))
11998   (clobber (reg:CC FLAGS_REG))]
11999  "!TARGET_CMOVE"
12000  "#"
12001  "&& reload_completed"
12002  [(parallel [(set (reg:CCZ FLAGS_REG)
12003		   (compare:CCZ (match_dup 1) (const_int 0)))
12004	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
12005   (set (strict_low_part (match_dup 3))
12006	(eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12007   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12008	      (clobber (reg:CC FLAGS_REG))])
12009   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12010	      (clobber (reg:CC FLAGS_REG))])
12011   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12012	      (clobber (reg:CC FLAGS_REG))])]
12013{
12014  operands[3] = gen_lowpart (QImode, operands[2]);
12015  ix86_expand_clear (operands[2]);
12016})
12017
12018(define_insn "*ffs<mode>_1"
12019  [(set (reg:CCZ FLAGS_REG)
12020	(compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12021		     (const_int 0)))
12022   (set (match_operand:SWI48 0 "register_operand" "=r")
12023	(ctz:SWI48 (match_dup 1)))]
12024  ""
12025  "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12026  [(set_attr "type" "alu1")
12027   (set_attr "prefix_0f" "1")
12028   (set_attr "mode" "<MODE>")])
12029
12030(define_insn "ctz<mode>2"
12031  [(set (match_operand:SWI248 0 "register_operand" "=r")
12032	(ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12033   (clobber (reg:CC FLAGS_REG))]
12034  ""
12035{
12036  if (TARGET_BMI)
12037    return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12038  else
12039    return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12040}
12041  [(set_attr "type" "alu1")
12042   (set_attr "prefix_0f" "1")
12043   (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12044   (set_attr "mode" "<MODE>")])
12045
12046(define_expand "clz<mode>2"
12047  [(parallel
12048     [(set (match_operand:SWI248 0 "register_operand" "")
12049	   (minus:SWI248
12050	     (match_dup 2)
12051	     (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12052      (clobber (reg:CC FLAGS_REG))])
12053   (parallel
12054     [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12055      (clobber (reg:CC FLAGS_REG))])]
12056  ""
12057{
12058  if (TARGET_LZCNT)
12059    {
12060      emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12061      DONE;
12062    }
12063  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12064})
12065
12066(define_insn "clz<mode>2_lzcnt"
12067  [(set (match_operand:SWI248 0 "register_operand" "=r")
12068	(clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12069   (clobber (reg:CC FLAGS_REG))]
12070  "TARGET_LZCNT"
12071  "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12072  [(set_attr "prefix_rep" "1")
12073   (set_attr "type" "bitmanip")
12074   (set_attr "mode" "<MODE>")])
12075
12076;; BMI instructions.
12077(define_insn "*bmi_andn_<mode>"
12078  [(set (match_operand:SWI48 0 "register_operand" "=r")
12079        (and:SWI48
12080          (not:SWI48
12081            (match_operand:SWI48 1 "register_operand" "r"))
12082            (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12083   (clobber (reg:CC FLAGS_REG))]
12084  "TARGET_BMI"
12085  "andn\t{%2, %1, %0|%0, %1, %2}"
12086  [(set_attr "type" "bitmanip")
12087   (set_attr "mode" "<MODE>")])
12088
12089(define_insn "bmi_bextr_<mode>"
12090  [(set (match_operand:SWI48 0 "register_operand" "=r")
12091        (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12092                       (match_operand:SWI48 2 "register_operand" "r")]
12093                       UNSPEC_BEXTR))
12094   (clobber (reg:CC FLAGS_REG))]
12095  "TARGET_BMI"
12096  "bextr\t{%2, %1, %0|%0, %1, %2}"
12097  [(set_attr "type" "bitmanip")
12098   (set_attr "mode" "<MODE>")])
12099
12100(define_insn "*bmi_blsi_<mode>"
12101  [(set (match_operand:SWI48 0 "register_operand" "=r")
12102        (and:SWI48
12103          (neg:SWI48
12104            (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12105          (match_dup 1)))
12106   (clobber (reg:CC FLAGS_REG))]
12107  "TARGET_BMI"
12108  "blsi\t{%1, %0|%0, %1}"
12109  [(set_attr "type" "bitmanip")
12110   (set_attr "mode" "<MODE>")])
12111
12112(define_insn "*bmi_blsmsk_<mode>"
12113  [(set (match_operand:SWI48 0 "register_operand" "=r")
12114        (xor:SWI48
12115          (plus:SWI48
12116            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12117            (const_int -1))
12118          (match_dup 1)))
12119   (clobber (reg:CC FLAGS_REG))]
12120  "TARGET_BMI"
12121  "blsmsk\t{%1, %0|%0, %1}"
12122  [(set_attr "type" "bitmanip")
12123   (set_attr "mode" "<MODE>")])
12124
12125(define_insn "*bmi_blsr_<mode>"
12126  [(set (match_operand:SWI48 0 "register_operand" "=r")
12127        (and:SWI48
12128          (plus:SWI48
12129            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12130            (const_int -1))
12131          (match_dup 1)))
12132   (clobber (reg:CC FLAGS_REG))]
12133   "TARGET_BMI"
12134   "blsr\t{%1, %0|%0, %1}"
12135  [(set_attr "type" "bitmanip")
12136   (set_attr "mode" "<MODE>")])
12137
12138;; BMI2 instructions.
12139(define_insn "bmi2_bzhi_<mode>3"
12140  [(set (match_operand:SWI48 0 "register_operand" "=r")
12141	(and:SWI48 (lshiftrt:SWI48 (const_int -1)
12142				   (match_operand:SWI48 2 "register_operand" "r"))
12143		   (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12144   (clobber (reg:CC FLAGS_REG))]
12145  "TARGET_BMI2"
12146  "bzhi\t{%2, %1, %0|%0, %1, %2}"
12147  [(set_attr "type" "bitmanip")
12148   (set_attr "prefix" "vex")
12149   (set_attr "mode" "<MODE>")])
12150
12151(define_insn "bmi2_pdep_<mode>3"
12152  [(set (match_operand:SWI48 0 "register_operand" "=r")
12153        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12154                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12155                       UNSPEC_PDEP))]
12156  "TARGET_BMI2"
12157  "pdep\t{%2, %1, %0|%0, %1, %2}"
12158  [(set_attr "type" "bitmanip")
12159   (set_attr "prefix" "vex")
12160   (set_attr "mode" "<MODE>")])
12161
12162(define_insn "bmi2_pext_<mode>3"
12163  [(set (match_operand:SWI48 0 "register_operand" "=r")
12164        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12165                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12166                       UNSPEC_PEXT))]
12167  "TARGET_BMI2"
12168  "pext\t{%2, %1, %0|%0, %1, %2}"
12169  [(set_attr "type" "bitmanip")
12170   (set_attr "prefix" "vex")
12171   (set_attr "mode" "<MODE>")])
12172
12173;; TBM instructions.
12174(define_insn "tbm_bextri_<mode>"
12175  [(set (match_operand:SWI48 0 "register_operand" "=r")
12176        (zero_extract:SWI48
12177          (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12178          (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12179          (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12180   (clobber (reg:CC FLAGS_REG))]
12181   "TARGET_TBM"
12182{
12183  operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12184  return "bextr\t{%2, %1, %0|%0, %1, %2}";
12185}
12186  [(set_attr "type" "bitmanip")
12187   (set_attr "mode" "<MODE>")])
12188
12189(define_insn "*tbm_blcfill_<mode>"
12190  [(set (match_operand:SWI48 0 "register_operand" "=r")
12191        (and:SWI48
12192          (plus:SWI48
12193            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12194            (const_int 1))
12195          (match_dup 1)))
12196   (clobber (reg:CC FLAGS_REG))]
12197   "TARGET_TBM"
12198   "blcfill\t{%1, %0|%0, %1}"
12199  [(set_attr "type" "bitmanip")
12200   (set_attr "mode" "<MODE>")])
12201
12202(define_insn "*tbm_blci_<mode>"
12203  [(set (match_operand:SWI48 0 "register_operand" "=r")
12204        (ior:SWI48
12205          (not:SWI48
12206            (plus:SWI48
12207              (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12208              (const_int 1)))
12209          (match_dup 1)))
12210   (clobber (reg:CC FLAGS_REG))]
12211   "TARGET_TBM"
12212   "blci\t{%1, %0|%0, %1}"
12213  [(set_attr "type" "bitmanip")
12214   (set_attr "mode" "<MODE>")])
12215
12216(define_insn "*tbm_blcic_<mode>"
12217  [(set (match_operand:SWI48 0 "register_operand" "=r")
12218        (and:SWI48
12219          (plus:SWI48
12220            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12221            (const_int 1))
12222          (not:SWI48
12223            (match_dup 1))))
12224   (clobber (reg:CC FLAGS_REG))]
12225   "TARGET_TBM"
12226   "blcic\t{%1, %0|%0, %1}"
12227  [(set_attr "type" "bitmanip")
12228   (set_attr "mode" "<MODE>")])
12229
12230(define_insn "*tbm_blcmsk_<mode>"
12231  [(set (match_operand:SWI48 0 "register_operand" "=r")
12232        (xor:SWI48
12233          (plus:SWI48
12234            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235            (const_int 1))
12236          (match_dup 1)))
12237   (clobber (reg:CC FLAGS_REG))]
12238   "TARGET_TBM"
12239   "blcmsk\t{%1, %0|%0, %1}"
12240  [(set_attr "type" "bitmanip")
12241   (set_attr "mode" "<MODE>")])
12242
12243(define_insn "*tbm_blcs_<mode>"
12244  [(set (match_operand:SWI48 0 "register_operand" "=r")
12245        (ior:SWI48
12246          (plus:SWI48
12247            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12248            (const_int 1))
12249          (match_dup 1)))
12250   (clobber (reg:CC FLAGS_REG))]
12251   "TARGET_TBM"
12252   "blcs\t{%1, %0|%0, %1}"
12253  [(set_attr "type" "bitmanip")
12254   (set_attr "mode" "<MODE>")])
12255
12256(define_insn "*tbm_blsfill_<mode>"
12257  [(set (match_operand:SWI48 0 "register_operand" "=r")
12258        (ior:SWI48
12259          (plus:SWI48
12260            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12261            (const_int -1))
12262          (match_dup 1)))
12263   (clobber (reg:CC FLAGS_REG))]
12264   "TARGET_TBM"
12265   "blsfill\t{%1, %0|%0, %1}"
12266  [(set_attr "type" "bitmanip")
12267   (set_attr "mode" "<MODE>")])
12268
12269(define_insn "*tbm_blsic_<mode>"
12270  [(set (match_operand:SWI48 0 "register_operand" "=r")
12271        (ior:SWI48
12272          (plus:SWI48
12273            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12274            (const_int -1))
12275          (not:SWI48
12276            (match_dup 1))))
12277   (clobber (reg:CC FLAGS_REG))]
12278   "TARGET_TBM"
12279   "blsic\t{%1, %0|%0, %1}"
12280  [(set_attr "type" "bitmanip")
12281   (set_attr "mode" "<MODE>")])
12282
12283(define_insn "*tbm_t1mskc_<mode>"
12284  [(set (match_operand:SWI48 0 "register_operand" "=r")
12285        (ior:SWI48
12286          (plus:SWI48
12287            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12288            (const_int 1))
12289          (not:SWI48
12290            (match_dup 1))))
12291   (clobber (reg:CC FLAGS_REG))]
12292   "TARGET_TBM"
12293   "t1mskc\t{%1, %0|%0, %1}"
12294  [(set_attr "type" "bitmanip")
12295   (set_attr "mode" "<MODE>")])
12296
12297(define_insn "*tbm_tzmsk_<mode>"
12298  [(set (match_operand:SWI48 0 "register_operand" "=r")
12299        (and:SWI48
12300          (plus:SWI48
12301            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12302            (const_int -1))
12303          (not:SWI48
12304            (match_dup 1))))
12305   (clobber (reg:CC FLAGS_REG))]
12306   "TARGET_TBM"
12307   "tzmsk\t{%1, %0|%0, %1}"
12308  [(set_attr "type" "bitmanip")
12309   (set_attr "mode" "<MODE>")])
12310
12311(define_insn "bsr_rex64"
12312  [(set (match_operand:DI 0 "register_operand" "=r")
12313	(minus:DI (const_int 63)
12314		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12315   (clobber (reg:CC FLAGS_REG))]
12316  "TARGET_64BIT"
12317  "bsr{q}\t{%1, %0|%0, %1}"
12318  [(set_attr "type" "alu1")
12319   (set_attr "prefix_0f" "1")
12320   (set_attr "mode" "DI")])
12321
12322(define_insn "bsr"
12323  [(set (match_operand:SI 0 "register_operand" "=r")
12324	(minus:SI (const_int 31)
12325		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12326   (clobber (reg:CC FLAGS_REG))]
12327  ""
12328  "bsr{l}\t{%1, %0|%0, %1}"
12329  [(set_attr "type" "alu1")
12330   (set_attr "prefix_0f" "1")
12331   (set_attr "mode" "SI")])
12332
12333(define_insn "*bsrhi"
12334  [(set (match_operand:HI 0 "register_operand" "=r")
12335	(minus:HI (const_int 15)
12336		  (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12337   (clobber (reg:CC FLAGS_REG))]
12338  ""
12339  "bsr{w}\t{%1, %0|%0, %1}"
12340  [(set_attr "type" "alu1")
12341   (set_attr "prefix_0f" "1")
12342   (set_attr "mode" "HI")])
12343
12344(define_insn "popcount<mode>2"
12345  [(set (match_operand:SWI248 0 "register_operand" "=r")
12346	(popcount:SWI248
12347	  (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12348   (clobber (reg:CC FLAGS_REG))]
12349  "TARGET_POPCNT"
12350{
12351#if TARGET_MACHO
12352  return "popcnt\t{%1, %0|%0, %1}";
12353#else
12354  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12355#endif
12356}
12357  [(set_attr "prefix_rep" "1")
12358   (set_attr "type" "bitmanip")
12359   (set_attr "mode" "<MODE>")])
12360
12361(define_insn "*popcount<mode>2_cmp"
12362  [(set (reg FLAGS_REG)
12363	(compare
12364	  (popcount:SWI248
12365	    (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12366	  (const_int 0)))
12367   (set (match_operand:SWI248 0 "register_operand" "=r")
12368	(popcount:SWI248 (match_dup 1)))]
12369  "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12370{
12371#if TARGET_MACHO
12372  return "popcnt\t{%1, %0|%0, %1}";
12373#else
12374  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12375#endif
12376}
12377  [(set_attr "prefix_rep" "1")
12378   (set_attr "type" "bitmanip")
12379   (set_attr "mode" "<MODE>")])
12380
12381(define_insn "*popcountsi2_cmp_zext"
12382  [(set (reg FLAGS_REG)
12383        (compare
12384          (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12385          (const_int 0)))
12386   (set (match_operand:DI 0 "register_operand" "=r")
12387        (zero_extend:DI(popcount:SI (match_dup 1))))]
12388  "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12389{
12390#if TARGET_MACHO
12391  return "popcnt\t{%1, %0|%0, %1}";
12392#else
12393  return "popcnt{l}\t{%1, %0|%0, %1}";
12394#endif
12395}
12396  [(set_attr "prefix_rep" "1")
12397   (set_attr "type" "bitmanip")
12398   (set_attr "mode" "SI")])
12399
12400(define_expand "bswap<mode>2"
12401  [(set (match_operand:SWI48 0 "register_operand" "")
12402	(bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12403  ""
12404{
12405  if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12406    {
12407      rtx x = operands[0];
12408
12409      emit_move_insn (x, operands[1]);
12410      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12411      emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12412      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12413      DONE;
12414    }
12415})
12416
12417(define_insn "*bswap<mode>2_movbe"
12418  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12419	(bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12420  "TARGET_MOVBE
12421   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12422  "@
12423    bswap\t%0
12424    movbe\t{%1, %0|%0, %1}
12425    movbe\t{%1, %0|%0, %1}"
12426  [(set_attr "type" "bitmanip,imov,imov")
12427   (set_attr "modrm" "0,1,1")
12428   (set_attr "prefix_0f" "*,1,1")
12429   (set_attr "prefix_extra" "*,1,1")
12430   (set_attr "mode" "<MODE>")])
12431
12432(define_insn "*bswap<mode>2_1"
12433  [(set (match_operand:SWI48 0 "register_operand" "=r")
12434	(bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12435  "TARGET_BSWAP"
12436  "bswap\t%0"
12437  [(set_attr "type" "bitmanip")
12438   (set_attr "modrm" "0")
12439   (set_attr "mode" "<MODE>")])
12440
12441(define_insn "*bswaphi_lowpart_1"
12442  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12443	(bswap:HI (match_dup 0)))
12444   (clobber (reg:CC FLAGS_REG))]
12445  "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12446  "@
12447    xchg{b}\t{%h0, %b0|%b0, %h0}
12448    rol{w}\t{$8, %0|%0, 8}"
12449  [(set_attr "length" "2,4")
12450   (set_attr "mode" "QI,HI")])
12451
12452(define_insn "bswaphi_lowpart"
12453  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12454	(bswap:HI (match_dup 0)))
12455   (clobber (reg:CC FLAGS_REG))]
12456  ""
12457  "rol{w}\t{$8, %0|%0, 8}"
12458  [(set_attr "length" "4")
12459   (set_attr "mode" "HI")])
12460
12461(define_expand "paritydi2"
12462  [(set (match_operand:DI 0 "register_operand" "")
12463	(parity:DI (match_operand:DI 1 "register_operand" "")))]
12464  "! TARGET_POPCNT"
12465{
12466  rtx scratch = gen_reg_rtx (QImode);
12467  rtx cond;
12468
12469  emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12470				NULL_RTX, operands[1]));
12471
12472  cond = gen_rtx_fmt_ee (ORDERED, QImode,
12473			 gen_rtx_REG (CCmode, FLAGS_REG),
12474			 const0_rtx);
12475  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12476
12477  if (TARGET_64BIT)
12478    emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12479  else
12480    {
12481      rtx tmp = gen_reg_rtx (SImode);
12482
12483      emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12484      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12485    }
12486  DONE;
12487})
12488
12489(define_expand "paritysi2"
12490  [(set (match_operand:SI 0 "register_operand" "")
12491	(parity:SI (match_operand:SI 1 "register_operand" "")))]
12492  "! TARGET_POPCNT"
12493{
12494  rtx scratch = gen_reg_rtx (QImode);
12495  rtx cond;
12496
12497  emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12498
12499  cond = gen_rtx_fmt_ee (ORDERED, QImode,
12500			 gen_rtx_REG (CCmode, FLAGS_REG),
12501			 const0_rtx);
12502  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12503
12504  emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12505  DONE;
12506})
12507
12508(define_insn_and_split "paritydi2_cmp"
12509  [(set (reg:CC FLAGS_REG)
12510	(unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12511		   UNSPEC_PARITY))
12512   (clobber (match_scratch:DI 0 "=r"))
12513   (clobber (match_scratch:SI 1 "=&r"))
12514   (clobber (match_scratch:HI 2 "=Q"))]
12515  "! TARGET_POPCNT"
12516  "#"
12517  "&& reload_completed"
12518  [(parallel
12519     [(set (match_dup 1)
12520	   (xor:SI (match_dup 1) (match_dup 4)))
12521      (clobber (reg:CC FLAGS_REG))])
12522   (parallel
12523     [(set (reg:CC FLAGS_REG)
12524	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12525      (clobber (match_dup 1))
12526      (clobber (match_dup 2))])]
12527{
12528  operands[4] = gen_lowpart (SImode, operands[3]);
12529
12530  if (TARGET_64BIT)
12531    {
12532      emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12533      emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12534    }
12535  else
12536    operands[1] = gen_highpart (SImode, operands[3]);
12537})
12538
12539(define_insn_and_split "paritysi2_cmp"
12540  [(set (reg:CC FLAGS_REG)
12541	(unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12542		   UNSPEC_PARITY))
12543   (clobber (match_scratch:SI 0 "=r"))
12544   (clobber (match_scratch:HI 1 "=&Q"))]
12545  "! TARGET_POPCNT"
12546  "#"
12547  "&& reload_completed"
12548  [(parallel
12549     [(set (match_dup 1)
12550	   (xor:HI (match_dup 1) (match_dup 3)))
12551      (clobber (reg:CC FLAGS_REG))])
12552   (parallel
12553     [(set (reg:CC FLAGS_REG)
12554	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12555      (clobber (match_dup 1))])]
12556{
12557  operands[3] = gen_lowpart (HImode, operands[2]);
12558
12559  emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12560  emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12561})
12562
12563(define_insn "*parityhi2_cmp"
12564  [(set (reg:CC FLAGS_REG)
12565	(unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12566		   UNSPEC_PARITY))
12567   (clobber (match_scratch:HI 0 "=Q"))]
12568  "! TARGET_POPCNT"
12569  "xor{b}\t{%h0, %b0|%b0, %h0}"
12570  [(set_attr "length" "2")
12571   (set_attr "mode" "HI")])
12572
12573
12574;; Thread-local storage patterns for ELF.
12575;;
12576;; Note that these code sequences must appear exactly as shown
12577;; in order to allow linker relaxation.
12578
12579(define_insn "*tls_global_dynamic_32_gnu"
12580  [(set (match_operand:SI 0 "register_operand" "=a")
12581	(unspec:SI
12582	 [(match_operand:SI 1 "register_operand" "b")
12583	  (match_operand:SI 2 "tls_symbolic_operand" "")
12584	  (match_operand:SI 3 "constant_call_address_operand" "z")]
12585	 UNSPEC_TLS_GD))
12586   (clobber (match_scratch:SI 4 "=d"))
12587   (clobber (match_scratch:SI 5 "=c"))
12588   (clobber (reg:CC FLAGS_REG))]
12589  "!TARGET_64BIT && TARGET_GNU_TLS"
12590{
12591  output_asm_insn
12592    ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12593  if (TARGET_SUN_TLS)
12594#ifdef HAVE_AS_IX86_TLSGDPLT
12595    return "call\t%a2@tlsgdplt";
12596#else
12597    return "call\t%p3@plt";
12598#endif
12599  return "call\t%P3";
12600}
12601  [(set_attr "type" "multi")
12602   (set_attr "length" "12")])
12603
12604(define_expand "tls_global_dynamic_32"
12605  [(parallel
12606    [(set (match_operand:SI 0 "register_operand" "")
12607	  (unspec:SI [(match_operand:SI 2 "register_operand" "")
12608		      (match_operand:SI 1 "tls_symbolic_operand" "")
12609		      (match_operand:SI 3 "constant_call_address_operand" "")]
12610		     UNSPEC_TLS_GD))
12611     (clobber (match_scratch:SI 4 ""))
12612     (clobber (match_scratch:SI 5 ""))
12613     (clobber (reg:CC FLAGS_REG))])])
12614
12615(define_insn "*tls_global_dynamic_64"
12616  [(set (match_operand:DI 0 "register_operand" "=a")
12617	(call:DI
12618	 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12619	 (match_operand:DI 3 "" "")))
12620   (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12621	      UNSPEC_TLS_GD)]
12622  "TARGET_64BIT"
12623{
12624  if (!TARGET_X32)
12625    fputs (ASM_BYTE "0x66\n", asm_out_file);
12626  output_asm_insn
12627    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12628  fputs (ASM_SHORT "0x6666\n", asm_out_file);
12629  fputs ("\trex64\n", asm_out_file);
12630  if (TARGET_SUN_TLS)
12631    return "call\t%p2@plt";
12632  return "call\t%P2";
12633}
12634  [(set_attr "type" "multi")
12635   (set (attr "length")
12636	(symbol_ref "TARGET_X32 ? 15 : 16"))])
12637
12638(define_expand "tls_global_dynamic_64"
12639  [(parallel
12640    [(set (match_operand:DI 0 "register_operand" "")
12641	  (call:DI
12642	   (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12643	   (const_int 0)))
12644     (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12645		UNSPEC_TLS_GD)])])
12646
12647(define_insn "*tls_local_dynamic_base_32_gnu"
12648  [(set (match_operand:SI 0 "register_operand" "=a")
12649	(unspec:SI
12650	 [(match_operand:SI 1 "register_operand" "b")
12651	  (match_operand:SI 2 "constant_call_address_operand" "z")]
12652	 UNSPEC_TLS_LD_BASE))
12653   (clobber (match_scratch:SI 3 "=d"))
12654   (clobber (match_scratch:SI 4 "=c"))
12655   (clobber (reg:CC FLAGS_REG))]
12656  "!TARGET_64BIT && TARGET_GNU_TLS"
12657{
12658  output_asm_insn
12659    ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12660  if (TARGET_SUN_TLS)
12661#ifdef HAVE_AS_IX86_TLSLDMPLT
12662    return "call\t%&@tlsldmplt";
12663#else
12664    return "call\t%p2@plt";
12665#endif
12666  return "call\t%P2";
12667}
12668  [(set_attr "type" "multi")
12669   (set_attr "length" "11")])
12670
12671(define_expand "tls_local_dynamic_base_32"
12672  [(parallel
12673     [(set (match_operand:SI 0 "register_operand" "")
12674	   (unspec:SI
12675	    [(match_operand:SI 1 "register_operand" "")
12676	     (match_operand:SI 2 "constant_call_address_operand" "")]
12677	    UNSPEC_TLS_LD_BASE))
12678      (clobber (match_scratch:SI 3 ""))
12679      (clobber (match_scratch:SI 4 ""))
12680      (clobber (reg:CC FLAGS_REG))])])
12681
12682(define_insn "*tls_local_dynamic_base_64"
12683  [(set (match_operand:DI 0 "register_operand" "=a")
12684	(call:DI
12685	 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12686	 (match_operand:DI 2 "" "")))
12687   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12688  "TARGET_64BIT"
12689{
12690  output_asm_insn
12691    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12692  if (TARGET_SUN_TLS)
12693    return "call\t%p1@plt";
12694  return "call\t%P1";
12695}
12696  [(set_attr "type" "multi")
12697   (set_attr "length" "12")])
12698
12699(define_expand "tls_local_dynamic_base_64"
12700  [(parallel
12701     [(set (match_operand:DI 0 "register_operand" "")
12702	   (call:DI
12703	    (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12704	    (const_int 0)))
12705      (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12706
12707;; Local dynamic of a single variable is a lose.  Show combine how
12708;; to convert that back to global dynamic.
12709
12710(define_insn_and_split "*tls_local_dynamic_32_once"
12711  [(set (match_operand:SI 0 "register_operand" "=a")
12712	(plus:SI
12713	 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12714		     (match_operand:SI 2 "constant_call_address_operand" "z")]
12715		    UNSPEC_TLS_LD_BASE)
12716	 (const:SI (unspec:SI
12717		    [(match_operand:SI 3 "tls_symbolic_operand" "")]
12718		    UNSPEC_DTPOFF))))
12719   (clobber (match_scratch:SI 4 "=d"))
12720   (clobber (match_scratch:SI 5 "=c"))
12721   (clobber (reg:CC FLAGS_REG))]
12722  ""
12723  "#"
12724  ""
12725  [(parallel
12726     [(set (match_dup 0)
12727	   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12728		      UNSPEC_TLS_GD))
12729      (clobber (match_dup 4))
12730      (clobber (match_dup 5))
12731      (clobber (reg:CC FLAGS_REG))])])
12732
12733;; Segment register for the thread base ptr load
12734(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12735
12736;; Load and add the thread base pointer from %<tp_seg>:0.
12737(define_insn "*load_tp_x32"
12738  [(set (match_operand:SI 0 "register_operand" "=r")
12739	(unspec:SI [(const_int 0)] UNSPEC_TP))]
12740  "TARGET_X32"
12741  "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12742  [(set_attr "type" "imov")
12743   (set_attr "modrm" "0")
12744   (set_attr "length" "7")
12745   (set_attr "memory" "load")
12746   (set_attr "imm_disp" "false")])
12747
12748(define_insn "*load_tp_x32_zext"
12749  [(set (match_operand:DI 0 "register_operand" "=r")
12750	(zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12751  "TARGET_X32"
12752  "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12753  [(set_attr "type" "imov")
12754   (set_attr "modrm" "0")
12755   (set_attr "length" "7")
12756   (set_attr "memory" "load")
12757   (set_attr "imm_disp" "false")])
12758
12759(define_insn "*load_tp_<mode>"
12760  [(set (match_operand:P 0 "register_operand" "=r")
12761	(unspec:P [(const_int 0)] UNSPEC_TP))]
12762  "!TARGET_X32"
12763  "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12764  [(set_attr "type" "imov")
12765   (set_attr "modrm" "0")
12766   (set_attr "length" "7")
12767   (set_attr "memory" "load")
12768   (set_attr "imm_disp" "false")])
12769
12770(define_insn "*add_tp_x32"
12771  [(set (match_operand:SI 0 "register_operand" "=r")
12772	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12773		 (match_operand:SI 1 "register_operand" "0")))
12774   (clobber (reg:CC FLAGS_REG))]
12775  "TARGET_X32"
12776  "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12777  [(set_attr "type" "alu")
12778   (set_attr "modrm" "0")
12779   (set_attr "length" "7")
12780   (set_attr "memory" "load")
12781   (set_attr "imm_disp" "false")])
12782
12783(define_insn "*add_tp_x32_zext"
12784  [(set (match_operand:DI 0 "register_operand" "=r")
12785	(zero_extend:DI
12786	  (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12787		   (match_operand:SI 1 "register_operand" "0"))))
12788   (clobber (reg:CC FLAGS_REG))]
12789  "TARGET_X32"
12790  "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12791  [(set_attr "type" "alu")
12792   (set_attr "modrm" "0")
12793   (set_attr "length" "7")
12794   (set_attr "memory" "load")
12795   (set_attr "imm_disp" "false")])
12796
12797(define_insn "*add_tp_<mode>"
12798  [(set (match_operand:P 0 "register_operand" "=r")
12799	(plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12800		(match_operand:P 1 "register_operand" "0")))
12801   (clobber (reg:CC FLAGS_REG))]
12802  "!TARGET_X32"
12803  "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12804  [(set_attr "type" "alu")
12805   (set_attr "modrm" "0")
12806   (set_attr "length" "7")
12807   (set_attr "memory" "load")
12808   (set_attr "imm_disp" "false")])
12809
12810;; The Sun linker took the AMD64 TLS spec literally and can only handle
12811;; %rax as destination of the initial executable code sequence.
12812(define_insn "tls_initial_exec_64_sun"
12813  [(set (match_operand:DI 0 "register_operand" "=a")
12814	(unspec:DI
12815	 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12816	 UNSPEC_TLS_IE_SUN))
12817   (clobber (reg:CC FLAGS_REG))]
12818  "TARGET_64BIT && TARGET_SUN_TLS"
12819{
12820  output_asm_insn
12821    ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12822  return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12823}
12824  [(set_attr "type" "multi")])
12825
12826;; GNU2 TLS patterns can be split.
12827
12828(define_expand "tls_dynamic_gnu2_32"
12829  [(set (match_dup 3)
12830	(plus:SI (match_operand:SI 2 "register_operand" "")
12831		 (const:SI
12832		  (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12833			     UNSPEC_TLSDESC))))
12834   (parallel
12835    [(set (match_operand:SI 0 "register_operand" "")
12836	  (unspec:SI [(match_dup 1) (match_dup 3)
12837		      (match_dup 2) (reg:SI SP_REG)]
12838		      UNSPEC_TLSDESC))
12839     (clobber (reg:CC FLAGS_REG))])]
12840  "!TARGET_64BIT && TARGET_GNU2_TLS"
12841{
12842  operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12843  ix86_tls_descriptor_calls_expanded_in_cfun = true;
12844})
12845
12846(define_insn "*tls_dynamic_gnu2_lea_32"
12847  [(set (match_operand:SI 0 "register_operand" "=r")
12848	(plus:SI (match_operand:SI 1 "register_operand" "b")
12849		 (const:SI
12850		  (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12851			      UNSPEC_TLSDESC))))]
12852  "!TARGET_64BIT && TARGET_GNU2_TLS"
12853  "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12854  [(set_attr "type" "lea")
12855   (set_attr "mode" "SI")
12856   (set_attr "length" "6")
12857   (set_attr "length_address" "4")])
12858
12859(define_insn "*tls_dynamic_gnu2_call_32"
12860  [(set (match_operand:SI 0 "register_operand" "=a")
12861	(unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12862		    (match_operand:SI 2 "register_operand" "0")
12863		    ;; we have to make sure %ebx still points to the GOT
12864		    (match_operand:SI 3 "register_operand" "b")
12865		    (reg:SI SP_REG)]
12866		   UNSPEC_TLSDESC))
12867   (clobber (reg:CC FLAGS_REG))]
12868  "!TARGET_64BIT && TARGET_GNU2_TLS"
12869  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12870  [(set_attr "type" "call")
12871   (set_attr "length" "2")
12872   (set_attr "length_address" "0")])
12873
12874(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12875  [(set (match_operand:SI 0 "register_operand" "=&a")
12876	(plus:SI
12877	 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12878		     (match_operand:SI 4 "" "")
12879		     (match_operand:SI 2 "register_operand" "b")
12880		     (reg:SI SP_REG)]
12881		    UNSPEC_TLSDESC)
12882	 (const:SI (unspec:SI
12883		    [(match_operand:SI 1 "tls_symbolic_operand" "")]
12884		    UNSPEC_DTPOFF))))
12885   (clobber (reg:CC FLAGS_REG))]
12886  "!TARGET_64BIT && TARGET_GNU2_TLS"
12887  "#"
12888  ""
12889  [(set (match_dup 0) (match_dup 5))]
12890{
12891  operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12892  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12893})
12894
12895(define_expand "tls_dynamic_gnu2_64"
12896  [(set (match_dup 2)
12897	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12898		   UNSPEC_TLSDESC))
12899   (parallel
12900    [(set (match_operand:DI 0 "register_operand" "")
12901	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12902		     UNSPEC_TLSDESC))
12903     (clobber (reg:CC FLAGS_REG))])]
12904  "TARGET_64BIT && TARGET_GNU2_TLS"
12905{
12906  operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12907  ix86_tls_descriptor_calls_expanded_in_cfun = true;
12908})
12909
12910(define_insn "*tls_dynamic_gnu2_lea_64"
12911  [(set (match_operand:DI 0 "register_operand" "=r")
12912	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12913		   UNSPEC_TLSDESC))]
12914  "TARGET_64BIT && TARGET_GNU2_TLS"
12915  "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12916  [(set_attr "type" "lea")
12917   (set_attr "mode" "DI")
12918   (set_attr "length" "7")
12919   (set_attr "length_address" "4")])
12920
12921(define_insn "*tls_dynamic_gnu2_call_64"
12922  [(set (match_operand:DI 0 "register_operand" "=a")
12923	(unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12924		    (match_operand:DI 2 "register_operand" "0")
12925		    (reg:DI SP_REG)]
12926		   UNSPEC_TLSDESC))
12927   (clobber (reg:CC FLAGS_REG))]
12928  "TARGET_64BIT && TARGET_GNU2_TLS"
12929  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12930  [(set_attr "type" "call")
12931   (set_attr "length" "2")
12932   (set_attr "length_address" "0")])
12933
12934(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12935  [(set (match_operand:DI 0 "register_operand" "=&a")
12936	(plus:DI
12937	 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12938		     (match_operand:DI 3 "" "")
12939		     (reg:DI SP_REG)]
12940		    UNSPEC_TLSDESC)
12941	 (const:DI (unspec:DI
12942		    [(match_operand 1 "tls_symbolic_operand" "")]
12943		    UNSPEC_DTPOFF))))
12944   (clobber (reg:CC FLAGS_REG))]
12945  "TARGET_64BIT && TARGET_GNU2_TLS"
12946  "#"
12947  ""
12948  [(set (match_dup 0) (match_dup 4))]
12949{
12950  operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12951  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12952})
12953
12954;; These patterns match the binary 387 instructions for addM3, subM3,
12955;; mulM3 and divM3.  There are three patterns for each of DFmode and
12956;; SFmode.  The first is the normal insn, the second the same insn but
12957;; with one operand a conversion, and the third the same insn but with
12958;; the other operand a conversion.  The conversion may be SFmode or
12959;; SImode if the target mode DFmode, but only SImode if the target mode
12960;; is SFmode.
12961
12962;; Gcc is slightly more smart about handling normal two address instructions
12963;; so use special patterns for add and mull.
12964
12965(define_insn "*fop_<mode>_comm_mixed"
12966  [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12967	(match_operator:MODEF 3 "binary_fp_operator"
12968	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12969	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12970  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12971   && COMMUTATIVE_ARITH_P (operands[3])
12972   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12973  "* return output_387_binary_op (insn, operands);"
12974  [(set (attr "type")
12975	(if_then_else (eq_attr "alternative" "1,2")
12976	   (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12977	      (const_string "ssemul")
12978	      (const_string "sseadd"))
12979	   (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12980	      (const_string "fmul")
12981	      (const_string "fop"))))
12982   (set_attr "isa" "*,noavx,avx")
12983   (set_attr "prefix" "orig,orig,vex")
12984   (set_attr "mode" "<MODE>")])
12985
12986(define_insn "*fop_<mode>_comm_sse"
12987  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12988	(match_operator:MODEF 3 "binary_fp_operator"
12989	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12990	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12991  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12992   && COMMUTATIVE_ARITH_P (operands[3])
12993   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12994  "* return output_387_binary_op (insn, operands);"
12995  [(set (attr "type")
12996        (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12997	   (const_string "ssemul")
12998	   (const_string "sseadd")))
12999   (set_attr "isa" "noavx,avx")
13000   (set_attr "prefix" "orig,vex")
13001   (set_attr "mode" "<MODE>")])
13002
13003(define_insn "*fop_<mode>_comm_i387"
13004  [(set (match_operand:MODEF 0 "register_operand" "=f")
13005	(match_operator:MODEF 3 "binary_fp_operator"
13006	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13007	   (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13008  "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13009   && COMMUTATIVE_ARITH_P (operands[3])
13010   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13011  "* return output_387_binary_op (insn, operands);"
13012  [(set (attr "type")
13013	(if_then_else (match_operand:MODEF 3 "mult_operator" "")
13014	   (const_string "fmul")
13015	   (const_string "fop")))
13016   (set_attr "mode" "<MODE>")])
13017
13018(define_insn "*fop_<mode>_1_mixed"
13019  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13020	(match_operator:MODEF 3 "binary_fp_operator"
13021	  [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13022	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13023  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13024   && !COMMUTATIVE_ARITH_P (operands[3])
13025   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13026  "* return output_387_binary_op (insn, operands);"
13027  [(set (attr "type")
13028        (cond [(and (eq_attr "alternative" "2,3")
13029	            (match_operand:MODEF 3 "mult_operator" ""))
13030                 (const_string "ssemul")
13031	       (and (eq_attr "alternative" "2,3")
13032	            (match_operand:MODEF 3 "div_operator" ""))
13033                 (const_string "ssediv")
13034	       (eq_attr "alternative" "2,3")
13035                 (const_string "sseadd")
13036	       (match_operand:MODEF 3 "mult_operator" "")
13037                 (const_string "fmul")
13038               (match_operand:MODEF 3 "div_operator" "")
13039                 (const_string "fdiv")
13040              ]
13041              (const_string "fop")))
13042   (set_attr "isa" "*,*,noavx,avx")
13043   (set_attr "prefix" "orig,orig,orig,vex")
13044   (set_attr "mode" "<MODE>")])
13045
13046(define_insn "*rcpsf2_sse"
13047  [(set (match_operand:SF 0 "register_operand" "=x")
13048	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13049		   UNSPEC_RCP))]
13050  "TARGET_SSE_MATH"
13051  "%vrcpss\t{%1, %d0|%d0, %1}"
13052  [(set_attr "type" "sse")
13053   (set_attr "atom_sse_attr" "rcp")
13054   (set_attr "prefix" "maybe_vex")
13055   (set_attr "mode" "SF")])
13056
13057(define_insn "*fop_<mode>_1_sse"
13058  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13059	(match_operator:MODEF 3 "binary_fp_operator"
13060	  [(match_operand:MODEF 1 "register_operand" "0,x")
13061	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13062  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13063   && !COMMUTATIVE_ARITH_P (operands[3])"
13064  "* return output_387_binary_op (insn, operands);"
13065  [(set (attr "type")
13066        (cond [(match_operand:MODEF 3 "mult_operator" "")
13067                 (const_string "ssemul")
13068	       (match_operand:MODEF 3 "div_operator" "")
13069                 (const_string "ssediv")
13070              ]
13071              (const_string "sseadd")))
13072   (set_attr "isa" "noavx,avx")
13073   (set_attr "prefix" "orig,vex")
13074   (set_attr "mode" "<MODE>")])
13075
13076;; This pattern is not fully shadowed by the pattern above.
13077(define_insn "*fop_<mode>_1_i387"
13078  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13079	(match_operator:MODEF 3 "binary_fp_operator"
13080	  [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13081	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13082  "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13083   && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13084   && !COMMUTATIVE_ARITH_P (operands[3])
13085   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13086  "* return output_387_binary_op (insn, operands);"
13087  [(set (attr "type")
13088        (cond [(match_operand:MODEF 3 "mult_operator" "")
13089                 (const_string "fmul")
13090               (match_operand:MODEF 3 "div_operator" "")
13091                 (const_string "fdiv")
13092              ]
13093              (const_string "fop")))
13094   (set_attr "mode" "<MODE>")])
13095
13096;; ??? Add SSE splitters for these!
13097(define_insn "*fop_<MODEF:mode>_2_i387"
13098  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13099	(match_operator:MODEF 3 "binary_fp_operator"
13100	  [(float:MODEF
13101	     (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13102	   (match_operand:MODEF 2 "register_operand" "0,0")]))]
13103  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13104   && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13105   && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13106  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13107  [(set (attr "type")
13108        (cond [(match_operand:MODEF 3 "mult_operator" "")
13109                 (const_string "fmul")
13110               (match_operand:MODEF 3 "div_operator" "")
13111                 (const_string "fdiv")
13112              ]
13113              (const_string "fop")))
13114   (set_attr "fp_int_src" "true")
13115   (set_attr "mode" "<SWI24:MODE>")])
13116
13117(define_insn "*fop_<MODEF:mode>_3_i387"
13118  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13119	(match_operator:MODEF 3 "binary_fp_operator"
13120	  [(match_operand:MODEF 1 "register_operand" "0,0")
13121	   (float:MODEF
13122	     (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13123  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13124   && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13125   && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13126  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13127  [(set (attr "type")
13128        (cond [(match_operand:MODEF 3 "mult_operator" "")
13129                 (const_string "fmul")
13130               (match_operand:MODEF 3 "div_operator" "")
13131                 (const_string "fdiv")
13132              ]
13133              (const_string "fop")))
13134   (set_attr "fp_int_src" "true")
13135   (set_attr "mode" "<MODE>")])
13136
13137(define_insn "*fop_df_4_i387"
13138  [(set (match_operand:DF 0 "register_operand" "=f,f")
13139	(match_operator:DF 3 "binary_fp_operator"
13140	   [(float_extend:DF
13141	     (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13142	    (match_operand:DF 2 "register_operand" "0,f")]))]
13143  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13144   && !(TARGET_SSE2 && TARGET_SSE_MATH)
13145   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13146  "* return output_387_binary_op (insn, operands);"
13147  [(set (attr "type")
13148        (cond [(match_operand:DF 3 "mult_operator" "")
13149                 (const_string "fmul")
13150               (match_operand:DF 3 "div_operator" "")
13151                 (const_string "fdiv")
13152              ]
13153              (const_string "fop")))
13154   (set_attr "mode" "SF")])
13155
13156(define_insn "*fop_df_5_i387"
13157  [(set (match_operand:DF 0 "register_operand" "=f,f")
13158	(match_operator:DF 3 "binary_fp_operator"
13159	  [(match_operand:DF 1 "register_operand" "0,f")
13160	   (float_extend:DF
13161	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13162  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13163   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13164  "* return output_387_binary_op (insn, operands);"
13165  [(set (attr "type")
13166        (cond [(match_operand:DF 3 "mult_operator" "")
13167                 (const_string "fmul")
13168               (match_operand:DF 3 "div_operator" "")
13169                 (const_string "fdiv")
13170              ]
13171              (const_string "fop")))
13172   (set_attr "mode" "SF")])
13173
13174(define_insn "*fop_df_6_i387"
13175  [(set (match_operand:DF 0 "register_operand" "=f,f")
13176	(match_operator:DF 3 "binary_fp_operator"
13177	  [(float_extend:DF
13178	    (match_operand:SF 1 "register_operand" "0,f"))
13179	   (float_extend:DF
13180	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13181  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13182   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13183  "* return output_387_binary_op (insn, operands);"
13184  [(set (attr "type")
13185        (cond [(match_operand:DF 3 "mult_operator" "")
13186                 (const_string "fmul")
13187               (match_operand:DF 3 "div_operator" "")
13188                 (const_string "fdiv")
13189              ]
13190              (const_string "fop")))
13191   (set_attr "mode" "SF")])
13192
13193(define_insn "*fop_xf_comm_i387"
13194  [(set (match_operand:XF 0 "register_operand" "=f")
13195	(match_operator:XF 3 "binary_fp_operator"
13196			[(match_operand:XF 1 "register_operand" "%0")
13197			 (match_operand:XF 2 "register_operand" "f")]))]
13198  "TARGET_80387
13199   && COMMUTATIVE_ARITH_P (operands[3])"
13200  "* return output_387_binary_op (insn, operands);"
13201  [(set (attr "type")
13202        (if_then_else (match_operand:XF 3 "mult_operator" "")
13203           (const_string "fmul")
13204           (const_string "fop")))
13205   (set_attr "mode" "XF")])
13206
13207(define_insn "*fop_xf_1_i387"
13208  [(set (match_operand:XF 0 "register_operand" "=f,f")
13209	(match_operator:XF 3 "binary_fp_operator"
13210			[(match_operand:XF 1 "register_operand" "0,f")
13211			 (match_operand:XF 2 "register_operand" "f,0")]))]
13212  "TARGET_80387
13213   && !COMMUTATIVE_ARITH_P (operands[3])"
13214  "* return output_387_binary_op (insn, operands);"
13215  [(set (attr "type")
13216        (cond [(match_operand:XF 3 "mult_operator" "")
13217                 (const_string "fmul")
13218               (match_operand:XF 3 "div_operator" "")
13219                 (const_string "fdiv")
13220              ]
13221              (const_string "fop")))
13222   (set_attr "mode" "XF")])
13223
13224(define_insn "*fop_xf_2_i387"
13225  [(set (match_operand:XF 0 "register_operand" "=f,f")
13226	(match_operator:XF 3 "binary_fp_operator"
13227	  [(float:XF
13228	     (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13229	   (match_operand:XF 2 "register_operand" "0,0")]))]
13230  "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13231  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13232  [(set (attr "type")
13233        (cond [(match_operand:XF 3 "mult_operator" "")
13234                 (const_string "fmul")
13235               (match_operand:XF 3 "div_operator" "")
13236                 (const_string "fdiv")
13237              ]
13238              (const_string "fop")))
13239   (set_attr "fp_int_src" "true")
13240   (set_attr "mode" "<MODE>")])
13241
13242(define_insn "*fop_xf_3_i387"
13243  [(set (match_operand:XF 0 "register_operand" "=f,f")
13244	(match_operator:XF 3 "binary_fp_operator"
13245	  [(match_operand:XF 1 "register_operand" "0,0")
13246	   (float:XF
13247	     (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13248  "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13249  "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13250  [(set (attr "type")
13251        (cond [(match_operand:XF 3 "mult_operator" "")
13252                 (const_string "fmul")
13253               (match_operand:XF 3 "div_operator" "")
13254                 (const_string "fdiv")
13255              ]
13256              (const_string "fop")))
13257   (set_attr "fp_int_src" "true")
13258   (set_attr "mode" "<MODE>")])
13259
13260(define_insn "*fop_xf_4_i387"
13261  [(set (match_operand:XF 0 "register_operand" "=f,f")
13262	(match_operator:XF 3 "binary_fp_operator"
13263	   [(float_extend:XF
13264	      (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13265	    (match_operand:XF 2 "register_operand" "0,f")]))]
13266  "TARGET_80387"
13267  "* return output_387_binary_op (insn, operands);"
13268  [(set (attr "type")
13269        (cond [(match_operand:XF 3 "mult_operator" "")
13270                 (const_string "fmul")
13271               (match_operand:XF 3 "div_operator" "")
13272                 (const_string "fdiv")
13273              ]
13274              (const_string "fop")))
13275   (set_attr "mode" "<MODE>")])
13276
13277(define_insn "*fop_xf_5_i387"
13278  [(set (match_operand:XF 0 "register_operand" "=f,f")
13279	(match_operator:XF 3 "binary_fp_operator"
13280	  [(match_operand:XF 1 "register_operand" "0,f")
13281	   (float_extend:XF
13282	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13283  "TARGET_80387"
13284  "* return output_387_binary_op (insn, operands);"
13285  [(set (attr "type")
13286        (cond [(match_operand:XF 3 "mult_operator" "")
13287                 (const_string "fmul")
13288               (match_operand:XF 3 "div_operator" "")
13289                 (const_string "fdiv")
13290              ]
13291              (const_string "fop")))
13292   (set_attr "mode" "<MODE>")])
13293
13294(define_insn "*fop_xf_6_i387"
13295  [(set (match_operand:XF 0 "register_operand" "=f,f")
13296	(match_operator:XF 3 "binary_fp_operator"
13297	  [(float_extend:XF
13298	     (match_operand:MODEF 1 "register_operand" "0,f"))
13299	   (float_extend:XF
13300	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13301  "TARGET_80387"
13302  "* return output_387_binary_op (insn, operands);"
13303  [(set (attr "type")
13304        (cond [(match_operand:XF 3 "mult_operator" "")
13305                 (const_string "fmul")
13306               (match_operand:XF 3 "div_operator" "")
13307                 (const_string "fdiv")
13308              ]
13309              (const_string "fop")))
13310   (set_attr "mode" "<MODE>")])
13311
13312(define_split
13313  [(set (match_operand 0 "register_operand" "")
13314	(match_operator 3 "binary_fp_operator"
13315	   [(float (match_operand:SWI24 1 "register_operand" ""))
13316	    (match_operand 2 "register_operand" "")]))]
13317  "reload_completed
13318   && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13319   && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13320  [(const_int 0)]
13321{
13322  operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13323  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13324  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13325			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
13326					  GET_MODE (operands[3]),
13327					  operands[4],
13328					  operands[2])));
13329  ix86_free_from_memory (GET_MODE (operands[1]));
13330  DONE;
13331})
13332
13333(define_split
13334  [(set (match_operand 0 "register_operand" "")
13335	(match_operator 3 "binary_fp_operator"
13336	   [(match_operand 1 "register_operand" "")
13337	    (float (match_operand:SWI24 2 "register_operand" ""))]))]
13338  "reload_completed
13339   && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13340   && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13341  [(const_int 0)]
13342{
13343  operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13344  operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13345  emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13346			  gen_rtx_fmt_ee (GET_CODE (operands[3]),
13347					  GET_MODE (operands[3]),
13348					  operands[1],
13349					  operands[4])));
13350  ix86_free_from_memory (GET_MODE (operands[2]));
13351  DONE;
13352})
13353
13354;; FPU special functions.
13355
13356;; This pattern implements a no-op XFmode truncation for
13357;; all fancy i386 XFmode math functions.
13358
13359(define_insn "truncxf<mode>2_i387_noop_unspec"
13360  [(set (match_operand:MODEF 0 "register_operand" "=f")
13361	(unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13362	UNSPEC_TRUNC_NOOP))]
13363  "TARGET_USE_FANCY_MATH_387"
13364  "* return output_387_reg_move (insn, operands);"
13365  [(set_attr "type" "fmov")
13366   (set_attr "mode" "<MODE>")])
13367
13368(define_insn "sqrtxf2"
13369  [(set (match_operand:XF 0 "register_operand" "=f")
13370	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13371  "TARGET_USE_FANCY_MATH_387"
13372  "fsqrt"
13373  [(set_attr "type" "fpspc")
13374   (set_attr "mode" "XF")
13375   (set_attr "athlon_decode" "direct")
13376   (set_attr "amdfam10_decode" "direct")
13377   (set_attr "bdver1_decode" "direct")])
13378
13379(define_insn "sqrt_extend<mode>xf2_i387"
13380  [(set (match_operand:XF 0 "register_operand" "=f")
13381	(sqrt:XF
13382	  (float_extend:XF
13383	    (match_operand:MODEF 1 "register_operand" "0"))))]
13384  "TARGET_USE_FANCY_MATH_387"
13385  "fsqrt"
13386  [(set_attr "type" "fpspc")
13387   (set_attr "mode" "XF")
13388   (set_attr "athlon_decode" "direct")
13389   (set_attr "amdfam10_decode" "direct")
13390   (set_attr "bdver1_decode" "direct")])
13391
13392(define_insn "*rsqrtsf2_sse"
13393  [(set (match_operand:SF 0 "register_operand" "=x")
13394	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13395		   UNSPEC_RSQRT))]
13396  "TARGET_SSE_MATH"
13397  "%vrsqrtss\t{%1, %d0|%d0, %1}"
13398  [(set_attr "type" "sse")
13399   (set_attr "atom_sse_attr" "rcp")
13400   (set_attr "prefix" "maybe_vex")
13401   (set_attr "mode" "SF")])
13402
13403(define_expand "rsqrtsf2"
13404  [(set (match_operand:SF 0 "register_operand" "")
13405	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13406		   UNSPEC_RSQRT))]
13407  "TARGET_SSE_MATH"
13408{
13409  ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13410  DONE;
13411})
13412
13413(define_insn "*sqrt<mode>2_sse"
13414  [(set (match_operand:MODEF 0 "register_operand" "=x")
13415	(sqrt:MODEF
13416	  (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13417  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13418  "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13419  [(set_attr "type" "sse")
13420   (set_attr "atom_sse_attr" "sqrt")
13421   (set_attr "prefix" "maybe_vex")
13422   (set_attr "mode" "<MODE>")
13423   (set_attr "athlon_decode" "*")
13424   (set_attr "amdfam10_decode" "*")
13425   (set_attr "bdver1_decode" "*")])
13426
13427(define_expand "sqrt<mode>2"
13428  [(set (match_operand:MODEF 0 "register_operand" "")
13429	(sqrt:MODEF
13430	  (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13431  "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13432   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13433{
13434  if (<MODE>mode == SFmode
13435      && TARGET_SSE_MATH
13436      && TARGET_RECIP_SQRT
13437      && !optimize_function_for_size_p (cfun)
13438      && flag_finite_math_only && !flag_trapping_math
13439      && flag_unsafe_math_optimizations)
13440    {
13441      ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13442      DONE;
13443    }
13444
13445  if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13446    {
13447      rtx op0 = gen_reg_rtx (XFmode);
13448      rtx op1 = force_reg (<MODE>mode, operands[1]);
13449
13450      emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13451      emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13452      DONE;
13453   }
13454})
13455
13456(define_insn "fpremxf4_i387"
13457  [(set (match_operand:XF 0 "register_operand" "=f")
13458	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
13459		    (match_operand:XF 3 "register_operand" "1")]
13460		   UNSPEC_FPREM_F))
13461   (set (match_operand:XF 1 "register_operand" "=u")
13462	(unspec:XF [(match_dup 2) (match_dup 3)]
13463		   UNSPEC_FPREM_U))
13464   (set (reg:CCFP FPSR_REG)
13465	(unspec:CCFP [(match_dup 2) (match_dup 3)]
13466		     UNSPEC_C2_FLAG))]
13467  "TARGET_USE_FANCY_MATH_387"
13468  "fprem"
13469  [(set_attr "type" "fpspc")
13470   (set_attr "mode" "XF")])
13471
13472(define_expand "fmodxf3"
13473  [(use (match_operand:XF 0 "register_operand" ""))
13474   (use (match_operand:XF 1 "general_operand" ""))
13475   (use (match_operand:XF 2 "general_operand" ""))]
13476  "TARGET_USE_FANCY_MATH_387"
13477{
13478  rtx label = gen_label_rtx ();
13479
13480  rtx op1 = gen_reg_rtx (XFmode);
13481  rtx op2 = gen_reg_rtx (XFmode);
13482
13483  emit_move_insn (op2, operands[2]);
13484  emit_move_insn (op1, operands[1]);
13485
13486  emit_label (label);
13487  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13488  ix86_emit_fp_unordered_jump (label);
13489  LABEL_NUSES (label) = 1;
13490
13491  emit_move_insn (operands[0], op1);
13492  DONE;
13493})
13494
13495(define_expand "fmod<mode>3"
13496  [(use (match_operand:MODEF 0 "register_operand" ""))
13497   (use (match_operand:MODEF 1 "general_operand" ""))
13498   (use (match_operand:MODEF 2 "general_operand" ""))]
13499  "TARGET_USE_FANCY_MATH_387"
13500{
13501  rtx (*gen_truncxf) (rtx, rtx);
13502
13503  rtx label = gen_label_rtx ();
13504
13505  rtx op1 = gen_reg_rtx (XFmode);
13506  rtx op2 = gen_reg_rtx (XFmode);
13507
13508  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13509  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13510
13511  emit_label (label);
13512  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13513  ix86_emit_fp_unordered_jump (label);
13514  LABEL_NUSES (label) = 1;
13515
13516  /* Truncate the result properly for strict SSE math.  */
13517  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13518      && !TARGET_MIX_SSE_I387)
13519    gen_truncxf = gen_truncxf<mode>2;
13520  else
13521    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13522
13523  emit_insn (gen_truncxf (operands[0], op1));
13524  DONE;
13525})
13526
13527(define_insn "fprem1xf4_i387"
13528  [(set (match_operand:XF 0 "register_operand" "=f")
13529	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
13530		    (match_operand:XF 3 "register_operand" "1")]
13531		   UNSPEC_FPREM1_F))
13532   (set (match_operand:XF 1 "register_operand" "=u")
13533	(unspec:XF [(match_dup 2) (match_dup 3)]
13534		   UNSPEC_FPREM1_U))
13535   (set (reg:CCFP FPSR_REG)
13536	(unspec:CCFP [(match_dup 2) (match_dup 3)]
13537		     UNSPEC_C2_FLAG))]
13538  "TARGET_USE_FANCY_MATH_387"
13539  "fprem1"
13540  [(set_attr "type" "fpspc")
13541   (set_attr "mode" "XF")])
13542
13543(define_expand "remainderxf3"
13544  [(use (match_operand:XF 0 "register_operand" ""))
13545   (use (match_operand:XF 1 "general_operand" ""))
13546   (use (match_operand:XF 2 "general_operand" ""))]
13547  "TARGET_USE_FANCY_MATH_387"
13548{
13549  rtx label = gen_label_rtx ();
13550
13551  rtx op1 = gen_reg_rtx (XFmode);
13552  rtx op2 = gen_reg_rtx (XFmode);
13553
13554  emit_move_insn (op2, operands[2]);
13555  emit_move_insn (op1, operands[1]);
13556
13557  emit_label (label);
13558  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13559  ix86_emit_fp_unordered_jump (label);
13560  LABEL_NUSES (label) = 1;
13561
13562  emit_move_insn (operands[0], op1);
13563  DONE;
13564})
13565
13566(define_expand "remainder<mode>3"
13567  [(use (match_operand:MODEF 0 "register_operand" ""))
13568   (use (match_operand:MODEF 1 "general_operand" ""))
13569   (use (match_operand:MODEF 2 "general_operand" ""))]
13570  "TARGET_USE_FANCY_MATH_387"
13571{
13572  rtx (*gen_truncxf) (rtx, rtx);
13573
13574  rtx label = gen_label_rtx ();
13575
13576  rtx op1 = gen_reg_rtx (XFmode);
13577  rtx op2 = gen_reg_rtx (XFmode);
13578
13579  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13580  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13581
13582  emit_label (label);
13583
13584  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13585  ix86_emit_fp_unordered_jump (label);
13586  LABEL_NUSES (label) = 1;
13587
13588  /* Truncate the result properly for strict SSE math.  */
13589  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13590      && !TARGET_MIX_SSE_I387)
13591    gen_truncxf = gen_truncxf<mode>2;
13592  else
13593    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13594
13595  emit_insn (gen_truncxf (operands[0], op1));
13596  DONE;
13597})
13598
13599(define_insn "*sinxf2_i387"
13600  [(set (match_operand:XF 0 "register_operand" "=f")
13601	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13602  "TARGET_USE_FANCY_MATH_387
13603   && flag_unsafe_math_optimizations"
13604  "fsin"
13605  [(set_attr "type" "fpspc")
13606   (set_attr "mode" "XF")])
13607
13608(define_insn "*sin_extend<mode>xf2_i387"
13609  [(set (match_operand:XF 0 "register_operand" "=f")
13610	(unspec:XF [(float_extend:XF
13611		      (match_operand:MODEF 1 "register_operand" "0"))]
13612		   UNSPEC_SIN))]
13613  "TARGET_USE_FANCY_MATH_387
13614   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13615       || TARGET_MIX_SSE_I387)
13616   && flag_unsafe_math_optimizations"
13617  "fsin"
13618  [(set_attr "type" "fpspc")
13619   (set_attr "mode" "XF")])
13620
13621(define_insn "*cosxf2_i387"
13622  [(set (match_operand:XF 0 "register_operand" "=f")
13623	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13624  "TARGET_USE_FANCY_MATH_387
13625   && flag_unsafe_math_optimizations"
13626  "fcos"
13627  [(set_attr "type" "fpspc")
13628   (set_attr "mode" "XF")])
13629
13630(define_insn "*cos_extend<mode>xf2_i387"
13631  [(set (match_operand:XF 0 "register_operand" "=f")
13632	(unspec:XF [(float_extend:XF
13633		      (match_operand:MODEF 1 "register_operand" "0"))]
13634		   UNSPEC_COS))]
13635  "TARGET_USE_FANCY_MATH_387
13636   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637       || TARGET_MIX_SSE_I387)
13638   && flag_unsafe_math_optimizations"
13639  "fcos"
13640  [(set_attr "type" "fpspc")
13641   (set_attr "mode" "XF")])
13642
13643;; When sincos pattern is defined, sin and cos builtin functions will be
13644;; expanded to sincos pattern with one of its outputs left unused.
13645;; CSE pass will figure out if two sincos patterns can be combined,
13646;; otherwise sincos pattern will be split back to sin or cos pattern,
13647;; depending on the unused output.
13648
13649(define_insn "sincosxf3"
13650  [(set (match_operand:XF 0 "register_operand" "=f")
13651	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13652		   UNSPEC_SINCOS_COS))
13653   (set (match_operand:XF 1 "register_operand" "=u")
13654        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13655  "TARGET_USE_FANCY_MATH_387
13656   && flag_unsafe_math_optimizations"
13657  "fsincos"
13658  [(set_attr "type" "fpspc")
13659   (set_attr "mode" "XF")])
13660
13661(define_split
13662  [(set (match_operand:XF 0 "register_operand" "")
13663	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
13664		   UNSPEC_SINCOS_COS))
13665   (set (match_operand:XF 1 "register_operand" "")
13666	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13667  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13668   && can_create_pseudo_p ()"
13669  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13670
13671(define_split
13672  [(set (match_operand:XF 0 "register_operand" "")
13673	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
13674		   UNSPEC_SINCOS_COS))
13675   (set (match_operand:XF 1 "register_operand" "")
13676	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13677  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13678   && can_create_pseudo_p ()"
13679  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13680
13681(define_insn "sincos_extend<mode>xf3_i387"
13682  [(set (match_operand:XF 0 "register_operand" "=f")
13683	(unspec:XF [(float_extend:XF
13684		      (match_operand:MODEF 2 "register_operand" "0"))]
13685		   UNSPEC_SINCOS_COS))
13686   (set (match_operand:XF 1 "register_operand" "=u")
13687        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13688  "TARGET_USE_FANCY_MATH_387
13689   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13690       || TARGET_MIX_SSE_I387)
13691   && flag_unsafe_math_optimizations"
13692  "fsincos"
13693  [(set_attr "type" "fpspc")
13694   (set_attr "mode" "XF")])
13695
13696(define_split
13697  [(set (match_operand:XF 0 "register_operand" "")
13698	(unspec:XF [(float_extend:XF
13699		      (match_operand:MODEF 2 "register_operand" ""))]
13700		   UNSPEC_SINCOS_COS))
13701   (set (match_operand:XF 1 "register_operand" "")
13702	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13703  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13704   && can_create_pseudo_p ()"
13705  [(set (match_dup 1)
13706	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13707
13708(define_split
13709  [(set (match_operand:XF 0 "register_operand" "")
13710	(unspec:XF [(float_extend:XF
13711		      (match_operand:MODEF 2 "register_operand" ""))]
13712		   UNSPEC_SINCOS_COS))
13713   (set (match_operand:XF 1 "register_operand" "")
13714	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13715  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13716   && can_create_pseudo_p ()"
13717  [(set (match_dup 0)
13718	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13719
13720(define_expand "sincos<mode>3"
13721  [(use (match_operand:MODEF 0 "register_operand" ""))
13722   (use (match_operand:MODEF 1 "register_operand" ""))
13723   (use (match_operand:MODEF 2 "register_operand" ""))]
13724  "TARGET_USE_FANCY_MATH_387
13725   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13726       || TARGET_MIX_SSE_I387)
13727   && flag_unsafe_math_optimizations"
13728{
13729  rtx op0 = gen_reg_rtx (XFmode);
13730  rtx op1 = gen_reg_rtx (XFmode);
13731
13732  emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13733  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13734  emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13735  DONE;
13736})
13737
13738(define_insn "fptanxf4_i387"
13739  [(set (match_operand:XF 0 "register_operand" "=f")
13740	(match_operand:XF 3 "const_double_operand" "F"))
13741   (set (match_operand:XF 1 "register_operand" "=u")
13742        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13743		   UNSPEC_TAN))]
13744  "TARGET_USE_FANCY_MATH_387
13745   && flag_unsafe_math_optimizations
13746   && standard_80387_constant_p (operands[3]) == 2"
13747  "fptan"
13748  [(set_attr "type" "fpspc")
13749   (set_attr "mode" "XF")])
13750
13751(define_insn "fptan_extend<mode>xf4_i387"
13752  [(set (match_operand:MODEF 0 "register_operand" "=f")
13753	(match_operand:MODEF 3 "const_double_operand" "F"))
13754   (set (match_operand:XF 1 "register_operand" "=u")
13755        (unspec:XF [(float_extend:XF
13756		      (match_operand:MODEF 2 "register_operand" "0"))]
13757		   UNSPEC_TAN))]
13758  "TARGET_USE_FANCY_MATH_387
13759   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13760       || TARGET_MIX_SSE_I387)
13761   && flag_unsafe_math_optimizations
13762   && standard_80387_constant_p (operands[3]) == 2"
13763  "fptan"
13764  [(set_attr "type" "fpspc")
13765   (set_attr "mode" "XF")])
13766
13767(define_expand "tanxf2"
13768  [(use (match_operand:XF 0 "register_operand" ""))
13769   (use (match_operand:XF 1 "register_operand" ""))]
13770  "TARGET_USE_FANCY_MATH_387
13771   && flag_unsafe_math_optimizations"
13772{
13773  rtx one = gen_reg_rtx (XFmode);
13774  rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13775
13776  emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13777  DONE;
13778})
13779
13780(define_expand "tan<mode>2"
13781  [(use (match_operand:MODEF 0 "register_operand" ""))
13782   (use (match_operand:MODEF 1 "register_operand" ""))]
13783  "TARGET_USE_FANCY_MATH_387
13784   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785       || TARGET_MIX_SSE_I387)
13786   && flag_unsafe_math_optimizations"
13787{
13788  rtx op0 = gen_reg_rtx (XFmode);
13789
13790  rtx one = gen_reg_rtx (<MODE>mode);
13791  rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13792
13793  emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13794					     operands[1], op2));
13795  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13796  DONE;
13797})
13798
13799(define_insn "*fpatanxf3_i387"
13800  [(set (match_operand:XF 0 "register_operand" "=f")
13801        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13802	            (match_operand:XF 2 "register_operand" "u")]
13803	           UNSPEC_FPATAN))
13804   (clobber (match_scratch:XF 3 "=2"))]
13805  "TARGET_USE_FANCY_MATH_387
13806   && flag_unsafe_math_optimizations"
13807  "fpatan"
13808  [(set_attr "type" "fpspc")
13809   (set_attr "mode" "XF")])
13810
13811(define_insn "fpatan_extend<mode>xf3_i387"
13812  [(set (match_operand:XF 0 "register_operand" "=f")
13813        (unspec:XF [(float_extend:XF
13814		      (match_operand:MODEF 1 "register_operand" "0"))
13815		    (float_extend:XF
13816		      (match_operand:MODEF 2 "register_operand" "u"))]
13817	           UNSPEC_FPATAN))
13818   (clobber (match_scratch:XF 3 "=2"))]
13819  "TARGET_USE_FANCY_MATH_387
13820   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13821       || TARGET_MIX_SSE_I387)
13822   && flag_unsafe_math_optimizations"
13823  "fpatan"
13824  [(set_attr "type" "fpspc")
13825   (set_attr "mode" "XF")])
13826
13827(define_expand "atan2xf3"
13828  [(parallel [(set (match_operand:XF 0 "register_operand" "")
13829		   (unspec:XF [(match_operand:XF 2 "register_operand" "")
13830			       (match_operand:XF 1 "register_operand" "")]
13831			      UNSPEC_FPATAN))
13832	      (clobber (match_scratch:XF 3 ""))])]
13833  "TARGET_USE_FANCY_MATH_387
13834   && flag_unsafe_math_optimizations")
13835
13836(define_expand "atan2<mode>3"
13837  [(use (match_operand:MODEF 0 "register_operand" ""))
13838   (use (match_operand:MODEF 1 "register_operand" ""))
13839   (use (match_operand:MODEF 2 "register_operand" ""))]
13840  "TARGET_USE_FANCY_MATH_387
13841   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13842       || TARGET_MIX_SSE_I387)
13843   && flag_unsafe_math_optimizations"
13844{
13845  rtx op0 = gen_reg_rtx (XFmode);
13846
13847  emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13848  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13849  DONE;
13850})
13851
13852(define_expand "atanxf2"
13853  [(parallel [(set (match_operand:XF 0 "register_operand" "")
13854		   (unspec:XF [(match_dup 2)
13855			       (match_operand:XF 1 "register_operand" "")]
13856			      UNSPEC_FPATAN))
13857	      (clobber (match_scratch:XF 3 ""))])]
13858  "TARGET_USE_FANCY_MATH_387
13859   && flag_unsafe_math_optimizations"
13860{
13861  operands[2] = gen_reg_rtx (XFmode);
13862  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
13863})
13864
13865(define_expand "atan<mode>2"
13866  [(use (match_operand:MODEF 0 "register_operand" ""))
13867   (use (match_operand:MODEF 1 "register_operand" ""))]
13868  "TARGET_USE_FANCY_MATH_387
13869   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13870       || TARGET_MIX_SSE_I387)
13871   && flag_unsafe_math_optimizations"
13872{
13873  rtx op0 = gen_reg_rtx (XFmode);
13874
13875  rtx op2 = gen_reg_rtx (<MODE>mode);
13876  emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
13877
13878  emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13879  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13880  DONE;
13881})
13882
13883(define_expand "asinxf2"
13884  [(set (match_dup 2)
13885	(mult:XF (match_operand:XF 1 "register_operand" "")
13886		 (match_dup 1)))
13887   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13888   (set (match_dup 5) (sqrt:XF (match_dup 4)))
13889   (parallel [(set (match_operand:XF 0 "register_operand" "")
13890        	   (unspec:XF [(match_dup 5) (match_dup 1)]
13891			      UNSPEC_FPATAN))
13892   	      (clobber (match_scratch:XF 6 ""))])]
13893  "TARGET_USE_FANCY_MATH_387
13894   && flag_unsafe_math_optimizations"
13895{
13896  int i;
13897
13898  if (optimize_insn_for_size_p ())
13899    FAIL;
13900
13901  for (i = 2; i < 6; i++)
13902    operands[i] = gen_reg_rtx (XFmode);
13903
13904  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13905})
13906
13907(define_expand "asin<mode>2"
13908  [(use (match_operand:MODEF 0 "register_operand" ""))
13909   (use (match_operand:MODEF 1 "general_operand" ""))]
13910 "TARGET_USE_FANCY_MATH_387
13911   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13912       || TARGET_MIX_SSE_I387)
13913   && flag_unsafe_math_optimizations"
13914{
13915  rtx op0 = gen_reg_rtx (XFmode);
13916  rtx op1 = gen_reg_rtx (XFmode);
13917
13918  if (optimize_insn_for_size_p ())
13919    FAIL;
13920
13921  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13922  emit_insn (gen_asinxf2 (op0, op1));
13923  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13924  DONE;
13925})
13926
13927(define_expand "acosxf2"
13928  [(set (match_dup 2)
13929	(mult:XF (match_operand:XF 1 "register_operand" "")
13930		 (match_dup 1)))
13931   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13932   (set (match_dup 5) (sqrt:XF (match_dup 4)))
13933   (parallel [(set (match_operand:XF 0 "register_operand" "")
13934        	   (unspec:XF [(match_dup 1) (match_dup 5)]
13935			      UNSPEC_FPATAN))
13936   	      (clobber (match_scratch:XF 6 ""))])]
13937  "TARGET_USE_FANCY_MATH_387
13938   && flag_unsafe_math_optimizations"
13939{
13940  int i;
13941
13942  if (optimize_insn_for_size_p ())
13943    FAIL;
13944
13945  for (i = 2; i < 6; i++)
13946    operands[i] = gen_reg_rtx (XFmode);
13947
13948  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
13949})
13950
13951(define_expand "acos<mode>2"
13952  [(use (match_operand:MODEF 0 "register_operand" ""))
13953   (use (match_operand:MODEF 1 "general_operand" ""))]
13954 "TARGET_USE_FANCY_MATH_387
13955   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13956       || TARGET_MIX_SSE_I387)
13957   && flag_unsafe_math_optimizations"
13958{
13959  rtx op0 = gen_reg_rtx (XFmode);
13960  rtx op1 = gen_reg_rtx (XFmode);
13961
13962  if (optimize_insn_for_size_p ())
13963    FAIL;
13964
13965  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13966  emit_insn (gen_acosxf2 (op0, op1));
13967  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13968  DONE;
13969})
13970
13971(define_insn "fyl2xxf3_i387"
13972  [(set (match_operand:XF 0 "register_operand" "=f")
13973        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13974		    (match_operand:XF 2 "register_operand" "u")]
13975	           UNSPEC_FYL2X))
13976   (clobber (match_scratch:XF 3 "=2"))]
13977  "TARGET_USE_FANCY_MATH_387
13978   && flag_unsafe_math_optimizations"
13979  "fyl2x"
13980  [(set_attr "type" "fpspc")
13981   (set_attr "mode" "XF")])
13982
13983(define_insn "fyl2x_extend<mode>xf3_i387"
13984  [(set (match_operand:XF 0 "register_operand" "=f")
13985        (unspec:XF [(float_extend:XF
13986		      (match_operand:MODEF 1 "register_operand" "0"))
13987		    (match_operand:XF 2 "register_operand" "u")]
13988	           UNSPEC_FYL2X))
13989   (clobber (match_scratch:XF 3 "=2"))]
13990  "TARGET_USE_FANCY_MATH_387
13991   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13992       || TARGET_MIX_SSE_I387)
13993   && flag_unsafe_math_optimizations"
13994  "fyl2x"
13995  [(set_attr "type" "fpspc")
13996   (set_attr "mode" "XF")])
13997
13998(define_expand "logxf2"
13999  [(parallel [(set (match_operand:XF 0 "register_operand" "")
14000		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14001			       (match_dup 2)] UNSPEC_FYL2X))
14002	      (clobber (match_scratch:XF 3 ""))])]
14003  "TARGET_USE_FANCY_MATH_387
14004   && flag_unsafe_math_optimizations"
14005{
14006  operands[2] = gen_reg_rtx (XFmode);
14007  emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14008})
14009
14010(define_expand "log<mode>2"
14011  [(use (match_operand:MODEF 0 "register_operand" ""))
14012   (use (match_operand:MODEF 1 "register_operand" ""))]
14013  "TARGET_USE_FANCY_MATH_387
14014   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015       || TARGET_MIX_SSE_I387)
14016   && flag_unsafe_math_optimizations"
14017{
14018  rtx op0 = gen_reg_rtx (XFmode);
14019
14020  rtx op2 = gen_reg_rtx (XFmode);
14021  emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14022
14023  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14024  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14025  DONE;
14026})
14027
14028(define_expand "log10xf2"
14029  [(parallel [(set (match_operand:XF 0 "register_operand" "")
14030		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14031			       (match_dup 2)] UNSPEC_FYL2X))
14032	      (clobber (match_scratch:XF 3 ""))])]
14033  "TARGET_USE_FANCY_MATH_387
14034   && flag_unsafe_math_optimizations"
14035{
14036  operands[2] = gen_reg_rtx (XFmode);
14037  emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14038})
14039
14040(define_expand "log10<mode>2"
14041  [(use (match_operand:MODEF 0 "register_operand" ""))
14042   (use (match_operand:MODEF 1 "register_operand" ""))]
14043  "TARGET_USE_FANCY_MATH_387
14044   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045       || TARGET_MIX_SSE_I387)
14046   && flag_unsafe_math_optimizations"
14047{
14048  rtx op0 = gen_reg_rtx (XFmode);
14049
14050  rtx op2 = gen_reg_rtx (XFmode);
14051  emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14052
14053  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14054  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14055  DONE;
14056})
14057
14058(define_expand "log2xf2"
14059  [(parallel [(set (match_operand:XF 0 "register_operand" "")
14060		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14061			       (match_dup 2)] UNSPEC_FYL2X))
14062	      (clobber (match_scratch:XF 3 ""))])]
14063  "TARGET_USE_FANCY_MATH_387
14064   && flag_unsafe_math_optimizations"
14065{
14066  operands[2] = gen_reg_rtx (XFmode);
14067  emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14068})
14069
14070(define_expand "log2<mode>2"
14071  [(use (match_operand:MODEF 0 "register_operand" ""))
14072   (use (match_operand:MODEF 1 "register_operand" ""))]
14073  "TARGET_USE_FANCY_MATH_387
14074   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14075       || TARGET_MIX_SSE_I387)
14076   && flag_unsafe_math_optimizations"
14077{
14078  rtx op0 = gen_reg_rtx (XFmode);
14079
14080  rtx op2 = gen_reg_rtx (XFmode);
14081  emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14082
14083  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14084  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14085  DONE;
14086})
14087
14088(define_insn "fyl2xp1xf3_i387"
14089  [(set (match_operand:XF 0 "register_operand" "=f")
14090        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14091		    (match_operand:XF 2 "register_operand" "u")]
14092	           UNSPEC_FYL2XP1))
14093   (clobber (match_scratch:XF 3 "=2"))]
14094  "TARGET_USE_FANCY_MATH_387
14095   && flag_unsafe_math_optimizations"
14096  "fyl2xp1"
14097  [(set_attr "type" "fpspc")
14098   (set_attr "mode" "XF")])
14099
14100(define_insn "fyl2xp1_extend<mode>xf3_i387"
14101  [(set (match_operand:XF 0 "register_operand" "=f")
14102        (unspec:XF [(float_extend:XF
14103		      (match_operand:MODEF 1 "register_operand" "0"))
14104		    (match_operand:XF 2 "register_operand" "u")]
14105	           UNSPEC_FYL2XP1))
14106   (clobber (match_scratch:XF 3 "=2"))]
14107  "TARGET_USE_FANCY_MATH_387
14108   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14109       || TARGET_MIX_SSE_I387)
14110   && flag_unsafe_math_optimizations"
14111  "fyl2xp1"
14112  [(set_attr "type" "fpspc")
14113   (set_attr "mode" "XF")])
14114
14115(define_expand "log1pxf2"
14116  [(use (match_operand:XF 0 "register_operand" ""))
14117   (use (match_operand:XF 1 "register_operand" ""))]
14118  "TARGET_USE_FANCY_MATH_387
14119   && flag_unsafe_math_optimizations"
14120{
14121  if (optimize_insn_for_size_p ())
14122    FAIL;
14123
14124  ix86_emit_i387_log1p (operands[0], operands[1]);
14125  DONE;
14126})
14127
14128(define_expand "log1p<mode>2"
14129  [(use (match_operand:MODEF 0 "register_operand" ""))
14130   (use (match_operand:MODEF 1 "register_operand" ""))]
14131  "TARGET_USE_FANCY_MATH_387
14132   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14133       || TARGET_MIX_SSE_I387)
14134   && flag_unsafe_math_optimizations"
14135{
14136  rtx op0;
14137
14138  if (optimize_insn_for_size_p ())
14139    FAIL;
14140
14141  op0 = gen_reg_rtx (XFmode);
14142
14143  operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14144
14145  ix86_emit_i387_log1p (op0, operands[1]);
14146  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14147  DONE;
14148})
14149
14150(define_insn "fxtractxf3_i387"
14151  [(set (match_operand:XF 0 "register_operand" "=f")
14152	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14153		   UNSPEC_XTRACT_FRACT))
14154   (set (match_operand:XF 1 "register_operand" "=u")
14155        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14156  "TARGET_USE_FANCY_MATH_387
14157   && flag_unsafe_math_optimizations"
14158  "fxtract"
14159  [(set_attr "type" "fpspc")
14160   (set_attr "mode" "XF")])
14161
14162(define_insn "fxtract_extend<mode>xf3_i387"
14163  [(set (match_operand:XF 0 "register_operand" "=f")
14164	(unspec:XF [(float_extend:XF
14165		      (match_operand:MODEF 2 "register_operand" "0"))]
14166		   UNSPEC_XTRACT_FRACT))
14167   (set (match_operand:XF 1 "register_operand" "=u")
14168        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14169  "TARGET_USE_FANCY_MATH_387
14170   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14171       || TARGET_MIX_SSE_I387)
14172   && flag_unsafe_math_optimizations"
14173  "fxtract"
14174  [(set_attr "type" "fpspc")
14175   (set_attr "mode" "XF")])
14176
14177(define_expand "logbxf2"
14178  [(parallel [(set (match_dup 2)
14179		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14180			      UNSPEC_XTRACT_FRACT))
14181	      (set (match_operand:XF 0 "register_operand" "")
14182		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14183  "TARGET_USE_FANCY_MATH_387
14184   && flag_unsafe_math_optimizations"
14185  "operands[2] = gen_reg_rtx (XFmode);")
14186
14187(define_expand "logb<mode>2"
14188  [(use (match_operand:MODEF 0 "register_operand" ""))
14189   (use (match_operand:MODEF 1 "register_operand" ""))]
14190  "TARGET_USE_FANCY_MATH_387
14191   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14192       || TARGET_MIX_SSE_I387)
14193   && flag_unsafe_math_optimizations"
14194{
14195  rtx op0 = gen_reg_rtx (XFmode);
14196  rtx op1 = gen_reg_rtx (XFmode);
14197
14198  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14199  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14200  DONE;
14201})
14202
14203(define_expand "ilogbxf2"
14204  [(use (match_operand:SI 0 "register_operand" ""))
14205   (use (match_operand:XF 1 "register_operand" ""))]
14206  "TARGET_USE_FANCY_MATH_387
14207   && flag_unsafe_math_optimizations"
14208{
14209  rtx op0, op1;
14210
14211  if (optimize_insn_for_size_p ())
14212    FAIL;
14213
14214  op0 = gen_reg_rtx (XFmode);
14215  op1 = gen_reg_rtx (XFmode);
14216
14217  emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14218  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14219  DONE;
14220})
14221
14222(define_expand "ilogb<mode>2"
14223  [(use (match_operand:SI 0 "register_operand" ""))
14224   (use (match_operand:MODEF 1 "register_operand" ""))]
14225  "TARGET_USE_FANCY_MATH_387
14226   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14227       || TARGET_MIX_SSE_I387)
14228   && flag_unsafe_math_optimizations"
14229{
14230  rtx op0, op1;
14231
14232  if (optimize_insn_for_size_p ())
14233    FAIL;
14234
14235  op0 = gen_reg_rtx (XFmode);
14236  op1 = gen_reg_rtx (XFmode);
14237
14238  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14239  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14240  DONE;
14241})
14242
14243(define_insn "*f2xm1xf2_i387"
14244  [(set (match_operand:XF 0 "register_operand" "=f")
14245	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14246		   UNSPEC_F2XM1))]
14247  "TARGET_USE_FANCY_MATH_387
14248   && flag_unsafe_math_optimizations"
14249  "f2xm1"
14250  [(set_attr "type" "fpspc")
14251   (set_attr "mode" "XF")])
14252
14253(define_insn "*fscalexf4_i387"
14254  [(set (match_operand:XF 0 "register_operand" "=f")
14255	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
14256		    (match_operand:XF 3 "register_operand" "1")]
14257		   UNSPEC_FSCALE_FRACT))
14258   (set (match_operand:XF 1 "register_operand" "=u")
14259	(unspec:XF [(match_dup 2) (match_dup 3)]
14260		   UNSPEC_FSCALE_EXP))]
14261  "TARGET_USE_FANCY_MATH_387
14262   && flag_unsafe_math_optimizations"
14263  "fscale"
14264  [(set_attr "type" "fpspc")
14265   (set_attr "mode" "XF")])
14266
14267(define_expand "expNcorexf3"
14268  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14269			       (match_operand:XF 2 "register_operand" "")))
14270   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14271   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14272   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14273   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14274   (parallel [(set (match_operand:XF 0 "register_operand" "")
14275		   (unspec:XF [(match_dup 8) (match_dup 4)]
14276			      UNSPEC_FSCALE_FRACT))
14277	      (set (match_dup 9)
14278		   (unspec:XF [(match_dup 8) (match_dup 4)]
14279			      UNSPEC_FSCALE_EXP))])]
14280  "TARGET_USE_FANCY_MATH_387
14281   && flag_unsafe_math_optimizations"
14282{
14283  int i;
14284
14285  if (optimize_insn_for_size_p ())
14286    FAIL;
14287
14288  for (i = 3; i < 10; i++)
14289    operands[i] = gen_reg_rtx (XFmode);
14290
14291  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14292})
14293
14294(define_expand "expxf2"
14295  [(use (match_operand:XF 0 "register_operand" ""))
14296   (use (match_operand:XF 1 "register_operand" ""))]
14297  "TARGET_USE_FANCY_MATH_387
14298   && flag_unsafe_math_optimizations"
14299{
14300  rtx op2;
14301
14302  if (optimize_insn_for_size_p ())
14303    FAIL;
14304
14305  op2 = gen_reg_rtx (XFmode);
14306  emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14307
14308  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14309  DONE;
14310})
14311
14312(define_expand "exp<mode>2"
14313  [(use (match_operand:MODEF 0 "register_operand" ""))
14314   (use (match_operand:MODEF 1 "general_operand" ""))]
14315 "TARGET_USE_FANCY_MATH_387
14316   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14317       || TARGET_MIX_SSE_I387)
14318   && flag_unsafe_math_optimizations"
14319{
14320  rtx op0, op1;
14321
14322  if (optimize_insn_for_size_p ())
14323    FAIL;
14324
14325  op0 = gen_reg_rtx (XFmode);
14326  op1 = gen_reg_rtx (XFmode);
14327
14328  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14329  emit_insn (gen_expxf2 (op0, op1));
14330  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14331  DONE;
14332})
14333
14334(define_expand "exp10xf2"
14335  [(use (match_operand:XF 0 "register_operand" ""))
14336   (use (match_operand:XF 1 "register_operand" ""))]
14337  "TARGET_USE_FANCY_MATH_387
14338   && flag_unsafe_math_optimizations"
14339{
14340  rtx op2;
14341
14342  if (optimize_insn_for_size_p ())
14343    FAIL;
14344
14345  op2 = gen_reg_rtx (XFmode);
14346  emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14347
14348  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14349  DONE;
14350})
14351
14352(define_expand "exp10<mode>2"
14353  [(use (match_operand:MODEF 0 "register_operand" ""))
14354   (use (match_operand:MODEF 1 "general_operand" ""))]
14355 "TARGET_USE_FANCY_MATH_387
14356   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14357       || TARGET_MIX_SSE_I387)
14358   && flag_unsafe_math_optimizations"
14359{
14360  rtx op0, op1;
14361
14362  if (optimize_insn_for_size_p ())
14363    FAIL;
14364
14365  op0 = gen_reg_rtx (XFmode);
14366  op1 = gen_reg_rtx (XFmode);
14367
14368  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14369  emit_insn (gen_exp10xf2 (op0, op1));
14370  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14371  DONE;
14372})
14373
14374(define_expand "exp2xf2"
14375  [(use (match_operand:XF 0 "register_operand" ""))
14376   (use (match_operand:XF 1 "register_operand" ""))]
14377  "TARGET_USE_FANCY_MATH_387
14378   && flag_unsafe_math_optimizations"
14379{
14380  rtx op2;
14381
14382  if (optimize_insn_for_size_p ())
14383    FAIL;
14384
14385  op2 = gen_reg_rtx (XFmode);
14386  emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14387
14388  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14389  DONE;
14390})
14391
14392(define_expand "exp2<mode>2"
14393  [(use (match_operand:MODEF 0 "register_operand" ""))
14394   (use (match_operand:MODEF 1 "general_operand" ""))]
14395 "TARGET_USE_FANCY_MATH_387
14396   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14397       || TARGET_MIX_SSE_I387)
14398   && flag_unsafe_math_optimizations"
14399{
14400  rtx op0, op1;
14401
14402  if (optimize_insn_for_size_p ())
14403    FAIL;
14404
14405  op0 = gen_reg_rtx (XFmode);
14406  op1 = gen_reg_rtx (XFmode);
14407
14408  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14409  emit_insn (gen_exp2xf2 (op0, op1));
14410  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14411  DONE;
14412})
14413
14414(define_expand "expm1xf2"
14415  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14416			       (match_dup 2)))
14417   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14418   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14419   (set (match_dup 9) (float_extend:XF (match_dup 13)))
14420   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14421   (parallel [(set (match_dup 7)
14422		   (unspec:XF [(match_dup 6) (match_dup 4)]
14423			      UNSPEC_FSCALE_FRACT))
14424	      (set (match_dup 8)
14425		   (unspec:XF [(match_dup 6) (match_dup 4)]
14426			      UNSPEC_FSCALE_EXP))])
14427   (parallel [(set (match_dup 10)
14428		   (unspec:XF [(match_dup 9) (match_dup 8)]
14429			      UNSPEC_FSCALE_FRACT))
14430	      (set (match_dup 11)
14431		   (unspec:XF [(match_dup 9) (match_dup 8)]
14432			      UNSPEC_FSCALE_EXP))])
14433   (set (match_dup 12) (minus:XF (match_dup 10)
14434				 (float_extend:XF (match_dup 13))))
14435   (set (match_operand:XF 0 "register_operand" "")
14436	(plus:XF (match_dup 12) (match_dup 7)))]
14437  "TARGET_USE_FANCY_MATH_387
14438   && flag_unsafe_math_optimizations"
14439{
14440  int i;
14441
14442  if (optimize_insn_for_size_p ())
14443    FAIL;
14444
14445  for (i = 2; i < 13; i++)
14446    operands[i] = gen_reg_rtx (XFmode);
14447
14448  operands[13]
14449    = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14450
14451  emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14452})
14453
14454(define_expand "expm1<mode>2"
14455  [(use (match_operand:MODEF 0 "register_operand" ""))
14456   (use (match_operand:MODEF 1 "general_operand" ""))]
14457 "TARGET_USE_FANCY_MATH_387
14458   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14459       || TARGET_MIX_SSE_I387)
14460   && flag_unsafe_math_optimizations"
14461{
14462  rtx op0, op1;
14463
14464  if (optimize_insn_for_size_p ())
14465    FAIL;
14466
14467  op0 = gen_reg_rtx (XFmode);
14468  op1 = gen_reg_rtx (XFmode);
14469
14470  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14471  emit_insn (gen_expm1xf2 (op0, op1));
14472  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14473  DONE;
14474})
14475
14476(define_expand "ldexpxf3"
14477  [(set (match_dup 3)
14478	(float:XF (match_operand:SI 2 "register_operand" "")))
14479   (parallel [(set (match_operand:XF 0 " register_operand" "")
14480		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14481			       (match_dup 3)]
14482			      UNSPEC_FSCALE_FRACT))
14483	      (set (match_dup 4)
14484		   (unspec:XF [(match_dup 1) (match_dup 3)]
14485			      UNSPEC_FSCALE_EXP))])]
14486  "TARGET_USE_FANCY_MATH_387
14487   && flag_unsafe_math_optimizations"
14488{
14489  if (optimize_insn_for_size_p ())
14490    FAIL;
14491
14492  operands[3] = gen_reg_rtx (XFmode);
14493  operands[4] = gen_reg_rtx (XFmode);
14494})
14495
14496(define_expand "ldexp<mode>3"
14497  [(use (match_operand:MODEF 0 "register_operand" ""))
14498   (use (match_operand:MODEF 1 "general_operand" ""))
14499   (use (match_operand:SI 2 "register_operand" ""))]
14500 "TARGET_USE_FANCY_MATH_387
14501   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14502       || TARGET_MIX_SSE_I387)
14503   && flag_unsafe_math_optimizations"
14504{
14505  rtx op0, op1;
14506
14507  if (optimize_insn_for_size_p ())
14508    FAIL;
14509
14510  op0 = gen_reg_rtx (XFmode);
14511  op1 = gen_reg_rtx (XFmode);
14512
14513  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14514  emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14515  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14516  DONE;
14517})
14518
14519(define_expand "scalbxf3"
14520  [(parallel [(set (match_operand:XF 0 " register_operand" "")
14521		   (unspec:XF [(match_operand:XF 1 "register_operand" "")
14522			       (match_operand:XF 2 "register_operand" "")]
14523			      UNSPEC_FSCALE_FRACT))
14524	      (set (match_dup 3)
14525		   (unspec:XF [(match_dup 1) (match_dup 2)]
14526			      UNSPEC_FSCALE_EXP))])]
14527  "TARGET_USE_FANCY_MATH_387
14528   && flag_unsafe_math_optimizations"
14529{
14530  if (optimize_insn_for_size_p ())
14531    FAIL;
14532
14533  operands[3] = gen_reg_rtx (XFmode);
14534})
14535
14536(define_expand "scalb<mode>3"
14537  [(use (match_operand:MODEF 0 "register_operand" ""))
14538   (use (match_operand:MODEF 1 "general_operand" ""))
14539   (use (match_operand:MODEF 2 "general_operand" ""))]
14540 "TARGET_USE_FANCY_MATH_387
14541   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14542       || TARGET_MIX_SSE_I387)
14543   && flag_unsafe_math_optimizations"
14544{
14545  rtx op0, op1, op2;
14546
14547  if (optimize_insn_for_size_p ())
14548    FAIL;
14549
14550  op0 = gen_reg_rtx (XFmode);
14551  op1 = gen_reg_rtx (XFmode);
14552  op2 = gen_reg_rtx (XFmode);
14553
14554  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14555  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14556  emit_insn (gen_scalbxf3 (op0, op1, op2));
14557  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14558  DONE;
14559})
14560
14561(define_expand "significandxf2"
14562  [(parallel [(set (match_operand:XF 0 "register_operand" "")
14563		   (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14564			      UNSPEC_XTRACT_FRACT))
14565	      (set (match_dup 2)
14566		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14567  "TARGET_USE_FANCY_MATH_387
14568   && flag_unsafe_math_optimizations"
14569  "operands[2] = gen_reg_rtx (XFmode);")
14570
14571(define_expand "significand<mode>2"
14572  [(use (match_operand:MODEF 0 "register_operand" ""))
14573   (use (match_operand:MODEF 1 "register_operand" ""))]
14574  "TARGET_USE_FANCY_MATH_387
14575   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14576       || TARGET_MIX_SSE_I387)
14577   && flag_unsafe_math_optimizations"
14578{
14579  rtx op0 = gen_reg_rtx (XFmode);
14580  rtx op1 = gen_reg_rtx (XFmode);
14581
14582  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14583  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14584  DONE;
14585})
14586
14587
14588(define_insn "sse4_1_round<mode>2"
14589  [(set (match_operand:MODEF 0 "register_operand" "=x")
14590	(unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14591		       (match_operand:SI 2 "const_0_to_15_operand" "n")]
14592		      UNSPEC_ROUND))]
14593  "TARGET_ROUND"
14594  "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14595  [(set_attr "type" "ssecvt")
14596   (set_attr "prefix_extra" "1")
14597   (set_attr "prefix" "maybe_vex")
14598   (set_attr "mode" "<MODE>")])
14599
14600(define_insn "rintxf2"
14601  [(set (match_operand:XF 0 "register_operand" "=f")
14602	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14603		   UNSPEC_FRNDINT))]
14604  "TARGET_USE_FANCY_MATH_387
14605   && flag_unsafe_math_optimizations"
14606  "frndint"
14607  [(set_attr "type" "fpspc")
14608   (set_attr "mode" "XF")])
14609
14610(define_expand "rint<mode>2"
14611  [(use (match_operand:MODEF 0 "register_operand" ""))
14612   (use (match_operand:MODEF 1 "register_operand" ""))]
14613  "(TARGET_USE_FANCY_MATH_387
14614    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14615	|| TARGET_MIX_SSE_I387)
14616    && flag_unsafe_math_optimizations)
14617   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14618       && !flag_trapping_math)"
14619{
14620  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14621      && !flag_trapping_math)
14622    {
14623      if (TARGET_ROUND)
14624	emit_insn (gen_sse4_1_round<mode>2
14625		   (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14626      else if (optimize_insn_for_size_p ())
14627        FAIL;
14628      else
14629	ix86_expand_rint (operands[0], operands[1]);
14630    }
14631  else
14632    {
14633      rtx op0 = gen_reg_rtx (XFmode);
14634      rtx op1 = gen_reg_rtx (XFmode);
14635
14636      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14637      emit_insn (gen_rintxf2 (op0, op1));
14638
14639      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14640    }
14641  DONE;
14642})
14643
14644(define_expand "round<mode>2"
14645  [(match_operand:X87MODEF 0 "register_operand" "")
14646   (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14647  "(TARGET_USE_FANCY_MATH_387
14648    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14649	|| TARGET_MIX_SSE_I387)
14650    && flag_unsafe_math_optimizations)
14651   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14652       && !flag_trapping_math && !flag_rounding_math)"
14653{
14654  if (optimize_insn_for_size_p ())
14655    FAIL;
14656
14657  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14658      && !flag_trapping_math && !flag_rounding_math)
14659    {
14660      if (TARGET_ROUND)
14661        {
14662	  operands[1] = force_reg (<MODE>mode, operands[1]);
14663	  ix86_expand_round_sse4 (operands[0], operands[1]);
14664	}
14665      else if (TARGET_64BIT || (<MODE>mode != DFmode))
14666	ix86_expand_round (operands[0], operands[1]);
14667      else
14668	ix86_expand_rounddf_32 (operands[0], operands[1]);
14669    }
14670  else
14671    {
14672      operands[1] = force_reg (<MODE>mode, operands[1]);
14673      ix86_emit_i387_round (operands[0], operands[1]);
14674    }
14675  DONE;
14676})
14677
14678(define_insn_and_split "*fistdi2_1"
14679  [(set (match_operand:DI 0 "nonimmediate_operand" "")
14680	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
14681		   UNSPEC_FIST))]
14682  "TARGET_USE_FANCY_MATH_387
14683   && can_create_pseudo_p ()"
14684  "#"
14685  "&& 1"
14686  [(const_int 0)]
14687{
14688  if (memory_operand (operands[0], VOIDmode))
14689    emit_insn (gen_fistdi2 (operands[0], operands[1]));
14690  else
14691    {
14692      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14693      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14694					 operands[2]));
14695    }
14696  DONE;
14697}
14698  [(set_attr "type" "fpspc")
14699   (set_attr "mode" "DI")])
14700
14701(define_insn "fistdi2"
14702  [(set (match_operand:DI 0 "memory_operand" "=m")
14703	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14704		   UNSPEC_FIST))
14705   (clobber (match_scratch:XF 2 "=&1f"))]
14706  "TARGET_USE_FANCY_MATH_387"
14707  "* return output_fix_trunc (insn, operands, false);"
14708  [(set_attr "type" "fpspc")
14709   (set_attr "mode" "DI")])
14710
14711(define_insn "fistdi2_with_temp"
14712  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14713	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14714		   UNSPEC_FIST))
14715   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14716   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14717  "TARGET_USE_FANCY_MATH_387"
14718  "#"
14719  [(set_attr "type" "fpspc")
14720   (set_attr "mode" "DI")])
14721
14722(define_split
14723  [(set (match_operand:DI 0 "register_operand" "")
14724	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
14725		   UNSPEC_FIST))
14726   (clobber (match_operand:DI 2 "memory_operand" ""))
14727   (clobber (match_scratch 3 ""))]
14728  "reload_completed"
14729  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14730	      (clobber (match_dup 3))])
14731   (set (match_dup 0) (match_dup 2))])
14732
14733(define_split
14734  [(set (match_operand:DI 0 "memory_operand" "")
14735	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
14736		   UNSPEC_FIST))
14737   (clobber (match_operand:DI 2 "memory_operand" ""))
14738   (clobber (match_scratch 3 ""))]
14739  "reload_completed"
14740  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14741	      (clobber (match_dup 3))])])
14742
14743(define_insn_and_split "*fist<mode>2_1"
14744  [(set (match_operand:SWI24 0 "register_operand" "")
14745	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14746		      UNSPEC_FIST))]
14747  "TARGET_USE_FANCY_MATH_387
14748   && can_create_pseudo_p ()"
14749  "#"
14750  "&& 1"
14751  [(const_int 0)]
14752{
14753  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14754  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14755					operands[2]));
14756  DONE;
14757}
14758  [(set_attr "type" "fpspc")
14759   (set_attr "mode" "<MODE>")])
14760
14761(define_insn "fist<mode>2"
14762  [(set (match_operand:SWI24 0 "memory_operand" "=m")
14763	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14764		      UNSPEC_FIST))]
14765  "TARGET_USE_FANCY_MATH_387"
14766  "* return output_fix_trunc (insn, operands, false);"
14767  [(set_attr "type" "fpspc")
14768   (set_attr "mode" "<MODE>")])
14769
14770(define_insn "fist<mode>2_with_temp"
14771  [(set (match_operand:SWI24 0 "register_operand" "=r")
14772	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14773		      UNSPEC_FIST))
14774   (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14775  "TARGET_USE_FANCY_MATH_387"
14776  "#"
14777  [(set_attr "type" "fpspc")
14778   (set_attr "mode" "<MODE>")])
14779
14780(define_split
14781  [(set (match_operand:SWI24 0 "register_operand" "")
14782	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14783		      UNSPEC_FIST))
14784   (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14785  "reload_completed"
14786  [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14787   (set (match_dup 0) (match_dup 2))])
14788
14789(define_split
14790  [(set (match_operand:SWI24 0 "memory_operand" "")
14791	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14792		      UNSPEC_FIST))
14793   (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14794  "reload_completed"
14795  [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14796
14797(define_expand "lrintxf<mode>2"
14798  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14799     (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14800		     UNSPEC_FIST))]
14801  "TARGET_USE_FANCY_MATH_387")
14802
14803(define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14804  [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14805     (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14806			UNSPEC_FIX_NOTRUNC))]
14807  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14808   && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14809
14810(define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14811  [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14812   (match_operand:X87MODEF 1 "register_operand" "")]
14813  "(TARGET_USE_FANCY_MATH_387
14814    && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14815	|| TARGET_MIX_SSE_I387)
14816    && flag_unsafe_math_optimizations)
14817   || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14818       && <SWI248x:MODE>mode != HImode
14819       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14820       && !flag_trapping_math && !flag_rounding_math)"
14821{
14822  if (optimize_insn_for_size_p ())
14823    FAIL;
14824
14825  if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14826      && <SWI248x:MODE>mode != HImode
14827      && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14828      && !flag_trapping_math && !flag_rounding_math)
14829    ix86_expand_lround (operands[0], operands[1]);
14830  else
14831    ix86_emit_i387_round (operands[0], operands[1]);
14832  DONE;
14833})
14834
14835;; Rounding mode control word calculation could clobber FLAGS_REG.
14836(define_insn_and_split "frndintxf2_floor"
14837  [(set (match_operand:XF 0 "register_operand" "")
14838	(unspec:XF [(match_operand:XF 1 "register_operand" "")]
14839	 UNSPEC_FRNDINT_FLOOR))
14840   (clobber (reg:CC FLAGS_REG))]
14841  "TARGET_USE_FANCY_MATH_387
14842   && flag_unsafe_math_optimizations
14843   && can_create_pseudo_p ()"
14844  "#"
14845  "&& 1"
14846  [(const_int 0)]
14847{
14848  ix86_optimize_mode_switching[I387_FLOOR] = 1;
14849
14850  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14851  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14852
14853  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14854					operands[2], operands[3]));
14855  DONE;
14856}
14857  [(set_attr "type" "frndint")
14858   (set_attr "i387_cw" "floor")
14859   (set_attr "mode" "XF")])
14860
14861(define_insn "frndintxf2_floor_i387"
14862  [(set (match_operand:XF 0 "register_operand" "=f")
14863	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14864	 UNSPEC_FRNDINT_FLOOR))
14865   (use (match_operand:HI 2 "memory_operand" "m"))
14866   (use (match_operand:HI 3 "memory_operand" "m"))]
14867  "TARGET_USE_FANCY_MATH_387
14868   && flag_unsafe_math_optimizations"
14869  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14870  [(set_attr "type" "frndint")
14871   (set_attr "i387_cw" "floor")
14872   (set_attr "mode" "XF")])
14873
14874(define_expand "floorxf2"
14875  [(use (match_operand:XF 0 "register_operand" ""))
14876   (use (match_operand:XF 1 "register_operand" ""))]
14877  "TARGET_USE_FANCY_MATH_387
14878   && flag_unsafe_math_optimizations"
14879{
14880  if (optimize_insn_for_size_p ())
14881    FAIL;
14882  emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14883  DONE;
14884})
14885
14886(define_expand "floor<mode>2"
14887  [(use (match_operand:MODEF 0 "register_operand" ""))
14888   (use (match_operand:MODEF 1 "register_operand" ""))]
14889  "(TARGET_USE_FANCY_MATH_387
14890    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891	|| TARGET_MIX_SSE_I387)
14892    && flag_unsafe_math_optimizations)
14893   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14894       && !flag_trapping_math)"
14895{
14896  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14897      && !flag_trapping_math)
14898    {
14899      if (TARGET_ROUND)
14900	emit_insn (gen_sse4_1_round<mode>2
14901		   (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14902      else if (optimize_insn_for_size_p ())
14903        FAIL;
14904      else if (TARGET_64BIT || (<MODE>mode != DFmode))
14905	ix86_expand_floorceil (operands[0], operands[1], true);
14906      else
14907	ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14908    }
14909  else
14910    {
14911      rtx op0, op1;
14912
14913      if (optimize_insn_for_size_p ())
14914	FAIL;
14915
14916      op0 = gen_reg_rtx (XFmode);
14917      op1 = gen_reg_rtx (XFmode);
14918      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14919      emit_insn (gen_frndintxf2_floor (op0, op1));
14920
14921      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14922    }
14923  DONE;
14924})
14925
14926(define_insn_and_split "*fist<mode>2_floor_1"
14927  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14928	(unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14929			UNSPEC_FIST_FLOOR))
14930   (clobber (reg:CC FLAGS_REG))]
14931  "TARGET_USE_FANCY_MATH_387
14932   && flag_unsafe_math_optimizations
14933   && can_create_pseudo_p ()"
14934  "#"
14935  "&& 1"
14936  [(const_int 0)]
14937{
14938  ix86_optimize_mode_switching[I387_FLOOR] = 1;
14939
14940  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14941  operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14942  if (memory_operand (operands[0], VOIDmode))
14943    emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14944				      operands[2], operands[3]));
14945  else
14946    {
14947      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14948      emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14949						  operands[2], operands[3],
14950						  operands[4]));
14951    }
14952  DONE;
14953}
14954  [(set_attr "type" "fistp")
14955   (set_attr "i387_cw" "floor")
14956   (set_attr "mode" "<MODE>")])
14957
14958(define_insn "fistdi2_floor"
14959  [(set (match_operand:DI 0 "memory_operand" "=m")
14960	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14961		   UNSPEC_FIST_FLOOR))
14962   (use (match_operand:HI 2 "memory_operand" "m"))
14963   (use (match_operand:HI 3 "memory_operand" "m"))
14964   (clobber (match_scratch:XF 4 "=&1f"))]
14965  "TARGET_USE_FANCY_MATH_387
14966   && flag_unsafe_math_optimizations"
14967  "* return output_fix_trunc (insn, operands, false);"
14968  [(set_attr "type" "fistp")
14969   (set_attr "i387_cw" "floor")
14970   (set_attr "mode" "DI")])
14971
14972(define_insn "fistdi2_floor_with_temp"
14973  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14974	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14975		   UNSPEC_FIST_FLOOR))
14976   (use (match_operand:HI 2 "memory_operand" "m,m"))
14977   (use (match_operand:HI 3 "memory_operand" "m,m"))
14978   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14979   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14980  "TARGET_USE_FANCY_MATH_387
14981   && flag_unsafe_math_optimizations"
14982  "#"
14983  [(set_attr "type" "fistp")
14984   (set_attr "i387_cw" "floor")
14985   (set_attr "mode" "DI")])
14986
14987(define_split
14988  [(set (match_operand:DI 0 "register_operand" "")
14989	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
14990		   UNSPEC_FIST_FLOOR))
14991   (use (match_operand:HI 2 "memory_operand" ""))
14992   (use (match_operand:HI 3 "memory_operand" ""))
14993   (clobber (match_operand:DI 4 "memory_operand" ""))
14994   (clobber (match_scratch 5 ""))]
14995  "reload_completed"
14996  [(parallel [(set (match_dup 4)
14997		   (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14998	      (use (match_dup 2))
14999	      (use (match_dup 3))
15000	      (clobber (match_dup 5))])
15001   (set (match_dup 0) (match_dup 4))])
15002
15003(define_split
15004  [(set (match_operand:DI 0 "memory_operand" "")
15005	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
15006		   UNSPEC_FIST_FLOOR))
15007   (use (match_operand:HI 2 "memory_operand" ""))
15008   (use (match_operand:HI 3 "memory_operand" ""))
15009   (clobber (match_operand:DI 4 "memory_operand" ""))
15010   (clobber (match_scratch 5 ""))]
15011  "reload_completed"
15012  [(parallel [(set (match_dup 0)
15013		   (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15014	      (use (match_dup 2))
15015	      (use (match_dup 3))
15016	      (clobber (match_dup 5))])])
15017
15018(define_insn "fist<mode>2_floor"
15019  [(set (match_operand:SWI24 0 "memory_operand" "=m")
15020	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15021		      UNSPEC_FIST_FLOOR))
15022   (use (match_operand:HI 2 "memory_operand" "m"))
15023   (use (match_operand:HI 3 "memory_operand" "m"))]
15024  "TARGET_USE_FANCY_MATH_387
15025   && flag_unsafe_math_optimizations"
15026  "* return output_fix_trunc (insn, operands, false);"
15027  [(set_attr "type" "fistp")
15028   (set_attr "i387_cw" "floor")
15029   (set_attr "mode" "<MODE>")])
15030
15031(define_insn "fist<mode>2_floor_with_temp"
15032  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15033	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15034		      UNSPEC_FIST_FLOOR))
15035   (use (match_operand:HI 2 "memory_operand" "m,m"))
15036   (use (match_operand:HI 3 "memory_operand" "m,m"))
15037   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15038  "TARGET_USE_FANCY_MATH_387
15039   && flag_unsafe_math_optimizations"
15040  "#"
15041  [(set_attr "type" "fistp")
15042   (set_attr "i387_cw" "floor")
15043   (set_attr "mode" "<MODE>")])
15044
15045(define_split
15046  [(set (match_operand:SWI24 0 "register_operand" "")
15047	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15048		      UNSPEC_FIST_FLOOR))
15049   (use (match_operand:HI 2 "memory_operand" ""))
15050   (use (match_operand:HI 3 "memory_operand" ""))
15051   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15052  "reload_completed"
15053  [(parallel [(set (match_dup 4)
15054		   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15055	      (use (match_dup 2))
15056	      (use (match_dup 3))])
15057   (set (match_dup 0) (match_dup 4))])
15058
15059(define_split
15060  [(set (match_operand:SWI24 0 "memory_operand" "")
15061	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15062		      UNSPEC_FIST_FLOOR))
15063   (use (match_operand:HI 2 "memory_operand" ""))
15064   (use (match_operand:HI 3 "memory_operand" ""))
15065   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15066  "reload_completed"
15067  [(parallel [(set (match_dup 0)
15068		   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15069	      (use (match_dup 2))
15070	      (use (match_dup 3))])])
15071
15072(define_expand "lfloorxf<mode>2"
15073  [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15074		   (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15075				   UNSPEC_FIST_FLOOR))
15076	      (clobber (reg:CC FLAGS_REG))])]
15077  "TARGET_USE_FANCY_MATH_387
15078   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15079   && flag_unsafe_math_optimizations")
15080
15081(define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15082  [(match_operand:SWI48 0 "nonimmediate_operand" "")
15083   (match_operand:MODEF 1 "register_operand" "")]
15084  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15085   && !flag_trapping_math"
15086{
15087  if (TARGET_64BIT && optimize_insn_for_size_p ())
15088    FAIL;
15089  ix86_expand_lfloorceil (operands[0], operands[1], true);
15090  DONE;
15091})
15092
15093;; Rounding mode control word calculation could clobber FLAGS_REG.
15094(define_insn_and_split "frndintxf2_ceil"
15095  [(set (match_operand:XF 0 "register_operand" "")
15096	(unspec:XF [(match_operand:XF 1 "register_operand" "")]
15097	 UNSPEC_FRNDINT_CEIL))
15098   (clobber (reg:CC FLAGS_REG))]
15099  "TARGET_USE_FANCY_MATH_387
15100   && flag_unsafe_math_optimizations
15101   && can_create_pseudo_p ()"
15102  "#"
15103  "&& 1"
15104  [(const_int 0)]
15105{
15106  ix86_optimize_mode_switching[I387_CEIL] = 1;
15107
15108  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15109  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15110
15111  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15112				       operands[2], operands[3]));
15113  DONE;
15114}
15115  [(set_attr "type" "frndint")
15116   (set_attr "i387_cw" "ceil")
15117   (set_attr "mode" "XF")])
15118
15119(define_insn "frndintxf2_ceil_i387"
15120  [(set (match_operand:XF 0 "register_operand" "=f")
15121	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15122	 UNSPEC_FRNDINT_CEIL))
15123   (use (match_operand:HI 2 "memory_operand" "m"))
15124   (use (match_operand:HI 3 "memory_operand" "m"))]
15125  "TARGET_USE_FANCY_MATH_387
15126   && flag_unsafe_math_optimizations"
15127  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15128  [(set_attr "type" "frndint")
15129   (set_attr "i387_cw" "ceil")
15130   (set_attr "mode" "XF")])
15131
15132(define_expand "ceilxf2"
15133  [(use (match_operand:XF 0 "register_operand" ""))
15134   (use (match_operand:XF 1 "register_operand" ""))]
15135  "TARGET_USE_FANCY_MATH_387
15136   && flag_unsafe_math_optimizations"
15137{
15138  if (optimize_insn_for_size_p ())
15139    FAIL;
15140  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15141  DONE;
15142})
15143
15144(define_expand "ceil<mode>2"
15145  [(use (match_operand:MODEF 0 "register_operand" ""))
15146   (use (match_operand:MODEF 1 "register_operand" ""))]
15147  "(TARGET_USE_FANCY_MATH_387
15148    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15149	|| TARGET_MIX_SSE_I387)
15150    && flag_unsafe_math_optimizations)
15151   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15152       && !flag_trapping_math)"
15153{
15154  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15155      && !flag_trapping_math)
15156    {
15157      if (TARGET_ROUND)
15158	emit_insn (gen_sse4_1_round<mode>2
15159		   (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15160      else if (optimize_insn_for_size_p ())
15161	FAIL;
15162      else if (TARGET_64BIT || (<MODE>mode != DFmode))
15163	ix86_expand_floorceil (operands[0], operands[1], false);
15164      else
15165	ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15166    }
15167  else
15168    {
15169      rtx op0, op1;
15170
15171      if (optimize_insn_for_size_p ())
15172	FAIL;
15173
15174      op0 = gen_reg_rtx (XFmode);
15175      op1 = gen_reg_rtx (XFmode);
15176      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15177      emit_insn (gen_frndintxf2_ceil (op0, op1));
15178
15179      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15180    }
15181  DONE;
15182})
15183
15184(define_insn_and_split "*fist<mode>2_ceil_1"
15185  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15186	(unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15187			UNSPEC_FIST_CEIL))
15188   (clobber (reg:CC FLAGS_REG))]
15189  "TARGET_USE_FANCY_MATH_387
15190   && flag_unsafe_math_optimizations
15191   && can_create_pseudo_p ()"
15192  "#"
15193  "&& 1"
15194  [(const_int 0)]
15195{
15196  ix86_optimize_mode_switching[I387_CEIL] = 1;
15197
15198  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15199  operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15200  if (memory_operand (operands[0], VOIDmode))
15201    emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15202				     operands[2], operands[3]));
15203  else
15204    {
15205      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15206      emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15207						 operands[2], operands[3],
15208						 operands[4]));
15209    }
15210  DONE;
15211}
15212  [(set_attr "type" "fistp")
15213   (set_attr "i387_cw" "ceil")
15214   (set_attr "mode" "<MODE>")])
15215
15216(define_insn "fistdi2_ceil"
15217  [(set (match_operand:DI 0 "memory_operand" "=m")
15218	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15219		   UNSPEC_FIST_CEIL))
15220   (use (match_operand:HI 2 "memory_operand" "m"))
15221   (use (match_operand:HI 3 "memory_operand" "m"))
15222   (clobber (match_scratch:XF 4 "=&1f"))]
15223  "TARGET_USE_FANCY_MATH_387
15224   && flag_unsafe_math_optimizations"
15225  "* return output_fix_trunc (insn, operands, false);"
15226  [(set_attr "type" "fistp")
15227   (set_attr "i387_cw" "ceil")
15228   (set_attr "mode" "DI")])
15229
15230(define_insn "fistdi2_ceil_with_temp"
15231  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15232	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15233		   UNSPEC_FIST_CEIL))
15234   (use (match_operand:HI 2 "memory_operand" "m,m"))
15235   (use (match_operand:HI 3 "memory_operand" "m,m"))
15236   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15237   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15238  "TARGET_USE_FANCY_MATH_387
15239   && flag_unsafe_math_optimizations"
15240  "#"
15241  [(set_attr "type" "fistp")
15242   (set_attr "i387_cw" "ceil")
15243   (set_attr "mode" "DI")])
15244
15245(define_split
15246  [(set (match_operand:DI 0 "register_operand" "")
15247	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
15248		   UNSPEC_FIST_CEIL))
15249   (use (match_operand:HI 2 "memory_operand" ""))
15250   (use (match_operand:HI 3 "memory_operand" ""))
15251   (clobber (match_operand:DI 4 "memory_operand" ""))
15252   (clobber (match_scratch 5 ""))]
15253  "reload_completed"
15254  [(parallel [(set (match_dup 4)
15255		   (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15256	      (use (match_dup 2))
15257	      (use (match_dup 3))
15258	      (clobber (match_dup 5))])
15259   (set (match_dup 0) (match_dup 4))])
15260
15261(define_split
15262  [(set (match_operand:DI 0 "memory_operand" "")
15263	(unspec:DI [(match_operand:XF 1 "register_operand" "")]
15264		   UNSPEC_FIST_CEIL))
15265   (use (match_operand:HI 2 "memory_operand" ""))
15266   (use (match_operand:HI 3 "memory_operand" ""))
15267   (clobber (match_operand:DI 4 "memory_operand" ""))
15268   (clobber (match_scratch 5 ""))]
15269  "reload_completed"
15270  [(parallel [(set (match_dup 0)
15271		   (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15272	      (use (match_dup 2))
15273	      (use (match_dup 3))
15274	      (clobber (match_dup 5))])])
15275
15276(define_insn "fist<mode>2_ceil"
15277  [(set (match_operand:SWI24 0 "memory_operand" "=m")
15278	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15279		      UNSPEC_FIST_CEIL))
15280   (use (match_operand:HI 2 "memory_operand" "m"))
15281   (use (match_operand:HI 3 "memory_operand" "m"))]
15282  "TARGET_USE_FANCY_MATH_387
15283   && flag_unsafe_math_optimizations"
15284  "* return output_fix_trunc (insn, operands, false);"
15285  [(set_attr "type" "fistp")
15286   (set_attr "i387_cw" "ceil")
15287   (set_attr "mode" "<MODE>")])
15288
15289(define_insn "fist<mode>2_ceil_with_temp"
15290  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15291	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15292		      UNSPEC_FIST_CEIL))
15293   (use (match_operand:HI 2 "memory_operand" "m,m"))
15294   (use (match_operand:HI 3 "memory_operand" "m,m"))
15295   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15296  "TARGET_USE_FANCY_MATH_387
15297   && flag_unsafe_math_optimizations"
15298  "#"
15299  [(set_attr "type" "fistp")
15300   (set_attr "i387_cw" "ceil")
15301   (set_attr "mode" "<MODE>")])
15302
15303(define_split
15304  [(set (match_operand:SWI24 0 "register_operand" "")
15305	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15306		      UNSPEC_FIST_CEIL))
15307   (use (match_operand:HI 2 "memory_operand" ""))
15308   (use (match_operand:HI 3 "memory_operand" ""))
15309   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15310  "reload_completed"
15311  [(parallel [(set (match_dup 4)
15312		   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15313	      (use (match_dup 2))
15314	      (use (match_dup 3))])
15315   (set (match_dup 0) (match_dup 4))])
15316
15317(define_split
15318  [(set (match_operand:SWI24 0 "memory_operand" "")
15319	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15320		      UNSPEC_FIST_CEIL))
15321   (use (match_operand:HI 2 "memory_operand" ""))
15322   (use (match_operand:HI 3 "memory_operand" ""))
15323   (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15324  "reload_completed"
15325  [(parallel [(set (match_dup 0)
15326		   (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15327	      (use (match_dup 2))
15328	      (use (match_dup 3))])])
15329
15330(define_expand "lceilxf<mode>2"
15331  [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15332		   (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15333				   UNSPEC_FIST_CEIL))
15334	      (clobber (reg:CC FLAGS_REG))])]
15335  "TARGET_USE_FANCY_MATH_387
15336   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15337   && flag_unsafe_math_optimizations")
15338
15339(define_expand "lceil<MODEF:mode><SWI48:mode>2"
15340  [(match_operand:SWI48 0 "nonimmediate_operand" "")
15341   (match_operand:MODEF 1 "register_operand" "")]
15342  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15343   && !flag_trapping_math"
15344{
15345  ix86_expand_lfloorceil (operands[0], operands[1], false);
15346  DONE;
15347})
15348
15349;; Rounding mode control word calculation could clobber FLAGS_REG.
15350(define_insn_and_split "frndintxf2_trunc"
15351  [(set (match_operand:XF 0 "register_operand" "")
15352	(unspec:XF [(match_operand:XF 1 "register_operand" "")]
15353	 UNSPEC_FRNDINT_TRUNC))
15354   (clobber (reg:CC FLAGS_REG))]
15355  "TARGET_USE_FANCY_MATH_387
15356   && flag_unsafe_math_optimizations
15357   && can_create_pseudo_p ()"
15358  "#"
15359  "&& 1"
15360  [(const_int 0)]
15361{
15362  ix86_optimize_mode_switching[I387_TRUNC] = 1;
15363
15364  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15365  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15366
15367  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15368					operands[2], operands[3]));
15369  DONE;
15370}
15371  [(set_attr "type" "frndint")
15372   (set_attr "i387_cw" "trunc")
15373   (set_attr "mode" "XF")])
15374
15375(define_insn "frndintxf2_trunc_i387"
15376  [(set (match_operand:XF 0 "register_operand" "=f")
15377	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15378	 UNSPEC_FRNDINT_TRUNC))
15379   (use (match_operand:HI 2 "memory_operand" "m"))
15380   (use (match_operand:HI 3 "memory_operand" "m"))]
15381  "TARGET_USE_FANCY_MATH_387
15382   && flag_unsafe_math_optimizations"
15383  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15384  [(set_attr "type" "frndint")
15385   (set_attr "i387_cw" "trunc")
15386   (set_attr "mode" "XF")])
15387
15388(define_expand "btruncxf2"
15389  [(use (match_operand:XF 0 "register_operand" ""))
15390   (use (match_operand:XF 1 "register_operand" ""))]
15391  "TARGET_USE_FANCY_MATH_387
15392   && flag_unsafe_math_optimizations"
15393{
15394  if (optimize_insn_for_size_p ())
15395    FAIL;
15396  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15397  DONE;
15398})
15399
15400(define_expand "btrunc<mode>2"
15401  [(use (match_operand:MODEF 0 "register_operand" ""))
15402   (use (match_operand:MODEF 1 "register_operand" ""))]
15403  "(TARGET_USE_FANCY_MATH_387
15404    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15405	|| TARGET_MIX_SSE_I387)
15406    && flag_unsafe_math_optimizations)
15407   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15408       && !flag_trapping_math)"
15409{
15410  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15411      && !flag_trapping_math)
15412    {
15413      if (TARGET_ROUND)
15414	emit_insn (gen_sse4_1_round<mode>2
15415		   (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15416      else if (optimize_insn_for_size_p ())
15417	FAIL;
15418      else if (TARGET_64BIT || (<MODE>mode != DFmode))
15419	ix86_expand_trunc (operands[0], operands[1]);
15420      else
15421	ix86_expand_truncdf_32 (operands[0], operands[1]);
15422    }
15423  else
15424    {
15425      rtx op0, op1;
15426
15427      if (optimize_insn_for_size_p ())
15428	FAIL;
15429
15430      op0 = gen_reg_rtx (XFmode);
15431      op1 = gen_reg_rtx (XFmode);
15432      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15433      emit_insn (gen_frndintxf2_trunc (op0, op1));
15434
15435      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15436    }
15437  DONE;
15438})
15439
15440;; Rounding mode control word calculation could clobber FLAGS_REG.
15441(define_insn_and_split "frndintxf2_mask_pm"
15442  [(set (match_operand:XF 0 "register_operand" "")
15443	(unspec:XF [(match_operand:XF 1 "register_operand" "")]
15444	 UNSPEC_FRNDINT_MASK_PM))
15445   (clobber (reg:CC FLAGS_REG))]
15446  "TARGET_USE_FANCY_MATH_387
15447   && flag_unsafe_math_optimizations
15448   && can_create_pseudo_p ()"
15449  "#"
15450  "&& 1"
15451  [(const_int 0)]
15452{
15453  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15454
15455  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15456  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15457
15458  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15459					  operands[2], operands[3]));
15460  DONE;
15461}
15462  [(set_attr "type" "frndint")
15463   (set_attr "i387_cw" "mask_pm")
15464   (set_attr "mode" "XF")])
15465
15466(define_insn "frndintxf2_mask_pm_i387"
15467  [(set (match_operand:XF 0 "register_operand" "=f")
15468	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15469	 UNSPEC_FRNDINT_MASK_PM))
15470   (use (match_operand:HI 2 "memory_operand" "m"))
15471   (use (match_operand:HI 3 "memory_operand" "m"))]
15472  "TARGET_USE_FANCY_MATH_387
15473   && flag_unsafe_math_optimizations"
15474  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15475  [(set_attr "type" "frndint")
15476   (set_attr "i387_cw" "mask_pm")
15477   (set_attr "mode" "XF")])
15478
15479(define_expand "nearbyintxf2"
15480  [(use (match_operand:XF 0 "register_operand" ""))
15481   (use (match_operand:XF 1 "register_operand" ""))]
15482  "TARGET_USE_FANCY_MATH_387
15483   && flag_unsafe_math_optimizations"
15484{
15485  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15486  DONE;
15487})
15488
15489(define_expand "nearbyint<mode>2"
15490  [(use (match_operand:MODEF 0 "register_operand" ""))
15491   (use (match_operand:MODEF 1 "register_operand" ""))]
15492  "TARGET_USE_FANCY_MATH_387
15493   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15494       || TARGET_MIX_SSE_I387)
15495   && flag_unsafe_math_optimizations"
15496{
15497  rtx op0 = gen_reg_rtx (XFmode);
15498  rtx op1 = gen_reg_rtx (XFmode);
15499
15500  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15501  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15502
15503  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15504  DONE;
15505})
15506
15507(define_insn "fxam<mode>2_i387"
15508  [(set (match_operand:HI 0 "register_operand" "=a")
15509	(unspec:HI
15510	  [(match_operand:X87MODEF 1 "register_operand" "f")]
15511	  UNSPEC_FXAM))]
15512  "TARGET_USE_FANCY_MATH_387"
15513  "fxam\n\tfnstsw\t%0"
15514  [(set_attr "type" "multi")
15515   (set_attr "length" "4")
15516   (set_attr "unit" "i387")
15517   (set_attr "mode" "<MODE>")])
15518
15519(define_insn_and_split "fxam<mode>2_i387_with_temp"
15520  [(set (match_operand:HI 0 "register_operand" "")
15521	(unspec:HI
15522	  [(match_operand:MODEF 1 "memory_operand" "")]
15523	  UNSPEC_FXAM_MEM))]
15524  "TARGET_USE_FANCY_MATH_387
15525   && can_create_pseudo_p ()"
15526  "#"
15527  "&& 1"
15528  [(set (match_dup 2)(match_dup 1))
15529   (set (match_dup 0)
15530	(unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15531{
15532  operands[2] = gen_reg_rtx (<MODE>mode);
15533
15534  MEM_VOLATILE_P (operands[1]) = 1;
15535}
15536  [(set_attr "type" "multi")
15537   (set_attr "unit" "i387")
15538   (set_attr "mode" "<MODE>")])
15539
15540(define_expand "isinfxf2"
15541  [(use (match_operand:SI 0 "register_operand" ""))
15542   (use (match_operand:XF 1 "register_operand" ""))]
15543  "TARGET_USE_FANCY_MATH_387
15544   && TARGET_C99_FUNCTIONS"
15545{
15546  rtx mask = GEN_INT (0x45);
15547  rtx val = GEN_INT (0x05);
15548
15549  rtx cond;
15550
15551  rtx scratch = gen_reg_rtx (HImode);
15552  rtx res = gen_reg_rtx (QImode);
15553
15554  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15555
15556  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15557  emit_insn (gen_cmpqi_ext_3 (scratch, val));
15558  cond = gen_rtx_fmt_ee (EQ, QImode,
15559			 gen_rtx_REG (CCmode, FLAGS_REG),
15560			 const0_rtx);
15561  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15562  emit_insn (gen_zero_extendqisi2 (operands[0], res));
15563  DONE;
15564})
15565
15566(define_expand "isinf<mode>2"
15567  [(use (match_operand:SI 0 "register_operand" ""))
15568   (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15569  "TARGET_USE_FANCY_MATH_387
15570   && TARGET_C99_FUNCTIONS
15571   && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15572{
15573  rtx mask = GEN_INT (0x45);
15574  rtx val = GEN_INT (0x05);
15575
15576  rtx cond;
15577
15578  rtx scratch = gen_reg_rtx (HImode);
15579  rtx res = gen_reg_rtx (QImode);
15580
15581  /* Remove excess precision by forcing value through memory. */
15582  if (memory_operand (operands[1], VOIDmode))
15583    emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15584  else
15585    {
15586      rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15587
15588      emit_move_insn (temp, operands[1]);
15589      emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15590    }
15591
15592  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15593  emit_insn (gen_cmpqi_ext_3 (scratch, val));
15594  cond = gen_rtx_fmt_ee (EQ, QImode,
15595			 gen_rtx_REG (CCmode, FLAGS_REG),
15596			 const0_rtx);
15597  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15598  emit_insn (gen_zero_extendqisi2 (operands[0], res));
15599  DONE;
15600})
15601
15602(define_expand "signbitxf2"
15603  [(use (match_operand:SI 0 "register_operand" ""))
15604   (use (match_operand:XF 1 "register_operand" ""))]
15605  "TARGET_USE_FANCY_MATH_387"
15606{
15607  rtx scratch = gen_reg_rtx (HImode);
15608
15609  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15610  emit_insn (gen_andsi3 (operands[0],
15611	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15612  DONE;
15613})
15614
15615(define_insn "movmsk_df"
15616  [(set (match_operand:SI 0 "register_operand" "=r")
15617	(unspec:SI
15618	  [(match_operand:DF 1 "register_operand" "x")]
15619	  UNSPEC_MOVMSK))]
15620  "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15621  "%vmovmskpd\t{%1, %0|%0, %1}"
15622  [(set_attr "type" "ssemov")
15623   (set_attr "prefix" "maybe_vex")
15624   (set_attr "mode" "DF")])
15625
15626;; Use movmskpd in SSE mode to avoid store forwarding stall
15627;; for 32bit targets and movq+shrq sequence for 64bit targets.
15628(define_expand "signbitdf2"
15629  [(use (match_operand:SI 0 "register_operand" ""))
15630   (use (match_operand:DF 1 "register_operand" ""))]
15631  "TARGET_USE_FANCY_MATH_387
15632   || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15633{
15634  if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15635    {
15636      emit_insn (gen_movmsk_df (operands[0], operands[1]));
15637      emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15638    }
15639  else
15640    {
15641      rtx scratch = gen_reg_rtx (HImode);
15642
15643      emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15644      emit_insn (gen_andsi3 (operands[0],
15645		 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15646    }
15647  DONE;
15648})
15649
15650(define_expand "signbitsf2"
15651  [(use (match_operand:SI 0 "register_operand" ""))
15652   (use (match_operand:SF 1 "register_operand" ""))]
15653  "TARGET_USE_FANCY_MATH_387
15654   && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15655{
15656  rtx scratch = gen_reg_rtx (HImode);
15657
15658  emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15659  emit_insn (gen_andsi3 (operands[0],
15660	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15661  DONE;
15662})
15663
15664;; Block operation instructions
15665
15666(define_insn "cld"
15667  [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15668  ""
15669  "cld"
15670  [(set_attr "length" "1")
15671   (set_attr "length_immediate" "0")
15672   (set_attr "modrm" "0")])
15673
15674(define_expand "movmem<mode>"
15675  [(use (match_operand:BLK 0 "memory_operand" ""))
15676   (use (match_operand:BLK 1 "memory_operand" ""))
15677   (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15678   (use (match_operand:SWI48 3 "const_int_operand" ""))
15679   (use (match_operand:SI 4 "const_int_operand" ""))
15680   (use (match_operand:SI 5 "const_int_operand" ""))]
15681  ""
15682{
15683 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15684			 operands[4], operands[5]))
15685   DONE;
15686 else
15687   FAIL;
15688})
15689
15690;; Most CPUs don't like single string operations
15691;; Handle this case here to simplify previous expander.
15692
15693(define_expand "strmov"
15694  [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15695   (set (match_operand 1 "memory_operand" "") (match_dup 4))
15696   (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15697	      (clobber (reg:CC FLAGS_REG))])
15698   (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15699	      (clobber (reg:CC FLAGS_REG))])]
15700  ""
15701{
15702  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15703
15704  /* If .md ever supports :P for Pmode, these can be directly
15705     in the pattern above.  */
15706  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15707  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15708
15709  /* Can't use this if the user has appropriated esi or edi.  */
15710  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15711      && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15712    {
15713      emit_insn (gen_strmov_singleop (operands[0], operands[1],
15714				      operands[2], operands[3],
15715				      operands[5], operands[6]));
15716      DONE;
15717    }
15718
15719  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15720})
15721
15722(define_expand "strmov_singleop"
15723  [(parallel [(set (match_operand 1 "memory_operand" "")
15724		   (match_operand 3 "memory_operand" ""))
15725	      (set (match_operand 0 "register_operand" "")
15726		   (match_operand 4 "" ""))
15727	      (set (match_operand 2 "register_operand" "")
15728		   (match_operand 5 "" ""))])]
15729  ""
15730  "ix86_current_function_needs_cld = 1;")
15731
15732(define_insn "*strmovdi_rex_1"
15733  [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15734	(mem:DI (match_operand:DI 3 "register_operand" "1")))
15735   (set (match_operand:DI 0 "register_operand" "=D")
15736	(plus:DI (match_dup 2)
15737		 (const_int 8)))
15738   (set (match_operand:DI 1 "register_operand" "=S")
15739	(plus:DI (match_dup 3)
15740		 (const_int 8)))]
15741  "TARGET_64BIT
15742   && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15743  "movsq"
15744  [(set_attr "type" "str")
15745   (set_attr "memory" "both")
15746   (set_attr "mode" "DI")])
15747
15748(define_insn "*strmovsi_1"
15749  [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15750	(mem:SI (match_operand:P 3 "register_operand" "1")))
15751   (set (match_operand:P 0 "register_operand" "=D")
15752	(plus:P (match_dup 2)
15753		(const_int 4)))
15754   (set (match_operand:P 1 "register_operand" "=S")
15755	(plus:P (match_dup 3)
15756		(const_int 4)))]
15757  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15758  "movs{l|d}"
15759  [(set_attr "type" "str")
15760   (set_attr "memory" "both")
15761   (set_attr "mode" "SI")])
15762
15763(define_insn "*strmovhi_1"
15764  [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15765	(mem:HI (match_operand:P 3 "register_operand" "1")))
15766   (set (match_operand:P 0 "register_operand" "=D")
15767	(plus:P (match_dup 2)
15768		(const_int 2)))
15769   (set (match_operand:P 1 "register_operand" "=S")
15770	(plus:P (match_dup 3)
15771		(const_int 2)))]
15772  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15773  "movsw"
15774  [(set_attr "type" "str")
15775   (set_attr "memory" "both")
15776   (set_attr "mode" "HI")])
15777
15778(define_insn "*strmovqi_1"
15779  [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15780	(mem:QI (match_operand:P 3 "register_operand" "1")))
15781   (set (match_operand:P 0 "register_operand" "=D")
15782	(plus:P (match_dup 2)
15783		(const_int 1)))
15784   (set (match_operand:P 1 "register_operand" "=S")
15785	(plus:P (match_dup 3)
15786		(const_int 1)))]
15787  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15788  "movsb"
15789  [(set_attr "type" "str")
15790   (set_attr "memory" "both")
15791   (set (attr "prefix_rex")
15792	(if_then_else
15793	  (match_test "<P:MODE>mode == DImode")
15794	  (const_string "0")
15795	  (const_string "*")))
15796   (set_attr "mode" "QI")])
15797
15798(define_expand "rep_mov"
15799  [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15800	      (set (match_operand 0 "register_operand" "")
15801		   (match_operand 5 "" ""))
15802	      (set (match_operand 2 "register_operand" "")
15803		   (match_operand 6 "" ""))
15804	      (set (match_operand 1 "memory_operand" "")
15805		   (match_operand 3 "memory_operand" ""))
15806	      (use (match_dup 4))])]
15807  ""
15808  "ix86_current_function_needs_cld = 1;")
15809
15810(define_insn "*rep_movdi_rex64"
15811  [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15812   (set (match_operand:DI 0 "register_operand" "=D")
15813        (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15814			    (const_int 3))
15815		 (match_operand:DI 3 "register_operand" "0")))
15816   (set (match_operand:DI 1 "register_operand" "=S")
15817        (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15818		 (match_operand:DI 4 "register_operand" "1")))
15819   (set (mem:BLK (match_dup 3))
15820	(mem:BLK (match_dup 4)))
15821   (use (match_dup 5))]
15822  "TARGET_64BIT
15823   && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15824  "rep{%;} movsq"
15825  [(set_attr "type" "str")
15826   (set_attr "prefix_rep" "1")
15827   (set_attr "memory" "both")
15828   (set_attr "mode" "DI")])
15829
15830(define_insn "*rep_movsi"
15831  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15832   (set (match_operand:P 0 "register_operand" "=D")
15833        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15834			  (const_int 2))
15835		 (match_operand:P 3 "register_operand" "0")))
15836   (set (match_operand:P 1 "register_operand" "=S")
15837        (plus:P (ashift:P (match_dup 5) (const_int 2))
15838		(match_operand:P 4 "register_operand" "1")))
15839   (set (mem:BLK (match_dup 3))
15840	(mem:BLK (match_dup 4)))
15841   (use (match_dup 5))]
15842  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15843  "rep{%;} movs{l|d}"
15844  [(set_attr "type" "str")
15845   (set_attr "prefix_rep" "1")
15846   (set_attr "memory" "both")
15847   (set_attr "mode" "SI")])
15848
15849(define_insn "*rep_movqi"
15850  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15851   (set (match_operand:P 0 "register_operand" "=D")
15852        (plus:P (match_operand:P 3 "register_operand" "0")
15853		(match_operand:P 5 "register_operand" "2")))
15854   (set (match_operand:P 1 "register_operand" "=S")
15855        (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15856   (set (mem:BLK (match_dup 3))
15857	(mem:BLK (match_dup 4)))
15858   (use (match_dup 5))]
15859  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15860  "rep{%;} movsb"
15861  [(set_attr "type" "str")
15862   (set_attr "prefix_rep" "1")
15863   (set_attr "memory" "both")
15864   (set_attr "mode" "QI")])
15865
15866(define_expand "setmem<mode>"
15867   [(use (match_operand:BLK 0 "memory_operand" ""))
15868    (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15869    (use (match_operand:QI 2 "nonmemory_operand" ""))
15870    (use (match_operand 3 "const_int_operand" ""))
15871    (use (match_operand:SI 4 "const_int_operand" ""))
15872    (use (match_operand:SI 5 "const_int_operand" ""))]
15873  ""
15874{
15875 if (ix86_expand_setmem (operands[0], operands[1],
15876			 operands[2], operands[3],
15877			 operands[4], operands[5]))
15878   DONE;
15879 else
15880   FAIL;
15881})
15882
15883;; Most CPUs don't like single string operations
15884;; Handle this case here to simplify previous expander.
15885
15886(define_expand "strset"
15887  [(set (match_operand 1 "memory_operand" "")
15888	(match_operand 2 "register_operand" ""))
15889   (parallel [(set (match_operand 0 "register_operand" "")
15890		   (match_dup 3))
15891	      (clobber (reg:CC FLAGS_REG))])]
15892  ""
15893{
15894  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15895    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15896
15897  /* If .md ever supports :P for Pmode, this can be directly
15898     in the pattern above.  */
15899  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15900			      GEN_INT (GET_MODE_SIZE (GET_MODE
15901						      (operands[2]))));
15902  /* Can't use this if the user has appropriated eax or edi.  */
15903  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15904      && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15905    {
15906      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15907				      operands[3]));
15908      DONE;
15909    }
15910})
15911
15912(define_expand "strset_singleop"
15913  [(parallel [(set (match_operand 1 "memory_operand" "")
15914		   (match_operand 2 "register_operand" ""))
15915	      (set (match_operand 0 "register_operand" "")
15916		   (match_operand 3 "" ""))
15917	      (unspec [(const_int 0)] UNSPEC_STOS)])]
15918  ""
15919  "ix86_current_function_needs_cld = 1;")
15920
15921(define_insn "*strsetdi_rex_1"
15922  [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15923	(match_operand:DI 2 "register_operand" "a"))
15924   (set (match_operand:DI 0 "register_operand" "=D")
15925	(plus:DI (match_dup 1)
15926		 (const_int 8)))
15927   (unspec [(const_int 0)] UNSPEC_STOS)]
15928  "TARGET_64BIT
15929   && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15930  "stosq"
15931  [(set_attr "type" "str")
15932   (set_attr "memory" "store")
15933   (set_attr "mode" "DI")])
15934
15935(define_insn "*strsetsi_1"
15936  [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15937	(match_operand:SI 2 "register_operand" "a"))
15938   (set (match_operand:P 0 "register_operand" "=D")
15939	(plus:P (match_dup 1)
15940		(const_int 4)))
15941   (unspec [(const_int 0)] UNSPEC_STOS)]
15942  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15943  "stos{l|d}"
15944  [(set_attr "type" "str")
15945   (set_attr "memory" "store")
15946   (set_attr "mode" "SI")])
15947
15948(define_insn "*strsethi_1"
15949  [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15950	(match_operand:HI 2 "register_operand" "a"))
15951   (set (match_operand:P 0 "register_operand" "=D")
15952	(plus:P (match_dup 1)
15953		(const_int 2)))
15954   (unspec [(const_int 0)] UNSPEC_STOS)]
15955  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15956  "stosw"
15957  [(set_attr "type" "str")
15958   (set_attr "memory" "store")
15959   (set_attr "mode" "HI")])
15960
15961(define_insn "*strsetqi_1"
15962  [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15963	(match_operand:QI 2 "register_operand" "a"))
15964   (set (match_operand:P 0 "register_operand" "=D")
15965	(plus:P (match_dup 1)
15966		(const_int 1)))
15967   (unspec [(const_int 0)] UNSPEC_STOS)]
15968  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15969  "stosb"
15970  [(set_attr "type" "str")
15971   (set_attr "memory" "store")
15972   (set (attr "prefix_rex")
15973	(if_then_else
15974	  (match_test "<P:MODE>mode == DImode")
15975	  (const_string "0")
15976	  (const_string "*")))
15977   (set_attr "mode" "QI")])
15978
15979(define_expand "rep_stos"
15980  [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15981	      (set (match_operand 0 "register_operand" "")
15982		   (match_operand 4 "" ""))
15983	      (set (match_operand 2 "memory_operand" "") (const_int 0))
15984	      (use (match_operand 3 "register_operand" ""))
15985	      (use (match_dup 1))])]
15986  ""
15987  "ix86_current_function_needs_cld = 1;")
15988
15989(define_insn "*rep_stosdi_rex64"
15990  [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15991   (set (match_operand:DI 0 "register_operand" "=D")
15992        (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15993			    (const_int 3))
15994		 (match_operand:DI 3 "register_operand" "0")))
15995   (set (mem:BLK (match_dup 3))
15996	(const_int 0))
15997   (use (match_operand:DI 2 "register_operand" "a"))
15998   (use (match_dup 4))]
15999  "TARGET_64BIT
16000   && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16001  "rep{%;} stosq"
16002  [(set_attr "type" "str")
16003   (set_attr "prefix_rep" "1")
16004   (set_attr "memory" "store")
16005   (set_attr "mode" "DI")])
16006
16007(define_insn "*rep_stossi"
16008  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16009   (set (match_operand:P 0 "register_operand" "=D")
16010        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16011			  (const_int 2))
16012		 (match_operand:P 3 "register_operand" "0")))
16013   (set (mem:BLK (match_dup 3))
16014	(const_int 0))
16015   (use (match_operand:SI 2 "register_operand" "a"))
16016   (use (match_dup 4))]
16017  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16018  "rep{%;} stos{l|d}"
16019  [(set_attr "type" "str")
16020   (set_attr "prefix_rep" "1")
16021   (set_attr "memory" "store")
16022   (set_attr "mode" "SI")])
16023
16024(define_insn "*rep_stosqi"
16025  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16026   (set (match_operand:P 0 "register_operand" "=D")
16027        (plus:P (match_operand:P 3 "register_operand" "0")
16028		(match_operand:P 4 "register_operand" "1")))
16029   (set (mem:BLK (match_dup 3))
16030	(const_int 0))
16031   (use (match_operand:QI 2 "register_operand" "a"))
16032   (use (match_dup 4))]
16033  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16034  "rep{%;} stosb"
16035  [(set_attr "type" "str")
16036   (set_attr "prefix_rep" "1")
16037   (set_attr "memory" "store")
16038   (set (attr "prefix_rex")
16039	(if_then_else
16040	  (match_test "<P:MODE>mode == DImode")
16041	  (const_string "0")
16042	  (const_string "*")))
16043   (set_attr "mode" "QI")])
16044
16045(define_expand "cmpstrnsi"
16046  [(set (match_operand:SI 0 "register_operand" "")
16047	(compare:SI (match_operand:BLK 1 "general_operand" "")
16048		    (match_operand:BLK 2 "general_operand" "")))
16049   (use (match_operand 3 "general_operand" ""))
16050   (use (match_operand 4 "immediate_operand" ""))]
16051  ""
16052{
16053  rtx addr1, addr2, out, outlow, count, countreg, align;
16054
16055  if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16056    FAIL;
16057
16058  /* Can't use this if the user has appropriated ecx, esi or edi.  */
16059  if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16060    FAIL;
16061
16062  out = operands[0];
16063  if (!REG_P (out))
16064    out = gen_reg_rtx (SImode);
16065
16066  addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16067  addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16068  if (addr1 != XEXP (operands[1], 0))
16069    operands[1] = replace_equiv_address_nv (operands[1], addr1);
16070  if (addr2 != XEXP (operands[2], 0))
16071    operands[2] = replace_equiv_address_nv (operands[2], addr2);
16072
16073  count = operands[3];
16074  countreg = ix86_zero_extend_to_Pmode (count);
16075
16076  /* %%% Iff we are testing strict equality, we can use known alignment
16077     to good advantage.  This may be possible with combine, particularly
16078     once cc0 is dead.  */
16079  align = operands[4];
16080
16081  if (CONST_INT_P (count))
16082    {
16083      if (INTVAL (count) == 0)
16084	{
16085	  emit_move_insn (operands[0], const0_rtx);
16086	  DONE;
16087	}
16088      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16089				     operands[1], operands[2]));
16090    }
16091  else
16092    {
16093      rtx (*gen_cmp) (rtx, rtx);
16094
16095      gen_cmp = (TARGET_64BIT
16096		 ? gen_cmpdi_1 : gen_cmpsi_1);
16097
16098      emit_insn (gen_cmp (countreg, countreg));
16099      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16100				  operands[1], operands[2]));
16101    }
16102
16103  outlow = gen_lowpart (QImode, out);
16104  emit_insn (gen_cmpintqi (outlow));
16105  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16106
16107  if (operands[0] != out)
16108    emit_move_insn (operands[0], out);
16109
16110  DONE;
16111})
16112
16113;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16114
16115(define_expand "cmpintqi"
16116  [(set (match_dup 1)
16117	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16118   (set (match_dup 2)
16119	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16120   (parallel [(set (match_operand:QI 0 "register_operand" "")
16121		   (minus:QI (match_dup 1)
16122			     (match_dup 2)))
16123	      (clobber (reg:CC FLAGS_REG))])]
16124  ""
16125{
16126  operands[1] = gen_reg_rtx (QImode);
16127  operands[2] = gen_reg_rtx (QImode);
16128})
16129
16130;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16131;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16132
16133(define_expand "cmpstrnqi_nz_1"
16134  [(parallel [(set (reg:CC FLAGS_REG)
16135		   (compare:CC (match_operand 4 "memory_operand" "")
16136			       (match_operand 5 "memory_operand" "")))
16137	      (use (match_operand 2 "register_operand" ""))
16138	      (use (match_operand:SI 3 "immediate_operand" ""))
16139	      (clobber (match_operand 0 "register_operand" ""))
16140	      (clobber (match_operand 1 "register_operand" ""))
16141	      (clobber (match_dup 2))])]
16142  ""
16143  "ix86_current_function_needs_cld = 1;")
16144
16145(define_insn "*cmpstrnqi_nz_1"
16146  [(set (reg:CC FLAGS_REG)
16147	(compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16148		    (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16149   (use (match_operand:P 6 "register_operand" "2"))
16150   (use (match_operand:SI 3 "immediate_operand" "i"))
16151   (clobber (match_operand:P 0 "register_operand" "=S"))
16152   (clobber (match_operand:P 1 "register_operand" "=D"))
16153   (clobber (match_operand:P 2 "register_operand" "=c"))]
16154  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16155  "repz{%;} cmpsb"
16156  [(set_attr "type" "str")
16157   (set_attr "mode" "QI")
16158   (set (attr "prefix_rex")
16159	(if_then_else
16160	  (match_test "<P:MODE>mode == DImode")
16161	  (const_string "0")
16162	  (const_string "*")))
16163   (set_attr "prefix_rep" "1")])
16164
16165;; The same, but the count is not known to not be zero.
16166
16167(define_expand "cmpstrnqi_1"
16168  [(parallel [(set (reg:CC FLAGS_REG)
16169		(if_then_else:CC (ne (match_operand 2 "register_operand" "")
16170				     (const_int 0))
16171		  (compare:CC (match_operand 4 "memory_operand" "")
16172			      (match_operand 5 "memory_operand" ""))
16173		  (const_int 0)))
16174	      (use (match_operand:SI 3 "immediate_operand" ""))
16175	      (use (reg:CC FLAGS_REG))
16176	      (clobber (match_operand 0 "register_operand" ""))
16177	      (clobber (match_operand 1 "register_operand" ""))
16178	      (clobber (match_dup 2))])]
16179  ""
16180  "ix86_current_function_needs_cld = 1;")
16181
16182(define_insn "*cmpstrnqi_1"
16183  [(set (reg:CC FLAGS_REG)
16184	(if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16185			     (const_int 0))
16186	  (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16187		      (mem:BLK (match_operand:P 5 "register_operand" "1")))
16188	  (const_int 0)))
16189   (use (match_operand:SI 3 "immediate_operand" "i"))
16190   (use (reg:CC FLAGS_REG))
16191   (clobber (match_operand:P 0 "register_operand" "=S"))
16192   (clobber (match_operand:P 1 "register_operand" "=D"))
16193   (clobber (match_operand:P 2 "register_operand" "=c"))]
16194  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16195  "repz{%;} cmpsb"
16196  [(set_attr "type" "str")
16197   (set_attr "mode" "QI")
16198   (set (attr "prefix_rex")
16199	(if_then_else
16200	  (match_test "<P:MODE>mode == DImode")
16201	  (const_string "0")
16202	  (const_string "*")))
16203   (set_attr "prefix_rep" "1")])
16204
16205(define_expand "strlen<mode>"
16206  [(set (match_operand:P 0 "register_operand" "")
16207	(unspec:P [(match_operand:BLK 1 "general_operand" "")
16208		   (match_operand:QI 2 "immediate_operand" "")
16209		   (match_operand 3 "immediate_operand" "")]
16210		  UNSPEC_SCAS))]
16211  ""
16212{
16213 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16214   DONE;
16215 else
16216   FAIL;
16217})
16218
16219(define_expand "strlenqi_1"
16220  [(parallel [(set (match_operand 0 "register_operand" "")
16221		   (match_operand 2 "" ""))
16222	      (clobber (match_operand 1 "register_operand" ""))
16223	      (clobber (reg:CC FLAGS_REG))])]
16224  ""
16225  "ix86_current_function_needs_cld = 1;")
16226
16227(define_insn "*strlenqi_1"
16228  [(set (match_operand:P 0 "register_operand" "=&c")
16229	(unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16230		   (match_operand:QI 2 "register_operand" "a")
16231		   (match_operand:P 3 "immediate_operand" "i")
16232		   (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16233   (clobber (match_operand:P 1 "register_operand" "=D"))
16234   (clobber (reg:CC FLAGS_REG))]
16235  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16236  "repnz{%;} scasb"
16237  [(set_attr "type" "str")
16238   (set_attr "mode" "QI")
16239   (set (attr "prefix_rex")
16240	(if_then_else
16241	  (match_test "<P:MODE>mode == DImode")
16242	  (const_string "0")
16243	  (const_string "*")))
16244   (set_attr "prefix_rep" "1")])
16245
16246;; Peephole optimizations to clean up after cmpstrn*.  This should be
16247;; handled in combine, but it is not currently up to the task.
16248;; When used for their truth value, the cmpstrn* expanders generate
16249;; code like this:
16250;;
16251;;   repz cmpsb
16252;;   seta 	%al
16253;;   setb 	%dl
16254;;   cmpb 	%al, %dl
16255;;   jcc	label
16256;;
16257;; The intermediate three instructions are unnecessary.
16258
16259;; This one handles cmpstrn*_nz_1...
16260(define_peephole2
16261  [(parallel[
16262     (set (reg:CC FLAGS_REG)
16263	  (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16264		      (mem:BLK (match_operand 5 "register_operand" ""))))
16265     (use (match_operand 6 "register_operand" ""))
16266     (use (match_operand:SI 3 "immediate_operand" ""))
16267     (clobber (match_operand 0 "register_operand" ""))
16268     (clobber (match_operand 1 "register_operand" ""))
16269     (clobber (match_operand 2 "register_operand" ""))])
16270   (set (match_operand:QI 7 "register_operand" "")
16271	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16272   (set (match_operand:QI 8 "register_operand" "")
16273	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16274   (set (reg FLAGS_REG)
16275	(compare (match_dup 7) (match_dup 8)))
16276  ]
16277  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16278  [(parallel[
16279     (set (reg:CC FLAGS_REG)
16280	  (compare:CC (mem:BLK (match_dup 4))
16281		      (mem:BLK (match_dup 5))))
16282     (use (match_dup 6))
16283     (use (match_dup 3))
16284     (clobber (match_dup 0))
16285     (clobber (match_dup 1))
16286     (clobber (match_dup 2))])])
16287
16288;; ...and this one handles cmpstrn*_1.
16289(define_peephole2
16290  [(parallel[
16291     (set (reg:CC FLAGS_REG)
16292	  (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16293			       (const_int 0))
16294	    (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16295		        (mem:BLK (match_operand 5 "register_operand" "")))
16296	    (const_int 0)))
16297     (use (match_operand:SI 3 "immediate_operand" ""))
16298     (use (reg:CC FLAGS_REG))
16299     (clobber (match_operand 0 "register_operand" ""))
16300     (clobber (match_operand 1 "register_operand" ""))
16301     (clobber (match_operand 2 "register_operand" ""))])
16302   (set (match_operand:QI 7 "register_operand" "")
16303	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16304   (set (match_operand:QI 8 "register_operand" "")
16305	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16306   (set (reg FLAGS_REG)
16307	(compare (match_dup 7) (match_dup 8)))
16308  ]
16309  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16310  [(parallel[
16311     (set (reg:CC FLAGS_REG)
16312	  (if_then_else:CC (ne (match_dup 6)
16313			       (const_int 0))
16314	    (compare:CC (mem:BLK (match_dup 4))
16315			(mem:BLK (match_dup 5)))
16316	    (const_int 0)))
16317     (use (match_dup 3))
16318     (use (reg:CC FLAGS_REG))
16319     (clobber (match_dup 0))
16320     (clobber (match_dup 1))
16321     (clobber (match_dup 2))])])
16322
16323;; Conditional move instructions.
16324
16325(define_expand "mov<mode>cc"
16326  [(set (match_operand:SWIM 0 "register_operand" "")
16327	(if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16328			   (match_operand:SWIM 2 "<general_operand>" "")
16329			   (match_operand:SWIM 3 "<general_operand>" "")))]
16330  ""
16331  "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16332
16333;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16334;; the register first winds up with `sbbl $0,reg', which is also weird.
16335;; So just document what we're doing explicitly.
16336
16337(define_expand "x86_mov<mode>cc_0_m1"
16338  [(parallel
16339    [(set (match_operand:SWI48 0 "register_operand" "")
16340	  (if_then_else:SWI48
16341	    (match_operator:SWI48 2 "ix86_carry_flag_operator"
16342	     [(match_operand 1 "flags_reg_operand" "")
16343	      (const_int 0)])
16344	    (const_int -1)
16345	    (const_int 0)))
16346     (clobber (reg:CC FLAGS_REG))])])
16347
16348(define_insn "*x86_mov<mode>cc_0_m1"
16349  [(set (match_operand:SWI48 0 "register_operand" "=r")
16350	(if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16351			     [(reg FLAGS_REG) (const_int 0)])
16352	  (const_int -1)
16353	  (const_int 0)))
16354   (clobber (reg:CC FLAGS_REG))]
16355  ""
16356  "sbb{<imodesuffix>}\t%0, %0"
16357  ; Since we don't have the proper number of operands for an alu insn,
16358  ; fill in all the blanks.
16359  [(set_attr "type" "alu")
16360   (set_attr "use_carry" "1")
16361   (set_attr "pent_pair" "pu")
16362   (set_attr "memory" "none")
16363   (set_attr "imm_disp" "false")
16364   (set_attr "mode" "<MODE>")
16365   (set_attr "length_immediate" "0")])
16366
16367(define_insn "*x86_mov<mode>cc_0_m1_se"
16368  [(set (match_operand:SWI48 0 "register_operand" "=r")
16369	(sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16370			     [(reg FLAGS_REG) (const_int 0)])
16371			    (const_int 1)
16372			    (const_int 0)))
16373   (clobber (reg:CC FLAGS_REG))]
16374  ""
16375  "sbb{<imodesuffix>}\t%0, %0"
16376  [(set_attr "type" "alu")
16377   (set_attr "use_carry" "1")
16378   (set_attr "pent_pair" "pu")
16379   (set_attr "memory" "none")
16380   (set_attr "imm_disp" "false")
16381   (set_attr "mode" "<MODE>")
16382   (set_attr "length_immediate" "0")])
16383
16384(define_insn "*x86_mov<mode>cc_0_m1_neg"
16385  [(set (match_operand:SWI48 0 "register_operand" "=r")
16386	(neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16387		    [(reg FLAGS_REG) (const_int 0)])))
16388   (clobber (reg:CC FLAGS_REG))]
16389  ""
16390  "sbb{<imodesuffix>}\t%0, %0"
16391  [(set_attr "type" "alu")
16392   (set_attr "use_carry" "1")
16393   (set_attr "pent_pair" "pu")
16394   (set_attr "memory" "none")
16395   (set_attr "imm_disp" "false")
16396   (set_attr "mode" "<MODE>")
16397   (set_attr "length_immediate" "0")])
16398
16399(define_insn "*mov<mode>cc_noc"
16400  [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16401	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16402			       [(reg FLAGS_REG) (const_int 0)])
16403	  (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16404	  (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16405  "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16406  "@
16407   cmov%O2%C1\t{%2, %0|%0, %2}
16408   cmov%O2%c1\t{%3, %0|%0, %3}"
16409  [(set_attr "type" "icmov")
16410   (set_attr "mode" "<MODE>")])
16411
16412(define_insn "*movqicc_noc"
16413  [(set (match_operand:QI 0 "register_operand" "=r,r")
16414	(if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16415			   [(reg FLAGS_REG) (const_int 0)])
16416		      (match_operand:QI 2 "register_operand" "r,0")
16417		      (match_operand:QI 3 "register_operand" "0,r")))]
16418  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16419  "#"
16420  [(set_attr "type" "icmov")
16421   (set_attr "mode" "QI")])
16422
16423(define_split
16424  [(set (match_operand 0 "register_operand")
16425	(if_then_else (match_operator 1 "ix86_comparison_operator"
16426			[(reg FLAGS_REG) (const_int 0)])
16427		      (match_operand 2 "register_operand")
16428		      (match_operand 3 "register_operand")))]
16429  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16430   && (GET_MODE (operands[0]) == QImode
16431       || GET_MODE (operands[0]) == HImode)
16432   && reload_completed"
16433  [(set (match_dup 0)
16434	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16435{
16436  operands[0] = gen_lowpart (SImode, operands[0]);
16437  operands[2] = gen_lowpart (SImode, operands[2]);
16438  operands[3] = gen_lowpart (SImode, operands[3]);
16439})
16440
16441(define_expand "mov<mode>cc"
16442  [(set (match_operand:X87MODEF 0 "register_operand" "")
16443	(if_then_else:X87MODEF
16444	  (match_operand 1 "ix86_fp_comparison_operator" "")
16445	  (match_operand:X87MODEF 2 "register_operand" "")
16446	  (match_operand:X87MODEF 3 "register_operand" "")))]
16447  "(TARGET_80387 && TARGET_CMOVE)
16448   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16449  "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16450
16451(define_insn "*movxfcc_1"
16452  [(set (match_operand:XF 0 "register_operand" "=f,f")
16453	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16454				[(reg FLAGS_REG) (const_int 0)])
16455		      (match_operand:XF 2 "register_operand" "f,0")
16456		      (match_operand:XF 3 "register_operand" "0,f")))]
16457  "TARGET_80387 && TARGET_CMOVE"
16458  "@
16459   fcmov%F1\t{%2, %0|%0, %2}
16460   fcmov%f1\t{%3, %0|%0, %3}"
16461  [(set_attr "type" "fcmov")
16462   (set_attr "mode" "XF")])
16463
16464(define_insn "*movdfcc_1_rex64"
16465  [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16466	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16467				[(reg FLAGS_REG) (const_int 0)])
16468		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16469		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16470  "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16471   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16472  "@
16473   fcmov%F1\t{%2, %0|%0, %2}
16474   fcmov%f1\t{%3, %0|%0, %3}
16475   cmov%O2%C1\t{%2, %0|%0, %2}
16476   cmov%O2%c1\t{%3, %0|%0, %3}"
16477  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16478   (set_attr "mode" "DF,DF,DI,DI")])
16479
16480(define_insn "*movdfcc_1"
16481  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16482	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16483				[(reg FLAGS_REG) (const_int 0)])
16484		      (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16485		      (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16486  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16487   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16488  "@
16489   fcmov%F1\t{%2, %0|%0, %2}
16490   fcmov%f1\t{%3, %0|%0, %3}
16491   #
16492   #"
16493  [(set_attr "type" "fcmov,fcmov,multi,multi")
16494   (set_attr "mode" "DF,DF,DI,DI")])
16495
16496(define_split
16497  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16498	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16499				[(reg FLAGS_REG) (const_int 0)])
16500		      (match_operand:DF 2 "nonimmediate_operand")
16501		      (match_operand:DF 3 "nonimmediate_operand")))]
16502  "!TARGET_64BIT && reload_completed"
16503  [(set (match_dup 2)
16504	(if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16505   (set (match_dup 3)
16506	(if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16507{
16508  split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16509  split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16510})
16511
16512(define_insn "*movsfcc_1_387"
16513  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16514	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16515				[(reg FLAGS_REG) (const_int 0)])
16516		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16517		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16518  "TARGET_80387 && TARGET_CMOVE
16519   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16520  "@
16521   fcmov%F1\t{%2, %0|%0, %2}
16522   fcmov%f1\t{%3, %0|%0, %3}
16523   cmov%O2%C1\t{%2, %0|%0, %2}
16524   cmov%O2%c1\t{%3, %0|%0, %3}"
16525  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16526   (set_attr "mode" "SF,SF,SI,SI")])
16527
16528;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16529;; the scalar versions to have only XMM registers as operands.
16530
16531;; XOP conditional move
16532(define_insn "*xop_pcmov_<mode>"
16533  [(set (match_operand:MODEF 0 "register_operand" "=x")
16534	(if_then_else:MODEF
16535	  (match_operand:MODEF 1 "register_operand" "x")
16536	  (match_operand:MODEF 2 "register_operand" "x")
16537	  (match_operand:MODEF 3 "register_operand" "x")))]
16538  "TARGET_XOP"
16539  "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16540  [(set_attr "type" "sse4arg")])
16541
16542;; These versions of the min/max patterns are intentionally ignorant of
16543;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16544;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16545;; are undefined in this condition, we're certain this is correct.
16546
16547(define_insn "<code><mode>3"
16548  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16549	(smaxmin:MODEF
16550	  (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16551	  (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16552  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16553  "@
16554   <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16555   v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16556  [(set_attr "isa" "noavx,avx")
16557   (set_attr "prefix" "orig,vex")
16558   (set_attr "type" "sseadd")
16559   (set_attr "mode" "<MODE>")])
16560
16561;; These versions of the min/max patterns implement exactly the operations
16562;;   min = (op1 < op2 ? op1 : op2)
16563;;   max = (!(op1 < op2) ? op1 : op2)
16564;; Their operands are not commutative, and thus they may be used in the
16565;; presence of -0.0 and NaN.
16566
16567(define_insn "*ieee_smin<mode>3"
16568  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16569	(unspec:MODEF
16570	  [(match_operand:MODEF 1 "register_operand" "0,x")
16571	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16572	 UNSPEC_IEEE_MIN))]
16573  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16574  "@
16575   min<ssemodesuffix>\t{%2, %0|%0, %2}
16576   vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16577  [(set_attr "isa" "noavx,avx")
16578   (set_attr "prefix" "orig,vex")
16579   (set_attr "type" "sseadd")
16580   (set_attr "mode" "<MODE>")])
16581
16582(define_insn "*ieee_smax<mode>3"
16583  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16584	(unspec:MODEF
16585	  [(match_operand:MODEF 1 "register_operand" "0,x")
16586	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16587	 UNSPEC_IEEE_MAX))]
16588  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16589  "@
16590   max<ssemodesuffix>\t{%2, %0|%0, %2}
16591   vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16592  [(set_attr "isa" "noavx,avx")
16593   (set_attr "prefix" "orig,vex")
16594   (set_attr "type" "sseadd")
16595   (set_attr "mode" "<MODE>")])
16596
16597;; Make two stack loads independent:
16598;;   fld aa              fld aa
16599;;   fld %st(0)     ->   fld bb
16600;;   fmul bb             fmul %st(1), %st
16601;;
16602;; Actually we only match the last two instructions for simplicity.
16603(define_peephole2
16604  [(set (match_operand 0 "fp_register_operand" "")
16605	(match_operand 1 "fp_register_operand" ""))
16606   (set (match_dup 0)
16607	(match_operator 2 "binary_fp_operator"
16608	   [(match_dup 0)
16609	    (match_operand 3 "memory_operand" "")]))]
16610  "REGNO (operands[0]) != REGNO (operands[1])"
16611  [(set (match_dup 0) (match_dup 3))
16612   (set (match_dup 0) (match_dup 4))]
16613
16614  ;; The % modifier is not operational anymore in peephole2's, so we have to
16615  ;; swap the operands manually in the case of addition and multiplication.
16616{
16617  rtx op0, op1;
16618
16619  if (COMMUTATIVE_ARITH_P (operands[2]))
16620    op0 = operands[0], op1 = operands[1];
16621  else
16622    op0 = operands[1], op1 = operands[0];
16623
16624  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16625				GET_MODE (operands[2]),
16626				op0, op1);
16627})
16628
16629;; Conditional addition patterns
16630(define_expand "add<mode>cc"
16631  [(match_operand:SWI 0 "register_operand" "")
16632   (match_operand 1 "ordered_comparison_operator" "")
16633   (match_operand:SWI 2 "register_operand" "")
16634   (match_operand:SWI 3 "const_int_operand" "")]
16635  ""
16636  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16637
16638;; Misc patterns (?)
16639
16640;; This pattern exists to put a dependency on all ebp-based memory accesses.
16641;; Otherwise there will be nothing to keep
16642;;
16643;; [(set (reg ebp) (reg esp))]
16644;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16645;;  (clobber (eflags)]
16646;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16647;;
16648;; in proper program order.
16649
16650(define_insn "pro_epilogue_adjust_stack_<mode>_add"
16651  [(set (match_operand:P 0 "register_operand" "=r,r")
16652	(plus:P (match_operand:P 1 "register_operand" "0,r")
16653	        (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16654   (clobber (reg:CC FLAGS_REG))
16655   (clobber (mem:BLK (scratch)))]
16656  ""
16657{
16658  switch (get_attr_type (insn))
16659    {
16660    case TYPE_IMOV:
16661      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16662
16663    case TYPE_ALU:
16664      gcc_assert (rtx_equal_p (operands[0], operands[1]));
16665      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16666	return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16667
16668      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16669
16670    default:
16671      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16672      return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16673    }
16674}
16675  [(set (attr "type")
16676	(cond [(and (eq_attr "alternative" "0")
16677		    (not (match_test "TARGET_OPT_AGU")))
16678		 (const_string "alu")
16679	       (match_operand:<MODE> 2 "const0_operand" "")
16680		 (const_string "imov")
16681	      ]
16682	      (const_string "lea")))
16683   (set (attr "length_immediate")
16684	(cond [(eq_attr "type" "imov")
16685		 (const_string "0")
16686	       (and (eq_attr "type" "alu")
16687		    (match_operand 2 "const128_operand" ""))
16688		 (const_string "1")
16689	      ]
16690	      (const_string "*")))
16691   (set_attr "mode" "<MODE>")])
16692
16693(define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16694  [(set (match_operand:P 0 "register_operand" "=r")
16695	(minus:P (match_operand:P 1 "register_operand" "0")
16696		 (match_operand:P 2 "register_operand" "r")))
16697   (clobber (reg:CC FLAGS_REG))
16698   (clobber (mem:BLK (scratch)))]
16699  ""
16700  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16701  [(set_attr "type" "alu")
16702   (set_attr "mode" "<MODE>")])
16703
16704(define_insn "allocate_stack_worker_probe_<mode>"
16705  [(set (match_operand:P 0 "register_operand" "=a")
16706	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16707			    UNSPECV_STACK_PROBE))
16708   (clobber (reg:CC FLAGS_REG))]
16709  "ix86_target_stack_probe ()"
16710  "call\t___chkstk_ms"
16711  [(set_attr "type" "multi")
16712   (set_attr "length" "5")])
16713
16714(define_expand "allocate_stack"
16715  [(match_operand 0 "register_operand" "")
16716   (match_operand 1 "general_operand" "")]
16717  "ix86_target_stack_probe ()"
16718{
16719  rtx x;
16720
16721#ifndef CHECK_STACK_LIMIT
16722#define CHECK_STACK_LIMIT 0
16723#endif
16724
16725  if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16726      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16727    {
16728      x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16729			       stack_pointer_rtx, 0, OPTAB_DIRECT);
16730      if (x != stack_pointer_rtx)
16731	emit_move_insn (stack_pointer_rtx, x);
16732    }
16733  else
16734    {
16735      x = copy_to_mode_reg (Pmode, operands[1]);
16736      if (TARGET_64BIT)
16737        emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16738      else
16739        emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16740      x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16741			       stack_pointer_rtx, 0, OPTAB_DIRECT);
16742      if (x != stack_pointer_rtx)
16743	emit_move_insn (stack_pointer_rtx, x);
16744    }
16745
16746  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16747  DONE;
16748})
16749
16750;; Use IOR for stack probes, this is shorter.
16751(define_expand "probe_stack"
16752  [(match_operand 0 "memory_operand" "")]
16753  ""
16754{
16755  rtx (*gen_ior3) (rtx, rtx, rtx);
16756
16757  gen_ior3 = (GET_MODE (operands[0]) == DImode
16758	      ? gen_iordi3 : gen_iorsi3);
16759
16760  emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16761  DONE;
16762})
16763
16764(define_insn "adjust_stack_and_probe<mode>"
16765  [(set (match_operand:P 0 "register_operand" "=r")
16766	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16767			    UNSPECV_PROBE_STACK_RANGE))
16768   (set (reg:P SP_REG)
16769        (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16770   (clobber (reg:CC FLAGS_REG))
16771   (clobber (mem:BLK (scratch)))]
16772  ""
16773  "* return output_adjust_stack_and_probe (operands[0]);"
16774  [(set_attr "type" "multi")])
16775
16776(define_insn "probe_stack_range<mode>"
16777  [(set (match_operand:P 0 "register_operand" "=r")
16778	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16779			    (match_operand:P 2 "const_int_operand" "n")]
16780			    UNSPECV_PROBE_STACK_RANGE))
16781   (clobber (reg:CC FLAGS_REG))]
16782  ""
16783  "* return output_probe_stack_range (operands[0], operands[2]);"
16784  [(set_attr "type" "multi")])
16785
16786(define_expand "builtin_setjmp_receiver"
16787  [(label_ref (match_operand 0 "" ""))]
16788  "!TARGET_64BIT && flag_pic"
16789{
16790#if TARGET_MACHO
16791  if (TARGET_MACHO)
16792    {
16793      rtx xops[3];
16794      rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16795      rtx label_rtx = gen_label_rtx ();
16796      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16797      xops[0] = xops[1] = picreg;
16798      xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16799      ix86_expand_binary_operator (MINUS, SImode, xops);
16800    }
16801  else
16802#endif
16803    emit_insn (gen_set_got (pic_offset_table_rtx));
16804  DONE;
16805})
16806
16807(define_insn_and_split "nonlocal_goto_receiver"
16808  [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16809  "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16810  "#"
16811  "&& reload_completed"
16812  [(const_int 0)]
16813{
16814  if (crtl->uses_pic_offset_table)
16815    {
16816      rtx xops[3];
16817      rtx label_rtx = gen_label_rtx ();
16818      rtx tmp;
16819
16820      /* Get a new pic base.  */
16821      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16822      /* Correct this with the offset from the new to the old.  */
16823      xops[0] = xops[1] = pic_offset_table_rtx;
16824      label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16825      tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16826			    UNSPEC_MACHOPIC_OFFSET);
16827      xops[2] = gen_rtx_CONST (Pmode, tmp);
16828      ix86_expand_binary_operator (MINUS, SImode, xops);
16829    }
16830  else
16831    /* No pic reg restore needed.  */
16832    emit_note (NOTE_INSN_DELETED);
16833
16834  DONE;
16835})
16836
16837;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16838
16839(define_split
16840  [(set (match_operand 0 "register_operand" "")
16841	(match_operator 3 "promotable_binary_operator"
16842	   [(match_operand 1 "register_operand" "")
16843	    (match_operand 2 "aligned_operand" "")]))
16844   (clobber (reg:CC FLAGS_REG))]
16845  "! TARGET_PARTIAL_REG_STALL && reload_completed
16846   && ((GET_MODE (operands[0]) == HImode
16847	&& ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16848            /* ??? next two lines just !satisfies_constraint_K (...) */
16849	    || !CONST_INT_P (operands[2])
16850	    || satisfies_constraint_K (operands[2])))
16851       || (GET_MODE (operands[0]) == QImode
16852	   && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16853  [(parallel [(set (match_dup 0)
16854		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16855	      (clobber (reg:CC FLAGS_REG))])]
16856{
16857  operands[0] = gen_lowpart (SImode, operands[0]);
16858  operands[1] = gen_lowpart (SImode, operands[1]);
16859  if (GET_CODE (operands[3]) != ASHIFT)
16860    operands[2] = gen_lowpart (SImode, operands[2]);
16861  PUT_MODE (operands[3], SImode);
16862})
16863
16864; Promote the QImode tests, as i386 has encoding of the AND
16865; instruction with 32-bit sign-extended immediate and thus the
16866; instruction size is unchanged, except in the %eax case for
16867; which it is increased by one byte, hence the ! optimize_size.
16868(define_split
16869  [(set (match_operand 0 "flags_reg_operand" "")
16870	(match_operator 2 "compare_operator"
16871	  [(and (match_operand 3 "aligned_operand" "")
16872		(match_operand 4 "const_int_operand" ""))
16873	   (const_int 0)]))
16874   (set (match_operand 1 "register_operand" "")
16875	(and (match_dup 3) (match_dup 4)))]
16876  "! TARGET_PARTIAL_REG_STALL && reload_completed
16877   && optimize_insn_for_speed_p ()
16878   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16879       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16880   /* Ensure that the operand will remain sign-extended immediate.  */
16881   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16882  [(parallel [(set (match_dup 0)
16883		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16884			            (const_int 0)]))
16885	      (set (match_dup 1)
16886		   (and:SI (match_dup 3) (match_dup 4)))])]
16887{
16888  operands[4]
16889    = gen_int_mode (INTVAL (operands[4])
16890		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16891  operands[1] = gen_lowpart (SImode, operands[1]);
16892  operands[3] = gen_lowpart (SImode, operands[3]);
16893})
16894
16895; Don't promote the QImode tests, as i386 doesn't have encoding of
16896; the TEST instruction with 32-bit sign-extended immediate and thus
16897; the instruction size would at least double, which is not what we
16898; want even with ! optimize_size.
16899(define_split
16900  [(set (match_operand 0 "flags_reg_operand" "")
16901	(match_operator 1 "compare_operator"
16902	  [(and (match_operand:HI 2 "aligned_operand" "")
16903		(match_operand:HI 3 "const_int_operand" ""))
16904	   (const_int 0)]))]
16905  "! TARGET_PARTIAL_REG_STALL && reload_completed
16906   && ! TARGET_FAST_PREFIX
16907   && optimize_insn_for_speed_p ()
16908   /* Ensure that the operand will remain sign-extended immediate.  */
16909   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16910  [(set (match_dup 0)
16911	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16912		         (const_int 0)]))]
16913{
16914  operands[3]
16915    = gen_int_mode (INTVAL (operands[3])
16916		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16917  operands[2] = gen_lowpart (SImode, operands[2]);
16918})
16919
16920(define_split
16921  [(set (match_operand 0 "register_operand" "")
16922	(neg (match_operand 1 "register_operand" "")))
16923   (clobber (reg:CC FLAGS_REG))]
16924  "! TARGET_PARTIAL_REG_STALL && reload_completed
16925   && (GET_MODE (operands[0]) == HImode
16926       || (GET_MODE (operands[0]) == QImode
16927	   && (TARGET_PROMOTE_QImode
16928	       || optimize_insn_for_size_p ())))"
16929  [(parallel [(set (match_dup 0)
16930		   (neg:SI (match_dup 1)))
16931	      (clobber (reg:CC FLAGS_REG))])]
16932{
16933  operands[0] = gen_lowpart (SImode, operands[0]);
16934  operands[1] = gen_lowpart (SImode, operands[1]);
16935})
16936
16937(define_split
16938  [(set (match_operand 0 "register_operand" "")
16939	(not (match_operand 1 "register_operand" "")))]
16940  "! TARGET_PARTIAL_REG_STALL && reload_completed
16941   && (GET_MODE (operands[0]) == HImode
16942       || (GET_MODE (operands[0]) == QImode
16943	   && (TARGET_PROMOTE_QImode
16944	       || optimize_insn_for_size_p ())))"
16945  [(set (match_dup 0)
16946	(not:SI (match_dup 1)))]
16947{
16948  operands[0] = gen_lowpart (SImode, operands[0]);
16949  operands[1] = gen_lowpart (SImode, operands[1]);
16950})
16951
16952;; RTL Peephole optimizations, run before sched2.  These primarily look to
16953;; transform a complex memory operation into two memory to register operations.
16954
16955;; Don't push memory operands
16956(define_peephole2
16957  [(set (match_operand:SWI 0 "push_operand" "")
16958	(match_operand:SWI 1 "memory_operand" ""))
16959   (match_scratch:SWI 2 "<r>")]
16960  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16961   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16962  [(set (match_dup 2) (match_dup 1))
16963   (set (match_dup 0) (match_dup 2))])
16964
16965;; We need to handle SFmode only, because DFmode and XFmode are split to
16966;; SImode pushes.
16967(define_peephole2
16968  [(set (match_operand:SF 0 "push_operand" "")
16969	(match_operand:SF 1 "memory_operand" ""))
16970   (match_scratch:SF 2 "r")]
16971  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16972   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16973  [(set (match_dup 2) (match_dup 1))
16974   (set (match_dup 0) (match_dup 2))])
16975
16976;; Don't move an immediate directly to memory when the instruction
16977;; gets too big.
16978(define_peephole2
16979  [(match_scratch:SWI124 1 "<r>")
16980   (set (match_operand:SWI124 0 "memory_operand" "")
16981        (const_int 0))]
16982  "optimize_insn_for_speed_p ()
16983   && !TARGET_USE_MOV0
16984   && TARGET_SPLIT_LONG_MOVES
16985   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16986   && peep2_regno_dead_p (0, FLAGS_REG)"
16987  [(parallel [(set (match_dup 2) (const_int 0))
16988	      (clobber (reg:CC FLAGS_REG))])
16989   (set (match_dup 0) (match_dup 1))]
16990  "operands[2] = gen_lowpart (SImode, operands[1]);")
16991
16992(define_peephole2
16993  [(match_scratch:SWI124 2 "<r>")
16994   (set (match_operand:SWI124 0 "memory_operand" "")
16995        (match_operand:SWI124 1 "immediate_operand" ""))]
16996  "optimize_insn_for_speed_p ()
16997   && TARGET_SPLIT_LONG_MOVES
16998   && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16999  [(set (match_dup 2) (match_dup 1))
17000   (set (match_dup 0) (match_dup 2))])
17001
17002;; Don't compare memory with zero, load and use a test instead.
17003(define_peephole2
17004  [(set (match_operand 0 "flags_reg_operand" "")
17005 	(match_operator 1 "compare_operator"
17006	  [(match_operand:SI 2 "memory_operand" "")
17007	   (const_int 0)]))
17008   (match_scratch:SI 3 "r")]
17009  "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17010  [(set (match_dup 3) (match_dup 2))
17011   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17012
17013;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17014;; Don't split NOTs with a displacement operand, because resulting XOR
17015;; will not be pairable anyway.
17016;;
17017;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17018;; represented using a modRM byte.  The XOR replacement is long decoded,
17019;; so this split helps here as well.
17020;;
17021;; Note: Can't do this as a regular split because we can't get proper
17022;; lifetime information then.
17023
17024(define_peephole2
17025  [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17026	(not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17027  "optimize_insn_for_speed_p ()
17028   && ((TARGET_NOT_UNPAIRABLE
17029	&& (!MEM_P (operands[0])
17030	    || !memory_displacement_operand (operands[0], <MODE>mode)))
17031       || (TARGET_NOT_VECTORMODE
17032	   && long_memory_operand (operands[0], <MODE>mode)))
17033   && peep2_regno_dead_p (0, FLAGS_REG)"
17034  [(parallel [(set (match_dup 0)
17035		   (xor:SWI124 (match_dup 1) (const_int -1)))
17036	      (clobber (reg:CC FLAGS_REG))])])
17037
17038;; Non pairable "test imm, reg" instructions can be translated to
17039;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17040;; byte opcode instead of two, have a short form for byte operands),
17041;; so do it for other CPUs as well.  Given that the value was dead,
17042;; this should not create any new dependencies.  Pass on the sub-word
17043;; versions if we're concerned about partial register stalls.
17044
17045(define_peephole2
17046  [(set (match_operand 0 "flags_reg_operand" "")
17047	(match_operator 1 "compare_operator"
17048	  [(and:SI (match_operand:SI 2 "register_operand" "")
17049		   (match_operand:SI 3 "immediate_operand" ""))
17050	   (const_int 0)]))]
17051  "ix86_match_ccmode (insn, CCNOmode)
17052   && (true_regnum (operands[2]) != AX_REG
17053       || satisfies_constraint_K (operands[3]))
17054   && peep2_reg_dead_p (1, operands[2])"
17055  [(parallel
17056     [(set (match_dup 0)
17057	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17058		            (const_int 0)]))
17059      (set (match_dup 2)
17060	   (and:SI (match_dup 2) (match_dup 3)))])])
17061
17062;; We don't need to handle HImode case, because it will be promoted to SImode
17063;; on ! TARGET_PARTIAL_REG_STALL
17064
17065(define_peephole2
17066  [(set (match_operand 0 "flags_reg_operand" "")
17067	(match_operator 1 "compare_operator"
17068	  [(and:QI (match_operand:QI 2 "register_operand" "")
17069		   (match_operand:QI 3 "immediate_operand" ""))
17070	   (const_int 0)]))]
17071  "! TARGET_PARTIAL_REG_STALL
17072   && ix86_match_ccmode (insn, CCNOmode)
17073   && true_regnum (operands[2]) != AX_REG
17074   && peep2_reg_dead_p (1, operands[2])"
17075  [(parallel
17076     [(set (match_dup 0)
17077	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17078		            (const_int 0)]))
17079      (set (match_dup 2)
17080	   (and:QI (match_dup 2) (match_dup 3)))])])
17081
17082(define_peephole2
17083  [(set (match_operand 0 "flags_reg_operand" "")
17084	(match_operator 1 "compare_operator"
17085	  [(and:SI
17086	     (zero_extract:SI
17087	       (match_operand 2 "ext_register_operand" "")
17088	       (const_int 8)
17089	       (const_int 8))
17090	     (match_operand 3 "const_int_operand" ""))
17091	   (const_int 0)]))]
17092  "! TARGET_PARTIAL_REG_STALL
17093   && ix86_match_ccmode (insn, CCNOmode)
17094   && true_regnum (operands[2]) != AX_REG
17095   && peep2_reg_dead_p (1, operands[2])"
17096  [(parallel [(set (match_dup 0)
17097		   (match_op_dup 1
17098		     [(and:SI
17099			(zero_extract:SI
17100			  (match_dup 2)
17101			  (const_int 8)
17102			  (const_int 8))
17103			(match_dup 3))
17104		      (const_int 0)]))
17105	      (set (zero_extract:SI (match_dup 2)
17106				    (const_int 8)
17107				    (const_int 8))
17108		   (and:SI
17109		     (zero_extract:SI
17110		       (match_dup 2)
17111		       (const_int 8)
17112		       (const_int 8))
17113		     (match_dup 3)))])])
17114
17115;; Don't do logical operations with memory inputs.
17116(define_peephole2
17117  [(match_scratch:SI 2 "r")
17118   (parallel [(set (match_operand:SI 0 "register_operand" "")
17119                   (match_operator:SI 3 "arith_or_logical_operator"
17120                     [(match_dup 0)
17121                      (match_operand:SI 1 "memory_operand" "")]))
17122              (clobber (reg:CC FLAGS_REG))])]
17123  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17124  [(set (match_dup 2) (match_dup 1))
17125   (parallel [(set (match_dup 0)
17126                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17127              (clobber (reg:CC FLAGS_REG))])])
17128
17129(define_peephole2
17130  [(match_scratch:SI 2 "r")
17131   (parallel [(set (match_operand:SI 0 "register_operand" "")
17132                   (match_operator:SI 3 "arith_or_logical_operator"
17133                     [(match_operand:SI 1 "memory_operand" "")
17134                      (match_dup 0)]))
17135              (clobber (reg:CC FLAGS_REG))])]
17136  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17137  [(set (match_dup 2) (match_dup 1))
17138   (parallel [(set (match_dup 0)
17139                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17140              (clobber (reg:CC FLAGS_REG))])])
17141
17142;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17143;; refers to the destination of the load!
17144
17145(define_peephole2
17146  [(set (match_operand:SI 0 "register_operand" "")
17147        (match_operand:SI 1 "register_operand" ""))
17148   (parallel [(set (match_dup 0)
17149                   (match_operator:SI 3 "commutative_operator"
17150                     [(match_dup 0)
17151                      (match_operand:SI 2 "memory_operand" "")]))
17152              (clobber (reg:CC FLAGS_REG))])]
17153  "REGNO (operands[0]) != REGNO (operands[1])
17154   && GENERAL_REGNO_P (REGNO (operands[0]))
17155   && GENERAL_REGNO_P (REGNO (operands[1]))"
17156  [(set (match_dup 0) (match_dup 4))
17157   (parallel [(set (match_dup 0)
17158                   (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17159              (clobber (reg:CC FLAGS_REG))])]
17160  "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17161
17162(define_peephole2
17163  [(set (match_operand 0 "register_operand" "")
17164        (match_operand 1 "register_operand" ""))
17165   (set (match_dup 0)
17166                   (match_operator 3 "commutative_operator"
17167                     [(match_dup 0)
17168                      (match_operand 2 "memory_operand" "")]))]
17169  "REGNO (operands[0]) != REGNO (operands[1])
17170   && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17171       || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17172  [(set (match_dup 0) (match_dup 2))
17173   (set (match_dup 0)
17174        (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17175
17176; Don't do logical operations with memory outputs
17177;
17178; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17179; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17180; the same decoder scheduling characteristics as the original.
17181
17182(define_peephole2
17183  [(match_scratch:SI 2 "r")
17184   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17185                   (match_operator:SI 3 "arith_or_logical_operator"
17186                     [(match_dup 0)
17187                      (match_operand:SI 1 "nonmemory_operand" "")]))
17188              (clobber (reg:CC FLAGS_REG))])]
17189  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17190   /* Do not split stack checking probes.  */
17191   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17192  [(set (match_dup 2) (match_dup 0))
17193   (parallel [(set (match_dup 2)
17194                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17195              (clobber (reg:CC FLAGS_REG))])
17196   (set (match_dup 0) (match_dup 2))])
17197
17198(define_peephole2
17199  [(match_scratch:SI 2 "r")
17200   (parallel [(set (match_operand:SI 0 "memory_operand" "")
17201                   (match_operator:SI 3 "arith_or_logical_operator"
17202                     [(match_operand:SI 1 "nonmemory_operand" "")
17203                      (match_dup 0)]))
17204              (clobber (reg:CC FLAGS_REG))])]
17205  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17206   /* Do not split stack checking probes.  */
17207   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17208  [(set (match_dup 2) (match_dup 0))
17209   (parallel [(set (match_dup 2)
17210                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17211              (clobber (reg:CC FLAGS_REG))])
17212   (set (match_dup 0) (match_dup 2))])
17213
17214;; Attempt to use arith or logical operations with memory outputs with
17215;; setting of flags.
17216(define_peephole2
17217  [(set (match_operand:SWI 0 "register_operand" "")
17218	(match_operand:SWI 1 "memory_operand" ""))
17219   (parallel [(set (match_dup 0)
17220		   (match_operator:SWI 3 "plusminuslogic_operator"
17221		     [(match_dup 0)
17222		      (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17223	      (clobber (reg:CC FLAGS_REG))])
17224   (set (match_dup 1) (match_dup 0))
17225   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17226  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17227   && peep2_reg_dead_p (4, operands[0])
17228   && !reg_overlap_mentioned_p (operands[0], operands[1])
17229   && !reg_overlap_mentioned_p (operands[0], operands[2])
17230   && (<MODE>mode != QImode
17231       || immediate_operand (operands[2], QImode)
17232       || q_regs_operand (operands[2], QImode))
17233   && ix86_match_ccmode (peep2_next_insn (3),
17234			 (GET_CODE (operands[3]) == PLUS
17235			  || GET_CODE (operands[3]) == MINUS)
17236			 ? CCGOCmode : CCNOmode)"
17237  [(parallel [(set (match_dup 4) (match_dup 5))
17238	      (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17239						  (match_dup 2)]))])]
17240{
17241  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17242  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17243				copy_rtx (operands[1]),
17244				copy_rtx (operands[2]));
17245  operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17246				 operands[5], const0_rtx);
17247})
17248
17249(define_peephole2
17250  [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17251		   (match_operator:SWI 2 "plusminuslogic_operator"
17252		     [(match_dup 0)
17253		      (match_operand:SWI 1 "memory_operand" "")]))
17254	      (clobber (reg:CC FLAGS_REG))])
17255   (set (match_dup 1) (match_dup 0))
17256   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17257  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17258   && GET_CODE (operands[2]) != MINUS
17259   && peep2_reg_dead_p (3, operands[0])
17260   && !reg_overlap_mentioned_p (operands[0], operands[1])
17261   && ix86_match_ccmode (peep2_next_insn (2),
17262			 GET_CODE (operands[2]) == PLUS
17263			 ? CCGOCmode : CCNOmode)"
17264  [(parallel [(set (match_dup 3) (match_dup 4))
17265	      (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17266						  (match_dup 0)]))])]
17267{
17268  operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17269  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17270				copy_rtx (operands[1]),
17271				copy_rtx (operands[0]));
17272  operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17273				 operands[4], const0_rtx);
17274})
17275
17276(define_peephole2
17277  [(set (match_operand:SWI12 0 "register_operand" "")
17278	(match_operand:SWI12 1 "memory_operand" ""))
17279   (parallel [(set (match_operand:SI 4 "register_operand" "")
17280		   (match_operator:SI 3 "plusminuslogic_operator"
17281		     [(match_dup 4)
17282		      (match_operand:SI 2 "nonmemory_operand" "")]))
17283	      (clobber (reg:CC FLAGS_REG))])
17284   (set (match_dup 1) (match_dup 0))
17285   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17286  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17287   && REG_P (operands[0]) && REG_P (operands[4])
17288   && REGNO (operands[0]) == REGNO (operands[4])
17289   && peep2_reg_dead_p (4, operands[0])
17290   && (<MODE>mode != QImode
17291       || immediate_operand (operands[2], SImode)
17292       || q_regs_operand (operands[2], SImode))
17293   && !reg_overlap_mentioned_p (operands[0], operands[1])
17294   && !reg_overlap_mentioned_p (operands[0], operands[2])
17295   && ix86_match_ccmode (peep2_next_insn (3),
17296			 (GET_CODE (operands[3]) == PLUS
17297			  || GET_CODE (operands[3]) == MINUS)
17298			 ? CCGOCmode : CCNOmode)"
17299  [(parallel [(set (match_dup 4) (match_dup 5))
17300	      (set (match_dup 1) (match_dup 6))])]
17301{
17302  operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17303  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17304  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17305				copy_rtx (operands[1]), operands[2]);
17306  operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17307				 operands[5], const0_rtx);
17308  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17309				copy_rtx (operands[1]),
17310				copy_rtx (operands[2]));
17311})
17312
17313;; Attempt to always use XOR for zeroing registers.
17314(define_peephole2
17315  [(set (match_operand 0 "register_operand" "")
17316	(match_operand 1 "const0_operand" ""))]
17317  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17318   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17319   && GENERAL_REG_P (operands[0])
17320   && peep2_regno_dead_p (0, FLAGS_REG)"
17321  [(parallel [(set (match_dup 0) (const_int 0))
17322	      (clobber (reg:CC FLAGS_REG))])]
17323  "operands[0] = gen_lowpart (word_mode, operands[0]);")
17324
17325(define_peephole2
17326  [(set (strict_low_part (match_operand 0 "register_operand" ""))
17327	(const_int 0))]
17328  "(GET_MODE (operands[0]) == QImode
17329    || GET_MODE (operands[0]) == HImode)
17330   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17331   && peep2_regno_dead_p (0, FLAGS_REG)"
17332  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17333	      (clobber (reg:CC FLAGS_REG))])])
17334
17335;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17336(define_peephole2
17337  [(set (match_operand:SWI248 0 "register_operand" "")
17338	(const_int -1))]
17339  "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17340   && peep2_regno_dead_p (0, FLAGS_REG)"
17341  [(parallel [(set (match_dup 0) (const_int -1))
17342	      (clobber (reg:CC FLAGS_REG))])]
17343{
17344  if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17345    operands[0] = gen_lowpart (SImode, operands[0]);
17346})
17347
17348;; Attempt to convert simple lea to add/shift.
17349;; These can be created by move expanders.
17350
17351(define_peephole2
17352  [(set (match_operand:SWI48 0 "register_operand" "")
17353  	(plus:SWI48 (match_dup 0)
17354		    (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17355  "peep2_regno_dead_p (0, FLAGS_REG)"
17356  [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17357	      (clobber (reg:CC FLAGS_REG))])])
17358
17359(define_peephole2
17360  [(set (match_operand:SI 0 "register_operand" "")
17361  	(subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17362			    (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17363  "TARGET_64BIT
17364   && peep2_regno_dead_p (0, FLAGS_REG)
17365   && REGNO (operands[0]) == REGNO (operands[1])"
17366  [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17367	      (clobber (reg:CC FLAGS_REG))])]
17368  "operands[2] = gen_lowpart (SImode, operands[2]);")
17369
17370(define_peephole2
17371  [(set (match_operand:SWI48 0 "register_operand" "")
17372  	(mult:SWI48 (match_dup 0)
17373		    (match_operand:SWI48 1 "const_int_operand" "")))]
17374  "exact_log2 (INTVAL (operands[1])) >= 0
17375   && peep2_regno_dead_p (0, FLAGS_REG)"
17376  [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17377	      (clobber (reg:CC FLAGS_REG))])]
17378  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17379
17380(define_peephole2
17381  [(set (match_operand:SI 0 "register_operand" "")
17382  	(subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17383		   (match_operand:DI 2 "const_int_operand" "")) 0))]
17384  "TARGET_64BIT
17385   && exact_log2 (INTVAL (operands[2])) >= 0
17386   && REGNO (operands[0]) == REGNO (operands[1])
17387   && peep2_regno_dead_p (0, FLAGS_REG)"
17388  [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17389	      (clobber (reg:CC FLAGS_REG))])]
17390  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17391
17392;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17393;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17394;; On many CPUs it is also faster, since special hardware to avoid esp
17395;; dependencies is present.
17396
17397;; While some of these conversions may be done using splitters, we use
17398;; peepholes in order to allow combine_stack_adjustments pass to see
17399;; nonobfuscated RTL.
17400
17401;; Convert prologue esp subtractions to push.
17402;; We need register to push.  In order to keep verify_flow_info happy we have
17403;; two choices
17404;; - use scratch and clobber it in order to avoid dependencies
17405;; - use already live register
17406;; We can't use the second way right now, since there is no reliable way how to
17407;; verify that given register is live.  First choice will also most likely in
17408;; fewer dependencies.  On the place of esp adjustments it is very likely that
17409;; call clobbered registers are dead.  We may want to use base pointer as an
17410;; alternative when no register is available later.
17411
17412(define_peephole2
17413  [(match_scratch:P 1 "r")
17414   (parallel [(set (reg:P SP_REG)
17415		   (plus:P (reg:P SP_REG)
17416			   (match_operand:P 0 "const_int_operand" "")))
17417	      (clobber (reg:CC FLAGS_REG))
17418	      (clobber (mem:BLK (scratch)))])]
17419  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17420   && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17421  [(clobber (match_dup 1))
17422   (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17423	      (clobber (mem:BLK (scratch)))])])
17424
17425(define_peephole2
17426  [(match_scratch:P 1 "r")
17427   (parallel [(set (reg:P SP_REG)
17428		   (plus:P (reg:P SP_REG)
17429			   (match_operand:P 0 "const_int_operand" "")))
17430	      (clobber (reg:CC FLAGS_REG))
17431	      (clobber (mem:BLK (scratch)))])]
17432  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17433   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17434  [(clobber (match_dup 1))
17435   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17436   (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17437	      (clobber (mem:BLK (scratch)))])])
17438
17439;; Convert esp subtractions to push.
17440(define_peephole2
17441  [(match_scratch:P 1 "r")
17442   (parallel [(set (reg:P SP_REG)
17443		   (plus:P (reg:P SP_REG)
17444			   (match_operand:P 0 "const_int_operand" "")))
17445	      (clobber (reg:CC FLAGS_REG))])]
17446  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17447   && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17448  [(clobber (match_dup 1))
17449   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17450
17451(define_peephole2
17452  [(match_scratch:P 1 "r")
17453   (parallel [(set (reg:P SP_REG)
17454		   (plus:P (reg:P SP_REG)
17455			   (match_operand:P 0 "const_int_operand" "")))
17456	      (clobber (reg:CC FLAGS_REG))])]
17457  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17458   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17459  [(clobber (match_dup 1))
17460   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17461   (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17462
17463;; Convert epilogue deallocator to pop.
17464(define_peephole2
17465  [(match_scratch:P 1 "r")
17466   (parallel [(set (reg:P SP_REG)
17467		   (plus:P (reg:P SP_REG)
17468			   (match_operand:P 0 "const_int_operand" "")))
17469	      (clobber (reg:CC FLAGS_REG))
17470	      (clobber (mem:BLK (scratch)))])]
17471  "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17472   && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17473  [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17474	      (clobber (mem:BLK (scratch)))])])
17475
17476;; Two pops case is tricky, since pop causes dependency
17477;; on destination register.  We use two registers if available.
17478(define_peephole2
17479  [(match_scratch:P 1 "r")
17480   (match_scratch:P 2 "r")
17481   (parallel [(set (reg:P SP_REG)
17482		   (plus:P (reg:P SP_REG)
17483			   (match_operand:P 0 "const_int_operand" "")))
17484	      (clobber (reg:CC FLAGS_REG))
17485	      (clobber (mem:BLK (scratch)))])]
17486  "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17487   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17488  [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17489	      (clobber (mem:BLK (scratch)))])
17490   (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17491
17492(define_peephole2
17493  [(match_scratch:P 1 "r")
17494   (parallel [(set (reg:P SP_REG)
17495		   (plus:P (reg:P SP_REG)
17496			   (match_operand:P 0 "const_int_operand" "")))
17497	      (clobber (reg:CC FLAGS_REG))
17498	      (clobber (mem:BLK (scratch)))])]
17499  "optimize_insn_for_size_p ()
17500   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17501  [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17502	      (clobber (mem:BLK (scratch)))])
17503   (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17504
17505;; Convert esp additions to pop.
17506(define_peephole2
17507  [(match_scratch:P 1 "r")
17508   (parallel [(set (reg:P SP_REG)
17509		   (plus:P (reg:P SP_REG)
17510			   (match_operand:P 0 "const_int_operand" "")))
17511	      (clobber (reg:CC FLAGS_REG))])]
17512  "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17513  [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17514
17515;; Two pops case is tricky, since pop causes dependency
17516;; on destination register.  We use two registers if available.
17517(define_peephole2
17518  [(match_scratch:P 1 "r")
17519   (match_scratch:P 2 "r")
17520   (parallel [(set (reg:P SP_REG)
17521		   (plus:P (reg:P SP_REG)
17522			   (match_operand:P 0 "const_int_operand" "")))
17523	      (clobber (reg:CC FLAGS_REG))])]
17524  "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17525  [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17526   (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17527
17528(define_peephole2
17529  [(match_scratch:P 1 "r")
17530   (parallel [(set (reg:P SP_REG)
17531		   (plus:P (reg:P SP_REG)
17532			   (match_operand:P 0 "const_int_operand" "")))
17533	      (clobber (reg:CC FLAGS_REG))])]
17534  "optimize_insn_for_size_p ()
17535   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17536  [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17537   (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17538
17539;; Convert compares with 1 to shorter inc/dec operations when CF is not
17540;; required and register dies.  Similarly for 128 to -128.
17541(define_peephole2
17542  [(set (match_operand 0 "flags_reg_operand" "")
17543	(match_operator 1 "compare_operator"
17544	  [(match_operand 2 "register_operand" "")
17545	   (match_operand 3 "const_int_operand" "")]))]
17546  "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17547     && incdec_operand (operands[3], GET_MODE (operands[3])))
17548    || (!TARGET_FUSE_CMP_AND_BRANCH
17549	&& INTVAL (operands[3]) == 128))
17550   && ix86_match_ccmode (insn, CCGCmode)
17551   && peep2_reg_dead_p (1, operands[2])"
17552  [(parallel [(set (match_dup 0)
17553		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17554	      (clobber (match_dup 2))])])
17555
17556;; Convert imul by three, five and nine into lea
17557(define_peephole2
17558  [(parallel
17559    [(set (match_operand:SWI48 0 "register_operand" "")
17560	  (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17561		      (match_operand:SWI48 2 "const359_operand" "")))
17562     (clobber (reg:CC FLAGS_REG))])]
17563  "!TARGET_PARTIAL_REG_STALL
17564   || <MODE>mode == SImode
17565   || optimize_function_for_size_p (cfun)"
17566  [(set (match_dup 0)
17567	(plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17568		    (match_dup 1)))]
17569  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17570
17571(define_peephole2
17572  [(parallel
17573    [(set (match_operand:SWI48 0 "register_operand" "")
17574	  (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17575		      (match_operand:SWI48 2 "const359_operand" "")))
17576     (clobber (reg:CC FLAGS_REG))])]
17577  "optimize_insn_for_speed_p ()
17578   && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17579  [(set (match_dup 0) (match_dup 1))
17580   (set (match_dup 0)
17581	(plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17582		    (match_dup 0)))]
17583  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17584
17585;; imul $32bit_imm, mem, reg is vector decoded, while
17586;; imul $32bit_imm, reg, reg is direct decoded.
17587(define_peephole2
17588  [(match_scratch:SWI48 3 "r")
17589   (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17590		   (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17591			       (match_operand:SWI48 2 "immediate_operand" "")))
17592	      (clobber (reg:CC FLAGS_REG))])]
17593  "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17594   && !satisfies_constraint_K (operands[2])"
17595  [(set (match_dup 3) (match_dup 1))
17596   (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17597	      (clobber (reg:CC FLAGS_REG))])])
17598
17599(define_peephole2
17600  [(match_scratch:SI 3 "r")
17601   (parallel [(set (match_operand:DI 0 "register_operand" "")
17602		   (zero_extend:DI
17603		     (mult:SI (match_operand:SI 1 "memory_operand" "")
17604			      (match_operand:SI 2 "immediate_operand" ""))))
17605	      (clobber (reg:CC FLAGS_REG))])]
17606  "TARGET_64BIT
17607   && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17608   && !satisfies_constraint_K (operands[2])"
17609  [(set (match_dup 3) (match_dup 1))
17610   (parallel [(set (match_dup 0)
17611		   (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17612	      (clobber (reg:CC FLAGS_REG))])])
17613
17614;; imul $8/16bit_imm, regmem, reg is vector decoded.
17615;; Convert it into imul reg, reg
17616;; It would be better to force assembler to encode instruction using long
17617;; immediate, but there is apparently no way to do so.
17618(define_peephole2
17619  [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17620		   (mult:SWI248
17621		    (match_operand:SWI248 1 "nonimmediate_operand" "")
17622		    (match_operand:SWI248 2 "const_int_operand" "")))
17623	      (clobber (reg:CC FLAGS_REG))])
17624   (match_scratch:SWI248 3 "r")]
17625  "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17626   && satisfies_constraint_K (operands[2])"
17627  [(set (match_dup 3) (match_dup 2))
17628   (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17629	      (clobber (reg:CC FLAGS_REG))])]
17630{
17631  if (!rtx_equal_p (operands[0], operands[1]))
17632    emit_move_insn (operands[0], operands[1]);
17633})
17634
17635;; After splitting up read-modify operations, array accesses with memory
17636;; operands might end up in form:
17637;;  sall    $2, %eax
17638;;  movl    4(%esp), %edx
17639;;  addl    %edx, %eax
17640;; instead of pre-splitting:
17641;;  sall    $2, %eax
17642;;  addl    4(%esp), %eax
17643;; Turn it into:
17644;;  movl    4(%esp), %edx
17645;;  leal    (%edx,%eax,4), %eax
17646
17647(define_peephole2
17648  [(match_scratch:P 5 "r")
17649   (parallel [(set (match_operand 0 "register_operand" "")
17650		   (ashift (match_operand 1 "register_operand" "")
17651			   (match_operand 2 "const_int_operand" "")))
17652	       (clobber (reg:CC FLAGS_REG))])
17653   (parallel [(set (match_operand 3 "register_operand" "")
17654		   (plus (match_dup 0)
17655			 (match_operand 4 "x86_64_general_operand" "")))
17656		   (clobber (reg:CC FLAGS_REG))])]
17657  "IN_RANGE (INTVAL (operands[2]), 1, 3)
17658   /* Validate MODE for lea.  */
17659   && ((!TARGET_PARTIAL_REG_STALL
17660	&& (GET_MODE (operands[0]) == QImode
17661	    || GET_MODE (operands[0]) == HImode))
17662       || GET_MODE (operands[0]) == SImode
17663       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17664   && (rtx_equal_p (operands[0], operands[3])
17665       || peep2_reg_dead_p (2, operands[0]))
17666   /* We reorder load and the shift.  */
17667   && !reg_overlap_mentioned_p (operands[0], operands[4])"
17668  [(set (match_dup 5) (match_dup 4))
17669   (set (match_dup 0) (match_dup 1))]
17670{
17671  enum machine_mode op1mode = GET_MODE (operands[1]);
17672  enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17673  int scale = 1 << INTVAL (operands[2]);
17674  rtx index = gen_lowpart (Pmode, operands[1]);
17675  rtx base = gen_lowpart (Pmode, operands[5]);
17676  rtx dest = gen_lowpart (mode, operands[3]);
17677
17678  operands[1] = gen_rtx_PLUS (Pmode, base,
17679  			      gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17680  operands[5] = base;
17681  if (mode != Pmode)
17682    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17683  if (op1mode != Pmode)
17684    operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17685  operands[0] = dest;
17686})
17687
17688;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17689;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17690;; caught for use by garbage collectors and the like.  Using an insn that
17691;; maps to SIGILL makes it more likely the program will rightfully die.
17692;; Keeping with tradition, "6" is in honor of #UD.
17693(define_insn "trap"
17694  [(trap_if (const_int 1) (const_int 6))]
17695  ""
17696  { return ASM_SHORT "0x0b0f"; }
17697  [(set_attr "length" "2")])
17698
17699(define_expand "prefetch"
17700  [(prefetch (match_operand 0 "address_operand" "")
17701	     (match_operand:SI 1 "const_int_operand" "")
17702	     (match_operand:SI 2 "const_int_operand" ""))]
17703  "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17704{
17705  int rw = INTVAL (operands[1]);
17706  int locality = INTVAL (operands[2]);
17707
17708  gcc_assert (rw == 0 || rw == 1);
17709  gcc_assert (IN_RANGE (locality, 0, 3));
17710
17711  if (TARGET_PREFETCHW && rw)
17712    operands[2] = GEN_INT (3);
17713  /* Use 3dNOW prefetch in case we are asking for write prefetch not
17714     supported by SSE counterpart or the SSE prefetch is not available
17715     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17716     of locality.  */
17717  else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17718    operands[2] = GEN_INT (3);
17719  else
17720    operands[1] = const0_rtx;
17721})
17722
17723(define_insn "*prefetch_sse"
17724  [(prefetch (match_operand 0 "address_operand" "p")
17725	     (const_int 0)
17726	     (match_operand:SI 1 "const_int_operand" ""))]
17727  "TARGET_PREFETCH_SSE"
17728{
17729  static const char * const patterns[4] = {
17730   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17731  };
17732
17733  int locality = INTVAL (operands[1]);
17734  gcc_assert (IN_RANGE (locality, 0, 3));
17735
17736  return patterns[locality];
17737}
17738  [(set_attr "type" "sse")
17739   (set_attr "atom_sse_attr" "prefetch")
17740   (set (attr "length_address")
17741	(symbol_ref "memory_address_length (operands[0], false)"))
17742   (set_attr "memory" "none")])
17743
17744(define_insn "*prefetch_3dnow"
17745  [(prefetch (match_operand 0 "address_operand" "p")
17746	     (match_operand:SI 1 "const_int_operand" "n")
17747	     (const_int 3))]
17748  "TARGET_3DNOW || TARGET_PREFETCHW"
17749{
17750  if (INTVAL (operands[1]) == 0)
17751    return "prefetch\t%a0";
17752  else
17753    return "prefetchw\t%a0";
17754}
17755  [(set_attr "type" "mmx")
17756   (set (attr "length_address")
17757	(symbol_ref "memory_address_length (operands[0], false)"))
17758   (set_attr "memory" "none")])
17759
17760(define_expand "stack_protect_set"
17761  [(match_operand 0 "memory_operand" "")
17762   (match_operand 1 "memory_operand" "")]
17763  "!TARGET_HAS_BIONIC"
17764{
17765  rtx (*insn)(rtx, rtx);
17766
17767#ifdef TARGET_THREAD_SSP_OFFSET
17768  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17769  insn = (TARGET_LP64
17770	  ? gen_stack_tls_protect_set_di
17771	  : gen_stack_tls_protect_set_si);
17772#else
17773  insn = (TARGET_LP64
17774	  ? gen_stack_protect_set_di
17775	  : gen_stack_protect_set_si);
17776#endif
17777
17778  emit_insn (insn (operands[0], operands[1]));
17779  DONE;
17780})
17781
17782(define_insn "stack_protect_set_<mode>"
17783  [(set (match_operand:PTR 0 "memory_operand" "=m")
17784	(unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17785		    UNSPEC_SP_SET))
17786   (set (match_scratch:PTR 2 "=&r") (const_int 0))
17787   (clobber (reg:CC FLAGS_REG))]
17788  "!TARGET_HAS_BIONIC"
17789  "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17790  [(set_attr "type" "multi")])
17791
17792(define_insn "stack_tls_protect_set_<mode>"
17793  [(set (match_operand:PTR 0 "memory_operand" "=m")
17794	(unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17795		    UNSPEC_SP_TLS_SET))
17796   (set (match_scratch:PTR 2 "=&r") (const_int 0))
17797   (clobber (reg:CC FLAGS_REG))]
17798  ""
17799  "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17800  [(set_attr "type" "multi")])
17801
17802(define_expand "stack_protect_test"
17803  [(match_operand 0 "memory_operand" "")
17804   (match_operand 1 "memory_operand" "")
17805   (match_operand 2 "" "")]
17806  "!TARGET_HAS_BIONIC"
17807{
17808  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17809
17810  rtx (*insn)(rtx, rtx, rtx);
17811
17812#ifdef TARGET_THREAD_SSP_OFFSET
17813  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17814  insn = (TARGET_LP64
17815	  ? gen_stack_tls_protect_test_di
17816	  : gen_stack_tls_protect_test_si);
17817#else
17818  insn = (TARGET_LP64
17819	  ? gen_stack_protect_test_di
17820	  : gen_stack_protect_test_si);
17821#endif
17822
17823  emit_insn (insn (flags, operands[0], operands[1]));
17824
17825  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17826				  flags, const0_rtx, operands[2]));
17827  DONE;
17828})
17829
17830(define_insn "stack_protect_test_<mode>"
17831  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17832	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17833		     (match_operand:PTR 2 "memory_operand" "m")]
17834		    UNSPEC_SP_TEST))
17835   (clobber (match_scratch:PTR 3 "=&r"))]
17836  "!TARGET_HAS_BIONIC"
17837  "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17838  [(set_attr "type" "multi")])
17839
17840(define_insn "stack_tls_protect_test_<mode>"
17841  [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17842	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17843		     (match_operand:PTR 2 "const_int_operand" "i")]
17844		    UNSPEC_SP_TLS_TEST))
17845   (clobber (match_scratch:PTR 3 "=r"))]
17846  ""
17847  "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17848  [(set_attr "type" "multi")])
17849
17850(define_insn "sse4_2_crc32<mode>"
17851  [(set (match_operand:SI 0 "register_operand" "=r")
17852	(unspec:SI
17853	  [(match_operand:SI 1 "register_operand" "0")
17854	   (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17855	  UNSPEC_CRC32))]
17856  "TARGET_SSE4_2 || TARGET_CRC32"
17857  "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17858  [(set_attr "type" "sselog1")
17859   (set_attr "prefix_rep" "1")
17860   (set_attr "prefix_extra" "1")
17861   (set (attr "prefix_data16")
17862     (if_then_else (match_operand:HI 2 "" "")
17863       (const_string "1")
17864       (const_string "*")))
17865   (set (attr "prefix_rex")
17866     (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17867       (const_string "1")
17868       (const_string "*")))
17869   (set_attr "mode" "SI")])
17870
17871(define_insn "sse4_2_crc32di"
17872  [(set (match_operand:DI 0 "register_operand" "=r")
17873	(unspec:DI
17874	  [(match_operand:DI 1 "register_operand" "0")
17875	   (match_operand:DI 2 "nonimmediate_operand" "rm")]
17876	  UNSPEC_CRC32))]
17877  "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17878  "crc32{q}\t{%2, %0|%0, %2}"
17879  [(set_attr "type" "sselog1")
17880   (set_attr "prefix_rep" "1")
17881   (set_attr "prefix_extra" "1")
17882   (set_attr "mode" "DI")])
17883
17884(define_expand "rdpmc"
17885  [(match_operand:DI 0 "register_operand" "")
17886   (match_operand:SI 1 "register_operand" "")]
17887  ""
17888{
17889  rtx reg = gen_reg_rtx (DImode);
17890  rtx si;
17891
17892  /* Force operand 1 into ECX.  */
17893  rtx ecx = gen_rtx_REG (SImode, CX_REG);
17894  emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17895  si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17896				UNSPECV_RDPMC);
17897
17898  if (TARGET_64BIT)
17899    {
17900      rtvec vec = rtvec_alloc (2);
17901      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17902      rtx upper = gen_reg_rtx (DImode);
17903      rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17904					gen_rtvec (1, const0_rtx),
17905					UNSPECV_RDPMC);
17906      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17907      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17908      emit_insn (load);
17909      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17910				   NULL, 1, OPTAB_DIRECT);
17911      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17912				 OPTAB_DIRECT);
17913    }
17914  else
17915    emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17916  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17917  DONE;
17918})
17919
17920(define_insn "*rdpmc"
17921  [(set (match_operand:DI 0 "register_operand" "=A")
17922  	(unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17923			    UNSPECV_RDPMC))]
17924  "!TARGET_64BIT"
17925  "rdpmc"
17926  [(set_attr "type" "other")
17927   (set_attr "length" "2")])
17928
17929(define_insn "*rdpmc_rex64"
17930  [(set (match_operand:DI 0 "register_operand" "=a")
17931  	(unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17932			    UNSPECV_RDPMC))
17933  (set (match_operand:DI 1 "register_operand" "=d")
17934       (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17935  "TARGET_64BIT"
17936  "rdpmc"
17937  [(set_attr "type" "other")
17938   (set_attr "length" "2")])
17939
17940(define_expand "rdtsc"
17941  [(set (match_operand:DI 0 "register_operand" "")
17942	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17943  ""
17944{
17945  if (TARGET_64BIT)
17946    {
17947      rtvec vec = rtvec_alloc (2);
17948      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17949      rtx upper = gen_reg_rtx (DImode);
17950      rtx lower = gen_reg_rtx (DImode);
17951      rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17952					 gen_rtvec (1, const0_rtx),
17953					 UNSPECV_RDTSC);
17954      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17955      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17956      emit_insn (load);
17957      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17958				   NULL, 1, OPTAB_DIRECT);
17959      lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17960				   OPTAB_DIRECT);
17961      emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17962      DONE;
17963    }
17964})
17965
17966(define_insn "*rdtsc"
17967  [(set (match_operand:DI 0 "register_operand" "=A")
17968	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17969  "!TARGET_64BIT"
17970  "rdtsc"
17971  [(set_attr "type" "other")
17972   (set_attr "length" "2")])
17973
17974(define_insn "*rdtsc_rex64"
17975  [(set (match_operand:DI 0 "register_operand" "=a")
17976	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17977   (set (match_operand:DI 1 "register_operand" "=d")
17978	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17979  "TARGET_64BIT"
17980  "rdtsc"
17981  [(set_attr "type" "other")
17982   (set_attr "length" "2")])
17983
17984(define_expand "rdtscp"
17985  [(match_operand:DI 0 "register_operand" "")
17986   (match_operand:SI 1 "memory_operand" "")]
17987  ""
17988{
17989  rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17990				    gen_rtvec (1, const0_rtx),
17991				    UNSPECV_RDTSCP);
17992  rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17993				    gen_rtvec (1, const0_rtx),
17994				    UNSPECV_RDTSCP);
17995  rtx reg = gen_reg_rtx (DImode);
17996  rtx tmp = gen_reg_rtx (SImode);
17997
17998  if (TARGET_64BIT)
17999    {
18000      rtvec vec = rtvec_alloc (3);
18001      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18002      rtx upper = gen_reg_rtx (DImode);
18003      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18004      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18005      RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18006      emit_insn (load);
18007      upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18008				   NULL, 1, OPTAB_DIRECT);
18009      reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18010				 OPTAB_DIRECT);
18011    }
18012  else
18013    {
18014      rtvec vec = rtvec_alloc (2);
18015      rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18016      RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18017      RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18018      emit_insn (load);
18019    }
18020  emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18021  emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18022  DONE;
18023})
18024
18025(define_insn "*rdtscp"
18026  [(set (match_operand:DI 0 "register_operand" "=A")
18027	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18028   (set (match_operand:SI 1 "register_operand" "=c")
18029	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18030  "!TARGET_64BIT"
18031  "rdtscp"
18032  [(set_attr "type" "other")
18033   (set_attr "length" "3")])
18034
18035(define_insn "*rdtscp_rex64"
18036  [(set (match_operand:DI 0 "register_operand" "=a")
18037	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18038   (set (match_operand:DI 1 "register_operand" "=d")
18039        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18040   (set (match_operand:SI 2 "register_operand" "=c")
18041	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18042  "TARGET_64BIT"
18043  "rdtscp"
18044  [(set_attr "type" "other")
18045   (set_attr "length" "3")])
18046
18047;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18048;;
18049;; LWP instructions
18050;;
18051;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18052
18053(define_expand "lwp_llwpcb"
18054  [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18055		    UNSPECV_LLWP_INTRINSIC)]
18056  "TARGET_LWP")
18057
18058(define_insn "*lwp_llwpcb<mode>1"
18059  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18060		    UNSPECV_LLWP_INTRINSIC)]
18061  "TARGET_LWP"
18062  "llwpcb\t%0"
18063  [(set_attr "type" "lwp")
18064   (set_attr "mode" "<MODE>")
18065   (set_attr "length" "5")])
18066
18067(define_expand "lwp_slwpcb"
18068  [(set (match_operand 0 "register_operand" "=r")
18069	(unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18070  "TARGET_LWP"
18071{
18072  rtx (*insn)(rtx);
18073
18074  insn = (TARGET_64BIT
18075	  ? gen_lwp_slwpcbdi
18076	  : gen_lwp_slwpcbsi);
18077
18078  emit_insn (insn (operands[0]));
18079  DONE;
18080})
18081
18082(define_insn "lwp_slwpcb<mode>"
18083  [(set (match_operand:P 0 "register_operand" "=r")
18084	(unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18085  "TARGET_LWP"
18086  "slwpcb\t%0"
18087  [(set_attr "type" "lwp")
18088   (set_attr "mode" "<MODE>")
18089   (set_attr "length" "5")])
18090
18091(define_expand "lwp_lwpval<mode>3"
18092  [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18093    	    	     (match_operand:SI 2 "nonimmediate_operand" "rm")
18094		     (match_operand:SI 3 "const_int_operand" "i")]
18095		    UNSPECV_LWPVAL_INTRINSIC)]
18096  "TARGET_LWP"
18097  ;; Avoid unused variable warning.
18098  "(void) operands[0];")
18099
18100(define_insn "*lwp_lwpval<mode>3_1"
18101  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18102    	    	     (match_operand:SI 1 "nonimmediate_operand" "rm")
18103		     (match_operand:SI 2 "const_int_operand" "i")]
18104		    UNSPECV_LWPVAL_INTRINSIC)]
18105  "TARGET_LWP"
18106  "lwpval\t{%2, %1, %0|%0, %1, %2}"
18107  [(set_attr "type" "lwp")
18108   (set_attr "mode" "<MODE>")
18109   (set (attr "length")
18110        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18111
18112(define_expand "lwp_lwpins<mode>3"
18113  [(set (reg:CCC FLAGS_REG)
18114	(unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18115			      (match_operand:SI 2 "nonimmediate_operand" "rm")
18116			      (match_operand:SI 3 "const_int_operand" "i")]
18117			     UNSPECV_LWPINS_INTRINSIC))
18118   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18119	(eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18120  "TARGET_LWP")
18121
18122(define_insn "*lwp_lwpins<mode>3_1"
18123  [(set (reg:CCC FLAGS_REG)
18124	(unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18125			      (match_operand:SI 1 "nonimmediate_operand" "rm")
18126			      (match_operand:SI 2 "const_int_operand" "i")]
18127			     UNSPECV_LWPINS_INTRINSIC))]
18128  "TARGET_LWP"
18129  "lwpins\t{%2, %1, %0|%0, %1, %2}"
18130  [(set_attr "type" "lwp")
18131   (set_attr "mode" "<MODE>")
18132   (set (attr "length")
18133        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18134
18135(define_insn "rdfsbase<mode>"
18136  [(set (match_operand:SWI48 0 "register_operand" "=r")
18137	(unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18138  "TARGET_64BIT && TARGET_FSGSBASE"
18139  "rdfsbase %0"
18140  [(set_attr "type" "other")
18141   (set_attr "prefix_extra" "2")])
18142
18143(define_insn "rdgsbase<mode>"
18144  [(set (match_operand:SWI48 0 "register_operand" "=r")
18145	(unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18146  "TARGET_64BIT && TARGET_FSGSBASE"
18147  "rdgsbase %0"
18148  [(set_attr "type" "other")
18149   (set_attr "prefix_extra" "2")])
18150
18151(define_insn "wrfsbase<mode>"
18152  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18153		    UNSPECV_WRFSBASE)]
18154  "TARGET_64BIT && TARGET_FSGSBASE"
18155  "wrfsbase %0"
18156  [(set_attr "type" "other")
18157   (set_attr "prefix_extra" "2")])
18158
18159(define_insn "wrgsbase<mode>"
18160  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18161		    UNSPECV_WRGSBASE)]
18162  "TARGET_64BIT && TARGET_FSGSBASE"
18163  "wrgsbase %0"
18164  [(set_attr "type" "other")
18165   (set_attr "prefix_extra" "2")])
18166
18167(define_insn "rdrand<mode>_1"
18168  [(set (match_operand:SWI248 0 "register_operand" "=r")
18169	(unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18170   (set (reg:CCC FLAGS_REG)
18171	(unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18172  "TARGET_RDRND"
18173  "rdrand\t%0"
18174  [(set_attr "type" "other")
18175   (set_attr "prefix_extra" "1")])
18176
18177(define_expand "pause"
18178  [(set (match_dup 0)
18179	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18180  ""
18181{
18182  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18183  MEM_VOLATILE_P (operands[0]) = 1;
18184})
18185
18186;; Use "rep; nop", instead of "pause", to support older assemblers.
18187;; They have the same encoding.
18188(define_insn "*pause"
18189  [(set (match_operand:BLK 0 "" "")
18190	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18191  ""
18192  "rep; nop"
18193  [(set_attr "length" "2")
18194   (set_attr "memory" "unknown")])
18195
18196(include "mmx.md")
18197(include "sse.md")
18198(include "sync.md")
18199