1;; GCC machine description for IA-32 and x86-64.
2;; Copyright (C) 1988-2015 Free Software Foundation, Inc.
3;; Mostly by William Schelter.
4;; x86_64 support added by Jan Hubicka
5;;
6;; This file is part of GCC.
7;;
8;; GCC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 3, or (at your option)
11;; any later version.
12;;
13;; GCC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16;; GNU General Public License for more details.
17;;
18;; You should have received a copy of the GNU General Public License
19;; along with GCC; see the file COPYING3.  If not see
20;; <http://www.gnu.org/licenses/>.  */
21;;
22;; The original PO technology requires these to be ordered by speed,
23;; so that assigner will pick the fastest.
24;;
25;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26;;
27;; The special asm out single letter directives following a '%' are:
28;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29;; C -- print opcode suffix for set/cmov insn.
30;; c -- like C, but print reversed condition
31;; F,f -- likewise, but for floating-point.
32;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33;;      otherwise nothing
34;; R -- print the prefix for register names.
35;; z -- print the opcode suffix for the size of the current operand.
36;; Z -- likewise, with special suffixes for x87 instructions.
37;; * -- print a star (in certain assembler syntax)
38;; A -- print an absolute memory reference.
39;; E -- print address with DImode register names if TARGET_64BIT.
40;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41;; s -- print a shift double count, followed by the assemblers argument
42;;	delimiter.
43;; b -- print the QImode name of the register for the indicated operand.
44;;	%b0 would print %al if operands[0] is reg 0.
45;; w --  likewise, print the HImode name of the register.
46;; k --  likewise, print the SImode name of the register.
47;; q --  likewise, print the DImode name of the register.
48;; x --  likewise, print the V4SFmode name of the register.
49;; t --  likewise, print the V8SFmode name of the register.
50;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51;; y -- print "st(0)" instead of "st" as a register.
52;; d -- print duplicated register operand for AVX instruction.
53;; D -- print condition for SSE cmp instruction.
54;; P -- if PIC, print an @PLT suffix.
55;; p -- print raw symbol name.
56;; X -- don't print any sort of PIC '@' suffix for a symbol.
57;; & -- print some in-use local-dynamic symbol name.
58;; H -- print a memory address offset by 8; used for sse high-parts
59;; K -- print HLE lock prefix
60;; Y -- print condition for XOP pcom* instruction.
61;; + -- print a branch hint as 'cs' or 'ds' prefix
62;; ; -- print a semicolon (after prefixes due to bug in older gas).
63;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64;; @ -- print a segment register of thread base pointer load
65;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66;; ! -- print MPX prefix for jxx/call/ret instructions if required.
67
68(define_c_enum "unspec" [
69  ;; Relocation specifiers
70  UNSPEC_GOT
71  UNSPEC_GOTOFF
72  UNSPEC_GOTPCREL
73  UNSPEC_GOTTPOFF
74  UNSPEC_TPOFF
75  UNSPEC_NTPOFF
76  UNSPEC_DTPOFF
77  UNSPEC_GOTNTPOFF
78  UNSPEC_INDNTPOFF
79  UNSPEC_PLTOFF
80  UNSPEC_MACHOPIC_OFFSET
81  UNSPEC_PCREL
82  UNSPEC_SIZEOF
83
84  ;; Prologue support
85  UNSPEC_STACK_ALLOC
86  UNSPEC_SET_GOT
87  UNSPEC_SET_RIP
88  UNSPEC_SET_GOT_OFFSET
89  UNSPEC_MEMORY_BLOCKAGE
90  UNSPEC_STACK_CHECK
91
92  ;; TLS support
93  UNSPEC_TP
94  UNSPEC_TLS_GD
95  UNSPEC_TLS_LD_BASE
96  UNSPEC_TLSDESC
97  UNSPEC_TLS_IE_SUN
98
99  ;; Other random patterns
100  UNSPEC_SCAS
101  UNSPEC_FNSTSW
102  UNSPEC_SAHF
103  UNSPEC_PARITY
104  UNSPEC_FSTCW
105  UNSPEC_FLDCW
106  UNSPEC_REP
107  UNSPEC_LD_MPIC	; load_macho_picbase
108  UNSPEC_TRUNC_NOOP
109  UNSPEC_DIV_ALREADY_SPLIT
110  UNSPEC_PAUSE
111  UNSPEC_LEA_ADDR
112  UNSPEC_XBEGIN_ABORT
113  UNSPEC_STOS
114  UNSPEC_PEEPSIB
115  UNSPEC_INSN_FALSE_DEP
116
117  ;; For SSE/MMX support:
118  UNSPEC_FIX_NOTRUNC
119  UNSPEC_MASKMOV
120  UNSPEC_MOVMSK
121  UNSPEC_RCP
122  UNSPEC_RSQRT
123  UNSPEC_PSADBW
124
125  ;; Generic math support
126  UNSPEC_COPYSIGN
127  UNSPEC_IEEE_MIN	; not commutative
128  UNSPEC_IEEE_MAX	; not commutative
129
130  ;; x87 Floating point
131  UNSPEC_SIN
132  UNSPEC_COS
133  UNSPEC_FPATAN
134  UNSPEC_FYL2X
135  UNSPEC_FYL2XP1
136  UNSPEC_FRNDINT
137  UNSPEC_FIST
138  UNSPEC_F2XM1
139  UNSPEC_TAN
140  UNSPEC_FXAM
141
142  ;; x87 Rounding
143  UNSPEC_FRNDINT_FLOOR
144  UNSPEC_FRNDINT_CEIL
145  UNSPEC_FRNDINT_TRUNC
146  UNSPEC_FRNDINT_MASK_PM
147  UNSPEC_FIST_FLOOR
148  UNSPEC_FIST_CEIL
149
150  ;; x87 Double output FP
151  UNSPEC_SINCOS_COS
152  UNSPEC_SINCOS_SIN
153  UNSPEC_XTRACT_FRACT
154  UNSPEC_XTRACT_EXP
155  UNSPEC_FSCALE_FRACT
156  UNSPEC_FSCALE_EXP
157  UNSPEC_FPREM_F
158  UNSPEC_FPREM_U
159  UNSPEC_FPREM1_F
160  UNSPEC_FPREM1_U
161
162  UNSPEC_C2_FLAG
163  UNSPEC_FXAM_MEM
164
165  ;; SSP patterns
166  UNSPEC_SP_SET
167  UNSPEC_SP_TEST
168  UNSPEC_SP_TLS_SET
169  UNSPEC_SP_TLS_TEST
170
171  ;; For ROUND support
172  UNSPEC_ROUND
173
174  ;; For CRC32 support
175  UNSPEC_CRC32
176
177  ;; For BMI support
178  UNSPEC_BEXTR
179
180  ;; For BMI2 support
181  UNSPEC_PDEP
182  UNSPEC_PEXT
183
184  ;; For AVX512F support
185  UNSPEC_KMOV
186
187  UNSPEC_BNDMK
188  UNSPEC_BNDMK_ADDR
189  UNSPEC_BNDSTX
190  UNSPEC_BNDLDX
191  UNSPEC_BNDLDX_ADDR
192  UNSPEC_BNDCL
193  UNSPEC_BNDCU
194  UNSPEC_BNDCN
195  UNSPEC_MPX_FENCE
196])
197
198(define_c_enum "unspecv" [
199  UNSPECV_BLOCKAGE
200  UNSPECV_STACK_PROBE
201  UNSPECV_PROBE_STACK_RANGE
202  UNSPECV_ALIGN
203  UNSPECV_PROLOGUE_USE
204  UNSPECV_SPLIT_STACK_RETURN
205  UNSPECV_CLD
206  UNSPECV_NOPS
207  UNSPECV_RDTSC
208  UNSPECV_RDTSCP
209  UNSPECV_RDPMC
210  UNSPECV_LLWP_INTRINSIC
211  UNSPECV_SLWP_INTRINSIC
212  UNSPECV_LWPVAL_INTRINSIC
213  UNSPECV_LWPINS_INTRINSIC
214  UNSPECV_RDFSBASE
215  UNSPECV_RDGSBASE
216  UNSPECV_WRFSBASE
217  UNSPECV_WRGSBASE
218  UNSPECV_FXSAVE
219  UNSPECV_FXRSTOR
220  UNSPECV_FXSAVE64
221  UNSPECV_FXRSTOR64
222  UNSPECV_XSAVE
223  UNSPECV_XRSTOR
224  UNSPECV_XSAVE64
225  UNSPECV_XRSTOR64
226  UNSPECV_XSAVEOPT
227  UNSPECV_XSAVEOPT64
228  UNSPECV_XSAVES
229  UNSPECV_XRSTORS
230  UNSPECV_XSAVES64
231  UNSPECV_XRSTORS64
232  UNSPECV_XSAVEC
233  UNSPECV_XSAVEC64
234
235  ;; For atomic compound assignments.
236  UNSPECV_FNSTENV
237  UNSPECV_FLDENV
238  UNSPECV_FNSTSW
239  UNSPECV_FNCLEX
240
241  ;; For RDRAND support
242  UNSPECV_RDRAND
243
244  ;; For RDSEED support
245  UNSPECV_RDSEED
246
247  ;; For RTM support
248  UNSPECV_XBEGIN
249  UNSPECV_XEND
250  UNSPECV_XABORT
251  UNSPECV_XTEST
252
253  UNSPECV_NLGR
254
255  ;; For CLWB support
256  UNSPECV_CLWB
257
258  ;; For PCOMMIT support
259  UNSPECV_PCOMMIT
260
261  ;; For CLFLUSHOPT support
262  UNSPECV_CLFLUSHOPT
263
264  ;; For MONITORX and MWAITX support 
265  UNSPECV_MONITORX
266  UNSPECV_MWAITX
267
268])
269
270;; Constants to represent rounding modes in the ROUND instruction
271(define_constants
272  [(ROUND_FLOOR			0x1)
273   (ROUND_CEIL			0x2)
274   (ROUND_TRUNC			0x3)
275   (ROUND_MXCSR			0x4)
276   (ROUND_NO_EXC		0x8)
277  ])
278
279;; Constants to represent AVX512F embeded rounding
280(define_constants
281  [(ROUND_NEAREST_INT			0)
282   (ROUND_NEG_INF			1)
283   (ROUND_POS_INF			2)
284   (ROUND_ZERO				3)
285   (NO_ROUND				4)
286   (ROUND_SAE				8)
287  ])
288
289;; Constants to represent pcomtrue/pcomfalse variants
290(define_constants
291  [(PCOM_FALSE			0)
292   (PCOM_TRUE			1)
293   (COM_FALSE_S			2)
294   (COM_FALSE_P			3)
295   (COM_TRUE_S			4)
296   (COM_TRUE_P			5)
297  ])
298
299;; Constants used in the XOP pperm instruction
300(define_constants
301  [(PPERM_SRC			0x00)	/* copy source */
302   (PPERM_INVERT		0x20)	/* invert source */
303   (PPERM_REVERSE		0x40)	/* bit reverse source */
304   (PPERM_REV_INV		0x60)	/* bit reverse & invert src */
305   (PPERM_ZERO			0x80)	/* all 0's */
306   (PPERM_ONES			0xa0)	/* all 1's */
307   (PPERM_SIGN			0xc0)	/* propagate sign bit */
308   (PPERM_INV_SIGN		0xe0)	/* invert & propagate sign */
309   (PPERM_SRC1			0x00)	/* use first source byte */
310   (PPERM_SRC2			0x10)	/* use second source byte */
311   ])
312
313;; Registers by name.
314(define_constants
315  [(AX_REG			 0)
316   (DX_REG			 1)
317   (CX_REG			 2)
318   (BX_REG			 3)
319   (SI_REG			 4)
320   (DI_REG			 5)
321   (BP_REG			 6)
322   (SP_REG			 7)
323   (ST0_REG			 8)
324   (ST1_REG			 9)
325   (ST2_REG			10)
326   (ST3_REG			11)
327   (ST4_REG			12)
328   (ST5_REG			13)
329   (ST6_REG			14)
330   (ST7_REG			15)
331   (FLAGS_REG			17)
332   (FPSR_REG			18)
333   (FPCR_REG			19)
334   (XMM0_REG			21)
335   (XMM1_REG			22)
336   (XMM2_REG			23)
337   (XMM3_REG			24)
338   (XMM4_REG			25)
339   (XMM5_REG			26)
340   (XMM6_REG			27)
341   (XMM7_REG			28)
342   (MM0_REG			29)
343   (MM1_REG			30)
344   (MM2_REG			31)
345   (MM3_REG			32)
346   (MM4_REG			33)
347   (MM5_REG			34)
348   (MM6_REG			35)
349   (MM7_REG			36)
350   (R8_REG			37)
351   (R9_REG			38)
352   (R10_REG			39)
353   (R11_REG			40)
354   (R12_REG			41)
355   (R13_REG			42)
356   (R14_REG			43)
357   (R15_REG			44)
358   (XMM8_REG			45)
359   (XMM9_REG			46)
360   (XMM10_REG			47)
361   (XMM11_REG			48)
362   (XMM12_REG			49)
363   (XMM13_REG			50)
364   (XMM14_REG			51)
365   (XMM15_REG			52)
366   (XMM16_REG			53)
367   (XMM17_REG			54)
368   (XMM18_REG			55)
369   (XMM19_REG			56)
370   (XMM20_REG			57)
371   (XMM21_REG			58)
372   (XMM22_REG			59)
373   (XMM23_REG			60)
374   (XMM24_REG			61)
375   (XMM25_REG			62)
376   (XMM26_REG			63)
377   (XMM27_REG			64)
378   (XMM28_REG			65)
379   (XMM29_REG			66)
380   (XMM30_REG			67)
381   (XMM31_REG			68)
382   (MASK0_REG			69)
383   (MASK1_REG			70)
384   (MASK2_REG			71)
385   (MASK3_REG			72)
386   (MASK4_REG			73)
387   (MASK5_REG			74)
388   (MASK6_REG			75)
389   (MASK7_REG			76)
390   (BND0_REG			77)
391   (BND1_REG			78)
392  ])
393
394;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
395;; from i386.c.
396
397;; In C guard expressions, put expressions which may be compile-time
398;; constants first.  This allows for better optimization.  For
399;; example, write "TARGET_64BIT && reload_completed", not
400;; "reload_completed && TARGET_64BIT".
401
402
403;; Processor type.
404(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
405		    atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
406		    btver2,knl"
407  (const (symbol_ref "ix86_schedule")))
408
409;; A basic instruction type.  Refinements due to arguments to be
410;; provided in other attributes.
411(define_attr "type"
412  "other,multi,
413   alu,alu1,negnot,imov,imovx,lea,
414   incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
415   imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
416   push,pop,call,callv,leave,
417   str,bitmanip,
418   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
419   fxch,fistp,fisttp,frndint,
420   sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
421   ssemul,sseimul,ssediv,sselog,sselog1,
422   sseishft,sseishft1,ssecmp,ssecomi,
423   ssecvt,ssecvt1,sseicvt,sseins,
424   sseshuf,sseshuf1,ssemuladd,sse4arg,
425   lwp,mskmov,msklog,
426   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
427   mpxmov,mpxmk,mpxchk,mpxld,mpxst"
428  (const_string "other"))
429
430;; Main data type used by the insn
431(define_attr "mode"
432  "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
433  V2DF,V2SF,V1DF,V8DF"
434  (const_string "unknown"))
435
436;; The CPU unit operations uses.
437(define_attr "unit" "integer,i387,sse,mmx,unknown"
438  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
439			  fxch,fistp,fisttp,frndint")
440	   (const_string "i387")
441	 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
442			  ssemul,sseimul,ssediv,sselog,sselog1,
443			  sseishft,sseishft1,ssecmp,ssecomi,
444			  ssecvt,ssecvt1,sseicvt,sseins,
445			  sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
446	   (const_string "sse")
447	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
448	   (const_string "mmx")
449	 (eq_attr "type" "other")
450	   (const_string "unknown")]
451	 (const_string "integer")))
452
453;; The minimum required alignment of vector mode memory operands of the SSE
454;; (non-VEX/EVEX) instruction in bits, if it is different from
455;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
456;; multiple alternatives, this should be conservative maximum of those minimum
457;; required alignments.
458(define_attr "ssememalign" "" (const_int 0))
459
460;; The (bounding maximum) length of an instruction immediate.
461(define_attr "length_immediate" ""
462  (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
463			  bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
464			  mpxld,mpxst")
465	   (const_int 0)
466	 (eq_attr "unit" "i387,sse,mmx")
467	   (const_int 0)
468	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
469			  rotate,rotatex,rotate1,imul,icmp,push,pop")
470	   (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
471	 (eq_attr "type" "imov,test")
472	   (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
473	 (eq_attr "type" "call")
474	   (if_then_else (match_operand 0 "constant_call_address_operand")
475	     (const_int 4)
476	     (const_int 0))
477	 (eq_attr "type" "callv")
478	   (if_then_else (match_operand 1 "constant_call_address_operand")
479	     (const_int 4)
480	     (const_int 0))
481	 ;; We don't know the size before shorten_branches.  Expect
482	 ;; the instruction to fit for better scheduling.
483	 (eq_attr "type" "ibr")
484	   (const_int 1)
485	 ]
486	 (symbol_ref "/* Update immediate_length and other attributes! */
487		      gcc_unreachable (),1")))
488
489;; The (bounding maximum) length of an instruction address.
490(define_attr "length_address" ""
491  (cond [(eq_attr "type" "str,other,multi,fxch")
492	   (const_int 0)
493	 (and (eq_attr "type" "call")
494	      (match_operand 0 "constant_call_address_operand"))
495	     (const_int 0)
496	 (and (eq_attr "type" "callv")
497	      (match_operand 1 "constant_call_address_operand"))
498	     (const_int 0)
499	 ]
500	 (symbol_ref "ix86_attr_length_address_default (insn)")))
501
502;; Set when length prefix is used.
503(define_attr "prefix_data16" ""
504  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
505	   (const_int 0)
506	 (eq_attr "mode" "HI")
507	   (const_int 1)
508	 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
509	   (const_int 1)
510	]
511	(const_int 0)))
512
513;; Set when string REP prefix is used.
514(define_attr "prefix_rep" ""
515  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
516	   (const_int 0)
517	 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
518	   (const_int 1)
519	 (and (eq_attr "type" "ibr,call,callv")
520	      (match_test "ix86_bnd_prefixed_insn_p (insn)"))
521	   (const_int 1)
522	]
523	(const_int 0)))
524
525;; Set when 0f opcode prefix is used.
526(define_attr "prefix_0f" ""
527  (if_then_else
528    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
529			  mpxmk,mpxmov,mpxchk,mpxld,mpxst")
530	 (eq_attr "unit" "sse,mmx"))
531    (const_int 1)
532    (const_int 0)))
533
534;; Set when REX opcode prefix is used.
535(define_attr "prefix_rex" ""
536  (cond [(not (match_test "TARGET_64BIT"))
537	   (const_int 0)
538	 (and (eq_attr "mode" "DI")
539	      (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
540		   (eq_attr "unit" "!mmx")))
541	   (const_int 1)
542	 (and (eq_attr "mode" "QI")
543	      (match_test "x86_extended_QIreg_mentioned_p (insn)"))
544	   (const_int 1)
545	 (match_test "x86_extended_reg_mentioned_p (insn)")
546	   (const_int 1)
547	 (and (eq_attr "type" "imovx")
548	      (match_operand:QI 1 "ext_QIreg_operand"))
549	   (const_int 1)
550	]
551	(const_int 0)))
552
553;; There are also additional prefixes in 3DNOW, SSSE3.
554;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
555;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
556;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
557(define_attr "prefix_extra" ""
558  (cond [(eq_attr "type" "ssemuladd,sse4arg")
559	   (const_int 2)
560	 (eq_attr "type" "sseiadd1,ssecvt1")
561	   (const_int 1)
562	]
563	(const_int 0)))
564
565;; Prefix used: original, VEX or maybe VEX.
566(define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
567  (cond [(eq_attr "mode" "OI,V8SF,V4DF")
568           (const_string "vex")
569         (eq_attr "mode" "XI,V16SF,V8DF")
570           (const_string "evex")
571        ]
572        (const_string "orig")))
573
574;; VEX W bit is used.
575(define_attr "prefix_vex_w" "" (const_int 0))
576
577;; The length of VEX prefix
578;; Only instructions with 0f prefix can have 2 byte VEX prefix,
579;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
580;; still prefix_0f 1, with prefix_extra 1.
581(define_attr "length_vex" ""
582  (if_then_else (and (eq_attr "prefix_0f" "1")
583		     (eq_attr "prefix_extra" "0"))
584    (if_then_else (eq_attr "prefix_vex_w" "1")
585      (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
586      (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
587    (if_then_else (eq_attr "prefix_vex_w" "1")
588      (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
589      (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
590
591;; 4-bytes evex prefix and 1 byte opcode.
592(define_attr "length_evex" "" (const_int 5))
593
594;; Set when modrm byte is used.
595(define_attr "modrm" ""
596  (cond [(eq_attr "type" "str,leave")
597	   (const_int 0)
598	 (eq_attr "unit" "i387")
599	   (const_int 0)
600         (and (eq_attr "type" "incdec")
601	      (and (not (match_test "TARGET_64BIT"))
602		   (ior (match_operand:SI 1 "register_operand")
603			(match_operand:HI 1 "register_operand"))))
604	   (const_int 0)
605	 (and (eq_attr "type" "push")
606	      (not (match_operand 1 "memory_operand")))
607	   (const_int 0)
608	 (and (eq_attr "type" "pop")
609	      (not (match_operand 0 "memory_operand")))
610	   (const_int 0)
611	 (and (eq_attr "type" "imov")
612	      (and (not (eq_attr "mode" "DI"))
613		   (ior (and (match_operand 0 "register_operand")
614			     (match_operand 1 "immediate_operand"))
615		        (ior (and (match_operand 0 "ax_reg_operand")
616				  (match_operand 1 "memory_displacement_only_operand"))
617			     (and (match_operand 0 "memory_displacement_only_operand")
618				  (match_operand 1 "ax_reg_operand"))))))
619	   (const_int 0)
620	 (and (eq_attr "type" "call")
621	      (match_operand 0 "constant_call_address_operand"))
622	     (const_int 0)
623	 (and (eq_attr "type" "callv")
624	      (match_operand 1 "constant_call_address_operand"))
625	     (const_int 0)
626	 (and (eq_attr "type" "alu,alu1,icmp,test")
627	      (match_operand 0 "ax_reg_operand"))
628	     (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
629	 ]
630	 (const_int 1)))
631
632;; When this attribute is set, calculate total insn length from
633;; length_nobnd attribute, prefixed with eventual bnd prefix byte
634(define_attr "length_nobnd" "" (const_int 0))
635
636;; The (bounding maximum) length of an instruction in bytes.
637;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
638;; Later we may want to split them and compute proper length as for
639;; other insns.
640(define_attr "length" ""
641  (cond [(eq_attr "length_nobnd" "!0")
642	   (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
643		 (attr "length_nobnd"))
644	 (eq_attr "type" "other,multi,fistp,frndint")
645	   (const_int 16)
646	 (eq_attr "type" "fcmp")
647	   (const_int 4)
648	 (eq_attr "unit" "i387")
649	   (plus (const_int 2)
650		 (plus (attr "prefix_data16")
651		       (attr "length_address")))
652	 (ior (eq_attr "prefix" "evex")
653	      (and (ior (eq_attr "prefix" "maybe_evex")
654			(eq_attr "prefix" "maybe_vex"))
655		   (match_test "TARGET_AVX512F")))
656	   (plus (attr "length_evex")
657		 (plus (attr "length_immediate")
658		       (plus (attr "modrm")
659			     (attr "length_address"))))
660	 (ior (eq_attr "prefix" "vex")
661	      (and (ior (eq_attr "prefix" "maybe_vex")
662			(eq_attr "prefix" "maybe_evex"))
663		   (match_test "TARGET_AVX")))
664	   (plus (attr "length_vex")
665		 (plus (attr "length_immediate")
666		       (plus (attr "modrm")
667			     (attr "length_address"))))]
668	 (plus (plus (attr "modrm")
669		     (plus (attr "prefix_0f")
670			   (plus (attr "prefix_rex")
671				 (plus (attr "prefix_extra")
672				       (const_int 1)))))
673	       (plus (attr "prefix_rep")
674		     (plus (attr "prefix_data16")
675			   (plus (attr "length_immediate")
676				 (attr "length_address")))))))
677
678;; The `memory' attribute is `none' if no memory is referenced, `load' or
679;; `store' if there is a simple memory reference therein, or `unknown'
680;; if the instruction is complex.
681
682(define_attr "memory" "none,load,store,both,unknown"
683  (cond [(eq_attr "type" "other,multi,str,lwp")
684	   (const_string "unknown")
685	 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
686	   (const_string "none")
687	 (eq_attr "type" "fistp,leave")
688	   (const_string "both")
689	 (eq_attr "type" "frndint")
690	   (const_string "load")
691	 (eq_attr "type" "mpxld")
692	   (const_string "load")
693	 (eq_attr "type" "mpxst")
694	   (const_string "store")
695	 (eq_attr "type" "push")
696	   (if_then_else (match_operand 1 "memory_operand")
697	     (const_string "both")
698	     (const_string "store"))
699	 (eq_attr "type" "pop")
700	   (if_then_else (match_operand 0 "memory_operand")
701	     (const_string "both")
702	     (const_string "load"))
703	 (eq_attr "type" "setcc")
704	   (if_then_else (match_operand 0 "memory_operand")
705	     (const_string "store")
706	     (const_string "none"))
707	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
708	   (if_then_else (ior (match_operand 0 "memory_operand")
709			      (match_operand 1 "memory_operand"))
710	     (const_string "load")
711	     (const_string "none"))
712	 (eq_attr "type" "ibr")
713	   (if_then_else (match_operand 0 "memory_operand")
714	     (const_string "load")
715	     (const_string "none"))
716	 (eq_attr "type" "call")
717	   (if_then_else (match_operand 0 "constant_call_address_operand")
718	     (const_string "none")
719	     (const_string "load"))
720	 (eq_attr "type" "callv")
721	   (if_then_else (match_operand 1 "constant_call_address_operand")
722	     (const_string "none")
723	     (const_string "load"))
724	 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
725	      (match_operand 1 "memory_operand"))
726	   (const_string "both")
727	 (and (match_operand 0 "memory_operand")
728	      (match_operand 1 "memory_operand"))
729	   (const_string "both")
730	 (match_operand 0 "memory_operand")
731	   (const_string "store")
732	 (match_operand 1 "memory_operand")
733	   (const_string "load")
734	 (and (eq_attr "type"
735		 "!alu1,negnot,ishift1,
736		   imov,imovx,icmp,test,bitmanip,
737		   fmov,fcmp,fsgn,
738		   sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
739		   sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
740		   mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
741	      (match_operand 2 "memory_operand"))
742	   (const_string "load")
743	 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
744	      (match_operand 3 "memory_operand"))
745	   (const_string "load")
746	]
747	(const_string "none")))
748
749;; Indicates if an instruction has both an immediate and a displacement.
750
751(define_attr "imm_disp" "false,true,unknown"
752  (cond [(eq_attr "type" "other,multi")
753	   (const_string "unknown")
754	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
755	      (and (match_operand 0 "memory_displacement_operand")
756		   (match_operand 1 "immediate_operand")))
757	   (const_string "true")
758	 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
759	      (and (match_operand 0 "memory_displacement_operand")
760		   (match_operand 2 "immediate_operand")))
761	   (const_string "true")
762	]
763	(const_string "false")))
764
765;; Indicates if an FP operation has an integer source.
766
767(define_attr "fp_int_src" "false,true"
768  (const_string "false"))
769
770;; Defines rounding mode of an FP operation.
771
772(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
773  (const_string "any"))
774
775;; Define attribute to classify add/sub insns that consumes carry flag (CF)
776(define_attr "use_carry" "0,1" (const_string "0"))
777
778;; Define attribute to indicate unaligned ssemov insns
779(define_attr "movu" "0,1" (const_string "0"))
780
781;; Used to control the "enabled" attribute on a per-instruction basis.
782(define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
783		    sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
784		    avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
785		    fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
786		    avx512vl,noavx512vl"
787  (const_string "base"))
788
789(define_attr "enabled" ""
790  (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
791	 (eq_attr "isa" "x64_sse4")
792	   (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
793	 (eq_attr "isa" "x64_sse4_noavx")
794	   (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
795	 (eq_attr "isa" "x64_avx")
796	   (symbol_ref "TARGET_64BIT && TARGET_AVX")
797	 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
798	 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
799	 (eq_attr "isa" "sse2_noavx")
800	   (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
801	 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
802	 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
803	 (eq_attr "isa" "sse4_noavx")
804	   (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
805	 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
806	 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
807	 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
808	 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
809	 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
810	 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
811	 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
812	 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
813	 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
814	 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
815	 (eq_attr "isa" "fma_avx512f")
816	   (symbol_ref "TARGET_FMA || TARGET_AVX512F")
817	 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
818	 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
819	 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
820	 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
821	 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
822	 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
823	]
824	(const_int 1)))
825
826(define_attr "preferred_for_size" "" (const_int 1))
827(define_attr "preferred_for_speed" "" (const_int 1))
828
829;; Describe a user's asm statement.
830(define_asm_attributes
831  [(set_attr "length" "128")
832   (set_attr "type" "multi")])
833
834(define_code_iterator plusminus [plus minus])
835
836(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
837
838(define_code_iterator multdiv [mult div])
839
840;; Base name for define_insn
841(define_code_attr plusminus_insn
842  [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
843   (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
844
845;; Base name for insn mnemonic.
846(define_code_attr plusminus_mnemonic
847  [(plus "add") (ss_plus "adds") (us_plus "addus")
848   (minus "sub") (ss_minus "subs") (us_minus "subus")])
849(define_code_attr multdiv_mnemonic
850  [(mult "mul") (div "div")])
851
852;; Mark commutative operators as such in constraints.
853(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
854			(minus "") (ss_minus "") (us_minus "")])
855
856;; Mapping of max and min
857(define_code_iterator maxmin [smax smin umax umin])
858
859;; Mapping of signed max and min
860(define_code_iterator smaxmin [smax smin])
861
862;; Mapping of unsigned max and min
863(define_code_iterator umaxmin [umax umin])
864
865;; Base name for integer and FP insn mnemonic
866(define_code_attr maxmin_int [(smax "maxs") (smin "mins")
867			      (umax "maxu") (umin "minu")])
868(define_code_attr maxmin_float [(smax "max") (smin "min")])
869
870;; Mapping of logic operators
871(define_code_iterator any_logic [and ior xor])
872(define_code_iterator any_or [ior xor])
873(define_code_iterator fpint_logic [and xor])
874
875;; Base name for insn mnemonic.
876(define_code_attr logic [(and "and") (ior "or") (xor "xor")])
877
878;; Mapping of logic-shift operators
879(define_code_iterator any_lshift [ashift lshiftrt])
880
881;; Mapping of shift-right operators
882(define_code_iterator any_shiftrt [lshiftrt ashiftrt])
883
884;; Mapping of all shift operators
885(define_code_iterator any_shift [ashift lshiftrt ashiftrt])
886
887;; Base name for define_insn
888(define_code_attr shift_insn
889  [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
890
891;; Base name for insn mnemonic.
892(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
893(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
894
895;; Mapping of rotate operators
896(define_code_iterator any_rotate [rotate rotatert])
897
898;; Base name for define_insn
899(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
900
901;; Base name for insn mnemonic.
902(define_code_attr rotate [(rotate "rol") (rotatert "ror")])
903
904;; Mapping of abs neg operators
905(define_code_iterator absneg [abs neg])
906
907;; Base name for x87 insn mnemonic.
908(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
909
910;; Used in signed and unsigned widening multiplications.
911(define_code_iterator any_extend [sign_extend zero_extend])
912
913;; Prefix for insn menmonic.
914(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
915
916;; Prefix for define_insn
917(define_code_attr u [(sign_extend "") (zero_extend "u")])
918(define_code_attr s [(sign_extend "s") (zero_extend "u")])
919(define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
920
921;; Used in signed and unsigned truncations.
922(define_code_iterator any_truncate [ss_truncate truncate us_truncate])
923;; Instruction suffix for truncations.
924(define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
925
926;; Used in signed and unsigned fix.
927(define_code_iterator any_fix [fix unsigned_fix])
928(define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
929
930;; Used in signed and unsigned float.
931(define_code_iterator any_float [float unsigned_float])
932(define_code_attr floatsuffix [(float "") (unsigned_float "u")])
933
934;; All integer modes.
935(define_mode_iterator SWI1248x [QI HI SI DI])
936
937;; All integer modes with AVX512BW.
938(define_mode_iterator SWI1248_AVX512BW
939  [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
940
941;; All integer modes without QImode.
942(define_mode_iterator SWI248x [HI SI DI])
943
944;; All integer modes without QImode and HImode.
945(define_mode_iterator SWI48x [SI DI])
946
947;; All integer modes without SImode and DImode.
948(define_mode_iterator SWI12 [QI HI])
949
950;; All integer modes without DImode.
951(define_mode_iterator SWI124 [QI HI SI])
952
953;; All integer modes without QImode and DImode.
954(define_mode_iterator SWI24 [HI SI])
955
956;; Single word integer modes.
957(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
958
959;; Single word integer modes without QImode.
960(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
961
962;; Single word integer modes without QImode and HImode.
963(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
964
965;; All math-dependant single and double word integer modes.
966(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
967			     (HI "TARGET_HIMODE_MATH")
968			     SI DI (TI "TARGET_64BIT")])
969
970;; Math-dependant single word integer modes.
971(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
972			    (HI "TARGET_HIMODE_MATH")
973			    SI (DI "TARGET_64BIT")])
974
975;; Math-dependant integer modes without DImode.
976(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
977			       (HI "TARGET_HIMODE_MATH")
978			       SI])
979
980;; Math-dependant single word integer modes without QImode.
981(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
982		      	       SI (DI "TARGET_64BIT")])
983
984;; Double word integer modes.
985(define_mode_iterator DWI [(DI "!TARGET_64BIT")
986			   (TI "TARGET_64BIT")])
987
988;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
989;; compile time constant, it is faster to use <MODE_SIZE> than
990;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
991;; command line options just use GET_MODE_SIZE macro.
992(define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
993			     (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
994			     (V16QI "16") (V32QI "32") (V64QI "64")
995			     (V8HI "16") (V16HI "32") (V32HI "64")
996			     (V4SI "16") (V8SI "32") (V16SI "64")
997			     (V2DI "16") (V4DI "32") (V8DI "64")
998			     (V1TI "16") (V2TI "32") (V4TI "64")
999			     (V2DF "16") (V4DF "32") (V8DF "64")
1000			     (V4SF "16") (V8SF "32") (V16SF "64")])
1001
1002;; Double word integer modes as mode attribute.
1003(define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1004(define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1005
1006;; Half mode for double word integer modes.
1007(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1008			    (DI "TARGET_64BIT")])
1009
1010;; Bound modes.
1011(define_mode_iterator BND [(BND32 "!TARGET_LP64")
1012			   (BND64 "TARGET_LP64")])
1013
1014;; Pointer mode corresponding to bound mode.
1015(define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1016
1017;; MPX check types
1018(define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1019
1020;; Check name
1021(define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1022			   (UNSPEC_BNDCU "cu")
1023			   (UNSPEC_BNDCN "cn")])
1024
1025;; Instruction suffix for integer modes.
1026(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1027
1028;; Instruction suffix for masks.
1029(define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1030
1031;; Pointer size prefix for integer modes (Intel asm dialect)
1032(define_mode_attr iptrsize [(QI "BYTE")
1033			    (HI "WORD")
1034			    (SI "DWORD")
1035			    (DI "QWORD")])
1036
1037;; Register class for integer modes.
1038(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1039
1040;; Immediate operand constraint for integer modes.
1041(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1042
1043;; General operand constraint for word modes.
1044(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1045
1046;; Immediate operand constraint for double integer modes.
1047(define_mode_attr di [(SI "nF") (DI "e")])
1048
1049;; Immediate operand constraint for shifts.
1050(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1051
1052;; General operand predicate for integer modes.
1053(define_mode_attr general_operand
1054	[(QI "general_operand")
1055	 (HI "general_operand")
1056	 (SI "x86_64_general_operand")
1057	 (DI "x86_64_general_operand")
1058	 (TI "x86_64_general_operand")])
1059
1060;; General sign extend operand predicate for integer modes,
1061;; which disallows VOIDmode operands and thus it is suitable
1062;; for use inside sign_extend.
1063(define_mode_attr general_sext_operand
1064	[(QI "sext_operand")
1065	 (HI "sext_operand")
1066	 (SI "x86_64_sext_operand")
1067	 (DI "x86_64_sext_operand")])
1068
1069;; General sign/zero extend operand predicate for integer modes.
1070(define_mode_attr general_szext_operand
1071	[(QI "general_operand")
1072	 (HI "general_operand")
1073	 (SI "x86_64_szext_general_operand")
1074	 (DI "x86_64_szext_general_operand")])
1075
1076;; Immediate operand predicate for integer modes.
1077(define_mode_attr immediate_operand
1078	[(QI "immediate_operand")
1079	 (HI "immediate_operand")
1080	 (SI "x86_64_immediate_operand")
1081	 (DI "x86_64_immediate_operand")])
1082
1083;; Nonmemory operand predicate for integer modes.
1084(define_mode_attr nonmemory_operand
1085	[(QI "nonmemory_operand")
1086	 (HI "nonmemory_operand")
1087	 (SI "x86_64_nonmemory_operand")
1088	 (DI "x86_64_nonmemory_operand")])
1089
1090;; Operand predicate for shifts.
1091(define_mode_attr shift_operand
1092	[(QI "nonimmediate_operand")
1093	 (HI "nonimmediate_operand")
1094	 (SI "nonimmediate_operand")
1095	 (DI "shiftdi_operand")
1096	 (TI "register_operand")])
1097
1098;; Operand predicate for shift argument.
1099(define_mode_attr shift_immediate_operand
1100	[(QI "const_1_to_31_operand")
1101	 (HI "const_1_to_31_operand")
1102	 (SI "const_1_to_31_operand")
1103	 (DI "const_1_to_63_operand")])
1104
1105;; Input operand predicate for arithmetic left shifts.
1106(define_mode_attr ashl_input_operand
1107	[(QI "nonimmediate_operand")
1108	 (HI "nonimmediate_operand")
1109	 (SI "nonimmediate_operand")
1110	 (DI "ashldi_input_operand")
1111	 (TI "reg_or_pm1_operand")])
1112
1113;; SSE and x87 SFmode and DFmode floating point modes
1114(define_mode_iterator MODEF [SF DF])
1115
1116;; All x87 floating point modes
1117(define_mode_iterator X87MODEF [SF DF XF])
1118
1119;; SSE instruction suffix for various modes
1120(define_mode_attr ssemodesuffix
1121  [(SF "ss") (DF "sd")
1122   (V16SF "ps") (V8DF "pd")
1123   (V8SF "ps") (V4DF "pd")
1124   (V4SF "ps") (V2DF "pd")
1125   (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1126   (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1127   (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1128
1129;; SSE vector suffix for floating point modes
1130(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1131
1132;; SSE vector mode corresponding to a scalar mode
1133(define_mode_attr ssevecmode
1134  [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1135(define_mode_attr ssevecmodelower
1136  [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1137
1138;; Instruction suffix for REX 64bit operators.
1139(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1140
1141;; This mode iterator allows :P to be used for patterns that operate on
1142;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1143(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1144
1145;; This mode iterator allows :W to be used for patterns that operate on
1146;; word_mode sized quantities.
1147(define_mode_iterator W
1148  [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1149
1150;; This mode iterator allows :PTR to be used for patterns that operate on
1151;; ptr_mode sized quantities.
1152(define_mode_iterator PTR
1153  [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1154
1155;; Scheduling descriptions
1156
1157(include "pentium.md")
1158(include "ppro.md")
1159(include "k6.md")
1160(include "athlon.md")
1161(include "bdver1.md")
1162(include "bdver3.md")
1163(include "btver2.md")
1164(include "geode.md")
1165(include "atom.md")
1166(include "slm.md")
1167(include "core2.md")
1168
1169
1170;; Operand and operator predicates and constraints
1171
1172(include "predicates.md")
1173(include "constraints.md")
1174
1175
1176;; Compare and branch/compare and store instructions.
1177
1178(define_expand "cbranch<mode>4"
1179  [(set (reg:CC FLAGS_REG)
1180	(compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1181		    (match_operand:SDWIM 2 "<general_operand>")))
1182   (set (pc) (if_then_else
1183	       (match_operator 0 "ordered_comparison_operator"
1184		[(reg:CC FLAGS_REG) (const_int 0)])
1185	       (label_ref (match_operand 3))
1186	       (pc)))]
1187  ""
1188{
1189  if (MEM_P (operands[1]) && MEM_P (operands[2]))
1190    operands[1] = force_reg (<MODE>mode, operands[1]);
1191  ix86_expand_branch (GET_CODE (operands[0]),
1192		      operands[1], operands[2], operands[3]);
1193  DONE;
1194})
1195
1196(define_expand "cstore<mode>4"
1197  [(set (reg:CC FLAGS_REG)
1198	(compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1199		    (match_operand:SWIM 3 "<general_operand>")))
1200   (set (match_operand:QI 0 "register_operand")
1201	(match_operator 1 "ordered_comparison_operator"
1202	  [(reg:CC FLAGS_REG) (const_int 0)]))]
1203  ""
1204{
1205  if (MEM_P (operands[2]) && MEM_P (operands[3]))
1206    operands[2] = force_reg (<MODE>mode, operands[2]);
1207  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208		     operands[2], operands[3]);
1209  DONE;
1210})
1211
1212(define_expand "cmp<mode>_1"
1213  [(set (reg:CC FLAGS_REG)
1214	(compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1215		    (match_operand:SWI48 1 "<general_operand>")))])
1216
1217(define_insn "*cmp<mode>_ccno_1"
1218  [(set (reg FLAGS_REG)
1219	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1220		 (match_operand:SWI 1 "const0_operand")))]
1221  "ix86_match_ccmode (insn, CCNOmode)"
1222  "@
1223   test{<imodesuffix>}\t%0, %0
1224   cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1225  [(set_attr "type" "test,icmp")
1226   (set_attr "length_immediate" "0,1")
1227   (set_attr "mode" "<MODE>")])
1228
1229(define_insn "*cmp<mode>_1"
1230  [(set (reg FLAGS_REG)
1231	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1232		 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1233  "ix86_match_ccmode (insn, CCmode)"
1234  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1235  [(set_attr "type" "icmp")
1236   (set_attr "mode" "<MODE>")])
1237
1238(define_insn "*cmp<mode>_minus_1"
1239  [(set (reg FLAGS_REG)
1240	(compare
1241	  (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1242		     (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1243	  (const_int 0)))]
1244  "ix86_match_ccmode (insn, CCGOCmode)"
1245  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1246  [(set_attr "type" "icmp")
1247   (set_attr "mode" "<MODE>")])
1248
1249(define_insn "*cmpqi_ext_1"
1250  [(set (reg FLAGS_REG)
1251	(compare
1252	  (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1253	  (subreg:QI
1254	    (zero_extract:SI
1255	      (match_operand 1 "ext_register_operand" "Q,Q")
1256	      (const_int 8)
1257	      (const_int 8)) 0)))]
1258  "ix86_match_ccmode (insn, CCmode)"
1259  "cmp{b}\t{%h1, %0|%0, %h1}"
1260  [(set_attr "isa" "*,nox64")
1261   (set_attr "type" "icmp")
1262   (set_attr "mode" "QI")])
1263
1264(define_insn "*cmpqi_ext_2"
1265  [(set (reg FLAGS_REG)
1266	(compare
1267	  (subreg:QI
1268	    (zero_extract:SI
1269	      (match_operand 0 "ext_register_operand" "Q")
1270	      (const_int 8)
1271	      (const_int 8)) 0)
1272	  (match_operand:QI 1 "const0_operand")))]
1273  "ix86_match_ccmode (insn, CCNOmode)"
1274  "test{b}\t%h0, %h0"
1275  [(set_attr "type" "test")
1276   (set_attr "length_immediate" "0")
1277   (set_attr "mode" "QI")])
1278
1279(define_expand "cmpqi_ext_3"
1280  [(set (reg:CC FLAGS_REG)
1281	(compare:CC
1282	  (subreg:QI
1283	    (zero_extract:SI
1284	      (match_operand 0 "ext_register_operand")
1285	      (const_int 8)
1286	      (const_int 8)) 0)
1287	  (match_operand:QI 1 "const_int_operand")))])
1288
1289(define_insn "*cmpqi_ext_3"
1290  [(set (reg FLAGS_REG)
1291	(compare
1292	  (subreg:QI
1293	    (zero_extract:SI
1294	      (match_operand 0 "ext_register_operand" "Q,Q")
1295	      (const_int 8)
1296	      (const_int 8)) 0)
1297	  (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1298  "ix86_match_ccmode (insn, CCmode)"
1299  "cmp{b}\t{%1, %h0|%h0, %1}"
1300  [(set_attr "isa" "*,nox64")
1301   (set_attr "type" "icmp")
1302   (set_attr "modrm" "1")
1303   (set_attr "mode" "QI")])
1304
1305(define_insn "*cmpqi_ext_4"
1306  [(set (reg FLAGS_REG)
1307	(compare
1308	  (subreg:QI
1309	    (zero_extract:SI
1310	      (match_operand 0 "ext_register_operand" "Q")
1311	      (const_int 8)
1312	      (const_int 8)) 0)
1313	  (subreg:QI
1314	    (zero_extract:SI
1315	      (match_operand 1 "ext_register_operand" "Q")
1316	      (const_int 8)
1317	      (const_int 8)) 0)))]
1318  "ix86_match_ccmode (insn, CCmode)"
1319  "cmp{b}\t{%h1, %h0|%h0, %h1}"
1320  [(set_attr "type" "icmp")
1321   (set_attr "mode" "QI")])
1322
1323;; These implement float point compares.
1324;; %%% See if we can get away with VOIDmode operands on the actual insns,
1325;; which would allow mix and match FP modes on the compares.  Which is what
1326;; the old patterns did, but with many more of them.
1327
1328(define_expand "cbranchxf4"
1329  [(set (reg:CC FLAGS_REG)
1330	(compare:CC (match_operand:XF 1 "nonmemory_operand")
1331		    (match_operand:XF 2 "nonmemory_operand")))
1332   (set (pc) (if_then_else
1333              (match_operator 0 "ix86_fp_comparison_operator"
1334               [(reg:CC FLAGS_REG)
1335                (const_int 0)])
1336              (label_ref (match_operand 3))
1337              (pc)))]
1338  "TARGET_80387"
1339{
1340  ix86_expand_branch (GET_CODE (operands[0]),
1341		      operands[1], operands[2], operands[3]);
1342  DONE;
1343})
1344
1345(define_expand "cstorexf4"
1346  [(set (reg:CC FLAGS_REG)
1347	(compare:CC (match_operand:XF 2 "nonmemory_operand")
1348		    (match_operand:XF 3 "nonmemory_operand")))
1349   (set (match_operand:QI 0 "register_operand")
1350              (match_operator 1 "ix86_fp_comparison_operator"
1351               [(reg:CC FLAGS_REG)
1352                (const_int 0)]))]
1353  "TARGET_80387"
1354{
1355  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1356		     operands[2], operands[3]);
1357  DONE;
1358})
1359
1360(define_expand "cbranch<mode>4"
1361  [(set (reg:CC FLAGS_REG)
1362	(compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1363		    (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1364   (set (pc) (if_then_else
1365              (match_operator 0 "ix86_fp_comparison_operator"
1366               [(reg:CC FLAGS_REG)
1367                (const_int 0)])
1368              (label_ref (match_operand 3))
1369              (pc)))]
1370  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1371{
1372  ix86_expand_branch (GET_CODE (operands[0]),
1373		      operands[1], operands[2], operands[3]);
1374  DONE;
1375})
1376
1377(define_expand "cstore<mode>4"
1378  [(set (reg:CC FLAGS_REG)
1379	(compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1380		    (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1381   (set (match_operand:QI 0 "register_operand")
1382              (match_operator 1 "ix86_fp_comparison_operator"
1383               [(reg:CC FLAGS_REG)
1384                (const_int 0)]))]
1385  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1386{
1387  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1388		     operands[2], operands[3]);
1389  DONE;
1390})
1391
1392(define_expand "cbranchcc4"
1393  [(set (pc) (if_then_else
1394              (match_operator 0 "comparison_operator"
1395               [(match_operand 1 "flags_reg_operand")
1396                (match_operand 2 "const0_operand")])
1397              (label_ref (match_operand 3))
1398              (pc)))]
1399  ""
1400{
1401  ix86_expand_branch (GET_CODE (operands[0]),
1402		      operands[1], operands[2], operands[3]);
1403  DONE;
1404})
1405
1406(define_expand "cstorecc4"
1407  [(set (match_operand:QI 0 "register_operand")
1408              (match_operator 1 "comparison_operator"
1409               [(match_operand 2 "flags_reg_operand")
1410                (match_operand 3 "const0_operand")]))]
1411  ""
1412{
1413  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1414		     operands[2], operands[3]);
1415  DONE;
1416})
1417
1418
1419;; FP compares, step 1:
1420;; Set the FP condition codes.
1421;;
1422;; CCFPmode	compare with exceptions
1423;; CCFPUmode	compare with no exceptions
1424
1425;; We may not use "#" to split and emit these, since the REG_DEAD notes
1426;; used to manage the reg stack popping would not be preserved.
1427
1428(define_insn "*cmp<mode>_0_i387"
1429  [(set (match_operand:HI 0 "register_operand" "=a")
1430	(unspec:HI
1431	  [(compare:CCFP
1432	     (match_operand:X87MODEF 1 "register_operand" "f")
1433	     (match_operand:X87MODEF 2 "const0_operand"))]
1434	UNSPEC_FNSTSW))]
1435  "TARGET_80387"
1436  "* return output_fp_compare (insn, operands, false, false);"
1437  [(set_attr "type" "multi")
1438   (set_attr "unit" "i387")
1439   (set_attr "mode" "<MODE>")])
1440
1441(define_insn_and_split "*cmp<mode>_0_cc_i387"
1442  [(set (reg:CCFP FLAGS_REG)
1443	(compare:CCFP
1444	  (match_operand:X87MODEF 1 "register_operand" "f")
1445	  (match_operand:X87MODEF 2 "const0_operand")))
1446   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1447  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1448  "#"
1449  "&& reload_completed"
1450  [(set (match_dup 0)
1451	(unspec:HI
1452	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1453	UNSPEC_FNSTSW))
1454   (set (reg:CC FLAGS_REG)
1455	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1456  ""
1457  [(set_attr "type" "multi")
1458   (set_attr "unit" "i387")
1459   (set_attr "mode" "<MODE>")])
1460
1461(define_insn "*cmpxf_i387"
1462  [(set (match_operand:HI 0 "register_operand" "=a")
1463	(unspec:HI
1464	  [(compare:CCFP
1465	     (match_operand:XF 1 "register_operand" "f")
1466	     (match_operand:XF 2 "register_operand" "f"))]
1467	  UNSPEC_FNSTSW))]
1468  "TARGET_80387"
1469  "* return output_fp_compare (insn, operands, false, false);"
1470  [(set_attr "type" "multi")
1471   (set_attr "unit" "i387")
1472   (set_attr "mode" "XF")])
1473
1474(define_insn_and_split "*cmpxf_cc_i387"
1475  [(set (reg:CCFP FLAGS_REG)
1476	(compare:CCFP
1477	  (match_operand:XF 1 "register_operand" "f")
1478	  (match_operand:XF 2 "register_operand" "f")))
1479   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1480  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1481  "#"
1482  "&& reload_completed"
1483  [(set (match_dup 0)
1484	(unspec:HI
1485	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1486	UNSPEC_FNSTSW))
1487   (set (reg:CC FLAGS_REG)
1488	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1489  ""
1490  [(set_attr "type" "multi")
1491   (set_attr "unit" "i387")
1492   (set_attr "mode" "XF")])
1493
1494(define_insn "*cmp<mode>_i387"
1495  [(set (match_operand:HI 0 "register_operand" "=a")
1496	(unspec:HI
1497	  [(compare:CCFP
1498	     (match_operand:MODEF 1 "register_operand" "f")
1499	     (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1500	  UNSPEC_FNSTSW))]
1501  "TARGET_80387"
1502  "* return output_fp_compare (insn, operands, false, false);"
1503  [(set_attr "type" "multi")
1504   (set_attr "unit" "i387")
1505   (set_attr "mode" "<MODE>")])
1506
1507(define_insn_and_split "*cmp<mode>_cc_i387"
1508  [(set (reg:CCFP FLAGS_REG)
1509	(compare:CCFP
1510	  (match_operand:MODEF 1 "register_operand" "f")
1511	  (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1512   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1513  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1514  "#"
1515  "&& reload_completed"
1516  [(set (match_dup 0)
1517	(unspec:HI
1518	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1519	UNSPEC_FNSTSW))
1520   (set (reg:CC FLAGS_REG)
1521	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1522  ""
1523  [(set_attr "type" "multi")
1524   (set_attr "unit" "i387")
1525   (set_attr "mode" "<MODE>")])
1526
1527(define_insn "*cmpu<mode>_i387"
1528  [(set (match_operand:HI 0 "register_operand" "=a")
1529	(unspec:HI
1530	  [(compare:CCFPU
1531	     (match_operand:X87MODEF 1 "register_operand" "f")
1532	     (match_operand:X87MODEF 2 "register_operand" "f"))]
1533	  UNSPEC_FNSTSW))]
1534  "TARGET_80387"
1535  "* return output_fp_compare (insn, operands, false, true);"
1536  [(set_attr "type" "multi")
1537   (set_attr "unit" "i387")
1538   (set_attr "mode" "<MODE>")])
1539
1540(define_insn_and_split "*cmpu<mode>_cc_i387"
1541  [(set (reg:CCFPU FLAGS_REG)
1542	(compare:CCFPU
1543	  (match_operand:X87MODEF 1 "register_operand" "f")
1544	  (match_operand:X87MODEF 2 "register_operand" "f")))
1545   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1546  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1547  "#"
1548  "&& reload_completed"
1549  [(set (match_dup 0)
1550	(unspec:HI
1551	  [(compare:CCFPU (match_dup 1)(match_dup 2))]
1552	UNSPEC_FNSTSW))
1553   (set (reg:CC FLAGS_REG)
1554	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1555  ""
1556  [(set_attr "type" "multi")
1557   (set_attr "unit" "i387")
1558   (set_attr "mode" "<MODE>")])
1559
1560(define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1561  [(set (match_operand:HI 0 "register_operand" "=a")
1562	(unspec:HI
1563	  [(compare:CCFP
1564	     (match_operand:X87MODEF 1 "register_operand" "f")
1565	     (match_operator:X87MODEF 3 "float_operator"
1566	       [(match_operand:SWI24 2 "memory_operand" "m")]))]
1567	  UNSPEC_FNSTSW))]
1568  "TARGET_80387
1569   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1570       || optimize_function_for_size_p (cfun))"
1571  "* return output_fp_compare (insn, operands, false, false);"
1572  [(set_attr "type" "multi")
1573   (set_attr "unit" "i387")
1574   (set_attr "fp_int_src" "true")
1575   (set_attr "mode" "<SWI24:MODE>")])
1576
1577(define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1578  [(set (reg:CCFP FLAGS_REG)
1579	(compare:CCFP
1580	  (match_operand:X87MODEF 1 "register_operand" "f")
1581	  (match_operator:X87MODEF 3 "float_operator"
1582	    [(match_operand:SWI24 2 "memory_operand" "m")])))
1583   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1584  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1585   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1586       || optimize_function_for_size_p (cfun))"
1587  "#"
1588  "&& reload_completed"
1589  [(set (match_dup 0)
1590	(unspec:HI
1591	  [(compare:CCFP
1592	     (match_dup 1)
1593	     (match_op_dup 3 [(match_dup 2)]))]
1594	UNSPEC_FNSTSW))
1595   (set (reg:CC FLAGS_REG)
1596	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1597  ""
1598  [(set_attr "type" "multi")
1599   (set_attr "unit" "i387")
1600   (set_attr "fp_int_src" "true")
1601   (set_attr "mode" "<SWI24:MODE>")])
1602
1603;; FP compares, step 2
1604;; Move the fpsw to ax.
1605
1606(define_insn "x86_fnstsw_1"
1607  [(set (match_operand:HI 0 "register_operand" "=a")
1608	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1609  "TARGET_80387"
1610  "fnstsw\t%0"
1611  [(set_attr "length" "2")
1612   (set_attr "mode" "SI")
1613   (set_attr "unit" "i387")])
1614
1615;; FP compares, step 3
1616;; Get ax into flags, general case.
1617
1618(define_insn "x86_sahf_1"
1619  [(set (reg:CC FLAGS_REG)
1620	(unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1621		   UNSPEC_SAHF))]
1622  "TARGET_SAHF"
1623{
1624#ifndef HAVE_AS_IX86_SAHF
1625  if (TARGET_64BIT)
1626    return ASM_BYTE "0x9e";
1627  else
1628#endif
1629  return "sahf";
1630}
1631  [(set_attr "length" "1")
1632   (set_attr "athlon_decode" "vector")
1633   (set_attr "amdfam10_decode" "direct")
1634   (set_attr "bdver1_decode" "direct")
1635   (set_attr "mode" "SI")])
1636
1637;; Pentium Pro can do steps 1 through 3 in one go.
1638;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1639;; (these i387 instructions set flags directly)
1640
1641(define_mode_iterator FPCMP [CCFP CCFPU])
1642(define_mode_attr unord [(CCFP "") (CCFPU "u")])
1643
1644(define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1645  [(set (reg:FPCMP FLAGS_REG)
1646	(compare:FPCMP
1647	  (match_operand:MODEF 0 "register_operand" "f,x")
1648	  (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1649  "TARGET_MIX_SSE_I387
1650   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1651  "* return output_fp_compare (insn, operands, true,
1652			       <FPCMP:MODE>mode == CCFPUmode);"
1653  [(set_attr "type" "fcmp,ssecomi")
1654   (set_attr "prefix" "orig,maybe_vex")
1655   (set_attr "mode" "<MODEF:MODE>")
1656   (set (attr "prefix_rep")
1657	(if_then_else (eq_attr "type" "ssecomi")
1658		      (const_string "0")
1659		      (const_string "*")))
1660   (set (attr "prefix_data16")
1661	(cond [(eq_attr "type" "fcmp")
1662		 (const_string "*")
1663	       (eq_attr "mode" "DF")
1664		 (const_string "1")
1665	      ]
1666	      (const_string "0")))
1667   (set_attr "athlon_decode" "vector")
1668   (set_attr "amdfam10_decode" "direct")
1669   (set_attr "bdver1_decode" "double")])
1670
1671(define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1672  [(set (reg:FPCMP FLAGS_REG)
1673	(compare:FPCMP
1674	  (match_operand:MODEF 0 "register_operand" "x")
1675	  (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1676  "TARGET_SSE_MATH
1677   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1678  "* return output_fp_compare (insn, operands, true,
1679			       <FPCMP:MODE>mode == CCFPUmode);"
1680  [(set_attr "type" "ssecomi")
1681   (set_attr "prefix" "maybe_vex")
1682   (set_attr "mode" "<MODEF:MODE>")
1683   (set_attr "prefix_rep" "0")
1684   (set (attr "prefix_data16")
1685	(if_then_else (eq_attr "mode" "DF")
1686		      (const_string "1")
1687		      (const_string "0")))
1688   (set_attr "athlon_decode" "vector")
1689   (set_attr "amdfam10_decode" "direct")
1690   (set_attr "bdver1_decode" "double")])
1691
1692(define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1693  [(set (reg:FPCMP FLAGS_REG)
1694	(compare:FPCMP
1695	  (match_operand:X87MODEF 0 "register_operand" "f")
1696	  (match_operand:X87MODEF 1 "register_operand" "f")))]
1697  "TARGET_80387 && TARGET_CMOVE
1698   && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1699  "* return output_fp_compare (insn, operands, true,
1700			       <FPCMP:MODE>mode == CCFPUmode);"
1701  [(set_attr "type" "fcmp")
1702   (set_attr "mode" "<X87MODEF:MODE>")
1703   (set_attr "athlon_decode" "vector")
1704   (set_attr "amdfam10_decode" "direct")
1705   (set_attr "bdver1_decode" "double")])
1706
1707;; Push/pop instructions.
1708
1709(define_insn "*push<mode>2"
1710  [(set (match_operand:DWI 0 "push_operand" "=<")
1711	(match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1712  ""
1713  "#"
1714  [(set_attr "type" "multi")
1715   (set_attr "mode" "<MODE>")])
1716
1717(define_split
1718  [(set (match_operand:TI 0 "push_operand")
1719        (match_operand:TI 1 "general_operand"))]
1720  "TARGET_64BIT && reload_completed
1721   && !SSE_REG_P (operands[1])"
1722  [(const_int 0)]
1723  "ix86_split_long_move (operands); DONE;")
1724
1725(define_insn "*pushdi2_rex64"
1726  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1727	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1728  "TARGET_64BIT"
1729  "@
1730   push{q}\t%1
1731   #"
1732  [(set_attr "type" "push,multi")
1733   (set_attr "mode" "DI")])
1734
1735;; Convert impossible pushes of immediate to existing instructions.
1736;; First try to get scratch register and go through it.  In case this
1737;; fails, push sign extended lower part first and then overwrite
1738;; upper part by 32bit move.
1739(define_peephole2
1740  [(match_scratch:DI 2 "r")
1741   (set (match_operand:DI 0 "push_operand")
1742        (match_operand:DI 1 "immediate_operand"))]
1743  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1744   && !x86_64_immediate_operand (operands[1], DImode)"
1745  [(set (match_dup 2) (match_dup 1))
1746   (set (match_dup 0) (match_dup 2))])
1747
1748;; We need to define this as both peepholer and splitter for case
1749;; peephole2 pass is not run.
1750;; "&& 1" is needed to keep it from matching the previous pattern.
1751(define_peephole2
1752  [(set (match_operand:DI 0 "push_operand")
1753        (match_operand:DI 1 "immediate_operand"))]
1754  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1755   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1756  [(set (match_dup 0) (match_dup 1))
1757   (set (match_dup 2) (match_dup 3))]
1758{
1759  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1760
1761  operands[1] = gen_lowpart (DImode, operands[2]);
1762  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1763						   GEN_INT (4)));
1764})
1765
1766(define_split
1767  [(set (match_operand:DI 0 "push_operand")
1768        (match_operand:DI 1 "immediate_operand"))]
1769  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1770		    ? epilogue_completed : reload_completed)
1771   && !symbolic_operand (operands[1], DImode)
1772   && !x86_64_immediate_operand (operands[1], DImode)"
1773  [(set (match_dup 0) (match_dup 1))
1774   (set (match_dup 2) (match_dup 3))]
1775{
1776  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1777
1778  operands[1] = gen_lowpart (DImode, operands[2]);
1779  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1780						   GEN_INT (4)));
1781})
1782
1783(define_split
1784  [(set (match_operand:DI 0 "push_operand")
1785        (match_operand:DI 1 "general_operand"))]
1786  "!TARGET_64BIT && reload_completed
1787   && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1788  [(const_int 0)]
1789  "ix86_split_long_move (operands); DONE;")
1790
1791(define_insn "*pushsi2"
1792  [(set (match_operand:SI 0 "push_operand" "=<")
1793	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1794  "!TARGET_64BIT"
1795  "push{l}\t%1"
1796  [(set_attr "type" "push")
1797   (set_attr "mode" "SI")])
1798
1799;; emit_push_insn when it calls move_by_pieces requires an insn to
1800;; "push a byte/word".  But actually we use pushl, which has the effect
1801;; of rounding the amount pushed up to a word.
1802
1803;; For TARGET_64BIT we always round up to 8 bytes.
1804(define_insn "*push<mode>2_rex64"
1805  [(set (match_operand:SWI124 0 "push_operand" "=X")
1806	(match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1807  "TARGET_64BIT"
1808  "push{q}\t%q1"
1809  [(set_attr "type" "push")
1810   (set_attr "mode" "DI")])
1811
1812(define_insn "*push<mode>2"
1813  [(set (match_operand:SWI12 0 "push_operand" "=X")
1814	(match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1815  "!TARGET_64BIT"
1816  "push{l}\t%k1"
1817  [(set_attr "type" "push")
1818   (set_attr "mode" "SI")])
1819
1820(define_insn "*push<mode>2_prologue"
1821  [(set (match_operand:W 0 "push_operand" "=<")
1822	(match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1823   (clobber (mem:BLK (scratch)))]
1824  ""
1825  "push{<imodesuffix>}\t%1"
1826  [(set_attr "type" "push")
1827   (set_attr "mode" "<MODE>")])
1828
1829(define_insn "*pop<mode>1"
1830  [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1831	(match_operand:W 1 "pop_operand" ">"))]
1832  ""
1833  "pop{<imodesuffix>}\t%0"
1834  [(set_attr "type" "pop")
1835   (set_attr "mode" "<MODE>")])
1836
1837(define_insn "*pop<mode>1_epilogue"
1838  [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1839	(match_operand:W 1 "pop_operand" ">"))
1840   (clobber (mem:BLK (scratch)))]
1841  ""
1842  "pop{<imodesuffix>}\t%0"
1843  [(set_attr "type" "pop")
1844   (set_attr "mode" "<MODE>")])
1845
1846(define_insn "*pushfl<mode>2"
1847  [(set (match_operand:W 0 "push_operand" "=<")
1848	(match_operand:W 1 "flags_reg_operand"))]
1849  ""
1850  "pushf{<imodesuffix>}"
1851  [(set_attr "type" "push")
1852   (set_attr "mode" "<MODE>")])
1853
1854(define_insn "*popfl<mode>1"
1855  [(set (match_operand:W 0 "flags_reg_operand")
1856	(match_operand:W 1 "pop_operand" ">"))]
1857  ""
1858  "popf{<imodesuffix>}"
1859  [(set_attr "type" "pop")
1860   (set_attr "mode" "<MODE>")])
1861
1862
1863;; Move instructions.
1864
1865(define_expand "movxi"
1866  [(set (match_operand:XI 0 "nonimmediate_operand")
1867	(match_operand:XI 1 "general_operand"))]
1868  "TARGET_AVX512F"
1869  "ix86_expand_vector_move (XImode, operands); DONE;")
1870
1871;; Reload patterns to support multi-word load/store
1872;; with non-offsetable address.
1873(define_expand "reload_noff_store"
1874  [(parallel [(match_operand 0 "memory_operand" "=m")
1875              (match_operand 1 "register_operand" "r")
1876              (match_operand:DI 2 "register_operand" "=&r")])]
1877  "TARGET_64BIT"
1878{
1879  rtx mem = operands[0];
1880  rtx addr = XEXP (mem, 0);
1881
1882  emit_move_insn (operands[2], addr);
1883  mem = replace_equiv_address_nv (mem, operands[2]);
1884
1885  emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1886  DONE;
1887})
1888
1889(define_expand "reload_noff_load"
1890  [(parallel [(match_operand 0 "register_operand" "=r")
1891              (match_operand 1 "memory_operand" "m")
1892              (match_operand:DI 2 "register_operand" "=r")])]
1893  "TARGET_64BIT"
1894{
1895  rtx mem = operands[1];
1896  rtx addr = XEXP (mem, 0);
1897
1898  emit_move_insn (operands[2], addr);
1899  mem = replace_equiv_address_nv (mem, operands[2]);
1900
1901  emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1902  DONE;
1903})
1904
1905(define_expand "movoi"
1906  [(set (match_operand:OI 0 "nonimmediate_operand")
1907	(match_operand:OI 1 "general_operand"))]
1908  "TARGET_AVX"
1909  "ix86_expand_vector_move (OImode, operands); DONE;")
1910
1911(define_expand "movti"
1912  [(set (match_operand:TI 0 "nonimmediate_operand")
1913	(match_operand:TI 1 "general_operand"))]
1914  "TARGET_64BIT || TARGET_SSE"
1915{
1916  if (TARGET_64BIT)
1917    ix86_expand_move (TImode, operands);
1918  else
1919    ix86_expand_vector_move (TImode, operands);
1920  DONE;
1921})
1922
1923;; This expands to what emit_move_complex would generate if we didn't
1924;; have a movti pattern.  Having this avoids problems with reload on
1925;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1926;; to have around all the time.
1927(define_expand "movcdi"
1928  [(set (match_operand:CDI 0 "nonimmediate_operand")
1929	(match_operand:CDI 1 "general_operand"))]
1930  ""
1931{
1932  if (push_operand (operands[0], CDImode))
1933    emit_move_complex_push (CDImode, operands[0], operands[1]);
1934  else
1935    emit_move_complex_parts (operands[0], operands[1]);
1936  DONE;
1937})
1938
1939(define_expand "mov<mode>"
1940  [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1941	(match_operand:SWI1248x 1 "general_operand"))]
1942  ""
1943  "ix86_expand_move (<MODE>mode, operands); DONE;")
1944
1945(define_insn "*mov<mode>_xor"
1946  [(set (match_operand:SWI48 0 "register_operand" "=r")
1947	(match_operand:SWI48 1 "const0_operand"))
1948   (clobber (reg:CC FLAGS_REG))]
1949  "reload_completed"
1950  "xor{l}\t%k0, %k0"
1951  [(set_attr "type" "alu1")
1952   (set_attr "mode" "SI")
1953   (set_attr "length_immediate" "0")])
1954
1955(define_insn "*mov<mode>_or"
1956  [(set (match_operand:SWI48 0 "register_operand" "=r")
1957	(match_operand:SWI48 1 "const_int_operand"))
1958   (clobber (reg:CC FLAGS_REG))]
1959  "reload_completed
1960   && operands[1] == constm1_rtx"
1961  "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1962  [(set_attr "type" "alu1")
1963   (set_attr "mode" "<MODE>")
1964   (set_attr "length_immediate" "1")])
1965
1966(define_insn "*movxi_internal_avx512f"
1967  [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1968	(match_operand:XI 1 "vector_move_operand"  "C ,xm,x"))]
1969  "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1970{
1971  switch (which_alternative)
1972    {
1973    case 0:
1974      return standard_sse_constant_opcode (insn, operands[1]);
1975    case 1:
1976    case 2:
1977      if (misaligned_operand (operands[0], XImode)
1978	  || misaligned_operand (operands[1], XImode))
1979	return "vmovdqu32\t{%1, %0|%0, %1}";
1980      else
1981	return "vmovdqa32\t{%1, %0|%0, %1}";
1982    default:
1983      gcc_unreachable ();
1984    }
1985}
1986  [(set_attr "type" "sselog1,ssemov,ssemov")
1987   (set_attr "prefix" "evex")
1988   (set_attr "mode" "XI")])
1989
1990(define_insn "*movoi_internal_avx"
1991  [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1992	(match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
1993  "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1994{
1995  switch (get_attr_type (insn))
1996    {
1997    case TYPE_SSELOG1:
1998      return standard_sse_constant_opcode (insn, operands[1]);
1999
2000    case TYPE_SSEMOV:
2001      if (misaligned_operand (operands[0], OImode)
2002	  || misaligned_operand (operands[1], OImode))
2003	{
2004	  if (get_attr_mode (insn) == MODE_V8SF)
2005	    return "vmovups\t{%1, %0|%0, %1}";
2006	  else if (get_attr_mode (insn) == MODE_XI)
2007	    return "vmovdqu32\t{%1, %0|%0, %1}";
2008	  else
2009	    return "vmovdqu\t{%1, %0|%0, %1}";
2010	}
2011      else
2012	{
2013	  if (get_attr_mode (insn) == MODE_V8SF)
2014	    return "vmovaps\t{%1, %0|%0, %1}";
2015	  else if (get_attr_mode (insn) == MODE_XI)
2016	    return "vmovdqa32\t{%1, %0|%0, %1}";
2017	  else
2018	    return "vmovdqa\t{%1, %0|%0, %1}";
2019	}
2020
2021    default:
2022      gcc_unreachable ();
2023    }
2024}
2025  [(set_attr "type" "sselog1,ssemov,ssemov")
2026   (set_attr "prefix" "vex")
2027   (set (attr "mode")
2028	(cond [(ior (match_operand 0 "ext_sse_reg_operand")
2029		    (match_operand 1 "ext_sse_reg_operand"))
2030		 (const_string "XI")
2031	       (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2032		 (const_string "V8SF")
2033	       (and (eq_attr "alternative" "2")
2034		    (match_test "TARGET_SSE_TYPELESS_STORES"))
2035		 (const_string "V8SF")
2036	      ]
2037	      (const_string "OI")))])
2038
2039(define_insn "*movti_internal"
2040  [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2041	(match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
2042  "(TARGET_64BIT || TARGET_SSE)
2043   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2044{
2045  switch (get_attr_type (insn))
2046    {
2047    case TYPE_MULTI:
2048      return "#";
2049
2050    case TYPE_SSELOG1:
2051      return standard_sse_constant_opcode (insn, operands[1]);
2052
2053    case TYPE_SSEMOV:
2054      /* TDmode values are passed as TImode on the stack.  Moving them
2055	 to stack may result in unaligned memory access.  */
2056      if (misaligned_operand (operands[0], TImode)
2057	  || misaligned_operand (operands[1], TImode))
2058	{
2059	  if (get_attr_mode (insn) == MODE_V4SF)
2060	    return "%vmovups\t{%1, %0|%0, %1}";
2061	  else if (get_attr_mode (insn) == MODE_XI)
2062	    return "vmovdqu32\t{%1, %0|%0, %1}";
2063	  else
2064	    return "%vmovdqu\t{%1, %0|%0, %1}";
2065	}
2066      else
2067	{
2068	  if (get_attr_mode (insn) == MODE_V4SF)
2069	    return "%vmovaps\t{%1, %0|%0, %1}";
2070	  else if (get_attr_mode (insn) == MODE_XI)
2071	    return "vmovdqa32\t{%1, %0|%0, %1}";
2072	  else
2073	    return "%vmovdqa\t{%1, %0|%0, %1}";
2074	}
2075
2076    default:
2077      gcc_unreachable ();
2078    }
2079}
2080  [(set_attr "isa" "x64,x64,*,*,*")
2081   (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2082   (set (attr "prefix")
2083     (if_then_else (eq_attr "type" "sselog1,ssemov")
2084       (const_string "maybe_vex")
2085       (const_string "orig")))
2086   (set (attr "mode")
2087	(cond [(ior (match_operand 0 "ext_sse_reg_operand")
2088		    (match_operand 1 "ext_sse_reg_operand"))
2089		 (const_string "XI")
2090	       (eq_attr "alternative" "0,1")
2091		 (const_string "DI")
2092	       (ior (not (match_test "TARGET_SSE2"))
2093		    (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2094		 (const_string "V4SF")
2095	       (and (eq_attr "alternative" "4")
2096		    (match_test "TARGET_SSE_TYPELESS_STORES"))
2097		 (const_string "V4SF")
2098	       (match_test "TARGET_AVX")
2099		 (const_string "TI")
2100	       (match_test "optimize_function_for_size_p (cfun)")
2101		 (const_string "V4SF")
2102	       ]
2103	       (const_string "TI")))])
2104
2105(define_split
2106  [(set (match_operand:TI 0 "nonimmediate_operand")
2107	(match_operand:TI 1 "general_operand"))]
2108  "reload_completed
2109   && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2110  [(const_int 0)]
2111  "ix86_split_long_move (operands); DONE;")
2112
2113(define_insn "*movdi_internal"
2114  [(set (match_operand:DI 0 "nonimmediate_operand"
2115    "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2116	(match_operand:DI 1 "general_operand"
2117    "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,*v,r   ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2118  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2119{
2120  switch (get_attr_type (insn))
2121    {
2122    case TYPE_MSKMOV:
2123      return "kmovq\t{%1, %0|%0, %1}";
2124
2125    case TYPE_MULTI:
2126      return "#";
2127
2128    case TYPE_MMX:
2129      return "pxor\t%0, %0";
2130
2131    case TYPE_MMXMOV:
2132      /* Handle broken assemblers that require movd instead of movq.  */
2133      if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2134	  && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2135	return "movd\t{%1, %0|%0, %1}";
2136      return "movq\t{%1, %0|%0, %1}";
2137
2138    case TYPE_SSELOG1:
2139      if (GENERAL_REG_P (operands[0]))
2140	return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2141
2142      return standard_sse_constant_opcode (insn, operands[1]);
2143
2144    case TYPE_SSEMOV:
2145      switch (get_attr_mode (insn))
2146	{
2147	case MODE_DI:
2148	  /* Handle broken assemblers that require movd instead of movq.  */
2149	  if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2150	      && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2151	    return "%vmovd\t{%1, %0|%0, %1}";
2152	  return "%vmovq\t{%1, %0|%0, %1}";
2153	case MODE_TI:
2154	  return "%vmovdqa\t{%1, %0|%0, %1}";
2155	case MODE_XI:
2156	  return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2157
2158	case MODE_V2SF:
2159	  gcc_assert (!TARGET_AVX);
2160	  return "movlps\t{%1, %0|%0, %1}";
2161	case MODE_V4SF:
2162	  return "%vmovaps\t{%1, %0|%0, %1}";
2163
2164	default:
2165	  gcc_unreachable ();
2166	}
2167
2168    case TYPE_SSECVT:
2169      if (SSE_REG_P (operands[0]))
2170	return "movq2dq\t{%1, %0|%0, %1}";
2171      else
2172	return "movdq2q\t{%1, %0|%0, %1}";
2173
2174    case TYPE_LEA:
2175      return "lea{q}\t{%E1, %0|%0, %E1}";
2176
2177    case TYPE_IMOV:
2178      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2179      if (get_attr_mode (insn) == MODE_SI)
2180	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2181      else if (which_alternative == 4)
2182	return "movabs{q}\t{%1, %0|%0, %1}";
2183      else if (ix86_use_lea_for_mov (insn, operands))
2184	return "lea{q}\t{%E1, %0|%0, %E1}";
2185      else
2186	return "mov{q}\t{%1, %0|%0, %1}";
2187
2188    default:
2189      gcc_unreachable ();
2190    }
2191}
2192  [(set (attr "isa")
2193     (cond [(eq_attr "alternative" "0,1")
2194	      (const_string "nox64")
2195	    (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2196	      (const_string "x64")
2197	    (eq_attr "alternative" "17")
2198	      (const_string "x64_sse4")
2199	   ]
2200	   (const_string "*")))
2201   (set (attr "type")
2202     (cond [(eq_attr "alternative" "0,1")
2203	      (const_string "multi")
2204	    (eq_attr "alternative" "6")
2205	      (const_string "mmx")
2206	    (eq_attr "alternative" "7,8,9,10,11")
2207	      (const_string "mmxmov")
2208	    (eq_attr "alternative" "12,17")
2209	      (const_string "sselog1")
2210	    (eq_attr "alternative" "13,14,15,16,18")
2211	      (const_string "ssemov")
2212	    (eq_attr "alternative" "19,20")
2213	      (const_string "ssecvt")
2214	    (eq_attr "alternative" "21,22,23,24")
2215	      (const_string "mskmov")
2216	    (and (match_operand 0 "register_operand")
2217		 (match_operand 1 "pic_32bit_operand"))
2218	      (const_string "lea")
2219	   ]
2220	   (const_string "imov")))
2221   (set (attr "modrm")
2222     (if_then_else
2223       (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2224	 (const_string "0")
2225	 (const_string "*")))
2226   (set (attr "length_immediate")
2227     (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2228	      (const_string "8")
2229	    (eq_attr "alternative" "17")
2230	      (const_string "1")
2231	   ]
2232	   (const_string "*")))
2233   (set (attr "prefix_rex")
2234     (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2235       (const_string "1")
2236       (const_string "*")))
2237   (set (attr "prefix_extra")
2238     (if_then_else (eq_attr "alternative" "17")
2239       (const_string "1")
2240       (const_string "*")))
2241   (set (attr "prefix")
2242     (if_then_else (eq_attr "type" "sselog1,ssemov")
2243       (const_string "maybe_vex")
2244       (const_string "orig")))
2245   (set (attr "prefix_data16")
2246     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2247       (const_string "1")
2248       (const_string "*")))
2249   (set (attr "mode")
2250     (cond [(eq_attr "alternative" "2")
2251	      (const_string "SI")
2252	    (eq_attr "alternative" "12,13")
2253	      (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2254			  (match_operand 1 "ext_sse_reg_operand"))
2255		       (const_string "XI")
2256		     (ior (not (match_test "TARGET_SSE2"))
2257			  (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2258		       (const_string "V4SF")
2259		     (match_test "TARGET_AVX")
2260		       (const_string "TI")
2261		     (match_test "optimize_function_for_size_p (cfun)")
2262		       (const_string "V4SF")
2263		    ]
2264		    (const_string "TI"))
2265
2266	    (and (eq_attr "alternative" "14,15")
2267		 (not (match_test "TARGET_SSE2")))
2268	      (const_string "V2SF")
2269	    (eq_attr "alternative" "17")
2270	      (const_string "TI")
2271	   ]
2272	   (const_string "DI")))])
2273
2274(define_split
2275  [(set (match_operand:DI 0 "nonimmediate_operand")
2276        (match_operand:DI 1 "general_operand"))]
2277  "!TARGET_64BIT && reload_completed
2278   && !(MMX_REG_P (operands[0])
2279	|| SSE_REG_P (operands[0])
2280	|| MASK_REG_P (operands[0]))
2281   && !(MMX_REG_P (operands[1])
2282	|| SSE_REG_P (operands[1])
2283	|| MASK_REG_P (operands[1]))"
2284  [(const_int 0)]
2285  "ix86_split_long_move (operands); DONE;")
2286
2287(define_insn "*movsi_internal"
2288  [(set (match_operand:SI 0 "nonimmediate_operand"
2289			"=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2290	(match_operand:SI 1 "general_operand"
2291			"g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2292  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2293{
2294  switch (get_attr_type (insn))
2295    {
2296    case TYPE_SSELOG1:
2297      if (GENERAL_REG_P (operands[0]))
2298	return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2299
2300      return standard_sse_constant_opcode (insn, operands[1]);
2301
2302    case TYPE_MSKMOV:
2303      return "kmovd\t{%1, %0|%0, %1}";
2304
2305    case TYPE_SSEMOV:
2306      switch (get_attr_mode (insn))
2307	{
2308	case MODE_SI:
2309          return "%vmovd\t{%1, %0|%0, %1}";
2310	case MODE_TI:
2311	  return "%vmovdqa\t{%1, %0|%0, %1}";
2312	case MODE_XI:
2313	  return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2314
2315	case MODE_V4SF:
2316	  return "%vmovaps\t{%1, %0|%0, %1}";
2317
2318	case MODE_SF:
2319	  gcc_assert (!TARGET_AVX);
2320          return "movss\t{%1, %0|%0, %1}";
2321
2322	default:
2323	  gcc_unreachable ();
2324	}
2325
2326    case TYPE_MMX:
2327      return "pxor\t%0, %0";
2328
2329    case TYPE_MMXMOV:
2330      switch (get_attr_mode (insn))
2331	{
2332	case MODE_DI:
2333	  return "movq\t{%1, %0|%0, %1}";
2334	case MODE_SI:
2335	  return "movd\t{%1, %0|%0, %1}";
2336
2337	default:
2338	  gcc_unreachable ();
2339	}
2340
2341    case TYPE_LEA:
2342      return "lea{l}\t{%E1, %0|%0, %E1}";
2343
2344    case TYPE_IMOV:
2345      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2346      if (ix86_use_lea_for_mov (insn, operands))
2347	return "lea{l}\t{%E1, %0|%0, %E1}";
2348      else
2349	return "mov{l}\t{%1, %0|%0, %1}";
2350
2351    default:
2352      gcc_unreachable ();
2353    }
2354}
2355  [(set (attr "isa")
2356     (if_then_else (eq_attr "alternative" "11")
2357       (const_string "sse4")
2358       (const_string "*")))
2359   (set (attr "type")
2360     (cond [(eq_attr "alternative" "2")
2361	      (const_string "mmx")
2362	    (eq_attr "alternative" "3,4,5")
2363	      (const_string "mmxmov")
2364	    (eq_attr "alternative" "6,11")
2365	      (const_string "sselog1")
2366	    (eq_attr "alternative" "7,8,9,10,12")
2367	      (const_string "ssemov")
2368	    (eq_attr "alternative" "13,14")
2369	      (const_string "mskmov")
2370	    (and (match_operand 0 "register_operand")
2371		 (match_operand 1 "pic_32bit_operand"))
2372	      (const_string "lea")
2373	   ]
2374	   (const_string "imov")))
2375   (set (attr "length_immediate")
2376     (if_then_else (eq_attr "alternative" "11")
2377       (const_string "1")
2378       (const_string "*")))
2379   (set (attr "prefix_extra")
2380     (if_then_else (eq_attr "alternative" "11")
2381       (const_string "1")
2382       (const_string "*")))
2383   (set (attr "prefix")
2384     (if_then_else (eq_attr "type" "sselog1,ssemov")
2385       (const_string "maybe_vex")
2386       (const_string "orig")))
2387   (set (attr "prefix_data16")
2388     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2389       (const_string "1")
2390       (const_string "*")))
2391   (set (attr "mode")
2392     (cond [(eq_attr "alternative" "2,3")
2393	      (const_string "DI")
2394	    (eq_attr "alternative" "6,7")
2395	      (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2396			  (match_operand 1 "ext_sse_reg_operand"))
2397		       (const_string "XI")
2398		     (ior (not (match_test "TARGET_SSE2"))
2399			  (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2400		       (const_string "V4SF")
2401		     (match_test "TARGET_AVX")
2402		       (const_string "TI")
2403		     (match_test "optimize_function_for_size_p (cfun)")
2404		       (const_string "V4SF")
2405		    ]
2406		    (const_string "TI"))
2407
2408	    (and (eq_attr "alternative" "8,9")
2409	         (not (match_test "TARGET_SSE2")))
2410	      (const_string "SF")
2411	    (eq_attr "alternative" "11")
2412	      (const_string "TI")
2413	   ]
2414	   (const_string "SI")))])
2415
2416(define_insn "kmovw"
2417  [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2418	(unspec:HI
2419	  [(match_operand:HI 1 "nonimmediate_operand" "r,km")]
2420	  UNSPEC_KMOV))]
2421  "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2422  "@
2423   kmovw\t{%k1, %0|%0, %k1}
2424   kmovw\t{%1, %0|%0, %1}";
2425  [(set_attr "mode" "HI")
2426   (set_attr "type" "mskmov")
2427   (set_attr "prefix" "vex")])
2428
2429
2430(define_insn "*movhi_internal"
2431  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m")
2432	(match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2433  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2434{
2435  switch (get_attr_type (insn))
2436    {
2437    case TYPE_IMOVX:
2438      /* movzwl is faster than movw on p2 due to partial word stalls,
2439	 though not as fast as an aligned movl.  */
2440      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2441
2442    case TYPE_MSKMOV:
2443      switch (which_alternative)
2444        {
2445	case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2446	case 5: /* FALLTHRU */
2447	case 7: return "kmovw\t{%1, %0|%0, %1}";
2448	case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2449	default: gcc_unreachable ();
2450	}
2451
2452    default:
2453      if (get_attr_mode (insn) == MODE_SI)
2454        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2455      else
2456        return "mov{w}\t{%1, %0|%0, %1}";
2457    }
2458}
2459  [(set (attr "type")
2460     (cond [(eq_attr "alternative" "4,5,6,7")
2461	      (const_string "mskmov")
2462	    (match_test "optimize_function_for_size_p (cfun)")
2463	      (const_string "imov")
2464	    (and (eq_attr "alternative" "0")
2465		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2466		      (not (match_test "TARGET_HIMODE_MATH"))))
2467	      (const_string "imov")
2468	    (and (eq_attr "alternative" "1,2")
2469		 (match_operand:HI 1 "aligned_operand"))
2470	      (const_string "imov")
2471	    (and (match_test "TARGET_MOVX")
2472		 (eq_attr "alternative" "0,2"))
2473	      (const_string "imovx")
2474	   ]
2475	   (const_string "imov")))
2476    (set (attr "prefix")
2477      (if_then_else (eq_attr "alternative" "4,5,6,7")
2478	(const_string "vex")
2479	(const_string "orig")))
2480    (set (attr "mode")
2481      (cond [(eq_attr "type" "imovx")
2482	       (const_string "SI")
2483	     (and (eq_attr "alternative" "1,2")
2484		  (match_operand:HI 1 "aligned_operand"))
2485	       (const_string "SI")
2486	     (and (eq_attr "alternative" "0")
2487		  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2488		       (not (match_test "TARGET_HIMODE_MATH"))))
2489	       (const_string "SI")
2490	    ]
2491	    (const_string "HI")))])
2492
2493;; Situation is quite tricky about when to choose full sized (SImode) move
2494;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2495;; partial register dependency machines (such as AMD Athlon), where QImode
2496;; moves issue extra dependency and for partial register stalls machines
2497;; that don't use QImode patterns (and QImode move cause stall on the next
2498;; instruction).
2499;;
2500;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2501;; register stall machines with, where we use QImode instructions, since
2502;; partial register stall can be caused there.  Then we use movzx.
2503
2504(define_insn "*movqi_internal"
2505  [(set (match_operand:QI 0 "nonimmediate_operand"
2506			"=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2507	(match_operand:QI 1 "general_operand"
2508			"q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2509  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2510{
2511  switch (get_attr_type (insn))
2512    {
2513    case TYPE_IMOVX:
2514      gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2515      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2516
2517    case TYPE_MSKMOV:
2518      switch (which_alternative)
2519        {
2520	case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2521				       : "kmovw\t{%k1, %0|%0, %k1}";
2522	case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2523				       : "kmovw\t{%1, %0|%0, %1}";
2524	case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2525				       : "kmovw\t{%1, %k0|%k0, %1}";
2526	case 10:
2527	case 11:
2528	  gcc_assert (TARGET_AVX512DQ);
2529	  return "kmovb\t{%1, %0|%0, %1}";
2530	default: gcc_unreachable ();
2531	}
2532
2533    default:
2534      if (get_attr_mode (insn) == MODE_SI)
2535        return "mov{l}\t{%k1, %k0|%k0, %k1}";
2536      else
2537        return "mov{b}\t{%1, %0|%0, %1}";
2538    }
2539}
2540  [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2541   (set (attr "type")
2542     (cond [(eq_attr "alternative" "7,8,9,10,11")
2543	      (const_string "mskmov")
2544	    (and (eq_attr "alternative" "5")
2545		 (not (match_operand:QI 1 "aligned_operand")))
2546	      (const_string "imovx")
2547	    (match_test "optimize_function_for_size_p (cfun)")
2548	      (const_string "imov")
2549	    (and (eq_attr "alternative" "3")
2550		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2551		      (not (match_test "TARGET_QIMODE_MATH"))))
2552	      (const_string "imov")
2553	    (eq_attr "alternative" "3,5")
2554	      (const_string "imovx")
2555	    (and (match_test "TARGET_MOVX")
2556		 (eq_attr "alternative" "2"))
2557	      (const_string "imovx")
2558	   ]
2559	   (const_string "imov")))
2560   (set (attr "prefix")
2561     (if_then_else (eq_attr "alternative" "7,8,9")
2562       (const_string "vex")
2563       (const_string "orig")))
2564   (set (attr "mode")
2565      (cond [(eq_attr "alternative" "3,4,5")
2566	       (const_string "SI")
2567	     (eq_attr "alternative" "6")
2568	       (const_string "QI")
2569	     (eq_attr "type" "imovx")
2570	       (const_string "SI")
2571	     (and (eq_attr "type" "imov")
2572		  (and (eq_attr "alternative" "0,1")
2573		       (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2574			    (and (not (match_test "optimize_function_for_size_p (cfun)"))
2575				 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2576	       (const_string "SI")
2577	     ;; Avoid partial register stalls when not using QImode arithmetic
2578	     (and (eq_attr "type" "imov")
2579		  (and (eq_attr "alternative" "0,1")
2580		       (and (match_test "TARGET_PARTIAL_REG_STALL")
2581			    (not (match_test "TARGET_QIMODE_MATH")))))
2582	       (const_string "SI")
2583	   ]
2584	   (const_string "QI")))])
2585
2586;; Stores and loads of ax to arbitrary constant address.
2587;; We fake an second form of instruction to force reload to load address
2588;; into register when rax is not available
2589(define_insn "*movabs<mode>_1"
2590  [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2591	(match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2592  "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2593  "@
2594   movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2595   mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2596  [(set_attr "type" "imov")
2597   (set_attr "modrm" "0,*")
2598   (set_attr "length_address" "8,0")
2599   (set_attr "length_immediate" "0,*")
2600   (set_attr "memory" "store")
2601   (set_attr "mode" "<MODE>")])
2602
2603(define_insn "*movabs<mode>_2"
2604  [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2605        (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2606  "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2607  "@
2608   movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2609   mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2610  [(set_attr "type" "imov")
2611   (set_attr "modrm" "0,*")
2612   (set_attr "length_address" "8,0")
2613   (set_attr "length_immediate" "0")
2614   (set_attr "memory" "load")
2615   (set_attr "mode" "<MODE>")])
2616
2617(define_insn "*swap<mode>"
2618  [(set (match_operand:SWI48 0 "register_operand" "+r")
2619	(match_operand:SWI48 1 "register_operand" "+r"))
2620   (set (match_dup 1)
2621	(match_dup 0))]
2622  ""
2623  "xchg{<imodesuffix>}\t%1, %0"
2624  [(set_attr "type" "imov")
2625   (set_attr "mode" "<MODE>")
2626   (set_attr "pent_pair" "np")
2627   (set_attr "athlon_decode" "vector")
2628   (set_attr "amdfam10_decode" "double")
2629   (set_attr "bdver1_decode" "double")])
2630
2631(define_insn "*swap<mode>_1"
2632  [(set (match_operand:SWI12 0 "register_operand" "+r")
2633	(match_operand:SWI12 1 "register_operand" "+r"))
2634   (set (match_dup 1)
2635	(match_dup 0))]
2636  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2637  "xchg{l}\t%k1, %k0"
2638  [(set_attr "type" "imov")
2639   (set_attr "mode" "SI")
2640   (set_attr "pent_pair" "np")
2641   (set_attr "athlon_decode" "vector")
2642   (set_attr "amdfam10_decode" "double")
2643   (set_attr "bdver1_decode" "double")])
2644
2645;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2646;; is disabled for AMDFAM10
2647(define_insn "*swap<mode>_2"
2648  [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2649	(match_operand:SWI12 1 "register_operand" "+<r>"))
2650   (set (match_dup 1)
2651	(match_dup 0))]
2652  "TARGET_PARTIAL_REG_STALL"
2653  "xchg{<imodesuffix>}\t%1, %0"
2654  [(set_attr "type" "imov")
2655   (set_attr "mode" "<MODE>")
2656   (set_attr "pent_pair" "np")
2657   (set_attr "athlon_decode" "vector")])
2658
2659(define_expand "movstrict<mode>"
2660  [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2661	(match_operand:SWI12 1 "general_operand"))]
2662  ""
2663{
2664  if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2665    FAIL;
2666  if (GET_CODE (operands[0]) == SUBREG
2667      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2668    FAIL;
2669  /* Don't generate memory->memory moves, go through a register */
2670  if (MEM_P (operands[0]) && MEM_P (operands[1]))
2671    operands[1] = force_reg (<MODE>mode, operands[1]);
2672})
2673
2674(define_insn "*movstrict<mode>_1"
2675  [(set (strict_low_part
2676	  (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2677	(match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2678  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2679   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2680  "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2681  [(set_attr "type" "imov")
2682   (set_attr "mode" "<MODE>")])
2683
2684(define_insn "*movstrict<mode>_xor"
2685  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2686	(match_operand:SWI12 1 "const0_operand"))
2687   (clobber (reg:CC FLAGS_REG))]
2688  "reload_completed"
2689  "xor{<imodesuffix>}\t%0, %0"
2690  [(set_attr "type" "alu1")
2691   (set_attr "mode" "<MODE>")
2692   (set_attr "length_immediate" "0")])
2693
2694(define_insn "*mov<mode>_extv_1"
2695  [(set (match_operand:SWI24 0 "register_operand" "=R")
2696	(sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2697			    (const_int 8)
2698			    (const_int 8)))]
2699  ""
2700  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2701  [(set_attr "type" "imovx")
2702   (set_attr "mode" "SI")])
2703
2704(define_insn "*movqi_extv_1"
2705  [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2706        (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2707                         (const_int 8)
2708                         (const_int 8)))]
2709  ""
2710{
2711  switch (get_attr_type (insn))
2712    {
2713    case TYPE_IMOVX:
2714      return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2715    default:
2716      return "mov{b}\t{%h1, %0|%0, %h1}";
2717    }
2718}
2719  [(set_attr "isa" "*,*,nox64")
2720   (set (attr "type")
2721     (if_then_else (and (match_operand:QI 0 "register_operand")
2722			(ior (not (match_operand:QI 0 "QIreg_operand"))
2723			     (match_test "TARGET_MOVX")))
2724	(const_string "imovx")
2725	(const_string "imov")))
2726   (set (attr "mode")
2727     (if_then_else (eq_attr "type" "imovx")
2728	(const_string "SI")
2729	(const_string "QI")))])
2730
2731(define_insn "*mov<mode>_extzv_1"
2732  [(set (match_operand:SWI48 0 "register_operand" "=R")
2733	(zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2734			    (const_int 8)
2735			    (const_int 8)))]
2736  ""
2737  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2738  [(set_attr "type" "imovx")
2739   (set_attr "mode" "SI")])
2740
2741(define_insn "*movqi_extzv_2"
2742  [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2743        (subreg:QI
2744	  (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2745			   (const_int 8)
2746			   (const_int 8)) 0))]
2747  ""
2748{
2749  switch (get_attr_type (insn))
2750    {
2751    case TYPE_IMOVX:
2752      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2753    default:
2754      return "mov{b}\t{%h1, %0|%0, %h1}";
2755    }
2756}
2757  [(set_attr "isa" "*,*,nox64")
2758   (set (attr "type")
2759     (if_then_else (and (match_operand:QI 0 "register_operand")
2760			(ior (not (match_operand:QI 0 "QIreg_operand"))
2761			     (match_test "TARGET_MOVX")))
2762	(const_string "imovx")
2763	(const_string "imov")))
2764   (set (attr "mode")
2765     (if_then_else (eq_attr "type" "imovx")
2766	(const_string "SI")
2767	(const_string "QI")))])
2768
2769(define_insn "mov<mode>_insv_1"
2770  [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2771			     (const_int 8)
2772			     (const_int 8))
2773	(match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2774  ""
2775{
2776  if (CONST_INT_P (operands[1]))
2777    operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2778  return "mov{b}\t{%b1, %h0|%h0, %b1}";
2779}
2780  [(set_attr "isa" "*,nox64")
2781   (set_attr "type" "imov")
2782   (set_attr "mode" "QI")])
2783
2784(define_insn "*movqi_insv_2"
2785  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2786			 (const_int 8)
2787			 (const_int 8))
2788	(lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2789		     (const_int 8)))]
2790  ""
2791  "mov{b}\t{%h1, %h0|%h0, %h1}"
2792  [(set_attr "type" "imov")
2793   (set_attr "mode" "QI")])
2794
2795;; Floating point push instructions.
2796
2797(define_insn "*pushtf"
2798  [(set (match_operand:TF 0 "push_operand" "=<,<")
2799	(match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2800  "TARGET_64BIT || TARGET_SSE"
2801{
2802  /* This insn should be already split before reg-stack.  */
2803  gcc_unreachable ();
2804}
2805  [(set_attr "isa" "*,x64")
2806   (set_attr "type" "multi")
2807   (set_attr "unit" "sse,*")
2808   (set_attr "mode" "TF,DI")])
2809
2810;; %%% Kill this when call knows how to work this out.
2811(define_split
2812  [(set (match_operand:TF 0 "push_operand")
2813	(match_operand:TF 1 "sse_reg_operand"))]
2814  "TARGET_SSE && reload_completed"
2815  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2816   (set (match_dup 0) (match_dup 1))]
2817{
2818  /* Preserve memory attributes. */
2819  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2820})
2821
2822(define_insn "*pushxf"
2823  [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2824	(match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2825  ""
2826{
2827  /* This insn should be already split before reg-stack.  */
2828  gcc_unreachable ();
2829}
2830  [(set_attr "type" "multi")
2831   (set_attr "unit" "i387,*,*,*")
2832   (set (attr "mode")
2833	(cond [(eq_attr "alternative" "1,2,3")
2834		 (if_then_else (match_test "TARGET_64BIT")
2835		   (const_string "DI")
2836		   (const_string "SI"))
2837	      ]
2838	      (const_string "XF")))
2839   (set (attr "preferred_for_size")
2840     (cond [(eq_attr "alternative" "1")
2841              (symbol_ref "false")]
2842           (symbol_ref "true")))])
2843
2844;; %%% Kill this when call knows how to work this out.
2845(define_split
2846  [(set (match_operand:XF 0 "push_operand")
2847	(match_operand:XF 1 "fp_register_operand"))]
2848  "reload_completed"
2849  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2850   (set (match_dup 0) (match_dup 1))]
2851{
2852  operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2853  /* Preserve memory attributes. */
2854  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2855})
2856
2857(define_insn "*pushdf"
2858  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
2859	(match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
2860  ""
2861{
2862  /* This insn should be already split before reg-stack.  */
2863  gcc_unreachable ();
2864}
2865  [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
2866   (set_attr "type" "multi")
2867   (set_attr "unit" "i387,*,*,*,*,sse")
2868   (set_attr "mode" "DF,SI,SI,SI,DI,DF")
2869   (set (attr "preferred_for_size")
2870     (cond [(eq_attr "alternative" "1")
2871              (symbol_ref "false")]
2872           (symbol_ref "true")))
2873   (set (attr "preferred_for_speed")
2874     (cond [(eq_attr "alternative" "1")
2875              (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
2876           (symbol_ref "true")))])
2877   
2878;; %%% Kill this when call knows how to work this out.
2879(define_split
2880  [(set (match_operand:DF 0 "push_operand")
2881	(match_operand:DF 1 "any_fp_register_operand"))]
2882  "reload_completed"
2883  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2884   (set (match_dup 0) (match_dup 1))]
2885{
2886  /* Preserve memory attributes. */
2887  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2888})
2889
2890(define_insn "*pushsf_rex64"
2891  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2892	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2893  "TARGET_64BIT"
2894{
2895  /* Anything else should be already split before reg-stack.  */
2896  gcc_assert (which_alternative == 1);
2897  return "push{q}\t%q1";
2898}
2899  [(set_attr "type" "multi,push,multi")
2900   (set_attr "unit" "i387,*,*")
2901   (set_attr "mode" "SF,DI,SF")])
2902
2903(define_insn "*pushsf"
2904  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2905	(match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2906  "!TARGET_64BIT"
2907{
2908  /* Anything else should be already split before reg-stack.  */
2909  gcc_assert (which_alternative == 1);
2910  return "push{l}\t%1";
2911}
2912  [(set_attr "type" "multi,push,multi")
2913   (set_attr "unit" "i387,*,*")
2914   (set_attr "mode" "SF,SI,SF")])
2915
2916;; %%% Kill this when call knows how to work this out.
2917(define_split
2918  [(set (match_operand:SF 0 "push_operand")
2919	(match_operand:SF 1 "any_fp_register_operand"))]
2920  "reload_completed"
2921  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2922   (set (match_dup 0) (match_dup 1))]
2923{
2924  rtx op = XEXP (operands[0], 0);
2925  if (GET_CODE (op) == PRE_DEC)
2926    {
2927      gcc_assert (!TARGET_64BIT);
2928      op = GEN_INT (-4);
2929    }
2930  else
2931    {
2932      op = XEXP (XEXP (op, 1), 1);
2933      gcc_assert (CONST_INT_P (op));
2934    }
2935  operands[2] = op;
2936  /* Preserve memory attributes. */
2937  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2938})
2939
2940(define_split
2941  [(set (match_operand:SF 0 "push_operand")
2942	(match_operand:SF 1 "memory_operand"))]
2943  "reload_completed
2944   && (operands[2] = find_constant_src (insn))"
2945  [(set (match_dup 0) (match_dup 2))])
2946
2947(define_split
2948  [(set (match_operand 0 "push_operand")
2949	(match_operand 1 "general_operand"))]
2950  "reload_completed
2951   && (GET_MODE (operands[0]) == TFmode
2952       || GET_MODE (operands[0]) == XFmode
2953       || GET_MODE (operands[0]) == DFmode)
2954   && !ANY_FP_REG_P (operands[1])"
2955  [(const_int 0)]
2956  "ix86_split_long_move (operands); DONE;")
2957
2958;; Floating point move instructions.
2959
2960(define_expand "movtf"
2961  [(set (match_operand:TF 0 "nonimmediate_operand")
2962	(match_operand:TF 1 "nonimmediate_operand"))]
2963  "TARGET_64BIT || TARGET_SSE"
2964  "ix86_expand_move (TFmode, operands); DONE;")
2965
2966(define_expand "mov<mode>"
2967  [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2968	(match_operand:X87MODEF 1 "general_operand"))]
2969  ""
2970  "ix86_expand_move (<MODE>mode, operands); DONE;")
2971
2972(define_insn "*movtf_internal"
2973  [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2974	(match_operand:TF 1 "general_operand"	   "C ,xm,x,*roF,*rC"))]
2975  "(TARGET_64BIT || TARGET_SSE)
2976   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2977   && (!can_create_pseudo_p ()
2978       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2979       || GET_CODE (operands[1]) != CONST_DOUBLE
2980       || (optimize_function_for_size_p (cfun)
2981	   && standard_sse_constant_p (operands[1])
2982	   && !memory_operand (operands[0], TFmode))
2983       || (!TARGET_MEMORY_MISMATCH_STALL
2984	   && memory_operand (operands[0], TFmode)))"
2985{
2986  switch (get_attr_type (insn))
2987    {
2988    case TYPE_SSELOG1:
2989      return standard_sse_constant_opcode (insn, operands[1]);
2990
2991    case TYPE_SSEMOV:
2992      /* Handle misaligned load/store since we
2993         don't have movmisaligntf pattern. */
2994      if (misaligned_operand (operands[0], TFmode)
2995	  || misaligned_operand (operands[1], TFmode))
2996	{
2997	  if (get_attr_mode (insn) == MODE_V4SF)
2998	    return "%vmovups\t{%1, %0|%0, %1}";
2999	  else
3000	    return "%vmovdqu\t{%1, %0|%0, %1}";
3001	}
3002      else
3003	{
3004	  if (get_attr_mode (insn) == MODE_V4SF)
3005	    return "%vmovaps\t{%1, %0|%0, %1}";
3006	  else
3007	    return "%vmovdqa\t{%1, %0|%0, %1}";
3008	}
3009
3010    case TYPE_MULTI:
3011	return "#";
3012
3013    default:
3014      gcc_unreachable ();
3015    }
3016}
3017  [(set_attr "isa" "*,*,*,x64,x64")
3018   (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3019   (set (attr "prefix")
3020     (if_then_else (eq_attr "type" "sselog1,ssemov")
3021       (const_string "maybe_vex")
3022       (const_string "orig")))
3023   (set (attr "mode")
3024        (cond [(eq_attr "alternative" "3,4")
3025		 (const_string "DI")
3026	       (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3027		 (const_string "V4SF")
3028	       (and (eq_attr "alternative" "2")
3029		    (match_test "TARGET_SSE_TYPELESS_STORES"))
3030		 (const_string "V4SF")
3031	       (match_test "TARGET_AVX")
3032		 (const_string "TI")
3033	       (ior (not (match_test "TARGET_SSE2"))
3034		    (match_test "optimize_function_for_size_p (cfun)"))
3035		 (const_string "V4SF")
3036	       ]
3037	       (const_string "TI")))])
3038
3039;; Possible store forwarding (partial memory) stall
3040;; in alternatives 4, 6, 7 and 8.
3041(define_insn "*movxf_internal"
3042  [(set (match_operand:XF 0 "nonimmediate_operand"
3043	 "=f,m,f,?r ,!o,?*r ,!o,!o,!o")
3044	(match_operand:XF 1 "general_operand"
3045	 "fm,f,G,roF,r , *roF,*r,F ,C"))]
3046  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3047   && (!can_create_pseudo_p ()
3048       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3049       || GET_CODE (operands[1]) != CONST_DOUBLE
3050       || (optimize_function_for_size_p (cfun)
3051	   && standard_80387_constant_p (operands[1]) > 0
3052	   && !memory_operand (operands[0], XFmode))
3053       || (!TARGET_MEMORY_MISMATCH_STALL
3054	   && memory_operand (operands[0], XFmode)))"
3055{
3056  switch (get_attr_type (insn))
3057    {
3058    case TYPE_FMOV:
3059      if (which_alternative == 2)
3060        return standard_80387_constant_opcode (operands[1]);
3061      return output_387_reg_move (insn, operands);
3062
3063    case TYPE_MULTI:
3064      return "#";
3065
3066    default:
3067      gcc_unreachable ();
3068    }
3069}
3070  [(set (attr "isa")
3071	(cond [(eq_attr "alternative" "7")
3072		 (const_string "nox64")
3073	       (eq_attr "alternative" "8")
3074		 (const_string "x64")
3075	      ]
3076	      (const_string "*")))
3077   (set (attr "type")
3078	(cond [(eq_attr "alternative" "3,4,5,6,7,8")
3079		 (const_string "multi")
3080	      ]
3081	      (const_string "fmov")))
3082   (set (attr "mode")
3083	(cond [(eq_attr "alternative" "3,4,5,6,7,8")
3084		 (if_then_else (match_test "TARGET_64BIT")
3085		   (const_string "DI")
3086		   (const_string "SI"))
3087	      ]
3088	      (const_string "XF")))
3089   (set (attr "preferred_for_size")
3090     (cond [(eq_attr "alternative" "3,4")
3091              (symbol_ref "false")]
3092           (symbol_ref "true")))])
3093   
3094;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3095(define_insn "*movdf_internal"
3096  [(set (match_operand:DF 0 "nonimmediate_operand"
3097    "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3098	(match_operand:DF 1 "general_operand"
3099    "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3100  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3101   && (!can_create_pseudo_p ()
3102       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3103       || GET_CODE (operands[1]) != CONST_DOUBLE
3104       || (optimize_function_for_size_p (cfun)
3105	   && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3106		&& standard_80387_constant_p (operands[1]) > 0)
3107	       || (TARGET_SSE2 && TARGET_SSE_MATH
3108		   && standard_sse_constant_p (operands[1])))
3109	   && !memory_operand (operands[0], DFmode))
3110       || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3111	   && memory_operand (operands[0], DFmode)))"
3112{
3113  switch (get_attr_type (insn))
3114    {
3115    case TYPE_FMOV:
3116      if (which_alternative == 2)
3117        return standard_80387_constant_opcode (operands[1]);
3118      return output_387_reg_move (insn, operands);
3119
3120    case TYPE_MULTI:
3121      return "#";
3122
3123    case TYPE_IMOV:
3124      if (get_attr_mode (insn) == MODE_SI)
3125	return "mov{l}\t{%1, %k0|%k0, %1}";
3126      else if (which_alternative == 11)
3127	return "movabs{q}\t{%1, %0|%0, %1}";
3128      else
3129	return "mov{q}\t{%1, %0|%0, %1}";
3130
3131    case TYPE_SSELOG1:
3132      return standard_sse_constant_opcode (insn, operands[1]);
3133
3134    case TYPE_SSEMOV:
3135      switch (get_attr_mode (insn))
3136	{
3137	case MODE_DF:
3138	  if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3139	    return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3140	  return "%vmovsd\t{%1, %0|%0, %1}";
3141
3142	case MODE_V4SF:
3143	  return "%vmovaps\t{%1, %0|%0, %1}";
3144	case MODE_V8DF:
3145	  return "vmovapd\t{%g1, %g0|%g0, %g1}";
3146	case MODE_V2DF:
3147	  return "%vmovapd\t{%1, %0|%0, %1}";
3148
3149	case MODE_V2SF:
3150	  gcc_assert (!TARGET_AVX);
3151	  return "movlps\t{%1, %0|%0, %1}";
3152	case MODE_V1DF:
3153	  gcc_assert (!TARGET_AVX);
3154	  return "movlpd\t{%1, %0|%0, %1}";
3155
3156	case MODE_DI:
3157	  /* Handle broken assemblers that require movd instead of movq.  */
3158	  if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3159	      && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3160	    return "%vmovd\t{%1, %0|%0, %1}";
3161	  return "%vmovq\t{%1, %0|%0, %1}";
3162
3163	default:
3164	  gcc_unreachable ();
3165	}
3166
3167    default:
3168      gcc_unreachable ();
3169    }
3170}
3171  [(set (attr "isa")
3172	(cond [(eq_attr "alternative" "3,4,5,6,7")
3173		 (const_string "nox64")
3174	       (eq_attr "alternative" "8,9,10,11,20,21")
3175		 (const_string "x64")
3176	       (eq_attr "alternative" "12,13,14,15")
3177		 (const_string "sse2")
3178	      ]
3179	      (const_string "*")))
3180   (set (attr "type")
3181	(cond [(eq_attr "alternative" "0,1,2")
3182		 (const_string "fmov")
3183	       (eq_attr "alternative" "3,4,5,6,7")
3184		 (const_string "multi")
3185	       (eq_attr "alternative" "8,9,10,11")
3186		 (const_string "imov")
3187	       (eq_attr "alternative" "12,16")
3188		 (const_string "sselog1")
3189	      ]
3190	      (const_string "ssemov")))
3191   (set (attr "modrm")
3192     (if_then_else (eq_attr "alternative" "11")
3193       (const_string "0")
3194       (const_string "*")))
3195   (set (attr "length_immediate")
3196     (if_then_else (eq_attr "alternative" "11")
3197       (const_string "8")
3198       (const_string "*")))
3199   (set (attr "prefix")
3200     (if_then_else (eq_attr "type" "sselog1,ssemov")
3201       (const_string "maybe_vex")
3202       (const_string "orig")))
3203   (set (attr "prefix_data16")
3204     (if_then_else
3205       (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3206	    (eq_attr "mode" "V1DF"))
3207       (const_string "1")
3208       (const_string "*")))
3209   (set (attr "mode")
3210	(cond [(eq_attr "alternative" "3,4,5,6,7,10")
3211		 (const_string "SI")
3212	       (eq_attr "alternative" "8,9,11,20,21")
3213		 (const_string "DI")
3214
3215	       /* xorps is one byte shorter for non-AVX targets.  */
3216	       (eq_attr "alternative" "12,16")
3217		 (cond [(not (match_test "TARGET_SSE2"))
3218		 	  (const_string "V4SF")
3219			(match_test "TARGET_AVX512F")
3220			  (const_string "XI")
3221			(match_test "TARGET_AVX")
3222			  (const_string "V2DF")
3223			(match_test "optimize_function_for_size_p (cfun)")
3224			  (const_string "V4SF")
3225			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3226			  (const_string "TI")
3227		       ]
3228		       (const_string "V2DF"))
3229
3230	       /* For architectures resolving dependencies on
3231		  whole SSE registers use movapd to break dependency
3232		  chains, otherwise use short move to avoid extra work.  */
3233
3234	       /* movaps is one byte shorter for non-AVX targets.  */
3235	       (eq_attr "alternative" "13,17")
3236		 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3237			     (match_operand 1 "ext_sse_reg_operand"))
3238			  (const_string "V8DF")
3239			(ior (not (match_test "TARGET_SSE2"))
3240			     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3241			  (const_string "V4SF")
3242			(match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3243			  (const_string "V2DF")
3244			(match_test "TARGET_AVX")
3245			  (const_string "DF")
3246			(match_test "optimize_function_for_size_p (cfun)")
3247			  (const_string "V4SF")
3248		       ]
3249		       (const_string "DF"))
3250
3251	       /* For architectures resolving dependencies on register
3252		  parts we may avoid extra work to zero out upper part
3253		  of register.  */
3254	       (eq_attr "alternative" "14,18")
3255		 (cond [(not (match_test "TARGET_SSE2"))
3256			  (const_string "V2SF")
3257			(match_test "TARGET_AVX")
3258			  (const_string "DF")
3259			(match_test "TARGET_SSE_SPLIT_REGS")
3260			  (const_string "V1DF")
3261		       ]
3262		       (const_string "DF"))
3263
3264	       (and (eq_attr "alternative" "15,19")
3265		    (not (match_test "TARGET_SSE2")))
3266		 (const_string "V2SF")
3267	      ]
3268	      (const_string "DF")))
3269   (set (attr "preferred_for_size")
3270     (cond [(eq_attr "alternative" "3,4")
3271              (symbol_ref "false")]
3272           (symbol_ref "true")))
3273   (set (attr "preferred_for_speed")
3274     (cond [(eq_attr "alternative" "3,4")
3275              (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3276           (symbol_ref "true")))])
3277
3278(define_insn "*movsf_internal"
3279  [(set (match_operand:SF 0 "nonimmediate_operand"
3280	  "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3281	(match_operand:SF 1 "general_operand"
3282	  "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3283  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3284   && (!can_create_pseudo_p ()
3285       || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3286       || GET_CODE (operands[1]) != CONST_DOUBLE
3287       || (optimize_function_for_size_p (cfun)
3288	   && ((!TARGET_SSE_MATH
3289		&& standard_80387_constant_p (operands[1]) > 0)
3290	       || (TARGET_SSE_MATH
3291		   && standard_sse_constant_p (operands[1]))))
3292       || memory_operand (operands[0], SFmode))"
3293{
3294  switch (get_attr_type (insn))
3295    {
3296    case TYPE_FMOV:
3297      if (which_alternative == 2)
3298        return standard_80387_constant_opcode (operands[1]);
3299      return output_387_reg_move (insn, operands);
3300
3301    case TYPE_IMOV:
3302      return "mov{l}\t{%1, %0|%0, %1}";
3303
3304    case TYPE_SSELOG1:
3305      return standard_sse_constant_opcode (insn, operands[1]);
3306
3307    case TYPE_SSEMOV:
3308      switch (get_attr_mode (insn))
3309	{
3310	case MODE_SF:
3311	  if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3312	    return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3313	  return "%vmovss\t{%1, %0|%0, %1}";
3314
3315	case MODE_V16SF:
3316	  return "vmovaps\t{%g1, %g0|%g0, %g1}";
3317	case MODE_V4SF:
3318	  return "%vmovaps\t{%1, %0|%0, %1}";
3319
3320	case MODE_SI:
3321	  return "%vmovd\t{%1, %0|%0, %1}";
3322
3323	default:
3324	  gcc_unreachable ();
3325	}
3326
3327    case TYPE_MMXMOV:
3328      switch (get_attr_mode (insn))
3329	{
3330	case MODE_DI:
3331	  return "movq\t{%1, %0|%0, %1}";
3332	case MODE_SI:
3333	  return "movd\t{%1, %0|%0, %1}";
3334
3335	default:
3336	  gcc_unreachable ();
3337	}
3338
3339    default:
3340      gcc_unreachable ();
3341    }
3342}
3343  [(set (attr "type")
3344	(cond [(eq_attr "alternative" "0,1,2")
3345		 (const_string "fmov")
3346	       (eq_attr "alternative" "3,4")
3347		 (const_string "imov")
3348	       (eq_attr "alternative" "5")
3349		 (const_string "sselog1")
3350	       (eq_attr "alternative" "11,12,13,14,15")
3351		 (const_string "mmxmov")
3352	      ]
3353	      (const_string "ssemov")))
3354   (set (attr "prefix")
3355     (if_then_else (eq_attr "type" "sselog1,ssemov")
3356       (const_string "maybe_vex")
3357       (const_string "orig")))
3358   (set (attr "prefix_data16")
3359     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3360       (const_string "1")
3361       (const_string "*")))
3362   (set (attr "mode")
3363        (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3364		 (const_string "SI")
3365	       (eq_attr "alternative" "11")
3366		 (const_string "DI")
3367	       (eq_attr "alternative" "5")
3368		 (cond [(not (match_test "TARGET_SSE2"))
3369 		 	  (const_string "V4SF")
3370			(match_test "TARGET_AVX512F")
3371			  (const_string "V16SF")
3372			(match_test "TARGET_AVX")
3373			  (const_string "V4SF")
3374 			(match_test "optimize_function_for_size_p (cfun)")
3375			  (const_string "V4SF")
3376 			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3377			  (const_string "TI")
3378		       ]
3379		       (const_string "V4SF"))
3380
3381	       /* For architectures resolving dependencies on
3382		  whole SSE registers use APS move to break dependency
3383		  chains, otherwise use short move to avoid extra work.
3384
3385		  Do the same for architectures resolving dependencies on
3386		  the parts.  While in DF mode it is better to always handle
3387		  just register parts, the SF mode is different due to lack
3388		  of instructions to load just part of the register.  It is
3389		  better to maintain the whole registers in single format
3390		  to avoid problems on using packed logical operations.  */
3391	       (eq_attr "alternative" "6")
3392		 (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3393			      (match_operand 1 "ext_sse_reg_operand"))
3394			  (const_string "V16SF")
3395			(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3396			     (match_test "TARGET_SSE_SPLIT_REGS"))
3397			  (const_string "V4SF")
3398		       ]
3399		       (const_string "SF"))
3400	      ]
3401	      (const_string "SF")))])
3402
3403(define_split
3404  [(set (match_operand 0 "any_fp_register_operand")
3405	(match_operand 1 "memory_operand"))]
3406  "reload_completed
3407   && (GET_MODE (operands[0]) == TFmode
3408       || GET_MODE (operands[0]) == XFmode
3409       || GET_MODE (operands[0]) == DFmode
3410       || GET_MODE (operands[0]) == SFmode)
3411   && (operands[2] = find_constant_src (insn))"
3412  [(set (match_dup 0) (match_dup 2))]
3413{
3414  rtx c = operands[2];
3415  int r = REGNO (operands[0]);
3416
3417  if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3418      || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3419    FAIL;
3420})
3421
3422(define_split
3423  [(set (match_operand 0 "any_fp_register_operand")
3424	(float_extend (match_operand 1 "memory_operand")))]
3425  "reload_completed
3426   && (GET_MODE (operands[0]) == TFmode
3427       || GET_MODE (operands[0]) == XFmode
3428       || GET_MODE (operands[0]) == DFmode)
3429   && (operands[2] = find_constant_src (insn))"
3430  [(set (match_dup 0) (match_dup 2))]
3431{
3432  rtx c = operands[2];
3433  int r = REGNO (operands[0]);
3434
3435  if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3436      || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3437    FAIL;
3438})
3439
3440;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3441(define_split
3442  [(set (match_operand:X87MODEF 0 "fp_register_operand")
3443	(match_operand:X87MODEF 1 "immediate_operand"))]
3444  "reload_completed
3445   && (standard_80387_constant_p (operands[1]) == 8
3446       || standard_80387_constant_p (operands[1]) == 9)"
3447  [(set (match_dup 0)(match_dup 1))
3448   (set (match_dup 0)
3449	(neg:X87MODEF (match_dup 0)))]
3450{
3451  REAL_VALUE_TYPE r;
3452
3453  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3454  if (real_isnegzero (&r))
3455    operands[1] = CONST0_RTX (<MODE>mode);
3456  else
3457    operands[1] = CONST1_RTX (<MODE>mode);
3458})
3459
3460(define_split
3461  [(set (match_operand 0 "nonimmediate_operand")
3462        (match_operand 1 "general_operand"))]
3463  "reload_completed
3464   && (GET_MODE (operands[0]) == TFmode
3465       || GET_MODE (operands[0]) == XFmode
3466       || GET_MODE (operands[0]) == DFmode)
3467   && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3468  [(const_int 0)]
3469  "ix86_split_long_move (operands); DONE;")
3470
3471(define_insn "swapxf"
3472  [(set (match_operand:XF 0 "register_operand" "+f")
3473	(match_operand:XF 1 "register_operand" "+f"))
3474   (set (match_dup 1)
3475	(match_dup 0))]
3476  "TARGET_80387"
3477{
3478  if (STACK_TOP_P (operands[0]))
3479    return "fxch\t%1";
3480  else
3481    return "fxch\t%0";
3482}
3483  [(set_attr "type" "fxch")
3484   (set_attr "mode" "XF")])
3485
3486(define_insn "*swap<mode>"
3487  [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3488	(match_operand:MODEF 1 "fp_register_operand" "+f"))
3489   (set (match_dup 1)
3490	(match_dup 0))]
3491  "TARGET_80387 || reload_completed"
3492{
3493  if (STACK_TOP_P (operands[0]))
3494    return "fxch\t%1";
3495  else
3496    return "fxch\t%0";
3497}
3498  [(set_attr "type" "fxch")
3499   (set_attr "mode" "<MODE>")])
3500
3501;; Zero extension instructions
3502
3503(define_expand "zero_extendsidi2"
3504  [(set (match_operand:DI 0 "nonimmediate_operand")
3505	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3506
3507(define_insn "*zero_extendsidi2"
3508  [(set (match_operand:DI 0 "nonimmediate_operand"
3509			"=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3510	(zero_extend:DI
3511	 (match_operand:SI 1 "x86_64_zext_operand"
3512	        	"0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3513  ""
3514{
3515  switch (get_attr_type (insn))
3516    {
3517    case TYPE_IMOVX:
3518      if (ix86_use_lea_for_mov (insn, operands))
3519	return "lea{l}\t{%E1, %k0|%k0, %E1}";
3520      else
3521	return "mov{l}\t{%1, %k0|%k0, %1}";
3522
3523    case TYPE_MULTI:
3524      return "#";
3525
3526    case TYPE_MMXMOV:
3527      return "movd\t{%1, %0|%0, %1}";
3528
3529    case TYPE_SSELOG1:
3530      return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3531
3532    case TYPE_SSEMOV:
3533      if (GENERAL_REG_P (operands[0]))
3534	return "%vmovd\t{%1, %k0|%k0, %1}";
3535
3536      return "%vmovd\t{%1, %0|%0, %1}";
3537
3538    default:
3539      gcc_unreachable ();
3540    }
3541}
3542  [(set (attr "isa")
3543     (cond [(eq_attr "alternative" "0,1,2")
3544	      (const_string "nox64")
3545	    (eq_attr "alternative" "3,7")
3546	      (const_string "x64")
3547	    (eq_attr "alternative" "8")
3548	      (const_string "x64_sse4")
3549	    (eq_attr "alternative" "10")
3550	      (const_string "sse2")
3551	   ]
3552	   (const_string "*")))
3553   (set (attr "type")
3554     (cond [(eq_attr "alternative" "0,1,2,4")
3555	      (const_string "multi")
3556	    (eq_attr "alternative" "5,6")
3557	      (const_string "mmxmov")
3558	    (eq_attr "alternative" "7,9,10")
3559	      (const_string "ssemov")
3560	    (eq_attr "alternative" "8")
3561	      (const_string "sselog1")
3562	   ]
3563	   (const_string "imovx")))
3564   (set (attr "prefix_extra")
3565     (if_then_else (eq_attr "alternative" "8")
3566       (const_string "1")
3567       (const_string "*")))
3568   (set (attr "length_immediate")
3569     (if_then_else (eq_attr "alternative" "8")
3570       (const_string "1")
3571       (const_string "*")))
3572   (set (attr "prefix")
3573     (if_then_else (eq_attr "type" "ssemov,sselog1")
3574       (const_string "maybe_vex")
3575       (const_string "orig")))
3576   (set (attr "prefix_0f")
3577     (if_then_else (eq_attr "type" "imovx")
3578       (const_string "0")
3579       (const_string "*")))
3580   (set (attr "mode")
3581     (cond [(eq_attr "alternative" "5,6")
3582	      (const_string "DI")
3583	    (eq_attr "alternative" "7,8,9")
3584	      (const_string "TI")
3585	   ]
3586	   (const_string "SI")))])
3587
3588(define_split
3589  [(set (match_operand:DI 0 "memory_operand")
3590     	(zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3591  "reload_completed"
3592  [(set (match_dup 4) (const_int 0))]
3593  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3594
3595(define_split
3596  [(set (match_operand:DI 0 "register_operand")
3597	(zero_extend:DI (match_operand:SI 1 "register_operand")))]
3598  "!TARGET_64BIT && reload_completed
3599   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3600   && true_regnum (operands[0]) == true_regnum (operands[1])"
3601  [(set (match_dup 4) (const_int 0))]
3602  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3603
3604(define_split
3605  [(set (match_operand:DI 0 "nonimmediate_operand")
3606	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3607  "!TARGET_64BIT && reload_completed
3608   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3609   && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3610  [(set (match_dup 3) (match_dup 1))
3611   (set (match_dup 4) (const_int 0))]
3612  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3613
3614(define_insn "zero_extend<mode>di2"
3615  [(set (match_operand:DI 0 "register_operand" "=r")
3616	(zero_extend:DI
3617	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3618  "TARGET_64BIT"
3619  "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3620  [(set_attr "type" "imovx")
3621   (set_attr "mode" "SI")])
3622
3623(define_expand "zero_extend<mode>si2"
3624  [(set (match_operand:SI 0 "register_operand")
3625	(zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3626  ""
3627{
3628  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3629    {
3630      operands[1] = force_reg (<MODE>mode, operands[1]);
3631      emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3632      DONE;
3633    }
3634})
3635
3636(define_insn_and_split "zero_extend<mode>si2_and"
3637  [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3638	(zero_extend:SI
3639	  (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3640   (clobber (reg:CC FLAGS_REG))]
3641  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3642  "#"
3643  "&& reload_completed"
3644  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3645	      (clobber (reg:CC FLAGS_REG))])]
3646{
3647  if (true_regnum (operands[0]) != true_regnum (operands[1]))
3648    {
3649      ix86_expand_clear (operands[0]);
3650
3651      gcc_assert (!TARGET_PARTIAL_REG_STALL);
3652      emit_insn (gen_movstrict<mode>
3653		  (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3654      DONE;
3655    }
3656
3657  operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3658}
3659  [(set_attr "type" "alu1")
3660   (set_attr "mode" "SI")])
3661
3662(define_insn "*zero_extend<mode>si2"
3663  [(set (match_operand:SI 0 "register_operand" "=r")
3664	(zero_extend:SI
3665	  (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3666  "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3667  "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3668  [(set_attr "type" "imovx")
3669   (set_attr "mode" "SI")])
3670
3671(define_expand "zero_extendqihi2"
3672  [(set (match_operand:HI 0 "register_operand")
3673	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3674  ""
3675{
3676  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3677    {
3678      operands[1] = force_reg (QImode, operands[1]);
3679      emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3680      DONE;
3681    }
3682})
3683
3684(define_insn_and_split "zero_extendqihi2_and"
3685  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3686	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3687   (clobber (reg:CC FLAGS_REG))]
3688  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3689  "#"
3690  "&& reload_completed"
3691  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3692	      (clobber (reg:CC FLAGS_REG))])]
3693{
3694  if (true_regnum (operands[0]) != true_regnum (operands[1]))
3695    {
3696      ix86_expand_clear (operands[0]);
3697
3698      gcc_assert (!TARGET_PARTIAL_REG_STALL);
3699      emit_insn (gen_movstrictqi
3700		  (gen_lowpart (QImode, operands[0]), operands[1]));
3701      DONE;
3702    }
3703
3704  operands[0] = gen_lowpart (SImode, operands[0]);
3705}
3706  [(set_attr "type" "alu1")
3707   (set_attr "mode" "SI")])
3708
3709; zero extend to SImode to avoid partial register stalls
3710(define_insn "*zero_extendqihi2"
3711  [(set (match_operand:HI 0 "register_operand" "=r")
3712	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3713  "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3714  "movz{bl|x}\t{%1, %k0|%k0, %1}"
3715  [(set_attr "type" "imovx")
3716   (set_attr "mode" "SI")])
3717
3718;; Sign extension instructions
3719
3720(define_expand "extendsidi2"
3721  [(set (match_operand:DI 0 "register_operand")
3722	(sign_extend:DI (match_operand:SI 1 "register_operand")))]
3723  ""
3724{
3725  if (!TARGET_64BIT)
3726    {
3727      emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3728      DONE;
3729    }
3730})
3731
3732(define_insn "*extendsidi2_rex64"
3733  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3734	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3735  "TARGET_64BIT"
3736  "@
3737   {cltq|cdqe}
3738   movs{lq|x}\t{%1, %0|%0, %1}"
3739  [(set_attr "type" "imovx")
3740   (set_attr "mode" "DI")
3741   (set_attr "prefix_0f" "0")
3742   (set_attr "modrm" "0,1")])
3743
3744(define_insn "extendsidi2_1"
3745  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3746	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3747   (clobber (reg:CC FLAGS_REG))
3748   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3749  "!TARGET_64BIT"
3750  "#")
3751
3752;; Split the memory case.  If the source register doesn't die, it will stay
3753;; this way, if it does die, following peephole2s take care of it.
3754(define_split
3755  [(set (match_operand:DI 0 "memory_operand")
3756	(sign_extend:DI (match_operand:SI 1 "register_operand")))
3757   (clobber (reg:CC FLAGS_REG))
3758   (clobber (match_operand:SI 2 "register_operand"))]
3759  "reload_completed"
3760  [(const_int 0)]
3761{
3762  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3763
3764  emit_move_insn (operands[3], operands[1]);
3765
3766  /* Generate a cltd if possible and doing so it profitable.  */
3767  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3768      && true_regnum (operands[1]) == AX_REG
3769      && true_regnum (operands[2]) == DX_REG)
3770    {
3771      emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3772    }
3773  else
3774    {
3775      emit_move_insn (operands[2], operands[1]);
3776      emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3777    }
3778  emit_move_insn (operands[4], operands[2]);
3779  DONE;
3780})
3781
3782;; Peepholes for the case where the source register does die, after
3783;; being split with the above splitter.
3784(define_peephole2
3785  [(set (match_operand:SI 0 "memory_operand")
3786	(match_operand:SI 1 "register_operand"))
3787   (set (match_operand:SI 2 "register_operand") (match_dup 1))
3788   (parallel [(set (match_dup 2)
3789		   (ashiftrt:SI (match_dup 2) (const_int 31)))
3790	       (clobber (reg:CC FLAGS_REG))])
3791   (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3792  "REGNO (operands[1]) != REGNO (operands[2])
3793   && peep2_reg_dead_p (2, operands[1])
3794   && peep2_reg_dead_p (4, operands[2])
3795   && !reg_mentioned_p (operands[2], operands[3])"
3796  [(set (match_dup 0) (match_dup 1))
3797   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3798	      (clobber (reg:CC FLAGS_REG))])
3799   (set (match_dup 3) (match_dup 1))])
3800
3801(define_peephole2
3802  [(set (match_operand:SI 0 "memory_operand")
3803	(match_operand:SI 1 "register_operand"))
3804   (parallel [(set (match_operand:SI 2 "register_operand")
3805		   (ashiftrt:SI (match_dup 1) (const_int 31)))
3806	       (clobber (reg:CC FLAGS_REG))])
3807   (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3808  "/* cltd is shorter than sarl $31, %eax */
3809   !optimize_function_for_size_p (cfun)
3810   && true_regnum (operands[1]) == AX_REG
3811   && true_regnum (operands[2]) == DX_REG
3812   && peep2_reg_dead_p (2, operands[1])
3813   && peep2_reg_dead_p (3, operands[2])
3814   && !reg_mentioned_p (operands[2], operands[3])"
3815  [(set (match_dup 0) (match_dup 1))
3816   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3817	      (clobber (reg:CC FLAGS_REG))])
3818   (set (match_dup 3) (match_dup 1))])
3819
3820;; Extend to register case.  Optimize case where source and destination
3821;; registers match and cases where we can use cltd.
3822(define_split
3823  [(set (match_operand:DI 0 "register_operand")
3824	(sign_extend:DI (match_operand:SI 1 "register_operand")))
3825   (clobber (reg:CC FLAGS_REG))
3826   (clobber (match_scratch:SI 2))]
3827  "reload_completed"
3828  [(const_int 0)]
3829{
3830  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3831
3832  if (true_regnum (operands[3]) != true_regnum (operands[1]))
3833    emit_move_insn (operands[3], operands[1]);
3834
3835  /* Generate a cltd if possible and doing so it profitable.  */
3836  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3837      && true_regnum (operands[3]) == AX_REG
3838      && true_regnum (operands[4]) == DX_REG)
3839    {
3840      emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3841      DONE;
3842    }
3843
3844  if (true_regnum (operands[4]) != true_regnum (operands[1]))
3845    emit_move_insn (operands[4], operands[1]);
3846
3847  emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3848  DONE;
3849})
3850
3851(define_insn "extend<mode>di2"
3852  [(set (match_operand:DI 0 "register_operand" "=r")
3853	(sign_extend:DI
3854	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3855  "TARGET_64BIT"
3856  "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3857  [(set_attr "type" "imovx")
3858   (set_attr "mode" "DI")])
3859
3860(define_insn "extendhisi2"
3861  [(set (match_operand:SI 0 "register_operand" "=*a,r")
3862	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3863  ""
3864{
3865  switch (get_attr_prefix_0f (insn))
3866    {
3867    case 0:
3868      return "{cwtl|cwde}";
3869    default:
3870      return "movs{wl|x}\t{%1, %0|%0, %1}";
3871    }
3872}
3873  [(set_attr "type" "imovx")
3874   (set_attr "mode" "SI")
3875   (set (attr "prefix_0f")
3876     ;; movsx is short decodable while cwtl is vector decoded.
3877     (if_then_else (and (eq_attr "cpu" "!k6")
3878			(eq_attr "alternative" "0"))
3879	(const_string "0")
3880	(const_string "1")))
3881   (set (attr "modrm")
3882     (if_then_else (eq_attr "prefix_0f" "0")
3883	(const_string "0")
3884	(const_string "1")))])
3885
3886(define_insn "*extendhisi2_zext"
3887  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3888	(zero_extend:DI
3889	 (sign_extend:SI
3890	  (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3891  "TARGET_64BIT"
3892{
3893  switch (get_attr_prefix_0f (insn))
3894    {
3895    case 0:
3896      return "{cwtl|cwde}";
3897    default:
3898      return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3899    }
3900}
3901  [(set_attr "type" "imovx")
3902   (set_attr "mode" "SI")
3903   (set (attr "prefix_0f")
3904     ;; movsx is short decodable while cwtl is vector decoded.
3905     (if_then_else (and (eq_attr "cpu" "!k6")
3906			(eq_attr "alternative" "0"))
3907	(const_string "0")
3908	(const_string "1")))
3909   (set (attr "modrm")
3910     (if_then_else (eq_attr "prefix_0f" "0")
3911	(const_string "0")
3912	(const_string "1")))])
3913
3914(define_insn "extendqisi2"
3915  [(set (match_operand:SI 0 "register_operand" "=r")
3916	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3917  ""
3918  "movs{bl|x}\t{%1, %0|%0, %1}"
3919   [(set_attr "type" "imovx")
3920    (set_attr "mode" "SI")])
3921
3922(define_insn "*extendqisi2_zext"
3923  [(set (match_operand:DI 0 "register_operand" "=r")
3924	(zero_extend:DI
3925	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3926  "TARGET_64BIT"
3927  "movs{bl|x}\t{%1, %k0|%k0, %1}"
3928   [(set_attr "type" "imovx")
3929    (set_attr "mode" "SI")])
3930
3931(define_insn "extendqihi2"
3932  [(set (match_operand:HI 0 "register_operand" "=*a,r")
3933	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3934  ""
3935{
3936  switch (get_attr_prefix_0f (insn))
3937    {
3938    case 0:
3939      return "{cbtw|cbw}";
3940    default:
3941      return "movs{bw|x}\t{%1, %0|%0, %1}";
3942    }
3943}
3944  [(set_attr "type" "imovx")
3945   (set_attr "mode" "HI")
3946   (set (attr "prefix_0f")
3947     ;; movsx is short decodable while cwtl is vector decoded.
3948     (if_then_else (and (eq_attr "cpu" "!k6")
3949			(eq_attr "alternative" "0"))
3950	(const_string "0")
3951	(const_string "1")))
3952   (set (attr "modrm")
3953     (if_then_else (eq_attr "prefix_0f" "0")
3954	(const_string "0")
3955	(const_string "1")))])
3956
3957;; Conversions between float and double.
3958
3959;; These are all no-ops in the model used for the 80387.
3960;; So just emit moves.
3961
3962;; %%% Kill these when call knows how to work out a DFmode push earlier.
3963(define_split
3964  [(set (match_operand:DF 0 "push_operand")
3965	(float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3966  "reload_completed"
3967  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3968   (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3969
3970(define_split
3971  [(set (match_operand:XF 0 "push_operand")
3972	(float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3973  "reload_completed"
3974  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3975   (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3976  "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3977
3978(define_expand "extendsfdf2"
3979  [(set (match_operand:DF 0 "nonimmediate_operand")
3980        (float_extend:DF (match_operand:SF 1 "general_operand")))]
3981  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3982{
3983  /* ??? Needed for compress_float_constant since all fp constants
3984     are TARGET_LEGITIMATE_CONSTANT_P.  */
3985  if (GET_CODE (operands[1]) == CONST_DOUBLE)
3986    {
3987      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3988	  && standard_80387_constant_p (operands[1]) > 0)
3989	{
3990	  operands[1] = simplify_const_unary_operation
3991	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3992	  emit_move_insn_1 (operands[0], operands[1]);
3993	  DONE;
3994	}
3995      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3996    }
3997})
3998
3999/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4000   cvtss2sd:
4001      unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4002      cvtps2pd xmm2,xmm1
4003   We do the conversion post reload to avoid producing of 128bit spills
4004   that might lead to ICE on 32bit target.  The sequence unlikely combine
4005   anyway.  */
4006(define_split
4007  [(set (match_operand:DF 0 "register_operand")
4008        (float_extend:DF
4009	  (match_operand:SF 1 "nonimmediate_operand")))]
4010  "TARGET_USE_VECTOR_FP_CONVERTS
4011   && optimize_insn_for_speed_p ()
4012   && reload_completed && SSE_REG_P (operands[0])"
4013   [(set (match_dup 2)
4014	 (float_extend:V2DF
4015	   (vec_select:V2SF
4016	     (match_dup 3)
4017	     (parallel [(const_int 0) (const_int 1)]))))]
4018{
4019  operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4020  operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4021  /* Use movss for loading from memory, unpcklps reg, reg for registers.
4022     Try to avoid move when unpacking can be done in source.  */
4023  if (REG_P (operands[1]))
4024    {
4025      /* If it is unsafe to overwrite upper half of source, we need
4026	 to move to destination and unpack there.  */
4027      if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4028	   || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4029	  && true_regnum (operands[0]) != true_regnum (operands[1]))
4030	{
4031	  rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4032	  emit_move_insn (tmp, operands[1]);
4033	}
4034      else
4035	operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4036      emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4037      		 			     operands[3]));
4038    }
4039  else
4040    emit_insn (gen_vec_setv4sf_0 (operands[3],
4041				  CONST0_RTX (V4SFmode), operands[1]));
4042})
4043
4044;; It's more profitable to split and then extend in the same register.
4045(define_peephole2
4046  [(set (match_operand:DF 0 "register_operand")
4047	(float_extend:DF
4048	  (match_operand:SF 1 "memory_operand")))]
4049  "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4050   && optimize_insn_for_speed_p ()
4051   && SSE_REG_P (operands[0])"
4052  [(set (match_dup 2) (match_dup 1))
4053   (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4054  "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4055
4056(define_insn "*extendsfdf2_mixed"
4057  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4058        (float_extend:DF
4059	  (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4060  "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4061{
4062  switch (which_alternative)
4063    {
4064    case 0:
4065    case 1:
4066      return output_387_reg_move (insn, operands);
4067
4068    case 2:
4069      return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4070
4071    default:
4072      gcc_unreachable ();
4073    }
4074}
4075  [(set_attr "type" "fmov,fmov,ssecvt")
4076   (set_attr "prefix" "orig,orig,maybe_vex")
4077   (set_attr "mode" "SF,XF,DF")])
4078
4079(define_insn "*extendsfdf2_sse"
4080  [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4081        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4082  "TARGET_SSE2 && TARGET_SSE_MATH"
4083  "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4084  [(set_attr "type" "ssecvt")
4085   (set_attr "prefix" "maybe_vex")
4086   (set_attr "mode" "DF")])
4087
4088(define_insn "*extendsfdf2_i387"
4089  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4090        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4091  "TARGET_80387"
4092  "* return output_387_reg_move (insn, operands);"
4093  [(set_attr "type" "fmov")
4094   (set_attr "mode" "SF,XF")])
4095
4096(define_expand "extend<mode>xf2"
4097  [(set (match_operand:XF 0 "nonimmediate_operand")
4098        (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4099  "TARGET_80387"
4100{
4101  /* ??? Needed for compress_float_constant since all fp constants
4102     are TARGET_LEGITIMATE_CONSTANT_P.  */
4103  if (GET_CODE (operands[1]) == CONST_DOUBLE)
4104    {
4105      if (standard_80387_constant_p (operands[1]) > 0)
4106	{
4107	  operands[1] = simplify_const_unary_operation
4108	    (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4109	  emit_move_insn_1 (operands[0], operands[1]);
4110	  DONE;
4111	}
4112      operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4113    }
4114})
4115
4116(define_insn "*extend<mode>xf2_i387"
4117  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4118        (float_extend:XF
4119	  (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4120  "TARGET_80387"
4121  "* return output_387_reg_move (insn, operands);"
4122  [(set_attr "type" "fmov")
4123   (set_attr "mode" "<MODE>,XF")])
4124
4125;; %%% This seems bad bad news.
4126;; This cannot output into an f-reg because there is no way to be sure
4127;; of truncating in that case.  Otherwise this is just like a simple move
4128;; insn.  So we pretend we can output to a reg in order to get better
4129;; register preferencing, but we really use a stack slot.
4130
4131;; Conversion from DFmode to SFmode.
4132
4133(define_expand "truncdfsf2"
4134  [(set (match_operand:SF 0 "nonimmediate_operand")
4135	(float_truncate:SF
4136	  (match_operand:DF 1 "nonimmediate_operand")))]
4137  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4138{
4139  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4140    ;
4141  else if (flag_unsafe_math_optimizations)
4142    ;
4143  else
4144    {
4145      rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4146      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4147      DONE;
4148    }
4149})
4150
4151/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4152   cvtsd2ss:
4153      unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4154      cvtpd2ps xmm2,xmm1
4155   We do the conversion post reload to avoid producing of 128bit spills
4156   that might lead to ICE on 32bit target.  The sequence unlikely combine
4157   anyway.  */
4158(define_split
4159  [(set (match_operand:SF 0 "register_operand")
4160        (float_truncate:SF
4161	  (match_operand:DF 1 "nonimmediate_operand")))]
4162  "TARGET_USE_VECTOR_FP_CONVERTS
4163   && optimize_insn_for_speed_p ()
4164   && reload_completed && SSE_REG_P (operands[0])"
4165   [(set (match_dup 2)
4166	 (vec_concat:V4SF
4167	   (float_truncate:V2SF
4168	     (match_dup 4))
4169	   (match_dup 3)))]
4170{
4171  operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4172  operands[3] = CONST0_RTX (V2SFmode);
4173  operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4174  /* Use movsd for loading from memory, unpcklpd for registers.
4175     Try to avoid move when unpacking can be done in source, or SSE3
4176     movddup is available.  */
4177  if (REG_P (operands[1]))
4178    {
4179      if (!TARGET_SSE3
4180	  && true_regnum (operands[0]) != true_regnum (operands[1])
4181	  && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4182	      || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4183	{
4184	  rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4185	  emit_move_insn (tmp, operands[1]);
4186	  operands[1] = tmp;
4187	}
4188      else if (!TARGET_SSE3)
4189	operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4190      emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4191    }
4192  else
4193    emit_insn (gen_sse2_loadlpd (operands[4],
4194				 CONST0_RTX (V2DFmode), operands[1]));
4195})
4196
4197;; It's more profitable to split and then extend in the same register.
4198(define_peephole2
4199  [(set (match_operand:SF 0 "register_operand")
4200	(float_truncate:SF
4201	  (match_operand:DF 1 "memory_operand")))]
4202  "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4203   && optimize_insn_for_speed_p ()
4204   && SSE_REG_P (operands[0])"
4205  [(set (match_dup 2) (match_dup 1))
4206   (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4207  "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4208
4209(define_expand "truncdfsf2_with_temp"
4210  [(parallel [(set (match_operand:SF 0)
4211		   (float_truncate:SF (match_operand:DF 1)))
4212	      (clobber (match_operand:SF 2))])])
4213
4214(define_insn "*truncdfsf_fast_mixed"
4215  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4216        (float_truncate:SF
4217          (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4218  "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4219{
4220  switch (which_alternative)
4221    {
4222    case 0:
4223      return output_387_reg_move (insn, operands);
4224    case 1:
4225      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4226    default:
4227      gcc_unreachable ();
4228    }
4229}
4230  [(set_attr "type" "fmov,ssecvt")
4231   (set_attr "prefix" "orig,maybe_vex")
4232   (set_attr "mode" "SF")])
4233
4234;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4235;; because nothing we do here is unsafe.
4236(define_insn "*truncdfsf_fast_sse"
4237  [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4238        (float_truncate:SF
4239          (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4240  "TARGET_SSE2 && TARGET_SSE_MATH"
4241  "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4242  [(set_attr "type" "ssecvt")
4243   (set_attr "prefix" "maybe_vex")
4244   (set_attr "mode" "SF")])
4245
4246(define_insn "*truncdfsf_fast_i387"
4247  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4248        (float_truncate:SF
4249          (match_operand:DF 1 "nonimmediate_operand" "f")))]
4250  "TARGET_80387 && flag_unsafe_math_optimizations"
4251  "* return output_387_reg_move (insn, operands);"
4252  [(set_attr "type" "fmov")
4253   (set_attr "mode" "SF")])
4254
4255(define_insn "*truncdfsf_mixed"
4256  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4257	(float_truncate:SF
4258	  (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4259   (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4260  "TARGET_MIX_SSE_I387"
4261{
4262  switch (which_alternative)
4263    {
4264    case 0:
4265      return output_387_reg_move (insn, operands);
4266    case 1:
4267      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4268
4269    default:
4270      return "#";
4271    }
4272}
4273  [(set_attr "isa" "*,sse2,*,*,*")
4274   (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4275   (set_attr "unit" "*,*,i387,i387,i387")
4276   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4277   (set_attr "mode" "SF")])
4278
4279(define_insn "*truncdfsf_i387"
4280  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4281	(float_truncate:SF
4282	  (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4283   (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4284  "TARGET_80387"
4285{
4286  switch (which_alternative)
4287    {
4288    case 0:
4289      return output_387_reg_move (insn, operands);
4290
4291    default:
4292      return "#";
4293    }
4294}
4295  [(set_attr "type" "fmov,multi,multi,multi")
4296   (set_attr "unit" "*,i387,i387,i387")
4297   (set_attr "mode" "SF")])
4298
4299(define_insn "*truncdfsf2_i387_1"
4300  [(set (match_operand:SF 0 "memory_operand" "=m")
4301	(float_truncate:SF
4302	  (match_operand:DF 1 "register_operand" "f")))]
4303  "TARGET_80387
4304   && !(TARGET_SSE2 && TARGET_SSE_MATH)
4305   && !TARGET_MIX_SSE_I387"
4306  "* return output_387_reg_move (insn, operands);"
4307  [(set_attr "type" "fmov")
4308   (set_attr "mode" "SF")])
4309
4310(define_split
4311  [(set (match_operand:SF 0 "register_operand")
4312	(float_truncate:SF
4313	 (match_operand:DF 1 "fp_register_operand")))
4314   (clobber (match_operand 2))]
4315  "reload_completed"
4316  [(set (match_dup 2) (match_dup 1))
4317   (set (match_dup 0) (match_dup 2))]
4318  "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4319
4320;; Conversion from XFmode to {SF,DF}mode
4321
4322(define_expand "truncxf<mode>2"
4323  [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4324		   (float_truncate:MODEF
4325		     (match_operand:XF 1 "register_operand")))
4326	      (clobber (match_dup 2))])]
4327  "TARGET_80387"
4328{
4329  if (flag_unsafe_math_optimizations)
4330    {
4331      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4332      emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4333      if (reg != operands[0])
4334	emit_move_insn (operands[0], reg);
4335      DONE;
4336    }
4337  else
4338    operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4339})
4340
4341(define_insn "*truncxfsf2_mixed"
4342  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4343	(float_truncate:SF
4344	  (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4345   (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4346  "TARGET_80387"
4347{
4348  gcc_assert (!which_alternative);
4349  return output_387_reg_move (insn, operands);
4350}
4351  [(set_attr "type" "fmov,multi,multi,multi")
4352   (set_attr "unit" "*,i387,i387,i387")
4353   (set_attr "mode" "SF")])
4354
4355(define_insn "*truncxfdf2_mixed"
4356  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4357	(float_truncate:DF
4358	  (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4359   (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4360  "TARGET_80387"
4361{
4362  gcc_assert (!which_alternative);
4363  return output_387_reg_move (insn, operands);
4364}
4365  [(set_attr "isa" "*,*,sse2,*")
4366   (set_attr "type" "fmov,multi,multi,multi")
4367   (set_attr "unit" "*,i387,i387,i387")
4368   (set_attr "mode" "DF")])
4369
4370(define_insn "truncxf<mode>2_i387_noop"
4371  [(set (match_operand:MODEF 0 "register_operand" "=f")
4372	(float_truncate:MODEF
4373	  (match_operand:XF 1 "register_operand" "f")))]
4374  "TARGET_80387 && flag_unsafe_math_optimizations"
4375  "* return output_387_reg_move (insn, operands);"
4376  [(set_attr "type" "fmov")
4377   (set_attr "mode" "<MODE>")])
4378
4379(define_insn "*truncxf<mode>2_i387"
4380  [(set (match_operand:MODEF 0 "memory_operand" "=m")
4381	(float_truncate:MODEF
4382	  (match_operand:XF 1 "register_operand" "f")))]
4383  "TARGET_80387"
4384  "* return output_387_reg_move (insn, operands);"
4385  [(set_attr "type" "fmov")
4386   (set_attr "mode" "<MODE>")])
4387
4388(define_split
4389  [(set (match_operand:MODEF 0 "register_operand")
4390	(float_truncate:MODEF
4391	  (match_operand:XF 1 "register_operand")))
4392   (clobber (match_operand:MODEF 2 "memory_operand"))]
4393  "TARGET_80387 && reload_completed"
4394  [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4395   (set (match_dup 0) (match_dup 2))])
4396
4397(define_split
4398  [(set (match_operand:MODEF 0 "memory_operand")
4399	(float_truncate:MODEF
4400	  (match_operand:XF 1 "register_operand")))
4401   (clobber (match_operand:MODEF 2 "memory_operand"))]
4402  "TARGET_80387"
4403  [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4404
4405;; Signed conversion to DImode.
4406
4407(define_expand "fix_truncxfdi2"
4408  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4409                   (fix:DI (match_operand:XF 1 "register_operand")))
4410	      (clobber (reg:CC FLAGS_REG))])]
4411  "TARGET_80387"
4412{
4413  if (TARGET_FISTTP)
4414   {
4415     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4416     DONE;
4417   }
4418})
4419
4420(define_expand "fix_trunc<mode>di2"
4421  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4422                   (fix:DI (match_operand:MODEF 1 "register_operand")))
4423              (clobber (reg:CC FLAGS_REG))])]
4424  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4425{
4426  if (TARGET_FISTTP
4427      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4428   {
4429     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4430     DONE;
4431   }
4432  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4433   {
4434     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4435     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4436     if (out != operands[0])
4437	emit_move_insn (operands[0], out);
4438     DONE;
4439   }
4440})
4441
4442;; Signed conversion to SImode.
4443
4444(define_expand "fix_truncxfsi2"
4445  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4446                   (fix:SI (match_operand:XF 1 "register_operand")))
4447	      (clobber (reg:CC FLAGS_REG))])]
4448  "TARGET_80387"
4449{
4450  if (TARGET_FISTTP)
4451   {
4452     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4453     DONE;
4454   }
4455})
4456
4457(define_expand "fix_trunc<mode>si2"
4458  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4459	           (fix:SI (match_operand:MODEF 1 "register_operand")))
4460	      (clobber (reg:CC FLAGS_REG))])]
4461  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4462{
4463  if (TARGET_FISTTP
4464      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4465   {
4466     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4467     DONE;
4468   }
4469  if (SSE_FLOAT_MODE_P (<MODE>mode))
4470   {
4471     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4472     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4473     if (out != operands[0])
4474	emit_move_insn (operands[0], out);
4475     DONE;
4476   }
4477})
4478
4479;; Signed conversion to HImode.
4480
4481(define_expand "fix_trunc<mode>hi2"
4482  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4483	           (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4484              (clobber (reg:CC FLAGS_REG))])]
4485  "TARGET_80387
4486   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4487{
4488  if (TARGET_FISTTP)
4489   {
4490     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4491     DONE;
4492   }
4493})
4494
4495;; Unsigned conversion to SImode.
4496
4497(define_expand "fixuns_trunc<mode>si2"
4498  [(parallel
4499    [(set (match_operand:SI 0 "register_operand")
4500	  (unsigned_fix:SI
4501	    (match_operand:MODEF 1 "nonimmediate_operand")))
4502     (use (match_dup 2))
4503     (clobber (match_scratch:<ssevecmode> 3))
4504     (clobber (match_scratch:<ssevecmode> 4))])]
4505  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4506{
4507  machine_mode mode = <MODE>mode;
4508  machine_mode vecmode = <ssevecmode>mode;
4509  REAL_VALUE_TYPE TWO31r;
4510  rtx two31;
4511
4512  if (optimize_insn_for_size_p ())
4513    FAIL;
4514
4515  real_ldexp (&TWO31r, &dconst1, 31);
4516  two31 = const_double_from_real_value (TWO31r, mode);
4517  two31 = ix86_build_const_vector (vecmode, true, two31);
4518  operands[2] = force_reg (vecmode, two31);
4519})
4520
4521(define_insn_and_split "*fixuns_trunc<mode>_1"
4522  [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4523	(unsigned_fix:SI
4524	  (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4525   (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4526   (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4527   (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4528  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4529   && optimize_function_for_speed_p (cfun)"
4530  "#"
4531  "&& reload_completed"
4532  [(const_int 0)]
4533{
4534  ix86_split_convert_uns_si_sse (operands);
4535  DONE;
4536})
4537
4538;; Unsigned conversion to HImode.
4539;; Without these patterns, we'll try the unsigned SI conversion which
4540;; is complex for SSE, rather than the signed SI conversion, which isn't.
4541
4542(define_expand "fixuns_trunc<mode>hi2"
4543  [(set (match_dup 2)
4544	(fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4545   (set (match_operand:HI 0 "nonimmediate_operand")
4546	(subreg:HI (match_dup 2) 0))]
4547  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4548  "operands[2] = gen_reg_rtx (SImode);")
4549
4550;; When SSE is available, it is always faster to use it!
4551(define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4552  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4553	(fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4554  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4555   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4556  "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4557  [(set_attr "type" "sseicvt")
4558   (set_attr "prefix" "maybe_vex")
4559   (set (attr "prefix_rex")
4560	(if_then_else
4561	  (match_test "<SWI48:MODE>mode == DImode")
4562	  (const_string "1")
4563	  (const_string "*")))
4564   (set_attr "mode" "<MODEF:MODE>")
4565   (set_attr "athlon_decode" "double,vector")
4566   (set_attr "amdfam10_decode" "double,double")
4567   (set_attr "bdver1_decode" "double,double")])
4568
4569;; Avoid vector decoded forms of the instruction.
4570(define_peephole2
4571  [(match_scratch:MODEF 2 "x")
4572   (set (match_operand:SWI48 0 "register_operand")
4573	(fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4574  "TARGET_AVOID_VECTOR_DECODE
4575   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4576   && optimize_insn_for_speed_p ()"
4577  [(set (match_dup 2) (match_dup 1))
4578   (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4579
4580(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4581  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4582	(fix:SWI248x (match_operand 1 "register_operand")))]
4583  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4584   && TARGET_FISTTP
4585   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4586	 && (TARGET_64BIT || <MODE>mode != DImode))
4587	&& TARGET_SSE_MATH)
4588   && can_create_pseudo_p ()"
4589  "#"
4590  "&& 1"
4591  [(const_int 0)]
4592{
4593  if (memory_operand (operands[0], VOIDmode))
4594    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4595  else
4596    {
4597      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4598      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4599							    operands[1],
4600							    operands[2]));
4601    }
4602  DONE;
4603}
4604  [(set_attr "type" "fisttp")
4605   (set_attr "mode" "<MODE>")])
4606
4607(define_insn "fix_trunc<mode>_i387_fisttp"
4608  [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4609	(fix:SWI248x (match_operand 1 "register_operand" "f")))
4610   (clobber (match_scratch:XF 2 "=&1f"))]
4611  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4612   && TARGET_FISTTP
4613   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4614	 && (TARGET_64BIT || <MODE>mode != DImode))
4615	&& TARGET_SSE_MATH)"
4616  "* return output_fix_trunc (insn, operands, true);"
4617  [(set_attr "type" "fisttp")
4618   (set_attr "mode" "<MODE>")])
4619
4620(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4621  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4622	(fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4623   (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4624   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4625  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4626   && TARGET_FISTTP
4627   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4628	&& (TARGET_64BIT || <MODE>mode != DImode))
4629	&& TARGET_SSE_MATH)"
4630  "#"
4631  [(set_attr "type" "fisttp")
4632   (set_attr "mode" "<MODE>")])
4633
4634(define_split
4635  [(set (match_operand:SWI248x 0 "register_operand")
4636	(fix:SWI248x (match_operand 1 "register_operand")))
4637   (clobber (match_operand:SWI248x 2 "memory_operand"))
4638   (clobber (match_scratch 3))]
4639  "reload_completed"
4640  [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4641	      (clobber (match_dup 3))])
4642   (set (match_dup 0) (match_dup 2))])
4643
4644(define_split
4645  [(set (match_operand:SWI248x 0 "memory_operand")
4646	(fix:SWI248x (match_operand 1 "register_operand")))
4647   (clobber (match_operand:SWI248x 2 "memory_operand"))
4648   (clobber (match_scratch 3))]
4649  "reload_completed"
4650  [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4651	      (clobber (match_dup 3))])])
4652
4653;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4654;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4655;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4656;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4657;; function in i386.c.
4658(define_insn_and_split "*fix_trunc<mode>_i387_1"
4659  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4660	(fix:SWI248x (match_operand 1 "register_operand")))
4661   (clobber (reg:CC FLAGS_REG))]
4662  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4663   && !TARGET_FISTTP
4664   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4665	 && (TARGET_64BIT || <MODE>mode != DImode))
4666   && can_create_pseudo_p ()"
4667  "#"
4668  "&& 1"
4669  [(const_int 0)]
4670{
4671  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4672
4673  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4674  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4675  if (memory_operand (operands[0], VOIDmode))
4676    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4677					 operands[2], operands[3]));
4678  else
4679    {
4680      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4681      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4682						     operands[2], operands[3],
4683						     operands[4]));
4684    }
4685  DONE;
4686}
4687  [(set_attr "type" "fistp")
4688   (set_attr "i387_cw" "trunc")
4689   (set_attr "mode" "<MODE>")])
4690
4691(define_insn "fix_truncdi_i387"
4692  [(set (match_operand:DI 0 "memory_operand" "=m")
4693	(fix:DI (match_operand 1 "register_operand" "f")))
4694   (use (match_operand:HI 2 "memory_operand" "m"))
4695   (use (match_operand:HI 3 "memory_operand" "m"))
4696   (clobber (match_scratch:XF 4 "=&1f"))]
4697  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4698   && !TARGET_FISTTP
4699   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4700  "* return output_fix_trunc (insn, operands, false);"
4701  [(set_attr "type" "fistp")
4702   (set_attr "i387_cw" "trunc")
4703   (set_attr "mode" "DI")])
4704
4705(define_insn "fix_truncdi_i387_with_temp"
4706  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4707	(fix:DI (match_operand 1 "register_operand" "f,f")))
4708   (use (match_operand:HI 2 "memory_operand" "m,m"))
4709   (use (match_operand:HI 3 "memory_operand" "m,m"))
4710   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4711   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4712  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4713   && !TARGET_FISTTP
4714   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4715  "#"
4716  [(set_attr "type" "fistp")
4717   (set_attr "i387_cw" "trunc")
4718   (set_attr "mode" "DI")])
4719
4720(define_split
4721  [(set (match_operand:DI 0 "register_operand")
4722	(fix:DI (match_operand 1 "register_operand")))
4723   (use (match_operand:HI 2 "memory_operand"))
4724   (use (match_operand:HI 3 "memory_operand"))
4725   (clobber (match_operand:DI 4 "memory_operand"))
4726   (clobber (match_scratch 5))]
4727  "reload_completed"
4728  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4729	      (use (match_dup 2))
4730	      (use (match_dup 3))
4731	      (clobber (match_dup 5))])
4732   (set (match_dup 0) (match_dup 4))])
4733
4734(define_split
4735  [(set (match_operand:DI 0 "memory_operand")
4736	(fix:DI (match_operand 1 "register_operand")))
4737   (use (match_operand:HI 2 "memory_operand"))
4738   (use (match_operand:HI 3 "memory_operand"))
4739   (clobber (match_operand:DI 4 "memory_operand"))
4740   (clobber (match_scratch 5))]
4741  "reload_completed"
4742  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4743	      (use (match_dup 2))
4744	      (use (match_dup 3))
4745	      (clobber (match_dup 5))])])
4746
4747(define_insn "fix_trunc<mode>_i387"
4748  [(set (match_operand:SWI24 0 "memory_operand" "=m")
4749	(fix:SWI24 (match_operand 1 "register_operand" "f")))
4750   (use (match_operand:HI 2 "memory_operand" "m"))
4751   (use (match_operand:HI 3 "memory_operand" "m"))]
4752  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4753   && !TARGET_FISTTP
4754   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4755  "* return output_fix_trunc (insn, operands, false);"
4756  [(set_attr "type" "fistp")
4757   (set_attr "i387_cw" "trunc")
4758   (set_attr "mode" "<MODE>")])
4759
4760(define_insn "fix_trunc<mode>_i387_with_temp"
4761  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4762	(fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4763   (use (match_operand:HI 2 "memory_operand" "m,m"))
4764   (use (match_operand:HI 3 "memory_operand" "m,m"))
4765   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4766  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4767   && !TARGET_FISTTP
4768   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4769  "#"
4770  [(set_attr "type" "fistp")
4771   (set_attr "i387_cw" "trunc")
4772   (set_attr "mode" "<MODE>")])
4773
4774(define_split
4775  [(set (match_operand:SWI24 0 "register_operand")
4776	(fix:SWI24 (match_operand 1 "register_operand")))
4777   (use (match_operand:HI 2 "memory_operand"))
4778   (use (match_operand:HI 3 "memory_operand"))
4779   (clobber (match_operand:SWI24 4 "memory_operand"))]
4780  "reload_completed"
4781  [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4782	      (use (match_dup 2))
4783	      (use (match_dup 3))])
4784   (set (match_dup 0) (match_dup 4))])
4785
4786(define_split
4787  [(set (match_operand:SWI24 0 "memory_operand")
4788	(fix:SWI24 (match_operand 1 "register_operand")))
4789   (use (match_operand:HI 2 "memory_operand"))
4790   (use (match_operand:HI 3 "memory_operand"))
4791   (clobber (match_operand:SWI24 4 "memory_operand"))]
4792  "reload_completed"
4793  [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4794	      (use (match_dup 2))
4795	      (use (match_dup 3))])])
4796
4797(define_insn "x86_fnstcw_1"
4798  [(set (match_operand:HI 0 "memory_operand" "=m")
4799	(unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4800  "TARGET_80387"
4801  "fnstcw\t%0"
4802  [(set (attr "length")
4803	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4804   (set_attr "mode" "HI")
4805   (set_attr "unit" "i387")
4806   (set_attr "bdver1_decode" "vector")])
4807
4808(define_insn "x86_fldcw_1"
4809  [(set (reg:HI FPCR_REG)
4810	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4811  "TARGET_80387"
4812  "fldcw\t%0"
4813  [(set (attr "length")
4814	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4815   (set_attr "mode" "HI")
4816   (set_attr "unit" "i387")
4817   (set_attr "athlon_decode" "vector")
4818   (set_attr "amdfam10_decode" "vector")
4819   (set_attr "bdver1_decode" "vector")])
4820
4821;; Conversion between fixed point and floating point.
4822
4823;; Even though we only accept memory inputs, the backend _really_
4824;; wants to be able to do this between registers.  Thankfully, LRA
4825;; will fix this up for us during register allocation.
4826
4827(define_insn "floathi<mode>2"
4828  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4829	(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4830  "TARGET_80387
4831   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4832       || TARGET_MIX_SSE_I387)"
4833  "fild%Z1\t%1"
4834  [(set_attr "type" "fmov")
4835   (set_attr "mode" "<MODE>")
4836   (set_attr "fp_int_src" "true")])
4837
4838(define_insn "float<SWI48x:mode>xf2"
4839  [(set (match_operand:XF 0 "register_operand" "=f")
4840	(float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4841  "TARGET_80387"
4842  "fild%Z1\t%1"
4843  [(set_attr "type" "fmov")
4844   (set_attr "mode" "XF")
4845   (set_attr "fp_int_src" "true")])
4846
4847(define_expand "float<SWI48:mode><MODEF:mode>2"
4848  [(set (match_operand:MODEF 0 "register_operand")
4849	(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4850  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4851{
4852  if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4853      && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4854    {
4855      rtx reg = gen_reg_rtx (XFmode);
4856      rtx (*insn)(rtx, rtx);
4857
4858      emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4859
4860      if (<MODEF:MODE>mode == SFmode)
4861	insn = gen_truncxfsf2;
4862      else if (<MODEF:MODE>mode == DFmode)
4863	insn = gen_truncxfdf2;
4864      else
4865	gcc_unreachable ();
4866
4867      emit_insn (insn (operands[0], reg));
4868      DONE;
4869    }
4870})
4871
4872(define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4873  [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4874	(float:MODEF
4875	  (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4876  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4877  "@
4878   fild%Z1\t%1
4879   %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4880   %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4881  [(set_attr "type" "fmov,sseicvt,sseicvt")
4882   (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4883   (set_attr "mode" "<MODEF:MODE>")
4884   (set (attr "prefix_rex")
4885     (if_then_else
4886       (and (eq_attr "prefix" "maybe_vex")
4887	    (match_test "<SWI48:MODE>mode == DImode"))
4888       (const_string "1")
4889       (const_string "*")))
4890   (set_attr "unit" "i387,*,*")
4891   (set_attr "athlon_decode" "*,double,direct")
4892   (set_attr "amdfam10_decode" "*,vector,double")
4893   (set_attr "bdver1_decode" "*,double,direct")
4894   (set_attr "fp_int_src" "true")
4895   (set (attr "enabled")
4896     (cond [(eq_attr "alternative" "0")
4897              (symbol_ref "TARGET_MIX_SSE_I387
4898                           && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4899                                                <SWI48:MODE>mode)")
4900           ]
4901           (symbol_ref "true")))
4902   (set (attr "preferred_for_speed")
4903     (cond [(eq_attr "alternative" "1")
4904              (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4905           (symbol_ref "true")))])
4906
4907(define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4908  [(set (match_operand:MODEF 0 "register_operand" "=f")
4909	(float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4910  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4911  "fild%Z1\t%1"
4912  [(set_attr "type" "fmov")
4913   (set_attr "mode" "<MODEF:MODE>")
4914   (set_attr "fp_int_src" "true")])
4915
4916;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4917;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4918;; alternative in sse2_loadld.
4919(define_split
4920  [(set (match_operand:MODEF 0 "register_operand")
4921	(float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4922  "TARGET_SSE2 && TARGET_SSE_MATH
4923   && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4924   && reload_completed && SSE_REG_P (operands[0])
4925   && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4926  [(const_int 0)]
4927{
4928  operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4929				     <MODE>mode, 0);
4930  operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4931
4932  emit_insn (gen_sse2_loadld (operands[4],
4933			      CONST0_RTX (V4SImode), operands[1]));
4934
4935  if (<ssevecmode>mode == V4SFmode)
4936    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4937  else
4938    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4939  DONE;
4940})
4941
4942;; Avoid partial SSE register dependency stalls
4943(define_split
4944  [(set (match_operand:MODEF 0 "register_operand")
4945	(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4946  "TARGET_SSE2 && TARGET_SSE_MATH
4947   && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4948   && optimize_function_for_speed_p (cfun)
4949   && reload_completed && SSE_REG_P (operands[0])"
4950  [(const_int 0)]
4951{
4952  const machine_mode vmode = <MODEF:ssevecmode>mode;
4953  const machine_mode mode = <MODEF:MODE>mode;
4954  rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4955
4956  emit_move_insn (op0, CONST0_RTX (vmode));
4957
4958  t = gen_rtx_FLOAT (mode, operands[1]);
4959  t = gen_rtx_VEC_DUPLICATE (vmode, t);
4960  t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4961  emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4962  DONE;
4963})
4964
4965;; Break partial reg stall for cvtsd2ss.
4966
4967(define_peephole2
4968  [(set (match_operand:SF 0 "register_operand")
4969        (float_truncate:SF
4970	  (match_operand:DF 1 "nonimmediate_operand")))]
4971  "TARGET_SSE2 && TARGET_SSE_MATH
4972   && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4973   && optimize_function_for_speed_p (cfun)
4974   && SSE_REG_P (operands[0])
4975   && (!SSE_REG_P (operands[1])
4976       || REGNO (operands[0]) != REGNO (operands[1]))"
4977  [(set (match_dup 0)
4978	(vec_merge:V4SF
4979	  (vec_duplicate:V4SF
4980	    (float_truncate:V2SF
4981	      (match_dup 1)))
4982	  (match_dup 0)
4983	  (const_int 1)))]
4984{
4985  operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4986				     SFmode, 0);
4987  operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4988				     DFmode, 0);
4989  emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4990})
4991
4992;; Break partial reg stall for cvtss2sd.
4993
4994(define_peephole2
4995  [(set (match_operand:DF 0 "register_operand")
4996        (float_extend:DF
4997          (match_operand:SF 1 "nonimmediate_operand")))]
4998  "TARGET_SSE2 && TARGET_SSE_MATH
4999   && TARGET_SSE_PARTIAL_REG_DEPENDENCY
5000   && optimize_function_for_speed_p (cfun)
5001   && SSE_REG_P (operands[0])
5002   && (!SSE_REG_P (operands[1])
5003       || REGNO (operands[0]) != REGNO (operands[1]))"
5004  [(set (match_dup 0)
5005        (vec_merge:V2DF
5006          (float_extend:V2DF
5007            (vec_select:V2SF
5008              (match_dup 1)
5009              (parallel [(const_int 0) (const_int 1)])))
5010          (match_dup 0)
5011          (const_int 1)))]
5012{
5013  operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
5014				     DFmode, 0);
5015  operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
5016				     SFmode, 0);
5017  emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5018})
5019
5020;; Avoid store forwarding (partial memory) stall penalty
5021;; by passing DImode value through XMM registers.  */
5022
5023(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5024  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5025	(float:X87MODEF
5026	  (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5027   (clobber (match_scratch:V4SI 3 "=X,x"))
5028   (clobber (match_scratch:V4SI 4 "=X,x"))
5029   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5030  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5031   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5032   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5033  "#"
5034  [(set_attr "type" "multi")
5035   (set_attr "mode" "<X87MODEF:MODE>")
5036   (set_attr "unit" "i387")
5037   (set_attr "fp_int_src" "true")])
5038
5039(define_split
5040  [(set (match_operand:X87MODEF 0 "fp_register_operand")
5041	(float:X87MODEF (match_operand:DI 1 "register_operand")))
5042   (clobber (match_scratch:V4SI 3))
5043   (clobber (match_scratch:V4SI 4))
5044   (clobber (match_operand:DI 2 "memory_operand"))]
5045  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5046   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5047   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5048   && reload_completed"
5049  [(set (match_dup 2) (match_dup 3))
5050   (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5051{
5052  /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5053     Assemble the 64-bit DImode value in an xmm register.  */
5054  emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5055			      gen_lowpart (SImode, operands[1])));
5056  emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5057			      gen_highpart (SImode, operands[1])));
5058  emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5059					 operands[4]));
5060
5061  operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5062})
5063
5064(define_split
5065  [(set (match_operand:X87MODEF 0 "fp_register_operand")
5066	(float:X87MODEF (match_operand:DI 1 "memory_operand")))
5067   (clobber (match_scratch:V4SI 3))
5068   (clobber (match_scratch:V4SI 4))
5069   (clobber (match_operand:DI 2 "memory_operand"))]
5070  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5071   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5072   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5073   && reload_completed"
5074  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5075
5076(define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5077  [(set (match_operand:MODEF 0 "register_operand")
5078	(unsigned_float:MODEF
5079	  (match_operand:SWI12 1 "nonimmediate_operand")))]
5080  "!TARGET_64BIT
5081   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5082{
5083  operands[1] = convert_to_mode (SImode, operands[1], 1);
5084  emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5085  DONE;
5086})
5087
5088;; Avoid store forwarding (partial memory) stall penalty by extending
5089;; SImode value to DImode through XMM register instead of pushing two
5090;; SImode values to stack. Also note that fild loads from memory only.
5091
5092(define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5093  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5094	(unsigned_float:X87MODEF
5095	  (match_operand:SI 1 "nonimmediate_operand" "rm")))
5096   (clobber (match_scratch:DI 3 "=x"))
5097   (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5098  "!TARGET_64BIT
5099   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5100   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5101  "#"
5102  "&& reload_completed"
5103  [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5104   (set (match_dup 2) (match_dup 3))
5105   (set (match_dup 0)
5106	(float:X87MODEF (match_dup 2)))]
5107  ""
5108  [(set_attr "type" "multi")
5109   (set_attr "mode" "<MODE>")])
5110
5111(define_expand "floatunssi<mode>2"
5112  [(parallel
5113     [(set (match_operand:X87MODEF 0 "register_operand")
5114	   (unsigned_float:X87MODEF
5115	     (match_operand:SI 1 "nonimmediate_operand")))
5116      (clobber (match_scratch:DI 3))
5117      (clobber (match_dup 2))])]
5118  "!TARGET_64BIT
5119   && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5120	&& TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5121       || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5122{
5123  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5124    {
5125      ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5126      DONE;
5127    }
5128  else
5129    operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5130})
5131
5132(define_expand "floatunsdisf2"
5133  [(use (match_operand:SF 0 "register_operand"))
5134   (use (match_operand:DI 1 "nonimmediate_operand"))]
5135  "TARGET_64BIT && TARGET_SSE_MATH"
5136  "x86_emit_floatuns (operands); DONE;")
5137
5138(define_expand "floatunsdidf2"
5139  [(use (match_operand:DF 0 "register_operand"))
5140   (use (match_operand:DI 1 "nonimmediate_operand"))]
5141  "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5142   && TARGET_SSE2 && TARGET_SSE_MATH"
5143{
5144  if (TARGET_64BIT)
5145    x86_emit_floatuns (operands);
5146  else
5147    ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5148  DONE;
5149})
5150
5151;; Load effective address instructions
5152
5153(define_insn_and_split "*lea<mode>"
5154  [(set (match_operand:SWI48 0 "register_operand" "=r")
5155	(match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5156  ""
5157{
5158  if (SImode_address_operand (operands[1], VOIDmode))
5159    {
5160      gcc_assert (TARGET_64BIT);
5161      return "lea{l}\t{%E1, %k0|%k0, %E1}";
5162    }
5163  else 
5164    return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5165}
5166  "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5167  [(const_int 0)]
5168{
5169  machine_mode mode = <MODE>mode;
5170  rtx pat;
5171
5172  /* ix86_avoid_lea_for_addr re-recognizes insn and may
5173     change operands[] array behind our back.  */
5174  pat = PATTERN (curr_insn);
5175
5176  operands[0] = SET_DEST (pat);
5177  operands[1] = SET_SRC (pat);
5178
5179  /* Emit all operations in SImode for zero-extended addresses.  */
5180  if (SImode_address_operand (operands[1], VOIDmode))
5181    mode = SImode;
5182
5183  ix86_split_lea_for_addr (curr_insn, operands, mode);
5184
5185  /* Zero-extend return register to DImode for zero-extended addresses.  */
5186  if (mode != <MODE>mode)
5187    emit_insn (gen_zero_extendsidi2
5188    	       (operands[0], gen_lowpart (mode, operands[0])));
5189
5190  DONE;
5191}
5192  [(set_attr "type" "lea")
5193   (set (attr "mode")
5194     (if_then_else
5195       (match_operand 1 "SImode_address_operand")
5196       (const_string "SI")
5197       (const_string "<MODE>")))])
5198
5199;; Add instructions
5200
5201(define_expand "add<mode>3"
5202  [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5203	(plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5204		    (match_operand:SDWIM 2 "<general_operand>")))]
5205  ""
5206  "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5207
5208(define_insn_and_split "*add<dwi>3_doubleword"
5209  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5210	(plus:<DWI>
5211	  (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5212	  (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5213   (clobber (reg:CC FLAGS_REG))]
5214  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5215  "#"
5216  "reload_completed"
5217  [(parallel [(set (reg:CCC FLAGS_REG)
5218		   (compare:CCC
5219		     (plus:DWIH (match_dup 1) (match_dup 2))
5220		     (match_dup 1)))
5221	      (set (match_dup 0)
5222		   (plus:DWIH (match_dup 1) (match_dup 2)))])
5223   (parallel [(set (match_dup 3)
5224		   (plus:DWIH
5225		     (plus:DWIH
5226		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5227		       (match_dup 4))
5228		     (match_dup 5)))
5229	      (clobber (reg:CC FLAGS_REG))])]
5230  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5231
5232(define_insn "*add<mode>_1"
5233  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5234	(plus:SWI48
5235	  (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5236	  (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5237   (clobber (reg:CC FLAGS_REG))]
5238  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5239{
5240  switch (get_attr_type (insn))
5241    {
5242    case TYPE_LEA:
5243      return "#";
5244
5245    case TYPE_INCDEC:
5246      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5247      if (operands[2] == const1_rtx)
5248        return "inc{<imodesuffix>}\t%0";
5249      else
5250        {
5251	  gcc_assert (operands[2] == constm1_rtx);
5252          return "dec{<imodesuffix>}\t%0";
5253	}
5254
5255    default:
5256      /* For most processors, ADD is faster than LEA.  This alternative
5257	 was added to use ADD as much as possible.  */
5258      if (which_alternative == 2)
5259        std::swap (operands[1], operands[2]);
5260        
5261      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5262      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5263        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5264
5265      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5266    }
5267}
5268  [(set (attr "type")
5269     (cond [(eq_attr "alternative" "3")
5270              (const_string "lea")
5271	    (match_operand:SWI48 2 "incdec_operand")
5272	      (const_string "incdec")
5273	   ]
5274	   (const_string "alu")))
5275   (set (attr "length_immediate")
5276      (if_then_else
5277	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5278	(const_string "1")
5279	(const_string "*")))
5280   (set_attr "mode" "<MODE>")])
5281
5282;; It may seem that nonimmediate operand is proper one for operand 1.
5283;; The addsi_1 pattern allows nonimmediate operand at that place and
5284;; we take care in ix86_binary_operator_ok to not allow two memory
5285;; operands so proper swapping will be done in reload.  This allow
5286;; patterns constructed from addsi_1 to match.
5287
5288(define_insn "addsi_1_zext"
5289  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5290	(zero_extend:DI
5291	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5292		   (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5293   (clobber (reg:CC FLAGS_REG))]
5294  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5295{
5296  switch (get_attr_type (insn))
5297    {
5298    case TYPE_LEA:
5299      return "#";
5300
5301    case TYPE_INCDEC:
5302      if (operands[2] == const1_rtx)
5303        return "inc{l}\t%k0";
5304      else
5305        {
5306	  gcc_assert (operands[2] == constm1_rtx);
5307          return "dec{l}\t%k0";
5308	}
5309
5310    default:
5311      /* For most processors, ADD is faster than LEA.  This alternative
5312	 was added to use ADD as much as possible.  */
5313      if (which_alternative == 1)
5314        std::swap (operands[1], operands[2]);
5315
5316      if (x86_maybe_negate_const_int (&operands[2], SImode))
5317        return "sub{l}\t{%2, %k0|%k0, %2}";
5318
5319      return "add{l}\t{%2, %k0|%k0, %2}";
5320    }
5321}
5322  [(set (attr "type")
5323     (cond [(eq_attr "alternative" "2")
5324	      (const_string "lea")
5325	    (match_operand:SI 2 "incdec_operand")
5326	      (const_string "incdec")
5327	   ]
5328	   (const_string "alu")))
5329   (set (attr "length_immediate")
5330      (if_then_else
5331	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5332	(const_string "1")
5333	(const_string "*")))
5334   (set_attr "mode" "SI")])
5335
5336(define_insn "*addhi_1"
5337  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5338	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5339		 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5340   (clobber (reg:CC FLAGS_REG))]
5341  "ix86_binary_operator_ok (PLUS, HImode, operands)"
5342{
5343  switch (get_attr_type (insn))
5344    {
5345    case TYPE_LEA:
5346      return "#";
5347
5348    case TYPE_INCDEC:
5349      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5350      if (operands[2] == const1_rtx)
5351	return "inc{w}\t%0";
5352      else
5353	{
5354	  gcc_assert (operands[2] == constm1_rtx);
5355	  return "dec{w}\t%0";
5356	}
5357
5358    default:
5359      /* For most processors, ADD is faster than LEA.  This alternative
5360	 was added to use ADD as much as possible.  */
5361      if (which_alternative == 2)
5362        std::swap (operands[1], operands[2]);
5363
5364      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5365      if (x86_maybe_negate_const_int (&operands[2], HImode))
5366	return "sub{w}\t{%2, %0|%0, %2}";
5367
5368      return "add{w}\t{%2, %0|%0, %2}";
5369    }
5370}
5371  [(set (attr "type")
5372     (cond [(eq_attr "alternative" "3")
5373              (const_string "lea")
5374	    (match_operand:HI 2 "incdec_operand")
5375	      (const_string "incdec")
5376	   ]
5377	   (const_string "alu")))
5378   (set (attr "length_immediate")
5379      (if_then_else
5380	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5381	(const_string "1")
5382	(const_string "*")))
5383   (set_attr "mode" "HI,HI,HI,SI")])
5384
5385;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5386(define_insn "*addqi_1"
5387  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5388	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5389		 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5390   (clobber (reg:CC FLAGS_REG))]
5391  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5392{
5393  bool widen = (which_alternative == 3 || which_alternative == 4);
5394
5395  switch (get_attr_type (insn))
5396    {
5397    case TYPE_LEA:
5398      return "#";
5399
5400    case TYPE_INCDEC:
5401      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5402      if (operands[2] == const1_rtx)
5403	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5404      else
5405	{
5406	  gcc_assert (operands[2] == constm1_rtx);
5407	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5408	}
5409
5410    default:
5411      /* For most processors, ADD is faster than LEA.  These alternatives
5412	 were added to use ADD as much as possible.  */
5413      if (which_alternative == 2 || which_alternative == 4)
5414        std::swap (operands[1], operands[2]);
5415
5416      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417      if (x86_maybe_negate_const_int (&operands[2], QImode))
5418	{
5419	  if (widen)
5420	    return "sub{l}\t{%2, %k0|%k0, %2}";
5421	  else
5422	    return "sub{b}\t{%2, %0|%0, %2}";
5423	}
5424      if (widen)
5425        return "add{l}\t{%k2, %k0|%k0, %k2}";
5426      else
5427        return "add{b}\t{%2, %0|%0, %2}";
5428    }
5429}
5430  [(set (attr "type")
5431     (cond [(eq_attr "alternative" "5")
5432              (const_string "lea")
5433	    (match_operand:QI 2 "incdec_operand")
5434	      (const_string "incdec")
5435	   ]
5436	   (const_string "alu")))
5437   (set (attr "length_immediate")
5438      (if_then_else
5439	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5440	(const_string "1")
5441	(const_string "*")))
5442   (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5443
5444(define_insn "*addqi_1_slp"
5445  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5446	(plus:QI (match_dup 0)
5447		 (match_operand:QI 1 "general_operand" "qn,qm")))
5448   (clobber (reg:CC FLAGS_REG))]
5449  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5450   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5451{
5452  switch (get_attr_type (insn))
5453    {
5454    case TYPE_INCDEC:
5455      if (operands[1] == const1_rtx)
5456	return "inc{b}\t%0";
5457      else
5458	{
5459	  gcc_assert (operands[1] == constm1_rtx);
5460	  return "dec{b}\t%0";
5461	}
5462
5463    default:
5464      if (x86_maybe_negate_const_int (&operands[1], QImode))
5465	return "sub{b}\t{%1, %0|%0, %1}";
5466
5467      return "add{b}\t{%1, %0|%0, %1}";
5468    }
5469}
5470  [(set (attr "type")
5471     (if_then_else (match_operand:QI 1 "incdec_operand")
5472	(const_string "incdec")
5473	(const_string "alu1")))
5474   (set (attr "memory")
5475     (if_then_else (match_operand 1 "memory_operand")
5476        (const_string "load")
5477        (const_string "none")))
5478   (set_attr "mode" "QI")])
5479
5480;; Split non destructive adds if we cannot use lea.
5481(define_split
5482  [(set (match_operand:SWI48 0 "register_operand")
5483	(plus:SWI48 (match_operand:SWI48 1 "register_operand")
5484		    (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5485   (clobber (reg:CC FLAGS_REG))]
5486  "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5487  [(set (match_dup 0) (match_dup 1))
5488   (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5489	      (clobber (reg:CC FLAGS_REG))])])
5490
5491;; Convert add to the lea pattern to avoid flags dependency.
5492(define_split
5493  [(set (match_operand:SWI 0 "register_operand")
5494	(plus:SWI (match_operand:SWI 1 "register_operand")
5495		  (match_operand:SWI 2 "<nonmemory_operand>")))
5496   (clobber (reg:CC FLAGS_REG))]
5497  "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5498  [(const_int 0)]
5499{
5500  machine_mode mode = <MODE>mode;
5501  rtx pat;
5502
5503  if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5504    { 
5505      mode = SImode; 
5506      operands[0] = gen_lowpart (mode, operands[0]);
5507      operands[1] = gen_lowpart (mode, operands[1]);
5508      operands[2] = gen_lowpart (mode, operands[2]);
5509    }
5510
5511  pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5512
5513  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5514  DONE;
5515})
5516
5517;; Split non destructive adds if we cannot use lea.
5518(define_split
5519  [(set (match_operand:DI 0 "register_operand")
5520  	(zero_extend:DI
5521	  (plus:SI (match_operand:SI 1 "register_operand")
5522		   (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5523   (clobber (reg:CC FLAGS_REG))]
5524  "TARGET_64BIT
5525   && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5526  [(set (match_dup 3) (match_dup 1))
5527   (parallel [(set (match_dup 0)
5528   	     	   (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5529	      (clobber (reg:CC FLAGS_REG))])]
5530  "operands[3] = gen_lowpart (SImode, operands[0]);")
5531
5532;; Convert add to the lea pattern to avoid flags dependency.
5533(define_split
5534  [(set (match_operand:DI 0 "register_operand")
5535	(zero_extend:DI
5536	  (plus:SI (match_operand:SI 1 "register_operand")
5537		   (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5538   (clobber (reg:CC FLAGS_REG))]
5539  "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5540  [(set (match_dup 0)
5541	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5542
5543(define_insn "*add<mode>_2"
5544  [(set (reg FLAGS_REG)
5545	(compare
5546	  (plus:SWI
5547	    (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5548	    (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5549	  (const_int 0)))
5550   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5551	(plus:SWI (match_dup 1) (match_dup 2)))]
5552  "ix86_match_ccmode (insn, CCGOCmode)
5553   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5554{
5555  switch (get_attr_type (insn))
5556    {
5557    case TYPE_INCDEC:
5558      if (operands[2] == const1_rtx)
5559        return "inc{<imodesuffix>}\t%0";
5560      else
5561        {
5562	  gcc_assert (operands[2] == constm1_rtx);
5563          return "dec{<imodesuffix>}\t%0";
5564	}
5565
5566    default:
5567      if (which_alternative == 2)
5568        std::swap (operands[1], operands[2]);
5569        
5570      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5571      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5572        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5573
5574      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5575    }
5576}
5577  [(set (attr "type")
5578     (if_then_else (match_operand:SWI 2 "incdec_operand")
5579	(const_string "incdec")
5580	(const_string "alu")))
5581   (set (attr "length_immediate")
5582      (if_then_else
5583	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5584	(const_string "1")
5585	(const_string "*")))
5586   (set_attr "mode" "<MODE>")])
5587
5588;; See comment for addsi_1_zext why we do use nonimmediate_operand
5589(define_insn "*addsi_2_zext"
5590  [(set (reg FLAGS_REG)
5591	(compare
5592	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5593		   (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5594	  (const_int 0)))
5595   (set (match_operand:DI 0 "register_operand" "=r,r")
5596	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5597  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5598   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5599{
5600  switch (get_attr_type (insn))
5601    {
5602    case TYPE_INCDEC:
5603      if (operands[2] == const1_rtx)
5604        return "inc{l}\t%k0";
5605      else
5606	{
5607	  gcc_assert (operands[2] == constm1_rtx);
5608          return "dec{l}\t%k0";
5609	}
5610
5611    default:
5612      if (which_alternative == 1)
5613        std::swap (operands[1], operands[2]);
5614
5615      if (x86_maybe_negate_const_int (&operands[2], SImode))
5616        return "sub{l}\t{%2, %k0|%k0, %2}";
5617
5618      return "add{l}\t{%2, %k0|%k0, %2}";
5619    }
5620}
5621  [(set (attr "type")
5622     (if_then_else (match_operand:SI 2 "incdec_operand")
5623	(const_string "incdec")
5624	(const_string "alu")))
5625   (set (attr "length_immediate")
5626      (if_then_else
5627	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5628	(const_string "1")
5629	(const_string "*")))
5630   (set_attr "mode" "SI")])
5631
5632(define_insn "*add<mode>_3"
5633  [(set (reg FLAGS_REG)
5634	(compare
5635	  (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5636	  (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5637   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5638  "ix86_match_ccmode (insn, CCZmode)
5639   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5640{
5641  switch (get_attr_type (insn))
5642    {
5643    case TYPE_INCDEC:
5644      if (operands[2] == const1_rtx)
5645        return "inc{<imodesuffix>}\t%0";
5646      else
5647        {
5648	  gcc_assert (operands[2] == constm1_rtx);
5649          return "dec{<imodesuffix>}\t%0";
5650	}
5651
5652    default:
5653      if (which_alternative == 1)
5654        std::swap (operands[1], operands[2]);
5655
5656      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5657      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5658        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5659
5660      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5661    }
5662}
5663  [(set (attr "type")
5664     (if_then_else (match_operand:SWI 2 "incdec_operand")
5665	(const_string "incdec")
5666	(const_string "alu")))
5667   (set (attr "length_immediate")
5668      (if_then_else
5669	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5670	(const_string "1")
5671	(const_string "*")))
5672   (set_attr "mode" "<MODE>")])
5673
5674;; See comment for addsi_1_zext why we do use nonimmediate_operand
5675(define_insn "*addsi_3_zext"
5676  [(set (reg FLAGS_REG)
5677	(compare
5678	  (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5679	  (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5680   (set (match_operand:DI 0 "register_operand" "=r,r")
5681	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5682  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5683   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5684{
5685  switch (get_attr_type (insn))
5686    {
5687    case TYPE_INCDEC:
5688      if (operands[2] == const1_rtx)
5689        return "inc{l}\t%k0";
5690      else
5691        {
5692	  gcc_assert (operands[2] == constm1_rtx);
5693          return "dec{l}\t%k0";
5694	}
5695
5696    default:
5697      if (which_alternative == 1)
5698        std::swap (operands[1], operands[2]);
5699
5700      if (x86_maybe_negate_const_int (&operands[2], SImode))
5701        return "sub{l}\t{%2, %k0|%k0, %2}";
5702
5703      return "add{l}\t{%2, %k0|%k0, %2}";
5704    }
5705}
5706  [(set (attr "type")
5707     (if_then_else (match_operand:SI 2 "incdec_operand")
5708	(const_string "incdec")
5709	(const_string "alu")))
5710   (set (attr "length_immediate")
5711      (if_then_else
5712	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5713	(const_string "1")
5714	(const_string "*")))
5715   (set_attr "mode" "SI")])
5716
5717; For comparisons against 1, -1 and 128, we may generate better code
5718; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5719; is matched then.  We can't accept general immediate, because for
5720; case of overflows,  the result is messed up.
5721; Also carry flag is reversed compared to cmp, so this conversion is valid
5722; only for comparisons not depending on it.
5723
5724(define_insn "*adddi_4"
5725  [(set (reg FLAGS_REG)
5726	(compare
5727	  (match_operand:DI 1 "nonimmediate_operand" "0")
5728	  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5729   (clobber (match_scratch:DI 0 "=rm"))]
5730  "TARGET_64BIT
5731   && ix86_match_ccmode (insn, CCGCmode)"
5732{
5733  switch (get_attr_type (insn))
5734    {
5735    case TYPE_INCDEC:
5736      if (operands[2] == constm1_rtx)
5737        return "inc{q}\t%0";
5738      else
5739        {
5740	  gcc_assert (operands[2] == const1_rtx);
5741          return "dec{q}\t%0";
5742	}
5743
5744    default:
5745      if (x86_maybe_negate_const_int (&operands[2], DImode))
5746	return "add{q}\t{%2, %0|%0, %2}";
5747
5748      return "sub{q}\t{%2, %0|%0, %2}";
5749    }
5750}
5751  [(set (attr "type")
5752     (if_then_else (match_operand:DI 2 "incdec_operand")
5753	(const_string "incdec")
5754	(const_string "alu")))
5755   (set (attr "length_immediate")
5756      (if_then_else
5757	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5758	(const_string "1")
5759	(const_string "*")))
5760   (set_attr "mode" "DI")])
5761
5762; For comparisons against 1, -1 and 128, we may generate better code
5763; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5764; is matched then.  We can't accept general immediate, because for
5765; case of overflows,  the result is messed up.
5766; Also carry flag is reversed compared to cmp, so this conversion is valid
5767; only for comparisons not depending on it.
5768
5769(define_insn "*add<mode>_4"
5770  [(set (reg FLAGS_REG)
5771	(compare
5772	  (match_operand:SWI124 1 "nonimmediate_operand" "0")
5773	  (match_operand:SWI124 2 "const_int_operand" "n")))
5774   (clobber (match_scratch:SWI124 0 "=<r>m"))]
5775  "ix86_match_ccmode (insn, CCGCmode)"
5776{
5777  switch (get_attr_type (insn))
5778    {
5779    case TYPE_INCDEC:
5780      if (operands[2] == constm1_rtx)
5781        return "inc{<imodesuffix>}\t%0";
5782      else
5783        {
5784	  gcc_assert (operands[2] == const1_rtx);
5785          return "dec{<imodesuffix>}\t%0";
5786	}
5787
5788    default:
5789      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5790	return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5791
5792      return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5793    }
5794}
5795  [(set (attr "type")
5796     (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5797	(const_string "incdec")
5798	(const_string "alu")))
5799   (set (attr "length_immediate")
5800      (if_then_else
5801	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5802	(const_string "1")
5803	(const_string "*")))
5804   (set_attr "mode" "<MODE>")])
5805
5806(define_insn "*add<mode>_5"
5807  [(set (reg FLAGS_REG)
5808	(compare
5809	  (plus:SWI
5810	    (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5811	    (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5812	  (const_int 0)))
5813   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5814  "ix86_match_ccmode (insn, CCGOCmode)
5815   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5816{
5817  switch (get_attr_type (insn))
5818    {
5819    case TYPE_INCDEC:
5820      if (operands[2] == const1_rtx)
5821        return "inc{<imodesuffix>}\t%0";
5822      else
5823        {
5824          gcc_assert (operands[2] == constm1_rtx);
5825          return "dec{<imodesuffix>}\t%0";
5826	}
5827
5828    default:
5829      if (which_alternative == 1)
5830        std::swap (operands[1], operands[2]);
5831
5832      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5833      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5834        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5835
5836      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5837    }
5838}
5839  [(set (attr "type")
5840     (if_then_else (match_operand:SWI 2 "incdec_operand")
5841	(const_string "incdec")
5842	(const_string "alu")))
5843   (set (attr "length_immediate")
5844      (if_then_else
5845	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5846	(const_string "1")
5847	(const_string "*")))
5848   (set_attr "mode" "<MODE>")])
5849
5850(define_insn "addqi_ext_1"
5851  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5852			 (const_int 8)
5853			 (const_int 8))
5854	(plus:SI
5855	  (zero_extract:SI
5856	    (match_operand 1 "ext_register_operand" "0,0")
5857	    (const_int 8)
5858	    (const_int 8))
5859	  (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5860   (clobber (reg:CC FLAGS_REG))]
5861  ""
5862{
5863  switch (get_attr_type (insn))
5864    {
5865    case TYPE_INCDEC:
5866      if (operands[2] == const1_rtx)
5867	return "inc{b}\t%h0";
5868      else
5869        {
5870	  gcc_assert (operands[2] == constm1_rtx);
5871          return "dec{b}\t%h0";
5872        }
5873
5874    default:
5875      return "add{b}\t{%2, %h0|%h0, %2}";
5876    }
5877}
5878  [(set_attr "isa" "*,nox64")
5879   (set (attr "type")
5880     (if_then_else (match_operand:QI 2 "incdec_operand")
5881	(const_string "incdec")
5882	(const_string "alu")))
5883   (set_attr "modrm" "1")
5884   (set_attr "mode" "QI")])
5885
5886(define_insn "*addqi_ext_2"
5887  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5888			 (const_int 8)
5889			 (const_int 8))
5890	(plus:SI
5891	  (zero_extract:SI
5892	    (match_operand 1 "ext_register_operand" "%0")
5893	    (const_int 8)
5894	    (const_int 8))
5895	  (zero_extract:SI
5896	    (match_operand 2 "ext_register_operand" "Q")
5897	    (const_int 8)
5898	    (const_int 8))))
5899   (clobber (reg:CC FLAGS_REG))]
5900  ""
5901  "add{b}\t{%h2, %h0|%h0, %h2}"
5902  [(set_attr "type" "alu")
5903   (set_attr "mode" "QI")])
5904
5905;; Add with jump on overflow.
5906(define_expand "addv<mode>4"
5907  [(parallel [(set (reg:CCO FLAGS_REG)
5908		   (eq:CCO (plus:<DWI>
5909			      (sign_extend:<DWI>
5910				 (match_operand:SWI 1 "nonimmediate_operand"))
5911			      (match_dup 4))
5912			   (sign_extend:<DWI>
5913			      (plus:SWI (match_dup 1)
5914					(match_operand:SWI 2
5915					   "<general_operand>")))))
5916	      (set (match_operand:SWI 0 "register_operand")
5917		   (plus:SWI (match_dup 1) (match_dup 2)))])
5918   (set (pc) (if_then_else
5919	       (eq (reg:CCO FLAGS_REG) (const_int 0))
5920	       (label_ref (match_operand 3))
5921	       (pc)))]
5922  ""
5923{
5924  ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5925  if (CONST_INT_P (operands[2]))
5926    operands[4] = operands[2];
5927  else
5928    operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5929})
5930
5931(define_insn "*addv<mode>4"
5932  [(set (reg:CCO FLAGS_REG)
5933	(eq:CCO (plus:<DWI>
5934		   (sign_extend:<DWI>
5935		      (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5936		   (sign_extend:<DWI>
5937		      (match_operand:SWI 2 "<general_sext_operand>"
5938					   "<r>mWe,<r>We")))
5939		(sign_extend:<DWI>
5940		   (plus:SWI (match_dup 1) (match_dup 2)))))
5941   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5942	(plus:SWI (match_dup 1) (match_dup 2)))]
5943  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5944  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5945  [(set_attr "type" "alu")
5946   (set_attr "mode" "<MODE>")])
5947
5948(define_insn "*addv<mode>4_1"
5949  [(set (reg:CCO FLAGS_REG)
5950	(eq:CCO (plus:<DWI>
5951		   (sign_extend:<DWI>
5952		      (match_operand:SWI 1 "nonimmediate_operand" "0"))
5953		   (match_operand:<DWI> 3 "const_int_operand" "i"))
5954		(sign_extend:<DWI>
5955		   (plus:SWI (match_dup 1)
5956			     (match_operand:SWI 2 "x86_64_immediate_operand"
5957						  "<i>")))))
5958   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5959	(plus:SWI (match_dup 1) (match_dup 2)))]
5960  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5961   && CONST_INT_P (operands[2])
5962   && INTVAL (operands[2]) == INTVAL (operands[3])"
5963  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5964  [(set_attr "type" "alu")
5965   (set_attr "mode" "<MODE>")
5966   (set (attr "length_immediate")
5967	(cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5968		  (const_string "1")
5969	       (match_test "<MODE_SIZE> == 8")
5970		  (const_string "4")]
5971	      (const_string "<MODE_SIZE>")))])
5972
5973;; The lea patterns for modes less than 32 bits need to be matched by
5974;; several insns converted to real lea by splitters.
5975
5976(define_insn_and_split "*lea_general_1"
5977  [(set (match_operand 0 "register_operand" "=r")
5978	(plus (plus (match_operand 1 "index_register_operand" "l")
5979		    (match_operand 2 "register_operand" "r"))
5980	      (match_operand 3 "immediate_operand" "i")))]
5981  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5982   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5983   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5984   && GET_MODE (operands[0]) == GET_MODE (operands[2])
5985   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5986       || GET_MODE (operands[3]) == VOIDmode)"
5987  "#"
5988  "&& reload_completed"
5989  [(const_int 0)]
5990{
5991  machine_mode mode = SImode;
5992  rtx pat;
5993
5994  operands[0] = gen_lowpart (mode, operands[0]);
5995  operands[1] = gen_lowpart (mode, operands[1]);
5996  operands[2] = gen_lowpart (mode, operands[2]);
5997  operands[3] = gen_lowpart (mode, operands[3]);
5998
5999  pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6000  		      operands[3]);
6001
6002  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6003  DONE;
6004}
6005  [(set_attr "type" "lea")
6006   (set_attr "mode" "SI")])
6007
6008(define_insn_and_split "*lea_general_2"
6009  [(set (match_operand 0 "register_operand" "=r")
6010	(plus (mult (match_operand 1 "index_register_operand" "l")
6011		    (match_operand 2 "const248_operand" "n"))
6012	      (match_operand 3 "nonmemory_operand" "ri")))]
6013  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6014   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6015   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6016   && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6017       || GET_MODE (operands[3]) == VOIDmode)"
6018  "#"
6019  "&& reload_completed"
6020  [(const_int 0)]
6021{
6022  machine_mode mode = SImode;
6023  rtx pat;
6024
6025  operands[0] = gen_lowpart (mode, operands[0]);
6026  operands[1] = gen_lowpart (mode, operands[1]);
6027  operands[3] = gen_lowpart (mode, operands[3]);
6028
6029  pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6030		      operands[3]);
6031
6032  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6033  DONE;
6034}
6035  [(set_attr "type" "lea")
6036   (set_attr "mode" "SI")])
6037
6038(define_insn_and_split "*lea_general_3"
6039  [(set (match_operand 0 "register_operand" "=r")
6040	(plus (plus (mult (match_operand 1 "index_register_operand" "l")
6041			  (match_operand 2 "const248_operand" "n"))
6042		    (match_operand 3 "register_operand" "r"))
6043	      (match_operand 4 "immediate_operand" "i")))]
6044  "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6045   && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6046   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6047   && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6048  "#"
6049  "&& reload_completed"
6050  [(const_int 0)]
6051{
6052  machine_mode mode = SImode;
6053  rtx pat;
6054
6055  operands[0] = gen_lowpart (mode, operands[0]);
6056  operands[1] = gen_lowpart (mode, operands[1]);
6057  operands[3] = gen_lowpart (mode, operands[3]);
6058  operands[4] = gen_lowpart (mode, operands[4]);
6059
6060  pat = gen_rtx_PLUS (mode,
6061  		      gen_rtx_PLUS (mode,
6062				    gen_rtx_MULT (mode, operands[1],
6063		      					operands[2]),
6064				    operands[3]),
6065  		      operands[4]);
6066
6067  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6068  DONE;
6069}
6070  [(set_attr "type" "lea")
6071   (set_attr "mode" "SI")])
6072
6073(define_insn_and_split "*lea_general_4"
6074  [(set (match_operand 0 "register_operand" "=r")
6075	(any_or (ashift
6076		  (match_operand 1 "index_register_operand" "l")
6077		  (match_operand 2 "const_int_operand" "n"))
6078		(match_operand 3 "const_int_operand" "n")))]
6079  "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6080      && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6081    || GET_MODE (operands[0]) == SImode
6082    || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6083   && GET_MODE (operands[0]) == GET_MODE (operands[1])
6084   && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6085   && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6086       < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6087  "#"
6088  "&& reload_completed"
6089  [(const_int 0)]
6090{
6091  machine_mode mode = GET_MODE (operands[0]);
6092  rtx pat;
6093
6094  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6095    { 
6096      mode = SImode; 
6097      operands[0] = gen_lowpart (mode, operands[0]);
6098      operands[1] = gen_lowpart (mode, operands[1]);
6099    }
6100
6101  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6102
6103  pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6104		       INTVAL (operands[3]));
6105
6106  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6107  DONE;
6108}
6109  [(set_attr "type" "lea")
6110   (set (attr "mode")
6111      (if_then_else (match_operand:DI 0)
6112	(const_string "DI")
6113	(const_string "SI")))])
6114
6115;; Subtract instructions
6116
6117(define_expand "sub<mode>3"
6118  [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6119	(minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6120		     (match_operand:SDWIM 2 "<general_operand>")))]
6121  ""
6122  "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6123
6124(define_insn_and_split "*sub<dwi>3_doubleword"
6125  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6126	(minus:<DWI>
6127	  (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6128	  (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6129   (clobber (reg:CC FLAGS_REG))]
6130  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6131  "#"
6132  "reload_completed"
6133  [(parallel [(set (reg:CC FLAGS_REG)
6134		   (compare:CC (match_dup 1) (match_dup 2)))
6135	      (set (match_dup 0)
6136		   (minus:DWIH (match_dup 1) (match_dup 2)))])
6137   (parallel [(set (match_dup 3)
6138		   (minus:DWIH
6139		     (minus:DWIH
6140		       (match_dup 4)
6141		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6142		     (match_dup 5)))
6143	      (clobber (reg:CC FLAGS_REG))])]
6144  "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6145
6146(define_insn "*sub<mode>_1"
6147  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6148	(minus:SWI
6149	  (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6150	  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6151   (clobber (reg:CC FLAGS_REG))]
6152  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6153  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6154  [(set_attr "type" "alu")
6155   (set_attr "mode" "<MODE>")])
6156
6157(define_insn "*subsi_1_zext"
6158  [(set (match_operand:DI 0 "register_operand" "=r")
6159	(zero_extend:DI
6160	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6161		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6162   (clobber (reg:CC FLAGS_REG))]
6163  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6164  "sub{l}\t{%2, %k0|%k0, %2}"
6165  [(set_attr "type" "alu")
6166   (set_attr "mode" "SI")])
6167
6168(define_insn "*subqi_1_slp"
6169  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6170	(minus:QI (match_dup 0)
6171		  (match_operand:QI 1 "general_operand" "qn,qm")))
6172   (clobber (reg:CC FLAGS_REG))]
6173  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6174   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6175  "sub{b}\t{%1, %0|%0, %1}"
6176  [(set_attr "type" "alu1")
6177   (set_attr "mode" "QI")])
6178
6179(define_insn "*sub<mode>_2"
6180  [(set (reg FLAGS_REG)
6181	(compare
6182	  (minus:SWI
6183	    (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6184	    (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6185	  (const_int 0)))
6186   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6187	(minus:SWI (match_dup 1) (match_dup 2)))]
6188  "ix86_match_ccmode (insn, CCGOCmode)
6189   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6190  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6191  [(set_attr "type" "alu")
6192   (set_attr "mode" "<MODE>")])
6193
6194(define_insn "*subsi_2_zext"
6195  [(set (reg FLAGS_REG)
6196	(compare
6197	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6198		    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6199	  (const_int 0)))
6200   (set (match_operand:DI 0 "register_operand" "=r")
6201	(zero_extend:DI
6202	  (minus:SI (match_dup 1)
6203		    (match_dup 2))))]
6204  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6205   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6206  "sub{l}\t{%2, %k0|%k0, %2}"
6207  [(set_attr "type" "alu")
6208   (set_attr "mode" "SI")])
6209
6210;; Subtract with jump on overflow.
6211(define_expand "subv<mode>4"
6212  [(parallel [(set (reg:CCO FLAGS_REG)
6213		   (eq:CCO (minus:<DWI>
6214			      (sign_extend:<DWI>
6215				 (match_operand:SWI 1 "nonimmediate_operand"))
6216			      (match_dup 4))
6217			   (sign_extend:<DWI>
6218			      (minus:SWI (match_dup 1)
6219					 (match_operand:SWI 2
6220					    "<general_operand>")))))
6221	      (set (match_operand:SWI 0 "register_operand")
6222		   (minus:SWI (match_dup 1) (match_dup 2)))])
6223   (set (pc) (if_then_else
6224	       (eq (reg:CCO FLAGS_REG) (const_int 0))
6225	       (label_ref (match_operand 3))
6226	       (pc)))]
6227  ""
6228{
6229  ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6230  if (CONST_INT_P (operands[2]))
6231    operands[4] = operands[2];
6232  else
6233    operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6234})
6235
6236(define_insn "*subv<mode>4"
6237  [(set (reg:CCO FLAGS_REG)
6238	(eq:CCO (minus:<DWI>
6239		   (sign_extend:<DWI>
6240		      (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6241		   (sign_extend:<DWI>
6242		      (match_operand:SWI 2 "<general_sext_operand>"
6243					   "<r>We,<r>m")))
6244		(sign_extend:<DWI>
6245		   (minus:SWI (match_dup 1) (match_dup 2)))))
6246   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6247	(minus:SWI (match_dup 1) (match_dup 2)))]
6248  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6249  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6250  [(set_attr "type" "alu")
6251   (set_attr "mode" "<MODE>")])
6252
6253(define_insn "*subv<mode>4_1"
6254  [(set (reg:CCO FLAGS_REG)
6255	(eq:CCO (minus:<DWI>
6256		   (sign_extend:<DWI>
6257		      (match_operand:SWI 1 "nonimmediate_operand" "0"))
6258		   (match_operand:<DWI> 3 "const_int_operand" "i"))
6259		(sign_extend:<DWI>
6260		   (minus:SWI (match_dup 1)
6261			      (match_operand:SWI 2 "x86_64_immediate_operand"
6262						   "<i>")))))
6263   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6264	(minus:SWI (match_dup 1) (match_dup 2)))]
6265  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6266   && CONST_INT_P (operands[2])
6267   && INTVAL (operands[2]) == INTVAL (operands[3])"
6268  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6269  [(set_attr "type" "alu")
6270   (set_attr "mode" "<MODE>")
6271   (set (attr "length_immediate")
6272	(cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6273		  (const_string "1")
6274	       (match_test "<MODE_SIZE> == 8")
6275		  (const_string "4")]
6276	      (const_string "<MODE_SIZE>")))])
6277
6278(define_insn "*sub<mode>_3"
6279  [(set (reg FLAGS_REG)
6280	(compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6281		 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6282   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6283	(minus:SWI (match_dup 1) (match_dup 2)))]
6284  "ix86_match_ccmode (insn, CCmode)
6285   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6286  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6287  [(set_attr "type" "alu")
6288   (set_attr "mode" "<MODE>")])
6289
6290(define_insn "*subsi_3_zext"
6291  [(set (reg FLAGS_REG)
6292	(compare (match_operand:SI 1 "register_operand" "0")
6293		 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6294   (set (match_operand:DI 0 "register_operand" "=r")
6295	(zero_extend:DI
6296	  (minus:SI (match_dup 1)
6297		    (match_dup 2))))]
6298  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6299   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6300  "sub{l}\t{%2, %1|%1, %2}"
6301  [(set_attr "type" "alu")
6302   (set_attr "mode" "SI")])
6303
6304;; Add with carry and subtract with borrow
6305
6306(define_insn "add<mode>3_carry"
6307  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6308	(plus:SWI
6309	  (plus:SWI
6310	    (match_operator:SWI 4 "ix86_carry_flag_operator"
6311	     [(match_operand 3 "flags_reg_operand") (const_int 0)])
6312	    (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6313	  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6314   (clobber (reg:CC FLAGS_REG))]
6315  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6316  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6317  [(set_attr "type" "alu")
6318   (set_attr "use_carry" "1")
6319   (set_attr "pent_pair" "pu")
6320   (set_attr "mode" "<MODE>")])
6321
6322(define_insn "*addsi3_carry_zext"
6323  [(set (match_operand:DI 0 "register_operand" "=r")
6324	(zero_extend:DI
6325	  (plus:SI
6326	    (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6327		      [(reg FLAGS_REG) (const_int 0)])
6328		     (match_operand:SI 1 "register_operand" "%0"))
6329	    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6330   (clobber (reg:CC FLAGS_REG))]
6331  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6332  "adc{l}\t{%2, %k0|%k0, %2}"
6333  [(set_attr "type" "alu")
6334   (set_attr "use_carry" "1")
6335   (set_attr "pent_pair" "pu")
6336   (set_attr "mode" "SI")])
6337
6338;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6339
6340(define_insn "addcarry<mode>"
6341  [(set (reg:CCC FLAGS_REG)
6342	(compare:CCC
6343	  (plus:SWI48
6344	    (plus:SWI48
6345	      (match_operator:SWI48 4 "ix86_carry_flag_operator"
6346	       [(match_operand 3 "flags_reg_operand") (const_int 0)])
6347	      (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6348	    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6349	  (match_dup 1)))
6350   (set (match_operand:SWI48 0 "register_operand" "=r")
6351	(plus:SWI48 (plus:SWI48 (match_op_dup 4
6352				 [(match_dup 3) (const_int 0)])
6353				(match_dup 1))
6354		    (match_dup 2)))]
6355  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6356  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6357  [(set_attr "type" "alu")
6358   (set_attr "use_carry" "1")
6359   (set_attr "pent_pair" "pu")
6360   (set_attr "mode" "<MODE>")])
6361
6362(define_insn "sub<mode>3_carry"
6363  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6364	(minus:SWI
6365	  (minus:SWI
6366	    (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6367	    (match_operator:SWI 4 "ix86_carry_flag_operator"
6368	     [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6369	  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6370   (clobber (reg:CC FLAGS_REG))]
6371  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6372  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6373  [(set_attr "type" "alu")
6374   (set_attr "use_carry" "1")
6375   (set_attr "pent_pair" "pu")
6376   (set_attr "mode" "<MODE>")])
6377
6378(define_insn "*subsi3_carry_zext"
6379  [(set (match_operand:DI 0 "register_operand" "=r")
6380	(zero_extend:DI
6381	  (minus:SI
6382	    (minus:SI
6383	      (match_operand:SI 1 "register_operand" "0")
6384	      (match_operator:SI 3 "ix86_carry_flag_operator"
6385	       [(reg FLAGS_REG) (const_int 0)]))
6386	    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6387   (clobber (reg:CC FLAGS_REG))]
6388  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6389  "sbb{l}\t{%2, %k0|%k0, %2}"
6390  [(set_attr "type" "alu")
6391   (set_attr "use_carry" "1")
6392   (set_attr "pent_pair" "pu")
6393   (set_attr "mode" "SI")])
6394
6395(define_insn "subborrow<mode>"
6396  [(set (reg:CCC FLAGS_REG)
6397	(compare:CCC
6398	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
6399	  (plus:SWI48
6400	    (match_operator:SWI48 4 "ix86_carry_flag_operator"
6401	     [(match_operand 3 "flags_reg_operand") (const_int 0)])
6402	    (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6403   (set (match_operand:SWI48 0 "register_operand" "=r")
6404	(minus:SWI48 (minus:SWI48 (match_dup 1)
6405				  (match_op_dup 4
6406				   [(match_dup 3) (const_int 0)]))
6407		     (match_dup 2)))]
6408  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6409  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6410  [(set_attr "type" "alu")
6411   (set_attr "use_carry" "1")
6412   (set_attr "pent_pair" "pu")
6413   (set_attr "mode" "<MODE>")])
6414
6415;; Overflow setting add instructions
6416
6417(define_expand "addqi3_cconly_overflow"
6418  [(parallel
6419     [(set (reg:CCC FLAGS_REG)
6420	   (compare:CCC
6421	     (plus:QI
6422	       (match_operand:QI 0 "nonimmediate_operand")
6423	       (match_operand:QI 1 "general_operand"))
6424	     (match_dup 0)))
6425      (clobber (match_scratch:QI 2))])]
6426  "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6427
6428(define_insn "*add<mode>3_cconly_overflow"
6429  [(set (reg:CCC FLAGS_REG)
6430	(compare:CCC
6431	  (plus:SWI
6432	    (match_operand:SWI 1 "nonimmediate_operand" "%0")
6433	    (match_operand:SWI 2 "<general_operand>" "<g>"))
6434	  (match_dup 1)))
6435   (clobber (match_scratch:SWI 0 "=<r>"))]
6436  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6437  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6438  [(set_attr "type" "alu")
6439   (set_attr "mode" "<MODE>")])
6440
6441(define_insn "*add<mode>3_cc_overflow"
6442  [(set (reg:CCC FLAGS_REG)
6443	(compare:CCC
6444	    (plus:SWI
6445		(match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6446		(match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6447	    (match_dup 1)))
6448   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449	(plus:SWI (match_dup 1) (match_dup 2)))]
6450  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6451  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6452  [(set_attr "type" "alu")
6453   (set_attr "mode" "<MODE>")])
6454
6455(define_insn "*addsi3_zext_cc_overflow"
6456  [(set (reg:CCC FLAGS_REG)
6457	(compare:CCC
6458	  (plus:SI
6459	    (match_operand:SI 1 "nonimmediate_operand" "%0")
6460	    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6461	  (match_dup 1)))
6462   (set (match_operand:DI 0 "register_operand" "=r")
6463	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6464  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6465  "add{l}\t{%2, %k0|%k0, %2}"
6466  [(set_attr "type" "alu")
6467   (set_attr "mode" "SI")])
6468
6469;; The patterns that match these are at the end of this file.
6470
6471(define_expand "<plusminus_insn>xf3"
6472  [(set (match_operand:XF 0 "register_operand")
6473	(plusminus:XF
6474	  (match_operand:XF 1 "register_operand")
6475	  (match_operand:XF 2 "register_operand")))]
6476  "TARGET_80387")
6477
6478(define_expand "<plusminus_insn><mode>3"
6479  [(set (match_operand:MODEF 0 "register_operand")
6480	(plusminus:MODEF
6481	  (match_operand:MODEF 1 "register_operand")
6482	  (match_operand:MODEF 2 "nonimmediate_operand")))]
6483  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6484    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6485
6486;; Multiply instructions
6487
6488(define_expand "mul<mode>3"
6489  [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6490		   (mult:SWIM248
6491		     (match_operand:SWIM248 1 "register_operand")
6492		     (match_operand:SWIM248 2 "<general_operand>")))
6493	      (clobber (reg:CC FLAGS_REG))])])
6494
6495(define_expand "mulqi3"
6496  [(parallel [(set (match_operand:QI 0 "register_operand")
6497		   (mult:QI
6498		     (match_operand:QI 1 "register_operand")
6499		     (match_operand:QI 2 "nonimmediate_operand")))
6500	      (clobber (reg:CC FLAGS_REG))])]
6501  "TARGET_QIMODE_MATH")
6502
6503;; On AMDFAM10
6504;; IMUL reg32/64, reg32/64, imm8 	Direct
6505;; IMUL reg32/64, mem32/64, imm8 	VectorPath
6506;; IMUL reg32/64, reg32/64, imm32 	Direct
6507;; IMUL reg32/64, mem32/64, imm32 	VectorPath
6508;; IMUL reg32/64, reg32/64 		Direct
6509;; IMUL reg32/64, mem32/64 		Direct
6510;;
6511;; On BDVER1, all above IMULs use DirectPath
6512
6513(define_insn "*mul<mode>3_1"
6514  [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6515	(mult:SWI48
6516	  (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6517	  (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6518   (clobber (reg:CC FLAGS_REG))]
6519  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6520  "@
6521   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6522   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6523   imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6524  [(set_attr "type" "imul")
6525   (set_attr "prefix_0f" "0,0,1")
6526   (set (attr "athlon_decode")
6527	(cond [(eq_attr "cpu" "athlon")
6528		  (const_string "vector")
6529	       (eq_attr "alternative" "1")
6530		  (const_string "vector")
6531	       (and (eq_attr "alternative" "2")
6532		    (match_operand 1 "memory_operand"))
6533		  (const_string "vector")]
6534	      (const_string "direct")))
6535   (set (attr "amdfam10_decode")
6536	(cond [(and (eq_attr "alternative" "0,1")
6537		    (match_operand 1 "memory_operand"))
6538		  (const_string "vector")]
6539	      (const_string "direct")))
6540   (set_attr "bdver1_decode" "direct")
6541   (set_attr "mode" "<MODE>")])
6542
6543(define_insn "*mulsi3_1_zext"
6544  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6545	(zero_extend:DI
6546	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6547		   (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6548   (clobber (reg:CC FLAGS_REG))]
6549  "TARGET_64BIT
6550   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6551  "@
6552   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6553   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6554   imul{l}\t{%2, %k0|%k0, %2}"
6555  [(set_attr "type" "imul")
6556   (set_attr "prefix_0f" "0,0,1")
6557   (set (attr "athlon_decode")
6558	(cond [(eq_attr "cpu" "athlon")
6559		  (const_string "vector")
6560	       (eq_attr "alternative" "1")
6561		  (const_string "vector")
6562	       (and (eq_attr "alternative" "2")
6563		    (match_operand 1 "memory_operand"))
6564		  (const_string "vector")]
6565	      (const_string "direct")))
6566   (set (attr "amdfam10_decode")
6567	(cond [(and (eq_attr "alternative" "0,1")
6568		    (match_operand 1 "memory_operand"))
6569		  (const_string "vector")]
6570	      (const_string "direct")))
6571   (set_attr "bdver1_decode" "direct")
6572   (set_attr "mode" "SI")])
6573
6574;; On AMDFAM10
6575;; IMUL reg16, reg16, imm8 	VectorPath
6576;; IMUL reg16, mem16, imm8 	VectorPath
6577;; IMUL reg16, reg16, imm16 	VectorPath
6578;; IMUL reg16, mem16, imm16 	VectorPath
6579;; IMUL reg16, reg16 		Direct
6580;; IMUL reg16, mem16 		Direct
6581;;
6582;; On BDVER1, all HI MULs use DoublePath
6583
6584(define_insn "*mulhi3_1"
6585  [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6586	(mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6587		 (match_operand:HI 2 "general_operand" "K,n,mr")))
6588   (clobber (reg:CC FLAGS_REG))]
6589  "TARGET_HIMODE_MATH
6590   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6591  "@
6592   imul{w}\t{%2, %1, %0|%0, %1, %2}
6593   imul{w}\t{%2, %1, %0|%0, %1, %2}
6594   imul{w}\t{%2, %0|%0, %2}"
6595  [(set_attr "type" "imul")
6596   (set_attr "prefix_0f" "0,0,1")
6597   (set (attr "athlon_decode")
6598	(cond [(eq_attr "cpu" "athlon")
6599		  (const_string "vector")
6600	       (eq_attr "alternative" "1,2")
6601		  (const_string "vector")]
6602	      (const_string "direct")))
6603   (set (attr "amdfam10_decode")
6604	(cond [(eq_attr "alternative" "0,1")
6605		  (const_string "vector")]
6606	      (const_string "direct")))
6607   (set_attr "bdver1_decode" "double")
6608   (set_attr "mode" "HI")])
6609
6610;;On AMDFAM10 and BDVER1
6611;; MUL reg8 	Direct
6612;; MUL mem8 	Direct
6613
6614(define_insn "*mulqi3_1"
6615  [(set (match_operand:QI 0 "register_operand" "=a")
6616	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6617		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6618   (clobber (reg:CC FLAGS_REG))]
6619  "TARGET_QIMODE_MATH
6620   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6621  "mul{b}\t%2"
6622  [(set_attr "type" "imul")
6623   (set_attr "length_immediate" "0")
6624   (set (attr "athlon_decode")
6625     (if_then_else (eq_attr "cpu" "athlon")
6626        (const_string "vector")
6627        (const_string "direct")))
6628   (set_attr "amdfam10_decode" "direct")
6629   (set_attr "bdver1_decode" "direct")
6630   (set_attr "mode" "QI")])
6631
6632;; Multiply with jump on overflow.
6633(define_expand "mulv<mode>4"
6634  [(parallel [(set (reg:CCO FLAGS_REG)
6635		   (eq:CCO (mult:<DWI>
6636			      (sign_extend:<DWI>
6637				 (match_operand:SWI48 1 "register_operand"))
6638			      (match_dup 4))
6639			   (sign_extend:<DWI>
6640			      (mult:SWI48 (match_dup 1)
6641					  (match_operand:SWI48 2
6642					     "<general_operand>")))))
6643	      (set (match_operand:SWI48 0 "register_operand")
6644		   (mult:SWI48 (match_dup 1) (match_dup 2)))])
6645   (set (pc) (if_then_else
6646	       (eq (reg:CCO FLAGS_REG) (const_int 0))
6647	       (label_ref (match_operand 3))
6648	       (pc)))]
6649  ""
6650{
6651  if (CONST_INT_P (operands[2]))
6652    operands[4] = operands[2];
6653  else
6654    operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6655})
6656
6657(define_insn "*mulv<mode>4"
6658  [(set (reg:CCO FLAGS_REG)
6659	(eq:CCO (mult:<DWI>
6660		   (sign_extend:<DWI>
6661		      (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6662		   (sign_extend:<DWI>
6663		      (match_operand:SWI48 2 "<general_sext_operand>"
6664					     "We,mr")))
6665		(sign_extend:<DWI>
6666		   (mult:SWI48 (match_dup 1) (match_dup 2)))))
6667   (set (match_operand:SWI48 0 "register_operand" "=r,r")
6668	(mult:SWI48 (match_dup 1) (match_dup 2)))]
6669  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6670  "@
6671   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6672   imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6673  [(set_attr "type" "imul")
6674   (set_attr "prefix_0f" "0,1")
6675   (set (attr "athlon_decode")
6676	(cond [(eq_attr "cpu" "athlon")
6677		  (const_string "vector")
6678	       (eq_attr "alternative" "0")
6679		  (const_string "vector")
6680	       (and (eq_attr "alternative" "1")
6681		    (match_operand 1 "memory_operand"))
6682		  (const_string "vector")]
6683	      (const_string "direct")))
6684   (set (attr "amdfam10_decode")
6685	(cond [(and (eq_attr "alternative" "1")
6686		    (match_operand 1 "memory_operand"))
6687		  (const_string "vector")]
6688	      (const_string "direct")))
6689   (set_attr "bdver1_decode" "direct")
6690   (set_attr "mode" "<MODE>")])
6691
6692(define_insn "*mulv<mode>4_1"
6693  [(set (reg:CCO FLAGS_REG)
6694	(eq:CCO (mult:<DWI>
6695		   (sign_extend:<DWI>
6696		      (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6697		   (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6698		(sign_extend:<DWI>
6699		   (mult:SWI48 (match_dup 1)
6700			       (match_operand:SWI 2 "x86_64_immediate_operand"
6701						    "K,<i>")))))
6702   (set (match_operand:SWI48 0 "register_operand" "=r,r")
6703	(mult:SWI48 (match_dup 1) (match_dup 2)))]
6704  "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6705   && CONST_INT_P (operands[2])
6706   && INTVAL (operands[2]) == INTVAL (operands[3])"
6707  "@
6708   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6709   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6710  [(set_attr "type" "imul")
6711   (set (attr "athlon_decode")
6712	(cond [(eq_attr "cpu" "athlon")
6713		  (const_string "vector")
6714	       (eq_attr "alternative" "1")
6715		  (const_string "vector")]
6716	      (const_string "direct")))
6717   (set (attr "amdfam10_decode")
6718	(cond [(match_operand 1 "memory_operand")
6719		  (const_string "vector")]
6720	      (const_string "direct")))
6721   (set_attr "bdver1_decode" "direct")
6722   (set_attr "mode" "<MODE>")
6723   (set (attr "length_immediate")
6724	(cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6725		  (const_string "1")
6726	       (match_test "<MODE_SIZE> == 8")
6727		  (const_string "4")]
6728	      (const_string "<MODE_SIZE>")))])
6729
6730(define_expand "umulv<mode>4"
6731  [(parallel [(set (reg:CCO FLAGS_REG)
6732		   (eq:CCO (mult:<DWI>
6733			      (zero_extend:<DWI>
6734				 (match_operand:SWI48 1
6735						      "nonimmediate_operand"))
6736			      (zero_extend:<DWI>
6737				 (match_operand:SWI48 2
6738						      "nonimmediate_operand")))
6739			   (zero_extend:<DWI>
6740			      (mult:SWI48 (match_dup 1) (match_dup 2)))))
6741	      (set (match_operand:SWI48 0 "register_operand")
6742		   (mult:SWI48 (match_dup 1) (match_dup 2)))
6743	      (clobber (match_scratch:SWI48 4))])
6744   (set (pc) (if_then_else
6745	       (eq (reg:CCO FLAGS_REG) (const_int 0))
6746	       (label_ref (match_operand 3))
6747	       (pc)))]
6748  ""
6749{
6750  if (MEM_P (operands[1]) && MEM_P (operands[2]))
6751    operands[1] = force_reg (<MODE>mode, operands[1]);
6752})
6753
6754(define_insn "*umulv<mode>4"
6755  [(set (reg:CCO FLAGS_REG)
6756	(eq:CCO (mult:<DWI>
6757		   (zero_extend:<DWI>
6758		      (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6759		   (zero_extend:<DWI>
6760		      (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6761		(zero_extend:<DWI>
6762		   (mult:SWI48 (match_dup 1) (match_dup 2)))))
6763   (set (match_operand:SWI48 0 "register_operand" "=a")
6764	(mult:SWI48 (match_dup 1) (match_dup 2)))
6765   (clobber (match_scratch:SWI48 3 "=d"))]
6766  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6767  "mul{<imodesuffix>}\t%2"
6768  [(set_attr "type" "imul")
6769   (set_attr "length_immediate" "0")
6770   (set (attr "athlon_decode")
6771     (if_then_else (eq_attr "cpu" "athlon")
6772       (const_string "vector")
6773       (const_string "double")))
6774   (set_attr "amdfam10_decode" "double")
6775   (set_attr "bdver1_decode" "direct")
6776   (set_attr "mode" "<MODE>")])
6777
6778(define_expand "<u>mulvqi4"
6779  [(parallel [(set (reg:CCO FLAGS_REG)
6780		   (eq:CCO (mult:HI
6781			      (any_extend:HI
6782				 (match_operand:QI 1 "nonimmediate_operand"))
6783			      (any_extend:HI
6784				 (match_operand:QI 2 "nonimmediate_operand")))
6785			   (any_extend:HI
6786			      (mult:QI (match_dup 1) (match_dup 2)))))
6787	      (set (match_operand:QI 0 "register_operand")
6788		   (mult:QI (match_dup 1) (match_dup 2)))])
6789   (set (pc) (if_then_else
6790	       (eq (reg:CCO FLAGS_REG) (const_int 0))
6791	       (label_ref (match_operand 3))
6792	       (pc)))]
6793  "TARGET_QIMODE_MATH"
6794{
6795  if (MEM_P (operands[1]) && MEM_P (operands[2]))
6796    operands[1] = force_reg (QImode, operands[1]);
6797})
6798
6799(define_insn "*<u>mulvqi4"
6800  [(set (reg:CCO FLAGS_REG)
6801	(eq:CCO (mult:HI
6802		   (any_extend:HI
6803		      (match_operand:QI 1 "nonimmediate_operand" "%0"))
6804		   (any_extend:HI
6805		      (match_operand:QI 2 "nonimmediate_operand" "qm")))
6806		(any_extend:HI
6807		   (mult:QI (match_dup 1) (match_dup 2)))))
6808   (set (match_operand:QI 0 "register_operand" "=a")
6809	(mult:QI (match_dup 1) (match_dup 2)))]
6810  "TARGET_QIMODE_MATH
6811   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6812  "<sgnprefix>mul{b}\t%2"
6813  [(set_attr "type" "imul")
6814   (set_attr "length_immediate" "0")
6815   (set (attr "athlon_decode")
6816     (if_then_else (eq_attr "cpu" "athlon")
6817	(const_string "vector")
6818	(const_string "direct")))
6819   (set_attr "amdfam10_decode" "direct")
6820   (set_attr "bdver1_decode" "direct")
6821   (set_attr "mode" "QI")])
6822
6823(define_expand "<u>mul<mode><dwi>3"
6824  [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6825		   (mult:<DWI>
6826		     (any_extend:<DWI>
6827		       (match_operand:DWIH 1 "nonimmediate_operand"))
6828		     (any_extend:<DWI>
6829		       (match_operand:DWIH 2 "register_operand"))))
6830	      (clobber (reg:CC FLAGS_REG))])])
6831
6832(define_expand "<u>mulqihi3"
6833  [(parallel [(set (match_operand:HI 0 "register_operand")
6834		   (mult:HI
6835		     (any_extend:HI
6836		       (match_operand:QI 1 "nonimmediate_operand"))
6837		     (any_extend:HI
6838		       (match_operand:QI 2 "register_operand"))))
6839	      (clobber (reg:CC FLAGS_REG))])]
6840  "TARGET_QIMODE_MATH")
6841
6842(define_insn "*bmi2_umulditi3_1"
6843  [(set (match_operand:DI 0 "register_operand" "=r")
6844	(mult:DI
6845	  (match_operand:DI 2 "nonimmediate_operand" "%d")
6846	  (match_operand:DI 3 "nonimmediate_operand" "rm")))
6847   (set (match_operand:DI 1 "register_operand" "=r")
6848	(truncate:DI
6849	  (lshiftrt:TI
6850	    (mult:TI (zero_extend:TI (match_dup 2))
6851		     (zero_extend:TI (match_dup 3)))
6852	    (const_int 64))))]
6853  "TARGET_64BIT && TARGET_BMI2
6854   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855  "mulx\t{%3, %0, %1|%1, %0, %3}"
6856  [(set_attr "type" "imulx")
6857   (set_attr "prefix" "vex")
6858   (set_attr "mode" "DI")])
6859
6860(define_insn "*bmi2_umulsidi3_1"
6861  [(set (match_operand:SI 0 "register_operand" "=r")
6862	(mult:SI
6863	  (match_operand:SI 2 "nonimmediate_operand" "%d")
6864	  (match_operand:SI 3 "nonimmediate_operand" "rm")))
6865   (set (match_operand:SI 1 "register_operand" "=r")
6866	(truncate:SI
6867	  (lshiftrt:DI
6868	    (mult:DI (zero_extend:DI (match_dup 2))
6869		     (zero_extend:DI (match_dup 3)))
6870	    (const_int 32))))]
6871  "!TARGET_64BIT && TARGET_BMI2
6872   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6873  "mulx\t{%3, %0, %1|%1, %0, %3}"
6874  [(set_attr "type" "imulx")
6875   (set_attr "prefix" "vex")
6876   (set_attr "mode" "SI")])
6877
6878(define_insn "*umul<mode><dwi>3_1"
6879  [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6880	(mult:<DWI>
6881	  (zero_extend:<DWI>
6882	    (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6883	  (zero_extend:<DWI>
6884	    (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6885   (clobber (reg:CC FLAGS_REG))]
6886  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6887  "@
6888   #
6889   mul{<imodesuffix>}\t%2"
6890  [(set_attr "isa" "bmi2,*")
6891   (set_attr "type" "imulx,imul")
6892   (set_attr "length_immediate" "*,0")
6893   (set (attr "athlon_decode")
6894	(cond [(eq_attr "alternative" "1")
6895		 (if_then_else (eq_attr "cpu" "athlon")
6896		   (const_string "vector")
6897		   (const_string "double"))]
6898	      (const_string "*")))
6899   (set_attr "amdfam10_decode" "*,double")
6900   (set_attr "bdver1_decode" "*,direct")
6901   (set_attr "prefix" "vex,orig")
6902   (set_attr "mode" "<MODE>")])
6903
6904;; Convert mul to the mulx pattern to avoid flags dependency.
6905(define_split
6906 [(set (match_operand:<DWI> 0 "register_operand")
6907       (mult:<DWI>
6908	 (zero_extend:<DWI>
6909	   (match_operand:DWIH 1 "register_operand"))
6910	 (zero_extend:<DWI>
6911	   (match_operand:DWIH 2 "nonimmediate_operand"))))
6912  (clobber (reg:CC FLAGS_REG))]
6913 "TARGET_BMI2 && reload_completed
6914  && true_regnum (operands[1]) == DX_REG"
6915  [(parallel [(set (match_dup 3)
6916		   (mult:DWIH (match_dup 1) (match_dup 2)))
6917	      (set (match_dup 4)
6918		   (truncate:DWIH
6919		     (lshiftrt:<DWI>
6920		       (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6921				   (zero_extend:<DWI> (match_dup 2)))
6922		       (match_dup 5))))])]
6923{
6924  split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6925
6926  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6927})
6928
6929(define_insn "*mul<mode><dwi>3_1"
6930  [(set (match_operand:<DWI> 0 "register_operand" "=A")
6931	(mult:<DWI>
6932	  (sign_extend:<DWI>
6933	    (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6934	  (sign_extend:<DWI>
6935	    (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6936   (clobber (reg:CC FLAGS_REG))]
6937  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6938  "imul{<imodesuffix>}\t%2"
6939  [(set_attr "type" "imul")
6940   (set_attr "length_immediate" "0")
6941   (set (attr "athlon_decode")
6942     (if_then_else (eq_attr "cpu" "athlon")
6943        (const_string "vector")
6944        (const_string "double")))
6945   (set_attr "amdfam10_decode" "double")
6946   (set_attr "bdver1_decode" "direct")
6947   (set_attr "mode" "<MODE>")])
6948
6949(define_insn "*<u>mulqihi3_1"
6950  [(set (match_operand:HI 0 "register_operand" "=a")
6951	(mult:HI
6952	  (any_extend:HI
6953	    (match_operand:QI 1 "nonimmediate_operand" "%0"))
6954	  (any_extend:HI
6955	    (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6956   (clobber (reg:CC FLAGS_REG))]
6957  "TARGET_QIMODE_MATH
6958   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6959  "<sgnprefix>mul{b}\t%2"
6960  [(set_attr "type" "imul")
6961   (set_attr "length_immediate" "0")
6962   (set (attr "athlon_decode")
6963     (if_then_else (eq_attr "cpu" "athlon")
6964        (const_string "vector")
6965        (const_string "direct")))
6966   (set_attr "amdfam10_decode" "direct")
6967   (set_attr "bdver1_decode" "direct")
6968   (set_attr "mode" "QI")])
6969
6970(define_expand "<s>mul<mode>3_highpart"
6971  [(parallel [(set (match_operand:SWI48 0 "register_operand")
6972		   (truncate:SWI48
6973		     (lshiftrt:<DWI>
6974		       (mult:<DWI>
6975			 (any_extend:<DWI>
6976			   (match_operand:SWI48 1 "nonimmediate_operand"))
6977			 (any_extend:<DWI>
6978			   (match_operand:SWI48 2 "register_operand")))
6979		       (match_dup 4))))
6980	      (clobber (match_scratch:SWI48 3))
6981	      (clobber (reg:CC FLAGS_REG))])]
6982  ""
6983  "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6984
6985(define_insn "*<s>muldi3_highpart_1"
6986  [(set (match_operand:DI 0 "register_operand" "=d")
6987	(truncate:DI
6988	  (lshiftrt:TI
6989	    (mult:TI
6990	      (any_extend:TI
6991		(match_operand:DI 1 "nonimmediate_operand" "%a"))
6992	      (any_extend:TI
6993		(match_operand:DI 2 "nonimmediate_operand" "rm")))
6994	    (const_int 64))))
6995   (clobber (match_scratch:DI 3 "=1"))
6996   (clobber (reg:CC FLAGS_REG))]
6997  "TARGET_64BIT
6998   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6999  "<sgnprefix>mul{q}\t%2"
7000  [(set_attr "type" "imul")
7001   (set_attr "length_immediate" "0")
7002   (set (attr "athlon_decode")
7003     (if_then_else (eq_attr "cpu" "athlon")
7004        (const_string "vector")
7005        (const_string "double")))
7006   (set_attr "amdfam10_decode" "double")
7007   (set_attr "bdver1_decode" "direct")
7008   (set_attr "mode" "DI")])
7009
7010(define_insn "*<s>mulsi3_highpart_1"
7011  [(set (match_operand:SI 0 "register_operand" "=d")
7012	(truncate:SI
7013	  (lshiftrt:DI
7014	    (mult:DI
7015	      (any_extend:DI
7016		(match_operand:SI 1 "nonimmediate_operand" "%a"))
7017	      (any_extend:DI
7018		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7019	    (const_int 32))))
7020   (clobber (match_scratch:SI 3 "=1"))
7021   (clobber (reg:CC FLAGS_REG))]
7022  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7023  "<sgnprefix>mul{l}\t%2"
7024  [(set_attr "type" "imul")
7025   (set_attr "length_immediate" "0")
7026   (set (attr "athlon_decode")
7027     (if_then_else (eq_attr "cpu" "athlon")
7028        (const_string "vector")
7029        (const_string "double")))
7030   (set_attr "amdfam10_decode" "double")
7031   (set_attr "bdver1_decode" "direct")
7032   (set_attr "mode" "SI")])
7033
7034(define_insn "*<s>mulsi3_highpart_zext"
7035  [(set (match_operand:DI 0 "register_operand" "=d")
7036	(zero_extend:DI (truncate:SI
7037	  (lshiftrt:DI
7038	    (mult:DI (any_extend:DI
7039		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7040		     (any_extend:DI
7041		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7042	    (const_int 32)))))
7043   (clobber (match_scratch:SI 3 "=1"))
7044   (clobber (reg:CC FLAGS_REG))]
7045  "TARGET_64BIT
7046   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7047  "<sgnprefix>mul{l}\t%2"
7048  [(set_attr "type" "imul")
7049   (set_attr "length_immediate" "0")
7050   (set (attr "athlon_decode")
7051     (if_then_else (eq_attr "cpu" "athlon")
7052        (const_string "vector")
7053        (const_string "double")))
7054   (set_attr "amdfam10_decode" "double")
7055   (set_attr "bdver1_decode" "direct")
7056   (set_attr "mode" "SI")])
7057
7058;; The patterns that match these are at the end of this file.
7059
7060(define_expand "mulxf3"
7061  [(set (match_operand:XF 0 "register_operand")
7062	(mult:XF (match_operand:XF 1 "register_operand")
7063		 (match_operand:XF 2 "register_operand")))]
7064  "TARGET_80387")
7065
7066(define_expand "mul<mode>3"
7067  [(set (match_operand:MODEF 0 "register_operand")
7068	(mult:MODEF (match_operand:MODEF 1 "register_operand")
7069		    (match_operand:MODEF 2 "nonimmediate_operand")))]
7070  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7071    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7072
7073;; Divide instructions
7074
7075;; The patterns that match these are at the end of this file.
7076
7077(define_expand "divxf3"
7078  [(set (match_operand:XF 0 "register_operand")
7079	(div:XF (match_operand:XF 1 "register_operand")
7080		(match_operand:XF 2 "register_operand")))]
7081  "TARGET_80387")
7082
7083(define_expand "divdf3"
7084  [(set (match_operand:DF 0 "register_operand")
7085 	(div:DF (match_operand:DF 1 "register_operand")
7086 		(match_operand:DF 2 "nonimmediate_operand")))]
7087   "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7088    || (TARGET_SSE2 && TARGET_SSE_MATH)")
7089
7090(define_expand "divsf3"
7091  [(set (match_operand:SF 0 "register_operand")
7092	(div:SF (match_operand:SF 1 "register_operand")
7093		(match_operand:SF 2 "nonimmediate_operand")))]
7094  "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7095    || TARGET_SSE_MATH"
7096{
7097  if (TARGET_SSE_MATH
7098      && TARGET_RECIP_DIV
7099      && optimize_insn_for_speed_p ()
7100      && flag_finite_math_only && !flag_trapping_math
7101      && flag_unsafe_math_optimizations)
7102    {
7103      ix86_emit_swdivsf (operands[0], operands[1],
7104			 operands[2], SFmode);
7105      DONE;
7106    }
7107})
7108
7109;; Divmod instructions.
7110
7111(define_expand "divmod<mode>4"
7112  [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7113		   (div:SWIM248
7114		     (match_operand:SWIM248 1 "register_operand")
7115		     (match_operand:SWIM248 2 "nonimmediate_operand")))
7116	      (set (match_operand:SWIM248 3 "register_operand")
7117		   (mod:SWIM248 (match_dup 1) (match_dup 2)))
7118	      (clobber (reg:CC FLAGS_REG))])])
7119
7120;; Split with 8bit unsigned divide:
7121;; 	if (dividend an divisor are in [0-255])
7122;;	   use 8bit unsigned integer divide
7123;;	 else
7124;;	   use original integer divide
7125(define_split
7126  [(set (match_operand:SWI48 0 "register_operand")
7127	(div:SWI48 (match_operand:SWI48 2 "register_operand")
7128		    (match_operand:SWI48 3 "nonimmediate_operand")))
7129   (set (match_operand:SWI48 1 "register_operand")
7130	(mod:SWI48 (match_dup 2) (match_dup 3)))
7131   (clobber (reg:CC FLAGS_REG))]
7132  "TARGET_USE_8BIT_IDIV
7133   && TARGET_QIMODE_MATH
7134   && can_create_pseudo_p ()
7135   && !optimize_insn_for_size_p ()"
7136  [(const_int 0)]
7137  "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7138
7139(define_insn_and_split "divmod<mode>4_1"
7140  [(set (match_operand:SWI48 0 "register_operand" "=a")
7141	(div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7142		   (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7143   (set (match_operand:SWI48 1 "register_operand" "=&d")
7144	(mod:SWI48 (match_dup 2) (match_dup 3)))
7145   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7146   (clobber (reg:CC FLAGS_REG))]
7147  ""
7148  "#"
7149  "reload_completed"
7150  [(parallel [(set (match_dup 1)
7151		   (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7152	      (clobber (reg:CC FLAGS_REG))])
7153   (parallel [(set (match_dup 0)
7154	           (div:SWI48 (match_dup 2) (match_dup 3)))
7155	      (set (match_dup 1)
7156		   (mod:SWI48 (match_dup 2) (match_dup 3)))
7157	      (use (match_dup 1))
7158	      (clobber (reg:CC FLAGS_REG))])]
7159{
7160  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7161
7162  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7163    operands[4] = operands[2];
7164  else
7165    {
7166      /* Avoid use of cltd in favor of a mov+shift.  */
7167      emit_move_insn (operands[1], operands[2]);
7168      operands[4] = operands[1];
7169    }
7170}
7171  [(set_attr "type" "multi")
7172   (set_attr "mode" "<MODE>")])
7173
7174(define_insn_and_split "*divmod<mode>4"
7175  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7176	(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7177		    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7178   (set (match_operand:SWIM248 1 "register_operand" "=&d")
7179	(mod:SWIM248 (match_dup 2) (match_dup 3)))
7180   (clobber (reg:CC FLAGS_REG))]
7181  ""
7182  "#"
7183  "reload_completed"
7184  [(parallel [(set (match_dup 1)
7185		   (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7186	      (clobber (reg:CC FLAGS_REG))])
7187   (parallel [(set (match_dup 0)
7188	           (div:SWIM248 (match_dup 2) (match_dup 3)))
7189	      (set (match_dup 1)
7190		   (mod:SWIM248 (match_dup 2) (match_dup 3)))
7191	      (use (match_dup 1))
7192	      (clobber (reg:CC FLAGS_REG))])]
7193{
7194  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7195
7196  if (<MODE>mode != HImode
7197      && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7198    operands[4] = operands[2];
7199  else
7200    {
7201      /* Avoid use of cltd in favor of a mov+shift.  */
7202      emit_move_insn (operands[1], operands[2]);
7203      operands[4] = operands[1];
7204    }
7205}
7206  [(set_attr "type" "multi")
7207   (set_attr "mode" "<MODE>")])
7208
7209(define_insn "*divmod<mode>4_noext"
7210  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7211	(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7212		    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7213   (set (match_operand:SWIM248 1 "register_operand" "=d")
7214	(mod:SWIM248 (match_dup 2) (match_dup 3)))
7215   (use (match_operand:SWIM248 4 "register_operand" "1"))
7216   (clobber (reg:CC FLAGS_REG))]
7217  ""
7218  "idiv{<imodesuffix>}\t%3"
7219  [(set_attr "type" "idiv")
7220   (set_attr "mode" "<MODE>")])
7221
7222(define_expand "divmodqi4"
7223  [(parallel [(set (match_operand:QI 0 "register_operand")
7224		   (div:QI
7225		     (match_operand:QI 1 "register_operand")
7226		     (match_operand:QI 2 "nonimmediate_operand")))
7227	      (set (match_operand:QI 3 "register_operand")
7228		   (mod:QI (match_dup 1) (match_dup 2)))
7229	      (clobber (reg:CC FLAGS_REG))])]
7230  "TARGET_QIMODE_MATH"
7231{
7232  rtx div, mod, insn;
7233  rtx tmp0, tmp1;
7234  
7235  tmp0 = gen_reg_rtx (HImode);
7236  tmp1 = gen_reg_rtx (HImode);
7237
7238  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7239     in AX.  */
7240  emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7241  emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7242
7243  /* Extract remainder from AH.  */
7244  tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7245  insn = emit_move_insn (operands[3], tmp1);
7246
7247  mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7248  set_unique_reg_note (insn, REG_EQUAL, mod);
7249
7250  /* Extract quotient from AL.  */
7251  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7252
7253  div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7254  set_unique_reg_note (insn, REG_EQUAL, div);
7255
7256  DONE;
7257})
7258
7259;; Divide AX by r/m8, with result stored in
7260;; AL <- Quotient
7261;; AH <- Remainder
7262;; Change div/mod to HImode and extend the second argument to HImode
7263;; so that mode of div/mod matches with mode of arguments.  Otherwise
7264;; combine may fail.
7265(define_insn "divmodhiqi3"
7266  [(set (match_operand:HI 0 "register_operand" "=a")
7267	(ior:HI
7268	  (ashift:HI
7269	    (zero_extend:HI
7270	      (truncate:QI
7271		(mod:HI (match_operand:HI 1 "register_operand" "0")
7272			(sign_extend:HI
7273			  (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7274	    (const_int 8))
7275	  (zero_extend:HI
7276	    (truncate:QI
7277	      (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7278   (clobber (reg:CC FLAGS_REG))]
7279  "TARGET_QIMODE_MATH"
7280  "idiv{b}\t%2"
7281  [(set_attr "type" "idiv")
7282   (set_attr "mode" "QI")])
7283
7284(define_expand "udivmod<mode>4"
7285  [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7286		   (udiv:SWIM248
7287		     (match_operand:SWIM248 1 "register_operand")
7288		     (match_operand:SWIM248 2 "nonimmediate_operand")))
7289	      (set (match_operand:SWIM248 3 "register_operand")
7290		   (umod:SWIM248 (match_dup 1) (match_dup 2)))
7291	      (clobber (reg:CC FLAGS_REG))])])
7292
7293;; Split with 8bit unsigned divide:
7294;; 	if (dividend an divisor are in [0-255])
7295;;	   use 8bit unsigned integer divide
7296;;	 else
7297;;	   use original integer divide
7298(define_split
7299  [(set (match_operand:SWI48 0 "register_operand")
7300	(udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7301		    (match_operand:SWI48 3 "nonimmediate_operand")))
7302   (set (match_operand:SWI48 1 "register_operand")
7303	(umod:SWI48 (match_dup 2) (match_dup 3)))
7304   (clobber (reg:CC FLAGS_REG))]
7305  "TARGET_USE_8BIT_IDIV
7306   && TARGET_QIMODE_MATH
7307   && can_create_pseudo_p ()
7308   && !optimize_insn_for_size_p ()"
7309  [(const_int 0)]
7310  "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7311
7312(define_insn_and_split "udivmod<mode>4_1"
7313  [(set (match_operand:SWI48 0 "register_operand" "=a")
7314	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7315		    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7316   (set (match_operand:SWI48 1 "register_operand" "=&d")
7317	(umod:SWI48 (match_dup 2) (match_dup 3)))
7318   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7319   (clobber (reg:CC FLAGS_REG))]
7320  ""
7321  "#"
7322  "reload_completed"
7323  [(set (match_dup 1) (const_int 0))
7324   (parallel [(set (match_dup 0)
7325		   (udiv:SWI48 (match_dup 2) (match_dup 3)))
7326	      (set (match_dup 1)
7327		   (umod:SWI48 (match_dup 2) (match_dup 3)))
7328	      (use (match_dup 1))
7329	      (clobber (reg:CC FLAGS_REG))])]
7330  ""
7331  [(set_attr "type" "multi")
7332   (set_attr "mode" "<MODE>")])
7333
7334(define_insn_and_split "*udivmod<mode>4"
7335  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7336	(udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7337		      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7338   (set (match_operand:SWIM248 1 "register_operand" "=&d")
7339	(umod:SWIM248 (match_dup 2) (match_dup 3)))
7340   (clobber (reg:CC FLAGS_REG))]
7341  ""
7342  "#"
7343  "reload_completed"
7344  [(set (match_dup 1) (const_int 0))
7345   (parallel [(set (match_dup 0)
7346		   (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7347	      (set (match_dup 1)
7348		   (umod:SWIM248 (match_dup 2) (match_dup 3)))
7349	      (use (match_dup 1))
7350	      (clobber (reg:CC FLAGS_REG))])]
7351  ""
7352  [(set_attr "type" "multi")
7353   (set_attr "mode" "<MODE>")])
7354
7355;; Optimize division or modulo by constant power of 2, if the constant
7356;; materializes only after expansion.
7357(define_insn_and_split "*udivmod<mode>4_pow2"
7358  [(set (match_operand:SWI48 0 "register_operand" "=r")
7359	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7360		    (match_operand:SWI48 3 "const_int_operand" "n")))
7361   (set (match_operand:SWI48 1 "register_operand" "=r")
7362	(umod:SWI48 (match_dup 2) (match_dup 3)))
7363   (clobber (reg:CC FLAGS_REG))]
7364  "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7365   && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7366  "#"
7367  "&& 1"
7368  [(set (match_dup 1) (match_dup 2))
7369   (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7370	      (clobber (reg:CC FLAGS_REG))])
7371   (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7372	      (clobber (reg:CC FLAGS_REG))])]
7373{
7374  int v = exact_log2 (UINTVAL (operands[3]));
7375  operands[4] = GEN_INT (v);
7376  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7377}
7378  [(set_attr "type" "multi")
7379   (set_attr "mode" "<MODE>")])
7380
7381(define_insn "*udivmod<mode>4_noext"
7382  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7383	(udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7384		      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7385   (set (match_operand:SWIM248 1 "register_operand" "=d")
7386	(umod:SWIM248 (match_dup 2) (match_dup 3)))
7387   (use (match_operand:SWIM248 4 "register_operand" "1"))
7388   (clobber (reg:CC FLAGS_REG))]
7389  ""
7390  "div{<imodesuffix>}\t%3"
7391  [(set_attr "type" "idiv")
7392   (set_attr "mode" "<MODE>")])
7393
7394(define_expand "udivmodqi4"
7395  [(parallel [(set (match_operand:QI 0 "register_operand")
7396		   (udiv:QI
7397		     (match_operand:QI 1 "register_operand")
7398		     (match_operand:QI 2 "nonimmediate_operand")))
7399	      (set (match_operand:QI 3 "register_operand")
7400		   (umod:QI (match_dup 1) (match_dup 2)))
7401	      (clobber (reg:CC FLAGS_REG))])]
7402  "TARGET_QIMODE_MATH"
7403{
7404  rtx div, mod, insn;
7405  rtx tmp0, tmp1;
7406  
7407  tmp0 = gen_reg_rtx (HImode);
7408  tmp1 = gen_reg_rtx (HImode);
7409
7410  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7411     in AX.  */
7412  emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7413  emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7414
7415  /* Extract remainder from AH.  */
7416  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7417  tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7418  insn = emit_move_insn (operands[3], tmp1);
7419
7420  mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7421  set_unique_reg_note (insn, REG_EQUAL, mod);
7422
7423  /* Extract quotient from AL.  */
7424  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7425
7426  div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7427  set_unique_reg_note (insn, REG_EQUAL, div);
7428
7429  DONE;
7430})
7431
7432(define_insn "udivmodhiqi3"
7433  [(set (match_operand:HI 0 "register_operand" "=a")
7434	(ior:HI
7435	  (ashift:HI
7436	    (zero_extend:HI
7437	      (truncate:QI
7438		(mod:HI (match_operand:HI 1 "register_operand" "0")
7439			(zero_extend:HI
7440			  (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7441	    (const_int 8))
7442	  (zero_extend:HI
7443	    (truncate:QI
7444	      (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7445   (clobber (reg:CC FLAGS_REG))]
7446  "TARGET_QIMODE_MATH"
7447  "div{b}\t%2"
7448  [(set_attr "type" "idiv")
7449   (set_attr "mode" "QI")])
7450
7451;; We cannot use div/idiv for double division, because it causes
7452;; "division by zero" on the overflow and that's not what we expect
7453;; from truncate.  Because true (non truncating) double division is
7454;; never generated, we can't create this insn anyway.
7455;
7456;(define_insn ""
7457;  [(set (match_operand:SI 0 "register_operand" "=a")
7458;	(truncate:SI
7459;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
7460;		   (zero_extend:DI
7461;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7462;   (set (match_operand:SI 3 "register_operand" "=d")
7463;	(truncate:SI
7464;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7465;   (clobber (reg:CC FLAGS_REG))]
7466;  ""
7467;  "div{l}\t{%2, %0|%0, %2}"
7468;  [(set_attr "type" "idiv")])
7469
7470;;- Logical AND instructions
7471
7472;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7473;; Note that this excludes ah.
7474
7475(define_expand "testsi_ccno_1"
7476  [(set (reg:CCNO FLAGS_REG)
7477	(compare:CCNO
7478	  (and:SI (match_operand:SI 0 "nonimmediate_operand")
7479		  (match_operand:SI 1 "x86_64_nonmemory_operand"))
7480	  (const_int 0)))])
7481
7482(define_expand "testqi_ccz_1"
7483  [(set (reg:CCZ FLAGS_REG)
7484        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7485			     (match_operand:QI 1 "nonmemory_operand"))
7486		 (const_int 0)))])
7487
7488(define_expand "testdi_ccno_1"
7489  [(set (reg:CCNO FLAGS_REG)
7490	(compare:CCNO
7491	  (and:DI (match_operand:DI 0 "nonimmediate_operand")
7492		  (match_operand:DI 1 "x86_64_szext_general_operand"))
7493	  (const_int 0)))]
7494  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7495
7496(define_insn "*testdi_1"
7497  [(set (reg FLAGS_REG)
7498	(compare
7499	 (and:DI
7500	  (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7501	  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7502	 (const_int 0)))]
7503  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7504   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7505  "@
7506   test{l}\t{%k1, %k0|%k0, %k1}
7507   test{l}\t{%k1, %k0|%k0, %k1}
7508   test{q}\t{%1, %0|%0, %1}
7509   test{q}\t{%1, %0|%0, %1}
7510   test{q}\t{%1, %0|%0, %1}"
7511  [(set_attr "type" "test")
7512   (set_attr "modrm" "0,1,0,1,1")
7513   (set_attr "mode" "SI,SI,DI,DI,DI")])
7514
7515(define_insn "*testqi_1_maybe_si"
7516  [(set (reg FLAGS_REG)
7517        (compare
7518	  (and:QI
7519	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7520	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7521	  (const_int 0)))]
7522   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7523    && ix86_match_ccmode (insn,
7524 			 CONST_INT_P (operands[1])
7525 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7526{
7527  if (which_alternative == 3)
7528    {
7529      if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7530	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7531      return "test{l}\t{%1, %k0|%k0, %1}";
7532    }
7533  return "test{b}\t{%1, %0|%0, %1}";
7534}
7535  [(set_attr "type" "test")
7536   (set_attr "modrm" "0,1,1,1")
7537   (set_attr "mode" "QI,QI,QI,SI")
7538   (set_attr "pent_pair" "uv,np,uv,np")])
7539
7540(define_insn "*test<mode>_1"
7541  [(set (reg FLAGS_REG)
7542	(compare
7543	 (and:SWI124
7544	  (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7545	  (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7546	 (const_int 0)))]
7547  "ix86_match_ccmode (insn, CCNOmode)
7548   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7549  "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7550  [(set_attr "type" "test")
7551   (set_attr "modrm" "0,1,1")
7552   (set_attr "mode" "<MODE>")
7553   (set_attr "pent_pair" "uv,np,uv")])
7554
7555(define_expand "testqi_ext_ccno_0"
7556  [(set (reg:CCNO FLAGS_REG)
7557	(compare:CCNO
7558	  (and:SI
7559	    (zero_extract:SI
7560	      (match_operand 0 "ext_register_operand")
7561	      (const_int 8)
7562	      (const_int 8))
7563	    (match_operand 1 "const_int_operand"))
7564	  (const_int 0)))])
7565
7566(define_insn "*testqi_ext_0"
7567  [(set (reg FLAGS_REG)
7568	(compare
7569	  (and:SI
7570	    (zero_extract:SI
7571	      (match_operand 0 "ext_register_operand" "Q")
7572	      (const_int 8)
7573	      (const_int 8))
7574	    (match_operand 1 "const_int_operand" "n"))
7575	  (const_int 0)))]
7576  "ix86_match_ccmode (insn, CCNOmode)"
7577  "test{b}\t{%1, %h0|%h0, %1}"
7578  [(set_attr "type" "test")
7579   (set_attr "mode" "QI")
7580   (set_attr "length_immediate" "1")
7581   (set_attr "modrm" "1")
7582   (set_attr "pent_pair" "np")])
7583
7584(define_insn "*testqi_ext_1"
7585  [(set (reg FLAGS_REG)
7586	(compare
7587	  (and:SI
7588	    (zero_extract:SI
7589	      (match_operand 0 "ext_register_operand" "Q,Q")
7590	      (const_int 8)
7591	      (const_int 8))
7592	    (zero_extend:SI
7593	      (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7594	  (const_int 0)))]
7595  "ix86_match_ccmode (insn, CCNOmode)"
7596  "test{b}\t{%1, %h0|%h0, %1}"
7597  [(set_attr "isa" "*,nox64")
7598   (set_attr "type" "test")
7599   (set_attr "mode" "QI")])
7600
7601(define_insn "*testqi_ext_2"
7602  [(set (reg FLAGS_REG)
7603	(compare
7604	  (and:SI
7605	    (zero_extract:SI
7606	      (match_operand 0 "ext_register_operand" "Q")
7607	      (const_int 8)
7608	      (const_int 8))
7609	    (zero_extract:SI
7610	      (match_operand 1 "ext_register_operand" "Q")
7611	      (const_int 8)
7612	      (const_int 8)))
7613	  (const_int 0)))]
7614  "ix86_match_ccmode (insn, CCNOmode)"
7615  "test{b}\t{%h1, %h0|%h0, %h1}"
7616  [(set_attr "type" "test")
7617   (set_attr "mode" "QI")])
7618
7619;; Combine likes to form bit extractions for some tests.  Humor it.
7620(define_insn "*testqi_ext_3"
7621  [(set (reg FLAGS_REG)
7622	(compare (zero_extract:SWI48
7623		   (match_operand 0 "nonimmediate_operand" "rm")
7624		   (match_operand:SWI48 1 "const_int_operand")
7625		   (match_operand:SWI48 2 "const_int_operand"))
7626		 (const_int 0)))]
7627  "ix86_match_ccmode (insn, CCNOmode)
7628   && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7629       || GET_MODE (operands[0]) == SImode
7630       || GET_MODE (operands[0]) == HImode
7631       || GET_MODE (operands[0]) == QImode)
7632   /* Ensure that resulting mask is zero or sign extended operand.  */
7633   && INTVAL (operands[2]) >= 0
7634   && ((INTVAL (operands[1]) > 0
7635	&& INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7636       || (<MODE>mode == DImode
7637	   && INTVAL (operands[1]) > 32
7638	   && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7639  "#")
7640
7641(define_split
7642  [(set (match_operand 0 "flags_reg_operand")
7643        (match_operator 1 "compare_operator"
7644	  [(zero_extract
7645	     (match_operand 2 "nonimmediate_operand")
7646	     (match_operand 3 "const_int_operand")
7647	     (match_operand 4 "const_int_operand"))
7648	   (const_int 0)]))]
7649  "ix86_match_ccmode (insn, CCNOmode)"
7650  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7651{
7652  rtx val = operands[2];
7653  HOST_WIDE_INT len = INTVAL (operands[3]);
7654  HOST_WIDE_INT pos = INTVAL (operands[4]);
7655  HOST_WIDE_INT mask;
7656  machine_mode mode, submode;
7657
7658  mode = GET_MODE (val);
7659  if (MEM_P (val))
7660    {
7661      /* ??? Combine likes to put non-volatile mem extractions in QImode
7662	 no matter the size of the test.  So find a mode that works.  */
7663      if (! MEM_VOLATILE_P (val))
7664	{
7665	  mode = smallest_mode_for_size (pos + len, MODE_INT);
7666	  val = adjust_address (val, mode, 0);
7667	}
7668    }
7669  else if (GET_CODE (val) == SUBREG
7670	   && (submode = GET_MODE (SUBREG_REG (val)),
7671	       GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7672	   && pos + len <= GET_MODE_BITSIZE (submode)
7673	   && GET_MODE_CLASS (submode) == MODE_INT)
7674    {
7675      /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7676      mode = submode;
7677      val = SUBREG_REG (val);
7678    }
7679  else if (mode == HImode && pos + len <= 8)
7680    {
7681      /* Small HImode tests can be converted to QImode.  */
7682      mode = QImode;
7683      val = gen_lowpart (QImode, val);
7684    }
7685
7686  if (len == HOST_BITS_PER_WIDE_INT)
7687    mask = -1;
7688  else
7689    mask = ((HOST_WIDE_INT)1 << len) - 1;
7690  mask <<= pos;
7691
7692  operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7693})
7694
7695;; Convert HImode/SImode test instructions with immediate to QImode ones.
7696;; i386 does not allow to encode test with 8bit sign extended immediate, so
7697;; this is relatively important trick.
7698;; Do the conversion only post-reload to avoid limiting of the register class
7699;; to QI regs.
7700(define_split
7701  [(set (match_operand 0 "flags_reg_operand")
7702	(match_operator 1 "compare_operator"
7703	  [(and (match_operand 2 "register_operand")
7704	        (match_operand 3 "const_int_operand"))
7705	   (const_int 0)]))]
7706   "reload_completed
7707    && QI_REG_P (operands[2])
7708    && GET_MODE (operands[2]) != QImode
7709    && ((ix86_match_ccmode (insn, CCZmode)
7710    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
7711	|| (ix86_match_ccmode (insn, CCNOmode)
7712	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
7713  [(set (match_dup 0)
7714	(match_op_dup 1
7715	  [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7716		   (match_dup 3))
7717	   (const_int 0)]))]
7718{
7719  operands[2] = gen_lowpart (SImode, operands[2]);
7720  operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7721})
7722
7723(define_split
7724  [(set (match_operand 0 "flags_reg_operand")
7725	(match_operator 1 "compare_operator"
7726	  [(and (match_operand 2 "nonimmediate_operand")
7727	        (match_operand 3 "const_int_operand"))
7728	   (const_int 0)]))]
7729   "reload_completed
7730    && GET_MODE (operands[2]) != QImode
7731    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7732    && ((ix86_match_ccmode (insn, CCZmode)
7733	 && !(INTVAL (operands[3]) & ~255))
7734	|| (ix86_match_ccmode (insn, CCNOmode)
7735	    && !(INTVAL (operands[3]) & ~127)))"
7736  [(set (match_dup 0)
7737	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7738			 (const_int 0)]))]
7739{
7740  operands[2] = gen_lowpart (QImode, operands[2]);
7741  operands[3] = gen_lowpart (QImode, operands[3]);
7742})
7743
7744(define_split
7745  [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7746	(any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7747			    (match_operand:SWI1248x 2 "mask_reg_operand")))
7748   (clobber (reg:CC FLAGS_REG))]
7749  "TARGET_AVX512F && reload_completed"
7750  [(set (match_dup 0)
7751	(any_logic:SWI1248x (match_dup 1)
7752			    (match_dup 2)))])
7753
7754(define_insn "*k<logic><mode>"
7755  [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7756	(any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7757			  (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7758  "TARGET_AVX512F"
7759  {
7760    if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7761      return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7762    else
7763      return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7764  }
7765  [(set_attr "mode" "<MODE>")
7766   (set_attr "type" "msklog")
7767   (set_attr "prefix" "vex")])
7768
7769;; %%% This used to optimize known byte-wide and operations to memory,
7770;; and sometimes to QImode registers.  If this is considered useful,
7771;; it should be done with splitters.
7772
7773(define_expand "and<mode>3"
7774  [(set (match_operand:SWIM 0 "nonimmediate_operand")
7775	(and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7776		  (match_operand:SWIM 2 "<general_szext_operand>")))]
7777  ""
7778{
7779  machine_mode mode = <MODE>mode;
7780  rtx (*insn) (rtx, rtx);
7781
7782  if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7783    {
7784      HOST_WIDE_INT ival = INTVAL (operands[2]);
7785
7786      if (ival == (HOST_WIDE_INT) 0xffffffff)
7787	mode = SImode;
7788      else if (ival == 0xffff)
7789	mode = HImode;
7790      else if (ival == 0xff)
7791	mode = QImode;
7792      }
7793
7794  if (mode == <MODE>mode)
7795    {
7796      ix86_expand_binary_operator (AND, <MODE>mode, operands);
7797      DONE;
7798    }
7799
7800  if (<MODE>mode == DImode)
7801    insn = (mode == SImode)
7802	   ? gen_zero_extendsidi2
7803	   : (mode == HImode)
7804	   ? gen_zero_extendhidi2
7805	   : gen_zero_extendqidi2;
7806  else if (<MODE>mode == SImode)
7807    insn = (mode == HImode)
7808	   ? gen_zero_extendhisi2
7809	   : gen_zero_extendqisi2;
7810  else if (<MODE>mode == HImode)
7811    insn = gen_zero_extendqihi2;
7812  else
7813    gcc_unreachable ();
7814
7815  emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7816  DONE;
7817})
7818
7819(define_insn "*anddi_1"
7820  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7821	(and:DI
7822	 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7823	 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7824   (clobber (reg:CC FLAGS_REG))]
7825  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7826{
7827  switch (get_attr_type (insn))
7828    {
7829    case TYPE_IMOVX:
7830      return "#";
7831
7832    case TYPE_MSKLOG:
7833      return "kandq\t{%2, %1, %0|%0, %1, %2}";
7834
7835    default:
7836      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7837      if (get_attr_mode (insn) == MODE_SI)
7838	return "and{l}\t{%k2, %k0|%k0, %k2}";
7839      else
7840	return "and{q}\t{%2, %0|%0, %2}";
7841    }
7842}
7843  [(set_attr "type" "alu,alu,alu,imovx,msklog")
7844   (set_attr "length_immediate" "*,*,*,0,0")
7845   (set (attr "prefix_rex")
7846     (if_then_else
7847       (and (eq_attr "type" "imovx")
7848	    (and (match_test "INTVAL (operands[2]) == 0xff")
7849		 (match_operand 1 "ext_QIreg_operand")))
7850       (const_string "1")
7851       (const_string "*")))
7852   (set_attr "mode" "SI,DI,DI,SI,DI")])
7853
7854(define_insn "*andsi_1"
7855  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7856	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7857		(match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7858   (clobber (reg:CC FLAGS_REG))]
7859  "ix86_binary_operator_ok (AND, SImode, operands)"
7860{
7861  switch (get_attr_type (insn))
7862    {
7863    case TYPE_IMOVX:
7864      return "#";
7865
7866    case TYPE_MSKLOG:
7867      return "kandd\t{%2, %1, %0|%0, %1, %2}";
7868
7869    default:
7870      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7871      return "and{l}\t{%2, %0|%0, %2}";
7872    }
7873}
7874  [(set_attr "type" "alu,alu,imovx,msklog")
7875   (set (attr "prefix_rex")
7876     (if_then_else
7877       (and (eq_attr "type" "imovx")
7878	    (and (match_test "INTVAL (operands[2]) == 0xff")
7879		 (match_operand 1 "ext_QIreg_operand")))
7880       (const_string "1")
7881       (const_string "*")))
7882   (set_attr "length_immediate" "*,*,0,0")
7883   (set_attr "mode" "SI")])
7884
7885;; See comment for addsi_1_zext why we do use nonimmediate_operand
7886(define_insn "*andsi_1_zext"
7887  [(set (match_operand:DI 0 "register_operand" "=r")
7888	(zero_extend:DI
7889	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7890		  (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7891   (clobber (reg:CC FLAGS_REG))]
7892  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7893  "and{l}\t{%2, %k0|%k0, %2}"
7894  [(set_attr "type" "alu")
7895   (set_attr "mode" "SI")])
7896
7897(define_insn "*andhi_1"
7898  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7899	(and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7900		(match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7901   (clobber (reg:CC FLAGS_REG))]
7902  "ix86_binary_operator_ok (AND, HImode, operands)"
7903{
7904  switch (get_attr_type (insn))
7905    {
7906    case TYPE_IMOVX:
7907      return "#";
7908
7909    case TYPE_MSKLOG:
7910      return "kandw\t{%2, %1, %0|%0, %1, %2}";
7911
7912    default:
7913      gcc_assert (rtx_equal_p (operands[0], operands[1]));
7914      return "and{w}\t{%2, %0|%0, %2}";
7915    }
7916}
7917  [(set_attr "type" "alu,alu,imovx,msklog")
7918   (set_attr "length_immediate" "*,*,0,*")
7919   (set (attr "prefix_rex")
7920     (if_then_else
7921       (and (eq_attr "type" "imovx")
7922	    (match_operand 1 "ext_QIreg_operand"))
7923       (const_string "1")
7924       (const_string "*")))
7925   (set_attr "mode" "HI,HI,SI,HI")])
7926
7927;; %%% Potential partial reg stall on alternative 2.  What to do?
7928(define_insn "*andqi_1"
7929  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7930	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7931		(match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7932   (clobber (reg:CC FLAGS_REG))]
7933  "ix86_binary_operator_ok (AND, QImode, operands)"
7934{
7935  switch (which_alternative)
7936    {
7937    case 0:
7938    case 1:
7939      return "and{b}\t{%2, %0|%0, %2}";
7940    case 2:
7941      return "and{l}\t{%k2, %k0|%k0, %k2}";
7942    case 3:
7943      return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7944			     : "kandw\t{%2, %1, %0|%0, %1, %2}";
7945    default:
7946      gcc_unreachable ();
7947    }
7948}
7949  [(set_attr "type" "alu,alu,alu,msklog")
7950   (set_attr "mode" "QI,QI,SI,HI")])
7951
7952(define_insn "*andqi_1_slp"
7953  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7954	(and:QI (match_dup 0)
7955		(match_operand:QI 1 "general_operand" "qn,qmn")))
7956   (clobber (reg:CC FLAGS_REG))]
7957  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7958   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7959  "and{b}\t{%1, %0|%0, %1}"
7960  [(set_attr "type" "alu1")
7961   (set_attr "mode" "QI")])
7962
7963(define_insn "kandn<mode>"
7964  [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7965	(and:SWI12
7966	  (not:SWI12
7967	    (match_operand:SWI12 1 "register_operand" "r,0,k"))
7968	  (match_operand:SWI12 2 "register_operand" "r,r,k")))
7969   (clobber (reg:CC FLAGS_REG))]
7970  "TARGET_AVX512F"
7971{
7972  switch (which_alternative)
7973    {
7974    case 0:
7975      return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7976    case 1:
7977      return "#";
7978    case 2:
7979      if (TARGET_AVX512DQ && <MODE>mode == QImode)
7980	return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7981      else
7982	return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7983    default:
7984      gcc_unreachable ();
7985    }
7986}
7987  [(set_attr "isa" "bmi,*,avx512f")
7988   (set_attr "type" "bitmanip,*,msklog")
7989   (set_attr "prefix" "*,*,vex")
7990   (set_attr "btver2_decode" "direct,*,*")
7991   (set_attr "mode" "<MODE>")])
7992
7993(define_split
7994  [(set (match_operand:SWI12 0 "general_reg_operand")
7995	(and:SWI12
7996	  (not:SWI12
7997	    (match_dup 0))
7998	  (match_operand:SWI12 1 "general_reg_operand")))
7999   (clobber (reg:CC FLAGS_REG))]
8000  "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8001  [(set (match_dup 0)
8002	(not:SWI12 (match_dup 0)))
8003   (parallel [(set (match_dup 0)
8004		   (and:SWI12 (match_dup 0)
8005			      (match_dup 1)))
8006	      (clobber (reg:CC FLAGS_REG))])])
8007
8008;; Turn *anddi_1 into *andsi_1_zext if possible.
8009(define_split
8010  [(set (match_operand:DI 0 "register_operand")
8011	(and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8012		(match_operand:DI 2 "x86_64_zext_immediate_operand")))
8013   (clobber (reg:CC FLAGS_REG))]
8014  "TARGET_64BIT"
8015  [(parallel [(set (match_dup 0)
8016		   (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8017	      (clobber (reg:CC FLAGS_REG))])]
8018  "operands[2] = gen_lowpart (SImode, operands[2]);")
8019
8020(define_split
8021  [(set (match_operand:SWI248 0 "register_operand")
8022	(and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8023		    (match_operand:SWI248 2 "const_int_operand")))
8024   (clobber (reg:CC FLAGS_REG))]
8025  "reload_completed
8026   && true_regnum (operands[0]) != true_regnum (operands[1])"
8027  [(const_int 0)]
8028{
8029  HOST_WIDE_INT ival = INTVAL (operands[2]);
8030  machine_mode mode;
8031  rtx (*insn) (rtx, rtx);
8032
8033  if (ival == (HOST_WIDE_INT) 0xffffffff)
8034    mode = SImode;
8035  else if (ival == 0xffff)
8036    mode = HImode;
8037  else
8038    {
8039      gcc_assert (ival == 0xff);
8040      mode = QImode;
8041    }
8042
8043  if (<MODE>mode == DImode)
8044    insn = (mode == SImode)
8045	   ? gen_zero_extendsidi2
8046	   : (mode == HImode)
8047	   ? gen_zero_extendhidi2
8048	   : gen_zero_extendqidi2;
8049  else
8050    {
8051      if (<MODE>mode != SImode)
8052	/* Zero extend to SImode to avoid partial register stalls.  */
8053	operands[0] = gen_lowpart (SImode, operands[0]);
8054
8055      insn = (mode == HImode)
8056	     ? gen_zero_extendhisi2
8057	     : gen_zero_extendqisi2;
8058    }
8059  emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8060  DONE;
8061})
8062
8063(define_split
8064  [(set (match_operand 0 "register_operand")
8065	(and (match_dup 0)
8066	     (const_int -65536)))
8067   (clobber (reg:CC FLAGS_REG))]
8068  "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8069    || optimize_function_for_size_p (cfun)"
8070  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8071  "operands[1] = gen_lowpart (HImode, operands[0]);")
8072
8073(define_split
8074  [(set (match_operand 0 "ext_register_operand")
8075	(and (match_dup 0)
8076	     (const_int -256)))
8077   (clobber (reg:CC FLAGS_REG))]
8078  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8079   && reload_completed"
8080  [(set (strict_low_part (match_dup 1)) (const_int 0))]
8081  "operands[1] = gen_lowpart (QImode, operands[0]);")
8082
8083(define_split
8084  [(set (match_operand 0 "ext_register_operand")
8085	(and (match_dup 0)
8086	     (const_int -65281)))
8087   (clobber (reg:CC FLAGS_REG))]
8088  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8089   && reload_completed"
8090  [(parallel [(set (zero_extract:SI (match_dup 0)
8091				    (const_int 8)
8092				    (const_int 8))
8093		   (xor:SI
8094		     (zero_extract:SI (match_dup 0)
8095				      (const_int 8)
8096				      (const_int 8))
8097		     (zero_extract:SI (match_dup 0)
8098				      (const_int 8)
8099				      (const_int 8))))
8100	      (clobber (reg:CC FLAGS_REG))])]
8101  "operands[0] = gen_lowpart (SImode, operands[0]);")
8102
8103(define_insn "*anddi_2"
8104  [(set (reg FLAGS_REG)
8105	(compare
8106	 (and:DI
8107	  (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8108	  (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8109	 (const_int 0)))
8110   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8111	(and:DI (match_dup 1) (match_dup 2)))]
8112  "TARGET_64BIT
8113   && ix86_match_ccmode
8114	(insn,
8115	 /* If we are going to emit andl instead of andq, and the operands[2]
8116	    constant might have the SImode sign bit set, make sure the sign
8117	    flag isn't tested, because the instruction will set the sign flag
8118	    based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8119	    conservatively assume it might have bit 31 set.  */
8120	 (satisfies_constraint_Z (operands[2])
8121	  && (!CONST_INT_P (operands[2])
8122	      || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8123	 ? CCZmode : CCNOmode)
8124   && ix86_binary_operator_ok (AND, DImode, operands)"
8125  "@
8126   and{l}\t{%k2, %k0|%k0, %k2}
8127   and{q}\t{%2, %0|%0, %2}
8128   and{q}\t{%2, %0|%0, %2}"
8129  [(set_attr "type" "alu")
8130   (set_attr "mode" "SI,DI,DI")])
8131
8132(define_insn "*andqi_2_maybe_si"
8133  [(set (reg FLAGS_REG)
8134	(compare (and:QI
8135		  (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8136		  (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8137		 (const_int 0)))
8138   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8139	(and:QI (match_dup 1) (match_dup 2)))]
8140  "ix86_binary_operator_ok (AND, QImode, operands)
8141   && ix86_match_ccmode (insn,
8142			 CONST_INT_P (operands[2])
8143			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8144{
8145  if (which_alternative == 2)
8146    {
8147      if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8148        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8149      return "and{l}\t{%2, %k0|%k0, %2}";
8150    }
8151  return "and{b}\t{%2, %0|%0, %2}";
8152}
8153  [(set_attr "type" "alu")
8154   (set_attr "mode" "QI,QI,SI")])
8155
8156(define_insn "*and<mode>_2"
8157  [(set (reg FLAGS_REG)
8158	(compare (and:SWI124
8159		  (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8160		  (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8161		 (const_int 0)))
8162   (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8163	(and:SWI124 (match_dup 1) (match_dup 2)))]
8164  "ix86_match_ccmode (insn, CCNOmode)
8165   && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8166  "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8167  [(set_attr "type" "alu")
8168   (set_attr "mode" "<MODE>")])
8169
8170;; See comment for addsi_1_zext why we do use nonimmediate_operand
8171(define_insn "*andsi_2_zext"
8172  [(set (reg FLAGS_REG)
8173	(compare (and:SI
8174		  (match_operand:SI 1 "nonimmediate_operand" "%0")
8175		  (match_operand:SI 2 "x86_64_general_operand" "rme"))
8176		 (const_int 0)))
8177   (set (match_operand:DI 0 "register_operand" "=r")
8178	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8179  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8180   && ix86_binary_operator_ok (AND, SImode, operands)"
8181  "and{l}\t{%2, %k0|%k0, %2}"
8182  [(set_attr "type" "alu")
8183   (set_attr "mode" "SI")])
8184
8185(define_insn "*andqi_2_slp"
8186  [(set (reg FLAGS_REG)
8187	(compare (and:QI
8188		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8189		   (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8190		 (const_int 0)))
8191   (set (strict_low_part (match_dup 0))
8192	(and:QI (match_dup 0) (match_dup 1)))]
8193  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8194   && ix86_match_ccmode (insn, CCNOmode)
8195   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8196  "and{b}\t{%1, %0|%0, %1}"
8197  [(set_attr "type" "alu1")
8198   (set_attr "mode" "QI")])
8199
8200;; ??? A bug in recog prevents it from recognizing a const_int as an
8201;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8202;; for a QImode operand, which of course failed.
8203(define_insn "andqi_ext_0"
8204  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8205			 (const_int 8)
8206			 (const_int 8))
8207	(and:SI
8208	  (zero_extract:SI
8209	    (match_operand 1 "ext_register_operand" "0")
8210	    (const_int 8)
8211	    (const_int 8))
8212	  (match_operand 2 "const_int_operand" "n")))
8213   (clobber (reg:CC FLAGS_REG))]
8214  ""
8215  "and{b}\t{%2, %h0|%h0, %2}"
8216  [(set_attr "type" "alu")
8217   (set_attr "length_immediate" "1")
8218   (set_attr "modrm" "1")
8219   (set_attr "mode" "QI")])
8220
8221;; Generated by peephole translating test to and.  This shows up
8222;; often in fp comparisons.
8223(define_insn "*andqi_ext_0_cc"
8224  [(set (reg FLAGS_REG)
8225	(compare
8226	  (and:SI
8227	    (zero_extract:SI
8228	      (match_operand 1 "ext_register_operand" "0")
8229	      (const_int 8)
8230	      (const_int 8))
8231	    (match_operand 2 "const_int_operand" "n"))
8232	  (const_int 0)))
8233   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8234			 (const_int 8)
8235			 (const_int 8))
8236	(and:SI
8237	  (zero_extract:SI
8238	    (match_dup 1)
8239	    (const_int 8)
8240	    (const_int 8))
8241	  (match_dup 2)))]
8242  "ix86_match_ccmode (insn, CCNOmode)"
8243  "and{b}\t{%2, %h0|%h0, %2}"
8244  [(set_attr "type" "alu")
8245   (set_attr "length_immediate" "1")
8246   (set_attr "modrm" "1")
8247   (set_attr "mode" "QI")])
8248
8249(define_insn "*andqi_ext_1"
8250  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8251			 (const_int 8)
8252			 (const_int 8))
8253	(and:SI
8254	  (zero_extract:SI
8255	    (match_operand 1 "ext_register_operand" "0,0")
8256	    (const_int 8)
8257	    (const_int 8))
8258	  (zero_extend:SI
8259	    (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8260   (clobber (reg:CC FLAGS_REG))]
8261  ""
8262  "and{b}\t{%2, %h0|%h0, %2}"
8263  [(set_attr "isa" "*,nox64")
8264   (set_attr "type" "alu")
8265   (set_attr "length_immediate" "0")
8266   (set_attr "mode" "QI")])
8267
8268(define_insn "*andqi_ext_2"
8269  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8270			 (const_int 8)
8271			 (const_int 8))
8272	(and:SI
8273	  (zero_extract:SI
8274	    (match_operand 1 "ext_register_operand" "%0")
8275	    (const_int 8)
8276	    (const_int 8))
8277	  (zero_extract:SI
8278	    (match_operand 2 "ext_register_operand" "Q")
8279	    (const_int 8)
8280	    (const_int 8))))
8281   (clobber (reg:CC FLAGS_REG))]
8282  ""
8283  "and{b}\t{%h2, %h0|%h0, %h2}"
8284  [(set_attr "type" "alu")
8285   (set_attr "length_immediate" "0")
8286   (set_attr "mode" "QI")])
8287
8288;; Convert wide AND instructions with immediate operand to shorter QImode
8289;; equivalents when possible.
8290;; Don't do the splitting with memory operands, since it introduces risk
8291;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8292;; for size, but that can (should?) be handled by generic code instead.
8293(define_split
8294  [(set (match_operand 0 "register_operand")
8295	(and (match_operand 1 "register_operand")
8296	     (match_operand 2 "const_int_operand")))
8297   (clobber (reg:CC FLAGS_REG))]
8298   "reload_completed
8299    && QI_REG_P (operands[0])
8300    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8301    && !(~INTVAL (operands[2]) & ~(255 << 8))
8302    && GET_MODE (operands[0]) != QImode"
8303  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8304		   (and:SI (zero_extract:SI (match_dup 1)
8305					    (const_int 8) (const_int 8))
8306			   (match_dup 2)))
8307	      (clobber (reg:CC FLAGS_REG))])]
8308{
8309  operands[0] = gen_lowpart (SImode, operands[0]);
8310  operands[1] = gen_lowpart (SImode, operands[1]);
8311  operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8312})
8313
8314;; Since AND can be encoded with sign extended immediate, this is only
8315;; profitable when 7th bit is not set.
8316(define_split
8317  [(set (match_operand 0 "register_operand")
8318	(and (match_operand 1 "general_operand")
8319	     (match_operand 2 "const_int_operand")))
8320   (clobber (reg:CC FLAGS_REG))]
8321   "reload_completed
8322    && ANY_QI_REG_P (operands[0])
8323    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8324    && !(~INTVAL (operands[2]) & ~255)
8325    && !(INTVAL (operands[2]) & 128)
8326    && GET_MODE (operands[0]) != QImode"
8327  [(parallel [(set (strict_low_part (match_dup 0))
8328		   (and:QI (match_dup 1)
8329			   (match_dup 2)))
8330	      (clobber (reg:CC FLAGS_REG))])]
8331{
8332  operands[0] = gen_lowpart (QImode, operands[0]);
8333  operands[1] = gen_lowpart (QImode, operands[1]);
8334  operands[2] = gen_lowpart (QImode, operands[2]);
8335})
8336
8337;; Logical inclusive and exclusive OR instructions
8338
8339;; %%% This used to optimize known byte-wide and operations to memory.
8340;; If this is considered useful, it should be done with splitters.
8341
8342(define_expand "<code><mode>3"
8343  [(set (match_operand:SWIM 0 "nonimmediate_operand")
8344	(any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8345		     (match_operand:SWIM 2 "<general_operand>")))]
8346  ""
8347  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8348
8349(define_insn "*<code><mode>_1"
8350  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8351	(any_or:SWI48
8352	 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8353	 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8354   (clobber (reg:CC FLAGS_REG))]
8355  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8356  "@
8357   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8358   <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8359   k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8360  [(set_attr "type" "alu,alu,msklog")
8361   (set_attr "mode" "<MODE>")])
8362
8363(define_insn "*<code>hi_1"
8364  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8365	(any_or:HI
8366	 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8367	 (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8368   (clobber (reg:CC FLAGS_REG))]
8369  "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8370  "@
8371  <logic>{w}\t{%2, %0|%0, %2}
8372  <logic>{w}\t{%2, %0|%0, %2}
8373  k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8374  [(set_attr "type" "alu,alu,msklog")
8375   (set_attr "mode" "HI")])
8376
8377;; %%% Potential partial reg stall on alternative 2.  What to do?
8378(define_insn "*<code>qi_1"
8379  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8380	(any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8381		   (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8382   (clobber (reg:CC FLAGS_REG))]
8383  "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8384  "@
8385   <logic>{b}\t{%2, %0|%0, %2}
8386   <logic>{b}\t{%2, %0|%0, %2}
8387   <logic>{l}\t{%k2, %k0|%k0, %k2}
8388   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8389  [(set_attr "type" "alu,alu,alu,msklog")
8390   (set_attr "mode" "QI,QI,SI,HI")])
8391
8392;; See comment for addsi_1_zext why we do use nonimmediate_operand
8393(define_insn "*<code>si_1_zext"
8394  [(set (match_operand:DI 0 "register_operand" "=r")
8395	(zero_extend:DI
8396	 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8397		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8398   (clobber (reg:CC FLAGS_REG))]
8399  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8400  "<logic>{l}\t{%2, %k0|%k0, %2}"
8401  [(set_attr "type" "alu")
8402   (set_attr "mode" "SI")])
8403
8404(define_insn "*<code>si_1_zext_imm"
8405  [(set (match_operand:DI 0 "register_operand" "=r")
8406	(any_or:DI
8407	 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8408	 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8409   (clobber (reg:CC FLAGS_REG))]
8410  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8411  "<logic>{l}\t{%2, %k0|%k0, %2}"
8412  [(set_attr "type" "alu")
8413   (set_attr "mode" "SI")])
8414
8415(define_insn "*<code>qi_1_slp"
8416  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8417	(any_or:QI (match_dup 0)
8418		   (match_operand:QI 1 "general_operand" "qmn,qn")))
8419   (clobber (reg:CC FLAGS_REG))]
8420  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8421   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8422  "<logic>{b}\t{%1, %0|%0, %1}"
8423  [(set_attr "type" "alu1")
8424   (set_attr "mode" "QI")])
8425
8426(define_insn "*<code><mode>_2"
8427  [(set (reg FLAGS_REG)
8428	(compare (any_or:SWI
8429		  (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8430		  (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8431		 (const_int 0)))
8432   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8433	(any_or:SWI (match_dup 1) (match_dup 2)))]
8434  "ix86_match_ccmode (insn, CCNOmode)
8435   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8436  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8437  [(set_attr "type" "alu")
8438   (set_attr "mode" "<MODE>")])
8439
8440(define_insn "kxnor<mode>"
8441  [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8442	(not:SWI12
8443	  (xor:SWI12
8444	    (match_operand:SWI12 1 "register_operand" "0,k")
8445	    (match_operand:SWI12 2 "register_operand" "r,k"))))
8446   (clobber (reg:CC FLAGS_REG))]
8447  "TARGET_AVX512F"
8448{
8449  if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8450    return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8451  return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8452}
8453  [(set_attr "type" "*,msklog")
8454   (set_attr "prefix" "*,vex")
8455   (set_attr "mode" "<MODE>")])
8456
8457(define_insn "kxnor<mode>"
8458  [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8459	(not:SWI48x
8460	  (xor:SWI48x
8461	    (match_operand:SWI48x 1 "register_operand" "0,k")
8462	    (match_operand:SWI48x 2 "register_operand" "r,k"))))
8463   (clobber (reg:CC FLAGS_REG))]
8464  "TARGET_AVX512BW"
8465  "@
8466   #
8467   kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8468  [(set_attr "type" "*,msklog")
8469   (set_attr "prefix" "*,vex")
8470   (set_attr "mode" "<MODE>")])
8471
8472(define_split
8473  [(set (match_operand:SWI1248x 0 "general_reg_operand")
8474	(not:SWI1248x
8475	  (xor:SWI1248x
8476	    (match_dup 0)
8477	    (match_operand:SWI1248x 1 "general_reg_operand"))))
8478   (clobber (reg:CC FLAGS_REG))]
8479  "TARGET_AVX512F && reload_completed"
8480   [(parallel [(set (match_dup 0)
8481		    (xor:SWI1248x (match_dup 0)
8482				  (match_dup 1)))
8483	       (clobber (reg:CC FLAGS_REG))])
8484    (set (match_dup 0)
8485	 (not:SWI1248x (match_dup 0)))])
8486
8487;;There are kortrest[bdq] but no intrinsics for them.
8488;;We probably don't need to implement them.
8489(define_insn "kortestzhi"
8490  [(set (reg:CCZ FLAGS_REG)
8491	(compare:CCZ
8492	  (ior:HI
8493	    (match_operand:HI 0 "register_operand" "k")
8494	    (match_operand:HI 1 "register_operand" "k"))
8495	  (const_int 0)))]
8496  "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8497  "kortestw\t{%1, %0|%0, %1}"
8498  [(set_attr "mode" "HI")
8499   (set_attr "type" "msklog")
8500   (set_attr "prefix" "vex")])
8501
8502(define_insn "kortestchi"
8503  [(set (reg:CCC FLAGS_REG)
8504	(compare:CCC
8505	  (ior:HI
8506	    (match_operand:HI 0 "register_operand" "k")
8507	    (match_operand:HI 1 "register_operand" "k"))
8508	  (const_int -1)))]
8509  "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8510  "kortestw\t{%1, %0|%0, %1}"
8511  [(set_attr "mode" "HI")
8512   (set_attr "type" "msklog")
8513   (set_attr "prefix" "vex")])
8514
8515(define_insn "kunpckhi"
8516  [(set (match_operand:HI 0 "register_operand" "=k")
8517	(ior:HI
8518	  (ashift:HI
8519	    (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8520	    (const_int 8))
8521	  (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8522  "TARGET_AVX512F"
8523  "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8524  [(set_attr "mode" "HI")
8525   (set_attr "type" "msklog")
8526   (set_attr "prefix" "vex")])
8527
8528(define_insn "kunpcksi"
8529  [(set (match_operand:SI 0 "register_operand" "=k")
8530	(ior:SI
8531	  (ashift:SI
8532	    (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8533	    (const_int 16))
8534	  (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8535  "TARGET_AVX512BW"
8536  "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8537  [(set_attr "mode" "SI")])
8538
8539(define_insn "kunpckdi"
8540  [(set (match_operand:DI 0 "register_operand" "=k")
8541	(ior:DI
8542	  (ashift:DI
8543	    (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8544	    (const_int 32))
8545	  (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8546  "TARGET_AVX512BW"
8547  "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8548  [(set_attr "mode" "DI")])
8549
8550;; See comment for addsi_1_zext why we do use nonimmediate_operand
8551;; ??? Special case for immediate operand is missing - it is tricky.
8552(define_insn "*<code>si_2_zext"
8553  [(set (reg FLAGS_REG)
8554	(compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8555			    (match_operand:SI 2 "x86_64_general_operand" "rme"))
8556		 (const_int 0)))
8557   (set (match_operand:DI 0 "register_operand" "=r")
8558	(zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8559  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8560   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8561  "<logic>{l}\t{%2, %k0|%k0, %2}"
8562  [(set_attr "type" "alu")
8563   (set_attr "mode" "SI")])
8564
8565(define_insn "*<code>si_2_zext_imm"
8566  [(set (reg FLAGS_REG)
8567	(compare (any_or:SI
8568		  (match_operand:SI 1 "nonimmediate_operand" "%0")
8569		  (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8570		 (const_int 0)))
8571   (set (match_operand:DI 0 "register_operand" "=r")
8572	(any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8573  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8574   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8575  "<logic>{l}\t{%2, %k0|%k0, %2}"
8576  [(set_attr "type" "alu")
8577   (set_attr "mode" "SI")])
8578
8579(define_insn "*<code>qi_2_slp"
8580  [(set (reg FLAGS_REG)
8581	(compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8582			    (match_operand:QI 1 "general_operand" "qmn,qn"))
8583		 (const_int 0)))
8584   (set (strict_low_part (match_dup 0))
8585	(any_or:QI (match_dup 0) (match_dup 1)))]
8586  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8587   && ix86_match_ccmode (insn, CCNOmode)
8588   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8589  "<logic>{b}\t{%1, %0|%0, %1}"
8590  [(set_attr "type" "alu1")
8591   (set_attr "mode" "QI")])
8592
8593(define_insn "*<code><mode>_3"
8594  [(set (reg FLAGS_REG)
8595	(compare (any_or:SWI
8596		  (match_operand:SWI 1 "nonimmediate_operand" "%0")
8597		  (match_operand:SWI 2 "<general_operand>" "<g>"))
8598		 (const_int 0)))
8599   (clobber (match_scratch:SWI 0 "=<r>"))]
8600  "ix86_match_ccmode (insn, CCNOmode)
8601   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8602  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8603  [(set_attr "type" "alu")
8604   (set_attr "mode" "<MODE>")])
8605
8606(define_insn "*<code>qi_ext_0"
8607  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8608			 (const_int 8)
8609			 (const_int 8))
8610	(any_or:SI
8611	  (zero_extract:SI
8612	    (match_operand 1 "ext_register_operand" "0")
8613	    (const_int 8)
8614	    (const_int 8))
8615	  (match_operand 2 "const_int_operand" "n")))
8616   (clobber (reg:CC FLAGS_REG))]
8617  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8618  "<logic>{b}\t{%2, %h0|%h0, %2}"
8619  [(set_attr "type" "alu")
8620   (set_attr "length_immediate" "1")
8621   (set_attr "modrm" "1")
8622   (set_attr "mode" "QI")])
8623
8624(define_insn "*<code>qi_ext_1"
8625  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8626			 (const_int 8)
8627			 (const_int 8))
8628	(any_or:SI
8629	  (zero_extract:SI
8630	    (match_operand 1 "ext_register_operand" "0,0")
8631	    (const_int 8)
8632	    (const_int 8))
8633	  (zero_extend:SI
8634	    (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8635   (clobber (reg:CC FLAGS_REG))]
8636  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8637  "<logic>{b}\t{%2, %h0|%h0, %2}"
8638  [(set_attr "isa" "*,nox64")
8639   (set_attr "type" "alu")
8640   (set_attr "length_immediate" "0")
8641   (set_attr "mode" "QI")])
8642
8643(define_insn "*<code>qi_ext_2"
8644  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8645			 (const_int 8)
8646			 (const_int 8))
8647	(any_or:SI
8648	  (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8649	  		   (const_int 8)
8650			   (const_int 8))
8651	  (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8652	  		   (const_int 8)
8653			   (const_int 8))))
8654   (clobber (reg:CC FLAGS_REG))]
8655  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8656  "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8657  [(set_attr "type" "alu")
8658   (set_attr "length_immediate" "0")
8659   (set_attr "mode" "QI")])
8660
8661(define_split
8662  [(set (match_operand 0 "register_operand")
8663	(any_or (match_operand 1 "register_operand")
8664		(match_operand 2 "const_int_operand")))
8665   (clobber (reg:CC FLAGS_REG))]
8666   "reload_completed
8667    && QI_REG_P (operands[0])
8668    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8669    && !(INTVAL (operands[2]) & ~(255 << 8))
8670    && GET_MODE (operands[0]) != QImode"
8671  [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8672		   (any_or:SI (zero_extract:SI (match_dup 1)
8673					       (const_int 8) (const_int 8))
8674			      (match_dup 2)))
8675	      (clobber (reg:CC FLAGS_REG))])]
8676{
8677  operands[0] = gen_lowpart (SImode, operands[0]);
8678  operands[1] = gen_lowpart (SImode, operands[1]);
8679  operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8680})
8681
8682;; Since OR can be encoded with sign extended immediate, this is only
8683;; profitable when 7th bit is set.
8684(define_split
8685  [(set (match_operand 0 "register_operand")
8686	(any_or (match_operand 1 "general_operand")
8687		(match_operand 2 "const_int_operand")))
8688   (clobber (reg:CC FLAGS_REG))]
8689   "reload_completed
8690    && ANY_QI_REG_P (operands[0])
8691    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8692    && !(INTVAL (operands[2]) & ~255)
8693    && (INTVAL (operands[2]) & 128)
8694    && GET_MODE (operands[0]) != QImode"
8695  [(parallel [(set (strict_low_part (match_dup 0))
8696		   (any_or:QI (match_dup 1)
8697			      (match_dup 2)))
8698	      (clobber (reg:CC FLAGS_REG))])]
8699{
8700  operands[0] = gen_lowpart (QImode, operands[0]);
8701  operands[1] = gen_lowpart (QImode, operands[1]);
8702  operands[2] = gen_lowpart (QImode, operands[2]);
8703})
8704
8705(define_expand "xorqi_cc_ext_1"
8706  [(parallel [
8707     (set (reg:CCNO FLAGS_REG)
8708	  (compare:CCNO
8709	    (xor:SI
8710	      (zero_extract:SI
8711		(match_operand 1 "ext_register_operand")
8712		(const_int 8)
8713		(const_int 8))
8714	      (match_operand:QI 2 "const_int_operand"))
8715	    (const_int 0)))
8716     (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8717			   (const_int 8)
8718			   (const_int 8))
8719	  (xor:SI
8720	    (zero_extract:SI
8721	     (match_dup 1)
8722	     (const_int 8)
8723	     (const_int 8))
8724	    (match_dup 2)))])])
8725
8726(define_insn "*xorqi_cc_ext_1"
8727  [(set (reg FLAGS_REG)
8728	(compare
8729	  (xor:SI
8730	    (zero_extract:SI
8731	      (match_operand 1 "ext_register_operand" "0,0")
8732	      (const_int 8)
8733	      (const_int 8))
8734	    (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8735	  (const_int 0)))
8736   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8737			 (const_int 8)
8738			 (const_int 8))
8739	(xor:SI
8740	  (zero_extract:SI
8741	   (match_dup 1)
8742	   (const_int 8)
8743	   (const_int 8))
8744	  (match_dup 2)))]
8745  "ix86_match_ccmode (insn, CCNOmode)"
8746  "xor{b}\t{%2, %h0|%h0, %2}"
8747  [(set_attr "isa" "*,nox64")
8748   (set_attr "type" "alu")
8749   (set_attr "modrm" "1")
8750   (set_attr "mode" "QI")])
8751
8752;; Negation instructions
8753
8754(define_expand "neg<mode>2"
8755  [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8756	(neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8757  ""
8758  "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8759
8760(define_insn_and_split "*neg<dwi>2_doubleword"
8761  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8762	(neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8763   (clobber (reg:CC FLAGS_REG))]
8764  "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8765  "#"
8766  "reload_completed"
8767  [(parallel
8768    [(set (reg:CCZ FLAGS_REG)
8769	  (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8770     (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8771   (parallel
8772    [(set (match_dup 2)
8773	  (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8774				(match_dup 3))
8775		     (const_int 0)))
8776     (clobber (reg:CC FLAGS_REG))])
8777   (parallel
8778    [(set (match_dup 2)
8779	  (neg:DWIH (match_dup 2)))
8780     (clobber (reg:CC FLAGS_REG))])]
8781  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8782
8783(define_insn "*neg<mode>2_1"
8784  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8785	(neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8786   (clobber (reg:CC FLAGS_REG))]
8787  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8788  "neg{<imodesuffix>}\t%0"
8789  [(set_attr "type" "negnot")
8790   (set_attr "mode" "<MODE>")])
8791
8792;; Combine is quite creative about this pattern.
8793(define_insn "*negsi2_1_zext"
8794  [(set (match_operand:DI 0 "register_operand" "=r")
8795	(lshiftrt:DI
8796	  (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8797			     (const_int 32)))
8798	(const_int 32)))
8799   (clobber (reg:CC FLAGS_REG))]
8800  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8801  "neg{l}\t%k0"
8802  [(set_attr "type" "negnot")
8803   (set_attr "mode" "SI")])
8804
8805;; The problem with neg is that it does not perform (compare x 0),
8806;; it really performs (compare 0 x), which leaves us with the zero
8807;; flag being the only useful item.
8808
8809(define_insn "*neg<mode>2_cmpz"
8810  [(set (reg:CCZ FLAGS_REG)
8811	(compare:CCZ
8812	  (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8813		   (const_int 0)))
8814   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8815	(neg:SWI (match_dup 1)))]
8816  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8817  "neg{<imodesuffix>}\t%0"
8818  [(set_attr "type" "negnot")
8819   (set_attr "mode" "<MODE>")])
8820
8821(define_insn "*negsi2_cmpz_zext"
8822  [(set (reg:CCZ FLAGS_REG)
8823	(compare:CCZ
8824	  (lshiftrt:DI
8825	    (neg:DI (ashift:DI
8826		      (match_operand:DI 1 "register_operand" "0")
8827		      (const_int 32)))
8828	    (const_int 32))
8829	  (const_int 0)))
8830   (set (match_operand:DI 0 "register_operand" "=r")
8831	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8832					(const_int 32)))
8833		     (const_int 32)))]
8834  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8835  "neg{l}\t%k0"
8836  [(set_attr "type" "negnot")
8837   (set_attr "mode" "SI")])
8838
8839;; Negate with jump on overflow.
8840(define_expand "negv<mode>3"
8841  [(parallel [(set (reg:CCO FLAGS_REG)
8842		   (ne:CCO (match_operand:SWI 1 "register_operand")
8843			   (match_dup 3)))
8844	      (set (match_operand:SWI 0 "register_operand")
8845		   (neg:SWI (match_dup 1)))])
8846   (set (pc) (if_then_else
8847	       (eq (reg:CCO FLAGS_REG) (const_int 0))
8848	       (label_ref (match_operand 2))
8849	       (pc)))]
8850  ""
8851{
8852  operands[3]
8853    = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8854		    <MODE>mode);
8855})
8856
8857(define_insn "*negv<mode>3"
8858  [(set (reg:CCO FLAGS_REG)
8859	(ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8860		(match_operand:SWI 2 "const_int_operand")))
8861   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8862	(neg:SWI (match_dup 1)))]
8863  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8864   && mode_signbit_p (<MODE>mode, operands[2])"
8865  "neg{<imodesuffix>}\t%0"
8866  [(set_attr "type" "negnot")
8867   (set_attr "mode" "<MODE>")])
8868
8869;; Changing of sign for FP values is doable using integer unit too.
8870
8871(define_expand "<code><mode>2"
8872  [(set (match_operand:X87MODEF 0 "register_operand")
8873	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8874  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8875  "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8876
8877(define_insn "*absneg<mode>2_mixed"
8878  [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8879	(match_operator:MODEF 3 "absneg_operator"
8880	  [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8881   (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8882   (clobber (reg:CC FLAGS_REG))]
8883  "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8884  "#")
8885
8886(define_insn "*absneg<mode>2_sse"
8887  [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8888	(match_operator:MODEF 3 "absneg_operator"
8889	  [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8890   (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8891   (clobber (reg:CC FLAGS_REG))]
8892  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8893  "#")
8894
8895(define_insn "*absneg<mode>2_i387"
8896  [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8897	(match_operator:X87MODEF 3 "absneg_operator"
8898	  [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8899   (use (match_operand 2))
8900   (clobber (reg:CC FLAGS_REG))]
8901  "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8902  "#")
8903
8904(define_expand "<code>tf2"
8905  [(set (match_operand:TF 0 "register_operand")
8906	(absneg:TF (match_operand:TF 1 "register_operand")))]
8907  "TARGET_SSE"
8908  "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8909
8910(define_insn "*absnegtf2_sse"
8911  [(set (match_operand:TF 0 "register_operand" "=x,x")
8912	(match_operator:TF 3 "absneg_operator"
8913	  [(match_operand:TF 1 "register_operand" "0,x")]))
8914   (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8915   (clobber (reg:CC FLAGS_REG))]
8916  "TARGET_SSE"
8917  "#")
8918
8919;; Splitters for fp abs and neg.
8920
8921(define_split
8922  [(set (match_operand 0 "fp_register_operand")
8923	(match_operator 1 "absneg_operator" [(match_dup 0)]))
8924   (use (match_operand 2))
8925   (clobber (reg:CC FLAGS_REG))]
8926  "reload_completed"
8927  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8928
8929(define_split
8930  [(set (match_operand 0 "register_operand")
8931	(match_operator 3 "absneg_operator"
8932	  [(match_operand 1 "register_operand")]))
8933   (use (match_operand 2 "nonimmediate_operand"))
8934   (clobber (reg:CC FLAGS_REG))]
8935  "reload_completed && SSE_REG_P (operands[0])"
8936  [(set (match_dup 0) (match_dup 3))]
8937{
8938  machine_mode mode = GET_MODE (operands[0]);
8939  machine_mode vmode = GET_MODE (operands[2]);
8940  rtx tmp;
8941
8942  operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8943  operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8944  if (operands_match_p (operands[0], operands[2]))
8945    std::swap (operands[1], operands[2]);
8946  if (GET_CODE (operands[3]) == ABS)
8947    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8948  else
8949    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8950  operands[3] = tmp;
8951})
8952
8953(define_split
8954  [(set (match_operand:SF 0 "register_operand")
8955	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8956   (use (match_operand:V4SF 2))
8957   (clobber (reg:CC FLAGS_REG))]
8958  "reload_completed"
8959  [(parallel [(set (match_dup 0) (match_dup 1))
8960	      (clobber (reg:CC FLAGS_REG))])]
8961{
8962  rtx tmp;
8963  operands[0] = gen_lowpart (SImode, operands[0]);
8964  if (GET_CODE (operands[1]) == ABS)
8965    {
8966      tmp = gen_int_mode (0x7fffffff, SImode);
8967      tmp = gen_rtx_AND (SImode, operands[0], tmp);
8968    }
8969  else
8970    {
8971      tmp = gen_int_mode (0x80000000, SImode);
8972      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8973    }
8974  operands[1] = tmp;
8975})
8976
8977(define_split
8978  [(set (match_operand:DF 0 "register_operand")
8979	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8980   (use (match_operand 2))
8981   (clobber (reg:CC FLAGS_REG))]
8982  "reload_completed"
8983  [(parallel [(set (match_dup 0) (match_dup 1))
8984	      (clobber (reg:CC FLAGS_REG))])]
8985{
8986  rtx tmp;
8987  if (TARGET_64BIT)
8988    {
8989      tmp = gen_lowpart (DImode, operands[0]);
8990      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8991      operands[0] = tmp;
8992
8993      if (GET_CODE (operands[1]) == ABS)
8994	tmp = const0_rtx;
8995      else
8996	tmp = gen_rtx_NOT (DImode, tmp);
8997    }
8998  else
8999    {
9000      operands[0] = gen_highpart (SImode, operands[0]);
9001      if (GET_CODE (operands[1]) == ABS)
9002	{
9003	  tmp = gen_int_mode (0x7fffffff, SImode);
9004	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
9005	}
9006      else
9007	{
9008	  tmp = gen_int_mode (0x80000000, SImode);
9009	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9010	}
9011    }
9012  operands[1] = tmp;
9013})
9014
9015(define_split
9016  [(set (match_operand:XF 0 "register_operand")
9017	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9018   (use (match_operand 2))
9019   (clobber (reg:CC FLAGS_REG))]
9020  "reload_completed"
9021  [(parallel [(set (match_dup 0) (match_dup 1))
9022	      (clobber (reg:CC FLAGS_REG))])]
9023{
9024  rtx tmp;
9025  operands[0] = gen_rtx_REG (SImode,
9026			     true_regnum (operands[0])
9027			     + (TARGET_64BIT ? 1 : 2));
9028  if (GET_CODE (operands[1]) == ABS)
9029    {
9030      tmp = GEN_INT (0x7fff);
9031      tmp = gen_rtx_AND (SImode, operands[0], tmp);
9032    }
9033  else
9034    {
9035      tmp = GEN_INT (0x8000);
9036      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9037    }
9038  operands[1] = tmp;
9039})
9040
9041;; Conditionalize these after reload. If they match before reload, we
9042;; lose the clobber and ability to use integer instructions.
9043
9044(define_insn "*<code><mode>2_1"
9045  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9046	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9047  "TARGET_80387
9048   && (reload_completed
9049       || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9050  "f<absneg_mnemonic>"
9051  [(set_attr "type" "fsgn")
9052   (set_attr "mode" "<MODE>")])
9053
9054(define_insn "*<code>extendsfdf2"
9055  [(set (match_operand:DF 0 "register_operand" "=f")
9056	(absneg:DF (float_extend:DF
9057		     (match_operand:SF 1 "register_operand" "0"))))]
9058  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9059  "f<absneg_mnemonic>"
9060  [(set_attr "type" "fsgn")
9061   (set_attr "mode" "DF")])
9062
9063(define_insn "*<code>extendsfxf2"
9064  [(set (match_operand:XF 0 "register_operand" "=f")
9065	(absneg:XF (float_extend:XF
9066		     (match_operand:SF 1 "register_operand" "0"))))]
9067  "TARGET_80387"
9068  "f<absneg_mnemonic>"
9069  [(set_attr "type" "fsgn")
9070   (set_attr "mode" "XF")])
9071
9072(define_insn "*<code>extenddfxf2"
9073  [(set (match_operand:XF 0 "register_operand" "=f")
9074	(absneg:XF (float_extend:XF
9075		     (match_operand:DF 1 "register_operand" "0"))))]
9076  "TARGET_80387"
9077  "f<absneg_mnemonic>"
9078  [(set_attr "type" "fsgn")
9079   (set_attr "mode" "XF")])
9080
9081;; Copysign instructions
9082
9083(define_mode_iterator CSGNMODE [SF DF TF])
9084(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9085
9086(define_expand "copysign<mode>3"
9087  [(match_operand:CSGNMODE 0 "register_operand")
9088   (match_operand:CSGNMODE 1 "nonmemory_operand")
9089   (match_operand:CSGNMODE 2 "register_operand")]
9090  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9091   || (TARGET_SSE && (<MODE>mode == TFmode))"
9092  "ix86_expand_copysign (operands); DONE;")
9093
9094(define_insn_and_split "copysign<mode>3_const"
9095  [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9096	(unspec:CSGNMODE
9097	  [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9098	   (match_operand:CSGNMODE 2 "register_operand" "0")
9099	   (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9100	  UNSPEC_COPYSIGN))]
9101  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9102   || (TARGET_SSE && (<MODE>mode == TFmode))"
9103  "#"
9104  "&& reload_completed"
9105  [(const_int 0)]
9106  "ix86_split_copysign_const (operands); DONE;")
9107
9108(define_insn "copysign<mode>3_var"
9109  [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9110	(unspec:CSGNMODE
9111	  [(match_operand:CSGNMODE 2 "register_operand"	"x,0,0,x,x")
9112	   (match_operand:CSGNMODE 3 "register_operand"	"1,1,x,1,x")
9113	   (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9114	   (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9115	  UNSPEC_COPYSIGN))
9116   (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9117  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9118   || (TARGET_SSE && (<MODE>mode == TFmode))"
9119  "#")
9120
9121(define_split
9122  [(set (match_operand:CSGNMODE 0 "register_operand")
9123	(unspec:CSGNMODE
9124	  [(match_operand:CSGNMODE 2 "register_operand")
9125	   (match_operand:CSGNMODE 3 "register_operand")
9126	   (match_operand:<CSGNVMODE> 4)
9127	   (match_operand:<CSGNVMODE> 5)]
9128	  UNSPEC_COPYSIGN))
9129   (clobber (match_scratch:<CSGNVMODE> 1))]
9130  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9131    || (TARGET_SSE && (<MODE>mode == TFmode)))
9132   && reload_completed"
9133  [(const_int 0)]
9134  "ix86_split_copysign_var (operands); DONE;")
9135
9136;; One complement instructions
9137
9138(define_expand "one_cmpl<mode>2"
9139  [(set (match_operand:SWIM 0 "nonimmediate_operand")
9140	(not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9141  ""
9142  "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9143
9144(define_insn "*one_cmpl<mode>2_1"
9145  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9146	(not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9147  "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9148  "@
9149   not{<imodesuffix>}\t%0
9150   knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9151  [(set_attr "isa" "*,avx512bw")
9152   (set_attr "type" "negnot,msklog")
9153   (set_attr "prefix" "*,vex")
9154   (set_attr "mode" "<MODE>")])
9155
9156(define_insn "*one_cmplhi2_1"
9157  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9158	(not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9159  "ix86_unary_operator_ok (NOT, HImode, operands)"
9160  "@
9161   not{w}\t%0
9162   knotw\t{%1, %0|%0, %1}"
9163  [(set_attr "isa" "*,avx512f")
9164   (set_attr "type" "negnot,msklog")
9165   (set_attr "prefix" "*,vex")
9166   (set_attr "mode" "HI")])
9167
9168;; %%% Potential partial reg stall on alternative 1.  What to do?
9169(define_insn "*one_cmplqi2_1"
9170  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9171	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9172  "ix86_unary_operator_ok (NOT, QImode, operands)"
9173{
9174  switch (which_alternative)
9175    {
9176    case 0:
9177      return "not{b}\t%0";
9178    case 1:
9179      return "not{l}\t%k0";
9180    case 2:
9181      if (TARGET_AVX512DQ)
9182	return "knotb\t{%1, %0|%0, %1}";
9183      return "knotw\t{%1, %0|%0, %1}";
9184    default:
9185      gcc_unreachable ();
9186    }
9187}
9188  [(set_attr "isa" "*,*,avx512f")
9189   (set_attr "type" "negnot,negnot,msklog")
9190   (set_attr "prefix" "*,*,vex")
9191   (set_attr "mode" "QI,SI,QI")])
9192
9193;; ??? Currently never generated - xor is used instead.
9194(define_insn "*one_cmplsi2_1_zext"
9195  [(set (match_operand:DI 0 "register_operand" "=r")
9196	(zero_extend:DI
9197	  (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9198  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9199  "not{l}\t%k0"
9200  [(set_attr "type" "negnot")
9201   (set_attr "mode" "SI")])
9202
9203(define_insn "*one_cmpl<mode>2_2"
9204  [(set (reg FLAGS_REG)
9205	(compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9206		 (const_int 0)))
9207   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9208	(not:SWI (match_dup 1)))]
9209  "ix86_match_ccmode (insn, CCNOmode)
9210   && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9211  "#"
9212  [(set_attr "type" "alu1")
9213   (set_attr "mode" "<MODE>")])
9214
9215(define_split
9216  [(set (match_operand 0 "flags_reg_operand")
9217	(match_operator 2 "compare_operator"
9218	  [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9219	   (const_int 0)]))
9220   (set (match_operand:SWI 1 "nonimmediate_operand")
9221	(not:SWI (match_dup 3)))]
9222  "ix86_match_ccmode (insn, CCNOmode)"
9223  [(parallel [(set (match_dup 0)
9224		   (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9225				    (const_int 0)]))
9226	      (set (match_dup 1)
9227		   (xor:SWI (match_dup 3) (const_int -1)))])])
9228
9229;; ??? Currently never generated - xor is used instead.
9230(define_insn "*one_cmplsi2_2_zext"
9231  [(set (reg FLAGS_REG)
9232	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9233		 (const_int 0)))
9234   (set (match_operand:DI 0 "register_operand" "=r")
9235	(zero_extend:DI (not:SI (match_dup 1))))]
9236  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9237   && ix86_unary_operator_ok (NOT, SImode, operands)"
9238  "#"
9239  [(set_attr "type" "alu1")
9240   (set_attr "mode" "SI")])
9241
9242(define_split
9243  [(set (match_operand 0 "flags_reg_operand")
9244	(match_operator 2 "compare_operator"
9245	  [(not:SI (match_operand:SI 3 "register_operand"))
9246	   (const_int 0)]))
9247   (set (match_operand:DI 1 "register_operand")
9248	(zero_extend:DI (not:SI (match_dup 3))))]
9249  "ix86_match_ccmode (insn, CCNOmode)"
9250  [(parallel [(set (match_dup 0)
9251		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9252				    (const_int 0)]))
9253	      (set (match_dup 1)
9254		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9255
9256;; Shift instructions
9257
9258;; DImode shifts are implemented using the i386 "shift double" opcode,
9259;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9260;; is variable, then the count is in %cl and the "imm" operand is dropped
9261;; from the assembler input.
9262;;
9263;; This instruction shifts the target reg/mem as usual, but instead of
9264;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9265;; is a left shift double, bits are taken from the high order bits of
9266;; reg, else if the insn is a shift right double, bits are taken from the
9267;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9268;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9269;;
9270;; Since sh[lr]d does not change the `reg' operand, that is done
9271;; separately, making all shifts emit pairs of shift double and normal
9272;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9273;; support a 63 bit shift, each shift where the count is in a reg expands
9274;; to a pair of shifts, a branch, a shift by 32 and a label.
9275;;
9276;; If the shift count is a constant, we need never emit more than one
9277;; shift pair, instead using moves and sign extension for counts greater
9278;; than 31.
9279
9280(define_expand "ashl<mode>3"
9281  [(set (match_operand:SDWIM 0 "<shift_operand>")
9282	(ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9283		      (match_operand:QI 2 "nonmemory_operand")))]
9284  ""
9285  "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9286
9287(define_insn "*ashl<mode>3_doubleword"
9288  [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9289	(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9290		    (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9291   (clobber (reg:CC FLAGS_REG))]
9292  ""
9293  "#"
9294  [(set_attr "type" "multi")])
9295
9296(define_split
9297  [(set (match_operand:DWI 0 "register_operand")
9298	(ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9299		    (match_operand:QI 2 "nonmemory_operand")))
9300   (clobber (reg:CC FLAGS_REG))]
9301  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9302  [(const_int 0)]
9303  "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9304
9305;; By default we don't ask for a scratch register, because when DWImode
9306;; values are manipulated, registers are already at a premium.  But if
9307;; we have one handy, we won't turn it away.
9308
9309(define_peephole2
9310  [(match_scratch:DWIH 3 "r")
9311   (parallel [(set (match_operand:<DWI> 0 "register_operand")
9312		   (ashift:<DWI>
9313		     (match_operand:<DWI> 1 "nonmemory_operand")
9314		     (match_operand:QI 2 "nonmemory_operand")))
9315	      (clobber (reg:CC FLAGS_REG))])
9316   (match_dup 3)]
9317  "TARGET_CMOVE"
9318  [(const_int 0)]
9319  "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9320
9321(define_insn "x86_64_shld"
9322  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9323        (ior:DI (ashift:DI (match_dup 0)
9324		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
9325		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9326		  (minus:QI (const_int 64) (match_dup 2)))))
9327   (clobber (reg:CC FLAGS_REG))]
9328  "TARGET_64BIT"
9329  "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9330  [(set_attr "type" "ishift")
9331   (set_attr "prefix_0f" "1")
9332   (set_attr "mode" "DI")
9333   (set_attr "athlon_decode" "vector")
9334   (set_attr "amdfam10_decode" "vector")
9335   (set_attr "bdver1_decode" "vector")])
9336
9337(define_insn "x86_shld"
9338  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9339        (ior:SI (ashift:SI (match_dup 0)
9340		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
9341		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9342		  (minus:QI (const_int 32) (match_dup 2)))))
9343   (clobber (reg:CC FLAGS_REG))]
9344  ""
9345  "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9346  [(set_attr "type" "ishift")
9347   (set_attr "prefix_0f" "1")
9348   (set_attr "mode" "SI")
9349   (set_attr "pent_pair" "np")
9350   (set_attr "athlon_decode" "vector")
9351   (set_attr "amdfam10_decode" "vector")
9352   (set_attr "bdver1_decode" "vector")])
9353
9354(define_expand "x86_shift<mode>_adj_1"
9355  [(set (reg:CCZ FLAGS_REG)
9356	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9357			     (match_dup 4))
9358		     (const_int 0)))
9359   (set (match_operand:SWI48 0 "register_operand")
9360        (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9361			    (match_operand:SWI48 1 "register_operand")
9362			    (match_dup 0)))
9363   (set (match_dup 1)
9364	(if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9365			    (match_operand:SWI48 3 "register_operand")
9366			    (match_dup 1)))]
9367  "TARGET_CMOVE"
9368  "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9369
9370(define_expand "x86_shift<mode>_adj_2"
9371  [(use (match_operand:SWI48 0 "register_operand"))
9372   (use (match_operand:SWI48 1 "register_operand"))
9373   (use (match_operand:QI 2 "register_operand"))]
9374  ""
9375{
9376  rtx_code_label *label = gen_label_rtx ();
9377  rtx tmp;
9378
9379  emit_insn (gen_testqi_ccz_1 (operands[2],
9380			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9381
9382  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9383  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9384  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9385			      gen_rtx_LABEL_REF (VOIDmode, label),
9386			      pc_rtx);
9387  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9388  JUMP_LABEL (tmp) = label;
9389
9390  emit_move_insn (operands[0], operands[1]);
9391  ix86_expand_clear (operands[1]);
9392
9393  emit_label (label);
9394  LABEL_NUSES (label) = 1;
9395
9396  DONE;
9397})
9398
9399;; Avoid useless masking of count operand.
9400(define_insn "*ashl<mode>3_mask"
9401  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9402	(ashift:SWI48
9403	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
9404	  (subreg:QI
9405	    (and:SI
9406	      (match_operand:SI 2 "register_operand" "c")
9407	      (match_operand:SI 3 "const_int_operand" "n")) 0)))
9408   (clobber (reg:CC FLAGS_REG))]
9409  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9410   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9411      == GET_MODE_BITSIZE (<MODE>mode)-1"
9412{
9413  return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9414}
9415  [(set_attr "type" "ishift")
9416   (set_attr "mode" "<MODE>")])
9417
9418(define_insn "*bmi2_ashl<mode>3_1"
9419  [(set (match_operand:SWI48 0 "register_operand" "=r")
9420	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9421		      (match_operand:SWI48 2 "register_operand" "r")))]
9422  "TARGET_BMI2"
9423  "shlx\t{%2, %1, %0|%0, %1, %2}"
9424  [(set_attr "type" "ishiftx")
9425   (set_attr "mode" "<MODE>")])
9426
9427(define_insn "*ashl<mode>3_1"
9428  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9429	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9430		      (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9431   (clobber (reg:CC FLAGS_REG))]
9432  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9433{
9434  switch (get_attr_type (insn))
9435    {
9436    case TYPE_LEA:
9437    case TYPE_ISHIFTX:
9438      return "#";
9439
9440    case TYPE_ALU:
9441      gcc_assert (operands[2] == const1_rtx);
9442      gcc_assert (rtx_equal_p (operands[0], operands[1]));
9443      return "add{<imodesuffix>}\t%0, %0";
9444
9445    default:
9446      if (operands[2] == const1_rtx
9447	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9448	return "sal{<imodesuffix>}\t%0";
9449      else
9450	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9451    }
9452}
9453  [(set_attr "isa" "*,*,bmi2")
9454   (set (attr "type")
9455     (cond [(eq_attr "alternative" "1")
9456	      (const_string "lea")
9457	    (eq_attr "alternative" "2")
9458	      (const_string "ishiftx")
9459            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9460		      (match_operand 0 "register_operand"))
9461		 (match_operand 2 "const1_operand"))
9462	      (const_string "alu")
9463	   ]
9464	   (const_string "ishift")))
9465   (set (attr "length_immediate")
9466     (if_then_else
9467       (ior (eq_attr "type" "alu")
9468	    (and (eq_attr "type" "ishift")
9469		 (and (match_operand 2 "const1_operand")
9470		      (ior (match_test "TARGET_SHIFT1")
9471			   (match_test "optimize_function_for_size_p (cfun)")))))
9472       (const_string "0")
9473       (const_string "*")))
9474   (set_attr "mode" "<MODE>")])
9475
9476;; Convert shift to the shiftx pattern to avoid flags dependency.
9477(define_split
9478  [(set (match_operand:SWI48 0 "register_operand")
9479	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9480		      (match_operand:QI 2 "register_operand")))
9481   (clobber (reg:CC FLAGS_REG))]
9482  "TARGET_BMI2 && reload_completed"
9483  [(set (match_dup 0)
9484	(ashift:SWI48 (match_dup 1) (match_dup 2)))]
9485  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9486
9487(define_insn "*bmi2_ashlsi3_1_zext"
9488  [(set (match_operand:DI 0 "register_operand" "=r")
9489	(zero_extend:DI
9490	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9491		     (match_operand:SI 2 "register_operand" "r"))))]
9492  "TARGET_64BIT && TARGET_BMI2"
9493  "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9494  [(set_attr "type" "ishiftx")
9495   (set_attr "mode" "SI")])
9496
9497(define_insn "*ashlsi3_1_zext"
9498  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9499	(zero_extend:DI
9500	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9501		     (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9502   (clobber (reg:CC FLAGS_REG))]
9503  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9504{
9505  switch (get_attr_type (insn))
9506    {
9507    case TYPE_LEA:
9508    case TYPE_ISHIFTX:
9509      return "#";
9510
9511    case TYPE_ALU:
9512      gcc_assert (operands[2] == const1_rtx);
9513      return "add{l}\t%k0, %k0";
9514
9515    default:
9516      if (operands[2] == const1_rtx
9517	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9518	return "sal{l}\t%k0";
9519      else
9520	return "sal{l}\t{%2, %k0|%k0, %2}";
9521    }
9522}
9523  [(set_attr "isa" "*,*,bmi2")
9524   (set (attr "type")
9525     (cond [(eq_attr "alternative" "1")
9526	      (const_string "lea")
9527	    (eq_attr "alternative" "2")
9528	      (const_string "ishiftx")
9529            (and (match_test "TARGET_DOUBLE_WITH_ADD")
9530		 (match_operand 2 "const1_operand"))
9531	      (const_string "alu")
9532	   ]
9533	   (const_string "ishift")))
9534   (set (attr "length_immediate")
9535     (if_then_else
9536       (ior (eq_attr "type" "alu")
9537	    (and (eq_attr "type" "ishift")
9538		 (and (match_operand 2 "const1_operand")
9539		      (ior (match_test "TARGET_SHIFT1")
9540			   (match_test "optimize_function_for_size_p (cfun)")))))
9541       (const_string "0")
9542       (const_string "*")))
9543   (set_attr "mode" "SI")])
9544
9545;; Convert shift to the shiftx pattern to avoid flags dependency.
9546(define_split
9547  [(set (match_operand:DI 0 "register_operand")
9548	(zero_extend:DI
9549	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9550		     (match_operand:QI 2 "register_operand"))))
9551   (clobber (reg:CC FLAGS_REG))]
9552  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9553  [(set (match_dup 0)
9554	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9555  "operands[2] = gen_lowpart (SImode, operands[2]);")
9556
9557(define_insn "*ashlhi3_1"
9558  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9559	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9560		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9561   (clobber (reg:CC FLAGS_REG))]
9562  "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9563{
9564  switch (get_attr_type (insn))
9565    {
9566    case TYPE_LEA:
9567      return "#";
9568
9569    case TYPE_ALU:
9570      gcc_assert (operands[2] == const1_rtx);
9571      return "add{w}\t%0, %0";
9572
9573    default:
9574      if (operands[2] == const1_rtx
9575	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9576	return "sal{w}\t%0";
9577      else
9578	return "sal{w}\t{%2, %0|%0, %2}";
9579    }
9580}
9581  [(set (attr "type")
9582     (cond [(eq_attr "alternative" "1")
9583	      (const_string "lea")
9584            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9585		      (match_operand 0 "register_operand"))
9586		 (match_operand 2 "const1_operand"))
9587	      (const_string "alu")
9588	   ]
9589	   (const_string "ishift")))
9590   (set (attr "length_immediate")
9591     (if_then_else
9592       (ior (eq_attr "type" "alu")
9593	    (and (eq_attr "type" "ishift")
9594		 (and (match_operand 2 "const1_operand")
9595		      (ior (match_test "TARGET_SHIFT1")
9596			   (match_test "optimize_function_for_size_p (cfun)")))))
9597       (const_string "0")
9598       (const_string "*")))
9599   (set_attr "mode" "HI,SI")])
9600
9601;; %%% Potential partial reg stall on alternative 1.  What to do?
9602(define_insn "*ashlqi3_1"
9603  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9604	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9605		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9606   (clobber (reg:CC FLAGS_REG))]
9607  "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9608{
9609  switch (get_attr_type (insn))
9610    {
9611    case TYPE_LEA:
9612      return "#";
9613
9614    case TYPE_ALU:
9615      gcc_assert (operands[2] == const1_rtx);
9616      if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9617        return "add{l}\t%k0, %k0";
9618      else
9619        return "add{b}\t%0, %0";
9620
9621    default:
9622      if (operands[2] == const1_rtx
9623	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9624	{
9625	  if (get_attr_mode (insn) == MODE_SI)
9626	    return "sal{l}\t%k0";
9627	  else
9628	    return "sal{b}\t%0";
9629	}
9630      else
9631	{
9632	  if (get_attr_mode (insn) == MODE_SI)
9633	    return "sal{l}\t{%2, %k0|%k0, %2}";
9634	  else
9635	    return "sal{b}\t{%2, %0|%0, %2}";
9636	}
9637    }
9638}
9639  [(set (attr "type")
9640     (cond [(eq_attr "alternative" "2")
9641	      (const_string "lea")
9642            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9643		      (match_operand 0 "register_operand"))
9644		 (match_operand 2 "const1_operand"))
9645	      (const_string "alu")
9646	   ]
9647	   (const_string "ishift")))
9648   (set (attr "length_immediate")
9649     (if_then_else
9650       (ior (eq_attr "type" "alu")
9651	    (and (eq_attr "type" "ishift")
9652		 (and (match_operand 2 "const1_operand")
9653		      (ior (match_test "TARGET_SHIFT1")
9654			   (match_test "optimize_function_for_size_p (cfun)")))))
9655       (const_string "0")
9656       (const_string "*")))
9657   (set_attr "mode" "QI,SI,SI")])
9658
9659(define_insn "*ashlqi3_1_slp"
9660  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9661	(ashift:QI (match_dup 0)
9662		   (match_operand:QI 1 "nonmemory_operand" "cI")))
9663   (clobber (reg:CC FLAGS_REG))]
9664  "(optimize_function_for_size_p (cfun)
9665    || !TARGET_PARTIAL_FLAG_REG_STALL
9666    || (operands[1] == const1_rtx
9667	&& (TARGET_SHIFT1
9668	    || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9669{
9670  switch (get_attr_type (insn))
9671    {
9672    case TYPE_ALU:
9673      gcc_assert (operands[1] == const1_rtx);
9674      return "add{b}\t%0, %0";
9675
9676    default:
9677      if (operands[1] == const1_rtx
9678	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9679	return "sal{b}\t%0";
9680      else
9681	return "sal{b}\t{%1, %0|%0, %1}";
9682    }
9683}
9684  [(set (attr "type")
9685     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9686		      (match_operand 0 "register_operand"))
9687		 (match_operand 1 "const1_operand"))
9688	      (const_string "alu")
9689	   ]
9690	   (const_string "ishift1")))
9691   (set (attr "length_immediate")
9692     (if_then_else
9693       (ior (eq_attr "type" "alu")
9694	    (and (eq_attr "type" "ishift1")
9695		 (and (match_operand 1 "const1_operand")
9696		      (ior (match_test "TARGET_SHIFT1")
9697			   (match_test "optimize_function_for_size_p (cfun)")))))
9698       (const_string "0")
9699       (const_string "*")))
9700   (set_attr "mode" "QI")])
9701
9702;; Convert ashift to the lea pattern to avoid flags dependency.
9703(define_split
9704  [(set (match_operand 0 "register_operand")
9705	(ashift (match_operand 1 "index_register_operand")
9706                (match_operand:QI 2 "const_int_operand")))
9707   (clobber (reg:CC FLAGS_REG))]
9708  "GET_MODE (operands[0]) == GET_MODE (operands[1])
9709   && reload_completed
9710   && true_regnum (operands[0]) != true_regnum (operands[1])"
9711  [(const_int 0)]
9712{
9713  machine_mode mode = GET_MODE (operands[0]);
9714  rtx pat;
9715
9716  if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9717    { 
9718      mode = SImode; 
9719      operands[0] = gen_lowpart (mode, operands[0]);
9720      operands[1] = gen_lowpart (mode, operands[1]);
9721    }
9722
9723  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9724
9725  pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9726
9727  emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9728  DONE;
9729})
9730
9731;; Convert ashift to the lea pattern to avoid flags dependency.
9732(define_split
9733  [(set (match_operand:DI 0 "register_operand")
9734	(zero_extend:DI
9735	  (ashift:SI (match_operand:SI 1 "index_register_operand")
9736		     (match_operand:QI 2 "const_int_operand"))))
9737   (clobber (reg:CC FLAGS_REG))]
9738  "TARGET_64BIT && reload_completed
9739   && true_regnum (operands[0]) != true_regnum (operands[1])"
9740  [(set (match_dup 0)
9741	(zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9742{
9743  operands[1] = gen_lowpart (SImode, operands[1]);
9744  operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9745})
9746
9747;; This pattern can't accept a variable shift count, since shifts by
9748;; zero don't affect the flags.  We assume that shifts by constant
9749;; zero are optimized away.
9750(define_insn "*ashl<mode>3_cmp"
9751  [(set (reg FLAGS_REG)
9752	(compare
9753	  (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9754		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9755	  (const_int 0)))
9756   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9757	(ashift:SWI (match_dup 1) (match_dup 2)))]
9758  "(optimize_function_for_size_p (cfun)
9759    || !TARGET_PARTIAL_FLAG_REG_STALL
9760    || (operands[2] == const1_rtx
9761	&& (TARGET_SHIFT1
9762	    || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9763   && ix86_match_ccmode (insn, CCGOCmode)
9764   && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9765{
9766  switch (get_attr_type (insn))
9767    {
9768    case TYPE_ALU:
9769      gcc_assert (operands[2] == const1_rtx);
9770      return "add{<imodesuffix>}\t%0, %0";
9771
9772    default:
9773      if (operands[2] == const1_rtx
9774	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9775	return "sal{<imodesuffix>}\t%0";
9776      else
9777	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9778    }
9779}
9780  [(set (attr "type")
9781     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9782		      (match_operand 0 "register_operand"))
9783		 (match_operand 2 "const1_operand"))
9784	      (const_string "alu")
9785	   ]
9786	   (const_string "ishift")))
9787   (set (attr "length_immediate")
9788     (if_then_else
9789       (ior (eq_attr "type" "alu")
9790	    (and (eq_attr "type" "ishift")
9791		 (and (match_operand 2 "const1_operand")
9792		      (ior (match_test "TARGET_SHIFT1")
9793			   (match_test "optimize_function_for_size_p (cfun)")))))
9794       (const_string "0")
9795       (const_string "*")))
9796   (set_attr "mode" "<MODE>")])
9797
9798(define_insn "*ashlsi3_cmp_zext"
9799  [(set (reg FLAGS_REG)
9800	(compare
9801	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
9802		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
9803	  (const_int 0)))
9804   (set (match_operand:DI 0 "register_operand" "=r")
9805	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9806  "TARGET_64BIT
9807   && (optimize_function_for_size_p (cfun)
9808       || !TARGET_PARTIAL_FLAG_REG_STALL
9809       || (operands[2] == const1_rtx
9810	   && (TARGET_SHIFT1
9811	       || TARGET_DOUBLE_WITH_ADD)))
9812   && ix86_match_ccmode (insn, CCGOCmode)
9813   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9814{
9815  switch (get_attr_type (insn))
9816    {
9817    case TYPE_ALU:
9818      gcc_assert (operands[2] == const1_rtx);
9819      return "add{l}\t%k0, %k0";
9820
9821    default:
9822      if (operands[2] == const1_rtx
9823	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9824	return "sal{l}\t%k0";
9825      else
9826	return "sal{l}\t{%2, %k0|%k0, %2}";
9827    }
9828}
9829  [(set (attr "type")
9830     (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9831		 (match_operand 2 "const1_operand"))
9832	      (const_string "alu")
9833	   ]
9834	   (const_string "ishift")))
9835   (set (attr "length_immediate")
9836     (if_then_else
9837       (ior (eq_attr "type" "alu")
9838	    (and (eq_attr "type" "ishift")
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(define_insn "*ashl<mode>3_cconly"
9847  [(set (reg FLAGS_REG)
9848	(compare
9849	  (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9850		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9851	  (const_int 0)))
9852   (clobber (match_scratch:SWI 0 "=<r>"))]
9853  "(optimize_function_for_size_p (cfun)
9854    || !TARGET_PARTIAL_FLAG_REG_STALL
9855    || (operands[2] == const1_rtx
9856	&& (TARGET_SHIFT1
9857	    || TARGET_DOUBLE_WITH_ADD)))
9858   && ix86_match_ccmode (insn, CCGOCmode)"
9859{
9860  switch (get_attr_type (insn))
9861    {
9862    case TYPE_ALU:
9863      gcc_assert (operands[2] == const1_rtx);
9864      return "add{<imodesuffix>}\t%0, %0";
9865
9866    default:
9867      if (operands[2] == const1_rtx
9868	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869	return "sal{<imodesuffix>}\t%0";
9870      else
9871	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9872    }
9873}
9874  [(set (attr "type")
9875     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9876		      (match_operand 0 "register_operand"))
9877		 (match_operand 2 "const1_operand"))
9878	      (const_string "alu")
9879	   ]
9880	   (const_string "ishift")))
9881   (set (attr "length_immediate")
9882     (if_then_else
9883       (ior (eq_attr "type" "alu")
9884	    (and (eq_attr "type" "ishift")
9885		 (and (match_operand 2 "const1_operand")
9886		      (ior (match_test "TARGET_SHIFT1")
9887			   (match_test "optimize_function_for_size_p (cfun)")))))
9888       (const_string "0")
9889       (const_string "*")))
9890   (set_attr "mode" "<MODE>")])
9891
9892;; See comment above `ashl<mode>3' about how this works.
9893
9894(define_expand "<shift_insn><mode>3"
9895  [(set (match_operand:SDWIM 0 "<shift_operand>")
9896	(any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9897			   (match_operand:QI 2 "nonmemory_operand")))]
9898  ""
9899  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9900
9901;; Avoid useless masking of count operand.
9902(define_insn "*<shift_insn><mode>3_mask"
9903  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9904	(any_shiftrt:SWI48
9905	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
9906	  (subreg:QI
9907	    (and:SI
9908	      (match_operand:SI 2 "register_operand" "c")
9909	      (match_operand:SI 3 "const_int_operand" "n")) 0)))
9910   (clobber (reg:CC FLAGS_REG))]
9911  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9912   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9913      == GET_MODE_BITSIZE (<MODE>mode)-1"
9914{
9915  return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9916}
9917  [(set_attr "type" "ishift")
9918   (set_attr "mode" "<MODE>")])
9919
9920(define_insn_and_split "*<shift_insn><mode>3_doubleword"
9921  [(set (match_operand:DWI 0 "register_operand" "=r")
9922	(any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9923			 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9924   (clobber (reg:CC FLAGS_REG))]
9925  ""
9926  "#"
9927  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9928  [(const_int 0)]
9929  "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9930  [(set_attr "type" "multi")])
9931
9932;; By default we don't ask for a scratch register, because when DWImode
9933;; values are manipulated, registers are already at a premium.  But if
9934;; we have one handy, we won't turn it away.
9935
9936(define_peephole2
9937  [(match_scratch:DWIH 3 "r")
9938   (parallel [(set (match_operand:<DWI> 0 "register_operand")
9939		   (any_shiftrt:<DWI>
9940		     (match_operand:<DWI> 1 "register_operand")
9941		     (match_operand:QI 2 "nonmemory_operand")))
9942	      (clobber (reg:CC FLAGS_REG))])
9943   (match_dup 3)]
9944  "TARGET_CMOVE"
9945  [(const_int 0)]
9946  "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9947
9948(define_insn "x86_64_shrd"
9949  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9950        (ior:DI (lshiftrt:DI (match_dup 0)
9951		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
9952		(ashift:DI (match_operand:DI 1 "register_operand" "r")
9953		  (minus:QI (const_int 64) (match_dup 2)))))
9954   (clobber (reg:CC FLAGS_REG))]
9955  "TARGET_64BIT"
9956  "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9957  [(set_attr "type" "ishift")
9958   (set_attr "prefix_0f" "1")
9959   (set_attr "mode" "DI")
9960   (set_attr "athlon_decode" "vector")
9961   (set_attr "amdfam10_decode" "vector")
9962   (set_attr "bdver1_decode" "vector")])
9963
9964(define_insn "x86_shrd"
9965  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9966        (ior:SI (lshiftrt:SI (match_dup 0)
9967		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
9968		(ashift:SI (match_operand:SI 1 "register_operand" "r")
9969		  (minus:QI (const_int 32) (match_dup 2)))))
9970   (clobber (reg:CC FLAGS_REG))]
9971  ""
9972  "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9973  [(set_attr "type" "ishift")
9974   (set_attr "prefix_0f" "1")
9975   (set_attr "mode" "SI")
9976   (set_attr "pent_pair" "np")
9977   (set_attr "athlon_decode" "vector")
9978   (set_attr "amdfam10_decode" "vector")
9979   (set_attr "bdver1_decode" "vector")])
9980
9981(define_insn "ashrdi3_cvt"
9982  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9983	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9984		     (match_operand:QI 2 "const_int_operand")))
9985   (clobber (reg:CC FLAGS_REG))]
9986  "TARGET_64BIT && INTVAL (operands[2]) == 63
9987   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9988   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9989  "@
9990   {cqto|cqo}
9991   sar{q}\t{%2, %0|%0, %2}"
9992  [(set_attr "type" "imovx,ishift")
9993   (set_attr "prefix_0f" "0,*")
9994   (set_attr "length_immediate" "0,*")
9995   (set_attr "modrm" "0,1")
9996   (set_attr "mode" "DI")])
9997
9998(define_insn "ashrsi3_cvt"
9999  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10000	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10001		     (match_operand:QI 2 "const_int_operand")))
10002   (clobber (reg:CC FLAGS_REG))]
10003  "INTVAL (operands[2]) == 31
10004   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10005   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10006  "@
10007   {cltd|cdq}
10008   sar{l}\t{%2, %0|%0, %2}"
10009  [(set_attr "type" "imovx,ishift")
10010   (set_attr "prefix_0f" "0,*")
10011   (set_attr "length_immediate" "0,*")
10012   (set_attr "modrm" "0,1")
10013   (set_attr "mode" "SI")])
10014
10015(define_insn "*ashrsi3_cvt_zext"
10016  [(set (match_operand:DI 0 "register_operand" "=*d,r")
10017	(zero_extend:DI
10018	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10019		       (match_operand:QI 2 "const_int_operand"))))
10020   (clobber (reg:CC FLAGS_REG))]
10021  "TARGET_64BIT && INTVAL (operands[2]) == 31
10022   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10023   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10024  "@
10025   {cltd|cdq}
10026   sar{l}\t{%2, %k0|%k0, %2}"
10027  [(set_attr "type" "imovx,ishift")
10028   (set_attr "prefix_0f" "0,*")
10029   (set_attr "length_immediate" "0,*")
10030   (set_attr "modrm" "0,1")
10031   (set_attr "mode" "SI")])
10032
10033(define_expand "x86_shift<mode>_adj_3"
10034  [(use (match_operand:SWI48 0 "register_operand"))
10035   (use (match_operand:SWI48 1 "register_operand"))
10036   (use (match_operand:QI 2 "register_operand"))]
10037  ""
10038{
10039  rtx_code_label *label = gen_label_rtx ();
10040  rtx tmp;
10041
10042  emit_insn (gen_testqi_ccz_1 (operands[2],
10043			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10044
10045  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10046  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10047  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10048			      gen_rtx_LABEL_REF (VOIDmode, label),
10049			      pc_rtx);
10050  tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10051  JUMP_LABEL (tmp) = label;
10052
10053  emit_move_insn (operands[0], operands[1]);
10054  emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10055				  GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10056  emit_label (label);
10057  LABEL_NUSES (label) = 1;
10058
10059  DONE;
10060})
10061
10062(define_insn "*bmi2_<shift_insn><mode>3_1"
10063  [(set (match_operand:SWI48 0 "register_operand" "=r")
10064	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10065			   (match_operand:SWI48 2 "register_operand" "r")))]
10066  "TARGET_BMI2"
10067  "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10068  [(set_attr "type" "ishiftx")
10069   (set_attr "mode" "<MODE>")])
10070
10071(define_insn "*<shift_insn><mode>3_1"
10072  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10073	(any_shiftrt:SWI48
10074	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10075	  (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10076   (clobber (reg:CC FLAGS_REG))]
10077  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10078{
10079  switch (get_attr_type (insn))
10080    {
10081    case TYPE_ISHIFTX:
10082      return "#";
10083
10084    default:
10085      if (operands[2] == const1_rtx
10086	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10087	return "<shift>{<imodesuffix>}\t%0";
10088      else
10089	return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10090    }
10091}
10092  [(set_attr "isa" "*,bmi2")
10093   (set_attr "type" "ishift,ishiftx")
10094   (set (attr "length_immediate")
10095     (if_then_else
10096       (and (match_operand 2 "const1_operand")
10097	    (ior (match_test "TARGET_SHIFT1")
10098		 (match_test "optimize_function_for_size_p (cfun)")))
10099       (const_string "0")
10100       (const_string "*")))
10101   (set_attr "mode" "<MODE>")])
10102
10103;; Convert shift to the shiftx pattern to avoid flags dependency.
10104(define_split
10105  [(set (match_operand:SWI48 0 "register_operand")
10106	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10107			   (match_operand:QI 2 "register_operand")))
10108   (clobber (reg:CC FLAGS_REG))]
10109  "TARGET_BMI2 && reload_completed"
10110  [(set (match_dup 0)
10111	(any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10112  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10113
10114(define_insn "*bmi2_<shift_insn>si3_1_zext"
10115  [(set (match_operand:DI 0 "register_operand" "=r")
10116	(zero_extend:DI
10117	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10118			  (match_operand:SI 2 "register_operand" "r"))))]
10119  "TARGET_64BIT && TARGET_BMI2"
10120  "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10121  [(set_attr "type" "ishiftx")
10122   (set_attr "mode" "SI")])
10123
10124(define_insn "*<shift_insn>si3_1_zext"
10125  [(set (match_operand:DI 0 "register_operand" "=r,r")
10126	(zero_extend:DI
10127	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10128			  (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10129   (clobber (reg:CC FLAGS_REG))]
10130  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10131{
10132  switch (get_attr_type (insn))
10133    {
10134    case TYPE_ISHIFTX:
10135      return "#";
10136
10137    default:
10138      if (operands[2] == const1_rtx
10139	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10140	return "<shift>{l}\t%k0";
10141      else
10142	return "<shift>{l}\t{%2, %k0|%k0, %2}";
10143    }
10144}
10145  [(set_attr "isa" "*,bmi2")
10146   (set_attr "type" "ishift,ishiftx")
10147   (set (attr "length_immediate")
10148     (if_then_else
10149       (and (match_operand 2 "const1_operand")
10150	    (ior (match_test "TARGET_SHIFT1")
10151		 (match_test "optimize_function_for_size_p (cfun)")))
10152       (const_string "0")
10153       (const_string "*")))
10154   (set_attr "mode" "SI")])
10155
10156;; Convert shift to the shiftx pattern to avoid flags dependency.
10157(define_split
10158  [(set (match_operand:DI 0 "register_operand")
10159	(zero_extend:DI
10160	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10161			  (match_operand:QI 2 "register_operand"))))
10162   (clobber (reg:CC FLAGS_REG))]
10163  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10164  [(set (match_dup 0)
10165	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10166  "operands[2] = gen_lowpart (SImode, operands[2]);")
10167
10168(define_insn "*<shift_insn><mode>3_1"
10169  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10170	(any_shiftrt:SWI12
10171	  (match_operand:SWI12 1 "nonimmediate_operand" "0")
10172	  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10173   (clobber (reg:CC FLAGS_REG))]
10174  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10175{
10176  if (operands[2] == const1_rtx
10177      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10178    return "<shift>{<imodesuffix>}\t%0";
10179  else
10180    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10181}
10182  [(set_attr "type" "ishift")
10183   (set (attr "length_immediate")
10184     (if_then_else
10185       (and (match_operand 2 "const1_operand")
10186	    (ior (match_test "TARGET_SHIFT1")
10187		 (match_test "optimize_function_for_size_p (cfun)")))
10188       (const_string "0")
10189       (const_string "*")))
10190   (set_attr "mode" "<MODE>")])
10191
10192(define_insn "*<shift_insn>qi3_1_slp"
10193  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10194	(any_shiftrt:QI (match_dup 0)
10195			(match_operand:QI 1 "nonmemory_operand" "cI")))
10196   (clobber (reg:CC FLAGS_REG))]
10197  "(optimize_function_for_size_p (cfun)
10198    || !TARGET_PARTIAL_REG_STALL
10199    || (operands[1] == const1_rtx
10200	&& TARGET_SHIFT1))"
10201{
10202  if (operands[1] == const1_rtx
10203      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10204    return "<shift>{b}\t%0";
10205  else
10206    return "<shift>{b}\t{%1, %0|%0, %1}";
10207}
10208  [(set_attr "type" "ishift1")
10209   (set (attr "length_immediate")
10210     (if_then_else
10211       (and (match_operand 1 "const1_operand")
10212	    (ior (match_test "TARGET_SHIFT1")
10213		 (match_test "optimize_function_for_size_p (cfun)")))
10214       (const_string "0")
10215       (const_string "*")))
10216   (set_attr "mode" "QI")])
10217
10218;; This pattern can't accept a variable shift count, since shifts by
10219;; zero don't affect the flags.  We assume that shifts by constant
10220;; zero are optimized away.
10221(define_insn "*<shift_insn><mode>3_cmp"
10222  [(set (reg FLAGS_REG)
10223	(compare
10224	  (any_shiftrt:SWI
10225	    (match_operand:SWI 1 "nonimmediate_operand" "0")
10226	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10227	  (const_int 0)))
10228   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10229	(any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10230  "(optimize_function_for_size_p (cfun)
10231    || !TARGET_PARTIAL_FLAG_REG_STALL
10232    || (operands[2] == const1_rtx
10233	&& TARGET_SHIFT1))
10234   && ix86_match_ccmode (insn, CCGOCmode)
10235   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10236{
10237  if (operands[2] == const1_rtx
10238      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10239    return "<shift>{<imodesuffix>}\t%0";
10240  else
10241    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10242}
10243  [(set_attr "type" "ishift")
10244   (set (attr "length_immediate")
10245     (if_then_else
10246       (and (match_operand 2 "const1_operand")
10247	    (ior (match_test "TARGET_SHIFT1")
10248		 (match_test "optimize_function_for_size_p (cfun)")))
10249       (const_string "0")
10250       (const_string "*")))
10251   (set_attr "mode" "<MODE>")])
10252
10253(define_insn "*<shift_insn>si3_cmp_zext"
10254  [(set (reg FLAGS_REG)
10255	(compare
10256	  (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10257			  (match_operand:QI 2 "const_1_to_31_operand" "I"))
10258	  (const_int 0)))
10259   (set (match_operand:DI 0 "register_operand" "=r")
10260	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10261  "TARGET_64BIT
10262   && (optimize_function_for_size_p (cfun)
10263       || !TARGET_PARTIAL_FLAG_REG_STALL
10264       || (operands[2] == const1_rtx
10265	   && TARGET_SHIFT1))
10266   && ix86_match_ccmode (insn, CCGOCmode)
10267   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10268{
10269  if (operands[2] == const1_rtx
10270      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10271    return "<shift>{l}\t%k0";
10272  else
10273    return "<shift>{l}\t{%2, %k0|%k0, %2}";
10274}
10275  [(set_attr "type" "ishift")
10276   (set (attr "length_immediate")
10277     (if_then_else
10278       (and (match_operand 2 "const1_operand")
10279	    (ior (match_test "TARGET_SHIFT1")
10280		 (match_test "optimize_function_for_size_p (cfun)")))
10281       (const_string "0")
10282       (const_string "*")))
10283   (set_attr "mode" "SI")])
10284
10285(define_insn "*<shift_insn><mode>3_cconly"
10286  [(set (reg FLAGS_REG)
10287	(compare
10288	  (any_shiftrt:SWI
10289	    (match_operand:SWI 1 "register_operand" "0")
10290	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10291	  (const_int 0)))
10292   (clobber (match_scratch:SWI 0 "=<r>"))]
10293  "(optimize_function_for_size_p (cfun)
10294    || !TARGET_PARTIAL_FLAG_REG_STALL
10295    || (operands[2] == const1_rtx
10296	&& TARGET_SHIFT1))
10297   && ix86_match_ccmode (insn, CCGOCmode)"
10298{
10299  if (operands[2] == const1_rtx
10300      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10301    return "<shift>{<imodesuffix>}\t%0";
10302  else
10303    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10304}
10305  [(set_attr "type" "ishift")
10306   (set (attr "length_immediate")
10307     (if_then_else
10308       (and (match_operand 2 "const1_operand")
10309	    (ior (match_test "TARGET_SHIFT1")
10310		 (match_test "optimize_function_for_size_p (cfun)")))
10311       (const_string "0")
10312       (const_string "*")))
10313   (set_attr "mode" "<MODE>")])
10314
10315;; Rotate instructions
10316
10317(define_expand "<rotate_insn>ti3"
10318  [(set (match_operand:TI 0 "register_operand")
10319	(any_rotate:TI (match_operand:TI 1 "register_operand")
10320		       (match_operand:QI 2 "nonmemory_operand")))]
10321  "TARGET_64BIT"
10322{
10323  if (const_1_to_63_operand (operands[2], VOIDmode))
10324    emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10325		(operands[0], operands[1], operands[2]));
10326  else
10327    FAIL;
10328
10329  DONE;
10330})
10331
10332(define_expand "<rotate_insn>di3"
10333  [(set (match_operand:DI 0 "shiftdi_operand")
10334	(any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10335		       (match_operand:QI 2 "nonmemory_operand")))]
10336 ""
10337{
10338  if (TARGET_64BIT)
10339    ix86_expand_binary_operator (<CODE>, DImode, operands);
10340  else if (const_1_to_31_operand (operands[2], VOIDmode))
10341    emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10342		(operands[0], operands[1], operands[2]));
10343  else
10344    FAIL;
10345
10346  DONE;
10347})
10348
10349(define_expand "<rotate_insn><mode>3"
10350  [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10351	(any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10352			    (match_operand:QI 2 "nonmemory_operand")))]
10353  ""
10354  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10355
10356;; Avoid useless masking of count operand.
10357(define_insn "*<rotate_insn><mode>3_mask"
10358  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10359	(any_rotate:SWI48
10360	  (match_operand:SWI48 1 "nonimmediate_operand" "0")
10361	  (subreg:QI
10362	    (and:SI
10363	      (match_operand:SI 2 "register_operand" "c")
10364	      (match_operand:SI 3 "const_int_operand" "n")) 0)))
10365   (clobber (reg:CC FLAGS_REG))]
10366  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10367   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10368      == GET_MODE_BITSIZE (<MODE>mode)-1"
10369{
10370  return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10371}
10372  [(set_attr "type" "rotate")
10373   (set_attr "mode" "<MODE>")])
10374
10375;; Implement rotation using two double-precision
10376;; shift instructions and a scratch register.
10377
10378(define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10379 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10380       (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10381		     (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10382  (clobber (reg:CC FLAGS_REG))
10383  (clobber (match_scratch:DWIH 3 "=&r"))]
10384 ""
10385 "#"
10386 "reload_completed"
10387 [(set (match_dup 3) (match_dup 4))
10388  (parallel
10389   [(set (match_dup 4)
10390	 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10391		   (lshiftrt:DWIH (match_dup 5)
10392				  (minus:QI (match_dup 6) (match_dup 2)))))
10393    (clobber (reg:CC FLAGS_REG))])
10394  (parallel
10395   [(set (match_dup 5)
10396	 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10397		   (lshiftrt:DWIH (match_dup 3)
10398				  (minus:QI (match_dup 6) (match_dup 2)))))
10399    (clobber (reg:CC FLAGS_REG))])]
10400{
10401  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10402
10403  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10404})
10405
10406(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10407 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10408       (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10409		       (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10410  (clobber (reg:CC FLAGS_REG))
10411  (clobber (match_scratch:DWIH 3 "=&r"))]
10412 ""
10413 "#"
10414 "reload_completed"
10415 [(set (match_dup 3) (match_dup 4))
10416  (parallel
10417   [(set (match_dup 4)
10418	 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10419		   (ashift:DWIH (match_dup 5)
10420				(minus:QI (match_dup 6) (match_dup 2)))))
10421    (clobber (reg:CC FLAGS_REG))])
10422  (parallel
10423   [(set (match_dup 5)
10424	 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10425		   (ashift:DWIH (match_dup 3)
10426				(minus:QI (match_dup 6) (match_dup 2)))))
10427    (clobber (reg:CC FLAGS_REG))])]
10428{
10429  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10430
10431  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10432})
10433
10434(define_insn "*bmi2_rorx<mode>3_1"
10435  [(set (match_operand:SWI48 0 "register_operand" "=r")
10436	(rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10437			(match_operand:QI 2 "immediate_operand" "<S>")))]
10438  "TARGET_BMI2"
10439  "rorx\t{%2, %1, %0|%0, %1, %2}"
10440  [(set_attr "type" "rotatex")
10441   (set_attr "mode" "<MODE>")])
10442
10443(define_insn "*<rotate_insn><mode>3_1"
10444  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10445	(any_rotate:SWI48
10446	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10447	  (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10448   (clobber (reg:CC FLAGS_REG))]
10449  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10450{
10451  switch (get_attr_type (insn))
10452    {
10453    case TYPE_ROTATEX:
10454      return "#";
10455
10456    default:
10457      if (operands[2] == const1_rtx
10458	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10459	return "<rotate>{<imodesuffix>}\t%0";
10460      else
10461	return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10462    }
10463}
10464  [(set_attr "isa" "*,bmi2")
10465   (set_attr "type" "rotate,rotatex")
10466   (set (attr "length_immediate")
10467     (if_then_else
10468       (and (eq_attr "type" "rotate")
10469	    (and (match_operand 2 "const1_operand")
10470		 (ior (match_test "TARGET_SHIFT1")
10471		      (match_test "optimize_function_for_size_p (cfun)"))))
10472       (const_string "0")
10473       (const_string "*")))
10474   (set_attr "mode" "<MODE>")])
10475
10476;; Convert rotate to the rotatex pattern to avoid flags dependency.
10477(define_split
10478  [(set (match_operand:SWI48 0 "register_operand")
10479	(rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10480		      (match_operand:QI 2 "immediate_operand")))
10481   (clobber (reg:CC FLAGS_REG))]
10482  "TARGET_BMI2 && reload_completed"
10483  [(set (match_dup 0)
10484	(rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10485{
10486  operands[2]
10487    = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10488})
10489
10490(define_split
10491  [(set (match_operand:SWI48 0 "register_operand")
10492	(rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10493			(match_operand:QI 2 "immediate_operand")))
10494   (clobber (reg:CC FLAGS_REG))]
10495  "TARGET_BMI2 && reload_completed"
10496  [(set (match_dup 0)
10497	(rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10498
10499(define_insn "*bmi2_rorxsi3_1_zext"
10500  [(set (match_operand:DI 0 "register_operand" "=r")
10501	(zero_extend:DI
10502	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10503		       (match_operand:QI 2 "immediate_operand" "I"))))]
10504  "TARGET_64BIT && TARGET_BMI2"
10505  "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10506  [(set_attr "type" "rotatex")
10507   (set_attr "mode" "SI")])
10508
10509(define_insn "*<rotate_insn>si3_1_zext"
10510  [(set (match_operand:DI 0 "register_operand" "=r,r")
10511	(zero_extend:DI
10512	  (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10513			 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10514   (clobber (reg:CC FLAGS_REG))]
10515  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10516{
10517  switch (get_attr_type (insn))
10518    {
10519    case TYPE_ROTATEX:
10520      return "#";
10521
10522    default:
10523      if (operands[2] == const1_rtx
10524	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10525	return "<rotate>{l}\t%k0";
10526      else
10527	return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10528    }
10529}
10530  [(set_attr "isa" "*,bmi2")
10531   (set_attr "type" "rotate,rotatex")
10532   (set (attr "length_immediate")
10533     (if_then_else
10534       (and (eq_attr "type" "rotate")
10535	    (and (match_operand 2 "const1_operand")
10536		 (ior (match_test "TARGET_SHIFT1")
10537		      (match_test "optimize_function_for_size_p (cfun)"))))
10538       (const_string "0")
10539       (const_string "*")))
10540   (set_attr "mode" "SI")])
10541
10542;; Convert rotate to the rotatex pattern to avoid flags dependency.
10543(define_split
10544  [(set (match_operand:DI 0 "register_operand")
10545	(zero_extend:DI
10546	  (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10547		     (match_operand:QI 2 "immediate_operand"))))
10548   (clobber (reg:CC FLAGS_REG))]
10549  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10550  [(set (match_dup 0)
10551	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10552{
10553  operands[2]
10554    = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10555})
10556
10557(define_split
10558  [(set (match_operand:DI 0 "register_operand")
10559	(zero_extend:DI
10560	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10561		       (match_operand:QI 2 "immediate_operand"))))
10562   (clobber (reg:CC FLAGS_REG))]
10563  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10564  [(set (match_dup 0)
10565	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10566
10567(define_insn "*<rotate_insn><mode>3_1"
10568  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10569	(any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10570			  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10571   (clobber (reg:CC FLAGS_REG))]
10572  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10573{
10574  if (operands[2] == const1_rtx
10575      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10576    return "<rotate>{<imodesuffix>}\t%0";
10577  else
10578    return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10579}
10580  [(set_attr "type" "rotate")
10581   (set (attr "length_immediate")
10582     (if_then_else
10583       (and (match_operand 2 "const1_operand")
10584	    (ior (match_test "TARGET_SHIFT1")
10585		 (match_test "optimize_function_for_size_p (cfun)")))
10586       (const_string "0")
10587       (const_string "*")))
10588   (set_attr "mode" "<MODE>")])
10589
10590(define_insn "*<rotate_insn>qi3_1_slp"
10591  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10592	(any_rotate:QI (match_dup 0)
10593		       (match_operand:QI 1 "nonmemory_operand" "cI")))
10594   (clobber (reg:CC FLAGS_REG))]
10595  "(optimize_function_for_size_p (cfun)
10596    || !TARGET_PARTIAL_REG_STALL
10597    || (operands[1] == const1_rtx
10598	&& TARGET_SHIFT1))"
10599{
10600  if (operands[1] == const1_rtx
10601      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10602    return "<rotate>{b}\t%0";
10603  else
10604    return "<rotate>{b}\t{%1, %0|%0, %1}";
10605}
10606  [(set_attr "type" "rotate1")
10607   (set (attr "length_immediate")
10608     (if_then_else
10609       (and (match_operand 1 "const1_operand")
10610	    (ior (match_test "TARGET_SHIFT1")
10611		 (match_test "optimize_function_for_size_p (cfun)")))
10612       (const_string "0")
10613       (const_string "*")))
10614   (set_attr "mode" "QI")])
10615
10616(define_split
10617 [(set (match_operand:HI 0 "register_operand")
10618       (any_rotate:HI (match_dup 0) (const_int 8)))
10619  (clobber (reg:CC FLAGS_REG))]
10620 "reload_completed
10621  && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10622 [(parallel [(set (strict_low_part (match_dup 0))
10623		  (bswap:HI (match_dup 0)))
10624	     (clobber (reg:CC FLAGS_REG))])])
10625
10626;; Bit set / bit test instructions
10627
10628(define_expand "extv"
10629  [(set (match_operand:SI 0 "register_operand")
10630	(sign_extract:SI (match_operand:SI 1 "register_operand")
10631			 (match_operand:SI 2 "const8_operand")
10632			 (match_operand:SI 3 "const8_operand")))]
10633  ""
10634{
10635  /* Handle extractions from %ah et al.  */
10636  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10637    FAIL;
10638
10639  /* From mips.md: extract_bit_field doesn't verify that our source
10640     matches the predicate, so check it again here.  */
10641  if (! ext_register_operand (operands[1], VOIDmode))
10642    FAIL;
10643})
10644
10645(define_expand "extzv"
10646  [(set (match_operand:SI 0 "register_operand")
10647	(zero_extract:SI (match_operand 1 "ext_register_operand")
10648			 (match_operand:SI 2 "const8_operand")
10649			 (match_operand:SI 3 "const8_operand")))]
10650  ""
10651{
10652  /* Handle extractions from %ah et al.  */
10653  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10654    FAIL;
10655
10656  /* From mips.md: extract_bit_field doesn't verify that our source
10657     matches the predicate, so check it again here.  */
10658  if (! ext_register_operand (operands[1], VOIDmode))
10659    FAIL;
10660})
10661
10662(define_expand "insv"
10663  [(set (zero_extract (match_operand 0 "register_operand")
10664		      (match_operand 1 "const_int_operand")
10665		      (match_operand 2 "const_int_operand"))
10666        (match_operand 3 "register_operand"))]
10667  ""
10668{
10669  rtx (*gen_mov_insv_1) (rtx, rtx);
10670
10671  if (ix86_expand_pinsr (operands))
10672    DONE;
10673
10674  /* Handle insertions to %ah et al.  */
10675  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10676    FAIL;
10677
10678  /* From mips.md: insert_bit_field doesn't verify that our source
10679     matches the predicate, so check it again here.  */
10680  if (! ext_register_operand (operands[0], VOIDmode))
10681    FAIL;
10682
10683  gen_mov_insv_1 = (TARGET_64BIT
10684		    ? gen_movdi_insv_1 : gen_movsi_insv_1);
10685
10686  emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10687  DONE;
10688})
10689
10690;; %%% bts, btr, btc, bt.
10691;; In general these instructions are *slow* when applied to memory,
10692;; since they enforce atomic operation.  When applied to registers,
10693;; it depends on the cpu implementation.  They're never faster than
10694;; the corresponding and/ior/xor operations, so with 32-bit there's
10695;; no point.  But in 64-bit, we can't hold the relevant immediates
10696;; within the instruction itself, so operating on bits in the high
10697;; 32-bits of a register becomes easier.
10698;;
10699;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10700;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10701;; negdf respectively, so they can never be disabled entirely.
10702
10703(define_insn "*btsq"
10704  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10705			 (const_int 1)
10706			 (match_operand:DI 1 "const_0_to_63_operand"))
10707	(const_int 1))
10708   (clobber (reg:CC FLAGS_REG))]
10709  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10710  "bts{q}\t{%1, %0|%0, %1}"
10711  [(set_attr "type" "alu1")
10712   (set_attr "prefix_0f" "1")
10713   (set_attr "mode" "DI")])
10714
10715(define_insn "*btrq"
10716  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10717			 (const_int 1)
10718			 (match_operand:DI 1 "const_0_to_63_operand"))
10719	(const_int 0))
10720   (clobber (reg:CC FLAGS_REG))]
10721  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10722  "btr{q}\t{%1, %0|%0, %1}"
10723  [(set_attr "type" "alu1")
10724   (set_attr "prefix_0f" "1")
10725   (set_attr "mode" "DI")])
10726
10727(define_insn "*btcq"
10728  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10729			 (const_int 1)
10730			 (match_operand:DI 1 "const_0_to_63_operand"))
10731	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10732   (clobber (reg:CC FLAGS_REG))]
10733  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10734  "btc{q}\t{%1, %0|%0, %1}"
10735  [(set_attr "type" "alu1")
10736   (set_attr "prefix_0f" "1")
10737   (set_attr "mode" "DI")])
10738
10739;; Allow Nocona to avoid these instructions if a register is available.
10740
10741(define_peephole2
10742  [(match_scratch:DI 2 "r")
10743   (parallel [(set (zero_extract:DI
10744		     (match_operand:DI 0 "register_operand")
10745		     (const_int 1)
10746		     (match_operand:DI 1 "const_0_to_63_operand"))
10747		   (const_int 1))
10748	      (clobber (reg:CC FLAGS_REG))])]
10749  "TARGET_64BIT && !TARGET_USE_BT"
10750  [(const_int 0)]
10751{
10752  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10753  rtx op1;
10754
10755  if (HOST_BITS_PER_WIDE_INT >= 64)
10756    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10757  else if (i < HOST_BITS_PER_WIDE_INT)
10758    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10759  else
10760    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10761
10762  op1 = immed_double_const (lo, hi, DImode);
10763  if (i >= 31)
10764    {
10765      emit_move_insn (operands[2], op1);
10766      op1 = operands[2];
10767    }
10768
10769  emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10770  DONE;
10771})
10772
10773(define_peephole2
10774  [(match_scratch:DI 2 "r")
10775   (parallel [(set (zero_extract:DI
10776		     (match_operand:DI 0 "register_operand")
10777		     (const_int 1)
10778		     (match_operand:DI 1 "const_0_to_63_operand"))
10779		   (const_int 0))
10780	      (clobber (reg:CC FLAGS_REG))])]
10781  "TARGET_64BIT && !TARGET_USE_BT"
10782  [(const_int 0)]
10783{
10784  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10785  rtx op1;
10786
10787  if (HOST_BITS_PER_WIDE_INT >= 64)
10788    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10789  else if (i < HOST_BITS_PER_WIDE_INT)
10790    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10791  else
10792    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10793
10794  op1 = immed_double_const (~lo, ~hi, DImode);
10795  if (i >= 32)
10796    {
10797      emit_move_insn (operands[2], op1);
10798      op1 = operands[2];
10799    }
10800
10801  emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10802  DONE;
10803})
10804
10805(define_peephole2
10806  [(match_scratch:DI 2 "r")
10807   (parallel [(set (zero_extract:DI
10808		     (match_operand:DI 0 "register_operand")
10809		     (const_int 1)
10810		     (match_operand:DI 1 "const_0_to_63_operand"))
10811	      (not:DI (zero_extract:DI
10812			(match_dup 0) (const_int 1) (match_dup 1))))
10813	      (clobber (reg:CC FLAGS_REG))])]
10814  "TARGET_64BIT && !TARGET_USE_BT"
10815  [(const_int 0)]
10816{
10817  HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10818  rtx op1;
10819
10820  if (HOST_BITS_PER_WIDE_INT >= 64)
10821    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10822  else if (i < HOST_BITS_PER_WIDE_INT)
10823    lo = (HOST_WIDE_INT)1 << i, hi = 0;
10824  else
10825    lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10826
10827  op1 = immed_double_const (lo, hi, DImode);
10828  if (i >= 31)
10829    {
10830      emit_move_insn (operands[2], op1);
10831      op1 = operands[2];
10832    }
10833
10834  emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10835  DONE;
10836})
10837
10838(define_insn "*bt<mode>"
10839  [(set (reg:CCC FLAGS_REG)
10840	(compare:CCC
10841	  (zero_extract:SWI48
10842	    (match_operand:SWI48 0 "register_operand" "r")
10843	    (const_int 1)
10844	    (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10845	  (const_int 0)))]
10846  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10847  "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10848  [(set_attr "type" "alu1")
10849   (set_attr "prefix_0f" "1")
10850   (set_attr "mode" "<MODE>")])
10851
10852;; Store-flag instructions.
10853
10854;; For all sCOND expanders, also expand the compare or test insn that
10855;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10856
10857(define_insn_and_split "*setcc_di_1"
10858  [(set (match_operand:DI 0 "register_operand" "=q")
10859	(match_operator:DI 1 "ix86_comparison_operator"
10860	  [(reg FLAGS_REG) (const_int 0)]))]
10861  "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10862  "#"
10863  "&& reload_completed"
10864  [(set (match_dup 2) (match_dup 1))
10865   (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10866{
10867  operands[1] = shallow_copy_rtx (operands[1]);
10868  PUT_MODE (operands[1], QImode);
10869  operands[2] = gen_lowpart (QImode, operands[0]);
10870})
10871
10872(define_insn_and_split "*setcc_si_1_and"
10873  [(set (match_operand:SI 0 "register_operand" "=q")
10874	(match_operator:SI 1 "ix86_comparison_operator"
10875	  [(reg FLAGS_REG) (const_int 0)]))
10876   (clobber (reg:CC FLAGS_REG))]
10877  "!TARGET_PARTIAL_REG_STALL
10878   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10879  "#"
10880  "&& reload_completed"
10881  [(set (match_dup 2) (match_dup 1))
10882   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10883	      (clobber (reg:CC FLAGS_REG))])]
10884{
10885  operands[1] = shallow_copy_rtx (operands[1]);
10886  PUT_MODE (operands[1], QImode);
10887  operands[2] = gen_lowpart (QImode, operands[0]);
10888})
10889
10890(define_insn_and_split "*setcc_si_1_movzbl"
10891  [(set (match_operand:SI 0 "register_operand" "=q")
10892	(match_operator:SI 1 "ix86_comparison_operator"
10893	  [(reg FLAGS_REG) (const_int 0)]))]
10894  "!TARGET_PARTIAL_REG_STALL
10895   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10896  "#"
10897  "&& reload_completed"
10898  [(set (match_dup 2) (match_dup 1))
10899   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10900{
10901  operands[1] = shallow_copy_rtx (operands[1]);
10902  PUT_MODE (operands[1], QImode);
10903  operands[2] = gen_lowpart (QImode, operands[0]);
10904})
10905
10906(define_insn "*setcc_qi"
10907  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10908	(match_operator:QI 1 "ix86_comparison_operator"
10909	  [(reg FLAGS_REG) (const_int 0)]))]
10910  ""
10911  "set%C1\t%0"
10912  [(set_attr "type" "setcc")
10913   (set_attr "mode" "QI")])
10914
10915(define_insn "*setcc_qi_slp"
10916  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10917	(match_operator:QI 1 "ix86_comparison_operator"
10918	  [(reg FLAGS_REG) (const_int 0)]))]
10919  ""
10920  "set%C1\t%0"
10921  [(set_attr "type" "setcc")
10922   (set_attr "mode" "QI")])
10923
10924;; In general it is not safe to assume too much about CCmode registers,
10925;; so simplify-rtx stops when it sees a second one.  Under certain
10926;; conditions this is safe on x86, so help combine not create
10927;;
10928;;	seta	%al
10929;;	testb	%al, %al
10930;;	sete	%al
10931
10932(define_split
10933  [(set (match_operand:QI 0 "nonimmediate_operand")
10934	(ne:QI (match_operator 1 "ix86_comparison_operator"
10935	         [(reg FLAGS_REG) (const_int 0)])
10936	    (const_int 0)))]
10937  ""
10938  [(set (match_dup 0) (match_dup 1))]
10939{
10940  operands[1] = shallow_copy_rtx (operands[1]);
10941  PUT_MODE (operands[1], QImode);
10942})
10943
10944(define_split
10945  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10946	(ne:QI (match_operator 1 "ix86_comparison_operator"
10947	         [(reg FLAGS_REG) (const_int 0)])
10948	    (const_int 0)))]
10949  ""
10950  [(set (match_dup 0) (match_dup 1))]
10951{
10952  operands[1] = shallow_copy_rtx (operands[1]);
10953  PUT_MODE (operands[1], QImode);
10954})
10955
10956(define_split
10957  [(set (match_operand:QI 0 "nonimmediate_operand")
10958	(eq:QI (match_operator 1 "ix86_comparison_operator"
10959	         [(reg FLAGS_REG) (const_int 0)])
10960	    (const_int 0)))]
10961  ""
10962  [(set (match_dup 0) (match_dup 1))]
10963{
10964  operands[1] = shallow_copy_rtx (operands[1]);
10965  PUT_MODE (operands[1], QImode);
10966  PUT_CODE (operands[1],
10967	    ix86_reverse_condition (GET_CODE (operands[1]),
10968				    GET_MODE (XEXP (operands[1], 0))));
10969
10970  /* Make sure that (a) the CCmode we have for the flags is strong
10971     enough for the reversed compare or (b) we have a valid FP compare.  */
10972  if (! ix86_comparison_operator (operands[1], VOIDmode))
10973    FAIL;
10974})
10975
10976(define_split
10977  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10978	(eq:QI (match_operator 1 "ix86_comparison_operator"
10979	         [(reg FLAGS_REG) (const_int 0)])
10980	    (const_int 0)))]
10981  ""
10982  [(set (match_dup 0) (match_dup 1))]
10983{
10984  operands[1] = shallow_copy_rtx (operands[1]);
10985  PUT_MODE (operands[1], QImode);
10986  PUT_CODE (operands[1],
10987  	    ix86_reverse_condition (GET_CODE (operands[1]),
10988				    GET_MODE (XEXP (operands[1], 0))));
10989
10990  /* Make sure that (a) the CCmode we have for the flags is strong
10991     enough for the reversed compare or (b) we have a valid FP compare.  */
10992  if (! ix86_comparison_operator (operands[1], VOIDmode))
10993    FAIL;
10994})
10995
10996;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10997;; subsequent logical operations are used to imitate conditional moves.
10998;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10999;; it directly.
11000
11001(define_insn "setcc_<mode>_sse"
11002  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11003	(match_operator:MODEF 3 "sse_comparison_operator"
11004	  [(match_operand:MODEF 1 "register_operand" "0,x")
11005	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11006  "SSE_FLOAT_MODE_P (<MODE>mode)"
11007  "@
11008   cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11009   vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11010  [(set_attr "isa" "noavx,avx")
11011   (set_attr "type" "ssecmp")
11012   (set_attr "length_immediate" "1")
11013   (set_attr "prefix" "orig,vex")
11014   (set_attr "mode" "<MODE>")])
11015
11016;; Basic conditional jump instructions.
11017;; We ignore the overflow flag for signed branch instructions.
11018
11019(define_insn "*jcc_1_bnd"
11020  [(set (pc)
11021	(if_then_else (match_operator 1 "ix86_comparison_operator"
11022				      [(reg FLAGS_REG) (const_int 0)])
11023		      (label_ref (match_operand 0))
11024		      (pc)))]
11025  "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11026  "bnd %+j%C1\t%l0"
11027  [(set_attr "type" "ibr")
11028   (set_attr "modrm" "0")
11029   (set (attr "length")
11030	   (if_then_else (and (ge (minus (match_dup 0) (pc))
11031				  (const_int -126))
11032			      (lt (minus (match_dup 0) (pc))
11033				  (const_int 128)))
11034	     (const_int 3)
11035	     (const_int 7)))])
11036
11037(define_insn "*jcc_1"
11038  [(set (pc)
11039	(if_then_else (match_operator 1 "ix86_comparison_operator"
11040				      [(reg FLAGS_REG) (const_int 0)])
11041		      (label_ref (match_operand 0))
11042		      (pc)))]
11043  ""
11044  "%+j%C1\t%l0"
11045  [(set_attr "type" "ibr")
11046   (set_attr "modrm" "0")
11047   (set (attr "length")
11048	   (if_then_else (and (ge (minus (match_dup 0) (pc))
11049				  (const_int -126))
11050			      (lt (minus (match_dup 0) (pc))
11051				  (const_int 128)))
11052	     (const_int 2)
11053	     (const_int 6)))])
11054
11055(define_insn "*jcc_2_bnd"
11056  [(set (pc)
11057	(if_then_else (match_operator 1 "ix86_comparison_operator"
11058				      [(reg FLAGS_REG) (const_int 0)])
11059		      (pc)
11060		      (label_ref (match_operand 0))))]
11061  "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11062  "bnd %+j%c1\t%l0"
11063  [(set_attr "type" "ibr")
11064   (set_attr "modrm" "0")
11065   (set (attr "length")
11066	   (if_then_else (and (ge (minus (match_dup 0) (pc))
11067				  (const_int -126))
11068			      (lt (minus (match_dup 0) (pc))
11069				  (const_int 128)))
11070	     (const_int 3)
11071	     (const_int 7)))])
11072
11073(define_insn "*jcc_2"
11074  [(set (pc)
11075	(if_then_else (match_operator 1 "ix86_comparison_operator"
11076				      [(reg FLAGS_REG) (const_int 0)])
11077		      (pc)
11078		      (label_ref (match_operand 0))))]
11079  ""
11080  "%+j%c1\t%l0"
11081  [(set_attr "type" "ibr")
11082   (set_attr "modrm" "0")
11083   (set (attr "length")
11084	   (if_then_else (and (ge (minus (match_dup 0) (pc))
11085				  (const_int -126))
11086			      (lt (minus (match_dup 0) (pc))
11087				  (const_int 128)))
11088	     (const_int 2)
11089	     (const_int 6)))])
11090
11091;; In general it is not safe to assume too much about CCmode registers,
11092;; so simplify-rtx stops when it sees a second one.  Under certain
11093;; conditions this is safe on x86, so help combine not create
11094;;
11095;;	seta	%al
11096;;	testb	%al, %al
11097;;	je	Lfoo
11098
11099(define_split
11100  [(set (pc)
11101	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11102				      [(reg FLAGS_REG) (const_int 0)])
11103			  (const_int 0))
11104		      (label_ref (match_operand 1))
11105		      (pc)))]
11106  ""
11107  [(set (pc)
11108	(if_then_else (match_dup 0)
11109		      (label_ref (match_dup 1))
11110		      (pc)))]
11111{
11112  operands[0] = shallow_copy_rtx (operands[0]);
11113  PUT_MODE (operands[0], VOIDmode);
11114})
11115
11116(define_split
11117  [(set (pc)
11118	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11119				      [(reg FLAGS_REG) (const_int 0)])
11120			  (const_int 0))
11121		      (label_ref (match_operand 1))
11122		      (pc)))]
11123  ""
11124  [(set (pc)
11125	(if_then_else (match_dup 0)
11126		      (label_ref (match_dup 1))
11127		      (pc)))]
11128{
11129  operands[0] = shallow_copy_rtx (operands[0]);
11130  PUT_MODE (operands[0], VOIDmode);
11131  PUT_CODE (operands[0],
11132  	    ix86_reverse_condition (GET_CODE (operands[0]),
11133				    GET_MODE (XEXP (operands[0], 0))));
11134
11135  /* Make sure that (a) the CCmode we have for the flags is strong
11136     enough for the reversed compare or (b) we have a valid FP compare.  */
11137  if (! ix86_comparison_operator (operands[0], VOIDmode))
11138    FAIL;
11139})
11140
11141;; zero_extend in SImode is correct also for DImode, since this is what combine
11142;; pass generates from shift insn with QImode operand.  Actually, the mode
11143;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
11144;; appropriate modulo of the bit offset value.
11145
11146(define_insn_and_split "*jcc_bt<mode>"
11147  [(set (pc)
11148  	(if_then_else (match_operator 0 "bt_comparison_operator"
11149			[(zero_extract:SWI48
11150			   (match_operand:SWI48 1 "register_operand" "r")
11151			   (const_int 1)
11152			   (zero_extend:SI
11153			     (match_operand:QI 2 "register_operand" "r")))
11154			 (const_int 0)])
11155		      (label_ref (match_operand 3))
11156		      (pc)))
11157   (clobber (reg:CC FLAGS_REG))]
11158  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11159  "#"
11160  "&& 1"
11161  [(set (reg:CCC FLAGS_REG)
11162	(compare:CCC
11163	  (zero_extract:SWI48
11164	    (match_dup 1)
11165	    (const_int 1)
11166	    (match_dup 2))
11167	  (const_int 0)))
11168   (set (pc)
11169	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11170		      (label_ref (match_dup 3))
11171		      (pc)))]
11172{
11173  operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
11174  operands[0] = shallow_copy_rtx (operands[0]);
11175  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11176})
11177
11178;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
11179;; zero extended to SImode.
11180(define_insn_and_split "*jcc_bt<mode>_1"
11181  [(set (pc)
11182  	(if_then_else (match_operator 0 "bt_comparison_operator"
11183			[(zero_extract:SWI48
11184			   (match_operand:SWI48 1 "register_operand" "r")
11185			   (const_int 1)
11186			   (match_operand:SI 2 "register_operand" "r"))
11187			 (const_int 0)])
11188		      (label_ref (match_operand 3))
11189		      (pc)))
11190   (clobber (reg:CC FLAGS_REG))]
11191  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11192  "#"
11193  "&& 1"
11194  [(set (reg:CCC FLAGS_REG)
11195	(compare:CCC
11196	  (zero_extract:SWI48
11197	    (match_dup 1)
11198	    (const_int 1)
11199	    (match_dup 2))
11200	  (const_int 0)))
11201   (set (pc)
11202	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11203		      (label_ref (match_dup 3))
11204		      (pc)))]
11205{
11206  operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11207  operands[0] = shallow_copy_rtx (operands[0]);
11208  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11209})
11210
11211;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
11212;; also for DImode, this is what combine produces.
11213(define_insn_and_split "*jcc_bt<mode>_mask"
11214  [(set (pc)
11215  	(if_then_else (match_operator 0 "bt_comparison_operator"
11216			[(zero_extract:SWI48
11217			   (match_operand:SWI48 1 "register_operand" "r")
11218			   (const_int 1)
11219			   (and:SI
11220			     (match_operand:SI 2 "register_operand" "r")
11221			     (match_operand:SI 3 "const_int_operand" "n")))])
11222		      (label_ref (match_operand 4))
11223		      (pc)))
11224   (clobber (reg:CC FLAGS_REG))]
11225  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11226   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11227      == GET_MODE_BITSIZE (<MODE>mode)-1"
11228  "#"
11229  "&& 1"
11230  [(set (reg:CCC FLAGS_REG)
11231	(compare:CCC
11232	  (zero_extract:SWI48
11233	    (match_dup 1)
11234	    (const_int 1)
11235	    (match_dup 2))
11236	  (const_int 0)))
11237   (set (pc)
11238	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11239		      (label_ref (match_dup 4))
11240		      (pc)))]
11241{
11242  operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11243  operands[0] = shallow_copy_rtx (operands[0]);
11244  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11245})
11246
11247(define_insn_and_split "*jcc_btsi_1"
11248  [(set (pc)
11249  	(if_then_else (match_operator 0 "bt_comparison_operator"
11250			[(and:SI
11251			   (lshiftrt:SI
11252			     (match_operand:SI 1 "register_operand" "r")
11253			     (match_operand:QI 2 "register_operand" "r"))
11254			   (const_int 1))
11255			 (const_int 0)])
11256		      (label_ref (match_operand 3))
11257		      (pc)))
11258   (clobber (reg:CC FLAGS_REG))]
11259  "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11260  "#"
11261  "&& 1"
11262  [(set (reg:CCC FLAGS_REG)
11263	(compare:CCC
11264	  (zero_extract:SI
11265	    (match_dup 1)
11266	    (const_int 1)
11267	    (match_dup 2))
11268	  (const_int 0)))
11269   (set (pc)
11270	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11271		      (label_ref (match_dup 3))
11272		      (pc)))]
11273{
11274  operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11275  operands[0] = shallow_copy_rtx (operands[0]);
11276  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11277})
11278
11279;; avoid useless masking of bit offset operand
11280(define_insn_and_split "*jcc_btsi_mask_1"
11281  [(set (pc)
11282  	(if_then_else
11283	  (match_operator 0 "bt_comparison_operator"
11284	    [(and:SI
11285	       (lshiftrt:SI
11286		 (match_operand:SI 1 "register_operand" "r")
11287		 (subreg:QI
11288		   (and:SI
11289		     (match_operand:SI 2 "register_operand" "r")
11290		     (match_operand:SI 3 "const_int_operand" "n")) 0))
11291	       (const_int 1))
11292	     (const_int 0)])
11293	  (label_ref (match_operand 4))
11294	  (pc)))
11295   (clobber (reg:CC FLAGS_REG))]
11296  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11297   && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11298  "#"
11299  "&& 1"
11300  [(set (reg:CCC FLAGS_REG)
11301	(compare:CCC
11302	  (zero_extract:SI
11303	    (match_dup 1)
11304	    (const_int 1)
11305	    (match_dup 2))
11306	  (const_int 0)))
11307   (set (pc)
11308	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11309		      (label_ref (match_dup 4))
11310		      (pc)))]
11311{
11312  operands[0] = shallow_copy_rtx (operands[0]);
11313  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11314})
11315
11316;; Define combination compare-and-branch fp compare instructions to help
11317;; combine.
11318
11319(define_insn "*jcc<mode>_0_i387"
11320  [(set (pc)
11321	(if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11322			[(match_operand:X87MODEF 1 "register_operand" "f")
11323			 (match_operand:X87MODEF 2 "const0_operand")])
11324	  (label_ref (match_operand 3))
11325	  (pc)))
11326   (clobber (reg:CCFP FPSR_REG))
11327   (clobber (reg:CCFP FLAGS_REG))
11328   (clobber (match_scratch:HI 4 "=a"))]
11329  "TARGET_80387 && !TARGET_CMOVE"
11330  "#")
11331
11332(define_insn "*jcc<mode>_0_r_i387"
11333  [(set (pc)
11334	(if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11335			[(match_operand:X87MODEF 1 "register_operand" "f")
11336			 (match_operand:X87MODEF 2 "const0_operand")])
11337	  (pc)
11338	  (label_ref (match_operand 3))))
11339   (clobber (reg:CCFP FPSR_REG))
11340   (clobber (reg:CCFP FLAGS_REG))
11341   (clobber (match_scratch:HI 4 "=a"))]
11342  "TARGET_80387 && !TARGET_CMOVE"
11343  "#")
11344
11345(define_insn "*jccxf_i387"
11346  [(set (pc)
11347	(if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11348			[(match_operand:XF 1 "register_operand" "f")
11349			 (match_operand:XF 2 "register_operand" "f")])
11350	  (label_ref (match_operand 3))
11351	  (pc)))
11352   (clobber (reg:CCFP FPSR_REG))
11353   (clobber (reg:CCFP FLAGS_REG))
11354   (clobber (match_scratch:HI 4 "=a"))]
11355  "TARGET_80387 && !TARGET_CMOVE"
11356  "#")
11357
11358(define_insn "*jccxf_r_i387"
11359  [(set (pc)
11360	(if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11361			[(match_operand:XF 1 "register_operand" "f")
11362			 (match_operand:XF 2 "register_operand" "f")])
11363	  (pc)
11364	  (label_ref (match_operand 3))))
11365   (clobber (reg:CCFP FPSR_REG))
11366   (clobber (reg:CCFP FLAGS_REG))
11367   (clobber (match_scratch:HI 4 "=a"))]
11368  "TARGET_80387 && !TARGET_CMOVE"
11369  "#")
11370
11371(define_insn "*jcc<mode>_i387"
11372  [(set (pc)
11373	(if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11374			[(match_operand:MODEF 1 "register_operand" "f")
11375			 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11376	  (label_ref (match_operand 3))
11377	  (pc)))
11378   (clobber (reg:CCFP FPSR_REG))
11379   (clobber (reg:CCFP FLAGS_REG))
11380   (clobber (match_scratch:HI 4 "=a"))]
11381  "TARGET_80387 && !TARGET_CMOVE"
11382  "#")
11383
11384(define_insn "*jcc<mode>_r_i387"
11385  [(set (pc)
11386	(if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11387			[(match_operand:MODEF 1 "register_operand" "f")
11388			 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11389	  (pc)
11390	  (label_ref (match_operand 3))))
11391   (clobber (reg:CCFP FPSR_REG))
11392   (clobber (reg:CCFP FLAGS_REG))
11393   (clobber (match_scratch:HI 4 "=a"))]
11394  "TARGET_80387 && !TARGET_CMOVE"
11395  "#")
11396
11397(define_insn "*jccu<mode>_i387"
11398  [(set (pc)
11399	(if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11400			[(match_operand:X87MODEF 1 "register_operand" "f")
11401			 (match_operand:X87MODEF 2 "register_operand" "f")])
11402	  (label_ref (match_operand 3))
11403	  (pc)))
11404   (clobber (reg:CCFP FPSR_REG))
11405   (clobber (reg:CCFP FLAGS_REG))
11406   (clobber (match_scratch:HI 4 "=a"))]
11407  "TARGET_80387 && !TARGET_CMOVE"
11408  "#")
11409
11410(define_insn "*jccu<mode>_r_i387"
11411  [(set (pc)
11412	(if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11413			[(match_operand:X87MODEF 1 "register_operand" "f")
11414			 (match_operand:X87MODEF 2 "register_operand" "f")])
11415	  (pc)
11416	  (label_ref (match_operand 3))))
11417   (clobber (reg:CCFP FPSR_REG))
11418   (clobber (reg:CCFP FLAGS_REG))
11419   (clobber (match_scratch:HI 4 "=a"))]
11420  "TARGET_80387 && !TARGET_CMOVE"
11421  "#")
11422
11423(define_split
11424  [(set (pc)
11425	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11426			[(match_operand:X87MODEF 1 "register_operand")
11427			 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11428	  (match_operand 3)
11429	  (match_operand 4)))
11430   (clobber (reg:CCFP FPSR_REG))
11431   (clobber (reg:CCFP FLAGS_REG))]
11432  "TARGET_80387 && !TARGET_CMOVE
11433   && reload_completed"
11434  [(const_int 0)]
11435{
11436  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11437	                operands[3], operands[4], NULL_RTX);
11438  DONE;
11439})
11440
11441(define_split
11442  [(set (pc)
11443	(if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11444			[(match_operand:X87MODEF 1 "register_operand")
11445			 (match_operand:X87MODEF 2 "general_operand")])
11446	  (match_operand 3)
11447	  (match_operand 4)))
11448   (clobber (reg:CCFP FPSR_REG))
11449   (clobber (reg:CCFP FLAGS_REG))
11450   (clobber (match_scratch:HI 5))]
11451  "TARGET_80387 && !TARGET_CMOVE
11452   && reload_completed"
11453  [(const_int 0)]
11454{
11455  ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11456			operands[3], operands[4], operands[5]);
11457  DONE;
11458})
11459
11460;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11461;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11462;; with a precedence over other operators and is always put in the first
11463;; place. Swap condition and operands to match ficom instruction.
11464
11465(define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11466  [(set (pc)
11467	(if_then_else
11468	  (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11469	    [(match_operator:X87MODEF 1 "float_operator"
11470	      [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11471	     (match_operand:X87MODEF 3 "register_operand" "f")])
11472	  (label_ref (match_operand 4))
11473	  (pc)))
11474   (clobber (reg:CCFP FPSR_REG))
11475   (clobber (reg:CCFP FLAGS_REG))
11476   (clobber (match_scratch:HI 5 "=a"))]
11477  "TARGET_80387 && !TARGET_CMOVE
11478   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11479       || optimize_function_for_size_p (cfun))"
11480  "#")
11481
11482(define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11483  [(set (pc)
11484	(if_then_else
11485	  (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11486	    [(match_operator:X87MODEF 1 "float_operator"
11487	      [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11488	     (match_operand:X87MODEF 3 "register_operand" "f")])
11489	  (pc)
11490	  (label_ref (match_operand 4))))
11491   (clobber (reg:CCFP FPSR_REG))
11492   (clobber (reg:CCFP FLAGS_REG))
11493   (clobber (match_scratch:HI 5 "=a"))]
11494  "TARGET_80387 && !TARGET_CMOVE
11495   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11496       || optimize_function_for_size_p (cfun))"
11497  "#")
11498
11499(define_split
11500  [(set (pc)
11501	(if_then_else
11502	  (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11503	    [(match_operator:X87MODEF 1 "float_operator"
11504	      [(match_operand:SWI24 2 "memory_operand")])
11505	     (match_operand:X87MODEF 3 "register_operand")])
11506	  (match_operand 4)
11507	  (match_operand 5)))
11508   (clobber (reg:CCFP FPSR_REG))
11509   (clobber (reg:CCFP FLAGS_REG))
11510   (clobber (match_scratch:HI 6))]
11511  "TARGET_80387 && !TARGET_CMOVE
11512   && reload_completed"
11513  [(const_int 0)]
11514{
11515  ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11516		        gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11517			operands[4], operands[5], operands[6]);
11518  DONE;
11519})
11520
11521;; Unconditional and other jump instructions
11522
11523(define_insn "jump_bnd"
11524  [(set (pc)
11525	(label_ref (match_operand 0)))]
11526  "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)"
11527  "bnd jmp\t%l0"
11528  [(set_attr "type" "ibr")
11529   (set (attr "length")
11530	   (if_then_else (and (ge (minus (match_dup 0) (pc))
11531				  (const_int -126))
11532			      (lt (minus (match_dup 0) (pc))
11533				  (const_int 128)))
11534	     (const_int 3)
11535	     (const_int 6)))
11536   (set_attr "modrm" "0")])
11537
11538(define_insn "jump"
11539  [(set (pc)
11540	(label_ref (match_operand 0)))]
11541  ""
11542  "jmp\t%l0"
11543  [(set_attr "type" "ibr")
11544   (set (attr "length")
11545	   (if_then_else (and (ge (minus (match_dup 0) (pc))
11546				  (const_int -126))
11547			      (lt (minus (match_dup 0) (pc))
11548				  (const_int 128)))
11549	     (const_int 2)
11550	     (const_int 5)))
11551   (set_attr "modrm" "0")])
11552
11553(define_expand "indirect_jump"
11554  [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11555  ""
11556{
11557  if (TARGET_X32)
11558    operands[0] = convert_memory_address (word_mode, operands[0]);
11559})
11560
11561(define_insn "*indirect_jump"
11562  [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11563  ""
11564  "%!jmp\t%A0"
11565  [(set_attr "type" "ibr")
11566   (set_attr "length_immediate" "0")])
11567
11568(define_expand "tablejump"
11569  [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11570	      (use (label_ref (match_operand 1)))])]
11571  ""
11572{
11573  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11574     relative.  Convert the relative address to an absolute address.  */
11575  if (flag_pic)
11576    {
11577      rtx op0, op1;
11578      enum rtx_code code;
11579
11580      /* We can't use @GOTOFF for text labels on VxWorks;
11581	 see gotoff_operand.  */
11582      if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11583	{
11584	  code = PLUS;
11585	  op0 = operands[0];
11586	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11587	}
11588      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11589	{
11590	  code = PLUS;
11591	  op0 = operands[0];
11592	  op1 = pic_offset_table_rtx;
11593	}
11594      else
11595	{
11596	  code = MINUS;
11597	  op0 = pic_offset_table_rtx;
11598	  op1 = operands[0];
11599	}
11600
11601      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11602					 OPTAB_DIRECT);
11603    }
11604
11605  if (TARGET_X32)
11606    operands[0] = convert_memory_address (word_mode, operands[0]);
11607})
11608
11609(define_insn "*tablejump_1"
11610  [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11611   (use (label_ref (match_operand 1)))]
11612  ""
11613  "%!jmp\t%A0"
11614  [(set_attr "type" "ibr")
11615   (set_attr "length_immediate" "0")])
11616
11617;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11618
11619(define_peephole2
11620  [(set (reg FLAGS_REG) (match_operand 0))
11621   (set (match_operand:QI 1 "register_operand")
11622	(match_operator:QI 2 "ix86_comparison_operator"
11623	  [(reg FLAGS_REG) (const_int 0)]))
11624   (set (match_operand 3 "q_regs_operand")
11625	(zero_extend (match_dup 1)))]
11626  "(peep2_reg_dead_p (3, operands[1])
11627    || operands_match_p (operands[1], operands[3]))
11628   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11629  [(set (match_dup 4) (match_dup 0))
11630   (set (strict_low_part (match_dup 5))
11631	(match_dup 2))]
11632{
11633  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11634  operands[5] = gen_lowpart (QImode, operands[3]);
11635  ix86_expand_clear (operands[3]);
11636})
11637
11638(define_peephole2
11639  [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11640	      (match_operand 4)])
11641   (set (match_operand:QI 1 "register_operand")
11642	(match_operator:QI 2 "ix86_comparison_operator"
11643	  [(reg FLAGS_REG) (const_int 0)]))
11644   (set (match_operand 3 "q_regs_operand")
11645	(zero_extend (match_dup 1)))]
11646  "(peep2_reg_dead_p (3, operands[1])
11647    || operands_match_p (operands[1], operands[3]))
11648   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11649  [(parallel [(set (match_dup 5) (match_dup 0))
11650	      (match_dup 4)])
11651   (set (strict_low_part (match_dup 6))
11652	(match_dup 2))]
11653{
11654  operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11655  operands[6] = gen_lowpart (QImode, operands[3]);
11656  ix86_expand_clear (operands[3]);
11657})
11658
11659;; Similar, but match zero extend with andsi3.
11660
11661(define_peephole2
11662  [(set (reg FLAGS_REG) (match_operand 0))
11663   (set (match_operand:QI 1 "register_operand")
11664	(match_operator:QI 2 "ix86_comparison_operator"
11665	  [(reg FLAGS_REG) (const_int 0)]))
11666   (parallel [(set (match_operand:SI 3 "q_regs_operand")
11667		   (and:SI (match_dup 3) (const_int 255)))
11668	      (clobber (reg:CC FLAGS_REG))])]
11669  "REGNO (operands[1]) == REGNO (operands[3])
11670   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11671  [(set (match_dup 4) (match_dup 0))
11672   (set (strict_low_part (match_dup 5))
11673	(match_dup 2))]
11674{
11675  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11676  operands[5] = gen_lowpart (QImode, operands[3]);
11677  ix86_expand_clear (operands[3]);
11678})
11679
11680(define_peephole2
11681  [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11682	      (match_operand 4)])
11683   (set (match_operand:QI 1 "register_operand")
11684	(match_operator:QI 2 "ix86_comparison_operator"
11685	  [(reg FLAGS_REG) (const_int 0)]))
11686   (parallel [(set (match_operand 3 "q_regs_operand")
11687		   (zero_extend (match_dup 1)))
11688	      (clobber (reg:CC FLAGS_REG))])]
11689  "(peep2_reg_dead_p (3, operands[1])
11690    || operands_match_p (operands[1], operands[3]))
11691   && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11692  [(parallel [(set (match_dup 5) (match_dup 0))
11693	      (match_dup 4)])
11694   (set (strict_low_part (match_dup 6))
11695	(match_dup 2))]
11696{
11697  operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11698  operands[6] = gen_lowpart (QImode, operands[3]);
11699  ix86_expand_clear (operands[3]);
11700})
11701
11702;; Call instructions.
11703
11704;; The predicates normally associated with named expanders are not properly
11705;; checked for calls.  This is a bug in the generic code, but it isn't that
11706;; easy to fix.  Ignore it for now and be prepared to fix things up.
11707
11708;; P6 processors will jump to the address after the decrement when %esp
11709;; is used as a call operand, so they will execute return address as a code.
11710;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11711
11712;; Register constraint for call instruction.
11713(define_mode_attr c [(SI "l") (DI "r")])
11714
11715;; Call subroutine returning no value.
11716
11717(define_expand "call"
11718  [(call (match_operand:QI 0)
11719	 (match_operand 1))
11720   (use (match_operand 2))]
11721  ""
11722{
11723  ix86_expand_call (NULL, operands[0], operands[1],
11724		    operands[2], NULL, false);
11725  DONE;
11726})
11727
11728(define_expand "sibcall"
11729  [(call (match_operand:QI 0)
11730	 (match_operand 1))
11731   (use (match_operand 2))]
11732  ""
11733{
11734  ix86_expand_call (NULL, operands[0], operands[1],
11735		    operands[2], NULL, true);
11736  DONE;
11737})
11738
11739(define_insn "*call"
11740  [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11741	 (match_operand 1))]
11742  "!SIBLING_CALL_P (insn)"
11743  "* return ix86_output_call_insn (insn, operands[0]);"
11744  [(set_attr "type" "call")])
11745
11746(define_insn "*sibcall"
11747  [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11748	 (match_operand 1))]
11749  "SIBLING_CALL_P (insn)"
11750  "* return ix86_output_call_insn (insn, operands[0]);"
11751  [(set_attr "type" "call")])
11752
11753(define_insn "*sibcall_memory"
11754  [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11755	 (match_operand 1))
11756   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11757  "!TARGET_X32"
11758  "* return ix86_output_call_insn (insn, operands[0]);"
11759  [(set_attr "type" "call")])
11760
11761(define_peephole2
11762  [(set (match_operand:W 0 "register_operand")
11763	(match_operand:W 1 "memory_operand"))
11764   (call (mem:QI (match_dup 0))
11765	 (match_operand 3))]
11766  "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11767   && peep2_reg_dead_p (2, operands[0])"
11768  [(parallel [(call (mem:QI (match_dup 1))
11769		    (match_dup 3))
11770	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11771
11772(define_peephole2
11773  [(set (match_operand:W 0 "register_operand")
11774	(match_operand:W 1 "memory_operand"))
11775   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11776   (call (mem:QI (match_dup 0))
11777	 (match_operand 3))]
11778  "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11779   && peep2_reg_dead_p (3, operands[0])"
11780  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11781   (parallel [(call (mem:QI (match_dup 1))
11782		    (match_dup 3))
11783	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11784
11785(define_expand "call_pop"
11786  [(parallel [(call (match_operand:QI 0)
11787		    (match_operand:SI 1))
11788	      (set (reg:SI SP_REG)
11789		   (plus:SI (reg:SI SP_REG)
11790			    (match_operand:SI 3)))])]
11791  "!TARGET_64BIT"
11792{
11793  ix86_expand_call (NULL, operands[0], operands[1],
11794		    operands[2], operands[3], false);
11795  DONE;
11796})
11797
11798(define_insn "*call_pop"
11799  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11800	 (match_operand 1))
11801   (set (reg:SI SP_REG)
11802	(plus:SI (reg:SI SP_REG)
11803		 (match_operand:SI 2 "immediate_operand" "i")))]
11804  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11805  "* return ix86_output_call_insn (insn, operands[0]);"
11806  [(set_attr "type" "call")])
11807
11808(define_insn "*sibcall_pop"
11809  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11810	 (match_operand 1))
11811   (set (reg:SI SP_REG)
11812	(plus:SI (reg:SI SP_REG)
11813		 (match_operand:SI 2 "immediate_operand" "i")))]
11814  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11815  "* return ix86_output_call_insn (insn, operands[0]);"
11816  [(set_attr "type" "call")])
11817
11818(define_insn "*sibcall_pop_memory"
11819  [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11820	 (match_operand 1))
11821   (set (reg:SI SP_REG)
11822	(plus:SI (reg:SI SP_REG)
11823		 (match_operand:SI 2 "immediate_operand" "i")))
11824   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11825  "!TARGET_64BIT"
11826  "* return ix86_output_call_insn (insn, operands[0]);"
11827  [(set_attr "type" "call")])
11828
11829(define_peephole2
11830  [(set (match_operand:SI 0 "register_operand")
11831	(match_operand:SI 1 "memory_operand"))
11832   (parallel [(call (mem:QI (match_dup 0))
11833		    (match_operand 3))
11834	      (set (reg:SI SP_REG)
11835		   (plus:SI (reg:SI SP_REG)
11836			    (match_operand:SI 4 "immediate_operand")))])]
11837  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11838   && peep2_reg_dead_p (2, operands[0])"
11839  [(parallel [(call (mem:QI (match_dup 1))
11840		    (match_dup 3))
11841	      (set (reg:SI SP_REG)
11842		   (plus:SI (reg:SI SP_REG)
11843			    (match_dup 4)))
11844	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11845
11846(define_peephole2
11847  [(set (match_operand:SI 0 "register_operand")
11848	(match_operand:SI 1 "memory_operand"))
11849   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11850   (parallel [(call (mem:QI (match_dup 0))
11851		    (match_operand 3))
11852	      (set (reg:SI SP_REG)
11853		   (plus:SI (reg:SI SP_REG)
11854			    (match_operand:SI 4 "immediate_operand")))])]
11855  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11856   && peep2_reg_dead_p (3, operands[0])"
11857  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11858   (parallel [(call (mem:QI (match_dup 1))
11859		    (match_dup 3))
11860	      (set (reg:SI SP_REG)
11861		   (plus:SI (reg:SI SP_REG)
11862			    (match_dup 4)))
11863	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11864
11865;; Combining simple memory jump instruction
11866
11867(define_peephole2
11868  [(set (match_operand:W 0 "register_operand")
11869        (match_operand:W 1 "memory_operand"))
11870   (set (pc) (match_dup 0))]
11871  "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11872  [(set (pc) (match_dup 1))])
11873
11874;; Call subroutine, returning value in operand 0
11875
11876(define_expand "call_value"
11877  [(set (match_operand 0)
11878	(call (match_operand:QI 1)
11879	      (match_operand 2)))
11880   (use (match_operand 3))]
11881  ""
11882{
11883  ix86_expand_call (operands[0], operands[1], operands[2],
11884		    operands[3], NULL, false);
11885  DONE;
11886})
11887
11888(define_expand "sibcall_value"
11889  [(set (match_operand 0)
11890	(call (match_operand:QI 1)
11891	      (match_operand 2)))
11892   (use (match_operand 3))]
11893  ""
11894{
11895  ix86_expand_call (operands[0], operands[1], operands[2],
11896		    operands[3], NULL, true);
11897  DONE;
11898})
11899
11900(define_insn "*call_value"
11901  [(set (match_operand 0)
11902	(call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11903	      (match_operand 2)))]
11904  "!SIBLING_CALL_P (insn)"
11905  "* return ix86_output_call_insn (insn, operands[1]);"
11906  [(set_attr "type" "callv")])
11907
11908(define_insn "*sibcall_value"
11909  [(set (match_operand 0)
11910	(call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11911	      (match_operand 2)))]
11912  "SIBLING_CALL_P (insn)"
11913  "* return ix86_output_call_insn (insn, operands[1]);"
11914  [(set_attr "type" "callv")])
11915
11916(define_insn "*sibcall_value_memory"
11917  [(set (match_operand 0)
11918 	(call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11919	      (match_operand 2)))
11920   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11921  "!TARGET_X32"
11922  "* return ix86_output_call_insn (insn, operands[1]);"
11923  [(set_attr "type" "callv")])
11924
11925(define_peephole2
11926  [(set (match_operand:W 0 "register_operand")
11927	(match_operand:W 1 "memory_operand"))
11928   (set (match_operand 2)
11929   (call (mem:QI (match_dup 0))
11930		 (match_operand 3)))]
11931  "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11932   && peep2_reg_dead_p (2, operands[0])"
11933  [(parallel [(set (match_dup 2)
11934		   (call (mem:QI (match_dup 1))
11935			 (match_dup 3)))
11936	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11937
11938(define_peephole2
11939  [(set (match_operand:W 0 "register_operand")
11940	(match_operand:W 1 "memory_operand"))
11941   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11942   (set (match_operand 2)
11943	(call (mem:QI (match_dup 0))
11944	      (match_operand 3)))]
11945  "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11946   && peep2_reg_dead_p (3, operands[0])"
11947  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11948   (parallel [(set (match_dup 2)
11949		   (call (mem:QI (match_dup 1))
11950			 (match_dup 3)))
11951	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11952
11953(define_expand "call_value_pop"
11954  [(parallel [(set (match_operand 0)
11955		   (call (match_operand:QI 1)
11956			 (match_operand:SI 2)))
11957	      (set (reg:SI SP_REG)
11958		   (plus:SI (reg:SI SP_REG)
11959			    (match_operand:SI 4)))])]
11960  "!TARGET_64BIT"
11961{
11962  ix86_expand_call (operands[0], operands[1], operands[2],
11963		    operands[3], operands[4], false);
11964  DONE;
11965})
11966
11967(define_insn "*call_value_pop"
11968  [(set (match_operand 0)
11969	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11970	      (match_operand 2)))
11971   (set (reg:SI SP_REG)
11972	(plus:SI (reg:SI SP_REG)
11973		 (match_operand:SI 3 "immediate_operand" "i")))]
11974  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11975  "* return ix86_output_call_insn (insn, operands[1]);"
11976  [(set_attr "type" "callv")])
11977
11978(define_insn "*sibcall_value_pop"
11979  [(set (match_operand 0)
11980	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11981	      (match_operand 2)))
11982   (set (reg:SI SP_REG)
11983	(plus:SI (reg:SI SP_REG)
11984		 (match_operand:SI 3 "immediate_operand" "i")))]
11985  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11986  "* return ix86_output_call_insn (insn, operands[1]);"
11987  [(set_attr "type" "callv")])
11988
11989(define_insn "*sibcall_value_pop_memory"
11990  [(set (match_operand 0)
11991 	(call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11992	      (match_operand 2)))
11993   (set (reg:SI SP_REG)
11994	(plus:SI (reg:SI SP_REG)
11995		 (match_operand:SI 3 "immediate_operand" "i")))
11996   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11997  "!TARGET_64BIT"
11998  "* return ix86_output_call_insn (insn, operands[1]);"
11999  [(set_attr "type" "callv")])
12000
12001(define_peephole2
12002  [(set (match_operand:SI 0 "register_operand")
12003	(match_operand:SI 1 "memory_operand"))
12004   (parallel [(set (match_operand 2)
12005		   (call (mem:QI (match_dup 0))
12006			 (match_operand 3)))
12007	      (set (reg:SI SP_REG)
12008		   (plus:SI (reg:SI SP_REG)
12009			    (match_operand:SI 4 "immediate_operand")))])]
12010  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12011   && peep2_reg_dead_p (2, operands[0])"
12012  [(parallel [(set (match_dup 2)
12013		   (call (mem:QI (match_dup 1))
12014			 (match_dup 3)))
12015	      (set (reg:SI SP_REG)
12016		   (plus:SI (reg:SI SP_REG)
12017			    (match_dup 4)))
12018	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12019
12020(define_peephole2
12021  [(set (match_operand:SI 0 "register_operand")
12022	(match_operand:SI 1 "memory_operand"))
12023   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12024   (parallel [(set (match_operand 2)
12025		   (call (mem:QI (match_dup 0))
12026			 (match_operand 3)))
12027	      (set (reg:SI SP_REG)
12028		   (plus:SI (reg:SI SP_REG)
12029			    (match_operand:SI 4 "immediate_operand")))])]
12030  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12031   && peep2_reg_dead_p (3, operands[0])"
12032  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12033   (parallel [(set (match_dup 2)
12034		   (call (mem:QI (match_dup 1))
12035			 (match_dup 3)))
12036	      (set (reg:SI SP_REG)
12037		   (plus:SI (reg:SI SP_REG)
12038			    (match_dup 4)))
12039	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12040
12041;; Call subroutine returning any type.
12042
12043(define_expand "untyped_call"
12044  [(parallel [(call (match_operand 0)
12045		    (const_int 0))
12046	      (match_operand 1)
12047	      (match_operand 2)])]
12048  ""
12049{
12050  int i;
12051
12052  /* In order to give reg-stack an easier job in validating two
12053     coprocessor registers as containing a possible return value,
12054     simply pretend the untyped call returns a complex long double
12055     value. 
12056
12057     We can't use SSE_REGPARM_MAX here since callee is unprototyped
12058     and should have the default ABI.  */
12059
12060  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12061		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12062		    operands[0], const0_rtx,
12063		    GEN_INT ((TARGET_64BIT
12064			      ? (ix86_abi == SYSV_ABI
12065				 ? X86_64_SSE_REGPARM_MAX
12066				 : X86_64_MS_SSE_REGPARM_MAX)
12067			      : X86_32_SSE_REGPARM_MAX)
12068		    	     - 1),
12069		    NULL, false);
12070
12071  for (i = 0; i < XVECLEN (operands[2], 0); i++)
12072    {
12073      rtx set = XVECEXP (operands[2], 0, i);
12074      emit_move_insn (SET_DEST (set), SET_SRC (set));
12075    }
12076
12077  /* The optimizer does not know that the call sets the function value
12078     registers we stored in the result block.  We avoid problems by
12079     claiming that all hard registers are used and clobbered at this
12080     point.  */
12081  emit_insn (gen_blockage ());
12082
12083  DONE;
12084})
12085
12086;; Prologue and epilogue instructions
12087
12088;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12089;; all of memory.  This blocks insns from being moved across this point.
12090
12091(define_insn "blockage"
12092  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12093  ""
12094  ""
12095  [(set_attr "length" "0")])
12096
12097;; Do not schedule instructions accessing memory across this point.
12098
12099(define_expand "memory_blockage"
12100  [(set (match_dup 0)
12101	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12102  ""
12103{
12104  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12105  MEM_VOLATILE_P (operands[0]) = 1;
12106})
12107
12108(define_insn "*memory_blockage"
12109  [(set (match_operand:BLK 0)
12110	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12111  ""
12112  ""
12113  [(set_attr "length" "0")])
12114
12115;; As USE insns aren't meaningful after reload, this is used instead
12116;; to prevent deleting instructions setting registers for PIC code
12117(define_insn "prologue_use"
12118  [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12119  ""
12120  ""
12121  [(set_attr "length" "0")])
12122
12123;; Insn emitted into the body of a function to return from a function.
12124;; This is only done if the function's epilogue is known to be simple.
12125;; See comments for ix86_can_use_return_insn_p in i386.c.
12126
12127(define_expand "return"
12128  [(simple_return)]
12129  "ix86_can_use_return_insn_p ()"
12130{
12131  if (crtl->args.pops_args)
12132    {
12133      rtx popc = GEN_INT (crtl->args.pops_args);
12134      emit_jump_insn (gen_simple_return_pop_internal (popc));
12135      DONE;
12136    }
12137})
12138
12139;; We need to disable this for TARGET_SEH, as otherwise
12140;; shrink-wrapped prologue gets enabled too.  This might exceed
12141;; the maximum size of prologue in unwind information.
12142;; Also disallow shrink-wrapping if using stack slot to pass the
12143;; static chain pointer - the first instruction has to be pushl %esi
12144;; and it can't be moved around, as we use alternate entry points
12145;; in that case.
12146
12147(define_expand "simple_return"
12148  [(simple_return)]
12149  "!TARGET_SEH && !ix86_static_chain_on_stack"
12150{
12151  if (crtl->args.pops_args)
12152    {
12153      rtx popc = GEN_INT (crtl->args.pops_args);
12154      emit_jump_insn (gen_simple_return_pop_internal (popc));
12155      DONE;
12156    }
12157})
12158
12159(define_insn "simple_return_internal"
12160  [(simple_return)]
12161  "reload_completed"
12162  "%!ret"
12163  [(set_attr "length_nobnd" "1")
12164   (set_attr "atom_unit" "jeu")
12165   (set_attr "length_immediate" "0")
12166   (set_attr "modrm" "0")])
12167
12168;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12169;; instruction Athlon and K8 have.
12170
12171(define_insn "simple_return_internal_long"
12172  [(simple_return)
12173   (unspec [(const_int 0)] UNSPEC_REP)]
12174  "reload_completed"
12175{
12176  if (ix86_bnd_prefixed_insn_p (insn))
12177    return "%!ret";
12178
12179  return "rep%; ret";
12180}
12181  [(set_attr "length" "2")
12182   (set_attr "atom_unit" "jeu")
12183   (set_attr "length_immediate" "0")
12184   (set_attr "prefix_rep" "1")
12185   (set_attr "modrm" "0")])
12186
12187(define_insn "simple_return_pop_internal"
12188  [(simple_return)
12189   (use (match_operand:SI 0 "const_int_operand"))]
12190  "reload_completed"
12191  "%!ret\t%0"
12192  [(set_attr "length_nobnd" "3")
12193   (set_attr "atom_unit" "jeu")
12194   (set_attr "length_immediate" "2")
12195   (set_attr "modrm" "0")])
12196
12197(define_insn "simple_return_indirect_internal"
12198  [(simple_return)
12199   (use (match_operand:SI 0 "register_operand" "r"))]
12200  "reload_completed"
12201  "%!jmp\t%A0"
12202  [(set_attr "type" "ibr")
12203   (set_attr "length_immediate" "0")])
12204
12205(define_insn "nop"
12206  [(const_int 0)]
12207  ""
12208  "nop"
12209  [(set_attr "length" "1")
12210   (set_attr "length_immediate" "0")
12211   (set_attr "modrm" "0")])
12212
12213;; Generate nops.  Operand 0 is the number of nops, up to 8.
12214(define_insn "nops"
12215  [(unspec_volatile [(match_operand 0 "const_int_operand")]
12216		    UNSPECV_NOPS)]
12217  "reload_completed"
12218{
12219  int num = INTVAL (operands[0]);
12220
12221  gcc_assert (IN_RANGE (num, 1, 8));
12222
12223  while (num--)
12224    fputs ("\tnop\n", asm_out_file);
12225
12226  return "";
12227}
12228  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12229   (set_attr "length_immediate" "0")
12230   (set_attr "modrm" "0")])
12231
12232;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12233;; branch prediction penalty for the third jump in a 16-byte
12234;; block on K8.
12235
12236(define_insn "pad"
12237  [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12238  ""
12239{
12240#ifdef ASM_OUTPUT_MAX_SKIP_PAD
12241  ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12242#else
12243  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12244     The align insn is used to avoid 3 jump instructions in the row to improve
12245     branch prediction and the benefits hardly outweigh the cost of extra 8
12246     nops on the average inserted by full alignment pseudo operation.  */
12247#endif
12248  return "";
12249}
12250  [(set_attr "length" "16")])
12251
12252(define_expand "prologue"
12253  [(const_int 0)]
12254  ""
12255  "ix86_expand_prologue (); DONE;")
12256
12257(define_insn "set_got"
12258  [(set (match_operand:SI 0 "register_operand" "=r")
12259	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12260   (clobber (reg:CC FLAGS_REG))]
12261  "!TARGET_64BIT"
12262  "* return output_set_got (operands[0], NULL_RTX);"
12263  [(set_attr "type" "multi")
12264   (set_attr "length" "12")])
12265
12266(define_insn "set_got_labelled"
12267  [(set (match_operand:SI 0 "register_operand" "=r")
12268	(unspec:SI [(label_ref (match_operand 1))]
12269	 UNSPEC_SET_GOT))
12270   (clobber (reg:CC FLAGS_REG))]
12271  "!TARGET_64BIT"
12272  "* return output_set_got (operands[0], operands[1]);"
12273  [(set_attr "type" "multi")
12274   (set_attr "length" "12")])
12275
12276(define_insn "set_got_rex64"
12277  [(set (match_operand:DI 0 "register_operand" "=r")
12278	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12279  "TARGET_64BIT"
12280  "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12281  [(set_attr "type" "lea")
12282   (set_attr "length_address" "4")
12283   (set_attr "mode" "DI")])
12284
12285(define_insn "set_rip_rex64"
12286  [(set (match_operand:DI 0 "register_operand" "=r")
12287	(unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12288  "TARGET_64BIT"
12289  "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12290  [(set_attr "type" "lea")
12291   (set_attr "length_address" "4")
12292   (set_attr "mode" "DI")])
12293
12294(define_insn "set_got_offset_rex64"
12295  [(set (match_operand:DI 0 "register_operand" "=r")
12296	(unspec:DI
12297	  [(label_ref (match_operand 1))]
12298	  UNSPEC_SET_GOT_OFFSET))]
12299  "TARGET_LP64"
12300  "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12301  [(set_attr "type" "imov")
12302   (set_attr "length_immediate" "0")
12303   (set_attr "length_address" "8")
12304   (set_attr "mode" "DI")])
12305
12306(define_expand "epilogue"
12307  [(const_int 0)]
12308  ""
12309  "ix86_expand_epilogue (1); DONE;")
12310
12311(define_expand "sibcall_epilogue"
12312  [(const_int 0)]
12313  ""
12314  "ix86_expand_epilogue (0); DONE;")
12315
12316(define_expand "eh_return"
12317  [(use (match_operand 0 "register_operand"))]
12318  ""
12319{
12320  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12321
12322  /* Tricky bit: we write the address of the handler to which we will
12323     be returning into someone else's stack frame, one word below the
12324     stack address we wish to restore.  */
12325  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12326  tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12327  tmp = gen_rtx_MEM (Pmode, tmp);
12328  emit_move_insn (tmp, ra);
12329
12330  emit_jump_insn (gen_eh_return_internal ());
12331  emit_barrier ();
12332  DONE;
12333})
12334
12335(define_insn_and_split "eh_return_internal"
12336  [(eh_return)]
12337  ""
12338  "#"
12339  "epilogue_completed"
12340  [(const_int 0)]
12341  "ix86_expand_epilogue (2); DONE;")
12342
12343(define_insn "leave"
12344  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12345   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12346   (clobber (mem:BLK (scratch)))]
12347  "!TARGET_64BIT"
12348  "leave"
12349  [(set_attr "type" "leave")])
12350
12351(define_insn "leave_rex64"
12352  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12353   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12354   (clobber (mem:BLK (scratch)))]
12355  "TARGET_64BIT"
12356  "leave"
12357  [(set_attr "type" "leave")])
12358
12359;; Handle -fsplit-stack.
12360
12361(define_expand "split_stack_prologue"
12362  [(const_int 0)]
12363  ""
12364{
12365  ix86_expand_split_stack_prologue ();
12366  DONE;
12367})
12368
12369;; In order to support the call/return predictor, we use a return
12370;; instruction which the middle-end doesn't see.
12371(define_insn "split_stack_return"
12372  [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12373		     UNSPECV_SPLIT_STACK_RETURN)]
12374  ""
12375{
12376  if (operands[0] == const0_rtx)
12377    return "ret";
12378  else
12379    return "ret\t%0";
12380}
12381  [(set_attr "atom_unit" "jeu")
12382   (set_attr "modrm" "0")
12383   (set (attr "length")
12384	(if_then_else (match_operand:SI 0 "const0_operand")
12385		      (const_int 1)
12386		      (const_int 3)))
12387   (set (attr "length_immediate")
12388	(if_then_else (match_operand:SI 0 "const0_operand")
12389		      (const_int 0)
12390		      (const_int 2)))])
12391
12392;; If there are operand 0 bytes available on the stack, jump to
12393;; operand 1.
12394
12395(define_expand "split_stack_space_check"
12396  [(set (pc) (if_then_else
12397	      (ltu (minus (reg SP_REG)
12398			  (match_operand 0 "register_operand"))
12399		   (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12400	      (label_ref (match_operand 1))
12401	      (pc)))]
12402  ""
12403{
12404  rtx reg, size, limit;
12405
12406  reg = gen_reg_rtx (Pmode);
12407  size = force_reg (Pmode, operands[0]);
12408  emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12409  limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12410			  UNSPEC_STACK_CHECK);
12411  limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12412  ix86_expand_branch (GEU, reg, limit, operands[1]);
12413
12414  DONE;
12415})
12416
12417;; Bit manipulation instructions.
12418
12419(define_expand "ffs<mode>2"
12420  [(set (match_dup 2) (const_int -1))
12421   (parallel [(set (match_dup 3) (match_dup 4))
12422	      (set (match_operand:SWI48 0 "register_operand")
12423		   (ctz:SWI48
12424		     (match_operand:SWI48 1 "nonimmediate_operand")))])
12425   (set (match_dup 0) (if_then_else:SWI48
12426			(eq (match_dup 3) (const_int 0))
12427			(match_dup 2)
12428			(match_dup 0)))
12429   (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12430	      (clobber (reg:CC FLAGS_REG))])]
12431  ""
12432{
12433  machine_mode flags_mode;
12434
12435  if (<MODE>mode == SImode && !TARGET_CMOVE)
12436    {
12437      emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12438      DONE;
12439    }
12440
12441  flags_mode
12442    = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12443
12444  operands[2] = gen_reg_rtx (<MODE>mode);
12445  operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12446  operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12447})
12448
12449(define_insn_and_split "ffssi2_no_cmove"
12450  [(set (match_operand:SI 0 "register_operand" "=r")
12451	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12452   (clobber (match_scratch:SI 2 "=&q"))
12453   (clobber (reg:CC FLAGS_REG))]
12454  "!TARGET_CMOVE"
12455  "#"
12456  "&& reload_completed"
12457  [(parallel [(set (match_dup 4) (match_dup 5))
12458	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
12459   (set (strict_low_part (match_dup 3))
12460	(eq:QI (match_dup 4) (const_int 0)))
12461   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12462	      (clobber (reg:CC FLAGS_REG))])
12463   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12464	      (clobber (reg:CC FLAGS_REG))])
12465   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12466	      (clobber (reg:CC FLAGS_REG))])]
12467{
12468  machine_mode flags_mode
12469    = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12470
12471  operands[3] = gen_lowpart (QImode, operands[2]);
12472  operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12473  operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12474
12475  ix86_expand_clear (operands[2]);
12476})
12477
12478(define_insn "*tzcnt<mode>_1"
12479  [(set (reg:CCC FLAGS_REG)
12480	(compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12481		     (const_int 0)))
12482   (set (match_operand:SWI48 0 "register_operand" "=r")
12483	(ctz:SWI48 (match_dup 1)))]
12484  "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12485  "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12486  [(set_attr "type" "alu1")
12487   (set_attr "prefix_0f" "1")
12488   (set_attr "prefix_rep" "1")
12489   (set_attr "btver2_decode" "double")
12490   (set_attr "mode" "<MODE>")])
12491
12492(define_insn "*bsf<mode>_1"
12493  [(set (reg:CCZ FLAGS_REG)
12494	(compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12495		     (const_int 0)))
12496   (set (match_operand:SWI48 0 "register_operand" "=r")
12497	(ctz:SWI48 (match_dup 1)))]
12498  ""
12499  "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12500  [(set_attr "type" "alu1")
12501   (set_attr "prefix_0f" "1")
12502   (set_attr "btver2_decode" "double")
12503   (set_attr "mode" "<MODE>")])
12504
12505(define_expand "ctz<mode>2"
12506  [(parallel
12507    [(set (match_operand:SWI248 0 "register_operand")
12508	  (ctz:SWI248
12509	    (match_operand:SWI248 1 "nonimmediate_operand")))
12510     (clobber (reg:CC FLAGS_REG))])])
12511
12512; False dependency happens when destination is only updated by tzcnt,
12513; lzcnt or popcnt.  There is no false dependency when destination is
12514; also used in source.
12515(define_insn_and_split "*ctz<mode>2_falsedep_1"
12516  [(set (match_operand:SWI48 0 "register_operand" "=r")
12517	(ctz:SWI48
12518	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12519   (clobber (reg:CC FLAGS_REG))]
12520  "(TARGET_BMI || TARGET_GENERIC)
12521   && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12522  "#"
12523  "&& reload_completed"
12524  [(parallel
12525    [(set (match_dup 0)
12526	  (ctz:SWI48 (match_dup 1)))
12527     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12528     (clobber (reg:CC FLAGS_REG))])]
12529{
12530  if (!reg_mentioned_p (operands[0], operands[1]))
12531    ix86_expand_clear (operands[0]);
12532})
12533
12534(define_insn "*ctz<mode>2_falsedep"
12535  [(set (match_operand:SWI48 0 "register_operand" "=r")
12536	(ctz:SWI48
12537	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12538   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12539	   UNSPEC_INSN_FALSE_DEP)
12540   (clobber (reg:CC FLAGS_REG))]
12541  ""
12542{
12543  if (TARGET_BMI)
12544    return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12545  else if (TARGET_GENERIC)
12546    /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12547    return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12548  else
12549    gcc_unreachable ();
12550}
12551  [(set_attr "type" "alu1")
12552   (set_attr "prefix_0f" "1")
12553   (set_attr "prefix_rep" "1")
12554   (set_attr "mode" "<MODE>")])
12555
12556(define_insn "*ctz<mode>2"
12557  [(set (match_operand:SWI248 0 "register_operand" "=r")
12558	(ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12559   (clobber (reg:CC FLAGS_REG))]
12560  ""
12561{
12562  if (TARGET_BMI)
12563    return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12564  else if (optimize_function_for_size_p (cfun))
12565    ;
12566  else if (TARGET_GENERIC)
12567    /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12568    return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12569
12570  return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12571}
12572  [(set_attr "type" "alu1")
12573   (set_attr "prefix_0f" "1")
12574   (set (attr "prefix_rep")
12575     (if_then_else
12576       (ior (match_test "TARGET_BMI")
12577	    (and (not (match_test "optimize_function_for_size_p (cfun)"))
12578		 (match_test "TARGET_GENERIC")))
12579       (const_string "1")
12580       (const_string "0")))
12581   (set_attr "mode" "<MODE>")])
12582
12583(define_expand "clz<mode>2"
12584  [(parallel
12585     [(set (match_operand:SWI248 0 "register_operand")
12586	   (minus:SWI248
12587	     (match_dup 2)
12588	     (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12589      (clobber (reg:CC FLAGS_REG))])
12590   (parallel
12591     [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12592      (clobber (reg:CC FLAGS_REG))])]
12593  ""
12594{
12595  if (TARGET_LZCNT)
12596    {
12597      emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12598      DONE;
12599    }
12600  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12601})
12602
12603(define_expand "clz<mode>2_lzcnt"
12604  [(parallel
12605    [(set (match_operand:SWI248 0 "register_operand")
12606	  (clz:SWI248
12607	    (match_operand:SWI248 1 "nonimmediate_operand")))
12608     (clobber (reg:CC FLAGS_REG))])]
12609  "TARGET_LZCNT")
12610
12611(define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12612  [(set (match_operand:SWI48 0 "register_operand" "=r")
12613	(clz:SWI48
12614	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12615   (clobber (reg:CC FLAGS_REG))]
12616  "TARGET_LZCNT
12617   && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12618  "#"
12619  "&& reload_completed"
12620  [(parallel
12621    [(set (match_dup 0)
12622	  (clz:SWI48 (match_dup 1)))
12623     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12624     (clobber (reg:CC FLAGS_REG))])]
12625{
12626  if (!reg_mentioned_p (operands[0], operands[1]))
12627    ix86_expand_clear (operands[0]);
12628})
12629
12630(define_insn "*clz<mode>2_lzcnt_falsedep"
12631  [(set (match_operand:SWI48 0 "register_operand" "=r")
12632	(clz:SWI48
12633	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12634   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12635	   UNSPEC_INSN_FALSE_DEP)
12636   (clobber (reg:CC FLAGS_REG))]
12637  "TARGET_LZCNT"
12638  "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12639  [(set_attr "prefix_rep" "1")
12640   (set_attr "type" "bitmanip")
12641   (set_attr "mode" "<MODE>")])
12642
12643(define_insn "*clz<mode>2_lzcnt"
12644  [(set (match_operand:SWI248 0 "register_operand" "=r")
12645	(clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12646   (clobber (reg:CC FLAGS_REG))]
12647  "TARGET_LZCNT"
12648  "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12649  [(set_attr "prefix_rep" "1")
12650   (set_attr "type" "bitmanip")
12651   (set_attr "mode" "<MODE>")])
12652
12653;; BMI instructions.
12654(define_insn "*bmi_andn_<mode>"
12655  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12656        (and:SWI48
12657          (not:SWI48
12658            (match_operand:SWI48 1 "register_operand" "r,r"))
12659            (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12660   (clobber (reg:CC FLAGS_REG))]
12661  "TARGET_BMI"
12662  "andn\t{%2, %1, %0|%0, %1, %2}"
12663  [(set_attr "type" "bitmanip")
12664   (set_attr "btver2_decode" "direct, double")
12665   (set_attr "mode" "<MODE>")])
12666
12667(define_insn "bmi_bextr_<mode>"
12668  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12669        (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12670                       (match_operand:SWI48 2 "register_operand" "r,r")]
12671                       UNSPEC_BEXTR))
12672   (clobber (reg:CC FLAGS_REG))]
12673  "TARGET_BMI"
12674  "bextr\t{%2, %1, %0|%0, %1, %2}"
12675  [(set_attr "type" "bitmanip")
12676   (set_attr "btver2_decode" "direct, double")
12677   (set_attr "mode" "<MODE>")])
12678
12679(define_insn "*bmi_blsi_<mode>"
12680  [(set (match_operand:SWI48 0 "register_operand" "=r")
12681        (and:SWI48
12682          (neg:SWI48
12683            (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12684          (match_dup 1)))
12685   (clobber (reg:CC FLAGS_REG))]
12686  "TARGET_BMI"
12687  "blsi\t{%1, %0|%0, %1}"
12688  [(set_attr "type" "bitmanip")
12689   (set_attr "btver2_decode" "double")
12690   (set_attr "mode" "<MODE>")])
12691
12692(define_insn "*bmi_blsmsk_<mode>"
12693  [(set (match_operand:SWI48 0 "register_operand" "=r")
12694        (xor:SWI48
12695          (plus:SWI48
12696            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12697            (const_int -1))
12698          (match_dup 1)))
12699   (clobber (reg:CC FLAGS_REG))]
12700  "TARGET_BMI"
12701  "blsmsk\t{%1, %0|%0, %1}"
12702  [(set_attr "type" "bitmanip")
12703   (set_attr "btver2_decode" "double")
12704   (set_attr "mode" "<MODE>")])
12705
12706(define_insn "*bmi_blsr_<mode>"
12707  [(set (match_operand:SWI48 0 "register_operand" "=r")
12708        (and:SWI48
12709          (plus:SWI48
12710            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12711            (const_int -1))
12712          (match_dup 1)))
12713   (clobber (reg:CC FLAGS_REG))]
12714   "TARGET_BMI"
12715   "blsr\t{%1, %0|%0, %1}"
12716  [(set_attr "type" "bitmanip")
12717   (set_attr "btver2_decode" "double")
12718   (set_attr "mode" "<MODE>")])
12719
12720;; BMI2 instructions.
12721(define_expand "bmi2_bzhi_<mode>3"
12722  [(parallel
12723    [(set (match_operand:SWI48 0 "register_operand")
12724	  (zero_extract:SWI48
12725	    (match_operand:SWI48 1 "nonimmediate_operand")
12726	    (umin:SWI48
12727	      (and:SWI48 (match_operand:SWI48 2 "register_operand")
12728			 (const_int 255))
12729	      (match_dup 3))
12730	    (const_int 0)))
12731     (clobber (reg:CC FLAGS_REG))])]
12732  "TARGET_BMI2"
12733  "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
12734
12735(define_insn "*bmi2_bzhi_<mode>3"
12736  [(set (match_operand:SWI48 0 "register_operand" "=r")
12737	(zero_extract:SWI48
12738	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12739	  (umin:SWI48
12740	    (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
12741		       (const_int 255))
12742	    (match_operand:SWI48 3 "const_int_operand" "n"))
12743	  (const_int 0)))
12744   (clobber (reg:CC FLAGS_REG))]
12745  "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12746  "bzhi\t{%2, %1, %0|%0, %1, %2}"
12747  [(set_attr "type" "bitmanip")
12748   (set_attr "prefix" "vex")
12749   (set_attr "mode" "<MODE>")])
12750
12751(define_mode_attr k [(SI "k") (DI "q")])
12752(define_insn "*bmi2_bzhi_<mode>3_1"
12753  [(set (match_operand:SWI48 0 "register_operand" "=r")
12754	(zero_extract:SWI48
12755	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12756	  (umin:SWI48
12757	    (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
12758	    (match_operand:SWI48 3 "const_int_operand" "n"))
12759	  (const_int 0)))
12760   (clobber (reg:CC FLAGS_REG))]
12761  "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12762  "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
12763  [(set_attr "type" "bitmanip")
12764   (set_attr "prefix" "vex")
12765   (set_attr "mode" "<MODE>")])
12766
12767(define_insn "bmi2_pdep_<mode>3"
12768  [(set (match_operand:SWI48 0 "register_operand" "=r")
12769        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12770                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12771                       UNSPEC_PDEP))]
12772  "TARGET_BMI2"
12773  "pdep\t{%2, %1, %0|%0, %1, %2}"
12774  [(set_attr "type" "bitmanip")
12775   (set_attr "prefix" "vex")
12776   (set_attr "mode" "<MODE>")])
12777
12778(define_insn "bmi2_pext_<mode>3"
12779  [(set (match_operand:SWI48 0 "register_operand" "=r")
12780        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12781                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12782                       UNSPEC_PEXT))]
12783  "TARGET_BMI2"
12784  "pext\t{%2, %1, %0|%0, %1, %2}"
12785  [(set_attr "type" "bitmanip")
12786   (set_attr "prefix" "vex")
12787   (set_attr "mode" "<MODE>")])
12788
12789;; TBM instructions.
12790(define_insn "tbm_bextri_<mode>"
12791  [(set (match_operand:SWI48 0 "register_operand" "=r")
12792        (zero_extract:SWI48
12793          (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12794          (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12795          (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12796   (clobber (reg:CC FLAGS_REG))]
12797   "TARGET_TBM"
12798{
12799  operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12800  return "bextr\t{%2, %1, %0|%0, %1, %2}";
12801}
12802  [(set_attr "type" "bitmanip")
12803   (set_attr "mode" "<MODE>")])
12804
12805(define_insn "*tbm_blcfill_<mode>"
12806  [(set (match_operand:SWI48 0 "register_operand" "=r")
12807        (and:SWI48
12808          (plus:SWI48
12809            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12810            (const_int 1))
12811          (match_dup 1)))
12812   (clobber (reg:CC FLAGS_REG))]
12813   "TARGET_TBM"
12814   "blcfill\t{%1, %0|%0, %1}"
12815  [(set_attr "type" "bitmanip")
12816   (set_attr "mode" "<MODE>")])
12817
12818(define_insn "*tbm_blci_<mode>"
12819  [(set (match_operand:SWI48 0 "register_operand" "=r")
12820        (ior:SWI48
12821          (not:SWI48
12822            (plus:SWI48
12823              (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12824              (const_int 1)))
12825          (match_dup 1)))
12826   (clobber (reg:CC FLAGS_REG))]
12827   "TARGET_TBM"
12828   "blci\t{%1, %0|%0, %1}"
12829  [(set_attr "type" "bitmanip")
12830   (set_attr "mode" "<MODE>")])
12831
12832(define_insn "*tbm_blcic_<mode>"
12833  [(set (match_operand:SWI48 0 "register_operand" "=r")
12834        (and:SWI48
12835          (plus:SWI48
12836            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12837            (const_int 1))
12838          (not:SWI48
12839            (match_dup 1))))
12840   (clobber (reg:CC FLAGS_REG))]
12841   "TARGET_TBM"
12842   "blcic\t{%1, %0|%0, %1}"
12843  [(set_attr "type" "bitmanip")
12844   (set_attr "mode" "<MODE>")])
12845
12846(define_insn "*tbm_blcmsk_<mode>"
12847  [(set (match_operand:SWI48 0 "register_operand" "=r")
12848        (xor:SWI48
12849          (plus:SWI48
12850            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12851            (const_int 1))
12852          (match_dup 1)))
12853   (clobber (reg:CC FLAGS_REG))]
12854   "TARGET_TBM"
12855   "blcmsk\t{%1, %0|%0, %1}"
12856  [(set_attr "type" "bitmanip")
12857   (set_attr "mode" "<MODE>")])
12858
12859(define_insn "*tbm_blcs_<mode>"
12860  [(set (match_operand:SWI48 0 "register_operand" "=r")
12861        (ior:SWI48
12862          (plus:SWI48
12863            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12864            (const_int 1))
12865          (match_dup 1)))
12866   (clobber (reg:CC FLAGS_REG))]
12867   "TARGET_TBM"
12868   "blcs\t{%1, %0|%0, %1}"
12869  [(set_attr "type" "bitmanip")
12870   (set_attr "mode" "<MODE>")])
12871
12872(define_insn "*tbm_blsfill_<mode>"
12873  [(set (match_operand:SWI48 0 "register_operand" "=r")
12874        (ior:SWI48
12875          (plus:SWI48
12876            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12877            (const_int -1))
12878          (match_dup 1)))
12879   (clobber (reg:CC FLAGS_REG))]
12880   "TARGET_TBM"
12881   "blsfill\t{%1, %0|%0, %1}"
12882  [(set_attr "type" "bitmanip")
12883   (set_attr "mode" "<MODE>")])
12884
12885(define_insn "*tbm_blsic_<mode>"
12886  [(set (match_operand:SWI48 0 "register_operand" "=r")
12887        (ior:SWI48
12888          (plus:SWI48
12889            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12890            (const_int -1))
12891          (not:SWI48
12892            (match_dup 1))))
12893   (clobber (reg:CC FLAGS_REG))]
12894   "TARGET_TBM"
12895   "blsic\t{%1, %0|%0, %1}"
12896  [(set_attr "type" "bitmanip")
12897   (set_attr "mode" "<MODE>")])
12898
12899(define_insn "*tbm_t1mskc_<mode>"
12900  [(set (match_operand:SWI48 0 "register_operand" "=r")
12901        (ior:SWI48
12902          (plus:SWI48
12903            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12904            (const_int 1))
12905          (not:SWI48
12906            (match_dup 1))))
12907   (clobber (reg:CC FLAGS_REG))]
12908   "TARGET_TBM"
12909   "t1mskc\t{%1, %0|%0, %1}"
12910  [(set_attr "type" "bitmanip")
12911   (set_attr "mode" "<MODE>")])
12912
12913(define_insn "*tbm_tzmsk_<mode>"
12914  [(set (match_operand:SWI48 0 "register_operand" "=r")
12915        (and:SWI48
12916          (plus:SWI48
12917            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12918            (const_int -1))
12919          (not:SWI48
12920            (match_dup 1))))
12921   (clobber (reg:CC FLAGS_REG))]
12922   "TARGET_TBM"
12923   "tzmsk\t{%1, %0|%0, %1}"
12924  [(set_attr "type" "bitmanip")
12925   (set_attr "mode" "<MODE>")])
12926
12927(define_insn "bsr_rex64"
12928  [(set (match_operand:DI 0 "register_operand" "=r")
12929	(minus:DI (const_int 63)
12930		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12931   (clobber (reg:CC FLAGS_REG))]
12932  "TARGET_64BIT"
12933  "bsr{q}\t{%1, %0|%0, %1}"
12934  [(set_attr "type" "alu1")
12935   (set_attr "prefix_0f" "1")
12936   (set_attr "mode" "DI")])
12937
12938(define_insn "bsr"
12939  [(set (match_operand:SI 0 "register_operand" "=r")
12940	(minus:SI (const_int 31)
12941		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12942   (clobber (reg:CC FLAGS_REG))]
12943  ""
12944  "bsr{l}\t{%1, %0|%0, %1}"
12945  [(set_attr "type" "alu1")
12946   (set_attr "prefix_0f" "1")
12947   (set_attr "mode" "SI")])
12948
12949(define_insn "*bsrhi"
12950  [(set (match_operand:HI 0 "register_operand" "=r")
12951	(minus:HI (const_int 15)
12952		  (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12953   (clobber (reg:CC FLAGS_REG))]
12954  ""
12955  "bsr{w}\t{%1, %0|%0, %1}"
12956  [(set_attr "type" "alu1")
12957   (set_attr "prefix_0f" "1")
12958   (set_attr "mode" "HI")])
12959
12960(define_expand "popcount<mode>2"
12961  [(parallel
12962    [(set (match_operand:SWI248 0 "register_operand")
12963	  (popcount:SWI248
12964	    (match_operand:SWI248 1 "nonimmediate_operand")))
12965     (clobber (reg:CC FLAGS_REG))])]
12966  "TARGET_POPCNT")
12967
12968(define_insn_and_split "*popcount<mode>2_falsedep_1"
12969  [(set (match_operand:SWI48 0 "register_operand" "=r")
12970	(popcount:SWI48
12971	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12972   (clobber (reg:CC FLAGS_REG))]
12973  "TARGET_POPCNT
12974   && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12975  "#"
12976  "&& reload_completed"
12977  [(parallel
12978    [(set (match_dup 0)
12979	  (popcount:SWI48 (match_dup 1)))
12980     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12981     (clobber (reg:CC FLAGS_REG))])]
12982{
12983  if (!reg_mentioned_p (operands[0], operands[1]))
12984    ix86_expand_clear (operands[0]);
12985})
12986
12987(define_insn "*popcount<mode>2_falsedep"
12988  [(set (match_operand:SWI48 0 "register_operand" "=r")
12989	(popcount:SWI48
12990	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12991   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12992	   UNSPEC_INSN_FALSE_DEP)
12993   (clobber (reg:CC FLAGS_REG))]
12994  "TARGET_POPCNT"
12995{
12996#if TARGET_MACHO
12997  return "popcnt\t{%1, %0|%0, %1}";
12998#else
12999  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13000#endif
13001}
13002  [(set_attr "prefix_rep" "1")
13003   (set_attr "type" "bitmanip")
13004   (set_attr "mode" "<MODE>")])
13005
13006(define_insn "*popcount<mode>2"
13007  [(set (match_operand:SWI248 0 "register_operand" "=r")
13008	(popcount:SWI248
13009	  (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13010   (clobber (reg:CC FLAGS_REG))]
13011  "TARGET_POPCNT"
13012{
13013#if TARGET_MACHO
13014  return "popcnt\t{%1, %0|%0, %1}";
13015#else
13016  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13017#endif
13018}
13019  [(set_attr "prefix_rep" "1")
13020   (set_attr "type" "bitmanip")
13021   (set_attr "mode" "<MODE>")])
13022
13023(define_expand "bswapdi2"
13024  [(set (match_operand:DI 0 "register_operand")
13025	(bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13026  "TARGET_64BIT"
13027{
13028  if (!TARGET_MOVBE)
13029    operands[1] = force_reg (DImode, operands[1]);
13030})
13031
13032(define_expand "bswapsi2"
13033  [(set (match_operand:SI 0 "register_operand")
13034	(bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13035  ""
13036{
13037  if (TARGET_MOVBE)
13038    ;
13039  else if (TARGET_BSWAP)
13040    operands[1] = force_reg (SImode, operands[1]);
13041  else
13042    {
13043      rtx x = operands[0];
13044
13045      emit_move_insn (x, operands[1]);
13046      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13047      emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13048      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13049      DONE;
13050    }
13051})
13052
13053(define_insn "*bswap<mode>2_movbe"
13054  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13055	(bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13056  "TARGET_MOVBE
13057   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13058  "@
13059    bswap\t%0
13060    movbe\t{%1, %0|%0, %1}
13061    movbe\t{%1, %0|%0, %1}"
13062  [(set_attr "type" "bitmanip,imov,imov")
13063   (set_attr "modrm" "0,1,1")
13064   (set_attr "prefix_0f" "*,1,1")
13065   (set_attr "prefix_extra" "*,1,1")
13066   (set_attr "mode" "<MODE>")])
13067
13068(define_insn "*bswap<mode>2"
13069  [(set (match_operand:SWI48 0 "register_operand" "=r")
13070	(bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13071  "TARGET_BSWAP"
13072  "bswap\t%0"
13073  [(set_attr "type" "bitmanip")
13074   (set_attr "modrm" "0")
13075   (set_attr "mode" "<MODE>")])
13076
13077(define_insn "*bswaphi_lowpart_1"
13078  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13079	(bswap:HI (match_dup 0)))
13080   (clobber (reg:CC FLAGS_REG))]
13081  "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13082  "@
13083    xchg{b}\t{%h0, %b0|%b0, %h0}
13084    rol{w}\t{$8, %0|%0, 8}"
13085  [(set_attr "length" "2,4")
13086   (set_attr "mode" "QI,HI")])
13087
13088(define_insn "bswaphi_lowpart"
13089  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13090	(bswap:HI (match_dup 0)))
13091   (clobber (reg:CC FLAGS_REG))]
13092  ""
13093  "rol{w}\t{$8, %0|%0, 8}"
13094  [(set_attr "length" "4")
13095   (set_attr "mode" "HI")])
13096
13097(define_expand "paritydi2"
13098  [(set (match_operand:DI 0 "register_operand")
13099	(parity:DI (match_operand:DI 1 "register_operand")))]
13100  "! TARGET_POPCNT"
13101{
13102  rtx scratch = gen_reg_rtx (QImode);
13103  rtx cond;
13104
13105  emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13106				NULL_RTX, operands[1]));
13107
13108  cond = gen_rtx_fmt_ee (ORDERED, QImode,
13109			 gen_rtx_REG (CCmode, FLAGS_REG),
13110			 const0_rtx);
13111  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13112
13113  if (TARGET_64BIT)
13114    emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13115  else
13116    {
13117      rtx tmp = gen_reg_rtx (SImode);
13118
13119      emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13120      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13121    }
13122  DONE;
13123})
13124
13125(define_expand "paritysi2"
13126  [(set (match_operand:SI 0 "register_operand")
13127	(parity:SI (match_operand:SI 1 "register_operand")))]
13128  "! TARGET_POPCNT"
13129{
13130  rtx scratch = gen_reg_rtx (QImode);
13131  rtx cond;
13132
13133  emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13134
13135  cond = gen_rtx_fmt_ee (ORDERED, QImode,
13136			 gen_rtx_REG (CCmode, FLAGS_REG),
13137			 const0_rtx);
13138  emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
13139
13140  emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13141  DONE;
13142})
13143
13144(define_insn_and_split "paritydi2_cmp"
13145  [(set (reg:CC FLAGS_REG)
13146	(unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13147		   UNSPEC_PARITY))
13148   (clobber (match_scratch:DI 0 "=r"))
13149   (clobber (match_scratch:SI 1 "=&r"))
13150   (clobber (match_scratch:HI 2 "=Q"))]
13151  "! TARGET_POPCNT"
13152  "#"
13153  "&& reload_completed"
13154  [(parallel
13155     [(set (match_dup 1)
13156	   (xor:SI (match_dup 1) (match_dup 4)))
13157      (clobber (reg:CC FLAGS_REG))])
13158   (parallel
13159     [(set (reg:CC FLAGS_REG)
13160	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13161      (clobber (match_dup 1))
13162      (clobber (match_dup 2))])]
13163{
13164  operands[4] = gen_lowpart (SImode, operands[3]);
13165
13166  if (TARGET_64BIT)
13167    {
13168      emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13169      emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13170    }
13171  else
13172    operands[1] = gen_highpart (SImode, operands[3]);
13173})
13174
13175(define_insn_and_split "paritysi2_cmp"
13176  [(set (reg:CC FLAGS_REG)
13177	(unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13178		   UNSPEC_PARITY))
13179   (clobber (match_scratch:SI 0 "=r"))
13180   (clobber (match_scratch:HI 1 "=&Q"))]
13181  "! TARGET_POPCNT"
13182  "#"
13183  "&& reload_completed"
13184  [(parallel
13185     [(set (match_dup 1)
13186	   (xor:HI (match_dup 1) (match_dup 3)))
13187      (clobber (reg:CC FLAGS_REG))])
13188   (parallel
13189     [(set (reg:CC FLAGS_REG)
13190	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13191      (clobber (match_dup 1))])]
13192{
13193  operands[3] = gen_lowpart (HImode, operands[2]);
13194
13195  emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13196  emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13197})
13198
13199(define_insn "*parityhi2_cmp"
13200  [(set (reg:CC FLAGS_REG)
13201	(unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13202		   UNSPEC_PARITY))
13203   (clobber (match_scratch:HI 0 "=Q"))]
13204  "! TARGET_POPCNT"
13205  "xor{b}\t{%h0, %b0|%b0, %h0}"
13206  [(set_attr "length" "2")
13207   (set_attr "mode" "HI")])
13208
13209
13210;; Thread-local storage patterns for ELF.
13211;;
13212;; Note that these code sequences must appear exactly as shown
13213;; in order to allow linker relaxation.
13214
13215(define_insn "*tls_global_dynamic_32_gnu"
13216  [(set (match_operand:SI 0 "register_operand" "=a")
13217	(unspec:SI
13218	 [(match_operand:SI 1 "register_operand" "b")
13219	  (match_operand 2 "tls_symbolic_operand")
13220	  (match_operand 3 "constant_call_address_operand" "Bz")
13221	  (reg:SI SP_REG)]
13222	 UNSPEC_TLS_GD))
13223   (clobber (match_scratch:SI 4 "=d"))
13224   (clobber (match_scratch:SI 5 "=c"))
13225   (clobber (reg:CC FLAGS_REG))]
13226  "!TARGET_64BIT && TARGET_GNU_TLS"
13227{
13228  output_asm_insn
13229    ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13230  if (TARGET_SUN_TLS)
13231#ifdef HAVE_AS_IX86_TLSGDPLT
13232    return "call\t%a2@tlsgdplt";
13233#else
13234    return "call\t%p3@plt";
13235#endif
13236  return "call\t%P3";
13237}
13238  [(set_attr "type" "multi")
13239   (set_attr "length" "12")])
13240
13241(define_expand "tls_global_dynamic_32"
13242  [(parallel
13243    [(set (match_operand:SI 0 "register_operand")
13244	  (unspec:SI [(match_operand:SI 2 "register_operand")
13245		      (match_operand 1 "tls_symbolic_operand")
13246		      (match_operand 3 "constant_call_address_operand")
13247		      (reg:SI SP_REG)]
13248		     UNSPEC_TLS_GD))
13249     (clobber (match_scratch:SI 4))
13250     (clobber (match_scratch:SI 5))
13251     (clobber (reg:CC FLAGS_REG))])]
13252  ""
13253  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13254
13255(define_insn "*tls_global_dynamic_64_<mode>"
13256  [(set (match_operand:P 0 "register_operand" "=a")
13257	(call:P
13258	 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13259	 (match_operand 3)))
13260   (unspec:P [(match_operand 1 "tls_symbolic_operand")
13261	      (reg:P SP_REG)]
13262	     UNSPEC_TLS_GD)]
13263  "TARGET_64BIT"
13264{
13265  if (!TARGET_X32)
13266    fputs (ASM_BYTE "0x66\n", asm_out_file);
13267  output_asm_insn
13268    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13269  fputs (ASM_SHORT "0x6666\n", asm_out_file);
13270  fputs ("\trex64\n", asm_out_file);
13271  if (TARGET_SUN_TLS)
13272    return "call\t%p2@plt";
13273  return "call\t%P2";
13274}
13275  [(set_attr "type" "multi")
13276   (set (attr "length")
13277	(symbol_ref "TARGET_X32 ? 15 : 16"))])
13278
13279(define_insn "*tls_global_dynamic_64_largepic"
13280  [(set (match_operand:DI 0 "register_operand" "=a")
13281	(call:DI
13282	 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13283			  (match_operand:DI 3 "immediate_operand" "i")))
13284	 (match_operand 4)))
13285   (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13286	       (reg:DI SP_REG)]
13287	      UNSPEC_TLS_GD)]
13288  "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13289   && GET_CODE (operands[3]) == CONST
13290   && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13291   && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13292{
13293  output_asm_insn
13294    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13295  output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13296  output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13297  return "call\t{*%%rax|rax}";
13298}
13299  [(set_attr "type" "multi")
13300   (set_attr "length" "22")])
13301
13302(define_expand "tls_global_dynamic_64_<mode>"
13303  [(parallel
13304    [(set (match_operand:P 0 "register_operand")
13305	  (call:P
13306	   (mem:QI (match_operand 2))
13307	   (const_int 0)))
13308     (unspec:P [(match_operand 1 "tls_symbolic_operand")
13309		(reg:P SP_REG)]
13310	       UNSPEC_TLS_GD)])]
13311  "TARGET_64BIT"
13312  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13313
13314(define_insn "*tls_local_dynamic_base_32_gnu"
13315  [(set (match_operand:SI 0 "register_operand" "=a")
13316	(unspec:SI
13317	 [(match_operand:SI 1 "register_operand" "b")
13318	  (match_operand 2 "constant_call_address_operand" "Bz")
13319	  (reg:SI SP_REG)]
13320	 UNSPEC_TLS_LD_BASE))
13321   (clobber (match_scratch:SI 3 "=d"))
13322   (clobber (match_scratch:SI 4 "=c"))
13323   (clobber (reg:CC FLAGS_REG))]
13324  "!TARGET_64BIT && TARGET_GNU_TLS"
13325{
13326  output_asm_insn
13327    ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13328  if (TARGET_SUN_TLS)
13329    {
13330      if (HAVE_AS_IX86_TLSLDMPLT)
13331	return "call\t%&@tlsldmplt";
13332      else
13333	return "call\t%p2@plt";
13334    }
13335  return "call\t%P2";
13336}
13337  [(set_attr "type" "multi")
13338   (set_attr "length" "11")])
13339
13340(define_expand "tls_local_dynamic_base_32"
13341  [(parallel
13342     [(set (match_operand:SI 0 "register_operand")
13343	   (unspec:SI
13344	    [(match_operand:SI 1 "register_operand")
13345	     (match_operand 2 "constant_call_address_operand")
13346	     (reg:SI SP_REG)]
13347	    UNSPEC_TLS_LD_BASE))
13348      (clobber (match_scratch:SI 3))
13349      (clobber (match_scratch:SI 4))
13350      (clobber (reg:CC FLAGS_REG))])]
13351  ""
13352  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13353
13354(define_insn "*tls_local_dynamic_base_64_<mode>"
13355  [(set (match_operand:P 0 "register_operand" "=a")
13356	(call:P
13357	 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13358	 (match_operand 2)))
13359   (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13360  "TARGET_64BIT"
13361{
13362  output_asm_insn
13363    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13364  if (TARGET_SUN_TLS)
13365    return "call\t%p1@plt";
13366  return "call\t%P1";
13367}
13368  [(set_attr "type" "multi")
13369   (set_attr "length" "12")])
13370
13371(define_insn "*tls_local_dynamic_base_64_largepic"
13372  [(set (match_operand:DI 0 "register_operand" "=a")
13373	(call:DI
13374	 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13375			  (match_operand:DI 2 "immediate_operand" "i")))
13376	 (match_operand 3)))
13377   (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13378  "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13379   && GET_CODE (operands[2]) == CONST
13380   && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13381   && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13382{
13383  output_asm_insn
13384    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13385  output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13386  output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13387  return "call\t{*%%rax|rax}";
13388}
13389  [(set_attr "type" "multi")
13390   (set_attr "length" "22")])
13391
13392(define_expand "tls_local_dynamic_base_64_<mode>"
13393  [(parallel
13394     [(set (match_operand:P 0 "register_operand")
13395	   (call:P
13396	    (mem:QI (match_operand 1))
13397	    (const_int 0)))
13398      (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13399  "TARGET_64BIT"
13400  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13401
13402;; Local dynamic of a single variable is a lose.  Show combine how
13403;; to convert that back to global dynamic.
13404
13405(define_insn_and_split "*tls_local_dynamic_32_once"
13406  [(set (match_operand:SI 0 "register_operand" "=a")
13407	(plus:SI
13408	 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13409		     (match_operand 2 "constant_call_address_operand" "Bz")
13410		     (reg:SI SP_REG)]
13411		    UNSPEC_TLS_LD_BASE)
13412	 (const:SI (unspec:SI
13413		    [(match_operand 3 "tls_symbolic_operand")]
13414		    UNSPEC_DTPOFF))))
13415   (clobber (match_scratch:SI 4 "=d"))
13416   (clobber (match_scratch:SI 5 "=c"))
13417   (clobber (reg:CC FLAGS_REG))]
13418  ""
13419  "#"
13420  ""
13421  [(parallel
13422     [(set (match_dup 0)
13423	   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13424		       (reg:SI SP_REG)]
13425		      UNSPEC_TLS_GD))
13426      (clobber (match_dup 4))
13427      (clobber (match_dup 5))
13428      (clobber (reg:CC FLAGS_REG))])])
13429
13430;; Segment register for the thread base ptr load
13431(define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13432
13433;; Load and add the thread base pointer from %<tp_seg>:0.
13434(define_insn "*load_tp_x32"
13435  [(set (match_operand:SI 0 "register_operand" "=r")
13436	(unspec:SI [(const_int 0)] UNSPEC_TP))]
13437  "TARGET_X32"
13438  "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13439  [(set_attr "type" "imov")
13440   (set_attr "modrm" "0")
13441   (set_attr "length" "7")
13442   (set_attr "memory" "load")
13443   (set_attr "imm_disp" "false")])
13444
13445(define_insn "*load_tp_x32_zext"
13446  [(set (match_operand:DI 0 "register_operand" "=r")
13447	(zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13448  "TARGET_X32"
13449  "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13450  [(set_attr "type" "imov")
13451   (set_attr "modrm" "0")
13452   (set_attr "length" "7")
13453   (set_attr "memory" "load")
13454   (set_attr "imm_disp" "false")])
13455
13456(define_insn "*load_tp_<mode>"
13457  [(set (match_operand:P 0 "register_operand" "=r")
13458	(unspec:P [(const_int 0)] UNSPEC_TP))]
13459  "!TARGET_X32"
13460  "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13461  [(set_attr "type" "imov")
13462   (set_attr "modrm" "0")
13463   (set_attr "length" "7")
13464   (set_attr "memory" "load")
13465   (set_attr "imm_disp" "false")])
13466
13467(define_insn "*add_tp_x32"
13468  [(set (match_operand:SI 0 "register_operand" "=r")
13469	(plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13470		 (match_operand:SI 1 "register_operand" "0")))
13471   (clobber (reg:CC FLAGS_REG))]
13472  "TARGET_X32"
13473  "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13474  [(set_attr "type" "alu")
13475   (set_attr "modrm" "0")
13476   (set_attr "length" "7")
13477   (set_attr "memory" "load")
13478   (set_attr "imm_disp" "false")])
13479
13480(define_insn "*add_tp_x32_zext"
13481  [(set (match_operand:DI 0 "register_operand" "=r")
13482	(zero_extend:DI
13483	  (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13484		   (match_operand:SI 1 "register_operand" "0"))))
13485   (clobber (reg:CC FLAGS_REG))]
13486  "TARGET_X32"
13487  "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13488  [(set_attr "type" "alu")
13489   (set_attr "modrm" "0")
13490   (set_attr "length" "7")
13491   (set_attr "memory" "load")
13492   (set_attr "imm_disp" "false")])
13493
13494(define_insn "*add_tp_<mode>"
13495  [(set (match_operand:P 0 "register_operand" "=r")
13496	(plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13497		(match_operand:P 1 "register_operand" "0")))
13498   (clobber (reg:CC FLAGS_REG))]
13499  "!TARGET_X32"
13500  "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13501  [(set_attr "type" "alu")
13502   (set_attr "modrm" "0")
13503   (set_attr "length" "7")
13504   (set_attr "memory" "load")
13505   (set_attr "imm_disp" "false")])
13506
13507;; The Sun linker took the AMD64 TLS spec literally and can only handle
13508;; %rax as destination of the initial executable code sequence.
13509(define_insn "tls_initial_exec_64_sun"
13510  [(set (match_operand:DI 0 "register_operand" "=a")
13511	(unspec:DI
13512	 [(match_operand 1 "tls_symbolic_operand")]
13513	 UNSPEC_TLS_IE_SUN))
13514   (clobber (reg:CC FLAGS_REG))]
13515  "TARGET_64BIT && TARGET_SUN_TLS"
13516{
13517  output_asm_insn
13518    ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13519  return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13520}
13521  [(set_attr "type" "multi")])
13522
13523;; GNU2 TLS patterns can be split.
13524
13525(define_expand "tls_dynamic_gnu2_32"
13526  [(set (match_dup 3)
13527	(plus:SI (match_operand:SI 2 "register_operand")
13528		 (const:SI
13529		  (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13530			     UNSPEC_TLSDESC))))
13531   (parallel
13532    [(set (match_operand:SI 0 "register_operand")
13533	  (unspec:SI [(match_dup 1) (match_dup 3)
13534		      (match_dup 2) (reg:SI SP_REG)]
13535		      UNSPEC_TLSDESC))
13536     (clobber (reg:CC FLAGS_REG))])]
13537  "!TARGET_64BIT && TARGET_GNU2_TLS"
13538{
13539  operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13540  ix86_tls_descriptor_calls_expanded_in_cfun = true;
13541})
13542
13543(define_insn "*tls_dynamic_gnu2_lea_32"
13544  [(set (match_operand:SI 0 "register_operand" "=r")
13545	(plus:SI (match_operand:SI 1 "register_operand" "b")
13546		 (const:SI
13547		  (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13548			      UNSPEC_TLSDESC))))]
13549  "!TARGET_64BIT && TARGET_GNU2_TLS"
13550  "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13551  [(set_attr "type" "lea")
13552   (set_attr "mode" "SI")
13553   (set_attr "length" "6")
13554   (set_attr "length_address" "4")])
13555
13556(define_insn "*tls_dynamic_gnu2_call_32"
13557  [(set (match_operand:SI 0 "register_operand" "=a")
13558	(unspec:SI [(match_operand 1 "tls_symbolic_operand")
13559		    (match_operand:SI 2 "register_operand" "0")
13560		    ;; we have to make sure %ebx still points to the GOT
13561		    (match_operand:SI 3 "register_operand" "b")
13562		    (reg:SI SP_REG)]
13563		   UNSPEC_TLSDESC))
13564   (clobber (reg:CC FLAGS_REG))]
13565  "!TARGET_64BIT && TARGET_GNU2_TLS"
13566  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13567  [(set_attr "type" "call")
13568   (set_attr "length" "2")
13569   (set_attr "length_address" "0")])
13570
13571(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13572  [(set (match_operand:SI 0 "register_operand" "=&a")
13573	(plus:SI
13574	 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13575		     (match_operand:SI 4)
13576		     (match_operand:SI 2 "register_operand" "b")
13577		     (reg:SI SP_REG)]
13578		    UNSPEC_TLSDESC)
13579	 (const:SI (unspec:SI
13580		    [(match_operand 1 "tls_symbolic_operand")]
13581		    UNSPEC_DTPOFF))))
13582   (clobber (reg:CC FLAGS_REG))]
13583  "!TARGET_64BIT && TARGET_GNU2_TLS"
13584  "#"
13585  ""
13586  [(set (match_dup 0) (match_dup 5))]
13587{
13588  operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13589  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13590})
13591
13592(define_expand "tls_dynamic_gnu2_64"
13593  [(set (match_dup 2)
13594	(unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13595		   UNSPEC_TLSDESC))
13596   (parallel
13597    [(set (match_operand:DI 0 "register_operand")
13598	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13599		     UNSPEC_TLSDESC))
13600     (clobber (reg:CC FLAGS_REG))])]
13601  "TARGET_64BIT && TARGET_GNU2_TLS"
13602{
13603  operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13604  ix86_tls_descriptor_calls_expanded_in_cfun = true;
13605})
13606
13607(define_insn "*tls_dynamic_gnu2_lea_64"
13608  [(set (match_operand:DI 0 "register_operand" "=r")
13609	(unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13610		   UNSPEC_TLSDESC))]
13611  "TARGET_64BIT && TARGET_GNU2_TLS"
13612  "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13613  [(set_attr "type" "lea")
13614   (set_attr "mode" "DI")
13615   (set_attr "length" "7")
13616   (set_attr "length_address" "4")])
13617
13618(define_insn "*tls_dynamic_gnu2_call_64"
13619  [(set (match_operand:DI 0 "register_operand" "=a")
13620	(unspec:DI [(match_operand 1 "tls_symbolic_operand")
13621		    (match_operand:DI 2 "register_operand" "0")
13622		    (reg:DI SP_REG)]
13623		   UNSPEC_TLSDESC))
13624   (clobber (reg:CC FLAGS_REG))]
13625  "TARGET_64BIT && TARGET_GNU2_TLS"
13626  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13627  [(set_attr "type" "call")
13628   (set_attr "length" "2")
13629   (set_attr "length_address" "0")])
13630
13631(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13632  [(set (match_operand:DI 0 "register_operand" "=&a")
13633	(plus:DI
13634	 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13635		     (match_operand:DI 3)
13636		     (reg:DI SP_REG)]
13637		    UNSPEC_TLSDESC)
13638	 (const:DI (unspec:DI
13639		    [(match_operand 1 "tls_symbolic_operand")]
13640		    UNSPEC_DTPOFF))))
13641   (clobber (reg:CC FLAGS_REG))]
13642  "TARGET_64BIT && TARGET_GNU2_TLS"
13643  "#"
13644  ""
13645  [(set (match_dup 0) (match_dup 4))]
13646{
13647  operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13648  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13649})
13650
13651;; These patterns match the binary 387 instructions for addM3, subM3,
13652;; mulM3 and divM3.  There are three patterns for each of DFmode and
13653;; SFmode.  The first is the normal insn, the second the same insn but
13654;; with one operand a conversion, and the third the same insn but with
13655;; the other operand a conversion.  The conversion may be SFmode or
13656;; SImode if the target mode DFmode, but only SImode if the target mode
13657;; is SFmode.
13658
13659;; Gcc is slightly more smart about handling normal two address instructions
13660;; so use special patterns for add and mull.
13661
13662(define_insn "*fop_<mode>_comm_mixed"
13663  [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13664	(match_operator:MODEF 3 "binary_fp_operator"
13665	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13666	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13667  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13668   && COMMUTATIVE_ARITH_P (operands[3])
13669   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13670  "* return output_387_binary_op (insn, operands);"
13671  [(set (attr "type")
13672	(if_then_else (eq_attr "alternative" "1,2")
13673	   (if_then_else (match_operand:MODEF 3 "mult_operator")
13674	      (const_string "ssemul")
13675	      (const_string "sseadd"))
13676	   (if_then_else (match_operand:MODEF 3 "mult_operator")
13677	      (const_string "fmul")
13678	      (const_string "fop"))))
13679   (set_attr "isa" "*,noavx,avx")
13680   (set_attr "prefix" "orig,orig,vex")
13681   (set_attr "mode" "<MODE>")])
13682
13683(define_insn "*fop_<mode>_comm_sse"
13684  [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13685	(match_operator:MODEF 3 "binary_fp_operator"
13686	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13687	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13688  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13689   && COMMUTATIVE_ARITH_P (operands[3])
13690   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13691  "* return output_387_binary_op (insn, operands);"
13692  [(set (attr "type")
13693        (if_then_else (match_operand:MODEF 3 "mult_operator")
13694	   (const_string "ssemul")
13695	   (const_string "sseadd")))
13696   (set_attr "isa" "noavx,avx")
13697   (set_attr "prefix" "orig,vex")
13698   (set_attr "mode" "<MODE>")])
13699
13700(define_insn "*fop_<mode>_comm_i387"
13701  [(set (match_operand:MODEF 0 "register_operand" "=f")
13702	(match_operator:MODEF 3 "binary_fp_operator"
13703	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13704	   (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13705  "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13706   && COMMUTATIVE_ARITH_P (operands[3])
13707   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13708  "* return output_387_binary_op (insn, operands);"
13709  [(set (attr "type")
13710	(if_then_else (match_operand:MODEF 3 "mult_operator")
13711	   (const_string "fmul")
13712	   (const_string "fop")))
13713   (set_attr "mode" "<MODE>")])
13714
13715(define_insn "*fop_<mode>_1_mixed"
13716  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13717	(match_operator:MODEF 3 "binary_fp_operator"
13718	  [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13719	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13720  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13721   && !COMMUTATIVE_ARITH_P (operands[3])
13722   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13723  "* return output_387_binary_op (insn, operands);"
13724  [(set (attr "type")
13725        (cond [(and (eq_attr "alternative" "2,3")
13726	            (match_operand:MODEF 3 "mult_operator"))
13727                 (const_string "ssemul")
13728	       (and (eq_attr "alternative" "2,3")
13729	            (match_operand:MODEF 3 "div_operator"))
13730                 (const_string "ssediv")
13731	       (eq_attr "alternative" "2,3")
13732                 (const_string "sseadd")
13733	       (match_operand:MODEF 3 "mult_operator")
13734                 (const_string "fmul")
13735               (match_operand:MODEF 3 "div_operator")
13736                 (const_string "fdiv")
13737              ]
13738              (const_string "fop")))
13739   (set_attr "isa" "*,*,noavx,avx")
13740   (set_attr "prefix" "orig,orig,orig,vex")
13741   (set_attr "mode" "<MODE>")])
13742
13743(define_insn "*rcpsf2_sse"
13744  [(set (match_operand:SF 0 "register_operand" "=x")
13745	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13746		   UNSPEC_RCP))]
13747  "TARGET_SSE_MATH"
13748  "%vrcpss\t{%1, %d0|%d0, %1}"
13749  [(set_attr "type" "sse")
13750   (set_attr "atom_sse_attr" "rcp")
13751   (set_attr "btver2_sse_attr" "rcp")
13752   (set_attr "prefix" "maybe_vex")
13753   (set_attr "mode" "SF")])
13754
13755(define_insn "*fop_<mode>_1_sse"
13756  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13757	(match_operator:MODEF 3 "binary_fp_operator"
13758	  [(match_operand:MODEF 1 "register_operand" "0,x")
13759	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13760  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13761   && !COMMUTATIVE_ARITH_P (operands[3])"
13762  "* return output_387_binary_op (insn, operands);"
13763  [(set (attr "type")
13764        (cond [(match_operand:MODEF 3 "mult_operator")
13765                 (const_string "ssemul")
13766	       (match_operand:MODEF 3 "div_operator")
13767                 (const_string "ssediv")
13768              ]
13769              (const_string "sseadd")))
13770   (set_attr "isa" "noavx,avx")
13771   (set_attr "prefix" "orig,vex")
13772   (set_attr "mode" "<MODE>")])
13773
13774;; This pattern is not fully shadowed by the pattern above.
13775(define_insn "*fop_<mode>_1_i387"
13776  [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13777	(match_operator:MODEF 3 "binary_fp_operator"
13778	  [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13779	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13780  "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13781   && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13782   && !COMMUTATIVE_ARITH_P (operands[3])
13783   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13784  "* return output_387_binary_op (insn, operands);"
13785  [(set (attr "type")
13786        (cond [(match_operand:MODEF 3 "mult_operator")
13787                 (const_string "fmul")
13788               (match_operand:MODEF 3 "div_operator")
13789                 (const_string "fdiv")
13790              ]
13791              (const_string "fop")))
13792   (set_attr "mode" "<MODE>")])
13793
13794;; ??? Add SSE splitters for these!
13795(define_insn "*fop_<MODEF:mode>_2_i387"
13796  [(set (match_operand:MODEF 0 "register_operand" "=f")
13797	(match_operator:MODEF 3 "binary_fp_operator"
13798	  [(float:MODEF
13799	     (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13800	   (match_operand:MODEF 2 "register_operand" "0")]))]
13801  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13802   && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13803   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13804       || optimize_function_for_size_p (cfun))"
13805  { return output_387_binary_op (insn, operands); }
13806  [(set (attr "type")
13807        (cond [(match_operand:MODEF 3 "mult_operator")
13808                 (const_string "fmul")
13809               (match_operand:MODEF 3 "div_operator")
13810                 (const_string "fdiv")
13811              ]
13812              (const_string "fop")))
13813   (set_attr "fp_int_src" "true")
13814   (set_attr "mode" "<SWI24:MODE>")])
13815
13816(define_insn "*fop_<MODEF:mode>_3_i387"
13817  [(set (match_operand:MODEF 0 "register_operand" "=f")
13818	(match_operator:MODEF 3 "binary_fp_operator"
13819	  [(match_operand:MODEF 1 "register_operand" "0")
13820	   (float:MODEF
13821	     (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13822  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13823   && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13824   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13825       || optimize_function_for_size_p (cfun))"
13826  { return output_387_binary_op (insn, operands); }
13827  [(set (attr "type")
13828        (cond [(match_operand:MODEF 3 "mult_operator")
13829                 (const_string "fmul")
13830               (match_operand:MODEF 3 "div_operator")
13831                 (const_string "fdiv")
13832              ]
13833              (const_string "fop")))
13834   (set_attr "fp_int_src" "true")
13835   (set_attr "mode" "<MODE>")])
13836
13837(define_insn "*fop_df_4_i387"
13838  [(set (match_operand:DF 0 "register_operand" "=f,f")
13839	(match_operator:DF 3 "binary_fp_operator"
13840	   [(float_extend:DF
13841	     (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13842	    (match_operand:DF 2 "register_operand" "0,f")]))]
13843  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13844   && !(TARGET_SSE2 && TARGET_SSE_MATH)
13845   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13846  "* return output_387_binary_op (insn, operands);"
13847  [(set (attr "type")
13848        (cond [(match_operand:DF 3 "mult_operator")
13849                 (const_string "fmul")
13850               (match_operand:DF 3 "div_operator")
13851                 (const_string "fdiv")
13852              ]
13853              (const_string "fop")))
13854   (set_attr "mode" "SF")])
13855
13856(define_insn "*fop_df_5_i387"
13857  [(set (match_operand:DF 0 "register_operand" "=f,f")
13858	(match_operator:DF 3 "binary_fp_operator"
13859	  [(match_operand:DF 1 "register_operand" "0,f")
13860	   (float_extend:DF
13861	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13862  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13863   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13864  "* return output_387_binary_op (insn, operands);"
13865  [(set (attr "type")
13866        (cond [(match_operand:DF 3 "mult_operator")
13867                 (const_string "fmul")
13868               (match_operand:DF 3 "div_operator")
13869                 (const_string "fdiv")
13870              ]
13871              (const_string "fop")))
13872   (set_attr "mode" "SF")])
13873
13874(define_insn "*fop_df_6_i387"
13875  [(set (match_operand:DF 0 "register_operand" "=f,f")
13876	(match_operator:DF 3 "binary_fp_operator"
13877	  [(float_extend:DF
13878	    (match_operand:SF 1 "register_operand" "0,f"))
13879	   (float_extend:DF
13880	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13881  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13882   && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13883  "* return output_387_binary_op (insn, operands);"
13884  [(set (attr "type")
13885        (cond [(match_operand:DF 3 "mult_operator")
13886                 (const_string "fmul")
13887               (match_operand:DF 3 "div_operator")
13888                 (const_string "fdiv")
13889              ]
13890              (const_string "fop")))
13891   (set_attr "mode" "SF")])
13892
13893(define_insn "*fop_xf_comm_i387"
13894  [(set (match_operand:XF 0 "register_operand" "=f")
13895	(match_operator:XF 3 "binary_fp_operator"
13896			[(match_operand:XF 1 "register_operand" "%0")
13897			 (match_operand:XF 2 "register_operand" "f")]))]
13898  "TARGET_80387
13899   && COMMUTATIVE_ARITH_P (operands[3])"
13900  "* return output_387_binary_op (insn, operands);"
13901  [(set (attr "type")
13902        (if_then_else (match_operand:XF 3 "mult_operator")
13903           (const_string "fmul")
13904           (const_string "fop")))
13905   (set_attr "mode" "XF")])
13906
13907(define_insn "*fop_xf_1_i387"
13908  [(set (match_operand:XF 0 "register_operand" "=f,f")
13909	(match_operator:XF 3 "binary_fp_operator"
13910			[(match_operand:XF 1 "register_operand" "0,f")
13911			 (match_operand:XF 2 "register_operand" "f,0")]))]
13912  "TARGET_80387
13913   && !COMMUTATIVE_ARITH_P (operands[3])"
13914  "* return output_387_binary_op (insn, operands);"
13915  [(set (attr "type")
13916        (cond [(match_operand:XF 3 "mult_operator")
13917                 (const_string "fmul")
13918               (match_operand:XF 3 "div_operator")
13919                 (const_string "fdiv")
13920              ]
13921              (const_string "fop")))
13922   (set_attr "mode" "XF")])
13923
13924(define_insn "*fop_xf_2_i387"
13925  [(set (match_operand:XF 0 "register_operand" "=f")
13926	(match_operator:XF 3 "binary_fp_operator"
13927	  [(float:XF
13928	     (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13929	   (match_operand:XF 2 "register_operand" "0")]))]
13930  "TARGET_80387
13931   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13932  { return output_387_binary_op (insn, operands); }
13933  [(set (attr "type")
13934        (cond [(match_operand:XF 3 "mult_operator")
13935                 (const_string "fmul")
13936               (match_operand:XF 3 "div_operator")
13937                 (const_string "fdiv")
13938              ]
13939              (const_string "fop")))
13940   (set_attr "fp_int_src" "true")
13941   (set_attr "mode" "<MODE>")])
13942
13943(define_insn "*fop_xf_3_i387"
13944  [(set (match_operand:XF 0 "register_operand" "=f")
13945	(match_operator:XF 3 "binary_fp_operator"
13946	  [(match_operand:XF 1 "register_operand" "0")
13947	   (float:XF
13948	     (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13949  "TARGET_80387
13950   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13951  { return output_387_binary_op (insn, operands); }
13952  [(set (attr "type")
13953        (cond [(match_operand:XF 3 "mult_operator")
13954                 (const_string "fmul")
13955               (match_operand:XF 3 "div_operator")
13956                 (const_string "fdiv")
13957              ]
13958              (const_string "fop")))
13959   (set_attr "fp_int_src" "true")
13960   (set_attr "mode" "<MODE>")])
13961
13962(define_insn "*fop_xf_4_i387"
13963  [(set (match_operand:XF 0 "register_operand" "=f,f")
13964	(match_operator:XF 3 "binary_fp_operator"
13965	   [(float_extend:XF
13966	      (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13967	    (match_operand:XF 2 "register_operand" "0,f")]))]
13968  "TARGET_80387"
13969  "* return output_387_binary_op (insn, operands);"
13970  [(set (attr "type")
13971        (cond [(match_operand:XF 3 "mult_operator")
13972                 (const_string "fmul")
13973               (match_operand:XF 3 "div_operator")
13974                 (const_string "fdiv")
13975              ]
13976              (const_string "fop")))
13977   (set_attr "mode" "<MODE>")])
13978
13979(define_insn "*fop_xf_5_i387"
13980  [(set (match_operand:XF 0 "register_operand" "=f,f")
13981	(match_operator:XF 3 "binary_fp_operator"
13982	  [(match_operand:XF 1 "register_operand" "0,f")
13983	   (float_extend:XF
13984	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13985  "TARGET_80387"
13986  "* return output_387_binary_op (insn, operands);"
13987  [(set (attr "type")
13988        (cond [(match_operand:XF 3 "mult_operator")
13989                 (const_string "fmul")
13990               (match_operand:XF 3 "div_operator")
13991                 (const_string "fdiv")
13992              ]
13993              (const_string "fop")))
13994   (set_attr "mode" "<MODE>")])
13995
13996(define_insn "*fop_xf_6_i387"
13997  [(set (match_operand:XF 0 "register_operand" "=f,f")
13998	(match_operator:XF 3 "binary_fp_operator"
13999	  [(float_extend:XF
14000	     (match_operand:MODEF 1 "register_operand" "0,f"))
14001	   (float_extend:XF
14002	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14003  "TARGET_80387"
14004  "* return output_387_binary_op (insn, operands);"
14005  [(set (attr "type")
14006        (cond [(match_operand:XF 3 "mult_operator")
14007                 (const_string "fmul")
14008               (match_operand:XF 3 "div_operator")
14009                 (const_string "fdiv")
14010              ]
14011              (const_string "fop")))
14012   (set_attr "mode" "<MODE>")])
14013
14014;; FPU special functions.
14015
14016;; This pattern implements a no-op XFmode truncation for
14017;; all fancy i386 XFmode math functions.
14018
14019(define_insn "truncxf<mode>2_i387_noop_unspec"
14020  [(set (match_operand:MODEF 0 "register_operand" "=f")
14021	(unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14022	UNSPEC_TRUNC_NOOP))]
14023  "TARGET_USE_FANCY_MATH_387"
14024  "* return output_387_reg_move (insn, operands);"
14025  [(set_attr "type" "fmov")
14026   (set_attr "mode" "<MODE>")])
14027
14028(define_insn "sqrtxf2"
14029  [(set (match_operand:XF 0 "register_operand" "=f")
14030	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14031  "TARGET_USE_FANCY_MATH_387"
14032  "fsqrt"
14033  [(set_attr "type" "fpspc")
14034   (set_attr "mode" "XF")
14035   (set_attr "athlon_decode" "direct")
14036   (set_attr "amdfam10_decode" "direct")
14037   (set_attr "bdver1_decode" "direct")])
14038
14039(define_insn "sqrt_extend<mode>xf2_i387"
14040  [(set (match_operand:XF 0 "register_operand" "=f")
14041	(sqrt:XF
14042	  (float_extend:XF
14043	    (match_operand:MODEF 1 "register_operand" "0"))))]
14044  "TARGET_USE_FANCY_MATH_387"
14045  "fsqrt"
14046  [(set_attr "type" "fpspc")
14047   (set_attr "mode" "XF")
14048   (set_attr "athlon_decode" "direct")
14049   (set_attr "amdfam10_decode" "direct")
14050   (set_attr "bdver1_decode" "direct")])
14051
14052(define_insn "*rsqrtsf2_sse"
14053  [(set (match_operand:SF 0 "register_operand" "=x")
14054	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14055		   UNSPEC_RSQRT))]
14056  "TARGET_SSE_MATH"
14057  "%vrsqrtss\t{%1, %d0|%d0, %1}"
14058  [(set_attr "type" "sse")
14059   (set_attr "atom_sse_attr" "rcp")
14060   (set_attr "btver2_sse_attr" "rcp")
14061   (set_attr "prefix" "maybe_vex")
14062   (set_attr "mode" "SF")])
14063
14064(define_expand "rsqrtsf2"
14065  [(set (match_operand:SF 0 "register_operand")
14066	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14067		   UNSPEC_RSQRT))]
14068  "TARGET_SSE_MATH"
14069{
14070  ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14071  DONE;
14072})
14073
14074(define_insn "*sqrt<mode>2_sse"
14075  [(set (match_operand:MODEF 0 "register_operand" "=x")
14076	(sqrt:MODEF
14077	  (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
14078  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14079  "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14080  [(set_attr "type" "sse")
14081   (set_attr "atom_sse_attr" "sqrt")
14082   (set_attr "btver2_sse_attr" "sqrt")
14083   (set_attr "prefix" "maybe_vex")
14084   (set_attr "mode" "<MODE>")
14085   (set_attr "athlon_decode" "*")
14086   (set_attr "amdfam10_decode" "*")
14087   (set_attr "bdver1_decode" "*")])
14088
14089(define_expand "sqrt<mode>2"
14090  [(set (match_operand:MODEF 0 "register_operand")
14091	(sqrt:MODEF
14092	  (match_operand:MODEF 1 "nonimmediate_operand")))]
14093  "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14094   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14095{
14096  if (<MODE>mode == SFmode
14097      && TARGET_SSE_MATH
14098      && TARGET_RECIP_SQRT
14099      && !optimize_function_for_size_p (cfun)
14100      && flag_finite_math_only && !flag_trapping_math
14101      && flag_unsafe_math_optimizations)
14102    {
14103      ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14104      DONE;
14105    }
14106
14107  if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14108    {
14109      rtx op0 = gen_reg_rtx (XFmode);
14110      rtx op1 = force_reg (<MODE>mode, operands[1]);
14111
14112      emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14113      emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14114      DONE;
14115   }
14116})
14117
14118(define_insn "fpremxf4_i387"
14119  [(set (match_operand:XF 0 "register_operand" "=f")
14120	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
14121		    (match_operand:XF 3 "register_operand" "1")]
14122		   UNSPEC_FPREM_F))
14123   (set (match_operand:XF 1 "register_operand" "=u")
14124	(unspec:XF [(match_dup 2) (match_dup 3)]
14125		   UNSPEC_FPREM_U))
14126   (set (reg:CCFP FPSR_REG)
14127	(unspec:CCFP [(match_dup 2) (match_dup 3)]
14128		     UNSPEC_C2_FLAG))]
14129  "TARGET_USE_FANCY_MATH_387
14130   && flag_finite_math_only"
14131  "fprem"
14132  [(set_attr "type" "fpspc")
14133   (set_attr "mode" "XF")])
14134
14135(define_expand "fmodxf3"
14136  [(use (match_operand:XF 0 "register_operand"))
14137   (use (match_operand:XF 1 "general_operand"))
14138   (use (match_operand:XF 2 "general_operand"))]
14139  "TARGET_USE_FANCY_MATH_387
14140   && flag_finite_math_only"
14141{
14142  rtx_code_label *label = gen_label_rtx ();
14143
14144  rtx op1 = gen_reg_rtx (XFmode);
14145  rtx op2 = gen_reg_rtx (XFmode);
14146
14147  emit_move_insn (op2, operands[2]);
14148  emit_move_insn (op1, operands[1]);
14149
14150  emit_label (label);
14151  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14152  ix86_emit_fp_unordered_jump (label);
14153  LABEL_NUSES (label) = 1;
14154
14155  emit_move_insn (operands[0], op1);
14156  DONE;
14157})
14158
14159(define_expand "fmod<mode>3"
14160  [(use (match_operand:MODEF 0 "register_operand"))
14161   (use (match_operand:MODEF 1 "general_operand"))
14162   (use (match_operand:MODEF 2 "general_operand"))]
14163  "TARGET_USE_FANCY_MATH_387
14164   && flag_finite_math_only"
14165{
14166  rtx (*gen_truncxf) (rtx, rtx);
14167
14168  rtx_code_label *label = gen_label_rtx ();
14169
14170  rtx op1 = gen_reg_rtx (XFmode);
14171  rtx op2 = gen_reg_rtx (XFmode);
14172
14173  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14174  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14175
14176  emit_label (label);
14177  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14178  ix86_emit_fp_unordered_jump (label);
14179  LABEL_NUSES (label) = 1;
14180
14181  /* Truncate the result properly for strict SSE math.  */
14182  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14183      && !TARGET_MIX_SSE_I387)
14184    gen_truncxf = gen_truncxf<mode>2;
14185  else
14186    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14187
14188  emit_insn (gen_truncxf (operands[0], op1));
14189  DONE;
14190})
14191
14192(define_insn "fprem1xf4_i387"
14193  [(set (match_operand:XF 0 "register_operand" "=f")
14194	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
14195		    (match_operand:XF 3 "register_operand" "1")]
14196		   UNSPEC_FPREM1_F))
14197   (set (match_operand:XF 1 "register_operand" "=u")
14198	(unspec:XF [(match_dup 2) (match_dup 3)]
14199		   UNSPEC_FPREM1_U))
14200   (set (reg:CCFP FPSR_REG)
14201	(unspec:CCFP [(match_dup 2) (match_dup 3)]
14202		     UNSPEC_C2_FLAG))]
14203  "TARGET_USE_FANCY_MATH_387
14204   && flag_finite_math_only"
14205  "fprem1"
14206  [(set_attr "type" "fpspc")
14207   (set_attr "mode" "XF")])
14208
14209(define_expand "remainderxf3"
14210  [(use (match_operand:XF 0 "register_operand"))
14211   (use (match_operand:XF 1 "general_operand"))
14212   (use (match_operand:XF 2 "general_operand"))]
14213  "TARGET_USE_FANCY_MATH_387
14214   && flag_finite_math_only"
14215{
14216  rtx_code_label *label = gen_label_rtx ();
14217
14218  rtx op1 = gen_reg_rtx (XFmode);
14219  rtx op2 = gen_reg_rtx (XFmode);
14220
14221  emit_move_insn (op2, operands[2]);
14222  emit_move_insn (op1, operands[1]);
14223
14224  emit_label (label);
14225  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14226  ix86_emit_fp_unordered_jump (label);
14227  LABEL_NUSES (label) = 1;
14228
14229  emit_move_insn (operands[0], op1);
14230  DONE;
14231})
14232
14233(define_expand "remainder<mode>3"
14234  [(use (match_operand:MODEF 0 "register_operand"))
14235   (use (match_operand:MODEF 1 "general_operand"))
14236   (use (match_operand:MODEF 2 "general_operand"))]
14237  "TARGET_USE_FANCY_MATH_387
14238   && flag_finite_math_only"
14239{
14240  rtx (*gen_truncxf) (rtx, rtx);
14241
14242  rtx_code_label *label = gen_label_rtx ();
14243
14244  rtx op1 = gen_reg_rtx (XFmode);
14245  rtx op2 = gen_reg_rtx (XFmode);
14246
14247  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14248  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14249
14250  emit_label (label);
14251
14252  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14253  ix86_emit_fp_unordered_jump (label);
14254  LABEL_NUSES (label) = 1;
14255
14256  /* Truncate the result properly for strict SSE math.  */
14257  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14258      && !TARGET_MIX_SSE_I387)
14259    gen_truncxf = gen_truncxf<mode>2;
14260  else
14261    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14262
14263  emit_insn (gen_truncxf (operands[0], op1));
14264  DONE;
14265})
14266
14267(define_int_iterator SINCOS
14268	[UNSPEC_SIN
14269	 UNSPEC_COS])
14270
14271(define_int_attr sincos
14272	[(UNSPEC_SIN "sin")
14273	 (UNSPEC_COS "cos")])
14274
14275(define_insn "*<sincos>xf2_i387"
14276  [(set (match_operand:XF 0 "register_operand" "=f")
14277	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14278		   SINCOS))]
14279  "TARGET_USE_FANCY_MATH_387
14280   && flag_unsafe_math_optimizations"
14281  "f<sincos>"
14282  [(set_attr "type" "fpspc")
14283   (set_attr "mode" "XF")])
14284
14285(define_insn "*<sincos>_extend<mode>xf2_i387"
14286  [(set (match_operand:XF 0 "register_operand" "=f")
14287	(unspec:XF [(float_extend:XF
14288		      (match_operand:MODEF 1 "register_operand" "0"))]
14289		   SINCOS))]
14290  "TARGET_USE_FANCY_MATH_387
14291   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14292       || TARGET_MIX_SSE_I387)
14293   && flag_unsafe_math_optimizations"
14294  "f<sincos>"
14295  [(set_attr "type" "fpspc")
14296   (set_attr "mode" "XF")])
14297
14298;; When sincos pattern is defined, sin and cos builtin functions will be
14299;; expanded to sincos pattern with one of its outputs left unused.
14300;; CSE pass will figure out if two sincos patterns can be combined,
14301;; otherwise sincos pattern will be split back to sin or cos pattern,
14302;; depending on the unused output.
14303
14304(define_insn "sincosxf3"
14305  [(set (match_operand:XF 0 "register_operand" "=f")
14306	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14307		   UNSPEC_SINCOS_COS))
14308   (set (match_operand:XF 1 "register_operand" "=u")
14309        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14310  "TARGET_USE_FANCY_MATH_387
14311   && flag_unsafe_math_optimizations"
14312  "fsincos"
14313  [(set_attr "type" "fpspc")
14314   (set_attr "mode" "XF")])
14315
14316(define_split
14317  [(set (match_operand:XF 0 "register_operand")
14318	(unspec:XF [(match_operand:XF 2 "register_operand")]
14319		   UNSPEC_SINCOS_COS))
14320   (set (match_operand:XF 1 "register_operand")
14321	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14322  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14323   && can_create_pseudo_p ()"
14324  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14325
14326(define_split
14327  [(set (match_operand:XF 0 "register_operand")
14328	(unspec:XF [(match_operand:XF 2 "register_operand")]
14329		   UNSPEC_SINCOS_COS))
14330   (set (match_operand:XF 1 "register_operand")
14331	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14332  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14333   && can_create_pseudo_p ()"
14334  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14335
14336(define_insn "sincos_extend<mode>xf3_i387"
14337  [(set (match_operand:XF 0 "register_operand" "=f")
14338	(unspec:XF [(float_extend:XF
14339		      (match_operand:MODEF 2 "register_operand" "0"))]
14340		   UNSPEC_SINCOS_COS))
14341   (set (match_operand:XF 1 "register_operand" "=u")
14342        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14343  "TARGET_USE_FANCY_MATH_387
14344   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14345       || TARGET_MIX_SSE_I387)
14346   && flag_unsafe_math_optimizations"
14347  "fsincos"
14348  [(set_attr "type" "fpspc")
14349   (set_attr "mode" "XF")])
14350
14351(define_split
14352  [(set (match_operand:XF 0 "register_operand")
14353	(unspec:XF [(float_extend:XF
14354		      (match_operand:MODEF 2 "register_operand"))]
14355		   UNSPEC_SINCOS_COS))
14356   (set (match_operand:XF 1 "register_operand")
14357	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14358  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14359   && can_create_pseudo_p ()"
14360  [(set (match_dup 1)
14361	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14362
14363(define_split
14364  [(set (match_operand:XF 0 "register_operand")
14365	(unspec:XF [(float_extend:XF
14366		      (match_operand:MODEF 2 "register_operand"))]
14367		   UNSPEC_SINCOS_COS))
14368   (set (match_operand:XF 1 "register_operand")
14369	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14370  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14371   && can_create_pseudo_p ()"
14372  [(set (match_dup 0)
14373	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14374
14375(define_expand "sincos<mode>3"
14376  [(use (match_operand:MODEF 0 "register_operand"))
14377   (use (match_operand:MODEF 1 "register_operand"))
14378   (use (match_operand:MODEF 2 "register_operand"))]
14379  "TARGET_USE_FANCY_MATH_387
14380   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14381       || TARGET_MIX_SSE_I387)
14382   && flag_unsafe_math_optimizations"
14383{
14384  rtx op0 = gen_reg_rtx (XFmode);
14385  rtx op1 = gen_reg_rtx (XFmode);
14386
14387  emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14388  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14389  emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14390  DONE;
14391})
14392
14393(define_insn "fptanxf4_i387"
14394  [(set (match_operand:XF 0 "register_operand" "=f")
14395	(match_operand:XF 3 "const_double_operand" "F"))
14396   (set (match_operand:XF 1 "register_operand" "=u")
14397        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14398		   UNSPEC_TAN))]
14399  "TARGET_USE_FANCY_MATH_387
14400   && flag_unsafe_math_optimizations
14401   && standard_80387_constant_p (operands[3]) == 2"
14402  "fptan"
14403  [(set_attr "type" "fpspc")
14404   (set_attr "mode" "XF")])
14405
14406(define_insn "fptan_extend<mode>xf4_i387"
14407  [(set (match_operand:MODEF 0 "register_operand" "=f")
14408	(match_operand:MODEF 3 "const_double_operand" "F"))
14409   (set (match_operand:XF 1 "register_operand" "=u")
14410        (unspec:XF [(float_extend:XF
14411		      (match_operand:MODEF 2 "register_operand" "0"))]
14412		   UNSPEC_TAN))]
14413  "TARGET_USE_FANCY_MATH_387
14414   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14415       || TARGET_MIX_SSE_I387)
14416   && flag_unsafe_math_optimizations
14417   && standard_80387_constant_p (operands[3]) == 2"
14418  "fptan"
14419  [(set_attr "type" "fpspc")
14420   (set_attr "mode" "XF")])
14421
14422(define_expand "tanxf2"
14423  [(use (match_operand:XF 0 "register_operand"))
14424   (use (match_operand:XF 1 "register_operand"))]
14425  "TARGET_USE_FANCY_MATH_387
14426   && flag_unsafe_math_optimizations"
14427{
14428  rtx one = gen_reg_rtx (XFmode);
14429  rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14430
14431  emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14432  DONE;
14433})
14434
14435(define_expand "tan<mode>2"
14436  [(use (match_operand:MODEF 0 "register_operand"))
14437   (use (match_operand:MODEF 1 "register_operand"))]
14438  "TARGET_USE_FANCY_MATH_387
14439   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14440       || TARGET_MIX_SSE_I387)
14441   && flag_unsafe_math_optimizations"
14442{
14443  rtx op0 = gen_reg_rtx (XFmode);
14444
14445  rtx one = gen_reg_rtx (<MODE>mode);
14446  rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14447
14448  emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14449					     operands[1], op2));
14450  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14451  DONE;
14452})
14453
14454(define_insn "*fpatanxf3_i387"
14455  [(set (match_operand:XF 0 "register_operand" "=f")
14456        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14457	            (match_operand:XF 2 "register_operand" "u")]
14458	           UNSPEC_FPATAN))
14459   (clobber (match_scratch:XF 3 "=2"))]
14460  "TARGET_USE_FANCY_MATH_387
14461   && flag_unsafe_math_optimizations"
14462  "fpatan"
14463  [(set_attr "type" "fpspc")
14464   (set_attr "mode" "XF")])
14465
14466(define_insn "fpatan_extend<mode>xf3_i387"
14467  [(set (match_operand:XF 0 "register_operand" "=f")
14468        (unspec:XF [(float_extend:XF
14469		      (match_operand:MODEF 1 "register_operand" "0"))
14470		    (float_extend:XF
14471		      (match_operand:MODEF 2 "register_operand" "u"))]
14472	           UNSPEC_FPATAN))
14473   (clobber (match_scratch:XF 3 "=2"))]
14474  "TARGET_USE_FANCY_MATH_387
14475   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14476       || TARGET_MIX_SSE_I387)
14477   && flag_unsafe_math_optimizations"
14478  "fpatan"
14479  [(set_attr "type" "fpspc")
14480   (set_attr "mode" "XF")])
14481
14482(define_expand "atan2xf3"
14483  [(parallel [(set (match_operand:XF 0 "register_operand")
14484		   (unspec:XF [(match_operand:XF 2 "register_operand")
14485			       (match_operand:XF 1 "register_operand")]
14486			      UNSPEC_FPATAN))
14487	      (clobber (match_scratch:XF 3))])]
14488  "TARGET_USE_FANCY_MATH_387
14489   && flag_unsafe_math_optimizations")
14490
14491(define_expand "atan2<mode>3"
14492  [(use (match_operand:MODEF 0 "register_operand"))
14493   (use (match_operand:MODEF 1 "register_operand"))
14494   (use (match_operand:MODEF 2 "register_operand"))]
14495  "TARGET_USE_FANCY_MATH_387
14496   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14497       || TARGET_MIX_SSE_I387)
14498   && flag_unsafe_math_optimizations"
14499{
14500  rtx op0 = gen_reg_rtx (XFmode);
14501
14502  emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14503  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14504  DONE;
14505})
14506
14507(define_expand "atanxf2"
14508  [(parallel [(set (match_operand:XF 0 "register_operand")
14509		   (unspec:XF [(match_dup 2)
14510			       (match_operand:XF 1 "register_operand")]
14511			      UNSPEC_FPATAN))
14512	      (clobber (match_scratch:XF 3))])]
14513  "TARGET_USE_FANCY_MATH_387
14514   && flag_unsafe_math_optimizations"
14515{
14516  operands[2] = gen_reg_rtx (XFmode);
14517  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14518})
14519
14520(define_expand "atan<mode>2"
14521  [(use (match_operand:MODEF 0 "register_operand"))
14522   (use (match_operand:MODEF 1 "register_operand"))]
14523  "TARGET_USE_FANCY_MATH_387
14524   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14525       || TARGET_MIX_SSE_I387)
14526   && flag_unsafe_math_optimizations"
14527{
14528  rtx op0 = gen_reg_rtx (XFmode);
14529
14530  rtx op2 = gen_reg_rtx (<MODE>mode);
14531  emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14532
14533  emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14534  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14535  DONE;
14536})
14537
14538(define_expand "asinxf2"
14539  [(set (match_dup 2)
14540	(mult:XF (match_operand:XF 1 "register_operand")
14541		 (match_dup 1)))
14542   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14543   (set (match_dup 5) (sqrt:XF (match_dup 4)))
14544   (parallel [(set (match_operand:XF 0 "register_operand")
14545        	   (unspec:XF [(match_dup 5) (match_dup 1)]
14546			      UNSPEC_FPATAN))
14547   	      (clobber (match_scratch:XF 6))])]
14548  "TARGET_USE_FANCY_MATH_387
14549   && flag_unsafe_math_optimizations"
14550{
14551  int i;
14552
14553  if (optimize_insn_for_size_p ())
14554    FAIL;
14555
14556  for (i = 2; i < 6; i++)
14557    operands[i] = gen_reg_rtx (XFmode);
14558
14559  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14560})
14561
14562(define_expand "asin<mode>2"
14563  [(use (match_operand:MODEF 0 "register_operand"))
14564   (use (match_operand:MODEF 1 "general_operand"))]
14565 "TARGET_USE_FANCY_MATH_387
14566   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14567       || TARGET_MIX_SSE_I387)
14568   && flag_unsafe_math_optimizations"
14569{
14570  rtx op0 = gen_reg_rtx (XFmode);
14571  rtx op1 = gen_reg_rtx (XFmode);
14572
14573  if (optimize_insn_for_size_p ())
14574    FAIL;
14575
14576  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14577  emit_insn (gen_asinxf2 (op0, op1));
14578  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14579  DONE;
14580})
14581
14582(define_expand "acosxf2"
14583  [(set (match_dup 2)
14584	(mult:XF (match_operand:XF 1 "register_operand")
14585		 (match_dup 1)))
14586   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14587   (set (match_dup 5) (sqrt:XF (match_dup 4)))
14588   (parallel [(set (match_operand:XF 0 "register_operand")
14589        	   (unspec:XF [(match_dup 1) (match_dup 5)]
14590			      UNSPEC_FPATAN))
14591   	      (clobber (match_scratch:XF 6))])]
14592  "TARGET_USE_FANCY_MATH_387
14593   && flag_unsafe_math_optimizations"
14594{
14595  int i;
14596
14597  if (optimize_insn_for_size_p ())
14598    FAIL;
14599
14600  for (i = 2; i < 6; i++)
14601    operands[i] = gen_reg_rtx (XFmode);
14602
14603  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14604})
14605
14606(define_expand "acos<mode>2"
14607  [(use (match_operand:MODEF 0 "register_operand"))
14608   (use (match_operand:MODEF 1 "general_operand"))]
14609 "TARGET_USE_FANCY_MATH_387
14610   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14611       || TARGET_MIX_SSE_I387)
14612   && flag_unsafe_math_optimizations"
14613{
14614  rtx op0 = gen_reg_rtx (XFmode);
14615  rtx op1 = gen_reg_rtx (XFmode);
14616
14617  if (optimize_insn_for_size_p ())
14618    FAIL;
14619
14620  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14621  emit_insn (gen_acosxf2 (op0, op1));
14622  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14623  DONE;
14624})
14625
14626(define_insn "fyl2xxf3_i387"
14627  [(set (match_operand:XF 0 "register_operand" "=f")
14628        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14629		    (match_operand:XF 2 "register_operand" "u")]
14630	           UNSPEC_FYL2X))
14631   (clobber (match_scratch:XF 3 "=2"))]
14632  "TARGET_USE_FANCY_MATH_387
14633   && flag_unsafe_math_optimizations"
14634  "fyl2x"
14635  [(set_attr "type" "fpspc")
14636   (set_attr "mode" "XF")])
14637
14638(define_insn "fyl2x_extend<mode>xf3_i387"
14639  [(set (match_operand:XF 0 "register_operand" "=f")
14640        (unspec:XF [(float_extend:XF
14641		      (match_operand:MODEF 1 "register_operand" "0"))
14642		    (match_operand:XF 2 "register_operand" "u")]
14643	           UNSPEC_FYL2X))
14644   (clobber (match_scratch:XF 3 "=2"))]
14645  "TARGET_USE_FANCY_MATH_387
14646   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14647       || TARGET_MIX_SSE_I387)
14648   && flag_unsafe_math_optimizations"
14649  "fyl2x"
14650  [(set_attr "type" "fpspc")
14651   (set_attr "mode" "XF")])
14652
14653(define_expand "logxf2"
14654  [(parallel [(set (match_operand:XF 0 "register_operand")
14655		   (unspec:XF [(match_operand:XF 1 "register_operand")
14656			       (match_dup 2)] UNSPEC_FYL2X))
14657	      (clobber (match_scratch:XF 3))])]
14658  "TARGET_USE_FANCY_MATH_387
14659   && flag_unsafe_math_optimizations"
14660{
14661  operands[2] = gen_reg_rtx (XFmode);
14662  emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14663})
14664
14665(define_expand "log<mode>2"
14666  [(use (match_operand:MODEF 0 "register_operand"))
14667   (use (match_operand:MODEF 1 "register_operand"))]
14668  "TARGET_USE_FANCY_MATH_387
14669   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14670       || TARGET_MIX_SSE_I387)
14671   && flag_unsafe_math_optimizations"
14672{
14673  rtx op0 = gen_reg_rtx (XFmode);
14674
14675  rtx op2 = gen_reg_rtx (XFmode);
14676  emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14677
14678  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14679  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14680  DONE;
14681})
14682
14683(define_expand "log10xf2"
14684  [(parallel [(set (match_operand:XF 0 "register_operand")
14685		   (unspec:XF [(match_operand:XF 1 "register_operand")
14686			       (match_dup 2)] UNSPEC_FYL2X))
14687	      (clobber (match_scratch:XF 3))])]
14688  "TARGET_USE_FANCY_MATH_387
14689   && flag_unsafe_math_optimizations"
14690{
14691  operands[2] = gen_reg_rtx (XFmode);
14692  emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14693})
14694
14695(define_expand "log10<mode>2"
14696  [(use (match_operand:MODEF 0 "register_operand"))
14697   (use (match_operand:MODEF 1 "register_operand"))]
14698  "TARGET_USE_FANCY_MATH_387
14699   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14700       || TARGET_MIX_SSE_I387)
14701   && flag_unsafe_math_optimizations"
14702{
14703  rtx op0 = gen_reg_rtx (XFmode);
14704
14705  rtx op2 = gen_reg_rtx (XFmode);
14706  emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14707
14708  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14709  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14710  DONE;
14711})
14712
14713(define_expand "log2xf2"
14714  [(parallel [(set (match_operand:XF 0 "register_operand")
14715		   (unspec:XF [(match_operand:XF 1 "register_operand")
14716			       (match_dup 2)] UNSPEC_FYL2X))
14717	      (clobber (match_scratch:XF 3))])]
14718  "TARGET_USE_FANCY_MATH_387
14719   && flag_unsafe_math_optimizations"
14720{
14721  operands[2] = gen_reg_rtx (XFmode);
14722  emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14723})
14724
14725(define_expand "log2<mode>2"
14726  [(use (match_operand:MODEF 0 "register_operand"))
14727   (use (match_operand:MODEF 1 "register_operand"))]
14728  "TARGET_USE_FANCY_MATH_387
14729   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14730       || TARGET_MIX_SSE_I387)
14731   && flag_unsafe_math_optimizations"
14732{
14733  rtx op0 = gen_reg_rtx (XFmode);
14734
14735  rtx op2 = gen_reg_rtx (XFmode);
14736  emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14737
14738  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14739  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14740  DONE;
14741})
14742
14743(define_insn "fyl2xp1xf3_i387"
14744  [(set (match_operand:XF 0 "register_operand" "=f")
14745        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14746		    (match_operand:XF 2 "register_operand" "u")]
14747	           UNSPEC_FYL2XP1))
14748   (clobber (match_scratch:XF 3 "=2"))]
14749  "TARGET_USE_FANCY_MATH_387
14750   && flag_unsafe_math_optimizations"
14751  "fyl2xp1"
14752  [(set_attr "type" "fpspc")
14753   (set_attr "mode" "XF")])
14754
14755(define_insn "fyl2xp1_extend<mode>xf3_i387"
14756  [(set (match_operand:XF 0 "register_operand" "=f")
14757        (unspec:XF [(float_extend:XF
14758		      (match_operand:MODEF 1 "register_operand" "0"))
14759		    (match_operand:XF 2 "register_operand" "u")]
14760	           UNSPEC_FYL2XP1))
14761   (clobber (match_scratch:XF 3 "=2"))]
14762  "TARGET_USE_FANCY_MATH_387
14763   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14764       || TARGET_MIX_SSE_I387)
14765   && flag_unsafe_math_optimizations"
14766  "fyl2xp1"
14767  [(set_attr "type" "fpspc")
14768   (set_attr "mode" "XF")])
14769
14770(define_expand "log1pxf2"
14771  [(use (match_operand:XF 0 "register_operand"))
14772   (use (match_operand:XF 1 "register_operand"))]
14773  "TARGET_USE_FANCY_MATH_387
14774   && flag_unsafe_math_optimizations"
14775{
14776  if (optimize_insn_for_size_p ())
14777    FAIL;
14778
14779  ix86_emit_i387_log1p (operands[0], operands[1]);
14780  DONE;
14781})
14782
14783(define_expand "log1p<mode>2"
14784  [(use (match_operand:MODEF 0 "register_operand"))
14785   (use (match_operand:MODEF 1 "register_operand"))]
14786  "TARGET_USE_FANCY_MATH_387
14787   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14788       || TARGET_MIX_SSE_I387)
14789   && flag_unsafe_math_optimizations"
14790{
14791  rtx op0;
14792
14793  if (optimize_insn_for_size_p ())
14794    FAIL;
14795
14796  op0 = gen_reg_rtx (XFmode);
14797
14798  operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14799
14800  ix86_emit_i387_log1p (op0, operands[1]);
14801  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14802  DONE;
14803})
14804
14805(define_insn "fxtractxf3_i387"
14806  [(set (match_operand:XF 0 "register_operand" "=f")
14807	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14808		   UNSPEC_XTRACT_FRACT))
14809   (set (match_operand:XF 1 "register_operand" "=u")
14810        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14811  "TARGET_USE_FANCY_MATH_387
14812   && flag_unsafe_math_optimizations"
14813  "fxtract"
14814  [(set_attr "type" "fpspc")
14815   (set_attr "mode" "XF")])
14816
14817(define_insn "fxtract_extend<mode>xf3_i387"
14818  [(set (match_operand:XF 0 "register_operand" "=f")
14819	(unspec:XF [(float_extend:XF
14820		      (match_operand:MODEF 2 "register_operand" "0"))]
14821		   UNSPEC_XTRACT_FRACT))
14822   (set (match_operand:XF 1 "register_operand" "=u")
14823        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14824  "TARGET_USE_FANCY_MATH_387
14825   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14826       || TARGET_MIX_SSE_I387)
14827   && flag_unsafe_math_optimizations"
14828  "fxtract"
14829  [(set_attr "type" "fpspc")
14830   (set_attr "mode" "XF")])
14831
14832(define_expand "logbxf2"
14833  [(parallel [(set (match_dup 2)
14834		   (unspec:XF [(match_operand:XF 1 "register_operand")]
14835			      UNSPEC_XTRACT_FRACT))
14836	      (set (match_operand:XF 0 "register_operand")
14837		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14838  "TARGET_USE_FANCY_MATH_387
14839   && flag_unsafe_math_optimizations"
14840  "operands[2] = gen_reg_rtx (XFmode);")
14841
14842(define_expand "logb<mode>2"
14843  [(use (match_operand:MODEF 0 "register_operand"))
14844   (use (match_operand:MODEF 1 "register_operand"))]
14845  "TARGET_USE_FANCY_MATH_387
14846   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14847       || TARGET_MIX_SSE_I387)
14848   && flag_unsafe_math_optimizations"
14849{
14850  rtx op0 = gen_reg_rtx (XFmode);
14851  rtx op1 = gen_reg_rtx (XFmode);
14852
14853  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14854  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14855  DONE;
14856})
14857
14858(define_expand "ilogbxf2"
14859  [(use (match_operand:SI 0 "register_operand"))
14860   (use (match_operand:XF 1 "register_operand"))]
14861  "TARGET_USE_FANCY_MATH_387
14862   && flag_unsafe_math_optimizations"
14863{
14864  rtx op0, op1;
14865
14866  if (optimize_insn_for_size_p ())
14867    FAIL;
14868
14869  op0 = gen_reg_rtx (XFmode);
14870  op1 = gen_reg_rtx (XFmode);
14871
14872  emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14873  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14874  DONE;
14875})
14876
14877(define_expand "ilogb<mode>2"
14878  [(use (match_operand:SI 0 "register_operand"))
14879   (use (match_operand:MODEF 1 "register_operand"))]
14880  "TARGET_USE_FANCY_MATH_387
14881   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14882       || TARGET_MIX_SSE_I387)
14883   && flag_unsafe_math_optimizations"
14884{
14885  rtx op0, op1;
14886
14887  if (optimize_insn_for_size_p ())
14888    FAIL;
14889
14890  op0 = gen_reg_rtx (XFmode);
14891  op1 = gen_reg_rtx (XFmode);
14892
14893  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14894  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14895  DONE;
14896})
14897
14898(define_insn "*f2xm1xf2_i387"
14899  [(set (match_operand:XF 0 "register_operand" "=f")
14900	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14901		   UNSPEC_F2XM1))]
14902  "TARGET_USE_FANCY_MATH_387
14903   && flag_unsafe_math_optimizations"
14904  "f2xm1"
14905  [(set_attr "type" "fpspc")
14906   (set_attr "mode" "XF")])
14907
14908(define_insn "fscalexf4_i387"
14909  [(set (match_operand:XF 0 "register_operand" "=f")
14910	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
14911		    (match_operand:XF 3 "register_operand" "1")]
14912		   UNSPEC_FSCALE_FRACT))
14913   (set (match_operand:XF 1 "register_operand" "=u")
14914	(unspec:XF [(match_dup 2) (match_dup 3)]
14915		   UNSPEC_FSCALE_EXP))]
14916  "TARGET_USE_FANCY_MATH_387
14917   && flag_unsafe_math_optimizations"
14918  "fscale"
14919  [(set_attr "type" "fpspc")
14920   (set_attr "mode" "XF")])
14921
14922(define_expand "expNcorexf3"
14923  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14924			       (match_operand:XF 2 "register_operand")))
14925   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14926   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14927   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14928   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14929   (parallel [(set (match_operand:XF 0 "register_operand")
14930		   (unspec:XF [(match_dup 8) (match_dup 4)]
14931			      UNSPEC_FSCALE_FRACT))
14932	      (set (match_dup 9)
14933		   (unspec:XF [(match_dup 8) (match_dup 4)]
14934			      UNSPEC_FSCALE_EXP))])]
14935  "TARGET_USE_FANCY_MATH_387
14936   && flag_unsafe_math_optimizations"
14937{
14938  int i;
14939
14940  if (optimize_insn_for_size_p ())
14941    FAIL;
14942
14943  for (i = 3; i < 10; i++)
14944    operands[i] = gen_reg_rtx (XFmode);
14945
14946  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14947})
14948
14949(define_expand "expxf2"
14950  [(use (match_operand:XF 0 "register_operand"))
14951   (use (match_operand:XF 1 "register_operand"))]
14952  "TARGET_USE_FANCY_MATH_387
14953   && flag_unsafe_math_optimizations"
14954{
14955  rtx op2;
14956
14957  if (optimize_insn_for_size_p ())
14958    FAIL;
14959
14960  op2 = gen_reg_rtx (XFmode);
14961  emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14962
14963  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14964  DONE;
14965})
14966
14967(define_expand "exp<mode>2"
14968  [(use (match_operand:MODEF 0 "register_operand"))
14969   (use (match_operand:MODEF 1 "general_operand"))]
14970 "TARGET_USE_FANCY_MATH_387
14971   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14972       || TARGET_MIX_SSE_I387)
14973   && flag_unsafe_math_optimizations"
14974{
14975  rtx op0, op1;
14976
14977  if (optimize_insn_for_size_p ())
14978    FAIL;
14979
14980  op0 = gen_reg_rtx (XFmode);
14981  op1 = gen_reg_rtx (XFmode);
14982
14983  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14984  emit_insn (gen_expxf2 (op0, op1));
14985  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14986  DONE;
14987})
14988
14989(define_expand "exp10xf2"
14990  [(use (match_operand:XF 0 "register_operand"))
14991   (use (match_operand:XF 1 "register_operand"))]
14992  "TARGET_USE_FANCY_MATH_387
14993   && flag_unsafe_math_optimizations"
14994{
14995  rtx op2;
14996
14997  if (optimize_insn_for_size_p ())
14998    FAIL;
14999
15000  op2 = gen_reg_rtx (XFmode);
15001  emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15002
15003  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15004  DONE;
15005})
15006
15007(define_expand "exp10<mode>2"
15008  [(use (match_operand:MODEF 0 "register_operand"))
15009   (use (match_operand:MODEF 1 "general_operand"))]
15010 "TARGET_USE_FANCY_MATH_387
15011   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15012       || TARGET_MIX_SSE_I387)
15013   && flag_unsafe_math_optimizations"
15014{
15015  rtx op0, op1;
15016
15017  if (optimize_insn_for_size_p ())
15018    FAIL;
15019
15020  op0 = gen_reg_rtx (XFmode);
15021  op1 = gen_reg_rtx (XFmode);
15022
15023  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15024  emit_insn (gen_exp10xf2 (op0, op1));
15025  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15026  DONE;
15027})
15028
15029(define_expand "exp2xf2"
15030  [(use (match_operand:XF 0 "register_operand"))
15031   (use (match_operand:XF 1 "register_operand"))]
15032  "TARGET_USE_FANCY_MATH_387
15033   && flag_unsafe_math_optimizations"
15034{
15035  rtx op2;
15036
15037  if (optimize_insn_for_size_p ())
15038    FAIL;
15039
15040  op2 = gen_reg_rtx (XFmode);
15041  emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
15042
15043  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15044  DONE;
15045})
15046
15047(define_expand "exp2<mode>2"
15048  [(use (match_operand:MODEF 0 "register_operand"))
15049   (use (match_operand:MODEF 1 "general_operand"))]
15050 "TARGET_USE_FANCY_MATH_387
15051   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15052       || TARGET_MIX_SSE_I387)
15053   && flag_unsafe_math_optimizations"
15054{
15055  rtx op0, op1;
15056
15057  if (optimize_insn_for_size_p ())
15058    FAIL;
15059
15060  op0 = gen_reg_rtx (XFmode);
15061  op1 = gen_reg_rtx (XFmode);
15062
15063  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15064  emit_insn (gen_exp2xf2 (op0, op1));
15065  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15066  DONE;
15067})
15068
15069(define_expand "expm1xf2"
15070  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15071			       (match_dup 2)))
15072   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15073   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15074   (set (match_dup 9) (float_extend:XF (match_dup 13)))
15075   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15076   (parallel [(set (match_dup 7)
15077		   (unspec:XF [(match_dup 6) (match_dup 4)]
15078			      UNSPEC_FSCALE_FRACT))
15079	      (set (match_dup 8)
15080		   (unspec:XF [(match_dup 6) (match_dup 4)]
15081			      UNSPEC_FSCALE_EXP))])
15082   (parallel [(set (match_dup 10)
15083		   (unspec:XF [(match_dup 9) (match_dup 8)]
15084			      UNSPEC_FSCALE_FRACT))
15085	      (set (match_dup 11)
15086		   (unspec:XF [(match_dup 9) (match_dup 8)]
15087			      UNSPEC_FSCALE_EXP))])
15088   (set (match_dup 12) (minus:XF (match_dup 10)
15089				 (float_extend:XF (match_dup 13))))
15090   (set (match_operand:XF 0 "register_operand")
15091	(plus:XF (match_dup 12) (match_dup 7)))]
15092  "TARGET_USE_FANCY_MATH_387
15093   && flag_unsafe_math_optimizations"
15094{
15095  int i;
15096
15097  if (optimize_insn_for_size_p ())
15098    FAIL;
15099
15100  for (i = 2; i < 13; i++)
15101    operands[i] = gen_reg_rtx (XFmode);
15102
15103  operands[13]
15104    = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15105
15106  emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15107})
15108
15109(define_expand "expm1<mode>2"
15110  [(use (match_operand:MODEF 0 "register_operand"))
15111   (use (match_operand:MODEF 1 "general_operand"))]
15112 "TARGET_USE_FANCY_MATH_387
15113   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15114       || TARGET_MIX_SSE_I387)
15115   && flag_unsafe_math_optimizations"
15116{
15117  rtx op0, op1;
15118
15119  if (optimize_insn_for_size_p ())
15120    FAIL;
15121
15122  op0 = gen_reg_rtx (XFmode);
15123  op1 = gen_reg_rtx (XFmode);
15124
15125  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15126  emit_insn (gen_expm1xf2 (op0, op1));
15127  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15128  DONE;
15129})
15130
15131(define_expand "ldexpxf3"
15132  [(match_operand:XF 0 "register_operand")
15133   (match_operand:XF 1 "register_operand")
15134   (match_operand:SI 2 "register_operand")]
15135  "TARGET_USE_FANCY_MATH_387
15136   && flag_unsafe_math_optimizations"
15137{
15138  rtx tmp1, tmp2;
15139  if (optimize_insn_for_size_p ())
15140    FAIL;
15141
15142  tmp1 = gen_reg_rtx (XFmode);
15143  tmp2 = gen_reg_rtx (XFmode);
15144
15145  emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15146  emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15147                                 operands[1], tmp1));
15148  DONE;
15149})
15150
15151(define_expand "ldexp<mode>3"
15152  [(use (match_operand:MODEF 0 "register_operand"))
15153   (use (match_operand:MODEF 1 "general_operand"))
15154   (use (match_operand:SI 2 "register_operand"))]
15155 "TARGET_USE_FANCY_MATH_387
15156   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15157       || TARGET_MIX_SSE_I387)
15158   && flag_unsafe_math_optimizations"
15159{
15160  rtx op0, op1;
15161
15162  if (optimize_insn_for_size_p ())
15163    FAIL;
15164
15165  op0 = gen_reg_rtx (XFmode);
15166  op1 = gen_reg_rtx (XFmode);
15167
15168  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15169  emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15170  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15171  DONE;
15172})
15173
15174(define_expand "scalbxf3"
15175  [(parallel [(set (match_operand:XF 0 " register_operand")
15176		   (unspec:XF [(match_operand:XF 1 "register_operand")
15177			       (match_operand:XF 2 "register_operand")]
15178			      UNSPEC_FSCALE_FRACT))
15179	      (set (match_dup 3)
15180		   (unspec:XF [(match_dup 1) (match_dup 2)]
15181			      UNSPEC_FSCALE_EXP))])]
15182  "TARGET_USE_FANCY_MATH_387
15183   && flag_unsafe_math_optimizations"
15184{
15185  if (optimize_insn_for_size_p ())
15186    FAIL;
15187
15188  operands[3] = gen_reg_rtx (XFmode);
15189})
15190
15191(define_expand "scalb<mode>3"
15192  [(use (match_operand:MODEF 0 "register_operand"))
15193   (use (match_operand:MODEF 1 "general_operand"))
15194   (use (match_operand:MODEF 2 "general_operand"))]
15195 "TARGET_USE_FANCY_MATH_387
15196   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15197       || TARGET_MIX_SSE_I387)
15198   && flag_unsafe_math_optimizations"
15199{
15200  rtx op0, op1, op2;
15201
15202  if (optimize_insn_for_size_p ())
15203    FAIL;
15204
15205  op0 = gen_reg_rtx (XFmode);
15206  op1 = gen_reg_rtx (XFmode);
15207  op2 = gen_reg_rtx (XFmode);
15208
15209  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15210  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15211  emit_insn (gen_scalbxf3 (op0, op1, op2));
15212  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15213  DONE;
15214})
15215
15216(define_expand "significandxf2"
15217  [(parallel [(set (match_operand:XF 0 "register_operand")
15218		   (unspec:XF [(match_operand:XF 1 "register_operand")]
15219			      UNSPEC_XTRACT_FRACT))
15220	      (set (match_dup 2)
15221		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15222  "TARGET_USE_FANCY_MATH_387
15223   && flag_unsafe_math_optimizations"
15224  "operands[2] = gen_reg_rtx (XFmode);")
15225
15226(define_expand "significand<mode>2"
15227  [(use (match_operand:MODEF 0 "register_operand"))
15228   (use (match_operand:MODEF 1 "register_operand"))]
15229  "TARGET_USE_FANCY_MATH_387
15230   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15231       || TARGET_MIX_SSE_I387)
15232   && flag_unsafe_math_optimizations"
15233{
15234  rtx op0 = gen_reg_rtx (XFmode);
15235  rtx op1 = gen_reg_rtx (XFmode);
15236
15237  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15238  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15239  DONE;
15240})
15241
15242
15243(define_insn "sse4_1_round<mode>2"
15244  [(set (match_operand:MODEF 0 "register_operand" "=x")
15245	(unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
15246		       (match_operand:SI 2 "const_0_to_15_operand" "n")]
15247		      UNSPEC_ROUND))]
15248  "TARGET_ROUND"
15249  "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15250  [(set_attr "type" "ssecvt")
15251   (set_attr "prefix_extra" "1")
15252   (set_attr "prefix" "maybe_vex")
15253   (set_attr "mode" "<MODE>")])
15254
15255(define_insn "rintxf2"
15256  [(set (match_operand:XF 0 "register_operand" "=f")
15257	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15258		   UNSPEC_FRNDINT))]
15259  "TARGET_USE_FANCY_MATH_387
15260   && flag_unsafe_math_optimizations"
15261  "frndint"
15262  [(set_attr "type" "fpspc")
15263   (set_attr "mode" "XF")])
15264
15265(define_expand "rint<mode>2"
15266  [(use (match_operand:MODEF 0 "register_operand"))
15267   (use (match_operand:MODEF 1 "register_operand"))]
15268  "(TARGET_USE_FANCY_MATH_387
15269    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15270	|| TARGET_MIX_SSE_I387)
15271    && flag_unsafe_math_optimizations)
15272   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15273       && !flag_trapping_math)"
15274{
15275  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15276      && !flag_trapping_math)
15277    {
15278      if (TARGET_ROUND)
15279	emit_insn (gen_sse4_1_round<mode>2
15280		   (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15281      else if (optimize_insn_for_size_p ())
15282        FAIL;
15283      else
15284	ix86_expand_rint (operands[0], operands[1]);
15285    }
15286  else
15287    {
15288      rtx op0 = gen_reg_rtx (XFmode);
15289      rtx op1 = gen_reg_rtx (XFmode);
15290
15291      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15292      emit_insn (gen_rintxf2 (op0, op1));
15293
15294      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15295    }
15296  DONE;
15297})
15298
15299(define_expand "round<mode>2"
15300  [(match_operand:X87MODEF 0 "register_operand")
15301   (match_operand:X87MODEF 1 "nonimmediate_operand")]
15302  "(TARGET_USE_FANCY_MATH_387
15303    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15304	|| TARGET_MIX_SSE_I387)
15305    && flag_unsafe_math_optimizations)
15306   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15307       && !flag_trapping_math && !flag_rounding_math)"
15308{
15309  if (optimize_insn_for_size_p ())
15310    FAIL;
15311
15312  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15313      && !flag_trapping_math && !flag_rounding_math)
15314    {
15315      if (TARGET_ROUND)
15316        {
15317	  operands[1] = force_reg (<MODE>mode, operands[1]);
15318	  ix86_expand_round_sse4 (operands[0], operands[1]);
15319	}
15320      else if (TARGET_64BIT || (<MODE>mode != DFmode))
15321	ix86_expand_round (operands[0], operands[1]);
15322      else
15323	ix86_expand_rounddf_32 (operands[0], operands[1]);
15324    }
15325  else
15326    {
15327      operands[1] = force_reg (<MODE>mode, operands[1]);
15328      ix86_emit_i387_round (operands[0], operands[1]);
15329    }
15330  DONE;
15331})
15332
15333(define_insn_and_split "*fistdi2_1"
15334  [(set (match_operand:DI 0 "nonimmediate_operand")
15335	(unspec:DI [(match_operand:XF 1 "register_operand")]
15336		   UNSPEC_FIST))]
15337  "TARGET_USE_FANCY_MATH_387
15338   && can_create_pseudo_p ()"
15339  "#"
15340  "&& 1"
15341  [(const_int 0)]
15342{
15343  if (memory_operand (operands[0], VOIDmode))
15344    emit_insn (gen_fistdi2 (operands[0], operands[1]));
15345  else
15346    {
15347      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15348      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15349					 operands[2]));
15350    }
15351  DONE;
15352}
15353  [(set_attr "type" "fpspc")
15354   (set_attr "mode" "DI")])
15355
15356(define_insn "fistdi2"
15357  [(set (match_operand:DI 0 "memory_operand" "=m")
15358	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15359		   UNSPEC_FIST))
15360   (clobber (match_scratch:XF 2 "=&1f"))]
15361  "TARGET_USE_FANCY_MATH_387"
15362  "* return output_fix_trunc (insn, operands, false);"
15363  [(set_attr "type" "fpspc")
15364   (set_attr "mode" "DI")])
15365
15366(define_insn "fistdi2_with_temp"
15367  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15368	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15369		   UNSPEC_FIST))
15370   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15371   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15372  "TARGET_USE_FANCY_MATH_387"
15373  "#"
15374  [(set_attr "type" "fpspc")
15375   (set_attr "mode" "DI")])
15376
15377(define_split
15378  [(set (match_operand:DI 0 "register_operand")
15379	(unspec:DI [(match_operand:XF 1 "register_operand")]
15380		   UNSPEC_FIST))
15381   (clobber (match_operand:DI 2 "memory_operand"))
15382   (clobber (match_scratch 3))]
15383  "reload_completed"
15384  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15385	      (clobber (match_dup 3))])
15386   (set (match_dup 0) (match_dup 2))])
15387
15388(define_split
15389  [(set (match_operand:DI 0 "memory_operand")
15390	(unspec:DI [(match_operand:XF 1 "register_operand")]
15391		   UNSPEC_FIST))
15392   (clobber (match_operand:DI 2 "memory_operand"))
15393   (clobber (match_scratch 3))]
15394  "reload_completed"
15395  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15396	      (clobber (match_dup 3))])])
15397
15398(define_insn_and_split "*fist<mode>2_1"
15399  [(set (match_operand:SWI24 0 "register_operand")
15400	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15401		      UNSPEC_FIST))]
15402  "TARGET_USE_FANCY_MATH_387
15403   && can_create_pseudo_p ()"
15404  "#"
15405  "&& 1"
15406  [(const_int 0)]
15407{
15408  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15409  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15410					operands[2]));
15411  DONE;
15412}
15413  [(set_attr "type" "fpspc")
15414   (set_attr "mode" "<MODE>")])
15415
15416(define_insn "fist<mode>2"
15417  [(set (match_operand:SWI24 0 "memory_operand" "=m")
15418	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15419		      UNSPEC_FIST))]
15420  "TARGET_USE_FANCY_MATH_387"
15421  "* return output_fix_trunc (insn, operands, false);"
15422  [(set_attr "type" "fpspc")
15423   (set_attr "mode" "<MODE>")])
15424
15425(define_insn "fist<mode>2_with_temp"
15426  [(set (match_operand:SWI24 0 "register_operand" "=r")
15427	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15428		      UNSPEC_FIST))
15429   (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15430  "TARGET_USE_FANCY_MATH_387"
15431  "#"
15432  [(set_attr "type" "fpspc")
15433   (set_attr "mode" "<MODE>")])
15434
15435(define_split
15436  [(set (match_operand:SWI24 0 "register_operand")
15437	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15438		      UNSPEC_FIST))
15439   (clobber (match_operand:SWI24 2 "memory_operand"))]
15440  "reload_completed"
15441  [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15442   (set (match_dup 0) (match_dup 2))])
15443
15444(define_split
15445  [(set (match_operand:SWI24 0 "memory_operand")
15446	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15447		      UNSPEC_FIST))
15448   (clobber (match_operand:SWI24 2 "memory_operand"))]
15449  "reload_completed"
15450  [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15451
15452(define_expand "lrintxf<mode>2"
15453  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15454     (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15455		     UNSPEC_FIST))]
15456  "TARGET_USE_FANCY_MATH_387")
15457
15458(define_expand "lrint<MODEF:mode><SWI48:mode>2"
15459  [(set (match_operand:SWI48 0 "nonimmediate_operand")
15460     (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15461		   UNSPEC_FIX_NOTRUNC))]
15462  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15463
15464(define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15465  [(match_operand:SWI248x 0 "nonimmediate_operand")
15466   (match_operand:X87MODEF 1 "register_operand")]
15467  "(TARGET_USE_FANCY_MATH_387
15468    && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15469	|| TARGET_MIX_SSE_I387)
15470    && flag_unsafe_math_optimizations)
15471   || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15472       && <SWI248x:MODE>mode != HImode 
15473       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15474       && !flag_trapping_math && !flag_rounding_math)"
15475{
15476  if (optimize_insn_for_size_p ())
15477    FAIL;
15478
15479  if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15480      && <SWI248x:MODE>mode != HImode
15481      && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15482      && !flag_trapping_math && !flag_rounding_math)
15483    ix86_expand_lround (operands[0], operands[1]);
15484  else
15485    ix86_emit_i387_round (operands[0], operands[1]);
15486  DONE;
15487})
15488
15489(define_int_iterator FRNDINT_ROUNDING
15490	[UNSPEC_FRNDINT_FLOOR
15491	 UNSPEC_FRNDINT_CEIL
15492	 UNSPEC_FRNDINT_TRUNC])
15493
15494(define_int_iterator FIST_ROUNDING
15495	[UNSPEC_FIST_FLOOR
15496	 UNSPEC_FIST_CEIL])
15497
15498;; Base name for define_insn
15499(define_int_attr rounding_insn
15500	[(UNSPEC_FRNDINT_FLOOR "floor")
15501	 (UNSPEC_FRNDINT_CEIL "ceil")
15502	 (UNSPEC_FRNDINT_TRUNC "btrunc")
15503	 (UNSPEC_FIST_FLOOR "floor")
15504	 (UNSPEC_FIST_CEIL "ceil")])
15505
15506(define_int_attr rounding
15507	[(UNSPEC_FRNDINT_FLOOR "floor")
15508	 (UNSPEC_FRNDINT_CEIL "ceil")
15509	 (UNSPEC_FRNDINT_TRUNC "trunc")
15510	 (UNSPEC_FIST_FLOOR "floor")
15511	 (UNSPEC_FIST_CEIL "ceil")])
15512
15513(define_int_attr ROUNDING
15514	[(UNSPEC_FRNDINT_FLOOR "FLOOR")
15515	 (UNSPEC_FRNDINT_CEIL "CEIL")
15516	 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15517	 (UNSPEC_FIST_FLOOR "FLOOR")
15518	 (UNSPEC_FIST_CEIL "CEIL")])
15519
15520;; Rounding mode control word calculation could clobber FLAGS_REG.
15521(define_insn_and_split "frndintxf2_<rounding>"
15522  [(set (match_operand:XF 0 "register_operand")
15523	(unspec:XF [(match_operand:XF 1 "register_operand")]
15524		   FRNDINT_ROUNDING))
15525   (clobber (reg:CC FLAGS_REG))]
15526  "TARGET_USE_FANCY_MATH_387
15527   && flag_unsafe_math_optimizations
15528   && can_create_pseudo_p ()"
15529  "#"
15530  "&& 1"
15531  [(const_int 0)]
15532{
15533  ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15534
15535  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15536  operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15537
15538  emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15539					     operands[2], operands[3]));
15540  DONE;
15541}
15542  [(set_attr "type" "frndint")
15543   (set_attr "i387_cw" "<rounding>")
15544   (set_attr "mode" "XF")])
15545
15546(define_insn "frndintxf2_<rounding>_i387"
15547  [(set (match_operand:XF 0 "register_operand" "=f")
15548	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15549		   FRNDINT_ROUNDING))
15550   (use (match_operand:HI 2 "memory_operand" "m"))
15551   (use (match_operand:HI 3 "memory_operand" "m"))]
15552  "TARGET_USE_FANCY_MATH_387
15553   && flag_unsafe_math_optimizations"
15554  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15555  [(set_attr "type" "frndint")
15556   (set_attr "i387_cw" "<rounding>")
15557   (set_attr "mode" "XF")])
15558
15559(define_expand "<rounding_insn>xf2"
15560  [(parallel [(set (match_operand:XF 0 "register_operand")
15561		   (unspec:XF [(match_operand:XF 1 "register_operand")]
15562			      FRNDINT_ROUNDING))
15563	      (clobber (reg:CC FLAGS_REG))])]
15564  "TARGET_USE_FANCY_MATH_387
15565   && flag_unsafe_math_optimizations
15566   && !optimize_insn_for_size_p ()")
15567
15568(define_expand "<rounding_insn><mode>2"
15569  [(parallel [(set (match_operand:MODEF 0 "register_operand")
15570		   (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15571				 FRNDINT_ROUNDING))
15572	      (clobber (reg:CC FLAGS_REG))])]
15573  "(TARGET_USE_FANCY_MATH_387
15574    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15575	|| TARGET_MIX_SSE_I387)
15576    && flag_unsafe_math_optimizations)
15577   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15578       && !flag_trapping_math)"
15579{
15580  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15581      && !flag_trapping_math)
15582    {
15583      if (TARGET_ROUND)
15584	emit_insn (gen_sse4_1_round<mode>2
15585		   (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15586      else if (optimize_insn_for_size_p ())
15587	FAIL;
15588      else if (TARGET_64BIT || (<MODE>mode != DFmode))
15589	{
15590	  if (ROUND_<ROUNDING> == ROUND_FLOOR)
15591	    ix86_expand_floorceil (operands[0], operands[1], true);
15592	  else if (ROUND_<ROUNDING> == ROUND_CEIL)
15593	    ix86_expand_floorceil (operands[0], operands[1], false);
15594	  else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15595	    ix86_expand_trunc (operands[0], operands[1]);
15596	  else
15597	    gcc_unreachable ();
15598	}
15599      else
15600	{
15601	  if (ROUND_<ROUNDING> == ROUND_FLOOR)
15602	    ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15603	  else if (ROUND_<ROUNDING> == ROUND_CEIL)
15604	    ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15605	  else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15606	    ix86_expand_truncdf_32 (operands[0], operands[1]);
15607	  else
15608	    gcc_unreachable ();
15609	}
15610    }
15611  else
15612    {
15613      rtx op0, op1;
15614
15615      if (optimize_insn_for_size_p ())
15616	FAIL;
15617
15618      op0 = gen_reg_rtx (XFmode);
15619      op1 = gen_reg_rtx (XFmode);
15620      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15621      emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15622
15623      emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15624    }
15625  DONE;
15626})
15627
15628;; Rounding mode control word calculation could clobber FLAGS_REG.
15629(define_insn_and_split "frndintxf2_mask_pm"
15630  [(set (match_operand:XF 0 "register_operand")
15631	(unspec:XF [(match_operand:XF 1 "register_operand")]
15632		   UNSPEC_FRNDINT_MASK_PM))
15633   (clobber (reg:CC FLAGS_REG))]
15634  "TARGET_USE_FANCY_MATH_387
15635   && flag_unsafe_math_optimizations
15636   && can_create_pseudo_p ()"
15637  "#"
15638  "&& 1"
15639  [(const_int 0)]
15640{
15641  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15642
15643  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15644  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15645
15646  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15647					  operands[2], operands[3]));
15648  DONE;
15649}
15650  [(set_attr "type" "frndint")
15651   (set_attr "i387_cw" "mask_pm")
15652   (set_attr "mode" "XF")])
15653
15654(define_insn "frndintxf2_mask_pm_i387"
15655  [(set (match_operand:XF 0 "register_operand" "=f")
15656	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15657		   UNSPEC_FRNDINT_MASK_PM))
15658   (use (match_operand:HI 2 "memory_operand" "m"))
15659   (use (match_operand:HI 3 "memory_operand" "m"))]
15660  "TARGET_USE_FANCY_MATH_387
15661   && flag_unsafe_math_optimizations"
15662  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15663  [(set_attr "type" "frndint")
15664   (set_attr "i387_cw" "mask_pm")
15665   (set_attr "mode" "XF")])
15666
15667(define_expand "nearbyintxf2"
15668  [(parallel [(set (match_operand:XF 0 "register_operand")
15669		   (unspec:XF [(match_operand:XF 1 "register_operand")]
15670			      UNSPEC_FRNDINT_MASK_PM))
15671	      (clobber (reg:CC FLAGS_REG))])]
15672  "TARGET_USE_FANCY_MATH_387
15673   && flag_unsafe_math_optimizations")
15674
15675(define_expand "nearbyint<mode>2"
15676  [(use (match_operand:MODEF 0 "register_operand"))
15677   (use (match_operand:MODEF 1 "register_operand"))]
15678  "TARGET_USE_FANCY_MATH_387
15679   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15680       || TARGET_MIX_SSE_I387)
15681   && flag_unsafe_math_optimizations"
15682{
15683  rtx op0 = gen_reg_rtx (XFmode);
15684  rtx op1 = gen_reg_rtx (XFmode);
15685
15686  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15687  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15688
15689  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15690  DONE;
15691})
15692
15693;; Rounding mode control word calculation could clobber FLAGS_REG.
15694(define_insn_and_split "*fist<mode>2_<rounding>_1"
15695  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15696	(unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15697			FIST_ROUNDING))
15698   (clobber (reg:CC FLAGS_REG))]
15699  "TARGET_USE_FANCY_MATH_387
15700   && flag_unsafe_math_optimizations
15701   && can_create_pseudo_p ()"
15702  "#"
15703  "&& 1"
15704  [(const_int 0)]
15705{
15706  ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15707
15708  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15709  operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15710  if (memory_operand (operands[0], VOIDmode))
15711    emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15712					   operands[2], operands[3]));
15713  else
15714    {
15715      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15716      emit_insn (gen_fist<mode>2_<rounding>_with_temp
15717		  (operands[0], operands[1], operands[2],
15718		   operands[3], operands[4]));
15719    }
15720  DONE;
15721}
15722  [(set_attr "type" "fistp")
15723   (set_attr "i387_cw" "<rounding>")
15724   (set_attr "mode" "<MODE>")])
15725
15726(define_insn "fistdi2_<rounding>"
15727  [(set (match_operand:DI 0 "memory_operand" "=m")
15728	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15729		   FIST_ROUNDING))
15730   (use (match_operand:HI 2 "memory_operand" "m"))
15731   (use (match_operand:HI 3 "memory_operand" "m"))
15732   (clobber (match_scratch:XF 4 "=&1f"))]
15733  "TARGET_USE_FANCY_MATH_387
15734   && flag_unsafe_math_optimizations"
15735  "* return output_fix_trunc (insn, operands, false);"
15736  [(set_attr "type" "fistp")
15737   (set_attr "i387_cw" "<rounding>")
15738   (set_attr "mode" "DI")])
15739
15740(define_insn "fistdi2_<rounding>_with_temp"
15741  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15742	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15743		   FIST_ROUNDING))
15744   (use (match_operand:HI 2 "memory_operand" "m,m"))
15745   (use (match_operand:HI 3 "memory_operand" "m,m"))
15746   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15747   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15748  "TARGET_USE_FANCY_MATH_387
15749   && flag_unsafe_math_optimizations"
15750  "#"
15751  [(set_attr "type" "fistp")
15752   (set_attr "i387_cw" "<rounding>")
15753   (set_attr "mode" "DI")])
15754
15755(define_split
15756  [(set (match_operand:DI 0 "register_operand")
15757	(unspec:DI [(match_operand:XF 1 "register_operand")]
15758		   FIST_ROUNDING))
15759   (use (match_operand:HI 2 "memory_operand"))
15760   (use (match_operand:HI 3 "memory_operand"))
15761   (clobber (match_operand:DI 4 "memory_operand"))
15762   (clobber (match_scratch 5))]
15763  "reload_completed"
15764  [(parallel [(set (match_dup 4)
15765		   (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15766	      (use (match_dup 2))
15767	      (use (match_dup 3))
15768	      (clobber (match_dup 5))])
15769   (set (match_dup 0) (match_dup 4))])
15770
15771(define_split
15772  [(set (match_operand:DI 0 "memory_operand")
15773	(unspec:DI [(match_operand:XF 1 "register_operand")]
15774		   FIST_ROUNDING))
15775   (use (match_operand:HI 2 "memory_operand"))
15776   (use (match_operand:HI 3 "memory_operand"))
15777   (clobber (match_operand:DI 4 "memory_operand"))
15778   (clobber (match_scratch 5))]
15779  "reload_completed"
15780  [(parallel [(set (match_dup 0)
15781		   (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15782	      (use (match_dup 2))
15783	      (use (match_dup 3))
15784	      (clobber (match_dup 5))])])
15785
15786(define_insn "fist<mode>2_<rounding>"
15787  [(set (match_operand:SWI24 0 "memory_operand" "=m")
15788	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15789		      FIST_ROUNDING))
15790   (use (match_operand:HI 2 "memory_operand" "m"))
15791   (use (match_operand:HI 3 "memory_operand" "m"))]
15792  "TARGET_USE_FANCY_MATH_387
15793   && flag_unsafe_math_optimizations"
15794  "* return output_fix_trunc (insn, operands, false);"
15795  [(set_attr "type" "fistp")
15796   (set_attr "i387_cw" "<rounding>")
15797   (set_attr "mode" "<MODE>")])
15798
15799(define_insn "fist<mode>2_<rounding>_with_temp"
15800  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15801	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15802		      FIST_ROUNDING))
15803   (use (match_operand:HI 2 "memory_operand" "m,m"))
15804   (use (match_operand:HI 3 "memory_operand" "m,m"))
15805   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15806  "TARGET_USE_FANCY_MATH_387
15807   && flag_unsafe_math_optimizations"
15808  "#"
15809  [(set_attr "type" "fistp")
15810   (set_attr "i387_cw" "<rounding>")
15811   (set_attr "mode" "<MODE>")])
15812
15813(define_split
15814  [(set (match_operand:SWI24 0 "register_operand")
15815	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15816		      FIST_ROUNDING))
15817   (use (match_operand:HI 2 "memory_operand"))
15818   (use (match_operand:HI 3 "memory_operand"))
15819   (clobber (match_operand:SWI24 4 "memory_operand"))]
15820  "reload_completed"
15821  [(parallel [(set (match_dup 4)
15822		   (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15823	      (use (match_dup 2))
15824	      (use (match_dup 3))])
15825   (set (match_dup 0) (match_dup 4))])
15826
15827(define_split
15828  [(set (match_operand:SWI24 0 "memory_operand")
15829	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15830		      FIST_ROUNDING))
15831   (use (match_operand:HI 2 "memory_operand"))
15832   (use (match_operand:HI 3 "memory_operand"))
15833   (clobber (match_operand:SWI24 4 "memory_operand"))]
15834  "reload_completed"
15835  [(parallel [(set (match_dup 0)
15836		   (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15837	      (use (match_dup 2))
15838	      (use (match_dup 3))])])
15839
15840(define_expand "l<rounding_insn>xf<mode>2"
15841  [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15842		   (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15843				   FIST_ROUNDING))
15844	      (clobber (reg:CC FLAGS_REG))])]
15845  "TARGET_USE_FANCY_MATH_387
15846   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15847   && flag_unsafe_math_optimizations")
15848
15849(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15850  [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15851		   (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15852				 FIST_ROUNDING))
15853	      (clobber (reg:CC FLAGS_REG))])]
15854  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15855   && !flag_trapping_math"
15856{
15857  if (TARGET_64BIT && optimize_insn_for_size_p ())
15858    FAIL;
15859
15860  if (ROUND_<ROUNDING> == ROUND_FLOOR)
15861    ix86_expand_lfloorceil (operands[0], operands[1], true);
15862  else if (ROUND_<ROUNDING> == ROUND_CEIL)
15863    ix86_expand_lfloorceil (operands[0], operands[1], false);
15864  else
15865    gcc_unreachable ();
15866
15867  DONE;
15868})
15869
15870(define_insn "fxam<mode>2_i387"
15871  [(set (match_operand:HI 0 "register_operand" "=a")
15872	(unspec:HI
15873	  [(match_operand:X87MODEF 1 "register_operand" "f")]
15874	  UNSPEC_FXAM))]
15875  "TARGET_USE_FANCY_MATH_387"
15876  "fxam\n\tfnstsw\t%0"
15877  [(set_attr "type" "multi")
15878   (set_attr "length" "4")
15879   (set_attr "unit" "i387")
15880   (set_attr "mode" "<MODE>")])
15881
15882(define_insn_and_split "fxam<mode>2_i387_with_temp"
15883  [(set (match_operand:HI 0 "register_operand")
15884	(unspec:HI
15885	  [(match_operand:MODEF 1 "memory_operand")]
15886	  UNSPEC_FXAM_MEM))]
15887  "TARGET_USE_FANCY_MATH_387
15888   && can_create_pseudo_p ()"
15889  "#"
15890  "&& 1"
15891  [(set (match_dup 2)(match_dup 1))
15892   (set (match_dup 0)
15893	(unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15894{
15895  operands[2] = gen_reg_rtx (<MODE>mode);
15896
15897  MEM_VOLATILE_P (operands[1]) = 1;
15898}
15899  [(set_attr "type" "multi")
15900   (set_attr "unit" "i387")
15901   (set_attr "mode" "<MODE>")])
15902
15903(define_expand "isinfxf2"
15904  [(use (match_operand:SI 0 "register_operand"))
15905   (use (match_operand:XF 1 "register_operand"))]
15906  "TARGET_USE_FANCY_MATH_387
15907   && ix86_libc_has_function (function_c99_misc)"
15908{
15909  rtx mask = GEN_INT (0x45);
15910  rtx val = GEN_INT (0x05);
15911
15912  rtx cond;
15913
15914  rtx scratch = gen_reg_rtx (HImode);
15915  rtx res = gen_reg_rtx (QImode);
15916
15917  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15918
15919  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15920  emit_insn (gen_cmpqi_ext_3 (scratch, val));
15921  cond = gen_rtx_fmt_ee (EQ, QImode,
15922			 gen_rtx_REG (CCmode, FLAGS_REG),
15923			 const0_rtx);
15924  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15925  emit_insn (gen_zero_extendqisi2 (operands[0], res));
15926  DONE;
15927})
15928
15929(define_expand "isinf<mode>2"
15930  [(use (match_operand:SI 0 "register_operand"))
15931   (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15932  "TARGET_USE_FANCY_MATH_387
15933   && ix86_libc_has_function (function_c99_misc)
15934   && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15935{
15936  rtx mask = GEN_INT (0x45);
15937  rtx val = GEN_INT (0x05);
15938
15939  rtx cond;
15940
15941  rtx scratch = gen_reg_rtx (HImode);
15942  rtx res = gen_reg_rtx (QImode);
15943
15944  /* Remove excess precision by forcing value through memory. */
15945  if (memory_operand (operands[1], VOIDmode))
15946    emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15947  else
15948    {
15949      rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15950
15951      emit_move_insn (temp, operands[1]);
15952      emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15953    }
15954
15955  emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15956  emit_insn (gen_cmpqi_ext_3 (scratch, val));
15957  cond = gen_rtx_fmt_ee (EQ, QImode,
15958			 gen_rtx_REG (CCmode, FLAGS_REG),
15959			 const0_rtx);
15960  emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15961  emit_insn (gen_zero_extendqisi2 (operands[0], res));
15962  DONE;
15963})
15964
15965(define_expand "signbitxf2"
15966  [(use (match_operand:SI 0 "register_operand"))
15967   (use (match_operand:XF 1 "register_operand"))]
15968  "TARGET_USE_FANCY_MATH_387"
15969{
15970  rtx scratch = gen_reg_rtx (HImode);
15971
15972  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15973  emit_insn (gen_andsi3 (operands[0],
15974	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15975  DONE;
15976})
15977
15978(define_insn "movmsk_df"
15979  [(set (match_operand:SI 0 "register_operand" "=r")
15980	(unspec:SI
15981	  [(match_operand:DF 1 "register_operand" "x")]
15982	  UNSPEC_MOVMSK))]
15983  "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15984  "%vmovmskpd\t{%1, %0|%0, %1}"
15985  [(set_attr "type" "ssemov")
15986   (set_attr "prefix" "maybe_vex")
15987   (set_attr "mode" "DF")])
15988
15989;; Use movmskpd in SSE mode to avoid store forwarding stall
15990;; for 32bit targets and movq+shrq sequence for 64bit targets.
15991(define_expand "signbitdf2"
15992  [(use (match_operand:SI 0 "register_operand"))
15993   (use (match_operand:DF 1 "register_operand"))]
15994  "TARGET_USE_FANCY_MATH_387
15995   || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15996{
15997  if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15998    {
15999      emit_insn (gen_movmsk_df (operands[0], operands[1]));
16000      emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16001    }
16002  else
16003    {
16004      rtx scratch = gen_reg_rtx (HImode);
16005
16006      emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16007      emit_insn (gen_andsi3 (operands[0],
16008		 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16009    }
16010  DONE;
16011})
16012
16013(define_expand "signbitsf2"
16014  [(use (match_operand:SI 0 "register_operand"))
16015   (use (match_operand:SF 1 "register_operand"))]
16016  "TARGET_USE_FANCY_MATH_387
16017   && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16018{
16019  rtx scratch = gen_reg_rtx (HImode);
16020
16021  emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16022  emit_insn (gen_andsi3 (operands[0],
16023	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16024  DONE;
16025})
16026
16027;; Block operation instructions
16028
16029(define_insn "cld"
16030  [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16031  ""
16032  "cld"
16033  [(set_attr "length" "1")
16034   (set_attr "length_immediate" "0")
16035   (set_attr "modrm" "0")])
16036
16037(define_expand "movmem<mode>"
16038  [(use (match_operand:BLK 0 "memory_operand"))
16039   (use (match_operand:BLK 1 "memory_operand"))
16040   (use (match_operand:SWI48 2 "nonmemory_operand"))
16041   (use (match_operand:SWI48 3 "const_int_operand"))
16042   (use (match_operand:SI 4 "const_int_operand"))
16043   (use (match_operand:SI 5 "const_int_operand"))
16044   (use (match_operand:SI 6 ""))
16045   (use (match_operand:SI 7 ""))
16046   (use (match_operand:SI 8 ""))]
16047  ""
16048{
16049 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16050			        operands[2], NULL, operands[3],
16051			        operands[4], operands[5],
16052				operands[6], operands[7],
16053				operands[8], false))
16054   DONE;
16055 else
16056   FAIL;
16057})
16058
16059;; Most CPUs don't like single string operations
16060;; Handle this case here to simplify previous expander.
16061
16062(define_expand "strmov"
16063  [(set (match_dup 4) (match_operand 3 "memory_operand"))
16064   (set (match_operand 1 "memory_operand") (match_dup 4))
16065   (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16066	      (clobber (reg:CC FLAGS_REG))])
16067   (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16068	      (clobber (reg:CC FLAGS_REG))])]
16069  ""
16070{
16071  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16072
16073  /* If .md ever supports :P for Pmode, these can be directly
16074     in the pattern above.  */
16075  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16076  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16077
16078  /* Can't use this if the user has appropriated esi or edi.  */
16079  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16080      && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16081    {
16082      emit_insn (gen_strmov_singleop (operands[0], operands[1],
16083				      operands[2], operands[3],
16084				      operands[5], operands[6]));
16085      DONE;
16086    }
16087
16088  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16089})
16090
16091(define_expand "strmov_singleop"
16092  [(parallel [(set (match_operand 1 "memory_operand")
16093		   (match_operand 3 "memory_operand"))
16094	      (set (match_operand 0 "register_operand")
16095		   (match_operand 4))
16096	      (set (match_operand 2 "register_operand")
16097		   (match_operand 5))])]
16098  ""
16099  "ix86_current_function_needs_cld = 1;")
16100
16101(define_insn "*strmovdi_rex_1"
16102  [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16103	(mem:DI (match_operand:P 3 "register_operand" "1")))
16104   (set (match_operand:P 0 "register_operand" "=D")
16105	(plus:P (match_dup 2)
16106		(const_int 8)))
16107   (set (match_operand:P 1 "register_operand" "=S")
16108	(plus:P (match_dup 3)
16109		(const_int 8)))]
16110  "TARGET_64BIT
16111   && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16112  "%^movsq"
16113  [(set_attr "type" "str")
16114   (set_attr "memory" "both")
16115   (set_attr "mode" "DI")])
16116
16117(define_insn "*strmovsi_1"
16118  [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16119	(mem:SI (match_operand:P 3 "register_operand" "1")))
16120   (set (match_operand:P 0 "register_operand" "=D")
16121	(plus:P (match_dup 2)
16122		(const_int 4)))
16123   (set (match_operand:P 1 "register_operand" "=S")
16124	(plus:P (match_dup 3)
16125		(const_int 4)))]
16126  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16127  "%^movs{l|d}"
16128  [(set_attr "type" "str")
16129   (set_attr "memory" "both")
16130   (set_attr "mode" "SI")])
16131
16132(define_insn "*strmovhi_1"
16133  [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16134	(mem:HI (match_operand:P 3 "register_operand" "1")))
16135   (set (match_operand:P 0 "register_operand" "=D")
16136	(plus:P (match_dup 2)
16137		(const_int 2)))
16138   (set (match_operand:P 1 "register_operand" "=S")
16139	(plus:P (match_dup 3)
16140		(const_int 2)))]
16141  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16142  "%^movsw"
16143  [(set_attr "type" "str")
16144   (set_attr "memory" "both")
16145   (set_attr "mode" "HI")])
16146
16147(define_insn "*strmovqi_1"
16148  [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16149	(mem:QI (match_operand:P 3 "register_operand" "1")))
16150   (set (match_operand:P 0 "register_operand" "=D")
16151	(plus:P (match_dup 2)
16152		(const_int 1)))
16153   (set (match_operand:P 1 "register_operand" "=S")
16154	(plus:P (match_dup 3)
16155		(const_int 1)))]
16156  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16157  "%^movsb"
16158  [(set_attr "type" "str")
16159   (set_attr "memory" "both")
16160   (set (attr "prefix_rex")
16161	(if_then_else
16162	  (match_test "<P:MODE>mode == DImode")
16163	  (const_string "0")
16164	  (const_string "*")))
16165   (set_attr "mode" "QI")])
16166
16167(define_expand "rep_mov"
16168  [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16169	      (set (match_operand 0 "register_operand")
16170		   (match_operand 5))
16171	      (set (match_operand 2 "register_operand")
16172		   (match_operand 6))
16173	      (set (match_operand 1 "memory_operand")
16174		   (match_operand 3 "memory_operand"))
16175	      (use (match_dup 4))])]
16176  ""
16177  "ix86_current_function_needs_cld = 1;")
16178
16179(define_insn "*rep_movdi_rex64"
16180  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16181   (set (match_operand:P 0 "register_operand" "=D")
16182        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16183			  (const_int 3))
16184		(match_operand:P 3 "register_operand" "0")))
16185   (set (match_operand:P 1 "register_operand" "=S")
16186        (plus:P (ashift:P (match_dup 5) (const_int 3))
16187		(match_operand:P 4 "register_operand" "1")))
16188   (set (mem:BLK (match_dup 3))
16189	(mem:BLK (match_dup 4)))
16190   (use (match_dup 5))]
16191  "TARGET_64BIT
16192   && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16193  "%^rep{%;} movsq"
16194  [(set_attr "type" "str")
16195   (set_attr "prefix_rep" "1")
16196   (set_attr "memory" "both")
16197   (set_attr "mode" "DI")])
16198
16199(define_insn "*rep_movsi"
16200  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16201   (set (match_operand:P 0 "register_operand" "=D")
16202        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16203			  (const_int 2))
16204		 (match_operand:P 3 "register_operand" "0")))
16205   (set (match_operand:P 1 "register_operand" "=S")
16206        (plus:P (ashift:P (match_dup 5) (const_int 2))
16207		(match_operand:P 4 "register_operand" "1")))
16208   (set (mem:BLK (match_dup 3))
16209	(mem:BLK (match_dup 4)))
16210   (use (match_dup 5))]
16211  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16212  "%^rep{%;} movs{l|d}"
16213  [(set_attr "type" "str")
16214   (set_attr "prefix_rep" "1")
16215   (set_attr "memory" "both")
16216   (set_attr "mode" "SI")])
16217
16218(define_insn "*rep_movqi"
16219  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16220   (set (match_operand:P 0 "register_operand" "=D")
16221        (plus:P (match_operand:P 3 "register_operand" "0")
16222		(match_operand:P 5 "register_operand" "2")))
16223   (set (match_operand:P 1 "register_operand" "=S")
16224        (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16225   (set (mem:BLK (match_dup 3))
16226	(mem:BLK (match_dup 4)))
16227   (use (match_dup 5))]
16228  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16229  "%^rep{%;} movsb"
16230  [(set_attr "type" "str")
16231   (set_attr "prefix_rep" "1")
16232   (set_attr "memory" "both")
16233   (set_attr "mode" "QI")])
16234
16235(define_expand "setmem<mode>"
16236   [(use (match_operand:BLK 0 "memory_operand"))
16237    (use (match_operand:SWI48 1 "nonmemory_operand"))
16238    (use (match_operand:QI 2 "nonmemory_operand"))
16239    (use (match_operand 3 "const_int_operand"))
16240    (use (match_operand:SI 4 "const_int_operand"))
16241    (use (match_operand:SI 5 "const_int_operand"))
16242    (use (match_operand:SI 6 ""))
16243    (use (match_operand:SI 7 ""))
16244    (use (match_operand:SI 8 ""))]
16245  ""
16246{
16247 if (ix86_expand_set_or_movmem (operands[0], NULL,
16248			        operands[1], operands[2],
16249				operands[3], operands[4],
16250			        operands[5], operands[6],
16251				operands[7], operands[8], true))
16252   DONE;
16253 else
16254   FAIL;
16255})
16256
16257;; Most CPUs don't like single string operations
16258;; Handle this case here to simplify previous expander.
16259
16260(define_expand "strset"
16261  [(set (match_operand 1 "memory_operand")
16262	(match_operand 2 "register_operand"))
16263   (parallel [(set (match_operand 0 "register_operand")
16264		   (match_dup 3))
16265	      (clobber (reg:CC FLAGS_REG))])]
16266  ""
16267{
16268  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16269    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16270
16271  /* If .md ever supports :P for Pmode, this can be directly
16272     in the pattern above.  */
16273  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16274			      GEN_INT (GET_MODE_SIZE (GET_MODE
16275						      (operands[2]))));
16276  /* Can't use this if the user has appropriated eax or edi.  */
16277  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16278      && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16279    {
16280      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16281				      operands[3]));
16282      DONE;
16283    }
16284})
16285
16286(define_expand "strset_singleop"
16287  [(parallel [(set (match_operand 1 "memory_operand")
16288		   (match_operand 2 "register_operand"))
16289	      (set (match_operand 0 "register_operand")
16290		   (match_operand 3))
16291	      (unspec [(const_int 0)] UNSPEC_STOS)])]
16292  ""
16293  "ix86_current_function_needs_cld = 1;")
16294
16295(define_insn "*strsetdi_rex_1"
16296  [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16297	(match_operand:DI 2 "register_operand" "a"))
16298   (set (match_operand:P 0 "register_operand" "=D")
16299	(plus:P (match_dup 1)
16300		(const_int 8)))
16301   (unspec [(const_int 0)] UNSPEC_STOS)]
16302  "TARGET_64BIT
16303   && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16304  "%^stosq"
16305  [(set_attr "type" "str")
16306   (set_attr "memory" "store")
16307   (set_attr "mode" "DI")])
16308
16309(define_insn "*strsetsi_1"
16310  [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16311	(match_operand:SI 2 "register_operand" "a"))
16312   (set (match_operand:P 0 "register_operand" "=D")
16313	(plus:P (match_dup 1)
16314		(const_int 4)))
16315   (unspec [(const_int 0)] UNSPEC_STOS)]
16316  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16317  "%^stos{l|d}"
16318  [(set_attr "type" "str")
16319   (set_attr "memory" "store")
16320   (set_attr "mode" "SI")])
16321
16322(define_insn "*strsethi_1"
16323  [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16324	(match_operand:HI 2 "register_operand" "a"))
16325   (set (match_operand:P 0 "register_operand" "=D")
16326	(plus:P (match_dup 1)
16327		(const_int 2)))
16328   (unspec [(const_int 0)] UNSPEC_STOS)]
16329  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16330  "%^stosw"
16331  [(set_attr "type" "str")
16332   (set_attr "memory" "store")
16333   (set_attr "mode" "HI")])
16334
16335(define_insn "*strsetqi_1"
16336  [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16337	(match_operand:QI 2 "register_operand" "a"))
16338   (set (match_operand:P 0 "register_operand" "=D")
16339	(plus:P (match_dup 1)
16340		(const_int 1)))
16341   (unspec [(const_int 0)] UNSPEC_STOS)]
16342  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16343  "%^stosb"
16344  [(set_attr "type" "str")
16345   (set_attr "memory" "store")
16346   (set (attr "prefix_rex")
16347	(if_then_else
16348	  (match_test "<P:MODE>mode == DImode")
16349	  (const_string "0")
16350	  (const_string "*")))
16351   (set_attr "mode" "QI")])
16352
16353(define_expand "rep_stos"
16354  [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16355	      (set (match_operand 0 "register_operand")
16356		   (match_operand 4))
16357	      (set (match_operand 2 "memory_operand") (const_int 0))
16358	      (use (match_operand 3 "register_operand"))
16359	      (use (match_dup 1))])]
16360  ""
16361  "ix86_current_function_needs_cld = 1;")
16362
16363(define_insn "*rep_stosdi_rex64"
16364  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16365   (set (match_operand:P 0 "register_operand" "=D")
16366        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16367			  (const_int 3))
16368		 (match_operand:P 3 "register_operand" "0")))
16369   (set (mem:BLK (match_dup 3))
16370	(const_int 0))
16371   (use (match_operand:DI 2 "register_operand" "a"))
16372   (use (match_dup 4))]
16373  "TARGET_64BIT
16374   && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16375  "%^rep{%;} stosq"
16376  [(set_attr "type" "str")
16377   (set_attr "prefix_rep" "1")
16378   (set_attr "memory" "store")
16379   (set_attr "mode" "DI")])
16380
16381(define_insn "*rep_stossi"
16382  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16383   (set (match_operand:P 0 "register_operand" "=D")
16384        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16385			  (const_int 2))
16386		 (match_operand:P 3 "register_operand" "0")))
16387   (set (mem:BLK (match_dup 3))
16388	(const_int 0))
16389   (use (match_operand:SI 2 "register_operand" "a"))
16390   (use (match_dup 4))]
16391  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16392  "%^rep{%;} stos{l|d}"
16393  [(set_attr "type" "str")
16394   (set_attr "prefix_rep" "1")
16395   (set_attr "memory" "store")
16396   (set_attr "mode" "SI")])
16397
16398(define_insn "*rep_stosqi"
16399  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16400   (set (match_operand:P 0 "register_operand" "=D")
16401        (plus:P (match_operand:P 3 "register_operand" "0")
16402		(match_operand:P 4 "register_operand" "1")))
16403   (set (mem:BLK (match_dup 3))
16404	(const_int 0))
16405   (use (match_operand:QI 2 "register_operand" "a"))
16406   (use (match_dup 4))]
16407  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16408  "%^rep{%;} stosb"
16409  [(set_attr "type" "str")
16410   (set_attr "prefix_rep" "1")
16411   (set_attr "memory" "store")
16412   (set (attr "prefix_rex")
16413	(if_then_else
16414	  (match_test "<P:MODE>mode == DImode")
16415	  (const_string "0")
16416	  (const_string "*")))
16417   (set_attr "mode" "QI")])
16418
16419(define_expand "cmpstrnsi"
16420  [(set (match_operand:SI 0 "register_operand")
16421	(compare:SI (match_operand:BLK 1 "general_operand")
16422		    (match_operand:BLK 2 "general_operand")))
16423   (use (match_operand 3 "general_operand"))
16424   (use (match_operand 4 "immediate_operand"))]
16425  ""
16426{
16427  rtx addr1, addr2, out, outlow, count, countreg, align;
16428
16429  if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16430    FAIL;
16431
16432  /* Can't use this if the user has appropriated ecx, esi or edi.  */
16433  if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16434    FAIL;
16435
16436  out = operands[0];
16437  if (!REG_P (out))
16438    out = gen_reg_rtx (SImode);
16439
16440  addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16441  addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16442  if (addr1 != XEXP (operands[1], 0))
16443    operands[1] = replace_equiv_address_nv (operands[1], addr1);
16444  if (addr2 != XEXP (operands[2], 0))
16445    operands[2] = replace_equiv_address_nv (operands[2], addr2);
16446
16447  count = operands[3];
16448  countreg = ix86_zero_extend_to_Pmode (count);
16449
16450  /* %%% Iff we are testing strict equality, we can use known alignment
16451     to good advantage.  This may be possible with combine, particularly
16452     once cc0 is dead.  */
16453  align = operands[4];
16454
16455  if (CONST_INT_P (count))
16456    {
16457      if (INTVAL (count) == 0)
16458	{
16459	  emit_move_insn (operands[0], const0_rtx);
16460	  DONE;
16461	}
16462      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16463				     operands[1], operands[2]));
16464    }
16465  else
16466    {
16467      rtx (*gen_cmp) (rtx, rtx);
16468
16469      gen_cmp = (TARGET_64BIT
16470		 ? gen_cmpdi_1 : gen_cmpsi_1);
16471
16472      emit_insn (gen_cmp (countreg, countreg));
16473      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16474				  operands[1], operands[2]));
16475    }
16476
16477  outlow = gen_lowpart (QImode, out);
16478  emit_insn (gen_cmpintqi (outlow));
16479  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16480
16481  if (operands[0] != out)
16482    emit_move_insn (operands[0], out);
16483
16484  DONE;
16485})
16486
16487;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16488
16489(define_expand "cmpintqi"
16490  [(set (match_dup 1)
16491	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16492   (set (match_dup 2)
16493	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16494   (parallel [(set (match_operand:QI 0 "register_operand")
16495		   (minus:QI (match_dup 1)
16496			     (match_dup 2)))
16497	      (clobber (reg:CC FLAGS_REG))])]
16498  ""
16499{
16500  operands[1] = gen_reg_rtx (QImode);
16501  operands[2] = gen_reg_rtx (QImode);
16502})
16503
16504;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16505;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16506
16507(define_expand "cmpstrnqi_nz_1"
16508  [(parallel [(set (reg:CC FLAGS_REG)
16509		   (compare:CC (match_operand 4 "memory_operand")
16510			       (match_operand 5 "memory_operand")))
16511	      (use (match_operand 2 "register_operand"))
16512	      (use (match_operand:SI 3 "immediate_operand"))
16513	      (clobber (match_operand 0 "register_operand"))
16514	      (clobber (match_operand 1 "register_operand"))
16515	      (clobber (match_dup 2))])]
16516  ""
16517  "ix86_current_function_needs_cld = 1;")
16518
16519(define_insn "*cmpstrnqi_nz_1"
16520  [(set (reg:CC FLAGS_REG)
16521	(compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16522		    (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16523   (use (match_operand:P 6 "register_operand" "2"))
16524   (use (match_operand:SI 3 "immediate_operand" "i"))
16525   (clobber (match_operand:P 0 "register_operand" "=S"))
16526   (clobber (match_operand:P 1 "register_operand" "=D"))
16527   (clobber (match_operand:P 2 "register_operand" "=c"))]
16528  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16529  "%^repz{%;} cmpsb"
16530  [(set_attr "type" "str")
16531   (set_attr "mode" "QI")
16532   (set (attr "prefix_rex")
16533	(if_then_else
16534	  (match_test "<P:MODE>mode == DImode")
16535	  (const_string "0")
16536	  (const_string "*")))
16537   (set_attr "prefix_rep" "1")])
16538
16539;; The same, but the count is not known to not be zero.
16540
16541(define_expand "cmpstrnqi_1"
16542  [(parallel [(set (reg:CC FLAGS_REG)
16543		(if_then_else:CC (ne (match_operand 2 "register_operand")
16544				     (const_int 0))
16545		  (compare:CC (match_operand 4 "memory_operand")
16546			      (match_operand 5 "memory_operand"))
16547		  (const_int 0)))
16548	      (use (match_operand:SI 3 "immediate_operand"))
16549	      (use (reg:CC FLAGS_REG))
16550	      (clobber (match_operand 0 "register_operand"))
16551	      (clobber (match_operand 1 "register_operand"))
16552	      (clobber (match_dup 2))])]
16553  ""
16554  "ix86_current_function_needs_cld = 1;")
16555
16556(define_insn "*cmpstrnqi_1"
16557  [(set (reg:CC FLAGS_REG)
16558	(if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16559			     (const_int 0))
16560	  (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16561		      (mem:BLK (match_operand:P 5 "register_operand" "1")))
16562	  (const_int 0)))
16563   (use (match_operand:SI 3 "immediate_operand" "i"))
16564   (use (reg:CC FLAGS_REG))
16565   (clobber (match_operand:P 0 "register_operand" "=S"))
16566   (clobber (match_operand:P 1 "register_operand" "=D"))
16567   (clobber (match_operand:P 2 "register_operand" "=c"))]
16568  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16569  "%^repz{%;} cmpsb"
16570  [(set_attr "type" "str")
16571   (set_attr "mode" "QI")
16572   (set (attr "prefix_rex")
16573	(if_then_else
16574	  (match_test "<P:MODE>mode == DImode")
16575	  (const_string "0")
16576	  (const_string "*")))
16577   (set_attr "prefix_rep" "1")])
16578
16579(define_expand "strlen<mode>"
16580  [(set (match_operand:P 0 "register_operand")
16581	(unspec:P [(match_operand:BLK 1 "general_operand")
16582		   (match_operand:QI 2 "immediate_operand")
16583		   (match_operand 3 "immediate_operand")]
16584		  UNSPEC_SCAS))]
16585  ""
16586{
16587 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16588   DONE;
16589 else
16590   FAIL;
16591})
16592
16593(define_expand "strlenqi_1"
16594  [(parallel [(set (match_operand 0 "register_operand")
16595		   (match_operand 2))
16596	      (clobber (match_operand 1 "register_operand"))
16597	      (clobber (reg:CC FLAGS_REG))])]
16598  ""
16599  "ix86_current_function_needs_cld = 1;")
16600
16601(define_insn "*strlenqi_1"
16602  [(set (match_operand:P 0 "register_operand" "=&c")
16603	(unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16604		   (match_operand:QI 2 "register_operand" "a")
16605		   (match_operand:P 3 "immediate_operand" "i")
16606		   (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16607   (clobber (match_operand:P 1 "register_operand" "=D"))
16608   (clobber (reg:CC FLAGS_REG))]
16609  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16610  "%^repnz{%;} scasb"
16611  [(set_attr "type" "str")
16612   (set_attr "mode" "QI")
16613   (set (attr "prefix_rex")
16614	(if_then_else
16615	  (match_test "<P:MODE>mode == DImode")
16616	  (const_string "0")
16617	  (const_string "*")))
16618   (set_attr "prefix_rep" "1")])
16619
16620;; Peephole optimizations to clean up after cmpstrn*.  This should be
16621;; handled in combine, but it is not currently up to the task.
16622;; When used for their truth value, the cmpstrn* expanders generate
16623;; code like this:
16624;;
16625;;   repz cmpsb
16626;;   seta 	%al
16627;;   setb 	%dl
16628;;   cmpb 	%al, %dl
16629;;   jcc	label
16630;;
16631;; The intermediate three instructions are unnecessary.
16632
16633;; This one handles cmpstrn*_nz_1...
16634(define_peephole2
16635  [(parallel[
16636     (set (reg:CC FLAGS_REG)
16637	  (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16638		      (mem:BLK (match_operand 5 "register_operand"))))
16639     (use (match_operand 6 "register_operand"))
16640     (use (match_operand:SI 3 "immediate_operand"))
16641     (clobber (match_operand 0 "register_operand"))
16642     (clobber (match_operand 1 "register_operand"))
16643     (clobber (match_operand 2 "register_operand"))])
16644   (set (match_operand:QI 7 "register_operand")
16645	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16646   (set (match_operand:QI 8 "register_operand")
16647	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16648   (set (reg FLAGS_REG)
16649	(compare (match_dup 7) (match_dup 8)))
16650  ]
16651  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16652  [(parallel[
16653     (set (reg:CC FLAGS_REG)
16654	  (compare:CC (mem:BLK (match_dup 4))
16655		      (mem:BLK (match_dup 5))))
16656     (use (match_dup 6))
16657     (use (match_dup 3))
16658     (clobber (match_dup 0))
16659     (clobber (match_dup 1))
16660     (clobber (match_dup 2))])])
16661
16662;; ...and this one handles cmpstrn*_1.
16663(define_peephole2
16664  [(parallel[
16665     (set (reg:CC FLAGS_REG)
16666	  (if_then_else:CC (ne (match_operand 6 "register_operand")
16667			       (const_int 0))
16668	    (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16669		        (mem:BLK (match_operand 5 "register_operand")))
16670	    (const_int 0)))
16671     (use (match_operand:SI 3 "immediate_operand"))
16672     (use (reg:CC FLAGS_REG))
16673     (clobber (match_operand 0 "register_operand"))
16674     (clobber (match_operand 1 "register_operand"))
16675     (clobber (match_operand 2 "register_operand"))])
16676   (set (match_operand:QI 7 "register_operand")
16677	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16678   (set (match_operand:QI 8 "register_operand")
16679	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16680   (set (reg FLAGS_REG)
16681	(compare (match_dup 7) (match_dup 8)))
16682  ]
16683  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16684  [(parallel[
16685     (set (reg:CC FLAGS_REG)
16686	  (if_then_else:CC (ne (match_dup 6)
16687			       (const_int 0))
16688	    (compare:CC (mem:BLK (match_dup 4))
16689			(mem:BLK (match_dup 5)))
16690	    (const_int 0)))
16691     (use (match_dup 3))
16692     (use (reg:CC FLAGS_REG))
16693     (clobber (match_dup 0))
16694     (clobber (match_dup 1))
16695     (clobber (match_dup 2))])])
16696
16697;; Conditional move instructions.
16698
16699(define_expand "mov<mode>cc"
16700  [(set (match_operand:SWIM 0 "register_operand")
16701	(if_then_else:SWIM (match_operand 1 "comparison_operator")
16702			   (match_operand:SWIM 2 "<general_operand>")
16703			   (match_operand:SWIM 3 "<general_operand>")))]
16704  ""
16705  "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16706
16707;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16708;; the register first winds up with `sbbl $0,reg', which is also weird.
16709;; So just document what we're doing explicitly.
16710
16711(define_expand "x86_mov<mode>cc_0_m1"
16712  [(parallel
16713    [(set (match_operand:SWI48 0 "register_operand")
16714	  (if_then_else:SWI48
16715	    (match_operator:SWI48 2 "ix86_carry_flag_operator"
16716	     [(match_operand 1 "flags_reg_operand")
16717	      (const_int 0)])
16718	    (const_int -1)
16719	    (const_int 0)))
16720     (clobber (reg:CC FLAGS_REG))])])
16721
16722(define_insn "*x86_mov<mode>cc_0_m1"
16723  [(set (match_operand:SWI48 0 "register_operand" "=r")
16724	(if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16725			     [(reg FLAGS_REG) (const_int 0)])
16726	  (const_int -1)
16727	  (const_int 0)))
16728   (clobber (reg:CC FLAGS_REG))]
16729  ""
16730  "sbb{<imodesuffix>}\t%0, %0"
16731  ; Since we don't have the proper number of operands for an alu insn,
16732  ; fill in all the blanks.
16733  [(set_attr "type" "alu")
16734   (set_attr "use_carry" "1")
16735   (set_attr "pent_pair" "pu")
16736   (set_attr "memory" "none")
16737   (set_attr "imm_disp" "false")
16738   (set_attr "mode" "<MODE>")
16739   (set_attr "length_immediate" "0")])
16740
16741(define_insn "*x86_mov<mode>cc_0_m1_se"
16742  [(set (match_operand:SWI48 0 "register_operand" "=r")
16743	(sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16744			     [(reg FLAGS_REG) (const_int 0)])
16745			    (const_int 1)
16746			    (const_int 0)))
16747   (clobber (reg:CC FLAGS_REG))]
16748  ""
16749  "sbb{<imodesuffix>}\t%0, %0"
16750  [(set_attr "type" "alu")
16751   (set_attr "use_carry" "1")
16752   (set_attr "pent_pair" "pu")
16753   (set_attr "memory" "none")
16754   (set_attr "imm_disp" "false")
16755   (set_attr "mode" "<MODE>")
16756   (set_attr "length_immediate" "0")])
16757
16758(define_insn "*x86_mov<mode>cc_0_m1_neg"
16759  [(set (match_operand:SWI48 0 "register_operand" "=r")
16760	(neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16761		    [(reg FLAGS_REG) (const_int 0)])))
16762   (clobber (reg:CC FLAGS_REG))]
16763  ""
16764  "sbb{<imodesuffix>}\t%0, %0"
16765  [(set_attr "type" "alu")
16766   (set_attr "use_carry" "1")
16767   (set_attr "pent_pair" "pu")
16768   (set_attr "memory" "none")
16769   (set_attr "imm_disp" "false")
16770   (set_attr "mode" "<MODE>")
16771   (set_attr "length_immediate" "0")])
16772
16773(define_insn "*mov<mode>cc_noc"
16774  [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16775	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16776			       [(reg FLAGS_REG) (const_int 0)])
16777	  (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16778	  (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16779  "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16780  "@
16781   cmov%O2%C1\t{%2, %0|%0, %2}
16782   cmov%O2%c1\t{%3, %0|%0, %3}"
16783  [(set_attr "type" "icmov")
16784   (set_attr "mode" "<MODE>")])
16785
16786;; Don't do conditional moves with memory inputs.  This splitter helps
16787;; register starved x86_32 by forcing inputs into registers before reload.
16788(define_split
16789  [(set (match_operand:SWI248 0 "register_operand")
16790	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16791			       [(reg FLAGS_REG) (const_int 0)])
16792	  (match_operand:SWI248 2 "nonimmediate_operand")
16793	  (match_operand:SWI248 3 "nonimmediate_operand")))]
16794  "!TARGET_64BIT && TARGET_CMOVE
16795   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16796   && (MEM_P (operands[2]) || MEM_P (operands[3]))
16797   && can_create_pseudo_p ()
16798   && optimize_insn_for_speed_p ()"
16799  [(set (match_dup 0)
16800	(if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16801{
16802  if (MEM_P (operands[2]))
16803    operands[2] = force_reg (<MODE>mode, operands[2]);
16804  if (MEM_P (operands[3]))
16805    operands[3] = force_reg (<MODE>mode, operands[3]);
16806})
16807
16808(define_insn "*movqicc_noc"
16809  [(set (match_operand:QI 0 "register_operand" "=r,r")
16810	(if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16811			   [(reg FLAGS_REG) (const_int 0)])
16812		      (match_operand:QI 2 "register_operand" "r,0")
16813		      (match_operand:QI 3 "register_operand" "0,r")))]
16814  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16815  "#"
16816  [(set_attr "type" "icmov")
16817   (set_attr "mode" "QI")])
16818
16819(define_split
16820  [(set (match_operand:SWI12 0 "register_operand")
16821	(if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16822			      [(reg FLAGS_REG) (const_int 0)])
16823		      (match_operand:SWI12 2 "register_operand")
16824		      (match_operand:SWI12 3 "register_operand")))]
16825  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16826   && reload_completed"
16827  [(set (match_dup 0)
16828	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16829{
16830  operands[0] = gen_lowpart (SImode, operands[0]);
16831  operands[2] = gen_lowpart (SImode, operands[2]);
16832  operands[3] = gen_lowpart (SImode, operands[3]);
16833})
16834
16835;; Don't do conditional moves with memory inputs
16836(define_peephole2
16837  [(match_scratch:SWI248 2 "r")
16838   (set (match_operand:SWI248 0 "register_operand")
16839	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16840			       [(reg FLAGS_REG) (const_int 0)])
16841	  (match_dup 0)
16842	  (match_operand:SWI248 3 "memory_operand")))]
16843  "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16844   && optimize_insn_for_speed_p ()"
16845  [(set (match_dup 2) (match_dup 3))
16846   (set (match_dup 0)
16847	(if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16848
16849(define_peephole2
16850  [(match_scratch:SWI248 2 "r")
16851   (set (match_operand:SWI248 0 "register_operand")
16852	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16853			       [(reg FLAGS_REG) (const_int 0)])
16854	  (match_operand:SWI248 3 "memory_operand")
16855	  (match_dup 0)))]
16856  "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16857   && optimize_insn_for_speed_p ()"
16858  [(set (match_dup 2) (match_dup 3))
16859   (set (match_dup 0)
16860	(if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16861
16862(define_expand "mov<mode>cc"
16863  [(set (match_operand:X87MODEF 0 "register_operand")
16864	(if_then_else:X87MODEF
16865	  (match_operand 1 "comparison_operator")
16866	  (match_operand:X87MODEF 2 "register_operand")
16867	  (match_operand:X87MODEF 3 "register_operand")))]
16868  "(TARGET_80387 && TARGET_CMOVE)
16869   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16870  "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16871
16872(define_insn "*movxfcc_1"
16873  [(set (match_operand:XF 0 "register_operand" "=f,f")
16874	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16875				[(reg FLAGS_REG) (const_int 0)])
16876		      (match_operand:XF 2 "register_operand" "f,0")
16877		      (match_operand:XF 3 "register_operand" "0,f")))]
16878  "TARGET_80387 && TARGET_CMOVE"
16879  "@
16880   fcmov%F1\t{%2, %0|%0, %2}
16881   fcmov%f1\t{%3, %0|%0, %3}"
16882  [(set_attr "type" "fcmov")
16883   (set_attr "mode" "XF")])
16884
16885(define_insn "*movdfcc_1"
16886  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16887	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16888				[(reg FLAGS_REG) (const_int 0)])
16889		      (match_operand:DF 2 "nonimmediate_operand"
16890					       "f ,0,rm,0 ,rm,0")
16891		      (match_operand:DF 3 "nonimmediate_operand"
16892					       "0 ,f,0 ,rm,0, rm")))]
16893  "TARGET_80387 && TARGET_CMOVE
16894   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16895  "@
16896   fcmov%F1\t{%2, %0|%0, %2}
16897   fcmov%f1\t{%3, %0|%0, %3}
16898   #
16899   #
16900   cmov%O2%C1\t{%2, %0|%0, %2}
16901   cmov%O2%c1\t{%3, %0|%0, %3}"
16902  [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16903   (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16904   (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16905
16906(define_split
16907  [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16908	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16909				[(reg FLAGS_REG) (const_int 0)])
16910		      (match_operand:DF 2 "nonimmediate_operand")
16911		      (match_operand:DF 3 "nonimmediate_operand")))]
16912  "!TARGET_64BIT && reload_completed"
16913  [(set (match_dup 2)
16914	(if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16915   (set (match_dup 3)
16916	(if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16917{
16918  split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16919  split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16920})
16921
16922(define_insn "*movsfcc_1_387"
16923  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16924	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16925				[(reg FLAGS_REG) (const_int 0)])
16926		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16927		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16928  "TARGET_80387 && TARGET_CMOVE
16929   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16930  "@
16931   fcmov%F1\t{%2, %0|%0, %2}
16932   fcmov%f1\t{%3, %0|%0, %3}
16933   cmov%O2%C1\t{%2, %0|%0, %2}
16934   cmov%O2%c1\t{%3, %0|%0, %3}"
16935  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16936   (set_attr "mode" "SF,SF,SI,SI")])
16937
16938;; Don't do conditional moves with memory inputs.  This splitter helps
16939;; register starved x86_32 by forcing inputs into registers before reload.
16940(define_split
16941  [(set (match_operand:MODEF 0 "register_operand")
16942	(if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16943			      [(reg FLAGS_REG) (const_int 0)])
16944	  (match_operand:MODEF 2 "nonimmediate_operand")
16945	  (match_operand:MODEF 3 "nonimmediate_operand")))]
16946  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16947   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16948   && (MEM_P (operands[2]) || MEM_P (operands[3]))
16949   && can_create_pseudo_p ()
16950   && optimize_insn_for_speed_p ()"
16951  [(set (match_dup 0)
16952	(if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16953{
16954  if (MEM_P (operands[2]))
16955    operands[2] = force_reg (<MODE>mode, operands[2]);
16956  if (MEM_P (operands[3]))
16957    operands[3] = force_reg (<MODE>mode, operands[3]);
16958})
16959
16960;; Don't do conditional moves with memory inputs
16961(define_peephole2
16962  [(match_scratch:MODEF 2 "r")
16963   (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16964	(if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16965			      [(reg FLAGS_REG) (const_int 0)])
16966	  (match_dup 0)
16967	  (match_operand:MODEF 3 "memory_operand")))]
16968  "(<MODE>mode != DFmode || TARGET_64BIT)
16969   && TARGET_80387 && TARGET_CMOVE
16970   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16971   && optimize_insn_for_speed_p ()"
16972  [(set (match_dup 2) (match_dup 3))
16973   (set (match_dup 0)
16974	(if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16975
16976(define_peephole2
16977  [(match_scratch:MODEF 2 "r")
16978   (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16979	(if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16980			      [(reg FLAGS_REG) (const_int 0)])
16981	  (match_operand:MODEF 3 "memory_operand")
16982	  (match_dup 0)))]
16983  "(<MODE>mode != DFmode || TARGET_64BIT)
16984   && TARGET_80387 && TARGET_CMOVE
16985   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16986   && optimize_insn_for_speed_p ()"
16987  [(set (match_dup 2) (match_dup 3))
16988   (set (match_dup 0)
16989	(if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16990
16991;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16992;; the scalar versions to have only XMM registers as operands.
16993
16994;; XOP conditional move
16995(define_insn "*xop_pcmov_<mode>"
16996  [(set (match_operand:MODEF 0 "register_operand" "=x")
16997	(if_then_else:MODEF
16998	  (match_operand:MODEF 1 "register_operand" "x")
16999	  (match_operand:MODEF 2 "register_operand" "x")
17000	  (match_operand:MODEF 3 "register_operand" "x")))]
17001  "TARGET_XOP"
17002  "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17003  [(set_attr "type" "sse4arg")])
17004
17005;; These versions of the min/max patterns are intentionally ignorant of
17006;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17007;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17008;; are undefined in this condition, we're certain this is correct.
17009
17010(define_insn "<code><mode>3"
17011  [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17012	(smaxmin:MODEF
17013	  (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17014	  (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17015  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17016  "@
17017   <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17018   v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17019  [(set_attr "isa" "noavx,avx")
17020   (set_attr "prefix" "orig,vex")
17021   (set_attr "type" "sseadd")
17022   (set_attr "mode" "<MODE>")])
17023
17024;; These versions of the min/max patterns implement exactly the operations
17025;;   min = (op1 < op2 ? op1 : op2)
17026;;   max = (!(op1 < op2) ? op1 : op2)
17027;; Their operands are not commutative, and thus they may be used in the
17028;; presence of -0.0 and NaN.
17029
17030(define_int_iterator IEEE_MAXMIN
17031	[UNSPEC_IEEE_MAX
17032	 UNSPEC_IEEE_MIN])
17033
17034(define_int_attr ieee_maxmin
17035	[(UNSPEC_IEEE_MAX "max")
17036	 (UNSPEC_IEEE_MIN "min")])
17037
17038(define_insn "*ieee_s<ieee_maxmin><mode>3"
17039  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
17040	(unspec:MODEF
17041	  [(match_operand:MODEF 1 "register_operand" "0,x")
17042	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
17043	  IEEE_MAXMIN))]
17044  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17045  "@
17046   <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17047   v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17048  [(set_attr "isa" "noavx,avx")
17049   (set_attr "prefix" "orig,vex")
17050   (set_attr "type" "sseadd")
17051   (set_attr "mode" "<MODE>")])
17052
17053;; Make two stack loads independent:
17054;;   fld aa              fld aa
17055;;   fld %st(0)     ->   fld bb
17056;;   fmul bb             fmul %st(1), %st
17057;;
17058;; Actually we only match the last two instructions for simplicity.
17059(define_peephole2
17060  [(set (match_operand 0 "fp_register_operand")
17061	(match_operand 1 "fp_register_operand"))
17062   (set (match_dup 0)
17063	(match_operator 2 "binary_fp_operator"
17064	   [(match_dup 0)
17065	    (match_operand 3 "memory_operand")]))]
17066  "REGNO (operands[0]) != REGNO (operands[1])"
17067  [(set (match_dup 0) (match_dup 3))
17068   (set (match_dup 0) (match_dup 4))]
17069
17070  ;; The % modifier is not operational anymore in peephole2's, so we have to
17071  ;; swap the operands manually in the case of addition and multiplication.
17072{
17073  rtx op0, op1;
17074
17075  if (COMMUTATIVE_ARITH_P (operands[2]))
17076    op0 = operands[0], op1 = operands[1];
17077  else
17078    op0 = operands[1], op1 = operands[0];
17079
17080  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
17081				GET_MODE (operands[2]),
17082				op0, op1);
17083})
17084
17085;; Conditional addition patterns
17086(define_expand "add<mode>cc"
17087  [(match_operand:SWI 0 "register_operand")
17088   (match_operand 1 "ordered_comparison_operator")
17089   (match_operand:SWI 2 "register_operand")
17090   (match_operand:SWI 3 "const_int_operand")]
17091  ""
17092  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17093
17094;; Misc patterns (?)
17095
17096;; This pattern exists to put a dependency on all ebp-based memory accesses.
17097;; Otherwise there will be nothing to keep
17098;;
17099;; [(set (reg ebp) (reg esp))]
17100;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17101;;  (clobber (eflags)]
17102;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17103;;
17104;; in proper program order.
17105
17106(define_insn "pro_epilogue_adjust_stack_<mode>_add"
17107  [(set (match_operand:P 0 "register_operand" "=r,r")
17108	(plus:P (match_operand:P 1 "register_operand" "0,r")
17109	        (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17110   (clobber (reg:CC FLAGS_REG))
17111   (clobber (mem:BLK (scratch)))]
17112  ""
17113{
17114  switch (get_attr_type (insn))
17115    {
17116    case TYPE_IMOV:
17117      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17118
17119    case TYPE_ALU:
17120      gcc_assert (rtx_equal_p (operands[0], operands[1]));
17121      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17122	return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17123
17124      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17125
17126    default:
17127      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17128      return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17129    }
17130}
17131  [(set (attr "type")
17132	(cond [(and (eq_attr "alternative" "0")
17133		    (not (match_test "TARGET_OPT_AGU")))
17134		 (const_string "alu")
17135	       (match_operand:<MODE> 2 "const0_operand")
17136		 (const_string "imov")
17137	      ]
17138	      (const_string "lea")))
17139   (set (attr "length_immediate")
17140	(cond [(eq_attr "type" "imov")
17141		 (const_string "0")
17142	       (and (eq_attr "type" "alu")
17143		    (match_operand 2 "const128_operand"))
17144		 (const_string "1")
17145	      ]
17146	      (const_string "*")))
17147   (set_attr "mode" "<MODE>")])
17148
17149(define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17150  [(set (match_operand:P 0 "register_operand" "=r")
17151	(minus:P (match_operand:P 1 "register_operand" "0")
17152		 (match_operand:P 2 "register_operand" "r")))
17153   (clobber (reg:CC FLAGS_REG))
17154   (clobber (mem:BLK (scratch)))]
17155  ""
17156  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17157  [(set_attr "type" "alu")
17158   (set_attr "mode" "<MODE>")])
17159
17160(define_insn "allocate_stack_worker_probe_<mode>"
17161  [(set (match_operand:P 0 "register_operand" "=a")
17162	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17163			    UNSPECV_STACK_PROBE))
17164   (clobber (reg:CC FLAGS_REG))]
17165  "ix86_target_stack_probe ()"
17166  "call\t___chkstk_ms"
17167  [(set_attr "type" "multi")
17168   (set_attr "length" "5")])
17169
17170(define_expand "allocate_stack"
17171  [(match_operand 0 "register_operand")
17172   (match_operand 1 "general_operand")]
17173  "ix86_target_stack_probe ()"
17174{
17175  rtx x;
17176
17177#ifndef CHECK_STACK_LIMIT
17178#define CHECK_STACK_LIMIT 0
17179#endif
17180
17181  if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17182      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17183    x = operands[1];
17184  else
17185    {
17186      rtx (*insn) (rtx, rtx);
17187
17188      x = copy_to_mode_reg (Pmode, operands[1]);
17189
17190      insn = (TARGET_64BIT
17191	      ? gen_allocate_stack_worker_probe_di
17192	      : gen_allocate_stack_worker_probe_si);
17193
17194      emit_insn (insn (x, x));
17195    }
17196
17197  x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17198			   stack_pointer_rtx, 0, OPTAB_DIRECT);
17199
17200  if (x != stack_pointer_rtx)
17201    emit_move_insn (stack_pointer_rtx, x);
17202
17203  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17204  DONE;
17205})
17206
17207;; Use IOR for stack probes, this is shorter.
17208(define_expand "probe_stack"
17209  [(match_operand 0 "memory_operand")]
17210  ""
17211{
17212  rtx (*gen_ior3) (rtx, rtx, rtx);
17213
17214  gen_ior3 = (GET_MODE (operands[0]) == DImode
17215	      ? gen_iordi3 : gen_iorsi3);
17216
17217  emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
17218  DONE;
17219})
17220
17221(define_insn "adjust_stack_and_probe<mode>"
17222  [(set (match_operand:P 0 "register_operand" "=r")
17223	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17224			    UNSPECV_PROBE_STACK_RANGE))
17225   (set (reg:P SP_REG)
17226        (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17227   (clobber (reg:CC FLAGS_REG))
17228   (clobber (mem:BLK (scratch)))]
17229  ""
17230  "* return output_adjust_stack_and_probe (operands[0]);"
17231  [(set_attr "type" "multi")])
17232
17233(define_insn "probe_stack_range<mode>"
17234  [(set (match_operand:P 0 "register_operand" "=r")
17235	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17236			    (match_operand:P 2 "const_int_operand" "n")]
17237			    UNSPECV_PROBE_STACK_RANGE))
17238   (clobber (reg:CC FLAGS_REG))]
17239  ""
17240  "* return output_probe_stack_range (operands[0], operands[2]);"
17241  [(set_attr "type" "multi")])
17242
17243(define_expand "builtin_setjmp_receiver"
17244  [(label_ref (match_operand 0))]
17245  "!TARGET_64BIT && flag_pic"
17246{
17247#if TARGET_MACHO
17248  if (TARGET_MACHO)
17249    {
17250      rtx xops[3];
17251      rtx_code_label *label_rtx = gen_label_rtx ();
17252      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17253      xops[0] = xops[1] = pic_offset_table_rtx;
17254      xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17255      ix86_expand_binary_operator (MINUS, SImode, xops);
17256    }
17257  else
17258#endif
17259    emit_insn (gen_set_got (pic_offset_table_rtx));
17260  DONE;
17261})
17262
17263;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17264;; Do not split instructions with mask registers.
17265(define_split
17266  [(set (match_operand 0 "general_reg_operand")
17267	(match_operator 3 "promotable_binary_operator"
17268	   [(match_operand 1 "general_reg_operand")
17269	    (match_operand 2 "aligned_operand")]))
17270   (clobber (reg:CC FLAGS_REG))]
17271  "! TARGET_PARTIAL_REG_STALL && reload_completed
17272   && ((GET_MODE (operands[0]) == HImode
17273	&& ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17274            /* ??? next two lines just !satisfies_constraint_K (...) */
17275	    || !CONST_INT_P (operands[2])
17276	    || satisfies_constraint_K (operands[2])))
17277       || (GET_MODE (operands[0]) == QImode
17278	   && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17279  [(parallel [(set (match_dup 0)
17280		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17281	      (clobber (reg:CC FLAGS_REG))])]
17282{
17283  operands[0] = gen_lowpart (SImode, operands[0]);
17284  operands[1] = gen_lowpart (SImode, operands[1]);
17285  if (GET_CODE (operands[3]) != ASHIFT)
17286    operands[2] = gen_lowpart (SImode, operands[2]);
17287  operands[3] = shallow_copy_rtx (operands[3]);
17288  PUT_MODE (operands[3], SImode);
17289})
17290
17291; Promote the QImode tests, as i386 has encoding of the AND
17292; instruction with 32-bit sign-extended immediate and thus the
17293; instruction size is unchanged, except in the %eax case for
17294; which it is increased by one byte, hence the ! optimize_size.
17295(define_split
17296  [(set (match_operand 0 "flags_reg_operand")
17297	(match_operator 2 "compare_operator"
17298	  [(and (match_operand 3 "aligned_operand")
17299		(match_operand 4 "const_int_operand"))
17300	   (const_int 0)]))
17301   (set (match_operand 1 "register_operand")
17302	(and (match_dup 3) (match_dup 4)))]
17303  "! TARGET_PARTIAL_REG_STALL && reload_completed
17304   && optimize_insn_for_speed_p ()
17305   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17306       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17307   /* Ensure that the operand will remain sign-extended immediate.  */
17308   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17309  [(parallel [(set (match_dup 0)
17310		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17311			            (const_int 0)]))
17312	      (set (match_dup 1)
17313		   (and:SI (match_dup 3) (match_dup 4)))])]
17314{
17315  operands[4]
17316    = gen_int_mode (INTVAL (operands[4])
17317		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17318  operands[1] = gen_lowpart (SImode, operands[1]);
17319  operands[3] = gen_lowpart (SImode, operands[3]);
17320})
17321
17322; Don't promote the QImode tests, as i386 doesn't have encoding of
17323; the TEST instruction with 32-bit sign-extended immediate and thus
17324; the instruction size would at least double, which is not what we
17325; want even with ! optimize_size.
17326(define_split
17327  [(set (match_operand 0 "flags_reg_operand")
17328	(match_operator 1 "compare_operator"
17329	  [(and (match_operand:HI 2 "aligned_operand")
17330		(match_operand:HI 3 "const_int_operand"))
17331	   (const_int 0)]))]
17332  "! TARGET_PARTIAL_REG_STALL && reload_completed
17333   && ! TARGET_FAST_PREFIX
17334   && optimize_insn_for_speed_p ()
17335   /* Ensure that the operand will remain sign-extended immediate.  */
17336   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17337  [(set (match_dup 0)
17338	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17339		         (const_int 0)]))]
17340{
17341  operands[3]
17342    = gen_int_mode (INTVAL (operands[3])
17343		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17344  operands[2] = gen_lowpart (SImode, operands[2]);
17345})
17346
17347(define_split
17348  [(set (match_operand 0 "register_operand")
17349	(neg (match_operand 1 "register_operand")))
17350   (clobber (reg:CC FLAGS_REG))]
17351  "! TARGET_PARTIAL_REG_STALL && reload_completed
17352   && (GET_MODE (operands[0]) == HImode
17353       || (GET_MODE (operands[0]) == QImode
17354	   && (TARGET_PROMOTE_QImode
17355	       || optimize_insn_for_size_p ())))"
17356  [(parallel [(set (match_dup 0)
17357		   (neg:SI (match_dup 1)))
17358	      (clobber (reg:CC FLAGS_REG))])]
17359{
17360  operands[0] = gen_lowpart (SImode, operands[0]);
17361  operands[1] = gen_lowpart (SImode, operands[1]);
17362})
17363
17364;; Do not split instructions with mask regs.
17365(define_split
17366  [(set (match_operand 0 "general_reg_operand")
17367	(not (match_operand 1 "general_reg_operand")))]
17368  "! TARGET_PARTIAL_REG_STALL && reload_completed
17369   && (GET_MODE (operands[0]) == HImode
17370       || (GET_MODE (operands[0]) == QImode
17371	   && (TARGET_PROMOTE_QImode
17372	       || optimize_insn_for_size_p ())))"
17373  [(set (match_dup 0)
17374	(not:SI (match_dup 1)))]
17375{
17376  operands[0] = gen_lowpart (SImode, operands[0]);
17377  operands[1] = gen_lowpart (SImode, operands[1]);
17378})
17379
17380;; RTL Peephole optimizations, run before sched2.  These primarily look to
17381;; transform a complex memory operation into two memory to register operations.
17382
17383;; Don't push memory operands
17384(define_peephole2
17385  [(set (match_operand:SWI 0 "push_operand")
17386	(match_operand:SWI 1 "memory_operand"))
17387   (match_scratch:SWI 2 "<r>")]
17388  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17389   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17390  [(set (match_dup 2) (match_dup 1))
17391   (set (match_dup 0) (match_dup 2))])
17392
17393;; We need to handle SFmode only, because DFmode and XFmode are split to
17394;; SImode pushes.
17395(define_peephole2
17396  [(set (match_operand:SF 0 "push_operand")
17397	(match_operand:SF 1 "memory_operand"))
17398   (match_scratch:SF 2 "r")]
17399  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17400   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17401  [(set (match_dup 2) (match_dup 1))
17402   (set (match_dup 0) (match_dup 2))])
17403
17404;; Don't move an immediate directly to memory when the instruction
17405;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17406(define_peephole2
17407  [(match_scratch:SWI124 1 "<r>")
17408   (set (match_operand:SWI124 0 "memory_operand")
17409        (const_int 0))]
17410  "optimize_insn_for_speed_p ()
17411   && ((<MODE>mode == HImode
17412       && TARGET_LCP_STALL)
17413       || (!TARGET_USE_MOV0
17414          && TARGET_SPLIT_LONG_MOVES
17415          && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17416   && peep2_regno_dead_p (0, FLAGS_REG)"
17417  [(parallel [(set (match_dup 2) (const_int 0))
17418	      (clobber (reg:CC FLAGS_REG))])
17419   (set (match_dup 0) (match_dup 1))]
17420  "operands[2] = gen_lowpart (SImode, operands[1]);")
17421
17422(define_peephole2
17423  [(match_scratch:SWI124 2 "<r>")
17424   (set (match_operand:SWI124 0 "memory_operand")
17425        (match_operand:SWI124 1 "immediate_operand"))]
17426  "optimize_insn_for_speed_p ()
17427   && ((<MODE>mode == HImode
17428       && TARGET_LCP_STALL)
17429       || (TARGET_SPLIT_LONG_MOVES
17430          && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17431  [(set (match_dup 2) (match_dup 1))
17432   (set (match_dup 0) (match_dup 2))])
17433
17434;; Don't compare memory with zero, load and use a test instead.
17435(define_peephole2
17436  [(set (match_operand 0 "flags_reg_operand")
17437 	(match_operator 1 "compare_operator"
17438	  [(match_operand:SI 2 "memory_operand")
17439	   (const_int 0)]))
17440   (match_scratch:SI 3 "r")]
17441  "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17442  [(set (match_dup 3) (match_dup 2))
17443   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17444
17445;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17446;; Don't split NOTs with a displacement operand, because resulting XOR
17447;; will not be pairable anyway.
17448;;
17449;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17450;; represented using a modRM byte.  The XOR replacement is long decoded,
17451;; so this split helps here as well.
17452;;
17453;; Note: Can't do this as a regular split because we can't get proper
17454;; lifetime information then.
17455
17456(define_peephole2
17457  [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17458	(not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17459  "optimize_insn_for_speed_p ()
17460   && ((TARGET_NOT_UNPAIRABLE
17461	&& (!MEM_P (operands[0])
17462	    || !memory_displacement_operand (operands[0], <MODE>mode)))
17463       || (TARGET_NOT_VECTORMODE
17464	   && long_memory_operand (operands[0], <MODE>mode)))
17465   && peep2_regno_dead_p (0, FLAGS_REG)"
17466  [(parallel [(set (match_dup 0)
17467		   (xor:SWI124 (match_dup 1) (const_int -1)))
17468	      (clobber (reg:CC FLAGS_REG))])])
17469
17470;; Non pairable "test imm, reg" instructions can be translated to
17471;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17472;; byte opcode instead of two, have a short form for byte operands),
17473;; so do it for other CPUs as well.  Given that the value was dead,
17474;; this should not create any new dependencies.  Pass on the sub-word
17475;; versions if we're concerned about partial register stalls.
17476
17477(define_peephole2
17478  [(set (match_operand 0 "flags_reg_operand")
17479	(match_operator 1 "compare_operator"
17480	  [(and:SI (match_operand:SI 2 "register_operand")
17481		   (match_operand:SI 3 "immediate_operand"))
17482	   (const_int 0)]))]
17483  "ix86_match_ccmode (insn, CCNOmode)
17484   && (true_regnum (operands[2]) != AX_REG
17485       || satisfies_constraint_K (operands[3]))
17486   && peep2_reg_dead_p (1, operands[2])"
17487  [(parallel
17488     [(set (match_dup 0)
17489	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17490		            (const_int 0)]))
17491      (set (match_dup 2)
17492	   (and:SI (match_dup 2) (match_dup 3)))])])
17493
17494;; We don't need to handle HImode case, because it will be promoted to SImode
17495;; on ! TARGET_PARTIAL_REG_STALL
17496
17497(define_peephole2
17498  [(set (match_operand 0 "flags_reg_operand")
17499	(match_operator 1 "compare_operator"
17500	  [(and:QI (match_operand:QI 2 "register_operand")
17501		   (match_operand:QI 3 "immediate_operand"))
17502	   (const_int 0)]))]
17503  "! TARGET_PARTIAL_REG_STALL
17504   && ix86_match_ccmode (insn, CCNOmode)
17505   && true_regnum (operands[2]) != AX_REG
17506   && peep2_reg_dead_p (1, operands[2])"
17507  [(parallel
17508     [(set (match_dup 0)
17509	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17510		            (const_int 0)]))
17511      (set (match_dup 2)
17512	   (and:QI (match_dup 2) (match_dup 3)))])])
17513
17514(define_peephole2
17515  [(set (match_operand 0 "flags_reg_operand")
17516	(match_operator 1 "compare_operator"
17517	  [(and:SI
17518	     (zero_extract:SI
17519	       (match_operand 2 "ext_register_operand")
17520	       (const_int 8)
17521	       (const_int 8))
17522	     (match_operand 3 "const_int_operand"))
17523	   (const_int 0)]))]
17524  "! TARGET_PARTIAL_REG_STALL
17525   && ix86_match_ccmode (insn, CCNOmode)
17526   && true_regnum (operands[2]) != AX_REG
17527   && peep2_reg_dead_p (1, operands[2])"
17528  [(parallel [(set (match_dup 0)
17529		   (match_op_dup 1
17530		     [(and:SI
17531			(zero_extract:SI
17532			  (match_dup 2)
17533			  (const_int 8)
17534			  (const_int 8))
17535			(match_dup 3))
17536		      (const_int 0)]))
17537	      (set (zero_extract:SI (match_dup 2)
17538				    (const_int 8)
17539				    (const_int 8))
17540		   (and:SI
17541		     (zero_extract:SI
17542		       (match_dup 2)
17543		       (const_int 8)
17544		       (const_int 8))
17545		     (match_dup 3)))])])
17546
17547;; Don't do logical operations with memory inputs.
17548(define_peephole2
17549  [(match_scratch:SI 2 "r")
17550   (parallel [(set (match_operand:SI 0 "register_operand")
17551                   (match_operator:SI 3 "arith_or_logical_operator"
17552                     [(match_dup 0)
17553                      (match_operand:SI 1 "memory_operand")]))
17554              (clobber (reg:CC FLAGS_REG))])]
17555  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17556  [(set (match_dup 2) (match_dup 1))
17557   (parallel [(set (match_dup 0)
17558                   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17559              (clobber (reg:CC FLAGS_REG))])])
17560
17561(define_peephole2
17562  [(match_scratch:SI 2 "r")
17563   (parallel [(set (match_operand:SI 0 "register_operand")
17564                   (match_operator:SI 3 "arith_or_logical_operator"
17565                     [(match_operand:SI 1 "memory_operand")
17566                      (match_dup 0)]))
17567              (clobber (reg:CC FLAGS_REG))])]
17568  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17569  [(set (match_dup 2) (match_dup 1))
17570   (parallel [(set (match_dup 0)
17571                   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17572              (clobber (reg:CC FLAGS_REG))])])
17573
17574;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17575;; refers to the destination of the load!
17576
17577(define_peephole2
17578  [(set (match_operand:SI 0 "register_operand")
17579        (match_operand:SI 1 "register_operand"))
17580   (parallel [(set (match_dup 0)
17581                   (match_operator:SI 3 "commutative_operator"
17582                     [(match_dup 0)
17583                      (match_operand:SI 2 "memory_operand")]))
17584              (clobber (reg:CC FLAGS_REG))])]
17585  "REGNO (operands[0]) != REGNO (operands[1])
17586   && GENERAL_REGNO_P (REGNO (operands[0]))
17587   && GENERAL_REGNO_P (REGNO (operands[1]))"
17588  [(set (match_dup 0) (match_dup 4))
17589   (parallel [(set (match_dup 0)
17590                   (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17591              (clobber (reg:CC FLAGS_REG))])]
17592  "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17593
17594(define_peephole2
17595  [(set (match_operand 0 "register_operand")
17596        (match_operand 1 "register_operand"))
17597   (set (match_dup 0)
17598                   (match_operator 3 "commutative_operator"
17599                     [(match_dup 0)
17600                      (match_operand 2 "memory_operand")]))]
17601  "REGNO (operands[0]) != REGNO (operands[1])
17602   && ((MMX_REGNO_P (REGNO (operands[0]))
17603        && MMX_REGNO_P (REGNO (operands[1]))) 
17604       || (SSE_REGNO_P (REGNO (operands[0]))
17605           && SSE_REGNO_P (REGNO (operands[1]))))"
17606  [(set (match_dup 0) (match_dup 2))
17607   (set (match_dup 0)
17608        (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17609
17610; Don't do logical operations with memory outputs
17611;
17612; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17613; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17614; the same decoder scheduling characteristics as the original.
17615
17616(define_peephole2
17617  [(match_scratch:SI 2 "r")
17618   (parallel [(set (match_operand:SI 0 "memory_operand")
17619                   (match_operator:SI 3 "arith_or_logical_operator"
17620                     [(match_dup 0)
17621                      (match_operand:SI 1 "nonmemory_operand")]))
17622              (clobber (reg:CC FLAGS_REG))])]
17623  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17624   /* Do not split stack checking probes.  */
17625   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17626  [(set (match_dup 2) (match_dup 0))
17627   (parallel [(set (match_dup 2)
17628                   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17629              (clobber (reg:CC FLAGS_REG))])
17630   (set (match_dup 0) (match_dup 2))])
17631
17632(define_peephole2
17633  [(match_scratch:SI 2 "r")
17634   (parallel [(set (match_operand:SI 0 "memory_operand")
17635                   (match_operator:SI 3 "arith_or_logical_operator"
17636                     [(match_operand:SI 1 "nonmemory_operand")
17637                      (match_dup 0)]))
17638              (clobber (reg:CC FLAGS_REG))])]
17639  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17640   /* Do not split stack checking probes.  */
17641   && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17642  [(set (match_dup 2) (match_dup 0))
17643   (parallel [(set (match_dup 2)
17644                   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17645              (clobber (reg:CC FLAGS_REG))])
17646   (set (match_dup 0) (match_dup 2))])
17647
17648;; Attempt to use arith or logical operations with memory outputs with
17649;; setting of flags.
17650(define_peephole2
17651  [(set (match_operand:SWI 0 "register_operand")
17652	(match_operand:SWI 1 "memory_operand"))
17653   (parallel [(set (match_dup 0)
17654		   (match_operator:SWI 3 "plusminuslogic_operator"
17655		     [(match_dup 0)
17656		      (match_operand:SWI 2 "<nonmemory_operand>")]))
17657	      (clobber (reg:CC FLAGS_REG))])
17658   (set (match_dup 1) (match_dup 0))
17659   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17660  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17661   && peep2_reg_dead_p (4, operands[0])
17662   && !reg_overlap_mentioned_p (operands[0], operands[1])
17663   && !reg_overlap_mentioned_p (operands[0], operands[2])
17664   && (<MODE>mode != QImode
17665       || immediate_operand (operands[2], QImode)
17666       || q_regs_operand (operands[2], QImode))
17667   && ix86_match_ccmode (peep2_next_insn (3),
17668			 (GET_CODE (operands[3]) == PLUS
17669			  || GET_CODE (operands[3]) == MINUS)
17670			 ? CCGOCmode : CCNOmode)"
17671  [(parallel [(set (match_dup 4) (match_dup 5))
17672	      (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17673						  (match_dup 2)]))])]
17674{
17675  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17676  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17677				copy_rtx (operands[1]),
17678				copy_rtx (operands[2]));
17679  operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17680				 operands[5], const0_rtx);
17681})
17682
17683(define_peephole2
17684  [(parallel [(set (match_operand:SWI 0 "register_operand")
17685		   (match_operator:SWI 2 "plusminuslogic_operator"
17686		     [(match_dup 0)
17687		      (match_operand:SWI 1 "memory_operand")]))
17688	      (clobber (reg:CC FLAGS_REG))])
17689   (set (match_dup 1) (match_dup 0))
17690   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17691  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17692   && GET_CODE (operands[2]) != MINUS
17693   && peep2_reg_dead_p (3, operands[0])
17694   && !reg_overlap_mentioned_p (operands[0], operands[1])
17695   && ix86_match_ccmode (peep2_next_insn (2),
17696			 GET_CODE (operands[2]) == PLUS
17697			 ? CCGOCmode : CCNOmode)"
17698  [(parallel [(set (match_dup 3) (match_dup 4))
17699	      (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17700						  (match_dup 0)]))])]
17701{
17702  operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17703  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17704				copy_rtx (operands[1]),
17705				copy_rtx (operands[0]));
17706  operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17707				 operands[4], const0_rtx);
17708})
17709
17710(define_peephole2
17711  [(set (match_operand:SWI12 0 "register_operand")
17712	(match_operand:SWI12 1 "memory_operand"))
17713   (parallel [(set (match_operand:SI 4 "register_operand")
17714		   (match_operator:SI 3 "plusminuslogic_operator"
17715		     [(match_dup 4)
17716		      (match_operand:SI 2 "nonmemory_operand")]))
17717	      (clobber (reg:CC FLAGS_REG))])
17718   (set (match_dup 1) (match_dup 0))
17719   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17720  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17721   && REG_P (operands[0]) && REG_P (operands[4])
17722   && REGNO (operands[0]) == REGNO (operands[4])
17723   && peep2_reg_dead_p (4, operands[0])
17724   && (<MODE>mode != QImode
17725       || immediate_operand (operands[2], SImode)
17726       || q_regs_operand (operands[2], SImode))
17727   && !reg_overlap_mentioned_p (operands[0], operands[1])
17728   && !reg_overlap_mentioned_p (operands[0], operands[2])
17729   && ix86_match_ccmode (peep2_next_insn (3),
17730			 (GET_CODE (operands[3]) == PLUS
17731			  || GET_CODE (operands[3]) == MINUS)
17732			 ? CCGOCmode : CCNOmode)"
17733  [(parallel [(set (match_dup 4) (match_dup 5))
17734	      (set (match_dup 1) (match_dup 6))])]
17735{
17736  operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17737  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17738  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17739				copy_rtx (operands[1]), operands[2]);
17740  operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17741				 operands[5], const0_rtx);
17742  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17743				copy_rtx (operands[1]),
17744				copy_rtx (operands[2]));
17745})
17746
17747;; Attempt to always use XOR for zeroing registers.
17748(define_peephole2
17749  [(set (match_operand 0 "register_operand")
17750	(match_operand 1 "const0_operand"))]
17751  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17752   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17753   && GENERAL_REGNO_P (REGNO (operands[0]))
17754   && peep2_regno_dead_p (0, FLAGS_REG)"
17755  [(parallel [(set (match_dup 0) (const_int 0))
17756	      (clobber (reg:CC FLAGS_REG))])]
17757  "operands[0] = gen_lowpart (word_mode, operands[0]);")
17758
17759(define_peephole2
17760  [(set (strict_low_part (match_operand 0 "register_operand"))
17761	(const_int 0))]
17762  "(GET_MODE (operands[0]) == QImode
17763    || GET_MODE (operands[0]) == HImode)
17764   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17765   && peep2_regno_dead_p (0, FLAGS_REG)"
17766  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17767	      (clobber (reg:CC FLAGS_REG))])])
17768
17769;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17770(define_peephole2
17771  [(set (match_operand:SWI248 0 "register_operand")
17772	(const_int -1))]
17773  "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17774   && GENERAL_REGNO_P (REGNO (operands[0]))
17775   && peep2_regno_dead_p (0, FLAGS_REG)"
17776  [(parallel [(set (match_dup 0) (const_int -1))
17777	      (clobber (reg:CC FLAGS_REG))])]
17778{
17779  if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17780    operands[0] = gen_lowpart (SImode, operands[0]);
17781})
17782
17783;; Attempt to convert simple lea to add/shift.
17784;; These can be created by move expanders.
17785;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17786;; relevant lea instructions were already split.
17787
17788(define_peephole2
17789  [(set (match_operand:SWI48 0 "register_operand")
17790  	(plus:SWI48 (match_dup 0)
17791		    (match_operand:SWI48 1 "<nonmemory_operand>")))]
17792  "!TARGET_OPT_AGU
17793   && peep2_regno_dead_p (0, FLAGS_REG)"
17794  [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17795	      (clobber (reg:CC FLAGS_REG))])])
17796
17797(define_peephole2
17798  [(set (match_operand:SWI48 0 "register_operand")
17799  	(plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17800		    (match_dup 0)))]
17801  "!TARGET_OPT_AGU
17802   && peep2_regno_dead_p (0, FLAGS_REG)"
17803  [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17804	      (clobber (reg:CC FLAGS_REG))])])
17805
17806(define_peephole2
17807  [(set (match_operand:DI 0 "register_operand")
17808  	(zero_extend:DI
17809	  (plus:SI (match_operand:SI 1 "register_operand")
17810		   (match_operand:SI 2 "nonmemory_operand"))))]
17811  "TARGET_64BIT && !TARGET_OPT_AGU
17812   && REGNO (operands[0]) == REGNO (operands[1])
17813   && peep2_regno_dead_p (0, FLAGS_REG)"
17814  [(parallel [(set (match_dup 0)
17815		   (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17816	      (clobber (reg:CC FLAGS_REG))])])
17817
17818(define_peephole2
17819  [(set (match_operand:DI 0 "register_operand")
17820  	(zero_extend:DI
17821	  (plus:SI (match_operand:SI 1 "nonmemory_operand")
17822		   (match_operand:SI 2 "register_operand"))))]
17823  "TARGET_64BIT && !TARGET_OPT_AGU
17824   && REGNO (operands[0]) == REGNO (operands[2])
17825   && peep2_regno_dead_p (0, FLAGS_REG)"
17826  [(parallel [(set (match_dup 0)
17827		   (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17828	      (clobber (reg:CC FLAGS_REG))])])
17829
17830(define_peephole2
17831  [(set (match_operand:SWI48 0 "register_operand")
17832  	(mult:SWI48 (match_dup 0)
17833		    (match_operand:SWI48 1 "const_int_operand")))]
17834  "exact_log2 (INTVAL (operands[1])) >= 0
17835   && peep2_regno_dead_p (0, FLAGS_REG)"
17836  [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17837	      (clobber (reg:CC FLAGS_REG))])]
17838  "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17839
17840(define_peephole2
17841  [(set (match_operand:DI 0 "register_operand")
17842  	(zero_extend:DI
17843	  (mult:SI (match_operand:SI 1 "register_operand")
17844		   (match_operand:SI 2 "const_int_operand"))))]
17845  "TARGET_64BIT
17846   && exact_log2 (INTVAL (operands[2])) >= 0
17847   && REGNO (operands[0]) == REGNO (operands[1])
17848   && peep2_regno_dead_p (0, FLAGS_REG)"
17849  [(parallel [(set (match_dup 0)
17850		   (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17851	      (clobber (reg:CC FLAGS_REG))])]
17852  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17853
17854;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17855;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17856;; On many CPUs it is also faster, since special hardware to avoid esp
17857;; dependencies is present.
17858
17859;; While some of these conversions may be done using splitters, we use
17860;; peepholes in order to allow combine_stack_adjustments pass to see
17861;; nonobfuscated RTL.
17862
17863;; Convert prologue esp subtractions to push.
17864;; We need register to push.  In order to keep verify_flow_info happy we have
17865;; two choices
17866;; - use scratch and clobber it in order to avoid dependencies
17867;; - use already live register
17868;; We can't use the second way right now, since there is no reliable way how to
17869;; verify that given register is live.  First choice will also most likely in
17870;; fewer dependencies.  On the place of esp adjustments it is very likely that
17871;; call clobbered registers are dead.  We may want to use base pointer as an
17872;; alternative when no register is available later.
17873
17874(define_peephole2
17875  [(match_scratch:W 1 "r")
17876   (parallel [(set (reg:P SP_REG)
17877		   (plus:P (reg:P SP_REG)
17878			   (match_operand:P 0 "const_int_operand")))
17879	      (clobber (reg:CC FLAGS_REG))
17880	      (clobber (mem:BLK (scratch)))])]
17881  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17882   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17883  [(clobber (match_dup 1))
17884   (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17885	      (clobber (mem:BLK (scratch)))])])
17886
17887(define_peephole2
17888  [(match_scratch:W 1 "r")
17889   (parallel [(set (reg:P SP_REG)
17890		   (plus:P (reg:P SP_REG)
17891			   (match_operand:P 0 "const_int_operand")))
17892	      (clobber (reg:CC FLAGS_REG))
17893	      (clobber (mem:BLK (scratch)))])]
17894  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17895   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17896  [(clobber (match_dup 1))
17897   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17898   (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17899	      (clobber (mem:BLK (scratch)))])])
17900
17901;; Convert esp subtractions to push.
17902(define_peephole2
17903  [(match_scratch:W 1 "r")
17904   (parallel [(set (reg:P SP_REG)
17905		   (plus:P (reg:P SP_REG)
17906			   (match_operand:P 0 "const_int_operand")))
17907	      (clobber (reg:CC FLAGS_REG))])]
17908  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17909   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17910  [(clobber (match_dup 1))
17911   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17912
17913(define_peephole2
17914  [(match_scratch:W 1 "r")
17915   (parallel [(set (reg:P SP_REG)
17916		   (plus:P (reg:P SP_REG)
17917			   (match_operand:P 0 "const_int_operand")))
17918	      (clobber (reg:CC FLAGS_REG))])]
17919  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17920   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17921  [(clobber (match_dup 1))
17922   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17923   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17924
17925;; Convert epilogue deallocator to pop.
17926(define_peephole2
17927  [(match_scratch:W 1 "r")
17928   (parallel [(set (reg:P SP_REG)
17929		   (plus:P (reg:P SP_REG)
17930			   (match_operand:P 0 "const_int_operand")))
17931	      (clobber (reg:CC FLAGS_REG))
17932	      (clobber (mem:BLK (scratch)))])]
17933  "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17934   && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17935  [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17936	      (clobber (mem:BLK (scratch)))])])
17937
17938;; Two pops case is tricky, since pop causes dependency
17939;; on destination register.  We use two registers if available.
17940(define_peephole2
17941  [(match_scratch:W 1 "r")
17942   (match_scratch:W 2 "r")
17943   (parallel [(set (reg:P SP_REG)
17944		   (plus:P (reg:P SP_REG)
17945			   (match_operand:P 0 "const_int_operand")))
17946	      (clobber (reg:CC FLAGS_REG))
17947	      (clobber (mem:BLK (scratch)))])]
17948  "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17949   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17950  [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17951	      (clobber (mem:BLK (scratch)))])
17952   (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17953
17954(define_peephole2
17955  [(match_scratch:W 1 "r")
17956   (parallel [(set (reg:P SP_REG)
17957		   (plus:P (reg:P SP_REG)
17958			   (match_operand:P 0 "const_int_operand")))
17959	      (clobber (reg:CC FLAGS_REG))
17960	      (clobber (mem:BLK (scratch)))])]
17961  "optimize_insn_for_size_p ()
17962   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17963  [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17964	      (clobber (mem:BLK (scratch)))])
17965   (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17966
17967;; Convert esp additions to pop.
17968(define_peephole2
17969  [(match_scratch:W 1 "r")
17970   (parallel [(set (reg:P SP_REG)
17971		   (plus:P (reg:P SP_REG)
17972			   (match_operand:P 0 "const_int_operand")))
17973	      (clobber (reg:CC FLAGS_REG))])]
17974  "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17975  [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17976
17977;; Two pops case is tricky, since pop causes dependency
17978;; on destination register.  We use two registers if available.
17979(define_peephole2
17980  [(match_scratch:W 1 "r")
17981   (match_scratch:W 2 "r")
17982   (parallel [(set (reg:P SP_REG)
17983		   (plus:P (reg:P SP_REG)
17984			   (match_operand:P 0 "const_int_operand")))
17985	      (clobber (reg:CC FLAGS_REG))])]
17986  "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17987  [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17988   (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17989
17990(define_peephole2
17991  [(match_scratch:W 1 "r")
17992   (parallel [(set (reg:P SP_REG)
17993		   (plus:P (reg:P SP_REG)
17994			   (match_operand:P 0 "const_int_operand")))
17995	      (clobber (reg:CC FLAGS_REG))])]
17996  "optimize_insn_for_size_p ()
17997   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17998  [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17999   (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18000
18001;; Convert compares with 1 to shorter inc/dec operations when CF is not
18002;; required and register dies.  Similarly for 128 to -128.
18003(define_peephole2
18004  [(set (match_operand 0 "flags_reg_operand")
18005	(match_operator 1 "compare_operator"
18006	  [(match_operand 2 "register_operand")
18007	   (match_operand 3 "const_int_operand")]))]
18008  "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18009     && incdec_operand (operands[3], GET_MODE (operands[3])))
18010    || (!TARGET_FUSE_CMP_AND_BRANCH
18011	&& INTVAL (operands[3]) == 128))
18012   && ix86_match_ccmode (insn, CCGCmode)
18013   && peep2_reg_dead_p (1, operands[2])"
18014  [(parallel [(set (match_dup 0)
18015		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18016	      (clobber (match_dup 2))])])
18017
18018;; Convert imul by three, five and nine into lea
18019(define_peephole2
18020  [(parallel
18021    [(set (match_operand:SWI48 0 "register_operand")
18022	  (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18023		      (match_operand:SWI48 2 "const359_operand")))
18024     (clobber (reg:CC FLAGS_REG))])]
18025  "!TARGET_PARTIAL_REG_STALL
18026   || <MODE>mode == SImode
18027   || optimize_function_for_size_p (cfun)"
18028  [(set (match_dup 0)
18029	(plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18030		    (match_dup 1)))]
18031  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18032
18033(define_peephole2
18034  [(parallel
18035    [(set (match_operand:SWI48 0 "register_operand")
18036	  (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18037		      (match_operand:SWI48 2 "const359_operand")))
18038     (clobber (reg:CC FLAGS_REG))])]
18039  "optimize_insn_for_speed_p ()
18040   && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18041  [(set (match_dup 0) (match_dup 1))
18042   (set (match_dup 0)
18043	(plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18044		    (match_dup 0)))]
18045  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18046
18047;; imul $32bit_imm, mem, reg is vector decoded, while
18048;; imul $32bit_imm, reg, reg is direct decoded.
18049(define_peephole2
18050  [(match_scratch:SWI48 3 "r")
18051   (parallel [(set (match_operand:SWI48 0 "register_operand")
18052		   (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18053			       (match_operand:SWI48 2 "immediate_operand")))
18054	      (clobber (reg:CC FLAGS_REG))])]
18055  "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18056   && !satisfies_constraint_K (operands[2])"
18057  [(set (match_dup 3) (match_dup 1))
18058   (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18059	      (clobber (reg:CC FLAGS_REG))])])
18060
18061(define_peephole2
18062  [(match_scratch:SI 3 "r")
18063   (parallel [(set (match_operand:DI 0 "register_operand")
18064		   (zero_extend:DI
18065		     (mult:SI (match_operand:SI 1 "memory_operand")
18066			      (match_operand:SI 2 "immediate_operand"))))
18067	      (clobber (reg:CC FLAGS_REG))])]
18068  "TARGET_64BIT
18069   && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18070   && !satisfies_constraint_K (operands[2])"
18071  [(set (match_dup 3) (match_dup 1))
18072   (parallel [(set (match_dup 0)
18073		   (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18074	      (clobber (reg:CC FLAGS_REG))])])
18075
18076;; imul $8/16bit_imm, regmem, reg is vector decoded.
18077;; Convert it into imul reg, reg
18078;; It would be better to force assembler to encode instruction using long
18079;; immediate, but there is apparently no way to do so.
18080(define_peephole2
18081  [(parallel [(set (match_operand:SWI248 0 "register_operand")
18082		   (mult:SWI248
18083		    (match_operand:SWI248 1 "nonimmediate_operand")
18084		    (match_operand:SWI248 2 "const_int_operand")))
18085	      (clobber (reg:CC FLAGS_REG))])
18086   (match_scratch:SWI248 3 "r")]
18087  "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18088   && satisfies_constraint_K (operands[2])"
18089  [(set (match_dup 3) (match_dup 2))
18090   (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18091	      (clobber (reg:CC FLAGS_REG))])]
18092{
18093  if (!rtx_equal_p (operands[0], operands[1]))
18094    emit_move_insn (operands[0], operands[1]);
18095})
18096
18097;; After splitting up read-modify operations, array accesses with memory
18098;; operands might end up in form:
18099;;  sall    $2, %eax
18100;;  movl    4(%esp), %edx
18101;;  addl    %edx, %eax
18102;; instead of pre-splitting:
18103;;  sall    $2, %eax
18104;;  addl    4(%esp), %eax
18105;; Turn it into:
18106;;  movl    4(%esp), %edx
18107;;  leal    (%edx,%eax,4), %eax
18108
18109(define_peephole2
18110  [(match_scratch:W 5 "r")
18111   (parallel [(set (match_operand 0 "register_operand")
18112		   (ashift (match_operand 1 "register_operand")
18113			   (match_operand 2 "const_int_operand")))
18114	       (clobber (reg:CC FLAGS_REG))])
18115   (parallel [(set (match_operand 3 "register_operand")
18116		   (plus (match_dup 0)
18117			 (match_operand 4 "x86_64_general_operand")))
18118		   (clobber (reg:CC FLAGS_REG))])]
18119  "IN_RANGE (INTVAL (operands[2]), 1, 3)
18120   /* Validate MODE for lea.  */
18121   && ((!TARGET_PARTIAL_REG_STALL
18122	&& (GET_MODE (operands[0]) == QImode
18123	    || GET_MODE (operands[0]) == HImode))
18124       || GET_MODE (operands[0]) == SImode
18125       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18126   && (rtx_equal_p (operands[0], operands[3])
18127       || peep2_reg_dead_p (2, operands[0]))
18128   /* We reorder load and the shift.  */
18129   && !reg_overlap_mentioned_p (operands[0], operands[4])"
18130  [(set (match_dup 5) (match_dup 4))
18131   (set (match_dup 0) (match_dup 1))]
18132{
18133  machine_mode op1mode = GET_MODE (operands[1]);
18134  machine_mode mode = op1mode == DImode ? DImode : SImode;
18135  int scale = 1 << INTVAL (operands[2]);
18136  rtx index = gen_lowpart (word_mode, operands[1]);
18137  rtx base = gen_lowpart (word_mode, operands[5]);
18138  rtx dest = gen_lowpart (mode, operands[3]);
18139
18140  operands[1] = gen_rtx_PLUS (word_mode, base,
18141			      gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18142  if (mode != word_mode)
18143    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18144
18145  operands[5] = base;
18146  if (op1mode != word_mode)
18147    operands[5] = gen_lowpart (op1mode, operands[5]);
18148
18149  operands[0] = dest;
18150})
18151
18152;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18153;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18154;; caught for use by garbage collectors and the like.  Using an insn that
18155;; maps to SIGILL makes it more likely the program will rightfully die.
18156;; Keeping with tradition, "6" is in honor of #UD.
18157(define_insn "trap"
18158  [(trap_if (const_int 1) (const_int 6))]
18159  ""
18160{
18161#ifdef HAVE_AS_IX86_UD2
18162  return "ud2";
18163#else
18164  return ASM_SHORT "0x0b0f";
18165#endif
18166}
18167  [(set_attr "length" "2")])
18168
18169(define_expand "prefetch"
18170  [(prefetch (match_operand 0 "address_operand")
18171	     (match_operand:SI 1 "const_int_operand")
18172	     (match_operand:SI 2 "const_int_operand"))]
18173  "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18174{
18175  bool write = INTVAL (operands[1]) != 0;
18176  int locality = INTVAL (operands[2]);
18177
18178  gcc_assert (IN_RANGE (locality, 0, 3));
18179
18180  /* Use 3dNOW prefetch in case we are asking for write prefetch not
18181     supported by SSE counterpart or the SSE prefetch is not available
18182     (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18183     of locality.  */
18184  if (TARGET_PREFETCHWT1 && write && locality <= 2)
18185    operands[2] = const2_rtx;
18186  else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18187    operands[2] = GEN_INT (3);
18188  else
18189    operands[1] = const0_rtx;
18190})
18191
18192(define_insn "*prefetch_sse"
18193  [(prefetch (match_operand 0 "address_operand" "p")
18194	     (const_int 0)
18195	     (match_operand:SI 1 "const_int_operand"))]
18196  "TARGET_PREFETCH_SSE"
18197{
18198  static const char * const patterns[4] = {
18199   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18200  };
18201
18202  int locality = INTVAL (operands[1]);
18203  gcc_assert (IN_RANGE (locality, 0, 3));
18204
18205  return patterns[locality];
18206}
18207  [(set_attr "type" "sse")
18208   (set_attr "atom_sse_attr" "prefetch")
18209   (set (attr "length_address")
18210	(symbol_ref "memory_address_length (operands[0], false)"))
18211   (set_attr "memory" "none")])
18212
18213(define_insn "*prefetch_3dnow"
18214  [(prefetch (match_operand 0 "address_operand" "p")
18215	     (match_operand:SI 1 "const_int_operand" "n")
18216	     (const_int 3))]
18217  "TARGET_PRFCHW"
18218{
18219  if (INTVAL (operands[1]) == 0)
18220    return "prefetch\t%a0";
18221  else
18222    return "prefetchw\t%a0";
18223}
18224  [(set_attr "type" "mmx")
18225   (set (attr "length_address")
18226	(symbol_ref "memory_address_length (operands[0], false)"))
18227   (set_attr "memory" "none")])
18228
18229(define_insn "*prefetch_prefetchwt1"
18230  [(prefetch (match_operand 0 "address_operand" "p")
18231	     (const_int 1)
18232	     (const_int 2))]
18233  "TARGET_PREFETCHWT1"
18234  "prefetchwt1\t%a0";
18235  [(set_attr "type" "sse")
18236   (set (attr "length_address")
18237	(symbol_ref "memory_address_length (operands[0], false)"))
18238   (set_attr "memory" "none")])
18239
18240(define_expand "stack_protect_set"
18241  [(match_operand 0 "memory_operand")
18242   (match_operand 1 "memory_operand")]
18243  "TARGET_SSP_TLS_GUARD"
18244{
18245  rtx (*insn)(rtx, rtx);
18246
18247#ifdef TARGET_THREAD_SSP_OFFSET
18248  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18249  insn = (TARGET_LP64
18250	  ? gen_stack_tls_protect_set_di
18251	  : gen_stack_tls_protect_set_si);
18252#else
18253  insn = (TARGET_LP64
18254	  ? gen_stack_protect_set_di
18255	  : gen_stack_protect_set_si);
18256#endif
18257
18258  emit_insn (insn (operands[0], operands[1]));
18259  DONE;
18260})
18261
18262(define_insn "stack_protect_set_<mode>"
18263  [(set (match_operand:PTR 0 "memory_operand" "=m")
18264	(unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18265		    UNSPEC_SP_SET))
18266   (set (match_scratch:PTR 2 "=&r") (const_int 0))
18267   (clobber (reg:CC FLAGS_REG))]
18268  "TARGET_SSP_TLS_GUARD"
18269  "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18270  [(set_attr "type" "multi")])
18271
18272(define_insn "stack_tls_protect_set_<mode>"
18273  [(set (match_operand:PTR 0 "memory_operand" "=m")
18274	(unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18275		    UNSPEC_SP_TLS_SET))
18276   (set (match_scratch:PTR 2 "=&r") (const_int 0))
18277   (clobber (reg:CC FLAGS_REG))]
18278  ""
18279  "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18280  [(set_attr "type" "multi")])
18281
18282(define_expand "stack_protect_test"
18283  [(match_operand 0 "memory_operand")
18284   (match_operand 1 "memory_operand")
18285   (match_operand 2)]
18286  "TARGET_SSP_TLS_GUARD"
18287{
18288  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18289
18290  rtx (*insn)(rtx, rtx, rtx);
18291
18292#ifdef TARGET_THREAD_SSP_OFFSET
18293  operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18294  insn = (TARGET_LP64
18295	  ? gen_stack_tls_protect_test_di
18296	  : gen_stack_tls_protect_test_si);
18297#else
18298  insn = (TARGET_LP64
18299	  ? gen_stack_protect_test_di
18300	  : gen_stack_protect_test_si);
18301#endif
18302
18303  emit_insn (insn (flags, operands[0], operands[1]));
18304
18305  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18306				  flags, const0_rtx, operands[2]));
18307  DONE;
18308})
18309
18310(define_insn "stack_protect_test_<mode>"
18311  [(set (match_operand:CCZ 0 "flags_reg_operand")
18312	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18313		     (match_operand:PTR 2 "memory_operand" "m")]
18314		    UNSPEC_SP_TEST))
18315   (clobber (match_scratch:PTR 3 "=&r"))]
18316  "TARGET_SSP_TLS_GUARD"
18317  "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18318  [(set_attr "type" "multi")])
18319
18320(define_insn "stack_tls_protect_test_<mode>"
18321  [(set (match_operand:CCZ 0 "flags_reg_operand")
18322	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18323		     (match_operand:PTR 2 "const_int_operand" "i")]
18324		    UNSPEC_SP_TLS_TEST))
18325   (clobber (match_scratch:PTR 3 "=r"))]
18326  ""
18327  "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18328  [(set_attr "type" "multi")])
18329
18330(define_insn "sse4_2_crc32<mode>"
18331  [(set (match_operand:SI 0 "register_operand" "=r")
18332	(unspec:SI
18333	  [(match_operand:SI 1 "register_operand" "0")
18334	   (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18335	  UNSPEC_CRC32))]
18336  "TARGET_SSE4_2 || TARGET_CRC32"
18337  "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18338  [(set_attr "type" "sselog1")
18339   (set_attr "prefix_rep" "1")
18340   (set_attr "prefix_extra" "1")
18341   (set (attr "prefix_data16")
18342     (if_then_else (match_operand:HI 2)
18343       (const_string "1")
18344       (const_string "*")))
18345   (set (attr "prefix_rex")
18346     (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18347       (const_string "1")
18348       (const_string "*")))
18349   (set_attr "mode" "SI")])
18350
18351(define_insn "sse4_2_crc32di"
18352  [(set (match_operand:DI 0 "register_operand" "=r")
18353	(unspec:DI
18354	  [(match_operand:DI 1 "register_operand" "0")
18355	   (match_operand:DI 2 "nonimmediate_operand" "rm")]
18356	  UNSPEC_CRC32))]
18357  "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18358  "crc32{q}\t{%2, %0|%0, %2}"
18359  [(set_attr "type" "sselog1")
18360   (set_attr "prefix_rep" "1")
18361   (set_attr "prefix_extra" "1")
18362   (set_attr "mode" "DI")])
18363
18364(define_insn "rdpmc"
18365  [(set (match_operand:DI 0 "register_operand" "=A")
18366  	(unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18367			    UNSPECV_RDPMC))]
18368  "!TARGET_64BIT"
18369  "rdpmc"
18370  [(set_attr "type" "other")
18371   (set_attr "length" "2")])
18372
18373(define_insn "rdpmc_rex64"
18374  [(set (match_operand:DI 0 "register_operand" "=a")
18375  	(unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18376			    UNSPECV_RDPMC))
18377   (set (match_operand:DI 1 "register_operand" "=d")
18378	(unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18379  "TARGET_64BIT"
18380  "rdpmc"
18381  [(set_attr "type" "other")
18382   (set_attr "length" "2")])
18383
18384(define_insn "rdtsc"
18385  [(set (match_operand:DI 0 "register_operand" "=A")
18386	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18387  "!TARGET_64BIT"
18388  "rdtsc"
18389  [(set_attr "type" "other")
18390   (set_attr "length" "2")])
18391
18392(define_insn "rdtsc_rex64"
18393  [(set (match_operand:DI 0 "register_operand" "=a")
18394	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18395   (set (match_operand:DI 1 "register_operand" "=d")
18396	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18397  "TARGET_64BIT"
18398  "rdtsc"
18399  [(set_attr "type" "other")
18400   (set_attr "length" "2")])
18401
18402(define_insn "rdtscp"
18403  [(set (match_operand:DI 0 "register_operand" "=A")
18404	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18405   (set (match_operand:SI 1 "register_operand" "=c")
18406	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18407  "!TARGET_64BIT"
18408  "rdtscp"
18409  [(set_attr "type" "other")
18410   (set_attr "length" "3")])
18411
18412(define_insn "rdtscp_rex64"
18413  [(set (match_operand:DI 0 "register_operand" "=a")
18414	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18415   (set (match_operand:DI 1 "register_operand" "=d")
18416	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18417   (set (match_operand:SI 2 "register_operand" "=c")
18418	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18419  "TARGET_64BIT"
18420  "rdtscp"
18421  [(set_attr "type" "other")
18422   (set_attr "length" "3")])
18423
18424;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18425;;
18426;; FXSR, XSAVE and XSAVEOPT instructions
18427;;
18428;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18429
18430(define_insn "fxsave"
18431  [(set (match_operand:BLK 0 "memory_operand" "=m")
18432	(unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18433  "TARGET_FXSR"
18434  "fxsave\t%0"
18435  [(set_attr "type" "other")
18436   (set_attr "memory" "store")
18437   (set (attr "length")
18438        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18439
18440(define_insn "fxsave64"
18441  [(set (match_operand:BLK 0 "memory_operand" "=m")
18442	(unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18443  "TARGET_64BIT && TARGET_FXSR"
18444  "fxsave64\t%0"
18445  [(set_attr "type" "other")
18446   (set_attr "memory" "store")
18447   (set (attr "length")
18448        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18449
18450(define_insn "fxrstor"
18451  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18452		    UNSPECV_FXRSTOR)]
18453  "TARGET_FXSR"
18454  "fxrstor\t%0"
18455  [(set_attr "type" "other")
18456   (set_attr "memory" "load")
18457   (set (attr "length")
18458        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18459
18460(define_insn "fxrstor64"
18461  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18462		    UNSPECV_FXRSTOR64)]
18463  "TARGET_64BIT && TARGET_FXSR"
18464  "fxrstor64\t%0"
18465  [(set_attr "type" "other")
18466   (set_attr "memory" "load")
18467   (set (attr "length")
18468        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18469
18470(define_int_iterator ANY_XSAVE
18471	[UNSPECV_XSAVE
18472	 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18473	 (UNSPECV_XSAVEC "TARGET_XSAVEC")
18474	 (UNSPECV_XSAVES "TARGET_XSAVES")])
18475
18476(define_int_iterator ANY_XSAVE64
18477	[UNSPECV_XSAVE64
18478	 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18479	 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18480	 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18481
18482(define_int_attr xsave
18483	[(UNSPECV_XSAVE "xsave")
18484	 (UNSPECV_XSAVE64 "xsave64")
18485	 (UNSPECV_XSAVEOPT "xsaveopt")
18486	 (UNSPECV_XSAVEOPT64 "xsaveopt64")
18487	 (UNSPECV_XSAVEC "xsavec")
18488	 (UNSPECV_XSAVEC64 "xsavec64")
18489	 (UNSPECV_XSAVES "xsaves")
18490	 (UNSPECV_XSAVES64 "xsaves64")])
18491
18492(define_int_iterator ANY_XRSTOR
18493	[UNSPECV_XRSTOR
18494	 (UNSPECV_XRSTORS "TARGET_XSAVES")])
18495
18496(define_int_iterator ANY_XRSTOR64
18497	[UNSPECV_XRSTOR64
18498	 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18499
18500(define_int_attr xrstor
18501	[(UNSPECV_XRSTOR "xrstor")
18502	 (UNSPECV_XRSTOR64 "xrstor")
18503	 (UNSPECV_XRSTORS "xrstors")
18504	 (UNSPECV_XRSTORS64 "xrstors")])
18505
18506(define_insn "<xsave>"
18507  [(set (match_operand:BLK 0 "memory_operand" "=m")
18508	(unspec_volatile:BLK
18509	 [(match_operand:DI 1 "register_operand" "A")]
18510	 ANY_XSAVE))]
18511  "!TARGET_64BIT && TARGET_XSAVE"
18512  "<xsave>\t%0"
18513  [(set_attr "type" "other")
18514   (set_attr "memory" "store")
18515   (set (attr "length")
18516        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18517
18518(define_insn "<xsave>_rex64"
18519  [(set (match_operand:BLK 0 "memory_operand" "=m")
18520	(unspec_volatile:BLK
18521	 [(match_operand:SI 1 "register_operand" "a")
18522	  (match_operand:SI 2 "register_operand" "d")]
18523	 ANY_XSAVE))]
18524  "TARGET_64BIT && TARGET_XSAVE"
18525  "<xsave>\t%0"
18526  [(set_attr "type" "other")
18527   (set_attr "memory" "store")
18528   (set (attr "length")
18529        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18530
18531(define_insn "<xsave>"
18532  [(set (match_operand:BLK 0 "memory_operand" "=m")
18533	(unspec_volatile:BLK
18534	 [(match_operand:SI 1 "register_operand" "a")
18535	  (match_operand:SI 2 "register_operand" "d")]
18536	 ANY_XSAVE64))]
18537  "TARGET_64BIT && TARGET_XSAVE"
18538  "<xsave>\t%0"
18539  [(set_attr "type" "other")
18540   (set_attr "memory" "store")
18541   (set (attr "length")
18542        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18543
18544(define_insn "<xrstor>"
18545   [(unspec_volatile:BLK
18546     [(match_operand:BLK 0 "memory_operand" "m")
18547      (match_operand:DI 1 "register_operand" "A")]
18548     ANY_XRSTOR)]
18549  "!TARGET_64BIT && TARGET_XSAVE"
18550  "<xrstor>\t%0"
18551  [(set_attr "type" "other")
18552   (set_attr "memory" "load")
18553   (set (attr "length")
18554        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18555
18556(define_insn "<xrstor>_rex64"
18557   [(unspec_volatile:BLK
18558     [(match_operand:BLK 0 "memory_operand" "m")
18559      (match_operand:SI 1 "register_operand" "a")
18560      (match_operand:SI 2 "register_operand" "d")]
18561     ANY_XRSTOR)]
18562  "TARGET_64BIT && TARGET_XSAVE"
18563  "<xrstor>\t%0"
18564  [(set_attr "type" "other")
18565   (set_attr "memory" "load")
18566   (set (attr "length")
18567        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18568
18569(define_insn "<xrstor>64"
18570   [(unspec_volatile:BLK
18571     [(match_operand:BLK 0 "memory_operand" "m")
18572      (match_operand:SI 1 "register_operand" "a")
18573      (match_operand:SI 2 "register_operand" "d")]
18574     ANY_XRSTOR64)]
18575  "TARGET_64BIT && TARGET_XSAVE"
18576  "<xrstor>64\t%0"
18577  [(set_attr "type" "other")
18578   (set_attr "memory" "load")
18579   (set (attr "length")
18580        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18581
18582;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18583;;
18584;; Floating-point instructions for atomic compound assignments
18585;;
18586;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18587
18588; Clobber all floating-point registers on environment save and restore
18589; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18590(define_insn "fnstenv"
18591  [(set (match_operand:BLK 0 "memory_operand" "=m")
18592	(unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18593   (clobber (reg:HI FPCR_REG))
18594   (clobber (reg:XF ST0_REG))
18595   (clobber (reg:XF ST1_REG))
18596   (clobber (reg:XF ST2_REG))
18597   (clobber (reg:XF ST3_REG))
18598   (clobber (reg:XF ST4_REG))
18599   (clobber (reg:XF ST5_REG))
18600   (clobber (reg:XF ST6_REG))
18601   (clobber (reg:XF ST7_REG))]
18602  "TARGET_80387"
18603  "fnstenv\t%0"
18604  [(set_attr "type" "other")
18605   (set_attr "memory" "store")
18606   (set (attr "length")
18607        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18608
18609(define_insn "fldenv"
18610  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18611		    UNSPECV_FLDENV)
18612   (clobber (reg:CCFP FPSR_REG))
18613   (clobber (reg:HI FPCR_REG))
18614   (clobber (reg:XF ST0_REG))
18615   (clobber (reg:XF ST1_REG))
18616   (clobber (reg:XF ST2_REG))
18617   (clobber (reg:XF ST3_REG))
18618   (clobber (reg:XF ST4_REG))
18619   (clobber (reg:XF ST5_REG))
18620   (clobber (reg:XF ST6_REG))
18621   (clobber (reg:XF ST7_REG))]
18622  "TARGET_80387"
18623  "fldenv\t%0"
18624  [(set_attr "type" "other")
18625   (set_attr "memory" "load")
18626   (set (attr "length")
18627        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18628
18629(define_insn "fnstsw"
18630  [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18631	(unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18632  "TARGET_80387"
18633  "fnstsw\t%0"
18634  [(set_attr "type" "other,other")
18635   (set_attr "memory" "none,store")
18636   (set (attr "length")
18637        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18638
18639(define_insn "fnclex"
18640  [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18641  "TARGET_80387"
18642  "fnclex"
18643  [(set_attr "type" "other")
18644   (set_attr "memory" "none")
18645   (set_attr "length" "2")])
18646
18647;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18648;;
18649;; LWP instructions
18650;;
18651;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18652
18653(define_expand "lwp_llwpcb"
18654  [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18655		    UNSPECV_LLWP_INTRINSIC)]
18656  "TARGET_LWP")
18657
18658(define_insn "*lwp_llwpcb<mode>1"
18659  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18660		    UNSPECV_LLWP_INTRINSIC)]
18661  "TARGET_LWP"
18662  "llwpcb\t%0"
18663  [(set_attr "type" "lwp")
18664   (set_attr "mode" "<MODE>")
18665   (set_attr "length" "5")])
18666
18667(define_expand "lwp_slwpcb"
18668  [(set (match_operand 0 "register_operand" "=r")
18669	(unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18670  "TARGET_LWP"
18671{
18672  rtx (*insn)(rtx);
18673
18674  insn = (Pmode == DImode
18675	  ? gen_lwp_slwpcbdi
18676	  : gen_lwp_slwpcbsi);
18677
18678  emit_insn (insn (operands[0]));
18679  DONE;
18680})
18681
18682(define_insn "lwp_slwpcb<mode>"
18683  [(set (match_operand:P 0 "register_operand" "=r")
18684	(unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18685  "TARGET_LWP"
18686  "slwpcb\t%0"
18687  [(set_attr "type" "lwp")
18688   (set_attr "mode" "<MODE>")
18689   (set_attr "length" "5")])
18690
18691(define_expand "lwp_lwpval<mode>3"
18692  [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18693    	    	     (match_operand:SI 2 "nonimmediate_operand" "rm")
18694		     (match_operand:SI 3 "const_int_operand" "i")]
18695		    UNSPECV_LWPVAL_INTRINSIC)]
18696  "TARGET_LWP"
18697  ;; Avoid unused variable warning.
18698  "(void) operands[0];")
18699
18700(define_insn "*lwp_lwpval<mode>3_1"
18701  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18702    	    	     (match_operand:SI 1 "nonimmediate_operand" "rm")
18703		     (match_operand:SI 2 "const_int_operand" "i")]
18704		    UNSPECV_LWPVAL_INTRINSIC)]
18705  "TARGET_LWP"
18706  "lwpval\t{%2, %1, %0|%0, %1, %2}"
18707  [(set_attr "type" "lwp")
18708   (set_attr "mode" "<MODE>")
18709   (set (attr "length")
18710        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18711
18712(define_expand "lwp_lwpins<mode>3"
18713  [(set (reg:CCC FLAGS_REG)
18714	(unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18715			      (match_operand:SI 2 "nonimmediate_operand" "rm")
18716			      (match_operand:SI 3 "const_int_operand" "i")]
18717			     UNSPECV_LWPINS_INTRINSIC))
18718   (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18719	(eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18720  "TARGET_LWP")
18721
18722(define_insn "*lwp_lwpins<mode>3_1"
18723  [(set (reg:CCC FLAGS_REG)
18724	(unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18725			      (match_operand:SI 1 "nonimmediate_operand" "rm")
18726			      (match_operand:SI 2 "const_int_operand" "i")]
18727			     UNSPECV_LWPINS_INTRINSIC))]
18728  "TARGET_LWP"
18729  "lwpins\t{%2, %1, %0|%0, %1, %2}"
18730  [(set_attr "type" "lwp")
18731   (set_attr "mode" "<MODE>")
18732   (set (attr "length")
18733        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18734
18735(define_int_iterator RDFSGSBASE
18736	[UNSPECV_RDFSBASE
18737	 UNSPECV_RDGSBASE])
18738
18739(define_int_iterator WRFSGSBASE
18740	[UNSPECV_WRFSBASE
18741	 UNSPECV_WRGSBASE])
18742
18743(define_int_attr fsgs
18744	[(UNSPECV_RDFSBASE "fs")
18745	 (UNSPECV_RDGSBASE "gs")
18746	 (UNSPECV_WRFSBASE "fs")
18747	 (UNSPECV_WRGSBASE "gs")])
18748
18749(define_insn "rd<fsgs>base<mode>"
18750  [(set (match_operand:SWI48 0 "register_operand" "=r")
18751	(unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18752  "TARGET_64BIT && TARGET_FSGSBASE"
18753  "rd<fsgs>base\t%0"
18754  [(set_attr "type" "other")
18755   (set_attr "prefix_extra" "2")])
18756
18757(define_insn "wr<fsgs>base<mode>"
18758  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18759		    WRFSGSBASE)]
18760  "TARGET_64BIT && TARGET_FSGSBASE"
18761  "wr<fsgs>base\t%0"
18762  [(set_attr "type" "other")
18763   (set_attr "prefix_extra" "2")])
18764
18765(define_insn "rdrand<mode>_1"
18766  [(set (match_operand:SWI248 0 "register_operand" "=r")
18767	(unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18768   (set (reg:CCC FLAGS_REG)
18769	(unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18770  "TARGET_RDRND"
18771  "rdrand\t%0"
18772  [(set_attr "type" "other")
18773   (set_attr "prefix_extra" "1")])
18774
18775(define_insn "rdseed<mode>_1"
18776  [(set (match_operand:SWI248 0 "register_operand" "=r")
18777	(unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18778   (set (reg:CCC FLAGS_REG)
18779	(unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18780  "TARGET_RDSEED"
18781  "rdseed\t%0"
18782  [(set_attr "type" "other")
18783   (set_attr "prefix_extra" "1")])
18784
18785(define_expand "pause"
18786  [(set (match_dup 0)
18787	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18788  ""
18789{
18790  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18791  MEM_VOLATILE_P (operands[0]) = 1;
18792})
18793
18794;; Use "rep; nop", instead of "pause", to support older assemblers.
18795;; They have the same encoding.
18796(define_insn "*pause"
18797  [(set (match_operand:BLK 0)
18798	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18799  ""
18800  "rep%; nop"
18801  [(set_attr "length" "2")
18802   (set_attr "memory" "unknown")])
18803
18804(define_expand "xbegin"
18805  [(set (match_operand:SI 0 "register_operand")
18806	(unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18807  "TARGET_RTM"
18808{
18809  rtx_code_label *label = gen_label_rtx ();
18810
18811  /* xbegin is emitted as jump_insn, so reload won't be able
18812     to reload its operand.  Force the value into AX hard register.  */
18813  rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18814  emit_move_insn (ax_reg, constm1_rtx);
18815
18816  emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18817
18818  emit_label (label);
18819  LABEL_NUSES (label) = 1;
18820
18821  emit_move_insn (operands[0], ax_reg);
18822
18823  DONE;
18824})
18825
18826(define_insn "xbegin_1"
18827  [(set (pc)
18828	(if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18829			  (const_int 0))
18830		      (label_ref (match_operand 1))
18831		      (pc)))
18832   (set (match_operand:SI 0 "register_operand" "+a")
18833	(unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18834  "TARGET_RTM"
18835  "xbegin\t%l1"
18836  [(set_attr "type" "other")
18837   (set_attr "length" "6")])
18838
18839(define_insn "xend"
18840  [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18841  "TARGET_RTM"
18842  "xend"
18843  [(set_attr "type" "other")
18844   (set_attr "length" "3")])
18845
18846(define_insn "xabort"
18847  [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18848		    UNSPECV_XABORT)]
18849  "TARGET_RTM"
18850  "xabort\t%0"
18851  [(set_attr "type" "other")
18852   (set_attr "length" "3")])
18853
18854(define_expand "xtest"
18855  [(set (match_operand:QI 0 "register_operand")
18856	(unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18857  "TARGET_RTM"
18858{
18859  emit_insn (gen_xtest_1 ());
18860
18861  ix86_expand_setcc (operands[0], NE,
18862		     gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18863  DONE;
18864})
18865
18866(define_insn "xtest_1"
18867  [(set (reg:CCZ FLAGS_REG)
18868	(unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18869  "TARGET_RTM"
18870  "xtest"
18871  [(set_attr "type" "other")
18872   (set_attr "length" "3")])
18873
18874(define_insn "pcommit"
18875  [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
18876  "TARGET_PCOMMIT"
18877  "pcommit"
18878  [(set_attr "type" "other")
18879   (set_attr "length" "4")])
18880
18881(define_insn "clwb"
18882  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18883                   UNSPECV_CLWB)]
18884  "TARGET_CLWB"
18885  "clwb\t%a0"
18886  [(set_attr "type" "sse")
18887   (set_attr "atom_sse_attr" "fence")
18888   (set_attr "memory" "unknown")])
18889
18890(define_insn "clflushopt"
18891  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18892                   UNSPECV_CLFLUSHOPT)]
18893  "TARGET_CLFLUSHOPT"
18894  "clflushopt\t%a0"
18895  [(set_attr "type" "sse")
18896   (set_attr "atom_sse_attr" "fence")
18897   (set_attr "memory" "unknown")])
18898
18899;; MONITORX and MWAITX
18900(define_insn "mwaitx"
18901  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
18902		     (match_operand:SI 1 "register_operand" "a")
18903		     (match_operand:SI 2 "register_operand" "b")]
18904		   UNSPECV_MWAITX)]
18905  "TARGET_MWAITX"
18906;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
18907;; Since 32bit register operands are implicitly zero extended to 64bit,
18908;; we only need to set up 32bit registers.
18909  "mwaitx"
18910  [(set_attr "length" "3")])
18911
18912(define_insn "monitorx_<mode>"
18913  [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
18914		     (match_operand:SI 1 "register_operand" "c")
18915		     (match_operand:SI 2 "register_operand" "d")]
18916		   UNSPECV_MONITORX)]
18917  "TARGET_MWAITX"
18918;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
18919;; RCX and RDX are used.  Since 32bit register operands are implicitly
18920;; zero extended to 64bit, we only need to set up 32bit registers.
18921  "%^monitorx"
18922  [(set (attr "length")
18923     (symbol_ref ("(Pmode != word_mode) + 3")))])
18924
18925;; MPX instructions
18926
18927(define_expand "<mode>_mk"
18928  [(set (match_operand:BND 0 "register_operand")
18929    (unspec:BND
18930      [(mem:<bnd_ptr>
18931       (match_par_dup 3
18932        [(match_operand:<bnd_ptr> 1 "register_operand")
18933	 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18934      UNSPEC_BNDMK))]
18935  "TARGET_MPX"
18936{
18937  operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18938						  operands[2]),
18939                                UNSPEC_BNDMK_ADDR);
18940})
18941
18942(define_insn "*<mode>_mk"
18943  [(set (match_operand:BND 0 "register_operand" "=w")
18944    (unspec:BND
18945      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18946        [(unspec:<bnd_ptr>
18947	   [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18948            (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18949	   UNSPEC_BNDMK_ADDR)])]
18950      UNSPEC_BNDMK))]
18951  "TARGET_MPX"
18952  "bndmk\t{%3, %0|%0, %3}"
18953  [(set_attr "type" "mpxmk")])
18954
18955(define_expand "mov<mode>"
18956  [(set (match_operand:BND 0 "general_operand")
18957        (match_operand:BND 1 "general_operand"))]
18958  "TARGET_MPX"
18959{
18960  ix86_expand_move (<MODE>mode, operands);DONE;
18961})
18962
18963(define_insn "*mov<mode>_internal_mpx"
18964  [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18965        (match_operand:BND 1 "general_operand" "wm,w"))]
18966  "TARGET_MPX"
18967  "bndmov\t{%1, %0|%0, %1}"
18968  [(set_attr "type" "mpxmov")])
18969
18970(define_expand "<mode>_<bndcheck>"
18971  [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18972                       (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18973              (set (match_dup 2)
18974                   (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18975  "TARGET_MPX"
18976{
18977  operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18978  MEM_VOLATILE_P (operands[2]) = 1;
18979})
18980
18981(define_insn "*<mode>_<bndcheck>"
18982  [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18983                       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18984              (set (match_operand:BLK 2 "bnd_mem_operator")
18985                   (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18986  "TARGET_MPX"
18987  "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18988  [(set_attr "type" "mpxchk")])
18989
18990(define_expand "<mode>_ldx"
18991  [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18992                       (unspec:BND
18993		         [(mem:<bnd_ptr>
18994			   (match_par_dup 3
18995			     [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18996	                      (match_operand:<bnd_ptr> 2 "register_operand")]))]
18997			 UNSPEC_BNDLDX))
18998              (use (mem:BLK (match_dup 1)))])]
18999  "TARGET_MPX"
19000{
19001  /* Avoid registers which connot be used as index.  */
19002  if (!index_register_operand (operands[2], Pmode))
19003    {
19004      rtx temp = gen_reg_rtx (Pmode);
19005      emit_move_insn (temp, operands[2]);
19006      operands[2] = temp;
19007    }
19008
19009  /* If it was a register originally then it may have
19010     mode other than Pmode.  We need to extend in such
19011     case because bndldx may work only with Pmode regs.  */
19012  if (GET_MODE (operands[2]) != Pmode)
19013    operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
19014
19015  operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19016                                                  operands[2]),
19017				UNSPEC_BNDLDX_ADDR);
19018})
19019
19020(define_insn "*<mode>_ldx"
19021  [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
19022                       (unspec:BND
19023		         [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19024			   [(unspec:<bnd_ptr>
19025			     [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19026	                      (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19027			    UNSPEC_BNDLDX_ADDR)])]
19028			 UNSPEC_BNDLDX))
19029              (use (mem:BLK (match_dup 1)))])]
19030  "TARGET_MPX"
19031  "bndldx\t{%3, %0|%0, %3}"
19032  [(set_attr "type" "mpxld")])
19033
19034(define_expand "<mode>_stx"
19035  [(parallel [(unspec [(mem:<bnd_ptr>
19036			 (match_par_dup 3
19037			   [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19038	                    (match_operand:<bnd_ptr> 1 "register_operand")]))
19039	               (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
19040              (set (match_dup 4)
19041                   (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19042  "TARGET_MPX"
19043{
19044  /* Avoid registers which connot be used as index.  */
19045  if (!index_register_operand (operands[1], Pmode))
19046    {
19047      rtx temp = gen_reg_rtx (Pmode);
19048      emit_move_insn (temp, operands[1]);
19049      operands[1] = temp;
19050    }
19051
19052  /* If it was a register originally then it may have
19053     mode other than Pmode.  We need to extend in such
19054     case because bndstx may work only with Pmode regs.  */
19055  if (GET_MODE (operands[1]) != Pmode)
19056    operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
19057
19058  operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19059                                                  operands[1]),
19060				UNSPEC_BNDLDX_ADDR);
19061  operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19062  MEM_VOLATILE_P (operands[4]) = 1;
19063})
19064
19065(define_insn "*<mode>_stx"
19066  [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19067			 [(unspec:<bnd_ptr>
19068			  [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19069	                   (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19070			 UNSPEC_BNDLDX_ADDR)])
19071	               (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
19072              (set (match_operand:BLK 4 "bnd_mem_operator")
19073                   (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19074  "TARGET_MPX"
19075  "bndstx\t{%2, %3|%3, %2}"
19076  [(set_attr "type" "mpxst")])
19077
19078(define_insn "move_size_reloc_<mode>"
19079  [(set (match_operand:SWI48 0 "register_operand" "=r")
19080       (unspec:SWI48
19081        [(match_operand:SWI48 1 "symbol_operand")]
19082        UNSPEC_SIZEOF))]
19083  "TARGET_MPX"
19084{
19085  if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19086    return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19087  else
19088    return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19089}
19090  [(set_attr "type" "imov")
19091   (set_attr "mode" "<MODE>")])
19092
19093(include "mmx.md")
19094(include "sse.md")
19095(include "sync.md")
19096