1157184Sache;; GCC machine description for IA-32 and x86-64.
2157184Sache;; Copyright (C) 1988-2020 Free Software Foundation, Inc.
3157184Sache;; Mostly by William Schelter.
4157184Sache;; x86_64 support added by Jan Hubicka
5157184Sache;;
6157184Sache;; This file is part of GCC.
7157184Sache;;
8157184Sache;; GCC is free software; you can redistribute it and/or modify
9157184Sache;; it under the terms of the GNU General Public License as published by
10157184Sache;; the Free Software Foundation; either version 3, or (at your option)
11157184Sache;; any later version.
12157184Sache;;
13157184Sache;; GCC is distributed in the hope that it will be useful,
14157184Sache;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15157184Sache;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16157184Sache;; GNU General Public License for more details.
17157184Sache;;
18157184Sache;; You should have received a copy of the GNU General Public License
19157184Sache;; along with GCC; see the file COPYING3.  If not see
20157184Sache;; <http://www.gnu.org/licenses/>.  */
21157184Sache;;
22157184Sache;; The original PO technology requires these to be ordered by speed,
23157184Sache;; so that assigner will pick the fastest.
24157184Sache;;
25157184Sache;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26157184Sache;;
27157184Sache;; The special asm out single letter directives following a '%' are:
28157184Sache;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29157184Sache;; C -- print opcode suffix for set/cmov insn.
30157184Sache;; c -- like C, but print reversed condition
31157184Sache;; F,f -- likewise, but for floating-point.
32157184Sache;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33157184Sache;;      otherwise nothing
34157184Sache;; R -- print the prefix for register names.
35157184Sache;; z -- print the opcode suffix for the size of the current operand.
36157184Sache;; Z -- likewise, with special suffixes for x87 instructions.
37157184Sache;; * -- print a star (in certain assembler syntax)
38157184Sache;; A -- print an absolute memory reference.
39157184Sache;; E -- print address with DImode register names if TARGET_64BIT.
40157184Sache;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41157184Sache;; s -- print a shift double count, followed by the assemblers argument
42157184Sache;;	delimiter.
43157184Sache;; b -- print the QImode name of the register for the indicated operand.
44157184Sache;;	%b0 would print %al if operands[0] is reg 0.
45157184Sache;; w --  likewise, print the HImode name of the register.
46157184Sache;; k --  likewise, print the SImode name of the register.
47157184Sache;; q --  likewise, print the DImode name of the register.
48157184Sache;; x --  likewise, print the V4SFmode name of the register.
49157184Sache;; t --  likewise, print the V8SFmode name of the register.
50157184Sache;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51157184Sache;; y -- print "st(0)" instead of "st" as a register.
52157184Sache;; d -- print duplicated register operand for AVX instruction.
53157184Sache;; D -- print condition for SSE cmp instruction.
54157184Sache;; P -- if PIC, print an @PLT suffix.
55157184Sache;; p -- print raw symbol name.
56157184Sache;; X -- don't print any sort of PIC '@' suffix for a symbol.
57157184Sache;; & -- print some in-use local-dynamic symbol name.
58157184Sache;; H -- print a memory address offset by 8; used for sse high-parts
59157184Sache;; K -- print HLE lock prefix
60157184Sache;; Y -- print condition for XOP pcom* instruction.
61157184Sache;; + -- print a branch hint as 'cs' or 'ds' prefix
62157184Sache;; ; -- print a semicolon (after prefixes due to bug in older gas).
63157184Sache;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64157184Sache;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65157184Sache;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
66157184Sache
67157184Sache(define_c_enum "unspec" [
68157184Sache  ;; Relocation specifiers
69157184Sache  UNSPEC_GOT
70157184Sache  UNSPEC_GOTOFF
71157184Sache  UNSPEC_GOTPCREL
72157184Sache  UNSPEC_GOTTPOFF
73157184Sache  UNSPEC_TPOFF
74157184Sache  UNSPEC_NTPOFF
75157184Sache  UNSPEC_DTPOFF
76157184Sache  UNSPEC_GOTNTPOFF
77157184Sache  UNSPEC_INDNTPOFF
78157184Sache  UNSPEC_PLTOFF
79157184Sache  UNSPEC_MACHOPIC_OFFSET
80157184Sache  UNSPEC_PCREL
81157184Sache  UNSPEC_SIZEOF
82157184Sache
83157184Sache  ;; Prologue support
84157184Sache  UNSPEC_STACK_ALLOC
85157184Sache  UNSPEC_SET_GOT
86157184Sache  UNSPEC_SET_RIP
87157184Sache  UNSPEC_SET_GOT_OFFSET
88157184Sache  UNSPEC_MEMORY_BLOCKAGE
89157184Sache  UNSPEC_PROBE_STACK
90157184Sache
91157184Sache  ;; TLS support
92157184Sache  UNSPEC_TP
93157184Sache  UNSPEC_TLS_GD
94157184Sache  UNSPEC_TLS_LD_BASE
95157184Sache  UNSPEC_TLSDESC
96157184Sache  UNSPEC_TLS_IE_SUN
97157184Sache
98157184Sache  ;; Other random patterns
99157184Sache  UNSPEC_SCAS
100157184Sache  UNSPEC_FNSTSW
101157184Sache  UNSPEC_SAHF
102157184Sache  UNSPEC_NOTRAP
103157184Sache  UNSPEC_PARITY
104157184Sache  UNSPEC_FSTCW
105157184Sache  UNSPEC_REP
106157184Sache  UNSPEC_LD_MPIC	; load_macho_picbase
107157184Sache  UNSPEC_TRUNC_NOOP
108157184Sache  UNSPEC_DIV_ALREADY_SPLIT
109157184Sache  UNSPEC_PAUSE
110157184Sache  UNSPEC_LEA_ADDR
111157184Sache  UNSPEC_XBEGIN_ABORT
112157184Sache  UNSPEC_STOS
113157184Sache  UNSPEC_PEEPSIB
114157184Sache  UNSPEC_INSN_FALSE_DEP
115157184Sache  UNSPEC_SBB
116157184Sache
117157184Sache  ;; For SSE/MMX support:
118157184Sache  UNSPEC_FIX_NOTRUNC
119157184Sache  UNSPEC_MASKMOV
120157184Sache  UNSPEC_MOVMSK
121157184Sache  UNSPEC_RCP
122157184Sache  UNSPEC_RSQRT
123157184Sache  UNSPEC_PSADBW
124157184Sache
125157184Sache  ;; Generic math support
126157184Sache  UNSPEC_COPYSIGN
127157184Sache  UNSPEC_XORSIGN
128157184Sache  UNSPEC_IEEE_MIN	; not commutative
129157184Sache  UNSPEC_IEEE_MAX	; not commutative
130157184Sache
131157184Sache  ;; x87 Floating point
132157184Sache  UNSPEC_SIN
133157184Sache  UNSPEC_COS
134157184Sache  UNSPEC_FPATAN
135157184Sache  UNSPEC_FYL2X
136157184Sache  UNSPEC_FYL2XP1
137157184Sache  UNSPEC_FRNDINT
138157184Sache  UNSPEC_FIST
139157184Sache  UNSPEC_F2XM1
140157184Sache  UNSPEC_TAN
141157184Sache  UNSPEC_FXAM
142157184Sache
143157184Sache  ;; x87 Rounding
144157184Sache  UNSPEC_FRNDINT_ROUNDEVEN
145157184Sache  UNSPEC_FRNDINT_FLOOR
146157184Sache  UNSPEC_FRNDINT_CEIL
147157184Sache  UNSPEC_FRNDINT_TRUNC
148157184Sache  UNSPEC_FIST_FLOOR
149157184Sache  UNSPEC_FIST_CEIL
150157184Sache
151157184Sache  ;; x87 Double output FP
152157184Sache  UNSPEC_SINCOS_COS
153157184Sache  UNSPEC_SINCOS_SIN
154157184Sache  UNSPEC_XTRACT_FRACT
155157184Sache  UNSPEC_XTRACT_EXP
156157184Sache  UNSPEC_FSCALE_FRACT
157157184Sache  UNSPEC_FSCALE_EXP
158157184Sache  UNSPEC_FPREM_F
159157184Sache  UNSPEC_FPREM_U
160157184Sache  UNSPEC_FPREM1_F
161157184Sache  UNSPEC_FPREM1_U
162157184Sache
163157184Sache  UNSPEC_C2_FLAG
164157184Sache  UNSPEC_FXAM_MEM
165157184Sache
166157184Sache  ;; SSP patterns
167157184Sache  UNSPEC_SP_SET
168157184Sache  UNSPEC_SP_TEST
169157184Sache
170157184Sache  ;; For ROUND support
171157184Sache  UNSPEC_ROUND
172157184Sache
173157184Sache  ;; For CRC32 support
174157184Sache  UNSPEC_CRC32
175157184Sache
176157184Sache  ;; For LZCNT suppoprt
177157184Sache  UNSPEC_LZCNT
178157184Sache
179157184Sache  ;; For BMI support
180157184Sache  UNSPEC_TZCNT
181157184Sache  UNSPEC_BEXTR
182157184Sache
183157184Sache  ;; For BMI2 support
184157184Sache  UNSPEC_PDEP
185157184Sache  UNSPEC_PEXT
186157184Sache
187157184Sache  ;; IRET support
188157184Sache  UNSPEC_INTERRUPT_RETURN
189157184Sache
190157184Sache  ;; For MOVDIRI and MOVDIR64B support
191157184Sache  UNSPEC_MOVDIRI
192157184Sache  UNSPEC_MOVDIR64B
193157184Sache])
194157184Sache
195157184Sache(define_c_enum "unspecv" [
196157184Sache  UNSPECV_UD2
197157184Sache  UNSPECV_BLOCKAGE
198157184Sache  UNSPECV_STACK_PROBE
199157184Sache  UNSPECV_PROBE_STACK_RANGE
200157184Sache  UNSPECV_ALIGN
201157184Sache  UNSPECV_PROLOGUE_USE
202157184Sache  UNSPECV_SPLIT_STACK_RETURN
203157184Sache  UNSPECV_CLD
204157184Sache  UNSPECV_NOPS
205157184Sache  UNSPECV_RDTSC
206157184Sache  UNSPECV_RDTSCP
207157184Sache  UNSPECV_RDPMC
208157184Sache  UNSPECV_LLWP_INTRINSIC
209157184Sache  UNSPECV_SLWP_INTRINSIC
210157184Sache  UNSPECV_LWPVAL_INTRINSIC
211157184Sache  UNSPECV_LWPINS_INTRINSIC
212157184Sache  UNSPECV_RDFSBASE
213157184Sache  UNSPECV_RDGSBASE
214157184Sache  UNSPECV_WRFSBASE
215157184Sache  UNSPECV_WRGSBASE
216157184Sache  UNSPECV_FXSAVE
217157184Sache  UNSPECV_FXRSTOR
218157184Sache  UNSPECV_FXSAVE64
219157184Sache  UNSPECV_FXRSTOR64
220157184Sache  UNSPECV_XSAVE
221157184Sache  UNSPECV_XRSTOR
222157184Sache  UNSPECV_XSAVE64
223157184Sache  UNSPECV_XRSTOR64
224157184Sache  UNSPECV_XSAVEOPT
225157184Sache  UNSPECV_XSAVEOPT64
226157184Sache  UNSPECV_XSAVES
227157184Sache  UNSPECV_XRSTORS
228157184Sache  UNSPECV_XSAVES64
229157184Sache  UNSPECV_XRSTORS64
230157184Sache  UNSPECV_XSAVEC
231157184Sache  UNSPECV_XSAVEC64
232157184Sache  UNSPECV_XGETBV
233157184Sache  UNSPECV_XSETBV
234157184Sache  UNSPECV_WBINVD
235157184Sache  UNSPECV_WBNOINVD
236157184Sache
237157184Sache  ;; For atomic compound assignments.
238157184Sache  UNSPECV_FNSTENV
239157184Sache  UNSPECV_FLDENV
240157184Sache  UNSPECV_FNSTSW
241157184Sache  UNSPECV_FNCLEX
242157184Sache
243157184Sache  ;; For RDRAND support
244157184Sache  UNSPECV_RDRAND
245157184Sache
246157184Sache  ;; For RDSEED support
247157184Sache  UNSPECV_RDSEED
248157184Sache
249157184Sache  ;; For RTM support
250157184Sache  UNSPECV_XBEGIN
251157184Sache  UNSPECV_XEND
252157184Sache  UNSPECV_XABORT
253157184Sache  UNSPECV_XTEST
254157184Sache
255157184Sache  UNSPECV_NLGR
256157184Sache
257157184Sache  ;; For CLWB support
258157184Sache  UNSPECV_CLWB
259157184Sache
260157184Sache  ;; For CLFLUSHOPT support
261157184Sache  UNSPECV_CLFLUSHOPT
262157184Sache
263157184Sache  ;; For MONITORX and MWAITX support 
264157184Sache  UNSPECV_MONITORX
265157184Sache  UNSPECV_MWAITX
266157184Sache
267157184Sache  ;; For CLZERO support
268157184Sache  UNSPECV_CLZERO
269157184Sache
270157184Sache  ;; For RDPKRU and WRPKRU support
271157184Sache  UNSPECV_PKU
272157184Sache
273157184Sache  ;; For RDPID support
274157184Sache  UNSPECV_RDPID
275157184Sache
276157184Sache  ;; For CET support
277157184Sache  UNSPECV_NOP_ENDBR
278157184Sache  UNSPECV_NOP_RDSSP
279157184Sache  UNSPECV_INCSSP
280157184Sache  UNSPECV_SAVEPREVSSP
281157184Sache  UNSPECV_RSTORSSP
282157184Sache  UNSPECV_WRSS
283157184Sache  UNSPECV_WRUSS
284157184Sache  UNSPECV_SETSSBSY
285157184Sache  UNSPECV_CLRSSBSY
286157184Sache
287157184Sache  ;; For WAITPKG support
288157184Sache  UNSPECV_UMWAIT
289157184Sache  UNSPECV_UMONITOR
290157184Sache  UNSPECV_TPAUSE
291157184Sache
292157184Sache  ;; For CLDEMOTE support
293157184Sache  UNSPECV_CLDEMOTE
294157184Sache
295157184Sache  ;; For Speculation Barrier support
296157184Sache  UNSPECV_SPECULATION_BARRIER
297157184Sache
298157184Sache  UNSPECV_PTWRITE
299157184Sache
300157184Sache  ;; For ENQCMD and ENQCMDS support
301157184Sache  UNSPECV_ENQCMD
302157184Sache  UNSPECV_ENQCMDS
303157184Sache])
304157184Sache
305157184Sache;; Constants to represent rounding modes in the ROUND instruction
306157184Sache(define_constants
307157184Sache  [(ROUND_ROUNDEVEN		0x0)
308157184Sache   (ROUND_FLOOR			0x1)
309157184Sache   (ROUND_CEIL			0x2)
310157184Sache   (ROUND_TRUNC			0x3)
311157184Sache   (ROUND_MXCSR			0x4)
312157184Sache   (ROUND_NO_EXC		0x8)
313157184Sache  ])
314157184Sache
315157184Sache;; Constants to represent AVX512F embeded rounding
316157184Sache(define_constants
317157184Sache  [(ROUND_NEAREST_INT			0)
318157184Sache   (ROUND_NEG_INF			1)
319157184Sache   (ROUND_POS_INF			2)
320157184Sache   (ROUND_ZERO				3)
321157184Sache   (NO_ROUND				4)
322157184Sache   (ROUND_SAE				8)
323157184Sache  ])
324157184Sache
325157184Sache;; Constants to represent pcomtrue/pcomfalse variants
326157184Sache(define_constants
327157184Sache  [(PCOM_FALSE			0)
328157184Sache   (PCOM_TRUE			1)
329157184Sache   (COM_FALSE_S			2)
330157184Sache   (COM_FALSE_P			3)
331157184Sache   (COM_TRUE_S			4)
332157184Sache   (COM_TRUE_P			5)
333157184Sache  ])
334157184Sache
335157184Sache;; Constants used in the XOP pperm instruction
336157184Sache(define_constants
337157184Sache  [(PPERM_SRC			0x00)	/* copy source */
338157184Sache   (PPERM_INVERT		0x20)	/* invert source */
339157184Sache   (PPERM_REVERSE		0x40)	/* bit reverse source */
340157184Sache   (PPERM_REV_INV		0x60)	/* bit reverse & invert src */
341157184Sache   (PPERM_ZERO			0x80)	/* all 0's */
342157184Sache   (PPERM_ONES			0xa0)	/* all 1's */
343157184Sache   (PPERM_SIGN			0xc0)	/* propagate sign bit */
344157184Sache   (PPERM_INV_SIGN		0xe0)	/* invert & propagate sign */
345157184Sache   (PPERM_SRC1			0x00)	/* use first source byte */
346157184Sache   (PPERM_SRC2			0x10)	/* use second source byte */
347157184Sache   ])
348157184Sache
349157184Sache;; Registers by name.
350157184Sache(define_constants
351157184Sache  [(AX_REG			 0)
352157184Sache   (DX_REG			 1)
353157184Sache   (CX_REG			 2)
354157184Sache   (BX_REG			 3)
355157184Sache   (SI_REG			 4)
356157184Sache   (DI_REG			 5)
357157184Sache   (BP_REG			 6)
358157184Sache   (SP_REG			 7)
359157184Sache   (ST0_REG			 8)
360157184Sache   (ST1_REG			 9)
361157184Sache   (ST2_REG			10)
362157184Sache   (ST3_REG			11)
363157184Sache   (ST4_REG			12)
364157184Sache   (ST5_REG			13)
365157184Sache   (ST6_REG			14)
366157184Sache   (ST7_REG			15)
367157184Sache   (ARGP_REG			16)
368157184Sache   (FLAGS_REG			17)
369157184Sache   (FPSR_REG			18)
370157184Sache   (FRAME_REG			19)
371157184Sache   (XMM0_REG			20)
372157184Sache   (XMM1_REG			21)
373157184Sache   (XMM2_REG			22)
374157184Sache   (XMM3_REG			23)
375157184Sache   (XMM4_REG			24)
376157184Sache   (XMM5_REG			25)
377157184Sache   (XMM6_REG			26)
378157184Sache   (XMM7_REG			27)
379157184Sache   (MM0_REG			28)
380157184Sache   (MM1_REG			29)
381157184Sache   (MM2_REG			30)
382157184Sache   (MM3_REG			31)
383157184Sache   (MM4_REG			32)
384157184Sache   (MM5_REG			33)
385157184Sache   (MM6_REG			34)
386157184Sache   (MM7_REG			35)
387157184Sache   (R8_REG			36)
388157184Sache   (R9_REG			37)
389157184Sache   (R10_REG			38)
390157184Sache   (R11_REG			39)
391157184Sache   (R12_REG			40)
392157184Sache   (R13_REG			41)
393157184Sache   (R14_REG			42)
394157184Sache   (R15_REG			43)
395157184Sache   (XMM8_REG			44)
396157184Sache   (XMM9_REG			45)
397157184Sache   (XMM10_REG			46)
398157184Sache   (XMM11_REG			47)
399157184Sache   (XMM12_REG			48)
400157184Sache   (XMM13_REG			49)
401157184Sache   (XMM14_REG			50)
402157184Sache   (XMM15_REG			51)
403157184Sache   (XMM16_REG			52)
404157184Sache   (XMM17_REG			53)
405157184Sache   (XMM18_REG			54)
406157184Sache   (XMM19_REG			55)
407157184Sache   (XMM20_REG			56)
408157184Sache   (XMM21_REG			57)
409157184Sache   (XMM22_REG			58)
410157184Sache   (XMM23_REG			59)
411157184Sache   (XMM24_REG			60)
412157184Sache   (XMM25_REG			61)
413157184Sache   (XMM26_REG			62)
414157184Sache   (XMM27_REG			63)
415157184Sache   (XMM28_REG			64)
416157184Sache   (XMM29_REG			65)
417157184Sache   (XMM30_REG			66)
418157184Sache   (XMM31_REG			67)
419157184Sache   (MASK0_REG			68)
420157184Sache   (MASK1_REG			69)
421157184Sache   (MASK2_REG			70)
422157184Sache   (MASK3_REG			71)
423157184Sache   (MASK4_REG			72)
424157184Sache   (MASK5_REG			73)
425157184Sache   (MASK6_REG			74)
426157184Sache   (MASK7_REG			75)
427157184Sache   (FIRST_PSEUDO_REG		76)
428157184Sache  ])
429157184Sache
430157184Sache;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
431157184Sache;; from i386.c.
432157184Sache
433157184Sache;; In C guard expressions, put expressions which may be compile-time
434157184Sache;; constants first.  This allows for better optimization.  For
435157184Sache;; example, write "TARGET_64BIT && reload_completed", not
436157184Sache;; "reload_completed && TARGET_64BIT".
437157184Sache
438157184Sache
439;; Processor type.
440(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
441		    atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
442		    bdver4,btver2,znver1,znver2,znver3"
443  (const (symbol_ref "ix86_schedule")))
444
445;; A basic instruction type.  Refinements due to arguments to be
446;; provided in other attributes.
447(define_attr "type"
448  "other,multi,
449   alu,alu1,negnot,imov,imovx,lea,
450   incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
451   imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
452   push,pop,call,callv,leave,
453   str,bitmanip,
454   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
455   fxch,fistp,fisttp,frndint,
456   sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
457   ssemul,sseimul,ssediv,sselog,sselog1,
458   sseishft,sseishft1,ssecmp,ssecomi,
459   ssecvt,ssecvt1,sseicvt,sseins,
460   sseshuf,sseshuf1,ssemuladd,sse4arg,
461   lwp,mskmov,msklog,
462   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
463  (const_string "other"))
464
465;; Main data type used by the insn
466(define_attr "mode"
467  "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
468  V2DF,V2SF,V1DF,V8DF"
469  (const_string "unknown"))
470
471;; The CPU unit operations uses.
472(define_attr "unit" "integer,i387,sse,mmx,unknown"
473  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
474			  fxch,fistp,fisttp,frndint")
475	   (const_string "i387")
476	 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
477			  ssemul,sseimul,ssediv,sselog,sselog1,
478			  sseishft,sseishft1,ssecmp,ssecomi,
479			  ssecvt,ssecvt1,sseicvt,sseins,
480			  sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
481	   (const_string "sse")
482	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
483	   (const_string "mmx")
484	 (eq_attr "type" "other")
485	   (const_string "unknown")]
486	 (const_string "integer")))
487
488;; The (bounding maximum) length of an instruction immediate.
489(define_attr "length_immediate" ""
490  (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
491			  bitmanip,imulx,msklog,mskmov")
492	   (const_int 0)
493	 (eq_attr "unit" "i387,sse,mmx")
494	   (const_int 0)
495	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
496			  rotate,rotatex,rotate1,imul,icmp,push,pop")
497	   (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
498	 (eq_attr "type" "imov,test")
499	   (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
500	 (eq_attr "type" "call")
501	   (if_then_else (match_operand 0 "constant_call_address_operand")
502	     (const_int 4)
503	     (const_int 0))
504	 (eq_attr "type" "callv")
505	   (if_then_else (match_operand 1 "constant_call_address_operand")
506	     (const_int 4)
507	     (const_int 0))
508	 ;; We don't know the size before shorten_branches.  Expect
509	 ;; the instruction to fit for better scheduling.
510	 (eq_attr "type" "ibr")
511	   (const_int 1)
512	 ]
513	 (symbol_ref "/* Update immediate_length and other attributes! */
514		      gcc_unreachable (),1")))
515
516;; The (bounding maximum) length of an instruction address.
517(define_attr "length_address" ""
518  (cond [(eq_attr "type" "str,other,multi,fxch")
519	   (const_int 0)
520	 (and (eq_attr "type" "call")
521	      (match_operand 0 "constant_call_address_operand"))
522	     (const_int 0)
523	 (and (eq_attr "type" "callv")
524	      (match_operand 1 "constant_call_address_operand"))
525	     (const_int 0)
526	 ]
527	 (symbol_ref "ix86_attr_length_address_default (insn)")))
528
529;; Set when length prefix is used.
530(define_attr "prefix_data16" ""
531  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
532	   (const_int 0)
533	 (eq_attr "mode" "HI")
534	   (const_int 1)
535	 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
536	   (const_int 1)
537	]
538	(const_int 0)))
539
540;; Set when string REP prefix is used.
541(define_attr "prefix_rep" ""
542  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
543	   (const_int 0)
544	 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
545	   (const_int 1)
546	]
547	(const_int 0)))
548
549;; Set when 0f opcode prefix is used.
550(define_attr "prefix_0f" ""
551  (if_then_else
552    (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
553	 (eq_attr "unit" "sse,mmx"))
554    (const_int 1)
555    (const_int 0)))
556
557;; Set when REX opcode prefix is used.
558(define_attr "prefix_rex" ""
559  (cond [(not (match_test "TARGET_64BIT"))
560	   (const_int 0)
561	 (and (eq_attr "mode" "DI")
562	      (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
563		   (eq_attr "unit" "!mmx")))
564	   (const_int 1)
565	 (and (eq_attr "mode" "QI")
566	      (match_test "x86_extended_QIreg_mentioned_p (insn)"))
567	   (const_int 1)
568	 (match_test "x86_extended_reg_mentioned_p (insn)")
569	   (const_int 1)
570	 (and (eq_attr "type" "imovx")
571	      (match_operand:QI 1 "ext_QIreg_operand"))
572	   (const_int 1)
573	]
574	(const_int 0)))
575
576;; There are also additional prefixes in 3DNOW, SSSE3.
577;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
578;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
579;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
580(define_attr "prefix_extra" ""
581  (cond [(eq_attr "type" "ssemuladd,sse4arg")
582	   (const_int 2)
583	 (eq_attr "type" "sseiadd1,ssecvt1")
584	   (const_int 1)
585	]
586	(const_int 0)))
587
588;; Prefix used: original, VEX or maybe VEX.
589(define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
590  (cond [(eq_attr "mode" "OI,V8SF,V4DF")
591           (const_string "vex")
592         (eq_attr "mode" "XI,V16SF,V8DF")
593           (const_string "evex")
594        ]
595        (const_string "orig")))
596
597;; VEX W bit is used.
598(define_attr "prefix_vex_w" "" (const_int 0))
599
600;; The length of VEX prefix
601;; Only instructions with 0f prefix can have 2 byte VEX prefix,
602;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
603;; still prefix_0f 1, with prefix_extra 1.
604(define_attr "length_vex" ""
605  (if_then_else (and (eq_attr "prefix_0f" "1")
606		     (eq_attr "prefix_extra" "0"))
607    (if_then_else (eq_attr "prefix_vex_w" "1")
608      (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
609      (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
610    (if_then_else (eq_attr "prefix_vex_w" "1")
611      (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
612      (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
613
614;; 4-bytes evex prefix and 1 byte opcode.
615(define_attr "length_evex" "" (const_int 5))
616
617;; Set when modrm byte is used.
618(define_attr "modrm" ""
619  (cond [(eq_attr "type" "str,leave")
620	   (const_int 0)
621	 (eq_attr "unit" "i387")
622	   (const_int 0)
623         (and (eq_attr "type" "incdec")
624	      (and (not (match_test "TARGET_64BIT"))
625		   (ior (match_operand:SI 1 "register_operand")
626			(match_operand:HI 1 "register_operand"))))
627	   (const_int 0)
628	 (and (eq_attr "type" "push")
629	      (not (match_operand 1 "memory_operand")))
630	   (const_int 0)
631	 (and (eq_attr "type" "pop")
632	      (not (match_operand 0 "memory_operand")))
633	   (const_int 0)
634	 (and (eq_attr "type" "imov")
635	      (and (not (eq_attr "mode" "DI"))
636		   (ior (and (match_operand 0 "register_operand")
637			     (match_operand 1 "immediate_operand"))
638		        (ior (and (match_operand 0 "ax_reg_operand")
639				  (match_operand 1 "memory_displacement_only_operand"))
640			     (and (match_operand 0 "memory_displacement_only_operand")
641				  (match_operand 1 "ax_reg_operand"))))))
642	   (const_int 0)
643	 (and (eq_attr "type" "call")
644	      (match_operand 0 "constant_call_address_operand"))
645	     (const_int 0)
646	 (and (eq_attr "type" "callv")
647	      (match_operand 1 "constant_call_address_operand"))
648	     (const_int 0)
649	 (and (eq_attr "type" "alu,alu1,icmp,test")
650	      (match_operand 0 "ax_reg_operand"))
651	     (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
652	 ]
653	 (const_int 1)))
654
655;; The (bounding maximum) length of an instruction in bytes.
656;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
657;; Later we may want to split them and compute proper length as for
658;; other insns.
659(define_attr "length" ""
660  (cond [(eq_attr "type" "other,multi,fistp,frndint")
661	   (const_int 16)
662	 (eq_attr "type" "fcmp")
663	   (const_int 4)
664	 (eq_attr "unit" "i387")
665	   (plus (const_int 2)
666		 (plus (attr "prefix_data16")
667		       (attr "length_address")))
668	 (ior (eq_attr "prefix" "evex")
669	      (and (ior (eq_attr "prefix" "maybe_evex")
670			(eq_attr "prefix" "maybe_vex"))
671		   (match_test "TARGET_AVX512F")))
672	   (plus (attr "length_evex")
673		 (plus (attr "length_immediate")
674		       (plus (attr "modrm")
675			     (attr "length_address"))))
676	 (ior (eq_attr "prefix" "vex")
677	      (and (ior (eq_attr "prefix" "maybe_vex")
678			(eq_attr "prefix" "maybe_evex"))
679		   (match_test "TARGET_AVX")))
680	   (plus (attr "length_vex")
681		 (plus (attr "length_immediate")
682		       (plus (attr "modrm")
683			     (attr "length_address"))))]
684	 (plus (plus (attr "modrm")
685		     (plus (attr "prefix_0f")
686			   (plus (attr "prefix_rex")
687				 (plus (attr "prefix_extra")
688				       (const_int 1)))))
689	       (plus (attr "prefix_rep")
690		     (plus (attr "prefix_data16")
691			   (plus (attr "length_immediate")
692				 (attr "length_address")))))))
693
694;; The `memory' attribute is `none' if no memory is referenced, `load' or
695;; `store' if there is a simple memory reference therein, or `unknown'
696;; if the instruction is complex.
697
698(define_attr "memory" "none,load,store,both,unknown"
699  (cond [(eq_attr "type" "other,multi,str,lwp")
700	   (const_string "unknown")
701	 (eq_attr "type" "lea,fcmov,fpspc")
702	   (const_string "none")
703	 (eq_attr "type" "fistp,leave")
704	   (const_string "both")
705	 (eq_attr "type" "frndint")
706	   (const_string "load")
707	 (eq_attr "type" "push")
708	   (if_then_else (match_operand 1 "memory_operand")
709	     (const_string "both")
710	     (const_string "store"))
711	 (eq_attr "type" "pop")
712	   (if_then_else (match_operand 0 "memory_operand")
713	     (const_string "both")
714	     (const_string "load"))
715	 (eq_attr "type" "setcc")
716	   (if_then_else (match_operand 0 "memory_operand")
717	     (const_string "store")
718	     (const_string "none"))
719	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
720	   (if_then_else (ior (match_operand 0 "memory_operand")
721			      (match_operand 1 "memory_operand"))
722	     (const_string "load")
723	     (const_string "none"))
724	 (eq_attr "type" "ibr")
725	   (if_then_else (match_operand 0 "memory_operand")
726	     (const_string "load")
727	     (const_string "none"))
728	 (eq_attr "type" "call")
729	   (if_then_else (match_operand 0 "constant_call_address_operand")
730	     (const_string "none")
731	     (const_string "load"))
732	 (eq_attr "type" "callv")
733	   (if_then_else (match_operand 1 "constant_call_address_operand")
734	     (const_string "none")
735	     (const_string "load"))
736	 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
737	      (match_operand 1 "memory_operand"))
738	   (const_string "both")
739	 (and (match_operand 0 "memory_operand")
740	      (match_operand 1 "memory_operand"))
741	   (const_string "both")
742	 (match_operand 0 "memory_operand")
743	   (const_string "store")
744	 (match_operand 1 "memory_operand")
745	   (const_string "load")
746	 (and (eq_attr "type"
747		 "!alu1,negnot,ishift1,rotate1,
748		   imov,imovx,icmp,test,bitmanip,
749		   fmov,fcmp,fsgn,
750		   sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
751		   sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
752		   mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
753	      (match_operand 2 "memory_operand"))
754	   (const_string "load")
755	 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
756	      (match_operand 3 "memory_operand"))
757	   (const_string "load")
758	]
759	(const_string "none")))
760
761;; Indicates if an instruction has both an immediate and a displacement.
762
763(define_attr "imm_disp" "false,true,unknown"
764  (cond [(eq_attr "type" "other,multi")
765	   (const_string "unknown")
766	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
767	      (and (match_operand 0 "memory_displacement_operand")
768		   (match_operand 1 "immediate_operand")))
769	   (const_string "true")
770	 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
771	      (and (match_operand 0 "memory_displacement_operand")
772		   (match_operand 2 "immediate_operand")))
773	   (const_string "true")
774	]
775	(const_string "false")))
776
777;; Indicates if an FP operation has an integer source.
778
779(define_attr "fp_int_src" "false,true"
780  (const_string "false"))
781
782;; Defines rounding mode of an FP operation.
783
784(define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
785  (const_string "any"))
786
787;; Define attribute to indicate AVX insns with partial XMM register update.
788(define_attr "avx_partial_xmm_update" "false,true"
789  (const_string "false"))
790
791;; Define attribute to classify add/sub insns that consumes carry flag (CF)
792(define_attr "use_carry" "0,1" (const_string "0"))
793
794;; Define attribute to indicate unaligned ssemov insns
795(define_attr "movu" "0,1" (const_string "0"))
796
797;; Used to control the "enabled" attribute on a per-instruction basis.
798(define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
799		    sse_noavx,sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
800		    avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
801		    avx512bw,noavx512bw,avx512dq,noavx512dq,
802		    avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
803  (const_string "base"))
804
805;; Define instruction set of MMX instructions
806(define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
807  (const_string "base"))
808
809(define_attr "enabled" ""
810  (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
811	 (eq_attr "isa" "x64_sse2")
812	   (symbol_ref "TARGET_64BIT && TARGET_SSE2")
813	 (eq_attr "isa" "x64_sse4")
814	   (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
815	 (eq_attr "isa" "x64_sse4_noavx")
816	   (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
817	 (eq_attr "isa" "x64_avx")
818	   (symbol_ref "TARGET_64BIT && TARGET_AVX")
819	 (eq_attr "isa" "x64_avx512dq")
820	   (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
821	 (eq_attr "isa" "x64_avx512bw")
822	   (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
823	 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
824	 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
825	 (eq_attr "isa" "sse_noavx")
826	   (symbol_ref "TARGET_SSE && !TARGET_AVX")
827	 (eq_attr "isa" "sse2_noavx")
828	   (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
829	 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
830	 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
831	 (eq_attr "isa" "sse4_noavx")
832	   (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
833	 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
834	 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
835	 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
836	 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
837	 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
838	 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
839	 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
840	 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
841	 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
842	 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
843	 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
844	 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
845	 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
846	 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
847	 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
848	 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
849
850	 (eq_attr "mmx_isa" "native")
851	   (symbol_ref "!TARGET_MMX_WITH_SSE")
852	 (eq_attr "mmx_isa" "sse")
853	   (symbol_ref "TARGET_MMX_WITH_SSE")
854	 (eq_attr "mmx_isa" "sse_noavx")
855	   (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
856	 (eq_attr "mmx_isa" "avx")
857	   (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
858	]
859	(const_int 1)))
860
861(define_attr "preferred_for_size" "" (const_int 1))
862(define_attr "preferred_for_speed" "" (const_int 1))
863
864;; Describe a user's asm statement.
865(define_asm_attributes
866  [(set_attr "length" "128")
867   (set_attr "type" "multi")])
868
869(define_code_iterator plusminus [plus minus])
870
871(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
872
873(define_code_iterator multdiv [mult div])
874
875;; Base name for define_insn
876(define_code_attr plusminus_insn
877  [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
878   (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
879
880;; Base name for insn mnemonic.
881(define_code_attr plusminus_mnemonic
882  [(plus "add") (ss_plus "adds") (us_plus "addus")
883   (minus "sub") (ss_minus "subs") (us_minus "subus")])
884(define_code_attr multdiv_mnemonic
885  [(mult "mul") (div "div")])
886
887;; Mark commutative operators as such in constraints.
888(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
889			(minus "") (ss_minus "") (us_minus "")])
890
891;; Mapping of max and min
892(define_code_iterator maxmin [smax smin umax umin])
893
894;; Mapping of signed max and min
895(define_code_iterator smaxmin [smax smin])
896
897;; Mapping of unsigned max and min
898(define_code_iterator umaxmin [umax umin])
899
900;; Base name for integer and FP insn mnemonic
901(define_code_attr maxmin_int [(smax "maxs") (smin "mins")
902			      (umax "maxu") (umin "minu")])
903(define_code_attr maxmin_float [(smax "max") (smin "min")])
904
905(define_int_iterator IEEE_MAXMIN
906	[UNSPEC_IEEE_MAX
907	 UNSPEC_IEEE_MIN])
908
909(define_int_attr ieee_maxmin
910	[(UNSPEC_IEEE_MAX "max")
911	 (UNSPEC_IEEE_MIN "min")])
912
913;; Mapping of logic operators
914(define_code_iterator any_logic [and ior xor])
915(define_code_iterator any_or [ior xor])
916(define_code_iterator fpint_logic [and xor])
917
918;; Base name for insn mnemonic.
919(define_code_attr logic [(and "and") (ior "or") (xor "xor")])
920
921;; Mapping of logic-shift operators
922(define_code_iterator any_lshift [ashift lshiftrt])
923
924;; Mapping of shift-right operators
925(define_code_iterator any_shiftrt [lshiftrt ashiftrt])
926
927;; Mapping of all shift operators
928(define_code_iterator any_shift [ashift lshiftrt ashiftrt])
929
930;; Base name for define_insn
931(define_code_attr shift_insn
932  [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
933
934;; Base name for insn mnemonic.
935(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
936(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
937
938;; Mapping of rotate operators
939(define_code_iterator any_rotate [rotate rotatert])
940
941;; Base name for define_insn
942(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
943
944;; Base name for insn mnemonic.
945(define_code_attr rotate [(rotate "rol") (rotatert "ror")])
946
947;; Mapping of abs neg operators
948(define_code_iterator absneg [abs neg])
949
950;; Base name for x87 insn mnemonic.
951(define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
952
953;; Used in signed and unsigned widening multiplications.
954(define_code_iterator any_extend [sign_extend zero_extend])
955
956;; Prefix for insn menmonic.
957(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
958			     (div "i") (udiv "")])
959;; Prefix for define_insn
960(define_code_attr s [(sign_extend "s") (zero_extend "u")])
961(define_code_attr u [(sign_extend "") (zero_extend "u")
962		     (div "") (udiv "u")])
963(define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
964			  (div "false") (udiv "true")])
965
966;; Used in signed and unsigned truncations.
967(define_code_iterator any_truncate [ss_truncate truncate us_truncate])
968;; Instruction suffix for truncations.
969(define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
970
971;; Used in signed and unsigned fix.
972(define_code_iterator any_fix [fix unsigned_fix])
973(define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
974(define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
975(define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
976
977;; Used in signed and unsigned float.
978(define_code_iterator any_float [float unsigned_float])
979(define_code_attr floatsuffix [(float "") (unsigned_float "u")])
980(define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
981(define_code_attr floatprefix [(float "s") (unsigned_float "u")])
982
983;; All integer modes.
984(define_mode_iterator SWI1248x [QI HI SI DI])
985
986;; All integer modes without QImode.
987(define_mode_iterator SWI248x [HI SI DI])
988
989;; All integer modes without QImode and HImode.
990(define_mode_iterator SWI48x [SI DI])
991
992;; All integer modes without SImode and DImode.
993(define_mode_iterator SWI12 [QI HI])
994
995;; All integer modes without DImode.
996(define_mode_iterator SWI124 [QI HI SI])
997
998;; All integer modes without QImode and DImode.
999(define_mode_iterator SWI24 [HI SI])
1000
1001;; Single word integer modes.
1002(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1003
1004;; Single word integer modes without QImode.
1005(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1006
1007;; Single word integer modes without QImode and HImode.
1008(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1009
1010;; All math-dependant single and double word integer modes.
1011(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1012			     (HI "TARGET_HIMODE_MATH")
1013			     SI DI (TI "TARGET_64BIT")])
1014
1015;; Math-dependant single word integer modes.
1016(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1017			    (HI "TARGET_HIMODE_MATH")
1018			    SI (DI "TARGET_64BIT")])
1019
1020;; Math-dependant integer modes without DImode.
1021(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1022			       (HI "TARGET_HIMODE_MATH")
1023			       SI])
1024
1025;; Math-dependant integer modes with DImode (enabled for 32bit with STV).
1026(define_mode_iterator SWIM1248s
1027	[(QI "TARGET_QIMODE_MATH")
1028	 (HI "TARGET_HIMODE_MATH")
1029	 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")])
1030
1031;; Math-dependant single word integer modes without QImode.
1032(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1033		      	       SI (DI "TARGET_64BIT")])
1034
1035;; Double word integer modes.
1036(define_mode_iterator DWI [(DI "!TARGET_64BIT")
1037			   (TI "TARGET_64BIT")])
1038
1039;; SWI and DWI together.
1040(define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1041
1042;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1043;; compile time constant, it is faster to use <MODE_SIZE> than
1044;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1045;; command line options just use GET_MODE_SIZE macro.
1046(define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1047			     (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1048			     (V16QI "16") (V32QI "32") (V64QI "64")
1049			     (V8HI "16") (V16HI "32") (V32HI "64")
1050			     (V4SI "16") (V8SI "32") (V16SI "64")
1051			     (V2DI "16") (V4DI "32") (V8DI "64")
1052			     (V1TI "16") (V2TI "32") (V4TI "64")
1053			     (V2DF "16") (V4DF "32") (V8DF "64")
1054			     (V4SF "16") (V8SF "32") (V16SF "64")])
1055
1056;; Double word integer modes as mode attribute.
1057(define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1058(define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1059
1060;; LEA mode corresponding to an integer mode
1061(define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1062
1063;; Half mode for double word integer modes.
1064(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1065			    (DI "TARGET_64BIT")])
1066
1067;; Instruction suffix for integer modes.
1068(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1069
1070;; Instruction suffix for masks.
1071(define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1072
1073;; Pointer size prefix for integer modes (Intel asm dialect)
1074(define_mode_attr iptrsize [(QI "BYTE")
1075			    (HI "WORD")
1076			    (SI "DWORD")
1077			    (DI "QWORD")])
1078
1079;; Register class for integer modes.
1080(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1081
1082;; Immediate operand constraint for integer modes.
1083(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1084
1085;; General operand constraint for word modes.
1086(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1087
1088;; Immediate operand constraint for double integer modes.
1089(define_mode_attr di [(SI "nF") (DI "Wd")])
1090
1091;; Immediate operand constraint for shifts.
1092(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1093
1094;; Print register name in the specified mode.
1095(define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1096
1097;; General operand predicate for integer modes.
1098(define_mode_attr general_operand
1099	[(QI "general_operand")
1100	 (HI "general_operand")
1101	 (SI "x86_64_general_operand")
1102	 (DI "x86_64_general_operand")
1103	 (TI "x86_64_general_operand")])
1104
1105;; General operand predicate for integer modes, where for TImode
1106;; we need both words of the operand to be general operands.
1107(define_mode_attr general_hilo_operand
1108	[(QI "general_operand")
1109	 (HI "general_operand")
1110	 (SI "x86_64_general_operand")
1111	 (DI "x86_64_general_operand")
1112	 (TI "x86_64_hilo_general_operand")])
1113
1114;; General sign extend operand predicate for integer modes,
1115;; which disallows VOIDmode operands and thus it is suitable
1116;; for use inside sign_extend.
1117(define_mode_attr general_sext_operand
1118	[(QI "sext_operand")
1119	 (HI "sext_operand")
1120	 (SI "x86_64_sext_operand")
1121	 (DI "x86_64_sext_operand")])
1122
1123;; General sign/zero extend operand predicate for integer modes.
1124(define_mode_attr general_szext_operand
1125	[(QI "general_operand")
1126	 (HI "general_operand")
1127	 (SI "x86_64_szext_general_operand")
1128	 (DI "x86_64_szext_general_operand")])
1129
1130(define_mode_attr nonmemory_szext_operand
1131	[(QI "nonmemory_operand")
1132	 (HI "nonmemory_operand")
1133	 (SI "x86_64_szext_nonmemory_operand")
1134	 (DI "x86_64_szext_nonmemory_operand")])
1135
1136;; Immediate operand predicate for integer modes.
1137(define_mode_attr immediate_operand
1138	[(QI "immediate_operand")
1139	 (HI "immediate_operand")
1140	 (SI "x86_64_immediate_operand")
1141	 (DI "x86_64_immediate_operand")])
1142
1143;; Nonmemory operand predicate for integer modes.
1144(define_mode_attr nonmemory_operand
1145	[(QI "nonmemory_operand")
1146	 (HI "nonmemory_operand")
1147	 (SI "x86_64_nonmemory_operand")
1148	 (DI "x86_64_nonmemory_operand")])
1149
1150;; Operand predicate for shifts.
1151(define_mode_attr shift_operand
1152	[(QI "nonimmediate_operand")
1153	 (HI "nonimmediate_operand")
1154	 (SI "nonimmediate_operand")
1155	 (DI "shiftdi_operand")
1156	 (TI "register_operand")])
1157
1158;; Operand predicate for shift argument.
1159(define_mode_attr shift_immediate_operand
1160	[(QI "const_1_to_31_operand")
1161	 (HI "const_1_to_31_operand")
1162	 (SI "const_1_to_31_operand")
1163	 (DI "const_1_to_63_operand")])
1164
1165;; Input operand predicate for arithmetic left shifts.
1166(define_mode_attr ashl_input_operand
1167	[(QI "nonimmediate_operand")
1168	 (HI "nonimmediate_operand")
1169	 (SI "nonimmediate_operand")
1170	 (DI "ashldi_input_operand")
1171	 (TI "reg_or_pm1_operand")])
1172
1173;; SSE and x87 SFmode and DFmode floating point modes
1174(define_mode_iterator MODEF [SF DF])
1175
1176;; All x87 floating point modes
1177(define_mode_iterator X87MODEF [SF DF XF])
1178
1179;; All SSE floating point modes
1180(define_mode_iterator SSEMODEF [SF DF TF])
1181(define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")])
1182
1183;; SSE instruction suffix for various modes
1184(define_mode_attr ssemodesuffix
1185  [(SF "ss") (DF "sd")
1186   (V16SF "ps") (V8DF "pd")
1187   (V8SF "ps") (V4DF "pd")
1188   (V4SF "ps") (V2DF "pd")
1189   (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1190   (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1191   (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1192
1193;; SSE vector suffix for floating point modes
1194(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1195
1196;; SSE vector mode corresponding to a scalar mode
1197(define_mode_attr ssevecmode
1198  [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1199(define_mode_attr ssevecmodelower
1200  [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1201
1202;; AVX512F vector mode corresponding to a scalar mode
1203(define_mode_attr avx512fvecmode
1204  [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1205
1206;; Instruction suffix for REX 64bit operators.
1207(define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1208(define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1209
1210;; This mode iterator allows :P to be used for patterns that operate on
1211;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1212(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1213
1214;; This mode iterator allows :W to be used for patterns that operate on
1215;; word_mode sized quantities.
1216(define_mode_iterator W
1217  [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1218
1219;; This mode iterator allows :PTR to be used for patterns that operate on
1220;; ptr_mode sized quantities.
1221(define_mode_iterator PTR
1222  [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1223
1224;; Scheduling descriptions
1225
1226(include "pentium.md")
1227(include "ppro.md")
1228(include "k6.md")
1229(include "athlon.md")
1230(include "bdver1.md")
1231(include "bdver3.md")
1232(include "btver2.md")
1233(include "znver1.md")
1234(include "geode.md")
1235(include "atom.md")
1236(include "slm.md")
1237(include "glm.md")
1238(include "core2.md")
1239(include "haswell.md")
1240
1241
1242;; Operand and operator predicates and constraints
1243
1244(include "predicates.md")
1245(include "constraints.md")
1246
1247
1248;; Compare and branch/compare and store instructions.
1249
1250(define_expand "cbranch<mode>4"
1251  [(set (reg:CC FLAGS_REG)
1252	(compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1253		    (match_operand:SDWIM 2 "<general_operand>")))
1254   (set (pc) (if_then_else
1255	       (match_operator 0 "ordered_comparison_operator"
1256		[(reg:CC FLAGS_REG) (const_int 0)])
1257	       (label_ref (match_operand 3))
1258	       (pc)))]
1259  ""
1260{
1261  if (MEM_P (operands[1]) && MEM_P (operands[2]))
1262    operands[1] = force_reg (<MODE>mode, operands[1]);
1263  ix86_expand_branch (GET_CODE (operands[0]),
1264		      operands[1], operands[2], operands[3]);
1265  DONE;
1266})
1267
1268(define_expand "cstore<mode>4"
1269  [(set (reg:CC FLAGS_REG)
1270	(compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1271		    (match_operand:SWIM 3 "<general_operand>")))
1272   (set (match_operand:QI 0 "register_operand")
1273	(match_operator 1 "ordered_comparison_operator"
1274	  [(reg:CC FLAGS_REG) (const_int 0)]))]
1275  ""
1276{
1277  if (MEM_P (operands[2]) && MEM_P (operands[3]))
1278    operands[2] = force_reg (<MODE>mode, operands[2]);
1279  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1280		     operands[2], operands[3]);
1281  DONE;
1282})
1283
1284(define_expand "@cmp<mode>_1"
1285  [(set (reg:CC FLAGS_REG)
1286	(compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1287		    (match_operand:SWI48 1 "<general_operand>")))])
1288
1289(define_mode_iterator SWI1248_AVX512BWDQ_64
1290  [(QI "TARGET_AVX512DQ") HI
1291   (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1292
1293(define_insn "*cmp<mode>_ccz_1"
1294  [(set (reg FLAGS_REG)
1295	(compare (match_operand:SWI1248_AVX512BWDQ_64 0
1296			"nonimmediate_operand" "<r>,?m<r>,$k")
1297		 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1298  "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1299  "@
1300   test{<imodesuffix>}\t%0, %0
1301   cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1302   kortest<mskmodesuffix>\t%0, %0"
1303  [(set_attr "type" "test,icmp,msklog")
1304   (set_attr "length_immediate" "0,1,*")
1305   (set_attr "prefix" "*,*,vex")
1306   (set_attr "mode" "<MODE>")])
1307
1308(define_insn "*cmp<mode>_ccno_1"
1309  [(set (reg FLAGS_REG)
1310	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1311		 (match_operand:SWI 1 "const0_operand")))]
1312  "ix86_match_ccmode (insn, CCNOmode)"
1313  "@
1314   test{<imodesuffix>}\t%0, %0
1315   cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1316  [(set_attr "type" "test,icmp")
1317   (set_attr "length_immediate" "0,1")
1318   (set_attr "mode" "<MODE>")])
1319
1320(define_insn "*cmp<mode>_1"
1321  [(set (reg FLAGS_REG)
1322	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1323		 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1324  "ix86_match_ccmode (insn, CCmode)"
1325  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1326  [(set_attr "type" "icmp")
1327   (set_attr "mode" "<MODE>")])
1328
1329(define_insn "*cmp<mode>_minus_1"
1330  [(set (reg FLAGS_REG)
1331	(compare
1332	  (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1333		     (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1334	  (const_int 0)))]
1335  "ix86_match_ccmode (insn, CCGOCmode)"
1336  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1337  [(set_attr "type" "icmp")
1338   (set_attr "mode" "<MODE>")])
1339
1340(define_insn "*cmpqi_ext_1"
1341  [(set (reg FLAGS_REG)
1342	(compare
1343	  (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1344	  (subreg:QI
1345	    (zero_extract:SI
1346	      (match_operand 1 "ext_register_operand" "Q,Q")
1347	      (const_int 8)
1348	      (const_int 8)) 0)))]
1349  "ix86_match_ccmode (insn, CCmode)"
1350  "cmp{b}\t{%h1, %0|%0, %h1}"
1351  [(set_attr "isa" "*,nox64")
1352   (set_attr "type" "icmp")
1353   (set_attr "mode" "QI")])
1354
1355(define_insn "*cmpqi_ext_2"
1356  [(set (reg FLAGS_REG)
1357	(compare
1358	  (subreg:QI
1359	    (zero_extract:SI
1360	      (match_operand 0 "ext_register_operand" "Q")
1361	      (const_int 8)
1362	      (const_int 8)) 0)
1363	  (match_operand:QI 1 "const0_operand")))]
1364  "ix86_match_ccmode (insn, CCNOmode)"
1365  "test{b}\t%h0, %h0"
1366  [(set_attr "type" "test")
1367   (set_attr "length_immediate" "0")
1368   (set_attr "mode" "QI")])
1369
1370(define_expand "cmpqi_ext_3"
1371  [(set (reg:CC FLAGS_REG)
1372	(compare:CC
1373	  (subreg:QI
1374	    (zero_extract:SI
1375	      (match_operand 0 "ext_register_operand")
1376	      (const_int 8)
1377	      (const_int 8)) 0)
1378	  (match_operand:QI 1 "const_int_operand")))])
1379
1380(define_insn "*cmpqi_ext_3"
1381  [(set (reg FLAGS_REG)
1382	(compare
1383	  (subreg:QI
1384	    (zero_extract:SI
1385	      (match_operand 0 "ext_register_operand" "Q,Q")
1386	      (const_int 8)
1387	      (const_int 8)) 0)
1388	  (match_operand:QI 1 "general_operand" "QnBc,m")))]
1389  "ix86_match_ccmode (insn, CCmode)"
1390  "cmp{b}\t{%1, %h0|%h0, %1}"
1391  [(set_attr "isa" "*,nox64")
1392   (set_attr "type" "icmp")
1393   (set_attr "mode" "QI")])
1394
1395(define_insn "*cmpqi_ext_4"
1396  [(set (reg FLAGS_REG)
1397	(compare
1398	  (subreg:QI
1399	    (zero_extract:SI
1400	      (match_operand 0 "ext_register_operand" "Q")
1401	      (const_int 8)
1402	      (const_int 8)) 0)
1403	  (subreg:QI
1404	    (zero_extract:SI
1405	      (match_operand 1 "ext_register_operand" "Q")
1406	      (const_int 8)
1407	      (const_int 8)) 0)))]
1408  "ix86_match_ccmode (insn, CCmode)"
1409  "cmp{b}\t{%h1, %h0|%h0, %h1}"
1410  [(set_attr "type" "icmp")
1411   (set_attr "mode" "QI")])
1412
1413;; These implement float point compares.
1414;; %%% See if we can get away with VOIDmode operands on the actual insns,
1415;; which would allow mix and match FP modes on the compares.  Which is what
1416;; the old patterns did, but with many more of them.
1417
1418(define_expand "cbranchxf4"
1419  [(set (reg:CC FLAGS_REG)
1420	(compare:CC (match_operand:XF 1 "nonmemory_operand")
1421		    (match_operand:XF 2 "nonmemory_operand")))
1422   (set (pc) (if_then_else
1423              (match_operator 0 "ix86_fp_comparison_operator"
1424               [(reg:CC FLAGS_REG)
1425                (const_int 0)])
1426              (label_ref (match_operand 3))
1427              (pc)))]
1428  "TARGET_80387"
1429{
1430  ix86_expand_branch (GET_CODE (operands[0]),
1431		      operands[1], operands[2], operands[3]);
1432  DONE;
1433})
1434
1435(define_expand "cstorexf4"
1436  [(set (reg:CC FLAGS_REG)
1437	(compare:CC (match_operand:XF 2 "nonmemory_operand")
1438		    (match_operand:XF 3 "nonmemory_operand")))
1439   (set (match_operand:QI 0 "register_operand")
1440              (match_operator 1 "ix86_fp_comparison_operator"
1441               [(reg:CC FLAGS_REG)
1442                (const_int 0)]))]
1443  "TARGET_80387"
1444{
1445  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1446		     operands[2], operands[3]);
1447  DONE;
1448})
1449
1450(define_expand "cbranch<mode>4"
1451  [(set (reg:CC FLAGS_REG)
1452	(compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1453		    (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1454   (set (pc) (if_then_else
1455              (match_operator 0 "ix86_fp_comparison_operator"
1456               [(reg:CC FLAGS_REG)
1457                (const_int 0)])
1458              (label_ref (match_operand 3))
1459              (pc)))]
1460  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1461{
1462  ix86_expand_branch (GET_CODE (operands[0]),
1463		      operands[1], operands[2], operands[3]);
1464  DONE;
1465})
1466
1467(define_expand "cstore<mode>4"
1468  [(set (reg:CC FLAGS_REG)
1469	(compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1470		    (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1471   (set (match_operand:QI 0 "register_operand")
1472              (match_operator 1 "ix86_fp_comparison_operator"
1473               [(reg:CC FLAGS_REG)
1474                (const_int 0)]))]
1475  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1476{
1477  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1478		     operands[2], operands[3]);
1479  DONE;
1480})
1481
1482(define_expand "cbranchcc4"
1483  [(set (pc) (if_then_else
1484              (match_operator 0 "comparison_operator"
1485               [(match_operand 1 "flags_reg_operand")
1486                (match_operand 2 "const0_operand")])
1487              (label_ref (match_operand 3))
1488              (pc)))]
1489  ""
1490{
1491  ix86_expand_branch (GET_CODE (operands[0]),
1492		      operands[1], operands[2], operands[3]);
1493  DONE;
1494})
1495
1496(define_expand "cstorecc4"
1497  [(set (match_operand:QI 0 "register_operand")
1498              (match_operator 1 "comparison_operator"
1499               [(match_operand 2 "flags_reg_operand")
1500                (match_operand 3 "const0_operand")]))]
1501  ""
1502{
1503  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1504		     operands[2], operands[3]);
1505  DONE;
1506})
1507
1508;; FP compares, step 1:
1509;; Set the FP condition codes and move fpsr to ax.
1510
1511;; We may not use "#" to split and emit these
1512;; due to reg-stack pops killing fpsr.
1513
1514(define_insn "*cmpxf_i387"
1515  [(set (match_operand:HI 0 "register_operand" "=a")
1516	(unspec:HI
1517	  [(compare:CCFP
1518	     (match_operand:XF 1 "register_operand" "f")
1519	     (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1520	  UNSPEC_FNSTSW))]
1521  "TARGET_80387"
1522  "* return output_fp_compare (insn, operands, false, false);"
1523  [(set_attr "type" "multi")
1524   (set_attr "unit" "i387")
1525   (set_attr "mode" "XF")])
1526
1527(define_insn "*cmp<mode>_i387"
1528  [(set (match_operand:HI 0 "register_operand" "=a")
1529	(unspec:HI
1530	  [(compare:CCFP
1531	     (match_operand:MODEF 1 "register_operand" "f")
1532	     (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1533	  UNSPEC_FNSTSW))]
1534  "TARGET_80387"
1535  "* return output_fp_compare (insn, operands, false, false);"
1536  [(set_attr "type" "multi")
1537   (set_attr "unit" "i387")
1538   (set_attr "mode" "<MODE>")])
1539
1540(define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1541  [(set (match_operand:HI 0 "register_operand" "=a")
1542	(unspec:HI
1543	  [(compare:CCFP
1544	     (match_operand:X87MODEF 1 "register_operand" "f")
1545	     (float:X87MODEF
1546	       (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1547	  UNSPEC_FNSTSW))]
1548  "TARGET_80387
1549   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1550       || optimize_function_for_size_p (cfun))"
1551  "* return output_fp_compare (insn, operands, false, false);"
1552  [(set_attr "type" "multi")
1553   (set_attr "unit" "i387")
1554   (set_attr "fp_int_src" "true")
1555   (set_attr "mode" "<SWI24:MODE>")])
1556
1557(define_insn "*cmpu<mode>_i387"
1558  [(set (match_operand:HI 0 "register_operand" "=a")
1559	(unspec:HI
1560	  [(unspec:CCFP
1561	     [(compare:CCFP
1562		(match_operand:X87MODEF 1 "register_operand" "f")
1563		(match_operand:X87MODEF 2 "register_operand" "f"))]
1564	     UNSPEC_NOTRAP)]
1565	  UNSPEC_FNSTSW))]
1566  "TARGET_80387"
1567  "* return output_fp_compare (insn, operands, false, true);"
1568  [(set_attr "type" "multi")
1569   (set_attr "unit" "i387")
1570   (set_attr "mode" "<MODE>")])
1571
1572;; FP compares, step 2:
1573;; Get ax into flags, general case.
1574
1575(define_insn "x86_sahf_1"
1576  [(set (reg:CC FLAGS_REG)
1577	(unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1578		   UNSPEC_SAHF))]
1579  "TARGET_SAHF"
1580{
1581#ifndef HAVE_AS_IX86_SAHF
1582  if (TARGET_64BIT)
1583    return ASM_BYTE "0x9e";
1584  else
1585#endif
1586  return "sahf";
1587}
1588  [(set_attr "length" "1")
1589   (set_attr "athlon_decode" "vector")
1590   (set_attr "amdfam10_decode" "direct")
1591   (set_attr "bdver1_decode" "direct")
1592   (set_attr "mode" "SI")])
1593
1594;; Pentium Pro can do both steps in one go.
1595;; (these instructions set flags directly)
1596
1597(define_subst_attr "unord" "unord_subst" "" "u")
1598(define_subst_attr "unordered" "unord_subst" "false" "true")
1599
1600(define_subst "unord_subst"
1601  [(set (match_operand:CCFP 0)
1602        (match_operand:CCFP 1))]
1603  ""
1604  [(set (match_dup 0)
1605        (unspec:CCFP
1606	  [(match_dup 1)]
1607	  UNSPEC_NOTRAP))])
1608
1609(define_insn "*cmpi<unord>xf_i387"
1610  [(set (reg:CCFP FLAGS_REG)
1611	(compare:CCFP
1612	  (match_operand:XF 0 "register_operand" "f")
1613	  (match_operand:XF 1 "register_operand" "f")))]
1614  "TARGET_80387 && TARGET_CMOVE"
1615  "* return output_fp_compare (insn, operands, true, <unordered>);"
1616  [(set_attr "type" "fcmp")
1617   (set_attr "mode" "XF")
1618   (set_attr "athlon_decode" "vector")
1619   (set_attr "amdfam10_decode" "direct")
1620   (set_attr "bdver1_decode" "double")
1621   (set_attr "znver1_decode" "double")])
1622
1623(define_insn "*cmpi<unord><MODEF:mode>"
1624  [(set (reg:CCFP FLAGS_REG)
1625	(compare:CCFP
1626	  (match_operand:MODEF 0 "register_operand" "f,v")
1627	  (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1628  "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1629   || (TARGET_80387 && TARGET_CMOVE)"
1630  "@
1631   * return output_fp_compare (insn, operands, true, <unordered>);
1632   %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1633  [(set_attr "type" "fcmp,ssecomi")
1634   (set_attr "prefix" "orig,maybe_vex")
1635   (set_attr "mode" "<MODEF:MODE>")
1636   (set_attr "prefix_rep" "*,0")
1637   (set (attr "prefix_data16")
1638	(cond [(eq_attr "alternative" "0")
1639		 (const_string "*")
1640	       (eq_attr "mode" "DF")
1641		 (const_string "1")
1642	      ]
1643	      (const_string "0")))
1644   (set_attr "athlon_decode" "vector")
1645   (set_attr "amdfam10_decode" "direct")
1646   (set_attr "bdver1_decode" "double")
1647   (set_attr "znver1_decode" "double")
1648   (set (attr "enabled")
1649     (if_then_else
1650       (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1651       (if_then_else
1652	 (eq_attr "alternative" "0")
1653	 (symbol_ref "TARGET_MIX_SSE_I387")
1654	 (symbol_ref "true"))
1655       (if_then_else
1656	 (eq_attr "alternative" "0")
1657	 (symbol_ref "true")
1658	 (symbol_ref "false"))))])
1659
1660;; Push/pop instructions.
1661
1662(define_insn "*push<mode>2"
1663  [(set (match_operand:DWI 0 "push_operand" "=<")
1664	(match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1665  ""
1666  "#"
1667  [(set_attr "type" "multi")
1668   (set_attr "mode" "<MODE>")])
1669
1670(define_split
1671  [(set (match_operand:DWI 0 "push_operand")
1672        (match_operand:DWI 1 "general_gr_operand"))]
1673  "reload_completed"
1674  [(const_int 0)]
1675  "ix86_split_long_move (operands); DONE;")
1676
1677(define_insn "*pushdi2_rex64"
1678  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1679	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1680  "TARGET_64BIT"
1681  "@
1682   push{q}\t%1
1683   #"
1684  [(set_attr "type" "push,multi")
1685   (set_attr "mode" "DI")])
1686
1687;; Convert impossible pushes of immediate to existing instructions.
1688;; First try to get scratch register and go through it.  In case this
1689;; fails, push sign extended lower part first and then overwrite
1690;; upper part by 32bit move.
1691
1692(define_peephole2
1693  [(match_scratch:DI 2 "r")
1694   (set (match_operand:DI 0 "push_operand")
1695        (match_operand:DI 1 "immediate_operand"))]
1696  "TARGET_64BIT
1697   && !symbolic_operand (operands[1], DImode)
1698   && !x86_64_immediate_operand (operands[1], DImode)"
1699  [(set (match_dup 2) (match_dup 1))
1700   (set (match_dup 0) (match_dup 2))])
1701
1702(define_split
1703  [(set (match_operand:DI 0 "push_operand")
1704        (match_operand:DI 1 "immediate_operand"))]
1705  "TARGET_64BIT && epilogue_completed
1706   && !symbolic_operand (operands[1], DImode)
1707   && !x86_64_immediate_operand (operands[1], DImode)"
1708  [(set (match_dup 0) (match_dup 1))
1709   (set (match_dup 2) (match_dup 3))]
1710{
1711  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1712
1713  operands[1] = gen_lowpart (DImode, operands[2]);
1714  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1715						   GEN_INT (4)));
1716})
1717
1718(define_insn "*pushsi2"
1719  [(set (match_operand:SI 0 "push_operand" "=<")
1720	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1721  "!TARGET_64BIT"
1722  "push{l}\t%1"
1723  [(set_attr "type" "push")
1724   (set_attr "mode" "SI")])
1725
1726;; emit_push_insn when it calls move_by_pieces requires an insn to
1727;; "push a byte/word".  But actually we use pushl, which has the effect
1728;; of rounding the amount pushed up to a word.
1729
1730;; For TARGET_64BIT we always round up to 8 bytes.
1731(define_insn "*push<mode>2_rex64"
1732  [(set (match_operand:SWI124 0 "push_operand" "=X")
1733	(match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1734  "TARGET_64BIT"
1735  "push{q}\t%q1"
1736  [(set_attr "type" "push")
1737   (set_attr "mode" "DI")])
1738
1739(define_insn "*push<mode>2"
1740  [(set (match_operand:SWI12 0 "push_operand" "=X")
1741	(match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1742  "!TARGET_64BIT"
1743  "push{l}\t%k1"
1744  [(set_attr "type" "push")
1745   (set_attr "mode" "SI")])
1746
1747(define_insn "*push<mode>2_prologue"
1748  [(set (match_operand:W 0 "push_operand" "=<")
1749	(match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1750   (clobber (mem:BLK (scratch)))]
1751  ""
1752  "push{<imodesuffix>}\t%1"
1753  [(set_attr "type" "push")
1754   (set_attr "mode" "<MODE>")])
1755
1756(define_insn "*pop<mode>1"
1757  [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1758	(match_operand:W 1 "pop_operand" ">"))]
1759  ""
1760  "pop{<imodesuffix>}\t%0"
1761  [(set_attr "type" "pop")
1762   (set_attr "mode" "<MODE>")])
1763
1764(define_insn "*pop<mode>1_epilogue"
1765  [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1766	(match_operand:W 1 "pop_operand" ">"))
1767   (clobber (mem:BLK (scratch)))]
1768  ""
1769  "pop{<imodesuffix>}\t%0"
1770  [(set_attr "type" "pop")
1771   (set_attr "mode" "<MODE>")])
1772
1773(define_insn "*pushfl<mode>2"
1774  [(set (match_operand:W 0 "push_operand" "=<")
1775	(match_operand:W 1 "flags_reg_operand"))]
1776  ""
1777  "pushf{<imodesuffix>}"
1778  [(set_attr "type" "push")
1779   (set_attr "mode" "<MODE>")])
1780
1781(define_insn "*popfl<mode>1"
1782  [(set (match_operand:W 0 "flags_reg_operand")
1783	(match_operand:W 1 "pop_operand" ">"))]
1784  ""
1785  "popf{<imodesuffix>}"
1786  [(set_attr "type" "pop")
1787   (set_attr "mode" "<MODE>")])
1788
1789
1790;; Reload patterns to support multi-word load/store
1791;; with non-offsetable address.
1792(define_expand "reload_noff_store"
1793  [(parallel [(match_operand 0 "memory_operand" "=m")
1794              (match_operand 1 "register_operand" "r")
1795              (match_operand:DI 2 "register_operand" "=&r")])]
1796  "TARGET_64BIT"
1797{
1798  rtx mem = operands[0];
1799  rtx addr = XEXP (mem, 0);
1800
1801  emit_move_insn (operands[2], addr);
1802  mem = replace_equiv_address_nv (mem, operands[2]);
1803
1804  emit_insn (gen_rtx_SET (mem, operands[1]));
1805  DONE;
1806})
1807
1808(define_expand "reload_noff_load"
1809  [(parallel [(match_operand 0 "register_operand" "=r")
1810              (match_operand 1 "memory_operand" "m")
1811              (match_operand:DI 2 "register_operand" "=r")])]
1812  "TARGET_64BIT"
1813{
1814  rtx mem = operands[1];
1815  rtx addr = XEXP (mem, 0);
1816
1817  emit_move_insn (operands[2], addr);
1818  mem = replace_equiv_address_nv (mem, operands[2]);
1819
1820  emit_insn (gen_rtx_SET (operands[0], mem));
1821  DONE;
1822})
1823
1824;; Move instructions.
1825
1826(define_expand "movxi"
1827  [(set (match_operand:XI 0 "nonimmediate_operand")
1828	(match_operand:XI 1 "general_operand"))]
1829  "TARGET_AVX512F"
1830  "ix86_expand_vector_move (XImode, operands); DONE;")
1831
1832(define_expand "movoi"
1833  [(set (match_operand:OI 0 "nonimmediate_operand")
1834	(match_operand:OI 1 "general_operand"))]
1835  "TARGET_AVX"
1836  "ix86_expand_vector_move (OImode, operands); DONE;")
1837
1838(define_expand "movti"
1839  [(set (match_operand:TI 0 "nonimmediate_operand")
1840	(match_operand:TI 1 "general_operand"))]
1841  "TARGET_64BIT || TARGET_SSE"
1842{
1843  if (TARGET_64BIT)
1844    ix86_expand_move (TImode, operands);
1845  else
1846    ix86_expand_vector_move (TImode, operands);
1847  DONE;
1848})
1849
1850;; This expands to what emit_move_complex would generate if we didn't
1851;; have a movti pattern.  Having this avoids problems with reload on
1852;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1853;; to have around all the time.
1854(define_expand "movcdi"
1855  [(set (match_operand:CDI 0 "nonimmediate_operand")
1856	(match_operand:CDI 1 "general_operand"))]
1857  ""
1858{
1859  if (push_operand (operands[0], CDImode))
1860    emit_move_complex_push (CDImode, operands[0], operands[1]);
1861  else
1862    emit_move_complex_parts (operands[0], operands[1]);
1863  DONE;
1864})
1865
1866(define_expand "mov<mode>"
1867  [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1868	(match_operand:SWI1248x 1 "general_operand"))]
1869  ""
1870  "ix86_expand_move (<MODE>mode, operands); DONE;")
1871
1872(define_insn "*mov<mode>_xor"
1873  [(set (match_operand:SWI48 0 "register_operand" "=r")
1874	(match_operand:SWI48 1 "const0_operand"))
1875   (clobber (reg:CC FLAGS_REG))]
1876  "reload_completed"
1877  "xor{l}\t%k0, %k0"
1878  [(set_attr "type" "alu1")
1879   (set_attr "mode" "SI")
1880   (set_attr "length_immediate" "0")])
1881
1882(define_insn "*mov<mode>_or"
1883  [(set (match_operand:SWI48 0 "register_operand" "=r")
1884	(match_operand:SWI48 1 "constm1_operand"))
1885   (clobber (reg:CC FLAGS_REG))]
1886  "reload_completed"
1887  "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1888  [(set_attr "type" "alu1")
1889   (set_attr "mode" "<MODE>")
1890   (set_attr "length_immediate" "1")])
1891
1892(define_insn "*movxi_internal_avx512f"
1893  [(set (match_operand:XI 0 "nonimmediate_operand"		"=v,v ,v ,m")
1894	(match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1895  "TARGET_AVX512F
1896   && (register_operand (operands[0], XImode)
1897       || register_operand (operands[1], XImode))"
1898{
1899  switch (get_attr_type (insn))
1900    {
1901    case TYPE_SSELOG1:
1902      return standard_sse_constant_opcode (insn, operands);
1903
1904    case TYPE_SSEMOV:
1905      return ix86_output_ssemov (insn, operands);
1906
1907    default:
1908      gcc_unreachable ();
1909    }
1910}
1911  [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1912   (set_attr "prefix" "evex")
1913   (set_attr "mode" "XI")])
1914
1915(define_insn "*movoi_internal_avx"
1916  [(set (match_operand:OI 0 "nonimmediate_operand"		"=v,v ,v ,m")
1917	(match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1918  "TARGET_AVX
1919   && (register_operand (operands[0], OImode)
1920       || register_operand (operands[1], OImode))"
1921{
1922  switch (get_attr_type (insn))
1923    {
1924    case TYPE_SSELOG1:
1925      return standard_sse_constant_opcode (insn, operands);
1926
1927    case TYPE_SSEMOV:
1928      return ix86_output_ssemov (insn, operands);
1929
1930    default:
1931      gcc_unreachable ();
1932    }
1933}
1934  [(set_attr "isa" "*,avx2,*,*")
1935   (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1936   (set_attr "prefix" "vex")
1937   (set_attr "mode" "OI")])
1938
1939(define_insn "*movti_internal"
1940  [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
1941	(match_operand:TI 1 "general_operand"	   "riFo,re,C,BC,vm,v,Yd,r"))]
1942  "(TARGET_64BIT
1943    && !(MEM_P (operands[0]) && MEM_P (operands[1])))
1944   || (TARGET_SSE
1945       && nonimmediate_or_sse_const_operand (operands[1], TImode)
1946       && (register_operand (operands[0], TImode)
1947	   || register_operand (operands[1], TImode)))"
1948{
1949  switch (get_attr_type (insn))
1950    {
1951    case TYPE_MULTI:
1952      return "#";
1953
1954    case TYPE_SSELOG1:
1955      return standard_sse_constant_opcode (insn, operands);
1956
1957    case TYPE_SSEMOV:
1958      return ix86_output_ssemov (insn, operands);
1959
1960    default:
1961      gcc_unreachable ();
1962    }
1963}
1964  [(set (attr "isa")
1965     (cond [(eq_attr "alternative" "0,1,6,7")
1966	      (const_string "x64")
1967	    (eq_attr "alternative" "3")
1968	      (const_string "sse2")
1969	   ]
1970	   (const_string "*")))
1971   (set (attr "type")
1972     (cond [(eq_attr "alternative" "0,1,6,7")
1973	      (const_string "multi")
1974	    (eq_attr "alternative" "2,3")
1975	      (const_string "sselog1")
1976	   ]
1977	   (const_string "ssemov")))
1978   (set (attr "prefix")
1979     (if_then_else (eq_attr "type" "sselog1,ssemov")
1980       (const_string "maybe_vex")
1981       (const_string "orig")))
1982   (set (attr "mode")
1983	(cond [(eq_attr "alternative" "0,1")
1984		 (const_string "DI")
1985	       (match_test "TARGET_AVX")
1986		 (const_string "TI")
1987	       (ior (not (match_test "TARGET_SSE2"))
1988		    (match_test "optimize_function_for_size_p (cfun)"))
1989		 (const_string "V4SF")
1990	       (and (eq_attr "alternative" "5")
1991		    (match_test "TARGET_SSE_TYPELESS_STORES"))
1992		 (const_string "V4SF")
1993	       ]
1994	       (const_string "TI")))
1995   (set (attr "preferred_for_speed")
1996     (cond [(eq_attr "alternative" "6")
1997	      (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
1998	    (eq_attr "alternative" "7")
1999	      (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2000	   ]
2001	   (symbol_ref "true")))])
2002
2003(define_split
2004  [(set (match_operand:TI 0 "sse_reg_operand")
2005        (match_operand:TI 1 "general_reg_operand"))]
2006  "TARGET_64BIT && TARGET_SSE4_1
2007   && reload_completed"
2008  [(set (match_dup 2)
2009  	(vec_merge:V2DI
2010	  (vec_duplicate:V2DI (match_dup 3))
2011	  (match_dup 2)
2012	  (const_int 2)))]
2013{
2014  operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2015  operands[3] = gen_highpart (DImode, operands[1]);
2016
2017  emit_move_insn (gen_lowpart (DImode, operands[0]),
2018  		  gen_lowpart (DImode, operands[1]));
2019})
2020
2021(define_insn "*movdi_internal"
2022  [(set (match_operand:DI 0 "nonimmediate_operand"
2023    "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m,*k")
2024	(match_operand:DI 1 "general_operand"
2025    "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,v,*Yd,r   ,*v,r  ,*x ,*y ,*r,*km,*k,*k,CBC"))]
2026  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2027{
2028  switch (get_attr_type (insn))
2029    {
2030    case TYPE_MSKMOV:
2031      return "kmovq\t{%1, %0|%0, %1}";
2032
2033    case TYPE_MSKLOG:
2034      if (operands[1] == const0_rtx)
2035	return "kxorq\t%0, %0, %0";
2036      else if (operands[1] == constm1_rtx)
2037	return "kxnorq\t%0, %0, %0";
2038      gcc_unreachable ();
2039
2040    case TYPE_MULTI:
2041      return "#";
2042
2043    case TYPE_MMX:
2044      return "pxor\t%0, %0";
2045
2046    case TYPE_MMXMOV:
2047      /* Handle broken assemblers that require movd instead of movq.  */
2048      if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2049	  && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2050	return "movd\t{%1, %0|%0, %1}";
2051      return "movq\t{%1, %0|%0, %1}";
2052
2053    case TYPE_SSELOG1:
2054      return standard_sse_constant_opcode (insn, operands);
2055
2056    case TYPE_SSEMOV:
2057      return ix86_output_ssemov (insn, operands);
2058
2059    case TYPE_SSECVT:
2060      if (SSE_REG_P (operands[0]))
2061	return "movq2dq\t{%1, %0|%0, %1}";
2062      else
2063	return "movdq2q\t{%1, %0|%0, %1}";
2064
2065    case TYPE_LEA:
2066      return "lea{q}\t{%E1, %0|%0, %E1}";
2067
2068    case TYPE_IMOV:
2069      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2070      if (get_attr_mode (insn) == MODE_SI)
2071	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2072      else if (which_alternative == 4)
2073	return "movabs{q}\t{%1, %0|%0, %1}";
2074      else if (ix86_use_lea_for_mov (insn, operands))
2075	return "lea{q}\t{%E1, %0|%0, %E1}";
2076      else
2077	return "mov{q}\t{%1, %0|%0, %1}";
2078
2079    default:
2080      gcc_unreachable ();
2081    }
2082}
2083  [(set (attr "isa")
2084     (cond [(eq_attr "alternative" "0,1,17,18")
2085	      (const_string "nox64")
2086	    (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2087	      (const_string "x64")
2088	    (eq_attr "alternative" "19,20")
2089	      (const_string "x64_sse2")
2090	    (eq_attr "alternative" "21,22")
2091	      (const_string "sse2")
2092	   ]
2093	   (const_string "*")))
2094   (set (attr "type")
2095     (cond [(eq_attr "alternative" "0,1,17,18")
2096	      (const_string "multi")
2097	    (eq_attr "alternative" "6")
2098	      (const_string "mmx")
2099	    (eq_attr "alternative" "7,8,9,10,11")
2100	      (const_string "mmxmov")
2101	    (eq_attr "alternative" "12")
2102	      (const_string "sselog1")
2103	    (eq_attr "alternative" "13,14,15,16,19,20")
2104	      (const_string "ssemov")
2105	    (eq_attr "alternative" "21,22")
2106	      (const_string "ssecvt")
2107	    (eq_attr "alternative" "23,24,25,26")
2108	      (const_string "mskmov")
2109	    (eq_attr "alternative" "27")
2110	      (const_string "msklog")
2111	    (and (match_operand 0 "register_operand")
2112		 (match_operand 1 "pic_32bit_operand"))
2113	      (const_string "lea")
2114	   ]
2115	   (const_string "imov")))
2116   (set (attr "modrm")
2117     (if_then_else
2118       (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2119       (const_string "0")
2120       (const_string "*")))
2121   (set (attr "length_immediate")
2122     (if_then_else
2123       (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2124       (const_string "8")
2125       (const_string "*")))
2126   (set (attr "prefix_rex")
2127     (if_then_else
2128       (eq_attr "alternative" "10,11,19,20")
2129       (const_string "1")
2130       (const_string "*")))
2131   (set (attr "prefix")
2132     (if_then_else (eq_attr "type" "sselog1,ssemov")
2133       (const_string "maybe_vex")
2134       (const_string "orig")))
2135   (set (attr "prefix_data16")
2136     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2137       (const_string "1")
2138       (const_string "*")))
2139   (set (attr "mode")
2140     (cond [(eq_attr "alternative" "2")
2141	      (const_string "SI")
2142	    (eq_attr "alternative" "12,13")
2143	      (cond [(match_test "TARGET_AVX")
2144		       (const_string "TI")
2145		     (ior (not (match_test "TARGET_SSE2"))
2146			  (match_test "optimize_function_for_size_p (cfun)"))
2147		       (const_string "V4SF")
2148		    ]
2149		    (const_string "TI"))
2150
2151	    (and (eq_attr "alternative" "14,15,16")
2152		 (not (match_test "TARGET_SSE2")))
2153	      (const_string "V2SF")
2154	   ]
2155	   (const_string "DI")))
2156   (set (attr "preferred_for_speed")
2157     (cond [(eq_attr "alternative" "10,17,19")
2158	      (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2159	    (eq_attr "alternative" "11,18,20")
2160	      (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2161	   ]
2162	   (symbol_ref "true")))
2163   (set (attr "enabled")
2164     (cond [(eq_attr "alternative" "15")
2165              (if_then_else
2166		(match_test "TARGET_STV && TARGET_SSE2")
2167		(symbol_ref "false")
2168		(const_string "*"))
2169	    (eq_attr "alternative" "16")
2170              (if_then_else
2171		(match_test "TARGET_STV && TARGET_SSE2")
2172		(symbol_ref "true")
2173		(symbol_ref "false"))
2174	   ]
2175	   (const_string "*")))])
2176
2177(define_split
2178  [(set (match_operand:<DWI> 0 "general_reg_operand")
2179        (match_operand:<DWI> 1 "sse_reg_operand"))]
2180  "TARGET_SSE4_1
2181   && reload_completed"
2182  [(set (match_dup 2)
2183  	(vec_select:DWIH
2184	  (match_dup 3)
2185	  (parallel [(const_int 1)])))]
2186{
2187  operands[2] = gen_highpart (<MODE>mode, operands[0]);
2188  operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2189
2190  emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2191  		  gen_lowpart (<MODE>mode, operands[1]));
2192})
2193
2194(define_split
2195  [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2196        (match_operand:DWI 1 "general_gr_operand"))]
2197  "reload_completed"
2198  [(const_int 0)]
2199  "ix86_split_long_move (operands); DONE;")
2200
2201(define_split
2202  [(set (match_operand:DI 0 "sse_reg_operand")
2203        (match_operand:DI 1 "general_reg_operand"))]
2204  "!TARGET_64BIT && TARGET_SSE4_1
2205   && reload_completed"
2206  [(set (match_dup 2)
2207  	(vec_merge:V4SI
2208	  (vec_duplicate:V4SI (match_dup 3))
2209	  (match_dup 2)
2210	  (const_int 2)))]
2211{
2212  operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2213  operands[3] = gen_highpart (SImode, operands[1]);
2214
2215  emit_move_insn (gen_lowpart (SImode, operands[0]),
2216  		  gen_lowpart (SImode, operands[1]));
2217})
2218
2219;; movabsq $0x0012345678000000, %rax is longer
2220;; than movl $0x12345678, %eax; shlq $24, %rax.
2221(define_peephole2
2222  [(set (match_operand:DI 0 "register_operand")
2223	(match_operand:DI 1 "const_int_operand"))]
2224  "TARGET_64BIT
2225   && optimize_insn_for_size_p ()
2226   && LEGACY_INT_REG_P (operands[0])
2227   && !x86_64_immediate_operand (operands[1], DImode)
2228   && !x86_64_zext_immediate_operand (operands[1], DImode)
2229   && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2230        & ~(HOST_WIDE_INT) 0xffffffff)
2231   && peep2_regno_dead_p (0, FLAGS_REG)"
2232  [(set (match_dup 0) (match_dup 1))
2233   (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2234	      (clobber (reg:CC FLAGS_REG))])]
2235{
2236  int shift = ctz_hwi (UINTVAL (operands[1]));
2237  operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2238  operands[2] = gen_int_mode (shift, QImode);
2239})
2240
2241(define_insn "*movsi_internal"
2242  [(set (match_operand:SI 0 "nonimmediate_operand"
2243    "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2244	(match_operand:SI 1 "general_operand"
2245    "g ,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,*v,r  ,*r,*km,*k ,CBC"))]
2246  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2247{
2248  switch (get_attr_type (insn))
2249    {
2250    case TYPE_SSELOG1:
2251      return standard_sse_constant_opcode (insn, operands);
2252
2253    case TYPE_MSKMOV:
2254      return "kmovd\t{%1, %0|%0, %1}";
2255
2256    case TYPE_MSKLOG:
2257      if (operands[1] == const0_rtx)
2258	return "kxord\t%0, %0, %0";
2259      else if (operands[1] == constm1_rtx)
2260	return "kxnord\t%0, %0, %0";
2261      gcc_unreachable ();
2262
2263    case TYPE_SSEMOV:
2264      return ix86_output_ssemov (insn, operands);
2265
2266    case TYPE_MMX:
2267      return "pxor\t%0, %0";
2268
2269    case TYPE_MMXMOV:
2270      switch (get_attr_mode (insn))
2271	{
2272	case MODE_DI:
2273	  return "movq\t{%1, %0|%0, %1}";
2274	case MODE_SI:
2275	  return "movd\t{%1, %0|%0, %1}";
2276
2277	default:
2278	  gcc_unreachable ();
2279	}
2280
2281    case TYPE_LEA:
2282      return "lea{l}\t{%E1, %0|%0, %E1}";
2283
2284    case TYPE_IMOV:
2285      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2286      if (ix86_use_lea_for_mov (insn, operands))
2287	return "lea{l}\t{%E1, %0|%0, %E1}";
2288      else
2289	return "mov{l}\t{%1, %0|%0, %1}";
2290
2291    default:
2292      gcc_unreachable ();
2293    }
2294}
2295  [(set (attr "isa")
2296     (cond [(eq_attr "alternative" "12,13")
2297	      (const_string "sse2")
2298	   ]
2299	   (const_string "*")))
2300   (set (attr "type")
2301     (cond [(eq_attr "alternative" "2")
2302	      (const_string "mmx")
2303	    (eq_attr "alternative" "3,4,5,6,7")
2304	      (const_string "mmxmov")
2305	    (eq_attr "alternative" "8")
2306	      (const_string "sselog1")
2307	    (eq_attr "alternative" "9,10,11,12,13")
2308	      (const_string "ssemov")
2309	    (eq_attr "alternative" "14,15,16")
2310	      (const_string "mskmov")
2311	    (eq_attr "alternative" "17")
2312	      (const_string "msklog")
2313	    (and (match_operand 0 "register_operand")
2314		 (match_operand 1 "pic_32bit_operand"))
2315	      (const_string "lea")
2316	   ]
2317	   (const_string "imov")))
2318   (set (attr "prefix")
2319     (if_then_else (eq_attr "type" "sselog1,ssemov")
2320       (const_string "maybe_vex")
2321       (const_string "orig")))
2322   (set (attr "prefix_data16")
2323     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2324       (const_string "1")
2325       (const_string "*")))
2326   (set (attr "mode")
2327     (cond [(eq_attr "alternative" "2,3")
2328	      (const_string "DI")
2329	    (eq_attr "alternative" "8,9")
2330	      (cond [(match_test "TARGET_AVX")
2331		       (const_string "TI")
2332		     (ior (not (match_test "TARGET_SSE2"))
2333			  (match_test "optimize_function_for_size_p (cfun)"))
2334		       (const_string "V4SF")
2335		    ]
2336		    (const_string "TI"))
2337
2338	    (and (eq_attr "alternative" "10,11")
2339	         (not (match_test "TARGET_SSE2")))
2340	      (const_string "SF")
2341	   ]
2342	   (const_string "SI")))
2343   (set (attr "preferred_for_speed")
2344     (cond [(eq_attr "alternative" "6,12")
2345	      (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2346	    (eq_attr "alternative" "7,13")
2347	      (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2348	   ]
2349	   (symbol_ref "true")))])
2350
2351(define_insn "*movhi_internal"
2352  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k")
2353	(match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k,CBC"))]
2354  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2355{
2356  switch (get_attr_type (insn))
2357    {
2358    case TYPE_IMOVX:
2359      /* movzwl is faster than movw on p2 due to partial word stalls,
2360	 though not as fast as an aligned movl.  */
2361      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2362
2363    case TYPE_MSKMOV:
2364      switch (which_alternative)
2365	{
2366	case 4:
2367	  return "kmovw\t{%k1, %0|%0, %k1}";
2368	case 6:
2369	  return "kmovw\t{%1, %k0|%k0, %1}";
2370	case 5:
2371	case 7:
2372	  return "kmovw\t{%1, %0|%0, %1}";
2373	default:
2374	  gcc_unreachable ();
2375	}
2376
2377    case TYPE_MSKLOG:
2378      if (operands[1] == const0_rtx)
2379	return "kxorw\t%0, %0, %0";
2380      else if (operands[1] == constm1_rtx)
2381	return "kxnorw\t%0, %0, %0";
2382      gcc_unreachable ();
2383
2384    default:
2385      if (get_attr_mode (insn) == MODE_SI)
2386	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2387      else
2388	return "mov{w}\t{%1, %0|%0, %1}";
2389    }
2390}
2391  [(set (attr "type")
2392     (cond [(eq_attr "alternative" "4,5,6,7")
2393	      (const_string "mskmov")
2394	    (eq_attr "alternative" "8")
2395	      (const_string "msklog")
2396	    (match_test "optimize_function_for_size_p (cfun)")
2397	      (const_string "imov")
2398	    (and (eq_attr "alternative" "0")
2399		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2400		      (not (match_test "TARGET_HIMODE_MATH"))))
2401	      (const_string "imov")
2402	    (and (eq_attr "alternative" "1,2")
2403		 (match_operand:HI 1 "aligned_operand"))
2404	      (const_string "imov")
2405	    (and (match_test "TARGET_MOVX")
2406		 (eq_attr "alternative" "0,2"))
2407	      (const_string "imovx")
2408	   ]
2409	   (const_string "imov")))
2410    (set (attr "prefix")
2411      (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2412	(const_string "vex")
2413	(const_string "orig")))
2414    (set (attr "mode")
2415      (cond [(eq_attr "type" "imovx")
2416	       (const_string "SI")
2417	     (and (eq_attr "alternative" "1,2")
2418		  (match_operand:HI 1 "aligned_operand"))
2419	       (const_string "SI")
2420	     (and (eq_attr "alternative" "0")
2421		  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2422		       (not (match_test "TARGET_HIMODE_MATH"))))
2423	       (const_string "SI")
2424	    ]
2425	    (const_string "HI")))])
2426
2427;; Situation is quite tricky about when to choose full sized (SImode) move
2428;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2429;; partial register dependency machines (such as AMD Athlon), where QImode
2430;; moves issue extra dependency and for partial register stalls machines
2431;; that don't use QImode patterns (and QImode move cause stall on the next
2432;; instruction).
2433;;
2434;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2435;; register stall machines with, where we use QImode instructions, since
2436;; partial register stall can be caused there.  Then we use movzx.
2437
2438(define_insn "*movqi_internal"
2439  [(set (match_operand:QI 0 "nonimmediate_operand"
2440			"=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k")
2441	(match_operand:QI 1 "general_operand"
2442			"Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))]
2443  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2444{
2445  char buf[128];
2446  const char *ops;
2447  const char *suffix;
2448
2449  switch (get_attr_type (insn))
2450    {
2451    case TYPE_IMOVX:
2452      gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2453      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2454
2455    case TYPE_MSKMOV:
2456      switch (which_alternative)
2457        {
2458	case 9:
2459	  ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2460	  break;
2461	case 11:
2462	  ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2463	  break;
2464	case 12:
2465	case 13:
2466	  gcc_assert (TARGET_AVX512DQ);
2467	  /* FALLTHRU */
2468	case 10:
2469	  ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2470	  break;
2471	default:
2472	  gcc_unreachable ();
2473	}
2474
2475      suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2476
2477      snprintf (buf, sizeof (buf), ops, suffix);
2478      output_asm_insn (buf, operands);
2479      return "";
2480
2481    case TYPE_MSKLOG:
2482      if (operands[1] == const0_rtx)
2483	{
2484	  if (get_attr_mode (insn) == MODE_HI)
2485	    return "kxorw\t%0, %0, %0";
2486	  else
2487	    return "kxorb\t%0, %0, %0";
2488	}
2489      else if (operands[1] == constm1_rtx)
2490	{
2491	  gcc_assert (TARGET_AVX512DQ);
2492	  return "kxnorb\t%0, %0, %0";
2493	}
2494      gcc_unreachable ();
2495
2496    default:
2497      if (get_attr_mode (insn) == MODE_SI)
2498	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2499      else
2500	return "mov{b}\t{%1, %0|%0, %1}";
2501    }
2502}
2503  [(set (attr "isa")
2504     (cond [(eq_attr "alternative" "1,2")
2505	      (const_string "x64")
2506	    (eq_attr "alternative" "12,13,15")
2507	      (const_string "avx512dq")
2508	   ]
2509	   (const_string "*")))
2510   (set (attr "type")
2511     (cond [(eq_attr "alternative" "9,10,11,12,13")
2512	      (const_string "mskmov")
2513	    (eq_attr "alternative" "14,15")
2514	      (const_string "msklog")
2515	    (and (eq_attr "alternative" "7")
2516		 (not (match_operand:QI 1 "aligned_operand")))
2517	      (const_string "imovx")
2518	    (match_test "optimize_function_for_size_p (cfun)")
2519	      (const_string "imov")
2520	    (and (eq_attr "alternative" "5")
2521		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2522		      (not (match_test "TARGET_QIMODE_MATH"))))
2523	      (const_string "imov")
2524	    (eq_attr "alternative" "5,7")
2525	      (const_string "imovx")
2526	    (and (match_test "TARGET_MOVX")
2527		 (eq_attr "alternative" "4"))
2528	      (const_string "imovx")
2529	   ]
2530	   (const_string "imov")))
2531   (set (attr "prefix")
2532     (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2533       (const_string "vex")
2534       (const_string "orig")))
2535   (set (attr "mode")
2536      (cond [(eq_attr "alternative" "5,6,7")
2537	       (const_string "SI")
2538	     (eq_attr "alternative" "8")
2539	       (const_string "QI")
2540	     (and (eq_attr "alternative" "9,10,11,14")
2541		  (not (match_test "TARGET_AVX512DQ")))
2542	       (const_string "HI")
2543	     (eq_attr "type" "imovx")
2544	       (const_string "SI")
2545	     ;; For -Os, 8-bit immediates are always shorter than 32-bit
2546	     ;; ones.
2547	     (and (eq_attr "type" "imov")
2548		  (and (eq_attr "alternative" "3")
2549		       (match_test "optimize_function_for_size_p (cfun)")))
2550	       (const_string "QI")
2551	     ;; For -Os, movl where one or both operands are NON_Q_REGS
2552	     ;; and both are LEGACY_REGS is shorter than movb.
2553	     ;; Otherwise movb and movl sizes are the same, so decide purely
2554	     ;; based on speed factors.
2555	     (and (eq_attr "type" "imov")
2556		  (and (eq_attr "alternative" "1")
2557		       (match_test "optimize_function_for_size_p (cfun)")))
2558	       (const_string "SI")
2559	     (and (eq_attr "type" "imov")
2560		  (and (eq_attr "alternative" "0,1,2,3")
2561		       (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2562			    (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2563	       (const_string "SI")
2564	     ;; Avoid partial register stalls when not using QImode arithmetic
2565	     (and (eq_attr "type" "imov")
2566		  (and (eq_attr "alternative" "0,1,2,3")
2567		       (and (match_test "TARGET_PARTIAL_REG_STALL")
2568			    (not (match_test "TARGET_QIMODE_MATH")))))
2569	       (const_string "SI")
2570	   ]
2571	   (const_string "QI")))])
2572
2573;; Stores and loads of ax to arbitrary constant address.
2574;; We fake an second form of instruction to force reload to load address
2575;; into register when rax is not available
2576(define_insn "*movabs<mode>_1"
2577  [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2578	(match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2579  "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2580{
2581  /* Recover the full memory rtx.  */
2582  operands[0] = SET_DEST (PATTERN (insn));
2583  switch (which_alternative)
2584    {
2585    case 0:
2586      return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2587    case 1:
2588      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2589    default:
2590      gcc_unreachable ();
2591    }
2592}
2593  [(set_attr "type" "imov")
2594   (set_attr "modrm" "0,*")
2595   (set_attr "length_address" "8,0")
2596   (set_attr "length_immediate" "0,*")
2597   (set_attr "memory" "store")
2598   (set_attr "mode" "<MODE>")])
2599
2600(define_insn "*movabs<mode>_2"
2601  [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2602        (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2603  "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2604{
2605  /* Recover the full memory rtx.  */
2606  operands[1] = SET_SRC (PATTERN (insn));
2607  switch (which_alternative)
2608    {
2609    case 0:
2610      return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2611    case 1:
2612      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2613    default:
2614      gcc_unreachable ();
2615    }
2616}
2617  [(set_attr "type" "imov")
2618   (set_attr "modrm" "0,*")
2619   (set_attr "length_address" "8,0")
2620   (set_attr "length_immediate" "0")
2621   (set_attr "memory" "load")
2622   (set_attr "mode" "<MODE>")])
2623
2624(define_insn "*swap<mode>"
2625  [(set (match_operand:SWI48 0 "register_operand" "+r")
2626	(match_operand:SWI48 1 "register_operand" "+r"))
2627   (set (match_dup 1)
2628	(match_dup 0))]
2629  ""
2630  "xchg{<imodesuffix>}\t%1, %0"
2631  [(set_attr "type" "imov")
2632   (set_attr "mode" "<MODE>")
2633   (set_attr "pent_pair" "np")
2634   (set_attr "athlon_decode" "vector")
2635   (set_attr "amdfam10_decode" "double")
2636   (set_attr "bdver1_decode" "double")])
2637
2638(define_insn "*swap<mode>"
2639  [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2640	(match_operand:SWI12 1 "register_operand" "+<r>,r"))
2641   (set (match_dup 1)
2642	(match_dup 0))]
2643  ""
2644  "@
2645   xchg{<imodesuffix>}\t%1, %0
2646   xchg{l}\t%k1, %k0"
2647  [(set_attr "type" "imov")
2648   (set_attr "mode" "<MODE>,SI")
2649   (set (attr "preferred_for_size")
2650     (cond [(eq_attr "alternative" "0")
2651	      (symbol_ref "false")]
2652	   (symbol_ref "true")))
2653   ;; Potential partial reg stall on alternative 1.
2654   (set (attr "preferred_for_speed")
2655     (cond [(eq_attr "alternative" "1")
2656	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2657	   (symbol_ref "true")))
2658   (set_attr "pent_pair" "np")
2659   (set_attr "athlon_decode" "vector")
2660   (set_attr "amdfam10_decode" "double")
2661   (set_attr "bdver1_decode" "double")])
2662
2663(define_peephole2
2664  [(set (match_operand:SWI 0 "general_reg_operand")
2665	(match_operand:SWI 1 "general_reg_operand"))
2666   (set (match_dup 1)
2667	(match_operand:SWI 2 "general_reg_operand"))
2668   (set (match_dup 2) (match_dup 0))]
2669  "peep2_reg_dead_p (3, operands[0])
2670   && optimize_insn_for_size_p ()"
2671  [(parallel [(set (match_dup 1) (match_dup 2))
2672	      (set (match_dup 2) (match_dup 1))])])
2673
2674(define_expand "movstrict<mode>"
2675  [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
2676	(match_operand:SWI12 1 "general_operand"))]
2677  ""
2678{
2679  gcc_assert (SUBREG_P (operands[0]));
2680  if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2681      || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
2682    FAIL;
2683})
2684
2685(define_insn "*movstrict<mode>_1"
2686  [(set (strict_low_part
2687	  (match_operand:SWI12 0 "register_operand" "+<r>"))
2688	(match_operand:SWI12 1 "general_operand" "<r>mn"))]
2689  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2690  "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2691  [(set_attr "type" "imov")
2692   (set_attr "mode" "<MODE>")])
2693
2694(define_insn "*movstrict<mode>_xor"
2695  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2696	(match_operand:SWI12 1 "const0_operand"))
2697   (clobber (reg:CC FLAGS_REG))]
2698  "reload_completed"
2699  "xor{<imodesuffix>}\t%0, %0"
2700  [(set_attr "type" "alu1")
2701   (set_attr "mode" "<MODE>")
2702   (set_attr "length_immediate" "0")])
2703
2704(define_expand "extv<mode>"
2705  [(set (match_operand:SWI24 0 "register_operand")
2706	(sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2707			    (match_operand:SI 2 "const_int_operand")
2708			    (match_operand:SI 3 "const_int_operand")))]
2709  ""
2710{
2711  /* Handle extractions from %ah et al.  */
2712  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2713    FAIL;
2714
2715  unsigned int regno = reg_or_subregno (operands[1]);
2716
2717  /* Be careful to expand only with registers having upper parts.  */
2718  if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2719    operands[1] = copy_to_reg (operands[1]);
2720})
2721
2722(define_insn "*extv<mode>"
2723  [(set (match_operand:SWI24 0 "register_operand" "=R")
2724	(sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2725			    (const_int 8)
2726			    (const_int 8)))]
2727  ""
2728  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2729  [(set_attr "type" "imovx")
2730   (set_attr "mode" "SI")])
2731
2732(define_expand "extzv<mode>"
2733  [(set (match_operand:SWI248 0 "register_operand")
2734	(zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2735			     (match_operand:SI 2 "const_int_operand")
2736			     (match_operand:SI 3 "const_int_operand")))]
2737  ""
2738{
2739  if (ix86_expand_pextr (operands))
2740    DONE;
2741
2742  /* Handle extractions from %ah et al.  */
2743  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2744    FAIL;
2745
2746  unsigned int regno = reg_or_subregno (operands[1]);
2747
2748  /* Be careful to expand only with registers having upper parts.  */
2749  if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2750    operands[1] = copy_to_reg (operands[1]);
2751})
2752
2753(define_insn "*extzvqi_mem_rex64"
2754  [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2755	(subreg:QI
2756	  (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2757			   (const_int 8)
2758			   (const_int 8)) 0))]
2759  "TARGET_64BIT && reload_completed"
2760  "mov{b}\t{%h1, %0|%0, %h1}"
2761  [(set_attr "type" "imov")
2762   (set_attr "mode" "QI")])
2763
2764(define_insn "*extzv<mode>"
2765  [(set (match_operand:SWI248 0 "register_operand" "=R")
2766	(zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2767			     (const_int 8)
2768			     (const_int 8)))]
2769  ""
2770  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2771  [(set_attr "type" "imovx")
2772   (set_attr "mode" "SI")])
2773
2774(define_insn "*extzvqi"
2775  [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2776	(subreg:QI
2777	  (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2778			   (const_int 8)
2779			   (const_int 8)) 0))]
2780  ""
2781{
2782  switch (get_attr_type (insn))
2783    {
2784    case TYPE_IMOVX:
2785      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2786    default:
2787      return "mov{b}\t{%h1, %0|%0, %h1}";
2788    }
2789}
2790  [(set_attr "isa" "*,*,nox64")
2791   (set (attr "type")
2792     (if_then_else (and (match_operand:QI 0 "register_operand")
2793			(ior (not (match_operand:QI 0 "QIreg_operand"))
2794			     (match_test "TARGET_MOVX")))
2795	(const_string "imovx")
2796	(const_string "imov")))
2797   (set (attr "mode")
2798     (if_then_else (eq_attr "type" "imovx")
2799	(const_string "SI")
2800	(const_string "QI")))])
2801
2802(define_peephole2
2803  [(set (match_operand:QI 0 "register_operand")
2804	(subreg:QI
2805	  (zero_extract:SI (match_operand 1 "ext_register_operand")
2806			   (const_int 8)
2807			   (const_int 8)) 0))
2808   (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2809  "TARGET_64BIT
2810   && peep2_reg_dead_p (2, operands[0])"
2811  [(set (match_dup 2)
2812	(subreg:QI
2813	  (zero_extract:SI (match_dup 1)
2814			   (const_int 8)
2815			   (const_int 8)) 0))])
2816
2817(define_expand "insv<mode>"
2818  [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2819			     (match_operand:SI 1 "const_int_operand")
2820			     (match_operand:SI 2 "const_int_operand"))
2821        (match_operand:SWI248 3 "register_operand"))]
2822  ""
2823{
2824  rtx dst;
2825
2826  if (ix86_expand_pinsr (operands))
2827    DONE;
2828
2829  /* Handle insertions to %ah et al.  */
2830  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2831    FAIL;
2832
2833  unsigned int regno = reg_or_subregno (operands[0]);
2834
2835  /* Be careful to expand only with registers having upper parts.  */
2836  if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2837    dst = copy_to_reg (operands[0]);
2838  else
2839    dst = operands[0];
2840
2841  emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2842
2843  /* Fix up the destination if needed.  */
2844  if (dst != operands[0])
2845    emit_move_insn (operands[0], dst);
2846
2847  DONE;
2848})
2849
2850(define_insn "*insvqi_1_mem_rex64"
2851  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2852			 (const_int 8)
2853			 (const_int 8))
2854	(subreg:SI
2855	  (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2856  "TARGET_64BIT && reload_completed"
2857  "mov{b}\t{%1, %h0|%h0, %1}"
2858  [(set_attr "type" "imov")
2859   (set_attr "mode" "QI")])
2860
2861(define_insn "insv<mode>_1"
2862  [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2863			     (const_int 8)
2864			     (const_int 8))
2865	(match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2866  ""
2867{
2868  if (CONST_INT_P (operands[1]))
2869    operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2870  return "mov{b}\t{%b1, %h0|%h0, %b1}";
2871}
2872  [(set_attr "isa" "*,nox64")
2873   (set_attr "type" "imov")
2874   (set_attr "mode" "QI")])
2875
2876(define_insn "*insvqi_1"
2877  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
2878			 (const_int 8)
2879			 (const_int 8))
2880	(subreg:SI
2881	  (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2882  ""
2883  "mov{b}\t{%1, %h0|%h0, %1}"
2884  [(set_attr "isa" "*,nox64")
2885   (set_attr "type" "imov")
2886   (set_attr "mode" "QI")])
2887
2888(define_peephole2
2889  [(set (match_operand:QI 0 "register_operand")
2890	(match_operand:QI 1 "norex_memory_operand"))
2891   (set (zero_extract:SI (match_operand 2 "ext_register_operand")
2892			 (const_int 8)
2893			 (const_int 8))
2894	(subreg:SI (match_dup 0) 0))]
2895  "TARGET_64BIT
2896   && peep2_reg_dead_p (2, operands[0])"
2897  [(set (zero_extract:SI (match_dup 2)
2898			 (const_int 8)
2899			 (const_int 8))
2900	   (subreg:SI (match_dup 1) 0))])
2901
2902(define_code_iterator any_extract [sign_extract zero_extract])
2903
2904(define_insn "*insvqi_2"
2905  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2906			 (const_int 8)
2907			 (const_int 8))
2908	(any_extract:SI (match_operand 1 "ext_register_operand" "Q")
2909			(const_int 8)
2910			(const_int 8)))]
2911  ""
2912  "mov{b}\t{%h1, %h0|%h0, %h1}"
2913  [(set_attr "type" "imov")
2914   (set_attr "mode" "QI")])
2915
2916(define_insn "*insvqi_3"
2917  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2918			 (const_int 8)
2919			 (const_int 8))
2920	(any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2921			(const_int 8)))]
2922  ""
2923  "mov{b}\t{%h1, %h0|%h0, %h1}"
2924  [(set_attr "type" "imov")
2925   (set_attr "mode" "QI")])
2926
2927;; Floating point push instructions.
2928
2929(define_insn "*pushtf"
2930  [(set (match_operand:TF 0 "push_operand" "=<,<")
2931	(match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
2932  "TARGET_64BIT || TARGET_SSE"
2933{
2934  /* This insn should be already split before reg-stack.  */
2935  return "#";
2936}
2937  [(set_attr "isa" "*,x64")
2938   (set_attr "type" "multi")
2939   (set_attr "unit" "sse,*")
2940   (set_attr "mode" "TF,DI")])
2941
2942;; %%% Kill this when call knows how to work this out.
2943(define_split
2944  [(set (match_operand:TF 0 "push_operand")
2945	(match_operand:TF 1 "sse_reg_operand"))]
2946  "TARGET_SSE && reload_completed"
2947  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2948   (set (match_dup 0) (match_dup 1))]
2949{
2950  /* Preserve memory attributes. */
2951  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2952})
2953
2954(define_insn_and_split "*pushxf_rounded"
2955  [(set (mem:XF
2956	  (pre_modify:P
2957	    (reg:P SP_REG)
2958	    (plus:P (reg:P SP_REG) (const_int -16))))
2959	(match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
2960  "TARGET_64BIT"
2961  "#"
2962  "&& 1"
2963  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2964   (set (match_dup 1) (match_dup 0))]
2965{
2966  rtx pat = PATTERN (curr_insn);
2967  operands[1] = SET_DEST (pat);
2968
2969  /* Preserve memory attributes. */
2970  operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
2971}
2972  [(set_attr "type" "multi")
2973   (set_attr "unit" "i387,*,*,*")
2974   (set (attr "mode")
2975	(cond [(eq_attr "alternative" "1,2,3")
2976		 (const_string "DI")
2977	      ]
2978	      (const_string "XF")))
2979   (set (attr "preferred_for_size")
2980     (cond [(eq_attr "alternative" "1")
2981              (symbol_ref "false")]
2982           (symbol_ref "true")))])
2983
2984(define_insn "*pushxf"
2985  [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
2986	(match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
2987  ""
2988{
2989  /* This insn should be already split before reg-stack.  */
2990  return "#";
2991}
2992  [(set_attr "isa" "*,*,*,nox64,x64")
2993   (set_attr "type" "multi")
2994   (set_attr "unit" "i387,*,*,*,*")
2995   (set (attr "mode")
2996	(cond [(eq_attr "alternative" "1,2,3,4")
2997		 (if_then_else (match_test "TARGET_64BIT")
2998		   (const_string "DI")
2999		   (const_string "SI"))
3000	      ]
3001	      (const_string "XF")))
3002   (set (attr "preferred_for_size")
3003     (cond [(eq_attr "alternative" "1")
3004              (symbol_ref "false")]
3005           (symbol_ref "true")))])
3006
3007;; %%% Kill this when call knows how to work this out.
3008(define_split
3009  [(set (match_operand:XF 0 "push_operand")
3010	(match_operand:XF 1 "fp_register_operand"))]
3011  "reload_completed"
3012  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3013   (set (match_dup 0) (match_dup 1))]
3014{
3015  operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3016  /* Preserve memory attributes. */
3017  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3018})
3019
3020(define_insn "*pushdf"
3021  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3022	(match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3023  ""
3024{
3025  /* This insn should be already split before reg-stack.  */
3026  return "#";
3027}
3028  [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3029   (set_attr "type" "multi")
3030   (set_attr "unit" "i387,*,*,*,*,sse")
3031   (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3032   (set (attr "preferred_for_size")
3033     (cond [(eq_attr "alternative" "1")
3034              (symbol_ref "false")]
3035           (symbol_ref "true")))
3036   (set (attr "preferred_for_speed")
3037     (cond [(eq_attr "alternative" "1")
3038              (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3039           (symbol_ref "true")))])
3040   
3041;; %%% Kill this when call knows how to work this out.
3042(define_split
3043  [(set (match_operand:DF 0 "push_operand")
3044	(match_operand:DF 1 "any_fp_register_operand"))]
3045  "reload_completed"
3046  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3047   (set (match_dup 0) (match_dup 1))]
3048{
3049  /* Preserve memory attributes. */
3050  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3051})
3052
3053(define_insn "*pushsf_rex64"
3054  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3055	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3056  "TARGET_64BIT"
3057{
3058  /* Anything else should be already split before reg-stack.  */
3059  if (which_alternative != 1)
3060    return "#";
3061  return "push{q}\t%q1";
3062}
3063  [(set_attr "type" "multi,push,multi")
3064   (set_attr "unit" "i387,*,*")
3065   (set_attr "mode" "SF,DI,SF")])
3066
3067(define_insn "*pushsf"
3068  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3069	(match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3070  "!TARGET_64BIT"
3071{
3072  /* Anything else should be already split before reg-stack.  */
3073  if (which_alternative != 1)
3074    return "#";
3075  return "push{l}\t%1";
3076}
3077  [(set_attr "type" "multi,push,multi")
3078   (set_attr "unit" "i387,*,*")
3079   (set_attr "mode" "SF,SI,SF")])
3080
3081;; %%% Kill this when call knows how to work this out.
3082(define_split
3083  [(set (match_operand:SF 0 "push_operand")
3084	(match_operand:SF 1 "any_fp_register_operand"))]
3085  "reload_completed"
3086  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3087   (set (match_dup 0) (match_dup 1))]
3088{
3089  rtx op = XEXP (operands[0], 0);
3090  if (GET_CODE (op) == PRE_DEC)
3091    {
3092      gcc_assert (!TARGET_64BIT);
3093      op = GEN_INT (-4);
3094    }
3095  else
3096    {
3097      op = XEXP (XEXP (op, 1), 1);
3098      gcc_assert (CONST_INT_P (op));
3099    }
3100  operands[2] = op;
3101  /* Preserve memory attributes. */
3102  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3103})
3104
3105(define_split
3106  [(set (match_operand:SF 0 "push_operand")
3107	(match_operand:SF 1 "memory_operand"))]
3108  "reload_completed
3109   && find_constant_src (insn)"
3110  [(set (match_dup 0) (match_dup 2))]
3111  "operands[2] = find_constant_src (curr_insn);")
3112
3113(define_split
3114  [(set (match_operand 0 "push_operand")
3115	(match_operand 1 "general_gr_operand"))]
3116  "reload_completed
3117   && (GET_MODE (operands[0]) == TFmode
3118       || GET_MODE (operands[0]) == XFmode
3119       || GET_MODE (operands[0]) == DFmode)"
3120  [(const_int 0)]
3121  "ix86_split_long_move (operands); DONE;")
3122
3123;; Floating point move instructions.
3124
3125(define_expand "movtf"
3126  [(set (match_operand:TF 0 "nonimmediate_operand")
3127	(match_operand:TF 1 "nonimmediate_operand"))]
3128  "TARGET_64BIT || TARGET_SSE"
3129  "ix86_expand_move (TFmode, operands); DONE;")
3130
3131(define_expand "mov<mode>"
3132  [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3133	(match_operand:X87MODEF 1 "general_operand"))]
3134  ""
3135  "ix86_expand_move (<MODE>mode, operands); DONE;")
3136
3137(define_insn "*movtf_internal"
3138  [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3139	(match_operand:TF 1 "general_operand"	   "C ,vm,v,*roF,*rC"))]
3140  "(TARGET_64BIT || TARGET_SSE)
3141   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3142   && (lra_in_progress || reload_completed
3143       || !CONST_DOUBLE_P (operands[1])
3144       || ((optimize_function_for_size_p (cfun)
3145	    || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3146	   && standard_sse_constant_p (operands[1], TFmode) == 1
3147	   && !memory_operand (operands[0], TFmode))
3148       || (!TARGET_MEMORY_MISMATCH_STALL
3149	   && memory_operand (operands[0], TFmode)))"
3150{
3151  switch (get_attr_type (insn))
3152    {
3153    case TYPE_SSELOG1:
3154      return standard_sse_constant_opcode (insn, operands);
3155
3156    case TYPE_SSEMOV:
3157      return ix86_output_ssemov (insn, operands);
3158
3159    case TYPE_MULTI:
3160	return "#";
3161
3162    default:
3163      gcc_unreachable ();
3164    }
3165}
3166  [(set_attr "isa" "*,*,*,x64,x64")
3167   (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3168   (set (attr "prefix")
3169     (if_then_else (eq_attr "type" "sselog1,ssemov")
3170       (const_string "maybe_vex")
3171       (const_string "orig")))
3172   (set (attr "mode")
3173        (cond [(eq_attr "alternative" "3,4")
3174		 (const_string "DI")
3175	       (match_test "TARGET_AVX")
3176		 (const_string "TI")
3177	       (ior (not (match_test "TARGET_SSE2"))
3178		    (match_test "optimize_function_for_size_p (cfun)"))
3179		 (const_string "V4SF")
3180	       (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3181		 (const_string "V4SF")
3182	       (and (eq_attr "alternative" "2")
3183		    (match_test "TARGET_SSE_TYPELESS_STORES"))
3184		 (const_string "V4SF")
3185	       ]
3186	       (const_string "TI")))])
3187
3188(define_split
3189  [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3190        (match_operand:TF 1 "general_gr_operand"))]
3191  "reload_completed"
3192  [(const_int 0)]
3193  "ix86_split_long_move (operands); DONE;")
3194
3195;; Possible store forwarding (partial memory) stall
3196;; in alternatives 4, 6, 7 and 8.
3197(define_insn "*movxf_internal"
3198  [(set (match_operand:XF 0 "nonimmediate_operand"
3199	 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3200	(match_operand:XF 1 "general_operand"
3201	 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3202  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3203   && (lra_in_progress || reload_completed
3204       || !CONST_DOUBLE_P (operands[1])
3205       || ((optimize_function_for_size_p (cfun)
3206	    || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3207	   && standard_80387_constant_p (operands[1]) > 0
3208	   && !memory_operand (operands[0], XFmode))
3209       || (!TARGET_MEMORY_MISMATCH_STALL
3210	   && memory_operand (operands[0], XFmode))
3211       || !TARGET_HARD_XF_REGS)"
3212{
3213  switch (get_attr_type (insn))
3214    {
3215    case TYPE_FMOV:
3216      if (which_alternative == 2)
3217        return standard_80387_constant_opcode (operands[1]);
3218      return output_387_reg_move (insn, operands);
3219
3220    case TYPE_MULTI:
3221      return "#";
3222
3223    default:
3224      gcc_unreachable ();
3225    }
3226}
3227  [(set (attr "isa")
3228	(cond [(eq_attr "alternative" "7,10")
3229		 (const_string "nox64")
3230	       (eq_attr "alternative" "8,11")
3231		 (const_string "x64")
3232	      ]
3233	      (const_string "*")))
3234   (set (attr "type")
3235	(cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3236		 (const_string "multi")
3237	      ]
3238	      (const_string "fmov")))
3239   (set (attr "mode")
3240	(cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3241		 (if_then_else (match_test "TARGET_64BIT")
3242		   (const_string "DI")
3243		   (const_string "SI"))
3244	      ]
3245	      (const_string "XF")))
3246   (set (attr "preferred_for_size")
3247     (cond [(eq_attr "alternative" "3,4")
3248              (symbol_ref "false")]
3249           (symbol_ref "true")))
3250   (set (attr "enabled")
3251     (cond [(eq_attr "alternative" "9,10,11")
3252              (if_then_else
3253		(match_test "TARGET_HARD_XF_REGS")
3254		(symbol_ref "false")
3255		(const_string "*"))
3256            (not (match_test "TARGET_HARD_XF_REGS"))
3257	      (symbol_ref "false")
3258	   ]
3259	   (const_string "*")))])
3260   
3261(define_split
3262  [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3263        (match_operand:XF 1 "general_gr_operand"))]
3264  "reload_completed"
3265  [(const_int 0)]
3266  "ix86_split_long_move (operands); DONE;")
3267
3268;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3269(define_insn "*movdf_internal"
3270  [(set (match_operand:DF 0 "nonimmediate_operand"
3271    "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r  ,o ,r  ,m")
3272	(match_operand:DF 1 "general_operand"
3273    "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))]
3274  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3275   && (lra_in_progress || reload_completed
3276       || !CONST_DOUBLE_P (operands[1])
3277       || ((optimize_function_for_size_p (cfun)
3278	    || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3279	   && ((IS_STACK_MODE (DFmode)
3280		&& standard_80387_constant_p (operands[1]) > 0)
3281	       || (TARGET_SSE2 && TARGET_SSE_MATH
3282		   && standard_sse_constant_p (operands[1], DFmode) == 1))
3283	   && !memory_operand (operands[0], DFmode))
3284       || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3285	   && memory_operand (operands[0], DFmode))
3286       || !TARGET_HARD_DF_REGS)"
3287{
3288  switch (get_attr_type (insn))
3289    {
3290    case TYPE_FMOV:
3291      if (which_alternative == 2)
3292        return standard_80387_constant_opcode (operands[1]);
3293      return output_387_reg_move (insn, operands);
3294
3295    case TYPE_MULTI:
3296      return "#";
3297
3298    case TYPE_IMOV:
3299      if (get_attr_mode (insn) == MODE_SI)
3300	return "mov{l}\t{%1, %k0|%k0, %1}";
3301      else if (which_alternative == 11)
3302	return "movabs{q}\t{%1, %0|%0, %1}";
3303      else
3304	return "mov{q}\t{%1, %0|%0, %1}";
3305
3306    case TYPE_SSELOG1:
3307      return standard_sse_constant_opcode (insn, operands);
3308
3309    case TYPE_SSEMOV:
3310      return ix86_output_ssemov (insn, operands);
3311
3312    default:
3313      gcc_unreachable ();
3314    }
3315}
3316  [(set (attr "isa")
3317	(cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3318		 (const_string "nox64")
3319	       (eq_attr "alternative" "8,9,10,11,24,25")
3320		 (const_string "x64")
3321	       (eq_attr "alternative" "12,13,14,15")
3322		 (const_string "sse2")
3323	       (eq_attr "alternative" "20,21")
3324		 (const_string "x64_sse2")
3325	      ]
3326	      (const_string "*")))
3327   (set (attr "type")
3328	(cond [(eq_attr "alternative" "0,1,2")
3329		 (const_string "fmov")
3330	       (eq_attr "alternative" "3,4,5,6,7,22,23")
3331		 (const_string "multi")
3332	       (eq_attr "alternative" "8,9,10,11,24,25")
3333		 (const_string "imov")
3334	       (eq_attr "alternative" "12,16")
3335		 (const_string "sselog1")
3336	      ]
3337	      (const_string "ssemov")))
3338   (set (attr "modrm")
3339     (if_then_else (eq_attr "alternative" "11")
3340       (const_string "0")
3341       (const_string "*")))
3342   (set (attr "length_immediate")
3343     (if_then_else (eq_attr "alternative" "11")
3344       (const_string "8")
3345       (const_string "*")))
3346   (set (attr "prefix")
3347     (if_then_else (eq_attr "type" "sselog1,ssemov")
3348       (const_string "maybe_vex")
3349       (const_string "orig")))
3350   (set (attr "prefix_data16")
3351     (if_then_else
3352       (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3353	    (eq_attr "mode" "V1DF"))
3354       (const_string "1")
3355       (const_string "*")))
3356   (set (attr "mode")
3357	(cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3358		 (const_string "SI")
3359	       (eq_attr "alternative" "8,9,11,20,21,24,25")
3360		 (const_string "DI")
3361
3362	       /* xorps is one byte shorter for non-AVX targets.  */
3363	       (eq_attr "alternative" "12,16")
3364		 (cond [(match_test "TARGET_AVX")
3365			  (const_string "V2DF")
3366			(ior (not (match_test "TARGET_SSE2"))
3367			     (match_test "optimize_function_for_size_p (cfun)"))
3368			  (const_string "V4SF")
3369			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3370			  (const_string "TI")
3371		       ]
3372		       (const_string "V2DF"))
3373
3374	       /* For architectures resolving dependencies on
3375		  whole SSE registers use movapd to break dependency
3376		  chains, otherwise use short move to avoid extra work.  */
3377
3378	       /* movaps is one byte shorter for non-AVX targets.  */
3379	       (eq_attr "alternative" "13,17")
3380		 (cond [(match_test "TARGET_AVX")
3381			  (const_string "DF")
3382			(ior (not (match_test "TARGET_SSE2"))
3383			     (match_test "optimize_function_for_size_p (cfun)"))
3384			  (const_string "V4SF")
3385			(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3386			  (const_string "V4SF")
3387			(match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3388			  (const_string "V2DF")
3389		       ]
3390		       (const_string "DF"))
3391
3392	       /* For architectures resolving dependencies on register
3393		  parts we may avoid extra work to zero out upper part
3394		  of register.  */
3395	       (eq_attr "alternative" "14,18")
3396		 (cond [(not (match_test "TARGET_SSE2"))
3397			  (const_string "V2SF")
3398			(match_test "TARGET_AVX")
3399			  (const_string "DF")
3400			(match_test "TARGET_SSE_SPLIT_REGS")
3401			  (const_string "V1DF")
3402		       ]
3403		       (const_string "DF"))
3404
3405	       (and (eq_attr "alternative" "15,19")
3406		    (not (match_test "TARGET_SSE2")))
3407		 (const_string "V2SF")
3408	      ]
3409	      (const_string "DF")))
3410   (set (attr "preferred_for_size")
3411     (cond [(eq_attr "alternative" "3,4")
3412              (symbol_ref "false")]
3413           (symbol_ref "true")))
3414   (set (attr "preferred_for_speed")
3415     (cond [(eq_attr "alternative" "3,4")
3416              (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3417	    (eq_attr "alternative" "20")
3418	      (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3419	    (eq_attr "alternative" "21")
3420	      (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3421	   ]
3422           (symbol_ref "true")))
3423   (set (attr "enabled")
3424     (cond [(eq_attr "alternative" "22,23,24,25")
3425              (if_then_else
3426		(match_test "TARGET_HARD_DF_REGS")
3427		(symbol_ref "false")
3428		(const_string "*"))
3429            (not (match_test "TARGET_HARD_DF_REGS"))
3430	      (symbol_ref "false")
3431	   ]
3432	   (const_string "*")))])
3433
3434(define_split
3435  [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3436        (match_operand:DF 1 "general_gr_operand"))]
3437  "!TARGET_64BIT && reload_completed"
3438  [(const_int 0)]
3439  "ix86_split_long_move (operands); DONE;")
3440
3441(define_insn "*movsf_internal"
3442  [(set (match_operand:SF 0 "nonimmediate_operand"
3443	  "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
3444	(match_operand:SF 1 "general_operand"
3445	  "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
3446  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3447   && (lra_in_progress || reload_completed
3448       || !CONST_DOUBLE_P (operands[1])
3449       || ((optimize_function_for_size_p (cfun)
3450	    || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3451	   && ((IS_STACK_MODE (SFmode)
3452		&& standard_80387_constant_p (operands[1]) > 0)
3453	       || (TARGET_SSE && TARGET_SSE_MATH
3454		   && standard_sse_constant_p (operands[1], SFmode) == 1)))
3455       || memory_operand (operands[0], SFmode)
3456       || !TARGET_HARD_SF_REGS)"
3457{
3458  switch (get_attr_type (insn))
3459    {
3460    case TYPE_FMOV:
3461      if (which_alternative == 2)
3462        return standard_80387_constant_opcode (operands[1]);
3463      return output_387_reg_move (insn, operands);
3464
3465    case TYPE_IMOV:
3466      return "mov{l}\t{%1, %0|%0, %1}";
3467
3468    case TYPE_SSELOG1:
3469      return standard_sse_constant_opcode (insn, operands);
3470
3471    case TYPE_SSEMOV:
3472      return ix86_output_ssemov (insn, operands);
3473
3474    case TYPE_MMXMOV:
3475      switch (get_attr_mode (insn))
3476	{
3477	case MODE_DI:
3478	  return "movq\t{%1, %0|%0, %1}";
3479	case MODE_SI:
3480	  return "movd\t{%1, %0|%0, %1}";
3481
3482	default:
3483	  gcc_unreachable ();
3484	}
3485
3486    default:
3487      gcc_unreachable ();
3488    }
3489}
3490  [(set (attr "isa")
3491     (cond [(eq_attr "alternative" "9,10")
3492	      (const_string "sse2")
3493	   ]
3494	   (const_string "*")))
3495   (set (attr "type")
3496	(cond [(eq_attr "alternative" "0,1,2")
3497		 (const_string "fmov")
3498	       (eq_attr "alternative" "3,4,16,17")
3499		 (const_string "imov")
3500	       (eq_attr "alternative" "5")
3501		 (const_string "sselog1")
3502	       (eq_attr "alternative" "11,12,13,14,15")
3503		 (const_string "mmxmov")
3504	      ]
3505	      (const_string "ssemov")))
3506   (set (attr "prefix")
3507     (if_then_else (eq_attr "type" "sselog1,ssemov")
3508       (const_string "maybe_vex")
3509       (const_string "orig")))
3510   (set (attr "prefix_data16")
3511     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3512       (const_string "1")
3513       (const_string "*")))
3514   (set (attr "mode")
3515        (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3516		 (const_string "SI")
3517	       (eq_attr "alternative" "11")
3518		 (const_string "DI")
3519	       (eq_attr "alternative" "5")
3520		 (cond [(and (match_test "TARGET_AVX512F")
3521			     (not (match_test "TARGET_PREFER_AVX256")))
3522			  (const_string "V16SF")
3523			(match_test "TARGET_AVX")
3524			  (const_string "V4SF")
3525			(ior (not (match_test "TARGET_SSE2"))
3526			     (match_test "optimize_function_for_size_p (cfun)"))
3527			  (const_string "V4SF")
3528			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3529			  (const_string "TI")
3530		       ]
3531		       (const_string "V4SF"))
3532
3533	       /* For architectures resolving dependencies on
3534		  whole SSE registers use APS move to break dependency
3535		  chains, otherwise use short move to avoid extra work.
3536
3537		  Do the same for architectures resolving dependencies on
3538		  the parts.  While in DF mode it is better to always handle
3539		  just register parts, the SF mode is different due to lack
3540		  of instructions to load just part of the register.  It is
3541		  better to maintain the whole registers in single format
3542		  to avoid problems on using packed logical operations.  */
3543	       (eq_attr "alternative" "6")
3544		 (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3545			     (match_test "TARGET_SSE_SPLIT_REGS"))
3546			  (const_string "V4SF")
3547		       ]
3548		       (const_string "SF"))
3549	      ]
3550	      (const_string "SF")))
3551   (set (attr "preferred_for_speed")
3552     (cond [(eq_attr "alternative" "9,14")
3553	      (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3554	    (eq_attr "alternative" "10,15")
3555	      (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3556	   ]
3557           (symbol_ref "true")))
3558   (set (attr "enabled")
3559     (cond [(eq_attr "alternative" "16,17")
3560              (if_then_else
3561		(match_test "TARGET_HARD_SF_REGS")
3562		(symbol_ref "false")
3563		(const_string "*"))
3564            (not (match_test "TARGET_HARD_SF_REGS"))
3565	      (symbol_ref "false")
3566	   ]
3567	   (const_string "*")))])
3568
3569(define_split
3570  [(set (match_operand 0 "any_fp_register_operand")
3571	(match_operand 1 "memory_operand"))]
3572  "reload_completed
3573   && (GET_MODE (operands[0]) == TFmode
3574       || GET_MODE (operands[0]) == XFmode
3575       || GET_MODE (operands[0]) == DFmode
3576       || GET_MODE (operands[0]) == SFmode)
3577   && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3578  [(set (match_dup 0) (match_dup 2))]
3579  "operands[2] = find_constant_src (curr_insn);")
3580
3581(define_split
3582  [(set (match_operand 0 "any_fp_register_operand")
3583	(float_extend (match_operand 1 "memory_operand")))]
3584  "reload_completed
3585   && (GET_MODE (operands[0]) == TFmode
3586       || GET_MODE (operands[0]) == XFmode
3587       || GET_MODE (operands[0]) == DFmode)
3588   && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3589  [(set (match_dup 0) (match_dup 2))]
3590  "operands[2] = find_constant_src (curr_insn);")
3591
3592;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3593(define_split
3594  [(set (match_operand:X87MODEF 0 "fp_register_operand")
3595	(match_operand:X87MODEF 1 "immediate_operand"))]
3596  "reload_completed
3597   && (standard_80387_constant_p (operands[1]) == 8
3598       || standard_80387_constant_p (operands[1]) == 9)"
3599  [(set (match_dup 0)(match_dup 1))
3600   (set (match_dup 0)
3601	(neg:X87MODEF (match_dup 0)))]
3602{
3603  if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3604    operands[1] = CONST0_RTX (<MODE>mode);
3605  else
3606    operands[1] = CONST1_RTX (<MODE>mode);
3607})
3608
3609(define_insn "*swapxf"
3610  [(set (match_operand:XF 0 "register_operand" "+f")
3611	(match_operand:XF 1 "register_operand" "+f"))
3612   (set (match_dup 1)
3613	(match_dup 0))]
3614  "TARGET_80387"
3615{
3616  if (STACK_TOP_P (operands[0]))
3617    return "fxch\t%1";
3618  else
3619    return "fxch\t%0";
3620}
3621  [(set_attr "type" "fxch")
3622   (set_attr "mode" "XF")])
3623
3624
3625;; Zero extension instructions
3626
3627(define_expand "zero_extendsidi2"
3628  [(set (match_operand:DI 0 "nonimmediate_operand")
3629	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3630
3631(define_insn "*zero_extendsidi2"
3632  [(set (match_operand:DI 0 "nonimmediate_operand"
3633		"=r,?r,?o,r   ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3634	(zero_extend:DI
3635	 (match_operand:SI 1 "x86_64_zext_operand"
3636	        "0 ,rm,r ,rmWz,0,r  ,m   ,v ,r ,m ,*x,*v,*k,*km")))]
3637  ""
3638{
3639  switch (get_attr_type (insn))
3640    {
3641    case TYPE_IMOVX:
3642      if (ix86_use_lea_for_mov (insn, operands))
3643	return "lea{l}\t{%E1, %k0|%k0, %E1}";
3644      else
3645	return "mov{l}\t{%1, %k0|%k0, %1}";
3646
3647    case TYPE_MULTI:
3648      return "#";
3649
3650    case TYPE_MMXMOV:
3651      return "movd\t{%1, %0|%0, %1}";
3652
3653    case TYPE_SSEMOV:
3654      if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3655	{
3656	  if (EXT_REX_SSE_REG_P (operands[0])
3657	      || EXT_REX_SSE_REG_P (operands[1]))
3658	    return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3659	  else
3660	    return "%vpmovzxdq\t{%1, %0|%0, %1}";
3661	}
3662
3663      if (GENERAL_REG_P (operands[0]))
3664	return "%vmovd\t{%1, %k0|%k0, %1}";
3665
3666      return "%vmovd\t{%1, %0|%0, %1}";
3667
3668    case TYPE_MSKMOV:
3669      return "kmovd\t{%1, %k0|%k0, %1}";
3670
3671    default:
3672      gcc_unreachable ();
3673    }
3674}
3675  [(set (attr "isa")
3676     (cond [(eq_attr "alternative" "0,1,2")
3677	      (const_string "nox64")
3678	    (eq_attr "alternative" "3")
3679	      (const_string "x64")
3680	    (eq_attr "alternative" "7,8,9")
3681	      (const_string "sse2")
3682	    (eq_attr "alternative" "10")
3683	      (const_string "sse4")
3684	    (eq_attr "alternative" "11")
3685	      (const_string "avx512f")
3686	    (eq_attr "alternative" "12")
3687	      (const_string "x64_avx512bw")
3688	    (eq_attr "alternative" "13")
3689	      (const_string "avx512bw")
3690	   ]
3691	   (const_string "*")))
3692   (set (attr "mmx_isa")
3693     (if_then_else (eq_attr "alternative" "5,6")
3694		   (const_string "native")
3695		   (const_string "*")))
3696   (set (attr "type")
3697     (cond [(eq_attr "alternative" "0,1,2,4")
3698	      (const_string "multi")
3699	    (eq_attr "alternative" "5,6")
3700	      (const_string "mmxmov")
3701	    (eq_attr "alternative" "7")
3702	      (if_then_else (match_test "TARGET_64BIT")
3703		(const_string "ssemov")
3704		(const_string "multi"))
3705	    (eq_attr "alternative" "8,9,10,11")
3706	      (const_string "ssemov")
3707	    (eq_attr "alternative" "12,13")
3708	      (const_string "mskmov")
3709	   ]
3710	   (const_string "imovx")))
3711   (set (attr "prefix_extra")
3712     (if_then_else (eq_attr "alternative" "10,11")
3713       (const_string "1")
3714       (const_string "*")))
3715   (set (attr "prefix")
3716     (if_then_else (eq_attr "type" "ssemov")
3717       (const_string "maybe_vex")
3718       (const_string "orig")))
3719   (set (attr "prefix_0f")
3720     (if_then_else (eq_attr "type" "imovx")
3721       (const_string "0")
3722       (const_string "*")))
3723   (set (attr "mode")
3724     (cond [(eq_attr "alternative" "5,6")
3725	      (const_string "DI")
3726	    (and (eq_attr "alternative" "7")
3727		 (match_test "TARGET_64BIT"))
3728	      (const_string "TI")
3729	    (eq_attr "alternative" "8,10,11")
3730	      (const_string "TI")
3731	   ]
3732	   (const_string "SI")))
3733   (set (attr "preferred_for_speed")
3734     (cond [(eq_attr "alternative" "7")
3735	      (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3736	    (eq_attr "alternative" "5,8")
3737	      (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3738	   ]
3739           (symbol_ref "true")))])
3740
3741(define_split
3742  [(set (match_operand:DI 0 "memory_operand")
3743     	(zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3744  "reload_completed"
3745  [(set (match_dup 4) (const_int 0))]
3746  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3747
3748(define_split
3749  [(set (match_operand:DI 0 "general_reg_operand")
3750	(zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3751  "!TARGET_64BIT && reload_completed
3752   && REGNO (operands[0]) == REGNO (operands[1])"
3753  [(set (match_dup 4) (const_int 0))]
3754  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3755
3756(define_split
3757  [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3758	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3759  "!TARGET_64BIT && reload_completed
3760   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3761  [(set (match_dup 3) (match_dup 1))
3762   (set (match_dup 4) (const_int 0))]
3763  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3764
3765(define_mode_attr kmov_isa
3766  [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3767
3768(define_insn "zero_extend<mode>di2"
3769  [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3770	(zero_extend:DI
3771	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3772  "TARGET_64BIT"
3773  "@
3774   movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3775   kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3776   kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3777  [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3778   (set_attr "type" "imovx,mskmov,mskmov")
3779   (set_attr "mode" "SI,<MODE>,<MODE>")])
3780
3781(define_expand "zero_extend<mode>si2"
3782  [(set (match_operand:SI 0 "register_operand")
3783	(zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3784  ""
3785{
3786  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3787    {
3788      operands[1] = force_reg (<MODE>mode, operands[1]);
3789      emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3790      DONE;
3791    }
3792})
3793
3794(define_insn_and_split "zero_extend<mode>si2_and"
3795  [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3796	(zero_extend:SI
3797	  (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3798   (clobber (reg:CC FLAGS_REG))]
3799  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3800  "#"
3801  "&& reload_completed"
3802  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3803	      (clobber (reg:CC FLAGS_REG))])]
3804{
3805  if (!REG_P (operands[1])
3806      || REGNO (operands[0]) != REGNO (operands[1]))
3807    {
3808      ix86_expand_clear (operands[0]);
3809
3810      gcc_assert (!TARGET_PARTIAL_REG_STALL);
3811      emit_insn (gen_rtx_SET
3812      		 (gen_rtx_STRICT_LOW_PART
3813		  (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
3814		  operands[1]));
3815      DONE;
3816    }
3817
3818  operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3819}
3820  [(set_attr "type" "alu1")
3821   (set_attr "mode" "SI")])
3822
3823(define_insn "*zero_extend<mode>si2"
3824  [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
3825	(zero_extend:SI
3826	  (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3827  "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3828  "@
3829   movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3830   kmov<mskmodesuffix>\t{%1, %0|%0, %1}
3831   kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3832  [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3833   (set_attr "type" "imovx,mskmov,mskmov")
3834   (set_attr "mode" "SI,<MODE>,<MODE>")])
3835
3836(define_expand "zero_extendqihi2"
3837  [(set (match_operand:HI 0 "register_operand")
3838	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3839  ""
3840{
3841  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3842    {
3843      operands[1] = force_reg (QImode, operands[1]);
3844      emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3845      DONE;
3846    }
3847})
3848
3849(define_insn_and_split "zero_extendqihi2_and"
3850  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3851	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3852   (clobber (reg:CC FLAGS_REG))]
3853  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3854  "#"
3855  "&& reload_completed"
3856  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3857	      (clobber (reg:CC FLAGS_REG))])]
3858{
3859  if (!REG_P (operands[1])
3860      || REGNO (operands[0]) != REGNO (operands[1]))
3861    {
3862      ix86_expand_clear (operands[0]);
3863
3864      gcc_assert (!TARGET_PARTIAL_REG_STALL);
3865      emit_insn (gen_rtx_SET
3866		 (gen_rtx_STRICT_LOW_PART
3867		  (VOIDmode, gen_lowpart (QImode, operands[0])),
3868		  operands[1]));
3869      DONE;
3870    }
3871
3872  operands[0] = gen_lowpart (SImode, operands[0]);
3873}
3874  [(set_attr "type" "alu1")
3875   (set_attr "mode" "SI")])
3876
3877; zero extend to SImode to avoid partial register stalls
3878(define_insn "*zero_extendqihi2"
3879  [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
3880	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
3881  "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3882  "@
3883   movz{bl|x}\t{%1, %k0|%k0, %1}
3884   kmovb\t{%1, %k0|%k0, %1}
3885   kmovb\t{%1, %0|%0, %1}"
3886  [(set_attr "isa" "*,avx512dq,avx512dq")
3887   (set_attr "type" "imovx,mskmov,mskmov")
3888   (set_attr "mode" "SI,QI,QI")])
3889
3890;; Sign extension instructions
3891
3892(define_expand "extendsidi2"
3893  [(set (match_operand:DI 0 "register_operand")
3894	(sign_extend:DI (match_operand:SI 1 "register_operand")))]
3895  ""
3896{
3897  if (!TARGET_64BIT)
3898    {
3899      emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3900      DONE;
3901    }
3902})
3903
3904(define_insn "*extendsidi2_rex64"
3905  [(set (match_operand:DI 0 "register_operand" "=*a,r")
3906	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3907  "TARGET_64BIT"
3908  "@
3909   {cltq|cdqe}
3910   movs{lq|x}\t{%1, %0|%0, %1}"
3911  [(set_attr "type" "imovx")
3912   (set_attr "mode" "DI")
3913   (set_attr "prefix_0f" "0")
3914   (set_attr "modrm" "0,1")])
3915
3916(define_insn "extendsidi2_1"
3917  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3918	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3919   (clobber (reg:CC FLAGS_REG))
3920   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3921  "!TARGET_64BIT"
3922  "#")
3923
3924;; Split the memory case.  If the source register doesn't die, it will stay
3925;; this way, if it does die, following peephole2s take care of it.
3926(define_split
3927  [(set (match_operand:DI 0 "memory_operand")
3928	(sign_extend:DI (match_operand:SI 1 "register_operand")))
3929   (clobber (reg:CC FLAGS_REG))
3930   (clobber (match_operand:SI 2 "register_operand"))]
3931  "reload_completed"
3932  [(const_int 0)]
3933{
3934  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3935
3936  emit_move_insn (operands[3], operands[1]);
3937
3938  /* Generate a cltd if possible and doing so it profitable.  */
3939  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3940      && REGNO (operands[1]) == AX_REG
3941      && REGNO (operands[2]) == DX_REG)
3942    {
3943      emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3944    }
3945  else
3946    {
3947      emit_move_insn (operands[2], operands[1]);
3948      emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3949    }
3950  emit_move_insn (operands[4], operands[2]);
3951  DONE;
3952})
3953
3954;; Peepholes for the case where the source register does die, after
3955;; being split with the above splitter.
3956(define_peephole2
3957  [(set (match_operand:SI 0 "memory_operand")
3958	(match_operand:SI 1 "general_reg_operand"))
3959   (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
3960   (parallel [(set (match_dup 2)
3961		   (ashiftrt:SI (match_dup 2) (const_int 31)))
3962	       (clobber (reg:CC FLAGS_REG))])
3963   (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3964  "REGNO (operands[1]) != REGNO (operands[2])
3965   && peep2_reg_dead_p (2, operands[1])
3966   && peep2_reg_dead_p (4, operands[2])
3967   && !reg_mentioned_p (operands[2], operands[3])"
3968  [(set (match_dup 0) (match_dup 1))
3969   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3970	      (clobber (reg:CC FLAGS_REG))])
3971   (set (match_dup 3) (match_dup 1))])
3972
3973(define_peephole2
3974  [(set (match_operand:SI 0 "memory_operand")
3975	(match_operand:SI 1 "general_reg_operand"))
3976   (parallel [(set (match_operand:SI 2 "general_reg_operand")
3977		   (ashiftrt:SI (match_dup 1) (const_int 31)))
3978	       (clobber (reg:CC FLAGS_REG))])
3979   (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3980  "/* cltd is shorter than sarl $31, %eax */
3981   !optimize_function_for_size_p (cfun)
3982   && REGNO (operands[1]) == AX_REG
3983   && REGNO (operands[2]) == DX_REG
3984   && peep2_reg_dead_p (2, operands[1])
3985   && peep2_reg_dead_p (3, operands[2])
3986   && !reg_mentioned_p (operands[2], operands[3])"
3987  [(set (match_dup 0) (match_dup 1))
3988   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3989	      (clobber (reg:CC FLAGS_REG))])
3990   (set (match_dup 3) (match_dup 1))])
3991
3992;; Extend to register case.  Optimize case where source and destination
3993;; registers match and cases where we can use cltd.
3994(define_split
3995  [(set (match_operand:DI 0 "register_operand")
3996	(sign_extend:DI (match_operand:SI 1 "register_operand")))
3997   (clobber (reg:CC FLAGS_REG))
3998   (clobber (match_scratch:SI 2))]
3999  "reload_completed"
4000  [(const_int 0)]
4001{
4002  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4003
4004  if (REGNO (operands[3]) != REGNO (operands[1]))
4005    emit_move_insn (operands[3], operands[1]);
4006
4007  /* Generate a cltd if possible and doing so it profitable.  */
4008  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4009      && REGNO (operands[3]) == AX_REG
4010      && REGNO (operands[4]) == DX_REG)
4011    {
4012      emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4013      DONE;
4014    }
4015
4016  if (REGNO (operands[4]) != REGNO (operands[1]))
4017    emit_move_insn (operands[4], operands[1]);
4018
4019  emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4020  DONE;
4021})
4022
4023(define_insn "extend<mode>di2"
4024  [(set (match_operand:DI 0 "register_operand" "=r")
4025	(sign_extend:DI
4026	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4027  "TARGET_64BIT"
4028  "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4029  [(set_attr "type" "imovx")
4030   (set_attr "mode" "DI")])
4031
4032(define_insn "extendhisi2"
4033  [(set (match_operand:SI 0 "register_operand" "=*a,r")
4034	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4035  ""
4036{
4037  switch (get_attr_prefix_0f (insn))
4038    {
4039    case 0:
4040      return "{cwtl|cwde}";
4041    default:
4042      return "movs{wl|x}\t{%1, %0|%0, %1}";
4043    }
4044}
4045  [(set_attr "type" "imovx")
4046   (set_attr "mode" "SI")
4047   (set (attr "prefix_0f")
4048     ;; movsx is short decodable while cwtl is vector decoded.
4049     (if_then_else (and (eq_attr "cpu" "!k6")
4050			(eq_attr "alternative" "0"))
4051	(const_string "0")
4052	(const_string "1")))
4053   (set (attr "znver1_decode")
4054     (if_then_else (eq_attr "prefix_0f" "0")
4055	(const_string "double")
4056	(const_string "direct")))
4057   (set (attr "modrm")
4058     (if_then_else (eq_attr "prefix_0f" "0")
4059	(const_string "0")
4060	(const_string "1")))])
4061
4062(define_insn "*extendhisi2_zext"
4063  [(set (match_operand:DI 0 "register_operand" "=*a,r")
4064	(zero_extend:DI
4065	 (sign_extend:SI
4066	  (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4067  "TARGET_64BIT"
4068{
4069  switch (get_attr_prefix_0f (insn))
4070    {
4071    case 0:
4072      return "{cwtl|cwde}";
4073    default:
4074      return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4075    }
4076}
4077  [(set_attr "type" "imovx")
4078   (set_attr "mode" "SI")
4079   (set (attr "prefix_0f")
4080     ;; movsx is short decodable while cwtl is vector decoded.
4081     (if_then_else (and (eq_attr "cpu" "!k6")
4082			(eq_attr "alternative" "0"))
4083	(const_string "0")
4084	(const_string "1")))
4085   (set (attr "modrm")
4086     (if_then_else (eq_attr "prefix_0f" "0")
4087	(const_string "0")
4088	(const_string "1")))])
4089
4090(define_insn "extendqisi2"
4091  [(set (match_operand:SI 0 "register_operand" "=r")
4092	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4093  ""
4094  "movs{bl|x}\t{%1, %0|%0, %1}"
4095   [(set_attr "type" "imovx")
4096    (set_attr "mode" "SI")])
4097
4098(define_insn "*extendqisi2_zext"
4099  [(set (match_operand:DI 0 "register_operand" "=r")
4100	(zero_extend:DI
4101	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4102  "TARGET_64BIT"
4103  "movs{bl|x}\t{%1, %k0|%k0, %1}"
4104   [(set_attr "type" "imovx")
4105    (set_attr "mode" "SI")])
4106
4107(define_insn "extendqihi2"
4108  [(set (match_operand:HI 0 "register_operand" "=*a,r")
4109	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4110  ""
4111{
4112  switch (get_attr_prefix_0f (insn))
4113    {
4114    case 0:
4115      return "{cbtw|cbw}";
4116    default:
4117      return "movs{bw|x}\t{%1, %0|%0, %1}";
4118    }
4119}
4120  [(set_attr "type" "imovx")
4121   (set_attr "mode" "HI")
4122   (set (attr "prefix_0f")
4123     ;; movsx is short decodable while cwtl is vector decoded.
4124     (if_then_else (and (eq_attr "cpu" "!k6")
4125			(eq_attr "alternative" "0"))
4126	(const_string "0")
4127	(const_string "1")))
4128   (set (attr "modrm")
4129     (if_then_else (eq_attr "prefix_0f" "0")
4130	(const_string "0")
4131	(const_string "1")))])
4132
4133;; Conversions between float and double.
4134
4135;; These are all no-ops in the model used for the 80387.
4136;; So just emit moves.
4137
4138;; %%% Kill these when call knows how to work out a DFmode push earlier.
4139(define_split
4140  [(set (match_operand:DF 0 "push_operand")
4141	(float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4142  "reload_completed"
4143  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4144   (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4145
4146(define_split
4147  [(set (match_operand:XF 0 "push_operand")
4148	(float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4149  "reload_completed"
4150  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4151   (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4152  "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4153
4154(define_expand "extendsfdf2"
4155  [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4156        (float_extend:DF (match_operand:SF 1 "general_operand")))]
4157  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4158{
4159  /* ??? Needed for compress_float_constant since all fp constants
4160     are TARGET_LEGITIMATE_CONSTANT_P.  */
4161  if (CONST_DOUBLE_P (operands[1]))
4162    {
4163      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4164	  && standard_80387_constant_p (operands[1]) > 0)
4165	{
4166	  operands[1] = simplify_const_unary_operation
4167	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4168	  emit_move_insn_1 (operands[0], operands[1]);
4169	  DONE;
4170	}
4171      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4172    }
4173})
4174
4175(define_insn "*extendsfdf2"
4176  [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4177        (float_extend:DF
4178	  (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4179  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4180{
4181  switch (which_alternative)
4182    {
4183    case 0:
4184    case 1:
4185      return output_387_reg_move (insn, operands);
4186
4187    case 2:
4188      return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4189    case 3:
4190      return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4191
4192    default:
4193      gcc_unreachable ();
4194    }
4195}
4196  [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4197   (set_attr "avx_partial_xmm_update" "false,false,false,true")
4198   (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4199   (set_attr "mode" "SF,XF,DF,DF")
4200   (set (attr "enabled")
4201     (if_then_else
4202       (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4203       (if_then_else
4204	 (eq_attr "alternative" "0,1")
4205	 (symbol_ref "TARGET_MIX_SSE_I387")
4206	 (symbol_ref "true"))
4207       (if_then_else
4208	 (eq_attr "alternative" "0,1")
4209	 (symbol_ref "true")
4210	 (symbol_ref "false"))))])
4211
4212/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4213   cvtss2sd:
4214      unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4215      cvtps2pd xmm2,xmm1
4216   We do the conversion post reload to avoid producing of 128bit spills
4217   that might lead to ICE on 32bit target.  The sequence unlikely combine
4218   anyway.  */
4219(define_split
4220  [(set (match_operand:DF 0 "sse_reg_operand")
4221        (float_extend:DF
4222	  (match_operand:SF 1 "nonimmediate_operand")))]
4223  "TARGET_USE_VECTOR_FP_CONVERTS
4224   && optimize_insn_for_speed_p ()
4225   && reload_completed
4226   && (!EXT_REX_SSE_REG_P (operands[0])
4227       || TARGET_AVX512VL)"
4228   [(set (match_dup 2)
4229	 (float_extend:V2DF
4230	   (vec_select:V2SF
4231	     (match_dup 3)
4232	     (parallel [(const_int 0) (const_int 1)]))))]
4233{
4234  operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4235  operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4236  /* Use movss for loading from memory, unpcklps reg, reg for registers.
4237     Try to avoid move when unpacking can be done in source.  */
4238  if (REG_P (operands[1]))
4239    {
4240      /* If it is unsafe to overwrite upper half of source, we need
4241	 to move to destination and unpack there.  */
4242      if (REGNO (operands[0]) != REGNO (operands[1])
4243	  || (EXT_REX_SSE_REG_P (operands[1])
4244	      && !TARGET_AVX512VL))
4245	{
4246	  rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4247	  emit_move_insn (tmp, operands[1]);
4248	}
4249      else
4250	operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4251      /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4252	 =v, v, then vbroadcastss will be only needed for AVX512F without
4253	 AVX512VL.  */
4254      if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4255	emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4256					       operands[3]));
4257      else
4258	{
4259	  rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4260	  emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4261	}
4262    }
4263  else
4264    emit_insn (gen_vec_setv4sf_0 (operands[3],
4265				  CONST0_RTX (V4SFmode), operands[1]));
4266})
4267
4268;; It's more profitable to split and then extend in the same register.
4269(define_peephole2
4270  [(set (match_operand:DF 0 "sse_reg_operand")
4271	(float_extend:DF
4272	  (match_operand:SF 1 "memory_operand")))]
4273  "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4274   && optimize_insn_for_speed_p ()"
4275  [(set (match_dup 2) (match_dup 1))
4276   (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4277  "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4278
4279;; Break partial SSE register dependency stall.  This splitter should split
4280;; late in the pass sequence (after register rename pass), so allocated
4281;; registers won't change anymore
4282
4283(define_split
4284  [(set (match_operand:DF 0 "sse_reg_operand")
4285        (float_extend:DF
4286          (match_operand:SF 1 "nonimmediate_operand")))]
4287  "!TARGET_AVX
4288   && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4289   && optimize_function_for_speed_p (cfun)
4290   && (!REG_P (operands[1])
4291       || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4292   && (!EXT_REX_SSE_REG_P (operands[0])
4293       || TARGET_AVX512VL)"
4294  [(set (match_dup 0)
4295        (vec_merge:V2DF
4296	  (vec_duplicate:V2DF
4297	    (float_extend:DF
4298	      (match_dup 1)))
4299	  (match_dup 0)
4300          (const_int 1)))]
4301{
4302  operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4303  emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4304})
4305
4306(define_expand "extend<mode>xf2"
4307  [(set (match_operand:XF 0 "nonimmediate_operand")
4308        (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4309  "TARGET_80387"
4310{
4311  /* ??? Needed for compress_float_constant since all fp constants
4312     are TARGET_LEGITIMATE_CONSTANT_P.  */
4313  if (CONST_DOUBLE_P (operands[1]))
4314    {
4315      if (standard_80387_constant_p (operands[1]) > 0)
4316	{
4317	  operands[1] = simplify_const_unary_operation
4318	    (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4319	  emit_move_insn_1 (operands[0], operands[1]);
4320	  DONE;
4321	}
4322      operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4323    }
4324})
4325
4326(define_insn "*extend<mode>xf2_i387"
4327  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4328        (float_extend:XF
4329	  (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4330  "TARGET_80387"
4331  "* return output_387_reg_move (insn, operands);"
4332  [(set_attr "type" "fmov")
4333   (set_attr "mode" "<MODE>,XF")])
4334
4335;; %%% This seems like bad news.
4336;; This cannot output into an f-reg because there is no way to be sure
4337;; of truncating in that case.  Otherwise this is just like a simple move
4338;; insn.  So we pretend we can output to a reg in order to get better
4339;; register preferencing, but we really use a stack slot.
4340
4341;; Conversion from DFmode to SFmode.
4342
4343(define_insn "truncdfsf2"
4344  [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4345	(float_truncate:SF
4346	  (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4347  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4348{
4349  switch (which_alternative)
4350    {
4351    case 0:
4352    case 1:
4353      return output_387_reg_move (insn, operands);
4354
4355    case 2:
4356      return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4357    case 3:
4358      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4359
4360    default:
4361      gcc_unreachable ();
4362    }
4363}
4364  [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4365   (set_attr "avx_partial_xmm_update" "false,false,false,true")
4366   (set_attr "mode" "SF")
4367   (set (attr "enabled")
4368     (if_then_else
4369       (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4370       (cond [(eq_attr "alternative" "0")
4371		(symbol_ref "TARGET_MIX_SSE_I387")
4372	      (eq_attr "alternative" "1")
4373		(symbol_ref "TARGET_MIX_SSE_I387
4374			     && flag_unsafe_math_optimizations")
4375	   ]
4376	   (symbol_ref "true"))
4377       (cond [(eq_attr "alternative" "0")
4378		(symbol_ref "true")
4379	      (eq_attr "alternative" "1")
4380		(symbol_ref "flag_unsafe_math_optimizations")
4381	   ]
4382	   (symbol_ref "false"))))])
4383
4384/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4385   cvtsd2ss:
4386      unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4387      cvtpd2ps xmm2,xmm1
4388   We do the conversion post reload to avoid producing of 128bit spills
4389   that might lead to ICE on 32bit target.  The sequence unlikely combine
4390   anyway.  */
4391(define_split
4392  [(set (match_operand:SF 0 "sse_reg_operand")
4393	(float_truncate:SF
4394	  (match_operand:DF 1 "nonimmediate_operand")))]
4395  "TARGET_USE_VECTOR_FP_CONVERTS
4396   && optimize_insn_for_speed_p ()
4397   && reload_completed
4398   && (!EXT_REX_SSE_REG_P (operands[0])
4399       || TARGET_AVX512VL)"
4400   [(set (match_dup 2)
4401	 (vec_concat:V4SF
4402	   (float_truncate:V2SF
4403	     (match_dup 4))
4404	   (match_dup 3)))]
4405{
4406  operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4407  operands[3] = CONST0_RTX (V2SFmode);
4408  operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4409  /* Use movsd for loading from memory, unpcklpd for registers.
4410     Try to avoid move when unpacking can be done in source, or SSE3
4411     movddup is available.  */
4412  if (REG_P (operands[1]))
4413    {
4414      if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
4415	  || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
4416	{
4417	  rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4418	  emit_move_insn (tmp, operands[1]);
4419	  operands[1] = tmp;
4420	}
4421      else if (!TARGET_SSE3)
4422	operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4423      emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4424    }
4425  else
4426    emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4427				   CONST0_RTX (DFmode)));
4428})
4429
4430;; It's more profitable to split and then truncate in the same register.
4431(define_peephole2
4432  [(set (match_operand:SF 0 "sse_reg_operand")
4433	(float_truncate:SF
4434	  (match_operand:DF 1 "memory_operand")))]
4435  "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4436   && optimize_insn_for_speed_p ()"
4437  [(set (match_dup 2) (match_dup 1))
4438   (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4439  "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4440
4441;; Break partial SSE register dependency stall.  This splitter should split
4442;; late in the pass sequence (after register rename pass), so allocated
4443;; registers won't change anymore
4444
4445(define_split
4446  [(set (match_operand:SF 0 "sse_reg_operand")
4447        (float_truncate:SF
4448	  (match_operand:DF 1 "nonimmediate_operand")))]
4449  "!TARGET_AVX
4450   && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4451   && optimize_function_for_speed_p (cfun)
4452   && (!REG_P (operands[1])
4453       || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4454   && (!EXT_REX_SSE_REG_P (operands[0])
4455       || TARGET_AVX512VL)"
4456  [(set (match_dup 0)
4457	(vec_merge:V4SF
4458	  (vec_duplicate:V4SF
4459	    (float_truncate:SF
4460	      (match_dup 1)))
4461	  (match_dup 0)
4462	  (const_int 1)))]
4463{
4464  operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4465  emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4466})
4467
4468;; Conversion from XFmode to {SF,DF}mode
4469
4470(define_insn "truncxf<mode>2"
4471  [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4472	(float_truncate:MODEF
4473	  (match_operand:XF 1 "register_operand" "f,f")))]
4474  "TARGET_80387"
4475  "* return output_387_reg_move (insn, operands);"
4476  [(set_attr "type" "fmov")
4477   (set_attr "mode" "<MODE>")
4478   (set (attr "enabled")
4479     (cond [(eq_attr "alternative" "1")
4480	      (symbol_ref "flag_unsafe_math_optimizations")
4481	   ]
4482	   (symbol_ref "true")))])
4483
4484;; Signed conversion to DImode.
4485
4486(define_expand "fix_truncxfdi2"
4487  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4488                   (fix:DI (match_operand:XF 1 "register_operand")))
4489	      (clobber (reg:CC FLAGS_REG))])]
4490  "TARGET_80387"
4491{
4492  if (TARGET_FISTTP)
4493   {
4494     emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4495     DONE;
4496   }
4497})
4498
4499(define_expand "fix_trunc<mode>di2"
4500  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4501                   (fix:DI (match_operand:MODEF 1 "register_operand")))
4502              (clobber (reg:CC FLAGS_REG))])]
4503  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4504{
4505  if (TARGET_FISTTP
4506      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4507   {
4508     emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4509     DONE;
4510   }
4511  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4512   {
4513     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4514     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4515     if (out != operands[0])
4516	emit_move_insn (operands[0], out);
4517     DONE;
4518   }
4519})
4520
4521;; Signed conversion to SImode.
4522
4523(define_expand "fix_truncxfsi2"
4524  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4525                   (fix:SI (match_operand:XF 1 "register_operand")))
4526	      (clobber (reg:CC FLAGS_REG))])]
4527  "TARGET_80387"
4528{
4529  if (TARGET_FISTTP)
4530   {
4531     emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4532     DONE;
4533   }
4534})
4535
4536(define_expand "fix_trunc<mode>si2"
4537  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4538	           (fix:SI (match_operand:MODEF 1 "register_operand")))
4539	      (clobber (reg:CC FLAGS_REG))])]
4540  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4541{
4542  if (TARGET_FISTTP
4543      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4544   {
4545     emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4546     DONE;
4547   }
4548  if (SSE_FLOAT_MODE_P (<MODE>mode))
4549   {
4550     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4551     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4552     if (out != operands[0])
4553	emit_move_insn (operands[0], out);
4554     DONE;
4555   }
4556})
4557
4558;; Signed conversion to HImode.
4559
4560(define_expand "fix_trunc<mode>hi2"
4561  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4562	           (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4563              (clobber (reg:CC FLAGS_REG))])]
4564  "TARGET_80387
4565   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4566{
4567  if (TARGET_FISTTP)
4568   {
4569     emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4570     DONE;
4571   }
4572})
4573
4574;; Unsigned conversion to DImode
4575
4576(define_insn "fixuns_trunc<mode>di2"
4577  [(set (match_operand:DI 0 "register_operand" "=r")
4578	(unsigned_fix:DI
4579	  (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4580  "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4581  "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4582  [(set_attr "type" "sseicvt")
4583   (set_attr "prefix" "evex")
4584   (set_attr "mode" "DI")])
4585
4586;; Unsigned conversion to SImode.
4587
4588(define_expand "fixuns_trunc<mode>si2"
4589  [(parallel
4590    [(set (match_operand:SI 0 "register_operand")
4591	  (unsigned_fix:SI
4592	    (match_operand:MODEF 1 "nonimmediate_operand")))
4593     (use (match_dup 2))
4594     (clobber (match_scratch:<ssevecmode> 3))
4595     (clobber (match_scratch:<ssevecmode> 4))])]
4596  "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4597{
4598  machine_mode mode = <MODE>mode;
4599  machine_mode vecmode = <ssevecmode>mode;
4600  REAL_VALUE_TYPE TWO31r;
4601  rtx two31;
4602
4603  if (TARGET_AVX512F)
4604    {
4605      emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4606      DONE;
4607    }
4608
4609  if (optimize_insn_for_size_p ())
4610    FAIL;
4611
4612  real_ldexp (&TWO31r, &dconst1, 31);
4613  two31 = const_double_from_real_value (TWO31r, mode);
4614  two31 = ix86_build_const_vector (vecmode, true, two31);
4615  operands[2] = force_reg (vecmode, two31);
4616})
4617
4618(define_insn "fixuns_trunc<mode>si2_avx512f"
4619  [(set (match_operand:SI 0 "register_operand" "=r")
4620	(unsigned_fix:SI
4621	  (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4622  "TARGET_AVX512F && TARGET_SSE_MATH"
4623  "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4624  [(set_attr "type" "sseicvt")
4625   (set_attr "prefix" "evex")
4626   (set_attr "mode" "SI")])
4627
4628(define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4629  [(set (match_operand:DI 0 "register_operand" "=r")
4630	(zero_extend:DI
4631	  (unsigned_fix:SI
4632	    (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4633  "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4634  "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4635  [(set_attr "type" "sseicvt")
4636   (set_attr "prefix" "evex")
4637   (set_attr "mode" "SI")])
4638
4639(define_insn_and_split "*fixuns_trunc<mode>_1"
4640  [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4641	(unsigned_fix:SI
4642	  (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4643   (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4644   (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4645   (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4646  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4647   && optimize_function_for_speed_p (cfun)"
4648  "#"
4649  "&& reload_completed"
4650  [(const_int 0)]
4651{
4652  ix86_split_convert_uns_si_sse (operands);
4653  DONE;
4654})
4655
4656;; Unsigned conversion to HImode.
4657;; Without these patterns, we'll try the unsigned SI conversion which
4658;; is complex for SSE, rather than the signed SI conversion, which isn't.
4659
4660(define_expand "fixuns_trunc<mode>hi2"
4661  [(set (match_dup 2)
4662	(fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4663   (set (match_operand:HI 0 "nonimmediate_operand")
4664	(subreg:HI (match_dup 2) 0))]
4665  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4666  "operands[2] = gen_reg_rtx (SImode);")
4667
4668;; When SSE is available, it is always faster to use it!
4669(define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4670  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4671	(fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4672  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4673   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4674  "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4675  [(set_attr "type" "sseicvt")
4676   (set_attr "prefix" "maybe_vex")
4677   (set (attr "prefix_rex")
4678	(if_then_else
4679	  (match_test "<SWI48:MODE>mode == DImode")
4680	  (const_string "1")
4681	  (const_string "*")))
4682   (set_attr "mode" "<MODEF:MODE>")
4683   (set_attr "athlon_decode" "double,vector")
4684   (set_attr "amdfam10_decode" "double,double")
4685   (set_attr "bdver1_decode" "double,double")])
4686
4687;; Avoid vector decoded forms of the instruction.
4688(define_peephole2
4689  [(match_scratch:MODEF 2 "x")
4690   (set (match_operand:SWI48 0 "register_operand")
4691	(fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4692  "TARGET_AVOID_VECTOR_DECODE
4693   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4694   && optimize_insn_for_speed_p ()"
4695  [(set (match_dup 2) (match_dup 1))
4696   (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4697
4698(define_insn "fix_trunc<mode>_i387_fisttp"
4699  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4700	(fix:SWI248x (match_operand 1 "register_operand" "f")))
4701   (clobber (match_scratch:XF 2 "=&f"))]
4702  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4703   && TARGET_FISTTP
4704   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4705	 && (TARGET_64BIT || <MODE>mode != DImode))
4706	&& TARGET_SSE_MATH)"
4707  "* return output_fix_trunc (insn, operands, true);"
4708  [(set_attr "type" "fisttp")
4709   (set_attr "mode" "<MODE>")])
4710
4711;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4712;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4713;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4714;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4715;; function in i386.c.
4716(define_insn_and_split "*fix_trunc<mode>_i387_1"
4717  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4718	(fix:SWI248x (match_operand 1 "register_operand")))
4719   (clobber (reg:CC FLAGS_REG))]
4720  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4721   && !TARGET_FISTTP
4722   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4723	 && (TARGET_64BIT || <MODE>mode != DImode))
4724   && ix86_pre_reload_split ()"
4725  "#"
4726  "&& 1"
4727  [(const_int 0)]
4728{
4729  ix86_optimize_mode_switching[I387_TRUNC] = 1;
4730
4731  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4732  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4733
4734  emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4735				       operands[2], operands[3]));
4736  DONE;
4737}
4738  [(set_attr "type" "fistp")
4739   (set_attr "i387_cw" "trunc")
4740   (set_attr "mode" "<MODE>")])
4741
4742(define_insn "fix_truncdi_i387"
4743  [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4744	(fix:DI (match_operand 1 "register_operand" "f")))
4745   (use (match_operand:HI 2 "memory_operand" "m"))
4746   (use (match_operand:HI 3 "memory_operand" "m"))
4747   (clobber (match_scratch:XF 4 "=&f"))]
4748  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4749   && !TARGET_FISTTP
4750   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4751  "* return output_fix_trunc (insn, operands, false);"
4752  [(set_attr "type" "fistp")
4753   (set_attr "i387_cw" "trunc")
4754   (set_attr "mode" "DI")])
4755
4756(define_insn "fix_trunc<mode>_i387"
4757  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4758	(fix:SWI24 (match_operand 1 "register_operand" "f")))
4759   (use (match_operand:HI 2 "memory_operand" "m"))
4760   (use (match_operand:HI 3 "memory_operand" "m"))]
4761  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4762   && !TARGET_FISTTP
4763   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4764  "* return output_fix_trunc (insn, operands, false);"
4765  [(set_attr "type" "fistp")
4766   (set_attr "i387_cw" "trunc")
4767   (set_attr "mode" "<MODE>")])
4768
4769(define_insn "x86_fnstcw_1"
4770  [(set (match_operand:HI 0 "memory_operand" "=m")
4771	(unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4772  "TARGET_80387"
4773  "fnstcw\t%0"
4774  [(set (attr "length")
4775	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4776   (set_attr "mode" "HI")
4777   (set_attr "unit" "i387")
4778   (set_attr "bdver1_decode" "vector")])
4779
4780;; Conversion between fixed point and floating point.
4781
4782;; Even though we only accept memory inputs, the backend _really_
4783;; wants to be able to do this between registers.  Thankfully, LRA
4784;; will fix this up for us during register allocation.
4785
4786(define_insn "floathi<mode>2"
4787  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4788	(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4789  "TARGET_80387
4790   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4791       || TARGET_MIX_SSE_I387)"
4792  "fild%Z1\t%1"
4793  [(set_attr "type" "fmov")
4794   (set_attr "mode" "<MODE>")
4795   (set_attr "znver1_decode" "double")
4796   (set_attr "fp_int_src" "true")])
4797
4798(define_insn "float<SWI48x:mode>xf2"
4799  [(set (match_operand:XF 0 "register_operand" "=f")
4800	(float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4801  "TARGET_80387"
4802  "fild%Z1\t%1"
4803  [(set_attr "type" "fmov")
4804   (set_attr "mode" "XF")
4805   (set_attr "znver1_decode" "double")
4806   (set_attr "fp_int_src" "true")])
4807
4808(define_expand "float<SWI48x:mode><MODEF:mode>2"
4809  [(set (match_operand:MODEF 0 "register_operand")
4810	(float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
4811  "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
4812   || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4813       && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
4814
4815(define_insn "*float<SWI48:mode><MODEF:mode>2"
4816  [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4817	(float:MODEF
4818	  (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4819  "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4820   || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4821  "@
4822   fild%Z1\t%1
4823   %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4824   %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4825  [(set_attr "type" "fmov,sseicvt,sseicvt")
4826   (set_attr "avx_partial_xmm_update" "false,true,true")
4827   (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4828   (set_attr "mode" "<MODEF:MODE>")
4829   (set (attr "prefix_rex")
4830     (if_then_else
4831       (and (eq_attr "prefix" "maybe_vex")
4832	    (match_test "<SWI48:MODE>mode == DImode"))
4833       (const_string "1")
4834       (const_string "*")))
4835   (set_attr "unit" "i387,*,*")
4836   (set_attr "athlon_decode" "*,double,direct")
4837   (set_attr "amdfam10_decode" "*,vector,double")
4838   (set_attr "bdver1_decode" "*,double,direct")
4839   (set_attr "znver1_decode" "double,*,*")
4840   (set_attr "fp_int_src" "true")
4841   (set (attr "enabled")
4842     (if_then_else
4843       (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
4844       (if_then_else
4845	 (eq_attr "alternative" "0")
4846	 (symbol_ref "TARGET_MIX_SSE_I387
4847		      && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4848					   <SWI48:MODE>mode)")
4849	 (symbol_ref "true"))
4850       (if_then_else
4851	 (eq_attr "alternative" "0")
4852	 (symbol_ref "true")
4853	 (symbol_ref "false"))))
4854   (set (attr "preferred_for_speed")
4855     (cond [(eq_attr "alternative" "1")
4856	      (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4857	   (symbol_ref "true")))])
4858
4859(define_insn "*floatdi<MODEF:mode>2_i387"
4860  [(set (match_operand:MODEF 0 "register_operand" "=f")
4861	(float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
4862  "!TARGET_64BIT
4863   && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
4864  "fild%Z1\t%1"
4865  [(set_attr "type" "fmov")
4866   (set_attr "mode" "<MODEF:MODE>")
4867   (set_attr "znver1_decode" "double")
4868   (set_attr "fp_int_src" "true")])
4869
4870;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4871;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4872;; alternative in sse2_loadld.
4873(define_split
4874  [(set (match_operand:MODEF 0 "sse_reg_operand")
4875	(float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4876  "TARGET_SSE2
4877   && TARGET_USE_VECTOR_CONVERTS
4878   && optimize_function_for_speed_p (cfun)
4879   && reload_completed
4880   && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
4881   && (!EXT_REX_SSE_REG_P (operands[0])
4882       || TARGET_AVX512VL)"
4883  [(const_int 0)]
4884{
4885  operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
4886  operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
4887
4888  emit_insn (gen_sse2_loadld (operands[4],
4889			      CONST0_RTX (V4SImode), operands[1]));
4890
4891  if (<ssevecmode>mode == V4SFmode)
4892    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4893  else
4894    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4895  DONE;
4896})
4897
4898;; Avoid store forwarding (partial memory) stall penalty
4899;; by passing DImode value through XMM registers.  */
4900
4901(define_split
4902  [(set (match_operand:X87MODEF 0 "register_operand")
4903	(float:X87MODEF
4904	  (match_operand:DI 1 "register_operand")))]
4905  "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
4906   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4907   && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
4908   && can_create_pseudo_p ()"
4909  [(const_int 0)]
4910{
4911  emit_insn (gen_floatdi<mode>2_i387_with_xmm
4912	     (operands[0], operands[1],
4913	      assign_386_stack_local (DImode, SLOT_TEMP)));
4914  DONE;
4915})
4916
4917(define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
4918  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4919	(float:X87MODEF
4920	  (match_operand:DI 1 "register_operand" "r,r")))
4921   (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
4922   (clobber (match_scratch:V4SI 3 "=x,x"))
4923   (clobber (match_scratch:V4SI 4 "=X,x"))]
4924  "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
4925   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4926   && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
4927  "#"
4928  "&& reload_completed"
4929  [(set (match_dup 2) (match_dup 3))
4930   (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4931{
4932  /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4933     Assemble the 64-bit DImode value in an xmm register.  */
4934  emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4935			      gen_lowpart (SImode, operands[1])));
4936  if (TARGET_SSE4_1)
4937    emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
4938				  gen_highpart (SImode, operands[1]),
4939				  GEN_INT (2)));
4940  else
4941    {
4942      emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4943				  gen_highpart (SImode, operands[1])));
4944      emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4945					     operands[4]));
4946    }
4947  operands[3] = gen_lowpart (DImode, operands[3]);
4948}
4949  [(set_attr "isa" "sse4,*")
4950   (set_attr "type" "multi")
4951   (set_attr "mode" "<X87MODEF:MODE>")
4952   (set_attr "unit" "i387")
4953   (set_attr "fp_int_src" "true")])
4954
4955;; Break partial SSE register dependency stall.  This splitter should split
4956;; late in the pass sequence (after register rename pass), so allocated
4957;; registers won't change anymore
4958
4959(define_split
4960  [(set (match_operand:MODEF 0 "sse_reg_operand")
4961	(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4962  "!TARGET_AVX
4963   && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4964   && optimize_function_for_speed_p (cfun)
4965   && (!EXT_REX_SSE_REG_P (operands[0])
4966       || TARGET_AVX512VL)"
4967  [(set (match_dup 0)
4968	(vec_merge:<MODEF:ssevecmode>
4969	  (vec_duplicate:<MODEF:ssevecmode>
4970	    (float:MODEF
4971	      (match_dup 1)))
4972	  (match_dup 0)
4973	  (const_int 1)))]
4974{
4975  const machine_mode vmode = <MODEF:ssevecmode>mode;
4976
4977  operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
4978  emit_move_insn (operands[0], CONST0_RTX (vmode));
4979})
4980
4981(define_expand "floatuns<SWI12:mode><MODEF:mode>2"
4982  [(set (match_operand:MODEF 0 "register_operand")
4983	(unsigned_float:MODEF
4984	  (match_operand:SWI12 1 "nonimmediate_operand")))]
4985  "!TARGET_64BIT
4986   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4987{
4988  operands[1] = convert_to_mode (SImode, operands[1], 1);
4989  emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
4990  DONE;
4991})
4992
4993(define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
4994  [(set (match_operand:MODEF 0 "register_operand" "=v")
4995	(unsigned_float:MODEF
4996	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
4997  "TARGET_AVX512F && TARGET_SSE_MATH"
4998  "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
4999  [(set_attr "type" "sseicvt")
5000   (set_attr "avx_partial_xmm_update" "true")
5001   (set_attr "prefix" "evex")
5002   (set_attr "mode" "<MODEF:MODE>")])
5003
5004;; Avoid store forwarding (partial memory) stall penalty by extending
5005;; SImode value to DImode through XMM register instead of pushing two
5006;; SImode values to stack. Also note that fild loads from memory only.
5007
5008(define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5009  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5010	(unsigned_float:X87MODEF
5011	  (match_operand:SI 1 "nonimmediate_operand" "rm")))
5012   (clobber (match_operand:DI 2 "memory_operand" "=m"))
5013   (clobber (match_scratch:DI 3 "=x"))]
5014  "!TARGET_64BIT
5015   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5016   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5017  "#"
5018  "&& reload_completed"
5019  [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5020   (set (match_dup 2) (match_dup 3))
5021   (set (match_dup 0)
5022	(float:X87MODEF (match_dup 2)))]
5023  ""
5024  [(set_attr "type" "multi")
5025   (set_attr "mode" "<MODE>")])
5026
5027(define_expand "floatunssi<mode>2"
5028  [(set (match_operand:X87MODEF 0 "register_operand")
5029	(unsigned_float:X87MODEF
5030	  (match_operand:SI 1 "nonimmediate_operand")))]
5031  "(!TARGET_64BIT
5032    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5033    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5034   || ((!TARGET_64BIT || TARGET_AVX512F)
5035       && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5036{
5037  if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5038    {
5039      emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5040		  (operands[0], operands[1],
5041		   assign_386_stack_local (DImode, SLOT_TEMP)));
5042      DONE;
5043    }
5044  if (!TARGET_AVX512F)
5045    {
5046      ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5047      DONE;
5048    }
5049})
5050
5051(define_expand "floatunsdisf2"
5052  [(set (match_operand:SF 0 "register_operand")
5053	(unsigned_float:SF
5054	  (match_operand:DI 1 "nonimmediate_operand")))]
5055  "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5056{
5057  if (!TARGET_AVX512F)
5058    {
5059      x86_emit_floatuns (operands);
5060      DONE;
5061    }
5062})
5063
5064(define_expand "floatunsdidf2"
5065  [(set (match_operand:DF 0 "register_operand")
5066	(unsigned_float:DF
5067	  (match_operand:DI 1 "nonimmediate_operand")))]
5068  "((TARGET_64BIT && TARGET_AVX512F)
5069    || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5070   && TARGET_SSE2 && TARGET_SSE_MATH"
5071{
5072  if (!TARGET_64BIT)
5073    {
5074      ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5075      DONE;
5076    }
5077  if (!TARGET_AVX512F)
5078    {
5079      x86_emit_floatuns (operands);
5080      DONE;
5081    }
5082})
5083
5084;; Load effective address instructions
5085
5086(define_insn_and_split "*lea<mode>"
5087  [(set (match_operand:SWI48 0 "register_operand" "=r")
5088	(match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5089  ""
5090{
5091  if (SImode_address_operand (operands[1], VOIDmode))
5092    {
5093      gcc_assert (TARGET_64BIT);
5094      return "lea{l}\t{%E1, %k0|%k0, %E1}";
5095    }
5096  else 
5097    return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5098}
5099  "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5100  [(const_int 0)]
5101{
5102  machine_mode mode = <MODE>mode;
5103  rtx pat;
5104
5105  /* ix86_avoid_lea_for_addr re-recognizes insn and may
5106     change operands[] array behind our back.  */
5107  pat = PATTERN (curr_insn);
5108
5109  operands[0] = SET_DEST (pat);
5110  operands[1] = SET_SRC (pat);
5111
5112  /* Emit all operations in SImode for zero-extended addresses.  */
5113  if (SImode_address_operand (operands[1], VOIDmode))
5114    mode = SImode;
5115
5116  ix86_split_lea_for_addr (curr_insn, operands, mode);
5117
5118  /* Zero-extend return register to DImode for zero-extended addresses.  */
5119  if (mode != <MODE>mode)
5120    emit_insn (gen_zero_extendsidi2
5121    	       (operands[0], gen_lowpart (mode, operands[0])));
5122
5123  DONE;
5124}
5125  [(set_attr "type" "lea")
5126   (set (attr "mode")
5127     (if_then_else
5128       (match_operand 1 "SImode_address_operand")
5129       (const_string "SI")
5130       (const_string "<MODE>")))])
5131
5132;; Add instructions
5133
5134(define_expand "add<mode>3"
5135  [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5136	(plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5137		    (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5138  ""
5139  "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5140
5141(define_insn_and_split "*add<dwi>3_doubleword"
5142  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
5143	(plus:<DWI>
5144	  (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5145	  (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
5146   (clobber (reg:CC FLAGS_REG))]
5147  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5148  "#"
5149  "reload_completed"
5150  [(parallel [(set (reg:CCC FLAGS_REG)
5151		   (compare:CCC
5152		     (plus:DWIH (match_dup 1) (match_dup 2))
5153		     (match_dup 1)))
5154	      (set (match_dup 0)
5155		   (plus:DWIH (match_dup 1) (match_dup 2)))])
5156   (parallel [(set (match_dup 3)
5157		   (plus:DWIH
5158		     (plus:DWIH
5159		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5160		       (match_dup 4))
5161		     (match_dup 5)))
5162	      (clobber (reg:CC FLAGS_REG))])]
5163{
5164  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5165  if (operands[2] == const0_rtx)
5166    {
5167      ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5168      DONE;
5169    }
5170})
5171
5172(define_insn "*add<mode>_1"
5173  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
5174	(plus:SWI48
5175	  (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5176	  (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le")))
5177   (clobber (reg:CC FLAGS_REG))]
5178  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5179{
5180  switch (get_attr_type (insn))
5181    {
5182    case TYPE_LEA:
5183      return "#";
5184
5185    case TYPE_INCDEC:
5186      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5187      if (operands[2] == const1_rtx)
5188        return "inc{<imodesuffix>}\t%0";
5189      else
5190        {
5191	  gcc_assert (operands[2] == constm1_rtx);
5192          return "dec{<imodesuffix>}\t%0";
5193	}
5194
5195    default:
5196      /* For most processors, ADD is faster than LEA.  This alternative
5197	 was added to use ADD as much as possible.  */
5198      if (which_alternative == 2)
5199        std::swap (operands[1], operands[2]);
5200        
5201      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5202      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5203        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5204
5205      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5206    }
5207}
5208  [(set (attr "type")
5209     (cond [(eq_attr "alternative" "3")
5210              (const_string "lea")
5211	    (match_operand:SWI48 2 "incdec_operand")
5212	      (const_string "incdec")
5213	   ]
5214	   (const_string "alu")))
5215   (set (attr "length_immediate")
5216      (if_then_else
5217	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5218	(const_string "1")
5219	(const_string "*")))
5220   (set_attr "mode" "<MODE>")])
5221
5222;; It may seem that nonimmediate operand is proper one for operand 1.
5223;; The addsi_1 pattern allows nonimmediate operand at that place and
5224;; we take care in ix86_binary_operator_ok to not allow two memory
5225;; operands so proper swapping will be done in reload.  This allow
5226;; patterns constructed from addsi_1 to match.
5227
5228(define_insn "addsi_1_zext"
5229  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5230	(zero_extend:DI
5231	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5232		   (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5233   (clobber (reg:CC FLAGS_REG))]
5234  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5235{
5236  switch (get_attr_type (insn))
5237    {
5238    case TYPE_LEA:
5239      return "#";
5240
5241    case TYPE_INCDEC:
5242      if (operands[2] == const1_rtx)
5243        return "inc{l}\t%k0";
5244      else
5245        {
5246	  gcc_assert (operands[2] == constm1_rtx);
5247          return "dec{l}\t%k0";
5248	}
5249
5250    default:
5251      /* For most processors, ADD is faster than LEA.  This alternative
5252	 was added to use ADD as much as possible.  */
5253      if (which_alternative == 1)
5254        std::swap (operands[1], operands[2]);
5255
5256      if (x86_maybe_negate_const_int (&operands[2], SImode))
5257        return "sub{l}\t{%2, %k0|%k0, %2}";
5258
5259      return "add{l}\t{%2, %k0|%k0, %2}";
5260    }
5261}
5262  [(set (attr "type")
5263     (cond [(eq_attr "alternative" "2")
5264	      (const_string "lea")
5265	    (match_operand:SI 2 "incdec_operand")
5266	      (const_string "incdec")
5267	   ]
5268	   (const_string "alu")))
5269   (set (attr "length_immediate")
5270      (if_then_else
5271	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5272	(const_string "1")
5273	(const_string "*")))
5274   (set_attr "mode" "SI")])
5275
5276(define_insn "*addhi_1"
5277  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5278	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5279		 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
5280   (clobber (reg:CC FLAGS_REG))]
5281  "ix86_binary_operator_ok (PLUS, HImode, operands)"
5282{
5283  switch (get_attr_type (insn))
5284    {
5285    case TYPE_LEA:
5286      return "#";
5287
5288    case TYPE_INCDEC:
5289      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5290      if (operands[2] == const1_rtx)
5291	return "inc{w}\t%0";
5292      else
5293	{
5294	  gcc_assert (operands[2] == constm1_rtx);
5295	  return "dec{w}\t%0";
5296	}
5297
5298    default:
5299      /* For most processors, ADD is faster than LEA.  This alternative
5300	 was added to use ADD as much as possible.  */
5301      if (which_alternative == 2)
5302        std::swap (operands[1], operands[2]);
5303
5304      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5305      if (x86_maybe_negate_const_int (&operands[2], HImode))
5306	return "sub{w}\t{%2, %0|%0, %2}";
5307
5308      return "add{w}\t{%2, %0|%0, %2}";
5309    }
5310}
5311  [(set (attr "type")
5312     (cond [(eq_attr "alternative" "3")
5313              (const_string "lea")
5314	    (match_operand:HI 2 "incdec_operand")
5315	      (const_string "incdec")
5316	   ]
5317	   (const_string "alu")))
5318   (set (attr "length_immediate")
5319      (if_then_else
5320	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5321	(const_string "1")
5322	(const_string "*")))
5323   (set_attr "mode" "HI,HI,HI,SI")])
5324
5325(define_insn "*addqi_1"
5326  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5327	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5328		 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
5329   (clobber (reg:CC FLAGS_REG))]
5330  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5331{
5332  bool widen = (get_attr_mode (insn) != MODE_QI);
5333
5334  switch (get_attr_type (insn))
5335    {
5336    case TYPE_LEA:
5337      return "#";
5338
5339    case TYPE_INCDEC:
5340      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5341      if (operands[2] == const1_rtx)
5342	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5343      else
5344	{
5345	  gcc_assert (operands[2] == constm1_rtx);
5346	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5347	}
5348
5349    default:
5350      /* For most processors, ADD is faster than LEA.  These alternatives
5351	 were added to use ADD as much as possible.  */
5352      if (which_alternative == 2 || which_alternative == 4)
5353        std::swap (operands[1], operands[2]);
5354
5355      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5356      if (x86_maybe_negate_const_int (&operands[2], QImode))
5357	{
5358	  if (widen)
5359	    return "sub{l}\t{%2, %k0|%k0, %2}";
5360	  else
5361	    return "sub{b}\t{%2, %0|%0, %2}";
5362	}
5363      if (widen)
5364        return "add{l}\t{%k2, %k0|%k0, %k2}";
5365      else
5366        return "add{b}\t{%2, %0|%0, %2}";
5367    }
5368}
5369  [(set (attr "type")
5370     (cond [(eq_attr "alternative" "5")
5371              (const_string "lea")
5372	    (match_operand:QI 2 "incdec_operand")
5373	      (const_string "incdec")
5374	   ]
5375	   (const_string "alu")))
5376   (set (attr "length_immediate")
5377      (if_then_else
5378	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5379	(const_string "1")
5380	(const_string "*")))
5381   (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5382   ;; Potential partial reg stall on alternatives 3 and 4.
5383   (set (attr "preferred_for_speed")
5384     (cond [(eq_attr "alternative" "3,4")
5385	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5386	   (symbol_ref "true")))])
5387
5388(define_insn "*add<mode>_1_slp"
5389  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
5390	(plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
5391		    (match_operand:SWI12 2 "general_operand" "<r>mn")))
5392   (clobber (reg:CC FLAGS_REG))]
5393  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5394   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
5395   && (rtx_equal_p (operands[0], operands[1])
5396       || rtx_equal_p (operands[0], operands[2]))"
5397{
5398  switch (get_attr_type (insn))
5399    {
5400    case TYPE_INCDEC:
5401      if (operands[2] == const1_rtx)
5402	return "inc{<imodesuffix>}\t%0";
5403      else
5404	{
5405	  gcc_assert (operands[2] == constm1_rtx);
5406	  return "dec{<imodesuffix>}\t%0";
5407	}
5408
5409    default:
5410      if (x86_maybe_negate_const_int (&operands[2], QImode))
5411	return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5412
5413      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5414    }
5415}
5416  [(set (attr "type")
5417     (if_then_else (match_operand:QI 2 "incdec_operand")
5418	(const_string "incdec")
5419	(const_string "alu")))
5420   (set_attr "mode" "<MODE>")])
5421
5422;; Split non destructive adds if we cannot use lea.
5423(define_split
5424  [(set (match_operand:SWI48 0 "register_operand")
5425	(plus:SWI48 (match_operand:SWI48 1 "register_operand")
5426		    (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5427   (clobber (reg:CC FLAGS_REG))]
5428  "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5429  [(set (match_dup 0) (match_dup 1))
5430   (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5431	      (clobber (reg:CC FLAGS_REG))])])
5432
5433;; Split non destructive adds if we cannot use lea.
5434(define_split
5435  [(set (match_operand:DI 0 "register_operand")
5436  	(zero_extend:DI
5437	  (plus:SI (match_operand:SI 1 "register_operand")
5438		   (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5439   (clobber (reg:CC FLAGS_REG))]
5440  "TARGET_64BIT
5441   && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5442  [(set (match_dup 3) (match_dup 1))
5443   (parallel [(set (match_dup 0)
5444   	     	   (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5445	      (clobber (reg:CC FLAGS_REG))])]
5446  "operands[3] = gen_lowpart (SImode, operands[0]);")
5447
5448;; Convert add to the lea pattern to avoid flags dependency.
5449(define_split
5450  [(set (match_operand:SWI 0 "register_operand")
5451	(plus:SWI (match_operand:SWI 1 "register_operand")
5452		  (match_operand:SWI 2 "<nonmemory_operand>")))
5453   (clobber (reg:CC FLAGS_REG))]
5454  "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5455  [(set (match_dup 0)
5456	(plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5457{
5458  if (<MODE>mode != <LEAMODE>mode)
5459    {
5460      operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5461      operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5462      operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5463    }
5464})
5465
5466;; Convert add to the lea pattern to avoid flags dependency.
5467(define_split
5468  [(set (match_operand:DI 0 "register_operand")
5469	(zero_extend:DI
5470	  (plus:SI (match_operand:SI 1 "register_operand")
5471		   (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5472   (clobber (reg:CC FLAGS_REG))]
5473  "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5474  [(set (match_dup 0)
5475	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5476
5477(define_insn "*add<mode>_2"
5478  [(set (reg FLAGS_REG)
5479	(compare
5480	  (plus:SWI
5481	    (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5482	    (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0"))
5483	  (const_int 0)))
5484   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
5485	(plus:SWI (match_dup 1) (match_dup 2)))]
5486  "ix86_match_ccmode (insn, CCGOCmode)
5487   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5488{
5489  switch (get_attr_type (insn))
5490    {
5491    case TYPE_INCDEC:
5492      if (operands[2] == const1_rtx)
5493        return "inc{<imodesuffix>}\t%0";
5494      else
5495        {
5496	  gcc_assert (operands[2] == constm1_rtx);
5497          return "dec{<imodesuffix>}\t%0";
5498	}
5499
5500    default:
5501      if (which_alternative == 2)
5502        std::swap (operands[1], operands[2]);
5503        
5504      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5505      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5506        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5507
5508      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5509    }
5510}
5511  [(set (attr "type")
5512     (if_then_else (match_operand:SWI 2 "incdec_operand")
5513	(const_string "incdec")
5514	(const_string "alu")))
5515   (set (attr "length_immediate")
5516      (if_then_else
5517	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5518	(const_string "1")
5519	(const_string "*")))
5520   (set_attr "mode" "<MODE>")])
5521
5522;; See comment for addsi_1_zext why we do use nonimmediate_operand
5523(define_insn "*addsi_2_zext"
5524  [(set (reg FLAGS_REG)
5525	(compare
5526	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5527		   (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5528	  (const_int 0)))
5529   (set (match_operand:DI 0 "register_operand" "=r,r")
5530	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5531  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5532   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5533{
5534  switch (get_attr_type (insn))
5535    {
5536    case TYPE_INCDEC:
5537      if (operands[2] == const1_rtx)
5538        return "inc{l}\t%k0";
5539      else
5540	{
5541	  gcc_assert (operands[2] == constm1_rtx);
5542          return "dec{l}\t%k0";
5543	}
5544
5545    default:
5546      if (which_alternative == 1)
5547        std::swap (operands[1], operands[2]);
5548
5549      if (x86_maybe_negate_const_int (&operands[2], SImode))
5550        return "sub{l}\t{%2, %k0|%k0, %2}";
5551
5552      return "add{l}\t{%2, %k0|%k0, %2}";
5553    }
5554}
5555  [(set (attr "type")
5556     (if_then_else (match_operand:SI 2 "incdec_operand")
5557	(const_string "incdec")
5558	(const_string "alu")))
5559   (set (attr "length_immediate")
5560      (if_then_else
5561	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5562	(const_string "1")
5563	(const_string "*")))
5564   (set_attr "mode" "SI")])
5565
5566(define_insn "*add<mode>_3"
5567  [(set (reg FLAGS_REG)
5568	(compare
5569	  (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5570	  (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5571   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5572  "ix86_match_ccmode (insn, CCZmode)
5573   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5574{
5575  switch (get_attr_type (insn))
5576    {
5577    case TYPE_INCDEC:
5578      if (operands[2] == const1_rtx)
5579        return "inc{<imodesuffix>}\t%0";
5580      else
5581        {
5582	  gcc_assert (operands[2] == constm1_rtx);
5583          return "dec{<imodesuffix>}\t%0";
5584	}
5585
5586    default:
5587      if (which_alternative == 1)
5588        std::swap (operands[1], operands[2]);
5589
5590      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5591      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5592        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5593
5594      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5595    }
5596}
5597  [(set (attr "type")
5598     (if_then_else (match_operand:SWI 2 "incdec_operand")
5599	(const_string "incdec")
5600	(const_string "alu")))
5601   (set (attr "length_immediate")
5602      (if_then_else
5603	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5604	(const_string "1")
5605	(const_string "*")))
5606   (set_attr "mode" "<MODE>")])
5607
5608;; See comment for addsi_1_zext why we do use nonimmediate_operand
5609(define_insn "*addsi_3_zext"
5610  [(set (reg FLAGS_REG)
5611	(compare
5612	  (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5613	  (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5614   (set (match_operand:DI 0 "register_operand" "=r,r")
5615	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5616  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5617   && ix86_binary_operator_ok (PLUS, SImode, operands)"
5618{
5619  switch (get_attr_type (insn))
5620    {
5621    case TYPE_INCDEC:
5622      if (operands[2] == const1_rtx)
5623        return "inc{l}\t%k0";
5624      else
5625        {
5626	  gcc_assert (operands[2] == constm1_rtx);
5627          return "dec{l}\t%k0";
5628	}
5629
5630    default:
5631      if (which_alternative == 1)
5632        std::swap (operands[1], operands[2]);
5633
5634      if (x86_maybe_negate_const_int (&operands[2], SImode))
5635        return "sub{l}\t{%2, %k0|%k0, %2}";
5636
5637      return "add{l}\t{%2, %k0|%k0, %2}";
5638    }
5639}
5640  [(set (attr "type")
5641     (if_then_else (match_operand:SI 2 "incdec_operand")
5642	(const_string "incdec")
5643	(const_string "alu")))
5644   (set (attr "length_immediate")
5645      (if_then_else
5646	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5647	(const_string "1")
5648	(const_string "*")))
5649   (set_attr "mode" "SI")])
5650
5651; For comparisons against 1, -1 and 128, we may generate better code
5652; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5653; is matched then.  We can't accept general immediate, because for
5654; case of overflows,  the result is messed up.
5655; Also carry flag is reversed compared to cmp, so this conversion is valid
5656; only for comparisons not depending on it.
5657
5658(define_insn "*adddi_4"
5659  [(set (reg FLAGS_REG)
5660	(compare
5661	  (match_operand:DI 1 "nonimmediate_operand" "0")
5662	  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5663   (clobber (match_scratch:DI 0 "=rm"))]
5664  "TARGET_64BIT
5665   && ix86_match_ccmode (insn, CCGCmode)"
5666{
5667  switch (get_attr_type (insn))
5668    {
5669    case TYPE_INCDEC:
5670      if (operands[2] == constm1_rtx)
5671        return "inc{q}\t%0";
5672      else
5673        {
5674	  gcc_assert (operands[2] == const1_rtx);
5675          return "dec{q}\t%0";
5676	}
5677
5678    default:
5679      if (x86_maybe_negate_const_int (&operands[2], DImode))
5680	return "add{q}\t{%2, %0|%0, %2}";
5681
5682      return "sub{q}\t{%2, %0|%0, %2}";
5683    }
5684}
5685  [(set (attr "type")
5686     (if_then_else (match_operand:DI 2 "incdec_operand")
5687	(const_string "incdec")
5688	(const_string "alu")))
5689   (set (attr "length_immediate")
5690      (if_then_else
5691	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5692	(const_string "1")
5693	(const_string "*")))
5694   (set_attr "mode" "DI")])
5695
5696; For comparisons against 1, -1 and 128, we may generate better code
5697; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5698; is matched then.  We can't accept general immediate, because for
5699; case of overflows,  the result is messed up.
5700; Also carry flag is reversed compared to cmp, so this conversion is valid
5701; only for comparisons not depending on it.
5702
5703(define_insn "*add<mode>_4"
5704  [(set (reg FLAGS_REG)
5705	(compare
5706	  (match_operand:SWI124 1 "nonimmediate_operand" "0")
5707	  (match_operand:SWI124 2 "const_int_operand" "n")))
5708   (clobber (match_scratch:SWI124 0 "=<r>m"))]
5709  "ix86_match_ccmode (insn, CCGCmode)"
5710{
5711  switch (get_attr_type (insn))
5712    {
5713    case TYPE_INCDEC:
5714      if (operands[2] == constm1_rtx)
5715        return "inc{<imodesuffix>}\t%0";
5716      else
5717        {
5718	  gcc_assert (operands[2] == const1_rtx);
5719          return "dec{<imodesuffix>}\t%0";
5720	}
5721
5722    default:
5723      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5724	return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5725
5726      return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5727    }
5728}
5729  [(set (attr "type")
5730     (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5731	(const_string "incdec")
5732	(const_string "alu")))
5733   (set (attr "length_immediate")
5734      (if_then_else
5735	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5736	(const_string "1")
5737	(const_string "*")))
5738   (set_attr "mode" "<MODE>")])
5739
5740(define_insn "*add<mode>_5"
5741  [(set (reg FLAGS_REG)
5742	(compare
5743	  (plus:SWI
5744	    (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5745	    (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5746	  (const_int 0)))
5747   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5748  "ix86_match_ccmode (insn, CCGOCmode)
5749   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5750{
5751  switch (get_attr_type (insn))
5752    {
5753    case TYPE_INCDEC:
5754      if (operands[2] == const1_rtx)
5755        return "inc{<imodesuffix>}\t%0";
5756      else
5757        {
5758          gcc_assert (operands[2] == constm1_rtx);
5759          return "dec{<imodesuffix>}\t%0";
5760	}
5761
5762    default:
5763      if (which_alternative == 1)
5764        std::swap (operands[1], operands[2]);
5765
5766      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5767      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5768        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5769
5770      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5771    }
5772}
5773  [(set (attr "type")
5774     (if_then_else (match_operand:SWI 2 "incdec_operand")
5775	(const_string "incdec")
5776	(const_string "alu")))
5777   (set (attr "length_immediate")
5778      (if_then_else
5779	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5780	(const_string "1")
5781	(const_string "*")))
5782   (set_attr "mode" "<MODE>")])
5783
5784(define_insn "addqi_ext_1"
5785  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
5786			 (const_int 8)
5787			 (const_int 8))
5788	(subreg:SI
5789	  (plus:QI
5790	    (subreg:QI
5791	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
5792			       (const_int 8)
5793			       (const_int 8)) 0)
5794	    (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
5795   (clobber (reg:CC FLAGS_REG))]
5796  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
5797   rtx_equal_p (operands[0], operands[1])"
5798{
5799  switch (get_attr_type (insn))
5800    {
5801    case TYPE_INCDEC:
5802      if (operands[2] == const1_rtx)
5803	return "inc{b}\t%h0";
5804      else
5805        {
5806	  gcc_assert (operands[2] == constm1_rtx);
5807          return "dec{b}\t%h0";
5808        }
5809
5810    default:
5811      return "add{b}\t{%2, %h0|%h0, %2}";
5812    }
5813}
5814  [(set_attr "isa" "*,nox64")
5815   (set (attr "type")
5816     (if_then_else (match_operand:QI 2 "incdec_operand")
5817	(const_string "incdec")
5818	(const_string "alu")))
5819   (set_attr "mode" "QI")])
5820
5821(define_insn "*addqi_ext_2"
5822  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
5823			 (const_int 8)
5824			 (const_int 8))
5825	(subreg:SI
5826	  (plus:QI
5827	    (subreg:QI
5828	      (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
5829			       (const_int 8)
5830			       (const_int 8)) 0)
5831	    (subreg:QI
5832	      (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
5833			       (const_int 8)
5834			       (const_int 8)) 0)) 0))
5835  (clobber (reg:CC FLAGS_REG))]
5836  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
5837   rtx_equal_p (operands[0], operands[1])
5838   || rtx_equal_p (operands[0], operands[2])"
5839  "add{b}\t{%h2, %h0|%h0, %h2}"
5840  [(set_attr "type" "alu")
5841   (set_attr "mode" "QI")])
5842
5843;; Like DWI, but use POImode instead of OImode.
5844(define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
5845
5846;; Add with jump on overflow.
5847(define_expand "addv<mode>4"
5848  [(parallel [(set (reg:CCO FLAGS_REG)
5849		   (eq:CCO
5850		     (plus:<DPWI>
5851		       (sign_extend:<DPWI>
5852			 (match_operand:SWIDWI 1 "nonimmediate_operand"))
5853		       (match_dup 4))
5854			 (sign_extend:<DPWI>
5855			   (plus:SWIDWI (match_dup 1)
5856			     (match_operand:SWIDWI 2
5857			       "<general_hilo_operand>")))))
5858	      (set (match_operand:SWIDWI 0 "register_operand")
5859		   (plus:SWIDWI (match_dup 1) (match_dup 2)))])
5860   (set (pc) (if_then_else
5861	       (eq (reg:CCO FLAGS_REG) (const_int 0))
5862	       (label_ref (match_operand 3))
5863	       (pc)))]
5864  ""
5865{
5866  ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5867  if (CONST_SCALAR_INT_P (operands[2]))
5868    operands[4] = operands[2];
5869  else
5870    operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
5871})
5872
5873(define_insn "*addv<mode>4"
5874  [(set (reg:CCO FLAGS_REG)
5875	(eq:CCO (plus:<DWI>
5876		   (sign_extend:<DWI>
5877		      (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5878		   (sign_extend:<DWI>
5879		      (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
5880		(sign_extend:<DWI>
5881		   (plus:SWI (match_dup 1) (match_dup 2)))))
5882   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5883	(plus:SWI (match_dup 1) (match_dup 2)))]
5884  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5885  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5886  [(set_attr "type" "alu")
5887   (set_attr "mode" "<MODE>")])
5888
5889(define_insn "addv<mode>4_1"
5890  [(set (reg:CCO FLAGS_REG)
5891	(eq:CCO (plus:<DWI>
5892		   (sign_extend:<DWI>
5893		      (match_operand:SWI 1 "nonimmediate_operand" "0"))
5894		   (match_operand:<DWI> 3 "const_int_operand" "i"))
5895		(sign_extend:<DWI>
5896		   (plus:SWI
5897		     (match_dup 1)
5898		     (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
5899   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5900	(plus:SWI (match_dup 1) (match_dup 2)))]
5901  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5902   && CONST_INT_P (operands[2])
5903   && INTVAL (operands[2]) == INTVAL (operands[3])"
5904  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5905  [(set_attr "type" "alu")
5906   (set_attr "mode" "<MODE>")
5907   (set (attr "length_immediate")
5908	(cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5909		  (const_string "1")
5910	       (match_test "<MODE_SIZE> == 8")
5911		  (const_string "4")]
5912	      (const_string "<MODE_SIZE>")))])
5913
5914;; Quad word integer modes as mode attribute.
5915(define_mode_attr QPWI [(SI "TI") (DI "POI")])
5916
5917(define_insn_and_split "*addv<dwi>4_doubleword"
5918  [(set (reg:CCO FLAGS_REG)
5919	(eq:CCO
5920	  (plus:<QPWI>
5921	    (sign_extend:<QPWI>
5922	      (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
5923	    (sign_extend:<QPWI>
5924	      (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
5925	  (sign_extend:<QPWI>
5926	    (plus:<DWI> (match_dup 1) (match_dup 2)))))
5927   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
5928	(plus:<DWI> (match_dup 1) (match_dup 2)))]
5929  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5930  "#"
5931  "reload_completed"
5932  [(parallel [(set (reg:CCC FLAGS_REG)
5933		   (compare:CCC
5934		     (plus:DWIH (match_dup 1) (match_dup 2))
5935		     (match_dup 1)))
5936	      (set (match_dup 0)
5937		   (plus:DWIH (match_dup 1) (match_dup 2)))])
5938   (parallel [(set (reg:CCO FLAGS_REG)
5939		   (eq:CCO
5940		     (plus:<DWI>
5941		       (plus:<DWI>
5942			 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
5943			 (sign_extend:<DWI> (match_dup 4)))
5944		       (sign_extend:<DWI> (match_dup 5)))
5945		     (sign_extend:<DWI>
5946		       (plus:DWIH
5947			 (plus:DWIH
5948			   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5949			   (match_dup 4))
5950			 (match_dup 5)))))
5951	      (set (match_dup 3)
5952		   (plus:DWIH
5953		     (plus:DWIH
5954		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5955		       (match_dup 4))
5956		     (match_dup 5)))])]
5957{
5958  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5959})
5960
5961(define_insn_and_split "*addv<dwi>4_doubleword_1"
5962  [(set (reg:CCO FLAGS_REG)
5963	(eq:CCO
5964	  (plus:<QPWI>
5965	    (sign_extend:<QPWI>
5966	      (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
5967	    (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
5968	  (sign_extend:<QPWI>
5969	    (plus:<DWI>
5970	      (match_dup 1)
5971	      (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
5972   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
5973	(plus:<DWI> (match_dup 1) (match_dup 2)))]
5974  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
5975   && CONST_SCALAR_INT_P (operands[2])
5976   && rtx_equal_p (operands[2], operands[3])"
5977  "#"
5978  "reload_completed"
5979  [(parallel [(set (reg:CCC FLAGS_REG)
5980		   (compare:CCC
5981		     (plus:DWIH (match_dup 1) (match_dup 2))
5982		     (match_dup 1)))
5983	      (set (match_dup 0)
5984		   (plus:DWIH (match_dup 1) (match_dup 2)))])
5985   (parallel [(set (reg:CCO FLAGS_REG)
5986		   (eq:CCO
5987		     (plus:<DWI>
5988		       (plus:<DWI>
5989			 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
5990			 (sign_extend:<DWI> (match_dup 4)))
5991		       (match_dup 5))
5992		     (sign_extend:<DWI>
5993		       (plus:DWIH
5994			 (plus:DWIH
5995			   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5996			   (match_dup 4))
5997			 (match_dup 5)))))
5998	      (set (match_dup 3)
5999		   (plus:DWIH
6000		     (plus:DWIH
6001		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6002		       (match_dup 4))
6003		     (match_dup 5)))])]
6004{
6005  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6006  if (operands[2] == const0_rtx)
6007    {
6008      emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
6009				    operands[5]));
6010      DONE;
6011    }
6012})
6013
6014(define_insn "*addv<mode>4_overflow_1"
6015  [(set (reg:CCO FLAGS_REG)
6016	(eq:CCO
6017	  (plus:<DWI>
6018	    (plus:<DWI>
6019	      (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6020		[(match_operand 3 "flags_reg_operand") (const_int 0)])
6021	      (sign_extend:<DWI>
6022		(match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
6023	    (sign_extend:<DWI>
6024	      (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
6025	  (sign_extend:<DWI>
6026	    (plus:SWI
6027	      (plus:SWI
6028		(match_operator:SWI 5 "ix86_carry_flag_operator"
6029		  [(match_dup 3) (const_int 0)])
6030		(match_dup 1))
6031	      (match_dup 2)))))
6032   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
6033	(plus:SWI
6034	  (plus:SWI
6035	    (match_op_dup 5 [(match_dup 3) (const_int 0)])
6036	    (match_dup 1))
6037	  (match_dup 2)))]
6038  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6039  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6040  [(set_attr "type" "alu")
6041   (set_attr "mode" "<MODE>")])
6042
6043(define_insn "*addv<mode>4_overflow_2"
6044  [(set (reg:CCO FLAGS_REG)
6045	(eq:CCO
6046	  (plus:<DWI>
6047	    (plus:<DWI>
6048	      (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6049		[(match_operand 3 "flags_reg_operand") (const_int 0)])
6050	      (sign_extend:<DWI>
6051		(match_operand:SWI 1 "nonimmediate_operand" "%0")))
6052	    (match_operand:<DWI> 6 "const_int_operand" ""))
6053	  (sign_extend:<DWI>
6054	    (plus:SWI
6055	      (plus:SWI
6056		(match_operator:SWI 5 "ix86_carry_flag_operator"
6057		  [(match_dup 3) (const_int 0)])
6058		(match_dup 1))
6059	      (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
6060   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
6061	(plus:SWI
6062	  (plus:SWI
6063	    (match_op_dup 5 [(match_dup 3) (const_int 0)])
6064	    (match_dup 1))
6065	  (match_dup 2)))]
6066  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6067   && CONST_INT_P (operands[2])
6068   && INTVAL (operands[2]) == INTVAL (operands[6])"
6069  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6070  [(set_attr "type" "alu")
6071   (set_attr "mode" "<MODE>")
6072   (set (attr "length_immediate")
6073     (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6074       (const_string "1")
6075       (const_string "4")))])
6076
6077(define_expand "uaddv<mode>4"
6078  [(parallel [(set (reg:CCC FLAGS_REG)
6079		   (compare:CCC
6080		     (plus:SWIDWI
6081		       (match_operand:SWIDWI 1 "nonimmediate_operand")
6082		       (match_operand:SWIDWI 2 "<general_hilo_operand>"))
6083		     (match_dup 1)))
6084	      (set (match_operand:SWIDWI 0 "register_operand")
6085		   (plus:SWIDWI (match_dup 1) (match_dup 2)))])
6086   (set (pc) (if_then_else
6087	       (ltu (reg:CCC FLAGS_REG) (const_int 0))
6088	       (label_ref (match_operand 3))
6089	       (pc)))]
6090  ""
6091  "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6092
6093;; The lea patterns for modes less than 32 bits need to be matched by
6094;; several insns converted to real lea by splitters.
6095
6096(define_insn_and_split "*lea<mode>_general_1"
6097  [(set (match_operand:SWI12 0 "register_operand" "=r")
6098	(plus:SWI12
6099	  (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6100		      (match_operand:SWI12 2 "register_operand" "r"))
6101	  (match_operand:SWI12 3 "immediate_operand" "i")))]
6102  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6103  "#"
6104  "&& reload_completed"
6105  [(set (match_dup 0)
6106	(plus:SI
6107	  (plus:SI (match_dup 1) (match_dup 2))
6108	  (match_dup 3)))]
6109{
6110  operands[0] = gen_lowpart (SImode, operands[0]);
6111  operands[1] = gen_lowpart (SImode, operands[1]);
6112  operands[2] = gen_lowpart (SImode, operands[2]);
6113  operands[3] = gen_lowpart (SImode, operands[3]);
6114}
6115  [(set_attr "type" "lea")
6116   (set_attr "mode" "SI")])
6117
6118(define_insn_and_split "*lea<mode>_general_2"
6119  [(set (match_operand:SWI12 0 "register_operand" "=r")
6120	(plus:SWI12
6121	  (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6122		      (match_operand 2 "const248_operand" "n"))
6123	  (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6124  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6125  "#"
6126  "&& reload_completed"
6127  [(set (match_dup 0)
6128	(plus:SI
6129	  (mult:SI (match_dup 1) (match_dup 2))
6130	  (match_dup 3)))]
6131{
6132  operands[0] = gen_lowpart (SImode, operands[0]);
6133  operands[1] = gen_lowpart (SImode, operands[1]);
6134  operands[3] = gen_lowpart (SImode, operands[3]);
6135}
6136  [(set_attr "type" "lea")
6137   (set_attr "mode" "SI")])
6138
6139(define_insn_and_split "*lea<mode>_general_2b"
6140  [(set (match_operand:SWI12 0 "register_operand" "=r")
6141	(plus:SWI12
6142	  (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6143			(match_operand 2 "const123_operand" "n"))
6144	  (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6145  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6146  "#"
6147  "&& reload_completed"
6148  [(set (match_dup 0)
6149	(plus:SI
6150	  (ashift:SI (match_dup 1) (match_dup 2))
6151	  (match_dup 3)))]
6152{
6153  operands[0] = gen_lowpart (SImode, operands[0]);
6154  operands[1] = gen_lowpart (SImode, operands[1]);
6155  operands[3] = gen_lowpart (SImode, operands[3]);
6156}
6157  [(set_attr "type" "lea")
6158   (set_attr "mode" "SI")])
6159
6160(define_insn_and_split "*lea<mode>_general_3"
6161  [(set (match_operand:SWI12 0 "register_operand" "=r")
6162	(plus:SWI12
6163	  (plus:SWI12
6164	    (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6165			(match_operand 2 "const248_operand" "n"))
6166	    (match_operand:SWI12 3 "register_operand" "r"))
6167	  (match_operand:SWI12 4 "immediate_operand" "i")))]
6168  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6169  "#"
6170  "&& reload_completed"
6171  [(set (match_dup 0)
6172	(plus:SI
6173	  (plus:SI
6174	    (mult:SI (match_dup 1) (match_dup 2))
6175	    (match_dup 3))
6176	  (match_dup 4)))]
6177{
6178  operands[0] = gen_lowpart (SImode, operands[0]);
6179  operands[1] = gen_lowpart (SImode, operands[1]);
6180  operands[3] = gen_lowpart (SImode, operands[3]);
6181  operands[4] = gen_lowpart (SImode, operands[4]);
6182}
6183  [(set_attr "type" "lea")
6184   (set_attr "mode" "SI")])
6185
6186(define_insn_and_split "*lea<mode>_general_3b"
6187  [(set (match_operand:SWI12 0 "register_operand" "=r")
6188	(plus:SWI12
6189	  (plus:SWI12
6190	    (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6191			  (match_operand 2 "const123_operand" "n"))
6192	    (match_operand:SWI12 3 "register_operand" "r"))
6193	  (match_operand:SWI12 4 "immediate_operand" "i")))]
6194  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6195  "#"
6196  "&& reload_completed"
6197  [(set (match_dup 0)
6198	(plus:SI
6199	  (plus:SI
6200	    (ashift:SI (match_dup 1) (match_dup 2))
6201	    (match_dup 3))
6202	  (match_dup 4)))]
6203{
6204  operands[0] = gen_lowpart (SImode, operands[0]);
6205  operands[1] = gen_lowpart (SImode, operands[1]);
6206  operands[3] = gen_lowpart (SImode, operands[3]);
6207  operands[4] = gen_lowpart (SImode, operands[4]);
6208}
6209  [(set_attr "type" "lea")
6210   (set_attr "mode" "SI")])
6211
6212(define_insn_and_split "*lea<mode>_general_4"
6213  [(set (match_operand:SWI12 0 "register_operand" "=r")
6214	(any_or:SWI12
6215	  (ashift:SWI12
6216	    (match_operand:SWI12 1 "index_register_operand" "l")
6217	    (match_operand 2 "const_0_to_3_operand" "n"))
6218	  (match_operand 3 "const_int_operand" "n")))]
6219  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6220   && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6221       < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6222  "#"
6223  "&& reload_completed"
6224  [(set (match_dup 0)
6225	(plus:SI
6226	  (mult:SI (match_dup 1) (match_dup 2))
6227	  (match_dup 3)))]
6228{
6229  operands[0] = gen_lowpart (SImode, operands[0]);
6230  operands[1] = gen_lowpart (SImode, operands[1]);
6231  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6232}
6233  [(set_attr "type" "lea")
6234   (set_attr "mode" "SI")])
6235
6236(define_insn_and_split "*lea<mode>_general_4"
6237  [(set (match_operand:SWI48 0 "register_operand" "=r")
6238	(any_or:SWI48
6239	  (ashift:SWI48
6240	    (match_operand:SWI48 1 "index_register_operand" "l")
6241	    (match_operand 2 "const_0_to_3_operand" "n"))
6242	  (match_operand 3 "const_int_operand" "n")))]
6243  "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6244   < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6245  "#"
6246  "&& reload_completed"
6247  [(set (match_dup 0)
6248	(plus:SWI48
6249	  (mult:SWI48 (match_dup 1) (match_dup 2))
6250	  (match_dup 3)))]
6251  "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6252  [(set_attr "type" "lea")
6253   (set_attr "mode" "<MODE>")])
6254
6255;; Subtract instructions
6256
6257(define_expand "sub<mode>3"
6258  [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6259	(minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6260		     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6261  ""
6262  "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6263
6264(define_insn_and_split "*sub<dwi>3_doubleword"
6265  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6266	(minus:<DWI>
6267	  (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6268	  (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6269   (clobber (reg:CC FLAGS_REG))]
6270  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6271  "#"
6272  "reload_completed"
6273  [(parallel [(set (reg:CC FLAGS_REG)
6274		   (compare:CC (match_dup 1) (match_dup 2)))
6275	      (set (match_dup 0)
6276		   (minus:DWIH (match_dup 1) (match_dup 2)))])
6277   (parallel [(set (match_dup 3)
6278		   (minus:DWIH
6279		     (minus:DWIH
6280		       (match_dup 4)
6281		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6282		     (match_dup 5)))
6283	      (clobber (reg:CC FLAGS_REG))])]
6284{
6285  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6286  if (operands[2] == const0_rtx)
6287    {
6288      ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6289      DONE;
6290    }
6291})
6292
6293(define_insn "*sub<mode>_1"
6294  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6295	(minus:SWI
6296	  (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6297	  (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6298   (clobber (reg:CC FLAGS_REG))]
6299  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6300  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6301  [(set_attr "type" "alu")
6302   (set_attr "mode" "<MODE>")])
6303
6304(define_insn "*subsi_1_zext"
6305  [(set (match_operand:DI 0 "register_operand" "=r")
6306	(zero_extend:DI
6307	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6308		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6309   (clobber (reg:CC FLAGS_REG))]
6310  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6311  "sub{l}\t{%2, %k0|%k0, %2}"
6312  [(set_attr "type" "alu")
6313   (set_attr "mode" "SI")])
6314
6315(define_insn "*sub<mode>_1_slp"
6316  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
6317	(minus:SWI12 (match_operand:SWI12 1 "register_operand" "0")
6318		     (match_operand:SWI12 2 "general_operand" "<r>mn")))
6319   (clobber (reg:CC FLAGS_REG))]
6320  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6321   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6322   && rtx_equal_p (operands[0], operands[1])"
6323  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6324  [(set_attr "type" "alu")
6325   (set_attr "mode" "<MODE>")])
6326
6327(define_insn "*sub<mode>_2"
6328  [(set (reg FLAGS_REG)
6329	(compare
6330	  (minus:SWI
6331	    (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6332	    (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6333	  (const_int 0)))
6334   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6335	(minus:SWI (match_dup 1) (match_dup 2)))]
6336  "ix86_match_ccmode (insn, CCGOCmode)
6337   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6338  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6339  [(set_attr "type" "alu")
6340   (set_attr "mode" "<MODE>")])
6341
6342(define_insn "*subsi_2_zext"
6343  [(set (reg FLAGS_REG)
6344	(compare
6345	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6346		    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6347	  (const_int 0)))
6348   (set (match_operand:DI 0 "register_operand" "=r")
6349	(zero_extend:DI
6350	  (minus:SI (match_dup 1)
6351		    (match_dup 2))))]
6352  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6353   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6354  "sub{l}\t{%2, %k0|%k0, %2}"
6355  [(set_attr "type" "alu")
6356   (set_attr "mode" "SI")])
6357
6358;; Subtract with jump on overflow.
6359(define_expand "subv<mode>4"
6360  [(parallel [(set (reg:CCO FLAGS_REG)
6361		   (eq:CCO
6362		     (minus:<DPWI>
6363		       (sign_extend:<DPWI>
6364			 (match_operand:SWIDWI 1 "nonimmediate_operand"))
6365		       (match_dup 4))
6366		     (sign_extend:<DPWI>
6367		       (minus:SWIDWI (match_dup 1)
6368				     (match_operand:SWIDWI 2
6369						"<general_hilo_operand>")))))
6370	      (set (match_operand:SWIDWI 0 "register_operand")
6371		   (minus:SWIDWI (match_dup 1) (match_dup 2)))])
6372   (set (pc) (if_then_else
6373	       (eq (reg:CCO FLAGS_REG) (const_int 0))
6374	       (label_ref (match_operand 3))
6375	       (pc)))]
6376  ""
6377{
6378  ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6379  if (CONST_SCALAR_INT_P (operands[2]))
6380    operands[4] = operands[2];
6381  else
6382    operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
6383})
6384
6385(define_insn "*subv<mode>4"
6386  [(set (reg:CCO FLAGS_REG)
6387	(eq:CCO (minus:<DWI>
6388		   (sign_extend:<DWI>
6389		      (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6390		   (sign_extend:<DWI>
6391		      (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6392		(sign_extend:<DWI>
6393		   (minus:SWI (match_dup 1) (match_dup 2)))))
6394   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6395	(minus:SWI (match_dup 1) (match_dup 2)))]
6396  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6397  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6398  [(set_attr "type" "alu")
6399   (set_attr "mode" "<MODE>")])
6400
6401(define_insn "subv<mode>4_1"
6402  [(set (reg:CCO FLAGS_REG)
6403	(eq:CCO (minus:<DWI>
6404		   (sign_extend:<DWI>
6405		      (match_operand:SWI 1 "nonimmediate_operand" "0"))
6406		   (match_operand:<DWI> 3 "const_int_operand" "i"))
6407		(sign_extend:<DWI>
6408		   (minus:SWI
6409		     (match_dup 1)
6410		     (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6411   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6412	(minus:SWI (match_dup 1) (match_dup 2)))]
6413  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6414   && CONST_INT_P (operands[2])
6415   && INTVAL (operands[2]) == INTVAL (operands[3])"
6416  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6417  [(set_attr "type" "alu")
6418   (set_attr "mode" "<MODE>")
6419   (set (attr "length_immediate")
6420	(cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6421		  (const_string "1")
6422	       (match_test "<MODE_SIZE> == 8")
6423		  (const_string "4")]
6424	      (const_string "<MODE_SIZE>")))])
6425
6426(define_insn_and_split "*subv<dwi>4_doubleword"
6427  [(set (reg:CCO FLAGS_REG)
6428	(eq:CCO
6429	  (minus:<QPWI>
6430	    (sign_extend:<QPWI>
6431	      (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
6432	    (sign_extend:<QPWI>
6433	      (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
6434	  (sign_extend:<QPWI>
6435	    (minus:<DWI> (match_dup 1) (match_dup 2)))))
6436   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6437	(minus:<DWI> (match_dup 1) (match_dup 2)))]
6438  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6439  "#"
6440  "reload_completed"
6441  [(parallel [(set (reg:CC FLAGS_REG)
6442		   (compare:CC (match_dup 1) (match_dup 2)))
6443	      (set (match_dup 0)
6444		   (minus:DWIH (match_dup 1) (match_dup 2)))])
6445   (parallel [(set (reg:CCO FLAGS_REG)
6446		   (eq:CCO
6447		     (minus:<DWI>
6448		       (minus:<DWI>
6449			 (sign_extend:<DWI> (match_dup 4))
6450			 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
6451		       (sign_extend:<DWI> (match_dup 5)))
6452		     (sign_extend:<DWI>
6453		       (minus:DWIH
6454			 (minus:DWIH
6455			   (match_dup 4)
6456			   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6457			 (match_dup 5)))))
6458	      (set (match_dup 3)
6459		   (minus:DWIH
6460		     (minus:DWIH
6461		       (match_dup 4)
6462		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6463		     (match_dup 5)))])]
6464{
6465  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6466})
6467
6468(define_insn_and_split "*subv<dwi>4_doubleword_1"
6469  [(set (reg:CCO FLAGS_REG)
6470	(eq:CCO
6471	  (minus:<QPWI>
6472	    (sign_extend:<QPWI>
6473	      (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
6474	    (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
6475	  (sign_extend:<QPWI>
6476	    (minus:<DWI>
6477	      (match_dup 1)
6478	      (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
6479   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
6480	(minus:<DWI> (match_dup 1) (match_dup 2)))]
6481  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6482   && CONST_SCALAR_INT_P (operands[2])
6483   && rtx_equal_p (operands[2], operands[3])"
6484  "#"
6485  "reload_completed"
6486  [(parallel [(set (reg:CC FLAGS_REG)
6487		   (compare:CC (match_dup 1) (match_dup 2)))
6488	      (set (match_dup 0)
6489		   (minus:DWIH (match_dup 1) (match_dup 2)))])
6490   (parallel [(set (reg:CCO FLAGS_REG)
6491		   (eq:CCO
6492		     (minus:<DWI>
6493		       (minus:<DWI>
6494			 (sign_extend:<DWI> (match_dup 4))
6495			 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
6496		       (match_dup 5))
6497		     (sign_extend:<DWI>
6498		       (minus:DWIH
6499			 (minus:DWIH
6500			   (match_dup 4)
6501			   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6502			 (match_dup 5)))))
6503	      (set (match_dup 3)
6504		   (minus:DWIH
6505		     (minus:DWIH
6506		       (match_dup 4)
6507		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6508		     (match_dup 5)))])]
6509{
6510  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6511  if (operands[2] == const0_rtx)
6512    {
6513      emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
6514				    operands[5]));
6515      DONE;
6516    }
6517})
6518
6519(define_insn "*subv<mode>4_overflow_1"
6520  [(set (reg:CCO FLAGS_REG)
6521	(eq:CCO
6522	  (minus:<DWI>
6523	    (minus:<DWI>
6524	      (sign_extend:<DWI>
6525		(match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6526	      (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6527		[(match_operand 3 "flags_reg_operand") (const_int 0)]))
6528	    (sign_extend:<DWI>
6529	      (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
6530	  (sign_extend:<DWI>
6531	    (minus:SWI
6532	      (minus:SWI
6533		(match_dup 1)
6534		(match_operator:SWI 5 "ix86_carry_flag_operator"
6535		  [(match_dup 3) (const_int 0)]))
6536	      (match_dup 2)))))
6537   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
6538	(minus:SWI
6539	  (minus:SWI
6540	    (match_dup 1)
6541	    (match_op_dup 5 [(match_dup 3) (const_int 0)]))
6542	  (match_dup 2)))]
6543  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6544  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6545  [(set_attr "type" "alu")
6546   (set_attr "mode" "<MODE>")])
6547
6548(define_insn "*subv<mode>4_overflow_2"
6549  [(set (reg:CCO FLAGS_REG)
6550	(eq:CCO
6551	  (minus:<DWI>
6552	    (minus:<DWI>
6553	      (sign_extend:<DWI>
6554		(match_operand:SWI 1 "nonimmediate_operand" "%0"))
6555	      (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6556		[(match_operand 3 "flags_reg_operand") (const_int 0)]))
6557	    (match_operand:<DWI> 6 "const_int_operand" ""))
6558	  (sign_extend:<DWI>
6559	    (minus:SWI
6560	      (minus:SWI
6561		(match_dup 1)
6562		(match_operator:SWI 5 "ix86_carry_flag_operator"
6563		  [(match_dup 3) (const_int 0)]))
6564	      (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
6565   (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
6566	(minus:SWI
6567	  (minus:SWI
6568	    (match_dup 1)
6569	    (match_op_dup 5 [(match_dup 3) (const_int 0)]))
6570	  (match_dup 2)))]
6571  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6572   && CONST_INT_P (operands[2])
6573   && INTVAL (operands[2]) == INTVAL (operands[6])"
6574  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6575  [(set_attr "type" "alu")
6576   (set_attr "mode" "<MODE>")
6577   (set (attr "length_immediate")
6578     (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6579       (const_string "1")
6580       (const_string "4")))])
6581
6582(define_expand "usubv<mode>4"
6583  [(parallel [(set (reg:CC FLAGS_REG)
6584		   (compare:CC
6585		     (match_operand:SWI 1 "nonimmediate_operand")
6586		     (match_operand:SWI 2 "<general_operand>")))
6587	      (set (match_operand:SWI 0 "register_operand")
6588		   (minus:SWI (match_dup 1) (match_dup 2)))])
6589   (set (pc) (if_then_else
6590	       (ltu (reg:CC FLAGS_REG) (const_int 0))
6591	       (label_ref (match_operand 3))
6592	       (pc)))]
6593  ""
6594  "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6595
6596(define_insn "*sub<mode>_3"
6597  [(set (reg FLAGS_REG)
6598	(compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6599		 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6600   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6601	(minus:SWI (match_dup 1) (match_dup 2)))]
6602  "ix86_match_ccmode (insn, CCmode)
6603   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6604  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6605  [(set_attr "type" "alu")
6606   (set_attr "mode" "<MODE>")])
6607
6608(define_peephole2
6609  [(parallel
6610     [(set (reg:CC FLAGS_REG)
6611	   (compare:CC (match_operand:SWI 0 "general_reg_operand")
6612		       (match_operand:SWI 1 "general_gr_operand")))
6613      (set (match_dup 0)
6614	   (minus:SWI (match_dup 0) (match_dup 1)))])]
6615  "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6616  [(set (reg:CC FLAGS_REG)
6617	(compare:CC (match_dup 0) (match_dup 1)))])
6618
6619;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
6620;; subl $1, %eax; jnc .Lxx;
6621(define_peephole2
6622  [(parallel
6623     [(set (match_operand:SWI 0 "general_reg_operand")
6624	   (plus:SWI (match_dup 0) (const_int -1)))
6625      (clobber (reg FLAGS_REG))])
6626   (set (reg:CCZ FLAGS_REG)
6627	(compare:CCZ (match_dup 0) (const_int -1)))
6628   (set (pc)
6629	(if_then_else (match_operator 1 "bt_comparison_operator"
6630			[(reg:CCZ FLAGS_REG) (const_int 0)])
6631		      (match_operand 2)
6632		      (pc)))]
6633   "peep2_regno_dead_p (3, FLAGS_REG)"
6634   [(parallel
6635      [(set (reg:CC FLAGS_REG)
6636	    (compare:CC (match_dup 0) (const_int 1)))
6637       (set (match_dup 0)
6638	    (minus:SWI (match_dup 0) (const_int 1)))])
6639    (set (pc)
6640	 (if_then_else (match_dup 3)
6641		       (match_dup 2)
6642		       (pc)))]
6643{
6644  rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
6645  operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
6646				? GEU : LTU, VOIDmode, cc, const0_rtx);
6647})
6648
6649(define_insn "*subsi_3_zext"
6650  [(set (reg FLAGS_REG)
6651	(compare (match_operand:SI 1 "register_operand" "0")
6652		 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6653   (set (match_operand:DI 0 "register_operand" "=r")
6654	(zero_extend:DI
6655	  (minus:SI (match_dup 1)
6656		    (match_dup 2))))]
6657  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6658   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6659  "sub{l}\t{%2, %1|%1, %2}"
6660  [(set_attr "type" "alu")
6661   (set_attr "mode" "SI")])
6662
6663;; Add with carry and subtract with borrow
6664
6665(define_insn "@add<mode>3_carry"
6666  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6667	(plus:SWI
6668	  (plus:SWI
6669	    (match_operator:SWI 4 "ix86_carry_flag_operator"
6670	     [(match_operand 3 "flags_reg_operand") (const_int 0)])
6671	    (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6672	  (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6673   (clobber (reg:CC FLAGS_REG))]
6674  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6675  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6676  [(set_attr "type" "alu")
6677   (set_attr "use_carry" "1")
6678   (set_attr "pent_pair" "pu")
6679   (set_attr "mode" "<MODE>")])
6680
6681(define_insn "*add<mode>3_carry_0"
6682  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6683	(plus:SWI
6684	  (match_operator:SWI 3 "ix86_carry_flag_operator"
6685	    [(match_operand 2 "flags_reg_operand") (const_int 0)])
6686	  (match_operand:SWI 1 "nonimmediate_operand" "0")))
6687   (clobber (reg:CC FLAGS_REG))]
6688  "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6689  "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6690  [(set_attr "type" "alu")
6691   (set_attr "use_carry" "1")
6692   (set_attr "pent_pair" "pu")
6693   (set_attr "mode" "<MODE>")])
6694
6695(define_insn "*addsi3_carry_zext"
6696  [(set (match_operand:DI 0 "register_operand" "=r")
6697	(zero_extend:DI
6698	  (plus:SI
6699	    (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6700		      [(reg FLAGS_REG) (const_int 0)])
6701		     (match_operand:SI 1 "register_operand" "%0"))
6702	    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6703   (clobber (reg:CC FLAGS_REG))]
6704  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6705  "adc{l}\t{%2, %k0|%k0, %2}"
6706  [(set_attr "type" "alu")
6707   (set_attr "use_carry" "1")
6708   (set_attr "pent_pair" "pu")
6709   (set_attr "mode" "SI")])
6710
6711(define_insn "*addsi3_carry_zext_0"
6712  [(set (match_operand:DI 0 "register_operand" "=r")
6713	(zero_extend:DI
6714	  (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6715		    [(reg FLAGS_REG) (const_int 0)])
6716		   (match_operand:SI 1 "register_operand" "0"))))
6717   (clobber (reg:CC FLAGS_REG))]
6718  "TARGET_64BIT"
6719  "adc{l}\t{$0, %k0|%k0, 0}"
6720  [(set_attr "type" "alu")
6721   (set_attr "use_carry" "1")
6722   (set_attr "pent_pair" "pu")
6723   (set_attr "mode" "SI")])
6724
6725;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6726
6727(define_insn "addcarry<mode>"
6728  [(set (reg:CCC FLAGS_REG)
6729	(compare:CCC
6730	  (zero_extend:<DWI>
6731	    (plus:SWI48
6732	      (plus:SWI48
6733		(match_operator:SWI48 5 "ix86_carry_flag_operator"
6734		  [(match_operand 3 "flags_reg_operand") (const_int 0)])
6735		(match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
6736	      (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
6737	  (plus:<DWI>
6738	    (zero_extend:<DWI> (match_dup 2))
6739	    (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6740	      [(match_dup 3) (const_int 0)]))))
6741   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6742	(plus:SWI48 (plus:SWI48 (match_op_dup 5
6743				 [(match_dup 3) (const_int 0)])
6744				(match_dup 1))
6745		    (match_dup 2)))]
6746  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6747  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6748  [(set_attr "type" "alu")
6749   (set_attr "use_carry" "1")
6750   (set_attr "pent_pair" "pu")
6751   (set_attr "mode" "<MODE>")])
6752
6753(define_expand "addcarry<mode>_0"
6754  [(parallel
6755     [(set (reg:CCC FLAGS_REG)
6756	   (compare:CCC
6757	     (plus:SWI48
6758	       (match_operand:SWI48 1 "nonimmediate_operand")
6759	       (match_operand:SWI48 2 "x86_64_general_operand"))
6760	     (match_dup 1)))
6761      (set (match_operand:SWI48 0 "nonimmediate_operand")
6762	   (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6763  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6764
6765(define_insn "*addcarry<mode>_1"
6766  [(set (reg:CCC FLAGS_REG)
6767	(compare:CCC
6768	  (zero_extend:<DWI>
6769	    (plus:SWI48
6770	      (plus:SWI48
6771		(match_operator:SWI48 5 "ix86_carry_flag_operator"
6772		  [(match_operand 3 "flags_reg_operand") (const_int 0)])
6773		(match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6774	      (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
6775	  (plus:<DWI>
6776	    (match_operand:<DWI> 6 "const_scalar_int_operand" "")
6777	    (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6778	      [(match_dup 3) (const_int 0)]))))
6779   (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
6780	(plus:SWI48 (plus:SWI48 (match_op_dup 5
6781				 [(match_dup 3) (const_int 0)])
6782				(match_dup 1))
6783		    (match_dup 2)))]
6784  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6785   && CONST_INT_P (operands[2])
6786   /* Check that operands[6] is operands[2] zero extended from
6787      <MODE>mode to <DWI>mode.  */
6788   && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
6789       ? (CONST_INT_P (operands[6])
6790	  && UINTVAL (operands[6]) == (UINTVAL (operands[2])
6791				       & GET_MODE_MASK (<MODE>mode)))
6792       : (CONST_WIDE_INT_P (operands[6])
6793	  && CONST_WIDE_INT_NUNITS (operands[6]) == 2
6794	  && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
6795	      == UINTVAL (operands[2]))
6796	  && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
6797  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6798  [(set_attr "type" "alu")
6799   (set_attr "use_carry" "1")
6800   (set_attr "pent_pair" "pu")
6801   (set_attr "mode" "<MODE>")
6802   (set (attr "length_immediate")
6803     (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6804       (const_string "1")
6805       (const_string "4")))])
6806
6807(define_insn "@sub<mode>3_carry"
6808  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6809	(minus:SWI
6810	  (minus:SWI
6811	    (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6812	    (match_operator:SWI 4 "ix86_carry_flag_operator"
6813	     [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6814	  (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6815   (clobber (reg:CC FLAGS_REG))]
6816  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6817  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6818  [(set_attr "type" "alu")
6819   (set_attr "use_carry" "1")
6820   (set_attr "pent_pair" "pu")
6821   (set_attr "mode" "<MODE>")])
6822
6823(define_insn "*sub<mode>3_carry_0"
6824  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6825	(minus:SWI
6826	  (match_operand:SWI 1 "nonimmediate_operand" "0")
6827	  (match_operator:SWI 3 "ix86_carry_flag_operator"
6828	    [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6829   (clobber (reg:CC FLAGS_REG))]
6830  "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6831  "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6832  [(set_attr "type" "alu")
6833   (set_attr "use_carry" "1")
6834   (set_attr "pent_pair" "pu")
6835   (set_attr "mode" "<MODE>")])
6836
6837(define_insn "*subsi3_carry_zext"
6838  [(set (match_operand:DI 0 "register_operand" "=r")
6839	(zero_extend:DI
6840	  (minus:SI
6841	    (minus:SI
6842	      (match_operand:SI 1 "register_operand" "0")
6843	      (match_operator:SI 3 "ix86_carry_flag_operator"
6844	       [(reg FLAGS_REG) (const_int 0)]))
6845	    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6846   (clobber (reg:CC FLAGS_REG))]
6847  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6848  "sbb{l}\t{%2, %k0|%k0, %2}"
6849  [(set_attr "type" "alu")
6850   (set_attr "use_carry" "1")
6851   (set_attr "pent_pair" "pu")
6852   (set_attr "mode" "SI")])
6853
6854(define_insn "*subsi3_carry_zext_0"
6855  [(set (match_operand:DI 0 "register_operand" "=r")
6856	(zero_extend:DI
6857	  (minus:SI
6858	    (match_operand:SI 1 "register_operand" "0")
6859	    (match_operator:SI 2 "ix86_carry_flag_operator"
6860	      [(reg FLAGS_REG) (const_int 0)]))))
6861   (clobber (reg:CC FLAGS_REG))]
6862  "TARGET_64BIT"
6863  "sbb{l}\t{$0, %k0|%k0, 0}"
6864  [(set_attr "type" "alu")
6865   (set_attr "use_carry" "1")
6866   (set_attr "pent_pair" "pu")
6867   (set_attr "mode" "SI")])
6868
6869(define_insn "@sub<mode>3_carry_ccc"
6870  [(set (reg:CCC FLAGS_REG)
6871	(compare:CCC
6872	  (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6873	  (plus:<DWI>
6874	    (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6875	    (zero_extend:<DWI>
6876	      (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6877   (clobber (match_scratch:DWIH 0 "=r"))]
6878  ""
6879  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6880  [(set_attr "type" "alu")
6881   (set_attr "mode" "<MODE>")])
6882
6883(define_insn "*sub<mode>3_carry_ccc_1"
6884  [(set (reg:CCC FLAGS_REG)
6885	(compare:CCC
6886	  (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6887	  (plus:<DWI>
6888	    (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6889	    (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6890   (clobber (match_scratch:DWIH 0 "=r"))]
6891  ""
6892{
6893  operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6894  return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6895}
6896  [(set_attr "type" "alu")
6897   (set_attr "mode" "<MODE>")])
6898
6899;; The sign flag is set from the
6900;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6901;; result, the overflow flag likewise, but the overflow flag is also
6902;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6903(define_insn "@sub<mode>3_carry_ccgz"
6904  [(set (reg:CCGZ FLAGS_REG)
6905	(unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6906		      (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6907		      (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6908		     UNSPEC_SBB))
6909   (clobber (match_scratch:DWIH 0 "=r"))]
6910  ""
6911  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6912  [(set_attr "type" "alu")
6913   (set_attr "mode" "<MODE>")])
6914
6915(define_insn "subborrow<mode>"
6916  [(set (reg:CCC FLAGS_REG)
6917	(compare:CCC
6918	  (zero_extend:<DWI>
6919	    (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6920	  (plus:<DWI>
6921	    (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6922	      [(match_operand 3 "flags_reg_operand") (const_int 0)])
6923	    (zero_extend:<DWI>
6924	      (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6925   (set (match_operand:SWI48 0 "register_operand" "=r")
6926	(minus:SWI48 (minus:SWI48
6927		       (match_dup 1)
6928		       (match_operator:SWI48 5 "ix86_carry_flag_operator"
6929			 [(match_dup 3) (const_int 0)]))
6930		     (match_dup 2)))]
6931  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6932  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6933  [(set_attr "type" "alu")
6934   (set_attr "use_carry" "1")
6935   (set_attr "pent_pair" "pu")
6936   (set_attr "mode" "<MODE>")])
6937
6938(define_expand "subborrow<mode>_0"
6939  [(parallel
6940     [(set (reg:CC FLAGS_REG)
6941	   (compare:CC
6942	     (match_operand:SWI48 1 "nonimmediate_operand")
6943	     (match_operand:SWI48 2 "<general_operand>")))
6944      (set (match_operand:SWI48 0 "register_operand")
6945	   (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6946  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6947
6948;; Overflow setting add instructions
6949
6950(define_expand "addqi3_cconly_overflow"
6951  [(parallel
6952     [(set (reg:CCC FLAGS_REG)
6953	   (compare:CCC
6954	     (plus:QI
6955	       (match_operand:QI 0 "nonimmediate_operand")
6956	       (match_operand:QI 1 "general_operand"))
6957	     (match_dup 0)))
6958      (clobber (match_scratch:QI 2))])]
6959  "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6960
6961(define_insn "*add<mode>3_cconly_overflow_1"
6962  [(set (reg:CCC FLAGS_REG)
6963	(compare:CCC
6964	  (plus:SWI
6965	    (match_operand:SWI 1 "nonimmediate_operand" "%0")
6966	    (match_operand:SWI 2 "<general_operand>" "<g>"))
6967	  (match_dup 1)))
6968   (clobber (match_scratch:SWI 0 "=<r>"))]
6969  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6970  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6971  [(set_attr "type" "alu")
6972   (set_attr "mode" "<MODE>")])
6973
6974(define_insn "*add<mode>3_cc_overflow_1"
6975  [(set (reg:CCC FLAGS_REG)
6976	(compare:CCC
6977	    (plus:SWI
6978		(match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6979		(match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6980	    (match_dup 1)))
6981   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6982	(plus:SWI (match_dup 1) (match_dup 2)))]
6983  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6984  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6985  [(set_attr "type" "alu")
6986   (set_attr "mode" "<MODE>")])
6987
6988(define_insn "*addsi3_zext_cc_overflow_1"
6989  [(set (reg:CCC FLAGS_REG)
6990	(compare:CCC
6991	  (plus:SI
6992	    (match_operand:SI 1 "nonimmediate_operand" "%0")
6993	    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6994	  (match_dup 1)))
6995   (set (match_operand:DI 0 "register_operand" "=r")
6996	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6997  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6998  "add{l}\t{%2, %k0|%k0, %2}"
6999  [(set_attr "type" "alu")
7000   (set_attr "mode" "SI")])
7001
7002(define_insn "*add<mode>3_cconly_overflow_2"
7003  [(set (reg:CCC FLAGS_REG)
7004	(compare:CCC
7005	  (plus:SWI
7006	    (match_operand:SWI 1 "nonimmediate_operand" "%0")
7007	    (match_operand:SWI 2 "<general_operand>" "<g>"))
7008	  (match_dup 2)))
7009   (clobber (match_scratch:SWI 0 "=<r>"))]
7010  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7011  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7012  [(set_attr "type" "alu")
7013   (set_attr "mode" "<MODE>")])
7014
7015(define_insn "*add<mode>3_cc_overflow_2"
7016  [(set (reg:CCC FLAGS_REG)
7017	(compare:CCC
7018	    (plus:SWI
7019		(match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7020		(match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
7021	    (match_dup 2)))
7022   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7023	(plus:SWI (match_dup 1) (match_dup 2)))]
7024  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7025  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7026  [(set_attr "type" "alu")
7027   (set_attr "mode" "<MODE>")])
7028
7029(define_insn "*addsi3_zext_cc_overflow_2"
7030  [(set (reg:CCC FLAGS_REG)
7031	(compare:CCC
7032	  (plus:SI
7033	    (match_operand:SI 1 "nonimmediate_operand" "%0")
7034	    (match_operand:SI 2 "x86_64_general_operand" "rme"))
7035	  (match_dup 2)))
7036   (set (match_operand:DI 0 "register_operand" "=r")
7037	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7038  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7039  "add{l}\t{%2, %k0|%k0, %2}"
7040  [(set_attr "type" "alu")
7041   (set_attr "mode" "SI")])
7042
7043(define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
7044  [(set (reg:CCC FLAGS_REG)
7045	(compare:CCC
7046	  (plus:<DWI>
7047	    (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
7048	    (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
7049	  (match_dup 1)))
7050   (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7051	(plus:<DWI> (match_dup 1) (match_dup 2)))]
7052  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7053  "#"
7054  "reload_completed"
7055  [(parallel [(set (reg:CCC FLAGS_REG)
7056		   (compare:CCC
7057		     (plus:DWIH (match_dup 1) (match_dup 2))
7058		     (match_dup 1)))
7059	      (set (match_dup 0)
7060		   (plus:DWIH (match_dup 1) (match_dup 2)))])
7061   (parallel [(set (reg:CCC FLAGS_REG)
7062		   (compare:CCC
7063		     (zero_extend:<DWI>
7064		       (plus:DWIH
7065			 (plus:DWIH
7066			   (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7067			   (match_dup 4))
7068			 (match_dup 5)))
7069		     (plus:<DWI>
7070		       (match_dup 6)
7071		       (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
7072	      (set (match_dup 3)
7073		   (plus:DWIH
7074		     (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7075				(match_dup 4))
7076		     (match_dup 5)))])]
7077{
7078  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7079  if (operands[2] == const0_rtx)
7080    {
7081      emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
7082      DONE;
7083    }
7084  if (CONST_INT_P (operands[5]))
7085    operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
7086					    operands[5], <MODE>mode);
7087  else
7088    operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
7089})
7090
7091;; x == 0 with zero flag test can be done also as x < 1U with carry flag
7092;; test, where the latter is preferrable if we have some carry consuming
7093;; instruction.
7094;; For x != 0, we need to use x < 1U with negation of carry, i.e.
7095;; + (1 - CF).
7096(define_insn_and_split "*add<mode>3_eq"
7097  [(set (match_operand:SWI 0 "nonimmediate_operand")
7098	(plus:SWI
7099	  (plus:SWI
7100	    (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
7101	    (match_operand:SWI 1 "nonimmediate_operand"))
7102	  (match_operand:SWI 2 "<general_operand>")))
7103   (clobber (reg:CC FLAGS_REG))]
7104  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7105   && ix86_pre_reload_split ()"
7106  "#"
7107  "&& 1"
7108  [(set (reg:CC FLAGS_REG)
7109	(compare:CC (match_dup 3) (const_int 1)))
7110   (parallel [(set (match_dup 0)
7111		   (plus:SWI
7112		     (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7113			       (match_dup 1))
7114		     (match_dup 2)))
7115	      (clobber (reg:CC FLAGS_REG))])])
7116
7117(define_insn_and_split "*add<mode>3_ne"
7118  [(set (match_operand:SWI 0 "nonimmediate_operand")
7119	(plus:SWI
7120	  (plus:SWI
7121	    (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
7122	    (match_operand:SWI 1 "nonimmediate_operand"))
7123	  (match_operand:SWI 2 "<immediate_operand>")))
7124   (clobber (reg:CC FLAGS_REG))]
7125  "CONST_INT_P (operands[2])
7126   && (<MODE>mode != DImode
7127       || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7128   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7129   && ix86_pre_reload_split ()"
7130  "#"
7131  "&& 1"
7132  [(set (reg:CC FLAGS_REG)
7133	(compare:CC (match_dup 3) (const_int 1)))
7134   (parallel [(set (match_dup 0)
7135		   (minus:SWI
7136		     (minus:SWI (match_dup 1)
7137				(ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7138		     (match_dup 2)))
7139	      (clobber (reg:CC FLAGS_REG))])]
7140{
7141  operands[2] = gen_int_mode (~INTVAL (operands[2]),
7142			      <MODE>mode == DImode ? SImode : <MODE>mode);
7143})
7144
7145(define_insn_and_split "*add<mode>3_eq_0"
7146  [(set (match_operand:SWI 0 "nonimmediate_operand")
7147	(plus:SWI
7148	  (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
7149	  (match_operand:SWI 1 "<general_operand>")))
7150   (clobber (reg:CC FLAGS_REG))]
7151  "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
7152   && ix86_pre_reload_split ()"
7153  "#"
7154  "&& 1"
7155  [(set (reg:CC FLAGS_REG)
7156	(compare:CC (match_dup 2) (const_int 1)))
7157   (parallel [(set (match_dup 0)
7158		   (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7159			     (match_dup 1)))
7160	      (clobber (reg:CC FLAGS_REG))])]
7161{
7162  if (!nonimmediate_operand (operands[1], <MODE>mode))
7163    operands[1] = force_reg (<MODE>mode, operands[1]);
7164})
7165
7166(define_insn_and_split "*add<mode>3_ne_0"
7167  [(set (match_operand:SWI 0 "nonimmediate_operand")
7168	(plus:SWI
7169	  (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
7170	  (match_operand:SWI 1 "<general_operand>")))
7171   (clobber (reg:CC FLAGS_REG))]
7172  "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
7173   && ix86_pre_reload_split ()"
7174  "#"
7175  "&& 1"
7176  [(set (reg:CC FLAGS_REG)
7177	(compare:CC (match_dup 2) (const_int 1)))
7178   (parallel [(set (match_dup 0)
7179		   (minus:SWI (minus:SWI
7180				(match_dup 1)
7181				(ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7182			      (const_int -1)))
7183	      (clobber (reg:CC FLAGS_REG))])]
7184{
7185  if (!nonimmediate_operand (operands[1], <MODE>mode))
7186    operands[1] = force_reg (<MODE>mode, operands[1]);
7187})
7188
7189(define_insn_and_split "*sub<mode>3_eq"
7190  [(set (match_operand:SWI 0 "nonimmediate_operand")
7191	(minus:SWI
7192	  (minus:SWI
7193	    (match_operand:SWI 1 "nonimmediate_operand")
7194	    (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7195		    (const_int 0)))
7196	  (match_operand:SWI 2 "<general_operand>")))
7197   (clobber (reg:CC FLAGS_REG))]
7198  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7199   && ix86_pre_reload_split ()"
7200  "#"
7201  "&& 1"
7202  [(set (reg:CC FLAGS_REG)
7203	(compare:CC (match_dup 3) (const_int 1)))
7204   (parallel [(set (match_dup 0)
7205		   (minus:SWI
7206		     (minus:SWI (match_dup 1)
7207				(ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7208		     (match_dup 2)))
7209	      (clobber (reg:CC FLAGS_REG))])])
7210
7211(define_insn_and_split "*sub<mode>3_ne"
7212  [(set (match_operand:SWI 0 "nonimmediate_operand")
7213	(plus:SWI
7214	  (minus:SWI
7215	    (match_operand:SWI 1 "nonimmediate_operand")
7216	    (ne:SWI (match_operand 3 "int_nonimmediate_operand")
7217		    (const_int 0)))
7218	  (match_operand:SWI 2 "<immediate_operand>")))
7219   (clobber (reg:CC FLAGS_REG))]
7220  "CONST_INT_P (operands[2])
7221   && (<MODE>mode != DImode
7222       || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7223   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7224   && ix86_pre_reload_split ()"
7225  "#"
7226  "&& 1"
7227  [(set (reg:CC FLAGS_REG)
7228	(compare:CC (match_dup 3) (const_int 1)))
7229   (parallel [(set (match_dup 0)
7230		   (plus:SWI
7231		     (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7232			       (match_dup 1))
7233		     (match_dup 2)))
7234	      (clobber (reg:CC FLAGS_REG))])]
7235{
7236  operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
7237			      <MODE>mode == DImode ? SImode : <MODE>mode);
7238})
7239
7240(define_insn_and_split "*sub<mode>3_eq_1"
7241  [(set (match_operand:SWI 0 "nonimmediate_operand")
7242	(plus:SWI
7243	  (minus:SWI
7244	    (match_operand:SWI 1 "nonimmediate_operand")
7245	    (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7246		    (const_int 0)))
7247	  (match_operand:SWI 2 "<immediate_operand>")))
7248   (clobber (reg:CC FLAGS_REG))]
7249  "CONST_INT_P (operands[2])
7250   && (<MODE>mode != DImode
7251       || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7252   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7253   && ix86_pre_reload_split ()"
7254  "#"
7255  "&& 1"
7256  [(set (reg:CC FLAGS_REG)
7257	(compare:CC (match_dup 3) (const_int 1)))
7258   (parallel [(set (match_dup 0)
7259		   (minus:SWI
7260		     (minus:SWI (match_dup 1)
7261				(ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7262		     (match_dup 2)))
7263	      (clobber (reg:CC FLAGS_REG))])]
7264{
7265  operands[2] = gen_int_mode (-INTVAL (operands[2]),
7266			      <MODE>mode == DImode ? SImode : <MODE>mode);
7267})
7268
7269(define_insn_and_split "*sub<mode>3_eq_0"
7270  [(set (match_operand:SWI 0 "nonimmediate_operand")
7271	(minus:SWI
7272	  (match_operand:SWI 1 "<general_operand>")
7273	  (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7274   (clobber (reg:CC FLAGS_REG))]
7275  "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7276   && ix86_pre_reload_split ()"
7277  "#"
7278  "&& 1"
7279  [(set (reg:CC FLAGS_REG)
7280	(compare:CC (match_dup 2) (const_int 1)))
7281   (parallel [(set (match_dup 0)
7282		   (minus:SWI (match_dup 1)
7283			      (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
7284	      (clobber (reg:CC FLAGS_REG))])]
7285{
7286  if (!nonimmediate_operand (operands[1], <MODE>mode))
7287    operands[1] = force_reg (<MODE>mode, operands[1]);
7288})
7289
7290(define_insn_and_split "*sub<mode>3_ne_0"
7291  [(set (match_operand:SWI 0 "nonimmediate_operand")
7292	(minus:SWI
7293	  (match_operand:SWI 1 "<general_operand>")
7294	  (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7295   (clobber (reg:CC FLAGS_REG))]
7296  "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7297   && ix86_pre_reload_split ()"
7298  "#"
7299  "&& 1"
7300  [(set (reg:CC FLAGS_REG)
7301	(compare:CC (match_dup 2) (const_int 1)))
7302   (parallel [(set (match_dup 0)
7303		   (plus:SWI (plus:SWI
7304			       (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7305			       (match_dup 1))
7306			     (const_int -1)))
7307	      (clobber (reg:CC FLAGS_REG))])]
7308{
7309  if (!nonimmediate_operand (operands[1], <MODE>mode))
7310    operands[1] = force_reg (<MODE>mode, operands[1]);
7311})
7312
7313;; The patterns that match these are at the end of this file.
7314
7315(define_expand "<plusminus_insn>xf3"
7316  [(set (match_operand:XF 0 "register_operand")
7317	(plusminus:XF
7318	  (match_operand:XF 1 "register_operand")
7319	  (match_operand:XF 2 "register_operand")))]
7320  "TARGET_80387")
7321
7322(define_expand "<plusminus_insn><mode>3"
7323  [(set (match_operand:MODEF 0 "register_operand")
7324	(plusminus:MODEF
7325	  (match_operand:MODEF 1 "register_operand")
7326	  (match_operand:MODEF 2 "nonimmediate_operand")))]
7327  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7328    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7329
7330;; Multiply instructions
7331
7332(define_expand "mul<mode>3"
7333  [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7334		   (mult:SWIM248
7335		     (match_operand:SWIM248 1 "register_operand")
7336		     (match_operand:SWIM248 2 "<general_operand>")))
7337	      (clobber (reg:CC FLAGS_REG))])])
7338
7339(define_expand "mulqi3"
7340  [(parallel [(set (match_operand:QI 0 "register_operand")
7341		   (mult:QI
7342		     (match_operand:QI 1 "register_operand")
7343		     (match_operand:QI 2 "nonimmediate_operand")))
7344	      (clobber (reg:CC FLAGS_REG))])]
7345  "TARGET_QIMODE_MATH")
7346
7347;; On AMDFAM10
7348;; IMUL reg32/64, reg32/64, imm8 	Direct
7349;; IMUL reg32/64, mem32/64, imm8 	VectorPath
7350;; IMUL reg32/64, reg32/64, imm32 	Direct
7351;; IMUL reg32/64, mem32/64, imm32 	VectorPath
7352;; IMUL reg32/64, reg32/64 		Direct
7353;; IMUL reg32/64, mem32/64 		Direct
7354;;
7355;; On BDVER1, all above IMULs use DirectPath
7356;;
7357;; On AMDFAM10
7358;; IMUL reg16, reg16, imm8 	VectorPath
7359;; IMUL reg16, mem16, imm8 	VectorPath
7360;; IMUL reg16, reg16, imm16 	VectorPath
7361;; IMUL reg16, mem16, imm16 	VectorPath
7362;; IMUL reg16, reg16 		Direct
7363;; IMUL reg16, mem16 		Direct
7364;;
7365;; On BDVER1, all HI MULs use DoublePath
7366
7367(define_insn "*mul<mode>3_1"
7368  [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7369	(mult:SWIM248
7370	  (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7371	  (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7372   (clobber (reg:CC FLAGS_REG))]
7373  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374  "@
7375   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7376   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7377   imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7378  [(set_attr "type" "imul")
7379   (set_attr "prefix_0f" "0,0,1")
7380   (set (attr "athlon_decode")
7381	(cond [(eq_attr "cpu" "athlon")
7382		  (const_string "vector")
7383	       (eq_attr "alternative" "1")
7384		  (const_string "vector")
7385	       (and (eq_attr "alternative" "2")
7386	       	    (ior (match_test "<MODE>mode == HImode")
7387		         (match_operand 1 "memory_operand")))
7388		  (const_string "vector")]
7389	      (const_string "direct")))
7390   (set (attr "amdfam10_decode")
7391	(cond [(and (eq_attr "alternative" "0,1")
7392	      	    (ior (match_test "<MODE>mode == HImode")
7393		         (match_operand 1 "memory_operand")))
7394		  (const_string "vector")]
7395	      (const_string "direct")))
7396   (set (attr "bdver1_decode")
7397   	(if_then_else
7398	  (match_test "<MODE>mode == HImode")
7399	    (const_string "double")
7400	    (const_string "direct")))
7401   (set_attr "mode" "<MODE>")])
7402
7403(define_insn "*mulsi3_1_zext"
7404  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7405	(zero_extend:DI
7406	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7407		   (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7408   (clobber (reg:CC FLAGS_REG))]
7409  "TARGET_64BIT
7410   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7411  "@
7412   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7413   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7414   imul{l}\t{%2, %k0|%k0, %2}"
7415  [(set_attr "type" "imul")
7416   (set_attr "prefix_0f" "0,0,1")
7417   (set (attr "athlon_decode")
7418	(cond [(eq_attr "cpu" "athlon")
7419		  (const_string "vector")
7420	       (eq_attr "alternative" "1")
7421		  (const_string "vector")
7422	       (and (eq_attr "alternative" "2")
7423		    (match_operand 1 "memory_operand"))
7424		  (const_string "vector")]
7425	      (const_string "direct")))
7426   (set (attr "amdfam10_decode")
7427	(cond [(and (eq_attr "alternative" "0,1")
7428		    (match_operand 1 "memory_operand"))
7429		  (const_string "vector")]
7430	      (const_string "direct")))
7431   (set_attr "bdver1_decode" "direct")
7432   (set_attr "mode" "SI")])
7433
7434;;On AMDFAM10 and BDVER1
7435;; MUL reg8 	Direct
7436;; MUL mem8 	Direct
7437
7438(define_insn "*mulqi3_1"
7439  [(set (match_operand:QI 0 "register_operand" "=a")
7440	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7441		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7442   (clobber (reg:CC FLAGS_REG))]
7443  "TARGET_QIMODE_MATH
7444   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7445  "mul{b}\t%2"
7446  [(set_attr "type" "imul")
7447   (set_attr "length_immediate" "0")
7448   (set (attr "athlon_decode")
7449     (if_then_else (eq_attr "cpu" "athlon")
7450        (const_string "vector")
7451        (const_string "direct")))
7452   (set_attr "amdfam10_decode" "direct")
7453   (set_attr "bdver1_decode" "direct")
7454   (set_attr "mode" "QI")])
7455
7456;; Multiply with jump on overflow.
7457(define_expand "mulv<mode>4"
7458  [(parallel [(set (reg:CCO FLAGS_REG)
7459		   (eq:CCO (mult:<DWI>
7460			      (sign_extend:<DWI>
7461				 (match_operand:SWI248 1 "register_operand"))
7462			      (match_dup 4))
7463			   (sign_extend:<DWI>
7464			      (mult:SWI248 (match_dup 1)
7465					   (match_operand:SWI248 2
7466					      "<general_operand>")))))
7467	      (set (match_operand:SWI248 0 "register_operand")
7468		   (mult:SWI248 (match_dup 1) (match_dup 2)))])
7469   (set (pc) (if_then_else
7470	       (eq (reg:CCO FLAGS_REG) (const_int 0))
7471	       (label_ref (match_operand 3))
7472	       (pc)))]
7473  ""
7474{
7475  if (CONST_INT_P (operands[2]))
7476    operands[4] = operands[2];
7477  else
7478    operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7479})
7480
7481(define_insn "*mulv<mode>4"
7482  [(set (reg:CCO FLAGS_REG)
7483	(eq:CCO (mult:<DWI>
7484		   (sign_extend:<DWI>
7485		      (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7486		   (sign_extend:<DWI>
7487		      (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7488		(sign_extend:<DWI>
7489		   (mult:SWI48 (match_dup 1) (match_dup 2)))))
7490   (set (match_operand:SWI48 0 "register_operand" "=r,r")
7491	(mult:SWI48 (match_dup 1) (match_dup 2)))]
7492  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7493  "@
7494   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7495   imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7496  [(set_attr "type" "imul")
7497   (set_attr "prefix_0f" "0,1")
7498   (set (attr "athlon_decode")
7499	(cond [(eq_attr "cpu" "athlon")
7500		  (const_string "vector")
7501	       (eq_attr "alternative" "0")
7502		  (const_string "vector")
7503	       (and (eq_attr "alternative" "1")
7504		    (match_operand 1 "memory_operand"))
7505		  (const_string "vector")]
7506	      (const_string "direct")))
7507   (set (attr "amdfam10_decode")
7508	(cond [(and (eq_attr "alternative" "1")
7509		    (match_operand 1 "memory_operand"))
7510		  (const_string "vector")]
7511	      (const_string "direct")))
7512   (set_attr "bdver1_decode" "direct")
7513   (set_attr "mode" "<MODE>")])
7514
7515(define_insn "*mulvhi4"
7516  [(set (reg:CCO FLAGS_REG)
7517	(eq:CCO (mult:SI
7518		   (sign_extend:SI
7519		      (match_operand:HI 1 "nonimmediate_operand" "%0"))
7520		   (sign_extend:SI
7521		      (match_operand:HI 2 "nonimmediate_operand" "mr")))
7522		(sign_extend:SI
7523		   (mult:HI (match_dup 1) (match_dup 2)))))
7524   (set (match_operand:HI 0 "register_operand" "=r")
7525	(mult:HI (match_dup 1) (match_dup 2)))]
7526  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7527  "imul{w}\t{%2, %0|%0, %2}"
7528  [(set_attr "type" "imul")
7529   (set_attr "prefix_0f" "1")
7530   (set_attr "athlon_decode" "vector")
7531   (set_attr "amdfam10_decode" "direct")
7532   (set_attr "bdver1_decode" "double")
7533   (set_attr "mode" "HI")])
7534
7535(define_insn "*mulv<mode>4_1"
7536  [(set (reg:CCO FLAGS_REG)
7537	(eq:CCO (mult:<DWI>
7538		   (sign_extend:<DWI>
7539		      (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7540		   (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7541		(sign_extend:<DWI>
7542		   (mult:SWI248 (match_dup 1)
7543				(match_operand:SWI248 2
7544				   "<immediate_operand>" "K,<i>")))))
7545   (set (match_operand:SWI248 0 "register_operand" "=r,r")
7546	(mult:SWI248 (match_dup 1) (match_dup 2)))]
7547  "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7548   && CONST_INT_P (operands[2])
7549   && INTVAL (operands[2]) == INTVAL (operands[3])"
7550  "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7551  [(set_attr "type" "imul")
7552   (set (attr "prefix_0f")
7553   	(if_then_else
7554	  (match_test "<MODE>mode == HImode")
7555	    (const_string "0")
7556	    (const_string "*")))
7557   (set (attr "athlon_decode")
7558	(cond [(eq_attr "cpu" "athlon")
7559		  (const_string "vector")
7560	       (eq_attr "alternative" "1")
7561		  (const_string "vector")]
7562	      (const_string "direct")))
7563   (set (attr "amdfam10_decode")
7564	(cond [(ior (match_test "<MODE>mode == HImode")
7565		    (match_operand 1 "memory_operand"))
7566		  (const_string "vector")]
7567	      (const_string "direct")))
7568   (set (attr "bdver1_decode")
7569   	(if_then_else
7570	  (match_test "<MODE>mode == HImode")
7571	    (const_string "double")
7572	    (const_string "direct")))
7573   (set_attr "mode" "<MODE>")
7574   (set (attr "length_immediate")
7575	(cond [(eq_attr "alternative" "0")
7576		  (const_string "1")
7577	       (match_test "<MODE_SIZE> == 8")
7578		  (const_string "4")]
7579	      (const_string "<MODE_SIZE>")))])
7580
7581(define_expand "umulv<mode>4"
7582  [(parallel [(set (reg:CCO FLAGS_REG)
7583		   (eq:CCO (mult:<DWI>
7584			      (zero_extend:<DWI>
7585				 (match_operand:SWI248 1
7586						      "nonimmediate_operand"))
7587			      (zero_extend:<DWI>
7588				 (match_operand:SWI248 2
7589						      "nonimmediate_operand")))
7590			   (zero_extend:<DWI>
7591			      (mult:SWI248 (match_dup 1) (match_dup 2)))))
7592	      (set (match_operand:SWI248 0 "register_operand")
7593		   (mult:SWI248 (match_dup 1) (match_dup 2)))
7594	      (clobber (match_scratch:SWI248 4))])
7595   (set (pc) (if_then_else
7596	       (eq (reg:CCO FLAGS_REG) (const_int 0))
7597	       (label_ref (match_operand 3))
7598	       (pc)))]
7599  ""
7600{
7601  if (MEM_P (operands[1]) && MEM_P (operands[2]))
7602    operands[1] = force_reg (<MODE>mode, operands[1]);
7603})
7604
7605(define_insn "*umulv<mode>4"
7606  [(set (reg:CCO FLAGS_REG)
7607	(eq:CCO (mult:<DWI>
7608		   (zero_extend:<DWI>
7609		      (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7610		   (zero_extend:<DWI>
7611		      (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7612		(zero_extend:<DWI>
7613		   (mult:SWI248 (match_dup 1) (match_dup 2)))))
7614   (set (match_operand:SWI248 0 "register_operand" "=a")
7615	(mult:SWI248 (match_dup 1) (match_dup 2)))
7616   (clobber (match_scratch:SWI248 3 "=d"))]
7617  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7618  "mul{<imodesuffix>}\t%2"
7619  [(set_attr "type" "imul")
7620   (set_attr "length_immediate" "0")
7621   (set (attr "athlon_decode")
7622     (if_then_else (eq_attr "cpu" "athlon")
7623       (const_string "vector")
7624       (const_string "double")))
7625   (set_attr "amdfam10_decode" "double")
7626   (set_attr "bdver1_decode" "direct")
7627   (set_attr "mode" "<MODE>")])
7628
7629(define_expand "<u>mulvqi4"
7630  [(parallel [(set (reg:CCO FLAGS_REG)
7631		   (eq:CCO (mult:HI
7632			      (any_extend:HI
7633				 (match_operand:QI 1 "nonimmediate_operand"))
7634			      (any_extend:HI
7635				 (match_operand:QI 2 "nonimmediate_operand")))
7636			   (any_extend:HI
7637			      (mult:QI (match_dup 1) (match_dup 2)))))
7638	      (set (match_operand:QI 0 "register_operand")
7639		   (mult:QI (match_dup 1) (match_dup 2)))])
7640   (set (pc) (if_then_else
7641	       (eq (reg:CCO FLAGS_REG) (const_int 0))
7642	       (label_ref (match_operand 3))
7643	       (pc)))]
7644  "TARGET_QIMODE_MATH"
7645{
7646  if (MEM_P (operands[1]) && MEM_P (operands[2]))
7647    operands[1] = force_reg (QImode, operands[1]);
7648})
7649
7650(define_insn "*<u>mulvqi4"
7651  [(set (reg:CCO FLAGS_REG)
7652	(eq:CCO (mult:HI
7653		   (any_extend:HI
7654		      (match_operand:QI 1 "nonimmediate_operand" "%0"))
7655		   (any_extend:HI
7656		      (match_operand:QI 2 "nonimmediate_operand" "qm")))
7657		(any_extend:HI
7658		   (mult:QI (match_dup 1) (match_dup 2)))))
7659   (set (match_operand:QI 0 "register_operand" "=a")
7660	(mult:QI (match_dup 1) (match_dup 2)))]
7661  "TARGET_QIMODE_MATH
7662   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663  "<sgnprefix>mul{b}\t%2"
7664  [(set_attr "type" "imul")
7665   (set_attr "length_immediate" "0")
7666   (set (attr "athlon_decode")
7667     (if_then_else (eq_attr "cpu" "athlon")
7668	(const_string "vector")
7669	(const_string "direct")))
7670   (set_attr "amdfam10_decode" "direct")
7671   (set_attr "bdver1_decode" "direct")
7672   (set_attr "mode" "QI")])
7673
7674(define_expand "<u>mul<mode><dwi>3"
7675  [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7676		   (mult:<DWI>
7677		     (any_extend:<DWI>
7678		       (match_operand:DWIH 1 "nonimmediate_operand"))
7679		     (any_extend:<DWI>
7680		       (match_operand:DWIH 2 "register_operand"))))
7681	      (clobber (reg:CC FLAGS_REG))])])
7682
7683(define_expand "<u>mulqihi3"
7684  [(parallel [(set (match_operand:HI 0 "register_operand")
7685		   (mult:HI
7686		     (any_extend:HI
7687		       (match_operand:QI 1 "nonimmediate_operand"))
7688		     (any_extend:HI
7689		       (match_operand:QI 2 "register_operand"))))
7690	      (clobber (reg:CC FLAGS_REG))])]
7691  "TARGET_QIMODE_MATH")
7692
7693(define_insn "*bmi2_umul<mode><dwi>3_1"
7694  [(set (match_operand:DWIH 0 "register_operand" "=r")
7695	(mult:DWIH
7696	  (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7697	  (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7698   (set (match_operand:DWIH 1 "register_operand" "=r")
7699	(truncate:DWIH
7700	  (lshiftrt:<DWI>
7701	    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7702			(zero_extend:<DWI> (match_dup 3)))
7703	    (match_operand:QI 4 "const_int_operand" "n"))))]
7704  "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7705   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7706  "mulx\t{%3, %0, %1|%1, %0, %3}"
7707  [(set_attr "type" "imulx")
7708   (set_attr "prefix" "vex")
7709   (set_attr "mode" "<MODE>")])
7710
7711(define_insn "*umul<mode><dwi>3_1"
7712  [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7713	(mult:<DWI>
7714	  (zero_extend:<DWI>
7715	    (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7716	  (zero_extend:<DWI>
7717	    (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7718   (clobber (reg:CC FLAGS_REG))]
7719  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7720  "@
7721   #
7722   mul{<imodesuffix>}\t%2"
7723  [(set_attr "isa" "bmi2,*")
7724   (set_attr "type" "imulx,imul")
7725   (set_attr "length_immediate" "*,0")
7726   (set (attr "athlon_decode")
7727	(cond [(eq_attr "alternative" "1")
7728		 (if_then_else (eq_attr "cpu" "athlon")
7729		   (const_string "vector")
7730		   (const_string "double"))]
7731	      (const_string "*")))
7732   (set_attr "amdfam10_decode" "*,double")
7733   (set_attr "bdver1_decode" "*,direct")
7734   (set_attr "prefix" "vex,orig")
7735   (set_attr "mode" "<MODE>")])
7736
7737;; Convert mul to the mulx pattern to avoid flags dependency.
7738(define_split
7739 [(set (match_operand:<DWI> 0 "register_operand")
7740       (mult:<DWI>
7741	 (zero_extend:<DWI>
7742	   (match_operand:DWIH 1 "register_operand"))
7743	 (zero_extend:<DWI>
7744	   (match_operand:DWIH 2 "nonimmediate_operand"))))
7745  (clobber (reg:CC FLAGS_REG))]
7746 "TARGET_BMI2 && reload_completed
7747  && REGNO (operands[1]) == DX_REG"
7748  [(parallel [(set (match_dup 3)
7749		   (mult:DWIH (match_dup 1) (match_dup 2)))
7750	      (set (match_dup 4)
7751		   (truncate:DWIH
7752		     (lshiftrt:<DWI>
7753		       (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7754				   (zero_extend:<DWI> (match_dup 2)))
7755		       (match_dup 5))))])]
7756{
7757  split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7758
7759  operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7760})
7761
7762(define_insn "*mul<mode><dwi>3_1"
7763  [(set (match_operand:<DWI> 0 "register_operand" "=A")
7764	(mult:<DWI>
7765	  (sign_extend:<DWI>
7766	    (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7767	  (sign_extend:<DWI>
7768	    (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7769   (clobber (reg:CC FLAGS_REG))]
7770  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7771  "imul{<imodesuffix>}\t%2"
7772  [(set_attr "type" "imul")
7773   (set_attr "length_immediate" "0")
7774   (set (attr "athlon_decode")
7775     (if_then_else (eq_attr "cpu" "athlon")
7776        (const_string "vector")
7777        (const_string "double")))
7778   (set_attr "amdfam10_decode" "double")
7779   (set_attr "bdver1_decode" "direct")
7780   (set_attr "mode" "<MODE>")])
7781
7782(define_insn "*<u>mulqihi3_1"
7783  [(set (match_operand:HI 0 "register_operand" "=a")
7784	(mult:HI
7785	  (any_extend:HI
7786	    (match_operand:QI 1 "nonimmediate_operand" "%0"))
7787	  (any_extend:HI
7788	    (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7789   (clobber (reg:CC FLAGS_REG))]
7790  "TARGET_QIMODE_MATH
7791   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7792  "<sgnprefix>mul{b}\t%2"
7793  [(set_attr "type" "imul")
7794   (set_attr "length_immediate" "0")
7795   (set (attr "athlon_decode")
7796     (if_then_else (eq_attr "cpu" "athlon")
7797        (const_string "vector")
7798        (const_string "direct")))
7799   (set_attr "amdfam10_decode" "direct")
7800   (set_attr "bdver1_decode" "direct")
7801   (set_attr "mode" "QI")])
7802
7803(define_expand "<s>mul<mode>3_highpart"
7804  [(parallel [(set (match_operand:DWIH 0 "register_operand")
7805		   (truncate:DWIH
7806		     (lshiftrt:<DWI>
7807		       (mult:<DWI>
7808			 (any_extend:<DWI>
7809			   (match_operand:DWIH 1 "nonimmediate_operand"))
7810			 (any_extend:<DWI>
7811			   (match_operand:DWIH 2 "register_operand")))
7812		       (match_dup 3))))
7813	      (clobber (match_scratch:DWIH 4))
7814	      (clobber (reg:CC FLAGS_REG))])]
7815  ""
7816  "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7817
7818(define_insn "*<s>muldi3_highpart_1"
7819  [(set (match_operand:DI 0 "register_operand" "=d")
7820	(truncate:DI
7821	  (lshiftrt:TI
7822	    (mult:TI
7823	      (any_extend:TI
7824		(match_operand:DI 1 "nonimmediate_operand" "%a"))
7825	      (any_extend:TI
7826		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7827	    (const_int 64))))
7828   (clobber (match_scratch:DI 3 "=1"))
7829   (clobber (reg:CC FLAGS_REG))]
7830  "TARGET_64BIT
7831   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7832  "<sgnprefix>mul{q}\t%2"
7833  [(set_attr "type" "imul")
7834   (set_attr "length_immediate" "0")
7835   (set (attr "athlon_decode")
7836     (if_then_else (eq_attr "cpu" "athlon")
7837        (const_string "vector")
7838        (const_string "double")))
7839   (set_attr "amdfam10_decode" "double")
7840   (set_attr "bdver1_decode" "direct")
7841   (set_attr "mode" "DI")])
7842
7843(define_insn "*<s>mulsi3_highpart_zext"
7844  [(set (match_operand:DI 0 "register_operand" "=d")
7845	(zero_extend:DI (truncate:SI
7846	  (lshiftrt:DI
7847	    (mult:DI (any_extend:DI
7848		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7849		     (any_extend:DI
7850		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7851	    (const_int 32)))))
7852   (clobber (match_scratch:SI 3 "=1"))
7853   (clobber (reg:CC FLAGS_REG))]
7854  "TARGET_64BIT
7855   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7856  "<sgnprefix>mul{l}\t%2"
7857  [(set_attr "type" "imul")
7858   (set_attr "length_immediate" "0")
7859   (set (attr "athlon_decode")
7860     (if_then_else (eq_attr "cpu" "athlon")
7861        (const_string "vector")
7862        (const_string "double")))
7863   (set_attr "amdfam10_decode" "double")
7864   (set_attr "bdver1_decode" "direct")
7865   (set_attr "mode" "SI")])
7866
7867(define_insn "*<s>mulsi3_highpart_1"
7868  [(set (match_operand:SI 0 "register_operand" "=d")
7869	(truncate:SI
7870	  (lshiftrt:DI
7871	    (mult:DI
7872	      (any_extend:DI
7873		(match_operand:SI 1 "nonimmediate_operand" "%a"))
7874	      (any_extend:DI
7875		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7876	    (const_int 32))))
7877   (clobber (match_scratch:SI 3 "=1"))
7878   (clobber (reg:CC FLAGS_REG))]
7879  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7880  "<sgnprefix>mul{l}\t%2"
7881  [(set_attr "type" "imul")
7882   (set_attr "length_immediate" "0")
7883   (set (attr "athlon_decode")
7884     (if_then_else (eq_attr "cpu" "athlon")
7885        (const_string "vector")
7886        (const_string "double")))
7887   (set_attr "amdfam10_decode" "double")
7888   (set_attr "bdver1_decode" "direct")
7889   (set_attr "mode" "SI")])
7890
7891;; The patterns that match these are at the end of this file.
7892
7893(define_expand "mulxf3"
7894  [(set (match_operand:XF 0 "register_operand")
7895	(mult:XF (match_operand:XF 1 "register_operand")
7896		 (match_operand:XF 2 "register_operand")))]
7897  "TARGET_80387")
7898
7899(define_expand "mul<mode>3"
7900  [(set (match_operand:MODEF 0 "register_operand")
7901	(mult:MODEF (match_operand:MODEF 1 "register_operand")
7902		    (match_operand:MODEF 2 "nonimmediate_operand")))]
7903  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7904    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7905
7906;; Divide instructions
7907
7908;; The patterns that match these are at the end of this file.
7909
7910(define_expand "divxf3"
7911  [(set (match_operand:XF 0 "register_operand")
7912	(div:XF (match_operand:XF 1 "register_operand")
7913		(match_operand:XF 2 "register_operand")))]
7914  "TARGET_80387")
7915
7916(define_expand "div<mode>3"
7917  [(set (match_operand:MODEF 0 "register_operand")
7918	(div:MODEF (match_operand:MODEF 1 "register_operand")
7919		   (match_operand:MODEF 2 "nonimmediate_operand")))]
7920  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7921    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7922{
7923  if (<MODE>mode == SFmode
7924      && TARGET_SSE && TARGET_SSE_MATH
7925      && TARGET_RECIP_DIV
7926      && optimize_insn_for_speed_p ()
7927      && flag_finite_math_only && !flag_trapping_math
7928      && flag_unsafe_math_optimizations)
7929    {
7930      ix86_emit_swdivsf (operands[0], operands[1],
7931			 operands[2], SFmode);
7932      DONE;
7933    }
7934})
7935
7936;; Divmod instructions.
7937
7938(define_code_iterator any_div [div udiv])
7939(define_code_attr paired_mod [(div "mod") (udiv "umod")])
7940
7941(define_expand "<u>divmod<mode>4"
7942  [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7943		   (any_div:SWIM248
7944		     (match_operand:SWIM248 1 "register_operand")
7945		     (match_operand:SWIM248 2 "nonimmediate_operand")))
7946	      (set (match_operand:SWIM248 3 "register_operand")
7947		   (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
7948	      (clobber (reg:CC FLAGS_REG))])])
7949
7950;; Split with 8bit unsigned divide:
7951;; 	if (dividend an divisor are in [0-255])
7952;;	   use 8bit unsigned integer divide
7953;;	 else
7954;;	   use original integer divide
7955(define_split
7956  [(set (match_operand:SWI48 0 "register_operand")
7957	(any_div:SWI48 (match_operand:SWI48 2 "register_operand")
7958		       (match_operand:SWI48 3 "nonimmediate_operand")))
7959   (set (match_operand:SWI48 1 "register_operand")
7960	(<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
7961   (clobber (reg:CC FLAGS_REG))]
7962  "TARGET_USE_8BIT_IDIV
7963   && TARGET_QIMODE_MATH
7964   && can_create_pseudo_p ()
7965   && !optimize_insn_for_size_p ()"
7966  [(const_int 0)]
7967  "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
7968
7969(define_split
7970  [(set (match_operand:DI 0 "register_operand")
7971	(zero_extend:DI
7972	  (any_div:SI (match_operand:SI 2 "register_operand")
7973		      (match_operand:SI 3 "nonimmediate_operand"))))
7974   (set (match_operand:SI 1 "register_operand")
7975	(<paired_mod>:SI (match_dup 2) (match_dup 3)))
7976   (clobber (reg:CC FLAGS_REG))]
7977  "TARGET_64BIT
7978   && TARGET_USE_8BIT_IDIV
7979   && TARGET_QIMODE_MATH
7980   && can_create_pseudo_p ()
7981   && !optimize_insn_for_size_p ()"
7982  [(const_int 0)]
7983  "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7984
7985(define_split
7986  [(set (match_operand:DI 1 "register_operand")
7987	(zero_extend:DI
7988	  (<paired_mod>:SI (match_operand:SI 2 "register_operand")
7989			   (match_operand:SI 3 "nonimmediate_operand"))))
7990   (set (match_operand:SI 0 "register_operand")
7991	(any_div:SI  (match_dup 2) (match_dup 3)))
7992   (clobber (reg:CC FLAGS_REG))]
7993  "TARGET_64BIT
7994   && TARGET_USE_8BIT_IDIV
7995   && TARGET_QIMODE_MATH
7996   && can_create_pseudo_p ()
7997   && !optimize_insn_for_size_p ()"
7998  [(const_int 0)]
7999  "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
8000
8001(define_insn_and_split "divmod<mode>4_1"
8002  [(set (match_operand:SWI48 0 "register_operand" "=a")
8003	(div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8004		   (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8005   (set (match_operand:SWI48 1 "register_operand" "=&d")
8006	(mod:SWI48 (match_dup 2) (match_dup 3)))
8007   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8008   (clobber (reg:CC FLAGS_REG))]
8009  ""
8010  "#"
8011  "reload_completed"
8012  [(parallel [(set (match_dup 1)
8013		   (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
8014	      (clobber (reg:CC FLAGS_REG))])
8015   (parallel [(set (match_dup 0)
8016	           (div:SWI48 (match_dup 2) (match_dup 3)))
8017	      (set (match_dup 1)
8018		   (mod:SWI48 (match_dup 2) (match_dup 3)))
8019	      (use (match_dup 1))
8020	      (clobber (reg:CC FLAGS_REG))])]
8021{
8022  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8023
8024  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8025    operands[4] = operands[2];
8026  else
8027    {
8028      /* Avoid use of cltd in favor of a mov+shift.  */
8029      emit_move_insn (operands[1], operands[2]);
8030      operands[4] = operands[1];
8031    }
8032}
8033  [(set_attr "type" "multi")
8034   (set_attr "mode" "<MODE>")])
8035
8036(define_insn_and_split "udivmod<mode>4_1"
8037  [(set (match_operand:SWI48 0 "register_operand" "=a")
8038	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8039		    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8040   (set (match_operand:SWI48 1 "register_operand" "=&d")
8041	(umod:SWI48 (match_dup 2) (match_dup 3)))
8042   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8043   (clobber (reg:CC FLAGS_REG))]
8044  ""
8045  "#"
8046  "reload_completed"
8047  [(set (match_dup 1) (const_int 0))
8048   (parallel [(set (match_dup 0)
8049		   (udiv:SWI48 (match_dup 2) (match_dup 3)))
8050	      (set (match_dup 1)
8051		   (umod:SWI48 (match_dup 2) (match_dup 3)))
8052	      (use (match_dup 1))
8053	      (clobber (reg:CC FLAGS_REG))])]
8054  ""
8055  [(set_attr "type" "multi")
8056   (set_attr "mode" "<MODE>")])
8057
8058(define_insn_and_split "divmodsi4_zext_1"
8059  [(set (match_operand:DI 0 "register_operand" "=a")
8060	(zero_extend:DI
8061	  (div:SI (match_operand:SI 2 "register_operand" "0")
8062		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8063   (set (match_operand:SI 1 "register_operand" "=&d")
8064	(mod:SI (match_dup 2) (match_dup 3)))
8065   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8066   (clobber (reg:CC FLAGS_REG))]
8067  "TARGET_64BIT"
8068  "#"
8069  "&& reload_completed"
8070  [(parallel [(set (match_dup 1)
8071		   (ashiftrt:SI (match_dup 4) (match_dup 5)))
8072	      (clobber (reg:CC FLAGS_REG))])
8073   (parallel [(set (match_dup 0)
8074		   (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8075	      (set (match_dup 1)
8076		   (mod:SI (match_dup 2) (match_dup 3)))
8077	      (use (match_dup 1))
8078	      (clobber (reg:CC FLAGS_REG))])]
8079{
8080  operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8081
8082  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8083    operands[4] = operands[2];
8084  else
8085    {
8086      /* Avoid use of cltd in favor of a mov+shift.  */
8087      emit_move_insn (operands[1], operands[2]);
8088      operands[4] = operands[1];
8089    }
8090}
8091  [(set_attr "type" "multi")
8092   (set_attr "mode" "SI")])
8093
8094(define_insn_and_split "udivmodsi4_zext_1"
8095  [(set (match_operand:DI 0 "register_operand" "=a")
8096	(zero_extend:DI
8097	  (udiv:SI (match_operand:SI 2 "register_operand" "0")
8098		   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8099   (set (match_operand:SI 1 "register_operand" "=&d")
8100	(umod:SI (match_dup 2) (match_dup 3)))
8101   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8102   (clobber (reg:CC FLAGS_REG))]
8103  "TARGET_64BIT"
8104  "#"
8105  "&& reload_completed"
8106  [(set (match_dup 1) (const_int 0))
8107   (parallel [(set (match_dup 0)
8108		   (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8109	      (set (match_dup 1)
8110		   (umod:SI (match_dup 2) (match_dup 3)))
8111	      (use (match_dup 1))
8112	      (clobber (reg:CC FLAGS_REG))])]
8113  ""
8114  [(set_attr "type" "multi")
8115   (set_attr "mode" "SI")])
8116
8117(define_insn_and_split "divmodsi4_zext_2"
8118  [(set (match_operand:DI 1 "register_operand" "=&d")
8119	(zero_extend:DI
8120	  (mod:SI (match_operand:SI 2 "register_operand" "0")
8121		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8122   (set (match_operand:SI 0 "register_operand" "=a")
8123	(div:SI (match_dup 2) (match_dup 3)))
8124   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8125   (clobber (reg:CC FLAGS_REG))]
8126  "TARGET_64BIT"
8127  "#"
8128  "&& reload_completed"
8129  [(parallel [(set (match_dup 6)
8130		   (ashiftrt:SI (match_dup 4) (match_dup 5)))
8131	      (clobber (reg:CC FLAGS_REG))])
8132   (parallel [(set (match_dup 1)
8133		   (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8134	      (set (match_dup 0)
8135		   (div:SI (match_dup 2) (match_dup 3)))
8136	      (use (match_dup 6))
8137	      (clobber (reg:CC FLAGS_REG))])]
8138{
8139  operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8140  operands[6] = gen_lowpart (SImode, operands[1]);
8141
8142  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8143    operands[4] = operands[2];
8144  else
8145    {
8146      /* Avoid use of cltd in favor of a mov+shift.  */
8147      emit_move_insn (operands[6], operands[2]);
8148      operands[4] = operands[6];
8149    }
8150}
8151  [(set_attr "type" "multi")
8152   (set_attr "mode" "SI")])
8153
8154(define_insn_and_split "udivmodsi4_zext_2"
8155  [(set (match_operand:DI 1 "register_operand" "=&d")
8156	(zero_extend:DI
8157	  (umod:SI (match_operand:SI 2 "register_operand" "0")
8158		 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8159   (set (match_operand:SI 0 "register_operand" "=a")
8160	(udiv:SI (match_dup 2) (match_dup 3)))
8161   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8162   (clobber (reg:CC FLAGS_REG))]
8163  "TARGET_64BIT"
8164  "#"
8165  "&& reload_completed"
8166  [(set (match_dup 4) (const_int 0))
8167   (parallel [(set (match_dup 1)
8168		   (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8169	      (set (match_dup 0)
8170		   (udiv:SI (match_dup 2) (match_dup 3)))
8171	      (use (match_dup 4))
8172	      (clobber (reg:CC FLAGS_REG))])]
8173  "operands[4] = gen_lowpart (SImode, operands[1]);"
8174  [(set_attr "type" "multi")
8175   (set_attr "mode" "SI")])
8176
8177(define_insn_and_split "*divmod<mode>4"
8178  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8179	(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8180		    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8181   (set (match_operand:SWIM248 1 "register_operand" "=&d")
8182	(mod:SWIM248 (match_dup 2) (match_dup 3)))
8183   (clobber (reg:CC FLAGS_REG))]
8184  ""
8185  "#"
8186  "reload_completed"
8187  [(parallel [(set (match_dup 1)
8188		   (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8189	      (clobber (reg:CC FLAGS_REG))])
8190   (parallel [(set (match_dup 0)
8191	           (div:SWIM248 (match_dup 2) (match_dup 3)))
8192	      (set (match_dup 1)
8193		   (mod:SWIM248 (match_dup 2) (match_dup 3)))
8194	      (use (match_dup 1))
8195	      (clobber (reg:CC FLAGS_REG))])]
8196{
8197  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8198
8199  if (<MODE>mode != HImode
8200      && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8201    operands[4] = operands[2];
8202  else
8203    {
8204      /* Avoid use of cltd in favor of a mov+shift.  */
8205      emit_move_insn (operands[1], operands[2]);
8206      operands[4] = operands[1];
8207    }
8208}
8209  [(set_attr "type" "multi")
8210   (set_attr "mode" "<MODE>")])
8211
8212(define_insn_and_split "*udivmod<mode>4"
8213  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8214	(udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8215		      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8216   (set (match_operand:SWIM248 1 "register_operand" "=&d")
8217	(umod:SWIM248 (match_dup 2) (match_dup 3)))
8218   (clobber (reg:CC FLAGS_REG))]
8219  ""
8220  "#"
8221  "reload_completed"
8222  [(set (match_dup 1) (const_int 0))
8223   (parallel [(set (match_dup 0)
8224		   (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8225	      (set (match_dup 1)
8226		   (umod:SWIM248 (match_dup 2) (match_dup 3)))
8227	      (use (match_dup 1))
8228	      (clobber (reg:CC FLAGS_REG))])]
8229  ""
8230  [(set_attr "type" "multi")
8231   (set_attr "mode" "<MODE>")])
8232
8233;; Optimize division or modulo by constant power of 2, if the constant
8234;; materializes only after expansion.
8235(define_insn_and_split "*udivmod<mode>4_pow2"
8236  [(set (match_operand:SWI48 0 "register_operand" "=r")
8237	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8238		    (match_operand:SWI48 3 "const_int_operand" "n")))
8239   (set (match_operand:SWI48 1 "register_operand" "=r")
8240	(umod:SWI48 (match_dup 2) (match_dup 3)))
8241   (clobber (reg:CC FLAGS_REG))]
8242  "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
8243  "#"
8244  "&& reload_completed"
8245  [(set (match_dup 1) (match_dup 2))
8246   (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8247	      (clobber (reg:CC FLAGS_REG))])
8248   (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8249	      (clobber (reg:CC FLAGS_REG))])]
8250{
8251  int v = exact_log2 (UINTVAL (operands[3]));
8252  operands[4] = GEN_INT (v);
8253  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8254}
8255  [(set_attr "type" "multi")
8256   (set_attr "mode" "<MODE>")])
8257
8258(define_insn_and_split "*divmodsi4_zext_1"
8259  [(set (match_operand:DI 0 "register_operand" "=a")
8260	(zero_extend:DI
8261	  (div:SI (match_operand:SI 2 "register_operand" "0")
8262		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8263   (set (match_operand:SI 1 "register_operand" "=&d")
8264	(mod:SI (match_dup 2) (match_dup 3)))
8265   (clobber (reg:CC FLAGS_REG))]
8266  "TARGET_64BIT"
8267  "#"
8268  "&& reload_completed"
8269  [(parallel [(set (match_dup 1)
8270		   (ashiftrt:SI (match_dup 4) (match_dup 5)))
8271	      (clobber (reg:CC FLAGS_REG))])
8272   (parallel [(set (match_dup 0)
8273		   (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8274	      (set (match_dup 1)
8275		   (mod:SI (match_dup 2) (match_dup 3)))
8276	      (use (match_dup 1))
8277	      (clobber (reg:CC FLAGS_REG))])]
8278{
8279  operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8280
8281  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8282    operands[4] = operands[2];
8283  else
8284    {
8285      /* Avoid use of cltd in favor of a mov+shift.  */
8286      emit_move_insn (operands[1], operands[2]);
8287      operands[4] = operands[1];
8288    }
8289}
8290  [(set_attr "type" "multi")
8291   (set_attr "mode" "SI")])
8292
8293(define_insn_and_split "*udivmodsi4_zext_1"
8294  [(set (match_operand:DI 0 "register_operand" "=a")
8295	(zero_extend:DI
8296	  (udiv:SI (match_operand:SI 2 "register_operand" "0")
8297		   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8298   (set (match_operand:SI 1 "register_operand" "=&d")
8299	(umod:SI (match_dup 2) (match_dup 3)))
8300   (clobber (reg:CC FLAGS_REG))]
8301  "TARGET_64BIT"
8302  "#"
8303  "&& reload_completed"
8304  [(set (match_dup 1) (const_int 0))
8305   (parallel [(set (match_dup 0)
8306		   (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8307	      (set (match_dup 1)
8308		   (umod:SI (match_dup 2) (match_dup 3)))
8309	      (use (match_dup 1))
8310	      (clobber (reg:CC FLAGS_REG))])]
8311  ""
8312  [(set_attr "type" "multi")
8313   (set_attr "mode" "SI")])
8314
8315(define_insn_and_split "*udivmodsi4_pow2_zext_1"
8316  [(set (match_operand:DI 0 "register_operand" "=r")
8317	(zero_extend:DI
8318	  (udiv:SI (match_operand:SI 2 "register_operand" "0")
8319		   (match_operand:SI 3 "const_int_operand" "n"))))
8320   (set (match_operand:SI 1 "register_operand" "=r")
8321	(umod:SI (match_dup 2) (match_dup 3)))
8322   (clobber (reg:CC FLAGS_REG))]
8323  "TARGET_64BIT
8324   && exact_log2 (UINTVAL (operands[3])) > 0"
8325  "#"
8326  "&& reload_completed"
8327  [(set (match_dup 1) (match_dup 2))
8328   (parallel [(set (match_dup 0)
8329		   (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8330	      (clobber (reg:CC FLAGS_REG))])
8331   (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8332	      (clobber (reg:CC FLAGS_REG))])]
8333{
8334  int v = exact_log2 (UINTVAL (operands[3]));
8335  operands[4] = GEN_INT (v);
8336  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8337}
8338  [(set_attr "type" "multi")
8339   (set_attr "mode" "SI")])
8340
8341(define_insn_and_split "*divmodsi4_zext_2"
8342  [(set (match_operand:DI 1 "register_operand" "=&d")
8343	(zero_extend:DI
8344	  (mod:SI (match_operand:SI 2 "register_operand" "0")
8345		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8346   (set (match_operand:SI 0 "register_operand" "=a")
8347	(div:SI (match_dup 2) (match_dup 3)))
8348   (clobber (reg:CC FLAGS_REG))]
8349  "TARGET_64BIT"
8350  "#"
8351  "&& reload_completed"
8352  [(parallel [(set (match_dup 6)
8353		   (ashiftrt:SI (match_dup 4) (match_dup 5)))
8354	      (clobber (reg:CC FLAGS_REG))])
8355   (parallel [(set (match_dup 1)
8356		   (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8357	      (set (match_dup 0)
8358		   (div:SI (match_dup 2) (match_dup 3)))
8359	      (use (match_dup 6))
8360	      (clobber (reg:CC FLAGS_REG))])]
8361{
8362  operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8363  operands[6] = gen_lowpart (SImode, operands[1]);
8364
8365  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8366    operands[4] = operands[2];
8367  else
8368    {
8369      /* Avoid use of cltd in favor of a mov+shift.  */
8370      emit_move_insn (operands[6], operands[2]);
8371      operands[4] = operands[6];
8372    }
8373}
8374  [(set_attr "type" "multi")
8375   (set_attr "mode" "SI")])
8376
8377(define_insn_and_split "*udivmodsi4_zext_2"
8378  [(set (match_operand:DI 1 "register_operand" "=&d")
8379	(zero_extend:DI
8380	  (umod:SI (match_operand:SI 2 "register_operand" "0")
8381		   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8382   (set (match_operand:SI 0 "register_operand" "=a")
8383	(udiv:SI (match_dup 2) (match_dup 3)))
8384   (clobber (reg:CC FLAGS_REG))]
8385  "TARGET_64BIT"
8386  "#"
8387  "&& reload_completed"
8388  [(set (match_dup 4) (const_int 0))
8389   (parallel [(set (match_dup 1)
8390		   (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8391	      (set (match_dup 0)
8392		   (udiv:SI (match_dup 2) (match_dup 3)))
8393	      (use (match_dup 4))
8394	      (clobber (reg:CC FLAGS_REG))])]
8395  "operands[4] = gen_lowpart (SImode, operands[1]);"
8396  [(set_attr "type" "multi")
8397   (set_attr "mode" "SI")])
8398
8399(define_insn_and_split "*udivmodsi4_pow2_zext_2"
8400  [(set (match_operand:DI 1 "register_operand" "=r")
8401	(zero_extend:DI
8402	  (umod:SI (match_operand:SI 2 "register_operand" "0")
8403		   (match_operand:SI 3 "const_int_operand" "n"))))
8404   (set (match_operand:SI 0 "register_operand" "=r")
8405	(umod:SI (match_dup 2) (match_dup 3)))
8406   (clobber (reg:CC FLAGS_REG))]
8407  "TARGET_64BIT
8408   && exact_log2 (UINTVAL (operands[3])) > 0"
8409  "#"
8410  "&& reload_completed"
8411  [(set (match_dup 1) (match_dup 2))
8412   (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8413	      (clobber (reg:CC FLAGS_REG))])
8414   (parallel [(set (match_dup 1)
8415		   (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8416	      (clobber (reg:CC FLAGS_REG))])]
8417{
8418  int v = exact_log2 (UINTVAL (operands[3]));
8419  operands[4] = GEN_INT (v);
8420  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8421}
8422  [(set_attr "type" "multi")
8423   (set_attr "mode" "SI")])
8424
8425(define_insn "*<u>divmod<mode>4_noext"
8426  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8427	(any_div:SWIM248
8428	  (match_operand:SWIM248 2 "register_operand" "0")
8429	  (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8430   (set (match_operand:SWIM248 1 "register_operand" "=d")
8431	(<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
8432   (use (match_operand:SWIM248 4 "register_operand" "1"))
8433   (clobber (reg:CC FLAGS_REG))]
8434  ""
8435  "<sgnprefix>div{<imodesuffix>}\t%3"
8436  [(set_attr "type" "idiv")
8437   (set_attr "mode" "<MODE>")])
8438
8439(define_insn "*<u>divmodsi4_noext_zext_1"
8440  [(set (match_operand:DI 0 "register_operand" "=a")
8441	(zero_extend:DI
8442	  (any_div:SI (match_operand:SI 2 "register_operand" "0")
8443		      (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8444   (set (match_operand:SI 1 "register_operand" "=d")
8445	(<paired_mod>:SI (match_dup 2) (match_dup 3)))
8446   (use (match_operand:SI 4 "register_operand" "1"))
8447   (clobber (reg:CC FLAGS_REG))]
8448  "TARGET_64BIT"
8449  "<sgnprefix>div{l}\t%3"
8450  [(set_attr "type" "idiv")
8451   (set_attr "mode" "SI")])
8452
8453(define_insn "*<u>divmodsi4_noext_zext_2"
8454  [(set (match_operand:DI 1 "register_operand" "=d")
8455	(zero_extend:DI
8456	  (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
8457			   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8458   (set (match_operand:SI 0 "register_operand" "=a")
8459	(any_div:SI (match_dup 2) (match_dup 3)))
8460   (use (match_operand:SI 4 "register_operand" "1"))
8461   (clobber (reg:CC FLAGS_REG))]
8462  "TARGET_64BIT"
8463  "<sgnprefix>div{l}\t%3"
8464  [(set_attr "type" "idiv")
8465   (set_attr "mode" "SI")])
8466
8467(define_expand "divmodqi4"
8468  [(parallel [(set (match_operand:QI 0 "register_operand")
8469		   (div:QI
8470		     (match_operand:QI 1 "register_operand")
8471		     (match_operand:QI 2 "nonimmediate_operand")))
8472	      (set (match_operand:QI 3 "register_operand")
8473		   (mod:QI (match_dup 1) (match_dup 2)))
8474	      (clobber (reg:CC FLAGS_REG))])]
8475  "TARGET_QIMODE_MATH"
8476{
8477  rtx div, mod;
8478  rtx tmp0, tmp1;
8479
8480  tmp0 = gen_reg_rtx (HImode);
8481  tmp1 = gen_reg_rtx (HImode);
8482
8483  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8484  emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8485  emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8486
8487  /* Extract remainder from AH.  */
8488  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8489  tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8490  rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8491
8492  mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8493  set_unique_reg_note (insn, REG_EQUAL, mod);
8494
8495  /* Extract quotient from AL.  */
8496  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8497
8498  div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8499  set_unique_reg_note (insn, REG_EQUAL, div);
8500
8501  DONE;
8502})
8503
8504(define_expand "udivmodqi4"
8505  [(parallel [(set (match_operand:QI 0 "register_operand")
8506		   (udiv:QI
8507		     (match_operand:QI 1 "register_operand")
8508		     (match_operand:QI 2 "nonimmediate_operand")))
8509	      (set (match_operand:QI 3 "register_operand")
8510		   (umod:QI (match_dup 1) (match_dup 2)))
8511	      (clobber (reg:CC FLAGS_REG))])]
8512  "TARGET_QIMODE_MATH"
8513{
8514  rtx div, mod;
8515  rtx tmp0, tmp1;
8516
8517  tmp0 = gen_reg_rtx (HImode);
8518  tmp1 = gen_reg_rtx (HImode);
8519
8520  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8521  emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8522  emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8523
8524  /* Extract remainder from AH.  */
8525  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8526  tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8527  rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8528
8529  mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8530  set_unique_reg_note (insn, REG_EQUAL, mod);
8531
8532  /* Extract quotient from AL.  */
8533  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8534
8535  div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8536  set_unique_reg_note (insn, REG_EQUAL, div);
8537
8538  DONE;
8539})
8540
8541;; Divide AX by r/m8, with result stored in
8542;; AL <- Quotient
8543;; AH <- Remainder
8544;; Change div/mod to HImode and extend the second argument to HImode
8545;; so that mode of div/mod matches with mode of arguments.  Otherwise
8546;; combine may fail.
8547(define_insn "<u>divmodhiqi3"
8548  [(set (match_operand:HI 0 "register_operand" "=a")
8549	(ior:HI
8550	  (ashift:HI
8551	    (zero_extend:HI
8552	      (truncate:QI
8553		(mod:HI (match_operand:HI 1 "register_operand" "0")
8554			(any_extend:HI
8555			  (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8556	    (const_int 8))
8557	  (zero_extend:HI
8558	    (truncate:QI
8559	      (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8560   (clobber (reg:CC FLAGS_REG))]
8561  "TARGET_QIMODE_MATH"
8562  "<sgnprefix>div{b}\t%2"
8563  [(set_attr "type" "idiv")
8564   (set_attr "mode" "QI")])
8565
8566;; We cannot use div/idiv for double division, because it causes
8567;; "division by zero" on the overflow and that's not what we expect
8568;; from truncate.  Because true (non truncating) double division is
8569;; never generated, we can't create this insn anyway.
8570;
8571;(define_insn ""
8572;  [(set (match_operand:SI 0 "register_operand" "=a")
8573;	(truncate:SI
8574;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
8575;		   (zero_extend:DI
8576;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8577;   (set (match_operand:SI 3 "register_operand" "=d")
8578;	(truncate:SI
8579;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8580;   (clobber (reg:CC FLAGS_REG))]
8581;  ""
8582;  "div{l}\t{%2, %0|%0, %2}"
8583;  [(set_attr "type" "idiv")])
8584
8585;;- Logical AND instructions
8586
8587;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8588;; Note that this excludes ah.
8589
8590(define_expand "@test<mode>_ccno_1"
8591  [(set (reg:CCNO FLAGS_REG)
8592	(compare:CCNO
8593	  (and:SWI48
8594	    (match_operand:SWI48 0 "nonimmediate_operand")
8595	    (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
8596	  (const_int 0)))])
8597
8598(define_expand "testqi_ccz_1"
8599  [(set (reg:CCZ FLAGS_REG)
8600	(compare:CCZ
8601	  (and:QI
8602	    (match_operand:QI 0 "nonimmediate_operand")
8603	    (match_operand:QI 1 "nonmemory_operand"))
8604	  (const_int 0)))])
8605
8606(define_insn "*testdi_1"
8607  [(set (reg FLAGS_REG)
8608	(compare
8609	  (and:DI
8610	    (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
8611	    (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
8612	 (const_int 0)))]
8613  "TARGET_64BIT
8614   && ix86_match_ccmode
8615	(insn,
8616	 /* If we are going to emit testl instead of testq, and the operands[1]
8617	    constant might have the SImode sign bit set, make sure the sign
8618	    flag isn't tested, because the instruction will set the sign flag
8619	    based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8620	    conservatively assume it might have bit 31 set.  */
8621	 (satisfies_constraint_Z (operands[1])
8622	  && (!CONST_INT_P (operands[1])
8623	      || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
8624	 ? CCZmode : CCNOmode)"
8625  "@
8626   test{l}\t{%k1, %k0|%k0, %k1}
8627   test{q}\t{%1, %0|%0, %1}"
8628  [(set_attr "type" "test")
8629   (set_attr "mode" "SI,DI")])
8630
8631(define_insn "*testqi_1_maybe_si"
8632  [(set (reg FLAGS_REG)
8633	(compare
8634	  (and:QI
8635	    (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r")
8636	    (match_operand:QI 1 "nonmemory_operand" "q,n,n,n"))
8637	  (const_int 0)))]
8638  "ix86_match_ccmode (insn,
8639		      CONST_INT_P (operands[1])
8640		      && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8641{
8642  if (which_alternative == 3)
8643    {
8644      if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8645	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8646      return "test{l}\t{%1, %k0|%k0, %1}";
8647    }
8648  return "test{b}\t{%1, %0|%0, %1}";
8649}
8650  [(set_attr "type" "test")
8651   (set_attr "mode" "QI,QI,QI,SI")
8652   (set_attr "pent_pair" "uv,uv,np,np")])
8653
8654(define_insn "*test<mode>_1"
8655  [(set (reg FLAGS_REG)
8656	(compare
8657	  (and:SWI124
8658	    (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
8659	    (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
8660	 (const_int 0)))]
8661  "ix86_match_ccmode (insn, CCNOmode)"
8662  "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8663  [(set_attr "type" "test")
8664   (set_attr "mode" "<MODE>")
8665   (set_attr "pent_pair" "uv,uv,np")])
8666
8667(define_expand "testqi_ext_1_ccno"
8668  [(set (reg:CCNO FLAGS_REG)
8669	(compare:CCNO
8670	  (and:QI
8671	    (subreg:QI
8672	      (zero_extract:SI (match_operand 0 "ext_register_operand")
8673			       (const_int 8)
8674			       (const_int 8)) 0)
8675	      (match_operand 1 "const_int_operand"))
8676	  (const_int 0)))])
8677
8678(define_insn "*testqi_ext_1"
8679  [(set (reg FLAGS_REG)
8680	(compare
8681	  (and:QI
8682	    (subreg:QI
8683	      (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8684			       (const_int 8)
8685			       (const_int 8)) 0)
8686	    (match_operand:QI 1 "general_operand" "QnBc,m"))
8687	  (const_int 0)))]
8688  "ix86_match_ccmode (insn, CCNOmode)"
8689  "test{b}\t{%1, %h0|%h0, %1}"
8690  [(set_attr "isa" "*,nox64")
8691   (set_attr "type" "test")
8692   (set_attr "mode" "QI")])
8693
8694(define_insn "*testqi_ext_2"
8695  [(set (reg FLAGS_REG)
8696	(compare
8697	  (and:QI
8698	    (subreg:QI
8699	      (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8700			       (const_int 8)
8701			       (const_int 8)) 0)
8702	    (subreg:QI
8703	      (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8704			       (const_int 8)
8705			       (const_int 8)) 0))
8706	  (const_int 0)))]
8707  "ix86_match_ccmode (insn, CCNOmode)"
8708  "test{b}\t{%h1, %h0|%h0, %h1}"
8709  [(set_attr "type" "test")
8710   (set_attr "mode" "QI")])
8711
8712;; Combine likes to form bit extractions for some tests.  Humor it.
8713(define_insn_and_split "*testqi_ext_3"
8714  [(set (match_operand 0 "flags_reg_operand")
8715        (match_operator 1 "compare_operator"
8716	  [(zero_extract:SWI248
8717	     (match_operand 2 "nonimmediate_operand" "rm")
8718	     (match_operand 3 "const_int_operand" "n")
8719	     (match_operand 4 "const_int_operand" "n"))
8720	   (const_int 0)]))]
8721  "((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8722    || GET_MODE (operands[2]) == SImode
8723    || GET_MODE (operands[2]) == HImode
8724    || GET_MODE (operands[2]) == QImode)
8725   /* Ensure that resulting mask is zero or sign extended operand.  */
8726   && INTVAL (operands[4]) >= 0
8727   && ((INTVAL (operands[3]) > 0
8728	&& INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8729       || (<MODE>mode == DImode
8730	   && INTVAL (operands[3]) > 32
8731	   && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
8732   && ix86_match_ccmode (insn,
8733			 /* If zero_extract mode precision is the same
8734			    as len, the SF of the zero_extract
8735			    comparison will be the most significant
8736			    extracted bit, but this could be matched
8737			    after splitting only for pos 0 len all bits
8738			    trivial extractions.  Require CCZmode.  */
8739			 (GET_MODE_PRECISION (<MODE>mode)
8740			  == INTVAL (operands[3]))
8741			 /* Otherwise, require CCZmode if we'd use a mask
8742			    with the most significant bit set and can't
8743			    widen it to wider mode.  *testdi_1 also
8744			    requires CCZmode if the mask has bit
8745			    31 set and all bits above it clear.  */
8746			 || (INTVAL (operands[3]) + INTVAL (operands[4])
8747			     >= 32)
8748			 /* We can't widen also if val is not a REG.  */
8749			 || (INTVAL (operands[3]) + INTVAL (operands[4])
8750			     == GET_MODE_PRECISION (GET_MODE (operands[2]))
8751			     && !register_operand (operands[2],
8752						   GET_MODE (operands[2])))
8753			 /* And we shouldn't widen if
8754			    TARGET_PARTIAL_REG_STALL.  */
8755			 || (TARGET_PARTIAL_REG_STALL
8756			     && (INTVAL (operands[3]) + INTVAL (operands[4])
8757				 >= (paradoxical_subreg_p (operands[2])
8758				     && (GET_MODE_CLASS
8759					  (GET_MODE (SUBREG_REG (operands[2])))
8760					 == MODE_INT)
8761				     ? GET_MODE_PRECISION
8762					 (GET_MODE (SUBREG_REG (operands[2])))
8763				     : GET_MODE_PRECISION
8764					 (GET_MODE (operands[2])))))
8765			 ? CCZmode : CCNOmode)"
8766  "#"
8767  "&& 1"
8768  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8769{
8770  rtx val = operands[2];
8771  HOST_WIDE_INT len = INTVAL (operands[3]);
8772  HOST_WIDE_INT pos = INTVAL (operands[4]);
8773  machine_mode mode = GET_MODE (val);
8774
8775  if (SUBREG_P (val))
8776    {
8777      machine_mode submode = GET_MODE (SUBREG_REG (val));
8778
8779      /* Narrow paradoxical subregs to prevent partial register stalls.  */
8780      if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8781	  && GET_MODE_CLASS (submode) == MODE_INT
8782	  && (GET_MODE (operands[0]) == CCZmode
8783	      || pos + len < GET_MODE_PRECISION (submode)
8784	      || REG_P (SUBREG_REG (val))))
8785	{
8786	  val = SUBREG_REG (val);
8787	  mode = submode;
8788	}
8789    }
8790
8791  /* Small HImode tests can be converted to QImode.  */
8792  if (pos + len <= 8
8793      && register_operand (val, HImode))
8794    {
8795      rtx nval = gen_lowpart (QImode, val);
8796      if (!MEM_P (nval)
8797	  || GET_MODE (operands[0]) == CCZmode
8798	  || pos + len < 8)
8799	{
8800	  val = nval;
8801	  mode = QImode;
8802	}
8803    }
8804
8805  gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8806
8807  /* If the mask is going to have the sign bit set in the mode
8808     we want to do the comparison in and user isn't interested just
8809     in the zero flag, then we must widen the target mode.  */
8810  if (pos + len == GET_MODE_PRECISION (mode)
8811      && GET_MODE (operands[0]) != CCZmode)
8812    {
8813      gcc_assert (pos + len < 32 && !MEM_P (val));
8814      mode = SImode;
8815      val = gen_lowpart (mode, val);
8816    }
8817
8818  wide_int mask
8819    = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8820
8821  operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8822})
8823
8824;; Convert HImode/SImode test instructions with immediate to QImode ones.
8825;; i386 does not allow to encode test with 8bit sign extended immediate, so
8826;; this is relatively important trick.
8827;; Do the conversion only post-reload to avoid limiting of the register class
8828;; to QI regs.
8829(define_split
8830  [(set (match_operand 0 "flags_reg_operand")
8831	(match_operator 1 "compare_operator"
8832	  [(and (match_operand 2 "QIreg_operand")
8833	        (match_operand 3 "const_int_operand"))
8834	   (const_int 0)]))]
8835   "reload_completed
8836    && GET_MODE (operands[2]) != QImode
8837    && ((ix86_match_ccmode (insn, CCZmode)
8838    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
8839	|| (ix86_match_ccmode (insn, CCNOmode)
8840	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
8841  [(set (match_dup 0)
8842	(match_op_dup 1
8843	  [(and:QI
8844	     (subreg:QI
8845	       (zero_extract:SI (match_dup 2)
8846				(const_int 8)
8847				(const_int 8)) 0)
8848	     (match_dup 3))
8849	   (const_int 0)]))]
8850{
8851  operands[2] = gen_lowpart (SImode, operands[2]);
8852  operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8853})
8854
8855(define_split
8856  [(set (match_operand 0 "flags_reg_operand")
8857	(match_operator 1 "compare_operator"
8858	  [(and (match_operand 2 "nonimmediate_operand")
8859	        (match_operand 3 "const_int_operand"))
8860	   (const_int 0)]))]
8861   "reload_completed
8862    && GET_MODE (operands[2]) != QImode
8863    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8864    && ((ix86_match_ccmode (insn, CCZmode)
8865	 && !(INTVAL (operands[3]) & ~255))
8866	|| (ix86_match_ccmode (insn, CCNOmode)
8867	    && !(INTVAL (operands[3]) & ~127)))"
8868  [(set (match_dup 0)
8869	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8870			 (const_int 0)]))]
8871{
8872  operands[2] = gen_lowpart (QImode, operands[2]);
8873  operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8874})
8875
8876;; %%% This used to optimize known byte-wide and operations to memory,
8877;; and sometimes to QImode registers.  If this is considered useful,
8878;; it should be done with splitters.
8879
8880(define_expand "and<mode>3"
8881  [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
8882	(and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
8883		       (match_operand:SWIM1248s 2 "<general_szext_operand>")))]
8884  ""
8885{
8886  machine_mode mode = <MODE>mode;
8887
8888  if (<MODE>mode == DImode && !TARGET_64BIT)
8889    ;
8890  else if (const_int_operand (operands[2], <MODE>mode)
8891	   && register_operand (operands[0], <MODE>mode)
8892	   && !(TARGET_ZERO_EXTEND_WITH_AND
8893		&& optimize_function_for_speed_p (cfun)))
8894    {
8895      unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
8896
8897      if (ival == GET_MODE_MASK (SImode))
8898	mode = SImode;
8899      else if (ival == GET_MODE_MASK (HImode))
8900	mode = HImode;
8901      else if (ival == GET_MODE_MASK (QImode))
8902	mode = QImode;
8903    }
8904
8905  if (mode != <MODE>mode)
8906    emit_insn (gen_extend_insn
8907	       (operands[0], gen_lowpart (mode, operands[1]),
8908		<MODE>mode, mode, 1));
8909  else
8910    ix86_expand_binary_operator (AND, <MODE>mode, operands);
8911
8912  DONE;
8913})
8914
8915(define_insn_and_split "*anddi3_doubleword"
8916  [(set (match_operand:DI 0 "nonimmediate_operand")
8917	(and:DI
8918	 (match_operand:DI 1 "nonimmediate_operand")
8919	 (match_operand:DI 2 "x86_64_szext_general_operand")))
8920   (clobber (reg:CC FLAGS_REG))]
8921  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8922   && ix86_binary_operator_ok (AND, DImode, operands)
8923   && ix86_pre_reload_split ()"
8924  "#"
8925  "&& 1"
8926  [(const_int 0)]
8927{
8928  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8929
8930  if (operands[2] == const0_rtx)
8931    emit_move_insn (operands[0], const0_rtx);
8932  else if (operands[2] == constm1_rtx)
8933    emit_move_insn (operands[0], operands[1]);
8934  else
8935    emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
8936
8937  if (operands[5] == const0_rtx)
8938    emit_move_insn (operands[3], const0_rtx);
8939  else if (operands[5] == constm1_rtx)
8940    emit_move_insn (operands[3], operands[4]);
8941  else
8942    emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
8943
8944  DONE;
8945})
8946
8947(define_insn "*anddi_1"
8948  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8949	(and:DI
8950	 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8951	 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L")))
8952   (clobber (reg:CC FLAGS_REG))]
8953  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8954  "@
8955   and{l}\t{%k2, %k0|%k0, %k2}
8956   and{q}\t{%2, %0|%0, %2}
8957   and{q}\t{%2, %0|%0, %2}
8958   #"
8959  [(set_attr "type" "alu,alu,alu,imovx")
8960   (set_attr "length_immediate" "*,*,*,0")
8961   (set (attr "prefix_rex")
8962     (if_then_else
8963       (and (eq_attr "type" "imovx")
8964	    (and (match_test "INTVAL (operands[2]) == 0xff")
8965		 (match_operand 1 "ext_QIreg_operand")))
8966       (const_string "1")
8967       (const_string "*")))
8968   (set_attr "mode" "SI,DI,DI,SI")])
8969
8970(define_insn_and_split "*anddi_1_btr"
8971  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8972	(and:DI
8973	 (match_operand:DI 1 "nonimmediate_operand" "%0")
8974	 (match_operand:DI 2 "const_int_operand" "n")))
8975   (clobber (reg:CC FLAGS_REG))]
8976  "TARGET_64BIT && TARGET_USE_BT
8977   && ix86_binary_operator_ok (AND, DImode, operands)
8978   && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8979  "#"
8980  "&& reload_completed"
8981  [(parallel [(set (zero_extract:DI (match_dup 0)
8982				    (const_int 1)
8983				    (match_dup 3))
8984		   (const_int 0))
8985	      (clobber (reg:CC FLAGS_REG))])]
8986  "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8987  [(set_attr "type" "alu1")
8988   (set_attr "prefix_0f" "1")
8989   (set_attr "znver1_decode" "double")
8990   (set_attr "mode" "DI")])
8991
8992;; Turn *anddi_1 into *andsi_1_zext if possible.
8993(define_split
8994  [(set (match_operand:DI 0 "register_operand")
8995	(and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8996		(match_operand:DI 2 "x86_64_zext_immediate_operand")))
8997   (clobber (reg:CC FLAGS_REG))]
8998  "TARGET_64BIT"
8999  [(parallel [(set (match_dup 0)
9000		   (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9001	      (clobber (reg:CC FLAGS_REG))])]
9002{
9003  if (GET_CODE (operands[2]) == SYMBOL_REF
9004      || GET_CODE (operands[2]) == LABEL_REF)
9005    {
9006      operands[2] = shallow_copy_rtx (operands[2]);
9007      PUT_MODE (operands[2], SImode);
9008    }
9009  else if (GET_CODE (operands[2]) == CONST)
9010    {
9011      /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
9012      operands[2] = copy_rtx (operands[2]);
9013      PUT_MODE (operands[2], SImode);
9014      PUT_MODE (XEXP (operands[2], 0), SImode);
9015      PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
9016    }    
9017  else
9018    operands[2] = gen_lowpart (SImode, operands[2]);
9019})
9020
9021;; See comment for addsi_1_zext why we do use nonimmediate_operand
9022(define_insn "*andsi_1_zext"
9023  [(set (match_operand:DI 0 "register_operand" "=r")
9024	(zero_extend:DI
9025	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9026		  (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9027   (clobber (reg:CC FLAGS_REG))]
9028  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9029  "and{l}\t{%2, %k0|%k0, %2}"
9030  [(set_attr "type" "alu")
9031   (set_attr "mode" "SI")])
9032
9033(define_insn "*and<mode>_1"
9034  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
9035	(and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
9036		   (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L")))
9037   (clobber (reg:CC FLAGS_REG))]
9038  "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9039  "@
9040   and{<imodesuffix>}\t{%2, %0|%0, %2}
9041   and{<imodesuffix>}\t{%2, %0|%0, %2}
9042   #"
9043  [(set_attr "type" "alu,alu,imovx")
9044   (set_attr "length_immediate" "*,*,0")
9045   (set (attr "prefix_rex")
9046     (if_then_else
9047       (and (eq_attr "type" "imovx")
9048	    (and (match_test "INTVAL (operands[2]) == 0xff")
9049		 (match_operand 1 "ext_QIreg_operand")))
9050       (const_string "1")
9051       (const_string "*")))
9052   (set_attr "mode" "<MODE>,<MODE>,SI")])
9053
9054(define_insn "*andqi_1"
9055  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9056	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9057		(match_operand:QI 2 "general_operand" "qn,m,rn")))
9058   (clobber (reg:CC FLAGS_REG))]
9059  "ix86_binary_operator_ok (AND, QImode, operands)"
9060  "@
9061   and{b}\t{%2, %0|%0, %2}
9062   and{b}\t{%2, %0|%0, %2}
9063   and{l}\t{%k2, %k0|%k0, %k2}"
9064  [(set_attr "type" "alu")
9065   (set_attr "mode" "QI,QI,SI")
9066   ;; Potential partial reg stall on alternative 2.
9067   (set (attr "preferred_for_speed")
9068     (cond [(eq_attr "alternative" "2")
9069	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9070	   (symbol_ref "true")))])
9071
9072(define_insn "*and<mode>_1_slp"
9073  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9074	(and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9075		   (match_operand:SWI12 2 "general_operand" "<r>mn")))
9076   (clobber (reg:CC FLAGS_REG))]
9077  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9078   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9079   && (rtx_equal_p (operands[0], operands[1])
9080       || rtx_equal_p (operands[0], operands[2]))"
9081  "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9082  [(set_attr "type" "alu")
9083   (set_attr "mode" "<MODE>")])
9084
9085(define_split
9086  [(set (match_operand:SWI248 0 "register_operand")
9087	(and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9088		    (match_operand:SWI248 2 "const_int_operand")))
9089   (clobber (reg:CC FLAGS_REG))]
9090  "reload_completed
9091   && (!REG_P (operands[1])
9092       || REGNO (operands[0]) != REGNO (operands[1]))"
9093  [(const_int 0)]
9094{
9095  unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
9096  machine_mode mode;
9097
9098  if (ival == GET_MODE_MASK (SImode))
9099    mode = SImode;
9100  else if (ival == GET_MODE_MASK (HImode))
9101    mode = HImode;
9102  else if (ival == GET_MODE_MASK (QImode))
9103    mode = QImode;
9104  else
9105    gcc_unreachable ();
9106
9107  /* Zero extend to SImode to avoid partial register stalls.  */
9108  if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
9109    operands[0] = gen_lowpart (SImode, operands[0]);
9110
9111  emit_insn (gen_extend_insn
9112	     (operands[0], gen_lowpart (mode, operands[1]),
9113	      GET_MODE (operands[0]), mode, 1));
9114  DONE;
9115})
9116
9117(define_split
9118  [(set (match_operand:SWI48 0 "register_operand")
9119	(and:SWI48 (match_dup 0)
9120		   (const_int -65536)))
9121   (clobber (reg:CC FLAGS_REG))]
9122  "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9123    || optimize_function_for_size_p (cfun)"
9124  [(set (strict_low_part (match_dup 1)) (const_int 0))]
9125  "operands[1] = gen_lowpart (HImode, operands[0]);")
9126
9127(define_split
9128  [(set (match_operand:SWI248 0 "any_QIreg_operand")
9129	(and:SWI248 (match_dup 0)
9130		    (const_int -256)))
9131   (clobber (reg:CC FLAGS_REG))]
9132  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9133   && reload_completed"
9134  [(set (strict_low_part (match_dup 1)) (const_int 0))]
9135  "operands[1] = gen_lowpart (QImode, operands[0]);")
9136
9137(define_split
9138  [(set (match_operand:SWI248 0 "QIreg_operand")
9139	(and:SWI248 (match_dup 0)
9140		    (const_int -65281)))
9141   (clobber (reg:CC FLAGS_REG))]
9142  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9143   && reload_completed"
9144  [(parallel
9145     [(set (zero_extract:SI (match_dup 0)
9146			    (const_int 8)
9147			    (const_int 8))
9148	   (subreg:SI
9149	     (xor:QI
9150	       (subreg:QI
9151		 (zero_extract:SI (match_dup 0)
9152				  (const_int 8)
9153				  (const_int 8)) 0)
9154	       (subreg:QI
9155		 (zero_extract:SI (match_dup 0)
9156				  (const_int 8)
9157				  (const_int 8)) 0)) 0))
9158      (clobber (reg:CC FLAGS_REG))])]
9159  "operands[0] = gen_lowpart (SImode, operands[0]);")
9160
9161(define_insn "*anddi_2"
9162  [(set (reg FLAGS_REG)
9163	(compare
9164	 (and:DI
9165	  (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9166	  (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
9167	 (const_int 0)))
9168   (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9169	(and:DI (match_dup 1) (match_dup 2)))]
9170  "TARGET_64BIT
9171   && ix86_match_ccmode
9172	(insn,
9173	 /* If we are going to emit andl instead of andq, and the operands[2]
9174	    constant might have the SImode sign bit set, make sure the sign
9175	    flag isn't tested, because the instruction will set the sign flag
9176	    based on bit 31 rather than bit 63.  If it isn't CONST_INT,
9177	    conservatively assume it might have bit 31 set.  */
9178	 (satisfies_constraint_Z (operands[2])
9179	  && (!CONST_INT_P (operands[2])
9180	      || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9181	 ? CCZmode : CCNOmode)
9182   && ix86_binary_operator_ok (AND, DImode, operands)"
9183  "@
9184   and{l}\t{%k2, %k0|%k0, %k2}
9185   and{q}\t{%2, %0|%0, %2}
9186   and{q}\t{%2, %0|%0, %2}"
9187  [(set_attr "type" "alu")
9188   (set_attr "mode" "SI,DI,DI")])
9189
9190;; See comment for addsi_1_zext why we do use nonimmediate_operand
9191(define_insn "*andsi_2_zext"
9192  [(set (reg FLAGS_REG)
9193	(compare (and:SI
9194		  (match_operand:SI 1 "nonimmediate_operand" "%0")
9195		  (match_operand:SI 2 "x86_64_general_operand" "rme"))
9196		 (const_int 0)))
9197   (set (match_operand:DI 0 "register_operand" "=r")
9198	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9199  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9200   && ix86_binary_operator_ok (AND, SImode, operands)"
9201  "and{l}\t{%2, %k0|%k0, %2}"
9202  [(set_attr "type" "alu")
9203   (set_attr "mode" "SI")])
9204
9205(define_insn "*andqi_2_maybe_si"
9206  [(set (reg FLAGS_REG)
9207	(compare (and:QI
9208		  (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9209		  (match_operand:QI 2 "general_operand" "qn,m,n"))
9210		 (const_int 0)))
9211   (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9212	(and:QI (match_dup 1) (match_dup 2)))]
9213  "ix86_binary_operator_ok (AND, QImode, operands)
9214   && ix86_match_ccmode (insn,
9215			 CONST_INT_P (operands[2])
9216			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9217{
9218  if (which_alternative == 2)
9219    {
9220      if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9221        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9222      return "and{l}\t{%2, %k0|%k0, %2}";
9223    }
9224  return "and{b}\t{%2, %0|%0, %2}";
9225}
9226  [(set_attr "type" "alu")
9227   (set_attr "mode" "QI,QI,SI")
9228   ;; Potential partial reg stall on alternative 2.
9229   (set (attr "preferred_for_speed")
9230     (cond [(eq_attr "alternative" "2")
9231	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9232	   (symbol_ref "true")))])
9233
9234(define_insn "*and<mode>_2"
9235  [(set (reg FLAGS_REG)
9236	(compare (and:SWI124
9237		  (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9238		  (match_operand:SWI124 2 "<general_operand>" "<r><i>,m"))
9239		 (const_int 0)))
9240   (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
9241	(and:SWI124 (match_dup 1) (match_dup 2)))]
9242  "ix86_match_ccmode (insn, CCNOmode)
9243   && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9244  "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9245  [(set_attr "type" "alu")
9246   (set_attr "mode" "<MODE>")])
9247
9248(define_insn "andqi_ext_1"
9249  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9250			 (const_int 8)
9251			 (const_int 8))
9252	(subreg:SI
9253	  (and:QI
9254	    (subreg:QI
9255	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9256			       (const_int 8)
9257			       (const_int 8)) 0)
9258	    (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9259   (clobber (reg:CC FLAGS_REG))]
9260  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9261   rtx_equal_p (operands[0], operands[1])"
9262  "and{b}\t{%2, %h0|%h0, %2}"
9263  [(set_attr "isa" "*,nox64")
9264   (set_attr "type" "alu")
9265   (set_attr "mode" "QI")])
9266
9267;; Generated by peephole translating test to and.  This shows up
9268;; often in fp comparisons.
9269(define_insn "*andqi_ext_1_cc"
9270  [(set (reg FLAGS_REG)
9271	(compare
9272	  (and:QI
9273	    (subreg:QI
9274	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9275			       (const_int 8)
9276			       (const_int 8)) 0)
9277	    (match_operand:QI 2 "general_operand" "QnBc,m"))
9278	  (const_int 0)))
9279   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9280			 (const_int 8)
9281			 (const_int 8))
9282	(subreg:SI
9283	  (and:QI
9284	    (subreg:QI
9285	      (zero_extract:SI (match_dup 1)
9286			       (const_int 8)
9287			       (const_int 8)) 0)
9288	    (match_dup 2)) 0))]
9289  "ix86_match_ccmode (insn, CCNOmode)
9290   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9291   && rtx_equal_p (operands[0], operands[1])"
9292  "and{b}\t{%2, %h0|%h0, %2}"
9293  [(set_attr "isa" "*,nox64")
9294   (set_attr "type" "alu")
9295   (set_attr "mode" "QI")])
9296
9297(define_insn "*andqi_ext_2"
9298  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9299			 (const_int 8)
9300			 (const_int 8))
9301	(subreg:SI
9302	  (and:QI
9303	    (subreg:QI
9304	      (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9305			       (const_int 8)
9306			       (const_int 8)) 0)
9307	    (subreg:QI
9308	      (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9309			       (const_int 8)
9310			       (const_int 8)) 0)) 0))
9311   (clobber (reg:CC FLAGS_REG))]
9312  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9313   rtx_equal_p (operands[0], operands[1])
9314   || rtx_equal_p (operands[0], operands[2])"
9315  "and{b}\t{%h2, %h0|%h0, %h2}"
9316  [(set_attr "type" "alu")
9317   (set_attr "mode" "QI")])
9318
9319;; Convert wide AND instructions with immediate operand to shorter QImode
9320;; equivalents when possible.
9321;; Don't do the splitting with memory operands, since it introduces risk
9322;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9323;; for size, but that can (should?) be handled by generic code instead.
9324(define_split
9325  [(set (match_operand:SWI248 0 "QIreg_operand")
9326	(and:SWI248 (match_operand:SWI248 1 "register_operand")
9327		    (match_operand:SWI248 2 "const_int_operand")))
9328   (clobber (reg:CC FLAGS_REG))]
9329   "reload_completed
9330    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9331    && !(~INTVAL (operands[2]) & ~(255 << 8))"
9332  [(parallel
9333     [(set (zero_extract:SI (match_dup 0)
9334			    (const_int 8)
9335			    (const_int 8))
9336	   (subreg:SI
9337	     (and:QI
9338	       (subreg:QI
9339		 (zero_extract:SI (match_dup 1)
9340				  (const_int 8)
9341				  (const_int 8)) 0)
9342	       (match_dup 2)) 0))
9343      (clobber (reg:CC FLAGS_REG))])]
9344{
9345  operands[0] = gen_lowpart (SImode, operands[0]);
9346  operands[1] = gen_lowpart (SImode, operands[1]);
9347  operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9348})
9349
9350;; Since AND can be encoded with sign extended immediate, this is only
9351;; profitable when 7th bit is not set.
9352(define_split
9353  [(set (match_operand:SWI248 0 "any_QIreg_operand")
9354	(and:SWI248 (match_operand:SWI248 1 "general_operand")
9355		    (match_operand:SWI248 2 "const_int_operand")))
9356   (clobber (reg:CC FLAGS_REG))]
9357   "reload_completed
9358    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9359    && !(~INTVAL (operands[2]) & ~255)
9360    && !(INTVAL (operands[2]) & 128)"
9361  [(parallel [(set (strict_low_part (match_dup 0))
9362		   (and:QI (match_dup 1)
9363			   (match_dup 2)))
9364	      (clobber (reg:CC FLAGS_REG))])]
9365{
9366  operands[0] = gen_lowpart (QImode, operands[0]);
9367  operands[1] = gen_lowpart (QImode, operands[1]);
9368  operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9369})
9370
9371(define_insn "*andndi3_doubleword"
9372  [(set (match_operand:DI 0 "register_operand")
9373	(and:DI
9374	  (not:DI (match_operand:DI 1 "register_operand"))
9375	  (match_operand:DI 2 "nonimmediate_operand")))
9376   (clobber (reg:CC FLAGS_REG))]
9377  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9378   && ix86_pre_reload_split ()"
9379  "#")
9380
9381(define_split
9382  [(set (match_operand:DI 0 "register_operand")
9383	(and:DI
9384	  (not:DI (match_operand:DI 1 "register_operand"))
9385	  (match_operand:DI 2 "nonimmediate_operand")))
9386   (clobber (reg:CC FLAGS_REG))]
9387  "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9388   && can_create_pseudo_p ()"
9389  [(parallel [(set (match_dup 0)
9390		   (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9391	      (clobber (reg:CC FLAGS_REG))])
9392   (parallel [(set (match_dup 3)
9393		   (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9394	      (clobber (reg:CC FLAGS_REG))])]
9395  "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9396
9397(define_split
9398  [(set (match_operand:DI 0 "register_operand")
9399	(and:DI
9400	  (not:DI (match_operand:DI 1 "register_operand"))
9401	  (match_operand:DI 2 "nonimmediate_operand")))
9402   (clobber (reg:CC FLAGS_REG))]
9403  "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9404   && can_create_pseudo_p ()"
9405  [(set (match_dup 6) (not:SI (match_dup 1)))
9406   (parallel [(set (match_dup 0)
9407		   (and:SI (match_dup 6) (match_dup 2)))
9408	      (clobber (reg:CC FLAGS_REG))])
9409   (set (match_dup 7) (not:SI (match_dup 4)))
9410   (parallel [(set (match_dup 3)
9411		   (and:SI (match_dup 7) (match_dup 5)))
9412	      (clobber (reg:CC FLAGS_REG))])]
9413{
9414  operands[6] = gen_reg_rtx (SImode);
9415  operands[7] = gen_reg_rtx (SImode);
9416
9417  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9418})
9419
9420(define_insn "*andn<mode>_1"
9421  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9422	(and:SWI48
9423	  (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9424	  (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9425   (clobber (reg:CC FLAGS_REG))]
9426  "TARGET_BMI"
9427  "andn\t{%2, %1, %0|%0, %1, %2}"
9428  [(set_attr "type" "bitmanip")
9429   (set_attr "btver2_decode" "direct, double")
9430   (set_attr "mode" "<MODE>")])
9431
9432(define_insn "*andn<mode>_1"
9433  [(set (match_operand:SWI12 0 "register_operand" "=r")
9434	(and:SWI12
9435	  (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9436	  (match_operand:SWI12 2 "register_operand" "r")))
9437   (clobber (reg:CC FLAGS_REG))]
9438  "TARGET_BMI"
9439  "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9440  [(set_attr "type" "bitmanip")
9441   (set_attr "btver2_decode" "direct")
9442   (set_attr "mode" "SI")])
9443
9444(define_insn "*andn_<mode>_ccno"
9445  [(set (reg FLAGS_REG)
9446	(compare
9447	  (and:SWI48
9448	    (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9449	    (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9450	  (const_int 0)))
9451   (clobber (match_scratch:SWI48 0 "=r,r"))]
9452  "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9453  "andn\t{%2, %1, %0|%0, %1, %2}"
9454  [(set_attr "type" "bitmanip")
9455   (set_attr "btver2_decode" "direct, double")
9456   (set_attr "mode" "<MODE>")])
9457
9458;; Logical inclusive and exclusive OR instructions
9459
9460;; %%% This used to optimize known byte-wide and operations to memory.
9461;; If this is considered useful, it should be done with splitters.
9462
9463(define_expand "<code><mode>3"
9464  [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9465	(any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
9466			  (match_operand:SWIM1248s 2 "<general_operand>")))]
9467  ""
9468  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9469
9470(define_insn_and_split "*<code>di3_doubleword"
9471  [(set (match_operand:DI 0 "nonimmediate_operand")
9472	(any_or:DI
9473	 (match_operand:DI 1 "nonimmediate_operand")
9474	 (match_operand:DI 2 "x86_64_szext_general_operand")))
9475   (clobber (reg:CC FLAGS_REG))]
9476  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9477   && ix86_binary_operator_ok (<CODE>, DImode, operands)
9478   && ix86_pre_reload_split ()"
9479  "#"
9480  "&& 1"
9481  [(const_int 0)]
9482{
9483  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9484
9485  if (operands[2] == const0_rtx)
9486    emit_move_insn (operands[0], operands[1]);
9487  else if (operands[2] == constm1_rtx)
9488    {
9489      if (<CODE> == IOR)
9490	emit_move_insn (operands[0], constm1_rtx);
9491      else
9492	ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9493    }
9494  else
9495    ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9496
9497  if (operands[5] == const0_rtx)
9498    emit_move_insn (operands[3], operands[4]);
9499  else if (operands[5] == constm1_rtx)
9500    {
9501      if (<CODE> == IOR)
9502	emit_move_insn (operands[3], constm1_rtx);
9503      else
9504	ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9505    }
9506  else
9507    ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9508
9509  DONE;
9510})
9511
9512(define_insn "*<code><mode>_1"
9513  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r")
9514	(any_or:SWI248
9515	 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9516	 (match_operand:SWI248 2 "<general_operand>" "r<i>,m")))
9517   (clobber (reg:CC FLAGS_REG))]
9518  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9519  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9520  [(set_attr "type" "alu")
9521   (set_attr "mode" "<MODE>")])
9522
9523(define_insn_and_split "*iordi_1_bts"
9524  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9525	(ior:DI
9526	 (match_operand:DI 1 "nonimmediate_operand" "%0")
9527	 (match_operand:DI 2 "const_int_operand" "n")))
9528   (clobber (reg:CC FLAGS_REG))]
9529  "TARGET_64BIT && TARGET_USE_BT
9530   && ix86_binary_operator_ok (IOR, DImode, operands)
9531   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9532  "#"
9533  "&& reload_completed"
9534  [(parallel [(set (zero_extract:DI (match_dup 0)
9535				    (const_int 1)
9536				    (match_dup 3))
9537		   (const_int 1))
9538	      (clobber (reg:CC FLAGS_REG))])]
9539  "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9540  [(set_attr "type" "alu1")
9541   (set_attr "prefix_0f" "1")
9542   (set_attr "znver1_decode" "double")
9543   (set_attr "mode" "DI")])
9544
9545(define_insn_and_split "*xordi_1_btc"
9546  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9547	(xor:DI
9548	 (match_operand:DI 1 "nonimmediate_operand" "%0")
9549	 (match_operand:DI 2 "const_int_operand" "n")))
9550   (clobber (reg:CC FLAGS_REG))]
9551  "TARGET_64BIT && TARGET_USE_BT
9552   && ix86_binary_operator_ok (XOR, DImode, operands)
9553   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9554  "#"
9555  "&& reload_completed"
9556  [(parallel [(set (zero_extract:DI (match_dup 0)
9557				    (const_int 1)
9558				    (match_dup 3))
9559		   (not:DI (zero_extract:DI (match_dup 0)
9560					    (const_int 1)
9561					    (match_dup 3))))
9562	      (clobber (reg:CC FLAGS_REG))])]
9563  "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9564  [(set_attr "type" "alu1")
9565   (set_attr "prefix_0f" "1")
9566   (set_attr "znver1_decode" "double")
9567   (set_attr "mode" "DI")])
9568
9569;; See comment for addsi_1_zext why we do use nonimmediate_operand
9570(define_insn "*<code>si_1_zext"
9571  [(set (match_operand:DI 0 "register_operand" "=r")
9572	(zero_extend:DI
9573	 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9574		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9575   (clobber (reg:CC FLAGS_REG))]
9576  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9577  "<logic>{l}\t{%2, %k0|%k0, %2}"
9578  [(set_attr "type" "alu")
9579   (set_attr "mode" "SI")])
9580
9581(define_insn "*<code>si_1_zext_imm"
9582  [(set (match_operand:DI 0 "register_operand" "=r")
9583	(any_or:DI
9584	 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9585	 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9586   (clobber (reg:CC FLAGS_REG))]
9587  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9588  "<logic>{l}\t{%2, %k0|%k0, %2}"
9589  [(set_attr "type" "alu")
9590   (set_attr "mode" "SI")])
9591
9592(define_insn "*<code>qi_1"
9593  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9594	(any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9595		   (match_operand:QI 2 "general_operand" "qn,m,rn")))
9596   (clobber (reg:CC FLAGS_REG))]
9597  "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9598  "@
9599   <logic>{b}\t{%2, %0|%0, %2}
9600   <logic>{b}\t{%2, %0|%0, %2}
9601   <logic>{l}\t{%k2, %k0|%k0, %k2}"
9602  [(set_attr "type" "alu")
9603   (set_attr "mode" "QI,QI,SI")
9604   ;; Potential partial reg stall on alternative 2.
9605   (set (attr "preferred_for_speed")
9606     (cond [(eq_attr "alternative" "2")
9607	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9608	   (symbol_ref "true")))])
9609
9610(define_insn "*<code><mode>_1_slp"
9611  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9612	(any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9613		      (match_operand:SWI12 2 "general_operand" "<r>mn")))
9614   (clobber (reg:CC FLAGS_REG))]
9615  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9616   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9617   && (rtx_equal_p (operands[0], operands[1])
9618       || rtx_equal_p (operands[0], operands[2]))"
9619  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9620  [(set_attr "type" "alu")
9621   (set_attr "mode" "<MODE>")])
9622
9623(define_insn "*<code><mode>_2"
9624  [(set (reg FLAGS_REG)
9625	(compare (any_or:SWI
9626		  (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9627		  (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
9628		 (const_int 0)))
9629   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9630	(any_or:SWI (match_dup 1) (match_dup 2)))]
9631  "ix86_match_ccmode (insn, CCNOmode)
9632   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9633  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9634  [(set_attr "type" "alu")
9635   (set_attr "mode" "<MODE>")])
9636
9637;; See comment for addsi_1_zext why we do use nonimmediate_operand
9638;; ??? Special case for immediate operand is missing - it is tricky.
9639(define_insn "*<code>si_2_zext"
9640  [(set (reg FLAGS_REG)
9641	(compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9642			    (match_operand:SI 2 "x86_64_general_operand" "rme"))
9643		 (const_int 0)))
9644   (set (match_operand:DI 0 "register_operand" "=r")
9645	(zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9646  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9647   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9648  "<logic>{l}\t{%2, %k0|%k0, %2}"
9649  [(set_attr "type" "alu")
9650   (set_attr "mode" "SI")])
9651
9652(define_insn "*<code>si_2_zext_imm"
9653  [(set (reg FLAGS_REG)
9654	(compare (any_or:SI
9655		  (match_operand:SI 1 "nonimmediate_operand" "%0")
9656		  (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9657		 (const_int 0)))
9658   (set (match_operand:DI 0 "register_operand" "=r")
9659	(any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9660  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9661   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9662  "<logic>{l}\t{%2, %k0|%k0, %2}"
9663  [(set_attr "type" "alu")
9664   (set_attr "mode" "SI")])
9665
9666(define_insn "*<code><mode>_3"
9667  [(set (reg FLAGS_REG)
9668	(compare (any_or:SWI
9669		  (match_operand:SWI 1 "nonimmediate_operand" "%0")
9670		  (match_operand:SWI 2 "<general_operand>" "<g>"))
9671		 (const_int 0)))
9672   (clobber (match_scratch:SWI 0 "=<r>"))]
9673  "ix86_match_ccmode (insn, CCNOmode)
9674   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9675  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9676  [(set_attr "type" "alu")
9677   (set_attr "mode" "<MODE>")])
9678
9679(define_insn "*<code>qi_ext_1"
9680  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9681			 (const_int 8)
9682			 (const_int 8))
9683	(subreg:SI
9684	  (any_or:QI
9685	    (subreg:QI
9686	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9687			       (const_int 8)
9688			       (const_int 8)) 0)
9689	    (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9690   (clobber (reg:CC FLAGS_REG))]
9691  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9692   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9693   && rtx_equal_p (operands[0], operands[1])"
9694  "<logic>{b}\t{%2, %h0|%h0, %2}"
9695  [(set_attr "isa" "*,nox64")
9696   (set_attr "type" "alu")
9697   (set_attr "mode" "QI")])
9698
9699(define_insn "*<code>qi_ext_2"
9700  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9701			 (const_int 8)
9702			 (const_int 8))
9703	(subreg:SI
9704	  (any_or:QI
9705	    (subreg:QI
9706	      (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9707			       (const_int 8)
9708			       (const_int 8)) 0)
9709	    (subreg:QI
9710	      (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9711			       (const_int 8)
9712			       (const_int 8)) 0)) 0))
9713   (clobber (reg:CC FLAGS_REG))]
9714  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9715   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9716   && (rtx_equal_p (operands[0], operands[1])
9717       || rtx_equal_p (operands[0], operands[2]))"
9718  "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9719  [(set_attr "type" "alu")
9720   (set_attr "mode" "QI")])
9721
9722;; Convert wide OR instructions with immediate operand to shorter QImode
9723;; equivalents when possible.
9724;; Don't do the splitting with memory operands, since it introduces risk
9725;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9726;; for size, but that can (should?) be handled by generic code instead.
9727(define_split
9728  [(set (match_operand:SWI248 0 "QIreg_operand")
9729	(any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9730		       (match_operand:SWI248 2 "const_int_operand")))
9731   (clobber (reg:CC FLAGS_REG))]
9732   "reload_completed
9733    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9734    && !(INTVAL (operands[2]) & ~(255 << 8))"
9735  [(parallel
9736     [(set (zero_extract:SI (match_dup 0)
9737			    (const_int 8)
9738			    (const_int 8))
9739	   (subreg:SI
9740	     (any_or:QI
9741	       (subreg:QI
9742		 (zero_extract:SI (match_dup 1)
9743				  (const_int 8)
9744				  (const_int 8)) 0)
9745	       (match_dup 2)) 0))
9746      (clobber (reg:CC FLAGS_REG))])]
9747{
9748  operands[0] = gen_lowpart (SImode, operands[0]);
9749  operands[1] = gen_lowpart (SImode, operands[1]);
9750  operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9751})
9752
9753;; Since OR can be encoded with sign extended immediate, this is only
9754;; profitable when 7th bit is set.
9755(define_split
9756  [(set (match_operand:SWI248 0 "any_QIreg_operand")
9757	(any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9758		       (match_operand:SWI248 2 "const_int_operand")))
9759   (clobber (reg:CC FLAGS_REG))]
9760   "reload_completed
9761    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9762    && !(INTVAL (operands[2]) & ~255)
9763    && (INTVAL (operands[2]) & 128)"
9764  [(parallel [(set (strict_low_part (match_dup 0))
9765		   (any_or:QI (match_dup 1)
9766			      (match_dup 2)))
9767	      (clobber (reg:CC FLAGS_REG))])]
9768{
9769  operands[0] = gen_lowpart (QImode, operands[0]);
9770  operands[1] = gen_lowpart (QImode, operands[1]);
9771  operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9772})
9773
9774(define_expand "xorqi_ext_1_cc"
9775  [(parallel [
9776     (set (reg:CCNO FLAGS_REG)
9777	  (compare:CCNO
9778	    (xor:QI
9779	      (subreg:QI
9780		(zero_extract:SI (match_operand 1 "ext_register_operand")
9781				 (const_int 8)
9782				 (const_int 8)) 0)
9783	      (match_operand 2 "const_int_operand"))
9784	    (const_int 0)))
9785     (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9786			   (const_int 8)
9787			   (const_int 8))
9788	  (subreg:SI
9789	    (xor:QI
9790	      (subreg:QI
9791		(zero_extract:SI (match_dup 1)
9792				 (const_int 8)
9793				 (const_int 8)) 0)
9794	    (match_dup 2)) 0))])])
9795
9796(define_insn "*xorqi_ext_1_cc"
9797  [(set (reg FLAGS_REG)
9798	(compare
9799	  (xor:QI
9800	    (subreg:QI
9801	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9802			       (const_int 8)
9803			       (const_int 8)) 0)
9804	    (match_operand:QI 2 "general_operand" "QnBc,m"))
9805	  (const_int 0)))
9806   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9807			 (const_int 8)
9808			 (const_int 8))
9809	(subreg:SI
9810	  (xor:QI
9811	    (subreg:QI
9812	      (zero_extract:SI (match_dup 1)
9813			       (const_int 8)
9814			       (const_int 8)) 0)
9815	  (match_dup 2)) 0))]
9816  "ix86_match_ccmode (insn, CCNOmode)
9817   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9818   && rtx_equal_p (operands[0], operands[1])"
9819  "xor{b}\t{%2, %h0|%h0, %2}"
9820  [(set_attr "isa" "*,nox64")
9821   (set_attr "type" "alu")
9822   (set_attr "mode" "QI")])
9823
9824;; Negation instructions
9825
9826(define_expand "neg<mode>2"
9827  [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9828	(neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9829  ""
9830  "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9831
9832(define_insn_and_split "*neg<dwi>2_doubleword"
9833  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9834	(neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9835   (clobber (reg:CC FLAGS_REG))]
9836  "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9837  "#"
9838  "reload_completed"
9839  [(parallel
9840    [(set (reg:CCZ FLAGS_REG)
9841	  (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9842     (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9843   (parallel
9844    [(set (match_dup 2)
9845	  (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9846				(match_dup 3))
9847		     (const_int 0)))
9848     (clobber (reg:CC FLAGS_REG))])
9849   (parallel
9850    [(set (match_dup 2)
9851	  (neg:DWIH (match_dup 2)))
9852     (clobber (reg:CC FLAGS_REG))])]
9853  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9854
9855(define_insn "*neg<mode>2_1"
9856  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9857	(neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9858   (clobber (reg:CC FLAGS_REG))]
9859  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9860  "neg{<imodesuffix>}\t%0"
9861  [(set_attr "type" "negnot")
9862   (set_attr "mode" "<MODE>")])
9863
9864(define_insn "*negsi2_1_zext"
9865  [(set (match_operand:DI 0 "register_operand" "=r")
9866	(zero_extend:DI
9867	  (neg:SI (match_operand:SI 1 "register_operand" "0"))))
9868   (clobber (reg:CC FLAGS_REG))]
9869  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9870  "neg{l}\t%k0"
9871  [(set_attr "type" "negnot")
9872   (set_attr "mode" "SI")])
9873
9874;; The problem with neg is that it does not perform (compare x 0),
9875;; it really performs (compare 0 x), which leaves us with the zero
9876;; flag being the only useful item.
9877
9878(define_insn "*neg<mode>2_cmpz"
9879  [(set (reg:CCZ FLAGS_REG)
9880	(compare:CCZ
9881	  (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9882		   (const_int 0)))
9883   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9884	(neg:SWI (match_dup 1)))]
9885  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9886  "neg{<imodesuffix>}\t%0"
9887  [(set_attr "type" "negnot")
9888   (set_attr "mode" "<MODE>")])
9889
9890(define_insn "*negsi2_cmpz_zext"
9891  [(set (reg:CCZ FLAGS_REG)
9892	(compare:CCZ
9893	  (neg:SI (match_operand:SI 1 "register_operand" "0"))
9894	  (const_int 0)))
9895   (set (match_operand:DI 0 "register_operand" "=r")
9896	(zero_extend:DI
9897	  (neg:SI (match_dup 1))))]
9898  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9899  "neg{l}\t%k0"
9900  [(set_attr "type" "negnot")
9901   (set_attr "mode" "SI")])
9902
9903;; Negate with jump on overflow.
9904(define_expand "negv<mode>3"
9905  [(parallel [(set (reg:CCO FLAGS_REG)
9906		   (ne:CCO (match_operand:SWI 1 "register_operand")
9907			   (match_dup 3)))
9908	      (set (match_operand:SWI 0 "register_operand")
9909		   (neg:SWI (match_dup 1)))])
9910   (set (pc) (if_then_else
9911	       (eq (reg:CCO FLAGS_REG) (const_int 0))
9912	       (label_ref (match_operand 2))
9913	       (pc)))]
9914  ""
9915{
9916  operands[3]
9917    = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9918		    <MODE>mode);
9919})
9920
9921(define_insn "*negv<mode>3"
9922  [(set (reg:CCO FLAGS_REG)
9923	(ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9924		(match_operand:SWI 2 "const_int_operand")))
9925   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9926	(neg:SWI (match_dup 1)))]
9927  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9928   && mode_signbit_p (<MODE>mode, operands[2])"
9929  "neg{<imodesuffix>}\t%0"
9930  [(set_attr "type" "negnot")
9931   (set_attr "mode" "<MODE>")])
9932
9933(define_expand "<code>tf2"
9934  [(set (match_operand:TF 0 "register_operand")
9935	(absneg:TF (match_operand:TF 1 "register_operand")))]
9936  "TARGET_SSE"
9937  "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9938
9939(define_insn "*<code>tf2_1"
9940  [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
9941	(absneg:TF
9942	  (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
9943   (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))
9944   (clobber (reg:CC FLAGS_REG))]
9945  "TARGET_SSE"
9946  "#"
9947  [(set_attr "isa" "noavx,noavx,avx,avx")])
9948
9949(define_insn "*nabstf2_1"
9950  [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
9951	(neg:TF
9952	  (abs:TF
9953	    (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
9954   (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
9955  "TARGET_SSE"
9956  "#"
9957  [(set_attr "isa" "noavx,noavx,avx,avx")])
9958
9959;; Special expand pattern to handle integer mode abs
9960
9961(define_expand "abs<mode>2"
9962  [(set (match_operand:SWI48x 0 "register_operand")
9963    (abs:SWI48x
9964      (match_operand:SWI48x 1 "register_operand")))]
9965  "TARGET_EXPAND_ABS"
9966  {
9967    machine_mode mode = <MODE>mode;
9968
9969    /* Generate rtx abs using abs (x) = (((signed) x >> (W-1)) ^ x) -
9970       ((signed) x >> (W-1)) */
9971    rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
9972    rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
9973					 shift_amount, NULL_RTX,
9974					 0, OPTAB_DIRECT);
9975    rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
9976				       operands[0], 0, OPTAB_DIRECT);
9977    rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
9978					 operands[0], 0, OPTAB_DIRECT);
9979    if (!rtx_equal_p (minus_dst, operands[0]))
9980      emit_move_insn (operands[0], minus_dst);
9981    DONE;
9982  })
9983
9984(define_expand "<code><mode>2"
9985  [(set (match_operand:X87MODEF 0 "register_operand")
9986	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9987  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9988  "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9989
9990;; Changing of sign for FP values is doable using integer unit too.
9991(define_insn "*<code><mode>2_i387_1"
9992  [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9993	(absneg:X87MODEF
9994	  (match_operand:X87MODEF 1 "register_operand" "0,0")))
9995   (clobber (reg:CC FLAGS_REG))]
9996  "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9997  "#")
9998
9999(define_split
10000  [(set (match_operand:X87MODEF 0 "fp_register_operand")
10001	(absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
10002   (clobber (reg:CC FLAGS_REG))]
10003  "TARGET_80387 && reload_completed"
10004  [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
10005
10006(define_split
10007  [(set (match_operand:X87MODEF 0 "general_reg_operand")
10008	(absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
10009   (clobber (reg:CC FLAGS_REG))]
10010  "TARGET_80387 && reload_completed"
10011  [(const_int 0)]
10012  "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10013
10014(define_insn "*<code><mode>2_1"
10015  [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
10016	(absneg:MODEF
10017	  (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
10018   (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
10019   (clobber (reg:CC FLAGS_REG))]
10020  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10021  "#"
10022  [(set_attr "isa" "noavx,noavx,avx,*,*")
10023   (set (attr "enabled")
10024     (if_then_else
10025       (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
10026       (if_then_else
10027	 (eq_attr "alternative" "3,4")
10028	 (symbol_ref "TARGET_MIX_SSE_I387")
10029	 (const_string "*"))
10030       (if_then_else
10031	 (eq_attr "alternative" "3,4")
10032	 (symbol_ref "true")
10033	 (symbol_ref "false"))))])
10034
10035(define_split
10036  [(set (match_operand:SSEMODEF 0 "sse_reg_operand")
10037	(absneg:SSEMODEF
10038	  (match_operand:SSEMODEF 1 "vector_operand")))
10039   (use (match_operand:<ssevecmodef> 2 "vector_operand"))
10040   (clobber (reg:CC FLAGS_REG))]
10041  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10042    || (TARGET_SSE && (<MODE>mode == TFmode)))
10043   && reload_completed"
10044  [(set (match_dup 0) (match_dup 3))]
10045{
10046  machine_mode mode = <MODE>mode;
10047  machine_mode vmode = <ssevecmodef>mode;
10048  enum rtx_code absneg_op = <CODE> == ABS ? AND : XOR;
10049
10050  operands[0] = lowpart_subreg (vmode, operands[0], mode);
10051  operands[1] = lowpart_subreg (vmode, operands[1], mode);
10052
10053  if (TARGET_AVX)
10054    {
10055      if (MEM_P (operands[1]))
10056        std::swap (operands[1], operands[2]);
10057    }
10058  else
10059   {
10060     if (operands_match_p (operands[0], operands[2]))
10061       std::swap (operands[1], operands[2]);
10062   }
10063
10064  operands[3]
10065    = gen_rtx_fmt_ee (absneg_op, vmode, operands[1], operands[2]);
10066})
10067
10068(define_split
10069  [(set (match_operand:MODEF 0 "fp_register_operand")
10070	(absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
10071   (use (match_operand 2))
10072   (clobber (reg:CC FLAGS_REG))]
10073  "TARGET_80387 && reload_completed"
10074  [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
10075
10076(define_split
10077  [(set (match_operand:MODEF 0 "general_reg_operand")
10078	(absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
10079   (use (match_operand 2))
10080   (clobber (reg:CC FLAGS_REG))]
10081  "TARGET_80387 && reload_completed"
10082  [(const_int 0)]
10083  "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10084
10085(define_insn "*nabs<mode>2_1"
10086  [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
10087	(neg:MODEF
10088	  (abs:MODEF
10089	    (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
10090   (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
10091  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10092  "#"
10093  [(set_attr "isa" "noavx,noavx,avx")])
10094
10095(define_split
10096  [(set (match_operand:SSEMODEF 0 "sse_reg_operand")
10097	(neg:SSEMODEF
10098	  (abs:SSEMODEF
10099	    (match_operand:SSEMODEF 1 "vector_operand"))))
10100   (use (match_operand:<ssevecmodef> 2 "vector_operand"))]
10101  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10102    || (TARGET_SSE && (<MODE>mode == TFmode)))
10103   && reload_completed"
10104  [(set (match_dup 0) (match_dup 3))]
10105{
10106  machine_mode mode = <MODE>mode;
10107  machine_mode vmode = <ssevecmodef>mode;
10108
10109  operands[0] = lowpart_subreg (vmode, operands[0], mode);
10110  operands[1] = lowpart_subreg (vmode, operands[1], mode);
10111
10112  if (TARGET_AVX)
10113    {
10114      if (MEM_P (operands[1]))
10115        std::swap (operands[1], operands[2]);
10116    }
10117  else
10118   {
10119     if (operands_match_p (operands[0], operands[2]))
10120       std::swap (operands[1], operands[2]);
10121   }
10122
10123  operands[3]
10124    = gen_rtx_fmt_ee (IOR, vmode, operands[1], operands[2]);
10125})
10126
10127;; Conditionalize these after reload. If they match before reload, we
10128;; lose the clobber and ability to use integer instructions.
10129
10130(define_insn "*<code><mode>2_i387"
10131  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10132	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10133  "TARGET_80387 && reload_completed"
10134  "<absneg_mnemonic>"
10135  [(set_attr "type" "fsgn")
10136   (set_attr "mode" "<MODE>")])
10137
10138;; Copysign instructions
10139
10140(define_expand "copysign<mode>3"
10141  [(match_operand:SSEMODEF 0 "register_operand")
10142   (match_operand:SSEMODEF 1 "nonmemory_operand")
10143   (match_operand:SSEMODEF 2 "register_operand")]
10144  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10145   || (TARGET_SSE && (<MODE>mode == TFmode))"
10146  "ix86_expand_copysign (operands); DONE;")
10147
10148(define_insn_and_split "@copysign<mode>3_const"
10149  [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv")
10150	(unspec:SSEMODEF
10151	  [(match_operand:<ssevecmodef> 1 "nonimm_or_0_operand" "YvmC")
10152	   (match_operand:SSEMODEF 2 "register_operand" "0")
10153	   (match_operand:<ssevecmodef> 3 "nonimmediate_operand" "Yvm")]
10154	  UNSPEC_COPYSIGN))]
10155  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10156   || (TARGET_SSE && (<MODE>mode == TFmode))"
10157  "#"
10158  "&& reload_completed"
10159  [(const_int 0)]
10160  "ix86_split_copysign_const (operands); DONE;")
10161
10162(define_insn "@copysign<mode>3_var"
10163  [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10164	(unspec:SSEMODEF
10165	  [(match_operand:SSEMODEF 2 "register_operand"	"Yv,0,0,Yv,Yv")
10166	   (match_operand:SSEMODEF 3 "register_operand"	"1,1,Yv,1,Yv")
10167	   (match_operand:<ssevecmodef> 4
10168	     "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10169	   (match_operand:<ssevecmodef> 5
10170	     "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10171	  UNSPEC_COPYSIGN))
10172   (clobber (match_scratch:<ssevecmodef> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10173  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10174   || (TARGET_SSE && (<MODE>mode == TFmode))"
10175  "#")
10176
10177(define_split
10178  [(set (match_operand:SSEMODEF 0 "register_operand")
10179	(unspec:SSEMODEF
10180	  [(match_operand:SSEMODEF 2 "register_operand")
10181	   (match_operand:SSEMODEF 3 "register_operand")
10182	   (match_operand:<ssevecmodef> 4)
10183	   (match_operand:<ssevecmodef> 5)]
10184	  UNSPEC_COPYSIGN))
10185   (clobber (match_scratch:<ssevecmodef> 1))]
10186  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10187    || (TARGET_SSE && (<MODE>mode == TFmode)))
10188   && reload_completed"
10189  [(const_int 0)]
10190  "ix86_split_copysign_var (operands); DONE;")
10191
10192(define_expand "xorsign<mode>3"
10193  [(match_operand:MODEF 0 "register_operand")
10194   (match_operand:MODEF 1 "register_operand")
10195   (match_operand:MODEF 2 "register_operand")]
10196  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10197{
10198  if (rtx_equal_p (operands[1], operands[2]))
10199    emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
10200  else
10201    ix86_expand_xorsign (operands);
10202  DONE;
10203})
10204
10205(define_insn_and_split "@xorsign<mode>3_1"
10206  [(set (match_operand:MODEF 0 "register_operand" "=&Yv")
10207	(unspec:MODEF
10208	  [(match_operand:MODEF 1 "register_operand" "Yv")
10209	   (match_operand:MODEF 2 "register_operand" "0")
10210	   (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
10211	  UNSPEC_XORSIGN))]
10212  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10213  "#"
10214  "&& reload_completed"
10215  [(const_int 0)]
10216  "ix86_split_xorsign (operands); DONE;")
10217
10218;; One complement instructions
10219
10220(define_expand "one_cmpl<mode>2"
10221  [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
10222	(not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))]
10223  ""
10224  "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10225
10226(define_insn_and_split "*one_cmpldi2_doubleword"
10227  [(set (match_operand:DI 0 "nonimmediate_operand")
10228	(not:DI (match_operand:DI 1 "nonimmediate_operand")))]
10229  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10230   && ix86_unary_operator_ok (NOT, DImode, operands)
10231   && ix86_pre_reload_split ()"
10232  "#"
10233  "&& 1"
10234  [(set (match_dup 0)
10235	(not:SI (match_dup 1)))
10236   (set (match_dup 2)
10237	(not:SI (match_dup 3)))]
10238  "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10239
10240(define_insn "*one_cmpl<mode>2_1"
10241  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10242	(not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10243  "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10244  "not{<imodesuffix>}\t%0"
10245  [(set_attr "type" "negnot")
10246   (set_attr "mode" "<MODE>")])
10247
10248(define_insn "*one_cmplsi2_1_zext"
10249  [(set (match_operand:DI 0 "register_operand" "=r")
10250	(zero_extend:DI
10251	  (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10252  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10253  "not{l}\t%k0"
10254  [(set_attr "type" "negnot")
10255   (set_attr "mode" "SI")])
10256
10257(define_insn "*one_cmplqi2_1"
10258  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10259	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10260  "ix86_unary_operator_ok (NOT, QImode, operands)"
10261  "@
10262   not{b}\t%0
10263   not{l}\t%k0"
10264  [(set_attr "type" "negnot")
10265   (set_attr "mode" "QI,SI")
10266   ;; Potential partial reg stall on alternative 1.
10267   (set (attr "preferred_for_speed")
10268     (cond [(eq_attr "alternative" "1")
10269	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10270	   (symbol_ref "true")))])
10271
10272(define_insn "*one_cmpl<mode>2_2"
10273  [(set (reg FLAGS_REG)
10274	(compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10275		 (const_int 0)))
10276   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10277	(not:SWI (match_dup 1)))]
10278  "ix86_match_ccmode (insn, CCNOmode)
10279   && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10280  "#"
10281  [(set_attr "type" "alu1")
10282   (set_attr "mode" "<MODE>")])
10283
10284(define_split
10285  [(set (match_operand 0 "flags_reg_operand")
10286	(match_operator 2 "compare_operator"
10287	  [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10288	   (const_int 0)]))
10289   (set (match_operand:SWI 1 "nonimmediate_operand")
10290	(not:SWI (match_dup 3)))]
10291  "ix86_match_ccmode (insn, CCNOmode)"
10292  [(parallel [(set (match_dup 0)
10293		   (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10294				    (const_int 0)]))
10295	      (set (match_dup 1)
10296		   (xor:SWI (match_dup 3) (const_int -1)))])])
10297
10298(define_insn "*one_cmplsi2_2_zext"
10299  [(set (reg FLAGS_REG)
10300	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10301		 (const_int 0)))
10302   (set (match_operand:DI 0 "register_operand" "=r")
10303	(zero_extend:DI (not:SI (match_dup 1))))]
10304  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10305   && ix86_unary_operator_ok (NOT, SImode, operands)"
10306  "#"
10307  [(set_attr "type" "alu1")
10308   (set_attr "mode" "SI")])
10309
10310(define_split
10311  [(set (match_operand 0 "flags_reg_operand")
10312	(match_operator 2 "compare_operator"
10313	  [(not:SI (match_operand:SI 3 "register_operand"))
10314	   (const_int 0)]))
10315   (set (match_operand:DI 1 "register_operand")
10316	(zero_extend:DI (not:SI (match_dup 3))))]
10317  "ix86_match_ccmode (insn, CCNOmode)"
10318  [(parallel [(set (match_dup 0)
10319		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10320				    (const_int 0)]))
10321	      (set (match_dup 1)
10322		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10323
10324;; Shift instructions
10325
10326;; DImode shifts are implemented using the i386 "shift double" opcode,
10327;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10328;; is variable, then the count is in %cl and the "imm" operand is dropped
10329;; from the assembler input.
10330;;
10331;; This instruction shifts the target reg/mem as usual, but instead of
10332;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10333;; is a left shift double, bits are taken from the high order bits of
10334;; reg, else if the insn is a shift right double, bits are taken from the
10335;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10336;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10337;;
10338;; Since sh[lr]d does not change the `reg' operand, that is done
10339;; separately, making all shifts emit pairs of shift double and normal
10340;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10341;; support a 63 bit shift, each shift where the count is in a reg expands
10342;; to a pair of shifts, a branch, a shift by 32 and a label.
10343;;
10344;; If the shift count is a constant, we need never emit more than one
10345;; shift pair, instead using moves and sign extension for counts greater
10346;; than 31.
10347
10348(define_expand "ashl<mode>3"
10349  [(set (match_operand:SDWIM 0 "<shift_operand>")
10350	(ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10351		      (match_operand:QI 2 "nonmemory_operand")))]
10352  ""
10353  "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10354
10355(define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10356  [(set (match_operand:<DWI> 0 "register_operand")
10357	(ashift:<DWI>
10358	  (match_operand:<DWI> 1 "register_operand")
10359	  (subreg:QI
10360	    (and:SI
10361	      (match_operand:SI 2 "register_operand" "c")
10362	      (match_operand:SI 3 "const_int_operand")) 0)))
10363   (clobber (reg:CC FLAGS_REG))]
10364  "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10365   && ix86_pre_reload_split ()"
10366  "#"
10367  "&& 1"
10368  [(parallel
10369     [(set (match_dup 6)
10370	   (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10371		     (lshiftrt:DWIH (match_dup 5)
10372		       (minus:QI (match_dup 8) (match_dup 2)))))
10373      (clobber (reg:CC FLAGS_REG))])
10374   (parallel
10375     [(set (match_dup 4)
10376	   (ashift:DWIH (match_dup 5) (match_dup 2)))
10377      (clobber (reg:CC FLAGS_REG))])]
10378{
10379  split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10380
10381  operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10382
10383  if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10384      != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10385    {
10386      rtx tem = gen_reg_rtx (SImode);
10387      emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10388      operands[2] = tem;
10389    }
10390
10391  operands[2] = gen_lowpart (QImode, operands[2]);
10392
10393  if (!rtx_equal_p (operands[6], operands[7]))
10394    emit_move_insn (operands[6], operands[7]);
10395})
10396
10397(define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10398  [(set (match_operand:<DWI> 0 "register_operand")
10399	(ashift:<DWI>
10400	  (match_operand:<DWI> 1 "register_operand")
10401	  (and:QI
10402	    (match_operand:QI 2 "register_operand" "c")
10403	    (match_operand:QI 3 "const_int_operand"))))
10404   (clobber (reg:CC FLAGS_REG))]
10405  "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10406   && ix86_pre_reload_split ()"
10407  "#"
10408  "&& 1"
10409  [(parallel
10410     [(set (match_dup 6)
10411	   (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10412		     (lshiftrt:DWIH (match_dup 5)
10413		       (minus:QI (match_dup 8) (match_dup 2)))))
10414      (clobber (reg:CC FLAGS_REG))])
10415   (parallel
10416     [(set (match_dup 4)
10417	   (ashift:DWIH (match_dup 5) (match_dup 2)))
10418      (clobber (reg:CC FLAGS_REG))])]
10419{
10420  split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10421
10422  operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10423
10424  if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10425      != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10426    {
10427      rtx tem = gen_reg_rtx (QImode);
10428      emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10429      operands[2] = tem;
10430    }
10431
10432  if (!rtx_equal_p (operands[6], operands[7]))
10433    emit_move_insn (operands[6], operands[7]);
10434})
10435
10436(define_insn "*ashl<mode>3_doubleword"
10437  [(set (match_operand:DWI 0 "register_operand" "=&r")
10438	(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10439		    (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10440   (clobber (reg:CC FLAGS_REG))]
10441  ""
10442  "#"
10443  [(set_attr "type" "multi")])
10444
10445(define_split
10446  [(set (match_operand:DWI 0 "register_operand")
10447	(ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10448		    (match_operand:QI 2 "nonmemory_operand")))
10449   (clobber (reg:CC FLAGS_REG))]
10450  "epilogue_completed"
10451  [(const_int 0)]
10452  "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10453
10454;; By default we don't ask for a scratch register, because when DWImode
10455;; values are manipulated, registers are already at a premium.  But if
10456;; we have one handy, we won't turn it away.
10457
10458(define_peephole2
10459  [(match_scratch:DWIH 3 "r")
10460   (parallel [(set (match_operand:<DWI> 0 "register_operand")
10461		   (ashift:<DWI>
10462		     (match_operand:<DWI> 1 "nonmemory_operand")
10463		     (match_operand:QI 2 "nonmemory_operand")))
10464	      (clobber (reg:CC FLAGS_REG))])
10465   (match_dup 3)]
10466  "TARGET_CMOVE"
10467  [(const_int 0)]
10468  "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10469
10470(define_insn "x86_64_shld"
10471  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10472        (ior:DI (ashift:DI (match_dup 0)
10473		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
10474		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10475		  (minus:QI (const_int 64) (match_dup 2)))))
10476   (clobber (reg:CC FLAGS_REG))]
10477  "TARGET_64BIT"
10478  "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10479  [(set_attr "type" "ishift")
10480   (set_attr "prefix_0f" "1")
10481   (set_attr "mode" "DI")
10482   (set_attr "athlon_decode" "vector")
10483   (set_attr "amdfam10_decode" "vector")
10484   (set_attr "bdver1_decode" "vector")])
10485
10486(define_insn "x86_shld"
10487  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10488        (ior:SI (ashift:SI (match_dup 0)
10489		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
10490		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10491		  (minus:QI (const_int 32) (match_dup 2)))))
10492   (clobber (reg:CC FLAGS_REG))]
10493  ""
10494  "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10495  [(set_attr "type" "ishift")
10496   (set_attr "prefix_0f" "1")
10497   (set_attr "mode" "SI")
10498   (set_attr "pent_pair" "np")
10499   (set_attr "athlon_decode" "vector")
10500   (set_attr "amdfam10_decode" "vector")
10501   (set_attr "bdver1_decode" "vector")])
10502
10503(define_expand "@x86_shift<mode>_adj_1"
10504  [(set (reg:CCZ FLAGS_REG)
10505	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10506			     (match_dup 4))
10507		     (const_int 0)))
10508   (set (match_operand:SWI48 0 "register_operand")
10509        (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10510			    (match_operand:SWI48 1 "register_operand")
10511			    (match_dup 0)))
10512   (set (match_dup 1)
10513	(if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10514			    (match_operand:SWI48 3 "register_operand")
10515			    (match_dup 1)))]
10516  "TARGET_CMOVE"
10517  "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10518
10519(define_expand "@x86_shift<mode>_adj_2"
10520  [(use (match_operand:SWI48 0 "register_operand"))
10521   (use (match_operand:SWI48 1 "register_operand"))
10522   (use (match_operand:QI 2 "register_operand"))]
10523  ""
10524{
10525  rtx_code_label *label = gen_label_rtx ();
10526  rtx tmp;
10527
10528  emit_insn (gen_testqi_ccz_1 (operands[2],
10529			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10530
10531  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10532  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10533  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10534			      gen_rtx_LABEL_REF (VOIDmode, label),
10535			      pc_rtx);
10536  tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10537  JUMP_LABEL (tmp) = label;
10538
10539  emit_move_insn (operands[0], operands[1]);
10540  ix86_expand_clear (operands[1]);
10541
10542  emit_label (label);
10543  LABEL_NUSES (label) = 1;
10544
10545  DONE;
10546})
10547
10548;; Avoid useless masking of count operand.
10549(define_insn_and_split "*ashl<mode>3_mask"
10550  [(set (match_operand:SWI48 0 "nonimmediate_operand")
10551	(ashift:SWI48
10552	  (match_operand:SWI48 1 "nonimmediate_operand")
10553	  (subreg:QI
10554	    (and:SI
10555	      (match_operand:SI 2 "register_operand" "c,r")
10556	      (match_operand:SI 3 "const_int_operand")) 0)))
10557   (clobber (reg:CC FLAGS_REG))]
10558  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10559   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10560      == GET_MODE_BITSIZE (<MODE>mode)-1
10561   && ix86_pre_reload_split ()"
10562  "#"
10563  "&& 1"
10564  [(parallel
10565     [(set (match_dup 0)
10566	   (ashift:SWI48 (match_dup 1)
10567			 (match_dup 2)))
10568      (clobber (reg:CC FLAGS_REG))])]
10569  "operands[2] = gen_lowpart (QImode, operands[2]);"
10570  [(set_attr "isa" "*,bmi2")])
10571
10572(define_insn_and_split "*ashl<mode>3_mask_1"
10573  [(set (match_operand:SWI48 0 "nonimmediate_operand")
10574	(ashift:SWI48
10575	  (match_operand:SWI48 1 "nonimmediate_operand")
10576	  (and:QI
10577	    (match_operand:QI 2 "register_operand" "c,r")
10578	    (match_operand:QI 3 "const_int_operand"))))
10579   (clobber (reg:CC FLAGS_REG))]
10580  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10581   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10582      == GET_MODE_BITSIZE (<MODE>mode)-1
10583   && ix86_pre_reload_split ()"
10584  "#"
10585  "&& 1"
10586  [(parallel
10587     [(set (match_dup 0)
10588	   (ashift:SWI48 (match_dup 1)
10589			 (match_dup 2)))
10590      (clobber (reg:CC FLAGS_REG))])]
10591  ""
10592  [(set_attr "isa" "*,bmi2")])
10593
10594(define_insn "*bmi2_ashl<mode>3_1"
10595  [(set (match_operand:SWI48 0 "register_operand" "=r")
10596	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10597		      (match_operand:SWI48 2 "register_operand" "r")))]
10598  "TARGET_BMI2"
10599  "shlx\t{%2, %1, %0|%0, %1, %2}"
10600  [(set_attr "type" "ishiftx")
10601   (set_attr "mode" "<MODE>")])
10602
10603(define_insn "*ashl<mode>3_1"
10604  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10605	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10606		      (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10607   (clobber (reg:CC FLAGS_REG))]
10608  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10609{
10610  switch (get_attr_type (insn))
10611    {
10612    case TYPE_LEA:
10613    case TYPE_ISHIFTX:
10614      return "#";
10615
10616    case TYPE_ALU:
10617      gcc_assert (operands[2] == const1_rtx);
10618      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10619      return "add{<imodesuffix>}\t%0, %0";
10620
10621    default:
10622      if (operands[2] == const1_rtx
10623	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10624	return "sal{<imodesuffix>}\t%0";
10625      else
10626	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10627    }
10628}
10629  [(set_attr "isa" "*,*,bmi2")
10630   (set (attr "type")
10631     (cond [(eq_attr "alternative" "1")
10632	      (const_string "lea")
10633	    (eq_attr "alternative" "2")
10634	      (const_string "ishiftx")
10635            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10636		      (match_operand 0 "register_operand"))
10637		 (match_operand 2 "const1_operand"))
10638	      (const_string "alu")
10639	   ]
10640	   (const_string "ishift")))
10641   (set (attr "length_immediate")
10642     (if_then_else
10643       (ior (eq_attr "type" "alu")
10644	    (and (eq_attr "type" "ishift")
10645		 (and (match_operand 2 "const1_operand")
10646		      (ior (match_test "TARGET_SHIFT1")
10647			   (match_test "optimize_function_for_size_p (cfun)")))))
10648       (const_string "0")
10649       (const_string "*")))
10650   (set_attr "mode" "<MODE>")])
10651
10652;; Convert shift to the shiftx pattern to avoid flags dependency.
10653(define_split
10654  [(set (match_operand:SWI48 0 "register_operand")
10655	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10656		      (match_operand:QI 2 "register_operand")))
10657   (clobber (reg:CC FLAGS_REG))]
10658  "TARGET_BMI2 && reload_completed"
10659  [(set (match_dup 0)
10660	(ashift:SWI48 (match_dup 1) (match_dup 2)))]
10661  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10662
10663(define_insn "*bmi2_ashlsi3_1_zext"
10664  [(set (match_operand:DI 0 "register_operand" "=r")
10665	(zero_extend:DI
10666	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10667		     (match_operand:SI 2 "register_operand" "r"))))]
10668  "TARGET_64BIT && TARGET_BMI2"
10669  "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10670  [(set_attr "type" "ishiftx")
10671   (set_attr "mode" "SI")])
10672
10673(define_insn "*ashlsi3_1_zext"
10674  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10675	(zero_extend:DI
10676	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10677		     (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10678   (clobber (reg:CC FLAGS_REG))]
10679  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10680{
10681  switch (get_attr_type (insn))
10682    {
10683    case TYPE_LEA:
10684    case TYPE_ISHIFTX:
10685      return "#";
10686
10687    case TYPE_ALU:
10688      gcc_assert (operands[2] == const1_rtx);
10689      return "add{l}\t%k0, %k0";
10690
10691    default:
10692      if (operands[2] == const1_rtx
10693	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10694	return "sal{l}\t%k0";
10695      else
10696	return "sal{l}\t{%2, %k0|%k0, %2}";
10697    }
10698}
10699  [(set_attr "isa" "*,*,bmi2")
10700   (set (attr "type")
10701     (cond [(eq_attr "alternative" "1")
10702	      (const_string "lea")
10703	    (eq_attr "alternative" "2")
10704	      (const_string "ishiftx")
10705            (and (match_test "TARGET_DOUBLE_WITH_ADD")
10706		 (match_operand 2 "const1_operand"))
10707	      (const_string "alu")
10708	   ]
10709	   (const_string "ishift")))
10710   (set (attr "length_immediate")
10711     (if_then_else
10712       (ior (eq_attr "type" "alu")
10713	    (and (eq_attr "type" "ishift")
10714		 (and (match_operand 2 "const1_operand")
10715		      (ior (match_test "TARGET_SHIFT1")
10716			   (match_test "optimize_function_for_size_p (cfun)")))))
10717       (const_string "0")
10718       (const_string "*")))
10719   (set_attr "mode" "SI")])
10720
10721;; Convert shift to the shiftx pattern to avoid flags dependency.
10722(define_split
10723  [(set (match_operand:DI 0 "register_operand")
10724	(zero_extend:DI
10725	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10726		     (match_operand:QI 2 "register_operand"))))
10727   (clobber (reg:CC FLAGS_REG))]
10728  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10729  [(set (match_dup 0)
10730	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10731  "operands[2] = gen_lowpart (SImode, operands[2]);")
10732
10733(define_insn "*ashlhi3_1"
10734  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10735	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10736		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10737   (clobber (reg:CC FLAGS_REG))]
10738  "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10739{
10740  switch (get_attr_type (insn))
10741    {
10742    case TYPE_LEA:
10743      return "#";
10744
10745    case TYPE_ALU:
10746      gcc_assert (operands[2] == const1_rtx);
10747      return "add{w}\t%0, %0";
10748
10749    default:
10750      if (operands[2] == const1_rtx
10751	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10752	return "sal{w}\t%0";
10753      else
10754	return "sal{w}\t{%2, %0|%0, %2}";
10755    }
10756}
10757  [(set (attr "type")
10758     (cond [(eq_attr "alternative" "1")
10759	      (const_string "lea")
10760            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10761		      (match_operand 0 "register_operand"))
10762		 (match_operand 2 "const1_operand"))
10763	      (const_string "alu")
10764	   ]
10765	   (const_string "ishift")))
10766   (set (attr "length_immediate")
10767     (if_then_else
10768       (ior (eq_attr "type" "alu")
10769	    (and (eq_attr "type" "ishift")
10770		 (and (match_operand 2 "const1_operand")
10771		      (ior (match_test "TARGET_SHIFT1")
10772			   (match_test "optimize_function_for_size_p (cfun)")))))
10773       (const_string "0")
10774       (const_string "*")))
10775   (set_attr "mode" "HI,SI")])
10776
10777(define_insn "*ashlqi3_1"
10778  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10779	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10780		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10781   (clobber (reg:CC FLAGS_REG))]
10782  "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10783{
10784  switch (get_attr_type (insn))
10785    {
10786    case TYPE_LEA:
10787      return "#";
10788
10789    case TYPE_ALU:
10790      gcc_assert (operands[2] == const1_rtx);
10791      if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10792        return "add{l}\t%k0, %k0";
10793      else
10794        return "add{b}\t%0, %0";
10795
10796    default:
10797      if (operands[2] == const1_rtx
10798	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10799	{
10800	  if (get_attr_mode (insn) == MODE_SI)
10801	    return "sal{l}\t%k0";
10802	  else
10803	    return "sal{b}\t%0";
10804	}
10805      else
10806	{
10807	  if (get_attr_mode (insn) == MODE_SI)
10808	    return "sal{l}\t{%2, %k0|%k0, %2}";
10809	  else
10810	    return "sal{b}\t{%2, %0|%0, %2}";
10811	}
10812    }
10813}
10814  [(set (attr "type")
10815     (cond [(eq_attr "alternative" "2")
10816	      (const_string "lea")
10817            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10818		      (match_operand 0 "register_operand"))
10819		 (match_operand 2 "const1_operand"))
10820	      (const_string "alu")
10821	   ]
10822	   (const_string "ishift")))
10823   (set (attr "length_immediate")
10824     (if_then_else
10825       (ior (eq_attr "type" "alu")
10826	    (and (eq_attr "type" "ishift")
10827		 (and (match_operand 2 "const1_operand")
10828		      (ior (match_test "TARGET_SHIFT1")
10829			   (match_test "optimize_function_for_size_p (cfun)")))))
10830       (const_string "0")
10831       (const_string "*")))
10832   (set_attr "mode" "QI,SI,SI")
10833   ;; Potential partial reg stall on alternative 1.
10834   (set (attr "preferred_for_speed")
10835     (cond [(eq_attr "alternative" "1")
10836	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10837	   (symbol_ref "true")))])
10838
10839(define_insn "*ashl<mode>3_1_slp"
10840  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
10841	(ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0")
10842		      (match_operand:QI 2 "nonmemory_operand" "cI")))
10843   (clobber (reg:CC FLAGS_REG))]
10844  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10845   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
10846   && rtx_equal_p (operands[0], operands[1])"
10847{
10848  switch (get_attr_type (insn))
10849    {
10850    case TYPE_ALU:
10851      gcc_assert (operands[2] == const1_rtx);
10852      return "add{<imodesuffix>}\t%0, %0";
10853
10854    default:
10855      if (operands[2] == const1_rtx
10856	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10857	return "sal{<imodesuffix>}\t%0";
10858      else
10859	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10860    }
10861}
10862  [(set (attr "type")
10863     (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10864		 (match_operand 2 "const1_operand"))
10865	      (const_string "alu")
10866	   ]
10867	   (const_string "ishift")))
10868   (set (attr "length_immediate")
10869     (if_then_else
10870       (ior (eq_attr "type" "alu")
10871	    (and (eq_attr "type" "ishift")
10872		 (and (match_operand 2 "const1_operand")
10873		      (ior (match_test "TARGET_SHIFT1")
10874			   (match_test "optimize_function_for_size_p (cfun)")))))
10875       (const_string "0")
10876       (const_string "*")))
10877   (set_attr "mode" "<MODE>")])
10878
10879;; Convert ashift to the lea pattern to avoid flags dependency.
10880(define_split
10881  [(set (match_operand:SWI 0 "register_operand")
10882	(ashift:SWI (match_operand:SWI 1 "index_register_operand")
10883		    (match_operand 2 "const_0_to_3_operand")))
10884   (clobber (reg:CC FLAGS_REG))]
10885  "reload_completed
10886   && REGNO (operands[0]) != REGNO (operands[1])"
10887  [(set (match_dup 0)
10888	(mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10889{
10890  if (<MODE>mode != <LEAMODE>mode)
10891    {
10892      operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10893      operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10894    }
10895  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10896})
10897
10898;; Convert ashift to the lea pattern to avoid flags dependency.
10899(define_split
10900  [(set (match_operand:DI 0 "register_operand")
10901	(zero_extend:DI
10902	  (ashift:SI (match_operand:SI 1 "index_register_operand")
10903		     (match_operand 2 "const_0_to_3_operand"))))
10904   (clobber (reg:CC FLAGS_REG))]
10905  "TARGET_64BIT && reload_completed
10906   && REGNO (operands[0]) != REGNO (operands[1])"
10907  [(set (match_dup 0)
10908	(zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10909{
10910  operands[1] = gen_lowpart (SImode, operands[1]);
10911  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10912})
10913
10914;; This pattern can't accept a variable shift count, since shifts by
10915;; zero don't affect the flags.  We assume that shifts by constant
10916;; zero are optimized away.
10917(define_insn "*ashl<mode>3_cmp"
10918  [(set (reg FLAGS_REG)
10919	(compare
10920	  (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10921		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10922	  (const_int 0)))
10923   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10924	(ashift:SWI (match_dup 1) (match_dup 2)))]
10925  "(optimize_function_for_size_p (cfun)
10926    || !TARGET_PARTIAL_FLAG_REG_STALL
10927    || (operands[2] == const1_rtx
10928	&& (TARGET_SHIFT1
10929	    || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10930   && ix86_match_ccmode (insn, CCGOCmode)
10931   && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10932{
10933  switch (get_attr_type (insn))
10934    {
10935    case TYPE_ALU:
10936      gcc_assert (operands[2] == const1_rtx);
10937      return "add{<imodesuffix>}\t%0, %0";
10938
10939    default:
10940      if (operands[2] == const1_rtx
10941	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10942	return "sal{<imodesuffix>}\t%0";
10943      else
10944	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10945    }
10946}
10947  [(set (attr "type")
10948     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10949		      (match_operand 0 "register_operand"))
10950		 (match_operand 2 "const1_operand"))
10951	      (const_string "alu")
10952	   ]
10953	   (const_string "ishift")))
10954   (set (attr "length_immediate")
10955     (if_then_else
10956       (ior (eq_attr "type" "alu")
10957	    (and (eq_attr "type" "ishift")
10958		 (and (match_operand 2 "const1_operand")
10959		      (ior (match_test "TARGET_SHIFT1")
10960			   (match_test "optimize_function_for_size_p (cfun)")))))
10961       (const_string "0")
10962       (const_string "*")))
10963   (set_attr "mode" "<MODE>")])
10964
10965(define_insn "*ashlsi3_cmp_zext"
10966  [(set (reg FLAGS_REG)
10967	(compare
10968	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10969		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10970	  (const_int 0)))
10971   (set (match_operand:DI 0 "register_operand" "=r")
10972	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10973  "TARGET_64BIT
10974   && (optimize_function_for_size_p (cfun)
10975       || !TARGET_PARTIAL_FLAG_REG_STALL
10976       || (operands[2] == const1_rtx
10977	   && (TARGET_SHIFT1
10978	       || TARGET_DOUBLE_WITH_ADD)))
10979   && ix86_match_ccmode (insn, CCGOCmode)
10980   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10981{
10982  switch (get_attr_type (insn))
10983    {
10984    case TYPE_ALU:
10985      gcc_assert (operands[2] == const1_rtx);
10986      return "add{l}\t%k0, %k0";
10987
10988    default:
10989      if (operands[2] == const1_rtx
10990	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10991	return "sal{l}\t%k0";
10992      else
10993	return "sal{l}\t{%2, %k0|%k0, %2}";
10994    }
10995}
10996  [(set (attr "type")
10997     (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10998		 (match_operand 2 "const1_operand"))
10999	      (const_string "alu")
11000	   ]
11001	   (const_string "ishift")))
11002   (set (attr "length_immediate")
11003     (if_then_else
11004       (ior (eq_attr "type" "alu")
11005	    (and (eq_attr "type" "ishift")
11006		 (and (match_operand 2 "const1_operand")
11007		      (ior (match_test "TARGET_SHIFT1")
11008			   (match_test "optimize_function_for_size_p (cfun)")))))
11009       (const_string "0")
11010       (const_string "*")))
11011   (set_attr "mode" "SI")])
11012
11013(define_insn "*ashl<mode>3_cconly"
11014  [(set (reg FLAGS_REG)
11015	(compare
11016	  (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11017		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11018	  (const_int 0)))
11019   (clobber (match_scratch:SWI 0 "=<r>"))]
11020  "(optimize_function_for_size_p (cfun)
11021    || !TARGET_PARTIAL_FLAG_REG_STALL
11022    || (operands[2] == const1_rtx
11023	&& (TARGET_SHIFT1
11024	    || TARGET_DOUBLE_WITH_ADD)))
11025   && ix86_match_ccmode (insn, CCGOCmode)"
11026{
11027  switch (get_attr_type (insn))
11028    {
11029    case TYPE_ALU:
11030      gcc_assert (operands[2] == const1_rtx);
11031      return "add{<imodesuffix>}\t%0, %0";
11032
11033    default:
11034      if (operands[2] == const1_rtx
11035	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11036	return "sal{<imodesuffix>}\t%0";
11037      else
11038	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11039    }
11040}
11041  [(set (attr "type")
11042     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11043		      (match_operand 0 "register_operand"))
11044		 (match_operand 2 "const1_operand"))
11045	      (const_string "alu")
11046	   ]
11047	   (const_string "ishift")))
11048   (set (attr "length_immediate")
11049     (if_then_else
11050       (ior (eq_attr "type" "alu")
11051	    (and (eq_attr "type" "ishift")
11052		 (and (match_operand 2 "const1_operand")
11053		      (ior (match_test "TARGET_SHIFT1")
11054			   (match_test "optimize_function_for_size_p (cfun)")))))
11055       (const_string "0")
11056       (const_string "*")))
11057   (set_attr "mode" "<MODE>")])
11058
11059;; See comment above `ashl<mode>3' about how this works.
11060
11061(define_expand "<shift_insn><mode>3"
11062  [(set (match_operand:SDWIM 0 "<shift_operand>")
11063	(any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11064			   (match_operand:QI 2 "nonmemory_operand")))]
11065  ""
11066  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11067
11068;; Avoid useless masking of count operand.
11069(define_insn_and_split "*<shift_insn><mode>3_mask"
11070  [(set (match_operand:SWI48 0 "nonimmediate_operand")
11071	(any_shiftrt:SWI48
11072	  (match_operand:SWI48 1 "nonimmediate_operand")
11073	  (subreg:QI
11074	    (and:SI
11075	      (match_operand:SI 2 "register_operand" "c,r")
11076	      (match_operand:SI 3 "const_int_operand")) 0)))
11077   (clobber (reg:CC FLAGS_REG))]
11078  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11079   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11080      == GET_MODE_BITSIZE (<MODE>mode)-1
11081   && ix86_pre_reload_split ()"
11082  "#"
11083  "&& 1"
11084  [(parallel
11085     [(set (match_dup 0)
11086	   (any_shiftrt:SWI48 (match_dup 1)
11087			      (match_dup 2)))
11088      (clobber (reg:CC FLAGS_REG))])]
11089  "operands[2] = gen_lowpart (QImode, operands[2]);"
11090  [(set_attr "isa" "*,bmi2")])
11091
11092(define_insn_and_split "*<shift_insn><mode>3_mask_1"
11093  [(set (match_operand:SWI48 0 "nonimmediate_operand")
11094	(any_shiftrt:SWI48
11095	  (match_operand:SWI48 1 "nonimmediate_operand")
11096	  (and:QI
11097	    (match_operand:QI 2 "register_operand" "c,r")
11098	    (match_operand:QI 3 "const_int_operand"))))
11099   (clobber (reg:CC FLAGS_REG))]
11100  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11101   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11102      == GET_MODE_BITSIZE (<MODE>mode)-1
11103   && ix86_pre_reload_split ()"
11104  "#"
11105  "&& 1"
11106  [(parallel
11107     [(set (match_dup 0)
11108	   (any_shiftrt:SWI48 (match_dup 1)
11109			      (match_dup 2)))
11110      (clobber (reg:CC FLAGS_REG))])]
11111  ""
11112  [(set_attr "isa" "*,bmi2")])
11113
11114(define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
11115  [(set (match_operand:<DWI> 0 "register_operand")
11116	(any_shiftrt:<DWI>
11117	  (match_operand:<DWI> 1 "register_operand")
11118	  (subreg:QI
11119	    (and:SI
11120	      (match_operand:SI 2 "register_operand" "c")
11121	      (match_operand:SI 3 "const_int_operand")) 0)))
11122   (clobber (reg:CC FLAGS_REG))]
11123  "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11124   && ix86_pre_reload_split ()"
11125  "#"
11126  "&& 1"
11127  [(parallel
11128     [(set (match_dup 4)
11129	   (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11130		     (ashift:DWIH (match_dup 7)
11131		       (minus:QI (match_dup 8) (match_dup 2)))))
11132      (clobber (reg:CC FLAGS_REG))])
11133   (parallel
11134     [(set (match_dup 6)
11135	   (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11136      (clobber (reg:CC FLAGS_REG))])]
11137{
11138  split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11139
11140  operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11141
11142  if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11143      != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11144    {
11145      rtx tem = gen_reg_rtx (SImode);
11146      emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11147      operands[2] = tem;
11148    }
11149
11150  operands[2] = gen_lowpart (QImode, operands[2]);
11151
11152  if (!rtx_equal_p (operands[4], operands[5]))
11153    emit_move_insn (operands[4], operands[5]);
11154})
11155
11156(define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
11157  [(set (match_operand:<DWI> 0 "register_operand")
11158	(any_shiftrt:<DWI>
11159	  (match_operand:<DWI> 1 "register_operand")
11160	  (and:QI
11161	    (match_operand:QI 2 "register_operand" "c")
11162	    (match_operand:QI 3 "const_int_operand"))))
11163   (clobber (reg:CC FLAGS_REG))]
11164  "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11165   && ix86_pre_reload_split ()"
11166  "#"
11167  "&& 1"
11168  [(parallel
11169     [(set (match_dup 4)
11170	   (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11171		     (ashift:DWIH (match_dup 7)
11172		       (minus:QI (match_dup 8) (match_dup 2)))))
11173      (clobber (reg:CC FLAGS_REG))])
11174   (parallel
11175     [(set (match_dup 6)
11176	   (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11177      (clobber (reg:CC FLAGS_REG))])]
11178{
11179  split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11180
11181  operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11182
11183  if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11184      != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11185    {
11186      rtx tem = gen_reg_rtx (QImode);
11187      emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11188      operands[2] = tem;
11189    }
11190
11191  if (!rtx_equal_p (operands[4], operands[5]))
11192    emit_move_insn (operands[4], operands[5]);
11193})
11194
11195(define_insn_and_split "*<shift_insn><mode>3_doubleword"
11196  [(set (match_operand:DWI 0 "register_operand" "=&r")
11197	(any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11198			 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11199   (clobber (reg:CC FLAGS_REG))]
11200  ""
11201  "#"
11202  "epilogue_completed"
11203  [(const_int 0)]
11204  "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11205  [(set_attr "type" "multi")])
11206
11207;; By default we don't ask for a scratch register, because when DWImode
11208;; values are manipulated, registers are already at a premium.  But if
11209;; we have one handy, we won't turn it away.
11210
11211(define_peephole2
11212  [(match_scratch:DWIH 3 "r")
11213   (parallel [(set (match_operand:<DWI> 0 "register_operand")
11214		   (any_shiftrt:<DWI>
11215		     (match_operand:<DWI> 1 "register_operand")
11216		     (match_operand:QI 2 "nonmemory_operand")))
11217	      (clobber (reg:CC FLAGS_REG))])
11218   (match_dup 3)]
11219  "TARGET_CMOVE"
11220  [(const_int 0)]
11221  "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11222
11223(define_insn "x86_64_shrd"
11224  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11225        (ior:DI (lshiftrt:DI (match_dup 0)
11226		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
11227		(ashift:DI (match_operand:DI 1 "register_operand" "r")
11228		  (minus:QI (const_int 64) (match_dup 2)))))
11229   (clobber (reg:CC FLAGS_REG))]
11230  "TARGET_64BIT"
11231  "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11232  [(set_attr "type" "ishift")
11233   (set_attr "prefix_0f" "1")
11234   (set_attr "mode" "DI")
11235   (set_attr "athlon_decode" "vector")
11236   (set_attr "amdfam10_decode" "vector")
11237   (set_attr "bdver1_decode" "vector")])
11238
11239(define_insn "x86_shrd"
11240  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11241        (ior:SI (lshiftrt:SI (match_dup 0)
11242		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
11243		(ashift:SI (match_operand:SI 1 "register_operand" "r")
11244		  (minus:QI (const_int 32) (match_dup 2)))))
11245   (clobber (reg:CC FLAGS_REG))]
11246  ""
11247  "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11248  [(set_attr "type" "ishift")
11249   (set_attr "prefix_0f" "1")
11250   (set_attr "mode" "SI")
11251   (set_attr "pent_pair" "np")
11252   (set_attr "athlon_decode" "vector")
11253   (set_attr "amdfam10_decode" "vector")
11254   (set_attr "bdver1_decode" "vector")])
11255
11256;; Base name for insn mnemonic.
11257(define_mode_attr cvt_mnemonic
11258  [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
11259
11260(define_insn "ashr<mode>3_cvt"
11261  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
11262	(ashiftrt:SWI48
11263	  (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
11264	  (match_operand:QI 2 "const_int_operand")))
11265   (clobber (reg:CC FLAGS_REG))]
11266  "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
11267   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11268   && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
11269  "@
11270   <cvt_mnemonic>
11271   sar{<imodesuffix>}\t{%2, %0|%0, %2}"
11272  [(set_attr "type" "imovx,ishift")
11273   (set_attr "prefix_0f" "0,*")
11274   (set_attr "length_immediate" "0,*")
11275   (set_attr "modrm" "0,1")
11276   (set_attr "mode" "<MODE>")])
11277
11278(define_insn "*ashrsi3_cvt_zext"
11279  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11280	(zero_extend:DI
11281	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11282		       (match_operand:QI 2 "const_int_operand"))))
11283   (clobber (reg:CC FLAGS_REG))]
11284  "TARGET_64BIT && INTVAL (operands[2]) == 31
11285   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11286   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11287  "@
11288   {cltd|cdq}
11289   sar{l}\t{%2, %k0|%k0, %2}"
11290  [(set_attr "type" "imovx,ishift")
11291   (set_attr "prefix_0f" "0,*")
11292   (set_attr "length_immediate" "0,*")
11293   (set_attr "modrm" "0,1")
11294   (set_attr "mode" "SI")])
11295
11296(define_expand "@x86_shift<mode>_adj_3"
11297  [(use (match_operand:SWI48 0 "register_operand"))
11298   (use (match_operand:SWI48 1 "register_operand"))
11299   (use (match_operand:QI 2 "register_operand"))]
11300  ""
11301{
11302  rtx_code_label *label = gen_label_rtx ();
11303  rtx tmp;
11304
11305  emit_insn (gen_testqi_ccz_1 (operands[2],
11306			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11307
11308  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11309  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11310  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11311			      gen_rtx_LABEL_REF (VOIDmode, label),
11312			      pc_rtx);
11313  tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11314  JUMP_LABEL (tmp) = label;
11315
11316  emit_move_insn (operands[0], operands[1]);
11317  emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11318				  GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11319  emit_label (label);
11320  LABEL_NUSES (label) = 1;
11321
11322  DONE;
11323})
11324
11325(define_insn "*bmi2_<shift_insn><mode>3_1"
11326  [(set (match_operand:SWI48 0 "register_operand" "=r")
11327	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11328			   (match_operand:SWI48 2 "register_operand" "r")))]
11329  "TARGET_BMI2"
11330  "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11331  [(set_attr "type" "ishiftx")
11332   (set_attr "mode" "<MODE>")])
11333
11334(define_insn "*<shift_insn><mode>3_1"
11335  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11336	(any_shiftrt:SWI48
11337	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11338	  (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11339   (clobber (reg:CC FLAGS_REG))]
11340  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11341{
11342  switch (get_attr_type (insn))
11343    {
11344    case TYPE_ISHIFTX:
11345      return "#";
11346
11347    default:
11348      if (operands[2] == const1_rtx
11349	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11350	return "<shift>{<imodesuffix>}\t%0";
11351      else
11352	return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11353    }
11354}
11355  [(set_attr "isa" "*,bmi2")
11356   (set_attr "type" "ishift,ishiftx")
11357   (set (attr "length_immediate")
11358     (if_then_else
11359       (and (match_operand 2 "const1_operand")
11360	    (ior (match_test "TARGET_SHIFT1")
11361		 (match_test "optimize_function_for_size_p (cfun)")))
11362       (const_string "0")
11363       (const_string "*")))
11364   (set_attr "mode" "<MODE>")])
11365
11366;; Convert shift to the shiftx pattern to avoid flags dependency.
11367(define_split
11368  [(set (match_operand:SWI48 0 "register_operand")
11369	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11370			   (match_operand:QI 2 "register_operand")))
11371   (clobber (reg:CC FLAGS_REG))]
11372  "TARGET_BMI2 && reload_completed"
11373  [(set (match_dup 0)
11374	(any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11375  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11376
11377(define_insn "*bmi2_<shift_insn>si3_1_zext"
11378  [(set (match_operand:DI 0 "register_operand" "=r")
11379	(zero_extend:DI
11380	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11381			  (match_operand:SI 2 "register_operand" "r"))))]
11382  "TARGET_64BIT && TARGET_BMI2"
11383  "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11384  [(set_attr "type" "ishiftx")
11385   (set_attr "mode" "SI")])
11386
11387(define_insn "*<shift_insn>si3_1_zext"
11388  [(set (match_operand:DI 0 "register_operand" "=r,r")
11389	(zero_extend:DI
11390	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11391			  (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11392   (clobber (reg:CC FLAGS_REG))]
11393  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11394{
11395  switch (get_attr_type (insn))
11396    {
11397    case TYPE_ISHIFTX:
11398      return "#";
11399
11400    default:
11401      if (operands[2] == const1_rtx
11402	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11403	return "<shift>{l}\t%k0";
11404      else
11405	return "<shift>{l}\t{%2, %k0|%k0, %2}";
11406    }
11407}
11408  [(set_attr "isa" "*,bmi2")
11409   (set_attr "type" "ishift,ishiftx")
11410   (set (attr "length_immediate")
11411     (if_then_else
11412       (and (match_operand 2 "const1_operand")
11413	    (ior (match_test "TARGET_SHIFT1")
11414		 (match_test "optimize_function_for_size_p (cfun)")))
11415       (const_string "0")
11416       (const_string "*")))
11417   (set_attr "mode" "SI")])
11418
11419;; Convert shift to the shiftx pattern to avoid flags dependency.
11420(define_split
11421  [(set (match_operand:DI 0 "register_operand")
11422	(zero_extend:DI
11423	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11424			  (match_operand:QI 2 "register_operand"))))
11425   (clobber (reg:CC FLAGS_REG))]
11426  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11427  [(set (match_dup 0)
11428	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11429  "operands[2] = gen_lowpart (SImode, operands[2]);")
11430
11431(define_insn "*<shift_insn><mode>3_1"
11432  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11433	(any_shiftrt:SWI12
11434	  (match_operand:SWI12 1 "nonimmediate_operand" "0")
11435	  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11436   (clobber (reg:CC FLAGS_REG))]
11437  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11438{
11439  if (operands[2] == const1_rtx
11440      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11441    return "<shift>{<imodesuffix>}\t%0";
11442  else
11443    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11444}
11445  [(set_attr "type" "ishift")
11446   (set (attr "length_immediate")
11447     (if_then_else
11448       (and (match_operand 2 "const1_operand")
11449	    (ior (match_test "TARGET_SHIFT1")
11450		 (match_test "optimize_function_for_size_p (cfun)")))
11451       (const_string "0")
11452       (const_string "*")))
11453   (set_attr "mode" "<MODE>")])
11454
11455(define_insn "*<shift_insn><mode>3_1_slp"
11456  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11457	(any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11458			   (match_operand:QI 2 "nonmemory_operand" "cI")))
11459   (clobber (reg:CC FLAGS_REG))]
11460  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11461   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
11462   && rtx_equal_p (operands[0], operands[1])"
11463{
11464  if (operands[2] == const1_rtx
11465      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11466    return "<shift>{<imodesuffix>}\t%0";
11467  else
11468    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11469}
11470  [(set_attr "type" "ishift")
11471   (set (attr "length_immediate")
11472     (if_then_else
11473       (and (match_operand 2 "const1_operand")
11474	    (ior (match_test "TARGET_SHIFT1")
11475		 (match_test "optimize_function_for_size_p (cfun)")))
11476       (const_string "0")
11477       (const_string "*")))
11478   (set_attr "mode" "<MODE>")])
11479
11480;; This pattern can't accept a variable shift count, since shifts by
11481;; zero don't affect the flags.  We assume that shifts by constant
11482;; zero are optimized away.
11483(define_insn "*<shift_insn><mode>3_cmp"
11484  [(set (reg FLAGS_REG)
11485	(compare
11486	  (any_shiftrt:SWI
11487	    (match_operand:SWI 1 "nonimmediate_operand" "0")
11488	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11489	  (const_int 0)))
11490   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11491	(any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11492  "(optimize_function_for_size_p (cfun)
11493    || !TARGET_PARTIAL_FLAG_REG_STALL
11494    || (operands[2] == const1_rtx
11495	&& TARGET_SHIFT1))
11496   && ix86_match_ccmode (insn, CCGOCmode)
11497   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11498{
11499  if (operands[2] == const1_rtx
11500      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11501    return "<shift>{<imodesuffix>}\t%0";
11502  else
11503    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11504}
11505  [(set_attr "type" "ishift")
11506   (set (attr "length_immediate")
11507     (if_then_else
11508       (and (match_operand 2 "const1_operand")
11509	    (ior (match_test "TARGET_SHIFT1")
11510		 (match_test "optimize_function_for_size_p (cfun)")))
11511       (const_string "0")
11512       (const_string "*")))
11513   (set_attr "mode" "<MODE>")])
11514
11515(define_insn "*<shift_insn>si3_cmp_zext"
11516  [(set (reg FLAGS_REG)
11517	(compare
11518	  (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11519			  (match_operand:QI 2 "const_1_to_31_operand" "I"))
11520	  (const_int 0)))
11521   (set (match_operand:DI 0 "register_operand" "=r")
11522	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11523  "TARGET_64BIT
11524   && (optimize_function_for_size_p (cfun)
11525       || !TARGET_PARTIAL_FLAG_REG_STALL
11526       || (operands[2] == const1_rtx
11527	   && TARGET_SHIFT1))
11528   && ix86_match_ccmode (insn, CCGOCmode)
11529   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11530{
11531  if (operands[2] == const1_rtx
11532      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11533    return "<shift>{l}\t%k0";
11534  else
11535    return "<shift>{l}\t{%2, %k0|%k0, %2}";
11536}
11537  [(set_attr "type" "ishift")
11538   (set (attr "length_immediate")
11539     (if_then_else
11540       (and (match_operand 2 "const1_operand")
11541	    (ior (match_test "TARGET_SHIFT1")
11542		 (match_test "optimize_function_for_size_p (cfun)")))
11543       (const_string "0")
11544       (const_string "*")))
11545   (set_attr "mode" "SI")])
11546
11547(define_insn "*<shift_insn><mode>3_cconly"
11548  [(set (reg FLAGS_REG)
11549	(compare
11550	  (any_shiftrt:SWI
11551	    (match_operand:SWI 1 "register_operand" "0")
11552	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11553	  (const_int 0)))
11554   (clobber (match_scratch:SWI 0 "=<r>"))]
11555  "(optimize_function_for_size_p (cfun)
11556    || !TARGET_PARTIAL_FLAG_REG_STALL
11557    || (operands[2] == const1_rtx
11558	&& TARGET_SHIFT1))
11559   && ix86_match_ccmode (insn, CCGOCmode)"
11560{
11561  if (operands[2] == const1_rtx
11562      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11563    return "<shift>{<imodesuffix>}\t%0";
11564  else
11565    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11566}
11567  [(set_attr "type" "ishift")
11568   (set (attr "length_immediate")
11569     (if_then_else
11570       (and (match_operand 2 "const1_operand")
11571	    (ior (match_test "TARGET_SHIFT1")
11572		 (match_test "optimize_function_for_size_p (cfun)")))
11573       (const_string "0")
11574       (const_string "*")))
11575   (set_attr "mode" "<MODE>")])
11576
11577;; Rotate instructions
11578
11579(define_expand "<rotate_insn>ti3"
11580  [(set (match_operand:TI 0 "register_operand")
11581	(any_rotate:TI (match_operand:TI 1 "register_operand")
11582		       (match_operand:QI 2 "nonmemory_operand")))]
11583  "TARGET_64BIT"
11584{
11585  if (const_1_to_63_operand (operands[2], VOIDmode))
11586    emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11587		(operands[0], operands[1], operands[2]));
11588  else
11589    FAIL;
11590
11591  DONE;
11592})
11593
11594(define_expand "<rotate_insn>di3"
11595  [(set (match_operand:DI 0 "shiftdi_operand")
11596	(any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11597		       (match_operand:QI 2 "nonmemory_operand")))]
11598 ""
11599{
11600  if (TARGET_64BIT)
11601    ix86_expand_binary_operator (<CODE>, DImode, operands);
11602  else if (const_1_to_31_operand (operands[2], VOIDmode))
11603    emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11604		(operands[0], operands[1], operands[2]));
11605  else
11606    FAIL;
11607
11608  DONE;
11609})
11610
11611(define_expand "<rotate_insn><mode>3"
11612  [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11613	(any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11614			    (match_operand:QI 2 "nonmemory_operand")))]
11615  ""
11616  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11617
11618;; Avoid useless masking of count operand.
11619(define_insn_and_split "*<rotate_insn><mode>3_mask"
11620  [(set (match_operand:SWI48 0 "nonimmediate_operand")
11621	(any_rotate:SWI48
11622	  (match_operand:SWI48 1 "nonimmediate_operand")
11623	  (subreg:QI
11624	    (and:SI
11625	      (match_operand:SI 2 "register_operand" "c")
11626	      (match_operand:SI 3 "const_int_operand")) 0)))
11627   (clobber (reg:CC FLAGS_REG))]
11628  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11629   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11630      == GET_MODE_BITSIZE (<MODE>mode)-1
11631   && ix86_pre_reload_split ()"
11632  "#"
11633  "&& 1"
11634  [(parallel
11635     [(set (match_dup 0)
11636	   (any_rotate:SWI48 (match_dup 1)
11637			     (match_dup 2)))
11638      (clobber (reg:CC FLAGS_REG))])]
11639  "operands[2] = gen_lowpart (QImode, operands[2]);")
11640
11641(define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11642  [(set (match_operand:SWI48 0 "nonimmediate_operand")
11643	(any_rotate:SWI48
11644	  (match_operand:SWI48 1 "nonimmediate_operand")
11645	  (and:QI
11646	    (match_operand:QI 2 "register_operand" "c")
11647	    (match_operand:QI 3 "const_int_operand"))))
11648   (clobber (reg:CC FLAGS_REG))]
11649  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11650   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11651      == GET_MODE_BITSIZE (<MODE>mode)-1
11652   && ix86_pre_reload_split ()"
11653  "#"
11654  "&& 1"
11655  [(parallel
11656     [(set (match_dup 0)
11657	   (any_rotate:SWI48 (match_dup 1)
11658			     (match_dup 2)))
11659      (clobber (reg:CC FLAGS_REG))])])
11660
11661;; Implement rotation using two double-precision
11662;; shift instructions and a scratch register.
11663
11664(define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11665 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11666       (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11667		     (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11668  (clobber (reg:CC FLAGS_REG))
11669  (clobber (match_scratch:DWIH 3 "=&r"))]
11670 ""
11671 "#"
11672 "reload_completed"
11673 [(set (match_dup 3) (match_dup 4))
11674  (parallel
11675   [(set (match_dup 4)
11676	 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11677		   (lshiftrt:DWIH (match_dup 5)
11678				  (minus:QI (match_dup 6) (match_dup 2)))))
11679    (clobber (reg:CC FLAGS_REG))])
11680  (parallel
11681   [(set (match_dup 5)
11682	 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11683		   (lshiftrt:DWIH (match_dup 3)
11684				  (minus:QI (match_dup 6) (match_dup 2)))))
11685    (clobber (reg:CC FLAGS_REG))])]
11686{
11687  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11688
11689  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11690})
11691
11692(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11693 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11694       (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11695		       (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11696  (clobber (reg:CC FLAGS_REG))
11697  (clobber (match_scratch:DWIH 3 "=&r"))]
11698 ""
11699 "#"
11700 "reload_completed"
11701 [(set (match_dup 3) (match_dup 4))
11702  (parallel
11703   [(set (match_dup 4)
11704	 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11705		   (ashift:DWIH (match_dup 5)
11706				(minus:QI (match_dup 6) (match_dup 2)))))
11707    (clobber (reg:CC FLAGS_REG))])
11708  (parallel
11709   [(set (match_dup 5)
11710	 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11711		   (ashift:DWIH (match_dup 3)
11712				(minus:QI (match_dup 6) (match_dup 2)))))
11713    (clobber (reg:CC FLAGS_REG))])]
11714{
11715  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11716
11717  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11718})
11719
11720(define_mode_attr rorx_immediate_operand
11721	[(SI "const_0_to_31_operand")
11722	 (DI "const_0_to_63_operand")])
11723
11724(define_insn "*bmi2_rorx<mode>3_1"
11725  [(set (match_operand:SWI48 0 "register_operand" "=r")
11726	(rotatert:SWI48
11727	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11728	  (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11729  "TARGET_BMI2"
11730  "rorx\t{%2, %1, %0|%0, %1, %2}"
11731  [(set_attr "type" "rotatex")
11732   (set_attr "mode" "<MODE>")])
11733
11734(define_insn "*<rotate_insn><mode>3_1"
11735  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11736	(any_rotate:SWI48
11737	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11738	  (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11739   (clobber (reg:CC FLAGS_REG))]
11740  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11741{
11742  switch (get_attr_type (insn))
11743    {
11744    case TYPE_ROTATEX:
11745      return "#";
11746
11747    default:
11748      if (operands[2] == const1_rtx
11749	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11750	return "<rotate>{<imodesuffix>}\t%0";
11751      else
11752	return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11753    }
11754}
11755  [(set_attr "isa" "*,bmi2")
11756   (set_attr "type" "rotate,rotatex")
11757   (set (attr "length_immediate")
11758     (if_then_else
11759       (and (eq_attr "type" "rotate")
11760	    (and (match_operand 2 "const1_operand")
11761		 (ior (match_test "TARGET_SHIFT1")
11762		      (match_test "optimize_function_for_size_p (cfun)"))))
11763       (const_string "0")
11764       (const_string "*")))
11765   (set_attr "mode" "<MODE>")])
11766
11767;; Convert rotate to the rotatex pattern to avoid flags dependency.
11768(define_split
11769  [(set (match_operand:SWI48 0 "register_operand")
11770	(rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11771		      (match_operand:QI 2 "const_int_operand")))
11772   (clobber (reg:CC FLAGS_REG))]
11773  "TARGET_BMI2 && reload_completed"
11774  [(set (match_dup 0)
11775	(rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11776{
11777  int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11778
11779  operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11780})
11781
11782(define_split
11783  [(set (match_operand:SWI48 0 "register_operand")
11784	(rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11785			(match_operand:QI 2 "const_int_operand")))
11786   (clobber (reg:CC FLAGS_REG))]
11787  "TARGET_BMI2 && reload_completed"
11788  [(set (match_dup 0)
11789	(rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11790
11791(define_insn "*bmi2_rorxsi3_1_zext"
11792  [(set (match_operand:DI 0 "register_operand" "=r")
11793	(zero_extend:DI
11794	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11795		       (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11796  "TARGET_64BIT && TARGET_BMI2"
11797  "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11798  [(set_attr "type" "rotatex")
11799   (set_attr "mode" "SI")])
11800
11801(define_insn "*<rotate_insn>si3_1_zext"
11802  [(set (match_operand:DI 0 "register_operand" "=r,r")
11803	(zero_extend:DI
11804	  (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11805			 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11806   (clobber (reg:CC FLAGS_REG))]
11807  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11808{
11809  switch (get_attr_type (insn))
11810    {
11811    case TYPE_ROTATEX:
11812      return "#";
11813
11814    default:
11815      if (operands[2] == const1_rtx
11816	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11817	return "<rotate>{l}\t%k0";
11818      else
11819	return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11820    }
11821}
11822  [(set_attr "isa" "*,bmi2")
11823   (set_attr "type" "rotate,rotatex")
11824   (set (attr "length_immediate")
11825     (if_then_else
11826       (and (eq_attr "type" "rotate")
11827	    (and (match_operand 2 "const1_operand")
11828		 (ior (match_test "TARGET_SHIFT1")
11829		      (match_test "optimize_function_for_size_p (cfun)"))))
11830       (const_string "0")
11831       (const_string "*")))
11832   (set_attr "mode" "SI")])
11833
11834;; Convert rotate to the rotatex pattern to avoid flags dependency.
11835(define_split
11836  [(set (match_operand:DI 0 "register_operand")
11837	(zero_extend:DI
11838	  (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11839		     (match_operand:QI 2 "const_int_operand"))))
11840   (clobber (reg:CC FLAGS_REG))]
11841  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11842  [(set (match_dup 0)
11843	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11844{
11845  int bitsize = GET_MODE_BITSIZE (SImode);
11846
11847  operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11848})
11849
11850(define_split
11851  [(set (match_operand:DI 0 "register_operand")
11852	(zero_extend:DI
11853	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11854		       (match_operand:QI 2 "const_int_operand"))))
11855   (clobber (reg:CC FLAGS_REG))]
11856  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11857  [(set (match_dup 0)
11858	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11859
11860(define_insn "*<rotate_insn><mode>3_1"
11861  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11862	(any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11863			  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11864   (clobber (reg:CC FLAGS_REG))]
11865  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11866{
11867  if (operands[2] == const1_rtx
11868      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11869    return "<rotate>{<imodesuffix>}\t%0";
11870  else
11871    return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11872}
11873  [(set_attr "type" "rotate")
11874   (set (attr "length_immediate")
11875     (if_then_else
11876       (and (match_operand 2 "const1_operand")
11877	    (ior (match_test "TARGET_SHIFT1")
11878		 (match_test "optimize_function_for_size_p (cfun)")))
11879       (const_string "0")
11880       (const_string "*")))
11881   (set_attr "mode" "<MODE>")])
11882
11883(define_insn "*<rotate_insn><mode>3_1_slp"
11884  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11885	(any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11886			  (match_operand:QI 2 "nonmemory_operand" "cI")))
11887   (clobber (reg:CC FLAGS_REG))]
11888  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11889   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
11890   && rtx_equal_p (operands[0], operands[1])"
11891{
11892  if (operands[2] == const1_rtx
11893      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11894    return "<rotate>{<imodesuffix>}\t%0";
11895  else
11896    return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11897}
11898  [(set_attr "type" "rotate")
11899   (set (attr "length_immediate")
11900     (if_then_else
11901       (and (match_operand 2 "const1_operand")
11902	    (ior (match_test "TARGET_SHIFT1")
11903		 (match_test "optimize_function_for_size_p (cfun)")))
11904       (const_string "0")
11905       (const_string "*")))
11906   (set_attr "mode" "<MODE>")])
11907
11908(define_split
11909 [(set (match_operand:HI 0 "QIreg_operand")
11910       (any_rotate:HI (match_dup 0) (const_int 8)))
11911  (clobber (reg:CC FLAGS_REG))]
11912 "reload_completed
11913  && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11914 [(parallel [(set (strict_low_part (match_dup 0))
11915		  (bswap:HI (match_dup 0)))
11916	     (clobber (reg:CC FLAGS_REG))])])
11917
11918;; Bit set / bit test instructions
11919
11920;; %%% bts, btr, btc
11921
11922;; These instructions are *slow* when applied to memory.
11923
11924(define_code_attr btsc [(ior "bts") (xor "btc")])
11925
11926(define_insn "*<btsc><mode>"
11927  [(set (match_operand:SWI48 0 "register_operand" "=r")
11928	(any_or:SWI48
11929	  (ashift:SWI48 (const_int 1)
11930			(match_operand:QI 2 "register_operand" "r"))
11931	  (match_operand:SWI48 1 "register_operand" "0")))
11932   (clobber (reg:CC FLAGS_REG))]
11933  "TARGET_USE_BT"
11934  "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11935  [(set_attr "type" "alu1")
11936   (set_attr "prefix_0f" "1")
11937   (set_attr "znver1_decode" "double")
11938   (set_attr "mode" "<MODE>")])
11939
11940;; Avoid useless masking of count operand.
11941(define_insn_and_split "*<btsc><mode>_mask"
11942  [(set (match_operand:SWI48 0 "register_operand")
11943	(any_or:SWI48
11944	  (ashift:SWI48
11945	    (const_int 1)
11946	    (subreg:QI
11947	      (and:SI
11948		(match_operand:SI 1 "register_operand")
11949		(match_operand:SI 2 "const_int_operand")) 0))
11950	  (match_operand:SWI48 3 "register_operand")))
11951   (clobber (reg:CC FLAGS_REG))]
11952  "TARGET_USE_BT
11953   && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11954      == GET_MODE_BITSIZE (<MODE>mode)-1
11955   && ix86_pre_reload_split ()"
11956  "#"
11957  "&& 1"
11958  [(parallel
11959     [(set (match_dup 0)
11960	   (any_or:SWI48
11961	     (ashift:SWI48 (const_int 1)
11962			   (match_dup 1))
11963	     (match_dup 3)))
11964      (clobber (reg:CC FLAGS_REG))])]
11965  "operands[1] = gen_lowpart (QImode, operands[1]);")
11966
11967(define_insn_and_split "*<btsc><mode>_mask_1"
11968  [(set (match_operand:SWI48 0 "register_operand")
11969	(any_or:SWI48
11970	  (ashift:SWI48
11971	    (const_int 1)
11972	    (and:QI
11973	      (match_operand:QI 1 "register_operand")
11974	      (match_operand:QI 2 "const_int_operand")))
11975	  (match_operand:SWI48 3 "register_operand")))
11976   (clobber (reg:CC FLAGS_REG))]
11977  "TARGET_USE_BT
11978   && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11979      == GET_MODE_BITSIZE (<MODE>mode)-1
11980   && ix86_pre_reload_split ()"
11981  "#"
11982  "&& 1"
11983  [(parallel
11984     [(set (match_dup 0)
11985	   (any_or:SWI48
11986	     (ashift:SWI48 (const_int 1)
11987			   (match_dup 1))
11988	     (match_dup 3)))
11989      (clobber (reg:CC FLAGS_REG))])])
11990
11991(define_insn "*btr<mode>"
11992  [(set (match_operand:SWI48 0 "register_operand" "=r")
11993	(and:SWI48
11994	  (rotate:SWI48 (const_int -2)
11995			(match_operand:QI 2 "register_operand" "r"))
11996	(match_operand:SWI48 1 "register_operand" "0")))
11997   (clobber (reg:CC FLAGS_REG))]
11998  "TARGET_USE_BT"
11999  "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12000  [(set_attr "type" "alu1")
12001   (set_attr "prefix_0f" "1")
12002   (set_attr "znver1_decode" "double")
12003   (set_attr "mode" "<MODE>")])
12004
12005;; Avoid useless masking of count operand.
12006(define_insn_and_split "*btr<mode>_mask"
12007  [(set (match_operand:SWI48 0 "register_operand")
12008	(and:SWI48
12009	  (rotate:SWI48
12010	    (const_int -2)
12011	    (subreg:QI
12012	      (and:SI
12013		(match_operand:SI 1 "register_operand")
12014		(match_operand:SI 2 "const_int_operand")) 0))
12015	  (match_operand:SWI48 3 "register_operand")))
12016   (clobber (reg:CC FLAGS_REG))]
12017  "TARGET_USE_BT
12018   && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12019      == GET_MODE_BITSIZE (<MODE>mode)-1
12020   && ix86_pre_reload_split ()"
12021  "#"
12022  "&& 1"
12023  [(parallel
12024     [(set (match_dup 0)
12025	   (and:SWI48
12026	     (rotate:SWI48 (const_int -2)
12027			   (match_dup 1))
12028	     (match_dup 3)))
12029      (clobber (reg:CC FLAGS_REG))])]
12030  "operands[1] = gen_lowpart (QImode, operands[1]);")
12031
12032(define_insn_and_split "*btr<mode>_mask_1"
12033  [(set (match_operand:SWI48 0 "register_operand")
12034	(and:SWI48
12035	  (rotate:SWI48
12036	    (const_int -2)
12037	    (and:QI
12038	      (match_operand:QI 1 "register_operand")
12039	      (match_operand:QI 2 "const_int_operand")))
12040	  (match_operand:SWI48 3 "register_operand")))
12041   (clobber (reg:CC FLAGS_REG))]
12042  "TARGET_USE_BT
12043   && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12044      == GET_MODE_BITSIZE (<MODE>mode)-1
12045   && ix86_pre_reload_split ()"
12046  "#"
12047  "&& 1"
12048  [(parallel
12049     [(set (match_dup 0)
12050	   (and:SWI48
12051	     (rotate:SWI48 (const_int -2)
12052			   (match_dup 1))
12053	     (match_dup 3)))
12054      (clobber (reg:CC FLAGS_REG))])])
12055
12056;; These instructions are never faster than the corresponding
12057;; and/ior/xor operations when using immediate operand, so with
12058;; 32-bit there's no point.  But in 64-bit, we can't hold the
12059;; relevant immediates within the instruction itself, so operating
12060;; on bits in the high 32-bits of a register becomes easier.
12061;;
12062;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12063;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12064;; negdf respectively, so they can never be disabled entirely.
12065
12066(define_insn "*btsq_imm"
12067  [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12068			 (const_int 1)
12069			 (match_operand 1 "const_0_to_63_operand" "J"))
12070	(const_int 1))
12071   (clobber (reg:CC FLAGS_REG))]
12072  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12073  "bts{q}\t{%1, %0|%0, %1}"
12074  [(set_attr "type" "alu1")
12075   (set_attr "prefix_0f" "1")
12076   (set_attr "znver1_decode" "double")
12077   (set_attr "mode" "DI")])
12078
12079(define_insn "*btrq_imm"
12080  [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12081			 (const_int 1)
12082			 (match_operand 1 "const_0_to_63_operand" "J"))
12083	(const_int 0))
12084   (clobber (reg:CC FLAGS_REG))]
12085  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12086  "btr{q}\t{%1, %0|%0, %1}"
12087  [(set_attr "type" "alu1")
12088   (set_attr "prefix_0f" "1")
12089   (set_attr "znver1_decode" "double")
12090   (set_attr "mode" "DI")])
12091
12092(define_insn "*btcq_imm"
12093  [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12094			 (const_int 1)
12095			 (match_operand 1 "const_0_to_63_operand" "J"))
12096	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12097   (clobber (reg:CC FLAGS_REG))]
12098  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12099  "btc{q}\t{%1, %0|%0, %1}"
12100  [(set_attr "type" "alu1")
12101   (set_attr "prefix_0f" "1")
12102   (set_attr "znver1_decode" "double")
12103   (set_attr "mode" "DI")])
12104
12105;; Allow Nocona to avoid these instructions if a register is available.
12106
12107(define_peephole2
12108  [(match_scratch:DI 2 "r")
12109   (parallel [(set (zero_extract:DI
12110		     (match_operand:DI 0 "nonimmediate_operand")
12111		     (const_int 1)
12112		     (match_operand 1 "const_0_to_63_operand"))
12113		   (const_int 1))
12114	      (clobber (reg:CC FLAGS_REG))])]
12115  "TARGET_64BIT && !TARGET_USE_BT"
12116  [(parallel [(set (match_dup 0)
12117		   (ior:DI (match_dup 0) (match_dup 3)))
12118	      (clobber (reg:CC FLAGS_REG))])]
12119{
12120  int i = INTVAL (operands[1]);
12121
12122  operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12123
12124  if (!x86_64_immediate_operand (operands[3], DImode))
12125    {
12126      emit_move_insn (operands[2], operands[3]);
12127      operands[3] = operands[2];
12128    }
12129})
12130
12131(define_peephole2
12132  [(match_scratch:DI 2 "r")
12133   (parallel [(set (zero_extract:DI
12134		     (match_operand:DI 0 "nonimmediate_operand")
12135		     (const_int 1)
12136		     (match_operand 1 "const_0_to_63_operand"))
12137		   (const_int 0))
12138	      (clobber (reg:CC FLAGS_REG))])]
12139  "TARGET_64BIT && !TARGET_USE_BT"
12140  [(parallel [(set (match_dup 0)
12141		   (and:DI (match_dup 0) (match_dup 3)))
12142	      (clobber (reg:CC FLAGS_REG))])]
12143{
12144  int i = INTVAL (operands[1]);
12145
12146  operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12147 
12148  if (!x86_64_immediate_operand (operands[3], DImode))
12149    {
12150      emit_move_insn (operands[2], operands[3]);
12151      operands[3] = operands[2];
12152    }
12153})
12154
12155(define_peephole2
12156  [(match_scratch:DI 2 "r")
12157   (parallel [(set (zero_extract:DI
12158		     (match_operand:DI 0 "nonimmediate_operand")
12159		     (const_int 1)
12160		     (match_operand 1 "const_0_to_63_operand"))
12161	      (not:DI (zero_extract:DI
12162			(match_dup 0) (const_int 1) (match_dup 1))))
12163	      (clobber (reg:CC FLAGS_REG))])]
12164  "TARGET_64BIT && !TARGET_USE_BT"
12165  [(parallel [(set (match_dup 0)
12166		   (xor:DI (match_dup 0) (match_dup 3)))
12167	      (clobber (reg:CC FLAGS_REG))])]
12168{
12169  int i = INTVAL (operands[1]);
12170
12171  operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12172
12173  if (!x86_64_immediate_operand (operands[3], DImode))
12174    {
12175      emit_move_insn (operands[2], operands[3]);
12176      operands[3] = operands[2];
12177    }
12178})
12179
12180;; %%% bt
12181
12182(define_insn "*bt<mode>"
12183  [(set (reg:CCC FLAGS_REG)
12184	(compare:CCC
12185	  (zero_extract:SWI48
12186	    (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12187	    (const_int 1)
12188	    (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12189	  (const_int 0)))]
12190  ""
12191{
12192  switch (get_attr_mode (insn))
12193    {
12194    case MODE_SI:
12195      return "bt{l}\t{%1, %k0|%k0, %1}";
12196
12197    case MODE_DI:
12198      return "bt{q}\t{%q1, %0|%0, %q1}";
12199
12200    default:
12201      gcc_unreachable ();
12202    }
12203}
12204  [(set_attr "type" "alu1")
12205   (set_attr "prefix_0f" "1")
12206   (set (attr "mode")
12207	(if_then_else
12208	  (and (match_test "CONST_INT_P (operands[1])")
12209	       (match_test "INTVAL (operands[1]) < 32"))
12210	  (const_string "SI")
12211	  (const_string "<MODE>")))])
12212
12213(define_insn_and_split "*jcc_bt<mode>"
12214  [(set (pc)
12215  	(if_then_else (match_operator 0 "bt_comparison_operator"
12216			[(zero_extract:SWI48
12217			   (match_operand:SWI48 1 "nonimmediate_operand")
12218			   (const_int 1)
12219			   (match_operand:SI 2 "nonmemory_operand"))
12220			 (const_int 0)])
12221		      (label_ref (match_operand 3))
12222		      (pc)))
12223   (clobber (reg:CC FLAGS_REG))]
12224  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12225   && (CONST_INT_P (operands[2])
12226       ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12227	  && INTVAL (operands[2])
12228	       >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12229       : !memory_operand (operands[1], <MODE>mode))
12230   && ix86_pre_reload_split ()"
12231  "#"
12232  "&& 1"
12233  [(set (reg:CCC FLAGS_REG)
12234	(compare:CCC
12235	  (zero_extract:SWI48
12236	    (match_dup 1)
12237	    (const_int 1)
12238	    (match_dup 2))
12239	  (const_int 0)))
12240   (set (pc)
12241	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12242		      (label_ref (match_dup 3))
12243		      (pc)))]
12244{
12245  operands[0] = shallow_copy_rtx (operands[0]);
12246  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12247})
12248
12249(define_insn_and_split "*jcc_bt<mode>_1"
12250  [(set (pc)
12251  	(if_then_else (match_operator 0 "bt_comparison_operator"
12252			[(zero_extract:SWI48
12253			   (match_operand:SWI48 1 "register_operand")
12254			   (const_int 1)
12255			   (zero_extend:SI
12256			     (match_operand:QI 2 "register_operand")))
12257			 (const_int 0)])
12258		      (label_ref (match_operand 3))
12259		      (pc)))
12260   (clobber (reg:CC FLAGS_REG))]
12261  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12262   && ix86_pre_reload_split ()"
12263  "#"
12264  "&& 1"
12265  [(set (reg:CCC FLAGS_REG)
12266	(compare:CCC
12267	  (zero_extract:SWI48
12268	    (match_dup 1)
12269	    (const_int 1)
12270	    (match_dup 2))
12271	  (const_int 0)))
12272   (set (pc)
12273	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12274		      (label_ref (match_dup 3))
12275		      (pc)))]
12276{
12277  operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12278  operands[0] = shallow_copy_rtx (operands[0]);
12279  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12280})
12281
12282;; Avoid useless masking of bit offset operand.
12283(define_insn_and_split "*jcc_bt<mode>_mask"
12284  [(set (pc)
12285  	(if_then_else (match_operator 0 "bt_comparison_operator"
12286			[(zero_extract:SWI48
12287			   (match_operand:SWI48 1 "register_operand")
12288			   (const_int 1)
12289			   (and:SI
12290			     (match_operand:SI 2 "register_operand")
12291			     (match_operand 3 "const_int_operand")))])
12292		      (label_ref (match_operand 4))
12293		      (pc)))
12294   (clobber (reg:CC FLAGS_REG))]
12295  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12296   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12297      == GET_MODE_BITSIZE (<MODE>mode)-1
12298   && ix86_pre_reload_split ()"
12299  "#"
12300  "&& 1"
12301  [(set (reg:CCC FLAGS_REG)
12302	(compare:CCC
12303	  (zero_extract:SWI48
12304	    (match_dup 1)
12305	    (const_int 1)
12306	    (match_dup 2))
12307	  (const_int 0)))
12308   (set (pc)
12309	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12310		      (label_ref (match_dup 4))
12311		      (pc)))]
12312{
12313  operands[0] = shallow_copy_rtx (operands[0]);
12314  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12315})
12316
12317;; Store-flag instructions.
12318
12319;; For all sCOND expanders, also expand the compare or test insn that
12320;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12321
12322(define_insn_and_split "*setcc_di_1"
12323  [(set (match_operand:DI 0 "register_operand" "=q")
12324	(match_operator:DI 1 "ix86_comparison_operator"
12325	  [(reg FLAGS_REG) (const_int 0)]))]
12326  "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12327  "#"
12328  "&& reload_completed"
12329  [(set (match_dup 2) (match_dup 1))
12330   (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12331{
12332  operands[1] = shallow_copy_rtx (operands[1]);
12333  PUT_MODE (operands[1], QImode);
12334  operands[2] = gen_lowpart (QImode, operands[0]);
12335})
12336
12337(define_insn_and_split "*setcc_si_1_and"
12338  [(set (match_operand:SI 0 "register_operand" "=q")
12339	(match_operator:SI 1 "ix86_comparison_operator"
12340	  [(reg FLAGS_REG) (const_int 0)]))
12341   (clobber (reg:CC FLAGS_REG))]
12342  "!TARGET_PARTIAL_REG_STALL
12343   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12344  "#"
12345  "&& reload_completed"
12346  [(set (match_dup 2) (match_dup 1))
12347   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12348	      (clobber (reg:CC FLAGS_REG))])]
12349{
12350  operands[1] = shallow_copy_rtx (operands[1]);
12351  PUT_MODE (operands[1], QImode);
12352  operands[2] = gen_lowpart (QImode, operands[0]);
12353})
12354
12355(define_insn_and_split "*setcc_si_1_movzbl"
12356  [(set (match_operand:SI 0 "register_operand" "=q")
12357	(match_operator:SI 1 "ix86_comparison_operator"
12358	  [(reg FLAGS_REG) (const_int 0)]))]
12359  "!TARGET_PARTIAL_REG_STALL
12360   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12361  "#"
12362  "&& reload_completed"
12363  [(set (match_dup 2) (match_dup 1))
12364   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12365{
12366  operands[1] = shallow_copy_rtx (operands[1]);
12367  PUT_MODE (operands[1], QImode);
12368  operands[2] = gen_lowpart (QImode, operands[0]);
12369})
12370
12371(define_insn "*setcc_qi"
12372  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12373	(match_operator:QI 1 "ix86_comparison_operator"
12374	  [(reg FLAGS_REG) (const_int 0)]))]
12375  ""
12376  "set%C1\t%0"
12377  [(set_attr "type" "setcc")
12378   (set_attr "mode" "QI")])
12379
12380(define_insn "*setcc_qi_slp"
12381  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
12382	(match_operator:QI 1 "ix86_comparison_operator"
12383	  [(reg FLAGS_REG) (const_int 0)]))]
12384  ""
12385  "set%C1\t%0"
12386  [(set_attr "type" "setcc")
12387   (set_attr "mode" "QI")])
12388
12389;; In general it is not safe to assume too much about CCmode registers,
12390;; so simplify-rtx stops when it sees a second one.  Under certain
12391;; conditions this is safe on x86, so help combine not create
12392;;
12393;;	seta	%al
12394;;	testb	%al, %al
12395;;	sete	%al
12396
12397(define_split
12398  [(set (match_operand:QI 0 "nonimmediate_operand")
12399	(ne:QI (match_operator 1 "ix86_comparison_operator"
12400	         [(reg FLAGS_REG) (const_int 0)])
12401	    (const_int 0)))]
12402  ""
12403  [(set (match_dup 0) (match_dup 1))]
12404{
12405  operands[1] = shallow_copy_rtx (operands[1]);
12406  PUT_MODE (operands[1], QImode);
12407})
12408
12409(define_split
12410  [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12411	(ne:QI (match_operator 1 "ix86_comparison_operator"
12412	         [(reg FLAGS_REG) (const_int 0)])
12413	    (const_int 0)))]
12414  ""
12415  [(set (match_dup 0) (match_dup 1))]
12416{
12417  operands[1] = shallow_copy_rtx (operands[1]);
12418  PUT_MODE (operands[1], QImode);
12419})
12420
12421(define_split
12422  [(set (match_operand:QI 0 "nonimmediate_operand")
12423	(eq:QI (match_operator 1 "ix86_comparison_operator"
12424	         [(reg FLAGS_REG) (const_int 0)])
12425	    (const_int 0)))]
12426  ""
12427  [(set (match_dup 0) (match_dup 1))]
12428{
12429  operands[1] = shallow_copy_rtx (operands[1]);
12430  PUT_MODE (operands[1], QImode);
12431  PUT_CODE (operands[1],
12432	    ix86_reverse_condition (GET_CODE (operands[1]),
12433				    GET_MODE (XEXP (operands[1], 0))));
12434
12435  /* Make sure that (a) the CCmode we have for the flags is strong
12436     enough for the reversed compare or (b) we have a valid FP compare.  */
12437  if (! ix86_comparison_operator (operands[1], VOIDmode))
12438    FAIL;
12439})
12440
12441(define_split
12442  [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12443	(eq:QI (match_operator 1 "ix86_comparison_operator"
12444	         [(reg FLAGS_REG) (const_int 0)])
12445	    (const_int 0)))]
12446  ""
12447  [(set (match_dup 0) (match_dup 1))]
12448{
12449  operands[1] = shallow_copy_rtx (operands[1]);
12450  PUT_MODE (operands[1], QImode);
12451  PUT_CODE (operands[1],
12452  	    ix86_reverse_condition (GET_CODE (operands[1]),
12453				    GET_MODE (XEXP (operands[1], 0))));
12454
12455  /* Make sure that (a) the CCmode we have for the flags is strong
12456     enough for the reversed compare or (b) we have a valid FP compare.  */
12457  if (! ix86_comparison_operator (operands[1], VOIDmode))
12458    FAIL;
12459})
12460
12461;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12462;; subsequent logical operations are used to imitate conditional moves.
12463;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12464;; it directly.
12465
12466(define_insn "setcc_<mode>_sse"
12467  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12468	(match_operator:MODEF 3 "sse_comparison_operator"
12469	  [(match_operand:MODEF 1 "register_operand" "0,x")
12470	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12471  "SSE_FLOAT_MODE_P (<MODE>mode)"
12472  "@
12473   cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12474   vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12475  [(set_attr "isa" "noavx,avx")
12476   (set_attr "type" "ssecmp")
12477   (set_attr "length_immediate" "1")
12478   (set_attr "prefix" "orig,vex")
12479   (set_attr "mode" "<MODE>")])
12480
12481;; Basic conditional jump instructions.
12482;; We ignore the overflow flag for signed branch instructions.
12483
12484(define_insn "*jcc"
12485  [(set (pc)
12486	(if_then_else (match_operator 1 "ix86_comparison_operator"
12487				      [(reg FLAGS_REG) (const_int 0)])
12488		      (label_ref (match_operand 0))
12489		      (pc)))]
12490  ""
12491  "%!%+j%C1\t%l0"
12492  [(set_attr "type" "ibr")
12493   (set_attr "modrm" "0")
12494   (set (attr "length")
12495	(if_then_else
12496	  (and (ge (minus (match_dup 0) (pc))
12497		   (const_int -126))
12498	       (lt (minus (match_dup 0) (pc))
12499		   (const_int 128)))
12500	  (const_int 2)
12501	  (const_int 6)))])
12502
12503;; In general it is not safe to assume too much about CCmode registers,
12504;; so simplify-rtx stops when it sees a second one.  Under certain
12505;; conditions this is safe on x86, so help combine not create
12506;;
12507;;	seta	%al
12508;;	testb	%al, %al
12509;;	je	Lfoo
12510
12511(define_split
12512  [(set (pc)
12513	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12514				      [(reg FLAGS_REG) (const_int 0)])
12515			  (const_int 0))
12516		      (label_ref (match_operand 1))
12517		      (pc)))]
12518  ""
12519  [(set (pc)
12520	(if_then_else (match_dup 0)
12521		      (label_ref (match_dup 1))
12522		      (pc)))]
12523{
12524  operands[0] = shallow_copy_rtx (operands[0]);
12525  PUT_MODE (operands[0], VOIDmode);
12526})
12527
12528(define_split
12529  [(set (pc)
12530	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12531				      [(reg FLAGS_REG) (const_int 0)])
12532			  (const_int 0))
12533		      (label_ref (match_operand 1))
12534		      (pc)))]
12535  ""
12536  [(set (pc)
12537	(if_then_else (match_dup 0)
12538		      (label_ref (match_dup 1))
12539		      (pc)))]
12540{
12541  operands[0] = shallow_copy_rtx (operands[0]);
12542  PUT_MODE (operands[0], VOIDmode);
12543  PUT_CODE (operands[0],
12544  	    ix86_reverse_condition (GET_CODE (operands[0]),
12545				    GET_MODE (XEXP (operands[0], 0))));
12546
12547  /* Make sure that (a) the CCmode we have for the flags is strong
12548     enough for the reversed compare or (b) we have a valid FP compare.  */
12549  if (! ix86_comparison_operator (operands[0], VOIDmode))
12550    FAIL;
12551})
12552
12553;; Unconditional and other jump instructions
12554
12555(define_insn "jump"
12556  [(set (pc)
12557	(label_ref (match_operand 0)))]
12558  ""
12559  "%!jmp\t%l0"
12560  [(set_attr "type" "ibr")
12561   (set_attr "modrm" "0")
12562   (set (attr "length")
12563	(if_then_else
12564	  (and (ge (minus (match_dup 0) (pc))
12565		   (const_int -126))
12566	       (lt (minus (match_dup 0) (pc))
12567		   (const_int 128)))
12568	  (const_int 2)
12569	  (const_int 5)))])
12570
12571(define_expand "indirect_jump"
12572  [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12573  ""
12574{
12575  if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12576    operands[0] = convert_memory_address (word_mode, operands[0]);
12577  cfun->machine->has_local_indirect_jump = true;
12578})
12579
12580(define_insn "*indirect_jump"
12581  [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12582  ""
12583  "* return ix86_output_indirect_jmp (operands[0]);"
12584  [(set (attr "type")
12585     (if_then_else (match_test "(cfun->machine->indirect_branch_type
12586				 != indirect_branch_keep)")
12587	(const_string "multi")
12588	(const_string "ibr")))
12589   (set_attr "length_immediate" "0")])
12590
12591(define_expand "tablejump"
12592  [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12593	      (use (label_ref (match_operand 1)))])]
12594  ""
12595{
12596  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12597     relative.  Convert the relative address to an absolute address.  */
12598  if (flag_pic)
12599    {
12600      rtx op0, op1;
12601      enum rtx_code code;
12602
12603      /* We can't use @GOTOFF for text labels on VxWorks;
12604	 see gotoff_operand.  */
12605      if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12606	{
12607	  code = PLUS;
12608	  op0 = operands[0];
12609	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12610	}
12611      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12612	{
12613	  code = PLUS;
12614	  op0 = operands[0];
12615	  op1 = pic_offset_table_rtx;
12616	}
12617      else
12618	{
12619	  code = MINUS;
12620	  op0 = pic_offset_table_rtx;
12621	  op1 = operands[0];
12622	}
12623
12624      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12625					 OPTAB_DIRECT);
12626    }
12627
12628  if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12629    operands[0] = convert_memory_address (word_mode, operands[0]);
12630  cfun->machine->has_local_indirect_jump = true;
12631})
12632
12633(define_insn "*tablejump_1"
12634  [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12635   (use (label_ref (match_operand 1)))]
12636  ""
12637  "* return ix86_output_indirect_jmp (operands[0]);"
12638  [(set (attr "type")
12639     (if_then_else (match_test "(cfun->machine->indirect_branch_type
12640				 != indirect_branch_keep)")
12641	(const_string "multi")
12642	(const_string "ibr")))
12643   (set_attr "length_immediate" "0")])
12644
12645;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12646
12647(define_peephole2
12648  [(set (reg FLAGS_REG) (match_operand 0))
12649   (set (match_operand:QI 1 "register_operand")
12650	(match_operator:QI 2 "ix86_comparison_operator"
12651	  [(reg FLAGS_REG) (const_int 0)]))
12652   (set (match_operand 3 "any_QIreg_operand")
12653	(zero_extend (match_dup 1)))]
12654  "(peep2_reg_dead_p (3, operands[1])
12655    || operands_match_p (operands[1], operands[3]))
12656   && ! reg_overlap_mentioned_p (operands[3], operands[0])
12657   && peep2_regno_dead_p (0, FLAGS_REG)"
12658  [(set (match_dup 4) (match_dup 0))
12659   (set (strict_low_part (match_dup 5))
12660	(match_dup 2))]
12661{
12662  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12663  operands[5] = gen_lowpart (QImode, operands[3]);
12664  ix86_expand_clear (operands[3]);
12665})
12666
12667(define_peephole2
12668  [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12669	      (match_operand 4)])
12670   (set (match_operand:QI 1 "register_operand")
12671	(match_operator:QI 2 "ix86_comparison_operator"
12672	  [(reg FLAGS_REG) (const_int 0)]))
12673   (set (match_operand 3 "any_QIreg_operand")
12674	(zero_extend (match_dup 1)))]
12675  "(peep2_reg_dead_p (3, operands[1])
12676    || operands_match_p (operands[1], operands[3]))
12677   && ! reg_overlap_mentioned_p (operands[3], operands[0])
12678   && ! reg_overlap_mentioned_p (operands[3], operands[4])
12679   && ! reg_set_p (operands[3], operands[4])
12680   && peep2_regno_dead_p (0, FLAGS_REG)"
12681  [(parallel [(set (match_dup 5) (match_dup 0))
12682	      (match_dup 4)])
12683   (set (strict_low_part (match_dup 6))
12684	(match_dup 2))]
12685{
12686  operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12687  operands[6] = gen_lowpart (QImode, operands[3]);
12688  ix86_expand_clear (operands[3]);
12689})
12690
12691(define_peephole2
12692  [(set (reg FLAGS_REG) (match_operand 0))
12693   (parallel [(set (reg FLAGS_REG) (match_operand 1))
12694	      (match_operand 5)])
12695   (set (match_operand:QI 2 "register_operand")
12696	(match_operator:QI 3 "ix86_comparison_operator"
12697	  [(reg FLAGS_REG) (const_int 0)]))
12698   (set (match_operand 4 "any_QIreg_operand")
12699	(zero_extend (match_dup 2)))]
12700  "(peep2_reg_dead_p (4, operands[2])
12701    || operands_match_p (operands[2], operands[4]))
12702   && ! reg_overlap_mentioned_p (operands[4], operands[0])
12703   && ! reg_overlap_mentioned_p (operands[4], operands[1])
12704   && ! reg_overlap_mentioned_p (operands[4], operands[5])
12705   && ! reg_set_p (operands[4], operands[5])
12706   && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12707   && peep2_regno_dead_p (0, FLAGS_REG)"
12708  [(set (match_dup 6) (match_dup 0))
12709   (parallel [(set (match_dup 7) (match_dup 1))
12710	      (match_dup 5)])
12711   (set (strict_low_part (match_dup 8))
12712	(match_dup 3))]
12713{
12714  operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12715  operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12716  operands[8] = gen_lowpart (QImode, operands[4]);
12717  ix86_expand_clear (operands[4]);
12718})
12719
12720;; Similar, but match zero extend with andsi3.
12721
12722(define_peephole2
12723  [(set (reg FLAGS_REG) (match_operand 0))
12724   (set (match_operand:QI 1 "register_operand")
12725	(match_operator:QI 2 "ix86_comparison_operator"
12726	  [(reg FLAGS_REG) (const_int 0)]))
12727   (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12728		   (and:SI (match_dup 3) (const_int 255)))
12729	      (clobber (reg:CC FLAGS_REG))])]
12730  "REGNO (operands[1]) == REGNO (operands[3])
12731   && ! reg_overlap_mentioned_p (operands[3], operands[0])
12732   && peep2_regno_dead_p (0, FLAGS_REG)"
12733  [(set (match_dup 4) (match_dup 0))
12734   (set (strict_low_part (match_dup 5))
12735	(match_dup 2))]
12736{
12737  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12738  operands[5] = gen_lowpart (QImode, operands[3]);
12739  ix86_expand_clear (operands[3]);
12740})
12741
12742(define_peephole2
12743  [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12744	      (match_operand 4)])
12745   (set (match_operand:QI 1 "register_operand")
12746	(match_operator:QI 2 "ix86_comparison_operator"
12747	  [(reg FLAGS_REG) (const_int 0)]))
12748   (parallel [(set (match_operand 3 "any_QIreg_operand")
12749		   (zero_extend (match_dup 1)))
12750	      (clobber (reg:CC FLAGS_REG))])]
12751  "(peep2_reg_dead_p (3, operands[1])
12752    || operands_match_p (operands[1], operands[3]))
12753   && ! reg_overlap_mentioned_p (operands[3], operands[0])
12754   && ! reg_overlap_mentioned_p (operands[3], operands[4])
12755   && ! reg_set_p (operands[3], operands[4])
12756   && peep2_regno_dead_p (0, FLAGS_REG)"
12757  [(parallel [(set (match_dup 5) (match_dup 0))
12758	      (match_dup 4)])
12759   (set (strict_low_part (match_dup 6))
12760	(match_dup 2))]
12761{
12762  operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12763  operands[6] = gen_lowpart (QImode, operands[3]);
12764  ix86_expand_clear (operands[3]);
12765})
12766
12767(define_peephole2
12768  [(set (reg FLAGS_REG) (match_operand 0))
12769   (parallel [(set (reg FLAGS_REG) (match_operand 1))
12770	      (match_operand 5)])
12771   (set (match_operand:QI 2 "register_operand")
12772	(match_operator:QI 3 "ix86_comparison_operator"
12773	  [(reg FLAGS_REG) (const_int 0)]))
12774   (parallel [(set (match_operand 4 "any_QIreg_operand")
12775		   (zero_extend (match_dup 2)))
12776	      (clobber (reg:CC FLAGS_REG))])]
12777  "(peep2_reg_dead_p (4, operands[2])
12778    || operands_match_p (operands[2], operands[4]))
12779   && ! reg_overlap_mentioned_p (operands[4], operands[0])
12780   && ! reg_overlap_mentioned_p (operands[4], operands[1])
12781   && ! reg_overlap_mentioned_p (operands[4], operands[5])
12782   && ! reg_set_p (operands[4], operands[5])
12783   && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12784   && peep2_regno_dead_p (0, FLAGS_REG)"
12785  [(set (match_dup 6) (match_dup 0))
12786   (parallel [(set (match_dup 7) (match_dup 1))
12787	      (match_dup 5)])
12788   (set (strict_low_part (match_dup 8))
12789	(match_dup 3))]
12790{
12791  operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12792  operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12793  operands[8] = gen_lowpart (QImode, operands[4]);
12794  ix86_expand_clear (operands[4]);
12795})
12796
12797;; Call instructions.
12798
12799;; The predicates normally associated with named expanders are not properly
12800;; checked for calls.  This is a bug in the generic code, but it isn't that
12801;; easy to fix.  Ignore it for now and be prepared to fix things up.
12802
12803;; P6 processors will jump to the address after the decrement when %esp
12804;; is used as a call operand, so they will execute return address as a code.
12805;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12806
12807;; Register constraint for call instruction.
12808(define_mode_attr c [(SI "l") (DI "r")])
12809
12810;; Call subroutine returning no value.
12811
12812(define_expand "call"
12813  [(call (match_operand:QI 0)
12814	 (match_operand 1))
12815   (use (match_operand 2))]
12816  ""
12817{
12818  ix86_expand_call (NULL, operands[0], operands[1],
12819		    operands[2], NULL, false);
12820  DONE;
12821})
12822
12823(define_expand "sibcall"
12824  [(call (match_operand:QI 0)
12825	 (match_operand 1))
12826   (use (match_operand 2))]
12827  ""
12828{
12829  ix86_expand_call (NULL, operands[0], operands[1],
12830		    operands[2], NULL, true);
12831  DONE;
12832})
12833
12834(define_insn "*call"
12835  [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12836	 (match_operand 1))]
12837  "!SIBLING_CALL_P (insn)"
12838  "* return ix86_output_call_insn (insn, operands[0]);"
12839  [(set_attr "type" "call")])
12840
12841;; This covers both call and sibcall since only GOT slot is allowed.
12842(define_insn "*call_got_x32"
12843  [(call (mem:QI (zero_extend:DI
12844		   (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12845	 (match_operand 1))]
12846  "TARGET_X32"
12847{
12848  rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12849  return ix86_output_call_insn (insn, fnaddr);
12850}
12851  [(set_attr "type" "call")])
12852
12853;; Since sibcall never returns, we can only use call-clobbered register
12854;; as GOT base.
12855(define_insn "*sibcall_GOT_32"
12856  [(call (mem:QI
12857	   (mem:SI (plus:SI
12858		     (match_operand:SI 0 "register_no_elim_operand" "U")
12859		     (match_operand:SI 1 "GOT32_symbol_operand"))))
12860	 (match_operand 2))]
12861  "!TARGET_MACHO
12862  && !TARGET_64BIT
12863  && !TARGET_INDIRECT_BRANCH_REGISTER
12864  && SIBLING_CALL_P (insn)"
12865{
12866  rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12867  fnaddr = gen_const_mem (SImode, fnaddr);
12868  return ix86_output_call_insn (insn, fnaddr);
12869}
12870  [(set_attr "type" "call")])
12871
12872(define_insn "*sibcall"
12873  [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12874	 (match_operand 1))]
12875  "SIBLING_CALL_P (insn)"
12876  "* return ix86_output_call_insn (insn, operands[0]);"
12877  [(set_attr "type" "call")])
12878
12879(define_insn "*sibcall_memory"
12880  [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12881	 (match_operand 1))
12882   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12883  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12884  "* return ix86_output_call_insn (insn, operands[0]);"
12885  [(set_attr "type" "call")])
12886
12887(define_peephole2
12888  [(set (match_operand:W 0 "register_operand")
12889	(match_operand:W 1 "memory_operand"))
12890   (call (mem:QI (match_dup 0))
12891	 (match_operand 3))]
12892  "!TARGET_X32
12893   && !TARGET_INDIRECT_BRANCH_REGISTER
12894   && SIBLING_CALL_P (peep2_next_insn (1))
12895   && !reg_mentioned_p (operands[0],
12896			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12897  [(parallel [(call (mem:QI (match_dup 1))
12898		    (match_dup 3))
12899	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12900
12901(define_peephole2
12902  [(set (match_operand:W 0 "register_operand")
12903	(match_operand:W 1 "memory_operand"))
12904   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12905   (call (mem:QI (match_dup 0))
12906	 (match_operand 3))]
12907  "!TARGET_X32
12908   && !TARGET_INDIRECT_BRANCH_REGISTER
12909   && SIBLING_CALL_P (peep2_next_insn (2))
12910   && !reg_mentioned_p (operands[0],
12911			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12912  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12913   (parallel [(call (mem:QI (match_dup 1))
12914		    (match_dup 3))
12915	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12916
12917(define_expand "call_pop"
12918  [(parallel [(call (match_operand:QI 0)
12919		    (match_operand:SI 1))
12920	      (set (reg:SI SP_REG)
12921		   (plus:SI (reg:SI SP_REG)
12922			    (match_operand:SI 3)))])]
12923  "!TARGET_64BIT"
12924{
12925  ix86_expand_call (NULL, operands[0], operands[1],
12926		    operands[2], operands[3], false);
12927  DONE;
12928})
12929
12930(define_insn "*call_pop"
12931  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12932	 (match_operand 1))
12933   (set (reg:SI SP_REG)
12934	(plus:SI (reg:SI SP_REG)
12935		 (match_operand:SI 2 "immediate_operand" "i")))]
12936  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12937  "* return ix86_output_call_insn (insn, operands[0]);"
12938  [(set_attr "type" "call")])
12939
12940(define_insn "*sibcall_pop"
12941  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12942	 (match_operand 1))
12943   (set (reg:SI SP_REG)
12944	(plus:SI (reg:SI SP_REG)
12945		 (match_operand:SI 2 "immediate_operand" "i")))]
12946  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12947  "* return ix86_output_call_insn (insn, operands[0]);"
12948  [(set_attr "type" "call")])
12949
12950(define_insn "*sibcall_pop_memory"
12951  [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12952	 (match_operand 1))
12953   (set (reg:SI SP_REG)
12954	(plus:SI (reg:SI SP_REG)
12955		 (match_operand:SI 2 "immediate_operand" "i")))
12956   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12957  "!TARGET_64BIT"
12958  "* return ix86_output_call_insn (insn, operands[0]);"
12959  [(set_attr "type" "call")])
12960
12961(define_peephole2
12962  [(set (match_operand:SI 0 "register_operand")
12963	(match_operand:SI 1 "memory_operand"))
12964   (parallel [(call (mem:QI (match_dup 0))
12965		    (match_operand 3))
12966	      (set (reg:SI SP_REG)
12967		   (plus:SI (reg:SI SP_REG)
12968			    (match_operand:SI 4 "immediate_operand")))])]
12969  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12970   && !reg_mentioned_p (operands[0],
12971			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12972  [(parallel [(call (mem:QI (match_dup 1))
12973		    (match_dup 3))
12974	      (set (reg:SI SP_REG)
12975		   (plus:SI (reg:SI SP_REG)
12976			    (match_dup 4)))
12977	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12978
12979(define_peephole2
12980  [(set (match_operand:SI 0 "register_operand")
12981	(match_operand:SI 1 "memory_operand"))
12982   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12983   (parallel [(call (mem:QI (match_dup 0))
12984		    (match_operand 3))
12985	      (set (reg:SI SP_REG)
12986		   (plus:SI (reg:SI SP_REG)
12987			    (match_operand:SI 4 "immediate_operand")))])]
12988  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12989   && !reg_mentioned_p (operands[0],
12990			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12991  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12992   (parallel [(call (mem:QI (match_dup 1))
12993		    (match_dup 3))
12994	      (set (reg:SI SP_REG)
12995		   (plus:SI (reg:SI SP_REG)
12996			    (match_dup 4)))
12997	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12998
12999;; Combining simple memory jump instruction
13000
13001(define_peephole2
13002  [(set (match_operand:W 0 "register_operand")
13003        (match_operand:W 1 "memory_operand"))
13004   (set (pc) (match_dup 0))]
13005  "!TARGET_X32
13006   && !TARGET_INDIRECT_BRANCH_REGISTER
13007   && peep2_reg_dead_p (2, operands[0])"
13008  [(set (pc) (match_dup 1))])
13009
13010;; Call subroutine, returning value in operand 0
13011
13012(define_expand "call_value"
13013  [(set (match_operand 0)
13014	(call (match_operand:QI 1)
13015	      (match_operand 2)))
13016   (use (match_operand 3))]
13017  ""
13018{
13019  ix86_expand_call (operands[0], operands[1], operands[2],
13020		    operands[3], NULL, false);
13021  DONE;
13022})
13023
13024(define_expand "sibcall_value"
13025  [(set (match_operand 0)
13026	(call (match_operand:QI 1)
13027	      (match_operand 2)))
13028   (use (match_operand 3))]
13029  ""
13030{
13031  ix86_expand_call (operands[0], operands[1], operands[2],
13032		    operands[3], NULL, true);
13033  DONE;
13034})
13035
13036(define_insn "*call_value"
13037  [(set (match_operand 0)
13038	(call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13039	      (match_operand 2)))]
13040  "!SIBLING_CALL_P (insn)"
13041  "* return ix86_output_call_insn (insn, operands[1]);"
13042  [(set_attr "type" "callv")])
13043
13044;; This covers both call and sibcall since only GOT slot is allowed.
13045(define_insn "*call_value_got_x32"
13046  [(set (match_operand 0)
13047	(call (mem:QI
13048		(zero_extend:DI
13049		  (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13050	      (match_operand 2)))]
13051  "TARGET_X32"
13052{
13053  rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13054  return ix86_output_call_insn (insn, fnaddr);
13055}
13056  [(set_attr "type" "callv")])
13057
13058;; Since sibcall never returns, we can only use call-clobbered register
13059;; as GOT base.
13060(define_insn "*sibcall_value_GOT_32"
13061  [(set (match_operand 0)
13062        (call (mem:QI
13063		(mem:SI (plus:SI
13064			  (match_operand:SI 1 "register_no_elim_operand" "U")
13065			  (match_operand:SI 2 "GOT32_symbol_operand"))))
13066	 (match_operand 3)))]
13067  "!TARGET_MACHO
13068   && !TARGET_64BIT
13069   && !TARGET_INDIRECT_BRANCH_REGISTER
13070   && SIBLING_CALL_P (insn)"
13071{
13072  rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13073  fnaddr = gen_const_mem (SImode, fnaddr);
13074  return ix86_output_call_insn (insn, fnaddr);
13075}
13076  [(set_attr "type" "callv")])
13077
13078(define_insn "*sibcall_value"
13079  [(set (match_operand 0)
13080	(call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13081	      (match_operand 2)))]
13082  "SIBLING_CALL_P (insn)"
13083  "* return ix86_output_call_insn (insn, operands[1]);"
13084  [(set_attr "type" "callv")])
13085
13086(define_insn "*sibcall_value_memory"
13087  [(set (match_operand 0)
13088 	(call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13089	      (match_operand 2)))
13090   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13091  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13092  "* return ix86_output_call_insn (insn, operands[1]);"
13093  [(set_attr "type" "callv")])
13094
13095(define_peephole2
13096  [(set (match_operand:W 0 "register_operand")
13097	(match_operand:W 1 "memory_operand"))
13098   (set (match_operand 2)
13099   (call (mem:QI (match_dup 0))
13100		 (match_operand 3)))]
13101  "!TARGET_X32
13102   && !TARGET_INDIRECT_BRANCH_REGISTER
13103   && SIBLING_CALL_P (peep2_next_insn (1))
13104   && !reg_mentioned_p (operands[0],
13105			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13106  [(parallel [(set (match_dup 2)
13107		   (call (mem:QI (match_dup 1))
13108			 (match_dup 3)))
13109	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13110
13111(define_peephole2
13112  [(set (match_operand:W 0 "register_operand")
13113	(match_operand:W 1 "memory_operand"))
13114   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13115   (set (match_operand 2)
13116	(call (mem:QI (match_dup 0))
13117	      (match_operand 3)))]
13118  "!TARGET_X32
13119   && !TARGET_INDIRECT_BRANCH_REGISTER
13120   && SIBLING_CALL_P (peep2_next_insn (2))
13121   && !reg_mentioned_p (operands[0],
13122			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13123  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13124   (parallel [(set (match_dup 2)
13125		   (call (mem:QI (match_dup 1))
13126			 (match_dup 3)))
13127	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13128
13129(define_expand "call_value_pop"
13130  [(parallel [(set (match_operand 0)
13131		   (call (match_operand:QI 1)
13132			 (match_operand:SI 2)))
13133	      (set (reg:SI SP_REG)
13134		   (plus:SI (reg:SI SP_REG)
13135			    (match_operand:SI 4)))])]
13136  "!TARGET_64BIT"
13137{
13138  ix86_expand_call (operands[0], operands[1], operands[2],
13139		    operands[3], operands[4], false);
13140  DONE;
13141})
13142
13143(define_insn "*call_value_pop"
13144  [(set (match_operand 0)
13145	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13146	      (match_operand 2)))
13147   (set (reg:SI SP_REG)
13148	(plus:SI (reg:SI SP_REG)
13149		 (match_operand:SI 3 "immediate_operand" "i")))]
13150  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13151  "* return ix86_output_call_insn (insn, operands[1]);"
13152  [(set_attr "type" "callv")])
13153
13154(define_insn "*sibcall_value_pop"
13155  [(set (match_operand 0)
13156	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13157	      (match_operand 2)))
13158   (set (reg:SI SP_REG)
13159	(plus:SI (reg:SI SP_REG)
13160		 (match_operand:SI 3 "immediate_operand" "i")))]
13161  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13162  "* return ix86_output_call_insn (insn, operands[1]);"
13163  [(set_attr "type" "callv")])
13164
13165(define_insn "*sibcall_value_pop_memory"
13166  [(set (match_operand 0)
13167 	(call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13168	      (match_operand 2)))
13169   (set (reg:SI SP_REG)
13170	(plus:SI (reg:SI SP_REG)
13171		 (match_operand:SI 3 "immediate_operand" "i")))
13172   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13173  "!TARGET_64BIT"
13174  "* return ix86_output_call_insn (insn, operands[1]);"
13175  [(set_attr "type" "callv")])
13176
13177(define_peephole2
13178  [(set (match_operand:SI 0 "register_operand")
13179	(match_operand:SI 1 "memory_operand"))
13180   (parallel [(set (match_operand 2)
13181		   (call (mem:QI (match_dup 0))
13182			 (match_operand 3)))
13183	      (set (reg:SI SP_REG)
13184		   (plus:SI (reg:SI SP_REG)
13185			    (match_operand:SI 4 "immediate_operand")))])]
13186  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13187   && !reg_mentioned_p (operands[0],
13188			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13189  [(parallel [(set (match_dup 2)
13190		   (call (mem:QI (match_dup 1))
13191			 (match_dup 3)))
13192	      (set (reg:SI SP_REG)
13193		   (plus:SI (reg:SI SP_REG)
13194			    (match_dup 4)))
13195	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13196
13197(define_peephole2
13198  [(set (match_operand:SI 0 "register_operand")
13199	(match_operand:SI 1 "memory_operand"))
13200   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13201   (parallel [(set (match_operand 2)
13202		   (call (mem:QI (match_dup 0))
13203			 (match_operand 3)))
13204	      (set (reg:SI SP_REG)
13205		   (plus:SI (reg:SI SP_REG)
13206			    (match_operand:SI 4 "immediate_operand")))])]
13207  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13208   && !reg_mentioned_p (operands[0],
13209			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13210  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13211   (parallel [(set (match_dup 2)
13212		   (call (mem:QI (match_dup 1))
13213			 (match_dup 3)))
13214	      (set (reg:SI SP_REG)
13215		   (plus:SI (reg:SI SP_REG)
13216			    (match_dup 4)))
13217	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13218
13219;; Call subroutine returning any type.
13220
13221(define_expand "untyped_call"
13222  [(parallel [(call (match_operand 0)
13223		    (const_int 0))
13224	      (match_operand 1)
13225	      (match_operand 2)])]
13226  ""
13227{
13228  int i;
13229
13230  /* In order to give reg-stack an easier job in validating two
13231     coprocessor registers as containing a possible return value,
13232     simply pretend the untyped call returns a complex long double
13233     value. 
13234
13235     We can't use SSE_REGPARM_MAX here since callee is unprototyped
13236     and should have the default ABI.  */
13237
13238  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13239		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13240		    operands[0], const0_rtx,
13241		    GEN_INT ((TARGET_64BIT
13242			      ? (ix86_abi == SYSV_ABI
13243				 ? X86_64_SSE_REGPARM_MAX
13244				 : X86_64_MS_SSE_REGPARM_MAX)
13245			      : X86_32_SSE_REGPARM_MAX)
13246		    	     - 1),
13247		    NULL, false);
13248
13249  for (i = 0; i < XVECLEN (operands[2], 0); i++)
13250    {
13251      rtx set = XVECEXP (operands[2], 0, i);
13252      emit_move_insn (SET_DEST (set), SET_SRC (set));
13253    }
13254
13255  /* The optimizer does not know that the call sets the function value
13256     registers we stored in the result block.  We avoid problems by
13257     claiming that all hard registers are used and clobbered at this
13258     point.  */
13259  emit_insn (gen_blockage ());
13260
13261  DONE;
13262})
13263
13264;; Prologue and epilogue instructions
13265
13266;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13267;; all of memory.  This blocks insns from being moved across this point.
13268
13269(define_insn "blockage"
13270  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13271  ""
13272  ""
13273  [(set_attr "length" "0")])
13274
13275;; Do not schedule instructions accessing memory across this point.
13276
13277(define_expand "memory_blockage"
13278  [(set (match_dup 0)
13279	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13280  ""
13281{
13282  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13283  MEM_VOLATILE_P (operands[0]) = 1;
13284})
13285
13286(define_insn "*memory_blockage"
13287  [(set (match_operand:BLK 0)
13288	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13289  ""
13290  ""
13291  [(set_attr "length" "0")])
13292
13293;; As USE insns aren't meaningful after reload, this is used instead
13294;; to prevent deleting instructions setting registers for PIC code
13295(define_insn "prologue_use"
13296  [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13297  ""
13298  ""
13299  [(set_attr "length" "0")])
13300
13301;; Insn emitted into the body of a function to return from a function.
13302;; This is only done if the function's epilogue is known to be simple.
13303;; See comments for ix86_can_use_return_insn_p in i386.c.
13304
13305(define_expand "return"
13306  [(simple_return)]
13307  "ix86_can_use_return_insn_p ()"
13308{
13309  if (crtl->args.pops_args)
13310    {
13311      rtx popc = GEN_INT (crtl->args.pops_args);
13312      emit_jump_insn (gen_simple_return_pop_internal (popc));
13313      DONE;
13314    }
13315})
13316
13317;; We need to disable this for TARGET_SEH, as otherwise
13318;; shrink-wrapped prologue gets enabled too.  This might exceed
13319;; the maximum size of prologue in unwind information.
13320;; Also disallow shrink-wrapping if using stack slot to pass the
13321;; static chain pointer - the first instruction has to be pushl %esi
13322;; and it can't be moved around, as we use alternate entry points
13323;; in that case.
13324
13325(define_expand "simple_return"
13326  [(simple_return)]
13327  "!TARGET_SEH && !ix86_static_chain_on_stack"
13328{
13329  if (crtl->args.pops_args)
13330    {
13331      rtx popc = GEN_INT (crtl->args.pops_args);
13332      emit_jump_insn (gen_simple_return_pop_internal (popc));
13333      DONE;
13334    }
13335})
13336
13337(define_insn "simple_return_internal"
13338  [(simple_return)]
13339  "reload_completed"
13340  "* return ix86_output_function_return (false);"
13341  [(set_attr "length" "1")
13342   (set_attr "atom_unit" "jeu")
13343   (set_attr "length_immediate" "0")
13344   (set_attr "modrm" "0")])
13345
13346(define_insn "interrupt_return"
13347  [(simple_return)
13348   (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13349  "reload_completed"
13350{
13351  return TARGET_64BIT ? "iretq" : "iret";
13352})
13353
13354;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13355;; instruction Athlon and K8 have.
13356
13357(define_insn "simple_return_internal_long"
13358  [(simple_return)
13359   (unspec [(const_int 0)] UNSPEC_REP)]
13360  "reload_completed"
13361  "* return ix86_output_function_return (true);"
13362  [(set_attr "length" "2")
13363   (set_attr "atom_unit" "jeu")
13364   (set_attr "length_immediate" "0")
13365   (set_attr "prefix_rep" "1")
13366   (set_attr "modrm" "0")])
13367
13368(define_insn_and_split "simple_return_pop_internal"
13369  [(simple_return)
13370   (use (match_operand:SI 0 "const_int_operand"))]
13371  "reload_completed"
13372  "%!ret\t%0"
13373  "&& cfun->machine->function_return_type != indirect_branch_keep"
13374  [(const_int 0)]
13375  "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13376  [(set_attr "length" "3")
13377   (set_attr "atom_unit" "jeu")
13378   (set_attr "length_immediate" "2")
13379   (set_attr "modrm" "0")])
13380
13381(define_expand "simple_return_indirect_internal"
13382  [(parallel
13383     [(simple_return)
13384      (use (match_operand 0 "register_operand"))])])
13385
13386(define_insn "*simple_return_indirect_internal<mode>"
13387  [(simple_return)
13388   (use (match_operand:W 0 "register_operand" "r"))]
13389  "reload_completed"
13390  "* return ix86_output_indirect_function_return (operands[0]);"
13391  [(set (attr "type")
13392     (if_then_else (match_test "(cfun->machine->indirect_branch_type
13393				 != indirect_branch_keep)")
13394	(const_string "multi")
13395	(const_string "ibr")))
13396   (set_attr "length_immediate" "0")])
13397
13398(define_insn "nop"
13399  [(const_int 0)]
13400  ""
13401  "nop"
13402  [(set_attr "length" "1")
13403   (set_attr "length_immediate" "0")
13404   (set_attr "modrm" "0")])
13405
13406;; Generate nops.  Operand 0 is the number of nops, up to 8.
13407(define_insn "nops"
13408  [(unspec_volatile [(match_operand 0 "const_int_operand")]
13409		    UNSPECV_NOPS)]
13410  "reload_completed"
13411{
13412  int num = INTVAL (operands[0]);
13413
13414  gcc_assert (IN_RANGE (num, 1, 8));
13415
13416  while (num--)
13417    fputs ("\tnop\n", asm_out_file);
13418
13419  return "";
13420}
13421  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13422   (set_attr "length_immediate" "0")
13423   (set_attr "modrm" "0")])
13424
13425;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13426;; branch prediction penalty for the third jump in a 16-byte
13427;; block on K8.
13428
13429(define_insn "pad"
13430  [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13431  ""
13432{
13433#ifdef ASM_OUTPUT_MAX_SKIP_PAD
13434  ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13435#else
13436  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13437     The align insn is used to avoid 3 jump instructions in the row to improve
13438     branch prediction and the benefits hardly outweigh the cost of extra 8
13439     nops on the average inserted by full alignment pseudo operation.  */
13440#endif
13441  return "";
13442}
13443  [(set_attr "length" "16")])
13444
13445(define_expand "prologue"
13446  [(const_int 0)]
13447  ""
13448  "ix86_expand_prologue (); DONE;")
13449
13450(define_expand "set_got"
13451  [(parallel
13452     [(set (match_operand:SI 0 "register_operand")
13453	   (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13454      (clobber (reg:CC FLAGS_REG))])]
13455  "!TARGET_64BIT"
13456{
13457  if (flag_pic && !TARGET_VXWORKS_RTP)
13458    ix86_pc_thunk_call_expanded = true;
13459})
13460
13461(define_insn "*set_got"
13462  [(set (match_operand:SI 0 "register_operand" "=r")
13463	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13464   (clobber (reg:CC FLAGS_REG))]
13465  "!TARGET_64BIT"
13466  "* return output_set_got (operands[0], NULL_RTX);"
13467  [(set_attr "type" "multi")
13468   (set_attr "length" "12")])
13469
13470(define_expand "set_got_labelled"
13471  [(parallel
13472     [(set (match_operand:SI 0 "register_operand")
13473	   (unspec:SI [(label_ref (match_operand 1))]
13474		      UNSPEC_SET_GOT))
13475      (clobber (reg:CC FLAGS_REG))])]
13476  "!TARGET_64BIT"
13477{
13478  if (flag_pic && !TARGET_VXWORKS_RTP)
13479    ix86_pc_thunk_call_expanded = true;
13480})
13481
13482(define_insn "*set_got_labelled"
13483  [(set (match_operand:SI 0 "register_operand" "=r")
13484	(unspec:SI [(label_ref (match_operand 1))]
13485	 UNSPEC_SET_GOT))
13486   (clobber (reg:CC FLAGS_REG))]
13487  "!TARGET_64BIT"
13488  "* return output_set_got (operands[0], operands[1]);"
13489  [(set_attr "type" "multi")
13490   (set_attr "length" "12")])
13491
13492(define_insn "set_got_rex64"
13493  [(set (match_operand:DI 0 "register_operand" "=r")
13494	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13495  "TARGET_64BIT"
13496  "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13497  [(set_attr "type" "lea")
13498   (set_attr "length_address" "4")
13499   (set_attr "mode" "DI")])
13500
13501(define_insn "set_rip_rex64"
13502  [(set (match_operand:DI 0 "register_operand" "=r")
13503	(unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13504  "TARGET_64BIT"
13505  "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13506  [(set_attr "type" "lea")
13507   (set_attr "length_address" "4")
13508   (set_attr "mode" "DI")])
13509
13510(define_insn "set_got_offset_rex64"
13511  [(set (match_operand:DI 0 "register_operand" "=r")
13512	(unspec:DI
13513	  [(label_ref (match_operand 1))]
13514	  UNSPEC_SET_GOT_OFFSET))]
13515  "TARGET_LP64"
13516  "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13517  [(set_attr "type" "imov")
13518   (set_attr "length_immediate" "0")
13519   (set_attr "length_address" "8")
13520   (set_attr "mode" "DI")])
13521
13522(define_expand "epilogue"
13523  [(const_int 0)]
13524  ""
13525  "ix86_expand_epilogue (1); DONE;")
13526
13527(define_expand "sibcall_epilogue"
13528  [(const_int 0)]
13529  ""
13530  "ix86_expand_epilogue (0); DONE;")
13531
13532(define_expand "eh_return"
13533  [(use (match_operand 0 "register_operand"))]
13534  ""
13535{
13536  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13537
13538  /* Tricky bit: we write the address of the handler to which we will
13539     be returning into someone else's stack frame, one word below the
13540     stack address we wish to restore.  */
13541  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13542  tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13543  /* Return address is always in word_mode.  */
13544  tmp = gen_rtx_MEM (word_mode, tmp);
13545  if (GET_MODE (ra) != word_mode)
13546    ra = convert_to_mode (word_mode, ra, 1);
13547  emit_move_insn (tmp, ra);
13548
13549  emit_jump_insn (gen_eh_return_internal ());
13550  emit_barrier ();
13551  DONE;
13552})
13553
13554(define_insn_and_split "eh_return_internal"
13555  [(eh_return)]
13556  ""
13557  "#"
13558  "epilogue_completed"
13559  [(const_int 0)]
13560  "ix86_expand_epilogue (2); DONE;")
13561
13562(define_expand "@leave_<mode>"
13563  [(parallel
13564    [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
13565     (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
13566     (clobber (mem:BLK (scratch)))])]
13567  ""
13568  "operands[0] = GEN_INT (<MODE_SIZE>);")
13569
13570(define_insn "*leave"
13571  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13572   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13573   (clobber (mem:BLK (scratch)))]
13574  "!TARGET_64BIT"
13575  "leave"
13576  [(set_attr "type" "leave")])
13577
13578(define_insn "*leave_rex64"
13579  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13580   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13581   (clobber (mem:BLK (scratch)))]
13582  "TARGET_64BIT"
13583  "leave"
13584  [(set_attr "type" "leave")])
13585
13586;; Handle -fsplit-stack.
13587
13588(define_expand "split_stack_prologue"
13589  [(const_int 0)]
13590  ""
13591{
13592  ix86_expand_split_stack_prologue ();
13593  DONE;
13594})
13595
13596;; In order to support the call/return predictor, we use a return
13597;; instruction which the middle-end doesn't see.
13598(define_insn "split_stack_return"
13599  [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13600		     UNSPECV_SPLIT_STACK_RETURN)]
13601  ""
13602{
13603  if (operands[0] == const0_rtx)
13604    return "ret";
13605  else
13606    return "ret\t%0";
13607}
13608  [(set_attr "atom_unit" "jeu")
13609   (set_attr "modrm" "0")
13610   (set (attr "length")
13611	(if_then_else (match_operand:SI 0 "const0_operand")
13612		      (const_int 1)
13613		      (const_int 3)))
13614   (set (attr "length_immediate")
13615	(if_then_else (match_operand:SI 0 "const0_operand")
13616		      (const_int 0)
13617		      (const_int 2)))])
13618
13619;; If there are operand 0 bytes available on the stack, jump to
13620;; operand 1.
13621
13622(define_expand "split_stack_space_check"
13623  [(set (pc) (if_then_else
13624	      (ltu (minus (reg SP_REG)
13625			  (match_operand 0 "register_operand"))
13626		   (match_dup 2))
13627	      (label_ref (match_operand 1))
13628	      (pc)))]
13629  ""
13630{
13631  rtx reg = gen_reg_rtx (Pmode);
13632
13633  emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13634
13635  operands[2] = ix86_split_stack_guard ();
13636  ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13637
13638  DONE;
13639})
13640
13641;; Bit manipulation instructions.
13642
13643(define_expand "ffs<mode>2"
13644  [(set (match_dup 2) (const_int -1))
13645   (parallel [(set (match_dup 3) (match_dup 4))
13646	      (set (match_operand:SWI48 0 "register_operand")
13647		   (ctz:SWI48
13648		     (match_operand:SWI48 1 "nonimmediate_operand")))])
13649   (set (match_dup 0) (if_then_else:SWI48
13650			(eq (match_dup 3) (const_int 0))
13651			(match_dup 2)
13652			(match_dup 0)))
13653   (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13654	      (clobber (reg:CC FLAGS_REG))])]
13655  ""
13656{
13657  machine_mode flags_mode;
13658
13659  if (<MODE>mode == SImode && !TARGET_CMOVE)
13660    {
13661      emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13662      DONE;
13663    }
13664
13665  flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13666
13667  operands[2] = gen_reg_rtx (<MODE>mode);
13668  operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13669  operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13670})
13671
13672(define_insn_and_split "ffssi2_no_cmove"
13673  [(set (match_operand:SI 0 "register_operand" "=r")
13674	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13675   (clobber (match_scratch:SI 2 "=&q"))
13676   (clobber (reg:CC FLAGS_REG))]
13677  "!TARGET_CMOVE"
13678  "#"
13679  "&& reload_completed"
13680  [(parallel [(set (match_dup 4) (match_dup 5))
13681	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
13682   (set (strict_low_part (match_dup 3))
13683	(eq:QI (match_dup 4) (const_int 0)))
13684   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13685	      (clobber (reg:CC FLAGS_REG))])
13686   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13687	      (clobber (reg:CC FLAGS_REG))])
13688   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13689	      (clobber (reg:CC FLAGS_REG))])]
13690{
13691  machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13692
13693  operands[3] = gen_lowpart (QImode, operands[2]);
13694  operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13695  operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13696
13697  ix86_expand_clear (operands[2]);
13698})
13699
13700(define_insn_and_split "*tzcnt<mode>_1"
13701  [(set (reg:CCC FLAGS_REG)
13702	(compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13703		     (const_int 0)))
13704   (set (match_operand:SWI48 0 "register_operand" "=r")
13705	(ctz:SWI48 (match_dup 1)))]
13706  "TARGET_BMI"
13707  "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13708  "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13709   && optimize_function_for_speed_p (cfun)
13710   && !reg_mentioned_p (operands[0], operands[1])"
13711  [(parallel
13712    [(set (reg:CCC FLAGS_REG)
13713	  (compare:CCC (match_dup 1) (const_int 0)))
13714     (set (match_dup 0)
13715	  (ctz:SWI48 (match_dup 1)))
13716     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13717  "ix86_expand_clear (operands[0]);"
13718  [(set_attr "type" "alu1")
13719   (set_attr "prefix_0f" "1")
13720   (set_attr "prefix_rep" "1")
13721   (set_attr "btver2_decode" "double")
13722   (set_attr "mode" "<MODE>")])
13723
13724; False dependency happens when destination is only updated by tzcnt,
13725; lzcnt or popcnt.  There is no false dependency when destination is
13726; also used in source.
13727(define_insn "*tzcnt<mode>_1_falsedep"
13728  [(set (reg:CCC FLAGS_REG)
13729	(compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13730		     (const_int 0)))
13731   (set (match_operand:SWI48 0 "register_operand" "=r")
13732	(ctz:SWI48 (match_dup 1)))
13733   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13734	   UNSPEC_INSN_FALSE_DEP)]
13735  "TARGET_BMI"
13736  "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13737  [(set_attr "type" "alu1")
13738   (set_attr "prefix_0f" "1")
13739   (set_attr "prefix_rep" "1")
13740   (set_attr "btver2_decode" "double")
13741   (set_attr "mode" "<MODE>")])
13742
13743(define_insn "*bsf<mode>_1"
13744  [(set (reg:CCZ FLAGS_REG)
13745	(compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13746		     (const_int 0)))
13747   (set (match_operand:SWI48 0 "register_operand" "=r")
13748	(ctz:SWI48 (match_dup 1)))]
13749  ""
13750  "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13751  [(set_attr "type" "alu1")
13752   (set_attr "prefix_0f" "1")
13753   (set_attr "btver2_decode" "double")
13754   (set_attr "znver1_decode" "vector")
13755   (set_attr "mode" "<MODE>")])
13756
13757(define_insn_and_split "ctz<mode>2"
13758  [(set (match_operand:SWI48 0 "register_operand" "=r")
13759	(ctz:SWI48
13760	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13761   (clobber (reg:CC FLAGS_REG))]
13762  ""
13763{
13764  if (TARGET_BMI)
13765    return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13766  else if (optimize_function_for_size_p (cfun))
13767    ;
13768  else if (TARGET_GENERIC)
13769    /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13770    return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13771
13772  return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13773}
13774  "(TARGET_BMI || TARGET_GENERIC)
13775   && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13776   && optimize_function_for_speed_p (cfun)
13777   && !reg_mentioned_p (operands[0], operands[1])"
13778  [(parallel
13779    [(set (match_dup 0)
13780	  (ctz:SWI48 (match_dup 1)))
13781     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13782     (clobber (reg:CC FLAGS_REG))])]
13783  "ix86_expand_clear (operands[0]);"
13784  [(set_attr "type" "alu1")
13785   (set_attr "prefix_0f" "1")
13786   (set (attr "prefix_rep")
13787     (if_then_else
13788       (ior (match_test "TARGET_BMI")
13789	    (and (not (match_test "optimize_function_for_size_p (cfun)"))
13790		 (match_test "TARGET_GENERIC")))
13791       (const_string "1")
13792       (const_string "0")))
13793   (set_attr "mode" "<MODE>")])
13794
13795; False dependency happens when destination is only updated by tzcnt,
13796; lzcnt or popcnt.  There is no false dependency when destination is
13797; also used in source.
13798(define_insn "*ctz<mode>2_falsedep"
13799  [(set (match_operand:SWI48 0 "register_operand" "=r")
13800	(ctz:SWI48
13801	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13802   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13803	   UNSPEC_INSN_FALSE_DEP)
13804   (clobber (reg:CC FLAGS_REG))]
13805  ""
13806{
13807  if (TARGET_BMI)
13808    return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13809  else if (TARGET_GENERIC)
13810    /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13811    return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13812  else
13813    gcc_unreachable ();
13814}
13815  [(set_attr "type" "alu1")
13816   (set_attr "prefix_0f" "1")
13817   (set_attr "prefix_rep" "1")
13818   (set_attr "mode" "<MODE>")])
13819
13820(define_insn "bsr_rex64"
13821  [(set (reg:CCZ FLAGS_REG)
13822	(compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13823		     (const_int 0)))
13824   (set (match_operand:DI 0 "register_operand" "=r")
13825	(minus:DI (const_int 63)
13826		  (clz:DI (match_dup 1))))]
13827  "TARGET_64BIT"
13828  "bsr{q}\t{%1, %0|%0, %1}"
13829  [(set_attr "type" "alu1")
13830   (set_attr "prefix_0f" "1")
13831   (set_attr "znver1_decode" "vector")
13832   (set_attr "mode" "DI")])
13833
13834(define_insn "bsr"
13835  [(set (reg:CCZ FLAGS_REG)
13836	(compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13837		     (const_int 0)))
13838   (set (match_operand:SI 0 "register_operand" "=r")
13839	(minus:SI (const_int 31)
13840		  (clz:SI (match_dup 1))))]
13841  ""
13842  "bsr{l}\t{%1, %0|%0, %1}"
13843  [(set_attr "type" "alu1")
13844   (set_attr "prefix_0f" "1")
13845   (set_attr "znver1_decode" "vector")
13846   (set_attr "mode" "SI")])
13847
13848(define_expand "clz<mode>2"
13849  [(parallel
13850     [(set (reg:CCZ FLAGS_REG)
13851	(compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13852		     (const_int 0)))
13853      (set (match_operand:SWI48 0 "register_operand")
13854	   (minus:SWI48
13855	     (match_dup 2)
13856	     (clz:SWI48 (match_dup 1))))])
13857   (parallel
13858     [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13859      (clobber (reg:CC FLAGS_REG))])]
13860  ""
13861{
13862  if (TARGET_LZCNT)
13863    {
13864      emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13865      DONE;
13866    }
13867  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13868})
13869
13870(define_insn_and_split "clz<mode>2_lzcnt"
13871  [(set (match_operand:SWI48 0 "register_operand" "=r")
13872	(clz:SWI48
13873	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13874   (clobber (reg:CC FLAGS_REG))]
13875  "TARGET_LZCNT"
13876  "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13877  "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13878   && optimize_function_for_speed_p (cfun)
13879   && !reg_mentioned_p (operands[0], operands[1])"
13880  [(parallel
13881    [(set (match_dup 0)
13882	  (clz:SWI48 (match_dup 1)))
13883     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13884     (clobber (reg:CC FLAGS_REG))])]
13885  "ix86_expand_clear (operands[0]);"
13886  [(set_attr "prefix_rep" "1")
13887   (set_attr "type" "bitmanip")
13888   (set_attr "mode" "<MODE>")])
13889
13890; False dependency happens when destination is only updated by tzcnt,
13891; lzcnt or popcnt.  There is no false dependency when destination is
13892; also used in source.
13893(define_insn "*clz<mode>2_lzcnt_falsedep"
13894  [(set (match_operand:SWI48 0 "register_operand" "=r")
13895	(clz:SWI48
13896	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13897   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13898	   UNSPEC_INSN_FALSE_DEP)
13899   (clobber (reg:CC FLAGS_REG))]
13900  "TARGET_LZCNT"
13901  "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13902  [(set_attr "prefix_rep" "1")
13903   (set_attr "type" "bitmanip")
13904   (set_attr "mode" "<MODE>")])
13905
13906(define_int_iterator LT_ZCNT
13907	[(UNSPEC_TZCNT "TARGET_BMI")
13908	 (UNSPEC_LZCNT "TARGET_LZCNT")])
13909
13910(define_int_attr lt_zcnt
13911	[(UNSPEC_TZCNT "tzcnt")
13912	 (UNSPEC_LZCNT "lzcnt")])
13913
13914(define_int_attr lt_zcnt_type
13915	[(UNSPEC_TZCNT "alu1")
13916	 (UNSPEC_LZCNT "bitmanip")])
13917
13918;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
13919;; provides operand size as output when source operand is zero. 
13920
13921(define_insn_and_split "<lt_zcnt>_<mode>"
13922  [(set (match_operand:SWI48 0 "register_operand" "=r")
13923	(unspec:SWI48
13924	  [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13925   (clobber (reg:CC FLAGS_REG))]
13926  ""
13927  "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13928  "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13929   && optimize_function_for_speed_p (cfun)
13930   && !reg_mentioned_p (operands[0], operands[1])"
13931  [(parallel
13932    [(set (match_dup 0)
13933	  (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13934     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13935     (clobber (reg:CC FLAGS_REG))])]
13936  "ix86_expand_clear (operands[0]);"
13937  [(set_attr "type" "<lt_zcnt_type>")
13938   (set_attr "prefix_0f" "1")
13939   (set_attr "prefix_rep" "1")
13940   (set_attr "mode" "<MODE>")])
13941
13942; False dependency happens when destination is only updated by tzcnt,
13943; lzcnt or popcnt.  There is no false dependency when destination is
13944; also used in source.
13945(define_insn "*<lt_zcnt>_<mode>_falsedep"
13946  [(set (match_operand:SWI48 0 "register_operand" "=r")
13947	(unspec:SWI48
13948	  [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13949   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13950	   UNSPEC_INSN_FALSE_DEP)
13951   (clobber (reg:CC FLAGS_REG))]
13952  ""
13953  "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13954  [(set_attr "type" "<lt_zcnt_type>")
13955   (set_attr "prefix_0f" "1")
13956   (set_attr "prefix_rep" "1")
13957   (set_attr "mode" "<MODE>")])
13958
13959(define_insn "<lt_zcnt>_hi"
13960  [(set (match_operand:HI 0 "register_operand" "=r")
13961	(unspec:HI
13962	  [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13963   (clobber (reg:CC FLAGS_REG))]
13964  ""
13965  "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13966  [(set_attr "type" "<lt_zcnt_type>")
13967   (set_attr "prefix_0f" "1")
13968   (set_attr "prefix_rep" "1")
13969   (set_attr "mode" "HI")])
13970
13971;; BMI instructions.
13972
13973(define_insn "bmi_bextr_<mode>"
13974  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13975	(unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13976		       (match_operand:SWI48 2 "register_operand" "r,r")]
13977		      UNSPEC_BEXTR))
13978   (clobber (reg:CC FLAGS_REG))]
13979  "TARGET_BMI"
13980  "bextr\t{%2, %1, %0|%0, %1, %2}"
13981  [(set_attr "type" "bitmanip")
13982   (set_attr "btver2_decode" "direct, double")
13983   (set_attr "mode" "<MODE>")])
13984
13985(define_insn "*bmi_bextr_<mode>_ccz"
13986  [(set (reg:CCZ FLAGS_REG)
13987	(compare:CCZ
13988	  (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13989			 (match_operand:SWI48 2 "register_operand" "r,r")]
13990			UNSPEC_BEXTR)
13991	  (const_int 0)))
13992   (clobber (match_scratch:SWI48 0 "=r,r"))]
13993  "TARGET_BMI"
13994  "bextr\t{%2, %1, %0|%0, %1, %2}"
13995  [(set_attr "type" "bitmanip")
13996   (set_attr "btver2_decode" "direct, double")
13997   (set_attr "mode" "<MODE>")])
13998
13999(define_insn "*bmi_blsi_<mode>"
14000  [(set (match_operand:SWI48 0 "register_operand" "=r")
14001        (and:SWI48
14002          (neg:SWI48
14003            (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14004          (match_dup 1)))
14005   (clobber (reg:CC FLAGS_REG))]
14006  "TARGET_BMI"
14007  "blsi\t{%1, %0|%0, %1}"
14008  [(set_attr "type" "bitmanip")
14009   (set_attr "btver2_decode" "double")
14010   (set_attr "mode" "<MODE>")])
14011
14012(define_insn "*bmi_blsmsk_<mode>"
14013  [(set (match_operand:SWI48 0 "register_operand" "=r")
14014        (xor:SWI48
14015          (plus:SWI48
14016            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14017            (const_int -1))
14018          (match_dup 1)))
14019   (clobber (reg:CC FLAGS_REG))]
14020  "TARGET_BMI"
14021  "blsmsk\t{%1, %0|%0, %1}"
14022  [(set_attr "type" "bitmanip")
14023   (set_attr "btver2_decode" "double")
14024   (set_attr "mode" "<MODE>")])
14025
14026(define_insn "*bmi_blsr_<mode>"
14027  [(set (match_operand:SWI48 0 "register_operand" "=r")
14028        (and:SWI48
14029          (plus:SWI48
14030            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14031            (const_int -1))
14032          (match_dup 1)))
14033   (clobber (reg:CC FLAGS_REG))]
14034   "TARGET_BMI"
14035   "blsr\t{%1, %0|%0, %1}"
14036  [(set_attr "type" "bitmanip")
14037   (set_attr "btver2_decode" "double")
14038   (set_attr "mode" "<MODE>")])
14039
14040(define_insn "*bmi_blsr_<mode>_cmp"
14041  [(set (reg:CCZ FLAGS_REG)
14042	(compare:CCZ
14043	  (and:SWI48
14044	    (plus:SWI48
14045	      (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14046	      (const_int -1))
14047	    (match_dup 1))
14048	  (const_int 0)))
14049   (set (match_operand:SWI48 0 "register_operand" "=r")
14050	(and:SWI48
14051	  (plus:SWI48
14052	    (match_dup 1)
14053	    (const_int -1))
14054	  (match_dup 1)))]
14055   "TARGET_BMI"
14056   "blsr\t{%1, %0|%0, %1}"
14057  [(set_attr "type" "bitmanip")
14058   (set_attr "btver2_decode" "double")
14059   (set_attr "mode" "<MODE>")])
14060
14061(define_insn "*bmi_blsr_<mode>_ccz"
14062  [(set (reg:CCZ FLAGS_REG)
14063	(compare:CCZ
14064	  (and:SWI48
14065	    (plus:SWI48
14066	      (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14067	      (const_int -1))
14068	    (match_dup 1))
14069	  (const_int 0)))
14070   (clobber (match_scratch:SWI48 0 "=r"))]
14071   "TARGET_BMI"
14072   "blsr\t{%1, %0|%0, %1}"
14073  [(set_attr "type" "bitmanip")
14074   (set_attr "btver2_decode" "double")
14075   (set_attr "mode" "<MODE>")])
14076
14077;; BMI2 instructions.
14078(define_expand "bmi2_bzhi_<mode>3"
14079  [(parallel
14080    [(set (match_operand:SWI48 0 "register_operand")
14081	  (if_then_else:SWI48
14082	    (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
14083			      (const_int 255))
14084		   (const_int 0))
14085	    (zero_extract:SWI48
14086	      (match_operand:SWI48 1 "nonimmediate_operand")
14087	      (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
14088			  (match_dup 3))
14089	      (const_int 0))
14090	    (const_int 0)))
14091     (clobber (reg:CC FLAGS_REG))])]
14092  "TARGET_BMI2"
14093  "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14094
14095(define_insn "*bmi2_bzhi_<mode>3"
14096  [(set (match_operand:SWI48 0 "register_operand" "=r")
14097	(if_then_else:SWI48
14098	  (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14099			    (const_int 255))
14100		 (const_int 0))
14101	  (zero_extract:SWI48
14102	    (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14103	    (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
14104			(match_operand:SWI48 3 "const_int_operand" "n"))
14105	    (const_int 0))
14106	  (const_int 0)))
14107   (clobber (reg:CC FLAGS_REG))]
14108  "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14109  "bzhi\t{%2, %1, %0|%0, %1, %2}"
14110  [(set_attr "type" "bitmanip")
14111   (set_attr "prefix" "vex")
14112   (set_attr "mode" "<MODE>")])
14113
14114(define_insn "*bmi2_bzhi_<mode>3_1"
14115  [(set (match_operand:SWI48 0 "register_operand" "=r")
14116	(if_then_else:SWI48
14117	  (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
14118	  (zero_extract:SWI48
14119	    (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14120	    (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
14121			(match_operand:SWI48 3 "const_int_operand" "n"))
14122	    (const_int 0))
14123	  (const_int 0)))
14124   (clobber (reg:CC FLAGS_REG))]
14125  "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14126  "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14127  [(set_attr "type" "bitmanip")
14128   (set_attr "prefix" "vex")
14129   (set_attr "mode" "<MODE>")])
14130
14131(define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14132  [(set (reg:CCZ FLAGS_REG)
14133	(compare:CCZ
14134	  (if_then_else:SWI48
14135	    (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
14136	    (zero_extract:SWI48
14137	      (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14138	      (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
14139			  (match_operand:SWI48 3 "const_int_operand" "n"))
14140	      (const_int 0))
14141	    (const_int 0))
14142	(const_int 0)))
14143   (clobber (match_scratch:SWI48 0 "=r"))]
14144  "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14145  "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14146  [(set_attr "type" "bitmanip")
14147   (set_attr "prefix" "vex")
14148   (set_attr "mode" "<MODE>")])
14149
14150(define_insn "*bmi2_bzhi_<mode>3_2"
14151  [(set (match_operand:SWI48 0 "register_operand" "=r")
14152	(and:SWI48
14153	  (plus:SWI48
14154	    (ashift:SWI48 (const_int 1)
14155			  (match_operand:QI 2 "register_operand" "r"))
14156	    (const_int -1))
14157	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14158   (clobber (reg:CC FLAGS_REG))]
14159  "TARGET_BMI2"
14160  "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14161  [(set_attr "type" "bitmanip")
14162   (set_attr "prefix" "vex")
14163   (set_attr "mode" "<MODE>")])
14164
14165(define_insn "*bmi2_bzhi_<mode>3_3"
14166  [(set (match_operand:SWI48 0 "register_operand" "=r")
14167	(and:SWI48
14168	  (not:SWI48
14169	    (ashift:SWI48 (const_int -1)
14170			  (match_operand:QI 2 "register_operand" "r")))
14171	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14172   (clobber (reg:CC FLAGS_REG))]
14173  "TARGET_BMI2"
14174  "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14175  [(set_attr "type" "bitmanip")
14176   (set_attr "prefix" "vex")
14177   (set_attr "mode" "<MODE>")])
14178
14179(define_insn "bmi2_pdep_<mode>3"
14180  [(set (match_operand:SWI48 0 "register_operand" "=r")
14181        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14182                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14183                       UNSPEC_PDEP))]
14184  "TARGET_BMI2"
14185  "pdep\t{%2, %1, %0|%0, %1, %2}"
14186  [(set_attr "type" "bitmanip")
14187   (set_attr "prefix" "vex")
14188   (set_attr "mode" "<MODE>")])
14189
14190(define_insn "bmi2_pext_<mode>3"
14191  [(set (match_operand:SWI48 0 "register_operand" "=r")
14192        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14193                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14194                       UNSPEC_PEXT))]
14195  "TARGET_BMI2"
14196  "pext\t{%2, %1, %0|%0, %1, %2}"
14197  [(set_attr "type" "bitmanip")
14198   (set_attr "prefix" "vex")
14199   (set_attr "mode" "<MODE>")])
14200
14201;; TBM instructions.
14202(define_expand "tbm_bextri_<mode>"
14203  [(parallel
14204    [(set (match_operand:SWI48 0 "register_operand")
14205	  (zero_extract:SWI48
14206	    (match_operand:SWI48 1 "nonimmediate_operand")
14207	    (match_operand 2 "const_0_to_255_operand" "N")
14208	    (match_operand 3 "const_0_to_255_operand" "N")))
14209     (clobber (reg:CC FLAGS_REG))])]
14210  "TARGET_TBM"
14211{
14212  if (operands[2] == const0_rtx
14213      || INTVAL (operands[3]) >= <MODE_SIZE> * BITS_PER_UNIT)
14214    {
14215      emit_move_insn (operands[0], const0_rtx);
14216      DONE;
14217    }
14218  if (INTVAL (operands[2]) + INTVAL (operands[3])
14219      > <MODE_SIZE> * BITS_PER_UNIT)
14220    operands[2] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - INTVAL (operands[3]));
14221})
14222
14223(define_insn "*tbm_bextri_<mode>"
14224  [(set (match_operand:SWI48 0 "register_operand" "=r")
14225        (zero_extract:SWI48
14226          (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14227          (match_operand 2 "const_0_to_255_operand" "N")
14228          (match_operand 3 "const_0_to_255_operand" "N")))
14229   (clobber (reg:CC FLAGS_REG))]
14230   "TARGET_TBM"
14231{
14232  operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14233  return "bextr\t{%2, %1, %0|%0, %1, %2}";
14234}
14235  [(set_attr "type" "bitmanip")
14236   (set_attr "mode" "<MODE>")])
14237
14238(define_insn "*tbm_blcfill_<mode>"
14239  [(set (match_operand:SWI48 0 "register_operand" "=r")
14240        (and:SWI48
14241          (plus:SWI48
14242            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14243            (const_int 1))
14244          (match_dup 1)))
14245   (clobber (reg:CC FLAGS_REG))]
14246   "TARGET_TBM"
14247   "blcfill\t{%1, %0|%0, %1}"
14248  [(set_attr "type" "bitmanip")
14249   (set_attr "mode" "<MODE>")])
14250
14251(define_insn "*tbm_blci_<mode>"
14252  [(set (match_operand:SWI48 0 "register_operand" "=r")
14253        (ior:SWI48
14254          (not:SWI48
14255            (plus:SWI48
14256              (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14257              (const_int 1)))
14258          (match_dup 1)))
14259   (clobber (reg:CC FLAGS_REG))]
14260   "TARGET_TBM"
14261   "blci\t{%1, %0|%0, %1}"
14262  [(set_attr "type" "bitmanip")
14263   (set_attr "mode" "<MODE>")])
14264
14265(define_insn "*tbm_blcic_<mode>"
14266  [(set (match_operand:SWI48 0 "register_operand" "=r")
14267        (and:SWI48
14268          (plus:SWI48
14269            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14270            (const_int 1))
14271          (not:SWI48
14272            (match_dup 1))))
14273   (clobber (reg:CC FLAGS_REG))]
14274   "TARGET_TBM"
14275   "blcic\t{%1, %0|%0, %1}"
14276  [(set_attr "type" "bitmanip")
14277   (set_attr "mode" "<MODE>")])
14278
14279(define_insn "*tbm_blcmsk_<mode>"
14280  [(set (match_operand:SWI48 0 "register_operand" "=r")
14281        (xor:SWI48
14282          (plus:SWI48
14283            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14284            (const_int 1))
14285          (match_dup 1)))
14286   (clobber (reg:CC FLAGS_REG))]
14287   "TARGET_TBM"
14288   "blcmsk\t{%1, %0|%0, %1}"
14289  [(set_attr "type" "bitmanip")
14290   (set_attr "mode" "<MODE>")])
14291
14292(define_insn "*tbm_blcs_<mode>"
14293  [(set (match_operand:SWI48 0 "register_operand" "=r")
14294        (ior:SWI48
14295          (plus:SWI48
14296            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14297            (const_int 1))
14298          (match_dup 1)))
14299   (clobber (reg:CC FLAGS_REG))]
14300   "TARGET_TBM"
14301   "blcs\t{%1, %0|%0, %1}"
14302  [(set_attr "type" "bitmanip")
14303   (set_attr "mode" "<MODE>")])
14304
14305(define_insn "*tbm_blsfill_<mode>"
14306  [(set (match_operand:SWI48 0 "register_operand" "=r")
14307        (ior:SWI48
14308          (plus:SWI48
14309            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14310            (const_int -1))
14311          (match_dup 1)))
14312   (clobber (reg:CC FLAGS_REG))]
14313   "TARGET_TBM"
14314   "blsfill\t{%1, %0|%0, %1}"
14315  [(set_attr "type" "bitmanip")
14316   (set_attr "mode" "<MODE>")])
14317
14318(define_insn "*tbm_blsic_<mode>"
14319  [(set (match_operand:SWI48 0 "register_operand" "=r")
14320        (ior:SWI48
14321          (plus:SWI48
14322            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14323            (const_int -1))
14324          (not:SWI48
14325            (match_dup 1))))
14326   (clobber (reg:CC FLAGS_REG))]
14327   "TARGET_TBM"
14328   "blsic\t{%1, %0|%0, %1}"
14329  [(set_attr "type" "bitmanip")
14330   (set_attr "mode" "<MODE>")])
14331
14332(define_insn "*tbm_t1mskc_<mode>"
14333  [(set (match_operand:SWI48 0 "register_operand" "=r")
14334        (ior:SWI48
14335          (plus:SWI48
14336            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14337            (const_int 1))
14338          (not:SWI48
14339            (match_dup 1))))
14340   (clobber (reg:CC FLAGS_REG))]
14341   "TARGET_TBM"
14342   "t1mskc\t{%1, %0|%0, %1}"
14343  [(set_attr "type" "bitmanip")
14344   (set_attr "mode" "<MODE>")])
14345
14346(define_insn "*tbm_tzmsk_<mode>"
14347  [(set (match_operand:SWI48 0 "register_operand" "=r")
14348        (and:SWI48
14349          (plus:SWI48
14350            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14351            (const_int -1))
14352          (not:SWI48
14353            (match_dup 1))))
14354   (clobber (reg:CC FLAGS_REG))]
14355   "TARGET_TBM"
14356   "tzmsk\t{%1, %0|%0, %1}"
14357  [(set_attr "type" "bitmanip")
14358   (set_attr "mode" "<MODE>")])
14359
14360(define_insn_and_split "popcount<mode>2"
14361  [(set (match_operand:SWI48 0 "register_operand" "=r")
14362	(popcount:SWI48
14363	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14364   (clobber (reg:CC FLAGS_REG))]
14365  "TARGET_POPCNT"
14366{
14367#if TARGET_MACHO
14368  return "popcnt\t{%1, %0|%0, %1}";
14369#else
14370  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14371#endif
14372}
14373  "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14374   && optimize_function_for_speed_p (cfun)
14375   && !reg_mentioned_p (operands[0], operands[1])"
14376  [(parallel
14377    [(set (match_dup 0)
14378	  (popcount:SWI48 (match_dup 1)))
14379     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14380     (clobber (reg:CC FLAGS_REG))])]
14381  "ix86_expand_clear (operands[0]);"
14382  [(set_attr "prefix_rep" "1")
14383   (set_attr "type" "bitmanip")
14384   (set_attr "mode" "<MODE>")])
14385
14386; False dependency happens when destination is only updated by tzcnt,
14387; lzcnt or popcnt.  There is no false dependency when destination is
14388; also used in source.
14389(define_insn "*popcount<mode>2_falsedep"
14390  [(set (match_operand:SWI48 0 "register_operand" "=r")
14391	(popcount:SWI48
14392	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14393   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14394	   UNSPEC_INSN_FALSE_DEP)
14395   (clobber (reg:CC FLAGS_REG))]
14396  "TARGET_POPCNT"
14397{
14398#if TARGET_MACHO
14399  return "popcnt\t{%1, %0|%0, %1}";
14400#else
14401  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14402#endif
14403}
14404  [(set_attr "prefix_rep" "1")
14405   (set_attr "type" "bitmanip")
14406   (set_attr "mode" "<MODE>")])
14407
14408(define_insn_and_split "*popcountsi2_zext"
14409  [(set (match_operand:DI 0 "register_operand" "=r")
14410	(and:DI
14411	  (subreg:DI
14412	    (popcount:SI
14413	      (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14414	  (const_int 63)))
14415   (clobber (reg:CC FLAGS_REG))]
14416  "TARGET_POPCNT && TARGET_64BIT"
14417{
14418#if TARGET_MACHO
14419  return "popcnt\t{%1, %k0|%k0, %1}";
14420#else
14421  return "popcnt{l}\t{%1, %k0|%k0, %1}";
14422#endif
14423}
14424  "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14425   && optimize_function_for_speed_p (cfun)
14426   && !reg_mentioned_p (operands[0], operands[1])"
14427  [(parallel
14428    [(set (match_dup 0)
14429	  (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
14430     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14431     (clobber (reg:CC FLAGS_REG))])]
14432  "ix86_expand_clear (operands[0]);"
14433  [(set_attr "prefix_rep" "1")
14434   (set_attr "type" "bitmanip")
14435   (set_attr "mode" "SI")])
14436
14437; False dependency happens when destination is only updated by tzcnt,
14438; lzcnt or popcnt.  There is no false dependency when destination is
14439; also used in source.
14440(define_insn "*popcountsi2_zext_falsedep"
14441  [(set (match_operand:DI 0 "register_operand" "=r")
14442	(and:DI
14443	  (subreg:DI
14444	    (popcount:SI
14445	      (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14446	  (const_int 63)))
14447   (unspec [(match_operand:DI 2 "register_operand" "0")]
14448	   UNSPEC_INSN_FALSE_DEP)
14449   (clobber (reg:CC FLAGS_REG))]
14450  "TARGET_POPCNT && TARGET_64BIT"
14451{
14452#if TARGET_MACHO
14453  return "popcnt\t{%1, %k0|%k0, %1}";
14454#else
14455  return "popcnt{l}\t{%1, %k0|%k0, %1}";
14456#endif
14457}
14458  [(set_attr "prefix_rep" "1")
14459   (set_attr "type" "bitmanip")
14460   (set_attr "mode" "SI")])
14461
14462(define_insn_and_split "*popcounthi2_1"
14463  [(set (match_operand:SI 0 "register_operand")
14464	(popcount:SI
14465	  (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14466   (clobber (reg:CC FLAGS_REG))]
14467  "TARGET_POPCNT
14468   && ix86_pre_reload_split ()"
14469  "#"
14470  "&& 1"
14471  [(const_int 0)]
14472{
14473  rtx tmp = gen_reg_rtx (HImode);
14474
14475  emit_insn (gen_popcounthi2 (tmp, operands[1]));
14476  emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14477  DONE;
14478})
14479
14480(define_insn "popcounthi2"
14481  [(set (match_operand:HI 0 "register_operand" "=r")
14482	(popcount:HI
14483	  (match_operand:HI 1 "nonimmediate_operand" "rm")))
14484   (clobber (reg:CC FLAGS_REG))]
14485  "TARGET_POPCNT"
14486{
14487#if TARGET_MACHO
14488  return "popcnt\t{%1, %0|%0, %1}";
14489#else
14490  return "popcnt{w}\t{%1, %0|%0, %1}";
14491#endif
14492}
14493  [(set_attr "prefix_rep" "1")
14494   (set_attr "type" "bitmanip")
14495   (set_attr "mode" "HI")])
14496
14497(define_expand "bswapdi2"
14498  [(set (match_operand:DI 0 "register_operand")
14499	(bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14500  "TARGET_64BIT"
14501{
14502  if (!TARGET_MOVBE)
14503    operands[1] = force_reg (DImode, operands[1]);
14504})
14505
14506(define_expand "bswapsi2"
14507  [(set (match_operand:SI 0 "register_operand")
14508	(bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14509  ""
14510{
14511  if (TARGET_MOVBE)
14512    ;
14513  else if (TARGET_BSWAP)
14514    operands[1] = force_reg (SImode, operands[1]);
14515  else
14516    {
14517      rtx x = operands[0];
14518
14519      emit_move_insn (x, operands[1]);
14520      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14521      emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14522      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14523      DONE;
14524    }
14525})
14526
14527(define_insn "*bswap<mode>2_movbe"
14528  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14529	(bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14530  "TARGET_MOVBE
14531   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14532  "@
14533    bswap\t%0
14534    movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14535    movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14536  [(set_attr "type" "bitmanip,imov,imov")
14537   (set_attr "modrm" "0,1,1")
14538   (set_attr "prefix_0f" "*,1,1")
14539   (set_attr "prefix_extra" "*,1,1")
14540   (set_attr "mode" "<MODE>")])
14541
14542(define_insn "*bswap<mode>2"
14543  [(set (match_operand:SWI48 0 "register_operand" "=r")
14544	(bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14545  "TARGET_BSWAP"
14546  "bswap\t%0"
14547  [(set_attr "type" "bitmanip")
14548   (set_attr "modrm" "0")
14549   (set_attr "mode" "<MODE>")])
14550
14551(define_expand "bswaphi2"
14552  [(set (match_operand:HI 0 "register_operand")
14553	(bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14554  "TARGET_MOVBE")
14555
14556(define_insn "*bswaphi2_movbe"
14557  [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14558	(bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14559  "TARGET_MOVBE
14560   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14561  "@
14562    xchg{b}\t{%h0, %b0|%b0, %h0}
14563    movbe{w}\t{%1, %0|%0, %1}
14564    movbe{w}\t{%1, %0|%0, %1}"
14565  [(set_attr "type" "imov")
14566   (set_attr "modrm" "*,1,1")
14567   (set_attr "prefix_0f" "*,1,1")
14568   (set_attr "prefix_extra" "*,1,1")
14569   (set_attr "pent_pair" "np,*,*")
14570   (set_attr "athlon_decode" "vector,*,*")
14571   (set_attr "amdfam10_decode" "double,*,*")
14572   (set_attr "bdver1_decode" "double,*,*")
14573   (set_attr "mode" "QI,HI,HI")])
14574
14575(define_peephole2
14576  [(set (match_operand:HI 0 "general_reg_operand")
14577	(bswap:HI (match_dup 0)))]
14578  "TARGET_MOVBE
14579   && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14580   && peep2_regno_dead_p (0, FLAGS_REG)"
14581  [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14582	      (clobber (reg:CC FLAGS_REG))])])
14583
14584(define_insn "bswaphi_lowpart"
14585  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14586	(bswap:HI (match_dup 0)))
14587   (clobber (reg:CC FLAGS_REG))]
14588  ""
14589  "@
14590    xchg{b}\t{%h0, %b0|%b0, %h0}
14591    rol{w}\t{$8, %0|%0, 8}"
14592  [(set (attr "preferred_for_size")
14593     (cond [(eq_attr "alternative" "0")
14594	      (symbol_ref "true")]
14595	   (symbol_ref "false")))
14596   (set (attr "preferred_for_speed")
14597     (cond [(eq_attr "alternative" "0")
14598	      (symbol_ref "TARGET_USE_XCHGB")]
14599	   (symbol_ref "!TARGET_USE_XCHGB")))
14600   (set_attr "length" "2,4")
14601   (set_attr "mode" "QI,HI")])
14602
14603(define_expand "paritydi2"
14604  [(set (match_operand:DI 0 "register_operand")
14605	(parity:DI (match_operand:DI 1 "register_operand")))]
14606  "! TARGET_POPCNT"
14607{
14608  rtx scratch = gen_reg_rtx (QImode);
14609
14610  emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14611				NULL_RTX, operands[1]));
14612
14613  ix86_expand_setcc (scratch, ORDERED,
14614		     gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14615
14616  if (TARGET_64BIT)
14617    emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14618  else
14619    {
14620      rtx tmp = gen_reg_rtx (SImode);
14621
14622      emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14623      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14624    }
14625  DONE;
14626})
14627
14628(define_expand "paritysi2"
14629  [(set (match_operand:SI 0 "register_operand")
14630	(parity:SI (match_operand:SI 1 "register_operand")))]
14631  "! TARGET_POPCNT"
14632{
14633  rtx scratch = gen_reg_rtx (QImode);
14634
14635  emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14636
14637  ix86_expand_setcc (scratch, ORDERED,
14638		     gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14639
14640  emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14641  DONE;
14642})
14643
14644(define_insn_and_split "paritydi2_cmp"
14645  [(set (reg:CC FLAGS_REG)
14646	(unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14647		   UNSPEC_PARITY))
14648   (clobber (match_scratch:DI 0 "=r"))
14649   (clobber (match_scratch:SI 1 "=&r"))
14650   (clobber (match_scratch:HI 2 "=Q"))]
14651  "! TARGET_POPCNT"
14652  "#"
14653  "&& reload_completed"
14654  [(parallel
14655     [(set (match_dup 1)
14656	   (xor:SI (match_dup 1) (match_dup 4)))
14657      (clobber (reg:CC FLAGS_REG))])
14658   (parallel
14659     [(set (reg:CC FLAGS_REG)
14660	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14661      (clobber (match_dup 1))
14662      (clobber (match_dup 2))])]
14663{
14664  operands[4] = gen_lowpart (SImode, operands[3]);
14665
14666  if (TARGET_64BIT)
14667    {
14668      emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14669      emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14670    }
14671  else
14672    operands[1] = gen_highpart (SImode, operands[3]);
14673})
14674
14675(define_insn_and_split "paritysi2_cmp"
14676  [(set (reg:CC FLAGS_REG)
14677	(unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14678		   UNSPEC_PARITY))
14679   (clobber (match_scratch:SI 0 "=r"))
14680   (clobber (match_scratch:HI 1 "=&Q"))]
14681  "! TARGET_POPCNT"
14682  "#"
14683  "&& reload_completed"
14684  [(parallel
14685     [(set (match_dup 1)
14686	   (xor:HI (match_dup 1) (match_dup 3)))
14687      (clobber (reg:CC FLAGS_REG))])
14688   (parallel
14689     [(set (reg:CC FLAGS_REG)
14690	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14691      (clobber (match_dup 1))])]
14692{
14693  operands[3] = gen_lowpart (HImode, operands[2]);
14694
14695  emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14696  emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14697})
14698
14699(define_insn "*parityhi2_cmp"
14700  [(set (reg:CC FLAGS_REG)
14701	(unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14702		   UNSPEC_PARITY))
14703   (clobber (match_scratch:HI 0 "=Q"))]
14704  "! TARGET_POPCNT"
14705  "xor{b}\t{%h0, %b0|%b0, %h0}"
14706  [(set_attr "length" "2")
14707   (set_attr "mode" "HI")])
14708
14709
14710;; Thread-local storage patterns for ELF.
14711;;
14712;; Note that these code sequences must appear exactly as shown
14713;; in order to allow linker relaxation.
14714
14715(define_insn "*tls_global_dynamic_32_gnu"
14716  [(set (match_operand:SI 0 "register_operand" "=a")
14717	(unspec:SI
14718	 [(match_operand:SI 1 "register_operand" "Yb")
14719	  (match_operand 2 "tls_symbolic_operand")
14720	  (match_operand 3 "constant_call_address_operand" "Bz")
14721	  (reg:SI SP_REG)]
14722	 UNSPEC_TLS_GD))
14723   (clobber (match_scratch:SI 4 "=d"))
14724   (clobber (match_scratch:SI 5 "=c"))
14725   (clobber (reg:CC FLAGS_REG))]
14726  "!TARGET_64BIT && TARGET_GNU_TLS"
14727{
14728  if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14729    output_asm_insn
14730      ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14731  else
14732    output_asm_insn
14733      ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14734  if (TARGET_SUN_TLS)
14735#ifdef HAVE_AS_IX86_TLSGDPLT
14736    return "call\t%a2@tlsgdplt";
14737#else
14738    return "call\t%p3@plt";
14739#endif
14740  if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14741    return "call\t%P3";
14742  return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14743}
14744  [(set_attr "type" "multi")
14745   (set_attr "length" "12")])
14746
14747(define_expand "tls_global_dynamic_32"
14748  [(parallel
14749    [(set (match_operand:SI 0 "register_operand")
14750	  (unspec:SI [(match_operand:SI 2 "register_operand")
14751		      (match_operand 1 "tls_symbolic_operand")
14752		      (match_operand 3 "constant_call_address_operand")
14753		      (reg:SI SP_REG)]
14754		     UNSPEC_TLS_GD))
14755     (clobber (match_scratch:SI 4))
14756     (clobber (match_scratch:SI 5))
14757     (clobber (reg:CC FLAGS_REG))])]
14758  ""
14759  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14760
14761(define_insn "*tls_global_dynamic_64_<mode>"
14762  [(set (match_operand:P 0 "register_operand" "=a")
14763	(call:P
14764	 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14765	 (match_operand 3)))
14766   (unspec:P [(match_operand 1 "tls_symbolic_operand")
14767	      (reg:P SP_REG)]
14768	     UNSPEC_TLS_GD)]
14769  "TARGET_64BIT"
14770{
14771  if (!TARGET_X32)
14772    /* The .loc directive has effect for 'the immediately following assembly
14773       instruction'.  So for a sequence:
14774         .loc f l
14775         .byte x
14776         insn1
14777       the 'immediately following assembly instruction' is insn1.
14778       We want to emit an insn prefix here, but if we use .byte (as shown in
14779       'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14780       inside the insn sequence, rather than to the start.  After relaxation
14781       of the sequence by the linker, the .loc might point inside an insn.
14782       Use data16 prefix instead, which doesn't have this problem.  */
14783    fputs ("\tdata16", asm_out_file);
14784  output_asm_insn
14785    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14786  if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14787    fputs (ASM_SHORT "0x6666\n", asm_out_file);
14788  else
14789    fputs (ASM_BYTE "0x66\n", asm_out_file);
14790  fputs ("\trex64\n", asm_out_file);
14791  if (TARGET_SUN_TLS)
14792    return "call\t%p2@plt";
14793  if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14794    return "call\t%P2";
14795  return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14796}
14797  [(set_attr "type" "multi")
14798   (set (attr "length")
14799	(symbol_ref "TARGET_X32 ? 15 : 16"))])
14800
14801(define_insn "*tls_global_dynamic_64_largepic"
14802  [(set (match_operand:DI 0 "register_operand" "=a")
14803	(call:DI
14804	 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14805			  (match_operand:DI 3 "immediate_operand" "i")))
14806	 (match_operand 4)))
14807   (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14808	       (reg:DI SP_REG)]
14809	      UNSPEC_TLS_GD)]
14810  "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14811   && GET_CODE (operands[3]) == CONST
14812   && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14813   && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14814{
14815  output_asm_insn
14816    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14817  output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14818  output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14819  return "call\t{*%%rax|rax}";
14820}
14821  [(set_attr "type" "multi")
14822   (set_attr "length" "22")])
14823
14824(define_expand "@tls_global_dynamic_64_<mode>"
14825  [(parallel
14826    [(set (match_operand:P 0 "register_operand")
14827	  (call:P
14828	   (mem:QI (match_operand 2))
14829	   (const_int 0)))
14830     (unspec:P [(match_operand 1 "tls_symbolic_operand")
14831		(reg:P SP_REG)]
14832	       UNSPEC_TLS_GD)])]
14833  "TARGET_64BIT"
14834  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14835
14836(define_insn "*tls_local_dynamic_base_32_gnu"
14837  [(set (match_operand:SI 0 "register_operand" "=a")
14838	(unspec:SI
14839	 [(match_operand:SI 1 "register_operand" "Yb")
14840	  (match_operand 2 "constant_call_address_operand" "Bz")
14841	  (reg:SI SP_REG)]
14842	 UNSPEC_TLS_LD_BASE))
14843   (clobber (match_scratch:SI 3 "=d"))
14844   (clobber (match_scratch:SI 4 "=c"))
14845   (clobber (reg:CC FLAGS_REG))]
14846  "!TARGET_64BIT && TARGET_GNU_TLS"
14847{
14848  output_asm_insn
14849    ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14850  if (TARGET_SUN_TLS)
14851    {
14852      if (HAVE_AS_IX86_TLSLDMPLT)
14853	return "call\t%&@tlsldmplt";
14854      else
14855	return "call\t%p2@plt";
14856    }
14857  if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14858    return "call\t%P2";
14859  return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14860}
14861  [(set_attr "type" "multi")
14862   (set_attr "length" "11")])
14863
14864(define_expand "tls_local_dynamic_base_32"
14865  [(parallel
14866     [(set (match_operand:SI 0 "register_operand")
14867	   (unspec:SI
14868	    [(match_operand:SI 1 "register_operand")
14869	     (match_operand 2 "constant_call_address_operand")
14870	     (reg:SI SP_REG)]
14871	    UNSPEC_TLS_LD_BASE))
14872      (clobber (match_scratch:SI 3))
14873      (clobber (match_scratch:SI 4))
14874      (clobber (reg:CC FLAGS_REG))])]
14875  ""
14876  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14877
14878(define_insn "*tls_local_dynamic_base_64_<mode>"
14879  [(set (match_operand:P 0 "register_operand" "=a")
14880	(call:P
14881	 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14882	 (match_operand 2)))
14883   (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14884  "TARGET_64BIT"
14885{
14886  output_asm_insn
14887    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14888  if (TARGET_SUN_TLS)
14889    return "call\t%p1@plt";
14890  if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14891    return "call\t%P1";
14892  return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14893}
14894  [(set_attr "type" "multi")
14895   (set_attr "length" "12")])
14896
14897(define_insn "*tls_local_dynamic_base_64_largepic"
14898  [(set (match_operand:DI 0 "register_operand" "=a")
14899	(call:DI
14900	 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14901			  (match_operand:DI 2 "immediate_operand" "i")))
14902	 (match_operand 3)))
14903   (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14904  "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14905   && GET_CODE (operands[2]) == CONST
14906   && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14907   && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14908{
14909  output_asm_insn
14910    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14911  output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14912  output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14913  return "call\t{*%%rax|rax}";
14914}
14915  [(set_attr "type" "multi")
14916   (set_attr "length" "22")])
14917
14918(define_expand "@tls_local_dynamic_base_64_<mode>"
14919  [(parallel
14920     [(set (match_operand:P 0 "register_operand")
14921	   (call:P
14922	    (mem:QI (match_operand 1))
14923	    (const_int 0)))
14924      (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14925  "TARGET_64BIT"
14926  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14927
14928;; Local dynamic of a single variable is a lose.  Show combine how
14929;; to convert that back to global dynamic.
14930
14931(define_insn_and_split "*tls_local_dynamic_32_once"
14932  [(set (match_operand:SI 0 "register_operand" "=a")
14933	(plus:SI
14934	 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14935		     (match_operand 2 "constant_call_address_operand" "Bz")
14936		     (reg:SI SP_REG)]
14937		    UNSPEC_TLS_LD_BASE)
14938	 (const:SI (unspec:SI
14939		    [(match_operand 3 "tls_symbolic_operand")]
14940		    UNSPEC_DTPOFF))))
14941   (clobber (match_scratch:SI 4 "=d"))
14942   (clobber (match_scratch:SI 5 "=c"))
14943   (clobber (reg:CC FLAGS_REG))]
14944  ""
14945  "#"
14946  ""
14947  [(parallel
14948     [(set (match_dup 0)
14949	   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14950		       (reg:SI SP_REG)]
14951		      UNSPEC_TLS_GD))
14952      (clobber (match_dup 4))
14953      (clobber (match_dup 5))
14954      (clobber (reg:CC FLAGS_REG))])])
14955
14956;; Load and add the thread base pointer from %<tp_seg>:0.
14957(define_insn_and_split "*load_tp_<mode>"
14958  [(set (match_operand:PTR 0 "register_operand" "=r")
14959	(unspec:PTR [(const_int 0)] UNSPEC_TP))]
14960  ""
14961  "#"
14962  ""
14963  [(set (match_dup 0)
14964	(match_dup 1))]
14965{
14966  addr_space_t as = DEFAULT_TLS_SEG_REG;
14967
14968  operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14969  set_mem_addr_space (operands[1], as);
14970})
14971
14972(define_insn_and_split "*load_tp_x32_zext"
14973  [(set (match_operand:DI 0 "register_operand" "=r")
14974	(zero_extend:DI
14975	  (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14976  "TARGET_X32"
14977  "#"
14978  ""
14979  [(set (match_dup 0)
14980	(zero_extend:DI (match_dup 1)))]
14981{
14982  addr_space_t as = DEFAULT_TLS_SEG_REG;
14983
14984  operands[1] = gen_const_mem (SImode, const0_rtx);
14985  set_mem_addr_space (operands[1], as);
14986})
14987
14988(define_insn_and_split "*add_tp_<mode>"
14989  [(set (match_operand:PTR 0 "register_operand" "=r")
14990	(plus:PTR
14991	  (unspec:PTR [(const_int 0)] UNSPEC_TP)
14992	  (match_operand:PTR 1 "register_operand" "0")))
14993   (clobber (reg:CC FLAGS_REG))]
14994  ""
14995  "#"
14996  ""
14997  [(parallel
14998     [(set (match_dup 0)
14999	   (plus:PTR (match_dup 1) (match_dup 2)))
15000      (clobber (reg:CC FLAGS_REG))])]
15001{
15002  addr_space_t as = DEFAULT_TLS_SEG_REG;
15003
15004  operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
15005  set_mem_addr_space (operands[2], as);
15006})
15007
15008(define_insn_and_split "*add_tp_x32_zext"
15009  [(set (match_operand:DI 0 "register_operand" "=r")
15010	(zero_extend:DI
15011	  (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15012		   (match_operand:SI 1 "register_operand" "0"))))
15013   (clobber (reg:CC FLAGS_REG))]
15014  "TARGET_X32"
15015  "#"
15016  ""
15017  [(parallel
15018     [(set (match_dup 0)
15019     	   (zero_extend:DI
15020	     (plus:SI (match_dup 1) (match_dup 2))))
15021      (clobber (reg:CC FLAGS_REG))])]
15022{
15023  addr_space_t as = DEFAULT_TLS_SEG_REG;
15024
15025  operands[2] = gen_const_mem (SImode, const0_rtx);
15026  set_mem_addr_space (operands[2], as);
15027})
15028
15029;; The Sun linker took the AMD64 TLS spec literally and can only handle
15030;; %rax as destination of the initial executable code sequence.
15031(define_insn "tls_initial_exec_64_sun"
15032  [(set (match_operand:DI 0 "register_operand" "=a")
15033	(unspec:DI
15034	 [(match_operand 1 "tls_symbolic_operand")]
15035	 UNSPEC_TLS_IE_SUN))
15036   (clobber (reg:CC FLAGS_REG))]
15037  "TARGET_64BIT && TARGET_SUN_TLS"
15038{
15039  output_asm_insn
15040    ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
15041  return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
15042}
15043  [(set_attr "type" "multi")])
15044
15045;; GNU2 TLS patterns can be split.
15046
15047(define_expand "tls_dynamic_gnu2_32"
15048  [(set (match_dup 3)
15049	(plus:SI (match_operand:SI 2 "register_operand")
15050		 (const:SI
15051		  (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
15052			     UNSPEC_TLSDESC))))
15053   (parallel
15054    [(set (match_operand:SI 0 "register_operand")
15055	  (unspec:SI [(match_dup 1) (match_dup 3)
15056		      (match_dup 2) (reg:SI SP_REG)]
15057		      UNSPEC_TLSDESC))
15058     (clobber (reg:CC FLAGS_REG))])]
15059  "!TARGET_64BIT && TARGET_GNU2_TLS"
15060{
15061  operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15062  ix86_tls_descriptor_calls_expanded_in_cfun = true;
15063})
15064
15065(define_insn "*tls_dynamic_gnu2_lea_32"
15066  [(set (match_operand:SI 0 "register_operand" "=r")
15067	(plus:SI (match_operand:SI 1 "register_operand" "b")
15068		 (const:SI
15069		  (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
15070			      UNSPEC_TLSDESC))))]
15071  "!TARGET_64BIT && TARGET_GNU2_TLS"
15072  "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
15073  [(set_attr "type" "lea")
15074   (set_attr "mode" "SI")
15075   (set_attr "length" "6")
15076   (set_attr "length_address" "4")])
15077
15078(define_insn "*tls_dynamic_gnu2_call_32"
15079  [(set (match_operand:SI 0 "register_operand" "=a")
15080	(unspec:SI [(match_operand 1 "tls_symbolic_operand")
15081		    (match_operand:SI 2 "register_operand" "0")
15082		    ;; we have to make sure %ebx still points to the GOT
15083		    (match_operand:SI 3 "register_operand" "b")
15084		    (reg:SI SP_REG)]
15085		   UNSPEC_TLSDESC))
15086   (clobber (reg:CC FLAGS_REG))]
15087  "!TARGET_64BIT && TARGET_GNU2_TLS"
15088  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15089  [(set_attr "type" "call")
15090   (set_attr "length" "2")
15091   (set_attr "length_address" "0")])
15092
15093(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15094  [(set (match_operand:SI 0 "register_operand" "=&a")
15095	(plus:SI
15096	 (unspec:SI [(match_operand 3 "tls_modbase_operand")
15097		     (match_operand:SI 4)
15098		     (match_operand:SI 2 "register_operand" "b")
15099		     (reg:SI SP_REG)]
15100		    UNSPEC_TLSDESC)
15101	 (const:SI (unspec:SI
15102		    [(match_operand 1 "tls_symbolic_operand")]
15103		    UNSPEC_DTPOFF))))
15104   (clobber (reg:CC FLAGS_REG))]
15105  "!TARGET_64BIT && TARGET_GNU2_TLS"
15106  "#"
15107  ""
15108  [(set (match_dup 0) (match_dup 5))]
15109{
15110  operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15111  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15112})
15113
15114(define_expand "@tls_dynamic_gnu2_64_<mode>"
15115  [(set (match_dup 2)
15116	(unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
15117		    UNSPEC_TLSDESC))
15118   (parallel
15119    [(set (match_operand:PTR 0 "register_operand")
15120	  (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
15121		      UNSPEC_TLSDESC))
15122     (clobber (reg:CC FLAGS_REG))])]
15123  "TARGET_64BIT && TARGET_GNU2_TLS"
15124{
15125  operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
15126  ix86_tls_descriptor_calls_expanded_in_cfun = true;
15127})
15128
15129(define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
15130  [(set (match_operand:PTR 0 "register_operand" "=r")
15131	(unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
15132		    UNSPEC_TLSDESC))]
15133  "TARGET_64BIT && TARGET_GNU2_TLS"
15134  "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15135  [(set_attr "type" "lea")
15136   (set_attr "mode" "<MODE>")
15137   (set_attr "length" "7")
15138   (set_attr "length_address" "4")])
15139
15140(define_insn "*tls_dynamic_gnu2_call_64_<mode>"
15141  [(set (match_operand:PTR 0 "register_operand" "=a")
15142	(unspec:PTR [(match_operand 1 "tls_symbolic_operand")
15143		   (match_operand:PTR 2 "register_operand" "0")
15144		   (reg:PTR SP_REG)]
15145		  UNSPEC_TLSDESC))
15146   (clobber (reg:CC FLAGS_REG))]
15147  "TARGET_64BIT && TARGET_GNU2_TLS"
15148  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15149  [(set_attr "type" "call")
15150   (set_attr "length" "2")
15151   (set_attr "length_address" "0")])
15152
15153(define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
15154  [(set (match_operand:PTR 0 "register_operand" "=&a")
15155	(plus:PTR
15156	 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
15157		      (match_operand:PTR 3)
15158		      (reg:PTR SP_REG)]
15159		     UNSPEC_TLSDESC)
15160	 (const:PTR (unspec:PTR
15161		     [(match_operand 1 "tls_symbolic_operand")]
15162		     UNSPEC_DTPOFF))))
15163   (clobber (reg:CC FLAGS_REG))]
15164  "TARGET_64BIT && TARGET_GNU2_TLS"
15165  "#"
15166  ""
15167  [(set (match_dup 0) (match_dup 4))]
15168{
15169  operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
15170  emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
15171})
15172
15173(define_split
15174  [(match_operand 0 "tls_address_pattern")]
15175  "TARGET_TLS_DIRECT_SEG_REFS"
15176  [(match_dup 0)]
15177  "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15178
15179
15180;; These patterns match the binary 387 instructions for addM3, subM3,
15181;; mulM3 and divM3.  There are three patterns for each of DFmode and
15182;; SFmode.  The first is the normal insn, the second the same insn but
15183;; with one operand a conversion, and the third the same insn but with
15184;; the other operand a conversion.  The conversion may be SFmode or
15185;; SImode if the target mode DFmode, but only SImode if the target mode
15186;; is SFmode.
15187
15188;; Gcc is slightly more smart about handling normal two address instructions
15189;; so use special patterns for add and mull.
15190
15191(define_insn "*fop_xf_comm_i387"
15192  [(set (match_operand:XF 0 "register_operand" "=f")
15193	(match_operator:XF 3 "binary_fp_operator"
15194			[(match_operand:XF 1 "register_operand" "%0")
15195			 (match_operand:XF 2 "register_operand" "f")]))]
15196  "TARGET_80387
15197   && COMMUTATIVE_ARITH_P (operands[3])"
15198  "* return output_387_binary_op (insn, operands);"
15199  [(set (attr "type")
15200	(if_then_else (match_operand:XF 3 "mult_operator")
15201	   (const_string "fmul")
15202	   (const_string "fop")))
15203   (set_attr "mode" "XF")])
15204
15205(define_insn "*fop_<mode>_comm"
15206  [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15207	(match_operator:MODEF 3 "binary_fp_operator"
15208	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15209	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15210  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15211    || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15212   && COMMUTATIVE_ARITH_P (operands[3])
15213   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15214  "* return output_387_binary_op (insn, operands);"
15215  [(set (attr "type")
15216	(if_then_else (eq_attr "alternative" "1,2")
15217	   (if_then_else (match_operand:MODEF 3 "mult_operator")
15218	      (const_string "ssemul")
15219	      (const_string "sseadd"))
15220	   (if_then_else (match_operand:MODEF 3 "mult_operator")
15221	      (const_string "fmul")
15222	      (const_string "fop"))))
15223   (set_attr "isa" "*,noavx,avx")
15224   (set_attr "prefix" "orig,orig,vex")
15225   (set_attr "mode" "<MODE>")
15226   (set (attr "enabled")
15227     (if_then_else
15228       (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15229       (if_then_else
15230	 (eq_attr "alternative" "0")
15231	 (symbol_ref "TARGET_MIX_SSE_I387
15232		      && X87_ENABLE_ARITH (<MODE>mode)")
15233	 (const_string "*"))
15234       (if_then_else
15235	 (eq_attr "alternative" "0")
15236	 (symbol_ref "true")
15237	 (symbol_ref "false"))))])
15238
15239(define_insn "*rcpsf2_sse"
15240  [(set (match_operand:SF 0 "register_operand" "=x,x,x")
15241	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
15242		   UNSPEC_RCP))]
15243  "TARGET_SSE && TARGET_SSE_MATH"
15244  "@
15245   %vrcpss\t{%d1, %0|%0, %d1}
15246   %vrcpss\t{%d1, %0|%0, %d1}
15247   %vrcpss\t{%1, %d0|%d0, %1}"
15248  [(set_attr "type" "sse")
15249   (set_attr "atom_sse_attr" "rcp")
15250   (set_attr "btver2_sse_attr" "rcp")
15251   (set_attr "prefix" "maybe_vex")
15252   (set_attr "mode" "SF")
15253   (set_attr "avx_partial_xmm_update" "false,false,true")
15254   (set (attr "preferred_for_speed")
15255      (cond [(match_test "TARGET_AVX")
15256	       (symbol_ref "true")
15257	     (eq_attr "alternative" "1,2")
15258	       (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15259	    ]
15260	    (symbol_ref "true")))])
15261
15262(define_insn "*fop_xf_1_i387"
15263  [(set (match_operand:XF 0 "register_operand" "=f,f")
15264	(match_operator:XF 3 "binary_fp_operator"
15265			[(match_operand:XF 1 "register_operand" "0,f")
15266			 (match_operand:XF 2 "register_operand" "f,0")]))]
15267  "TARGET_80387
15268   && !COMMUTATIVE_ARITH_P (operands[3])"
15269  "* return output_387_binary_op (insn, operands);"
15270  [(set (attr "type")
15271	(if_then_else (match_operand:XF 3 "div_operator")
15272	   (const_string "fdiv")
15273	   (const_string "fop")))
15274   (set_attr "mode" "XF")])
15275
15276(define_insn "*fop_<mode>_1"
15277  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
15278	(match_operator:MODEF 3 "binary_fp_operator"
15279	  [(match_operand:MODEF 1
15280	     "x87nonimm_ssenomem_operand" "0,fm,0,v")
15281	   (match_operand:MODEF 2
15282	     "nonimmediate_operand"	  "fm,0,xm,vm")]))]
15283  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15284    || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15285   && !COMMUTATIVE_ARITH_P (operands[3])
15286   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15287  "* return output_387_binary_op (insn, operands);"
15288  [(set (attr "type")
15289	(if_then_else (eq_attr "alternative" "2,3")
15290	   (if_then_else (match_operand:MODEF 3 "div_operator")
15291	      (const_string "ssediv")
15292	      (const_string "sseadd"))
15293	   (if_then_else (match_operand:MODEF 3 "div_operator")
15294	      (const_string "fdiv")
15295	      (const_string "fop"))))
15296   (set_attr "isa" "*,*,noavx,avx")
15297   (set_attr "prefix" "orig,orig,orig,vex")
15298   (set_attr "mode" "<MODE>")
15299   (set (attr "enabled")
15300     (if_then_else
15301       (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15302       (if_then_else
15303	 (eq_attr "alternative" "0,1")
15304	 (symbol_ref "TARGET_MIX_SSE_I387
15305		      && X87_ENABLE_ARITH (<MODE>mode)")
15306	 (const_string "*"))
15307       (if_then_else
15308	 (eq_attr "alternative" "0,1")
15309	 (symbol_ref "true")
15310	 (symbol_ref "false"))))])
15311
15312(define_insn "*fop_<X87MODEF:mode>_2_i387"
15313  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15314	(match_operator:X87MODEF 3 "binary_fp_operator"
15315	  [(float:X87MODEF
15316	     (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15317	   (match_operand:X87MODEF 2 "register_operand" "0")]))]
15318  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
15319   && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15320   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15321       || optimize_function_for_size_p (cfun))"
15322  "* return output_387_binary_op (insn, operands);"
15323  [(set (attr "type")
15324	(cond [(match_operand:X87MODEF 3 "mult_operator")
15325		 (const_string "fmul")
15326	       (match_operand:X87MODEF 3 "div_operator")
15327		 (const_string "fdiv")
15328	      ]
15329	      (const_string "fop")))
15330   (set_attr "fp_int_src" "true")
15331   (set_attr "mode" "<SWI24:MODE>")])
15332
15333(define_insn "*fop_<X87MODEF:mode>_3_i387"
15334  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15335	(match_operator:X87MODEF 3 "binary_fp_operator"
15336	  [(match_operand:X87MODEF 1 "register_operand" "0")
15337	   (float:X87MODEF
15338	     (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15339  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
15340   && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15341   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15342       || optimize_function_for_size_p (cfun))"
15343  "* return output_387_binary_op (insn, operands);"
15344  [(set (attr "type")
15345	(cond [(match_operand:X87MODEF 3 "mult_operator")
15346		 (const_string "fmul")
15347	       (match_operand:X87MODEF 3 "div_operator")
15348		 (const_string "fdiv")
15349	      ]
15350	      (const_string "fop")))
15351   (set_attr "fp_int_src" "true")
15352   (set_attr "mode" "<SWI24:MODE>")])
15353
15354(define_insn "*fop_xf_4_i387"
15355  [(set (match_operand:XF 0 "register_operand" "=f,f")
15356	(match_operator:XF 3 "binary_fp_operator"
15357	   [(float_extend:XF
15358	      (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15359	    (match_operand:XF 2 "register_operand" "0,f")]))]
15360  "TARGET_80387"
15361  "* return output_387_binary_op (insn, operands);"
15362  [(set (attr "type")
15363	(cond [(match_operand:XF 3 "mult_operator")
15364		 (const_string "fmul")
15365	       (match_operand:XF 3 "div_operator")
15366		 (const_string "fdiv")
15367	      ]
15368	      (const_string "fop")))
15369   (set_attr "mode" "<MODE>")])
15370
15371(define_insn "*fop_df_4_i387"
15372  [(set (match_operand:DF 0 "register_operand" "=f,f")
15373	(match_operator:DF 3 "binary_fp_operator"
15374	   [(float_extend:DF
15375	     (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15376	    (match_operand:DF 2 "register_operand" "0,f")]))]
15377  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15378   && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15379  "* return output_387_binary_op (insn, operands);"
15380  [(set (attr "type")
15381	(cond [(match_operand:DF 3 "mult_operator")
15382		 (const_string "fmul")
15383	       (match_operand:DF 3 "div_operator")
15384		 (const_string "fdiv")
15385	      ]
15386	      (const_string "fop")))
15387   (set_attr "mode" "SF")])
15388
15389(define_insn "*fop_xf_5_i387"
15390  [(set (match_operand:XF 0 "register_operand" "=f,f")
15391	(match_operator:XF 3 "binary_fp_operator"
15392	  [(match_operand:XF 1 "register_operand" "0,f")
15393	   (float_extend:XF
15394	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15395  "TARGET_80387"
15396  "* return output_387_binary_op (insn, operands);"
15397  [(set (attr "type")
15398	(cond [(match_operand:XF 3 "mult_operator")
15399		 (const_string "fmul")
15400	       (match_operand:XF 3 "div_operator")
15401		 (const_string "fdiv")
15402	      ]
15403	      (const_string "fop")))
15404   (set_attr "mode" "<MODE>")])
15405
15406(define_insn "*fop_df_5_i387"
15407  [(set (match_operand:DF 0 "register_operand" "=f,f")
15408	(match_operator:DF 3 "binary_fp_operator"
15409	  [(match_operand:DF 1 "register_operand" "0,f")
15410	   (float_extend:DF
15411	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15412  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15413   && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15414  "* return output_387_binary_op (insn, operands);"
15415  [(set (attr "type")
15416	(cond [(match_operand:DF 3 "mult_operator")
15417		 (const_string "fmul")
15418	       (match_operand:DF 3 "div_operator")
15419		 (const_string "fdiv")
15420	      ]
15421	      (const_string "fop")))
15422   (set_attr "mode" "SF")])
15423
15424(define_insn "*fop_xf_6_i387"
15425  [(set (match_operand:XF 0 "register_operand" "=f,f")
15426	(match_operator:XF 3 "binary_fp_operator"
15427	  [(float_extend:XF
15428	     (match_operand:MODEF 1 "register_operand" "0,f"))
15429	   (float_extend:XF
15430	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15431  "TARGET_80387"
15432  "* return output_387_binary_op (insn, operands);"
15433  [(set (attr "type")
15434	(cond [(match_operand:XF 3 "mult_operator")
15435		 (const_string "fmul")
15436	       (match_operand:XF 3 "div_operator")
15437		 (const_string "fdiv")
15438	      ]
15439	      (const_string "fop")))
15440   (set_attr "mode" "<MODE>")])
15441
15442(define_insn "*fop_df_6_i387"
15443  [(set (match_operand:DF 0 "register_operand" "=f,f")
15444	(match_operator:DF 3 "binary_fp_operator"
15445	  [(float_extend:DF
15446	    (match_operand:SF 1 "register_operand" "0,f"))
15447	   (float_extend:DF
15448	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15449  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15450   && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15451  "* return output_387_binary_op (insn, operands);"
15452  [(set (attr "type")
15453	(cond [(match_operand:DF 3 "mult_operator")
15454		 (const_string "fmul")
15455	       (match_operand:DF 3 "div_operator")
15456		 (const_string "fdiv")
15457	      ]
15458	      (const_string "fop")))
15459   (set_attr "mode" "SF")])
15460
15461;; FPU special functions.
15462
15463;; This pattern implements a no-op XFmode truncation for
15464;; all fancy i386 XFmode math functions.
15465
15466(define_insn "truncxf<mode>2_i387_noop_unspec"
15467  [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
15468	(unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15469	UNSPEC_TRUNC_NOOP))]
15470  "TARGET_USE_FANCY_MATH_387"
15471  "* return output_387_reg_move (insn, operands);"
15472  [(set_attr "type" "fmov")
15473   (set_attr "mode" "<MODE>")])
15474
15475(define_insn "sqrtxf2"
15476  [(set (match_operand:XF 0 "register_operand" "=f")
15477	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15478  "TARGET_USE_FANCY_MATH_387"
15479  "fsqrt"
15480  [(set_attr "type" "fpspc")
15481   (set_attr "mode" "XF")
15482   (set_attr "athlon_decode" "direct")
15483   (set_attr "amdfam10_decode" "direct")
15484   (set_attr "bdver1_decode" "direct")])
15485
15486(define_insn "*rsqrtsf2_sse"
15487  [(set (match_operand:SF 0 "register_operand" "=x,x,x")
15488	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
15489		   UNSPEC_RSQRT))]
15490  "TARGET_SSE && TARGET_SSE_MATH"
15491  "@
15492   %vrsqrtss\t{%d1, %0|%0, %d1}
15493   %vrsqrtss\t{%d1, %0|%0, %d1}
15494   %vrsqrtss\t{%1, %d0|%d0, %1}"
15495  [(set_attr "type" "sse")
15496   (set_attr "atom_sse_attr" "rcp")
15497   (set_attr "btver2_sse_attr" "rcp")
15498   (set_attr "prefix" "maybe_vex")
15499   (set_attr "mode" "SF")
15500   (set_attr "avx_partial_xmm_update" "false,false,true")
15501   (set (attr "preferred_for_speed")
15502      (cond [(match_test "TARGET_AVX")
15503	       (symbol_ref "true")
15504	     (eq_attr "alternative" "1,2")
15505	       (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15506	    ]
15507	    (symbol_ref "true")))])
15508
15509(define_expand "rsqrtsf2"
15510  [(set (match_operand:SF 0 "register_operand")
15511	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15512		   UNSPEC_RSQRT))]
15513  "TARGET_SSE && TARGET_SSE_MATH"
15514{
15515  ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15516  DONE;
15517})
15518
15519(define_insn "*sqrt<mode>2_sse"
15520  [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
15521	(sqrt:MODEF
15522	  (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
15523  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15524  "@
15525   %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15526   %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15527   %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15528  [(set_attr "type" "sse")
15529   (set_attr "atom_sse_attr" "sqrt")
15530   (set_attr "btver2_sse_attr" "sqrt")
15531   (set_attr "prefix" "maybe_vex")
15532   (set_attr "avx_partial_xmm_update" "false,false,true")
15533   (set_attr "mode" "<MODE>")
15534   (set (attr "preferred_for_speed")
15535      (cond [(match_test "TARGET_AVX")
15536	       (symbol_ref "true")
15537	     (eq_attr "alternative" "1,2")
15538	       (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15539	    ]
15540	    (symbol_ref "true")))])
15541
15542(define_expand "sqrt<mode>2"
15543  [(set (match_operand:MODEF 0 "register_operand")
15544	(sqrt:MODEF
15545	  (match_operand:MODEF 1 "nonimmediate_operand")))]
15546  "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15547   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15548{
15549  if (<MODE>mode == SFmode
15550      && TARGET_SSE && TARGET_SSE_MATH
15551      && TARGET_RECIP_SQRT
15552      && !optimize_function_for_size_p (cfun)
15553      && flag_finite_math_only && !flag_trapping_math
15554      && flag_unsafe_math_optimizations)
15555    {
15556      ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15557      DONE;
15558    }
15559
15560  if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15561    {
15562      rtx op0 = gen_reg_rtx (XFmode);
15563      rtx op1 = gen_reg_rtx (XFmode);
15564
15565      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15566      emit_insn (gen_sqrtxf2 (op0, op1));
15567      emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15568      DONE;
15569   }
15570})
15571
15572(define_expand "hypot<mode>3"
15573  [(use (match_operand:MODEF 0 "register_operand"))
15574   (use (match_operand:MODEF 1 "general_operand"))
15575   (use (match_operand:MODEF 2 "general_operand"))]
15576  "TARGET_USE_FANCY_MATH_387
15577   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15578       || TARGET_MIX_SSE_I387)
15579   && flag_finite_math_only
15580   && flag_unsafe_math_optimizations"
15581{
15582  rtx op0 = gen_reg_rtx (XFmode);
15583  rtx op1 = gen_reg_rtx (XFmode);
15584  rtx op2 = gen_reg_rtx (XFmode);
15585
15586  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15587  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15588
15589  emit_insn (gen_mulxf3 (op1, op1, op1));
15590  emit_insn (gen_mulxf3 (op2, op2, op2));
15591  emit_insn (gen_addxf3 (op0, op2, op1));
15592  emit_insn (gen_sqrtxf2 (op0, op0));
15593
15594  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15595  DONE;
15596})
15597
15598(define_insn "x86_fnstsw_1"
15599  [(set (match_operand:HI 0 "register_operand" "=a")
15600	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
15601  "TARGET_80387"
15602  "fnstsw\t%0"
15603  [(set_attr "length" "2")
15604   (set_attr "mode" "SI")
15605   (set_attr "unit" "i387")])
15606
15607(define_insn "fpremxf4_i387"
15608  [(set (match_operand:XF 0 "register_operand" "=f")
15609	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15610		    (match_operand:XF 3 "register_operand" "1")]
15611		   UNSPEC_FPREM_F))
15612   (set (match_operand:XF 1 "register_operand" "=f")
15613	(unspec:XF [(match_dup 2) (match_dup 3)]
15614		   UNSPEC_FPREM_U))
15615   (set (reg:CCFP FPSR_REG)
15616	(unspec:CCFP [(match_dup 2) (match_dup 3)]
15617		     UNSPEC_C2_FLAG))]
15618  "TARGET_USE_FANCY_MATH_387
15619   && flag_finite_math_only"
15620  "fprem"
15621  [(set_attr "type" "fpspc")
15622   (set_attr "znver1_decode" "vector")
15623   (set_attr "mode" "XF")])
15624
15625(define_expand "fmodxf3"
15626  [(use (match_operand:XF 0 "register_operand"))
15627   (use (match_operand:XF 1 "general_operand"))
15628   (use (match_operand:XF 2 "general_operand"))]
15629  "TARGET_USE_FANCY_MATH_387
15630   && flag_finite_math_only"
15631{
15632  rtx_code_label *label = gen_label_rtx ();
15633
15634  rtx op1 = gen_reg_rtx (XFmode);
15635  rtx op2 = gen_reg_rtx (XFmode);
15636
15637  emit_move_insn (op2, operands[2]);
15638  emit_move_insn (op1, operands[1]);
15639
15640  emit_label (label);
15641  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15642  ix86_emit_fp_unordered_jump (label);
15643  LABEL_NUSES (label) = 1;
15644
15645  emit_move_insn (operands[0], op1);
15646  DONE;
15647})
15648
15649(define_expand "fmod<mode>3"
15650  [(use (match_operand:MODEF 0 "register_operand"))
15651   (use (match_operand:MODEF 1 "general_operand"))
15652   (use (match_operand:MODEF 2 "general_operand"))]
15653  "TARGET_USE_FANCY_MATH_387
15654   && flag_finite_math_only"
15655{
15656  rtx (*gen_truncxf) (rtx, rtx);
15657
15658  rtx_code_label *label = gen_label_rtx ();
15659
15660  rtx op1 = gen_reg_rtx (XFmode);
15661  rtx op2 = gen_reg_rtx (XFmode);
15662
15663  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15664  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15665
15666  emit_label (label);
15667  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15668  ix86_emit_fp_unordered_jump (label);
15669  LABEL_NUSES (label) = 1;
15670
15671  /* Truncate the result properly for strict SSE math.  */
15672  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15673      && !TARGET_MIX_SSE_I387)
15674    gen_truncxf = gen_truncxf<mode>2;
15675  else
15676    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15677
15678  emit_insn (gen_truncxf (operands[0], op1));
15679  DONE;
15680})
15681
15682(define_insn "fprem1xf4_i387"
15683  [(set (match_operand:XF 0 "register_operand" "=f")
15684	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15685		    (match_operand:XF 3 "register_operand" "1")]
15686		   UNSPEC_FPREM1_F))
15687   (set (match_operand:XF 1 "register_operand" "=f")
15688	(unspec:XF [(match_dup 2) (match_dup 3)]
15689		   UNSPEC_FPREM1_U))
15690   (set (reg:CCFP FPSR_REG)
15691	(unspec:CCFP [(match_dup 2) (match_dup 3)]
15692		     UNSPEC_C2_FLAG))]
15693  "TARGET_USE_FANCY_MATH_387
15694   && flag_finite_math_only"
15695  "fprem1"
15696  [(set_attr "type" "fpspc")
15697   (set_attr "znver1_decode" "vector")
15698   (set_attr "mode" "XF")])
15699
15700(define_expand "remainderxf3"
15701  [(use (match_operand:XF 0 "register_operand"))
15702   (use (match_operand:XF 1 "general_operand"))
15703   (use (match_operand:XF 2 "general_operand"))]
15704  "TARGET_USE_FANCY_MATH_387
15705   && flag_finite_math_only"
15706{
15707  rtx_code_label *label = gen_label_rtx ();
15708
15709  rtx op1 = gen_reg_rtx (XFmode);
15710  rtx op2 = gen_reg_rtx (XFmode);
15711
15712  emit_move_insn (op2, operands[2]);
15713  emit_move_insn (op1, operands[1]);
15714
15715  emit_label (label);
15716  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15717  ix86_emit_fp_unordered_jump (label);
15718  LABEL_NUSES (label) = 1;
15719
15720  emit_move_insn (operands[0], op1);
15721  DONE;
15722})
15723
15724(define_expand "remainder<mode>3"
15725  [(use (match_operand:MODEF 0 "register_operand"))
15726   (use (match_operand:MODEF 1 "general_operand"))
15727   (use (match_operand:MODEF 2 "general_operand"))]
15728  "TARGET_USE_FANCY_MATH_387
15729   && flag_finite_math_only"
15730{
15731  rtx (*gen_truncxf) (rtx, rtx);
15732
15733  rtx_code_label *label = gen_label_rtx ();
15734
15735  rtx op1 = gen_reg_rtx (XFmode);
15736  rtx op2 = gen_reg_rtx (XFmode);
15737
15738  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15739  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15740
15741  emit_label (label);
15742
15743  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15744  ix86_emit_fp_unordered_jump (label);
15745  LABEL_NUSES (label) = 1;
15746
15747  /* Truncate the result properly for strict SSE math.  */
15748  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15749      && !TARGET_MIX_SSE_I387)
15750    gen_truncxf = gen_truncxf<mode>2;
15751  else
15752    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15753
15754  emit_insn (gen_truncxf (operands[0], op1));
15755  DONE;
15756})
15757
15758(define_int_iterator SINCOS
15759	[UNSPEC_SIN
15760	 UNSPEC_COS])
15761
15762(define_int_attr sincos
15763	[(UNSPEC_SIN "sin")
15764	 (UNSPEC_COS "cos")])
15765
15766(define_insn "<sincos>xf2"
15767  [(set (match_operand:XF 0 "register_operand" "=f")
15768	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15769		   SINCOS))]
15770  "TARGET_USE_FANCY_MATH_387
15771   && flag_unsafe_math_optimizations"
15772  "f<sincos>"
15773  [(set_attr "type" "fpspc")
15774   (set_attr "znver1_decode" "vector")
15775   (set_attr "mode" "XF")])
15776
15777(define_expand "<sincos><mode>2"
15778  [(set (match_operand:MODEF 0 "register_operand")
15779	(unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
15780		      SINCOS))]
15781  "TARGET_USE_FANCY_MATH_387
15782   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15783       || TARGET_MIX_SSE_I387)
15784   && flag_unsafe_math_optimizations"
15785{
15786  rtx op0 = gen_reg_rtx (XFmode);
15787  rtx op1 = gen_reg_rtx (XFmode);
15788
15789  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15790  emit_insn (gen_<sincos>xf2 (op0, op1));
15791  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15792  DONE;
15793})
15794
15795(define_insn "sincosxf3"
15796  [(set (match_operand:XF 0 "register_operand" "=f")
15797	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15798		   UNSPEC_SINCOS_COS))
15799   (set (match_operand:XF 1 "register_operand" "=f")
15800        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15801  "TARGET_USE_FANCY_MATH_387
15802   && flag_unsafe_math_optimizations"
15803  "fsincos"
15804  [(set_attr "type" "fpspc")
15805   (set_attr "znver1_decode" "vector")
15806   (set_attr "mode" "XF")])
15807
15808(define_expand "sincos<mode>3"
15809  [(use (match_operand:MODEF 0 "register_operand"))
15810   (use (match_operand:MODEF 1 "register_operand"))
15811   (use (match_operand:MODEF 2 "general_operand"))]
15812  "TARGET_USE_FANCY_MATH_387
15813   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15814       || TARGET_MIX_SSE_I387)
15815   && flag_unsafe_math_optimizations"
15816{
15817  rtx op0 = gen_reg_rtx (XFmode);
15818  rtx op1 = gen_reg_rtx (XFmode);
15819  rtx op2 = gen_reg_rtx (XFmode);
15820
15821  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15822  emit_insn (gen_sincosxf3 (op0, op1, op2));
15823  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15824  emit_insn (gen_truncxf<mode>2 (operands[1], op1));
15825  DONE;
15826})
15827
15828(define_insn "fptanxf4_i387"
15829  [(set (match_operand:SF 0 "register_operand" "=f")
15830	(match_operand:SF 3 "const1_operand"))
15831   (set (match_operand:XF 1 "register_operand" "=f")
15832        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15833		   UNSPEC_TAN))]
15834  "TARGET_USE_FANCY_MATH_387
15835   && flag_unsafe_math_optimizations"
15836  "fptan"
15837  [(set_attr "type" "fpspc")
15838   (set_attr "znver1_decode" "vector")
15839   (set_attr "mode" "XF")])
15840
15841(define_expand "tanxf2"
15842  [(use (match_operand:XF 0 "register_operand"))
15843   (use (match_operand:XF 1 "register_operand"))]
15844  "TARGET_USE_FANCY_MATH_387
15845   && flag_unsafe_math_optimizations"
15846{
15847  rtx one = gen_reg_rtx (SFmode);
15848  emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
15849				CONST1_RTX (SFmode)));
15850  DONE;
15851})
15852
15853(define_expand "tan<mode>2"
15854  [(use (match_operand:MODEF 0 "register_operand"))
15855   (use (match_operand:MODEF 1 "general_operand"))]
15856  "TARGET_USE_FANCY_MATH_387
15857   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15858       || TARGET_MIX_SSE_I387)
15859   && flag_unsafe_math_optimizations"
15860{
15861  rtx op0 = gen_reg_rtx (XFmode);
15862  rtx op1 = gen_reg_rtx (XFmode);
15863
15864  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15865  emit_insn (gen_tanxf2 (op0, op1));
15866  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15867  DONE;
15868})
15869
15870(define_insn "atan2xf3"
15871  [(set (match_operand:XF 0 "register_operand" "=f")
15872        (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15873	            (match_operand:XF 1 "register_operand" "f")]
15874	           UNSPEC_FPATAN))
15875   (clobber (match_scratch:XF 3 "=1"))]
15876  "TARGET_USE_FANCY_MATH_387
15877   && flag_unsafe_math_optimizations"
15878  "fpatan"
15879  [(set_attr "type" "fpspc")
15880   (set_attr "znver1_decode" "vector")
15881   (set_attr "mode" "XF")])
15882
15883(define_expand "atan2<mode>3"
15884  [(use (match_operand:MODEF 0 "register_operand"))
15885   (use (match_operand:MODEF 1 "general_operand"))
15886   (use (match_operand:MODEF 2 "general_operand"))]
15887  "TARGET_USE_FANCY_MATH_387
15888   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15889       || TARGET_MIX_SSE_I387)
15890   && flag_unsafe_math_optimizations"
15891{
15892  rtx op0 = gen_reg_rtx (XFmode);
15893  rtx op1 = gen_reg_rtx (XFmode);
15894  rtx op2 = gen_reg_rtx (XFmode);
15895
15896  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15897  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15898
15899  emit_insn (gen_atan2xf3 (op0, op1, op2));
15900  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15901  DONE;
15902})
15903
15904(define_expand "atanxf2"
15905  [(parallel [(set (match_operand:XF 0 "register_operand")
15906		   (unspec:XF [(match_dup 2)
15907			       (match_operand:XF 1 "register_operand")]
15908			      UNSPEC_FPATAN))
15909	      (clobber (match_scratch:XF 3))])]
15910  "TARGET_USE_FANCY_MATH_387
15911   && flag_unsafe_math_optimizations"
15912  "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15913
15914(define_expand "atan<mode>2"
15915  [(use (match_operand:MODEF 0 "register_operand"))
15916   (use (match_operand:MODEF 1 "general_operand"))]
15917  "TARGET_USE_FANCY_MATH_387
15918   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15919       || TARGET_MIX_SSE_I387)
15920   && flag_unsafe_math_optimizations"
15921{
15922  rtx op0 = gen_reg_rtx (XFmode);
15923  rtx op1 = gen_reg_rtx (XFmode);
15924
15925  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15926  emit_insn (gen_atanxf2 (op0, op1));
15927  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15928  DONE;
15929})
15930
15931(define_expand "asinxf2"
15932  [(set (match_dup 2)
15933	(mult:XF (match_operand:XF 1 "register_operand")
15934		 (match_dup 1)))
15935   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15936   (set (match_dup 5) (sqrt:XF (match_dup 4)))
15937   (parallel [(set (match_operand:XF 0 "register_operand")
15938        	   (unspec:XF [(match_dup 5) (match_dup 1)]
15939			      UNSPEC_FPATAN))
15940   	      (clobber (match_scratch:XF 6))])]
15941  "TARGET_USE_FANCY_MATH_387
15942   && flag_unsafe_math_optimizations"
15943{
15944  int i;
15945
15946  for (i = 2; i < 6; i++)
15947    operands[i] = gen_reg_rtx (XFmode);
15948
15949  emit_move_insn (operands[3], CONST1_RTX (XFmode));
15950})
15951
15952(define_expand "asin<mode>2"
15953  [(use (match_operand:MODEF 0 "register_operand"))
15954   (use (match_operand:MODEF 1 "general_operand"))]
15955  "TARGET_USE_FANCY_MATH_387
15956   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15957       || TARGET_MIX_SSE_I387)
15958   && flag_unsafe_math_optimizations"
15959{
15960  rtx op0 = gen_reg_rtx (XFmode);
15961  rtx op1 = gen_reg_rtx (XFmode);
15962
15963  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15964  emit_insn (gen_asinxf2 (op0, op1));
15965  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15966  DONE;
15967})
15968
15969(define_expand "acosxf2"
15970  [(set (match_dup 2)
15971	(mult:XF (match_operand:XF 1 "register_operand")
15972		 (match_dup 1)))
15973   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15974   (set (match_dup 5) (sqrt:XF (match_dup 4)))
15975   (parallel [(set (match_operand:XF 0 "register_operand")
15976        	   (unspec:XF [(match_dup 1) (match_dup 5)]
15977			      UNSPEC_FPATAN))
15978   	      (clobber (match_scratch:XF 6))])]
15979  "TARGET_USE_FANCY_MATH_387
15980   && flag_unsafe_math_optimizations"
15981{
15982  int i;
15983
15984  for (i = 2; i < 6; i++)
15985    operands[i] = gen_reg_rtx (XFmode);
15986
15987  emit_move_insn (operands[3], CONST1_RTX (XFmode));
15988})
15989
15990(define_expand "acos<mode>2"
15991  [(use (match_operand:MODEF 0 "register_operand"))
15992   (use (match_operand:MODEF 1 "general_operand"))]
15993  "TARGET_USE_FANCY_MATH_387
15994   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15995       || TARGET_MIX_SSE_I387)
15996   && flag_unsafe_math_optimizations"
15997{
15998  rtx op0 = gen_reg_rtx (XFmode);
15999  rtx op1 = gen_reg_rtx (XFmode);
16000
16001  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16002  emit_insn (gen_acosxf2 (op0, op1));
16003  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16004  DONE;
16005})
16006
16007(define_expand "sinhxf2"
16008  [(use (match_operand:XF 0 "register_operand"))
16009   (use (match_operand:XF 1 "register_operand"))]
16010  "TARGET_USE_FANCY_MATH_387
16011   && flag_finite_math_only
16012   && flag_unsafe_math_optimizations"
16013{
16014  ix86_emit_i387_sinh (operands[0], operands[1]);
16015  DONE;
16016})
16017
16018(define_expand "sinh<mode>2"
16019  [(use (match_operand:MODEF 0 "register_operand"))
16020   (use (match_operand:MODEF 1 "general_operand"))]
16021  "TARGET_USE_FANCY_MATH_387
16022   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16023       || TARGET_MIX_SSE_I387)
16024   && flag_finite_math_only
16025   && flag_unsafe_math_optimizations"
16026{
16027  rtx op0 = gen_reg_rtx (XFmode);
16028  rtx op1 = gen_reg_rtx (XFmode);
16029
16030  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16031  emit_insn (gen_sinhxf2 (op0, op1));
16032  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16033  DONE;
16034})
16035
16036(define_expand "coshxf2"
16037  [(use (match_operand:XF 0 "register_operand"))
16038   (use (match_operand:XF 1 "register_operand"))]
16039  "TARGET_USE_FANCY_MATH_387
16040   && flag_unsafe_math_optimizations"
16041{
16042  ix86_emit_i387_cosh (operands[0], operands[1]);
16043  DONE;
16044})
16045
16046(define_expand "cosh<mode>2"
16047  [(use (match_operand:MODEF 0 "register_operand"))
16048   (use (match_operand:MODEF 1 "general_operand"))]
16049  "TARGET_USE_FANCY_MATH_387
16050   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16051       || TARGET_MIX_SSE_I387)
16052   && flag_unsafe_math_optimizations"
16053{
16054  rtx op0 = gen_reg_rtx (XFmode);
16055  rtx op1 = gen_reg_rtx (XFmode);
16056
16057  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16058  emit_insn (gen_coshxf2 (op0, op1));
16059  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16060  DONE;
16061})
16062
16063(define_expand "tanhxf2"
16064  [(use (match_operand:XF 0 "register_operand"))
16065   (use (match_operand:XF 1 "register_operand"))]
16066  "TARGET_USE_FANCY_MATH_387
16067   && flag_unsafe_math_optimizations"
16068{
16069  ix86_emit_i387_tanh (operands[0], operands[1]);
16070  DONE;
16071})
16072
16073(define_expand "tanh<mode>2"
16074  [(use (match_operand:MODEF 0 "register_operand"))
16075   (use (match_operand:MODEF 1 "general_operand"))]
16076  "TARGET_USE_FANCY_MATH_387
16077   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16078       || TARGET_MIX_SSE_I387)
16079   && flag_unsafe_math_optimizations"
16080{
16081  rtx op0 = gen_reg_rtx (XFmode);
16082  rtx op1 = gen_reg_rtx (XFmode);
16083
16084  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16085  emit_insn (gen_tanhxf2 (op0, op1));
16086  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16087  DONE;
16088})
16089
16090(define_expand "asinhxf2"
16091  [(use (match_operand:XF 0 "register_operand"))
16092   (use (match_operand:XF 1 "register_operand"))]
16093  "TARGET_USE_FANCY_MATH_387
16094   && flag_finite_math_only
16095   && flag_unsafe_math_optimizations"
16096{
16097  ix86_emit_i387_asinh (operands[0], operands[1]);
16098  DONE;
16099})
16100
16101(define_expand "asinh<mode>2"
16102  [(use (match_operand:MODEF 0 "register_operand"))
16103   (use (match_operand:MODEF 1 "general_operand"))]
16104  "TARGET_USE_FANCY_MATH_387
16105   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16106       || TARGET_MIX_SSE_I387)
16107   && flag_finite_math_only
16108   && flag_unsafe_math_optimizations"
16109{
16110  rtx op0 = gen_reg_rtx (XFmode);
16111  rtx op1 = gen_reg_rtx (XFmode);
16112
16113  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16114  emit_insn (gen_asinhxf2 (op0, op1));
16115  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16116  DONE;
16117})
16118
16119(define_expand "acoshxf2"
16120  [(use (match_operand:XF 0 "register_operand"))
16121   (use (match_operand:XF 1 "register_operand"))]
16122  "TARGET_USE_FANCY_MATH_387
16123   && flag_unsafe_math_optimizations"
16124{
16125  ix86_emit_i387_acosh (operands[0], operands[1]);
16126  DONE;
16127})
16128
16129(define_expand "acosh<mode>2"
16130  [(use (match_operand:MODEF 0 "register_operand"))
16131   (use (match_operand:MODEF 1 "general_operand"))]
16132  "TARGET_USE_FANCY_MATH_387
16133   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16134       || TARGET_MIX_SSE_I387)
16135   && flag_unsafe_math_optimizations"
16136{
16137  rtx op0 = gen_reg_rtx (XFmode);
16138  rtx op1 = gen_reg_rtx (XFmode);
16139
16140  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16141  emit_insn (gen_acoshxf2 (op0, op1));
16142  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16143  DONE;
16144})
16145
16146(define_expand "atanhxf2"
16147  [(use (match_operand:XF 0 "register_operand"))
16148   (use (match_operand:XF 1 "register_operand"))]
16149  "TARGET_USE_FANCY_MATH_387
16150   && flag_unsafe_math_optimizations"
16151{
16152  ix86_emit_i387_atanh (operands[0], operands[1]);
16153  DONE;
16154})
16155
16156(define_expand "atanh<mode>2"
16157  [(use (match_operand:MODEF 0 "register_operand"))
16158   (use (match_operand:MODEF 1 "general_operand"))]
16159  "TARGET_USE_FANCY_MATH_387
16160   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16161       || TARGET_MIX_SSE_I387)
16162   && flag_unsafe_math_optimizations"
16163{
16164  rtx op0 = gen_reg_rtx (XFmode);
16165  rtx op1 = gen_reg_rtx (XFmode);
16166
16167  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16168  emit_insn (gen_atanhxf2 (op0, op1));
16169  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16170  DONE;
16171})
16172
16173(define_insn "fyl2xxf3_i387"
16174  [(set (match_operand:XF 0 "register_operand" "=f")
16175        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16176		    (match_operand:XF 2 "register_operand" "f")]
16177	           UNSPEC_FYL2X))
16178   (clobber (match_scratch:XF 3 "=2"))]
16179  "TARGET_USE_FANCY_MATH_387
16180   && flag_unsafe_math_optimizations"
16181  "fyl2x"
16182  [(set_attr "type" "fpspc")
16183   (set_attr "znver1_decode" "vector")
16184   (set_attr "mode" "XF")])
16185
16186(define_expand "logxf2"
16187  [(parallel [(set (match_operand:XF 0 "register_operand")
16188		   (unspec:XF [(match_operand:XF 1 "register_operand")
16189			       (match_dup 2)] UNSPEC_FYL2X))
16190	      (clobber (match_scratch:XF 3))])]
16191  "TARGET_USE_FANCY_MATH_387
16192   && flag_unsafe_math_optimizations"
16193{
16194  operands[2]
16195    = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
16196})
16197
16198(define_expand "log<mode>2"
16199  [(use (match_operand:MODEF 0 "register_operand"))
16200   (use (match_operand:MODEF 1 "general_operand"))]
16201  "TARGET_USE_FANCY_MATH_387
16202   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16203       || TARGET_MIX_SSE_I387)
16204   && flag_unsafe_math_optimizations"
16205{
16206  rtx op0 = gen_reg_rtx (XFmode);
16207  rtx op1 = gen_reg_rtx (XFmode);
16208
16209  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16210  emit_insn (gen_logxf2 (op0, op1));
16211  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16212  DONE;
16213})
16214
16215(define_expand "log10xf2"
16216  [(parallel [(set (match_operand:XF 0 "register_operand")
16217		   (unspec:XF [(match_operand:XF 1 "register_operand")
16218			       (match_dup 2)] UNSPEC_FYL2X))
16219	      (clobber (match_scratch:XF 3))])]
16220  "TARGET_USE_FANCY_MATH_387
16221   && flag_unsafe_math_optimizations"
16222{
16223  operands[2]
16224    = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
16225})
16226
16227(define_expand "log10<mode>2"
16228  [(use (match_operand:MODEF 0 "register_operand"))
16229   (use (match_operand:MODEF 1 "general_operand"))]
16230  "TARGET_USE_FANCY_MATH_387
16231   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16232       || TARGET_MIX_SSE_I387)
16233   && flag_unsafe_math_optimizations"
16234{
16235  rtx op0 = gen_reg_rtx (XFmode);
16236  rtx op1 = gen_reg_rtx (XFmode);
16237
16238  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16239  emit_insn (gen_log10xf2 (op0, op1));
16240  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16241  DONE;
16242})
16243
16244(define_expand "log2xf2"
16245  [(parallel [(set (match_operand:XF 0 "register_operand")
16246		   (unspec:XF [(match_operand:XF 1 "register_operand")
16247			       (match_dup 2)] UNSPEC_FYL2X))
16248	      (clobber (match_scratch:XF 3))])]
16249  "TARGET_USE_FANCY_MATH_387
16250   && flag_unsafe_math_optimizations"
16251  "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
16252
16253(define_expand "log2<mode>2"
16254  [(use (match_operand:MODEF 0 "register_operand"))
16255   (use (match_operand:MODEF 1 "general_operand"))]
16256  "TARGET_USE_FANCY_MATH_387
16257   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16258       || TARGET_MIX_SSE_I387)
16259   && flag_unsafe_math_optimizations"
16260{
16261  rtx op0 = gen_reg_rtx (XFmode);
16262  rtx op1 = gen_reg_rtx (XFmode);
16263
16264  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16265  emit_insn (gen_log2xf2 (op0, op1));
16266  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16267  DONE;
16268})
16269
16270(define_insn "fyl2xp1xf3_i387"
16271  [(set (match_operand:XF 0 "register_operand" "=f")
16272        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16273		    (match_operand:XF 2 "register_operand" "f")]
16274	           UNSPEC_FYL2XP1))
16275   (clobber (match_scratch:XF 3 "=2"))]
16276  "TARGET_USE_FANCY_MATH_387
16277   && flag_unsafe_math_optimizations"
16278  "fyl2xp1"
16279  [(set_attr "type" "fpspc")
16280   (set_attr "znver1_decode" "vector")
16281   (set_attr "mode" "XF")])
16282
16283(define_expand "log1pxf2"
16284  [(use (match_operand:XF 0 "register_operand"))
16285   (use (match_operand:XF 1 "register_operand"))]
16286  "TARGET_USE_FANCY_MATH_387
16287   && flag_unsafe_math_optimizations"
16288{
16289  ix86_emit_i387_log1p (operands[0], operands[1]);
16290  DONE;
16291})
16292
16293(define_expand "log1p<mode>2"
16294  [(use (match_operand:MODEF 0 "register_operand"))
16295   (use (match_operand:MODEF 1 "general_operand"))]
16296  "TARGET_USE_FANCY_MATH_387
16297   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16298       || TARGET_MIX_SSE_I387)
16299   && flag_unsafe_math_optimizations"
16300{
16301  rtx op0 = gen_reg_rtx (XFmode);
16302  rtx op1 = gen_reg_rtx (XFmode);
16303
16304  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16305  emit_insn (gen_log1pxf2 (op0, op1));
16306  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16307  DONE;
16308})
16309
16310(define_insn "fxtractxf3_i387"
16311  [(set (match_operand:XF 0 "register_operand" "=f")
16312	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16313		   UNSPEC_XTRACT_FRACT))
16314   (set (match_operand:XF 1 "register_operand" "=f")
16315        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16316  "TARGET_USE_FANCY_MATH_387
16317   && flag_unsafe_math_optimizations"
16318  "fxtract"
16319  [(set_attr "type" "fpspc")
16320   (set_attr "znver1_decode" "vector")
16321   (set_attr "mode" "XF")])
16322
16323(define_expand "logbxf2"
16324  [(parallel [(set (match_dup 2)
16325		   (unspec:XF [(match_operand:XF 1 "register_operand")]
16326			      UNSPEC_XTRACT_FRACT))
16327	      (set (match_operand:XF 0 "register_operand")
16328		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16329  "TARGET_USE_FANCY_MATH_387
16330   && flag_unsafe_math_optimizations"
16331  "operands[2] = gen_reg_rtx (XFmode);")
16332
16333(define_expand "logb<mode>2"
16334  [(use (match_operand:MODEF 0 "register_operand"))
16335   (use (match_operand:MODEF 1 "general_operand"))]
16336  "TARGET_USE_FANCY_MATH_387
16337   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16338       || TARGET_MIX_SSE_I387)
16339   && flag_unsafe_math_optimizations"
16340{
16341  rtx op0 = gen_reg_rtx (XFmode);
16342  rtx op1 = gen_reg_rtx (XFmode);
16343
16344  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16345  emit_insn (gen_logbxf2 (op0, op1));
16346  emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16347  DONE;
16348})
16349
16350(define_expand "ilogbxf2"
16351  [(use (match_operand:SI 0 "register_operand"))
16352   (use (match_operand:XF 1 "register_operand"))]
16353  "TARGET_USE_FANCY_MATH_387
16354   && flag_unsafe_math_optimizations"
16355{
16356  rtx op0, op1;
16357
16358  if (optimize_insn_for_size_p ())
16359    FAIL;
16360
16361  op0 = gen_reg_rtx (XFmode);
16362  op1 = gen_reg_rtx (XFmode);
16363
16364  emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16365  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16366  DONE;
16367})
16368
16369(define_expand "ilogb<mode>2"
16370  [(use (match_operand:SI 0 "register_operand"))
16371   (use (match_operand:MODEF 1 "general_operand"))]
16372  "TARGET_USE_FANCY_MATH_387
16373   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16374       || TARGET_MIX_SSE_I387)
16375   && flag_unsafe_math_optimizations"
16376{
16377  rtx op0, op1, op2;
16378
16379  if (optimize_insn_for_size_p ())
16380    FAIL;
16381
16382  op0 = gen_reg_rtx (XFmode);
16383  op1 = gen_reg_rtx (XFmode);
16384  op2 = gen_reg_rtx (XFmode);
16385
16386  emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
16387  emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
16388  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16389  DONE;
16390})
16391
16392(define_insn "*f2xm1xf2_i387"
16393  [(set (match_operand:XF 0 "register_operand" "=f")
16394	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16395		   UNSPEC_F2XM1))]
16396  "TARGET_USE_FANCY_MATH_387
16397   && flag_unsafe_math_optimizations"
16398  "f2xm1"
16399  [(set_attr "type" "fpspc")
16400   (set_attr "znver1_decode" "vector")
16401   (set_attr "mode" "XF")])
16402
16403(define_insn "fscalexf4_i387"
16404  [(set (match_operand:XF 0 "register_operand" "=f")
16405	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
16406		    (match_operand:XF 3 "register_operand" "1")]
16407		   UNSPEC_FSCALE_FRACT))
16408   (set (match_operand:XF 1 "register_operand" "=f")
16409	(unspec:XF [(match_dup 2) (match_dup 3)]
16410		   UNSPEC_FSCALE_EXP))]
16411  "TARGET_USE_FANCY_MATH_387
16412   && flag_unsafe_math_optimizations"
16413  "fscale"
16414  [(set_attr "type" "fpspc")
16415   (set_attr "znver1_decode" "vector")
16416   (set_attr "mode" "XF")])
16417
16418(define_expand "expNcorexf3"
16419  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16420			       (match_operand:XF 2 "register_operand")))
16421   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16422   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16423   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16424   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16425   (parallel [(set (match_operand:XF 0 "register_operand")
16426		   (unspec:XF [(match_dup 8) (match_dup 4)]
16427			      UNSPEC_FSCALE_FRACT))
16428	      (set (match_dup 9)
16429		   (unspec:XF [(match_dup 8) (match_dup 4)]
16430			      UNSPEC_FSCALE_EXP))])]
16431  "TARGET_USE_FANCY_MATH_387
16432   && flag_unsafe_math_optimizations"
16433{
16434  int i;
16435
16436  for (i = 3; i < 10; i++)
16437    operands[i] = gen_reg_rtx (XFmode);
16438
16439  emit_move_insn (operands[7], CONST1_RTX (XFmode));
16440})
16441
16442(define_expand "expxf2"
16443  [(use (match_operand:XF 0 "register_operand"))
16444   (use (match_operand:XF 1 "register_operand"))]
16445  "TARGET_USE_FANCY_MATH_387
16446   && flag_unsafe_math_optimizations"
16447{
16448  rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
16449
16450  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16451  DONE;
16452})
16453
16454(define_expand "exp<mode>2"
16455  [(use (match_operand:MODEF 0 "register_operand"))
16456   (use (match_operand:MODEF 1 "general_operand"))]
16457  "TARGET_USE_FANCY_MATH_387
16458   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16459       || TARGET_MIX_SSE_I387)
16460   && flag_unsafe_math_optimizations"
16461{
16462  rtx op0 = gen_reg_rtx (XFmode);
16463  rtx op1 = gen_reg_rtx (XFmode);
16464
16465  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16466  emit_insn (gen_expxf2 (op0, op1));
16467  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16468  DONE;
16469})
16470
16471(define_expand "exp10xf2"
16472  [(use (match_operand:XF 0 "register_operand"))
16473   (use (match_operand:XF 1 "register_operand"))]
16474  "TARGET_USE_FANCY_MATH_387
16475   && flag_unsafe_math_optimizations"
16476{
16477  rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
16478
16479  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16480  DONE;
16481})
16482
16483(define_expand "exp10<mode>2"
16484  [(use (match_operand:MODEF 0 "register_operand"))
16485   (use (match_operand:MODEF 1 "general_operand"))]
16486  "TARGET_USE_FANCY_MATH_387
16487   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16488       || TARGET_MIX_SSE_I387)
16489   && flag_unsafe_math_optimizations"
16490{
16491  rtx op0 = gen_reg_rtx (XFmode);
16492  rtx op1 = gen_reg_rtx (XFmode);
16493
16494  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16495  emit_insn (gen_exp10xf2 (op0, op1));
16496  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16497  DONE;
16498})
16499
16500(define_expand "exp2xf2"
16501  [(use (match_operand:XF 0 "register_operand"))
16502   (use (match_operand:XF 1 "register_operand"))]
16503  "TARGET_USE_FANCY_MATH_387
16504   && flag_unsafe_math_optimizations"
16505{
16506  rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
16507
16508  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16509  DONE;
16510})
16511
16512(define_expand "exp2<mode>2"
16513  [(use (match_operand:MODEF 0 "register_operand"))
16514   (use (match_operand:MODEF 1 "general_operand"))]
16515  "TARGET_USE_FANCY_MATH_387
16516   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16517       || TARGET_MIX_SSE_I387)
16518   && flag_unsafe_math_optimizations"
16519{
16520  rtx op0 = gen_reg_rtx (XFmode);
16521  rtx op1 = gen_reg_rtx (XFmode);
16522
16523  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16524  emit_insn (gen_exp2xf2 (op0, op1));
16525  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16526  DONE;
16527})
16528
16529(define_expand "expm1xf2"
16530  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16531			       (match_dup 2)))
16532   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16533   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16534   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16535   (parallel [(set (match_dup 7)
16536		   (unspec:XF [(match_dup 6) (match_dup 4)]
16537			      UNSPEC_FSCALE_FRACT))
16538	      (set (match_dup 8)
16539		   (unspec:XF [(match_dup 6) (match_dup 4)]
16540			      UNSPEC_FSCALE_EXP))])
16541   (parallel [(set (match_dup 10)
16542		   (unspec:XF [(match_dup 9) (match_dup 8)]
16543			      UNSPEC_FSCALE_FRACT))
16544	      (set (match_dup 11)
16545		   (unspec:XF [(match_dup 9) (match_dup 8)]
16546			      UNSPEC_FSCALE_EXP))])
16547   (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16548   (set (match_operand:XF 0 "register_operand")
16549	(plus:XF (match_dup 12) (match_dup 7)))]
16550  "TARGET_USE_FANCY_MATH_387
16551   && flag_unsafe_math_optimizations"
16552{
16553  int i;
16554
16555  for (i = 2; i < 13; i++)
16556    operands[i] = gen_reg_rtx (XFmode);
16557
16558  emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16559  emit_move_insn (operands[9], CONST1_RTX (XFmode));
16560})
16561
16562(define_expand "expm1<mode>2"
16563  [(use (match_operand:MODEF 0 "register_operand"))
16564   (use (match_operand:MODEF 1 "general_operand"))]
16565  "TARGET_USE_FANCY_MATH_387
16566   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16567       || TARGET_MIX_SSE_I387)
16568   && flag_unsafe_math_optimizations"
16569{
16570  rtx op0 = gen_reg_rtx (XFmode);
16571  rtx op1 = gen_reg_rtx (XFmode);
16572
16573  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16574  emit_insn (gen_expm1xf2 (op0, op1));
16575  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16576  DONE;
16577})
16578
16579(define_expand "ldexpxf3"
16580  [(match_operand:XF 0 "register_operand")
16581   (match_operand:XF 1 "register_operand")
16582   (match_operand:SI 2 "register_operand")]
16583  "TARGET_USE_FANCY_MATH_387
16584   && flag_unsafe_math_optimizations"
16585{
16586  rtx tmp1 = gen_reg_rtx (XFmode);
16587  rtx tmp2 = gen_reg_rtx (XFmode);
16588
16589  emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16590  emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16591                                 operands[1], tmp1));
16592  DONE;
16593})
16594
16595(define_expand "ldexp<mode>3"
16596  [(use (match_operand:MODEF 0 "register_operand"))
16597   (use (match_operand:MODEF 1 "general_operand"))
16598   (use (match_operand:SI 2 "register_operand"))]
16599  "TARGET_USE_FANCY_MATH_387
16600   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16601       || TARGET_MIX_SSE_I387)
16602   && flag_unsafe_math_optimizations"
16603{
16604  rtx op0 = gen_reg_rtx (XFmode);
16605  rtx op1 = gen_reg_rtx (XFmode);
16606
16607  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16608  emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16609  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16610  DONE;
16611})
16612
16613(define_expand "scalbxf3"
16614  [(parallel [(set (match_operand:XF 0 " register_operand")
16615		   (unspec:XF [(match_operand:XF 1 "register_operand")
16616			       (match_operand:XF 2 "register_operand")]
16617			      UNSPEC_FSCALE_FRACT))
16618	      (set (match_dup 3)
16619		   (unspec:XF [(match_dup 1) (match_dup 2)]
16620			      UNSPEC_FSCALE_EXP))])]
16621  "TARGET_USE_FANCY_MATH_387
16622   && flag_unsafe_math_optimizations"
16623  "operands[3] = gen_reg_rtx (XFmode);")
16624
16625(define_expand "scalb<mode>3"
16626  [(use (match_operand:MODEF 0 "register_operand"))
16627   (use (match_operand:MODEF 1 "general_operand"))
16628   (use (match_operand:MODEF 2 "general_operand"))]
16629  "TARGET_USE_FANCY_MATH_387
16630   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16631       || TARGET_MIX_SSE_I387)
16632   && flag_unsafe_math_optimizations"
16633{
16634  rtx op0 = gen_reg_rtx (XFmode);
16635  rtx op1 = gen_reg_rtx (XFmode);
16636  rtx op2 = gen_reg_rtx (XFmode);
16637
16638  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16639  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16640  emit_insn (gen_scalbxf3 (op0, op1, op2));
16641  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16642  DONE;
16643})
16644
16645(define_expand "significandxf2"
16646  [(parallel [(set (match_operand:XF 0 "register_operand")
16647		   (unspec:XF [(match_operand:XF 1 "register_operand")]
16648			      UNSPEC_XTRACT_FRACT))
16649	      (set (match_dup 2)
16650		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16651  "TARGET_USE_FANCY_MATH_387
16652   && flag_unsafe_math_optimizations"
16653  "operands[2] = gen_reg_rtx (XFmode);")
16654
16655(define_expand "significand<mode>2"
16656  [(use (match_operand:MODEF 0 "register_operand"))
16657   (use (match_operand:MODEF 1 "general_operand"))]
16658  "TARGET_USE_FANCY_MATH_387
16659   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16660       || TARGET_MIX_SSE_I387)
16661   && flag_unsafe_math_optimizations"
16662{
16663  rtx op0 = gen_reg_rtx (XFmode);
16664  rtx op1 = gen_reg_rtx (XFmode);
16665
16666  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16667  emit_insn (gen_significandxf2 (op0, op1));
16668  emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16669  DONE;
16670})
16671
16672
16673(define_insn "sse4_1_round<mode>2"
16674  [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v,v")
16675	(unspec:MODEF
16676	  [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,v,m")
16677	   (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n,n")]
16678	  UNSPEC_ROUND))]
16679  "TARGET_SSE4_1"
16680  "@
16681   %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16682   %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16683   %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16684   vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16685   vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16686  [(set_attr "type" "ssecvt")
16687   (set_attr "prefix_extra" "1,1,1,*,*")
16688   (set_attr "length_immediate" "*,*,*,1,1")
16689   (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
16690   (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
16691   (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
16692   (set_attr "mode" "<MODE>")
16693   (set (attr "preferred_for_speed")
16694      (cond [(match_test "TARGET_AVX")
16695	       (symbol_ref "true")
16696	     (eq_attr "alternative" "1,2")
16697	       (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16698	    ]
16699	    (symbol_ref "true")))])
16700
16701(define_insn "rintxf2"
16702  [(set (match_operand:XF 0 "register_operand" "=f")
16703	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16704		   UNSPEC_FRNDINT))]
16705  "TARGET_USE_FANCY_MATH_387"
16706  "frndint"
16707  [(set_attr "type" "fpspc")
16708   (set_attr "znver1_decode" "vector")
16709   (set_attr "mode" "XF")])
16710
16711(define_expand "rint<mode>2"
16712  [(use (match_operand:MODEF 0 "register_operand"))
16713   (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16714  "TARGET_USE_FANCY_MATH_387
16715   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16716{
16717  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16718    {
16719      if (TARGET_SSE4_1)
16720	emit_insn (gen_sse4_1_round<mode>2
16721		   (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16722      else
16723	ix86_expand_rint (operands[0], operands[1]);
16724    }
16725  else
16726    {
16727      rtx op0 = gen_reg_rtx (XFmode);
16728      rtx op1 = gen_reg_rtx (XFmode);
16729
16730      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16731      emit_insn (gen_rintxf2 (op0, op1));
16732      emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16733    }
16734  DONE;
16735})
16736
16737(define_expand "nearbyintxf2"
16738  [(set (match_operand:XF 0 "register_operand")
16739	(unspec:XF [(match_operand:XF 1 "register_operand")]
16740		   UNSPEC_FRNDINT))]
16741  "TARGET_USE_FANCY_MATH_387
16742   && !flag_trapping_math")
16743
16744(define_expand "nearbyint<mode>2"
16745  [(use (match_operand:MODEF 0 "register_operand"))
16746   (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16747  "(TARGET_USE_FANCY_MATH_387
16748    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16749	  || TARGET_MIX_SSE_I387)
16750    && !flag_trapping_math)
16751   || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
16752{
16753  if (TARGET_SSE4_1 && TARGET_SSE_MATH)
16754    emit_insn (gen_sse4_1_round<mode>2
16755	       (operands[0], operands[1], GEN_INT (ROUND_MXCSR
16756						   | ROUND_NO_EXC)));
16757  else
16758    {
16759      rtx op0 = gen_reg_rtx (XFmode);
16760      rtx op1 = gen_reg_rtx (XFmode);
16761
16762      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16763      emit_insn (gen_nearbyintxf2 (op0, op1));
16764      emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16765    }
16766  DONE;
16767})
16768
16769(define_expand "round<mode>2"
16770  [(match_operand:X87MODEF 0 "register_operand")
16771   (match_operand:X87MODEF 1 "nonimmediate_operand")]
16772  "(TARGET_USE_FANCY_MATH_387
16773    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16774	|| TARGET_MIX_SSE_I387)
16775    && flag_unsafe_math_optimizations
16776    && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16777   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16778       && !flag_trapping_math && !flag_rounding_math)"
16779{
16780  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16781      && !flag_trapping_math && !flag_rounding_math)
16782    {
16783      if (TARGET_SSE4_1)
16784        {
16785	  operands[1] = force_reg (<MODE>mode, operands[1]);
16786	  ix86_expand_round_sse4 (operands[0], operands[1]);
16787	}
16788      else if (TARGET_64BIT || (<MODE>mode != DFmode))
16789	ix86_expand_round (operands[0], operands[1]);
16790      else
16791	ix86_expand_rounddf_32 (operands[0], operands[1]);
16792    }
16793  else
16794    {
16795      operands[1] = force_reg (<MODE>mode, operands[1]);
16796      ix86_emit_i387_round (operands[0], operands[1]);
16797    }
16798  DONE;
16799})
16800
16801(define_insn "lrintxfdi2"
16802  [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16803	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16804		   UNSPEC_FIST))
16805   (clobber (match_scratch:XF 2 "=&f"))]
16806  "TARGET_USE_FANCY_MATH_387"
16807  "* return output_fix_trunc (insn, operands, false);"
16808  [(set_attr "type" "fpspc")
16809   (set_attr "mode" "DI")])
16810
16811(define_insn "lrintxf<mode>2"
16812  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16813	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16814		      UNSPEC_FIST))]
16815  "TARGET_USE_FANCY_MATH_387"
16816  "* return output_fix_trunc (insn, operands, false);"
16817  [(set_attr "type" "fpspc")
16818   (set_attr "mode" "<MODE>")])
16819
16820(define_expand "lrint<MODEF:mode><SWI48:mode>2"
16821  [(set (match_operand:SWI48 0 "nonimmediate_operand")
16822     (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16823		   UNSPEC_FIX_NOTRUNC))]
16824  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16825
16826(define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16827  [(match_operand:SWI248x 0 "nonimmediate_operand")
16828   (match_operand:X87MODEF 1 "register_operand")]
16829  "(TARGET_USE_FANCY_MATH_387
16830    && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16831	|| TARGET_MIX_SSE_I387)
16832    && flag_unsafe_math_optimizations)
16833   || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16834       && <SWI248x:MODE>mode != HImode 
16835       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16836       && !flag_trapping_math && !flag_rounding_math)"
16837{
16838  if (optimize_insn_for_size_p ())
16839    FAIL;
16840
16841  if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16842      && <SWI248x:MODE>mode != HImode
16843      && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16844      && !flag_trapping_math && !flag_rounding_math)
16845    ix86_expand_lround (operands[0], operands[1]);
16846  else
16847    ix86_emit_i387_round (operands[0], operands[1]);
16848  DONE;
16849})
16850
16851(define_int_iterator FRNDINT_ROUNDING
16852	[UNSPEC_FRNDINT_ROUNDEVEN
16853	 UNSPEC_FRNDINT_FLOOR
16854	 UNSPEC_FRNDINT_CEIL
16855	 UNSPEC_FRNDINT_TRUNC])
16856
16857(define_int_iterator FIST_ROUNDING
16858	[UNSPEC_FIST_FLOOR
16859	 UNSPEC_FIST_CEIL])
16860
16861;; Base name for define_insn
16862(define_int_attr rounding_insn
16863	[(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
16864	 (UNSPEC_FRNDINT_FLOOR "floor")
16865	 (UNSPEC_FRNDINT_CEIL "ceil")
16866	 (UNSPEC_FRNDINT_TRUNC "btrunc")
16867	 (UNSPEC_FIST_FLOOR "floor")
16868	 (UNSPEC_FIST_CEIL "ceil")])
16869
16870(define_int_attr rounding
16871	[(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
16872	 (UNSPEC_FRNDINT_FLOOR "floor")
16873	 (UNSPEC_FRNDINT_CEIL "ceil")
16874	 (UNSPEC_FRNDINT_TRUNC "trunc")
16875	 (UNSPEC_FIST_FLOOR "floor")
16876	 (UNSPEC_FIST_CEIL "ceil")])
16877
16878(define_int_attr ROUNDING
16879	[(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
16880	 (UNSPEC_FRNDINT_FLOOR "FLOOR")
16881	 (UNSPEC_FRNDINT_CEIL "CEIL")
16882	 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16883	 (UNSPEC_FIST_FLOOR "FLOOR")
16884	 (UNSPEC_FIST_CEIL "CEIL")])
16885
16886;; Rounding mode control word calculation could clobber FLAGS_REG.
16887(define_insn_and_split "frndintxf2_<rounding>"
16888  [(set (match_operand:XF 0 "register_operand")
16889	(unspec:XF [(match_operand:XF 1 "register_operand")]
16890		   FRNDINT_ROUNDING))
16891   (clobber (reg:CC FLAGS_REG))]
16892  "TARGET_USE_FANCY_MATH_387
16893   && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16894   && ix86_pre_reload_split ()"
16895  "#"
16896  "&& 1"
16897  [(const_int 0)]
16898{
16899  ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16900
16901  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16902  operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16903
16904  emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
16905					     operands[2], operands[3]));
16906  DONE;
16907}
16908  [(set_attr "type" "frndint")
16909   (set_attr "i387_cw" "<rounding>")
16910   (set_attr "mode" "XF")])
16911
16912(define_insn "frndintxf2_<rounding>_i387"
16913  [(set (match_operand:XF 0 "register_operand" "=f")
16914	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16915		   FRNDINT_ROUNDING))
16916   (use (match_operand:HI 2 "memory_operand" "m"))
16917   (use (match_operand:HI 3 "memory_operand" "m"))]
16918  "TARGET_USE_FANCY_MATH_387
16919   && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16920  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16921  [(set_attr "type" "frndint")
16922   (set_attr "i387_cw" "<rounding>")
16923   (set_attr "mode" "XF")])
16924
16925(define_expand "<rounding_insn>xf2"
16926  [(parallel [(set (match_operand:XF 0 "register_operand")
16927		   (unspec:XF [(match_operand:XF 1 "register_operand")]
16928			      FRNDINT_ROUNDING))
16929	      (clobber (reg:CC FLAGS_REG))])]
16930  "TARGET_USE_FANCY_MATH_387
16931   && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16932
16933(define_expand "<rounding_insn><mode>2"
16934  [(parallel [(set (match_operand:MODEF 0 "register_operand")
16935		   (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16936				 FRNDINT_ROUNDING))
16937	      (clobber (reg:CC FLAGS_REG))])]
16938  "(TARGET_USE_FANCY_MATH_387
16939    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16940	|| TARGET_MIX_SSE_I387)
16941    && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16942   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16943       && (TARGET_SSE4_1
16944	   || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
16945	       && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
16946{
16947  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16948      && (TARGET_SSE4_1
16949	  || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
16950	      && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
16951    {
16952      if (TARGET_SSE4_1)
16953	emit_insn (gen_sse4_1_round<mode>2
16954		   (operands[0], operands[1],
16955		    GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
16956      else if (TARGET_64BIT || (<MODE>mode != DFmode))
16957	{
16958	  if (ROUND_<ROUNDING> == ROUND_FLOOR)
16959	    ix86_expand_floorceil (operands[0], operands[1], true);
16960	  else if (ROUND_<ROUNDING> == ROUND_CEIL)
16961	    ix86_expand_floorceil (operands[0], operands[1], false);
16962	  else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16963	    ix86_expand_trunc (operands[0], operands[1]);
16964	  else
16965	    gcc_unreachable ();
16966	}
16967      else
16968	{
16969	  if (ROUND_<ROUNDING> == ROUND_FLOOR)
16970	    ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16971	  else if (ROUND_<ROUNDING> == ROUND_CEIL)
16972	    ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16973	  else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16974	    ix86_expand_truncdf_32 (operands[0], operands[1]);
16975	  else
16976	    gcc_unreachable ();
16977	}
16978    }
16979  else
16980    {
16981      rtx op0 = gen_reg_rtx (XFmode);
16982      rtx op1 = gen_reg_rtx (XFmode);
16983
16984      emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16985      emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16986      emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16987    }
16988  DONE;
16989})
16990
16991;; Rounding mode control word calculation could clobber FLAGS_REG.
16992(define_insn_and_split "*fist<mode>2_<rounding>_1"
16993  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16994	(unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16995			FIST_ROUNDING))
16996   (clobber (reg:CC FLAGS_REG))]
16997  "TARGET_USE_FANCY_MATH_387
16998   && flag_unsafe_math_optimizations
16999   && ix86_pre_reload_split ()"
17000  "#"
17001  "&& 1"
17002  [(const_int 0)]
17003{
17004  ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17005
17006  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17007  operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17008
17009  emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17010					 operands[2], operands[3]));
17011  DONE;
17012}
17013  [(set_attr "type" "fistp")
17014   (set_attr "i387_cw" "<rounding>")
17015   (set_attr "mode" "<MODE>")])
17016
17017(define_insn "fistdi2_<rounding>"
17018  [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
17019	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17020		   FIST_ROUNDING))
17021   (use (match_operand:HI 2 "memory_operand" "m"))
17022   (use (match_operand:HI 3 "memory_operand" "m"))
17023   (clobber (match_scratch:XF 4 "=&f"))]
17024  "TARGET_USE_FANCY_MATH_387
17025   && flag_unsafe_math_optimizations"
17026  "* return output_fix_trunc (insn, operands, false);"
17027  [(set_attr "type" "fistp")
17028   (set_attr "i387_cw" "<rounding>")
17029   (set_attr "mode" "DI")])
17030
17031(define_insn "fist<mode>2_<rounding>"
17032  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
17033	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17034		      FIST_ROUNDING))
17035   (use (match_operand:HI 2 "memory_operand" "m"))
17036   (use (match_operand:HI 3 "memory_operand" "m"))]
17037  "TARGET_USE_FANCY_MATH_387
17038   && flag_unsafe_math_optimizations"
17039  "* return output_fix_trunc (insn, operands, false);"
17040  [(set_attr "type" "fistp")
17041   (set_attr "i387_cw" "<rounding>")
17042   (set_attr "mode" "<MODE>")])
17043
17044(define_expand "l<rounding_insn>xf<mode>2"
17045  [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17046		   (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17047				   FIST_ROUNDING))
17048	      (clobber (reg:CC FLAGS_REG))])]
17049  "TARGET_USE_FANCY_MATH_387
17050   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17051   && flag_unsafe_math_optimizations")
17052
17053(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17054  [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17055		   (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17056				 FIST_ROUNDING))
17057	      (clobber (reg:CC FLAGS_REG))])]
17058  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17059   && (TARGET_SSE4_1 || !flag_trapping_math)"
17060{
17061  if (TARGET_SSE4_1)
17062    {
17063      rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
17064
17065      emit_insn (gen_sse4_1_round<MODEF:mode>2
17066		 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
17067					     | ROUND_NO_EXC)));
17068      emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
17069		 (operands[0], tmp));
17070    }
17071  else if (ROUND_<ROUNDING> == ROUND_FLOOR)
17072    ix86_expand_lfloorceil (operands[0], operands[1], true);
17073  else if (ROUND_<ROUNDING> == ROUND_CEIL)
17074    ix86_expand_lfloorceil (operands[0], operands[1], false);
17075  else
17076    gcc_unreachable ();
17077
17078  DONE;
17079})
17080
17081(define_insn "fxam<mode>2_i387"
17082  [(set (match_operand:HI 0 "register_operand" "=a")
17083	(unspec:HI
17084	  [(match_operand:X87MODEF 1 "register_operand" "f")]
17085	  UNSPEC_FXAM))]
17086  "TARGET_USE_FANCY_MATH_387"
17087  "fxam\n\tfnstsw\t%0"
17088  [(set_attr "type" "multi")
17089   (set_attr "length" "4")
17090   (set_attr "unit" "i387")
17091   (set_attr "mode" "<MODE>")])
17092
17093(define_expand "signbittf2"
17094  [(use (match_operand:SI 0 "register_operand"))
17095   (use (match_operand:TF 1 "register_operand"))]
17096  "TARGET_SSE"
17097{
17098  if (TARGET_SSE4_1)
17099    {
17100      rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17101      rtx scratch = gen_reg_rtx (QImode);
17102
17103      emit_insn (gen_ptesttf2 (operands[1], mask));
17104	ix86_expand_setcc (scratch, NE,
17105			   gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17106
17107      emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17108    }
17109  else
17110    {
17111      emit_insn (gen_sse_movmskps (operands[0],
17112				   gen_lowpart (V4SFmode, operands[1])));
17113      emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17114    }
17115  DONE;
17116})
17117
17118(define_expand "signbitxf2"
17119  [(use (match_operand:SI 0 "register_operand"))
17120   (use (match_operand:XF 1 "register_operand"))]
17121  "TARGET_USE_FANCY_MATH_387"
17122{
17123  rtx scratch = gen_reg_rtx (HImode);
17124
17125  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17126  emit_insn (gen_andsi3 (operands[0],
17127	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17128  DONE;
17129})
17130
17131(define_insn "movmsk_df"
17132  [(set (match_operand:SI 0 "register_operand" "=r")
17133	(unspec:SI
17134	  [(match_operand:DF 1 "register_operand" "x")]
17135	  UNSPEC_MOVMSK))]
17136  "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17137  "%vmovmskpd\t{%1, %0|%0, %1}"
17138  [(set_attr "type" "ssemov")
17139   (set_attr "prefix" "maybe_vex")
17140   (set_attr "mode" "DF")])
17141
17142;; Use movmskpd in SSE mode to avoid store forwarding stall
17143;; for 32bit targets and movq+shrq sequence for 64bit targets.
17144(define_expand "signbitdf2"
17145  [(use (match_operand:SI 0 "register_operand"))
17146   (use (match_operand:DF 1 "register_operand"))]
17147  "TARGET_USE_FANCY_MATH_387
17148   || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17149{
17150  if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17151    {
17152      emit_insn (gen_movmsk_df (operands[0], operands[1]));
17153      emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17154    }
17155  else
17156    {
17157      rtx scratch = gen_reg_rtx (HImode);
17158
17159      emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17160      emit_insn (gen_andsi3 (operands[0],
17161		 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17162    }
17163  DONE;
17164})
17165
17166(define_expand "signbitsf2"
17167  [(use (match_operand:SI 0 "register_operand"))
17168   (use (match_operand:SF 1 "register_operand"))]
17169  "TARGET_USE_FANCY_MATH_387
17170   && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17171{
17172  rtx scratch = gen_reg_rtx (HImode);
17173
17174  emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17175  emit_insn (gen_andsi3 (operands[0],
17176	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17177  DONE;
17178})
17179
17180;; Block operation instructions
17181
17182(define_insn "cld"
17183  [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17184  ""
17185  "cld"
17186  [(set_attr "length" "1")
17187   (set_attr "length_immediate" "0")
17188   (set_attr "modrm" "0")])
17189
17190(define_expand "cpymem<mode>"
17191  [(use (match_operand:BLK 0 "memory_operand"))
17192   (use (match_operand:BLK 1 "memory_operand"))
17193   (use (match_operand:SWI48 2 "nonmemory_operand"))
17194   (use (match_operand:SWI48 3 "const_int_operand"))
17195   (use (match_operand:SI 4 "const_int_operand"))
17196   (use (match_operand:SI 5 "const_int_operand"))
17197   (use (match_operand:SI 6 ""))
17198   (use (match_operand:SI 7 ""))
17199   (use (match_operand:SI 8 ""))]
17200  ""
17201{
17202 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
17203			        operands[2], NULL, operands[3],
17204			        operands[4], operands[5],
17205				operands[6], operands[7],
17206				operands[8], false))
17207   DONE;
17208 else
17209   FAIL;
17210})
17211
17212;; Most CPUs don't like single string operations
17213;; Handle this case here to simplify previous expander.
17214
17215(define_expand "strmov"
17216  [(set (match_dup 4) (match_operand 3 "memory_operand"))
17217   (set (match_operand 1 "memory_operand") (match_dup 4))
17218   (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17219	      (clobber (reg:CC FLAGS_REG))])
17220   (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17221	      (clobber (reg:CC FLAGS_REG))])]
17222  ""
17223{
17224  /* Can't use this for non-default address spaces.  */
17225  if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17226    FAIL;
17227
17228  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17229
17230  /* If .md ever supports :P for Pmode, these can be directly
17231     in the pattern above.  */
17232  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17233  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17234
17235  /* Can't use this if the user has appropriated esi or edi.  */
17236  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17237      && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17238    {
17239      emit_insn (gen_strmov_singleop (operands[0], operands[1],
17240				      operands[2], operands[3],
17241				      operands[5], operands[6]));
17242      DONE;
17243    }
17244
17245  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17246})
17247
17248(define_expand "strmov_singleop"
17249  [(parallel [(set (match_operand 1 "memory_operand")
17250		   (match_operand 3 "memory_operand"))
17251	      (set (match_operand 0 "register_operand")
17252		   (match_operand 4))
17253	      (set (match_operand 2 "register_operand")
17254		   (match_operand 5))])]
17255  ""
17256{
17257  if (TARGET_CLD)
17258    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17259})
17260
17261(define_insn "*strmovdi_rex_1"
17262  [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17263	(mem:DI (match_operand:P 3 "register_operand" "1")))
17264   (set (match_operand:P 0 "register_operand" "=D")
17265	(plus:P (match_dup 2)
17266		(const_int 8)))
17267   (set (match_operand:P 1 "register_operand" "=S")
17268	(plus:P (match_dup 3)
17269		(const_int 8)))]
17270  "TARGET_64BIT
17271   && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17272   && ix86_check_no_addr_space (insn)"
17273  "%^movsq"
17274  [(set_attr "type" "str")
17275   (set_attr "memory" "both")
17276   (set_attr "mode" "DI")])
17277
17278(define_insn "*strmovsi_1"
17279  [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17280	(mem:SI (match_operand:P 3 "register_operand" "1")))
17281   (set (match_operand:P 0 "register_operand" "=D")
17282	(plus:P (match_dup 2)
17283		(const_int 4)))
17284   (set (match_operand:P 1 "register_operand" "=S")
17285	(plus:P (match_dup 3)
17286		(const_int 4)))]
17287  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17288   && ix86_check_no_addr_space (insn)"
17289  "%^movs{l|d}"
17290  [(set_attr "type" "str")
17291   (set_attr "memory" "both")
17292   (set_attr "mode" "SI")])
17293
17294(define_insn "*strmovhi_1"
17295  [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17296	(mem:HI (match_operand:P 3 "register_operand" "1")))
17297   (set (match_operand:P 0 "register_operand" "=D")
17298	(plus:P (match_dup 2)
17299		(const_int 2)))
17300   (set (match_operand:P 1 "register_operand" "=S")
17301	(plus:P (match_dup 3)
17302		(const_int 2)))]
17303  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17304   && ix86_check_no_addr_space (insn)"
17305  "%^movsw"
17306  [(set_attr "type" "str")
17307   (set_attr "memory" "both")
17308   (set_attr "mode" "HI")])
17309
17310(define_insn "*strmovqi_1"
17311  [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17312	(mem:QI (match_operand:P 3 "register_operand" "1")))
17313   (set (match_operand:P 0 "register_operand" "=D")
17314	(plus:P (match_dup 2)
17315		(const_int 1)))
17316   (set (match_operand:P 1 "register_operand" "=S")
17317	(plus:P (match_dup 3)
17318		(const_int 1)))]
17319  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17320   && ix86_check_no_addr_space (insn)"
17321  "%^movsb"
17322  [(set_attr "type" "str")
17323   (set_attr "memory" "both")
17324   (set (attr "prefix_rex")
17325	(if_then_else
17326	  (match_test "<P:MODE>mode == DImode")
17327	  (const_string "0")
17328	  (const_string "*")))
17329   (set_attr "mode" "QI")])
17330
17331(define_expand "rep_mov"
17332  [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17333	      (set (match_operand 0 "register_operand")
17334		   (match_operand 5))
17335	      (set (match_operand 2 "register_operand")
17336		   (match_operand 6))
17337	      (set (match_operand 1 "memory_operand")
17338		   (match_operand 3 "memory_operand"))
17339	      (use (match_dup 4))])]
17340  ""
17341{
17342  if (TARGET_CLD)
17343    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17344})
17345
17346(define_insn "*rep_movdi_rex64"
17347  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17348   (set (match_operand:P 0 "register_operand" "=D")
17349        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17350			  (const_int 3))
17351		(match_operand:P 3 "register_operand" "0")))
17352   (set (match_operand:P 1 "register_operand" "=S")
17353        (plus:P (ashift:P (match_dup 5) (const_int 3))
17354		(match_operand:P 4 "register_operand" "1")))
17355   (set (mem:BLK (match_dup 3))
17356	(mem:BLK (match_dup 4)))
17357   (use (match_dup 5))]
17358  "TARGET_64BIT
17359   && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17360   && ix86_check_no_addr_space (insn)"
17361  "%^rep{%;} movsq"
17362  [(set_attr "type" "str")
17363   (set_attr "prefix_rep" "1")
17364   (set_attr "memory" "both")
17365   (set_attr "mode" "DI")])
17366
17367(define_insn "*rep_movsi"
17368  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17369   (set (match_operand:P 0 "register_operand" "=D")
17370        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17371			  (const_int 2))
17372		 (match_operand:P 3 "register_operand" "0")))
17373   (set (match_operand:P 1 "register_operand" "=S")
17374        (plus:P (ashift:P (match_dup 5) (const_int 2))
17375		(match_operand:P 4 "register_operand" "1")))
17376   (set (mem:BLK (match_dup 3))
17377	(mem:BLK (match_dup 4)))
17378   (use (match_dup 5))]
17379  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17380   && ix86_check_no_addr_space (insn)"
17381  "%^rep{%;} movs{l|d}"
17382  [(set_attr "type" "str")
17383   (set_attr "prefix_rep" "1")
17384   (set_attr "memory" "both")
17385   (set_attr "mode" "SI")])
17386
17387(define_insn "*rep_movqi"
17388  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17389   (set (match_operand:P 0 "register_operand" "=D")
17390        (plus:P (match_operand:P 3 "register_operand" "0")
17391		(match_operand:P 5 "register_operand" "2")))
17392   (set (match_operand:P 1 "register_operand" "=S")
17393        (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17394   (set (mem:BLK (match_dup 3))
17395	(mem:BLK (match_dup 4)))
17396   (use (match_dup 5))]
17397  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17398   && ix86_check_no_addr_space (insn)"
17399  "%^rep{%;} movsb"
17400  [(set_attr "type" "str")
17401   (set_attr "prefix_rep" "1")
17402   (set_attr "memory" "both")
17403   (set_attr "mode" "QI")])
17404
17405(define_expand "setmem<mode>"
17406   [(use (match_operand:BLK 0 "memory_operand"))
17407    (use (match_operand:SWI48 1 "nonmemory_operand"))
17408    (use (match_operand:QI 2 "nonmemory_operand"))
17409    (use (match_operand 3 "const_int_operand"))
17410    (use (match_operand:SI 4 "const_int_operand"))
17411    (use (match_operand:SI 5 "const_int_operand"))
17412    (use (match_operand:SI 6 ""))
17413    (use (match_operand:SI 7 ""))
17414    (use (match_operand:SI 8 ""))]
17415  ""
17416{
17417 if (ix86_expand_set_or_cpymem (operands[0], NULL,
17418			        operands[1], operands[2],
17419				operands[3], operands[4],
17420			        operands[5], operands[6],
17421				operands[7], operands[8], true))
17422   DONE;
17423 else
17424   FAIL;
17425})
17426
17427;; Most CPUs don't like single string operations
17428;; Handle this case here to simplify previous expander.
17429
17430(define_expand "strset"
17431  [(set (match_operand 1 "memory_operand")
17432	(match_operand 2 "register_operand"))
17433   (parallel [(set (match_operand 0 "register_operand")
17434		   (match_dup 3))
17435	      (clobber (reg:CC FLAGS_REG))])]
17436  ""
17437{
17438  /* Can't use this for non-default address spaces.  */
17439  if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17440    FAIL;
17441
17442  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17443    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17444
17445  /* If .md ever supports :P for Pmode, this can be directly
17446     in the pattern above.  */
17447  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17448			      GEN_INT (GET_MODE_SIZE (GET_MODE
17449						      (operands[2]))));
17450  /* Can't use this if the user has appropriated eax or edi.  */
17451  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17452      && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17453    {
17454      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17455				      operands[3]));
17456      DONE;
17457    }
17458})
17459
17460(define_expand "strset_singleop"
17461  [(parallel [(set (match_operand 1 "memory_operand")
17462		   (match_operand 2 "register_operand"))
17463	      (set (match_operand 0 "register_operand")
17464		   (match_operand 3))
17465	      (unspec [(const_int 0)] UNSPEC_STOS)])]
17466  ""
17467{
17468  if (TARGET_CLD)
17469    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17470})
17471
17472(define_insn "*strsetdi_rex_1"
17473  [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17474	(match_operand:DI 2 "register_operand" "a"))
17475   (set (match_operand:P 0 "register_operand" "=D")
17476	(plus:P (match_dup 1)
17477		(const_int 8)))
17478   (unspec [(const_int 0)] UNSPEC_STOS)]
17479  "TARGET_64BIT
17480   && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17481   && ix86_check_no_addr_space (insn)"
17482  "%^stosq"
17483  [(set_attr "type" "str")
17484   (set_attr "memory" "store")
17485   (set_attr "mode" "DI")])
17486
17487(define_insn "*strsetsi_1"
17488  [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17489	(match_operand:SI 2 "register_operand" "a"))
17490   (set (match_operand:P 0 "register_operand" "=D")
17491	(plus:P (match_dup 1)
17492		(const_int 4)))
17493   (unspec [(const_int 0)] UNSPEC_STOS)]
17494  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17495   && ix86_check_no_addr_space (insn)"
17496  "%^stos{l|d}"
17497  [(set_attr "type" "str")
17498   (set_attr "memory" "store")
17499   (set_attr "mode" "SI")])
17500
17501(define_insn "*strsethi_1"
17502  [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17503	(match_operand:HI 2 "register_operand" "a"))
17504   (set (match_operand:P 0 "register_operand" "=D")
17505	(plus:P (match_dup 1)
17506		(const_int 2)))
17507   (unspec [(const_int 0)] UNSPEC_STOS)]
17508  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17509   && ix86_check_no_addr_space (insn)"
17510  "%^stosw"
17511  [(set_attr "type" "str")
17512   (set_attr "memory" "store")
17513   (set_attr "mode" "HI")])
17514
17515(define_insn "*strsetqi_1"
17516  [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17517	(match_operand:QI 2 "register_operand" "a"))
17518   (set (match_operand:P 0 "register_operand" "=D")
17519	(plus:P (match_dup 1)
17520		(const_int 1)))
17521   (unspec [(const_int 0)] UNSPEC_STOS)]
17522  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17523   && ix86_check_no_addr_space (insn)"
17524  "%^stosb"
17525  [(set_attr "type" "str")
17526   (set_attr "memory" "store")
17527   (set (attr "prefix_rex")
17528	(if_then_else
17529	  (match_test "<P:MODE>mode == DImode")
17530	  (const_string "0")
17531	  (const_string "*")))
17532   (set_attr "mode" "QI")])
17533
17534(define_expand "rep_stos"
17535  [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17536	      (set (match_operand 0 "register_operand")
17537		   (match_operand 4))
17538	      (set (match_operand 2 "memory_operand") (const_int 0))
17539	      (use (match_operand 3 "register_operand"))
17540	      (use (match_dup 1))])]
17541  ""
17542{
17543  if (TARGET_CLD)
17544    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17545})
17546
17547(define_insn "*rep_stosdi_rex64"
17548  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17549   (set (match_operand:P 0 "register_operand" "=D")
17550        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17551			  (const_int 3))
17552		 (match_operand:P 3 "register_operand" "0")))
17553   (set (mem:BLK (match_dup 3))
17554	(const_int 0))
17555   (use (match_operand:DI 2 "register_operand" "a"))
17556   (use (match_dup 4))]
17557  "TARGET_64BIT
17558   && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17559   && ix86_check_no_addr_space (insn)"
17560  "%^rep{%;} stosq"
17561  [(set_attr "type" "str")
17562   (set_attr "prefix_rep" "1")
17563   (set_attr "memory" "store")
17564   (set_attr "mode" "DI")])
17565
17566(define_insn "*rep_stossi"
17567  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17568   (set (match_operand:P 0 "register_operand" "=D")
17569        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17570			  (const_int 2))
17571		 (match_operand:P 3 "register_operand" "0")))
17572   (set (mem:BLK (match_dup 3))
17573	(const_int 0))
17574   (use (match_operand:SI 2 "register_operand" "a"))
17575   (use (match_dup 4))]
17576  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17577   && ix86_check_no_addr_space (insn)"
17578  "%^rep{%;} stos{l|d}"
17579  [(set_attr "type" "str")
17580   (set_attr "prefix_rep" "1")
17581   (set_attr "memory" "store")
17582   (set_attr "mode" "SI")])
17583
17584(define_insn "*rep_stosqi"
17585  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17586   (set (match_operand:P 0 "register_operand" "=D")
17587        (plus:P (match_operand:P 3 "register_operand" "0")
17588		(match_operand:P 4 "register_operand" "1")))
17589   (set (mem:BLK (match_dup 3))
17590	(const_int 0))
17591   (use (match_operand:QI 2 "register_operand" "a"))
17592   (use (match_dup 4))]
17593  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17594   && ix86_check_no_addr_space (insn)"
17595  "%^rep{%;} stosb"
17596  [(set_attr "type" "str")
17597   (set_attr "prefix_rep" "1")
17598   (set_attr "memory" "store")
17599   (set (attr "prefix_rex")
17600	(if_then_else
17601	  (match_test "<P:MODE>mode == DImode")
17602	  (const_string "0")
17603	  (const_string "*")))
17604   (set_attr "mode" "QI")])
17605
17606(define_expand "cmpstrnsi"
17607  [(set (match_operand:SI 0 "register_operand")
17608	(compare:SI (match_operand:BLK 1 "general_operand")
17609		    (match_operand:BLK 2 "general_operand")))
17610   (use (match_operand 3 "general_operand"))
17611   (use (match_operand 4 "immediate_operand"))]
17612  ""
17613{
17614  rtx addr1, addr2, countreg, align, out;
17615
17616  if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17617    FAIL;
17618
17619  /* Can't use this if the user has appropriated ecx, esi or edi.  */
17620  if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17621    FAIL;
17622
17623  /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
17624     will have rewritten the length arg to be the minimum of the const string
17625     length and the actual length arg.  If both strings are the same and
17626     shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17627     will incorrectly base the results on chars past the 0 byte.  */
17628  tree t1 = MEM_EXPR (operands[1]);
17629  tree t2 = MEM_EXPR (operands[2]);
17630  if (!((t1 && TREE_CODE (t1) == MEM_REF
17631         && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17632         && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17633      || (t2 && TREE_CODE (t2) == MEM_REF
17634          && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17635          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17636    FAIL;
17637
17638  addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17639  addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17640  if (addr1 != XEXP (operands[1], 0))
17641    operands[1] = replace_equiv_address_nv (operands[1], addr1);
17642  if (addr2 != XEXP (operands[2], 0))
17643    operands[2] = replace_equiv_address_nv (operands[2], addr2);
17644
17645  countreg = ix86_zero_extend_to_Pmode (operands[3]);
17646
17647  /* %%% Iff we are testing strict equality, we can use known alignment
17648     to good advantage.  This may be possible with combine, particularly
17649     once cc0 is dead.  */
17650  align = operands[4];
17651
17652  if (CONST_INT_P (operands[3]))
17653    {
17654      if (operands[3] == const0_rtx)
17655	{
17656	  emit_move_insn (operands[0], const0_rtx);
17657	  DONE;
17658	}
17659      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17660				     operands[1], operands[2]));
17661    }
17662  else
17663    {
17664      emit_insn (gen_cmp_1 (Pmode, countreg, countreg));
17665      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17666				  operands[1], operands[2]));
17667    }
17668
17669  out = gen_lowpart (QImode, operands[0]);
17670  emit_insn (gen_cmpintqi (out));
17671  emit_move_insn (operands[0], gen_rtx_SIGN_EXTEND (SImode, out));
17672
17673  DONE;
17674})
17675
17676;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17677
17678(define_expand "cmpintqi"
17679  [(set (match_dup 1)
17680	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17681   (set (match_dup 2)
17682	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17683   (parallel [(set (match_operand:QI 0 "register_operand")
17684		   (minus:QI (match_dup 1)
17685			     (match_dup 2)))
17686	      (clobber (reg:CC FLAGS_REG))])]
17687  ""
17688{
17689  operands[1] = gen_reg_rtx (QImode);
17690  operands[2] = gen_reg_rtx (QImode);
17691})
17692
17693;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17694;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17695
17696(define_expand "cmpstrnqi_nz_1"
17697  [(parallel [(set (reg:CC FLAGS_REG)
17698		   (compare:CC (match_operand 4 "memory_operand")
17699			       (match_operand 5 "memory_operand")))
17700	      (use (match_operand 2 "register_operand"))
17701	      (use (match_operand:SI 3 "immediate_operand"))
17702	      (clobber (match_operand 0 "register_operand"))
17703	      (clobber (match_operand 1 "register_operand"))
17704	      (clobber (match_dup 2))])]
17705  ""
17706{
17707  if (TARGET_CLD)
17708    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17709})
17710
17711(define_insn "*cmpstrnqi_nz_1"
17712  [(set (reg:CC FLAGS_REG)
17713	(compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17714		    (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17715   (use (match_operand:P 6 "register_operand" "2"))
17716   (use (match_operand:SI 3 "immediate_operand" "i"))
17717   (clobber (match_operand:P 0 "register_operand" "=S"))
17718   (clobber (match_operand:P 1 "register_operand" "=D"))
17719   (clobber (match_operand:P 2 "register_operand" "=c"))]
17720  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17721   && ix86_check_no_addr_space (insn)"
17722  "%^repz{%;} cmpsb"
17723  [(set_attr "type" "str")
17724   (set_attr "mode" "QI")
17725   (set (attr "prefix_rex")
17726	(if_then_else
17727	  (match_test "<P:MODE>mode == DImode")
17728	  (const_string "0")
17729	  (const_string "*")))
17730   (set_attr "prefix_rep" "1")])
17731
17732;; The same, but the count is not known to not be zero.
17733
17734(define_expand "cmpstrnqi_1"
17735  [(parallel [(set (reg:CC FLAGS_REG)
17736		(if_then_else:CC (ne (match_operand 2 "register_operand")
17737				     (const_int 0))
17738		  (compare:CC (match_operand 4 "memory_operand")
17739			      (match_operand 5 "memory_operand"))
17740		  (const_int 0)))
17741	      (use (match_operand:SI 3 "immediate_operand"))
17742	      (use (reg:CC FLAGS_REG))
17743	      (clobber (match_operand 0 "register_operand"))
17744	      (clobber (match_operand 1 "register_operand"))
17745	      (clobber (match_dup 2))])]
17746  ""
17747{
17748  if (TARGET_CLD)
17749    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17750})
17751
17752(define_insn "*cmpstrnqi_1"
17753  [(set (reg:CC FLAGS_REG)
17754	(if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17755			     (const_int 0))
17756	  (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17757		      (mem:BLK (match_operand:P 5 "register_operand" "1")))
17758	  (const_int 0)))
17759   (use (match_operand:SI 3 "immediate_operand" "i"))
17760   (use (reg:CC FLAGS_REG))
17761   (clobber (match_operand:P 0 "register_operand" "=S"))
17762   (clobber (match_operand:P 1 "register_operand" "=D"))
17763   (clobber (match_operand:P 2 "register_operand" "=c"))]
17764  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17765   && ix86_check_no_addr_space (insn)"
17766  "%^repz{%;} cmpsb"
17767  [(set_attr "type" "str")
17768   (set_attr "mode" "QI")
17769   (set (attr "prefix_rex")
17770	(if_then_else
17771	  (match_test "<P:MODE>mode == DImode")
17772	  (const_string "0")
17773	  (const_string "*")))
17774   (set_attr "prefix_rep" "1")])
17775
17776(define_expand "strlen<mode>"
17777  [(set (match_operand:P 0 "register_operand")
17778	(unspec:P [(match_operand:BLK 1 "general_operand")
17779		   (match_operand:QI 2 "immediate_operand")
17780		   (match_operand 3 "immediate_operand")]
17781		  UNSPEC_SCAS))]
17782  ""
17783{
17784 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17785   DONE;
17786 else
17787   FAIL;
17788})
17789
17790(define_expand "strlenqi_1"
17791  [(parallel [(set (match_operand 0 "register_operand")
17792		   (match_operand 2))
17793	      (clobber (match_operand 1 "register_operand"))
17794	      (clobber (reg:CC FLAGS_REG))])]
17795  ""
17796{
17797  if (TARGET_CLD)
17798    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17799})
17800
17801(define_insn "*strlenqi_1"
17802  [(set (match_operand:P 0 "register_operand" "=&c")
17803	(unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17804		   (match_operand:QI 2 "register_operand" "a")
17805		   (match_operand:P 3 "immediate_operand" "i")
17806		   (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17807   (clobber (match_operand:P 1 "register_operand" "=D"))
17808   (clobber (reg:CC FLAGS_REG))]
17809  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17810   && ix86_check_no_addr_space (insn)"
17811  "%^repnz{%;} scasb"
17812  [(set_attr "type" "str")
17813   (set_attr "mode" "QI")
17814   (set (attr "prefix_rex")
17815	(if_then_else
17816	  (match_test "<P:MODE>mode == DImode")
17817	  (const_string "0")
17818	  (const_string "*")))
17819   (set_attr "prefix_rep" "1")])
17820
17821;; Peephole optimizations to clean up after cmpstrn*.  This should be
17822;; handled in combine, but it is not currently up to the task.
17823;; When used for their truth value, the cmpstrn* expanders generate
17824;; code like this:
17825;;
17826;;   repz cmpsb
17827;;   seta 	%al
17828;;   setb 	%dl
17829;;   cmpb 	%al, %dl
17830;;   jcc	label
17831;;
17832;; The intermediate three instructions are unnecessary.
17833
17834;; This one handles cmpstrn*_nz_1...
17835(define_peephole2
17836  [(parallel[
17837     (set (reg:CC FLAGS_REG)
17838	  (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17839		      (mem:BLK (match_operand 5 "register_operand"))))
17840     (use (match_operand 6 "register_operand"))
17841     (use (match_operand:SI 3 "immediate_operand"))
17842     (clobber (match_operand 0 "register_operand"))
17843     (clobber (match_operand 1 "register_operand"))
17844     (clobber (match_operand 2 "register_operand"))])
17845   (set (match_operand:QI 7 "register_operand")
17846	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17847   (set (match_operand:QI 8 "register_operand")
17848	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17849   (set (reg FLAGS_REG)
17850	(compare (match_dup 7) (match_dup 8)))
17851  ]
17852  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17853  [(parallel[
17854     (set (reg:CC FLAGS_REG)
17855	  (compare:CC (mem:BLK (match_dup 4))
17856		      (mem:BLK (match_dup 5))))
17857     (use (match_dup 6))
17858     (use (match_dup 3))
17859     (clobber (match_dup 0))
17860     (clobber (match_dup 1))
17861     (clobber (match_dup 2))])])
17862
17863;; ...and this one handles cmpstrn*_1.
17864(define_peephole2
17865  [(parallel[
17866     (set (reg:CC FLAGS_REG)
17867	  (if_then_else:CC (ne (match_operand 6 "register_operand")
17868			       (const_int 0))
17869	    (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17870		        (mem:BLK (match_operand 5 "register_operand")))
17871	    (const_int 0)))
17872     (use (match_operand:SI 3 "immediate_operand"))
17873     (use (reg:CC FLAGS_REG))
17874     (clobber (match_operand 0 "register_operand"))
17875     (clobber (match_operand 1 "register_operand"))
17876     (clobber (match_operand 2 "register_operand"))])
17877   (set (match_operand:QI 7 "register_operand")
17878	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17879   (set (match_operand:QI 8 "register_operand")
17880	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17881   (set (reg FLAGS_REG)
17882	(compare (match_dup 7) (match_dup 8)))
17883  ]
17884  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17885  [(parallel[
17886     (set (reg:CC FLAGS_REG)
17887	  (if_then_else:CC (ne (match_dup 6)
17888			       (const_int 0))
17889	    (compare:CC (mem:BLK (match_dup 4))
17890			(mem:BLK (match_dup 5)))
17891	    (const_int 0)))
17892     (use (match_dup 3))
17893     (use (reg:CC FLAGS_REG))
17894     (clobber (match_dup 0))
17895     (clobber (match_dup 1))
17896     (clobber (match_dup 2))])])
17897
17898;; Conditional move instructions.
17899
17900(define_expand "mov<mode>cc"
17901  [(set (match_operand:SWIM 0 "register_operand")
17902	(if_then_else:SWIM (match_operand 1 "comparison_operator")
17903			   (match_operand:SWIM 2 "<general_operand>")
17904			   (match_operand:SWIM 3 "<general_operand>")))]
17905  ""
17906  "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17907
17908;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17909;; the register first winds up with `sbbl $0,reg', which is also weird.
17910;; So just document what we're doing explicitly.
17911
17912(define_expand "x86_mov<mode>cc_0_m1"
17913  [(parallel
17914    [(set (match_operand:SWI48 0 "register_operand")
17915	  (if_then_else:SWI48
17916	    (match_operator:SWI48 2 "ix86_carry_flag_operator"
17917	     [(match_operand 1 "flags_reg_operand")
17918	      (const_int 0)])
17919	    (const_int -1)
17920	    (const_int 0)))
17921     (clobber (reg:CC FLAGS_REG))])])
17922
17923(define_insn "*x86_mov<mode>cc_0_m1"
17924  [(set (match_operand:SWI48 0 "register_operand" "=r")
17925	(if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17926			     [(reg FLAGS_REG) (const_int 0)])
17927	  (const_int -1)
17928	  (const_int 0)))
17929   (clobber (reg:CC FLAGS_REG))]
17930  ""
17931  "sbb{<imodesuffix>}\t%0, %0"
17932  [(set_attr "type" "alu1")
17933   (set_attr "use_carry" "1")
17934   (set_attr "pent_pair" "pu")
17935   (set_attr "mode" "<MODE>")
17936   (set_attr "length_immediate" "0")])
17937
17938(define_insn "*x86_mov<mode>cc_0_m1_se"
17939  [(set (match_operand:SWI48 0 "register_operand" "=r")
17940	(sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17941			     [(reg FLAGS_REG) (const_int 0)])
17942			    (const_int 1)
17943			    (const_int 0)))
17944   (clobber (reg:CC FLAGS_REG))]
17945  ""
17946  "sbb{<imodesuffix>}\t%0, %0"
17947  [(set_attr "type" "alu1")
17948   (set_attr "use_carry" "1")
17949   (set_attr "pent_pair" "pu")
17950   (set_attr "mode" "<MODE>")
17951   (set_attr "length_immediate" "0")])
17952
17953(define_insn "*x86_mov<mode>cc_0_m1_neg"
17954  [(set (match_operand:SWI48 0 "register_operand" "=r")
17955	(neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17956		    [(reg FLAGS_REG) (const_int 0)])))
17957   (clobber (reg:CC FLAGS_REG))]
17958  ""
17959  "sbb{<imodesuffix>}\t%0, %0"
17960  [(set_attr "type" "alu1")
17961   (set_attr "use_carry" "1")
17962   (set_attr "pent_pair" "pu")
17963   (set_attr "mode" "<MODE>")
17964   (set_attr "length_immediate" "0")])
17965
17966(define_insn_and_split "*x86_mov<SWI48:mode>cc_0_m1_neg_leu<SWI:mode>"
17967  [(set (match_operand:SWI48 0 "register_operand" "=r")
17968	(neg:SWI48
17969	  (leu:SWI48
17970	    (match_operand:SWI 1 "nonimmediate_operand" "<SWI:r>m")
17971	    (match_operand:SWI 2 "<SWI:immediate_operand>" "<SWI:i>"))))
17972   (clobber (reg:CC FLAGS_REG))]
17973  "CONST_INT_P (operands[2])
17974   && INTVAL (operands[2]) != -1
17975   && INTVAL (operands[2]) != 2147483647"
17976  "#"
17977  ""
17978  [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
17979   (parallel [(set (match_dup 0)
17980		   (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
17981	      (clobber (reg:CC FLAGS_REG))])]
17982  "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
17983
17984(define_insn "*mov<mode>cc_noc"
17985  [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17986	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17987			       [(reg FLAGS_REG) (const_int 0)])
17988	  (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17989	  (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17990  "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17991  "@
17992   cmov%O2%C1\t{%2, %0|%0, %2}
17993   cmov%O2%c1\t{%3, %0|%0, %3}"
17994  [(set_attr "type" "icmov")
17995   (set_attr "mode" "<MODE>")])
17996
17997(define_insn "*movsicc_noc_zext"
17998  [(set (match_operand:DI 0 "register_operand" "=r,r")
17999	(if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18000			   [(reg FLAGS_REG) (const_int 0)])
18001	  (zero_extend:DI
18002	    (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18003	  (zero_extend:DI
18004	    (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18005  "TARGET_64BIT
18006   && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18007  "@
18008   cmov%O2%C1\t{%2, %k0|%k0, %2}
18009   cmov%O2%c1\t{%3, %k0|%k0, %3}"
18010  [(set_attr "type" "icmov")
18011   (set_attr "mode" "SI")])
18012
18013;; Don't do conditional moves with memory inputs.  This splitter helps
18014;; register starved x86_32 by forcing inputs into registers before reload.
18015(define_split
18016  [(set (match_operand:SWI248 0 "register_operand")
18017	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18018			       [(reg FLAGS_REG) (const_int 0)])
18019	  (match_operand:SWI248 2 "nonimmediate_operand")
18020	  (match_operand:SWI248 3 "nonimmediate_operand")))]
18021  "!TARGET_64BIT && TARGET_CMOVE
18022   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18023   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18024   && can_create_pseudo_p ()
18025   && optimize_insn_for_speed_p ()"
18026  [(set (match_dup 0)
18027	(if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18028{
18029  if (MEM_P (operands[2]))
18030    operands[2] = force_reg (<MODE>mode, operands[2]);
18031  if (MEM_P (operands[3]))
18032    operands[3] = force_reg (<MODE>mode, operands[3]);
18033})
18034
18035(define_insn "*movqicc_noc"
18036  [(set (match_operand:QI 0 "register_operand" "=r,r")
18037	(if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18038			   [(reg FLAGS_REG) (const_int 0)])
18039		      (match_operand:QI 2 "register_operand" "r,0")
18040		      (match_operand:QI 3 "register_operand" "0,r")))]
18041  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18042  "#"
18043  [(set_attr "type" "icmov")
18044   (set_attr "mode" "QI")])
18045
18046(define_split
18047  [(set (match_operand:SWI12 0 "register_operand")
18048	(if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18049			      [(reg FLAGS_REG) (const_int 0)])
18050		      (match_operand:SWI12 2 "register_operand")
18051		      (match_operand:SWI12 3 "register_operand")))]
18052  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18053   && reload_completed"
18054  [(set (match_dup 0)
18055	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18056{
18057  operands[0] = gen_lowpart (SImode, operands[0]);
18058  operands[2] = gen_lowpart (SImode, operands[2]);
18059  operands[3] = gen_lowpart (SImode, operands[3]);
18060})
18061
18062;; Don't do conditional moves with memory inputs
18063(define_peephole2
18064  [(match_scratch:SWI248 4 "r")
18065   (set (match_operand:SWI248 0 "register_operand")
18066	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18067			       [(reg FLAGS_REG) (const_int 0)])
18068	  (match_operand:SWI248 2 "nonimmediate_operand")
18069	  (match_operand:SWI248 3 "nonimmediate_operand")))]
18070  "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18071   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18072   && optimize_insn_for_speed_p ()"
18073  [(set (match_dup 4) (match_dup 5))
18074   (set (match_dup 0)
18075	(if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18076{
18077  if (MEM_P (operands[2]))
18078    {
18079      operands[5] = operands[2];
18080      operands[2] = operands[4];
18081    }
18082  else if (MEM_P (operands[3]))
18083    {
18084      operands[5] = operands[3];
18085      operands[3] = operands[4];
18086    }
18087  else
18088    gcc_unreachable ();
18089})
18090
18091(define_peephole2
18092  [(match_scratch:SI 4 "r")
18093   (set (match_operand:DI 0 "register_operand")
18094	(if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18095			   [(reg FLAGS_REG) (const_int 0)])
18096	  (zero_extend:DI
18097	    (match_operand:SI 2 "nonimmediate_operand"))
18098	  (zero_extend:DI
18099	    (match_operand:SI 3 "nonimmediate_operand"))))]
18100  "TARGET_64BIT
18101   && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18102   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18103   && optimize_insn_for_speed_p ()"
18104  [(set (match_dup 4) (match_dup 5))
18105   (set (match_dup 0)
18106	(if_then_else:DI (match_dup 1)
18107	  (zero_extend:DI (match_dup 2))
18108	  (zero_extend:DI (match_dup 3))))]
18109{
18110  if (MEM_P (operands[2]))
18111    {
18112      operands[5] = operands[2];
18113      operands[2] = operands[4];
18114    }
18115  else if (MEM_P (operands[3]))
18116    {
18117      operands[5] = operands[3];
18118      operands[3] = operands[4];
18119    }
18120  else
18121    gcc_unreachable ();
18122})
18123
18124(define_expand "mov<mode>cc"
18125  [(set (match_operand:X87MODEF 0 "register_operand")
18126	(if_then_else:X87MODEF
18127	  (match_operand 1 "comparison_operator")
18128	  (match_operand:X87MODEF 2 "register_operand")
18129	  (match_operand:X87MODEF 3 "register_operand")))]
18130  "(TARGET_80387 && TARGET_CMOVE)
18131   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18132  "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18133
18134(define_insn "*movxfcc_1"
18135  [(set (match_operand:XF 0 "register_operand" "=f,f")
18136	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18137				[(reg FLAGS_REG) (const_int 0)])
18138		      (match_operand:XF 2 "register_operand" "f,0")
18139		      (match_operand:XF 3 "register_operand" "0,f")))]
18140  "TARGET_80387 && TARGET_CMOVE"
18141  "@
18142   fcmov%F1\t{%2, %0|%0, %2}
18143   fcmov%f1\t{%3, %0|%0, %3}"
18144  [(set_attr "type" "fcmov")
18145   (set_attr "mode" "XF")])
18146
18147(define_insn "*movdfcc_1"
18148  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18149	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18150				[(reg FLAGS_REG) (const_int 0)])
18151		      (match_operand:DF 2 "nonimmediate_operand"
18152					       "f ,0,rm,0 ,rm,0")
18153		      (match_operand:DF 3 "nonimmediate_operand"
18154					       "0 ,f,0 ,rm,0, rm")))]
18155  "TARGET_80387 && TARGET_CMOVE
18156   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18157  "@
18158   fcmov%F1\t{%2, %0|%0, %2}
18159   fcmov%f1\t{%3, %0|%0, %3}
18160   #
18161   #
18162   cmov%O2%C1\t{%2, %0|%0, %2}
18163   cmov%O2%c1\t{%3, %0|%0, %3}"
18164  [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18165   (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18166   (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18167
18168(define_split
18169  [(set (match_operand:DF 0 "general_reg_operand")
18170	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18171				[(reg FLAGS_REG) (const_int 0)])
18172		      (match_operand:DF 2 "nonimmediate_operand")
18173		      (match_operand:DF 3 "nonimmediate_operand")))]
18174  "!TARGET_64BIT && reload_completed"
18175  [(set (match_dup 2)
18176	(if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18177   (set (match_dup 3)
18178	(if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18179{
18180  split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18181  split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18182})
18183
18184(define_insn "*movsfcc_1_387"
18185  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18186	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18187				[(reg FLAGS_REG) (const_int 0)])
18188		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18189		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18190  "TARGET_80387 && TARGET_CMOVE
18191   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18192  "@
18193   fcmov%F1\t{%2, %0|%0, %2}
18194   fcmov%f1\t{%3, %0|%0, %3}
18195   cmov%O2%C1\t{%2, %0|%0, %2}
18196   cmov%O2%c1\t{%3, %0|%0, %3}"
18197  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18198   (set_attr "mode" "SF,SF,SI,SI")])
18199
18200;; Don't do conditional moves with memory inputs.  This splitter helps
18201;; register starved x86_32 by forcing inputs into registers before reload.
18202(define_split
18203  [(set (match_operand:MODEF 0 "register_operand")
18204	(if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18205			      [(reg FLAGS_REG) (const_int 0)])
18206	  (match_operand:MODEF 2 "nonimmediate_operand")
18207	  (match_operand:MODEF 3 "nonimmediate_operand")))]
18208  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18209   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18210   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18211   && can_create_pseudo_p ()
18212   && optimize_insn_for_speed_p ()"
18213  [(set (match_dup 0)
18214	(if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18215{
18216  if (MEM_P (operands[2]))
18217    operands[2] = force_reg (<MODE>mode, operands[2]);
18218  if (MEM_P (operands[3]))
18219    operands[3] = force_reg (<MODE>mode, operands[3]);
18220})
18221
18222;; Don't do conditional moves with memory inputs
18223(define_peephole2
18224  [(match_scratch:MODEF 4 "r")
18225   (set (match_operand:MODEF 0 "general_reg_operand")
18226	(if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18227			      [(reg FLAGS_REG) (const_int 0)])
18228	  (match_operand:MODEF 2 "nonimmediate_operand")
18229	  (match_operand:MODEF 3 "nonimmediate_operand")))]
18230  "(<MODE>mode != DFmode || TARGET_64BIT)
18231   && TARGET_80387 && TARGET_CMOVE
18232   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18233   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18234   && optimize_insn_for_speed_p ()"
18235  [(set (match_dup 4) (match_dup 5))
18236   (set (match_dup 0)
18237	(if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18238{
18239  if (MEM_P (operands[2]))
18240    {
18241      operands[5] = operands[2];
18242      operands[2] = operands[4];
18243    }
18244  else if (MEM_P (operands[3]))
18245    {
18246      operands[5] = operands[3];
18247      operands[3] = operands[4];
18248    }
18249  else
18250    gcc_unreachable ();
18251})
18252
18253;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18254;; the scalar versions to have only XMM registers as operands.
18255
18256;; XOP conditional move
18257(define_insn "*xop_pcmov_<mode>"
18258  [(set (match_operand:MODEF 0 "register_operand" "=x")
18259	(if_then_else:MODEF
18260	  (match_operand:MODEF 1 "register_operand" "x")
18261	  (match_operand:MODEF 2 "register_operand" "x")
18262	  (match_operand:MODEF 3 "register_operand" "x")))]
18263  "TARGET_XOP"
18264  "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18265  [(set_attr "type" "sse4arg")])
18266
18267;; These versions of the min/max patterns are intentionally ignorant of
18268;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18269;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18270;; are undefined in this condition, we're certain this is correct.
18271
18272(define_insn "<code><mode>3"
18273  [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18274	(smaxmin:MODEF
18275	  (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18276	  (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18277  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18278  "@
18279   <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18280   v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18281  [(set_attr "isa" "noavx,avx")
18282   (set_attr "prefix" "orig,vex")
18283   (set_attr "type" "sseadd")
18284   (set_attr "mode" "<MODE>")])
18285
18286;; These versions of the min/max patterns implement exactly the operations
18287;;   min = (op1 < op2 ? op1 : op2)
18288;;   max = (!(op1 < op2) ? op1 : op2)
18289;; Their operands are not commutative, and thus they may be used in the
18290;; presence of -0.0 and NaN.
18291
18292(define_insn "*ieee_s<ieee_maxmin><mode>3"
18293  [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18294	(unspec:MODEF
18295	  [(match_operand:MODEF 1 "register_operand" "0,v")
18296	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18297	  IEEE_MAXMIN))]
18298  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18299  "@
18300   <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18301   v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18302  [(set_attr "isa" "noavx,avx")
18303   (set_attr "prefix" "orig,maybe_evex")
18304   (set_attr "type" "sseadd")
18305   (set_attr "mode" "<MODE>")])
18306
18307;; Make two stack loads independent:
18308;;   fld aa              fld aa
18309;;   fld %st(0)     ->   fld bb
18310;;   fmul bb             fmul %st(1), %st
18311;;
18312;; Actually we only match the last two instructions for simplicity.
18313
18314(define_peephole2
18315  [(set (match_operand 0 "fp_register_operand")
18316	(match_operand 1 "fp_register_operand"))
18317   (set (match_dup 0)
18318	(match_operator 2 "binary_fp_operator"
18319	   [(match_dup 0)
18320	    (match_operand 3 "memory_operand")]))]
18321  "REGNO (operands[0]) != REGNO (operands[1])"
18322  [(set (match_dup 0) (match_dup 3))
18323   (set (match_dup 0)
18324	(match_op_dup 2
18325	  [(match_dup 5) (match_dup 4)]))]
18326{
18327  operands[4] = operands[0];
18328  operands[5] = operands[1];
18329
18330  /* The % modifier is not operational anymore in peephole2's, so we have to
18331     swap the operands manually in the case of addition and multiplication. */
18332  if (COMMUTATIVE_ARITH_P (operands[2]))
18333    std::swap (operands[4], operands[5]);
18334})
18335
18336(define_peephole2
18337  [(set (match_operand 0 "fp_register_operand")
18338	(match_operand 1 "fp_register_operand"))
18339   (set (match_dup 0)
18340	(match_operator 2 "binary_fp_operator"
18341	   [(match_operand 3 "memory_operand")
18342	    (match_dup 0)]))]
18343  "REGNO (operands[0]) != REGNO (operands[1])"
18344  [(set (match_dup 0) (match_dup 3))
18345   (set (match_dup 0)
18346	(match_op_dup 2
18347	  [(match_dup 4) (match_dup 5)]))]
18348{
18349  operands[4] = operands[0];
18350  operands[5] = operands[1];
18351
18352  /* The % modifier is not operational anymore in peephole2's, so we have to
18353     swap the operands manually in the case of addition and multiplication. */
18354  if (COMMUTATIVE_ARITH_P (operands[2]))
18355    std::swap (operands[4], operands[5]);
18356})
18357
18358;; Conditional addition patterns
18359(define_expand "add<mode>cc"
18360  [(match_operand:SWI 0 "register_operand")
18361   (match_operand 1 "ordered_comparison_operator")
18362   (match_operand:SWI 2 "register_operand")
18363   (match_operand:SWI 3 "const_int_operand")]
18364  ""
18365  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18366
18367;; min/max patterns
18368
18369(define_mode_iterator MAXMIN_IMODE
18370  [(SI "TARGET_SSE4_1") (DI "TARGET_AVX512VL")])
18371(define_code_attr maxmin_rel
18372  [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
18373
18374(define_expand "<code><mode>3"
18375  [(parallel
18376    [(set (match_operand:MAXMIN_IMODE 0 "register_operand")
18377	  (maxmin:MAXMIN_IMODE
18378	    (match_operand:MAXMIN_IMODE 1 "register_operand")
18379	    (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand")))
18380     (clobber (reg:CC FLAGS_REG))])]
18381  "TARGET_STV")
18382
18383(define_insn_and_split "*<code><mode>3_1"
18384  [(set (match_operand:MAXMIN_IMODE 0 "register_operand")
18385	(maxmin:MAXMIN_IMODE
18386	  (match_operand:MAXMIN_IMODE 1 "register_operand")
18387	  (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand")))
18388   (clobber (reg:CC FLAGS_REG))]
18389  "(TARGET_64BIT || <MODE>mode != DImode) && TARGET_STV
18390   && ix86_pre_reload_split ()"
18391  "#"
18392  "&& 1"
18393  [(set (match_dup 0)
18394	(if_then_else:MAXMIN_IMODE (match_dup 3)
18395	  (match_dup 1)
18396	  (match_dup 2)))]
18397{
18398  machine_mode mode = <MODE>mode;
18399
18400  if (!register_operand (operands[2], mode))
18401    operands[2] = force_reg (mode, operands[2]);
18402
18403  enum rtx_code code = <maxmin_rel>;
18404  machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], operands[2]);
18405  rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
18406
18407  rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], operands[2]);
18408  emit_insn (gen_rtx_SET (flags, tmp));
18409
18410  operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
18411})
18412
18413(define_insn_and_split "*<code>di3_doubleword"
18414  [(set (match_operand:DI 0 "register_operand")
18415	(maxmin:DI (match_operand:DI 1 "register_operand")
18416		   (match_operand:DI 2 "nonimmediate_operand")))
18417   (clobber (reg:CC FLAGS_REG))]
18418  "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
18419   && ix86_pre_reload_split ()"
18420  "#"
18421  "&& 1"
18422  [(set (match_dup 0)
18423	(if_then_else:SI (match_dup 6)
18424	  (match_dup 1)
18425	  (match_dup 2)))
18426   (set (match_dup 3)
18427	(if_then_else:SI (match_dup 6)
18428	  (match_dup 4)
18429	  (match_dup 5)))]
18430{
18431  if (!register_operand (operands[2], DImode))
18432    operands[2] = force_reg (DImode, operands[2]);
18433
18434  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
18435
18436  rtx cmplo[2] = { operands[1], operands[2] };
18437  rtx cmphi[2] = { operands[4], operands[5] };
18438
18439  enum rtx_code code = <maxmin_rel>;
18440
18441  switch (code)
18442    {
18443    case LE: case LEU:
18444      std::swap (cmplo[0], cmplo[1]);
18445      std::swap (cmphi[0], cmphi[1]);
18446      code = swap_condition (code);
18447      /* FALLTHRU */
18448
18449    case GE: case GEU:
18450      {
18451	bool uns = (code == GEU);
18452	rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
18453	  = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
18454
18455	emit_insn (gen_cmp_1 (SImode, cmplo[0], cmplo[1]));
18456
18457	rtx tmp = gen_rtx_SCRATCH (SImode);
18458	emit_insn (sbb_insn (SImode, tmp, cmphi[0], cmphi[1]));
18459
18460	rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
18461	operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
18462
18463	break;
18464      }
18465
18466    default:
18467      gcc_unreachable ();
18468    }
18469})
18470
18471;; Misc patterns (?)
18472
18473;; This pattern exists to put a dependency on all ebp-based memory accesses.
18474;; Otherwise there will be nothing to keep
18475;;
18476;; [(set (reg ebp) (reg esp))]
18477;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18478;;  (clobber (eflags)]
18479;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18480;;
18481;; in proper program order.
18482
18483(define_insn "@pro_epilogue_adjust_stack_add_<mode>"
18484  [(set (match_operand:P 0 "register_operand" "=r,r")
18485	(plus:P (match_operand:P 1 "register_operand" "0,r")
18486	        (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18487   (clobber (reg:CC FLAGS_REG))
18488   (clobber (mem:BLK (scratch)))]
18489  ""
18490{
18491  switch (get_attr_type (insn))
18492    {
18493    case TYPE_IMOV:
18494      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18495
18496    case TYPE_ALU:
18497      gcc_assert (rtx_equal_p (operands[0], operands[1]));
18498      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18499	return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18500
18501      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18502
18503    default:
18504      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18505      return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18506    }
18507}
18508  [(set (attr "type")
18509	(cond [(and (eq_attr "alternative" "0")
18510		    (not (match_test "TARGET_OPT_AGU")))
18511		 (const_string "alu")
18512	       (match_operand:<MODE> 2 "const0_operand")
18513		 (const_string "imov")
18514	      ]
18515	      (const_string "lea")))
18516   (set (attr "length_immediate")
18517	(cond [(eq_attr "type" "imov")
18518		 (const_string "0")
18519	       (and (eq_attr "type" "alu")
18520		    (match_operand 2 "const128_operand"))
18521		 (const_string "1")
18522	      ]
18523	      (const_string "*")))
18524   (set_attr "mode" "<MODE>")])
18525
18526(define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
18527  [(set (match_operand:P 0 "register_operand" "=r")
18528	(minus:P (match_operand:P 1 "register_operand" "0")
18529		 (match_operand:P 2 "register_operand" "r")))
18530   (clobber (reg:CC FLAGS_REG))
18531   (clobber (mem:BLK (scratch)))]
18532  ""
18533  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18534  [(set_attr "type" "alu")
18535   (set_attr "mode" "<MODE>")])
18536
18537(define_insn "@allocate_stack_worker_probe_<mode>"
18538  [(set (match_operand:P 0 "register_operand" "=a")
18539	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18540			    UNSPECV_STACK_PROBE))
18541   (clobber (reg:CC FLAGS_REG))]
18542  "ix86_target_stack_probe ()"
18543  "call\t___chkstk_ms"
18544  [(set_attr "type" "multi")
18545   (set_attr "length" "5")])
18546
18547(define_expand "allocate_stack"
18548  [(match_operand 0 "register_operand")
18549   (match_operand 1 "general_operand")]
18550  "ix86_target_stack_probe ()"
18551{
18552  rtx x;
18553
18554#ifndef CHECK_STACK_LIMIT
18555#define CHECK_STACK_LIMIT 0
18556#endif
18557
18558  if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18559      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18560    x = operands[1];
18561  else
18562    {
18563      x = copy_to_mode_reg (Pmode, operands[1]);
18564
18565      emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
18566    }
18567
18568  x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18569			   stack_pointer_rtx, 0, OPTAB_DIRECT);
18570
18571  if (x != stack_pointer_rtx)
18572    emit_move_insn (stack_pointer_rtx, x);
18573
18574  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18575  DONE;
18576})
18577
18578(define_expand "probe_stack"
18579  [(match_operand 0 "memory_operand")]
18580  ""
18581{
18582  emit_insn (gen_probe_stack_1
18583	     (word_mode, operands[0], const0_rtx));
18584  DONE;
18585})
18586
18587;; Use OR for stack probes, this is shorter.
18588(define_insn "@probe_stack_1_<mode>"
18589  [(set (match_operand:W 0 "memory_operand" "=m")
18590	(unspec:W [(match_operand:W 1 "const0_operand")]
18591		  UNSPEC_PROBE_STACK))
18592   (clobber (reg:CC FLAGS_REG))]
18593  ""
18594  "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18595  [(set_attr "type" "alu1")
18596   (set_attr "mode" "<MODE>")
18597   (set_attr "length_immediate" "1")])
18598  
18599(define_insn "@adjust_stack_and_probe_<mode>"
18600  [(set (match_operand:P 0 "register_operand" "=r")
18601	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18602			    UNSPECV_PROBE_STACK_RANGE))
18603   (set (reg:P SP_REG)
18604        (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18605   (clobber (reg:CC FLAGS_REG))
18606   (clobber (mem:BLK (scratch)))]
18607  ""
18608  "* return output_adjust_stack_and_probe (operands[0]);"
18609  [(set_attr "type" "multi")])
18610
18611(define_insn "@probe_stack_range_<mode>"
18612  [(set (match_operand:P 0 "register_operand" "=r")
18613	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18614			    (match_operand:P 2 "const_int_operand" "n")]
18615			    UNSPECV_PROBE_STACK_RANGE))
18616   (clobber (reg:CC FLAGS_REG))]
18617  ""
18618  "* return output_probe_stack_range (operands[0], operands[2]);"
18619  [(set_attr "type" "multi")])
18620
18621(define_expand "builtin_setjmp_receiver"
18622  [(label_ref (match_operand 0))]
18623  "!TARGET_64BIT && flag_pic"
18624{
18625#if TARGET_MACHO
18626  if (TARGET_MACHO)
18627    {
18628      rtx xops[3];
18629      rtx_code_label *label_rtx = gen_label_rtx ();
18630      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18631      xops[0] = xops[1] = pic_offset_table_rtx;
18632      xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18633      ix86_expand_binary_operator (MINUS, SImode, xops);
18634    }
18635  else
18636#endif
18637    emit_insn (gen_set_got (pic_offset_table_rtx));
18638  DONE;
18639})
18640
18641(define_expand "save_stack_nonlocal"
18642  [(set (match_operand 0 "memory_operand")
18643        (match_operand 1 "register_operand"))]
18644  ""
18645{
18646  rtx stack_slot;
18647  if ((flag_cf_protection & CF_RETURN))
18648    {
18649      /* Copy shadow stack pointer to the first slot and stack ppointer
18650	 to the second slot.  */
18651      rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18652      stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18653      rtx ssp = gen_reg_rtx (word_mode);
18654      emit_insn ((word_mode == SImode)
18655		 ? gen_rdsspsi (ssp)
18656		 : gen_rdsspdi (ssp));
18657      emit_move_insn (ssp_slot, ssp);
18658    }
18659  else
18660    stack_slot = adjust_address (operands[0], Pmode, 0);
18661  emit_move_insn (stack_slot, operands[1]);
18662  DONE;
18663})
18664
18665(define_expand "restore_stack_nonlocal"
18666  [(set (match_operand 0 "register_operand" "")
18667	(match_operand 1 "memory_operand" ""))]
18668  ""
18669{
18670  rtx stack_slot;
18671  if ((flag_cf_protection & CF_RETURN))
18672    {
18673      /* Restore shadow stack pointer from the first slot and stack
18674	 pointer from the second slot.  */
18675      rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18676      stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18677
18678      rtx flags, jump, noadj_label, inc_label, loop_label;
18679      rtx reg_adj, reg_ssp, tmp, clob;
18680
18681      /* Get the current shadow stack pointer.  The code below will check if
18682	 SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
18683	 is a NOP.  */
18684      reg_ssp = gen_reg_rtx (word_mode);
18685      emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18686      emit_insn ((word_mode == SImode)
18687		 ? gen_rdsspsi (reg_ssp)
18688		 : gen_rdsspdi (reg_ssp));
18689
18690      /* Compare through substraction the saved and the current ssp to decide
18691	 if ssp has to be adjusted.  */
18692      tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18693						 ssp_slot));
18694      clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18695      tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18696      emit_insn (tmp);
18697
18698      /* Compare and jump over adjustment code.  */
18699      tmp = gen_rtx_COMPARE (CCZmode, reg_ssp, const0_rtx);
18700      flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18701      emit_insn (gen_rtx_SET (flags, tmp));
18702
18703      noadj_label = gen_label_rtx ();
18704      tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18705      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18706				  gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18707				  pc_rtx);
18708      jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18709      JUMP_LABEL (jump) = noadj_label;
18710
18711      /* Compute the numebr of frames to adjust.  */
18712      reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18713      tmp = gen_rtx_SET (reg_adj,
18714			 gen_rtx_LSHIFTRT (ptr_mode,
18715					   negate_rtx (ptr_mode, reg_adj),
18716					   GEN_INT ((word_mode == SImode)
18717						    ? 2
18718						    : 3)));
18719      clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18720      tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18721      emit_insn (tmp);
18722
18723      /* Check if number of frames <= 255 so no loop is needed.  */
18724      tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18725      flags = gen_rtx_REG (CCmode, FLAGS_REG);
18726      emit_insn (gen_rtx_SET (flags, tmp));
18727
18728      inc_label = gen_label_rtx ();
18729      tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18730      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18731				  gen_rtx_LABEL_REF (VOIDmode, inc_label),
18732				  pc_rtx);
18733      jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18734      JUMP_LABEL (jump) = inc_label;
18735
18736      rtx reg_255 = gen_reg_rtx (word_mode);
18737      emit_move_insn (reg_255, GEN_INT (255));
18738
18739      /* Adjust the ssp in a loop.  */
18740      loop_label = gen_label_rtx ();
18741      emit_label (loop_label);
18742      LABEL_NUSES (loop_label) = 1;
18743
18744      emit_insn ((word_mode == SImode)
18745		 ? gen_incsspsi (reg_255)
18746		 : gen_incsspdi (reg_255));
18747      tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18748						 reg_adj,
18749						 GEN_INT (255)));
18750      clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18751      tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18752      emit_insn (tmp);
18753
18754      tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18755      flags = gen_rtx_REG (CCmode, FLAGS_REG);
18756      emit_insn (gen_rtx_SET (flags, tmp));
18757
18758      /* Jump to the loop label.  */
18759      tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18760      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18761				  gen_rtx_LABEL_REF (VOIDmode, loop_label),
18762				  pc_rtx);
18763      jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18764      JUMP_LABEL (jump) = loop_label;
18765
18766      emit_label (inc_label);
18767      LABEL_NUSES (inc_label) = 1;
18768      emit_insn ((word_mode == SImode)
18769		 ? gen_incsspsi (reg_ssp)
18770		 : gen_incsspdi (reg_ssp));
18771
18772      emit_label (noadj_label);
18773      LABEL_NUSES (noadj_label) = 1;
18774    }
18775  else
18776    stack_slot = adjust_address (operands[1], Pmode, 0);
18777  emit_move_insn (operands[0], stack_slot);
18778  DONE;
18779})
18780
18781
18782;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18783;; Do not split instructions with mask registers.
18784(define_split
18785  [(set (match_operand 0 "general_reg_operand")
18786	(match_operator 3 "promotable_binary_operator"
18787	   [(match_operand 1 "general_reg_operand")
18788	    (match_operand 2 "aligned_operand")]))
18789   (clobber (reg:CC FLAGS_REG))]
18790  "! TARGET_PARTIAL_REG_STALL && reload_completed
18791   && ((GET_MODE (operands[0]) == HImode
18792	&& ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18793            /* ??? next two lines just !satisfies_constraint_K (...) */
18794	    || !CONST_INT_P (operands[2])
18795	    || satisfies_constraint_K (operands[2])))
18796       || (GET_MODE (operands[0]) == QImode
18797	   && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18798  [(parallel [(set (match_dup 0)
18799		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18800	      (clobber (reg:CC FLAGS_REG))])]
18801{
18802  operands[0] = gen_lowpart (SImode, operands[0]);
18803  operands[1] = gen_lowpart (SImode, operands[1]);
18804  if (GET_CODE (operands[3]) != ASHIFT)
18805    operands[2] = gen_lowpart (SImode, operands[2]);
18806  operands[3] = shallow_copy_rtx (operands[3]);
18807  PUT_MODE (operands[3], SImode);
18808})
18809
18810; Promote the QImode tests, as i386 has encoding of the AND
18811; instruction with 32-bit sign-extended immediate and thus the
18812; instruction size is unchanged, except in the %eax case for
18813; which it is increased by one byte, hence the ! optimize_size.
18814(define_split
18815  [(set (match_operand 0 "flags_reg_operand")
18816	(match_operator 2 "compare_operator"
18817	  [(and (match_operand 3 "aligned_operand")
18818		(match_operand 4 "const_int_operand"))
18819	   (const_int 0)]))
18820   (set (match_operand 1 "register_operand")
18821	(and (match_dup 3) (match_dup 4)))]
18822  "! TARGET_PARTIAL_REG_STALL && reload_completed
18823   && optimize_insn_for_speed_p ()
18824   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18825       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18826   /* Ensure that the operand will remain sign-extended immediate.  */
18827   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18828  [(parallel [(set (match_dup 0)
18829		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18830			            (const_int 0)]))
18831	      (set (match_dup 1)
18832		   (and:SI (match_dup 3) (match_dup 4)))])]
18833{
18834  operands[4]
18835    = gen_int_mode (INTVAL (operands[4])
18836		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18837  operands[1] = gen_lowpart (SImode, operands[1]);
18838  operands[3] = gen_lowpart (SImode, operands[3]);
18839})
18840
18841; Don't promote the QImode tests, as i386 doesn't have encoding of
18842; the TEST instruction with 32-bit sign-extended immediate and thus
18843; the instruction size would at least double, which is not what we
18844; want even with ! optimize_size.
18845(define_split
18846  [(set (match_operand 0 "flags_reg_operand")
18847	(match_operator 1 "compare_operator"
18848	  [(and (match_operand:HI 2 "aligned_operand")
18849		(match_operand:HI 3 "const_int_operand"))
18850	   (const_int 0)]))]
18851  "! TARGET_PARTIAL_REG_STALL && reload_completed
18852   && ! TARGET_FAST_PREFIX
18853   && optimize_insn_for_speed_p ()
18854   /* Ensure that the operand will remain sign-extended immediate.  */
18855   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18856  [(set (match_dup 0)
18857	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18858		         (const_int 0)]))]
18859{
18860  operands[3]
18861    = gen_int_mode (INTVAL (operands[3])
18862		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18863  operands[2] = gen_lowpart (SImode, operands[2]);
18864})
18865
18866(define_split
18867  [(set (match_operand 0 "register_operand")
18868	(neg (match_operand 1 "register_operand")))
18869   (clobber (reg:CC FLAGS_REG))]
18870  "! TARGET_PARTIAL_REG_STALL && reload_completed
18871   && (GET_MODE (operands[0]) == HImode
18872       || (GET_MODE (operands[0]) == QImode
18873	   && (TARGET_PROMOTE_QImode
18874	       || optimize_insn_for_size_p ())))"
18875  [(parallel [(set (match_dup 0)
18876		   (neg:SI (match_dup 1)))
18877	      (clobber (reg:CC FLAGS_REG))])]
18878{
18879  operands[0] = gen_lowpart (SImode, operands[0]);
18880  operands[1] = gen_lowpart (SImode, operands[1]);
18881})
18882
18883;; Do not split instructions with mask regs.
18884(define_split
18885  [(set (match_operand 0 "general_reg_operand")
18886	(not (match_operand 1 "general_reg_operand")))]
18887  "! TARGET_PARTIAL_REG_STALL && reload_completed
18888   && (GET_MODE (operands[0]) == HImode
18889       || (GET_MODE (operands[0]) == QImode
18890	   && (TARGET_PROMOTE_QImode
18891	       || optimize_insn_for_size_p ())))"
18892  [(set (match_dup 0)
18893	(not:SI (match_dup 1)))]
18894{
18895  operands[0] = gen_lowpart (SImode, operands[0]);
18896  operands[1] = gen_lowpart (SImode, operands[1]);
18897})
18898
18899;; RTL Peephole optimizations, run before sched2.  These primarily look to
18900;; transform a complex memory operation into two memory to register operations.
18901
18902;; Don't push memory operands
18903(define_peephole2
18904  [(set (match_operand:SWI 0 "push_operand")
18905	(match_operand:SWI 1 "memory_operand"))
18906   (match_scratch:SWI 2 "<r>")]
18907  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18908   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18909  [(set (match_dup 2) (match_dup 1))
18910   (set (match_dup 0) (match_dup 2))])
18911
18912;; We need to handle SFmode only, because DFmode and XFmode are split to
18913;; SImode pushes.
18914(define_peephole2
18915  [(set (match_operand:SF 0 "push_operand")
18916	(match_operand:SF 1 "memory_operand"))
18917   (match_scratch:SF 2 "r")]
18918  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18919   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18920  [(set (match_dup 2) (match_dup 1))
18921   (set (match_dup 0) (match_dup 2))])
18922
18923;; Don't move an immediate directly to memory when the instruction
18924;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18925(define_peephole2
18926  [(match_scratch:SWI124 1 "<r>")
18927   (set (match_operand:SWI124 0 "memory_operand")
18928        (const_int 0))]
18929  "optimize_insn_for_speed_p ()
18930   && ((<MODE>mode == HImode
18931       && TARGET_LCP_STALL)
18932       || (!TARGET_USE_MOV0
18933          && TARGET_SPLIT_LONG_MOVES
18934          && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18935   && peep2_regno_dead_p (0, FLAGS_REG)"
18936  [(parallel [(set (match_dup 2) (const_int 0))
18937	      (clobber (reg:CC FLAGS_REG))])
18938   (set (match_dup 0) (match_dup 1))]
18939  "operands[2] = gen_lowpart (SImode, operands[1]);")
18940
18941(define_peephole2
18942  [(match_scratch:SWI124 2 "<r>")
18943   (set (match_operand:SWI124 0 "memory_operand")
18944        (match_operand:SWI124 1 "immediate_operand"))]
18945  "optimize_insn_for_speed_p ()
18946   && ((<MODE>mode == HImode
18947       && TARGET_LCP_STALL)
18948       || (TARGET_SPLIT_LONG_MOVES
18949          && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18950  [(set (match_dup 2) (match_dup 1))
18951   (set (match_dup 0) (match_dup 2))])
18952
18953;; Don't compare memory with zero, load and use a test instead.
18954(define_peephole2
18955  [(set (match_operand 0 "flags_reg_operand")
18956 	(match_operator 1 "compare_operator"
18957	  [(match_operand:SI 2 "memory_operand")
18958	   (const_int 0)]))
18959   (match_scratch:SI 3 "r")]
18960  "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18961  [(set (match_dup 3) (match_dup 2))
18962   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18963
18964;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18965;; Don't split NOTs with a displacement operand, because resulting XOR
18966;; will not be pairable anyway.
18967;;
18968;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18969;; represented using a modRM byte.  The XOR replacement is long decoded,
18970;; so this split helps here as well.
18971;;
18972;; Note: Can't do this as a regular split because we can't get proper
18973;; lifetime information then.
18974
18975(define_peephole2
18976  [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18977	(not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18978  "optimize_insn_for_speed_p ()
18979   && ((TARGET_NOT_UNPAIRABLE
18980	&& (!MEM_P (operands[0])
18981	    || !memory_displacement_operand (operands[0], <MODE>mode)))
18982       || (TARGET_NOT_VECTORMODE
18983	   && long_memory_operand (operands[0], <MODE>mode)))
18984   && peep2_regno_dead_p (0, FLAGS_REG)"
18985  [(parallel [(set (match_dup 0)
18986		   (xor:SWI124 (match_dup 1) (const_int -1)))
18987	      (clobber (reg:CC FLAGS_REG))])])
18988
18989;; Non pairable "test imm, reg" instructions can be translated to
18990;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18991;; byte opcode instead of two, have a short form for byte operands),
18992;; so do it for other CPUs as well.  Given that the value was dead,
18993;; this should not create any new dependencies.  Pass on the sub-word
18994;; versions if we're concerned about partial register stalls.
18995
18996(define_peephole2
18997  [(set (match_operand 0 "flags_reg_operand")
18998	(match_operator 1 "compare_operator"
18999	  [(and:SI (match_operand:SI 2 "register_operand")
19000		   (match_operand:SI 3 "immediate_operand"))
19001	   (const_int 0)]))]
19002  "ix86_match_ccmode (insn, CCNOmode)
19003   && (REGNO (operands[2]) != AX_REG
19004       || satisfies_constraint_K (operands[3]))
19005   && peep2_reg_dead_p (1, operands[2])"
19006  [(parallel
19007     [(set (match_dup 0)
19008	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19009		            (const_int 0)]))
19010      (set (match_dup 2)
19011	   (and:SI (match_dup 2) (match_dup 3)))])])
19012
19013;; We don't need to handle HImode case, because it will be promoted to SImode
19014;; on ! TARGET_PARTIAL_REG_STALL
19015
19016(define_peephole2
19017  [(set (match_operand 0 "flags_reg_operand")
19018	(match_operator 1 "compare_operator"
19019	  [(and:QI (match_operand:QI 2 "register_operand")
19020		   (match_operand:QI 3 "immediate_operand"))
19021	   (const_int 0)]))]
19022  "! TARGET_PARTIAL_REG_STALL
19023   && ix86_match_ccmode (insn, CCNOmode)
19024   && REGNO (operands[2]) != AX_REG
19025   && peep2_reg_dead_p (1, operands[2])"
19026  [(parallel
19027     [(set (match_dup 0)
19028	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19029		            (const_int 0)]))
19030      (set (match_dup 2)
19031	   (and:QI (match_dup 2) (match_dup 3)))])])
19032
19033(define_peephole2
19034  [(set (match_operand 0 "flags_reg_operand")
19035	(match_operator 1 "compare_operator"
19036	  [(and:QI
19037	     (subreg:QI
19038	       (zero_extract:SI (match_operand 2 "QIreg_operand")
19039				(const_int 8)
19040				(const_int 8)) 0)
19041	     (match_operand 3 "const_int_operand"))
19042	   (const_int 0)]))]
19043  "! TARGET_PARTIAL_REG_STALL
19044   && ix86_match_ccmode (insn, CCNOmode)
19045   && REGNO (operands[2]) != AX_REG
19046   && peep2_reg_dead_p (1, operands[2])"
19047  [(parallel
19048     [(set (match_dup 0)
19049	   (match_op_dup 1
19050	     [(and:QI
19051		(subreg:QI
19052		  (zero_extract:SI (match_dup 2)
19053				   (const_int 8)
19054				   (const_int 8)) 0)
19055		(match_dup 3))
19056	      (const_int 0)]))
19057      (set (zero_extract:SI (match_dup 2)
19058			    (const_int 8)
19059			    (const_int 8))
19060	   (subreg:SI
19061	     (and:QI
19062	       (subreg:QI
19063		 (zero_extract:SI (match_dup 2)
19064				  (const_int 8)
19065				  (const_int 8)) 0)
19066	       (match_dup 3)) 0))])])
19067
19068;; Don't do logical operations with memory inputs.
19069(define_peephole2
19070  [(match_scratch:SWI 2 "<r>")
19071   (parallel [(set (match_operand:SWI 0 "register_operand")
19072		   (match_operator:SWI 3 "arith_or_logical_operator"
19073		     [(match_dup 0)
19074		      (match_operand:SWI 1 "memory_operand")]))
19075	      (clobber (reg:CC FLAGS_REG))])]
19076  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19077  [(set (match_dup 2) (match_dup 1))
19078   (parallel [(set (match_dup 0)
19079		   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19080	      (clobber (reg:CC FLAGS_REG))])])
19081
19082(define_peephole2
19083  [(match_scratch:SWI 2 "<r>")
19084   (parallel [(set (match_operand:SWI 0 "register_operand")
19085		   (match_operator:SWI 3 "arith_or_logical_operator"
19086		     [(match_operand:SWI 1 "memory_operand")
19087		      (match_dup 0)]))
19088	      (clobber (reg:CC FLAGS_REG))])]
19089  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19090  [(set (match_dup 2) (match_dup 1))
19091   (parallel [(set (match_dup 0)
19092		   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19093	      (clobber (reg:CC FLAGS_REG))])])
19094
19095;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
19096;; the memory address refers to the destination of the load!
19097
19098(define_peephole2
19099  [(set (match_operand:SWI 0 "general_reg_operand")
19100	(match_operand:SWI 1 "general_reg_operand"))
19101   (parallel [(set (match_dup 0)
19102		   (match_operator:SWI 3 "commutative_operator"
19103		     [(match_dup 0)
19104		      (match_operand:SWI 2 "memory_operand")]))
19105	      (clobber (reg:CC FLAGS_REG))])]
19106  "REGNO (operands[0]) != REGNO (operands[1])
19107   && (<MODE>mode != QImode
19108       || any_QIreg_operand (operands[1], QImode))"
19109  [(set (match_dup 0) (match_dup 4))
19110   (parallel [(set (match_dup 0)
19111		   (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19112	      (clobber (reg:CC FLAGS_REG))])]
19113  "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19114
19115(define_peephole2
19116  [(set (match_operand 0 "mmx_reg_operand")
19117	(match_operand 1 "mmx_reg_operand"))
19118   (set (match_dup 0)
19119	(match_operator 3 "commutative_operator"
19120	  [(match_dup 0)
19121	   (match_operand 2 "memory_operand")]))]
19122  "REGNO (operands[0]) != REGNO (operands[1])"
19123  [(set (match_dup 0) (match_dup 2))
19124   (set (match_dup 0)
19125	(match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19126
19127(define_peephole2
19128  [(set (match_operand 0 "sse_reg_operand")
19129	(match_operand 1 "sse_reg_operand"))
19130   (set (match_dup 0)
19131	(match_operator 3 "commutative_operator"
19132	  [(match_dup 0)
19133	   (match_operand 2 "memory_operand")]))]
19134  "REGNO (operands[0]) != REGNO (operands[1])"
19135  [(set (match_dup 0) (match_dup 2))
19136   (set (match_dup 0)
19137	(match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19138
19139; Don't do logical operations with memory outputs
19140;
19141; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19142; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19143; the same decoder scheduling characteristics as the original.
19144
19145(define_peephole2
19146  [(match_scratch:SWI 2 "<r>")
19147   (parallel [(set (match_operand:SWI 0 "memory_operand")
19148		   (match_operator:SWI 3 "arith_or_logical_operator"
19149		     [(match_dup 0)
19150		      (match_operand:SWI 1 "<nonmemory_operand>")]))
19151	      (clobber (reg:CC FLAGS_REG))])]
19152  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19153  [(set (match_dup 2) (match_dup 0))
19154   (parallel [(set (match_dup 2)
19155		   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19156	      (clobber (reg:CC FLAGS_REG))])
19157   (set (match_dup 0) (match_dup 2))])
19158
19159(define_peephole2
19160  [(match_scratch:SWI 2 "<r>")
19161   (parallel [(set (match_operand:SWI 0 "memory_operand")
19162		   (match_operator:SWI 3 "arith_or_logical_operator"
19163		     [(match_operand:SWI 1 "<nonmemory_operand>")
19164		      (match_dup 0)]))
19165	      (clobber (reg:CC FLAGS_REG))])]
19166  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19167  [(set (match_dup 2) (match_dup 0))
19168   (parallel [(set (match_dup 2)
19169		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19170	      (clobber (reg:CC FLAGS_REG))])
19171   (set (match_dup 0) (match_dup 2))])
19172
19173;; Attempt to use arith or logical operations with memory outputs with
19174;; setting of flags.
19175(define_peephole2
19176  [(set (match_operand:SWI 0 "register_operand")
19177	(match_operand:SWI 1 "memory_operand"))
19178   (parallel [(set (match_dup 0)
19179		   (match_operator:SWI 3 "plusminuslogic_operator"
19180		     [(match_dup 0)
19181		      (match_operand:SWI 2 "<nonmemory_operand>")]))
19182	      (clobber (reg:CC FLAGS_REG))])
19183   (set (match_dup 1) (match_dup 0))
19184   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19185  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19186   && peep2_reg_dead_p (4, operands[0])
19187   && !reg_overlap_mentioned_p (operands[0], operands[1])
19188   && !reg_overlap_mentioned_p (operands[0], operands[2])
19189   && (<MODE>mode != QImode
19190       || immediate_operand (operands[2], QImode)
19191       || any_QIreg_operand (operands[2], QImode))
19192   && ix86_match_ccmode (peep2_next_insn (3),
19193			 (GET_CODE (operands[3]) == PLUS
19194			  || GET_CODE (operands[3]) == MINUS)
19195			 ? CCGOCmode : CCNOmode)"
19196  [(parallel [(set (match_dup 4) (match_dup 6))
19197	      (set (match_dup 1) (match_dup 5))])]
19198{
19199  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19200  operands[5]
19201    = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19202		      copy_rtx (operands[1]),
19203		      operands[2]);
19204  operands[6]
19205    = gen_rtx_COMPARE (GET_MODE (operands[4]),
19206		       copy_rtx (operands[5]),
19207		       const0_rtx);
19208})
19209
19210;; Likewise for cmpelim optimized pattern.
19211(define_peephole2
19212  [(set (match_operand:SWI 0 "register_operand")
19213	(match_operand:SWI 1 "memory_operand"))
19214   (parallel [(set (reg FLAGS_REG)
19215		   (compare (match_operator:SWI 3 "plusminuslogic_operator"
19216			      [(match_dup 0)
19217			       (match_operand:SWI 2 "<nonmemory_operand>")])
19218			    (const_int 0)))
19219	      (set (match_dup 0) (match_dup 3))])
19220   (set (match_dup 1) (match_dup 0))]
19221  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19222   && peep2_reg_dead_p (3, operands[0])
19223   && !reg_overlap_mentioned_p (operands[0], operands[1])
19224   && !reg_overlap_mentioned_p (operands[0], operands[2])
19225   && ix86_match_ccmode (peep2_next_insn (1),
19226			 (GET_CODE (operands[3]) == PLUS
19227			  || GET_CODE (operands[3]) == MINUS)
19228			 ? CCGOCmode : CCNOmode)"
19229  [(parallel [(set (match_dup 4) (match_dup 6))
19230	      (set (match_dup 1) (match_dup 5))])]
19231{
19232  operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19233  operands[5]
19234    = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19235		      copy_rtx (operands[1]), operands[2]);
19236  operands[6]
19237    = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19238		       const0_rtx);
19239})
19240
19241;; Likewise for instances where we have a lea pattern.
19242(define_peephole2
19243  [(set (match_operand:SWI 0 "register_operand")
19244	(match_operand:SWI 1 "memory_operand"))
19245   (set (match_operand:<LEAMODE> 3 "register_operand")
19246	(plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
19247			(match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
19248   (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
19249   (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
19250  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19251   && REGNO (operands[4]) == REGNO (operands[0])
19252   && REGNO (operands[5]) == REGNO (operands[3])
19253   && peep2_reg_dead_p (4, operands[3])
19254   && ((REGNO (operands[0]) == REGNO (operands[3]))
19255       || peep2_reg_dead_p (2, operands[0]))
19256   && !reg_overlap_mentioned_p (operands[0], operands[1])
19257   && !reg_overlap_mentioned_p (operands[3], operands[1])
19258   && !reg_overlap_mentioned_p (operands[0], operands[2])
19259   && (<MODE>mode != QImode
19260       || immediate_operand (operands[2], QImode)
19261       || any_QIreg_operand (operands[2], QImode))
19262   && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19263  [(parallel [(set (match_dup 6) (match_dup 8))
19264	      (set (match_dup 1) (match_dup 7))])]
19265{
19266  operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
19267  operands[7]
19268    = gen_rtx_PLUS (<MODE>mode,
19269		    copy_rtx (operands[1]),
19270		    gen_lowpart (<MODE>mode, operands[2]));
19271  operands[8]
19272    = gen_rtx_COMPARE (GET_MODE (operands[6]),
19273		       copy_rtx (operands[7]),
19274		       const0_rtx);
19275})
19276
19277(define_peephole2
19278  [(parallel [(set (match_operand:SWI 0 "register_operand")
19279		   (match_operator:SWI 2 "plusminuslogic_operator"
19280		     [(match_dup 0)
19281		      (match_operand:SWI 1 "memory_operand")]))
19282	      (clobber (reg:CC FLAGS_REG))])
19283   (set (match_dup 1) (match_dup 0))
19284   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19285  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19286   && COMMUTATIVE_ARITH_P (operands[2])
19287   && peep2_reg_dead_p (3, operands[0])
19288   && !reg_overlap_mentioned_p (operands[0], operands[1])
19289   && ix86_match_ccmode (peep2_next_insn (2),
19290			 GET_CODE (operands[2]) == PLUS
19291			 ? CCGOCmode : CCNOmode)"
19292  [(parallel [(set (match_dup 3) (match_dup 5))
19293	      (set (match_dup 1) (match_dup 4))])]
19294{
19295  operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19296  operands[4]
19297    = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19298		      copy_rtx (operands[1]),
19299		      operands[0]);
19300  operands[5]
19301    = gen_rtx_COMPARE (GET_MODE (operands[3]),
19302		       copy_rtx (operands[4]),
19303		       const0_rtx);
19304})
19305
19306;; Likewise for cmpelim optimized pattern.
19307(define_peephole2
19308  [(parallel [(set (reg FLAGS_REG)
19309		   (compare (match_operator:SWI 2 "plusminuslogic_operator"
19310			      [(match_operand:SWI 0 "register_operand")
19311			       (match_operand:SWI 1 "memory_operand")])
19312			    (const_int 0)))
19313	      (set (match_dup 0) (match_dup 2))])
19314   (set (match_dup 1) (match_dup 0))]
19315  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19316   && COMMUTATIVE_ARITH_P (operands[2])
19317   && peep2_reg_dead_p (2, operands[0])
19318   && !reg_overlap_mentioned_p (operands[0], operands[1])
19319   && ix86_match_ccmode (peep2_next_insn (0),
19320			 GET_CODE (operands[2]) == PLUS
19321			 ? CCGOCmode : CCNOmode)"
19322  [(parallel [(set (match_dup 3) (match_dup 5))
19323	      (set (match_dup 1) (match_dup 4))])]
19324{
19325  operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19326  operands[4]
19327    = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19328		      copy_rtx (operands[1]), operands[0]);
19329  operands[5]
19330    = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19331		       const0_rtx);
19332})
19333
19334(define_peephole2
19335  [(set (match_operand:SWI12 0 "register_operand")
19336	(match_operand:SWI12 1 "memory_operand"))
19337   (parallel [(set (match_operand:SI 4 "register_operand")
19338		   (match_operator:SI 3 "plusminuslogic_operator"
19339		     [(match_dup 4)
19340		      (match_operand:SI 2 "nonmemory_operand")]))
19341	      (clobber (reg:CC FLAGS_REG))])
19342   (set (match_dup 1) (match_dup 0))
19343   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19344  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19345   && REGNO (operands[0]) == REGNO (operands[4])
19346   && peep2_reg_dead_p (4, operands[0])
19347   && (<MODE>mode != QImode
19348       || immediate_operand (operands[2], SImode)
19349       || any_QIreg_operand (operands[2], SImode))
19350   && !reg_overlap_mentioned_p (operands[0], operands[1])
19351   && !reg_overlap_mentioned_p (operands[0], operands[2])
19352   && ix86_match_ccmode (peep2_next_insn (3),
19353			 (GET_CODE (operands[3]) == PLUS
19354			  || GET_CODE (operands[3]) == MINUS)
19355			 ? CCGOCmode : CCNOmode)"
19356  [(parallel [(set (match_dup 5) (match_dup 7))
19357	      (set (match_dup 1) (match_dup 6))])]
19358{
19359  operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
19360  operands[6]
19361    = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19362		      copy_rtx (operands[1]),
19363		      gen_lowpart (<MODE>mode, operands[2]));
19364  operands[7]
19365    = gen_rtx_COMPARE (GET_MODE (operands[5]),
19366		       copy_rtx (operands[6]),
19367		       const0_rtx);
19368})
19369
19370;; peephole2 comes before regcprop, so deal also with a case that
19371;; would be cleaned up by regcprop.
19372(define_peephole2
19373  [(set (match_operand:SWI 0 "register_operand")
19374	(match_operand:SWI 1 "memory_operand"))
19375   (parallel [(set (match_dup 0)
19376		   (match_operator:SWI 3 "plusminuslogic_operator"
19377		     [(match_dup 0)
19378		      (match_operand:SWI 2 "<nonmemory_operand>")]))
19379	      (clobber (reg:CC FLAGS_REG))])
19380   (set (match_operand:SWI 4 "register_operand") (match_dup 0))
19381   (set (match_dup 1) (match_dup 4))
19382   (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
19383  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19384   && peep2_reg_dead_p (3, operands[0])
19385   && peep2_reg_dead_p (5, operands[4])
19386   && !reg_overlap_mentioned_p (operands[0], operands[1])
19387   && !reg_overlap_mentioned_p (operands[0], operands[2])
19388   && !reg_overlap_mentioned_p (operands[4], operands[1])
19389   && (<MODE>mode != QImode
19390       || immediate_operand (operands[2], QImode)
19391       || any_QIreg_operand (operands[2], QImode))
19392   && ix86_match_ccmode (peep2_next_insn (4),
19393			 (GET_CODE (operands[3]) == PLUS
19394			  || GET_CODE (operands[3]) == MINUS)
19395			 ? CCGOCmode : CCNOmode)"
19396  [(parallel [(set (match_dup 5) (match_dup 7))
19397	      (set (match_dup 1) (match_dup 6))])]
19398{
19399  operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
19400  operands[6]
19401    = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19402		      copy_rtx (operands[1]),
19403		      operands[2]);
19404  operands[7]
19405    = gen_rtx_COMPARE (GET_MODE (operands[5]),
19406		       copy_rtx (operands[6]),
19407		       const0_rtx);
19408})
19409
19410(define_peephole2
19411  [(set (match_operand:SWI12 0 "register_operand")
19412	(match_operand:SWI12 1 "memory_operand"))
19413   (parallel [(set (match_operand:SI 4 "register_operand")
19414		   (match_operator:SI 3 "plusminuslogic_operator"
19415		     [(match_dup 4)
19416		      (match_operand:SI 2 "nonmemory_operand")]))
19417	      (clobber (reg:CC FLAGS_REG))])
19418   (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
19419   (set (match_dup 1) (match_dup 5))
19420   (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
19421  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19422   && REGNO (operands[0]) == REGNO (operands[4])
19423   && peep2_reg_dead_p (3, operands[0])
19424   && peep2_reg_dead_p (5, operands[5])
19425   && (<MODE>mode != QImode
19426       || immediate_operand (operands[2], SImode)
19427       || any_QIreg_operand (operands[2], SImode))
19428   && !reg_overlap_mentioned_p (operands[0], operands[1])
19429   && !reg_overlap_mentioned_p (operands[0], operands[2])
19430   && !reg_overlap_mentioned_p (operands[5], operands[1])
19431   && ix86_match_ccmode (peep2_next_insn (4),
19432			 (GET_CODE (operands[3]) == PLUS
19433			  || GET_CODE (operands[3]) == MINUS)
19434			 ? CCGOCmode : CCNOmode)"
19435  [(parallel [(set (match_dup 6) (match_dup 8))
19436	      (set (match_dup 1) (match_dup 7))])]
19437{
19438  operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
19439  operands[7]
19440    = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19441		      copy_rtx (operands[1]),
19442		      gen_lowpart (<MODE>mode, operands[2]));
19443  operands[8]
19444    = gen_rtx_COMPARE (GET_MODE (operands[6]),
19445		       copy_rtx (operands[7]),
19446		       const0_rtx);
19447})
19448
19449;; Likewise for cmpelim optimized pattern.
19450(define_peephole2
19451  [(set (match_operand:SWI 0 "register_operand")
19452	(match_operand:SWI 1 "memory_operand"))
19453   (parallel [(set (reg FLAGS_REG)
19454		   (compare (match_operator:SWI 3 "plusminuslogic_operator"
19455			      [(match_dup 0)
19456			       (match_operand:SWI 2 "<nonmemory_operand>")])
19457			    (const_int 0)))
19458	      (set (match_dup 0) (match_dup 3))])
19459   (set (match_operand:SWI 4 "register_operand") (match_dup 0))
19460   (set (match_dup 1) (match_dup 4))]
19461  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19462   && peep2_reg_dead_p (3, operands[0])
19463   && peep2_reg_dead_p (4, operands[4])
19464   && !reg_overlap_mentioned_p (operands[0], operands[1])
19465   && !reg_overlap_mentioned_p (operands[0], operands[2])
19466   && !reg_overlap_mentioned_p (operands[4], operands[1])
19467   && ix86_match_ccmode (peep2_next_insn (1),
19468			 (GET_CODE (operands[3]) == PLUS
19469			  || GET_CODE (operands[3]) == MINUS)
19470			 ? CCGOCmode : CCNOmode)"
19471  [(parallel [(set (match_dup 5) (match_dup 7))
19472	      (set (match_dup 1) (match_dup 6))])]
19473{
19474  operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19475  operands[6]
19476    = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19477		      copy_rtx (operands[1]), operands[2]);
19478  operands[7]
19479    = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
19480		       const0_rtx);
19481})
19482
19483;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
19484;; into x = z; x ^= y; x != z
19485(define_peephole2
19486  [(set (match_operand:SWI 0 "register_operand")
19487	(match_operand:SWI 1 "memory_operand"))
19488   (set (match_operand:SWI 3 "register_operand") (match_dup 0))
19489   (parallel [(set (match_operand:SWI 4 "register_operand")
19490		   (xor:SWI (match_dup 4)
19491			    (match_operand:SWI 2 "<nonmemory_operand>")))
19492	      (clobber (reg:CC FLAGS_REG))])
19493   (set (match_dup 1) (match_dup 4))
19494   (set (reg:CCZ FLAGS_REG)
19495	(compare:CCZ (match_operand:SWI 5 "register_operand")
19496		     (match_operand:SWI 6 "<nonmemory_operand>")))]
19497  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19498   && (REGNO (operands[4]) == REGNO (operands[0])
19499       || REGNO (operands[4]) == REGNO (operands[3]))
19500   && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
19501			     ? 3 : 0], operands[5])
19502       ? rtx_equal_p (operands[2], operands[6])
19503       : rtx_equal_p (operands[2], operands[5])
19504	 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
19505				  ? 3 : 0], operands[6]))
19506   && peep2_reg_dead_p (4, operands[4])
19507   && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
19508				    ? 3 : 0])
19509   && !reg_overlap_mentioned_p (operands[0], operands[1])
19510   && !reg_overlap_mentioned_p (operands[0], operands[2])
19511   && !reg_overlap_mentioned_p (operands[3], operands[0])
19512   && !reg_overlap_mentioned_p (operands[3], operands[1])
19513   && !reg_overlap_mentioned_p (operands[3], operands[2])
19514   && (<MODE>mode != QImode
19515       || immediate_operand (operands[2], QImode)
19516       || any_QIreg_operand (operands[2], QImode))"
19517  [(parallel [(set (match_dup 7) (match_dup 9))
19518	      (set (match_dup 1) (match_dup 8))])]
19519{
19520  operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
19521  operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
19522			     operands[2]);
19523  operands[9]
19524    = gen_rtx_COMPARE (GET_MODE (operands[7]),
19525		       copy_rtx (operands[8]),
19526		       const0_rtx);
19527})
19528
19529(define_peephole2
19530  [(set (match_operand:SWI12 0 "register_operand")
19531	(match_operand:SWI12 1 "memory_operand"))
19532   (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
19533   (parallel [(set (match_operand:SI 4 "register_operand")
19534		   (xor:SI (match_dup 4)
19535			   (match_operand:SI 2 "<nonmemory_operand>")))
19536	      (clobber (reg:CC FLAGS_REG))])
19537   (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
19538   (set (reg:CCZ FLAGS_REG)
19539	(compare:CCZ (match_operand:SWI12 6 "register_operand")
19540		     (match_operand:SWI12 7 "<nonmemory_operand>")))]
19541  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19542   && (REGNO (operands[5]) == REGNO (operands[0])
19543       || REGNO (operands[5]) == REGNO (operands[3]))
19544   && REGNO (operands[5]) == REGNO (operands[4])
19545   && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
19546			     ? 3 : 0], operands[6])
19547       ? (REG_P (operands[2])
19548	  ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
19549	  : rtx_equal_p (operands[2], operands[7]))
19550       : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
19551				? 3 : 0], operands[7])
19552	  && REG_P (operands[2])
19553	  && REGNO (operands[2]) == REGNO (operands[6])))
19554   && peep2_reg_dead_p (4, operands[5])
19555   && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
19556				    ? 3 : 0])
19557   && !reg_overlap_mentioned_p (operands[0], operands[1])
19558   && !reg_overlap_mentioned_p (operands[0], operands[2])
19559   && !reg_overlap_mentioned_p (operands[3], operands[0])
19560   && !reg_overlap_mentioned_p (operands[3], operands[1])
19561   && !reg_overlap_mentioned_p (operands[3], operands[2])
19562   && (<MODE>mode != QImode
19563       || immediate_operand (operands[2], SImode)
19564       || any_QIreg_operand (operands[2], SImode))"
19565  [(parallel [(set (match_dup 8) (match_dup 10))
19566	      (set (match_dup 1) (match_dup 9))])]
19567{
19568  operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
19569  operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
19570			     gen_lowpart (<MODE>mode, operands[2]));
19571  operands[10]
19572    = gen_rtx_COMPARE (GET_MODE (operands[8]),
19573		       copy_rtx (operands[9]),
19574		       const0_rtx);
19575})
19576
19577;; Attempt to optimize away memory stores of values the memory already
19578;; has.  See PR79593.
19579(define_peephole2
19580  [(set (match_operand 0 "register_operand")
19581        (match_operand 1 "memory_operand"))
19582   (set (match_operand 2 "memory_operand") (match_dup 0))]
19583  "!MEM_VOLATILE_P (operands[1])
19584   && !MEM_VOLATILE_P (operands[2])
19585   && rtx_equal_p (operands[1], operands[2])
19586   && !reg_overlap_mentioned_p (operands[0], operands[2])"
19587  [(set (match_dup 0) (match_dup 1))])
19588
19589;; Attempt to always use XOR for zeroing registers (including FP modes).
19590(define_peephole2
19591  [(set (match_operand 0 "general_reg_operand")
19592	(match_operand 1 "const0_operand"))]
19593  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19594   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19595   && peep2_regno_dead_p (0, FLAGS_REG)"
19596  [(parallel [(set (match_dup 0) (const_int 0))
19597	      (clobber (reg:CC FLAGS_REG))])]
19598  "operands[0] = gen_lowpart (word_mode, operands[0]);")
19599
19600(define_peephole2
19601  [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19602	(const_int 0))]
19603  "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19604   && peep2_regno_dead_p (0, FLAGS_REG)"
19605  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19606	      (clobber (reg:CC FLAGS_REG))])])
19607
19608;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19609(define_peephole2
19610  [(set (match_operand:SWI248 0 "general_reg_operand")
19611	(const_int -1))]
19612  "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19613   && peep2_regno_dead_p (0, FLAGS_REG)"
19614  [(parallel [(set (match_dup 0) (const_int -1))
19615	      (clobber (reg:CC FLAGS_REG))])]
19616{
19617  if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19618    operands[0] = gen_lowpart (SImode, operands[0]);
19619})
19620
19621;; Attempt to convert simple lea to add/shift.
19622;; These can be created by move expanders.
19623;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19624;; relevant lea instructions were already split.
19625
19626(define_peephole2
19627  [(set (match_operand:SWI48 0 "register_operand")
19628  	(plus:SWI48 (match_dup 0)
19629		    (match_operand:SWI48 1 "<nonmemory_operand>")))]
19630  "!TARGET_OPT_AGU
19631   && peep2_regno_dead_p (0, FLAGS_REG)"
19632  [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19633	      (clobber (reg:CC FLAGS_REG))])])
19634
19635(define_peephole2
19636  [(set (match_operand:SWI48 0 "register_operand")
19637  	(plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19638		    (match_dup 0)))]
19639  "!TARGET_OPT_AGU
19640   && peep2_regno_dead_p (0, FLAGS_REG)"
19641  [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19642	      (clobber (reg:CC FLAGS_REG))])])
19643
19644(define_peephole2
19645  [(set (match_operand:DI 0 "register_operand")
19646  	(zero_extend:DI
19647	  (plus:SI (match_operand:SI 1 "register_operand")
19648		   (match_operand:SI 2 "nonmemory_operand"))))]
19649  "TARGET_64BIT && !TARGET_OPT_AGU
19650   && REGNO (operands[0]) == REGNO (operands[1])
19651   && peep2_regno_dead_p (0, FLAGS_REG)"
19652  [(parallel [(set (match_dup 0)
19653		   (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19654	      (clobber (reg:CC FLAGS_REG))])])
19655
19656(define_peephole2
19657  [(set (match_operand:DI 0 "register_operand")
19658  	(zero_extend:DI
19659	  (plus:SI (match_operand:SI 1 "nonmemory_operand")
19660		   (match_operand:SI 2 "register_operand"))))]
19661  "TARGET_64BIT && !TARGET_OPT_AGU
19662   && REGNO (operands[0]) == REGNO (operands[2])
19663   && peep2_regno_dead_p (0, FLAGS_REG)"
19664  [(parallel [(set (match_dup 0)
19665		   (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19666	      (clobber (reg:CC FLAGS_REG))])])
19667
19668(define_peephole2
19669  [(set (match_operand:SWI48 0 "register_operand")
19670  	(mult:SWI48 (match_dup 0)
19671		    (match_operand:SWI48 1 "const_int_operand")))]
19672  "pow2p_hwi (INTVAL (operands[1]))
19673   && peep2_regno_dead_p (0, FLAGS_REG)"
19674  [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19675	      (clobber (reg:CC FLAGS_REG))])]
19676  "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19677
19678(define_peephole2
19679  [(set (match_operand:DI 0 "register_operand")
19680  	(zero_extend:DI
19681	  (mult:SI (match_operand:SI 1 "register_operand")
19682		   (match_operand:SI 2 "const_int_operand"))))]
19683  "TARGET_64BIT
19684   && pow2p_hwi (INTVAL (operands[2]))
19685   && REGNO (operands[0]) == REGNO (operands[1])
19686   && peep2_regno_dead_p (0, FLAGS_REG)"
19687  [(parallel [(set (match_dup 0)
19688		   (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19689	      (clobber (reg:CC FLAGS_REG))])]
19690  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19691
19692;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19693;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19694;; On many CPUs it is also faster, since special hardware to avoid esp
19695;; dependencies is present.
19696
19697;; While some of these conversions may be done using splitters, we use
19698;; peepholes in order to allow combine_stack_adjustments pass to see
19699;; nonobfuscated RTL.
19700
19701;; Convert prologue esp subtractions to push.
19702;; We need register to push.  In order to keep verify_flow_info happy we have
19703;; two choices
19704;; - use scratch and clobber it in order to avoid dependencies
19705;; - use already live register
19706;; We can't use the second way right now, since there is no reliable way how to
19707;; verify that given register is live.  First choice will also most likely in
19708;; fewer dependencies.  On the place of esp adjustments it is very likely that
19709;; call clobbered registers are dead.  We may want to use base pointer as an
19710;; alternative when no register is available later.
19711
19712(define_peephole2
19713  [(match_scratch:W 1 "r")
19714   (parallel [(set (reg:P SP_REG)
19715		   (plus:P (reg:P SP_REG)
19716			   (match_operand:P 0 "const_int_operand")))
19717	      (clobber (reg:CC FLAGS_REG))
19718	      (clobber (mem:BLK (scratch)))])]
19719  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19720   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19721   && ix86_red_zone_size == 0"
19722  [(clobber (match_dup 1))
19723   (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19724	      (clobber (mem:BLK (scratch)))])])
19725
19726(define_peephole2
19727  [(match_scratch:W 1 "r")
19728   (parallel [(set (reg:P SP_REG)
19729		   (plus:P (reg:P SP_REG)
19730			   (match_operand:P 0 "const_int_operand")))
19731	      (clobber (reg:CC FLAGS_REG))
19732	      (clobber (mem:BLK (scratch)))])]
19733  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19734   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19735   && ix86_red_zone_size == 0"
19736  [(clobber (match_dup 1))
19737   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19738   (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19739	      (clobber (mem:BLK (scratch)))])])
19740
19741;; Convert esp subtractions to push.
19742(define_peephole2
19743  [(match_scratch:W 1 "r")
19744   (parallel [(set (reg:P SP_REG)
19745		   (plus:P (reg:P SP_REG)
19746			   (match_operand:P 0 "const_int_operand")))
19747	      (clobber (reg:CC FLAGS_REG))])]
19748  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19749   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19750   && ix86_red_zone_size == 0"
19751  [(clobber (match_dup 1))
19752   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19753
19754(define_peephole2
19755  [(match_scratch:W 1 "r")
19756   (parallel [(set (reg:P SP_REG)
19757		   (plus:P (reg:P SP_REG)
19758			   (match_operand:P 0 "const_int_operand")))
19759	      (clobber (reg:CC FLAGS_REG))])]
19760  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19761   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19762   && ix86_red_zone_size == 0"
19763  [(clobber (match_dup 1))
19764   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19765   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19766
19767;; Convert epilogue deallocator to pop.
19768(define_peephole2
19769  [(match_scratch:W 1 "r")
19770   (parallel [(set (reg:P SP_REG)
19771		   (plus:P (reg:P SP_REG)
19772			   (match_operand:P 0 "const_int_operand")))
19773	      (clobber (reg:CC FLAGS_REG))
19774	      (clobber (mem:BLK (scratch)))])]
19775  "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19776   && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19777  [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19778	      (clobber (mem:BLK (scratch)))])])
19779
19780;; Two pops case is tricky, since pop causes dependency
19781;; on destination register.  We use two registers if available.
19782(define_peephole2
19783  [(match_scratch:W 1 "r")
19784   (match_scratch:W 2 "r")
19785   (parallel [(set (reg:P SP_REG)
19786		   (plus:P (reg:P SP_REG)
19787			   (match_operand:P 0 "const_int_operand")))
19788	      (clobber (reg:CC FLAGS_REG))
19789	      (clobber (mem:BLK (scratch)))])]
19790  "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19791   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19792  [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19793	      (clobber (mem:BLK (scratch)))])
19794   (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19795
19796(define_peephole2
19797  [(match_scratch:W 1 "r")
19798   (parallel [(set (reg:P SP_REG)
19799		   (plus:P (reg:P SP_REG)
19800			   (match_operand:P 0 "const_int_operand")))
19801	      (clobber (reg:CC FLAGS_REG))
19802	      (clobber (mem:BLK (scratch)))])]
19803  "optimize_insn_for_size_p ()
19804   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19805  [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19806	      (clobber (mem:BLK (scratch)))])
19807   (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19808
19809;; Convert esp additions to pop.
19810(define_peephole2
19811  [(match_scratch:W 1 "r")
19812   (parallel [(set (reg:P SP_REG)
19813		   (plus:P (reg:P SP_REG)
19814			   (match_operand:P 0 "const_int_operand")))
19815	      (clobber (reg:CC FLAGS_REG))])]
19816  "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19817  [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19818
19819;; Two pops case is tricky, since pop causes dependency
19820;; on destination register.  We use two registers if available.
19821(define_peephole2
19822  [(match_scratch:W 1 "r")
19823   (match_scratch:W 2 "r")
19824   (parallel [(set (reg:P SP_REG)
19825		   (plus:P (reg:P SP_REG)
19826			   (match_operand:P 0 "const_int_operand")))
19827	      (clobber (reg:CC FLAGS_REG))])]
19828  "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19829  [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19830   (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19831
19832(define_peephole2
19833  [(match_scratch:W 1 "r")
19834   (parallel [(set (reg:P SP_REG)
19835		   (plus:P (reg:P SP_REG)
19836			   (match_operand:P 0 "const_int_operand")))
19837	      (clobber (reg:CC FLAGS_REG))])]
19838  "optimize_insn_for_size_p ()
19839   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19840  [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19841   (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19842
19843;; Convert compares with 1 to shorter inc/dec operations when CF is not
19844;; required and register dies.  Similarly for 128 to -128.
19845(define_peephole2
19846  [(set (match_operand 0 "flags_reg_operand")
19847	(match_operator 1 "compare_operator"
19848	  [(match_operand 2 "register_operand")
19849	   (match_operand 3 "const_int_operand")]))]
19850  "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19851     && incdec_operand (operands[3], GET_MODE (operands[3])))
19852    || (!TARGET_FUSE_CMP_AND_BRANCH
19853	&& INTVAL (operands[3]) == 128))
19854   && ix86_match_ccmode (insn, CCGCmode)
19855   && peep2_reg_dead_p (1, operands[2])"
19856  [(parallel [(set (match_dup 0)
19857		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19858	      (clobber (match_dup 2))])])
19859
19860;; Convert imul by three, five and nine into lea
19861(define_peephole2
19862  [(parallel
19863    [(set (match_operand:SWI48 0 "register_operand")
19864	  (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19865		      (match_operand:SWI48 2 "const359_operand")))
19866     (clobber (reg:CC FLAGS_REG))])]
19867  "!TARGET_PARTIAL_REG_STALL
19868   || <MODE>mode == SImode
19869   || optimize_function_for_size_p (cfun)"
19870  [(set (match_dup 0)
19871	(plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19872		    (match_dup 1)))]
19873  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19874
19875(define_peephole2
19876  [(parallel
19877    [(set (match_operand:SWI48 0 "register_operand")
19878	  (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19879		      (match_operand:SWI48 2 "const359_operand")))
19880     (clobber (reg:CC FLAGS_REG))])]
19881  "optimize_insn_for_speed_p ()
19882   && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19883  [(set (match_dup 0) (match_dup 1))
19884   (set (match_dup 0)
19885	(plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19886		    (match_dup 0)))]
19887  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19888
19889;; imul $32bit_imm, mem, reg is vector decoded, while
19890;; imul $32bit_imm, reg, reg is direct decoded.
19891(define_peephole2
19892  [(match_scratch:SWI48 3 "r")
19893   (parallel [(set (match_operand:SWI48 0 "register_operand")
19894		   (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19895			       (match_operand:SWI48 2 "immediate_operand")))
19896	      (clobber (reg:CC FLAGS_REG))])]
19897  "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19898   && !satisfies_constraint_K (operands[2])"
19899  [(set (match_dup 3) (match_dup 1))
19900   (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19901	      (clobber (reg:CC FLAGS_REG))])])
19902
19903(define_peephole2
19904  [(match_scratch:SI 3 "r")
19905   (parallel [(set (match_operand:DI 0 "register_operand")
19906		   (zero_extend:DI
19907		     (mult:SI (match_operand:SI 1 "memory_operand")
19908			      (match_operand:SI 2 "immediate_operand"))))
19909	      (clobber (reg:CC FLAGS_REG))])]
19910  "TARGET_64BIT
19911   && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19912   && !satisfies_constraint_K (operands[2])"
19913  [(set (match_dup 3) (match_dup 1))
19914   (parallel [(set (match_dup 0)
19915		   (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19916	      (clobber (reg:CC FLAGS_REG))])])
19917
19918;; imul $8/16bit_imm, regmem, reg is vector decoded.
19919;; Convert it into imul reg, reg
19920;; It would be better to force assembler to encode instruction using long
19921;; immediate, but there is apparently no way to do so.
19922(define_peephole2
19923  [(parallel [(set (match_operand:SWI248 0 "register_operand")
19924		   (mult:SWI248
19925		    (match_operand:SWI248 1 "nonimmediate_operand")
19926		    (match_operand:SWI248 2 "const_int_operand")))
19927	      (clobber (reg:CC FLAGS_REG))])
19928   (match_scratch:SWI248 3 "r")]
19929  "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19930   && satisfies_constraint_K (operands[2])"
19931  [(set (match_dup 3) (match_dup 2))
19932   (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19933	      (clobber (reg:CC FLAGS_REG))])]
19934{
19935  if (!rtx_equal_p (operands[0], operands[1]))
19936    emit_move_insn (operands[0], operands[1]);
19937})
19938
19939;; After splitting up read-modify operations, array accesses with memory
19940;; operands might end up in form:
19941;;  sall    $2, %eax
19942;;  movl    4(%esp), %edx
19943;;  addl    %edx, %eax
19944;; instead of pre-splitting:
19945;;  sall    $2, %eax
19946;;  addl    4(%esp), %eax
19947;; Turn it into:
19948;;  movl    4(%esp), %edx
19949;;  leal    (%edx,%eax,4), %eax
19950
19951(define_peephole2
19952  [(match_scratch:W 5 "r")
19953   (parallel [(set (match_operand 0 "register_operand")
19954		   (ashift (match_operand 1 "register_operand")
19955			   (match_operand 2 "const_int_operand")))
19956	       (clobber (reg:CC FLAGS_REG))])
19957   (parallel [(set (match_operand 3 "register_operand")
19958		   (plus (match_dup 0)
19959			 (match_operand 4 "x86_64_general_operand")))
19960		   (clobber (reg:CC FLAGS_REG))])]
19961  "IN_RANGE (INTVAL (operands[2]), 1, 3)
19962   /* Validate MODE for lea.  */
19963   && ((!TARGET_PARTIAL_REG_STALL
19964	&& (GET_MODE (operands[0]) == QImode
19965	    || GET_MODE (operands[0]) == HImode))
19966       || GET_MODE (operands[0]) == SImode
19967       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19968   && (rtx_equal_p (operands[0], operands[3])
19969       || peep2_reg_dead_p (2, operands[0]))
19970   /* We reorder load and the shift.  */
19971   && !reg_overlap_mentioned_p (operands[0], operands[4])"
19972  [(set (match_dup 5) (match_dup 4))
19973   (set (match_dup 0) (match_dup 1))]
19974{
19975  machine_mode op1mode = GET_MODE (operands[1]);
19976  machine_mode mode = op1mode == DImode ? DImode : SImode;
19977  int scale = 1 << INTVAL (operands[2]);
19978  rtx index = gen_lowpart (word_mode, operands[1]);
19979  rtx base = gen_lowpart (word_mode, operands[5]);
19980  rtx dest = gen_lowpart (mode, operands[3]);
19981
19982  operands[1] = gen_rtx_PLUS (word_mode, base,
19983			      gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19984  if (mode != word_mode)
19985    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19986
19987  operands[5] = base;
19988  if (op1mode != word_mode)
19989    operands[5] = gen_lowpart (op1mode, operands[5]);
19990
19991  operands[0] = dest;
19992})
19993
19994;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19995;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19996;; caught for use by garbage collectors and the like.  Using an insn that
19997;; maps to SIGILL makes it more likely the program will rightfully die.
19998;; Keeping with tradition, "6" is in honor of #UD.
19999(define_insn "trap"
20000  [(trap_if (const_int 1) (const_int 6))]
20001  ""
20002{
20003#ifdef HAVE_AS_IX86_UD2
20004  return "ud2";
20005#else
20006  return ASM_SHORT "0x0b0f";
20007#endif
20008}
20009  [(set_attr "length" "2")])
20010
20011(define_insn "ud2"
20012  [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
20013  ""
20014{
20015#ifdef HAVE_AS_IX86_UD2
20016  return "ud2";
20017#else
20018  return ASM_SHORT "0x0b0f";
20019#endif
20020}
20021  [(set_attr "length" "2")])
20022
20023(define_expand "prefetch"
20024  [(prefetch (match_operand 0 "address_operand")
20025	     (match_operand:SI 1 "const_int_operand")
20026	     (match_operand:SI 2 "const_int_operand"))]
20027  "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20028{
20029  bool write = operands[1] != const0_rtx;
20030  int locality = INTVAL (operands[2]);
20031
20032  gcc_assert (IN_RANGE (locality, 0, 3));
20033
20034  /* Use 3dNOW prefetch in case we are asking for write prefetch not
20035     supported by SSE counterpart (non-SSE2 athlon machines) or the
20036     SSE prefetch is not available (K6 machines).  Otherwise use SSE
20037     prefetch as it allows specifying of locality.  */
20038
20039  if (write)
20040    {
20041      if (TARGET_PREFETCHWT1)
20042	operands[2] = GEN_INT (MAX (locality, 2)); 
20043      else if (TARGET_PRFCHW)
20044	operands[2] = GEN_INT (3);
20045      else if (TARGET_3DNOW && !TARGET_SSE2)
20046	operands[2] = GEN_INT (3);
20047      else if (TARGET_PREFETCH_SSE)
20048	operands[1] = const0_rtx;
20049      else
20050	{
20051	  gcc_assert (TARGET_3DNOW);
20052	  operands[2] = GEN_INT (3);
20053	}
20054    }
20055  else
20056    {
20057      if (TARGET_PREFETCH_SSE)
20058	;
20059      else
20060	{
20061	  gcc_assert (TARGET_3DNOW);
20062	  operands[2] = GEN_INT (3);
20063	}
20064    }
20065})
20066
20067(define_insn "*prefetch_sse"
20068  [(prefetch (match_operand 0 "address_operand" "p")
20069	     (const_int 0)
20070	     (match_operand:SI 1 "const_int_operand"))]
20071  "TARGET_PREFETCH_SSE"
20072{
20073  static const char * const patterns[4] = {
20074   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20075  };
20076
20077  int locality = INTVAL (operands[1]);
20078  gcc_assert (IN_RANGE (locality, 0, 3));
20079
20080  return patterns[locality];
20081}
20082  [(set_attr "type" "sse")
20083   (set_attr "atom_sse_attr" "prefetch")
20084   (set (attr "length_address")
20085	(symbol_ref "memory_address_length (operands[0], false)"))
20086   (set_attr "memory" "none")])
20087
20088(define_insn "*prefetch_3dnow"
20089  [(prefetch (match_operand 0 "address_operand" "p")
20090	     (match_operand:SI 1 "const_int_operand" "n")
20091	     (const_int 3))]
20092  "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20093{
20094  if (operands[1] == const0_rtx)
20095    return "prefetch\t%a0";
20096  else
20097    return "prefetchw\t%a0";
20098}
20099  [(set_attr "type" "mmx")
20100   (set (attr "length_address")
20101	(symbol_ref "memory_address_length (operands[0], false)"))
20102   (set_attr "memory" "none")])
20103
20104(define_insn "*prefetch_prefetchwt1"
20105  [(prefetch (match_operand 0 "address_operand" "p")
20106	     (const_int 1)
20107	     (const_int 2))]
20108  "TARGET_PREFETCHWT1"
20109  "prefetchwt1\t%a0";
20110  [(set_attr "type" "sse")
20111   (set (attr "length_address")
20112	(symbol_ref "memory_address_length (operands[0], false)"))
20113   (set_attr "memory" "none")])
20114
20115(define_expand "stack_protect_set"
20116  [(match_operand 0 "memory_operand")
20117   (match_operand 1 "memory_operand")]
20118  ""
20119{
20120  emit_insn (gen_stack_protect_set_1
20121	     (ptr_mode, operands[0], operands[1]));
20122  DONE;
20123})
20124
20125(define_insn "@stack_protect_set_1_<mode>"
20126  [(set (match_operand:PTR 0 "memory_operand" "=m")
20127	(unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
20128		    UNSPEC_SP_SET))
20129   (set (match_scratch:PTR 2 "=&r") (const_int 0))
20130   (clobber (reg:CC FLAGS_REG))]
20131  ""
20132{
20133  output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
20134  output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
20135  return "xor{l}\t%k2, %k2";
20136}
20137  [(set_attr "type" "multi")])
20138
20139;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
20140;; immediately followed by *mov{s,d}i_internal to the same register,
20141;; where we can avoid the xor{l} above.  We don't split this, so that
20142;; scheduling or anything else doesn't separate the *stack_protect_set*
20143;; pattern from the set of the register that overwrites the register
20144;; with a new value.
20145(define_insn "*stack_protect_set_2_<mode>"
20146  [(set (match_operand:PTR 0 "memory_operand" "=m")
20147	(unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
20148		    UNSPEC_SP_SET))
20149   (set (match_operand:SI 1 "register_operand" "=&r")
20150	(match_operand:SI 2 "general_operand" "g"))
20151   (clobber (reg:CC FLAGS_REG))]
20152  "reload_completed
20153   && !reg_overlap_mentioned_p (operands[1], operands[2])"
20154{
20155  output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
20156  output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
20157  if (pic_32bit_operand (operands[2], SImode)
20158      || ix86_use_lea_for_mov (insn, operands + 1))
20159    return "lea{l}\t{%E2, %1|%1, %E2}";
20160  else
20161    return "mov{l}\t{%2, %1|%1, %2}";
20162}
20163  [(set_attr "type" "multi")
20164   (set_attr "length" "24")])
20165
20166(define_peephole2
20167 [(parallel [(set (match_operand:PTR 0 "memory_operand")
20168		  (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
20169			      UNSPEC_SP_SET))
20170	     (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
20171	     (clobber (reg:CC FLAGS_REG))])
20172  (set (match_operand:SI 3 "general_reg_operand")
20173       (match_operand:SI 4))]
20174 "REGNO (operands[2]) == REGNO (operands[3])
20175  && general_operand (operands[4], SImode)
20176  && (general_reg_operand (operands[4], SImode)
20177      || memory_operand (operands[4], SImode)
20178      || immediate_operand (operands[4], SImode))
20179  && !reg_overlap_mentioned_p (operands[3], operands[4])"
20180 [(parallel [(set (match_dup 0)
20181		  (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
20182	     (set (match_dup 3) (match_dup 4))
20183	     (clobber (reg:CC FLAGS_REG))])])
20184
20185(define_insn "*stack_protect_set_3"
20186  [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
20187	(unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
20188		   UNSPEC_SP_SET))
20189   (set (match_operand:DI 1 "register_operand" "=&r,r,r")
20190	(match_operand:DI 2 "general_operand" "Z,rem,i"))
20191   (clobber (reg:CC FLAGS_REG))]
20192  "TARGET_64BIT
20193   && reload_completed
20194   && !reg_overlap_mentioned_p (operands[1], operands[2])"
20195{
20196  output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
20197  output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
20198  if (pic_32bit_operand (operands[2], DImode))
20199    return "lea{q}\t{%E2, %1|%1, %E2}";
20200  else if (which_alternative == 0)
20201    return "mov{l}\t{%k2, %k1|%k1, %k2}";
20202  else if (which_alternative == 2)
20203    return "movabs{q}\t{%2, %1|%1, %2}";
20204  else if (ix86_use_lea_for_mov (insn, operands + 1))
20205    return "lea{q}\t{%E2, %1|%1, %E2}";
20206  else
20207    return "mov{q}\t{%2, %1|%1, %2}";
20208}
20209  [(set_attr "type" "multi")
20210   (set_attr "length" "24")])
20211
20212(define_peephole2
20213 [(parallel [(set (match_operand:DI 0 "memory_operand")
20214		  (unspec:DI [(match_operand:DI 1 "memory_operand")]
20215			     UNSPEC_SP_SET))
20216	     (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
20217	     (clobber (reg:CC FLAGS_REG))])
20218  (set (match_dup 2) (match_operand:DI 3))]
20219 "TARGET_64BIT
20220  && general_operand (operands[3], DImode)
20221  && (general_reg_operand (operands[3], DImode)
20222      || memory_operand (operands[3], DImode)
20223      || x86_64_zext_immediate_operand (operands[3], DImode)
20224      || x86_64_immediate_operand (operands[3], DImode)
20225      || (CONSTANT_P (operands[3])
20226	  && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
20227  && !reg_overlap_mentioned_p (operands[2], operands[3])"
20228 [(parallel [(set (match_dup 0)
20229		  (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
20230	     (set (match_dup 2) (match_dup 3))
20231	     (clobber (reg:CC FLAGS_REG))])])
20232
20233(define_expand "stack_protect_test"
20234  [(match_operand 0 "memory_operand")
20235   (match_operand 1 "memory_operand")
20236   (match_operand 2)]
20237  ""
20238{
20239  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20240
20241  emit_insn (gen_stack_protect_test_1
20242	     (ptr_mode, flags, operands[0], operands[1]));
20243
20244  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20245				  flags, const0_rtx, operands[2]));
20246  DONE;
20247})
20248
20249(define_insn "@stack_protect_test_1_<mode>"
20250  [(set (match_operand:CCZ 0 "flags_reg_operand")
20251	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20252		     (match_operand:PTR 2 "memory_operand" "m")]
20253		    UNSPEC_SP_TEST))
20254   (clobber (match_scratch:PTR 3 "=&r"))]
20255  ""
20256{
20257  output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
20258  return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
20259}
20260  [(set_attr "type" "multi")])
20261
20262(define_insn "sse4_2_crc32<mode>"
20263  [(set (match_operand:SI 0 "register_operand" "=r")
20264	(unspec:SI
20265	  [(match_operand:SI 1 "register_operand" "0")
20266	   (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20267	  UNSPEC_CRC32))]
20268  "TARGET_SSE4_2 || TARGET_CRC32"
20269  "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20270  [(set_attr "type" "sselog1")
20271   (set_attr "prefix_rep" "1")
20272   (set_attr "prefix_extra" "1")
20273   (set (attr "prefix_data16")
20274     (if_then_else (match_operand:HI 2)
20275       (const_string "1")
20276       (const_string "*")))
20277   (set (attr "prefix_rex")
20278     (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20279       (const_string "1")
20280       (const_string "*")))
20281   (set_attr "mode" "SI")])
20282
20283(define_insn "sse4_2_crc32di"
20284  [(set (match_operand:DI 0 "register_operand" "=r")
20285	(unspec:DI
20286	  [(match_operand:DI 1 "register_operand" "0")
20287	   (match_operand:DI 2 "nonimmediate_operand" "rm")]
20288	  UNSPEC_CRC32))]
20289  "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20290  "crc32{q}\t{%2, %0|%0, %2}"
20291  [(set_attr "type" "sselog1")
20292   (set_attr "prefix_rep" "1")
20293   (set_attr "prefix_extra" "1")
20294   (set_attr "mode" "DI")])
20295
20296(define_insn "rdpmc"
20297  [(set (match_operand:DI 0 "register_operand" "=A")
20298  	(unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20299			    UNSPECV_RDPMC))]
20300  "!TARGET_64BIT"
20301  "rdpmc"
20302  [(set_attr "type" "other")
20303   (set_attr "length" "2")])
20304
20305(define_insn "rdpmc_rex64"
20306  [(set (match_operand:DI 0 "register_operand" "=a")
20307  	(unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20308			    UNSPECV_RDPMC))
20309   (set (match_operand:DI 1 "register_operand" "=d")
20310	(unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
20311  "TARGET_64BIT"
20312  "rdpmc"
20313  [(set_attr "type" "other")
20314   (set_attr "length" "2")])
20315
20316(define_insn "rdtsc"
20317  [(set (match_operand:DI 0 "register_operand" "=A")
20318	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20319  "!TARGET_64BIT"
20320  "rdtsc"
20321  [(set_attr "type" "other")
20322   (set_attr "length" "2")])
20323
20324(define_insn "rdtsc_rex64"
20325  [(set (match_operand:DI 0 "register_operand" "=a")
20326	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20327   (set (match_operand:DI 1 "register_operand" "=d")
20328	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20329  "TARGET_64BIT"
20330  "rdtsc"
20331  [(set_attr "type" "other")
20332   (set_attr "length" "2")])
20333
20334(define_insn "rdtscp"
20335  [(set (match_operand:DI 0 "register_operand" "=A")
20336	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20337   (set (match_operand:SI 1 "register_operand" "=c")
20338	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20339  "!TARGET_64BIT"
20340  "rdtscp"
20341  [(set_attr "type" "other")
20342   (set_attr "length" "3")])
20343
20344(define_insn "rdtscp_rex64"
20345  [(set (match_operand:DI 0 "register_operand" "=a")
20346	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20347   (set (match_operand:DI 1 "register_operand" "=d")
20348	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20349   (set (match_operand:SI 2 "register_operand" "=c")
20350	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20351  "TARGET_64BIT"
20352  "rdtscp"
20353  [(set_attr "type" "other")
20354   (set_attr "length" "3")])
20355
20356;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20357;;
20358;; FXSR, XSAVE and XSAVEOPT instructions
20359;;
20360;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20361
20362(define_insn "fxsave"
20363  [(set (match_operand:BLK 0 "memory_operand" "=m")
20364	(unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20365  "TARGET_FXSR"
20366  "fxsave\t%0"
20367  [(set_attr "type" "other")
20368   (set_attr "memory" "store")
20369   (set (attr "length")
20370        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20371
20372(define_insn "fxsave64"
20373  [(set (match_operand:BLK 0 "memory_operand" "=m")
20374	(unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20375  "TARGET_64BIT && TARGET_FXSR"
20376  "fxsave64\t%0"
20377  [(set_attr "type" "other")
20378   (set_attr "memory" "store")
20379   (set (attr "length")
20380        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20381
20382(define_insn "fxrstor"
20383  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20384		    UNSPECV_FXRSTOR)]
20385  "TARGET_FXSR"
20386  "fxrstor\t%0"
20387  [(set_attr "type" "other")
20388   (set_attr "memory" "load")
20389   (set (attr "length")
20390        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20391
20392(define_insn "fxrstor64"
20393  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20394		    UNSPECV_FXRSTOR64)]
20395  "TARGET_64BIT && TARGET_FXSR"
20396  "fxrstor64\t%0"
20397  [(set_attr "type" "other")
20398   (set_attr "memory" "load")
20399   (set (attr "length")
20400        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20401
20402(define_int_iterator ANY_XSAVE
20403	[UNSPECV_XSAVE
20404	 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20405	 (UNSPECV_XSAVEC "TARGET_XSAVEC")
20406	 (UNSPECV_XSAVES "TARGET_XSAVES")])
20407
20408(define_int_iterator ANY_XSAVE64
20409	[UNSPECV_XSAVE64
20410	 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20411	 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20412	 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20413
20414(define_int_attr xsave
20415	[(UNSPECV_XSAVE "xsave")
20416	 (UNSPECV_XSAVE64 "xsave64")
20417	 (UNSPECV_XSAVEOPT "xsaveopt")
20418	 (UNSPECV_XSAVEOPT64 "xsaveopt64")
20419	 (UNSPECV_XSAVEC "xsavec")
20420	 (UNSPECV_XSAVEC64 "xsavec64")
20421	 (UNSPECV_XSAVES "xsaves")
20422	 (UNSPECV_XSAVES64 "xsaves64")])
20423
20424(define_int_iterator ANY_XRSTOR
20425	[UNSPECV_XRSTOR
20426	 (UNSPECV_XRSTORS "TARGET_XSAVES")])
20427
20428(define_int_iterator ANY_XRSTOR64
20429	[UNSPECV_XRSTOR64
20430	 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20431
20432(define_int_attr xrstor
20433	[(UNSPECV_XRSTOR "xrstor")
20434	 (UNSPECV_XRSTOR64 "xrstor")
20435	 (UNSPECV_XRSTORS "xrstors")
20436	 (UNSPECV_XRSTORS64 "xrstors")])
20437
20438(define_insn "<xsave>"
20439  [(set (match_operand:BLK 0 "memory_operand" "=m")
20440	(unspec_volatile:BLK
20441	 [(match_operand:DI 1 "register_operand" "A")]
20442	 ANY_XSAVE))]
20443  "!TARGET_64BIT && TARGET_XSAVE"
20444  "<xsave>\t%0"
20445  [(set_attr "type" "other")
20446   (set_attr "memory" "store")
20447   (set (attr "length")
20448        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20449
20450(define_insn "<xsave>_rex64"
20451  [(set (match_operand:BLK 0 "memory_operand" "=m")
20452	(unspec_volatile:BLK
20453	 [(match_operand:SI 1 "register_operand" "a")
20454	  (match_operand:SI 2 "register_operand" "d")]
20455	 ANY_XSAVE))]
20456  "TARGET_64BIT && TARGET_XSAVE"
20457  "<xsave>\t%0"
20458  [(set_attr "type" "other")
20459   (set_attr "memory" "store")
20460   (set (attr "length")
20461        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20462
20463(define_insn "<xsave>"
20464  [(set (match_operand:BLK 0 "memory_operand" "=m")
20465	(unspec_volatile:BLK
20466	 [(match_operand:SI 1 "register_operand" "a")
20467	  (match_operand:SI 2 "register_operand" "d")]
20468	 ANY_XSAVE64))]
20469  "TARGET_64BIT && TARGET_XSAVE"
20470  "<xsave>\t%0"
20471  [(set_attr "type" "other")
20472   (set_attr "memory" "store")
20473   (set (attr "length")
20474        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20475
20476(define_insn "<xrstor>"
20477   [(unspec_volatile:BLK
20478     [(match_operand:BLK 0 "memory_operand" "m")
20479      (match_operand:DI 1 "register_operand" "A")]
20480     ANY_XRSTOR)]
20481  "!TARGET_64BIT && TARGET_XSAVE"
20482  "<xrstor>\t%0"
20483  [(set_attr "type" "other")
20484   (set_attr "memory" "load")
20485   (set (attr "length")
20486        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20487
20488(define_insn "<xrstor>_rex64"
20489   [(unspec_volatile:BLK
20490     [(match_operand:BLK 0 "memory_operand" "m")
20491      (match_operand:SI 1 "register_operand" "a")
20492      (match_operand:SI 2 "register_operand" "d")]
20493     ANY_XRSTOR)]
20494  "TARGET_64BIT && TARGET_XSAVE"
20495  "<xrstor>\t%0"
20496  [(set_attr "type" "other")
20497   (set_attr "memory" "load")
20498   (set (attr "length")
20499        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20500
20501(define_insn "<xrstor>64"
20502   [(unspec_volatile:BLK
20503     [(match_operand:BLK 0 "memory_operand" "m")
20504      (match_operand:SI 1 "register_operand" "a")
20505      (match_operand:SI 2 "register_operand" "d")]
20506     ANY_XRSTOR64)]
20507  "TARGET_64BIT && TARGET_XSAVE"
20508  "<xrstor>64\t%0"
20509  [(set_attr "type" "other")
20510   (set_attr "memory" "load")
20511   (set (attr "length")
20512        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20513
20514(define_insn "xsetbv"
20515  [(unspec_volatile:SI
20516	 [(match_operand:SI 0 "register_operand" "c")
20517	  (match_operand:DI 1 "register_operand" "A")]
20518	 UNSPECV_XSETBV)]
20519  "!TARGET_64BIT && TARGET_XSAVE"
20520  "xsetbv"
20521  [(set_attr "type" "other")])
20522
20523(define_insn "xsetbv_rex64"
20524  [(unspec_volatile:SI
20525	 [(match_operand:SI 0 "register_operand" "c")
20526	  (match_operand:SI 1 "register_operand" "a")
20527	  (match_operand:SI 2 "register_operand" "d")]
20528	 UNSPECV_XSETBV)]
20529  "TARGET_64BIT && TARGET_XSAVE"
20530  "xsetbv"
20531  [(set_attr "type" "other")])
20532
20533(define_insn "xgetbv"
20534  [(set (match_operand:DI 0 "register_operand" "=A")
20535  	(unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20536			    UNSPECV_XGETBV))]
20537  "!TARGET_64BIT && TARGET_XSAVE"
20538  "xgetbv"
20539  [(set_attr "type" "other")])
20540
20541(define_insn "xgetbv_rex64"
20542  [(set (match_operand:DI 0 "register_operand" "=a")
20543  	(unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20544			    UNSPECV_XGETBV))
20545   (set (match_operand:DI 1 "register_operand" "=d")
20546	(unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20547  "TARGET_64BIT && TARGET_XSAVE"
20548  "xgetbv"
20549  [(set_attr "type" "other")])
20550
20551;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20552;;
20553;; Floating-point instructions for atomic compound assignments
20554;;
20555;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20556
20557; Clobber all floating-point registers on environment save and restore
20558; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20559(define_insn "fnstenv"
20560  [(set (match_operand:BLK 0 "memory_operand" "=m")
20561	(unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20562   (clobber (reg:XF ST0_REG))
20563   (clobber (reg:XF ST1_REG))
20564   (clobber (reg:XF ST2_REG))
20565   (clobber (reg:XF ST3_REG))
20566   (clobber (reg:XF ST4_REG))
20567   (clobber (reg:XF ST5_REG))
20568   (clobber (reg:XF ST6_REG))
20569   (clobber (reg:XF ST7_REG))]
20570  "TARGET_80387"
20571  "fnstenv\t%0"
20572  [(set_attr "type" "other")
20573   (set_attr "memory" "store")
20574   (set (attr "length")
20575        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20576
20577(define_insn "fldenv"
20578  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20579		    UNSPECV_FLDENV)
20580   (clobber (reg:XF ST0_REG))
20581   (clobber (reg:XF ST1_REG))
20582   (clobber (reg:XF ST2_REG))
20583   (clobber (reg:XF ST3_REG))
20584   (clobber (reg:XF ST4_REG))
20585   (clobber (reg:XF ST5_REG))
20586   (clobber (reg:XF ST6_REG))
20587   (clobber (reg:XF ST7_REG))]
20588  "TARGET_80387"
20589  "fldenv\t%0"
20590  [(set_attr "type" "other")
20591   (set_attr "memory" "load")
20592   (set (attr "length")
20593        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20594
20595(define_insn "fnstsw"
20596  [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20597	(unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20598  "TARGET_80387"
20599  "fnstsw\t%0"
20600  [(set_attr "type" "other,other")
20601   (set_attr "memory" "none,store")
20602   (set (attr "length")
20603        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20604
20605(define_insn "fnclex"
20606  [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20607  "TARGET_80387"
20608  "fnclex"
20609  [(set_attr "type" "other")
20610   (set_attr "memory" "none")
20611   (set_attr "length" "2")])
20612
20613;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20614;;
20615;; LWP instructions
20616;;
20617;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20618
20619(define_expand "lwp_llwpcb"
20620  [(unspec_volatile [(match_operand 0 "register_operand")]
20621		    UNSPECV_LLWP_INTRINSIC)]
20622  "TARGET_LWP")
20623
20624(define_insn "*lwp_llwpcb<mode>_1"
20625  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20626		    UNSPECV_LLWP_INTRINSIC)]
20627  "TARGET_LWP"
20628  "llwpcb\t%0"
20629  [(set_attr "type" "lwp")
20630   (set_attr "mode" "<MODE>")
20631   (set_attr "length" "5")])
20632
20633(define_expand "lwp_slwpcb"
20634  [(set (match_operand 0 "register_operand")
20635	(unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20636  "TARGET_LWP"
20637  "emit_insn (gen_lwp_slwpcb_1 (Pmode, operands[0])); DONE;")
20638
20639(define_insn "@lwp_slwpcb<mode>_1"
20640  [(set (match_operand:P 0 "register_operand" "=r")
20641	(unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20642  "TARGET_LWP"
20643  "slwpcb\t%0"
20644  [(set_attr "type" "lwp")
20645   (set_attr "mode" "<MODE>")
20646   (set_attr "length" "5")])
20647
20648(define_expand "lwp_lwpval<mode>3"
20649  [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20650    	    	     (match_operand:SI 2 "nonimmediate_operand")
20651		     (match_operand:SI 3 "const_int_operand")]
20652		    UNSPECV_LWPVAL_INTRINSIC)]
20653  "TARGET_LWP"
20654  ;; Avoid unused variable warning.
20655  "(void) operands[0];")
20656
20657(define_insn "*lwp_lwpval<mode>3_1"
20658  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20659    	    	     (match_operand:SI 1 "nonimmediate_operand" "rm")
20660		     (match_operand:SI 2 "const_int_operand" "i")]
20661		    UNSPECV_LWPVAL_INTRINSIC)]
20662  "TARGET_LWP"
20663  "lwpval\t{%2, %1, %0|%0, %1, %2}"
20664  [(set_attr "type" "lwp")
20665   (set_attr "mode" "<MODE>")
20666   (set (attr "length")
20667        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20668
20669(define_expand "lwp_lwpins<mode>3"
20670  [(set (reg:CCC FLAGS_REG)
20671	(unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20672			      (match_operand:SI 2 "nonimmediate_operand")
20673			      (match_operand:SI 3 "const_int_operand")]
20674			     UNSPECV_LWPINS_INTRINSIC))
20675   (set (match_operand:QI 0 "nonimmediate_operand")
20676	(eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20677  "TARGET_LWP")
20678
20679(define_insn "*lwp_lwpins<mode>3_1"
20680  [(set (reg:CCC FLAGS_REG)
20681	(unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20682			      (match_operand:SI 1 "nonimmediate_operand" "rm")
20683			      (match_operand:SI 2 "const_int_operand" "i")]
20684			     UNSPECV_LWPINS_INTRINSIC))]
20685  "TARGET_LWP"
20686  "lwpins\t{%2, %1, %0|%0, %1, %2}"
20687  [(set_attr "type" "lwp")
20688   (set_attr "mode" "<MODE>")
20689   (set (attr "length")
20690        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20691
20692(define_int_iterator RDFSGSBASE
20693	[UNSPECV_RDFSBASE
20694	 UNSPECV_RDGSBASE])
20695
20696(define_int_iterator WRFSGSBASE
20697	[UNSPECV_WRFSBASE
20698	 UNSPECV_WRGSBASE])
20699
20700(define_int_attr fsgs
20701	[(UNSPECV_RDFSBASE "fs")
20702	 (UNSPECV_RDGSBASE "gs")
20703	 (UNSPECV_WRFSBASE "fs")
20704	 (UNSPECV_WRGSBASE "gs")])
20705
20706(define_insn "rd<fsgs>base<mode>"
20707  [(set (match_operand:SWI48 0 "register_operand" "=r")
20708	(unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20709  "TARGET_64BIT && TARGET_FSGSBASE"
20710  "rd<fsgs>base\t%0"
20711  [(set_attr "type" "other")
20712   (set_attr "prefix_extra" "2")])
20713
20714(define_insn "wr<fsgs>base<mode>"
20715  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20716		    WRFSGSBASE)]
20717  "TARGET_64BIT && TARGET_FSGSBASE"
20718  "wr<fsgs>base\t%0"
20719  [(set_attr "type" "other")
20720   (set_attr "prefix_extra" "2")])
20721
20722(define_insn "ptwrite<mode>"
20723  [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
20724		    UNSPECV_PTWRITE)]
20725  "TARGET_PTWRITE"
20726  "ptwrite\t%0"
20727  [(set_attr "type" "other")
20728   (set_attr "prefix_extra" "2")])
20729
20730(define_insn "rdrand<mode>_1"
20731  [(set (match_operand:SWI248 0 "register_operand" "=r")
20732	(unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20733   (set (reg:CCC FLAGS_REG)
20734	(unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20735  "TARGET_RDRND"
20736  "rdrand\t%0"
20737  [(set_attr "type" "other")
20738   (set_attr "prefix_extra" "1")])
20739
20740(define_insn "rdseed<mode>_1"
20741  [(set (match_operand:SWI248 0 "register_operand" "=r")
20742	(unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20743   (set (reg:CCC FLAGS_REG)
20744	(unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20745  "TARGET_RDSEED"
20746  "rdseed\t%0"
20747  [(set_attr "type" "other")
20748   (set_attr "prefix_extra" "1")])
20749
20750(define_expand "pause"
20751  [(set (match_dup 0)
20752	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20753  ""
20754{
20755  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20756  MEM_VOLATILE_P (operands[0]) = 1;
20757})
20758
20759;; Use "rep; nop", instead of "pause", to support older assemblers.
20760;; They have the same encoding.
20761(define_insn "*pause"
20762  [(set (match_operand:BLK 0)
20763	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20764  ""
20765  "rep%; nop"
20766  [(set_attr "length" "2")
20767   (set_attr "memory" "unknown")])
20768
20769;; CET instructions
20770(define_insn "rdssp<mode>"
20771  [(set (match_operand:SWI48x 0 "register_operand" "=r")
20772	(unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20773  "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20774  "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20775  [(set_attr "length" "6")
20776   (set_attr "type" "other")])
20777
20778(define_insn "incssp<mode>"
20779  [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20780		    UNSPECV_INCSSP)]
20781  "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20782  "incssp<mskmodesuffix>\t%0"
20783  [(set_attr "length" "4")
20784   (set_attr "type" "other")])
20785
20786(define_insn "saveprevssp"
20787  [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20788  "TARGET_SHSTK"
20789  "saveprevssp"
20790  [(set_attr "length" "5")
20791   (set_attr "type" "other")])
20792
20793(define_expand "rstorssp"
20794  [(unspec_volatile [(match_operand 0 "memory_operand")]
20795		    UNSPECV_RSTORSSP)]
20796  "TARGET_SHSTK")
20797
20798(define_insn "*rstorssp<mode>"
20799  [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20800		    UNSPECV_RSTORSSP)]
20801  "TARGET_SHSTK"
20802  "rstorssp\t%0"
20803  [(set_attr "length" "5")
20804   (set_attr "type" "other")])
20805
20806(define_insn "wrss<mode>"
20807  [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20808		     (match_operand:SWI48x 1 "memory_operand" "m")]
20809		    UNSPECV_WRSS)]
20810  "TARGET_SHSTK"
20811  "wrss<mskmodesuffix>\t%0, %1"
20812  [(set_attr "length" "3")
20813   (set_attr "type" "other")])
20814
20815(define_insn "wruss<mode>"
20816  [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20817		     (match_operand:SWI48x 1 "memory_operand" "m")]
20818		    UNSPECV_WRUSS)]
20819  "TARGET_SHSTK"
20820  "wruss<mskmodesuffix>\t%0, %1"
20821  [(set_attr "length" "4")
20822   (set_attr "type" "other")])
20823
20824(define_insn "setssbsy"
20825  [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20826  "TARGET_SHSTK"
20827  "setssbsy"
20828  [(set_attr "length" "4")
20829   (set_attr "type" "other")])
20830
20831(define_expand "clrssbsy"
20832  [(unspec_volatile [(match_operand 0 "memory_operand")]
20833		    UNSPECV_CLRSSBSY)]
20834  "TARGET_SHSTK")
20835
20836(define_insn "*clrssbsy<mode>"
20837  [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20838		    UNSPECV_CLRSSBSY)]
20839  "TARGET_SHSTK"
20840  "clrssbsy\t%0"
20841  [(set_attr "length" "4")
20842   (set_attr "type" "other")])
20843
20844(define_insn "nop_endbr"
20845  [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20846  "(flag_cf_protection & CF_BRANCH)"
20847{
20848  return TARGET_64BIT ? "endbr64" : "endbr32";
20849}
20850  [(set_attr "length" "4")
20851   (set_attr "length_immediate" "0")
20852   (set_attr "modrm" "0")])
20853
20854;; For RTM support
20855(define_expand "xbegin"
20856  [(set (match_operand:SI 0 "register_operand")
20857	(unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20858  "TARGET_RTM"
20859{
20860  rtx_code_label *label = gen_label_rtx ();
20861
20862  /* xbegin is emitted as jump_insn, so reload won't be able
20863     to reload its operand.  Force the value into AX hard register.  */
20864  rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20865  emit_move_insn (ax_reg, constm1_rtx);
20866
20867  emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20868
20869  emit_label (label);
20870  LABEL_NUSES (label) = 1;
20871
20872  emit_move_insn (operands[0], ax_reg);
20873
20874  DONE;
20875})
20876
20877(define_insn "xbegin_1"
20878  [(set (pc)
20879	(if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20880			  (const_int 0))
20881		      (label_ref (match_operand 1))
20882		      (pc)))
20883   (set (match_operand:SI 0 "register_operand" "+a")
20884	(unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20885  "TARGET_RTM"
20886  "xbegin\t%l1"
20887  [(set_attr "type" "other")
20888   (set_attr "length" "6")])
20889
20890(define_insn "xend"
20891  [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20892  "TARGET_RTM"
20893  "xend"
20894  [(set_attr "type" "other")
20895   (set_attr "length" "3")])
20896
20897(define_insn "xabort"
20898  [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20899		    UNSPECV_XABORT)]
20900  "TARGET_RTM"
20901  "xabort\t%0"
20902  [(set_attr "type" "other")
20903   (set_attr "length" "3")])
20904
20905(define_expand "xtest"
20906  [(set (match_operand:QI 0 "register_operand")
20907	(unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20908  "TARGET_RTM"
20909{
20910  emit_insn (gen_xtest_1 ());
20911
20912  ix86_expand_setcc (operands[0], NE,
20913		     gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20914  DONE;
20915})
20916
20917(define_insn "xtest_1"
20918  [(set (reg:CCZ FLAGS_REG)
20919	(unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20920  "TARGET_RTM"
20921  "xtest"
20922  [(set_attr "type" "other")
20923   (set_attr "length" "3")])
20924
20925(define_insn "clwb"
20926  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20927                   UNSPECV_CLWB)]
20928  "TARGET_CLWB"
20929  "clwb\t%a0"
20930  [(set_attr "type" "sse")
20931   (set_attr "atom_sse_attr" "fence")
20932   (set_attr "memory" "unknown")])
20933
20934(define_insn "clflushopt"
20935  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20936                   UNSPECV_CLFLUSHOPT)]
20937  "TARGET_CLFLUSHOPT"
20938  "clflushopt\t%a0"
20939  [(set_attr "type" "sse")
20940   (set_attr "atom_sse_attr" "fence")
20941   (set_attr "memory" "unknown")])
20942
20943;; MONITORX and MWAITX
20944(define_insn "mwaitx"
20945  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20946		     (match_operand:SI 1 "register_operand" "a")
20947		     (match_operand:SI 2 "register_operand" "b")]
20948		   UNSPECV_MWAITX)]
20949  "TARGET_MWAITX"
20950;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20951;; Since 32bit register operands are implicitly zero extended to 64bit,
20952;; we only need to set up 32bit registers.
20953  "mwaitx"
20954  [(set_attr "length" "3")])
20955
20956(define_insn "@monitorx_<mode>"
20957  [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20958		     (match_operand:SI 1 "register_operand" "c")
20959		     (match_operand:SI 2 "register_operand" "d")]
20960		   UNSPECV_MONITORX)]
20961  "TARGET_MWAITX"
20962;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20963;; RCX and RDX are used.  Since 32bit register operands are implicitly
20964;; zero extended to 64bit, we only need to set up 32bit registers.
20965  "%^monitorx"
20966  [(set (attr "length")
20967     (symbol_ref ("(Pmode != word_mode) + 3")))])
20968
20969;; CLZERO
20970(define_insn "@clzero_<mode>"
20971  [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20972                   UNSPECV_CLZERO)]
20973  "TARGET_CLZERO"
20974  "clzero"
20975  [(set_attr "length" "3")
20976  (set_attr "memory" "unknown")])
20977
20978;; RDPKRU and WRPKRU
20979
20980(define_expand "rdpkru"
20981  [(parallel
20982     [(set (match_operand:SI 0 "register_operand")
20983	   (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20984      (set (match_dup 2) (const_int 0))])]
20985  "TARGET_PKU"
20986{
20987  operands[1] = force_reg (SImode, const0_rtx);
20988  operands[2] = gen_reg_rtx (SImode);
20989})
20990
20991(define_insn "*rdpkru"
20992  [(set (match_operand:SI 0 "register_operand" "=a")
20993	(unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20994			    UNSPECV_PKU))
20995   (set (match_operand:SI 1 "register_operand" "=d")
20996	(const_int 0))]
20997  "TARGET_PKU"
20998  "rdpkru"
20999  [(set_attr "type" "other")])
21000
21001(define_expand "wrpkru"
21002  [(unspec_volatile:SI
21003     [(match_operand:SI 0 "register_operand")
21004      (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
21005  "TARGET_PKU"
21006{
21007  operands[1] = force_reg (SImode, const0_rtx);
21008  operands[2] = force_reg (SImode, const0_rtx);
21009})
21010
21011(define_insn "*wrpkru"
21012  [(unspec_volatile:SI
21013     [(match_operand:SI 0 "register_operand" "a")
21014      (match_operand:SI 1 "register_operand" "d")
21015      (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
21016  "TARGET_PKU"
21017  "wrpkru"
21018  [(set_attr "type" "other")])
21019
21020(define_insn "rdpid"
21021  [(set (match_operand:SI 0 "register_operand" "=r")
21022	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
21023  "!TARGET_64BIT && TARGET_RDPID"
21024  "rdpid\t%0"
21025  [(set_attr "type" "other")])
21026
21027(define_insn "rdpid_rex64"
21028  [(set (match_operand:DI 0 "register_operand" "=r")
21029	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
21030  "TARGET_64BIT && TARGET_RDPID"
21031  "rdpid\t%0"
21032  [(set_attr "type" "other")])
21033
21034;; Intirinsics for > i486
21035
21036(define_insn "wbinvd"
21037  [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
21038  ""
21039  "wbinvd"
21040  [(set_attr "type" "other")])
21041
21042(define_insn "wbnoinvd"
21043  [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
21044  "TARGET_WBNOINVD"
21045  "wbnoinvd"
21046  [(set_attr "type" "other")])
21047
21048;; MOVDIRI and MOVDIR64B
21049
21050(define_insn "movdiri<mode>"
21051  [(set (match_operand:SWI48 0 "memory_operand" "=m")
21052	(unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
21053		      UNSPEC_MOVDIRI))]
21054  "TARGET_MOVDIRI"
21055  "movdiri\t{%1, %0|%0, %1}"
21056  [(set_attr "type" "other")])
21057
21058(define_insn "@movdir64b_<mode>"
21059  [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
21060	(unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
21061		   UNSPEC_MOVDIR64B))]
21062  "TARGET_MOVDIR64B"
21063  "movdir64b\t{%1, %0|%0, %1}"
21064  [(set_attr "type" "other")])
21065
21066;; ENQCMD and ENQCMDS
21067
21068(define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
21069(define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
21070
21071(define_insn "@enqcmd<enqcmd_sfx>_<mode>"
21072  [(set (reg:CCZ FLAGS_REG)
21073	(unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
21074			      (match_operand:XI 1 "memory_operand" "m")]
21075			     ENQCMD))]
21076  "TARGET_ENQCMD"
21077  "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
21078  [(set_attr "type" "other")])
21079
21080;; WAITPKG
21081
21082(define_insn "umwait"
21083  [(set (reg:CCC FLAGS_REG)
21084	(unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21085			      (match_operand:DI 1 "register_operand" "A")]
21086			     UNSPECV_UMWAIT))]
21087  "!TARGET_64BIT && TARGET_WAITPKG"
21088  "umwait\t%0"
21089  [(set_attr "length" "3")])
21090
21091(define_insn "umwait_rex64"
21092  [(set (reg:CCC FLAGS_REG)
21093	(unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21094			      (match_operand:SI 1 "register_operand" "a")
21095			      (match_operand:SI 2 "register_operand" "d")]
21096			     UNSPECV_UMWAIT))]
21097  "TARGET_64BIT && TARGET_WAITPKG"
21098  "umwait\t%0"
21099  [(set_attr "length" "3")])
21100
21101(define_insn "@umonitor_<mode>"
21102  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
21103		    UNSPECV_UMONITOR)]
21104  "TARGET_WAITPKG"
21105  "umonitor\t%0"
21106  [(set (attr "length")
21107     (symbol_ref ("(Pmode != word_mode) + 3")))])
21108
21109(define_insn "tpause"
21110  [(set (reg:CCC FLAGS_REG)
21111	(unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21112			      (match_operand:DI 1 "register_operand" "A")]
21113			     UNSPECV_TPAUSE))]
21114  "!TARGET_64BIT && TARGET_WAITPKG"
21115  "tpause\t%0"
21116  [(set_attr "length" "3")])
21117
21118(define_insn "tpause_rex64"
21119  [(set (reg:CCC FLAGS_REG)
21120	(unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21121			      (match_operand:SI 1 "register_operand" "a")
21122			      (match_operand:SI 2 "register_operand" "d")]
21123			     UNSPECV_TPAUSE))]
21124  "TARGET_64BIT && TARGET_WAITPKG"
21125  "tpause\t%0"
21126  [(set_attr "length" "3")])
21127
21128(define_insn "cldemote"
21129  [(unspec_volatile[(match_operand 0 "address_operand" "p")]
21130		 UNSPECV_CLDEMOTE)]
21131  "TARGET_CLDEMOTE"
21132  "cldemote\t%a0"
21133  [(set_attr "type" "other")
21134   (set_attr "memory" "unknown")])
21135
21136(define_insn "speculation_barrier"
21137  [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
21138  ""
21139  "lfence"
21140  [(set_attr "type" "other")
21141   (set_attr "length" "3")])
21142
21143(include "mmx.md")
21144(include "sse.md")
21145(include "sync.md")
21146