1;; GCC machine description for IA-32 and x86-64.
2;; Copyright (C) 1988-2018 Free Software Foundation, Inc.
3;; Mostly by William Schelter.
4;; x86_64 support added by Jan Hubicka
5;;
6;; This file is part of GCC.
7;;
8;; GCC is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation; either version 3, or (at your option)
11;; any later version.
12;;
13;; GCC is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16;; GNU General Public License for more details.
17;;
18;; You should have received a copy of the GNU General Public License
19;; along with GCC; see the file COPYING3.  If not see
20;; <http://www.gnu.org/licenses/>.  */
21;;
22;; The original PO technology requires these to be ordered by speed,
23;; so that assigner will pick the fastest.
24;;
25;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
26;;
27;; The special asm out single letter directives following a '%' are:
28;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29;; C -- print opcode suffix for set/cmov insn.
30;; c -- like C, but print reversed condition
31;; F,f -- likewise, but for floating-point.
32;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33;;      otherwise nothing
34;; R -- print the prefix for register names.
35;; z -- print the opcode suffix for the size of the current operand.
36;; Z -- likewise, with special suffixes for x87 instructions.
37;; * -- print a star (in certain assembler syntax)
38;; A -- print an absolute memory reference.
39;; E -- print address with DImode register names if TARGET_64BIT.
40;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41;; s -- print a shift double count, followed by the assemblers argument
42;;	delimiter.
43;; b -- print the QImode name of the register for the indicated operand.
44;;	%b0 would print %al if operands[0] is reg 0.
45;; w --  likewise, print the HImode name of the register.
46;; k --  likewise, print the SImode name of the register.
47;; q --  likewise, print the DImode name of the register.
48;; x --  likewise, print the V4SFmode name of the register.
49;; t --  likewise, print the V8SFmode name of the register.
50;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51;; y -- print "st(0)" instead of "st" as a register.
52;; d -- print duplicated register operand for AVX instruction.
53;; D -- print condition for SSE cmp instruction.
54;; P -- if PIC, print an @PLT suffix.
55;; p -- print raw symbol name.
56;; X -- don't print any sort of PIC '@' suffix for a symbol.
57;; & -- print some in-use local-dynamic symbol name.
58;; H -- print a memory address offset by 8; used for sse high-parts
59;; K -- print HLE lock prefix
60;; Y -- print condition for XOP pcom* instruction.
61;; + -- print a branch hint as 'cs' or 'ds' prefix
62;; ; -- print a semicolon (after prefixes due to bug in older gas).
63;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65;; ! -- print MPX or NOTRACK prefix for jxx/call/ret instructions if required.
66
67(define_c_enum "unspec" [
68  ;; Relocation specifiers
69  UNSPEC_GOT
70  UNSPEC_GOTOFF
71  UNSPEC_GOTPCREL
72  UNSPEC_GOTTPOFF
73  UNSPEC_TPOFF
74  UNSPEC_NTPOFF
75  UNSPEC_DTPOFF
76  UNSPEC_GOTNTPOFF
77  UNSPEC_INDNTPOFF
78  UNSPEC_PLTOFF
79  UNSPEC_MACHOPIC_OFFSET
80  UNSPEC_PCREL
81  UNSPEC_SIZEOF
82
83  ;; Prologue support
84  UNSPEC_STACK_ALLOC
85  UNSPEC_SET_GOT
86  UNSPEC_SET_RIP
87  UNSPEC_SET_GOT_OFFSET
88  UNSPEC_MEMORY_BLOCKAGE
89  UNSPEC_PROBE_STACK
90
91  ;; TLS support
92  UNSPEC_TP
93  UNSPEC_TLS_GD
94  UNSPEC_TLS_LD_BASE
95  UNSPEC_TLSDESC
96  UNSPEC_TLS_IE_SUN
97
98  ;; Other random patterns
99  UNSPEC_SCAS
100  UNSPEC_FNSTSW
101  UNSPEC_SAHF
102  UNSPEC_NOTRAP
103  UNSPEC_PARITY
104  UNSPEC_FSTCW
105  UNSPEC_FLDCW
106  UNSPEC_REP
107  UNSPEC_LD_MPIC	; load_macho_picbase
108  UNSPEC_TRUNC_NOOP
109  UNSPEC_DIV_ALREADY_SPLIT
110  UNSPEC_PAUSE
111  UNSPEC_LEA_ADDR
112  UNSPEC_XBEGIN_ABORT
113  UNSPEC_STOS
114  UNSPEC_PEEPSIB
115  UNSPEC_INSN_FALSE_DEP
116  UNSPEC_SBB
117
118  ;; For SSE/MMX support:
119  UNSPEC_FIX_NOTRUNC
120  UNSPEC_MASKMOV
121  UNSPEC_MOVMSK
122  UNSPEC_RCP
123  UNSPEC_RSQRT
124  UNSPEC_PSADBW
125
126  ;; Generic math support
127  UNSPEC_COPYSIGN
128  UNSPEC_IEEE_MIN	; not commutative
129  UNSPEC_IEEE_MAX	; not commutative
130
131  ;; x87 Floating point
132  UNSPEC_SIN
133  UNSPEC_COS
134  UNSPEC_FPATAN
135  UNSPEC_FYL2X
136  UNSPEC_FYL2XP1
137  UNSPEC_FRNDINT
138  UNSPEC_FIST
139  UNSPEC_F2XM1
140  UNSPEC_TAN
141  UNSPEC_FXAM
142
143  ;; x87 Rounding
144  UNSPEC_FRNDINT_FLOOR
145  UNSPEC_FRNDINT_CEIL
146  UNSPEC_FRNDINT_TRUNC
147  UNSPEC_FRNDINT_MASK_PM
148  UNSPEC_FIST_FLOOR
149  UNSPEC_FIST_CEIL
150
151  ;; x87 Double output FP
152  UNSPEC_SINCOS_COS
153  UNSPEC_SINCOS_SIN
154  UNSPEC_XTRACT_FRACT
155  UNSPEC_XTRACT_EXP
156  UNSPEC_FSCALE_FRACT
157  UNSPEC_FSCALE_EXP
158  UNSPEC_FPREM_F
159  UNSPEC_FPREM_U
160  UNSPEC_FPREM1_F
161  UNSPEC_FPREM1_U
162
163  UNSPEC_C2_FLAG
164  UNSPEC_FXAM_MEM
165
166  ;; SSP patterns
167  UNSPEC_SP_SET
168  UNSPEC_SP_TEST
169
170  ;; For ROUND support
171  UNSPEC_ROUND
172
173  ;; For CRC32 support
174  UNSPEC_CRC32
175
176  ;; For LZCNT suppoprt
177  UNSPEC_LZCNT
178
179  ;; For BMI support
180  UNSPEC_TZCNT
181  UNSPEC_BEXTR
182
183  ;; For BMI2 support
184  UNSPEC_PDEP
185  UNSPEC_PEXT
186
187  UNSPEC_BNDMK
188  UNSPEC_BNDMK_ADDR
189  UNSPEC_BNDSTX
190  UNSPEC_BNDLDX
191  UNSPEC_BNDLDX_ADDR
192  UNSPEC_BNDCL
193  UNSPEC_BNDCU
194  UNSPEC_BNDCN
195  UNSPEC_MPX_FENCE
196
197  ;; IRET support
198  UNSPEC_INTERRUPT_RETURN
199])
200
201(define_c_enum "unspecv" [
202  UNSPECV_UD2
203  UNSPECV_BLOCKAGE
204  UNSPECV_STACK_PROBE
205  UNSPECV_PROBE_STACK_RANGE
206  UNSPECV_ALIGN
207  UNSPECV_PROLOGUE_USE
208  UNSPECV_SPLIT_STACK_RETURN
209  UNSPECV_CLD
210  UNSPECV_NOPS
211  UNSPECV_RDTSC
212  UNSPECV_RDTSCP
213  UNSPECV_RDPMC
214  UNSPECV_LLWP_INTRINSIC
215  UNSPECV_SLWP_INTRINSIC
216  UNSPECV_LWPVAL_INTRINSIC
217  UNSPECV_LWPINS_INTRINSIC
218  UNSPECV_RDFSBASE
219  UNSPECV_RDGSBASE
220  UNSPECV_WRFSBASE
221  UNSPECV_WRGSBASE
222  UNSPECV_FXSAVE
223  UNSPECV_FXRSTOR
224  UNSPECV_FXSAVE64
225  UNSPECV_FXRSTOR64
226  UNSPECV_XSAVE
227  UNSPECV_XRSTOR
228  UNSPECV_XSAVE64
229  UNSPECV_XRSTOR64
230  UNSPECV_XSAVEOPT
231  UNSPECV_XSAVEOPT64
232  UNSPECV_XSAVES
233  UNSPECV_XRSTORS
234  UNSPECV_XSAVES64
235  UNSPECV_XRSTORS64
236  UNSPECV_XSAVEC
237  UNSPECV_XSAVEC64
238  UNSPECV_XGETBV
239  UNSPECV_XSETBV
240  UNSPECV_WBINVD
241  UNSPECV_WBNOINVD
242
243  ;; For atomic compound assignments.
244  UNSPECV_FNSTENV
245  UNSPECV_FLDENV
246  UNSPECV_FNSTSW
247  UNSPECV_FNCLEX
248
249  ;; For RDRAND support
250  UNSPECV_RDRAND
251
252  ;; For RDSEED support
253  UNSPECV_RDSEED
254
255  ;; For RTM support
256  UNSPECV_XBEGIN
257  UNSPECV_XEND
258  UNSPECV_XABORT
259  UNSPECV_XTEST
260
261  UNSPECV_NLGR
262
263  ;; For CLWB support
264  UNSPECV_CLWB
265
266  ;; For CLFLUSHOPT support
267  UNSPECV_CLFLUSHOPT
268
269  ;; For MONITORX and MWAITX support
270  UNSPECV_MONITORX
271  UNSPECV_MWAITX
272
273  ;; For CLZERO support
274  UNSPECV_CLZERO
275
276  ;; For RDPKRU and WRPKRU support
277  UNSPECV_PKU
278
279  ;; For RDPID support
280  UNSPECV_RDPID
281
282  ;; For CET support
283  UNSPECV_NOP_ENDBR
284  UNSPECV_NOP_RDSSP
285  UNSPECV_INCSSP
286  UNSPECV_SAVEPREVSSP
287  UNSPECV_RSTORSSP
288  UNSPECV_WRSS
289  UNSPECV_WRUSS
290  UNSPECV_SETSSBSY
291  UNSPECV_CLRSSBSY
292  UNSPECV_MOVDIRI
293  UNSPECV_MOVDIR64B
294])
295
296;; Constants to represent rounding modes in the ROUND instruction
297(define_constants
298  [(ROUND_FLOOR			0x1)
299   (ROUND_CEIL			0x2)
300   (ROUND_TRUNC			0x3)
301   (ROUND_MXCSR			0x4)
302   (ROUND_NO_EXC		0x8)
303  ])
304
305;; Constants to represent AVX512F embeded rounding
306(define_constants
307  [(ROUND_NEAREST_INT			0)
308   (ROUND_NEG_INF			1)
309   (ROUND_POS_INF			2)
310   (ROUND_ZERO				3)
311   (NO_ROUND				4)
312   (ROUND_SAE				8)
313  ])
314
315;; Constants to represent pcomtrue/pcomfalse variants
316(define_constants
317  [(PCOM_FALSE			0)
318   (PCOM_TRUE			1)
319   (COM_FALSE_S			2)
320   (COM_FALSE_P			3)
321   (COM_TRUE_S			4)
322   (COM_TRUE_P			5)
323  ])
324
325;; Constants used in the XOP pperm instruction
326(define_constants
327  [(PPERM_SRC			0x00)	/* copy source */
328   (PPERM_INVERT		0x20)	/* invert source */
329   (PPERM_REVERSE		0x40)	/* bit reverse source */
330   (PPERM_REV_INV		0x60)	/* bit reverse & invert src */
331   (PPERM_ZERO			0x80)	/* all 0's */
332   (PPERM_ONES			0xa0)	/* all 1's */
333   (PPERM_SIGN			0xc0)	/* propagate sign bit */
334   (PPERM_INV_SIGN		0xe0)	/* invert & propagate sign */
335   (PPERM_SRC1			0x00)	/* use first source byte */
336   (PPERM_SRC2			0x10)	/* use second source byte */
337   ])
338
339;; Registers by name.
340(define_constants
341  [(AX_REG			 0)
342   (DX_REG			 1)
343   (CX_REG			 2)
344   (BX_REG			 3)
345   (SI_REG			 4)
346   (DI_REG			 5)
347   (BP_REG			 6)
348   (SP_REG			 7)
349   (ST0_REG			 8)
350   (ST1_REG			 9)
351   (ST2_REG			10)
352   (ST3_REG			11)
353   (ST4_REG			12)
354   (ST5_REG			13)
355   (ST6_REG			14)
356   (ST7_REG			15)
357   (ARGP_REG			16)
358   (FLAGS_REG			17)
359   (FPSR_REG			18)
360   (FPCR_REG			19)
361   (FRAME_REG			20)
362   (XMM0_REG			21)
363   (XMM1_REG			22)
364   (XMM2_REG			23)
365   (XMM3_REG			24)
366   (XMM4_REG			25)
367   (XMM5_REG			26)
368   (XMM6_REG			27)
369   (XMM7_REG			28)
370   (MM0_REG			29)
371   (MM1_REG			30)
372   (MM2_REG			31)
373   (MM3_REG			32)
374   (MM4_REG			33)
375   (MM5_REG			34)
376   (MM6_REG			35)
377   (MM7_REG			36)
378   (R8_REG			37)
379   (R9_REG			38)
380   (R10_REG			39)
381   (R11_REG			40)
382   (R12_REG			41)
383   (R13_REG			42)
384   (R14_REG			43)
385   (R15_REG			44)
386   (XMM8_REG			45)
387   (XMM9_REG			46)
388   (XMM10_REG			47)
389   (XMM11_REG			48)
390   (XMM12_REG			49)
391   (XMM13_REG			50)
392   (XMM14_REG			51)
393   (XMM15_REG			52)
394   (XMM16_REG			53)
395   (XMM17_REG			54)
396   (XMM18_REG			55)
397   (XMM19_REG			56)
398   (XMM20_REG			57)
399   (XMM21_REG			58)
400   (XMM22_REG			59)
401   (XMM23_REG			60)
402   (XMM24_REG			61)
403   (XMM25_REG			62)
404   (XMM26_REG			63)
405   (XMM27_REG			64)
406   (XMM28_REG			65)
407   (XMM29_REG			66)
408   (XMM30_REG			67)
409   (XMM31_REG			68)
410   (MASK0_REG			69)
411   (MASK1_REG			70)
412   (MASK2_REG			71)
413   (MASK3_REG			72)
414   (MASK4_REG			73)
415   (MASK5_REG			74)
416   (MASK6_REG			75)
417   (MASK7_REG			76)
418   (BND0_REG			77)
419   (BND1_REG			78)
420   (BND2_REG			79)
421   (BND3_REG			80)
422   (FIRST_PSEUDO_REG		81)
423  ])
424
425;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
426;; from i386.c.
427
428;; In C guard expressions, put expressions which may be compile-time
429;; constants first.  This allows for better optimization.  For
430;; example, write "TARGET_64BIT && reload_completed", not
431;; "reload_completed && TARGET_64BIT".
432
433
434;; Processor type.
435(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
436		    atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
437		    bdver4,btver2,znver1"
438  (const (symbol_ref "ix86_schedule")))
439
440;; A basic instruction type.  Refinements due to arguments to be
441;; provided in other attributes.
442(define_attr "type"
443  "other,multi,
444   alu,alu1,negnot,imov,imovx,lea,
445   incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
446   imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
447   push,pop,call,callv,leave,
448   str,bitmanip,
449   fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
450   fxch,fistp,fisttp,frndint,
451   sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
452   ssemul,sseimul,ssediv,sselog,sselog1,
453   sseishft,sseishft1,ssecmp,ssecomi,
454   ssecvt,ssecvt1,sseicvt,sseins,
455   sseshuf,sseshuf1,ssemuladd,sse4arg,
456   lwp,mskmov,msklog,
457   mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
458   mpxmov,mpxmk,mpxchk,mpxld,mpxst"
459  (const_string "other"))
460
461;; Main data type used by the insn
462(define_attr "mode"
463  "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
464  V2DF,V2SF,V1DF,V8DF"
465  (const_string "unknown"))
466
467;; The CPU unit operations uses.
468(define_attr "unit" "integer,i387,sse,mmx,unknown"
469  (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
470			  fxch,fistp,fisttp,frndint")
471	   (const_string "i387")
472	 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
473			  ssemul,sseimul,ssediv,sselog,sselog1,
474			  sseishft,sseishft1,ssecmp,ssecomi,
475			  ssecvt,ssecvt1,sseicvt,sseins,
476			  sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
477	   (const_string "sse")
478	 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
479	   (const_string "mmx")
480	 (eq_attr "type" "other")
481	   (const_string "unknown")]
482	 (const_string "integer")))
483
484;; The (bounding maximum) length of an instruction immediate.
485(define_attr "length_immediate" ""
486  (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
487			  bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
488			  mpxld,mpxst")
489	   (const_int 0)
490	 (eq_attr "unit" "i387,sse,mmx")
491	   (const_int 0)
492	 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
493			  rotate,rotatex,rotate1,imul,icmp,push,pop")
494	   (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
495	 (eq_attr "type" "imov,test")
496	   (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
497	 (eq_attr "type" "call")
498	   (if_then_else (match_operand 0 "constant_call_address_operand")
499	     (const_int 4)
500	     (const_int 0))
501	 (eq_attr "type" "callv")
502	   (if_then_else (match_operand 1 "constant_call_address_operand")
503	     (const_int 4)
504	     (const_int 0))
505	 ;; We don't know the size before shorten_branches.  Expect
506	 ;; the instruction to fit for better scheduling.
507	 (eq_attr "type" "ibr")
508	   (const_int 1)
509	 ]
510	 (symbol_ref "/* Update immediate_length and other attributes! */
511		      gcc_unreachable (),1")))
512
513;; The (bounding maximum) length of an instruction address.
514(define_attr "length_address" ""
515  (cond [(eq_attr "type" "str,other,multi,fxch")
516	   (const_int 0)
517	 (and (eq_attr "type" "call")
518	      (match_operand 0 "constant_call_address_operand"))
519	     (const_int 0)
520	 (and (eq_attr "type" "callv")
521	      (match_operand 1 "constant_call_address_operand"))
522	     (const_int 0)
523	 ]
524	 (symbol_ref "ix86_attr_length_address_default (insn)")))
525
526;; Set when length prefix is used.
527(define_attr "prefix_data16" ""
528  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
529	   (const_int 0)
530	 (eq_attr "mode" "HI")
531	   (const_int 1)
532	 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
533	   (const_int 1)
534	]
535	(const_int 0)))
536
537;; Set when string REP prefix is used.
538(define_attr "prefix_rep" ""
539  (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
540	   (const_int 0)
541	 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
542	   (const_int 1)
543	 (and (eq_attr "type" "ibr,call,callv")
544	      (match_test "ix86_bnd_prefixed_insn_p (insn)"))
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			  mpxmk,mpxmov,mpxchk,mpxld,mpxst")
554	 (eq_attr "unit" "sse,mmx"))
555    (const_int 1)
556    (const_int 0)))
557
558;; Set when REX opcode prefix is used.
559(define_attr "prefix_rex" ""
560  (cond [(not (match_test "TARGET_64BIT"))
561	   (const_int 0)
562	 (and (eq_attr "mode" "DI")
563	      (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
564		   (eq_attr "unit" "!mmx")))
565	   (const_int 1)
566	 (and (eq_attr "mode" "QI")
567	      (match_test "x86_extended_QIreg_mentioned_p (insn)"))
568	   (const_int 1)
569	 (match_test "x86_extended_reg_mentioned_p (insn)")
570	   (const_int 1)
571	 (and (eq_attr "type" "imovx")
572	      (match_operand:QI 1 "ext_QIreg_operand"))
573	   (const_int 1)
574	]
575	(const_int 0)))
576
577;; There are also additional prefixes in 3DNOW, SSSE3.
578;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
579;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
580;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
581(define_attr "prefix_extra" ""
582  (cond [(eq_attr "type" "ssemuladd,sse4arg")
583	   (const_int 2)
584	 (eq_attr "type" "sseiadd1,ssecvt1")
585	   (const_int 1)
586	]
587	(const_int 0)))
588
589;; Set when BND opcode prefix may be used.
590(define_attr "maybe_prefix_bnd" "" (const_int 0))
591
592;; Prefix used: original, VEX or maybe VEX.
593(define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
594  (cond [(eq_attr "mode" "OI,V8SF,V4DF")
595           (const_string "vex")
596         (eq_attr "mode" "XI,V16SF,V8DF")
597           (const_string "evex")
598        ]
599        (const_string "orig")))
600
601;; VEX W bit is used.
602(define_attr "prefix_vex_w" "" (const_int 0))
603
604;; The length of VEX prefix
605;; Only instructions with 0f prefix can have 2 byte VEX prefix,
606;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
607;; still prefix_0f 1, with prefix_extra 1.
608(define_attr "length_vex" ""
609  (if_then_else (and (eq_attr "prefix_0f" "1")
610		     (eq_attr "prefix_extra" "0"))
611    (if_then_else (eq_attr "prefix_vex_w" "1")
612      (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
613      (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
614    (if_then_else (eq_attr "prefix_vex_w" "1")
615      (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
616      (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
617
618;; 4-bytes evex prefix and 1 byte opcode.
619(define_attr "length_evex" "" (const_int 5))
620
621;; Set when modrm byte is used.
622(define_attr "modrm" ""
623  (cond [(eq_attr "type" "str,leave")
624	   (const_int 0)
625	 (eq_attr "unit" "i387")
626	   (const_int 0)
627         (and (eq_attr "type" "incdec")
628	      (and (not (match_test "TARGET_64BIT"))
629		   (ior (match_operand:SI 1 "register_operand")
630			(match_operand:HI 1 "register_operand"))))
631	   (const_int 0)
632	 (and (eq_attr "type" "push")
633	      (not (match_operand 1 "memory_operand")))
634	   (const_int 0)
635	 (and (eq_attr "type" "pop")
636	      (not (match_operand 0 "memory_operand")))
637	   (const_int 0)
638	 (and (eq_attr "type" "imov")
639	      (and (not (eq_attr "mode" "DI"))
640		   (ior (and (match_operand 0 "register_operand")
641			     (match_operand 1 "immediate_operand"))
642		        (ior (and (match_operand 0 "ax_reg_operand")
643				  (match_operand 1 "memory_displacement_only_operand"))
644			     (and (match_operand 0 "memory_displacement_only_operand")
645				  (match_operand 1 "ax_reg_operand"))))))
646	   (const_int 0)
647	 (and (eq_attr "type" "call")
648	      (match_operand 0 "constant_call_address_operand"))
649	     (const_int 0)
650	 (and (eq_attr "type" "callv")
651	      (match_operand 1 "constant_call_address_operand"))
652	     (const_int 0)
653	 (and (eq_attr "type" "alu,alu1,icmp,test")
654	      (match_operand 0 "ax_reg_operand"))
655	     (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
656	 ]
657	 (const_int 1)))
658
659(define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
660  (cond [(eq_attr "modrm" "0")
661	   (const_string "none")
662	 (eq_attr "type" "alu,imul,ishift")
663	   (const_string "op02")
664	 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
665	   (const_string "op01")
666	 (eq_attr "type" "incdec")
667	   (const_string "incdec")
668	 (eq_attr "type" "push,pop")
669	   (const_string "pushpop")]
670	 (const_string "unknown")))
671
672;; The (bounding maximum) length of an instruction in bytes.
673;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
674;; Later we may want to split them and compute proper length as for
675;; other insns.
676(define_attr "length" ""
677  (cond [(eq_attr "type" "other,multi,fistp,frndint")
678	   (const_int 16)
679	 (eq_attr "type" "fcmp")
680	   (const_int 4)
681	 (eq_attr "unit" "i387")
682	   (plus (const_int 2)
683		 (plus (attr "prefix_data16")
684		       (attr "length_address")))
685	 (ior (eq_attr "prefix" "evex")
686	      (and (ior (eq_attr "prefix" "maybe_evex")
687			(eq_attr "prefix" "maybe_vex"))
688		   (match_test "TARGET_AVX512F")))
689	   (plus (attr "length_evex")
690		 (plus (attr "length_immediate")
691		       (plus (attr "modrm")
692			     (attr "length_address"))))
693	 (ior (eq_attr "prefix" "vex")
694	      (and (ior (eq_attr "prefix" "maybe_vex")
695			(eq_attr "prefix" "maybe_evex"))
696		   (match_test "TARGET_AVX")))
697	   (plus (attr "length_vex")
698		 (plus (attr "length_immediate")
699		       (plus (attr "modrm")
700			     (attr "length_address"))))]
701	 (plus (plus (attr "modrm")
702		     (plus (attr "prefix_0f")
703			   (plus (attr "prefix_rex")
704				 (plus (attr "prefix_extra")
705				       (const_int 1)))))
706	       (plus (attr "prefix_rep")
707		     (plus (attr "prefix_data16")
708			   (plus (attr "length_immediate")
709				 (attr "length_address")))))))
710
711;; The `memory' attribute is `none' if no memory is referenced, `load' or
712;; `store' if there is a simple memory reference therein, or `unknown'
713;; if the instruction is complex.
714
715(define_attr "memory" "none,load,store,both,unknown"
716  (cond [(eq_attr "type" "other,multi,str,lwp")
717	   (const_string "unknown")
718	 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
719	   (const_string "none")
720	 (eq_attr "type" "fistp,leave")
721	   (const_string "both")
722	 (eq_attr "type" "frndint")
723	   (const_string "load")
724	 (eq_attr "type" "mpxld")
725	   (const_string "load")
726	 (eq_attr "type" "mpxst")
727	   (const_string "store")
728	 (eq_attr "type" "push")
729	   (if_then_else (match_operand 1 "memory_operand")
730	     (const_string "both")
731	     (const_string "store"))
732	 (eq_attr "type" "pop")
733	   (if_then_else (match_operand 0 "memory_operand")
734	     (const_string "both")
735	     (const_string "load"))
736	 (eq_attr "type" "setcc")
737	   (if_then_else (match_operand 0 "memory_operand")
738	     (const_string "store")
739	     (const_string "none"))
740	 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
741	   (if_then_else (ior (match_operand 0 "memory_operand")
742			      (match_operand 1 "memory_operand"))
743	     (const_string "load")
744	     (const_string "none"))
745	 (eq_attr "type" "ibr")
746	   (if_then_else (match_operand 0 "memory_operand")
747	     (const_string "load")
748	     (const_string "none"))
749	 (eq_attr "type" "call")
750	   (if_then_else (match_operand 0 "constant_call_address_operand")
751	     (const_string "none")
752	     (const_string "load"))
753	 (eq_attr "type" "callv")
754	   (if_then_else (match_operand 1 "constant_call_address_operand")
755	     (const_string "none")
756	     (const_string "load"))
757	 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
758	      (match_operand 1 "memory_operand"))
759	   (const_string "both")
760	 (and (match_operand 0 "memory_operand")
761	      (match_operand 1 "memory_operand"))
762	   (const_string "both")
763	 (match_operand 0 "memory_operand")
764	   (const_string "store")
765	 (match_operand 1 "memory_operand")
766	   (const_string "load")
767	 (and (eq_attr "type"
768		 "!alu1,negnot,ishift1,rotate1,
769		   imov,imovx,icmp,test,bitmanip,
770		   fmov,fcmp,fsgn,
771		   sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
772		   sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
773		   mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
774	      (match_operand 2 "memory_operand"))
775	   (const_string "load")
776	 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
777	      (match_operand 3 "memory_operand"))
778	   (const_string "load")
779	]
780	(const_string "none")))
781
782;; Indicates if an instruction has both an immediate and a displacement.
783
784(define_attr "imm_disp" "false,true,unknown"
785  (cond [(eq_attr "type" "other,multi")
786	   (const_string "unknown")
787	 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
788	      (and (match_operand 0 "memory_displacement_operand")
789		   (match_operand 1 "immediate_operand")))
790	   (const_string "true")
791	 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
792	      (and (match_operand 0 "memory_displacement_operand")
793		   (match_operand 2 "immediate_operand")))
794	   (const_string "true")
795	]
796	(const_string "false")))
797
798;; Indicates if an FP operation has an integer source.
799
800(define_attr "fp_int_src" "false,true"
801  (const_string "false"))
802
803;; Defines rounding mode of an FP operation.
804
805(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
806  (const_string "any"))
807
808;; Define attribute to classify add/sub insns that consumes carry flag (CF)
809(define_attr "use_carry" "0,1" (const_string "0"))
810
811;; Define attribute to indicate unaligned ssemov insns
812(define_attr "movu" "0,1" (const_string "0"))
813
814;; Used to control the "enabled" attribute on a per-instruction basis.
815(define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
816		    sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
817		    avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
818		    avx512bw,noavx512bw,avx512dq,noavx512dq,
819		    avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
820  (const_string "base"))
821
822(define_attr "enabled" ""
823  (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
824	 (eq_attr "isa" "x64_sse4")
825	   (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
826	 (eq_attr "isa" "x64_sse4_noavx")
827	   (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
828	 (eq_attr "isa" "x64_avx")
829	   (symbol_ref "TARGET_64BIT && TARGET_AVX")
830	 (eq_attr "isa" "x64_avx512dq")
831	   (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
832	 (eq_attr "isa" "x64_avx512bw")
833	   (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
834	 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
835	 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
836	 (eq_attr "isa" "sse2_noavx")
837	   (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
838	 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
839	 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
840	 (eq_attr "isa" "sse4_noavx")
841	   (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
842	 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
843	 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
844	 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
845	 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
846	 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
847	 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
848	 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
849	 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
850	 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
851	 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
852	 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
853	 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
854	 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
855	 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
856	 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
857	 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
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 "abs") (neg "chs")])
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
959;; Prefix for define_insn
960(define_code_attr u [(sign_extend "") (zero_extend "u")])
961(define_code_attr s [(sign_extend "s") (zero_extend "u")])
962(define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
963
964;; Used in signed and unsigned truncations.
965(define_code_iterator any_truncate [ss_truncate truncate us_truncate])
966;; Instruction suffix for truncations.
967(define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
968
969;; Used in signed and unsigned fix.
970(define_code_iterator any_fix [fix unsigned_fix])
971(define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
972
973;; Used in signed and unsigned float.
974(define_code_iterator any_float [float unsigned_float])
975(define_code_attr floatsuffix [(float "") (unsigned_float "u")])
976
977;; All integer modes.
978(define_mode_iterator SWI1248x [QI HI SI DI])
979
980;; All integer modes without QImode.
981(define_mode_iterator SWI248x [HI SI DI])
982
983;; All integer modes without QImode and HImode.
984(define_mode_iterator SWI48x [SI DI])
985
986;; All integer modes without SImode and DImode.
987(define_mode_iterator SWI12 [QI HI])
988
989;; All integer modes without DImode.
990(define_mode_iterator SWI124 [QI HI SI])
991
992;; All integer modes without QImode and DImode.
993(define_mode_iterator SWI24 [HI SI])
994
995;; Single word integer modes.
996(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
997
998;; Single word integer modes without QImode.
999(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1000
1001;; Single word integer modes without QImode and HImode.
1002(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1003
1004;; All math-dependant single and double word integer modes.
1005(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1006			     (HI "TARGET_HIMODE_MATH")
1007			     SI DI (TI "TARGET_64BIT")])
1008
1009;; Math-dependant single word integer modes.
1010(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1011			    (HI "TARGET_HIMODE_MATH")
1012			    SI (DI "TARGET_64BIT")])
1013
1014;; Math-dependant integer modes without DImode.
1015(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1016			       (HI "TARGET_HIMODE_MATH")
1017			       SI])
1018
1019;; Math-dependant integer modes with DImode.
1020(define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1021				 (HI "TARGET_HIMODE_MATH")
1022				 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1023
1024;; Math-dependant single word integer modes without QImode.
1025(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1026		      	       SI (DI "TARGET_64BIT")])
1027
1028;; Double word integer modes.
1029(define_mode_iterator DWI [(DI "!TARGET_64BIT")
1030			   (TI "TARGET_64BIT")])
1031
1032;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1033;; compile time constant, it is faster to use <MODE_SIZE> than
1034;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1035;; command line options just use GET_MODE_SIZE macro.
1036(define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1037			     (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1038			     (V16QI "16") (V32QI "32") (V64QI "64")
1039			     (V8HI "16") (V16HI "32") (V32HI "64")
1040			     (V4SI "16") (V8SI "32") (V16SI "64")
1041			     (V2DI "16") (V4DI "32") (V8DI "64")
1042			     (V1TI "16") (V2TI "32") (V4TI "64")
1043			     (V2DF "16") (V4DF "32") (V8DF "64")
1044			     (V4SF "16") (V8SF "32") (V16SF "64")])
1045
1046;; Double word integer modes as mode attribute.
1047(define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1048(define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1049
1050;; LEA mode corresponding to an integer mode
1051(define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1052
1053;; Half mode for double word integer modes.
1054(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1055			    (DI "TARGET_64BIT")])
1056
1057;; Bound modes.
1058(define_mode_iterator BND [(BND32 "!TARGET_LP64")
1059			   (BND64 "TARGET_LP64")])
1060
1061;; Pointer mode corresponding to bound mode.
1062(define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1063
1064;; MPX check types
1065(define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1066
1067;; Check name
1068(define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1069			   (UNSPEC_BNDCU "cu")
1070			   (UNSPEC_BNDCN "cn")])
1071
1072;; Instruction suffix for integer modes.
1073(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1074
1075;; Instruction suffix for masks.
1076(define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1077
1078;; Pointer size prefix for integer modes (Intel asm dialect)
1079(define_mode_attr iptrsize [(QI "BYTE")
1080			    (HI "WORD")
1081			    (SI "DWORD")
1082			    (DI "QWORD")])
1083
1084;; Register class for integer modes.
1085(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1086
1087;; Immediate operand constraint for integer modes.
1088(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1089
1090;; General operand constraint for word modes.
1091(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1092
1093;; Immediate operand constraint for double integer modes.
1094(define_mode_attr di [(SI "nF") (DI "Wd")])
1095
1096;; Immediate operand constraint for shifts.
1097(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1098
1099;; Print register name in the specified mode.
1100(define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1101
1102;; General operand predicate for integer modes.
1103(define_mode_attr general_operand
1104	[(QI "general_operand")
1105	 (HI "general_operand")
1106	 (SI "x86_64_general_operand")
1107	 (DI "x86_64_general_operand")
1108	 (TI "x86_64_general_operand")])
1109
1110;; General operand predicate for integer modes, where for TImode
1111;; we need both words of the operand to be general operands.
1112(define_mode_attr general_hilo_operand
1113	[(QI "general_operand")
1114	 (HI "general_operand")
1115	 (SI "x86_64_general_operand")
1116	 (DI "x86_64_general_operand")
1117	 (TI "x86_64_hilo_general_operand")])
1118
1119;; General sign extend operand predicate for integer modes,
1120;; which disallows VOIDmode operands and thus it is suitable
1121;; for use inside sign_extend.
1122(define_mode_attr general_sext_operand
1123	[(QI "sext_operand")
1124	 (HI "sext_operand")
1125	 (SI "x86_64_sext_operand")
1126	 (DI "x86_64_sext_operand")])
1127
1128;; General sign/zero extend operand predicate for integer modes.
1129(define_mode_attr general_szext_operand
1130	[(QI "general_operand")
1131	 (HI "general_operand")
1132	 (SI "x86_64_szext_general_operand")
1133	 (DI "x86_64_szext_general_operand")])
1134
1135;; Immediate operand predicate for integer modes.
1136(define_mode_attr immediate_operand
1137	[(QI "immediate_operand")
1138	 (HI "immediate_operand")
1139	 (SI "x86_64_immediate_operand")
1140	 (DI "x86_64_immediate_operand")])
1141
1142;; Nonmemory operand predicate for integer modes.
1143(define_mode_attr nonmemory_operand
1144	[(QI "nonmemory_operand")
1145	 (HI "nonmemory_operand")
1146	 (SI "x86_64_nonmemory_operand")
1147	 (DI "x86_64_nonmemory_operand")])
1148
1149;; Operand predicate for shifts.
1150(define_mode_attr shift_operand
1151	[(QI "nonimmediate_operand")
1152	 (HI "nonimmediate_operand")
1153	 (SI "nonimmediate_operand")
1154	 (DI "shiftdi_operand")
1155	 (TI "register_operand")])
1156
1157;; Operand predicate for shift argument.
1158(define_mode_attr shift_immediate_operand
1159	[(QI "const_1_to_31_operand")
1160	 (HI "const_1_to_31_operand")
1161	 (SI "const_1_to_31_operand")
1162	 (DI "const_1_to_63_operand")])
1163
1164;; Input operand predicate for arithmetic left shifts.
1165(define_mode_attr ashl_input_operand
1166	[(QI "nonimmediate_operand")
1167	 (HI "nonimmediate_operand")
1168	 (SI "nonimmediate_operand")
1169	 (DI "ashldi_input_operand")
1170	 (TI "reg_or_pm1_operand")])
1171
1172;; SSE and x87 SFmode and DFmode floating point modes
1173(define_mode_iterator MODEF [SF DF])
1174
1175;; All x87 floating point modes
1176(define_mode_iterator X87MODEF [SF DF XF])
1177
1178;; SSE instruction suffix for various modes
1179(define_mode_attr ssemodesuffix
1180  [(SF "ss") (DF "sd")
1181   (V16SF "ps") (V8DF "pd")
1182   (V8SF "ps") (V4DF "pd")
1183   (V4SF "ps") (V2DF "pd")
1184   (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1185   (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1186   (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1187
1188;; SSE vector suffix for floating point modes
1189(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1190
1191;; SSE vector mode corresponding to a scalar mode
1192(define_mode_attr ssevecmode
1193  [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1194(define_mode_attr ssevecmodelower
1195  [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1196
1197;; AVX512F vector mode corresponding to a scalar mode
1198(define_mode_attr avx512fvecmode
1199  [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1200
1201;; Instruction suffix for REX 64bit operators.
1202(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1203
1204;; This mode iterator allows :P to be used for patterns that operate on
1205;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1206(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1207
1208;; This mode iterator allows :W to be used for patterns that operate on
1209;; word_mode sized quantities.
1210(define_mode_iterator W
1211  [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1212
1213;; This mode iterator allows :PTR to be used for patterns that operate on
1214;; ptr_mode sized quantities.
1215(define_mode_iterator PTR
1216  [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1217
1218;; Scheduling descriptions
1219
1220(include "pentium.md")
1221(include "ppro.md")
1222(include "k6.md")
1223(include "athlon.md")
1224(include "bdver1.md")
1225(include "bdver3.md")
1226(include "btver2.md")
1227(include "znver1.md")
1228(include "geode.md")
1229(include "atom.md")
1230(include "slm.md")
1231(include "core2.md")
1232(include "haswell.md")
1233
1234
1235;; Operand and operator predicates and constraints
1236
1237(include "predicates.md")
1238(include "constraints.md")
1239
1240
1241;; Compare and branch/compare and store instructions.
1242
1243(define_expand "cbranch<mode>4"
1244  [(set (reg:CC FLAGS_REG)
1245	(compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1246		    (match_operand:SDWIM 2 "<general_operand>")))
1247   (set (pc) (if_then_else
1248	       (match_operator 0 "ordered_comparison_operator"
1249		[(reg:CC FLAGS_REG) (const_int 0)])
1250	       (label_ref (match_operand 3))
1251	       (pc)))]
1252  ""
1253{
1254  if (MEM_P (operands[1]) && MEM_P (operands[2]))
1255    operands[1] = force_reg (<MODE>mode, operands[1]);
1256  ix86_expand_branch (GET_CODE (operands[0]),
1257		      operands[1], operands[2], operands[3]);
1258  DONE;
1259})
1260
1261(define_expand "cstore<mode>4"
1262  [(set (reg:CC FLAGS_REG)
1263	(compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1264		    (match_operand:SWIM 3 "<general_operand>")))
1265   (set (match_operand:QI 0 "register_operand")
1266	(match_operator 1 "ordered_comparison_operator"
1267	  [(reg:CC FLAGS_REG) (const_int 0)]))]
1268  ""
1269{
1270  if (MEM_P (operands[2]) && MEM_P (operands[3]))
1271    operands[2] = force_reg (<MODE>mode, operands[2]);
1272  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1273		     operands[2], operands[3]);
1274  DONE;
1275})
1276
1277(define_expand "cmp<mode>_1"
1278  [(set (reg:CC FLAGS_REG)
1279	(compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1280		    (match_operand:SWI48 1 "<general_operand>")))])
1281
1282(define_mode_iterator SWI1248_AVX512BWDQ2_64
1283  [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1284   (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1285
1286(define_insn "*cmp<mode>_ccz_1"
1287  [(set (reg FLAGS_REG)
1288	(compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1289			"nonimmediate_operand" "<r>,?m<r>,$k")
1290		 (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1291  "ix86_match_ccmode (insn, CCZmode)"
1292  "@
1293   test{<imodesuffix>}\t%0, %0
1294   cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1295   ktest<mskmodesuffix>\t%0, %0"
1296  [(set_attr "type" "test,icmp,msklog")
1297   (set_attr "length_immediate" "0,1,*")
1298   (set_attr "modrm_class" "op0,unknown,*")
1299   (set_attr "prefix" "*,*,vex")
1300   (set_attr "mode" "<MODE>")])
1301
1302(define_insn "*cmp<mode>_ccno_1"
1303  [(set (reg FLAGS_REG)
1304	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1305		 (match_operand:SWI 1 "const0_operand")))]
1306  "ix86_match_ccmode (insn, CCNOmode)"
1307  "@
1308   test{<imodesuffix>}\t%0, %0
1309   cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1310  [(set_attr "type" "test,icmp")
1311   (set_attr "length_immediate" "0,1")
1312   (set_attr "modrm_class" "op0,unknown")
1313   (set_attr "mode" "<MODE>")])
1314
1315(define_insn "*cmp<mode>_1"
1316  [(set (reg FLAGS_REG)
1317	(compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1318		 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1319  "ix86_match_ccmode (insn, CCmode)"
1320  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1321  [(set_attr "type" "icmp")
1322   (set_attr "mode" "<MODE>")])
1323
1324(define_insn "*cmp<mode>_minus_1"
1325  [(set (reg FLAGS_REG)
1326	(compare
1327	  (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1328		     (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1329	  (const_int 0)))]
1330  "ix86_match_ccmode (insn, CCGOCmode)"
1331  "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1332  [(set_attr "type" "icmp")
1333   (set_attr "mode" "<MODE>")])
1334
1335(define_insn "*cmpqi_ext_1"
1336  [(set (reg FLAGS_REG)
1337	(compare
1338	  (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1339	  (subreg:QI
1340	    (zero_extract:SI
1341	      (match_operand 1 "ext_register_operand" "Q,Q")
1342	      (const_int 8)
1343	      (const_int 8)) 0)))]
1344  "ix86_match_ccmode (insn, CCmode)"
1345  "cmp{b}\t{%h1, %0|%0, %h1}"
1346  [(set_attr "isa" "*,nox64")
1347   (set_attr "type" "icmp")
1348   (set_attr "mode" "QI")])
1349
1350(define_insn "*cmpqi_ext_2"
1351  [(set (reg FLAGS_REG)
1352	(compare
1353	  (subreg:QI
1354	    (zero_extract:SI
1355	      (match_operand 0 "ext_register_operand" "Q")
1356	      (const_int 8)
1357	      (const_int 8)) 0)
1358	  (match_operand:QI 1 "const0_operand")))]
1359  "ix86_match_ccmode (insn, CCNOmode)"
1360  "test{b}\t%h0, %h0"
1361  [(set_attr "type" "test")
1362   (set_attr "length_immediate" "0")
1363   (set_attr "mode" "QI")])
1364
1365(define_expand "cmpqi_ext_3"
1366  [(set (reg:CC FLAGS_REG)
1367	(compare:CC
1368	  (subreg:QI
1369	    (zero_extract:SI
1370	      (match_operand 0 "ext_register_operand")
1371	      (const_int 8)
1372	      (const_int 8)) 0)
1373	  (match_operand:QI 1 "const_int_operand")))])
1374
1375(define_insn "*cmpqi_ext_3"
1376  [(set (reg FLAGS_REG)
1377	(compare
1378	  (subreg:QI
1379	    (zero_extract:SI
1380	      (match_operand 0 "ext_register_operand" "Q,Q")
1381	      (const_int 8)
1382	      (const_int 8)) 0)
1383	  (match_operand:QI 1 "general_operand" "QnBc,m")))]
1384  "ix86_match_ccmode (insn, CCmode)"
1385  "cmp{b}\t{%1, %h0|%h0, %1}"
1386  [(set_attr "isa" "*,nox64")
1387   (set_attr "type" "icmp")
1388   (set_attr "mode" "QI")])
1389
1390(define_insn "*cmpqi_ext_4"
1391  [(set (reg FLAGS_REG)
1392	(compare
1393	  (subreg:QI
1394	    (zero_extract:SI
1395	      (match_operand 0 "ext_register_operand" "Q")
1396	      (const_int 8)
1397	      (const_int 8)) 0)
1398	  (subreg:QI
1399	    (zero_extract:SI
1400	      (match_operand 1 "ext_register_operand" "Q")
1401	      (const_int 8)
1402	      (const_int 8)) 0)))]
1403  "ix86_match_ccmode (insn, CCmode)"
1404  "cmp{b}\t{%h1, %h0|%h0, %h1}"
1405  [(set_attr "type" "icmp")
1406   (set_attr "mode" "QI")])
1407
1408;; These implement float point compares.
1409;; %%% See if we can get away with VOIDmode operands on the actual insns,
1410;; which would allow mix and match FP modes on the compares.  Which is what
1411;; the old patterns did, but with many more of them.
1412
1413(define_expand "cbranchxf4"
1414  [(set (reg:CC FLAGS_REG)
1415	(compare:CC (match_operand:XF 1 "nonmemory_operand")
1416		    (match_operand:XF 2 "nonmemory_operand")))
1417   (set (pc) (if_then_else
1418              (match_operator 0 "ix86_fp_comparison_operator"
1419               [(reg:CC FLAGS_REG)
1420                (const_int 0)])
1421              (label_ref (match_operand 3))
1422              (pc)))]
1423  "TARGET_80387"
1424{
1425  ix86_expand_branch (GET_CODE (operands[0]),
1426		      operands[1], operands[2], operands[3]);
1427  DONE;
1428})
1429
1430(define_expand "cstorexf4"
1431  [(set (reg:CC FLAGS_REG)
1432	(compare:CC (match_operand:XF 2 "nonmemory_operand")
1433		    (match_operand:XF 3 "nonmemory_operand")))
1434   (set (match_operand:QI 0 "register_operand")
1435              (match_operator 1 "ix86_fp_comparison_operator"
1436               [(reg:CC FLAGS_REG)
1437                (const_int 0)]))]
1438  "TARGET_80387"
1439{
1440  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1441		     operands[2], operands[3]);
1442  DONE;
1443})
1444
1445(define_expand "cbranch<mode>4"
1446  [(set (reg:CC FLAGS_REG)
1447	(compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1448		    (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1449   (set (pc) (if_then_else
1450              (match_operator 0 "ix86_fp_comparison_operator"
1451               [(reg:CC FLAGS_REG)
1452                (const_int 0)])
1453              (label_ref (match_operand 3))
1454              (pc)))]
1455  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1456{
1457  ix86_expand_branch (GET_CODE (operands[0]),
1458		      operands[1], operands[2], operands[3]);
1459  DONE;
1460})
1461
1462(define_expand "cstore<mode>4"
1463  [(set (reg:CC FLAGS_REG)
1464	(compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1465		    (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1466   (set (match_operand:QI 0 "register_operand")
1467              (match_operator 1 "ix86_fp_comparison_operator"
1468               [(reg:CC FLAGS_REG)
1469                (const_int 0)]))]
1470  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1471{
1472  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1473		     operands[2], operands[3]);
1474  DONE;
1475})
1476
1477(define_expand "cbranchcc4"
1478  [(set (pc) (if_then_else
1479              (match_operator 0 "comparison_operator"
1480               [(match_operand 1 "flags_reg_operand")
1481                (match_operand 2 "const0_operand")])
1482              (label_ref (match_operand 3))
1483              (pc)))]
1484  ""
1485{
1486  ix86_expand_branch (GET_CODE (operands[0]),
1487		      operands[1], operands[2], operands[3]);
1488  DONE;
1489})
1490
1491(define_expand "cstorecc4"
1492  [(set (match_operand:QI 0 "register_operand")
1493              (match_operator 1 "comparison_operator"
1494               [(match_operand 2 "flags_reg_operand")
1495                (match_operand 3 "const0_operand")]))]
1496  ""
1497{
1498  ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1499		     operands[2], operands[3]);
1500  DONE;
1501})
1502
1503
1504;; FP compares, step 1:
1505;; Set the FP condition codes.
1506
1507;; We may not use "#" to split and emit these, since the REG_DEAD notes
1508;; used to manage the reg stack popping would not be preserved.
1509
1510(define_insn "*cmp<mode>_0_i387"
1511  [(set (match_operand:HI 0 "register_operand" "=a")
1512	(unspec:HI
1513	  [(compare:CCFP
1514	     (match_operand:X87MODEF 1 "register_operand" "f")
1515	     (match_operand:X87MODEF 2 "const0_operand"))]
1516	UNSPEC_FNSTSW))]
1517  "TARGET_80387"
1518  "* return output_fp_compare (insn, operands, false, false);"
1519  [(set_attr "type" "multi")
1520   (set_attr "unit" "i387")
1521   (set_attr "mode" "<MODE>")])
1522
1523(define_insn_and_split "*cmp<mode>_0_cc_i387"
1524  [(set (reg:CCFP FLAGS_REG)
1525	(compare:CCFP
1526	  (match_operand:X87MODEF 1 "register_operand" "f")
1527	  (match_operand:X87MODEF 2 "const0_operand")))
1528   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1529  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1530  "#"
1531  "&& reload_completed"
1532  [(set (match_dup 0)
1533	(unspec:HI
1534	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1535	UNSPEC_FNSTSW))
1536   (set (reg:CC FLAGS_REG)
1537	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1538  ""
1539  [(set_attr "type" "multi")
1540   (set_attr "unit" "i387")
1541   (set_attr "mode" "<MODE>")])
1542
1543(define_insn "*cmpxf_i387"
1544  [(set (match_operand:HI 0 "register_operand" "=a")
1545	(unspec:HI
1546	  [(compare:CCFP
1547	     (match_operand:XF 1 "register_operand" "f")
1548	     (match_operand:XF 2 "register_operand" "f"))]
1549	  UNSPEC_FNSTSW))]
1550  "TARGET_80387"
1551  "* return output_fp_compare (insn, operands, false, false);"
1552  [(set_attr "type" "multi")
1553   (set_attr "unit" "i387")
1554   (set_attr "mode" "XF")])
1555
1556(define_insn_and_split "*cmpxf_cc_i387"
1557  [(set (reg:CCFP FLAGS_REG)
1558	(compare:CCFP
1559	  (match_operand:XF 1 "register_operand" "f")
1560	  (match_operand:XF 2 "register_operand" "f")))
1561   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1562  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1563  "#"
1564  "&& reload_completed"
1565  [(set (match_dup 0)
1566	(unspec:HI
1567	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1568	UNSPEC_FNSTSW))
1569   (set (reg:CC FLAGS_REG)
1570	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1571  ""
1572  [(set_attr "type" "multi")
1573   (set_attr "unit" "i387")
1574   (set_attr "mode" "XF")])
1575
1576(define_insn "*cmp<mode>_i387"
1577  [(set (match_operand:HI 0 "register_operand" "=a")
1578	(unspec:HI
1579	  [(compare:CCFP
1580	     (match_operand:MODEF 1 "register_operand" "f")
1581	     (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1582	  UNSPEC_FNSTSW))]
1583  "TARGET_80387"
1584  "* return output_fp_compare (insn, operands, false, false);"
1585  [(set_attr "type" "multi")
1586   (set_attr "unit" "i387")
1587   (set_attr "mode" "<MODE>")])
1588
1589(define_insn_and_split "*cmp<mode>_cc_i387"
1590  [(set (reg:CCFP FLAGS_REG)
1591	(compare:CCFP
1592	  (match_operand:MODEF 1 "register_operand" "f")
1593	  (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1594   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1595  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1596  "#"
1597  "&& reload_completed"
1598  [(set (match_dup 0)
1599	(unspec:HI
1600	  [(compare:CCFP (match_dup 1)(match_dup 2))]
1601	UNSPEC_FNSTSW))
1602   (set (reg:CC FLAGS_REG)
1603	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1604  ""
1605  [(set_attr "type" "multi")
1606   (set_attr "unit" "i387")
1607   (set_attr "mode" "<MODE>")])
1608
1609(define_insn "*cmpu<mode>_i387"
1610  [(set (match_operand:HI 0 "register_operand" "=a")
1611	(unspec:HI
1612	  [(unspec:CCFP
1613	     [(compare:CCFP
1614		(match_operand:X87MODEF 1 "register_operand" "f")
1615		(match_operand:X87MODEF 2 "register_operand" "f"))]
1616	     UNSPEC_NOTRAP)]
1617	  UNSPEC_FNSTSW))]
1618  "TARGET_80387"
1619  "* return output_fp_compare (insn, operands, false, true);"
1620  [(set_attr "type" "multi")
1621   (set_attr "unit" "i387")
1622   (set_attr "mode" "<MODE>")])
1623
1624(define_insn_and_split "*cmpu<mode>_cc_i387"
1625  [(set (reg:CCFP FLAGS_REG)
1626	(unspec:CCFP
1627	  [(compare:CCFP
1628	     (match_operand:X87MODEF 1 "register_operand" "f")
1629	     (match_operand:X87MODEF 2 "register_operand" "f"))]
1630	  UNSPEC_NOTRAP))
1631   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1632  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1633  "#"
1634  "&& reload_completed"
1635  [(set (match_dup 0)
1636	(unspec:HI
1637	  [(unspec:CCFP
1638	     [(compare:CCFP (match_dup 1)(match_dup 2))]
1639	     UNSPEC_NOTRAP)]
1640	  UNSPEC_FNSTSW))
1641   (set (reg:CC FLAGS_REG)
1642	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1643  ""
1644  [(set_attr "type" "multi")
1645   (set_attr "unit" "i387")
1646   (set_attr "mode" "<MODE>")])
1647
1648(define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1649  [(set (match_operand:HI 0 "register_operand" "=a")
1650	(unspec:HI
1651	  [(compare:CCFP
1652	     (match_operand:X87MODEF 1 "register_operand" "f")
1653	     (float:X87MODEF
1654	       (match_operand:SWI24 2 "memory_operand" "m")))]
1655	  UNSPEC_FNSTSW))]
1656  "TARGET_80387
1657   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1658       || optimize_function_for_size_p (cfun))"
1659  "* return output_fp_compare (insn, operands, false, false);"
1660  [(set_attr "type" "multi")
1661   (set_attr "unit" "i387")
1662   (set_attr "fp_int_src" "true")
1663   (set_attr "mode" "<SWI24:MODE>")])
1664
1665(define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1666  [(set (reg:CCFP FLAGS_REG)
1667	(compare:CCFP
1668	  (match_operand:X87MODEF 1 "register_operand" "f")
1669	  (float:X87MODEF
1670	    (match_operand:SWI24 2 "memory_operand" "m"))))
1671   (clobber (match_operand:HI 0 "register_operand" "=a"))]
1672  "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1673   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1674       || optimize_function_for_size_p (cfun))"
1675  "#"
1676  "&& reload_completed"
1677  [(set (match_dup 0)
1678	(unspec:HI
1679	  [(compare:CCFP
1680	     (match_dup 1)
1681	     (float:X87MODEF (match_dup 2)))]
1682	UNSPEC_FNSTSW))
1683   (set (reg:CC FLAGS_REG)
1684	(unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1685  ""
1686  [(set_attr "type" "multi")
1687   (set_attr "unit" "i387")
1688   (set_attr "fp_int_src" "true")
1689   (set_attr "mode" "<SWI24:MODE>")])
1690
1691;; FP compares, step 2
1692;; Move the fpsw to ax.
1693
1694(define_insn "x86_fnstsw_1"
1695  [(set (match_operand:HI 0 "register_operand" "=a")
1696	(unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1697  "TARGET_80387"
1698  "fnstsw\t%0"
1699  [(set_attr "length" "2")
1700   (set_attr "mode" "SI")
1701   (set_attr "unit" "i387")])
1702
1703;; FP compares, step 3
1704;; Get ax into flags, general case.
1705
1706(define_insn "x86_sahf_1"
1707  [(set (reg:CC FLAGS_REG)
1708	(unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1709		   UNSPEC_SAHF))]
1710  "TARGET_SAHF"
1711{
1712#ifndef HAVE_AS_IX86_SAHF
1713  if (TARGET_64BIT)
1714    return ASM_BYTE "0x9e";
1715  else
1716#endif
1717  return "sahf";
1718}
1719  [(set_attr "length" "1")
1720   (set_attr "athlon_decode" "vector")
1721   (set_attr "amdfam10_decode" "direct")
1722   (set_attr "bdver1_decode" "direct")
1723   (set_attr "mode" "SI")])
1724
1725;; Pentium Pro can do steps 1 through 3 in one go.
1726;; (these instructions set flags directly)
1727
1728(define_subst_attr "unord" "unord_subst" "" "u")
1729(define_subst_attr "unordered" "unord_subst" "false" "true")
1730
1731(define_subst "unord_subst"
1732  [(set (match_operand:CCFP 0)
1733        (match_operand:CCFP 1))]
1734  ""
1735  [(set (match_dup 0)
1736        (unspec:CCFP
1737	  [(match_dup 1)]
1738	  UNSPEC_NOTRAP))])
1739
1740(define_insn "*cmpi<unord><MODEF:mode>"
1741  [(set (reg:CCFP FLAGS_REG)
1742	(compare:CCFP
1743	  (match_operand:MODEF 0 "register_operand" "f,v")
1744	  (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1745  "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1746   || (TARGET_80387 && TARGET_CMOVE)"
1747  "@
1748   * return output_fp_compare (insn, operands, true, <unordered>);
1749   %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1750  [(set_attr "type" "fcmp,ssecomi")
1751   (set_attr "prefix" "orig,maybe_vex")
1752   (set_attr "mode" "<MODEF:MODE>")
1753   (set_attr "prefix_rep" "*,0")
1754   (set (attr "prefix_data16")
1755	(cond [(eq_attr "alternative" "0")
1756		 (const_string "*")
1757	       (eq_attr "mode" "DF")
1758		 (const_string "1")
1759	      ]
1760	      (const_string "0")))
1761   (set_attr "athlon_decode" "vector")
1762   (set_attr "amdfam10_decode" "direct")
1763   (set_attr "bdver1_decode" "double")
1764   (set_attr "znver1_decode" "double")
1765   (set (attr "enabled")
1766     (if_then_else
1767       (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1768       (if_then_else
1769	 (eq_attr "alternative" "0")
1770	 (symbol_ref "TARGET_MIX_SSE_I387")
1771	 (symbol_ref "true"))
1772       (if_then_else
1773	 (eq_attr "alternative" "0")
1774	 (symbol_ref "true")
1775	 (symbol_ref "false"))))])
1776
1777(define_insn "*cmpi<unord>xf_i387"
1778  [(set (reg:CCFP FLAGS_REG)
1779	(compare:CCFP
1780	  (match_operand:XF 0 "register_operand" "f")
1781	  (match_operand:XF 1 "register_operand" "f")))]
1782  "TARGET_80387 && TARGET_CMOVE"
1783  "* return output_fp_compare (insn, operands, true, <unordered>);"
1784  [(set_attr "type" "fcmp")
1785   (set_attr "mode" "XF")
1786   (set_attr "athlon_decode" "vector")
1787   (set_attr "amdfam10_decode" "direct")
1788   (set_attr "bdver1_decode" "double")
1789   (set_attr "znver1_decode" "double")])
1790
1791;; Push/pop instructions.
1792
1793(define_insn "*push<mode>2"
1794  [(set (match_operand:DWI 0 "push_operand" "=<")
1795	(match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1796  ""
1797  "#"
1798  [(set_attr "type" "multi")
1799   (set_attr "mode" "<MODE>")])
1800
1801(define_split
1802  [(set (match_operand:DWI 0 "push_operand")
1803        (match_operand:DWI 1 "general_gr_operand"))]
1804  "reload_completed"
1805  [(const_int 0)]
1806  "ix86_split_long_move (operands); DONE;")
1807
1808(define_insn "*pushdi2_rex64"
1809  [(set (match_operand:DI 0 "push_operand" "=<,!<")
1810	(match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1811  "TARGET_64BIT"
1812  "@
1813   push{q}\t%1
1814   #"
1815  [(set_attr "type" "push,multi")
1816   (set_attr "mode" "DI")])
1817
1818;; Convert impossible pushes of immediate to existing instructions.
1819;; First try to get scratch register and go through it.  In case this
1820;; fails, push sign extended lower part first and then overwrite
1821;; upper part by 32bit move.
1822(define_peephole2
1823  [(match_scratch:DI 2 "r")
1824   (set (match_operand:DI 0 "push_operand")
1825        (match_operand:DI 1 "immediate_operand"))]
1826  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1827   && !x86_64_immediate_operand (operands[1], DImode)"
1828  [(set (match_dup 2) (match_dup 1))
1829   (set (match_dup 0) (match_dup 2))])
1830
1831;; We need to define this as both peepholer and splitter for case
1832;; peephole2 pass is not run.
1833;; "&& 1" is needed to keep it from matching the previous pattern.
1834(define_peephole2
1835  [(set (match_operand:DI 0 "push_operand")
1836        (match_operand:DI 1 "immediate_operand"))]
1837  "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1838   && !x86_64_immediate_operand (operands[1], DImode) && 1"
1839  [(set (match_dup 0) (match_dup 1))
1840   (set (match_dup 2) (match_dup 3))]
1841{
1842  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1843
1844  operands[1] = gen_lowpart (DImode, operands[2]);
1845  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1846						   GEN_INT (4)));
1847})
1848
1849(define_split
1850  [(set (match_operand:DI 0 "push_operand")
1851        (match_operand:DI 1 "immediate_operand"))]
1852  "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1853		    ? epilogue_completed : reload_completed)
1854   && !symbolic_operand (operands[1], DImode)
1855   && !x86_64_immediate_operand (operands[1], DImode)"
1856  [(set (match_dup 0) (match_dup 1))
1857   (set (match_dup 2) (match_dup 3))]
1858{
1859  split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1860
1861  operands[1] = gen_lowpart (DImode, operands[2]);
1862  operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1863						   GEN_INT (4)));
1864})
1865
1866(define_insn "*pushsi2"
1867  [(set (match_operand:SI 0 "push_operand" "=<")
1868	(match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1869  "!TARGET_64BIT"
1870  "push{l}\t%1"
1871  [(set_attr "type" "push")
1872   (set_attr "mode" "SI")])
1873
1874;; emit_push_insn when it calls move_by_pieces requires an insn to
1875;; "push a byte/word".  But actually we use pushl, which has the effect
1876;; of rounding the amount pushed up to a word.
1877
1878;; For TARGET_64BIT we always round up to 8 bytes.
1879(define_insn "*push<mode>2_rex64"
1880  [(set (match_operand:SWI124 0 "push_operand" "=X")
1881	(match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1882  "TARGET_64BIT"
1883  "push{q}\t%q1"
1884  [(set_attr "type" "push")
1885   (set_attr "mode" "DI")])
1886
1887(define_insn "*push<mode>2"
1888  [(set (match_operand:SWI12 0 "push_operand" "=X")
1889	(match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1890  "!TARGET_64BIT"
1891  "push{l}\t%k1"
1892  [(set_attr "type" "push")
1893   (set_attr "mode" "SI")])
1894
1895(define_insn "*push<mode>2_prologue"
1896  [(set (match_operand:W 0 "push_operand" "=<")
1897	(match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1898   (clobber (mem:BLK (scratch)))]
1899  ""
1900  "push{<imodesuffix>}\t%1"
1901  [(set_attr "type" "push")
1902   (set_attr "mode" "<MODE>")])
1903
1904(define_insn "*pop<mode>1"
1905  [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1906	(match_operand:W 1 "pop_operand" ">"))]
1907  ""
1908  "pop{<imodesuffix>}\t%0"
1909  [(set_attr "type" "pop")
1910   (set_attr "mode" "<MODE>")])
1911
1912(define_insn "*pop<mode>1_epilogue"
1913  [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1914	(match_operand:W 1 "pop_operand" ">"))
1915   (clobber (mem:BLK (scratch)))]
1916  ""
1917  "pop{<imodesuffix>}\t%0"
1918  [(set_attr "type" "pop")
1919   (set_attr "mode" "<MODE>")])
1920
1921(define_insn "*pushfl<mode>2"
1922  [(set (match_operand:W 0 "push_operand" "=<")
1923	(match_operand:W 1 "flags_reg_operand"))]
1924  ""
1925  "pushf{<imodesuffix>}"
1926  [(set_attr "type" "push")
1927   (set_attr "mode" "<MODE>")])
1928
1929(define_insn "*popfl<mode>1"
1930  [(set (match_operand:W 0 "flags_reg_operand")
1931	(match_operand:W 1 "pop_operand" ">"))]
1932  ""
1933  "popf{<imodesuffix>}"
1934  [(set_attr "type" "pop")
1935   (set_attr "mode" "<MODE>")])
1936
1937
1938;; Reload patterns to support multi-word load/store
1939;; with non-offsetable address.
1940(define_expand "reload_noff_store"
1941  [(parallel [(match_operand 0 "memory_operand" "=m")
1942              (match_operand 1 "register_operand" "r")
1943              (match_operand:DI 2 "register_operand" "=&r")])]
1944  "TARGET_64BIT"
1945{
1946  rtx mem = operands[0];
1947  rtx addr = XEXP (mem, 0);
1948
1949  emit_move_insn (operands[2], addr);
1950  mem = replace_equiv_address_nv (mem, operands[2]);
1951
1952  emit_insn (gen_rtx_SET (mem, operands[1]));
1953  DONE;
1954})
1955
1956(define_expand "reload_noff_load"
1957  [(parallel [(match_operand 0 "register_operand" "=r")
1958              (match_operand 1 "memory_operand" "m")
1959              (match_operand:DI 2 "register_operand" "=r")])]
1960  "TARGET_64BIT"
1961{
1962  rtx mem = operands[1];
1963  rtx addr = XEXP (mem, 0);
1964
1965  emit_move_insn (operands[2], addr);
1966  mem = replace_equiv_address_nv (mem, operands[2]);
1967
1968  emit_insn (gen_rtx_SET (operands[0], mem));
1969  DONE;
1970})
1971
1972;; Move instructions.
1973
1974(define_expand "movxi"
1975  [(set (match_operand:XI 0 "nonimmediate_operand")
1976	(match_operand:XI 1 "general_operand"))]
1977  "TARGET_AVX512F"
1978  "ix86_expand_vector_move (XImode, operands); DONE;")
1979
1980(define_expand "movoi"
1981  [(set (match_operand:OI 0 "nonimmediate_operand")
1982	(match_operand:OI 1 "general_operand"))]
1983  "TARGET_AVX"
1984  "ix86_expand_vector_move (OImode, operands); DONE;")
1985
1986(define_expand "movti"
1987  [(set (match_operand:TI 0 "nonimmediate_operand")
1988	(match_operand:TI 1 "general_operand"))]
1989  "TARGET_64BIT || TARGET_SSE"
1990{
1991  if (TARGET_64BIT)
1992    ix86_expand_move (TImode, operands);
1993  else
1994    ix86_expand_vector_move (TImode, operands);
1995  DONE;
1996})
1997
1998;; This expands to what emit_move_complex would generate if we didn't
1999;; have a movti pattern.  Having this avoids problems with reload on
2000;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2001;; to have around all the time.
2002(define_expand "movcdi"
2003  [(set (match_operand:CDI 0 "nonimmediate_operand")
2004	(match_operand:CDI 1 "general_operand"))]
2005  ""
2006{
2007  if (push_operand (operands[0], CDImode))
2008    emit_move_complex_push (CDImode, operands[0], operands[1]);
2009  else
2010    emit_move_complex_parts (operands[0], operands[1]);
2011  DONE;
2012})
2013
2014(define_expand "mov<mode>"
2015  [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2016	(match_operand:SWI1248x 1 "general_operand"))]
2017  ""
2018  "ix86_expand_move (<MODE>mode, operands); DONE;")
2019
2020(define_insn "*mov<mode>_xor"
2021  [(set (match_operand:SWI48 0 "register_operand" "=r")
2022	(match_operand:SWI48 1 "const0_operand"))
2023   (clobber (reg:CC FLAGS_REG))]
2024  "reload_completed"
2025  "xor{l}\t%k0, %k0"
2026  [(set_attr "type" "alu1")
2027   (set_attr "modrm_class" "op0")
2028   (set_attr "mode" "SI")
2029   (set_attr "length_immediate" "0")])
2030
2031(define_insn "*mov<mode>_or"
2032  [(set (match_operand:SWI48 0 "register_operand" "=r")
2033	(match_operand:SWI48 1 "constm1_operand"))
2034   (clobber (reg:CC FLAGS_REG))]
2035  "reload_completed"
2036  "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2037  [(set_attr "type" "alu1")
2038   (set_attr "mode" "<MODE>")
2039   (set_attr "length_immediate" "1")])
2040
2041(define_insn "*movxi_internal_avx512f"
2042  [(set (match_operand:XI 0 "nonimmediate_operand"		"=v,v ,v ,m")
2043	(match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2044  "TARGET_AVX512F
2045   && (register_operand (operands[0], XImode)
2046       || register_operand (operands[1], XImode))"
2047{
2048  switch (get_attr_type (insn))
2049    {
2050    case TYPE_SSELOG1:
2051      return standard_sse_constant_opcode (insn, operands);
2052
2053    case TYPE_SSEMOV:
2054      if (misaligned_operand (operands[0], XImode)
2055	  || misaligned_operand (operands[1], XImode))
2056	return "vmovdqu32\t{%1, %0|%0, %1}";
2057      else
2058	return "vmovdqa32\t{%1, %0|%0, %1}";
2059
2060    default:
2061      gcc_unreachable ();
2062    }
2063}
2064  [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2065   (set_attr "prefix" "evex")
2066   (set_attr "mode" "XI")])
2067
2068(define_insn "*movoi_internal_avx"
2069  [(set (match_operand:OI 0 "nonimmediate_operand"		"=v,v ,v ,m")
2070	(match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2071  "TARGET_AVX
2072   && (register_operand (operands[0], OImode)
2073       || register_operand (operands[1], OImode))"
2074{
2075  switch (get_attr_type (insn))
2076    {
2077    case TYPE_SSELOG1:
2078      return standard_sse_constant_opcode (insn, operands);
2079
2080    case TYPE_SSEMOV:
2081      if (misaligned_operand (operands[0], OImode)
2082	  || misaligned_operand (operands[1], OImode))
2083	{
2084	  if (get_attr_mode (insn) == MODE_V8SF)
2085	    return "vmovups\t{%1, %0|%0, %1}";
2086	  else if (get_attr_mode (insn) == MODE_XI)
2087	    return "vmovdqu32\t{%1, %0|%0, %1}";
2088	  else
2089	    return "vmovdqu\t{%1, %0|%0, %1}";
2090	}
2091      else
2092	{
2093	  if (get_attr_mode (insn) == MODE_V8SF)
2094	    return "vmovaps\t{%1, %0|%0, %1}";
2095	  else if (get_attr_mode (insn) == MODE_XI)
2096	    return "vmovdqa32\t{%1, %0|%0, %1}";
2097	  else
2098	    return "vmovdqa\t{%1, %0|%0, %1}";
2099	}
2100
2101    default:
2102      gcc_unreachable ();
2103    }
2104}
2105  [(set_attr "isa" "*,avx2,*,*")
2106   (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2107   (set_attr "prefix" "vex")
2108   (set (attr "mode")
2109	(cond [(ior (match_operand 0 "ext_sse_reg_operand")
2110		    (match_operand 1 "ext_sse_reg_operand"))
2111		 (const_string "XI")
2112	       (and (eq_attr "alternative" "1")
2113		    (match_test "TARGET_AVX512VL"))
2114		 (const_string "XI")
2115	       (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2116		    (and (eq_attr "alternative" "3")
2117			 (match_test "TARGET_SSE_TYPELESS_STORES")))
2118		 (const_string "V8SF")
2119	      ]
2120	      (const_string "OI")))])
2121
2122(define_insn "*movti_internal"
2123  [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2124	(match_operand:TI 1 "general_operand"	   "riFo,re,C,BC,vm,v,Ye,r"))]
2125  "(TARGET_64BIT
2126    && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2127   || (TARGET_SSE
2128       && nonimmediate_or_sse_const_operand (operands[1], TImode)
2129       && (register_operand (operands[0], TImode)
2130	   || register_operand (operands[1], TImode)))"
2131{
2132  switch (get_attr_type (insn))
2133    {
2134    case TYPE_MULTI:
2135      return "#";
2136
2137    case TYPE_SSELOG1:
2138      return standard_sse_constant_opcode (insn, operands);
2139
2140    case TYPE_SSEMOV:
2141      /* TDmode values are passed as TImode on the stack.  Moving them
2142	 to stack may result in unaligned memory access.  */
2143      if (misaligned_operand (operands[0], TImode)
2144	  || misaligned_operand (operands[1], TImode))
2145	{
2146	  if (get_attr_mode (insn) == MODE_V4SF)
2147	    return "%vmovups\t{%1, %0|%0, %1}";
2148	  else if (get_attr_mode (insn) == MODE_XI)
2149	    return "vmovdqu32\t{%1, %0|%0, %1}";
2150	  else
2151	    return "%vmovdqu\t{%1, %0|%0, %1}";
2152	}
2153      else
2154	{
2155	  if (get_attr_mode (insn) == MODE_V4SF)
2156	    return "%vmovaps\t{%1, %0|%0, %1}";
2157	  else if (get_attr_mode (insn) == MODE_XI)
2158	    return "vmovdqa32\t{%1, %0|%0, %1}";
2159	  else
2160	    return "%vmovdqa\t{%1, %0|%0, %1}";
2161	}
2162
2163    default:
2164      gcc_unreachable ();
2165    }
2166}
2167  [(set (attr "isa")
2168     (cond [(eq_attr "alternative" "0,1,6,7")
2169	      (const_string "x64")
2170	    (eq_attr "alternative" "3")
2171	      (const_string "sse2")
2172	   ]
2173	   (const_string "*")))
2174   (set (attr "type")
2175     (cond [(eq_attr "alternative" "0,1,6,7")
2176	      (const_string "multi")
2177	    (eq_attr "alternative" "2,3")
2178	      (const_string "sselog1")
2179	   ]
2180	   (const_string "ssemov")))
2181   (set (attr "prefix")
2182     (if_then_else (eq_attr "type" "sselog1,ssemov")
2183       (const_string "maybe_vex")
2184       (const_string "orig")))
2185   (set (attr "mode")
2186	(cond [(eq_attr "alternative" "0,1")
2187		 (const_string "DI")
2188	       (ior (match_operand 0 "ext_sse_reg_operand")
2189		    (match_operand 1 "ext_sse_reg_operand"))
2190		 (const_string "XI")
2191	       (and (eq_attr "alternative" "3")
2192		    (match_test "TARGET_AVX512VL"))
2193		 (const_string "XI")
2194	       (ior (not (match_test "TARGET_SSE2"))
2195		    (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2196			 (and (eq_attr "alternative" "5")
2197			      (match_test "TARGET_SSE_TYPELESS_STORES"))))
2198		 (const_string "V4SF")
2199	       (match_test "TARGET_AVX")
2200		 (const_string "TI")
2201	       (match_test "optimize_function_for_size_p (cfun)")
2202		 (const_string "V4SF")
2203	       ]
2204	       (const_string "TI")))])
2205
2206(define_split
2207  [(set (match_operand:TI 0 "sse_reg_operand")
2208        (match_operand:TI 1 "general_reg_operand"))]
2209  "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2210   && reload_completed"
2211  [(set (match_dup 2)
2212  	(vec_merge:V2DI
2213	  (vec_duplicate:V2DI (match_dup 3))
2214	  (match_dup 2)
2215	  (const_int 2)))]
2216{
2217  operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2218  operands[3] = gen_highpart (DImode, operands[1]);
2219
2220  emit_move_insn (gen_lowpart (DImode, operands[0]),
2221  		  gen_lowpart (DImode, operands[1]));
2222})
2223
2224(define_insn "*movdi_internal"
2225  [(set (match_operand:DI 0 "nonimmediate_operand"
2226    "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?*Yd,?r ,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m")
2227	(match_operand:DI 1 "general_operand"
2228    "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,v,*Ye,r   ,*Yj,r   ,*Yj ,*Yn ,*r,*km,*k,*k"))]
2229  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2230{
2231  switch (get_attr_type (insn))
2232    {
2233    case TYPE_MSKMOV:
2234      return "kmovq\t{%1, %0|%0, %1}";
2235
2236    case TYPE_MULTI:
2237      return "#";
2238
2239    case TYPE_MMX:
2240      return "pxor\t%0, %0";
2241
2242    case TYPE_MMXMOV:
2243      /* Handle broken assemblers that require movd instead of movq.  */
2244      if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2245	  && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2246	return "movd\t{%1, %0|%0, %1}";
2247      return "movq\t{%1, %0|%0, %1}";
2248
2249    case TYPE_SSELOG1:
2250      return standard_sse_constant_opcode (insn, operands);
2251
2252    case TYPE_SSEMOV:
2253      switch (get_attr_mode (insn))
2254	{
2255	case MODE_DI:
2256	  /* Handle broken assemblers that require movd instead of movq.  */
2257	  if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2258	      && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2259	    return "%vmovd\t{%1, %0|%0, %1}";
2260	  return "%vmovq\t{%1, %0|%0, %1}";
2261
2262	case MODE_TI:
2263	  /* Handle AVX512 registers set.  */
2264	  if (EXT_REX_SSE_REG_P (operands[0])
2265	      || EXT_REX_SSE_REG_P (operands[1]))
2266	    return "vmovdqa64\t{%1, %0|%0, %1}";
2267	  return "%vmovdqa\t{%1, %0|%0, %1}";
2268
2269	case MODE_V2SF:
2270	  gcc_assert (!TARGET_AVX);
2271	  return "movlps\t{%1, %0|%0, %1}";
2272	case MODE_V4SF:
2273	  return "%vmovaps\t{%1, %0|%0, %1}";
2274
2275	default:
2276	  gcc_unreachable ();
2277	}
2278
2279    case TYPE_SSECVT:
2280      if (SSE_REG_P (operands[0]))
2281	return "movq2dq\t{%1, %0|%0, %1}";
2282      else
2283	return "movdq2q\t{%1, %0|%0, %1}";
2284
2285    case TYPE_LEA:
2286      return "lea{q}\t{%E1, %0|%0, %E1}";
2287
2288    case TYPE_IMOV:
2289      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2290      if (get_attr_mode (insn) == MODE_SI)
2291	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2292      else if (which_alternative == 4)
2293	return "movabs{q}\t{%1, %0|%0, %1}";
2294      else if (ix86_use_lea_for_mov (insn, operands))
2295	return "lea{q}\t{%E1, %0|%0, %E1}";
2296      else
2297	return "mov{q}\t{%1, %0|%0, %1}";
2298
2299    default:
2300      gcc_unreachable ();
2301    }
2302}
2303  [(set (attr "isa")
2304     (cond [(eq_attr "alternative" "0,1,17,18")
2305	      (const_string "nox64")
2306	    (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25")
2307	      (const_string "x64")
2308	   ]
2309	   (const_string "*")))
2310   (set (attr "type")
2311     (cond [(eq_attr "alternative" "0,1,17,18")
2312	      (const_string "multi")
2313	    (eq_attr "alternative" "6")
2314	      (const_string "mmx")
2315	    (eq_attr "alternative" "7,8,9,10,11")
2316	      (const_string "mmxmov")
2317	    (eq_attr "alternative" "12")
2318	      (const_string "sselog1")
2319	    (eq_attr "alternative" "13,14,15,16,19,20")
2320	      (const_string "ssemov")
2321	    (eq_attr "alternative" "21,22")
2322	      (const_string "ssecvt")
2323	    (eq_attr "alternative" "23,24,25,26")
2324	      (const_string "mskmov")
2325	    (and (match_operand 0 "register_operand")
2326		 (match_operand 1 "pic_32bit_operand"))
2327	      (const_string "lea")
2328	   ]
2329	   (const_string "imov")))
2330   (set (attr "modrm")
2331     (if_then_else
2332       (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2333       (const_string "0")
2334       (const_string "*")))
2335   (set (attr "length_immediate")
2336     (if_then_else
2337       (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2338       (const_string "8")
2339       (const_string "*")))
2340   (set (attr "prefix_rex")
2341     (if_then_else
2342       (eq_attr "alternative" "10,11,19,20")
2343       (const_string "1")
2344       (const_string "*")))
2345   (set (attr "prefix")
2346     (if_then_else (eq_attr "type" "sselog1,ssemov")
2347       (const_string "maybe_vex")
2348       (const_string "orig")))
2349   (set (attr "prefix_data16")
2350     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2351       (const_string "1")
2352       (const_string "*")))
2353   (set (attr "mode")
2354     (cond [(eq_attr "alternative" "2")
2355	      (const_string "SI")
2356	    (eq_attr "alternative" "12,13")
2357	      (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2358			  (match_operand 1 "ext_sse_reg_operand"))
2359		       (const_string "TI")
2360		     (ior (not (match_test "TARGET_SSE2"))
2361			  (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2362		       (const_string "V4SF")
2363		     (match_test "TARGET_AVX")
2364		       (const_string "TI")
2365		     (match_test "optimize_function_for_size_p (cfun)")
2366		       (const_string "V4SF")
2367		    ]
2368		    (const_string "TI"))
2369
2370	    (and (eq_attr "alternative" "14,15,16")
2371		 (not (match_test "TARGET_SSE2")))
2372	      (const_string "V2SF")
2373	   ]
2374	   (const_string "DI")))
2375   (set (attr "enabled")
2376     (cond [(eq_attr "alternative" "15")
2377              (if_then_else
2378		(match_test "TARGET_STV && TARGET_SSE2")
2379		(symbol_ref "false")
2380		(const_string "*"))
2381	    (eq_attr "alternative" "16")
2382              (if_then_else
2383		(match_test "TARGET_STV && TARGET_SSE2")
2384		(symbol_ref "true")
2385		(symbol_ref "false"))
2386	   ]
2387	   (const_string "*")))])
2388
2389(define_split
2390  [(set (match_operand:<DWI> 0 "general_reg_operand")
2391        (match_operand:<DWI> 1 "sse_reg_operand"))]
2392  "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC
2393   && reload_completed"
2394  [(set (match_dup 2)
2395  	(vec_select:DWIH
2396	  (match_dup 3)
2397	  (parallel [(const_int 1)])))]
2398{
2399  operands[2] = gen_highpart (<MODE>mode, operands[0]);
2400  operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2401
2402  emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2403  		  gen_lowpart (<MODE>mode, operands[1]));
2404})
2405
2406(define_split
2407  [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2408        (match_operand:DWI 1 "general_gr_operand"))]
2409  "reload_completed"
2410  [(const_int 0)]
2411  "ix86_split_long_move (operands); DONE;")
2412
2413(define_split
2414  [(set (match_operand:DI 0 "sse_reg_operand")
2415        (match_operand:DI 1 "general_reg_operand"))]
2416  "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2417   && reload_completed"
2418  [(set (match_dup 2)
2419  	(vec_merge:V4SI
2420	  (vec_duplicate:V4SI (match_dup 3))
2421	  (match_dup 2)
2422	  (const_int 2)))]
2423{
2424  operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2425  operands[3] = gen_highpart (SImode, operands[1]);
2426
2427  emit_move_insn (gen_lowpart (SImode, operands[0]),
2428  		  gen_lowpart (SImode, operands[1]));
2429})
2430
2431;; movabsq $0x0012345678000000, %rax is longer
2432;; than movl $0x12345678, %eax; shlq $24, %rax.
2433(define_peephole2
2434  [(set (match_operand:DI 0 "register_operand")
2435	(match_operand:DI 1 "const_int_operand"))]
2436  "TARGET_64BIT
2437   && optimize_insn_for_size_p ()
2438   && LEGACY_INT_REG_P (operands[0])
2439   && !x86_64_immediate_operand (operands[1], DImode)
2440   && !x86_64_zext_immediate_operand (operands[1], DImode)
2441   && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2442        & ~(HOST_WIDE_INT) 0xffffffff)
2443   && peep2_regno_dead_p (0, FLAGS_REG)"
2444  [(set (match_dup 0) (match_dup 1))
2445   (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2446	      (clobber (reg:CC FLAGS_REG))])]
2447{
2448  int shift = ctz_hwi (UINTVAL (operands[1]));
2449  operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2450  operands[2] = gen_int_mode (shift, QImode);
2451})
2452
2453(define_insn "*movsi_internal"
2454  [(set (match_operand:SI 0 "nonimmediate_operand"
2455    "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm")
2456	(match_operand:SI 1 "general_operand"
2457    "g ,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,r   ,*r,*km,*k"))]
2458  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2459{
2460  switch (get_attr_type (insn))
2461    {
2462    case TYPE_SSELOG1:
2463      return standard_sse_constant_opcode (insn, operands);
2464
2465    case TYPE_MSKMOV:
2466      return "kmovd\t{%1, %0|%0, %1}";
2467
2468    case TYPE_SSEMOV:
2469      switch (get_attr_mode (insn))
2470	{
2471	case MODE_SI:
2472          return "%vmovd\t{%1, %0|%0, %1}";
2473	case MODE_TI:
2474	  return "%vmovdqa\t{%1, %0|%0, %1}";
2475	case MODE_XI:
2476	  return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2477
2478	case MODE_V4SF:
2479	  return "%vmovaps\t{%1, %0|%0, %1}";
2480
2481	case MODE_SF:
2482	  gcc_assert (!TARGET_AVX);
2483          return "movss\t{%1, %0|%0, %1}";
2484
2485	default:
2486	  gcc_unreachable ();
2487	}
2488
2489    case TYPE_MMX:
2490      return "pxor\t%0, %0";
2491
2492    case TYPE_MMXMOV:
2493      switch (get_attr_mode (insn))
2494	{
2495	case MODE_DI:
2496	  return "movq\t{%1, %0|%0, %1}";
2497	case MODE_SI:
2498	  return "movd\t{%1, %0|%0, %1}";
2499
2500	default:
2501	  gcc_unreachable ();
2502	}
2503
2504    case TYPE_LEA:
2505      return "lea{l}\t{%E1, %0|%0, %E1}";
2506
2507    case TYPE_IMOV:
2508      gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2509      if (ix86_use_lea_for_mov (insn, operands))
2510	return "lea{l}\t{%E1, %0|%0, %E1}";
2511      else
2512	return "mov{l}\t{%1, %0|%0, %1}";
2513
2514    default:
2515      gcc_unreachable ();
2516    }
2517}
2518  [(set (attr "type")
2519     (cond [(eq_attr "alternative" "2")
2520	      (const_string "mmx")
2521	    (eq_attr "alternative" "3,4,5,6,7")
2522	      (const_string "mmxmov")
2523	    (eq_attr "alternative" "8")
2524	      (const_string "sselog1")
2525	    (eq_attr "alternative" "9,10,11,12,13")
2526	      (const_string "ssemov")
2527	    (eq_attr "alternative" "14,15,16")
2528	      (const_string "mskmov")
2529	    (and (match_operand 0 "register_operand")
2530		 (match_operand 1 "pic_32bit_operand"))
2531	      (const_string "lea")
2532	   ]
2533	   (const_string "imov")))
2534   (set (attr "prefix")
2535     (if_then_else (eq_attr "type" "sselog1,ssemov")
2536       (const_string "maybe_vex")
2537       (const_string "orig")))
2538   (set (attr "prefix_data16")
2539     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2540       (const_string "1")
2541       (const_string "*")))
2542   (set (attr "mode")
2543     (cond [(eq_attr "alternative" "2,3")
2544	      (const_string "DI")
2545	    (eq_attr "alternative" "8,9")
2546	      (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2547			  (match_operand 1 "ext_sse_reg_operand"))
2548		       (const_string "XI")
2549		     (ior (not (match_test "TARGET_SSE2"))
2550			  (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2551		       (const_string "V4SF")
2552		     (match_test "TARGET_AVX")
2553		       (const_string "TI")
2554		     (match_test "optimize_function_for_size_p (cfun)")
2555		       (const_string "V4SF")
2556		    ]
2557		    (const_string "TI"))
2558
2559	    (and (eq_attr "alternative" "10,11")
2560	         (not (match_test "TARGET_SSE2")))
2561	      (const_string "SF")
2562	   ]
2563	   (const_string "SI")))])
2564
2565(define_insn "*movhi_internal"
2566  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2567	(match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2568  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2569{
2570  switch (get_attr_type (insn))
2571    {
2572    case TYPE_IMOVX:
2573      /* movzwl is faster than movw on p2 due to partial word stalls,
2574	 though not as fast as an aligned movl.  */
2575      return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2576
2577    case TYPE_MSKMOV:
2578      switch (which_alternative)
2579	{
2580	case 4:
2581	  return "kmovw\t{%k1, %0|%0, %k1}";
2582	case 6:
2583	  return "kmovw\t{%1, %k0|%k0, %1}";
2584	case 5:
2585	case 7:
2586	  return "kmovw\t{%1, %0|%0, %1}";
2587	default:
2588	  gcc_unreachable ();
2589	}
2590
2591    default:
2592      if (get_attr_mode (insn) == MODE_SI)
2593	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2594      else
2595	return "mov{w}\t{%1, %0|%0, %1}";
2596    }
2597}
2598  [(set (attr "type")
2599     (cond [(eq_attr "alternative" "4,5,6,7")
2600	      (const_string "mskmov")
2601	    (match_test "optimize_function_for_size_p (cfun)")
2602	      (const_string "imov")
2603	    (and (eq_attr "alternative" "0")
2604		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2605		      (not (match_test "TARGET_HIMODE_MATH"))))
2606	      (const_string "imov")
2607	    (and (eq_attr "alternative" "1,2")
2608		 (match_operand:HI 1 "aligned_operand"))
2609	      (const_string "imov")
2610	    (and (match_test "TARGET_MOVX")
2611		 (eq_attr "alternative" "0,2"))
2612	      (const_string "imovx")
2613	   ]
2614	   (const_string "imov")))
2615    (set (attr "prefix")
2616      (if_then_else (eq_attr "alternative" "4,5,6,7")
2617	(const_string "vex")
2618	(const_string "orig")))
2619    (set (attr "mode")
2620      (cond [(eq_attr "type" "imovx")
2621	       (const_string "SI")
2622	     (and (eq_attr "alternative" "1,2")
2623		  (match_operand:HI 1 "aligned_operand"))
2624	       (const_string "SI")
2625	     (and (eq_attr "alternative" "0")
2626		  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2627		       (not (match_test "TARGET_HIMODE_MATH"))))
2628	       (const_string "SI")
2629	    ]
2630	    (const_string "HI")))])
2631
2632;; Situation is quite tricky about when to choose full sized (SImode) move
2633;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2634;; partial register dependency machines (such as AMD Athlon), where QImode
2635;; moves issue extra dependency and for partial register stalls machines
2636;; that don't use QImode patterns (and QImode move cause stall on the next
2637;; instruction).
2638;;
2639;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2640;; register stall machines with, where we use QImode instructions, since
2641;; partial register stall can be caused there.  Then we use movzx.
2642
2643(define_insn "*movqi_internal"
2644  [(set (match_operand:QI 0 "nonimmediate_operand"
2645			"=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2646	(match_operand:QI 1 "general_operand"
2647			"Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2648  "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2649{
2650  static char buf[128];
2651  const char *ops;
2652  const char *suffix;
2653
2654  switch (get_attr_type (insn))
2655    {
2656    case TYPE_IMOVX:
2657      gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2658      return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2659
2660    case TYPE_MSKMOV:
2661      switch (which_alternative)
2662        {
2663	case 9:
2664	  ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2665	  break;
2666	case 11:
2667	  ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2668	  break;
2669	case 12:
2670	case 13:
2671	  gcc_assert (TARGET_AVX512DQ);
2672	  /* FALLTHRU */
2673	case 10:
2674	  ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2675	  break;
2676	default:
2677	  gcc_unreachable ();
2678	}
2679
2680      suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2681
2682      snprintf (buf, sizeof (buf), ops, suffix);
2683      return buf;
2684
2685    default:
2686      if (get_attr_mode (insn) == MODE_SI)
2687	return "mov{l}\t{%k1, %k0|%k0, %k1}";
2688      else
2689	return "mov{b}\t{%1, %0|%0, %1}";
2690    }
2691}
2692  [(set (attr "isa")
2693     (cond [(eq_attr "alternative" "1,2")
2694	      (const_string "x64")
2695	    (eq_attr "alternative" "12,13")
2696	      (const_string "avx512dq")
2697	   ]
2698	   (const_string "*")))
2699   (set (attr "type")
2700     (cond [(eq_attr "alternative" "9,10,11,12,13")
2701	      (const_string "mskmov")
2702	    (and (eq_attr "alternative" "7")
2703		 (not (match_operand:QI 1 "aligned_operand")))
2704	      (const_string "imovx")
2705	    (match_test "optimize_function_for_size_p (cfun)")
2706	      (const_string "imov")
2707	    (and (eq_attr "alternative" "5")
2708		 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2709		      (not (match_test "TARGET_QIMODE_MATH"))))
2710	      (const_string "imov")
2711	    (eq_attr "alternative" "5,7")
2712	      (const_string "imovx")
2713	    (and (match_test "TARGET_MOVX")
2714		 (eq_attr "alternative" "4"))
2715	      (const_string "imovx")
2716	   ]
2717	   (const_string "imov")))
2718   (set (attr "prefix")
2719     (if_then_else (eq_attr "alternative" "9,10,11")
2720       (const_string "vex")
2721       (const_string "orig")))
2722   (set (attr "mode")
2723      (cond [(eq_attr "alternative" "5,6,7")
2724	       (const_string "SI")
2725	     (eq_attr "alternative" "8")
2726	       (const_string "QI")
2727	     (and (eq_attr "alternative" "9,10,11")
2728		  (not (match_test "TARGET_AVX512DQ")))
2729	       (const_string "HI")
2730	     (eq_attr "type" "imovx")
2731	       (const_string "SI")
2732	     ;; For -Os, 8-bit immediates are always shorter than 32-bit
2733	     ;; ones.
2734	     (and (eq_attr "type" "imov")
2735		  (and (eq_attr "alternative" "3")
2736		       (match_test "optimize_function_for_size_p (cfun)")))
2737	       (const_string "QI")
2738	     ;; For -Os, movl where one or both operands are NON_Q_REGS
2739	     ;; and both are LEGACY_REGS is shorter than movb.
2740	     ;; Otherwise movb and movl sizes are the same, so decide purely
2741	     ;; based on speed factors.
2742	     (and (eq_attr "type" "imov")
2743		  (and (eq_attr "alternative" "1")
2744		       (match_test "optimize_function_for_size_p (cfun)")))
2745	       (const_string "SI")
2746	     (and (eq_attr "type" "imov")
2747		  (and (eq_attr "alternative" "0,1,2,3")
2748		       (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2749			    (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2750	       (const_string "SI")
2751	     ;; Avoid partial register stalls when not using QImode arithmetic
2752	     (and (eq_attr "type" "imov")
2753		  (and (eq_attr "alternative" "0,1,2,3")
2754		       (and (match_test "TARGET_PARTIAL_REG_STALL")
2755			    (not (match_test "TARGET_QIMODE_MATH")))))
2756	       (const_string "SI")
2757	   ]
2758	   (const_string "QI")))])
2759
2760;; Stores and loads of ax to arbitrary constant address.
2761;; We fake an second form of instruction to force reload to load address
2762;; into register when rax is not available
2763(define_insn "*movabs<mode>_1"
2764  [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2765	(match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2766  "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2767{
2768  /* Recover the full memory rtx.  */
2769  operands[0] = SET_DEST (PATTERN (insn));
2770  switch (which_alternative)
2771    {
2772    case 0:
2773      return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2774    case 1:
2775      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2776    default:
2777      gcc_unreachable ();
2778    }
2779}
2780  [(set_attr "type" "imov")
2781   (set_attr "modrm" "0,*")
2782   (set_attr "length_address" "8,0")
2783   (set_attr "length_immediate" "0,*")
2784   (set_attr "memory" "store")
2785   (set_attr "mode" "<MODE>")])
2786
2787(define_insn "*movabs<mode>_2"
2788  [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2789        (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2790  "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2791{
2792  /* Recover the full memory rtx.  */
2793  operands[1] = SET_SRC (PATTERN (insn));
2794  switch (which_alternative)
2795    {
2796    case 0:
2797      return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2798    case 1:
2799      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2800    default:
2801      gcc_unreachable ();
2802    }
2803}
2804  [(set_attr "type" "imov")
2805   (set_attr "modrm" "0,*")
2806   (set_attr "length_address" "8,0")
2807   (set_attr "length_immediate" "0")
2808   (set_attr "memory" "load")
2809   (set_attr "mode" "<MODE>")])
2810
2811(define_insn "*swap<mode>"
2812  [(set (match_operand:SWI48 0 "register_operand" "+r")
2813	(match_operand:SWI48 1 "register_operand" "+r"))
2814   (set (match_dup 1)
2815	(match_dup 0))]
2816  ""
2817  "xchg{<imodesuffix>}\t%1, %0"
2818  [(set_attr "type" "imov")
2819   (set_attr "mode" "<MODE>")
2820   (set_attr "pent_pair" "np")
2821   (set_attr "athlon_decode" "vector")
2822   (set_attr "amdfam10_decode" "double")
2823   (set_attr "bdver1_decode" "double")])
2824
2825(define_insn "*swap<mode>"
2826  [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2827	(match_operand:SWI12 1 "register_operand" "+<r>,r"))
2828   (set (match_dup 1)
2829	(match_dup 0))]
2830  ""
2831  "@
2832   xchg{<imodesuffix>}\t%1, %0
2833   xchg{l}\t%k1, %k0"
2834  [(set_attr "type" "imov")
2835   (set_attr "mode" "<MODE>,SI")
2836   (set (attr "preferred_for_size")
2837     (cond [(eq_attr "alternative" "0")
2838	      (symbol_ref "false")]
2839	   (symbol_ref "true")))
2840   ;; Potential partial reg stall on alternative 1.
2841   (set (attr "preferred_for_speed")
2842     (cond [(eq_attr "alternative" "1")
2843	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2844	   (symbol_ref "true")))
2845   (set_attr "pent_pair" "np")
2846   (set_attr "athlon_decode" "vector")
2847   (set_attr "amdfam10_decode" "double")
2848   (set_attr "bdver1_decode" "double")])
2849
2850(define_expand "movstrict<mode>"
2851  [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2852	(match_operand:SWI12 1 "general_operand"))]
2853  ""
2854{
2855  if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2856    FAIL;
2857  if (SUBREG_P (operands[0])
2858      && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2859    FAIL;
2860  /* Don't generate memory->memory moves, go through a register */
2861  if (MEM_P (operands[0]) && MEM_P (operands[1]))
2862    operands[1] = force_reg (<MODE>mode, operands[1]);
2863})
2864
2865(define_insn "*movstrict<mode>_1"
2866  [(set (strict_low_part
2867	  (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2868	(match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2869  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2870   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2871  "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2872  [(set_attr "type" "imov")
2873   (set_attr "mode" "<MODE>")])
2874
2875(define_insn "*movstrict<mode>_xor"
2876  [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2877	(match_operand:SWI12 1 "const0_operand"))
2878   (clobber (reg:CC FLAGS_REG))]
2879  "reload_completed"
2880  "xor{<imodesuffix>}\t%0, %0"
2881  [(set_attr "type" "alu1")
2882   (set_attr "modrm_class" "op0")
2883   (set_attr "mode" "<MODE>")
2884   (set_attr "length_immediate" "0")])
2885
2886(define_expand "extv<mode>"
2887  [(set (match_operand:SWI24 0 "register_operand")
2888	(sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2889			    (match_operand:SI 2 "const_int_operand")
2890			    (match_operand:SI 3 "const_int_operand")))]
2891  ""
2892{
2893  /* Handle extractions from %ah et al.  */
2894  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2895    FAIL;
2896
2897  unsigned int regno = reg_or_subregno (operands[1]);
2898
2899  /* Be careful to expand only with registers having upper parts.  */
2900  if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2901    operands[1] = copy_to_reg (operands[1]);
2902})
2903
2904(define_insn "*extv<mode>"
2905  [(set (match_operand:SWI24 0 "register_operand" "=R")
2906	(sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2907			    (const_int 8)
2908			    (const_int 8)))]
2909  ""
2910  "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2911  [(set_attr "type" "imovx")
2912   (set_attr "mode" "SI")])
2913
2914(define_expand "extzv<mode>"
2915  [(set (match_operand:SWI248 0 "register_operand")
2916	(zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2917			     (match_operand:SI 2 "const_int_operand")
2918			     (match_operand:SI 3 "const_int_operand")))]
2919  ""
2920{
2921  if (ix86_expand_pextr (operands))
2922    DONE;
2923
2924  /* Handle extractions from %ah et al.  */
2925  if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2926    FAIL;
2927
2928  unsigned int regno = reg_or_subregno (operands[1]);
2929
2930  /* Be careful to expand only with registers having upper parts.  */
2931  if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2932    operands[1] = copy_to_reg (operands[1]);
2933})
2934
2935(define_insn "*extzvqi_mem_rex64"
2936  [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2937	(subreg:QI
2938	  (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2939			   (const_int 8)
2940			   (const_int 8)) 0))]
2941  "TARGET_64BIT && reload_completed"
2942  "mov{b}\t{%h1, %0|%0, %h1}"
2943  [(set_attr "type" "imov")
2944   (set_attr "mode" "QI")])
2945
2946(define_insn "*extzv<mode>"
2947  [(set (match_operand:SWI248 0 "register_operand" "=R")
2948	(zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2949			     (const_int 8)
2950			     (const_int 8)))]
2951  ""
2952  "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2953  [(set_attr "type" "imovx")
2954   (set_attr "mode" "SI")])
2955
2956(define_insn "*extzvqi"
2957  [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2958	(subreg:QI
2959	  (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2960			   (const_int 8)
2961			   (const_int 8)) 0))]
2962  ""
2963{
2964  switch (get_attr_type (insn))
2965    {
2966    case TYPE_IMOVX:
2967      return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2968    default:
2969      return "mov{b}\t{%h1, %0|%0, %h1}";
2970    }
2971}
2972  [(set_attr "isa" "*,*,nox64")
2973   (set (attr "type")
2974     (if_then_else (and (match_operand:QI 0 "register_operand")
2975			(ior (not (match_operand:QI 0 "QIreg_operand"))
2976			     (match_test "TARGET_MOVX")))
2977	(const_string "imovx")
2978	(const_string "imov")))
2979   (set (attr "mode")
2980     (if_then_else (eq_attr "type" "imovx")
2981	(const_string "SI")
2982	(const_string "QI")))])
2983
2984(define_peephole2
2985  [(set (match_operand:QI 0 "register_operand")
2986	(subreg:QI
2987	  (zero_extract:SI (match_operand 1 "ext_register_operand")
2988			   (const_int 8)
2989			   (const_int 8)) 0))
2990   (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2991  "TARGET_64BIT
2992   && peep2_reg_dead_p (2, operands[0])"
2993  [(set (match_dup 2)
2994	(subreg:QI
2995	  (zero_extract:SI (match_dup 1)
2996			   (const_int 8)
2997			   (const_int 8)) 0))])
2998
2999(define_expand "insv<mode>"
3000  [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3001			     (match_operand:SI 1 "const_int_operand")
3002			     (match_operand:SI 2 "const_int_operand"))
3003        (match_operand:SWI248 3 "register_operand"))]
3004  ""
3005{
3006  rtx dst;
3007
3008  if (ix86_expand_pinsr (operands))
3009    DONE;
3010
3011  /* Handle insertions to %ah et al.  */
3012  if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3013    FAIL;
3014
3015  unsigned int regno = reg_or_subregno (operands[0]);
3016
3017  /* Be careful to expand only with registers having upper parts.  */
3018  if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3019    dst = copy_to_reg (operands[0]);
3020  else
3021    dst = operands[0];
3022
3023  emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3024
3025  /* Fix up the destination if needed.  */
3026  if (dst != operands[0])
3027    emit_move_insn (operands[0], dst);
3028
3029  DONE;
3030})
3031
3032(define_insn "*insvqi_1_mem_rex64"
3033  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3034			 (const_int 8)
3035			 (const_int 8))
3036	(subreg:SI
3037	  (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3038  "TARGET_64BIT && reload_completed"
3039  "mov{b}\t{%1, %h0|%h0, %1}"
3040  [(set_attr "type" "imov")
3041   (set_attr "mode" "QI")])
3042
3043(define_insn "insv<mode>_1"
3044  [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3045			     (const_int 8)
3046			     (const_int 8))
3047	(match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3048  ""
3049{
3050  if (CONST_INT_P (operands[1]))
3051    operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3052  return "mov{b}\t{%b1, %h0|%h0, %b1}";
3053}
3054  [(set_attr "isa" "*,nox64")
3055   (set_attr "type" "imov")
3056   (set_attr "mode" "QI")])
3057
3058(define_insn "*insvqi_1"
3059  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3060			 (const_int 8)
3061			 (const_int 8))
3062	(subreg:SI
3063	  (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3064  ""
3065  "mov{b}\t{%1, %h0|%h0, %1}"
3066  [(set_attr "isa" "*,nox64")
3067   (set_attr "type" "imov")
3068   (set_attr "mode" "QI")])
3069
3070(define_peephole2
3071  [(set (match_operand:QI 0 "register_operand")
3072	(match_operand:QI 1 "norex_memory_operand"))
3073   (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3074			 (const_int 8)
3075			 (const_int 8))
3076	(subreg:SI (match_dup 0) 0))]
3077  "TARGET_64BIT
3078   && peep2_reg_dead_p (2, operands[0])"
3079  [(set (zero_extract:SI (match_dup 2)
3080			 (const_int 8)
3081			 (const_int 8))
3082	   (subreg:SI (match_dup 1) 0))])
3083
3084(define_code_iterator any_extract [sign_extract zero_extract])
3085
3086(define_insn "*insvqi_2"
3087  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3088			 (const_int 8)
3089			 (const_int 8))
3090	(any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3091			(const_int 8)
3092			(const_int 8)))]
3093  ""
3094  "mov{b}\t{%h1, %h0|%h0, %h1}"
3095  [(set_attr "type" "imov")
3096   (set_attr "mode" "QI")])
3097
3098(define_insn "*insvqi_3"
3099  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3100			 (const_int 8)
3101			 (const_int 8))
3102	(any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3103			(const_int 8)))]
3104  ""
3105  "mov{b}\t{%h1, %h0|%h0, %h1}"
3106  [(set_attr "type" "imov")
3107   (set_attr "mode" "QI")])
3108
3109;; Floating point push instructions.
3110
3111(define_insn "*pushtf"
3112  [(set (match_operand:TF 0 "push_operand" "=<,<")
3113	(match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3114  "TARGET_64BIT || TARGET_SSE"
3115{
3116  /* This insn should be already split before reg-stack.  */
3117  gcc_unreachable ();
3118}
3119  [(set_attr "isa" "*,x64")
3120   (set_attr "type" "multi")
3121   (set_attr "unit" "sse,*")
3122   (set_attr "mode" "TF,DI")])
3123
3124;; %%% Kill this when call knows how to work this out.
3125(define_split
3126  [(set (match_operand:TF 0 "push_operand")
3127	(match_operand:TF 1 "sse_reg_operand"))]
3128  "TARGET_SSE && reload_completed"
3129  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3130   (set (match_dup 0) (match_dup 1))]
3131{
3132  /* Preserve memory attributes. */
3133  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3134})
3135
3136(define_insn_and_split "*pushxf_rounded"
3137  [(set (mem:XF
3138	  (pre_modify:P
3139	    (reg:P SP_REG)
3140	    (plus:P (reg:P SP_REG) (const_int -16))))
3141	(match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3142  "TARGET_64BIT"
3143  "#"
3144  "&& 1"
3145  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3146   (set (match_dup 1) (match_dup 0))]
3147{
3148  rtx pat = PATTERN (curr_insn);
3149  operands[1] = SET_DEST (pat);
3150
3151  /* Preserve memory attributes. */
3152  operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3153}
3154  [(set_attr "type" "multi")
3155   (set_attr "unit" "i387,*,*,*")
3156   (set (attr "mode")
3157	(cond [(eq_attr "alternative" "1,2,3")
3158		 (const_string "DI")
3159	      ]
3160	      (const_string "XF")))
3161   (set (attr "preferred_for_size")
3162     (cond [(eq_attr "alternative" "1")
3163              (symbol_ref "false")]
3164           (symbol_ref "true")))])
3165
3166(define_insn "*pushxf"
3167  [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3168	(match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3169  ""
3170{
3171  /* This insn should be already split before reg-stack.  */
3172  gcc_unreachable ();
3173}
3174  [(set_attr "isa" "*,*,*,nox64,x64")
3175   (set_attr "type" "multi")
3176   (set_attr "unit" "i387,*,*,*,*")
3177   (set (attr "mode")
3178	(cond [(eq_attr "alternative" "1,2,3,4")
3179		 (if_then_else (match_test "TARGET_64BIT")
3180		   (const_string "DI")
3181		   (const_string "SI"))
3182	      ]
3183	      (const_string "XF")))
3184   (set (attr "preferred_for_size")
3185     (cond [(eq_attr "alternative" "1")
3186              (symbol_ref "false")]
3187           (symbol_ref "true")))])
3188
3189;; %%% Kill this when call knows how to work this out.
3190(define_split
3191  [(set (match_operand:XF 0 "push_operand")
3192	(match_operand:XF 1 "fp_register_operand"))]
3193  "reload_completed"
3194  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3195   (set (match_dup 0) (match_dup 1))]
3196{
3197  operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3198  /* Preserve memory attributes. */
3199  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3200})
3201
3202(define_insn "*pushdf"
3203  [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3204	(match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3205  ""
3206{
3207  /* This insn should be already split before reg-stack.  */
3208  gcc_unreachable ();
3209}
3210  [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3211   (set_attr "type" "multi")
3212   (set_attr "unit" "i387,*,*,*,*,sse")
3213   (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3214   (set (attr "preferred_for_size")
3215     (cond [(eq_attr "alternative" "1")
3216              (symbol_ref "false")]
3217           (symbol_ref "true")))
3218   (set (attr "preferred_for_speed")
3219     (cond [(eq_attr "alternative" "1")
3220              (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3221           (symbol_ref "true")))])
3222
3223;; %%% Kill this when call knows how to work this out.
3224(define_split
3225  [(set (match_operand:DF 0 "push_operand")
3226	(match_operand:DF 1 "any_fp_register_operand"))]
3227  "reload_completed"
3228  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3229   (set (match_dup 0) (match_dup 1))]
3230{
3231  /* Preserve memory attributes. */
3232  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3233})
3234
3235(define_insn "*pushsf_rex64"
3236  [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3237	(match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3238  "TARGET_64BIT"
3239{
3240  /* Anything else should be already split before reg-stack.  */
3241  gcc_assert (which_alternative == 1);
3242  return "push{q}\t%q1";
3243}
3244  [(set_attr "type" "multi,push,multi")
3245   (set_attr "unit" "i387,*,*")
3246   (set_attr "mode" "SF,DI,SF")])
3247
3248(define_insn "*pushsf"
3249  [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3250	(match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3251  "!TARGET_64BIT"
3252{
3253  /* Anything else should be already split before reg-stack.  */
3254  gcc_assert (which_alternative == 1);
3255  return "push{l}\t%1";
3256}
3257  [(set_attr "type" "multi,push,multi")
3258   (set_attr "unit" "i387,*,*")
3259   (set_attr "mode" "SF,SI,SF")])
3260
3261;; %%% Kill this when call knows how to work this out.
3262(define_split
3263  [(set (match_operand:SF 0 "push_operand")
3264	(match_operand:SF 1 "any_fp_register_operand"))]
3265  "reload_completed"
3266  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3267   (set (match_dup 0) (match_dup 1))]
3268{
3269  rtx op = XEXP (operands[0], 0);
3270  if (GET_CODE (op) == PRE_DEC)
3271    {
3272      gcc_assert (!TARGET_64BIT);
3273      op = GEN_INT (-4);
3274    }
3275  else
3276    {
3277      op = XEXP (XEXP (op, 1), 1);
3278      gcc_assert (CONST_INT_P (op));
3279    }
3280  operands[2] = op;
3281  /* Preserve memory attributes. */
3282  operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3283})
3284
3285(define_split
3286  [(set (match_operand:SF 0 "push_operand")
3287	(match_operand:SF 1 "memory_operand"))]
3288  "reload_completed
3289   && find_constant_src (insn)"
3290  [(set (match_dup 0) (match_dup 2))]
3291  "operands[2] = find_constant_src (curr_insn);")
3292
3293(define_split
3294  [(set (match_operand 0 "push_operand")
3295	(match_operand 1 "general_gr_operand"))]
3296  "reload_completed
3297   && (GET_MODE (operands[0]) == TFmode
3298       || GET_MODE (operands[0]) == XFmode
3299       || GET_MODE (operands[0]) == DFmode)"
3300  [(const_int 0)]
3301  "ix86_split_long_move (operands); DONE;")
3302
3303;; Floating point move instructions.
3304
3305(define_expand "movtf"
3306  [(set (match_operand:TF 0 "nonimmediate_operand")
3307	(match_operand:TF 1 "nonimmediate_operand"))]
3308  "TARGET_64BIT || TARGET_SSE"
3309  "ix86_expand_move (TFmode, operands); DONE;")
3310
3311(define_expand "mov<mode>"
3312  [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3313	(match_operand:X87MODEF 1 "general_operand"))]
3314  ""
3315  "ix86_expand_move (<MODE>mode, operands); DONE;")
3316
3317(define_insn "*movtf_internal"
3318  [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3319	(match_operand:TF 1 "general_operand"	   "C ,vm,v,*roF,*rC"))]
3320  "(TARGET_64BIT || TARGET_SSE)
3321   && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3322   && (lra_in_progress || reload_completed
3323       || !CONST_DOUBLE_P (operands[1])
3324       || ((optimize_function_for_size_p (cfun)
3325	    || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3326	   && standard_sse_constant_p (operands[1], TFmode) == 1
3327	   && !memory_operand (operands[0], TFmode))
3328       || (!TARGET_MEMORY_MISMATCH_STALL
3329	   && memory_operand (operands[0], TFmode)))"
3330{
3331  switch (get_attr_type (insn))
3332    {
3333    case TYPE_SSELOG1:
3334      return standard_sse_constant_opcode (insn, operands);
3335
3336    case TYPE_SSEMOV:
3337      /* Handle misaligned load/store since we
3338         don't have movmisaligntf pattern. */
3339      if (misaligned_operand (operands[0], TFmode)
3340	  || misaligned_operand (operands[1], TFmode))
3341	{
3342	  if (get_attr_mode (insn) == MODE_V4SF)
3343	    return "%vmovups\t{%1, %0|%0, %1}";
3344	  else if (TARGET_AVX512VL
3345		   && (EXT_REX_SSE_REG_P (operands[0])
3346		       || EXT_REX_SSE_REG_P (operands[1])))
3347	    return "vmovdqu64\t{%1, %0|%0, %1}";
3348	  else
3349	    return "%vmovdqu\t{%1, %0|%0, %1}";
3350	}
3351      else
3352	{
3353	  if (get_attr_mode (insn) == MODE_V4SF)
3354	    return "%vmovaps\t{%1, %0|%0, %1}";
3355	  else if (TARGET_AVX512VL
3356		   && (EXT_REX_SSE_REG_P (operands[0])
3357		       || EXT_REX_SSE_REG_P (operands[1])))
3358	    return "vmovdqa64\t{%1, %0|%0, %1}";
3359	  else
3360	    return "%vmovdqa\t{%1, %0|%0, %1}";
3361	}
3362
3363    case TYPE_MULTI:
3364	return "#";
3365
3366    default:
3367      gcc_unreachable ();
3368    }
3369}
3370  [(set_attr "isa" "*,*,*,x64,x64")
3371   (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3372   (set (attr "prefix")
3373     (if_then_else (eq_attr "type" "sselog1,ssemov")
3374       (const_string "maybe_vex")
3375       (const_string "orig")))
3376   (set (attr "mode")
3377        (cond [(eq_attr "alternative" "3,4")
3378		 (const_string "DI")
3379	       (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3380		 (const_string "V4SF")
3381	       (and (eq_attr "alternative" "2")
3382		    (match_test "TARGET_SSE_TYPELESS_STORES"))
3383		 (const_string "V4SF")
3384	       (match_test "TARGET_AVX")
3385		 (const_string "TI")
3386	       (ior (not (match_test "TARGET_SSE2"))
3387		    (match_test "optimize_function_for_size_p (cfun)"))
3388		 (const_string "V4SF")
3389	       ]
3390	       (const_string "TI")))])
3391
3392(define_split
3393  [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3394        (match_operand:TF 1 "general_gr_operand"))]
3395  "reload_completed"
3396  [(const_int 0)]
3397  "ix86_split_long_move (operands); DONE;")
3398
3399;; Possible store forwarding (partial memory) stall
3400;; in alternatives 4, 6, 7 and 8.
3401(define_insn "*movxf_internal"
3402  [(set (match_operand:XF 0 "nonimmediate_operand"
3403	 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3404	(match_operand:XF 1 "general_operand"
3405	 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3406  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3407   && (lra_in_progress || reload_completed
3408       || !CONST_DOUBLE_P (operands[1])
3409       || ((optimize_function_for_size_p (cfun)
3410	    || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3411	   && standard_80387_constant_p (operands[1]) > 0
3412	   && !memory_operand (operands[0], XFmode))
3413       || (!TARGET_MEMORY_MISMATCH_STALL
3414	   && memory_operand (operands[0], XFmode))
3415       || !TARGET_HARD_XF_REGS)"
3416{
3417  switch (get_attr_type (insn))
3418    {
3419    case TYPE_FMOV:
3420      if (which_alternative == 2)
3421        return standard_80387_constant_opcode (operands[1]);
3422      return output_387_reg_move (insn, operands);
3423
3424    case TYPE_MULTI:
3425      return "#";
3426
3427    default:
3428      gcc_unreachable ();
3429    }
3430}
3431  [(set (attr "isa")
3432	(cond [(eq_attr "alternative" "7,10")
3433		 (const_string "nox64")
3434	       (eq_attr "alternative" "8,11")
3435		 (const_string "x64")
3436	      ]
3437	      (const_string "*")))
3438   (set (attr "type")
3439	(cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3440		 (const_string "multi")
3441	      ]
3442	      (const_string "fmov")))
3443   (set (attr "mode")
3444	(cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3445		 (if_then_else (match_test "TARGET_64BIT")
3446		   (const_string "DI")
3447		   (const_string "SI"))
3448	      ]
3449	      (const_string "XF")))
3450   (set (attr "preferred_for_size")
3451     (cond [(eq_attr "alternative" "3,4")
3452              (symbol_ref "false")]
3453           (symbol_ref "true")))
3454   (set (attr "enabled")
3455     (cond [(eq_attr "alternative" "9,10,11")
3456              (if_then_else
3457		(match_test "TARGET_HARD_XF_REGS")
3458		(symbol_ref "false")
3459		(const_string "*"))
3460            (not (match_test "TARGET_HARD_XF_REGS"))
3461	      (symbol_ref "false")
3462	   ]
3463	   (const_string "*")))])
3464
3465(define_split
3466  [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3467        (match_operand:XF 1 "general_gr_operand"))]
3468  "reload_completed"
3469  [(const_int 0)]
3470  "ix86_split_long_move (operands); DONE;")
3471
3472;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3473(define_insn "*movdf_internal"
3474  [(set (match_operand:DF 0 "nonimmediate_operand"
3475    "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r  ,o ,r  ,m")
3476	(match_operand:DF 1 "general_operand"
3477    "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
3478  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3479   && (lra_in_progress || reload_completed
3480       || !CONST_DOUBLE_P (operands[1])
3481       || ((optimize_function_for_size_p (cfun)
3482	    || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3483	   && ((IS_STACK_MODE (DFmode)
3484		&& standard_80387_constant_p (operands[1]) > 0)
3485	       || (TARGET_SSE2 && TARGET_SSE_MATH
3486		   && standard_sse_constant_p (operands[1], DFmode) == 1))
3487	   && !memory_operand (operands[0], DFmode))
3488       || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3489	   && memory_operand (operands[0], DFmode))
3490       || !TARGET_HARD_DF_REGS)"
3491{
3492  switch (get_attr_type (insn))
3493    {
3494    case TYPE_FMOV:
3495      if (which_alternative == 2)
3496        return standard_80387_constant_opcode (operands[1]);
3497      return output_387_reg_move (insn, operands);
3498
3499    case TYPE_MULTI:
3500      return "#";
3501
3502    case TYPE_IMOV:
3503      if (get_attr_mode (insn) == MODE_SI)
3504	return "mov{l}\t{%1, %k0|%k0, %1}";
3505      else if (which_alternative == 11)
3506	return "movabs{q}\t{%1, %0|%0, %1}";
3507      else
3508	return "mov{q}\t{%1, %0|%0, %1}";
3509
3510    case TYPE_SSELOG1:
3511      return standard_sse_constant_opcode (insn, operands);
3512
3513    case TYPE_SSEMOV:
3514      switch (get_attr_mode (insn))
3515	{
3516	case MODE_DF:
3517	  if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3518	    return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3519	  return "%vmovsd\t{%1, %0|%0, %1}";
3520
3521	case MODE_V4SF:
3522	  return "%vmovaps\t{%1, %0|%0, %1}";
3523	case MODE_V8DF:
3524	  return "vmovapd\t{%g1, %g0|%g0, %g1}";
3525	case MODE_V2DF:
3526	  return "%vmovapd\t{%1, %0|%0, %1}";
3527
3528	case MODE_V2SF:
3529	  gcc_assert (!TARGET_AVX);
3530	  return "movlps\t{%1, %0|%0, %1}";
3531	case MODE_V1DF:
3532	  gcc_assert (!TARGET_AVX);
3533	  return "movlpd\t{%1, %0|%0, %1}";
3534
3535	case MODE_DI:
3536	  /* Handle broken assemblers that require movd instead of movq.  */
3537	  if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3538	      && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3539	    return "%vmovd\t{%1, %0|%0, %1}";
3540	  return "%vmovq\t{%1, %0|%0, %1}";
3541
3542	default:
3543	  gcc_unreachable ();
3544	}
3545
3546    default:
3547      gcc_unreachable ();
3548    }
3549}
3550  [(set (attr "isa")
3551	(cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3552		 (const_string "nox64")
3553	       (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3554		 (const_string "x64")
3555	       (eq_attr "alternative" "12,13,14,15")
3556		 (const_string "sse2")
3557	      ]
3558	      (const_string "*")))
3559   (set (attr "type")
3560	(cond [(eq_attr "alternative" "0,1,2")
3561		 (const_string "fmov")
3562	       (eq_attr "alternative" "3,4,5,6,7,22,23")
3563		 (const_string "multi")
3564	       (eq_attr "alternative" "8,9,10,11,24,25")
3565		 (const_string "imov")
3566	       (eq_attr "alternative" "12,16")
3567		 (const_string "sselog1")
3568	      ]
3569	      (const_string "ssemov")))
3570   (set (attr "modrm")
3571     (if_then_else (eq_attr "alternative" "11")
3572       (const_string "0")
3573       (const_string "*")))
3574   (set (attr "length_immediate")
3575     (if_then_else (eq_attr "alternative" "11")
3576       (const_string "8")
3577       (const_string "*")))
3578   (set (attr "prefix")
3579     (if_then_else (eq_attr "type" "sselog1,ssemov")
3580       (const_string "maybe_vex")
3581       (const_string "orig")))
3582   (set (attr "prefix_data16")
3583     (if_then_else
3584       (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3585	    (eq_attr "mode" "V1DF"))
3586       (const_string "1")
3587       (const_string "*")))
3588   (set (attr "mode")
3589	(cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3590		 (const_string "SI")
3591	       (eq_attr "alternative" "8,9,11,20,21,24,25")
3592		 (const_string "DI")
3593
3594	       /* xorps is one byte shorter for non-AVX targets.  */
3595	       (eq_attr "alternative" "12,16")
3596		 (cond [(not (match_test "TARGET_SSE2"))
3597		 	  (const_string "V4SF")
3598			(and (match_test "TARGET_AVX512F")
3599			  (not (match_test "TARGET_PREFER_AVX256")))
3600			  (const_string "XI")
3601			(match_test "TARGET_AVX")
3602			  (const_string "V2DF")
3603			(match_test "optimize_function_for_size_p (cfun)")
3604			  (const_string "V4SF")
3605			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3606			  (const_string "TI")
3607		       ]
3608		       (const_string "V2DF"))
3609
3610	       /* For architectures resolving dependencies on
3611		  whole SSE registers use movapd to break dependency
3612		  chains, otherwise use short move to avoid extra work.  */
3613
3614	       /* movaps is one byte shorter for non-AVX targets.  */
3615	       (eq_attr "alternative" "13,17")
3616		 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3617				  (not (match_test "TARGET_AVX512VL")))
3618			     (ior (match_operand 0 "ext_sse_reg_operand")
3619				  (match_operand 1 "ext_sse_reg_operand")))
3620			  (const_string "V8DF")
3621			(ior (not (match_test "TARGET_SSE2"))
3622			     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3623			  (const_string "V4SF")
3624			(match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3625			  (const_string "V2DF")
3626			(match_test "TARGET_AVX")
3627			  (const_string "DF")
3628			(match_test "optimize_function_for_size_p (cfun)")
3629			  (const_string "V4SF")
3630		       ]
3631		       (const_string "DF"))
3632
3633	       /* For architectures resolving dependencies on register
3634		  parts we may avoid extra work to zero out upper part
3635		  of register.  */
3636	       (eq_attr "alternative" "14,18")
3637		 (cond [(not (match_test "TARGET_SSE2"))
3638			  (const_string "V2SF")
3639			(match_test "TARGET_AVX")
3640			  (const_string "DF")
3641			(match_test "TARGET_SSE_SPLIT_REGS")
3642			  (const_string "V1DF")
3643		       ]
3644		       (const_string "DF"))
3645
3646	       (and (eq_attr "alternative" "15,19")
3647		    (not (match_test "TARGET_SSE2")))
3648		 (const_string "V2SF")
3649	      ]
3650	      (const_string "DF")))
3651   (set (attr "preferred_for_size")
3652     (cond [(eq_attr "alternative" "3,4")
3653              (symbol_ref "false")]
3654           (symbol_ref "true")))
3655   (set (attr "preferred_for_speed")
3656     (cond [(eq_attr "alternative" "3,4")
3657              (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3658           (symbol_ref "true")))
3659   (set (attr "enabled")
3660     (cond [(eq_attr "alternative" "22,23,24,25")
3661              (if_then_else
3662		(match_test "TARGET_HARD_DF_REGS")
3663		(symbol_ref "false")
3664		(const_string "*"))
3665            (not (match_test "TARGET_HARD_DF_REGS"))
3666	      (symbol_ref "false")
3667	   ]
3668	   (const_string "*")))])
3669
3670(define_split
3671  [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3672        (match_operand:DF 1 "general_gr_operand"))]
3673  "!TARGET_64BIT && reload_completed"
3674  [(const_int 0)]
3675  "ix86_split_long_move (operands); DONE;")
3676
3677(define_insn "*movsf_internal"
3678  [(set (match_operand:SF 0 "nonimmediate_operand"
3679	  "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
3680	(match_operand:SF 1 "general_operand"
3681	  "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
3682  "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3683   && (lra_in_progress || reload_completed
3684       || !CONST_DOUBLE_P (operands[1])
3685       || ((optimize_function_for_size_p (cfun)
3686	    || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3687	   && ((IS_STACK_MODE (SFmode)
3688		&& standard_80387_constant_p (operands[1]) > 0)
3689	       || (TARGET_SSE && TARGET_SSE_MATH
3690		   && standard_sse_constant_p (operands[1], SFmode) == 1)))
3691       || memory_operand (operands[0], SFmode)
3692       || !TARGET_HARD_SF_REGS)"
3693{
3694  switch (get_attr_type (insn))
3695    {
3696    case TYPE_FMOV:
3697      if (which_alternative == 2)
3698        return standard_80387_constant_opcode (operands[1]);
3699      return output_387_reg_move (insn, operands);
3700
3701    case TYPE_IMOV:
3702      return "mov{l}\t{%1, %0|%0, %1}";
3703
3704    case TYPE_SSELOG1:
3705      return standard_sse_constant_opcode (insn, operands);
3706
3707    case TYPE_SSEMOV:
3708      switch (get_attr_mode (insn))
3709	{
3710	case MODE_SF:
3711	  if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3712	    return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3713	  return "%vmovss\t{%1, %0|%0, %1}";
3714
3715	case MODE_V16SF:
3716	  return "vmovaps\t{%g1, %g0|%g0, %g1}";
3717	case MODE_V4SF:
3718	  return "%vmovaps\t{%1, %0|%0, %1}";
3719
3720	case MODE_SI:
3721	  return "%vmovd\t{%1, %0|%0, %1}";
3722
3723	default:
3724	  gcc_unreachable ();
3725	}
3726
3727    case TYPE_MMXMOV:
3728      switch (get_attr_mode (insn))
3729	{
3730	case MODE_DI:
3731	  return "movq\t{%1, %0|%0, %1}";
3732	case MODE_SI:
3733	  return "movd\t{%1, %0|%0, %1}";
3734
3735	default:
3736	  gcc_unreachable ();
3737	}
3738
3739    default:
3740      gcc_unreachable ();
3741    }
3742}
3743  [(set (attr "type")
3744	(cond [(eq_attr "alternative" "0,1,2")
3745		 (const_string "fmov")
3746	       (eq_attr "alternative" "3,4,16,17")
3747		 (const_string "imov")
3748	       (eq_attr "alternative" "5")
3749		 (const_string "sselog1")
3750	       (eq_attr "alternative" "11,12,13,14,15")
3751		 (const_string "mmxmov")
3752	      ]
3753	      (const_string "ssemov")))
3754   (set (attr "prefix")
3755     (if_then_else (eq_attr "type" "sselog1,ssemov")
3756       (const_string "maybe_vex")
3757       (const_string "orig")))
3758   (set (attr "prefix_data16")
3759     (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3760       (const_string "1")
3761       (const_string "*")))
3762   (set (attr "mode")
3763        (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3764		 (const_string "SI")
3765	       (eq_attr "alternative" "11")
3766		 (const_string "DI")
3767	       (eq_attr "alternative" "5")
3768		 (cond [(not (match_test "TARGET_SSE2"))
3769 		 	  (const_string "V4SF")
3770			(and (match_test "TARGET_AVX512F")
3771			  (not (match_test "TARGET_PREFER_AVX256")))
3772			  (const_string "V16SF")
3773			(match_test "TARGET_AVX")
3774			  (const_string "V4SF")
3775 			(match_test "optimize_function_for_size_p (cfun)")
3776			  (const_string "V4SF")
3777 			(match_test "TARGET_SSE_LOAD0_BY_PXOR")
3778			  (const_string "TI")
3779		       ]
3780		       (const_string "V4SF"))
3781
3782	       /* For architectures resolving dependencies on
3783		  whole SSE registers use APS move to break dependency
3784		  chains, otherwise use short move to avoid extra work.
3785
3786		  Do the same for architectures resolving dependencies on
3787		  the parts.  While in DF mode it is better to always handle
3788		  just register parts, the SF mode is different due to lack
3789		  of instructions to load just part of the register.  It is
3790		  better to maintain the whole registers in single format
3791		  to avoid problems on using packed logical operations.  */
3792	       (eq_attr "alternative" "6")
3793		 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3794				  (not (match_test "TARGET_AVX512VL")))
3795			     (ior (match_operand 0 "ext_sse_reg_operand")
3796				  (match_operand 1 "ext_sse_reg_operand")))
3797			  (const_string "V16SF")
3798			(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3799			     (match_test "TARGET_SSE_SPLIT_REGS"))
3800			  (const_string "V4SF")
3801		       ]
3802		       (const_string "SF"))
3803	      ]
3804	      (const_string "SF")))
3805   (set (attr "enabled")
3806     (cond [(eq_attr "alternative" "16,17")
3807              (if_then_else
3808		(match_test "TARGET_HARD_SF_REGS")
3809		(symbol_ref "false")
3810		(const_string "*"))
3811            (not (match_test "TARGET_HARD_SF_REGS"))
3812	      (symbol_ref "false")
3813	   ]
3814	   (const_string "*")))])
3815
3816(define_split
3817  [(set (match_operand 0 "any_fp_register_operand")
3818	(match_operand 1 "nonimmediate_operand"))]
3819  "reload_completed
3820   && (GET_MODE (operands[0]) == TFmode
3821       || GET_MODE (operands[0]) == XFmode
3822       || GET_MODE (operands[0]) == DFmode
3823       || GET_MODE (operands[0]) == SFmode)
3824   && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3825  [(set (match_dup 0) (match_dup 2))]
3826  "operands[2] = find_constant_src (curr_insn);")
3827
3828(define_split
3829  [(set (match_operand 0 "any_fp_register_operand")
3830	(float_extend (match_operand 1 "nonimmediate_operand")))]
3831  "reload_completed
3832   && (GET_MODE (operands[0]) == TFmode
3833       || GET_MODE (operands[0]) == XFmode
3834       || GET_MODE (operands[0]) == DFmode)
3835   && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3836  [(set (match_dup 0) (match_dup 2))]
3837  "operands[2] = find_constant_src (curr_insn);")
3838
3839;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3840(define_split
3841  [(set (match_operand:X87MODEF 0 "fp_register_operand")
3842	(match_operand:X87MODEF 1 "immediate_operand"))]
3843  "reload_completed
3844   && (standard_80387_constant_p (operands[1]) == 8
3845       || standard_80387_constant_p (operands[1]) == 9)"
3846  [(set (match_dup 0)(match_dup 1))
3847   (set (match_dup 0)
3848	(neg:X87MODEF (match_dup 0)))]
3849{
3850  if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3851    operands[1] = CONST0_RTX (<MODE>mode);
3852  else
3853    operands[1] = CONST1_RTX (<MODE>mode);
3854})
3855
3856(define_insn "swapxf"
3857  [(set (match_operand:XF 0 "register_operand" "+f")
3858	(match_operand:XF 1 "register_operand" "+f"))
3859   (set (match_dup 1)
3860	(match_dup 0))]
3861  "TARGET_80387"
3862{
3863  if (STACK_TOP_P (operands[0]))
3864    return "fxch\t%1";
3865  else
3866    return "fxch\t%0";
3867}
3868  [(set_attr "type" "fxch")
3869   (set_attr "mode" "XF")])
3870
3871(define_insn "*swap<mode>"
3872  [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3873	(match_operand:MODEF 1 "fp_register_operand" "+f"))
3874   (set (match_dup 1)
3875	(match_dup 0))]
3876  "TARGET_80387 || reload_completed"
3877{
3878  if (STACK_TOP_P (operands[0]))
3879    return "fxch\t%1";
3880  else
3881    return "fxch\t%0";
3882}
3883  [(set_attr "type" "fxch")
3884   (set_attr "mode" "<MODE>")])
3885
3886;; Zero extension instructions
3887
3888(define_expand "zero_extendsidi2"
3889  [(set (match_operand:DI 0 "nonimmediate_operand")
3890	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3891
3892(define_insn "*zero_extendsidi2"
3893  [(set (match_operand:DI 0 "nonimmediate_operand"
3894		"=r,?r,?o,r   ,o,?*Ym,?!*y,$r,$Yi,$x,*x,*v,*r")
3895	(zero_extend:DI
3896	 (match_operand:SI 1 "x86_64_zext_operand"
3897	        "0 ,rm,r ,rmWz,0,r   ,m   ,Yj,r  ,m ,*x,*v,*k")))]
3898  ""
3899{
3900  switch (get_attr_type (insn))
3901    {
3902    case TYPE_IMOVX:
3903      if (ix86_use_lea_for_mov (insn, operands))
3904	return "lea{l}\t{%E1, %k0|%k0, %E1}";
3905      else
3906	return "mov{l}\t{%1, %k0|%k0, %1}";
3907
3908    case TYPE_MULTI:
3909      return "#";
3910
3911    case TYPE_MMXMOV:
3912      return "movd\t{%1, %0|%0, %1}";
3913
3914    case TYPE_SSEMOV:
3915      if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3916	{
3917	  if (EXT_REX_SSE_REG_P (operands[0])
3918	      || EXT_REX_SSE_REG_P (operands[1]))
3919	    return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3920	  else
3921	    return "%vpmovzxdq\t{%1, %0|%0, %1}";
3922	}
3923
3924      if (GENERAL_REG_P (operands[0]))
3925	return "%vmovd\t{%1, %k0|%k0, %1}";
3926
3927      return "%vmovd\t{%1, %0|%0, %1}";
3928
3929    case TYPE_MSKMOV:
3930      return "kmovd\t{%1, %k0|%k0, %1}";
3931
3932    default:
3933      gcc_unreachable ();
3934    }
3935}
3936  [(set (attr "isa")
3937     (cond [(eq_attr "alternative" "0,1,2")
3938	      (const_string "nox64")
3939	    (eq_attr "alternative" "3")
3940	      (const_string "x64")
3941	    (eq_attr "alternative" "9")
3942	      (const_string "sse2")
3943	    (eq_attr "alternative" "10")
3944	      (const_string "sse4")
3945	    (eq_attr "alternative" "11")
3946	      (const_string "avx512f")
3947	    (eq_attr "alternative" "12")
3948	      (const_string "x64_avx512bw")
3949	   ]
3950	   (const_string "*")))
3951   (set (attr "type")
3952     (cond [(eq_attr "alternative" "0,1,2,4")
3953	      (const_string "multi")
3954	    (eq_attr "alternative" "5,6")
3955	      (const_string "mmxmov")
3956	    (eq_attr "alternative" "7")
3957	      (if_then_else (match_test "TARGET_64BIT")
3958		(const_string "ssemov")
3959		(const_string "multi"))
3960	    (eq_attr "alternative" "8,9,10,11")
3961	      (const_string "ssemov")
3962	    (eq_attr "alternative" "12")
3963	      (const_string "mskmov")
3964	   ]
3965	   (const_string "imovx")))
3966   (set (attr "prefix_extra")
3967     (if_then_else (eq_attr "alternative" "10,11")
3968       (const_string "1")
3969       (const_string "*")))
3970   (set (attr "prefix")
3971     (if_then_else (eq_attr "type" "ssemov")
3972       (const_string "maybe_vex")
3973       (const_string "orig")))
3974   (set (attr "prefix_0f")
3975     (if_then_else (eq_attr "type" "imovx")
3976       (const_string "0")
3977       (const_string "*")))
3978   (set (attr "mode")
3979     (cond [(eq_attr "alternative" "5,6")
3980	      (const_string "DI")
3981	    (and (eq_attr "alternative" "7")
3982		 (match_test "TARGET_64BIT"))
3983	      (const_string "TI")
3984	    (eq_attr "alternative" "8,10,11")
3985	      (const_string "TI")
3986	   ]
3987	   (const_string "SI")))])
3988
3989(define_split
3990  [(set (match_operand:DI 0 "memory_operand")
3991     	(zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3992  "reload_completed"
3993  [(set (match_dup 4) (const_int 0))]
3994  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3995
3996(define_split
3997  [(set (match_operand:DI 0 "general_reg_operand")
3998	(zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3999  "!TARGET_64BIT && reload_completed
4000   && REGNO (operands[0]) == REGNO (operands[1])"
4001  [(set (match_dup 4) (const_int 0))]
4002  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4003
4004(define_split
4005  [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4006	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4007  "!TARGET_64BIT && reload_completed
4008   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4009  [(set (match_dup 3) (match_dup 1))
4010   (set (match_dup 4) (const_int 0))]
4011  "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4012
4013(define_mode_attr kmov_isa
4014  [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4015
4016(define_insn "zero_extend<mode>di2"
4017  [(set (match_operand:DI 0 "register_operand" "=r,*r")
4018	(zero_extend:DI
4019	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4020  "TARGET_64BIT"
4021  "@
4022   movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4023   kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4024  [(set_attr "isa" "*,<kmov_isa>")
4025   (set_attr "type" "imovx,mskmov")
4026   (set_attr "mode" "SI,<MODE>")])
4027
4028(define_expand "zero_extend<mode>si2"
4029  [(set (match_operand:SI 0 "register_operand")
4030	(zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4031  ""
4032{
4033  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4034    {
4035      operands[1] = force_reg (<MODE>mode, operands[1]);
4036      emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4037      DONE;
4038    }
4039})
4040
4041(define_insn_and_split "zero_extend<mode>si2_and"
4042  [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4043	(zero_extend:SI
4044	  (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4045   (clobber (reg:CC FLAGS_REG))]
4046  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4047  "#"
4048  "&& reload_completed"
4049  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4050	      (clobber (reg:CC FLAGS_REG))])]
4051{
4052  if (!REG_P (operands[1])
4053      || REGNO (operands[0]) != REGNO (operands[1]))
4054    {
4055      ix86_expand_clear (operands[0]);
4056
4057      gcc_assert (!TARGET_PARTIAL_REG_STALL);
4058      emit_insn (gen_movstrict<mode>
4059		  (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4060      DONE;
4061    }
4062
4063  operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4064}
4065  [(set_attr "type" "alu1")
4066   (set_attr "mode" "SI")])
4067
4068(define_insn "*zero_extend<mode>si2"
4069  [(set (match_operand:SI 0 "register_operand" "=r,*r")
4070	(zero_extend:SI
4071	  (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4072  "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4073  "@
4074   movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4075   kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4076  [(set_attr "isa" "*,<kmov_isa>")
4077   (set_attr "type" "imovx,mskmov")
4078   (set_attr "mode" "SI,<MODE>")])
4079
4080(define_expand "zero_extendqihi2"
4081  [(set (match_operand:HI 0 "register_operand")
4082	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4083  ""
4084{
4085  if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4086    {
4087      operands[1] = force_reg (QImode, operands[1]);
4088      emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4089      DONE;
4090    }
4091})
4092
4093(define_insn_and_split "zero_extendqihi2_and"
4094  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4095	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4096   (clobber (reg:CC FLAGS_REG))]
4097  "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4098  "#"
4099  "&& reload_completed"
4100  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4101	      (clobber (reg:CC FLAGS_REG))])]
4102{
4103  if (!REG_P (operands[1])
4104      || REGNO (operands[0]) != REGNO (operands[1]))
4105    {
4106      ix86_expand_clear (operands[0]);
4107
4108      gcc_assert (!TARGET_PARTIAL_REG_STALL);
4109      emit_insn (gen_movstrictqi
4110		  (gen_lowpart (QImode, operands[0]), operands[1]));
4111      DONE;
4112    }
4113
4114  operands[0] = gen_lowpart (SImode, operands[0]);
4115}
4116  [(set_attr "type" "alu1")
4117   (set_attr "mode" "SI")])
4118
4119; zero extend to SImode to avoid partial register stalls
4120(define_insn "*zero_extendqihi2"
4121  [(set (match_operand:HI 0 "register_operand" "=r,*r")
4122	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4123  "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4124  "@
4125   movz{bl|x}\t{%1, %k0|%k0, %1}
4126   kmovb\t{%1, %k0|%k0, %1}"
4127  [(set_attr "isa" "*,avx512dq")
4128   (set_attr "type" "imovx,mskmov")
4129   (set_attr "mode" "SI,QI")])
4130
4131(define_insn_and_split "*zext<mode>_doubleword_and"
4132  [(set (match_operand:DI 0 "register_operand" "=&<r>")
4133	(zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4134  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4135   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4136  "#"
4137  "&& reload_completed && GENERAL_REG_P (operands[0])"
4138  [(set (match_dup 2) (const_int 0))]
4139{
4140  split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4141
4142  emit_move_insn (operands[0], const0_rtx);
4143
4144  gcc_assert (!TARGET_PARTIAL_REG_STALL);
4145  emit_insn (gen_movstrict<mode>
4146	     (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4147})
4148
4149(define_insn_and_split "*zext<mode>_doubleword"
4150  [(set (match_operand:DI 0 "register_operand" "=r")
4151	(zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4152  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4153   && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4154  "#"
4155  "&& reload_completed && GENERAL_REG_P (operands[0])"
4156  [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4157   (set (match_dup 2) (const_int 0))]
4158  "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4159
4160(define_insn_and_split "*zextsi_doubleword"
4161  [(set (match_operand:DI 0 "register_operand" "=r")
4162	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4163  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4164  "#"
4165  "&& reload_completed && GENERAL_REG_P (operands[0])"
4166  [(set (match_dup 0) (match_dup 1))
4167   (set (match_dup 2) (const_int 0))]
4168  "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4169
4170;; Sign extension instructions
4171
4172(define_expand "extendsidi2"
4173  [(set (match_operand:DI 0 "register_operand")
4174	(sign_extend:DI (match_operand:SI 1 "register_operand")))]
4175  ""
4176{
4177  if (!TARGET_64BIT)
4178    {
4179      emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4180      DONE;
4181    }
4182})
4183
4184(define_insn "*extendsidi2_rex64"
4185  [(set (match_operand:DI 0 "register_operand" "=*a,r")
4186	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4187  "TARGET_64BIT"
4188  "@
4189   {cltq|cdqe}
4190   movs{lq|x}\t{%1, %0|%0, %1}"
4191  [(set_attr "type" "imovx")
4192   (set_attr "mode" "DI")
4193   (set_attr "prefix_0f" "0")
4194   (set_attr "modrm" "0,1")])
4195
4196(define_insn "extendsidi2_1"
4197  [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4198	(sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4199   (clobber (reg:CC FLAGS_REG))
4200   (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4201  "!TARGET_64BIT"
4202  "#")
4203
4204;; Split the memory case.  If the source register doesn't die, it will stay
4205;; this way, if it does die, following peephole2s take care of it.
4206(define_split
4207  [(set (match_operand:DI 0 "memory_operand")
4208	(sign_extend:DI (match_operand:SI 1 "register_operand")))
4209   (clobber (reg:CC FLAGS_REG))
4210   (clobber (match_operand:SI 2 "register_operand"))]
4211  "reload_completed"
4212  [(const_int 0)]
4213{
4214  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4215
4216  emit_move_insn (operands[3], operands[1]);
4217
4218  /* Generate a cltd if possible and doing so it profitable.  */
4219  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4220      && REGNO (operands[1]) == AX_REG
4221      && REGNO (operands[2]) == DX_REG)
4222    {
4223      emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4224    }
4225  else
4226    {
4227      emit_move_insn (operands[2], operands[1]);
4228      emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4229    }
4230  emit_move_insn (operands[4], operands[2]);
4231  DONE;
4232})
4233
4234;; Peepholes for the case where the source register does die, after
4235;; being split with the above splitter.
4236(define_peephole2
4237  [(set (match_operand:SI 0 "memory_operand")
4238	(match_operand:SI 1 "general_reg_operand"))
4239   (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4240   (parallel [(set (match_dup 2)
4241		   (ashiftrt:SI (match_dup 2) (const_int 31)))
4242	       (clobber (reg:CC FLAGS_REG))])
4243   (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4244  "REGNO (operands[1]) != REGNO (operands[2])
4245   && peep2_reg_dead_p (2, operands[1])
4246   && peep2_reg_dead_p (4, operands[2])
4247   && !reg_mentioned_p (operands[2], operands[3])"
4248  [(set (match_dup 0) (match_dup 1))
4249   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4250	      (clobber (reg:CC FLAGS_REG))])
4251   (set (match_dup 3) (match_dup 1))])
4252
4253(define_peephole2
4254  [(set (match_operand:SI 0 "memory_operand")
4255	(match_operand:SI 1 "general_reg_operand"))
4256   (parallel [(set (match_operand:SI 2 "general_reg_operand")
4257		   (ashiftrt:SI (match_dup 1) (const_int 31)))
4258	       (clobber (reg:CC FLAGS_REG))])
4259   (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4260  "/* cltd is shorter than sarl $31, %eax */
4261   !optimize_function_for_size_p (cfun)
4262   && REGNO (operands[1]) == AX_REG
4263   && REGNO (operands[2]) == DX_REG
4264   && peep2_reg_dead_p (2, operands[1])
4265   && peep2_reg_dead_p (3, operands[2])
4266   && !reg_mentioned_p (operands[2], operands[3])"
4267  [(set (match_dup 0) (match_dup 1))
4268   (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4269	      (clobber (reg:CC FLAGS_REG))])
4270   (set (match_dup 3) (match_dup 1))])
4271
4272;; Extend to register case.  Optimize case where source and destination
4273;; registers match and cases where we can use cltd.
4274(define_split
4275  [(set (match_operand:DI 0 "register_operand")
4276	(sign_extend:DI (match_operand:SI 1 "register_operand")))
4277   (clobber (reg:CC FLAGS_REG))
4278   (clobber (match_scratch:SI 2))]
4279  "reload_completed"
4280  [(const_int 0)]
4281{
4282  split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4283
4284  if (REGNO (operands[3]) != REGNO (operands[1]))
4285    emit_move_insn (operands[3], operands[1]);
4286
4287  /* Generate a cltd if possible and doing so it profitable.  */
4288  if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4289      && REGNO (operands[3]) == AX_REG
4290      && REGNO (operands[4]) == DX_REG)
4291    {
4292      emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4293      DONE;
4294    }
4295
4296  if (REGNO (operands[4]) != REGNO (operands[1]))
4297    emit_move_insn (operands[4], operands[1]);
4298
4299  emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4300  DONE;
4301})
4302
4303(define_insn "extend<mode>di2"
4304  [(set (match_operand:DI 0 "register_operand" "=r")
4305	(sign_extend:DI
4306	 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4307  "TARGET_64BIT"
4308  "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4309  [(set_attr "type" "imovx")
4310   (set_attr "mode" "DI")])
4311
4312(define_insn "extendhisi2"
4313  [(set (match_operand:SI 0 "register_operand" "=*a,r")
4314	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4315  ""
4316{
4317  switch (get_attr_prefix_0f (insn))
4318    {
4319    case 0:
4320      return "{cwtl|cwde}";
4321    default:
4322      return "movs{wl|x}\t{%1, %0|%0, %1}";
4323    }
4324}
4325  [(set_attr "type" "imovx")
4326   (set_attr "mode" "SI")
4327   (set (attr "prefix_0f")
4328     ;; movsx is short decodable while cwtl is vector decoded.
4329     (if_then_else (and (eq_attr "cpu" "!k6")
4330			(eq_attr "alternative" "0"))
4331	(const_string "0")
4332	(const_string "1")))
4333   (set (attr "znver1_decode")
4334     (if_then_else (eq_attr "prefix_0f" "0")
4335	(const_string "double")
4336	(const_string "direct")))
4337   (set (attr "modrm")
4338     (if_then_else (eq_attr "prefix_0f" "0")
4339	(const_string "0")
4340	(const_string "1")))])
4341
4342(define_insn "*extendhisi2_zext"
4343  [(set (match_operand:DI 0 "register_operand" "=*a,r")
4344	(zero_extend:DI
4345	 (sign_extend:SI
4346	  (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4347  "TARGET_64BIT"
4348{
4349  switch (get_attr_prefix_0f (insn))
4350    {
4351    case 0:
4352      return "{cwtl|cwde}";
4353    default:
4354      return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4355    }
4356}
4357  [(set_attr "type" "imovx")
4358   (set_attr "mode" "SI")
4359   (set (attr "prefix_0f")
4360     ;; movsx is short decodable while cwtl is vector decoded.
4361     (if_then_else (and (eq_attr "cpu" "!k6")
4362			(eq_attr "alternative" "0"))
4363	(const_string "0")
4364	(const_string "1")))
4365   (set (attr "modrm")
4366     (if_then_else (eq_attr "prefix_0f" "0")
4367	(const_string "0")
4368	(const_string "1")))])
4369
4370(define_insn "extendqisi2"
4371  [(set (match_operand:SI 0 "register_operand" "=r")
4372	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4373  ""
4374  "movs{bl|x}\t{%1, %0|%0, %1}"
4375   [(set_attr "type" "imovx")
4376    (set_attr "mode" "SI")])
4377
4378(define_insn "*extendqisi2_zext"
4379  [(set (match_operand:DI 0 "register_operand" "=r")
4380	(zero_extend:DI
4381	  (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4382  "TARGET_64BIT"
4383  "movs{bl|x}\t{%1, %k0|%k0, %1}"
4384   [(set_attr "type" "imovx")
4385    (set_attr "mode" "SI")])
4386
4387(define_insn "extendqihi2"
4388  [(set (match_operand:HI 0 "register_operand" "=*a,r")
4389	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4390  ""
4391{
4392  switch (get_attr_prefix_0f (insn))
4393    {
4394    case 0:
4395      return "{cbtw|cbw}";
4396    default:
4397      return "movs{bw|x}\t{%1, %0|%0, %1}";
4398    }
4399}
4400  [(set_attr "type" "imovx")
4401   (set_attr "mode" "HI")
4402   (set (attr "prefix_0f")
4403     ;; movsx is short decodable while cwtl is vector decoded.
4404     (if_then_else (and (eq_attr "cpu" "!k6")
4405			(eq_attr "alternative" "0"))
4406	(const_string "0")
4407	(const_string "1")))
4408   (set (attr "modrm")
4409     (if_then_else (eq_attr "prefix_0f" "0")
4410	(const_string "0")
4411	(const_string "1")))])
4412
4413;; Conversions between float and double.
4414
4415;; These are all no-ops in the model used for the 80387.
4416;; So just emit moves.
4417
4418;; %%% Kill these when call knows how to work out a DFmode push earlier.
4419(define_split
4420  [(set (match_operand:DF 0 "push_operand")
4421	(float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4422  "reload_completed"
4423  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4424   (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4425
4426(define_split
4427  [(set (match_operand:XF 0 "push_operand")
4428	(float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4429  "reload_completed"
4430  [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4431   (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4432  "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4433
4434(define_expand "extendsfdf2"
4435  [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4436        (float_extend:DF (match_operand:SF 1 "general_operand")))]
4437  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4438{
4439  /* ??? Needed for compress_float_constant since all fp constants
4440     are TARGET_LEGITIMATE_CONSTANT_P.  */
4441  if (CONST_DOUBLE_P (operands[1]))
4442    {
4443      if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4444	  && standard_80387_constant_p (operands[1]) > 0)
4445	{
4446	  operands[1] = simplify_const_unary_operation
4447	    (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4448	  emit_move_insn_1 (operands[0], operands[1]);
4449	  DONE;
4450	}
4451      operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4452    }
4453})
4454
4455/* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4456   cvtss2sd:
4457      unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4458      cvtps2pd xmm2,xmm1
4459   We do the conversion post reload to avoid producing of 128bit spills
4460   that might lead to ICE on 32bit target.  The sequence unlikely combine
4461   anyway.  */
4462(define_split
4463  [(set (match_operand:DF 0 "sse_reg_operand")
4464        (float_extend:DF
4465	  (match_operand:SF 1 "nonimmediate_operand")))]
4466  "TARGET_USE_VECTOR_FP_CONVERTS
4467   && optimize_insn_for_speed_p ()
4468   && reload_completed
4469   && (!EXT_REX_SSE_REG_P (operands[0])
4470       || TARGET_AVX512VL)"
4471   [(set (match_dup 2)
4472	 (float_extend:V2DF
4473	   (vec_select:V2SF
4474	     (match_dup 3)
4475	     (parallel [(const_int 0) (const_int 1)]))))]
4476{
4477  operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4478  operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4479  /* Use movss for loading from memory, unpcklps reg, reg for registers.
4480     Try to avoid move when unpacking can be done in source.  */
4481  if (REG_P (operands[1]))
4482    {
4483      /* If it is unsafe to overwrite upper half of source, we need
4484	 to move to destination and unpack there.  */
4485      if (REGNO (operands[0]) != REGNO (operands[1])
4486	  || (EXT_REX_SSE_REG_P (operands[1])
4487	      && !TARGET_AVX512VL))
4488	{
4489	  rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4490	  emit_move_insn (tmp, operands[1]);
4491	}
4492      else
4493	operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4494      /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4495	 =v, v, then vbroadcastss will be only needed for AVX512F without
4496	 AVX512VL.  */
4497      if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4498	emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4499					       operands[3]));
4500      else
4501	{
4502	  rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4503	  emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4504	}
4505    }
4506  else
4507    emit_insn (gen_vec_setv4sf_0 (operands[3],
4508				  CONST0_RTX (V4SFmode), operands[1]));
4509})
4510
4511;; It's more profitable to split and then extend in the same register.
4512(define_peephole2
4513  [(set (match_operand:DF 0 "sse_reg_operand")
4514	(float_extend:DF
4515	  (match_operand:SF 1 "memory_operand")))]
4516  "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4517   && optimize_insn_for_speed_p ()"
4518  [(set (match_dup 2) (match_dup 1))
4519   (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4520  "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4521
4522(define_insn "*extendsfdf2"
4523  [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4524        (float_extend:DF
4525	  (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4526  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4527{
4528  switch (which_alternative)
4529    {
4530    case 0:
4531    case 1:
4532      return output_387_reg_move (insn, operands);
4533
4534    case 2:
4535      return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4536
4537    default:
4538      gcc_unreachable ();
4539    }
4540}
4541  [(set_attr "type" "fmov,fmov,ssecvt")
4542   (set_attr "prefix" "orig,orig,maybe_vex")
4543   (set_attr "mode" "SF,XF,DF")
4544   (set (attr "enabled")
4545     (if_then_else
4546       (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4547       (if_then_else
4548	 (eq_attr "alternative" "0,1")
4549	 (symbol_ref "TARGET_MIX_SSE_I387")
4550	 (symbol_ref "true"))
4551       (if_then_else
4552	 (eq_attr "alternative" "0,1")
4553	 (symbol_ref "true")
4554	 (symbol_ref "false"))))])
4555
4556(define_expand "extend<mode>xf2"
4557  [(set (match_operand:XF 0 "nonimmediate_operand")
4558        (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4559  "TARGET_80387"
4560{
4561  /* ??? Needed for compress_float_constant since all fp constants
4562     are TARGET_LEGITIMATE_CONSTANT_P.  */
4563  if (CONST_DOUBLE_P (operands[1]))
4564    {
4565      if (standard_80387_constant_p (operands[1]) > 0)
4566	{
4567	  operands[1] = simplify_const_unary_operation
4568	    (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4569	  emit_move_insn_1 (operands[0], operands[1]);
4570	  DONE;
4571	}
4572      operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4573    }
4574})
4575
4576(define_insn "*extend<mode>xf2_i387"
4577  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4578        (float_extend:XF
4579	  (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4580  "TARGET_80387"
4581  "* return output_387_reg_move (insn, operands);"
4582  [(set_attr "type" "fmov")
4583   (set_attr "mode" "<MODE>,XF")])
4584
4585;; %%% This seems like bad news.
4586;; This cannot output into an f-reg because there is no way to be sure
4587;; of truncating in that case.  Otherwise this is just like a simple move
4588;; insn.  So we pretend we can output to a reg in order to get better
4589;; register preferencing, but we really use a stack slot.
4590
4591;; Conversion from DFmode to SFmode.
4592
4593(define_expand "truncdfsf2"
4594  [(set (match_operand:SF 0 "nonimmediate_operand")
4595	(float_truncate:SF
4596	  (match_operand:DF 1 "nonimmediate_operand")))]
4597  "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4598{
4599  if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4600    ;
4601  else if (flag_unsafe_math_optimizations)
4602    ;
4603  else
4604    {
4605      rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4606      emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4607      DONE;
4608    }
4609})
4610
4611/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4612   cvtsd2ss:
4613      unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4614      cvtpd2ps xmm2,xmm1
4615   We do the conversion post reload to avoid producing of 128bit spills
4616   that might lead to ICE on 32bit target.  The sequence unlikely combine
4617   anyway.  */
4618(define_split
4619  [(set (match_operand:SF 0 "sse_reg_operand")
4620        (float_truncate:SF
4621	  (match_operand:DF 1 "nonimmediate_operand")))]
4622  "TARGET_USE_VECTOR_FP_CONVERTS
4623   && optimize_insn_for_speed_p ()
4624   && reload_completed
4625   && (!EXT_REX_SSE_REG_P (operands[0])
4626       || TARGET_AVX512VL)"
4627   [(set (match_dup 2)
4628	 (vec_concat:V4SF
4629	   (float_truncate:V2SF
4630	     (match_dup 4))
4631	   (match_dup 3)))]
4632{
4633  operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4634  operands[3] = CONST0_RTX (V2SFmode);
4635  operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4636  /* Use movsd for loading from memory, unpcklpd for registers.
4637     Try to avoid move when unpacking can be done in source, or SSE3
4638     movddup is available.  */
4639  if (REG_P (operands[1]))
4640    {
4641      if (!TARGET_SSE3
4642	  && REGNO (operands[0]) != REGNO (operands[1]))
4643	{
4644	  rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4645	  emit_move_insn (tmp, operands[1]);
4646	  operands[1] = tmp;
4647	}
4648      else if (!TARGET_SSE3)
4649	operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4650      emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4651    }
4652  else
4653    emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4654				   CONST0_RTX (DFmode)));
4655})
4656
4657;; It's more profitable to split and then extend in the same register.
4658(define_peephole2
4659  [(set (match_operand:SF 0 "sse_reg_operand")
4660	(float_truncate:SF
4661	  (match_operand:DF 1 "memory_operand")))]
4662  "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4663   && optimize_insn_for_speed_p ()"
4664  [(set (match_dup 2) (match_dup 1))
4665   (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4666  "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4667
4668(define_expand "truncdfsf2_with_temp"
4669  [(parallel [(set (match_operand:SF 0)
4670		   (float_truncate:SF (match_operand:DF 1)))
4671	      (clobber (match_operand:SF 2))])])
4672
4673;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4674;; because nothing we do there is unsafe.
4675(define_insn "*truncdfsf_fast_mixed"
4676  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4677        (float_truncate:SF
4678          (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4679  "TARGET_SSE2 && TARGET_SSE_MATH"
4680{
4681  switch (which_alternative)
4682    {
4683    case 0:
4684      return output_387_reg_move (insn, operands);
4685    case 1:
4686      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4687    default:
4688      gcc_unreachable ();
4689    }
4690}
4691  [(set_attr "type" "fmov,ssecvt")
4692   (set_attr "prefix" "orig,maybe_vex")
4693   (set_attr "mode" "SF")
4694   (set (attr "enabled")
4695     (cond [(eq_attr "alternative" "0")
4696              (symbol_ref "TARGET_MIX_SSE_I387
4697			   && flag_unsafe_math_optimizations")
4698	   ]
4699           (symbol_ref "true")))])
4700
4701(define_insn "*truncdfsf_fast_i387"
4702  [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4703        (float_truncate:SF
4704          (match_operand:DF 1 "nonimmediate_operand" "f")))]
4705  "TARGET_80387 && flag_unsafe_math_optimizations"
4706  "* return output_387_reg_move (insn, operands);"
4707  [(set_attr "type" "fmov")
4708   (set_attr "mode" "SF")])
4709
4710(define_insn "*truncdfsf_mixed"
4711  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
4712	(float_truncate:SF
4713	  (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4714   (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4715  "TARGET_MIX_SSE_I387"
4716{
4717  switch (which_alternative)
4718    {
4719    case 0:
4720      return output_387_reg_move (insn, operands);
4721    case 1:
4722      return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4723
4724    default:
4725      return "#";
4726    }
4727}
4728  [(set_attr "isa" "*,sse2,*,*,*")
4729   (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4730   (set_attr "unit" "*,*,i387,i387,i387")
4731   (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4732   (set_attr "mode" "SF")])
4733
4734(define_insn "*truncdfsf_i387"
4735  [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
4736	(float_truncate:SF
4737	  (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4738   (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4739  "TARGET_80387"
4740{
4741  switch (which_alternative)
4742    {
4743    case 0:
4744      return output_387_reg_move (insn, operands);
4745
4746    default:
4747      return "#";
4748    }
4749}
4750  [(set_attr "type" "fmov,multi,multi,multi")
4751   (set_attr "unit" "*,i387,i387,i387")
4752   (set_attr "mode" "SF")])
4753
4754(define_insn "*truncdfsf2_i387_1"
4755  [(set (match_operand:SF 0 "memory_operand" "=m")
4756	(float_truncate:SF
4757	  (match_operand:DF 1 "register_operand" "f")))]
4758  "TARGET_80387
4759   && !(TARGET_SSE2 && TARGET_SSE_MATH)
4760   && !TARGET_MIX_SSE_I387"
4761  "* return output_387_reg_move (insn, operands);"
4762  [(set_attr "type" "fmov")
4763   (set_attr "mode" "SF")])
4764
4765(define_split
4766  [(set (match_operand:SF 0 "register_operand")
4767	(float_truncate:SF
4768	 (match_operand:DF 1 "fp_register_operand")))
4769   (clobber (match_operand 2))]
4770  "reload_completed"
4771  [(set (match_dup 2) (match_dup 1))
4772   (set (match_dup 0) (match_dup 2))]
4773  "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4774
4775;; Conversion from XFmode to {SF,DF}mode
4776
4777(define_expand "truncxf<mode>2"
4778  [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4779		   (float_truncate:MODEF
4780		     (match_operand:XF 1 "register_operand")))
4781	      (clobber (match_dup 2))])]
4782  "TARGET_80387"
4783{
4784  if (flag_unsafe_math_optimizations)
4785    {
4786      rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4787      emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4788      if (reg != operands[0])
4789	emit_move_insn (operands[0], reg);
4790      DONE;
4791    }
4792  else
4793    operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4794})
4795
4796(define_insn "*truncxfsf2_mixed"
4797  [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4798	(float_truncate:SF
4799	  (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4800   (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4801  "TARGET_80387"
4802{
4803  gcc_assert (!which_alternative);
4804  return output_387_reg_move (insn, operands);
4805}
4806  [(set_attr "type" "fmov,multi,multi,multi")
4807   (set_attr "unit" "*,i387,i387,i387")
4808   (set_attr "mode" "SF")])
4809
4810(define_insn "*truncxfdf2_mixed"
4811  [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4812	(float_truncate:DF
4813	  (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4814   (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4815  "TARGET_80387"
4816{
4817  gcc_assert (!which_alternative);
4818  return output_387_reg_move (insn, operands);
4819}
4820  [(set_attr "isa" "*,*,sse2,*")
4821   (set_attr "type" "fmov,multi,multi,multi")
4822   (set_attr "unit" "*,i387,i387,i387")
4823   (set_attr "mode" "DF")])
4824
4825(define_insn "truncxf<mode>2_i387_noop"
4826  [(set (match_operand:MODEF 0 "register_operand" "=f")
4827	(float_truncate:MODEF
4828	  (match_operand:XF 1 "register_operand" "f")))]
4829  "TARGET_80387 && flag_unsafe_math_optimizations"
4830  "* return output_387_reg_move (insn, operands);"
4831  [(set_attr "type" "fmov")
4832   (set_attr "mode" "<MODE>")])
4833
4834(define_insn "*truncxf<mode>2_i387"
4835  [(set (match_operand:MODEF 0 "memory_operand" "=m")
4836	(float_truncate:MODEF
4837	  (match_operand:XF 1 "register_operand" "f")))]
4838  "TARGET_80387"
4839  "* return output_387_reg_move (insn, operands);"
4840  [(set_attr "type" "fmov")
4841   (set_attr "mode" "<MODE>")])
4842
4843(define_split
4844  [(set (match_operand:MODEF 0 "register_operand")
4845	(float_truncate:MODEF
4846	  (match_operand:XF 1 "register_operand")))
4847   (clobber (match_operand:MODEF 2 "memory_operand"))]
4848  "TARGET_80387 && reload_completed"
4849  [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4850   (set (match_dup 0) (match_dup 2))])
4851
4852(define_split
4853  [(set (match_operand:MODEF 0 "memory_operand")
4854	(float_truncate:MODEF
4855	  (match_operand:XF 1 "register_operand")))
4856   (clobber (match_operand:MODEF 2 "memory_operand"))]
4857  "TARGET_80387"
4858  [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4859
4860;; Signed conversion to DImode.
4861
4862(define_expand "fix_truncxfdi2"
4863  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4864                   (fix:DI (match_operand:XF 1 "register_operand")))
4865	      (clobber (reg:CC FLAGS_REG))])]
4866  "TARGET_80387"
4867{
4868  if (TARGET_FISTTP)
4869   {
4870     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4871     DONE;
4872   }
4873})
4874
4875(define_expand "fix_trunc<mode>di2"
4876  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4877                   (fix:DI (match_operand:MODEF 1 "register_operand")))
4878              (clobber (reg:CC FLAGS_REG))])]
4879  "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4880{
4881  if (TARGET_FISTTP
4882      && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4883   {
4884     emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4885     DONE;
4886   }
4887  if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4888   {
4889     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4890     emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4891     if (out != operands[0])
4892	emit_move_insn (operands[0], out);
4893     DONE;
4894   }
4895})
4896
4897;; Signed conversion to SImode.
4898
4899(define_expand "fix_truncxfsi2"
4900  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4901                   (fix:SI (match_operand:XF 1 "register_operand")))
4902	      (clobber (reg:CC FLAGS_REG))])]
4903  "TARGET_80387"
4904{
4905  if (TARGET_FISTTP)
4906   {
4907     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4908     DONE;
4909   }
4910})
4911
4912(define_expand "fix_trunc<mode>si2"
4913  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4914	           (fix:SI (match_operand:MODEF 1 "register_operand")))
4915	      (clobber (reg:CC FLAGS_REG))])]
4916  "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4917{
4918  if (TARGET_FISTTP
4919      && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4920   {
4921     emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4922     DONE;
4923   }
4924  if (SSE_FLOAT_MODE_P (<MODE>mode))
4925   {
4926     rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4927     emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4928     if (out != operands[0])
4929	emit_move_insn (operands[0], out);
4930     DONE;
4931   }
4932})
4933
4934;; Signed conversion to HImode.
4935
4936(define_expand "fix_trunc<mode>hi2"
4937  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4938	           (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4939              (clobber (reg:CC FLAGS_REG))])]
4940  "TARGET_80387
4941   && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4942{
4943  if (TARGET_FISTTP)
4944   {
4945     emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4946     DONE;
4947   }
4948})
4949
4950;; Unsigned conversion to SImode.
4951
4952(define_expand "fixuns_trunc<mode>si2"
4953  [(parallel
4954    [(set (match_operand:SI 0 "register_operand")
4955	  (unsigned_fix:SI
4956	    (match_operand:MODEF 1 "nonimmediate_operand")))
4957     (use (match_dup 2))
4958     (clobber (match_scratch:<ssevecmode> 3))
4959     (clobber (match_scratch:<ssevecmode> 4))])]
4960  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4961{
4962  machine_mode mode = <MODE>mode;
4963  machine_mode vecmode = <ssevecmode>mode;
4964  REAL_VALUE_TYPE TWO31r;
4965  rtx two31;
4966
4967  if (optimize_insn_for_size_p ())
4968    FAIL;
4969
4970  real_ldexp (&TWO31r, &dconst1, 31);
4971  two31 = const_double_from_real_value (TWO31r, mode);
4972  two31 = ix86_build_const_vector (vecmode, true, two31);
4973  operands[2] = force_reg (vecmode, two31);
4974})
4975
4976(define_insn_and_split "*fixuns_trunc<mode>_1"
4977  [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4978	(unsigned_fix:SI
4979	  (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4980   (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4981   (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4982   (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4983  "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4984   && optimize_function_for_speed_p (cfun)"
4985  "#"
4986  "&& reload_completed"
4987  [(const_int 0)]
4988{
4989  ix86_split_convert_uns_si_sse (operands);
4990  DONE;
4991})
4992
4993;; Unsigned conversion to HImode.
4994;; Without these patterns, we'll try the unsigned SI conversion which
4995;; is complex for SSE, rather than the signed SI conversion, which isn't.
4996
4997(define_expand "fixuns_trunc<mode>hi2"
4998  [(set (match_dup 2)
4999	(fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5000   (set (match_operand:HI 0 "nonimmediate_operand")
5001	(subreg:HI (match_dup 2) 0))]
5002  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5003  "operands[2] = gen_reg_rtx (SImode);")
5004
5005;; When SSE is available, it is always faster to use it!
5006(define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5007  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5008	(fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5009  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5010   && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5011  "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5012  [(set_attr "type" "sseicvt")
5013   (set_attr "prefix" "maybe_vex")
5014   (set (attr "prefix_rex")
5015	(if_then_else
5016	  (match_test "<SWI48:MODE>mode == DImode")
5017	  (const_string "1")
5018	  (const_string "*")))
5019   (set_attr "mode" "<MODEF:MODE>")
5020   (set_attr "athlon_decode" "double,vector")
5021   (set_attr "amdfam10_decode" "double,double")
5022   (set_attr "bdver1_decode" "double,double")])
5023
5024;; Avoid vector decoded forms of the instruction.
5025(define_peephole2
5026  [(match_scratch:MODEF 2 "x")
5027   (set (match_operand:SWI48 0 "register_operand")
5028	(fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5029  "TARGET_AVOID_VECTOR_DECODE
5030   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5031   && optimize_insn_for_speed_p ()"
5032  [(set (match_dup 2) (match_dup 1))
5033   (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5034
5035(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5036  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5037	(fix:SWI248x (match_operand 1 "register_operand")))]
5038  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5039   && TARGET_FISTTP
5040   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5041	 && (TARGET_64BIT || <MODE>mode != DImode))
5042	&& TARGET_SSE_MATH)
5043   && can_create_pseudo_p ()"
5044  "#"
5045  "&& 1"
5046  [(const_int 0)]
5047{
5048  if (memory_operand (operands[0], VOIDmode))
5049    emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5050  else
5051    {
5052      operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5053      emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5054							    operands[1],
5055							    operands[2]));
5056    }
5057  DONE;
5058}
5059  [(set_attr "type" "fisttp")
5060   (set_attr "mode" "<MODE>")])
5061
5062(define_insn "fix_trunc<mode>_i387_fisttp"
5063  [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5064	(fix:SWI248x (match_operand 1 "register_operand" "f")))
5065   (clobber (match_scratch:XF 2 "=&1f"))]
5066  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5067   && TARGET_FISTTP
5068   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5069	 && (TARGET_64BIT || <MODE>mode != DImode))
5070	&& TARGET_SSE_MATH)"
5071  "* return output_fix_trunc (insn, operands, true);"
5072  [(set_attr "type" "fisttp")
5073   (set_attr "mode" "<MODE>")])
5074
5075(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5076  [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5077	(fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5078   (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5079   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5080  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5081   && TARGET_FISTTP
5082   && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5083	&& (TARGET_64BIT || <MODE>mode != DImode))
5084	&& TARGET_SSE_MATH)"
5085  "#"
5086  [(set_attr "type" "fisttp")
5087   (set_attr "mode" "<MODE>")])
5088
5089(define_split
5090  [(set (match_operand:SWI248x 0 "register_operand")
5091	(fix:SWI248x (match_operand 1 "register_operand")))
5092   (clobber (match_operand:SWI248x 2 "memory_operand"))
5093   (clobber (match_scratch 3))]
5094  "reload_completed"
5095  [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5096	      (clobber (match_dup 3))])
5097   (set (match_dup 0) (match_dup 2))])
5098
5099(define_split
5100  [(set (match_operand:SWI248x 0 "memory_operand")
5101	(fix:SWI248x (match_operand 1 "register_operand")))
5102   (clobber (match_operand:SWI248x 2 "memory_operand"))
5103   (clobber (match_scratch 3))]
5104  "reload_completed"
5105  [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5106	      (clobber (match_dup 3))])])
5107
5108;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5109;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5110;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5111;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5112;; function in i386.c.
5113(define_insn_and_split "*fix_trunc<mode>_i387_1"
5114  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5115	(fix:SWI248x (match_operand 1 "register_operand")))
5116   (clobber (reg:CC FLAGS_REG))]
5117  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5118   && !TARGET_FISTTP
5119   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5120	 && (TARGET_64BIT || <MODE>mode != DImode))
5121   && can_create_pseudo_p ()"
5122  "#"
5123  "&& 1"
5124  [(const_int 0)]
5125{
5126  ix86_optimize_mode_switching[I387_TRUNC] = 1;
5127
5128  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5129  operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5130  if (memory_operand (operands[0], VOIDmode))
5131    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5132					 operands[2], operands[3]));
5133  else
5134    {
5135      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5136      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5137						     operands[2], operands[3],
5138						     operands[4]));
5139    }
5140  DONE;
5141}
5142  [(set_attr "type" "fistp")
5143   (set_attr "i387_cw" "trunc")
5144   (set_attr "mode" "<MODE>")])
5145
5146(define_insn "fix_truncdi_i387"
5147  [(set (match_operand:DI 0 "memory_operand" "=m")
5148	(fix:DI (match_operand 1 "register_operand" "f")))
5149   (use (match_operand:HI 2 "memory_operand" "m"))
5150   (use (match_operand:HI 3 "memory_operand" "m"))
5151   (clobber (match_scratch:XF 4 "=&1f"))]
5152  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5153   && !TARGET_FISTTP
5154   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5155  "* return output_fix_trunc (insn, operands, false);"
5156  [(set_attr "type" "fistp")
5157   (set_attr "i387_cw" "trunc")
5158   (set_attr "mode" "DI")])
5159
5160(define_insn "fix_truncdi_i387_with_temp"
5161  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5162	(fix:DI (match_operand 1 "register_operand" "f,f")))
5163   (use (match_operand:HI 2 "memory_operand" "m,m"))
5164   (use (match_operand:HI 3 "memory_operand" "m,m"))
5165   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5166   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5167  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5168   && !TARGET_FISTTP
5169   && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5170  "#"
5171  [(set_attr "type" "fistp")
5172   (set_attr "i387_cw" "trunc")
5173   (set_attr "mode" "DI")])
5174
5175(define_split
5176  [(set (match_operand:DI 0 "register_operand")
5177	(fix:DI (match_operand 1 "register_operand")))
5178   (use (match_operand:HI 2 "memory_operand"))
5179   (use (match_operand:HI 3 "memory_operand"))
5180   (clobber (match_operand:DI 4 "memory_operand"))
5181   (clobber (match_scratch 5))]
5182  "reload_completed"
5183  [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5184	      (use (match_dup 2))
5185	      (use (match_dup 3))
5186	      (clobber (match_dup 5))])
5187   (set (match_dup 0) (match_dup 4))])
5188
5189(define_split
5190  [(set (match_operand:DI 0 "memory_operand")
5191	(fix:DI (match_operand 1 "register_operand")))
5192   (use (match_operand:HI 2 "memory_operand"))
5193   (use (match_operand:HI 3 "memory_operand"))
5194   (clobber (match_operand:DI 4 "memory_operand"))
5195   (clobber (match_scratch 5))]
5196  "reload_completed"
5197  [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5198	      (use (match_dup 2))
5199	      (use (match_dup 3))
5200	      (clobber (match_dup 5))])])
5201
5202(define_insn "fix_trunc<mode>_i387"
5203  [(set (match_operand:SWI24 0 "memory_operand" "=m")
5204	(fix:SWI24 (match_operand 1 "register_operand" "f")))
5205   (use (match_operand:HI 2 "memory_operand" "m"))
5206   (use (match_operand:HI 3 "memory_operand" "m"))]
5207  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5208   && !TARGET_FISTTP
5209   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5210  "* return output_fix_trunc (insn, operands, false);"
5211  [(set_attr "type" "fistp")
5212   (set_attr "i387_cw" "trunc")
5213   (set_attr "mode" "<MODE>")])
5214
5215(define_insn "fix_trunc<mode>_i387_with_temp"
5216  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5217	(fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5218   (use (match_operand:HI 2 "memory_operand" "m,m"))
5219   (use (match_operand:HI 3 "memory_operand" "m,m"))
5220   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5221  "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5222   && !TARGET_FISTTP
5223   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5224  "#"
5225  [(set_attr "type" "fistp")
5226   (set_attr "i387_cw" "trunc")
5227   (set_attr "mode" "<MODE>")])
5228
5229(define_split
5230  [(set (match_operand:SWI24 0 "register_operand")
5231	(fix:SWI24 (match_operand 1 "register_operand")))
5232   (use (match_operand:HI 2 "memory_operand"))
5233   (use (match_operand:HI 3 "memory_operand"))
5234   (clobber (match_operand:SWI24 4 "memory_operand"))]
5235  "reload_completed"
5236  [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5237	      (use (match_dup 2))
5238	      (use (match_dup 3))])
5239   (set (match_dup 0) (match_dup 4))])
5240
5241(define_split
5242  [(set (match_operand:SWI24 0 "memory_operand")
5243	(fix:SWI24 (match_operand 1 "register_operand")))
5244   (use (match_operand:HI 2 "memory_operand"))
5245   (use (match_operand:HI 3 "memory_operand"))
5246   (clobber (match_operand:SWI24 4 "memory_operand"))]
5247  "reload_completed"
5248  [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5249	      (use (match_dup 2))
5250	      (use (match_dup 3))])])
5251
5252(define_insn "x86_fnstcw_1"
5253  [(set (match_operand:HI 0 "memory_operand" "=m")
5254	(unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5255  "TARGET_80387"
5256  "fnstcw\t%0"
5257  [(set (attr "length")
5258	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5259   (set_attr "mode" "HI")
5260   (set_attr "unit" "i387")
5261   (set_attr "bdver1_decode" "vector")])
5262
5263(define_insn "x86_fldcw_1"
5264  [(set (reg:HI FPCR_REG)
5265	(unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5266  "TARGET_80387"
5267  "fldcw\t%0"
5268  [(set (attr "length")
5269	(symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5270   (set_attr "mode" "HI")
5271   (set_attr "unit" "i387")
5272   (set_attr "athlon_decode" "vector")
5273   (set_attr "amdfam10_decode" "vector")
5274   (set_attr "bdver1_decode" "vector")])
5275
5276;; Conversion between fixed point and floating point.
5277
5278;; Even though we only accept memory inputs, the backend _really_
5279;; wants to be able to do this between registers.  Thankfully, LRA
5280;; will fix this up for us during register allocation.
5281
5282(define_insn "floathi<mode>2"
5283  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5284	(float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5285  "TARGET_80387
5286   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5287       || TARGET_MIX_SSE_I387)"
5288  "fild%Z1\t%1"
5289  [(set_attr "type" "fmov")
5290   (set_attr "mode" "<MODE>")
5291   (set_attr "znver1_decode" "double")
5292   (set_attr "fp_int_src" "true")])
5293
5294(define_insn "float<SWI48x:mode>xf2"
5295  [(set (match_operand:XF 0 "register_operand" "=f")
5296	(float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5297  "TARGET_80387"
5298  "fild%Z1\t%1"
5299  [(set_attr "type" "fmov")
5300   (set_attr "mode" "XF")
5301   (set_attr "znver1_decode" "double")
5302   (set_attr "fp_int_src" "true")])
5303
5304(define_expand "float<SWI48:mode><MODEF:mode>2"
5305  [(set (match_operand:MODEF 0 "register_operand")
5306	(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5307  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5308{
5309  if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5310      && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5311    {
5312      rtx reg = gen_reg_rtx (XFmode);
5313      rtx (*insn)(rtx, rtx);
5314
5315      emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5316
5317      if (<MODEF:MODE>mode == SFmode)
5318	insn = gen_truncxfsf2;
5319      else if (<MODEF:MODE>mode == DFmode)
5320	insn = gen_truncxfdf2;
5321      else
5322	gcc_unreachable ();
5323
5324      emit_insn (insn (operands[0], reg));
5325      DONE;
5326    }
5327})
5328
5329(define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5330  [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5331	(float:MODEF
5332	  (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5333  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5334  "@
5335   fild%Z1\t%1
5336   %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5337   %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5338  [(set_attr "type" "fmov,sseicvt,sseicvt")
5339   (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5340   (set_attr "mode" "<MODEF:MODE>")
5341   (set (attr "prefix_rex")
5342     (if_then_else
5343       (and (eq_attr "prefix" "maybe_vex")
5344	    (match_test "<SWI48:MODE>mode == DImode"))
5345       (const_string "1")
5346       (const_string "*")))
5347   (set_attr "unit" "i387,*,*")
5348   (set_attr "athlon_decode" "*,double,direct")
5349   (set_attr "amdfam10_decode" "*,vector,double")
5350   (set_attr "bdver1_decode" "*,double,direct")
5351   (set_attr "znver1_decode" "double,*,*")
5352   (set_attr "fp_int_src" "true")
5353   (set (attr "enabled")
5354     (cond [(eq_attr "alternative" "0")
5355              (symbol_ref "TARGET_MIX_SSE_I387
5356                           && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5357                                                <SWI48:MODE>mode)")
5358           ]
5359           (symbol_ref "true")))
5360   (set (attr "preferred_for_speed")
5361     (cond [(eq_attr "alternative" "1")
5362              (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5363           (symbol_ref "true")))])
5364
5365(define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5366  [(set (match_operand:MODEF 0 "register_operand" "=f")
5367	(float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5368  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5369  "fild%Z1\t%1"
5370  [(set_attr "type" "fmov")
5371   (set_attr "mode" "<MODEF:MODE>")
5372   (set_attr "znver1_decode" "double")
5373   (set_attr "fp_int_src" "true")])
5374
5375;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5376;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5377;; alternative in sse2_loadld.
5378(define_split
5379  [(set (match_operand:MODEF 0 "sse_reg_operand")
5380	(float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5381  "TARGET_SSE2
5382   && TARGET_USE_VECTOR_CONVERTS
5383   && optimize_function_for_speed_p (cfun)
5384   && reload_completed
5385   && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5386   && (!EXT_REX_SSE_REG_P (operands[0])
5387       || TARGET_AVX512VL)"
5388  [(const_int 0)]
5389{
5390  operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5391  operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5392
5393  emit_insn (gen_sse2_loadld (operands[4],
5394			      CONST0_RTX (V4SImode), operands[1]));
5395
5396  if (<ssevecmode>mode == V4SFmode)
5397    emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5398  else
5399    emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5400  DONE;
5401})
5402
5403;; Avoid partial SSE register dependency stalls.  This splitter should split
5404;; late in the pass sequence (after register rename pass), so allocated
5405;; registers won't change anymore
5406
5407(define_split
5408  [(set (match_operand:MODEF 0 "sse_reg_operand")
5409	(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5410  "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5411   && optimize_function_for_speed_p (cfun)
5412   && (!EXT_REX_SSE_REG_P (operands[0])
5413       || TARGET_AVX512VL)"
5414  [(set (match_dup 0)
5415	(vec_merge:<MODEF:ssevecmode>
5416	  (vec_duplicate:<MODEF:ssevecmode>
5417	    (float:MODEF
5418	      (match_dup 1)))
5419	  (match_dup 0)
5420	  (const_int 1)))]
5421{
5422  const machine_mode vmode = <MODEF:ssevecmode>mode;
5423
5424  operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5425  emit_move_insn (operands[0], CONST0_RTX (vmode));
5426})
5427
5428;; Break partial reg stall for cvtsd2ss.  This splitter should split
5429;; late in the pass sequence (after register rename pass),
5430;; so allocated registers won't change anymore.
5431
5432(define_split
5433  [(set (match_operand:SF 0 "sse_reg_operand")
5434        (float_truncate:SF
5435	  (match_operand:DF 1 "nonimmediate_operand")))]
5436  "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5437   && optimize_function_for_speed_p (cfun)
5438   && (!REG_P (operands[1])
5439       || REGNO (operands[0]) != REGNO (operands[1]))
5440   && (!EXT_REX_SSE_REG_P (operands[0])
5441       || TARGET_AVX512VL)"
5442  [(set (match_dup 0)
5443	(vec_merge:V4SF
5444	  (vec_duplicate:V4SF
5445	    (float_truncate:SF
5446	      (match_dup 1)))
5447	  (match_dup 0)
5448	  (const_int 1)))]
5449{
5450  operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5451  emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5452})
5453
5454;; Break partial reg stall for cvtss2sd.  This splitter should split
5455;; late in the pass sequence (after register rename pass),
5456;; so allocated registers won't change anymore.
5457
5458(define_split
5459  [(set (match_operand:DF 0 "sse_reg_operand")
5460        (float_extend:DF
5461          (match_operand:SF 1 "nonimmediate_operand")))]
5462  "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5463   && optimize_function_for_speed_p (cfun)
5464   && (!REG_P (operands[1])
5465       || REGNO (operands[0]) != REGNO (operands[1]))
5466   && (!EXT_REX_SSE_REG_P (operands[0])
5467       || TARGET_AVX512VL)"
5468  [(set (match_dup 0)
5469        (vec_merge:V2DF
5470	  (vec_duplicate:V2DF
5471	    (float_extend:DF
5472	      (match_dup 1)))
5473	  (match_dup 0)
5474          (const_int 1)))]
5475{
5476  operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5477  emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5478})
5479
5480;; Avoid store forwarding (partial memory) stall penalty
5481;; by passing DImode value through XMM registers.  */
5482
5483(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5484  [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5485	(float:X87MODEF
5486	  (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5487   (clobber (match_scratch:V4SI 3 "=X,x"))
5488   (clobber (match_scratch:V4SI 4 "=X,x"))
5489   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5490  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5491   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5492   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5493  "#"
5494  [(set_attr "type" "multi")
5495   (set_attr "mode" "<X87MODEF:MODE>")
5496   (set_attr "unit" "i387")
5497   (set_attr "fp_int_src" "true")])
5498
5499(define_split
5500  [(set (match_operand:X87MODEF 0 "fp_register_operand")
5501	(float:X87MODEF (match_operand:DI 1 "register_operand")))
5502   (clobber (match_scratch:V4SI 3))
5503   (clobber (match_scratch:V4SI 4))
5504   (clobber (match_operand:DI 2 "memory_operand"))]
5505  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5506   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5507   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5508   && reload_completed"
5509  [(set (match_dup 2) (match_dup 3))
5510   (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5511{
5512  /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5513     Assemble the 64-bit DImode value in an xmm register.  */
5514  emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5515			      gen_lowpart (SImode, operands[1])));
5516  emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5517			      gen_highpart (SImode, operands[1])));
5518  emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5519					 operands[4]));
5520
5521  operands[3] = gen_lowpart (DImode, operands[3]);
5522})
5523
5524(define_split
5525  [(set (match_operand:X87MODEF 0 "fp_register_operand")
5526	(float:X87MODEF (match_operand:DI 1 "memory_operand")))
5527   (clobber (match_scratch:V4SI 3))
5528   (clobber (match_scratch:V4SI 4))
5529   (clobber (match_operand:DI 2 "memory_operand"))]
5530  "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5531   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5532   && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5533   && reload_completed"
5534  [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5535
5536(define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5537  [(set (match_operand:MODEF 0 "register_operand")
5538	(unsigned_float:MODEF
5539	  (match_operand:SWI12 1 "nonimmediate_operand")))]
5540  "!TARGET_64BIT
5541   && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5542{
5543  operands[1] = convert_to_mode (SImode, operands[1], 1);
5544  emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5545  DONE;
5546})
5547
5548;; Avoid store forwarding (partial memory) stall penalty by extending
5549;; SImode value to DImode through XMM register instead of pushing two
5550;; SImode values to stack. Also note that fild loads from memory only.
5551
5552(define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5553  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5554	(unsigned_float:X87MODEF
5555	  (match_operand:SI 1 "nonimmediate_operand" "rm")))
5556   (clobber (match_scratch:DI 3 "=x"))
5557   (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5558  "!TARGET_64BIT
5559   && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5560   && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5561  "#"
5562  "&& reload_completed"
5563  [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5564   (set (match_dup 2) (match_dup 3))
5565   (set (match_dup 0)
5566	(float:X87MODEF (match_dup 2)))]
5567  ""
5568  [(set_attr "type" "multi")
5569   (set_attr "mode" "<MODE>")])
5570
5571(define_expand "floatunssi<mode>2"
5572  [(parallel
5573     [(set (match_operand:X87MODEF 0 "register_operand")
5574	   (unsigned_float:X87MODEF
5575	     (match_operand:SI 1 "nonimmediate_operand")))
5576      (clobber (match_scratch:DI 3))
5577      (clobber (match_dup 2))])]
5578  "!TARGET_64BIT
5579   && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5580	&& TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5581       || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5582{
5583  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5584    {
5585      ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5586      DONE;
5587    }
5588  else
5589    operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5590})
5591
5592(define_expand "floatunsdisf2"
5593  [(use (match_operand:SF 0 "register_operand"))
5594   (use (match_operand:DI 1 "nonimmediate_operand"))]
5595  "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5596  "x86_emit_floatuns (operands); DONE;")
5597
5598(define_expand "floatunsdidf2"
5599  [(use (match_operand:DF 0 "register_operand"))
5600   (use (match_operand:DI 1 "nonimmediate_operand"))]
5601  "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5602   && TARGET_SSE2 && TARGET_SSE_MATH"
5603{
5604  if (TARGET_64BIT)
5605    x86_emit_floatuns (operands);
5606  else
5607    ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5608  DONE;
5609})
5610
5611;; Load effective address instructions
5612
5613(define_insn_and_split "*lea<mode>"
5614  [(set (match_operand:SWI48 0 "register_operand" "=r")
5615	(match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5616  ""
5617{
5618  if (SImode_address_operand (operands[1], VOIDmode))
5619    {
5620      gcc_assert (TARGET_64BIT);
5621      return "lea{l}\t{%E1, %k0|%k0, %E1}";
5622    }
5623  else
5624    return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5625}
5626  "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5627  [(const_int 0)]
5628{
5629  machine_mode mode = <MODE>mode;
5630  rtx pat;
5631
5632  /* ix86_avoid_lea_for_addr re-recognizes insn and may
5633     change operands[] array behind our back.  */
5634  pat = PATTERN (curr_insn);
5635
5636  operands[0] = SET_DEST (pat);
5637  operands[1] = SET_SRC (pat);
5638
5639  /* Emit all operations in SImode for zero-extended addresses.  */
5640  if (SImode_address_operand (operands[1], VOIDmode))
5641    mode = SImode;
5642
5643  ix86_split_lea_for_addr (curr_insn, operands, mode);
5644
5645  /* Zero-extend return register to DImode for zero-extended addresses.  */
5646  if (mode != <MODE>mode)
5647    emit_insn (gen_zero_extendsidi2
5648    	       (operands[0], gen_lowpart (mode, operands[0])));
5649
5650  DONE;
5651}
5652  [(set_attr "type" "lea")
5653   (set (attr "mode")
5654     (if_then_else
5655       (match_operand 1 "SImode_address_operand")
5656       (const_string "SI")
5657       (const_string "<MODE>")))])
5658
5659;; Add instructions
5660
5661(define_expand "add<mode>3"
5662  [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5663	(plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5664		    (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5665  ""
5666  "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5667
5668(define_insn_and_split "*add<dwi>3_doubleword"
5669  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5670	(plus:<DWI>
5671	  (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5672	  (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5673							"ro<di>,r<di>")))
5674   (clobber (reg:CC FLAGS_REG))]
5675  "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5676  "#"
5677  "reload_completed"
5678  [(parallel [(set (reg:CCC FLAGS_REG)
5679		   (compare:CCC
5680		     (plus:DWIH (match_dup 1) (match_dup 2))
5681		     (match_dup 1)))
5682	      (set (match_dup 0)
5683		   (plus:DWIH (match_dup 1) (match_dup 2)))])
5684   (parallel [(set (match_dup 3)
5685		   (plus:DWIH
5686		     (plus:DWIH
5687		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5688		       (match_dup 4))
5689		     (match_dup 5)))
5690	      (clobber (reg:CC FLAGS_REG))])]
5691{
5692  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5693  if (operands[2] == const0_rtx)
5694    {
5695      ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5696      DONE;
5697    }
5698})
5699
5700(define_insn "*add<mode>_1"
5701  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5702	(plus:SWI48
5703	  (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5704	  (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5705   (clobber (reg:CC FLAGS_REG))]
5706  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5707{
5708  switch (get_attr_type (insn))
5709    {
5710    case TYPE_LEA:
5711      return "#";
5712
5713    case TYPE_INCDEC:
5714      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5715      if (operands[2] == const1_rtx)
5716        return "inc{<imodesuffix>}\t%0";
5717      else
5718        {
5719	  gcc_assert (operands[2] == constm1_rtx);
5720          return "dec{<imodesuffix>}\t%0";
5721	}
5722
5723    default:
5724      /* For most processors, ADD is faster than LEA.  This alternative
5725	 was added to use ADD as much as possible.  */
5726      if (which_alternative == 2)
5727        std::swap (operands[1], operands[2]);
5728
5729      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5730      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5731        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5732
5733      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5734    }
5735}
5736  [(set (attr "type")
5737     (cond [(eq_attr "alternative" "3")
5738              (const_string "lea")
5739	    (match_operand:SWI48 2 "incdec_operand")
5740	      (const_string "incdec")
5741	   ]
5742	   (const_string "alu")))
5743   (set (attr "length_immediate")
5744      (if_then_else
5745	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5746	(const_string "1")
5747	(const_string "*")))
5748   (set_attr "mode" "<MODE>")])
5749
5750;; It may seem that nonimmediate operand is proper one for operand 1.
5751;; The addsi_1 pattern allows nonimmediate operand at that place and
5752;; we take care in ix86_binary_operator_ok to not allow two memory
5753;; operands so proper swapping will be done in reload.  This allow
5754;; patterns constructed from addsi_1 to match.
5755
5756(define_insn "addsi_1_zext"
5757  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5758	(zero_extend:DI
5759	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5760		   (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5761   (clobber (reg:CC FLAGS_REG))]
5762  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5763{
5764  switch (get_attr_type (insn))
5765    {
5766    case TYPE_LEA:
5767      return "#";
5768
5769    case TYPE_INCDEC:
5770      if (operands[2] == const1_rtx)
5771        return "inc{l}\t%k0";
5772      else
5773        {
5774	  gcc_assert (operands[2] == constm1_rtx);
5775          return "dec{l}\t%k0";
5776	}
5777
5778    default:
5779      /* For most processors, ADD is faster than LEA.  This alternative
5780	 was added to use ADD as much as possible.  */
5781      if (which_alternative == 1)
5782        std::swap (operands[1], operands[2]);
5783
5784      if (x86_maybe_negate_const_int (&operands[2], SImode))
5785        return "sub{l}\t{%2, %k0|%k0, %2}";
5786
5787      return "add{l}\t{%2, %k0|%k0, %2}";
5788    }
5789}
5790  [(set (attr "type")
5791     (cond [(eq_attr "alternative" "2")
5792	      (const_string "lea")
5793	    (match_operand:SI 2 "incdec_operand")
5794	      (const_string "incdec")
5795	   ]
5796	   (const_string "alu")))
5797   (set (attr "length_immediate")
5798      (if_then_else
5799	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5800	(const_string "1")
5801	(const_string "*")))
5802   (set_attr "mode" "SI")])
5803
5804(define_insn "*addhi_1"
5805  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5806	(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5807		 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5808   (clobber (reg:CC FLAGS_REG))]
5809  "ix86_binary_operator_ok (PLUS, HImode, operands)"
5810{
5811  switch (get_attr_type (insn))
5812    {
5813    case TYPE_LEA:
5814      return "#";
5815
5816    case TYPE_INCDEC:
5817      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5818      if (operands[2] == const1_rtx)
5819	return "inc{w}\t%0";
5820      else
5821	{
5822	  gcc_assert (operands[2] == constm1_rtx);
5823	  return "dec{w}\t%0";
5824	}
5825
5826    default:
5827      /* For most processors, ADD is faster than LEA.  This alternative
5828	 was added to use ADD as much as possible.  */
5829      if (which_alternative == 2)
5830        std::swap (operands[1], operands[2]);
5831
5832      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5833      if (x86_maybe_negate_const_int (&operands[2], HImode))
5834	return "sub{w}\t{%2, %0|%0, %2}";
5835
5836      return "add{w}\t{%2, %0|%0, %2}";
5837    }
5838}
5839  [(set (attr "type")
5840     (cond [(eq_attr "alternative" "3")
5841              (const_string "lea")
5842	    (match_operand:HI 2 "incdec_operand")
5843	      (const_string "incdec")
5844	   ]
5845	   (const_string "alu")))
5846   (set (attr "length_immediate")
5847      (if_then_else
5848	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5849	(const_string "1")
5850	(const_string "*")))
5851   (set_attr "mode" "HI,HI,HI,SI")])
5852
5853(define_insn "*addqi_1"
5854  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5855	(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5856		 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5857   (clobber (reg:CC FLAGS_REG))]
5858  "ix86_binary_operator_ok (PLUS, QImode, operands)"
5859{
5860  bool widen = (get_attr_mode (insn) != MODE_QI);
5861
5862  switch (get_attr_type (insn))
5863    {
5864    case TYPE_LEA:
5865      return "#";
5866
5867    case TYPE_INCDEC:
5868      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5869      if (operands[2] == const1_rtx)
5870	return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5871      else
5872	{
5873	  gcc_assert (operands[2] == constm1_rtx);
5874	  return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5875	}
5876
5877    default:
5878      /* For most processors, ADD is faster than LEA.  These alternatives
5879	 were added to use ADD as much as possible.  */
5880      if (which_alternative == 2 || which_alternative == 4)
5881        std::swap (operands[1], operands[2]);
5882
5883      gcc_assert (rtx_equal_p (operands[0], operands[1]));
5884      if (x86_maybe_negate_const_int (&operands[2], QImode))
5885	{
5886	  if (widen)
5887	    return "sub{l}\t{%2, %k0|%k0, %2}";
5888	  else
5889	    return "sub{b}\t{%2, %0|%0, %2}";
5890	}
5891      if (widen)
5892        return "add{l}\t{%k2, %k0|%k0, %k2}";
5893      else
5894        return "add{b}\t{%2, %0|%0, %2}";
5895    }
5896}
5897  [(set (attr "type")
5898     (cond [(eq_attr "alternative" "5")
5899              (const_string "lea")
5900	    (match_operand:QI 2 "incdec_operand")
5901	      (const_string "incdec")
5902	   ]
5903	   (const_string "alu")))
5904   (set (attr "length_immediate")
5905      (if_then_else
5906	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5907	(const_string "1")
5908	(const_string "*")))
5909   (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5910   ;; Potential partial reg stall on alternatives 3 and 4.
5911   (set (attr "preferred_for_speed")
5912     (cond [(eq_attr "alternative" "3,4")
5913	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5914	   (symbol_ref "true")))])
5915
5916(define_insn "*addqi_1_slp"
5917  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5918	(plus:QI (match_dup 0)
5919		 (match_operand:QI 1 "general_operand" "qn,qm")))
5920   (clobber (reg:CC FLAGS_REG))]
5921  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5922   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5923{
5924  switch (get_attr_type (insn))
5925    {
5926    case TYPE_INCDEC:
5927      if (operands[1] == const1_rtx)
5928	return "inc{b}\t%0";
5929      else
5930	{
5931	  gcc_assert (operands[1] == constm1_rtx);
5932	  return "dec{b}\t%0";
5933	}
5934
5935    default:
5936      if (x86_maybe_negate_const_int (&operands[1], QImode))
5937	return "sub{b}\t{%1, %0|%0, %1}";
5938
5939      return "add{b}\t{%1, %0|%0, %1}";
5940    }
5941}
5942  [(set (attr "type")
5943     (if_then_else (match_operand:QI 1 "incdec_operand")
5944	(const_string "incdec")
5945	(const_string "alu1")))
5946   (set (attr "memory")
5947     (if_then_else (match_operand 1 "memory_operand")
5948        (const_string "load")
5949        (const_string "none")))
5950   (set_attr "mode" "QI")])
5951
5952;; Split non destructive adds if we cannot use lea.
5953(define_split
5954  [(set (match_operand:SWI48 0 "register_operand")
5955	(plus:SWI48 (match_operand:SWI48 1 "register_operand")
5956		    (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5957   (clobber (reg:CC FLAGS_REG))]
5958  "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5959  [(set (match_dup 0) (match_dup 1))
5960   (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5961	      (clobber (reg:CC FLAGS_REG))])])
5962
5963;; Split non destructive adds if we cannot use lea.
5964(define_split
5965  [(set (match_operand:DI 0 "register_operand")
5966  	(zero_extend:DI
5967	  (plus:SI (match_operand:SI 1 "register_operand")
5968		   (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5969   (clobber (reg:CC FLAGS_REG))]
5970  "TARGET_64BIT
5971   && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5972  [(set (match_dup 3) (match_dup 1))
5973   (parallel [(set (match_dup 0)
5974   	     	   (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5975	      (clobber (reg:CC FLAGS_REG))])]
5976  "operands[3] = gen_lowpart (SImode, operands[0]);")
5977
5978;; Convert add to the lea pattern to avoid flags dependency.
5979(define_split
5980  [(set (match_operand:SWI 0 "register_operand")
5981	(plus:SWI (match_operand:SWI 1 "register_operand")
5982		  (match_operand:SWI 2 "<nonmemory_operand>")))
5983   (clobber (reg:CC FLAGS_REG))]
5984  "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5985  [(set (match_dup 0)
5986	(plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5987{
5988  if (<MODE>mode != <LEAMODE>mode)
5989    {
5990      operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5991      operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5992      operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5993    }
5994})
5995
5996;; Convert add to the lea pattern to avoid flags dependency.
5997(define_split
5998  [(set (match_operand:DI 0 "register_operand")
5999	(zero_extend:DI
6000	  (plus:SI (match_operand:SI 1 "register_operand")
6001		   (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6002   (clobber (reg:CC FLAGS_REG))]
6003  "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6004  [(set (match_dup 0)
6005	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6006
6007(define_insn "*add<mode>_2"
6008  [(set (reg FLAGS_REG)
6009	(compare
6010	  (plus:SWI
6011	    (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6012	    (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6013	  (const_int 0)))
6014   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6015	(plus:SWI (match_dup 1) (match_dup 2)))]
6016  "ix86_match_ccmode (insn, CCGOCmode)
6017   && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6018{
6019  switch (get_attr_type (insn))
6020    {
6021    case TYPE_INCDEC:
6022      if (operands[2] == const1_rtx)
6023        return "inc{<imodesuffix>}\t%0";
6024      else
6025        {
6026	  gcc_assert (operands[2] == constm1_rtx);
6027          return "dec{<imodesuffix>}\t%0";
6028	}
6029
6030    default:
6031      if (which_alternative == 2)
6032        std::swap (operands[1], operands[2]);
6033
6034      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6036        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6037
6038      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6039    }
6040}
6041  [(set (attr "type")
6042     (if_then_else (match_operand:SWI 2 "incdec_operand")
6043	(const_string "incdec")
6044	(const_string "alu")))
6045   (set (attr "length_immediate")
6046      (if_then_else
6047	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6048	(const_string "1")
6049	(const_string "*")))
6050   (set_attr "mode" "<MODE>")])
6051
6052;; See comment for addsi_1_zext why we do use nonimmediate_operand
6053(define_insn "*addsi_2_zext"
6054  [(set (reg FLAGS_REG)
6055	(compare
6056	  (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6057		   (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6058	  (const_int 0)))
6059   (set (match_operand:DI 0 "register_operand" "=r,r")
6060	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6061  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6062   && ix86_binary_operator_ok (PLUS, SImode, operands)"
6063{
6064  switch (get_attr_type (insn))
6065    {
6066    case TYPE_INCDEC:
6067      if (operands[2] == const1_rtx)
6068        return "inc{l}\t%k0";
6069      else
6070	{
6071	  gcc_assert (operands[2] == constm1_rtx);
6072          return "dec{l}\t%k0";
6073	}
6074
6075    default:
6076      if (which_alternative == 1)
6077        std::swap (operands[1], operands[2]);
6078
6079      if (x86_maybe_negate_const_int (&operands[2], SImode))
6080        return "sub{l}\t{%2, %k0|%k0, %2}";
6081
6082      return "add{l}\t{%2, %k0|%k0, %2}";
6083    }
6084}
6085  [(set (attr "type")
6086     (if_then_else (match_operand:SI 2 "incdec_operand")
6087	(const_string "incdec")
6088	(const_string "alu")))
6089   (set (attr "length_immediate")
6090      (if_then_else
6091	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6092	(const_string "1")
6093	(const_string "*")))
6094   (set_attr "mode" "SI")])
6095
6096(define_insn "*add<mode>_3"
6097  [(set (reg FLAGS_REG)
6098	(compare
6099	  (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6100	  (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6101   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6102  "ix86_match_ccmode (insn, CCZmode)
6103   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6104{
6105  switch (get_attr_type (insn))
6106    {
6107    case TYPE_INCDEC:
6108      if (operands[2] == const1_rtx)
6109        return "inc{<imodesuffix>}\t%0";
6110      else
6111        {
6112	  gcc_assert (operands[2] == constm1_rtx);
6113          return "dec{<imodesuffix>}\t%0";
6114	}
6115
6116    default:
6117      if (which_alternative == 1)
6118        std::swap (operands[1], operands[2]);
6119
6120      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6121      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6122        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6123
6124      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6125    }
6126}
6127  [(set (attr "type")
6128     (if_then_else (match_operand:SWI 2 "incdec_operand")
6129	(const_string "incdec")
6130	(const_string "alu")))
6131   (set (attr "length_immediate")
6132      (if_then_else
6133	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6134	(const_string "1")
6135	(const_string "*")))
6136   (set_attr "mode" "<MODE>")])
6137
6138;; See comment for addsi_1_zext why we do use nonimmediate_operand
6139(define_insn "*addsi_3_zext"
6140  [(set (reg FLAGS_REG)
6141	(compare
6142	  (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6143	  (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6144   (set (match_operand:DI 0 "register_operand" "=r,r")
6145	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6146  "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6147   && ix86_binary_operator_ok (PLUS, SImode, operands)"
6148{
6149  switch (get_attr_type (insn))
6150    {
6151    case TYPE_INCDEC:
6152      if (operands[2] == const1_rtx)
6153        return "inc{l}\t%k0";
6154      else
6155        {
6156	  gcc_assert (operands[2] == constm1_rtx);
6157          return "dec{l}\t%k0";
6158	}
6159
6160    default:
6161      if (which_alternative == 1)
6162        std::swap (operands[1], operands[2]);
6163
6164      if (x86_maybe_negate_const_int (&operands[2], SImode))
6165        return "sub{l}\t{%2, %k0|%k0, %2}";
6166
6167      return "add{l}\t{%2, %k0|%k0, %2}";
6168    }
6169}
6170  [(set (attr "type")
6171     (if_then_else (match_operand:SI 2 "incdec_operand")
6172	(const_string "incdec")
6173	(const_string "alu")))
6174   (set (attr "length_immediate")
6175      (if_then_else
6176	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6177	(const_string "1")
6178	(const_string "*")))
6179   (set_attr "mode" "SI")])
6180
6181; For comparisons against 1, -1 and 128, we may generate better code
6182; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6183; is matched then.  We can't accept general immediate, because for
6184; case of overflows,  the result is messed up.
6185; Also carry flag is reversed compared to cmp, so this conversion is valid
6186; only for comparisons not depending on it.
6187
6188(define_insn "*adddi_4"
6189  [(set (reg FLAGS_REG)
6190	(compare
6191	  (match_operand:DI 1 "nonimmediate_operand" "0")
6192	  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6193   (clobber (match_scratch:DI 0 "=rm"))]
6194  "TARGET_64BIT
6195   && ix86_match_ccmode (insn, CCGCmode)"
6196{
6197  switch (get_attr_type (insn))
6198    {
6199    case TYPE_INCDEC:
6200      if (operands[2] == constm1_rtx)
6201        return "inc{q}\t%0";
6202      else
6203        {
6204	  gcc_assert (operands[2] == const1_rtx);
6205          return "dec{q}\t%0";
6206	}
6207
6208    default:
6209      if (x86_maybe_negate_const_int (&operands[2], DImode))
6210	return "add{q}\t{%2, %0|%0, %2}";
6211
6212      return "sub{q}\t{%2, %0|%0, %2}";
6213    }
6214}
6215  [(set (attr "type")
6216     (if_then_else (match_operand:DI 2 "incdec_operand")
6217	(const_string "incdec")
6218	(const_string "alu")))
6219   (set (attr "length_immediate")
6220      (if_then_else
6221	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6222	(const_string "1")
6223	(const_string "*")))
6224   (set_attr "mode" "DI")])
6225
6226; For comparisons against 1, -1 and 128, we may generate better code
6227; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6228; is matched then.  We can't accept general immediate, because for
6229; case of overflows,  the result is messed up.
6230; Also carry flag is reversed compared to cmp, so this conversion is valid
6231; only for comparisons not depending on it.
6232
6233(define_insn "*add<mode>_4"
6234  [(set (reg FLAGS_REG)
6235	(compare
6236	  (match_operand:SWI124 1 "nonimmediate_operand" "0")
6237	  (match_operand:SWI124 2 "const_int_operand" "n")))
6238   (clobber (match_scratch:SWI124 0 "=<r>m"))]
6239  "ix86_match_ccmode (insn, CCGCmode)"
6240{
6241  switch (get_attr_type (insn))
6242    {
6243    case TYPE_INCDEC:
6244      if (operands[2] == constm1_rtx)
6245        return "inc{<imodesuffix>}\t%0";
6246      else
6247        {
6248	  gcc_assert (operands[2] == const1_rtx);
6249          return "dec{<imodesuffix>}\t%0";
6250	}
6251
6252    default:
6253      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6254	return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6255
6256      return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6257    }
6258}
6259  [(set (attr "type")
6260     (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6261	(const_string "incdec")
6262	(const_string "alu")))
6263   (set (attr "length_immediate")
6264      (if_then_else
6265	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6266	(const_string "1")
6267	(const_string "*")))
6268   (set_attr "mode" "<MODE>")])
6269
6270(define_insn "*add<mode>_5"
6271  [(set (reg FLAGS_REG)
6272	(compare
6273	  (plus:SWI
6274	    (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6275	    (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6276	  (const_int 0)))
6277   (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6278  "ix86_match_ccmode (insn, CCGOCmode)
6279   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6280{
6281  switch (get_attr_type (insn))
6282    {
6283    case TYPE_INCDEC:
6284      if (operands[2] == const1_rtx)
6285        return "inc{<imodesuffix>}\t%0";
6286      else
6287        {
6288          gcc_assert (operands[2] == constm1_rtx);
6289          return "dec{<imodesuffix>}\t%0";
6290	}
6291
6292    default:
6293      if (which_alternative == 1)
6294        std::swap (operands[1], operands[2]);
6295
6296      gcc_assert (rtx_equal_p (operands[0], operands[1]));
6297      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6298        return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6299
6300      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6301    }
6302}
6303  [(set (attr "type")
6304     (if_then_else (match_operand:SWI 2 "incdec_operand")
6305	(const_string "incdec")
6306	(const_string "alu")))
6307   (set (attr "length_immediate")
6308      (if_then_else
6309	(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6310	(const_string "1")
6311	(const_string "*")))
6312   (set_attr "mode" "<MODE>")])
6313
6314(define_insn "addqi_ext_1"
6315  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6316			 (const_int 8)
6317			 (const_int 8))
6318	(subreg:SI
6319	  (plus:QI
6320	    (subreg:QI
6321	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6322			       (const_int 8)
6323			       (const_int 8)) 0)
6324	    (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6325   (clobber (reg:CC FLAGS_REG))]
6326  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6327   rtx_equal_p (operands[0], operands[1])"
6328{
6329  switch (get_attr_type (insn))
6330    {
6331    case TYPE_INCDEC:
6332      if (operands[2] == const1_rtx)
6333	return "inc{b}\t%h0";
6334      else
6335        {
6336	  gcc_assert (operands[2] == constm1_rtx);
6337          return "dec{b}\t%h0";
6338        }
6339
6340    default:
6341      return "add{b}\t{%2, %h0|%h0, %2}";
6342    }
6343}
6344  [(set_attr "isa" "*,nox64")
6345   (set (attr "type")
6346     (if_then_else (match_operand:QI 2 "incdec_operand")
6347	(const_string "incdec")
6348	(const_string "alu")))
6349   (set_attr "mode" "QI")])
6350
6351(define_insn "*addqi_ext_2"
6352  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6353			 (const_int 8)
6354			 (const_int 8))
6355	(subreg:SI
6356	  (plus:QI
6357	    (subreg:QI
6358	      (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6359			       (const_int 8)
6360			       (const_int 8)) 0)
6361	    (subreg:QI
6362	      (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6363			       (const_int 8)
6364			       (const_int 8)) 0)) 0))
6365  (clobber (reg:CC FLAGS_REG))]
6366  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6367   rtx_equal_p (operands[0], operands[1])
6368   || rtx_equal_p (operands[0], operands[2])"
6369  "add{b}\t{%h2, %h0|%h0, %h2}"
6370  [(set_attr "type" "alu")
6371   (set_attr "mode" "QI")])
6372
6373;; Add with jump on overflow.
6374(define_expand "addv<mode>4"
6375  [(parallel [(set (reg:CCO FLAGS_REG)
6376		   (eq:CCO (plus:<DWI>
6377			      (sign_extend:<DWI>
6378				 (match_operand:SWI 1 "nonimmediate_operand"))
6379			      (match_dup 4))
6380			   (sign_extend:<DWI>
6381			      (plus:SWI (match_dup 1)
6382					(match_operand:SWI 2
6383					   "<general_operand>")))))
6384	      (set (match_operand:SWI 0 "register_operand")
6385		   (plus:SWI (match_dup 1) (match_dup 2)))])
6386   (set (pc) (if_then_else
6387	       (eq (reg:CCO FLAGS_REG) (const_int 0))
6388	       (label_ref (match_operand 3))
6389	       (pc)))]
6390  ""
6391{
6392  ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6393  if (CONST_INT_P (operands[2]))
6394    operands[4] = operands[2];
6395  else
6396    operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6397})
6398
6399(define_insn "*addv<mode>4"
6400  [(set (reg:CCO FLAGS_REG)
6401	(eq:CCO (plus:<DWI>
6402		   (sign_extend:<DWI>
6403		      (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6404		   (sign_extend:<DWI>
6405		      (match_operand:SWI 2 "<general_sext_operand>"
6406					   "<r>mWe,<r>We")))
6407		(sign_extend:<DWI>
6408		   (plus:SWI (match_dup 1) (match_dup 2)))))
6409   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6410	(plus:SWI (match_dup 1) (match_dup 2)))]
6411  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6412  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6413  [(set_attr "type" "alu")
6414   (set_attr "mode" "<MODE>")])
6415
6416(define_insn "*addv<mode>4_1"
6417  [(set (reg:CCO FLAGS_REG)
6418	(eq:CCO (plus:<DWI>
6419		   (sign_extend:<DWI>
6420		      (match_operand:SWI 1 "nonimmediate_operand" "0"))
6421		   (match_operand:<DWI> 3 "const_int_operand" "i"))
6422		(sign_extend:<DWI>
6423		   (plus:SWI (match_dup 1)
6424			     (match_operand:SWI 2 "x86_64_immediate_operand"
6425						  "<i>")))))
6426   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6427	(plus:SWI (match_dup 1) (match_dup 2)))]
6428  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6429   && CONST_INT_P (operands[2])
6430   && INTVAL (operands[2]) == INTVAL (operands[3])"
6431  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6432  [(set_attr "type" "alu")
6433   (set_attr "mode" "<MODE>")
6434   (set (attr "length_immediate")
6435	(cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6436		  (const_string "1")
6437	       (match_test "<MODE_SIZE> == 8")
6438		  (const_string "4")]
6439	      (const_string "<MODE_SIZE>")))])
6440
6441(define_expand "uaddv<mode>4"
6442  [(parallel [(set (reg:CCC FLAGS_REG)
6443		   (compare:CCC
6444		     (plus:SWI
6445		       (match_operand:SWI 1 "nonimmediate_operand")
6446		       (match_operand:SWI 2 "<general_operand>"))
6447		     (match_dup 1)))
6448	      (set (match_operand:SWI 0 "register_operand")
6449		   (plus:SWI (match_dup 1) (match_dup 2)))])
6450   (set (pc) (if_then_else
6451	       (ltu (reg:CCC FLAGS_REG) (const_int 0))
6452	       (label_ref (match_operand 3))
6453	       (pc)))]
6454  ""
6455  "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6456
6457;; The lea patterns for modes less than 32 bits need to be matched by
6458;; several insns converted to real lea by splitters.
6459
6460(define_insn_and_split "*lea<mode>_general_1"
6461  [(set (match_operand:SWI12 0 "register_operand" "=r")
6462	(plus:SWI12
6463	  (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6464		      (match_operand:SWI12 2 "register_operand" "r"))
6465	  (match_operand:SWI12 3 "immediate_operand" "i")))]
6466  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6467  "#"
6468  "&& reload_completed"
6469  [(set (match_dup 0)
6470	(plus:SI
6471	  (plus:SI (match_dup 1) (match_dup 2))
6472	  (match_dup 3)))]
6473{
6474  operands[0] = gen_lowpart (SImode, operands[0]);
6475  operands[1] = gen_lowpart (SImode, operands[1]);
6476  operands[2] = gen_lowpart (SImode, operands[2]);
6477  operands[3] = gen_lowpart (SImode, operands[3]);
6478}
6479  [(set_attr "type" "lea")
6480   (set_attr "mode" "SI")])
6481
6482(define_insn_and_split "*lea<mode>_general_2"
6483  [(set (match_operand:SWI12 0 "register_operand" "=r")
6484	(plus:SWI12
6485	  (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6486		      (match_operand 2 "const248_operand" "n"))
6487	  (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6488  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6489  "#"
6490  "&& reload_completed"
6491  [(set (match_dup 0)
6492	(plus:SI
6493	  (mult:SI (match_dup 1) (match_dup 2))
6494	  (match_dup 3)))]
6495{
6496  operands[0] = gen_lowpart (SImode, operands[0]);
6497  operands[1] = gen_lowpart (SImode, operands[1]);
6498  operands[3] = gen_lowpart (SImode, operands[3]);
6499}
6500  [(set_attr "type" "lea")
6501   (set_attr "mode" "SI")])
6502
6503(define_insn_and_split "*lea<mode>_general_2b"
6504  [(set (match_operand:SWI12 0 "register_operand" "=r")
6505	(plus:SWI12
6506	  (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6507			(match_operand 2 "const123_operand" "n"))
6508	  (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6509  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6510  "#"
6511  "&& reload_completed"
6512  [(set (match_dup 0)
6513	(plus:SI
6514	  (ashift:SI (match_dup 1) (match_dup 2))
6515	  (match_dup 3)))]
6516{
6517  operands[0] = gen_lowpart (SImode, operands[0]);
6518  operands[1] = gen_lowpart (SImode, operands[1]);
6519  operands[3] = gen_lowpart (SImode, operands[3]);
6520}
6521  [(set_attr "type" "lea")
6522   (set_attr "mode" "SI")])
6523
6524(define_insn_and_split "*lea<mode>_general_3"
6525  [(set (match_operand:SWI12 0 "register_operand" "=r")
6526	(plus:SWI12
6527	  (plus:SWI12
6528	    (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6529			(match_operand 2 "const248_operand" "n"))
6530	    (match_operand:SWI12 3 "register_operand" "r"))
6531	  (match_operand:SWI12 4 "immediate_operand" "i")))]
6532  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6533  "#"
6534  "&& reload_completed"
6535  [(set (match_dup 0)
6536	(plus:SI
6537	  (plus:SI
6538	    (mult:SI (match_dup 1) (match_dup 2))
6539	    (match_dup 3))
6540	  (match_dup 4)))]
6541{
6542  operands[0] = gen_lowpart (SImode, operands[0]);
6543  operands[1] = gen_lowpart (SImode, operands[1]);
6544  operands[3] = gen_lowpart (SImode, operands[3]);
6545  operands[4] = gen_lowpart (SImode, operands[4]);
6546}
6547  [(set_attr "type" "lea")
6548   (set_attr "mode" "SI")])
6549
6550(define_insn_and_split "*lea<mode>_general_3b"
6551  [(set (match_operand:SWI12 0 "register_operand" "=r")
6552	(plus:SWI12
6553	  (plus:SWI12
6554	    (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6555			  (match_operand 2 "const123_operand" "n"))
6556	    (match_operand:SWI12 3 "register_operand" "r"))
6557	  (match_operand:SWI12 4 "immediate_operand" "i")))]
6558  "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6559  "#"
6560  "&& reload_completed"
6561  [(set (match_dup 0)
6562	(plus:SI
6563	  (plus:SI
6564	    (ashift:SI (match_dup 1) (match_dup 2))
6565	    (match_dup 3))
6566	  (match_dup 4)))]
6567{
6568  operands[0] = gen_lowpart (SImode, operands[0]);
6569  operands[1] = gen_lowpart (SImode, operands[1]);
6570  operands[3] = gen_lowpart (SImode, operands[3]);
6571  operands[4] = gen_lowpart (SImode, operands[4]);
6572}
6573  [(set_attr "type" "lea")
6574   (set_attr "mode" "SI")])
6575
6576(define_insn_and_split "*lea<mode>_general_4"
6577  [(set (match_operand:SWI12 0 "register_operand" "=r")
6578	(any_or:SWI12
6579	  (ashift:SWI12
6580	    (match_operand:SWI12 1 "index_register_operand" "l")
6581	    (match_operand 2 "const_0_to_3_operand" "n"))
6582	  (match_operand 3 "const_int_operand" "n")))]
6583  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6584   && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6585       < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6586  "#"
6587  "&& reload_completed"
6588  [(set (match_dup 0)
6589	(plus:SI
6590	  (mult:SI (match_dup 1) (match_dup 2))
6591	  (match_dup 3)))]
6592{
6593  operands[0] = gen_lowpart (SImode, operands[0]);
6594  operands[1] = gen_lowpart (SImode, operands[1]);
6595  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6596}
6597  [(set_attr "type" "lea")
6598   (set_attr "mode" "SI")])
6599
6600(define_insn_and_split "*lea<mode>_general_4"
6601  [(set (match_operand:SWI48 0 "register_operand" "=r")
6602	(any_or:SWI48
6603	  (ashift:SWI48
6604	    (match_operand:SWI48 1 "index_register_operand" "l")
6605	    (match_operand 2 "const_0_to_3_operand" "n"))
6606	  (match_operand 3 "const_int_operand" "n")))]
6607  "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6608   < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6609  "#"
6610  "&& reload_completed"
6611  [(set (match_dup 0)
6612	(plus:SWI48
6613	  (mult:SWI48 (match_dup 1) (match_dup 2))
6614	  (match_dup 3)))]
6615  "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6616  [(set_attr "type" "lea")
6617   (set_attr "mode" "<MODE>")])
6618
6619;; Subtract instructions
6620
6621(define_expand "sub<mode>3"
6622  [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6623	(minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6624		     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6625  ""
6626  "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6627
6628(define_insn_and_split "*sub<dwi>3_doubleword"
6629  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6630	(minus:<DWI>
6631	  (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6632	  (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6633							"ro<di>,r<di>")))
6634   (clobber (reg:CC FLAGS_REG))]
6635  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6636  "#"
6637  "reload_completed"
6638  [(parallel [(set (reg:CC FLAGS_REG)
6639		   (compare:CC (match_dup 1) (match_dup 2)))
6640	      (set (match_dup 0)
6641		   (minus:DWIH (match_dup 1) (match_dup 2)))])
6642   (parallel [(set (match_dup 3)
6643		   (minus:DWIH
6644		     (minus:DWIH
6645		       (match_dup 4)
6646		       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6647		     (match_dup 5)))
6648	      (clobber (reg:CC FLAGS_REG))])]
6649{
6650  split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6651  if (operands[2] == const0_rtx)
6652    {
6653      ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6654      DONE;
6655    }
6656})
6657
6658(define_insn "*sub<mode>_1"
6659  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6660	(minus:SWI
6661	  (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6662	  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6663   (clobber (reg:CC FLAGS_REG))]
6664  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6665  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6666  [(set_attr "type" "alu")
6667   (set_attr "mode" "<MODE>")])
6668
6669(define_insn "*subsi_1_zext"
6670  [(set (match_operand:DI 0 "register_operand" "=r")
6671	(zero_extend:DI
6672	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6673		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6674   (clobber (reg:CC FLAGS_REG))]
6675  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6676  "sub{l}\t{%2, %k0|%k0, %2}"
6677  [(set_attr "type" "alu")
6678   (set_attr "mode" "SI")])
6679
6680(define_insn "*subqi_1_slp"
6681  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6682	(minus:QI (match_dup 0)
6683		  (match_operand:QI 1 "general_operand" "qn,qm")))
6684   (clobber (reg:CC FLAGS_REG))]
6685  "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6686   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6687  "sub{b}\t{%1, %0|%0, %1}"
6688  [(set_attr "type" "alu1")
6689   (set_attr "mode" "QI")])
6690
6691(define_insn "*sub<mode>_2"
6692  [(set (reg FLAGS_REG)
6693	(compare
6694	  (minus:SWI
6695	    (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6696	    (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6697	  (const_int 0)))
6698   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6699	(minus:SWI (match_dup 1) (match_dup 2)))]
6700  "ix86_match_ccmode (insn, CCGOCmode)
6701   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6702  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6703  [(set_attr "type" "alu")
6704   (set_attr "mode" "<MODE>")])
6705
6706(define_insn "*subsi_2_zext"
6707  [(set (reg FLAGS_REG)
6708	(compare
6709	  (minus:SI (match_operand:SI 1 "register_operand" "0")
6710		    (match_operand:SI 2 "x86_64_general_operand" "rme"))
6711	  (const_int 0)))
6712   (set (match_operand:DI 0 "register_operand" "=r")
6713	(zero_extend:DI
6714	  (minus:SI (match_dup 1)
6715		    (match_dup 2))))]
6716  "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6717   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6718  "sub{l}\t{%2, %k0|%k0, %2}"
6719  [(set_attr "type" "alu")
6720   (set_attr "mode" "SI")])
6721
6722;; Subtract with jump on overflow.
6723(define_expand "subv<mode>4"
6724  [(parallel [(set (reg:CCO FLAGS_REG)
6725		   (eq:CCO (minus:<DWI>
6726			      (sign_extend:<DWI>
6727				 (match_operand:SWI 1 "nonimmediate_operand"))
6728			      (match_dup 4))
6729			   (sign_extend:<DWI>
6730			      (minus:SWI (match_dup 1)
6731					 (match_operand:SWI 2
6732					    "<general_operand>")))))
6733	      (set (match_operand:SWI 0 "register_operand")
6734		   (minus:SWI (match_dup 1) (match_dup 2)))])
6735   (set (pc) (if_then_else
6736	       (eq (reg:CCO FLAGS_REG) (const_int 0))
6737	       (label_ref (match_operand 3))
6738	       (pc)))]
6739  ""
6740{
6741  ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6742  if (CONST_INT_P (operands[2]))
6743    operands[4] = operands[2];
6744  else
6745    operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6746})
6747
6748(define_insn "*subv<mode>4"
6749  [(set (reg:CCO FLAGS_REG)
6750	(eq:CCO (minus:<DWI>
6751		   (sign_extend:<DWI>
6752		      (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6753		   (sign_extend:<DWI>
6754		      (match_operand:SWI 2 "<general_sext_operand>"
6755					   "<r>We,<r>m")))
6756		(sign_extend:<DWI>
6757		   (minus:SWI (match_dup 1) (match_dup 2)))))
6758   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6759	(minus:SWI (match_dup 1) (match_dup 2)))]
6760  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6761  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6762  [(set_attr "type" "alu")
6763   (set_attr "mode" "<MODE>")])
6764
6765(define_insn "*subv<mode>4_1"
6766  [(set (reg:CCO FLAGS_REG)
6767	(eq:CCO (minus:<DWI>
6768		   (sign_extend:<DWI>
6769		      (match_operand:SWI 1 "nonimmediate_operand" "0"))
6770		   (match_operand:<DWI> 3 "const_int_operand" "i"))
6771		(sign_extend:<DWI>
6772		   (minus:SWI (match_dup 1)
6773			      (match_operand:SWI 2 "x86_64_immediate_operand"
6774						   "<i>")))))
6775   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6776	(minus:SWI (match_dup 1) (match_dup 2)))]
6777  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6778   && CONST_INT_P (operands[2])
6779   && INTVAL (operands[2]) == INTVAL (operands[3])"
6780  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6781  [(set_attr "type" "alu")
6782   (set_attr "mode" "<MODE>")
6783   (set (attr "length_immediate")
6784	(cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6785		  (const_string "1")
6786	       (match_test "<MODE_SIZE> == 8")
6787		  (const_string "4")]
6788	      (const_string "<MODE_SIZE>")))])
6789
6790(define_expand "usubv<mode>4"
6791  [(parallel [(set (reg:CC FLAGS_REG)
6792		   (compare:CC
6793		     (match_operand:SWI 1 "nonimmediate_operand")
6794		     (match_operand:SWI 2 "<general_operand>")))
6795	      (set (match_operand:SWI 0 "register_operand")
6796		   (minus:SWI (match_dup 1) (match_dup 2)))])
6797   (set (pc) (if_then_else
6798	       (ltu (reg:CC FLAGS_REG) (const_int 0))
6799	       (label_ref (match_operand 3))
6800	       (pc)))]
6801  ""
6802  "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6803
6804(define_insn "*sub<mode>_3"
6805  [(set (reg FLAGS_REG)
6806	(compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6807		 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6808   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6809	(minus:SWI (match_dup 1) (match_dup 2)))]
6810  "ix86_match_ccmode (insn, CCmode)
6811   && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6812  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6813  [(set_attr "type" "alu")
6814   (set_attr "mode" "<MODE>")])
6815
6816(define_peephole2
6817  [(parallel
6818     [(set (reg:CC FLAGS_REG)
6819	   (compare:CC (match_operand:SWI 0 "general_reg_operand")
6820		       (match_operand:SWI 1 "general_gr_operand")))
6821      (set (match_dup 0)
6822	   (minus:SWI (match_dup 0) (match_dup 1)))])]
6823  "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6824  [(set (reg:CC FLAGS_REG)
6825	(compare:CC (match_dup 0) (match_dup 1)))])
6826
6827(define_insn "*subsi_3_zext"
6828  [(set (reg FLAGS_REG)
6829	(compare (match_operand:SI 1 "register_operand" "0")
6830		 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6831   (set (match_operand:DI 0 "register_operand" "=r")
6832	(zero_extend:DI
6833	  (minus:SI (match_dup 1)
6834		    (match_dup 2))))]
6835  "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6836   && ix86_binary_operator_ok (MINUS, SImode, operands)"
6837  "sub{l}\t{%2, %1|%1, %2}"
6838  [(set_attr "type" "alu")
6839   (set_attr "mode" "SI")])
6840
6841;; Add with carry and subtract with borrow
6842
6843(define_insn "add<mode>3_carry"
6844  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6845	(plus:SWI
6846	  (plus:SWI
6847	    (match_operator:SWI 4 "ix86_carry_flag_operator"
6848	     [(match_operand 3 "flags_reg_operand") (const_int 0)])
6849	    (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6850	  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6851   (clobber (reg:CC FLAGS_REG))]
6852  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6853  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6854  [(set_attr "type" "alu")
6855   (set_attr "use_carry" "1")
6856   (set_attr "pent_pair" "pu")
6857   (set_attr "mode" "<MODE>")])
6858
6859(define_insn "*add<mode>3_carry_0"
6860  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6861	(plus:SWI
6862	  (match_operator:SWI 3 "ix86_carry_flag_operator"
6863	    [(match_operand 2 "flags_reg_operand") (const_int 0)])
6864	  (match_operand:SWI 1 "nonimmediate_operand" "0")))
6865   (clobber (reg:CC FLAGS_REG))]
6866  "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6867  "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6868  [(set_attr "type" "alu")
6869   (set_attr "use_carry" "1")
6870   (set_attr "pent_pair" "pu")
6871   (set_attr "mode" "<MODE>")])
6872
6873(define_insn "*addsi3_carry_zext"
6874  [(set (match_operand:DI 0 "register_operand" "=r")
6875	(zero_extend:DI
6876	  (plus:SI
6877	    (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6878		      [(reg FLAGS_REG) (const_int 0)])
6879		     (match_operand:SI 1 "register_operand" "%0"))
6880	    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6881   (clobber (reg:CC FLAGS_REG))]
6882  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6883  "adc{l}\t{%2, %k0|%k0, %2}"
6884  [(set_attr "type" "alu")
6885   (set_attr "use_carry" "1")
6886   (set_attr "pent_pair" "pu")
6887   (set_attr "mode" "SI")])
6888
6889(define_insn "*addsi3_carry_zext_0"
6890  [(set (match_operand:DI 0 "register_operand" "=r")
6891	(zero_extend:DI
6892	  (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6893		    [(reg FLAGS_REG) (const_int 0)])
6894		   (match_operand:SI 1 "register_operand" "0"))))
6895   (clobber (reg:CC FLAGS_REG))]
6896  "TARGET_64BIT"
6897  "adc{l}\t{$0, %k0|%k0, 0}"
6898  [(set_attr "type" "alu")
6899   (set_attr "use_carry" "1")
6900   (set_attr "pent_pair" "pu")
6901   (set_attr "mode" "SI")])
6902
6903;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6904
6905(define_insn "addcarry<mode>"
6906  [(set (reg:CCC FLAGS_REG)
6907	(compare:CCC
6908	  (zero_extend:<DWI>
6909	    (plus:SWI48
6910	      (plus:SWI48
6911		(match_operator:SWI48 5 "ix86_carry_flag_operator"
6912		  [(match_operand 3 "flags_reg_operand") (const_int 0)])
6913		(match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6914	      (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6915	  (plus:<DWI>
6916	    (zero_extend:<DWI> (match_dup 2))
6917	    (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6918	      [(match_dup 3) (const_int 0)]))))
6919   (set (match_operand:SWI48 0 "register_operand" "=r")
6920	(plus:SWI48 (plus:SWI48 (match_op_dup 5
6921				 [(match_dup 3) (const_int 0)])
6922				(match_dup 1))
6923		    (match_dup 2)))]
6924  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6925  "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6926  [(set_attr "type" "alu")
6927   (set_attr "use_carry" "1")
6928   (set_attr "pent_pair" "pu")
6929   (set_attr "mode" "<MODE>")])
6930
6931(define_expand "addcarry<mode>_0"
6932  [(parallel
6933     [(set (reg:CCC FLAGS_REG)
6934	   (compare:CCC
6935	     (plus:SWI48
6936	       (match_operand:SWI48 1 "nonimmediate_operand")
6937	       (match_operand:SWI48 2 "x86_64_general_operand"))
6938	     (match_dup 1)))
6939      (set (match_operand:SWI48 0 "register_operand")
6940	   (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6941  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6942
6943(define_insn "sub<mode>3_carry"
6944  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6945	(minus:SWI
6946	  (minus:SWI
6947	    (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6948	    (match_operator:SWI 4 "ix86_carry_flag_operator"
6949	     [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6950	  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6951   (clobber (reg:CC FLAGS_REG))]
6952  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6953  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6954  [(set_attr "type" "alu")
6955   (set_attr "use_carry" "1")
6956   (set_attr "pent_pair" "pu")
6957   (set_attr "mode" "<MODE>")])
6958
6959(define_insn "*sub<mode>3_carry_0"
6960  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6961	(minus:SWI
6962	  (match_operand:SWI 1 "nonimmediate_operand" "0")
6963	  (match_operator:SWI 3 "ix86_carry_flag_operator"
6964	    [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6965   (clobber (reg:CC FLAGS_REG))]
6966  "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6967  "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6968  [(set_attr "type" "alu")
6969   (set_attr "use_carry" "1")
6970   (set_attr "pent_pair" "pu")
6971   (set_attr "mode" "<MODE>")])
6972
6973(define_insn "*subsi3_carry_zext"
6974  [(set (match_operand:DI 0 "register_operand" "=r")
6975	(zero_extend:DI
6976	  (minus:SI
6977	    (minus:SI
6978	      (match_operand:SI 1 "register_operand" "0")
6979	      (match_operator:SI 3 "ix86_carry_flag_operator"
6980	       [(reg FLAGS_REG) (const_int 0)]))
6981	    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6982   (clobber (reg:CC FLAGS_REG))]
6983  "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6984  "sbb{l}\t{%2, %k0|%k0, %2}"
6985  [(set_attr "type" "alu")
6986   (set_attr "use_carry" "1")
6987   (set_attr "pent_pair" "pu")
6988   (set_attr "mode" "SI")])
6989
6990(define_insn "*subsi3_carry_zext_0"
6991  [(set (match_operand:DI 0 "register_operand" "=r")
6992	(zero_extend:DI
6993	  (minus:SI
6994	    (match_operand:SI 1 "register_operand" "0")
6995	    (match_operator:SI 2 "ix86_carry_flag_operator"
6996	      [(reg FLAGS_REG) (const_int 0)]))))
6997   (clobber (reg:CC FLAGS_REG))]
6998  "TARGET_64BIT"
6999  "sbb{l}\t{$0, %k0|%k0, 0}"
7000  [(set_attr "type" "alu")
7001   (set_attr "use_carry" "1")
7002   (set_attr "pent_pair" "pu")
7003   (set_attr "mode" "SI")])
7004
7005(define_insn "sub<mode>3_carry_ccc"
7006  [(set (reg:CCC FLAGS_REG)
7007	(compare:CCC
7008	  (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7009	  (plus:<DWI>
7010	    (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7011	    (zero_extend:<DWI>
7012	      (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
7013   (clobber (match_scratch:DWIH 0 "=r"))]
7014  ""
7015  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7016  [(set_attr "type" "alu")
7017   (set_attr "mode" "<MODE>")])
7018
7019(define_insn "*sub<mode>3_carry_ccc_1"
7020  [(set (reg:CCC FLAGS_REG)
7021	(compare:CCC
7022	  (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7023	  (plus:<DWI>
7024	    (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7025	    (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7026   (clobber (match_scratch:DWIH 0 "=r"))]
7027  ""
7028{
7029  operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7030  return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7031}
7032  [(set_attr "type" "alu")
7033   (set_attr "mode" "<MODE>")])
7034
7035;; The sign flag is set from the
7036;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7037;; result, the overflow flag likewise, but the overflow flag is also
7038;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7039(define_insn "sub<mode>3_carry_ccgz"
7040  [(set (reg:CCGZ FLAGS_REG)
7041	(unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7042		      (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7043		      (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7044		     UNSPEC_SBB))
7045   (clobber (match_scratch:DWIH 0 "=r"))]
7046  ""
7047  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7048  [(set_attr "type" "alu")
7049   (set_attr "mode" "<MODE>")])
7050
7051(define_insn "subborrow<mode>"
7052  [(set (reg:CCC FLAGS_REG)
7053	(compare:CCC
7054	  (zero_extend:<DWI>
7055	    (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7056	  (plus:<DWI>
7057	    (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7058	      [(match_operand 3 "flags_reg_operand") (const_int 0)])
7059	    (zero_extend:<DWI>
7060	      (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7061   (set (match_operand:SWI48 0 "register_operand" "=r")
7062	(minus:SWI48 (minus:SWI48
7063		       (match_dup 1)
7064		       (match_operator:SWI48 5 "ix86_carry_flag_operator"
7065			 [(match_dup 3) (const_int 0)]))
7066		     (match_dup 2)))]
7067  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7068  "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7069  [(set_attr "type" "alu")
7070   (set_attr "use_carry" "1")
7071   (set_attr "pent_pair" "pu")
7072   (set_attr "mode" "<MODE>")])
7073
7074(define_expand "subborrow<mode>_0"
7075  [(parallel
7076     [(set (reg:CC FLAGS_REG)
7077	   (compare:CC
7078	     (match_operand:SWI48 1 "nonimmediate_operand")
7079	     (match_operand:SWI48 2 "<general_operand>")))
7080      (set (match_operand:SWI48 0 "register_operand")
7081	   (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7082  "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7083
7084;; Overflow setting add instructions
7085
7086(define_expand "addqi3_cconly_overflow"
7087  [(parallel
7088     [(set (reg:CCC FLAGS_REG)
7089	   (compare:CCC
7090	     (plus:QI
7091	       (match_operand:QI 0 "nonimmediate_operand")
7092	       (match_operand:QI 1 "general_operand"))
7093	     (match_dup 0)))
7094      (clobber (match_scratch:QI 2))])]
7095  "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7096
7097(define_insn "*add<mode>3_cconly_overflow_1"
7098  [(set (reg:CCC FLAGS_REG)
7099	(compare:CCC
7100	  (plus:SWI
7101	    (match_operand:SWI 1 "nonimmediate_operand" "%0")
7102	    (match_operand:SWI 2 "<general_operand>" "<g>"))
7103	  (match_dup 1)))
7104   (clobber (match_scratch:SWI 0 "=<r>"))]
7105  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7106  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7107  [(set_attr "type" "alu")
7108   (set_attr "mode" "<MODE>")])
7109
7110(define_insn "*add<mode>3_cc_overflow_1"
7111  [(set (reg:CCC FLAGS_REG)
7112	(compare:CCC
7113	    (plus:SWI
7114		(match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7115		(match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7116	    (match_dup 1)))
7117   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7118	(plus:SWI (match_dup 1) (match_dup 2)))]
7119  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7120  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7121  [(set_attr "type" "alu")
7122   (set_attr "mode" "<MODE>")])
7123
7124(define_insn "*addsi3_zext_cc_overflow_1"
7125  [(set (reg:CCC FLAGS_REG)
7126	(compare:CCC
7127	  (plus:SI
7128	    (match_operand:SI 1 "nonimmediate_operand" "%0")
7129	    (match_operand:SI 2 "x86_64_general_operand" "rme"))
7130	  (match_dup 1)))
7131   (set (match_operand:DI 0 "register_operand" "=r")
7132	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7133  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7134  "add{l}\t{%2, %k0|%k0, %2}"
7135  [(set_attr "type" "alu")
7136   (set_attr "mode" "SI")])
7137
7138(define_insn "*add<mode>3_cconly_overflow_2"
7139  [(set (reg:CCC FLAGS_REG)
7140	(compare:CCC
7141	  (plus:SWI
7142	    (match_operand:SWI 1 "nonimmediate_operand" "%0")
7143	    (match_operand:SWI 2 "<general_operand>" "<g>"))
7144	  (match_dup 2)))
7145   (clobber (match_scratch:SWI 0 "=<r>"))]
7146  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7147  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7148  [(set_attr "type" "alu")
7149   (set_attr "mode" "<MODE>")])
7150
7151(define_insn "*add<mode>3_cc_overflow_2"
7152  [(set (reg:CCC FLAGS_REG)
7153	(compare:CCC
7154	    (plus:SWI
7155		(match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7156		(match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7157	    (match_dup 2)))
7158   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7159	(plus:SWI (match_dup 1) (match_dup 2)))]
7160  "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7161  "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7162  [(set_attr "type" "alu")
7163   (set_attr "mode" "<MODE>")])
7164
7165(define_insn "*addsi3_zext_cc_overflow_2"
7166  [(set (reg:CCC FLAGS_REG)
7167	(compare:CCC
7168	  (plus:SI
7169	    (match_operand:SI 1 "nonimmediate_operand" "%0")
7170	    (match_operand:SI 2 "x86_64_general_operand" "rme"))
7171	  (match_dup 2)))
7172   (set (match_operand:DI 0 "register_operand" "=r")
7173	(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7174  "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7175  "add{l}\t{%2, %k0|%k0, %2}"
7176  [(set_attr "type" "alu")
7177   (set_attr "mode" "SI")])
7178
7179;; The patterns that match these are at the end of this file.
7180
7181(define_expand "<plusminus_insn>xf3"
7182  [(set (match_operand:XF 0 "register_operand")
7183	(plusminus:XF
7184	  (match_operand:XF 1 "register_operand")
7185	  (match_operand:XF 2 "register_operand")))]
7186  "TARGET_80387")
7187
7188(define_expand "<plusminus_insn><mode>3"
7189  [(set (match_operand:MODEF 0 "register_operand")
7190	(plusminus:MODEF
7191	  (match_operand:MODEF 1 "register_operand")
7192	  (match_operand:MODEF 2 "nonimmediate_operand")))]
7193  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7194    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7195
7196;; Multiply instructions
7197
7198(define_expand "mul<mode>3"
7199  [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7200		   (mult:SWIM248
7201		     (match_operand:SWIM248 1 "register_operand")
7202		     (match_operand:SWIM248 2 "<general_operand>")))
7203	      (clobber (reg:CC FLAGS_REG))])])
7204
7205(define_expand "mulqi3"
7206  [(parallel [(set (match_operand:QI 0 "register_operand")
7207		   (mult:QI
7208		     (match_operand:QI 1 "register_operand")
7209		     (match_operand:QI 2 "nonimmediate_operand")))
7210	      (clobber (reg:CC FLAGS_REG))])]
7211  "TARGET_QIMODE_MATH")
7212
7213;; On AMDFAM10
7214;; IMUL reg32/64, reg32/64, imm8 	Direct
7215;; IMUL reg32/64, mem32/64, imm8 	VectorPath
7216;; IMUL reg32/64, reg32/64, imm32 	Direct
7217;; IMUL reg32/64, mem32/64, imm32 	VectorPath
7218;; IMUL reg32/64, reg32/64 		Direct
7219;; IMUL reg32/64, mem32/64 		Direct
7220;;
7221;; On BDVER1, all above IMULs use DirectPath
7222;;
7223;; On AMDFAM10
7224;; IMUL reg16, reg16, imm8 	VectorPath
7225;; IMUL reg16, mem16, imm8 	VectorPath
7226;; IMUL reg16, reg16, imm16 	VectorPath
7227;; IMUL reg16, mem16, imm16 	VectorPath
7228;; IMUL reg16, reg16 		Direct
7229;; IMUL reg16, mem16 		Direct
7230;;
7231;; On BDVER1, all HI MULs use DoublePath
7232
7233(define_insn "*mul<mode>3_1"
7234  [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7235	(mult:SWIM248
7236	  (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7237	  (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7238   (clobber (reg:CC FLAGS_REG))]
7239  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7240  "@
7241   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7242   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7243   imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7244  [(set_attr "type" "imul")
7245   (set_attr "prefix_0f" "0,0,1")
7246   (set (attr "athlon_decode")
7247	(cond [(eq_attr "cpu" "athlon")
7248		  (const_string "vector")
7249	       (eq_attr "alternative" "1")
7250		  (const_string "vector")
7251	       (and (eq_attr "alternative" "2")
7252	       	    (ior (match_test "<MODE>mode == HImode")
7253		         (match_operand 1 "memory_operand")))
7254		  (const_string "vector")]
7255	      (const_string "direct")))
7256   (set (attr "amdfam10_decode")
7257	(cond [(and (eq_attr "alternative" "0,1")
7258	      	    (ior (match_test "<MODE>mode == HImode")
7259		         (match_operand 1 "memory_operand")))
7260		  (const_string "vector")]
7261	      (const_string "direct")))
7262   (set (attr "bdver1_decode")
7263   	(if_then_else
7264	  (match_test "<MODE>mode == HImode")
7265	    (const_string "double")
7266	    (const_string "direct")))
7267   (set_attr "mode" "<MODE>")])
7268
7269(define_insn "*mulsi3_1_zext"
7270  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7271	(zero_extend:DI
7272	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7273		   (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7274   (clobber (reg:CC FLAGS_REG))]
7275  "TARGET_64BIT
7276   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7277  "@
7278   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7279   imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7280   imul{l}\t{%2, %k0|%k0, %2}"
7281  [(set_attr "type" "imul")
7282   (set_attr "prefix_0f" "0,0,1")
7283   (set (attr "athlon_decode")
7284	(cond [(eq_attr "cpu" "athlon")
7285		  (const_string "vector")
7286	       (eq_attr "alternative" "1")
7287		  (const_string "vector")
7288	       (and (eq_attr "alternative" "2")
7289		    (match_operand 1 "memory_operand"))
7290		  (const_string "vector")]
7291	      (const_string "direct")))
7292   (set (attr "amdfam10_decode")
7293	(cond [(and (eq_attr "alternative" "0,1")
7294		    (match_operand 1 "memory_operand"))
7295		  (const_string "vector")]
7296	      (const_string "direct")))
7297   (set_attr "bdver1_decode" "direct")
7298   (set_attr "mode" "SI")])
7299
7300;;On AMDFAM10 and BDVER1
7301;; MUL reg8 	Direct
7302;; MUL mem8 	Direct
7303
7304(define_insn "*mulqi3_1"
7305  [(set (match_operand:QI 0 "register_operand" "=a")
7306	(mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7307		 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7308   (clobber (reg:CC FLAGS_REG))]
7309  "TARGET_QIMODE_MATH
7310   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7311  "mul{b}\t%2"
7312  [(set_attr "type" "imul")
7313   (set_attr "length_immediate" "0")
7314   (set (attr "athlon_decode")
7315     (if_then_else (eq_attr "cpu" "athlon")
7316        (const_string "vector")
7317        (const_string "direct")))
7318   (set_attr "amdfam10_decode" "direct")
7319   (set_attr "bdver1_decode" "direct")
7320   (set_attr "mode" "QI")])
7321
7322;; Multiply with jump on overflow.
7323(define_expand "mulv<mode>4"
7324  [(parallel [(set (reg:CCO FLAGS_REG)
7325		   (eq:CCO (mult:<DWI>
7326			      (sign_extend:<DWI>
7327				 (match_operand:SWI248 1 "register_operand"))
7328			      (match_dup 4))
7329			   (sign_extend:<DWI>
7330			      (mult:SWI248 (match_dup 1)
7331					   (match_operand:SWI248 2
7332					      "<general_operand>")))))
7333	      (set (match_operand:SWI248 0 "register_operand")
7334		   (mult:SWI248 (match_dup 1) (match_dup 2)))])
7335   (set (pc) (if_then_else
7336	       (eq (reg:CCO FLAGS_REG) (const_int 0))
7337	       (label_ref (match_operand 3))
7338	       (pc)))]
7339  ""
7340{
7341  if (CONST_INT_P (operands[2]))
7342    operands[4] = operands[2];
7343  else
7344    operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7345})
7346
7347(define_insn "*mulv<mode>4"
7348  [(set (reg:CCO FLAGS_REG)
7349	(eq:CCO (mult:<DWI>
7350		   (sign_extend:<DWI>
7351		      (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7352		   (sign_extend:<DWI>
7353		      (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7354		(sign_extend:<DWI>
7355		   (mult:SWI48 (match_dup 1) (match_dup 2)))))
7356   (set (match_operand:SWI48 0 "register_operand" "=r,r")
7357	(mult:SWI48 (match_dup 1) (match_dup 2)))]
7358  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7359  "@
7360   imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7361   imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7362  [(set_attr "type" "imul")
7363   (set_attr "prefix_0f" "0,1")
7364   (set (attr "athlon_decode")
7365	(cond [(eq_attr "cpu" "athlon")
7366		  (const_string "vector")
7367	       (eq_attr "alternative" "0")
7368		  (const_string "vector")
7369	       (and (eq_attr "alternative" "1")
7370		    (match_operand 1 "memory_operand"))
7371		  (const_string "vector")]
7372	      (const_string "direct")))
7373   (set (attr "amdfam10_decode")
7374	(cond [(and (eq_attr "alternative" "1")
7375		    (match_operand 1 "memory_operand"))
7376		  (const_string "vector")]
7377	      (const_string "direct")))
7378   (set_attr "bdver1_decode" "direct")
7379   (set_attr "mode" "<MODE>")])
7380
7381(define_insn "*mulvhi4"
7382  [(set (reg:CCO FLAGS_REG)
7383	(eq:CCO (mult:SI
7384		   (sign_extend:SI
7385		      (match_operand:HI 1 "nonimmediate_operand" "%0"))
7386		   (sign_extend:SI
7387		      (match_operand:HI 2 "nonimmediate_operand" "mr")))
7388		(sign_extend:SI
7389		   (mult:HI (match_dup 1) (match_dup 2)))))
7390   (set (match_operand:HI 0 "register_operand" "=r")
7391	(mult:HI (match_dup 1) (match_dup 2)))]
7392  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7393  "imul{w}\t{%2, %0|%0, %2}"
7394  [(set_attr "type" "imul")
7395   (set_attr "prefix_0f" "1")
7396   (set_attr "athlon_decode" "vector")
7397   (set_attr "amdfam10_decode" "direct")
7398   (set_attr "bdver1_decode" "double")
7399   (set_attr "mode" "HI")])
7400
7401(define_insn "*mulv<mode>4_1"
7402  [(set (reg:CCO FLAGS_REG)
7403	(eq:CCO (mult:<DWI>
7404		   (sign_extend:<DWI>
7405		      (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7406		   (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7407		(sign_extend:<DWI>
7408		   (mult:SWI248 (match_dup 1)
7409				(match_operand:SWI248 2
7410				   "<immediate_operand>" "K,<i>")))))
7411   (set (match_operand:SWI248 0 "register_operand" "=r,r")
7412	(mult:SWI248 (match_dup 1) (match_dup 2)))]
7413  "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7414   && CONST_INT_P (operands[2])
7415   && INTVAL (operands[2]) == INTVAL (operands[3])"
7416  "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7417  [(set_attr "type" "imul")
7418   (set (attr "prefix_0f")
7419   	(if_then_else
7420	  (match_test "<MODE>mode == HImode")
7421	    (const_string "0")
7422	    (const_string "*")))
7423   (set (attr "athlon_decode")
7424	(cond [(eq_attr "cpu" "athlon")
7425		  (const_string "vector")
7426	       (eq_attr "alternative" "1")
7427		  (const_string "vector")]
7428	      (const_string "direct")))
7429   (set (attr "amdfam10_decode")
7430	(cond [(ior (match_test "<MODE>mode == HImode")
7431		    (match_operand 1 "memory_operand"))
7432		  (const_string "vector")]
7433	      (const_string "direct")))
7434   (set (attr "bdver1_decode")
7435   	(if_then_else
7436	  (match_test "<MODE>mode == HImode")
7437	    (const_string "double")
7438	    (const_string "direct")))
7439   (set_attr "mode" "<MODE>")
7440   (set (attr "length_immediate")
7441	(cond [(eq_attr "alternative" "0")
7442		  (const_string "1")
7443	       (match_test "<MODE_SIZE> == 8")
7444		  (const_string "4")]
7445	      (const_string "<MODE_SIZE>")))])
7446
7447(define_expand "umulv<mode>4"
7448  [(parallel [(set (reg:CCO FLAGS_REG)
7449		   (eq:CCO (mult:<DWI>
7450			      (zero_extend:<DWI>
7451				 (match_operand:SWI248 1
7452						      "nonimmediate_operand"))
7453			      (zero_extend:<DWI>
7454				 (match_operand:SWI248 2
7455						      "nonimmediate_operand")))
7456			   (zero_extend:<DWI>
7457			      (mult:SWI248 (match_dup 1) (match_dup 2)))))
7458	      (set (match_operand:SWI248 0 "register_operand")
7459		   (mult:SWI248 (match_dup 1) (match_dup 2)))
7460	      (clobber (match_scratch:SWI248 4))])
7461   (set (pc) (if_then_else
7462	       (eq (reg:CCO FLAGS_REG) (const_int 0))
7463	       (label_ref (match_operand 3))
7464	       (pc)))]
7465  ""
7466{
7467  if (MEM_P (operands[1]) && MEM_P (operands[2]))
7468    operands[1] = force_reg (<MODE>mode, operands[1]);
7469})
7470
7471(define_insn "*umulv<mode>4"
7472  [(set (reg:CCO FLAGS_REG)
7473	(eq:CCO (mult:<DWI>
7474		   (zero_extend:<DWI>
7475		      (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7476		   (zero_extend:<DWI>
7477		      (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7478		(zero_extend:<DWI>
7479		   (mult:SWI248 (match_dup 1) (match_dup 2)))))
7480   (set (match_operand:SWI248 0 "register_operand" "=a")
7481	(mult:SWI248 (match_dup 1) (match_dup 2)))
7482   (clobber (match_scratch:SWI248 3 "=d"))]
7483  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7484  "mul{<imodesuffix>}\t%2"
7485  [(set_attr "type" "imul")
7486   (set_attr "length_immediate" "0")
7487   (set (attr "athlon_decode")
7488     (if_then_else (eq_attr "cpu" "athlon")
7489       (const_string "vector")
7490       (const_string "double")))
7491   (set_attr "amdfam10_decode" "double")
7492   (set_attr "bdver1_decode" "direct")
7493   (set_attr "mode" "<MODE>")])
7494
7495(define_expand "<u>mulvqi4"
7496  [(parallel [(set (reg:CCO FLAGS_REG)
7497		   (eq:CCO (mult:HI
7498			      (any_extend:HI
7499				 (match_operand:QI 1 "nonimmediate_operand"))
7500			      (any_extend:HI
7501				 (match_operand:QI 2 "nonimmediate_operand")))
7502			   (any_extend:HI
7503			      (mult:QI (match_dup 1) (match_dup 2)))))
7504	      (set (match_operand:QI 0 "register_operand")
7505		   (mult:QI (match_dup 1) (match_dup 2)))])
7506   (set (pc) (if_then_else
7507	       (eq (reg:CCO FLAGS_REG) (const_int 0))
7508	       (label_ref (match_operand 3))
7509	       (pc)))]
7510  "TARGET_QIMODE_MATH"
7511{
7512  if (MEM_P (operands[1]) && MEM_P (operands[2]))
7513    operands[1] = force_reg (QImode, operands[1]);
7514})
7515
7516(define_insn "*<u>mulvqi4"
7517  [(set (reg:CCO FLAGS_REG)
7518	(eq:CCO (mult:HI
7519		   (any_extend:HI
7520		      (match_operand:QI 1 "nonimmediate_operand" "%0"))
7521		   (any_extend:HI
7522		      (match_operand:QI 2 "nonimmediate_operand" "qm")))
7523		(any_extend:HI
7524		   (mult:QI (match_dup 1) (match_dup 2)))))
7525   (set (match_operand:QI 0 "register_operand" "=a")
7526	(mult:QI (match_dup 1) (match_dup 2)))]
7527  "TARGET_QIMODE_MATH
7528   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7529  "<sgnprefix>mul{b}\t%2"
7530  [(set_attr "type" "imul")
7531   (set_attr "length_immediate" "0")
7532   (set (attr "athlon_decode")
7533     (if_then_else (eq_attr "cpu" "athlon")
7534	(const_string "vector")
7535	(const_string "direct")))
7536   (set_attr "amdfam10_decode" "direct")
7537   (set_attr "bdver1_decode" "direct")
7538   (set_attr "mode" "QI")])
7539
7540(define_expand "<u>mul<mode><dwi>3"
7541  [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7542		   (mult:<DWI>
7543		     (any_extend:<DWI>
7544		       (match_operand:DWIH 1 "nonimmediate_operand"))
7545		     (any_extend:<DWI>
7546		       (match_operand:DWIH 2 "register_operand"))))
7547	      (clobber (reg:CC FLAGS_REG))])])
7548
7549(define_expand "<u>mulqihi3"
7550  [(parallel [(set (match_operand:HI 0 "register_operand")
7551		   (mult:HI
7552		     (any_extend:HI
7553		       (match_operand:QI 1 "nonimmediate_operand"))
7554		     (any_extend:HI
7555		       (match_operand:QI 2 "register_operand"))))
7556	      (clobber (reg:CC FLAGS_REG))])]
7557  "TARGET_QIMODE_MATH")
7558
7559(define_insn "*bmi2_umul<mode><dwi>3_1"
7560  [(set (match_operand:DWIH 0 "register_operand" "=r")
7561	(mult:DWIH
7562	  (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7563	  (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7564   (set (match_operand:DWIH 1 "register_operand" "=r")
7565	(truncate:DWIH
7566	  (lshiftrt:<DWI>
7567	    (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7568			(zero_extend:<DWI> (match_dup 3)))
7569	    (match_operand:QI 4 "const_int_operand" "n"))))]
7570  "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7571   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7572  "mulx\t{%3, %0, %1|%1, %0, %3}"
7573  [(set_attr "type" "imulx")
7574   (set_attr "prefix" "vex")
7575   (set_attr "mode" "<MODE>")])
7576
7577(define_insn "*umul<mode><dwi>3_1"
7578  [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7579	(mult:<DWI>
7580	  (zero_extend:<DWI>
7581	    (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7582	  (zero_extend:<DWI>
7583	    (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7584   (clobber (reg:CC FLAGS_REG))]
7585  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7586  "@
7587   #
7588   mul{<imodesuffix>}\t%2"
7589  [(set_attr "isa" "bmi2,*")
7590   (set_attr "type" "imulx,imul")
7591   (set_attr "length_immediate" "*,0")
7592   (set (attr "athlon_decode")
7593	(cond [(eq_attr "alternative" "1")
7594		 (if_then_else (eq_attr "cpu" "athlon")
7595		   (const_string "vector")
7596		   (const_string "double"))]
7597	      (const_string "*")))
7598   (set_attr "amdfam10_decode" "*,double")
7599   (set_attr "bdver1_decode" "*,direct")
7600   (set_attr "prefix" "vex,orig")
7601   (set_attr "mode" "<MODE>")])
7602
7603;; Convert mul to the mulx pattern to avoid flags dependency.
7604(define_split
7605 [(set (match_operand:<DWI> 0 "register_operand")
7606       (mult:<DWI>
7607	 (zero_extend:<DWI>
7608	   (match_operand:DWIH 1 "register_operand"))
7609	 (zero_extend:<DWI>
7610	   (match_operand:DWIH 2 "nonimmediate_operand"))))
7611  (clobber (reg:CC FLAGS_REG))]
7612 "TARGET_BMI2 && reload_completed
7613  && REGNO (operands[1]) == DX_REG"
7614  [(parallel [(set (match_dup 3)
7615		   (mult:DWIH (match_dup 1) (match_dup 2)))
7616	      (set (match_dup 4)
7617		   (truncate:DWIH
7618		     (lshiftrt:<DWI>
7619		       (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7620				   (zero_extend:<DWI> (match_dup 2)))
7621		       (match_dup 5))))])]
7622{
7623  split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7624
7625  operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7626})
7627
7628(define_insn "*mul<mode><dwi>3_1"
7629  [(set (match_operand:<DWI> 0 "register_operand" "=A")
7630	(mult:<DWI>
7631	  (sign_extend:<DWI>
7632	    (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7633	  (sign_extend:<DWI>
7634	    (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7635   (clobber (reg:CC FLAGS_REG))]
7636  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7637  "imul{<imodesuffix>}\t%2"
7638  [(set_attr "type" "imul")
7639   (set_attr "length_immediate" "0")
7640   (set (attr "athlon_decode")
7641     (if_then_else (eq_attr "cpu" "athlon")
7642        (const_string "vector")
7643        (const_string "double")))
7644   (set_attr "amdfam10_decode" "double")
7645   (set_attr "bdver1_decode" "direct")
7646   (set_attr "mode" "<MODE>")])
7647
7648(define_insn "*<u>mulqihi3_1"
7649  [(set (match_operand:HI 0 "register_operand" "=a")
7650	(mult:HI
7651	  (any_extend:HI
7652	    (match_operand:QI 1 "nonimmediate_operand" "%0"))
7653	  (any_extend:HI
7654	    (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7655   (clobber (reg:CC FLAGS_REG))]
7656  "TARGET_QIMODE_MATH
7657   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7658  "<sgnprefix>mul{b}\t%2"
7659  [(set_attr "type" "imul")
7660   (set_attr "length_immediate" "0")
7661   (set (attr "athlon_decode")
7662     (if_then_else (eq_attr "cpu" "athlon")
7663        (const_string "vector")
7664        (const_string "direct")))
7665   (set_attr "amdfam10_decode" "direct")
7666   (set_attr "bdver1_decode" "direct")
7667   (set_attr "mode" "QI")])
7668
7669(define_expand "<s>mul<mode>3_highpart"
7670  [(parallel [(set (match_operand:SWI48 0 "register_operand")
7671		   (truncate:SWI48
7672		     (lshiftrt:<DWI>
7673		       (mult:<DWI>
7674			 (any_extend:<DWI>
7675			   (match_operand:SWI48 1 "nonimmediate_operand"))
7676			 (any_extend:<DWI>
7677			   (match_operand:SWI48 2 "register_operand")))
7678		       (match_dup 3))))
7679	      (clobber (match_scratch:SWI48 4))
7680	      (clobber (reg:CC FLAGS_REG))])]
7681  ""
7682  "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7683
7684(define_insn "*<s>muldi3_highpart_1"
7685  [(set (match_operand:DI 0 "register_operand" "=d")
7686	(truncate:DI
7687	  (lshiftrt:TI
7688	    (mult:TI
7689	      (any_extend:TI
7690		(match_operand:DI 1 "nonimmediate_operand" "%a"))
7691	      (any_extend:TI
7692		(match_operand:DI 2 "nonimmediate_operand" "rm")))
7693	    (const_int 64))))
7694   (clobber (match_scratch:DI 3 "=1"))
7695   (clobber (reg:CC FLAGS_REG))]
7696  "TARGET_64BIT
7697   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7698  "<sgnprefix>mul{q}\t%2"
7699  [(set_attr "type" "imul")
7700   (set_attr "length_immediate" "0")
7701   (set (attr "athlon_decode")
7702     (if_then_else (eq_attr "cpu" "athlon")
7703        (const_string "vector")
7704        (const_string "double")))
7705   (set_attr "amdfam10_decode" "double")
7706   (set_attr "bdver1_decode" "direct")
7707   (set_attr "mode" "DI")])
7708
7709(define_insn "*<s>mulsi3_highpart_zext"
7710  [(set (match_operand:DI 0 "register_operand" "=d")
7711	(zero_extend:DI (truncate:SI
7712	  (lshiftrt:DI
7713	    (mult:DI (any_extend:DI
7714		       (match_operand:SI 1 "nonimmediate_operand" "%a"))
7715		     (any_extend:DI
7716		       (match_operand:SI 2 "nonimmediate_operand" "rm")))
7717	    (const_int 32)))))
7718   (clobber (match_scratch:SI 3 "=1"))
7719   (clobber (reg:CC FLAGS_REG))]
7720  "TARGET_64BIT
7721   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722  "<sgnprefix>mul{l}\t%2"
7723  [(set_attr "type" "imul")
7724   (set_attr "length_immediate" "0")
7725   (set (attr "athlon_decode")
7726     (if_then_else (eq_attr "cpu" "athlon")
7727        (const_string "vector")
7728        (const_string "double")))
7729   (set_attr "amdfam10_decode" "double")
7730   (set_attr "bdver1_decode" "direct")
7731   (set_attr "mode" "SI")])
7732
7733(define_insn "*<s>mulsi3_highpart_1"
7734  [(set (match_operand:SI 0 "register_operand" "=d")
7735	(truncate:SI
7736	  (lshiftrt:DI
7737	    (mult:DI
7738	      (any_extend:DI
7739		(match_operand:SI 1 "nonimmediate_operand" "%a"))
7740	      (any_extend:DI
7741		(match_operand:SI 2 "nonimmediate_operand" "rm")))
7742	    (const_int 32))))
7743   (clobber (match_scratch:SI 3 "=1"))
7744   (clobber (reg:CC FLAGS_REG))]
7745  "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7746  "<sgnprefix>mul{l}\t%2"
7747  [(set_attr "type" "imul")
7748   (set_attr "length_immediate" "0")
7749   (set (attr "athlon_decode")
7750     (if_then_else (eq_attr "cpu" "athlon")
7751        (const_string "vector")
7752        (const_string "double")))
7753   (set_attr "amdfam10_decode" "double")
7754   (set_attr "bdver1_decode" "direct")
7755   (set_attr "mode" "SI")])
7756
7757;; The patterns that match these are at the end of this file.
7758
7759(define_expand "mulxf3"
7760  [(set (match_operand:XF 0 "register_operand")
7761	(mult:XF (match_operand:XF 1 "register_operand")
7762		 (match_operand:XF 2 "register_operand")))]
7763  "TARGET_80387")
7764
7765(define_expand "mul<mode>3"
7766  [(set (match_operand:MODEF 0 "register_operand")
7767	(mult:MODEF (match_operand:MODEF 1 "register_operand")
7768		    (match_operand:MODEF 2 "nonimmediate_operand")))]
7769  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7770    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7771
7772;; Divide instructions
7773
7774;; The patterns that match these are at the end of this file.
7775
7776(define_expand "divxf3"
7777  [(set (match_operand:XF 0 "register_operand")
7778	(div:XF (match_operand:XF 1 "register_operand")
7779		(match_operand:XF 2 "register_operand")))]
7780  "TARGET_80387")
7781
7782(define_expand "div<mode>3"
7783  [(set (match_operand:MODEF 0 "register_operand")
7784	(div:MODEF (match_operand:MODEF 1 "register_operand")
7785		   (match_operand:MODEF 2 "nonimmediate_operand")))]
7786  "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7787    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7788{
7789  if (<MODE>mode == SFmode
7790      && TARGET_SSE && TARGET_SSE_MATH
7791      && TARGET_RECIP_DIV
7792      && optimize_insn_for_speed_p ()
7793      && flag_finite_math_only && !flag_trapping_math
7794      && flag_unsafe_math_optimizations)
7795    {
7796      ix86_emit_swdivsf (operands[0], operands[1],
7797			 operands[2], SFmode);
7798      DONE;
7799    }
7800})
7801
7802;; Divmod instructions.
7803
7804(define_expand "divmod<mode>4"
7805  [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7806		   (div:SWIM248
7807		     (match_operand:SWIM248 1 "register_operand")
7808		     (match_operand:SWIM248 2 "nonimmediate_operand")))
7809	      (set (match_operand:SWIM248 3 "register_operand")
7810		   (mod:SWIM248 (match_dup 1) (match_dup 2)))
7811	      (clobber (reg:CC FLAGS_REG))])])
7812
7813;; Split with 8bit unsigned divide:
7814;; 	if (dividend an divisor are in [0-255])
7815;;	   use 8bit unsigned integer divide
7816;;	 else
7817;;	   use original integer divide
7818(define_split
7819  [(set (match_operand:SWI48 0 "register_operand")
7820	(div:SWI48 (match_operand:SWI48 2 "register_operand")
7821		    (match_operand:SWI48 3 "nonimmediate_operand")))
7822   (set (match_operand:SWI48 1 "register_operand")
7823	(mod:SWI48 (match_dup 2) (match_dup 3)))
7824   (clobber (reg:CC FLAGS_REG))]
7825  "TARGET_USE_8BIT_IDIV
7826   && TARGET_QIMODE_MATH
7827   && can_create_pseudo_p ()
7828   && !optimize_insn_for_size_p ()"
7829  [(const_int 0)]
7830  "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7831
7832(define_split
7833  [(set (match_operand:DI 0 "register_operand")
7834	(zero_extend:DI
7835	  (div:SI (match_operand:SI 2 "register_operand")
7836		  (match_operand:SI 3 "nonimmediate_operand"))))
7837   (set (match_operand:SI 1 "register_operand")
7838	(mod:SI (match_dup 2) (match_dup 3)))
7839   (clobber (reg:CC FLAGS_REG))]
7840  "TARGET_USE_8BIT_IDIV
7841   && TARGET_QIMODE_MATH
7842   && can_create_pseudo_p ()
7843   && !optimize_insn_for_size_p ()"
7844  [(const_int 0)]
7845  "ix86_split_idivmod (SImode, operands, true); DONE;")
7846
7847(define_split
7848  [(set (match_operand:DI 1 "register_operand")
7849	(zero_extend:DI
7850	  (mod:SI (match_operand:SI 2 "register_operand")
7851		  (match_operand:SI 3 "nonimmediate_operand"))))
7852   (set (match_operand:SI 0 "register_operand")
7853	(div:SI  (match_dup 2) (match_dup 3)))
7854   (clobber (reg:CC FLAGS_REG))]
7855  "TARGET_USE_8BIT_IDIV
7856   && TARGET_QIMODE_MATH
7857   && can_create_pseudo_p ()
7858   && !optimize_insn_for_size_p ()"
7859  [(const_int 0)]
7860  "ix86_split_idivmod (SImode, operands, true); DONE;")
7861
7862(define_insn_and_split "divmod<mode>4_1"
7863  [(set (match_operand:SWI48 0 "register_operand" "=a")
7864	(div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7865		   (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7866   (set (match_operand:SWI48 1 "register_operand" "=&d")
7867	(mod:SWI48 (match_dup 2) (match_dup 3)))
7868   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7869   (clobber (reg:CC FLAGS_REG))]
7870  ""
7871  "#"
7872  "reload_completed"
7873  [(parallel [(set (match_dup 1)
7874		   (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7875	      (clobber (reg:CC FLAGS_REG))])
7876   (parallel [(set (match_dup 0)
7877	           (div:SWI48 (match_dup 2) (match_dup 3)))
7878	      (set (match_dup 1)
7879		   (mod:SWI48 (match_dup 2) (match_dup 3)))
7880	      (use (match_dup 1))
7881	      (clobber (reg:CC FLAGS_REG))])]
7882{
7883  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7884
7885  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7886    operands[4] = operands[2];
7887  else
7888    {
7889      /* Avoid use of cltd in favor of a mov+shift.  */
7890      emit_move_insn (operands[1], operands[2]);
7891      operands[4] = operands[1];
7892    }
7893}
7894  [(set_attr "type" "multi")
7895   (set_attr "mode" "<MODE>")])
7896
7897(define_insn_and_split "divmodsi4_zext_1"
7898  [(set (match_operand:DI 0 "register_operand" "=a")
7899	(zero_extend:DI
7900	  (div:SI (match_operand:SI 2 "register_operand" "0")
7901		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7902   (set (match_operand:SI 1 "register_operand" "=&d")
7903	(mod:SI (match_dup 2) (match_dup 3)))
7904   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7905   (clobber (reg:CC FLAGS_REG))]
7906  "TARGET_64BIT"
7907  "#"
7908  "reload_completed"
7909  [(parallel [(set (match_dup 1)
7910		   (ashiftrt:SI (match_dup 4) (match_dup 5)))
7911	      (clobber (reg:CC FLAGS_REG))])
7912   (parallel [(set (match_dup 0)
7913		   (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7914	      (set (match_dup 1)
7915		   (mod:SI (match_dup 2) (match_dup 3)))
7916	      (use (match_dup 1))
7917	      (clobber (reg:CC FLAGS_REG))])]
7918{
7919  operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7920
7921  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7922    operands[4] = operands[2];
7923  else
7924    {
7925      /* Avoid use of cltd in favor of a mov+shift.  */
7926      emit_move_insn (operands[1], operands[2]);
7927      operands[4] = operands[1];
7928    }
7929}
7930  [(set_attr "type" "multi")
7931   (set_attr "mode" "SI")])
7932
7933(define_insn_and_split "divmodsi4_zext_2"
7934  [(set (match_operand:DI 1 "register_operand" "=&d")
7935	(zero_extend:DI
7936	  (mod:SI (match_operand:SI 2 "register_operand" "0")
7937		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7938   (set (match_operand:SI 0 "register_operand" "=a")
7939	(div:SI (match_dup 2) (match_dup 3)))
7940   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7941   (clobber (reg:CC FLAGS_REG))]
7942  "TARGET_64BIT"
7943  "#"
7944  "reload_completed"
7945  [(parallel [(set (match_dup 6)
7946		   (ashiftrt:SI (match_dup 4) (match_dup 5)))
7947	      (clobber (reg:CC FLAGS_REG))])
7948   (parallel [(set (match_dup 1)
7949		   (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7950	      (set (match_dup 0)
7951		   (div:SI (match_dup 2) (match_dup 3)))
7952	      (use (match_dup 6))
7953	      (clobber (reg:CC FLAGS_REG))])]
7954{
7955  operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7956  operands[6] = gen_lowpart (SImode, operands[1]);
7957
7958  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7959    operands[4] = operands[2];
7960  else
7961    {
7962      /* Avoid use of cltd in favor of a mov+shift.  */
7963      emit_move_insn (operands[6], operands[2]);
7964      operands[4] = operands[6];
7965    }
7966}
7967  [(set_attr "type" "multi")
7968   (set_attr "mode" "SI")])
7969
7970(define_insn_and_split "*divmod<mode>4"
7971  [(set (match_operand:SWIM248 0 "register_operand" "=a")
7972	(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7973		    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7974   (set (match_operand:SWIM248 1 "register_operand" "=&d")
7975	(mod:SWIM248 (match_dup 2) (match_dup 3)))
7976   (clobber (reg:CC FLAGS_REG))]
7977  ""
7978  "#"
7979  "reload_completed"
7980  [(parallel [(set (match_dup 1)
7981		   (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7982	      (clobber (reg:CC FLAGS_REG))])
7983   (parallel [(set (match_dup 0)
7984	           (div:SWIM248 (match_dup 2) (match_dup 3)))
7985	      (set (match_dup 1)
7986		   (mod:SWIM248 (match_dup 2) (match_dup 3)))
7987	      (use (match_dup 1))
7988	      (clobber (reg:CC FLAGS_REG))])]
7989{
7990  operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7991
7992  if (<MODE>mode != HImode
7993      && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7994    operands[4] = operands[2];
7995  else
7996    {
7997      /* Avoid use of cltd in favor of a mov+shift.  */
7998      emit_move_insn (operands[1], operands[2]);
7999      operands[4] = operands[1];
8000    }
8001}
8002  [(set_attr "type" "multi")
8003   (set_attr "mode" "<MODE>")])
8004
8005(define_insn_and_split "*divmodsi4_zext_1"
8006  [(set (match_operand:DI 0 "register_operand" "=a")
8007	(zero_extend:DI
8008	  (div:SI (match_operand:SI 2 "register_operand" "0")
8009		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8010   (set (match_operand:SI 1 "register_operand" "=&d")
8011	(mod:SI (match_dup 2) (match_dup 3)))
8012   (clobber (reg:CC FLAGS_REG))]
8013  "TARGET_64BIT"
8014  "#"
8015  "reload_completed"
8016  [(parallel [(set (match_dup 1)
8017		   (ashiftrt:SI (match_dup 4) (match_dup 5)))
8018	      (clobber (reg:CC FLAGS_REG))])
8019   (parallel [(set (match_dup 0)
8020		   (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8021	      (set (match_dup 1)
8022		   (mod:SI (match_dup 2) (match_dup 3)))
8023	      (use (match_dup 1))
8024	      (clobber (reg:CC FLAGS_REG))])]
8025{
8026  operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8027
8028  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8029    operands[4] = operands[2];
8030  else
8031    {
8032      /* Avoid use of cltd in favor of a mov+shift.  */
8033      emit_move_insn (operands[1], operands[2]);
8034      operands[4] = operands[1];
8035    }
8036}
8037  [(set_attr "type" "multi")
8038   (set_attr "mode" "SI")])
8039
8040(define_insn_and_split "*divmodsi4_zext_2"
8041  [(set (match_operand:DI 1 "register_operand" "=&d")
8042	(zero_extend:DI
8043	  (mod:SI (match_operand:SI 2 "register_operand" "0")
8044		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8045   (set (match_operand:SI 0 "register_operand" "=a")
8046	(div:SI (match_dup 2) (match_dup 3)))
8047   (clobber (reg:CC FLAGS_REG))]
8048  "TARGET_64BIT"
8049  "#"
8050  "reload_completed"
8051  [(parallel [(set (match_dup 6)
8052		   (ashiftrt:SI (match_dup 4) (match_dup 5)))
8053	      (clobber (reg:CC FLAGS_REG))])
8054   (parallel [(set (match_dup 1)
8055		   (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8056	      (set (match_dup 0)
8057		   (div:SI (match_dup 2) (match_dup 3)))
8058	      (use (match_dup 6))
8059	      (clobber (reg:CC FLAGS_REG))])]
8060{
8061  operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8062  operands[6] = gen_lowpart (SImode, operands[1]);
8063
8064  if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8065    operands[4] = operands[2];
8066  else
8067    {
8068      /* Avoid use of cltd in favor of a mov+shift.  */
8069      emit_move_insn (operands[6], operands[2]);
8070      operands[4] = operands[6];
8071    }
8072}
8073  [(set_attr "type" "multi")
8074   (set_attr "mode" "SI")])
8075
8076(define_insn "*divmod<mode>4_noext"
8077  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8078	(div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8079		    (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8080   (set (match_operand:SWIM248 1 "register_operand" "=d")
8081	(mod:SWIM248 (match_dup 2) (match_dup 3)))
8082   (use (match_operand:SWIM248 4 "register_operand" "1"))
8083   (clobber (reg:CC FLAGS_REG))]
8084  ""
8085  "idiv{<imodesuffix>}\t%3"
8086  [(set_attr "type" "idiv")
8087   (set_attr "mode" "<MODE>")])
8088
8089(define_insn "*divmodsi4_noext_zext_1"
8090  [(set (match_operand:DI 0 "register_operand" "=a")
8091	(zero_extend:DI
8092	  (div:SI (match_operand:SI 2 "register_operand" "0")
8093		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8094   (set (match_operand:SI 1 "register_operand" "=d")
8095	(mod:SI (match_dup 2) (match_dup 3)))
8096   (use (match_operand:SI 4 "register_operand" "1"))
8097   (clobber (reg:CC FLAGS_REG))]
8098  "TARGET_64BIT"
8099  "idiv{l}\t%3"
8100  [(set_attr "type" "idiv")
8101   (set_attr "mode" "SI")])
8102
8103(define_insn "*divmodsi4_noext_zext_2"
8104  [(set (match_operand:DI 1 "register_operand" "=d")
8105	(zero_extend:DI
8106	  (mod:SI (match_operand:SI 2 "register_operand" "0")
8107		  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8108   (set (match_operand:SI 0 "register_operand" "=a")
8109	(div:SI (match_dup 2) (match_dup 3)))
8110   (use (match_operand:SI 4 "register_operand" "1"))
8111   (clobber (reg:CC FLAGS_REG))]
8112  "TARGET_64BIT"
8113  "idiv{l}\t%3"
8114  [(set_attr "type" "idiv")
8115   (set_attr "mode" "SI")])
8116
8117(define_expand "divmodqi4"
8118  [(parallel [(set (match_operand:QI 0 "register_operand")
8119		   (div:QI
8120		     (match_operand:QI 1 "register_operand")
8121		     (match_operand:QI 2 "nonimmediate_operand")))
8122	      (set (match_operand:QI 3 "register_operand")
8123		   (mod:QI (match_dup 1) (match_dup 2)))
8124	      (clobber (reg:CC FLAGS_REG))])]
8125  "TARGET_QIMODE_MATH"
8126{
8127  rtx div, mod;
8128  rtx tmp0, tmp1;
8129
8130  tmp0 = gen_reg_rtx (HImode);
8131  tmp1 = gen_reg_rtx (HImode);
8132
8133  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8134  emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8135  emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8136
8137  /* Extract remainder from AH.  */
8138  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8139  tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8140  rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8141
8142  mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8143  set_unique_reg_note (insn, REG_EQUAL, mod);
8144
8145  /* Extract quotient from AL.  */
8146  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8147
8148  div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8149  set_unique_reg_note (insn, REG_EQUAL, div);
8150
8151  DONE;
8152})
8153
8154;; Divide AX by r/m8, with result stored in
8155;; AL <- Quotient
8156;; AH <- Remainder
8157;; Change div/mod to HImode and extend the second argument to HImode
8158;; so that mode of div/mod matches with mode of arguments.  Otherwise
8159;; combine may fail.
8160(define_insn "divmodhiqi3"
8161  [(set (match_operand:HI 0 "register_operand" "=a")
8162	(ior:HI
8163	  (ashift:HI
8164	    (zero_extend:HI
8165	      (truncate:QI
8166		(mod:HI (match_operand:HI 1 "register_operand" "0")
8167			(sign_extend:HI
8168			  (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8169	    (const_int 8))
8170	  (zero_extend:HI
8171	    (truncate:QI
8172	      (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8173   (clobber (reg:CC FLAGS_REG))]
8174  "TARGET_QIMODE_MATH"
8175  "idiv{b}\t%2"
8176  [(set_attr "type" "idiv")
8177   (set_attr "mode" "QI")])
8178
8179(define_expand "udivmod<mode>4"
8180  [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8181		   (udiv:SWIM248
8182		     (match_operand:SWIM248 1 "register_operand")
8183		     (match_operand:SWIM248 2 "nonimmediate_operand")))
8184	      (set (match_operand:SWIM248 3 "register_operand")
8185		   (umod:SWIM248 (match_dup 1) (match_dup 2)))
8186	      (clobber (reg:CC FLAGS_REG))])])
8187
8188;; Split with 8bit unsigned divide:
8189;; 	if (dividend an divisor are in [0-255])
8190;;	   use 8bit unsigned integer divide
8191;;	 else
8192;;	   use original integer divide
8193(define_split
8194  [(set (match_operand:SWI48 0 "register_operand")
8195	(udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8196		    (match_operand:SWI48 3 "nonimmediate_operand")))
8197   (set (match_operand:SWI48 1 "register_operand")
8198	(umod:SWI48 (match_dup 2) (match_dup 3)))
8199   (clobber (reg:CC FLAGS_REG))]
8200  "TARGET_USE_8BIT_IDIV
8201   && TARGET_QIMODE_MATH
8202   && can_create_pseudo_p ()
8203   && !optimize_insn_for_size_p ()"
8204  [(const_int 0)]
8205  "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8206
8207(define_split
8208  [(set (match_operand:DI 0 "register_operand")
8209	(zero_extend:DI
8210	  (udiv:SI (match_operand:SI 2 "register_operand")
8211		   (match_operand:SI 3 "nonimmediate_operand"))))
8212   (set (match_operand:SI 1 "register_operand")
8213	(umod:SI (match_dup 2) (match_dup 3)))
8214   (clobber (reg:CC FLAGS_REG))]
8215  "TARGET_64BIT
8216   && TARGET_USE_8BIT_IDIV
8217   && TARGET_QIMODE_MATH
8218   && can_create_pseudo_p ()
8219   && !optimize_insn_for_size_p ()"
8220  [(const_int 0)]
8221  "ix86_split_idivmod (SImode, operands, false); DONE;")
8222
8223(define_split
8224  [(set (match_operand:DI 1 "register_operand")
8225	(zero_extend:DI
8226	  (umod:SI (match_operand:SI 2 "register_operand")
8227		   (match_operand:SI 3 "nonimmediate_operand"))))
8228   (set (match_operand:SI 0 "register_operand")
8229	(udiv:SI (match_dup 2) (match_dup 3)))
8230   (clobber (reg:CC FLAGS_REG))]
8231  "TARGET_64BIT
8232   && TARGET_USE_8BIT_IDIV
8233   && TARGET_QIMODE_MATH
8234   && can_create_pseudo_p ()
8235   && !optimize_insn_for_size_p ()"
8236  [(const_int 0)]
8237  "ix86_split_idivmod (SImode, operands, false); DONE;")
8238
8239(define_insn_and_split "udivmod<mode>4_1"
8240  [(set (match_operand:SWI48 0 "register_operand" "=a")
8241	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8242		    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8243   (set (match_operand:SWI48 1 "register_operand" "=&d")
8244	(umod:SWI48 (match_dup 2) (match_dup 3)))
8245   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8246   (clobber (reg:CC FLAGS_REG))]
8247  ""
8248  "#"
8249  "reload_completed"
8250  [(set (match_dup 1) (const_int 0))
8251   (parallel [(set (match_dup 0)
8252		   (udiv:SWI48 (match_dup 2) (match_dup 3)))
8253	      (set (match_dup 1)
8254		   (umod:SWI48 (match_dup 2) (match_dup 3)))
8255	      (use (match_dup 1))
8256	      (clobber (reg:CC FLAGS_REG))])]
8257  ""
8258  [(set_attr "type" "multi")
8259   (set_attr "mode" "<MODE>")])
8260
8261(define_insn_and_split "udivmodsi4_zext_1"
8262  [(set (match_operand:DI 0 "register_operand" "=a")
8263	(zero_extend:DI
8264	  (udiv:SI (match_operand:SI 2 "register_operand" "0")
8265		   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8266   (set (match_operand:SI 1 "register_operand" "=&d")
8267	(umod:SI (match_dup 2) (match_dup 3)))
8268   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8269   (clobber (reg:CC FLAGS_REG))]
8270  "TARGET_64BIT"
8271  "#"
8272  "reload_completed"
8273  [(set (match_dup 1) (const_int 0))
8274   (parallel [(set (match_dup 0)
8275		   (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8276	      (set (match_dup 1)
8277		   (umod:SI (match_dup 2) (match_dup 3)))
8278	      (use (match_dup 1))
8279	      (clobber (reg:CC FLAGS_REG))])]
8280  ""
8281  [(set_attr "type" "multi")
8282   (set_attr "mode" "SI")])
8283
8284(define_insn_and_split "udivmodsi4_zext_2"
8285  [(set (match_operand:DI 1 "register_operand" "=&d")
8286	(zero_extend:DI
8287	  (umod:SI (match_operand:SI 2 "register_operand" "0")
8288		 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8289   (set (match_operand:SI 0 "register_operand" "=a")
8290	(udiv:SI (match_dup 2) (match_dup 3)))
8291   (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8292   (clobber (reg:CC FLAGS_REG))]
8293  "TARGET_64BIT"
8294  "#"
8295  "reload_completed"
8296  [(set (match_dup 4) (const_int 0))
8297   (parallel [(set (match_dup 1)
8298		   (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8299	      (set (match_dup 0)
8300		   (udiv:SI (match_dup 2) (match_dup 3)))
8301	      (use (match_dup 4))
8302	      (clobber (reg:CC FLAGS_REG))])]
8303  "operands[4] = gen_lowpart (SImode, operands[1]);"
8304  [(set_attr "type" "multi")
8305   (set_attr "mode" "SI")])
8306
8307(define_insn_and_split "*udivmod<mode>4"
8308  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8309	(udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8310		      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8311   (set (match_operand:SWIM248 1 "register_operand" "=&d")
8312	(umod:SWIM248 (match_dup 2) (match_dup 3)))
8313   (clobber (reg:CC FLAGS_REG))]
8314  ""
8315  "#"
8316  "reload_completed"
8317  [(set (match_dup 1) (const_int 0))
8318   (parallel [(set (match_dup 0)
8319		   (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8320	      (set (match_dup 1)
8321		   (umod:SWIM248 (match_dup 2) (match_dup 3)))
8322	      (use (match_dup 1))
8323	      (clobber (reg:CC FLAGS_REG))])]
8324  ""
8325  [(set_attr "type" "multi")
8326   (set_attr "mode" "<MODE>")])
8327
8328(define_insn_and_split "*udivmodsi4_zext_1"
8329  [(set (match_operand:DI 0 "register_operand" "=a")
8330	(zero_extend:DI
8331	  (udiv:SI (match_operand:SI 2 "register_operand" "0")
8332		   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8333   (set (match_operand:SI 1 "register_operand" "=&d")
8334	(umod:SI (match_dup 2) (match_dup 3)))
8335   (clobber (reg:CC FLAGS_REG))]
8336  "TARGET_64BIT"
8337  "#"
8338  "reload_completed"
8339  [(set (match_dup 1) (const_int 0))
8340   (parallel [(set (match_dup 0)
8341		   (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8342	      (set (match_dup 1)
8343		   (umod:SI (match_dup 2) (match_dup 3)))
8344	      (use (match_dup 1))
8345	      (clobber (reg:CC FLAGS_REG))])]
8346  ""
8347  [(set_attr "type" "multi")
8348   (set_attr "mode" "SI")])
8349
8350(define_insn_and_split "*udivmodsi4_zext_2"
8351  [(set (match_operand:DI 1 "register_operand" "=&d")
8352	(zero_extend:DI
8353	  (umod:SI (match_operand:SI 2 "register_operand" "0")
8354		   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8355   (set (match_operand:SI 0 "register_operand" "=a")
8356	(udiv:SI (match_dup 2) (match_dup 3)))
8357   (clobber (reg:CC FLAGS_REG))]
8358  "TARGET_64BIT"
8359  "#"
8360  "reload_completed"
8361  [(set (match_dup 4) (const_int 0))
8362   (parallel [(set (match_dup 1)
8363		   (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8364	      (set (match_dup 0)
8365		   (udiv:SI (match_dup 2) (match_dup 3)))
8366	      (use (match_dup 4))
8367	      (clobber (reg:CC FLAGS_REG))])]
8368  "operands[4] = gen_lowpart (SImode, operands[1]);"
8369  [(set_attr "type" "multi")
8370   (set_attr "mode" "SI")])
8371
8372;; Optimize division or modulo by constant power of 2, if the constant
8373;; materializes only after expansion.
8374(define_insn_and_split "*udivmod<mode>4_pow2"
8375  [(set (match_operand:SWI48 0 "register_operand" "=r")
8376	(udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8377		    (match_operand:SWI48 3 "const_int_operand" "n")))
8378   (set (match_operand:SWI48 1 "register_operand" "=r")
8379	(umod:SWI48 (match_dup 2) (match_dup 3)))
8380   (clobber (reg:CC FLAGS_REG))]
8381  "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8382   && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8383  "#"
8384  "&& 1"
8385  [(set (match_dup 1) (match_dup 2))
8386   (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8387	      (clobber (reg:CC FLAGS_REG))])
8388   (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8389	      (clobber (reg:CC FLAGS_REG))])]
8390{
8391  int v = exact_log2 (UINTVAL (operands[3]));
8392  operands[4] = GEN_INT (v);
8393  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8394}
8395  [(set_attr "type" "multi")
8396   (set_attr "mode" "<MODE>")])
8397
8398(define_insn_and_split "*udivmodsi4_pow2_zext_1"
8399  [(set (match_operand:DI 0 "register_operand" "=r")
8400	(zero_extend:DI
8401	  (udiv:SI (match_operand:SI 2 "register_operand" "0")
8402		   (match_operand:SI 3 "const_int_operand" "n"))))
8403   (set (match_operand:SI 1 "register_operand" "=r")
8404	(umod:SI (match_dup 2) (match_dup 3)))
8405   (clobber (reg:CC FLAGS_REG))]
8406  "TARGET_64BIT
8407   && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8408   && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8409  "#"
8410  "&& 1"
8411  [(set (match_dup 1) (match_dup 2))
8412   (parallel [(set (match_dup 0)
8413		   (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8414	      (clobber (reg:CC FLAGS_REG))])
8415   (parallel [(set (match_dup 1) (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_and_split "*udivmodsi4_pow2_zext_2"
8426  [(set (match_operand:DI 1 "register_operand" "=r")
8427	(zero_extend:DI
8428	  (umod:SI (match_operand:SI 2 "register_operand" "0")
8429		   (match_operand:SI 3 "const_int_operand" "n"))))
8430   (set (match_operand:SI 0 "register_operand" "=r")
8431	(umod:SI (match_dup 2) (match_dup 3)))
8432   (clobber (reg:CC FLAGS_REG))]
8433  "TARGET_64BIT
8434   && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8435   && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8436  "#"
8437  "&& 1"
8438  [(set (match_dup 1) (match_dup 2))
8439   (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8440	      (clobber (reg:CC FLAGS_REG))])
8441   (parallel [(set (match_dup 1)
8442		   (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8443	      (clobber (reg:CC FLAGS_REG))])]
8444{
8445  int v = exact_log2 (UINTVAL (operands[3]));
8446  operands[4] = GEN_INT (v);
8447  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8448}
8449  [(set_attr "type" "multi")
8450   (set_attr "mode" "SI")])
8451
8452(define_insn "*udivmod<mode>4_noext"
8453  [(set (match_operand:SWIM248 0 "register_operand" "=a")
8454	(udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8455		      (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8456   (set (match_operand:SWIM248 1 "register_operand" "=d")
8457	(umod:SWIM248 (match_dup 2) (match_dup 3)))
8458   (use (match_operand:SWIM248 4 "register_operand" "1"))
8459   (clobber (reg:CC FLAGS_REG))]
8460  ""
8461  "div{<imodesuffix>}\t%3"
8462  [(set_attr "type" "idiv")
8463   (set_attr "mode" "<MODE>")])
8464
8465(define_insn "*udivmodsi4_noext_zext_1"
8466  [(set (match_operand:DI 0 "register_operand" "=a")
8467	(zero_extend:DI
8468	  (udiv:SI (match_operand:SI 2 "register_operand" "0")
8469		   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8470   (set (match_operand:SI 1 "register_operand" "=d")
8471	(umod:SI (match_dup 2) (match_dup 3)))
8472   (use (match_operand:SI 4 "register_operand" "1"))
8473   (clobber (reg:CC FLAGS_REG))]
8474  "TARGET_64BIT"
8475  "div{l}\t%3"
8476  [(set_attr "type" "idiv")
8477   (set_attr "mode" "SI")])
8478
8479(define_insn "*udivmodsi4_noext_zext_2"
8480  [(set (match_operand:DI 1 "register_operand" "=d")
8481	(zero_extend:DI
8482	  (umod:SI (match_operand:SI 2 "register_operand" "0")
8483		   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8484   (set (match_operand:SI 0 "register_operand" "=a")
8485	(udiv:SI (match_dup 2) (match_dup 3)))
8486   (use (match_operand:SI 4 "register_operand" "1"))
8487   (clobber (reg:CC FLAGS_REG))]
8488  "TARGET_64BIT"
8489  "div{l}\t%3"
8490  [(set_attr "type" "idiv")
8491   (set_attr "mode" "SI")])
8492
8493(define_expand "udivmodqi4"
8494  [(parallel [(set (match_operand:QI 0 "register_operand")
8495		   (udiv:QI
8496		     (match_operand:QI 1 "register_operand")
8497		     (match_operand:QI 2 "nonimmediate_operand")))
8498	      (set (match_operand:QI 3 "register_operand")
8499		   (umod:QI (match_dup 1) (match_dup 2)))
8500	      (clobber (reg:CC FLAGS_REG))])]
8501  "TARGET_QIMODE_MATH"
8502{
8503  rtx div, mod;
8504  rtx tmp0, tmp1;
8505
8506  tmp0 = gen_reg_rtx (HImode);
8507  tmp1 = gen_reg_rtx (HImode);
8508
8509  /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8510  emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8511  emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8512
8513  /* Extract remainder from AH.  */
8514  tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8515  tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8516  rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8517
8518  mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8519  set_unique_reg_note (insn, REG_EQUAL, mod);
8520
8521  /* Extract quotient from AL.  */
8522  insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8523
8524  div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8525  set_unique_reg_note (insn, REG_EQUAL, div);
8526
8527  DONE;
8528})
8529
8530(define_insn "udivmodhiqi3"
8531  [(set (match_operand:HI 0 "register_operand" "=a")
8532	(ior:HI
8533	  (ashift:HI
8534	    (zero_extend:HI
8535	      (truncate:QI
8536		(mod:HI (match_operand:HI 1 "register_operand" "0")
8537			(zero_extend:HI
8538			  (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8539	    (const_int 8))
8540	  (zero_extend:HI
8541	    (truncate:QI
8542	      (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8543   (clobber (reg:CC FLAGS_REG))]
8544  "TARGET_QIMODE_MATH"
8545  "div{b}\t%2"
8546  [(set_attr "type" "idiv")
8547   (set_attr "mode" "QI")])
8548
8549;; We cannot use div/idiv for double division, because it causes
8550;; "division by zero" on the overflow and that's not what we expect
8551;; from truncate.  Because true (non truncating) double division is
8552;; never generated, we can't create this insn anyway.
8553;
8554;(define_insn ""
8555;  [(set (match_operand:SI 0 "register_operand" "=a")
8556;	(truncate:SI
8557;	  (udiv:DI (match_operand:DI 1 "register_operand" "A")
8558;		   (zero_extend:DI
8559;		     (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8560;   (set (match_operand:SI 3 "register_operand" "=d")
8561;	(truncate:SI
8562;	  (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8563;   (clobber (reg:CC FLAGS_REG))]
8564;  ""
8565;  "div{l}\t{%2, %0|%0, %2}"
8566;  [(set_attr "type" "idiv")])
8567
8568;;- Logical AND instructions
8569
8570;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8571;; Note that this excludes ah.
8572
8573(define_expand "testsi_ccno_1"
8574  [(set (reg:CCNO FLAGS_REG)
8575	(compare:CCNO
8576	  (and:SI (match_operand:SI 0 "nonimmediate_operand")
8577		  (match_operand:SI 1 "x86_64_nonmemory_operand"))
8578	  (const_int 0)))])
8579
8580(define_expand "testqi_ccz_1"
8581  [(set (reg:CCZ FLAGS_REG)
8582        (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8583			     (match_operand:QI 1 "nonmemory_operand"))
8584		 (const_int 0)))])
8585
8586(define_expand "testdi_ccno_1"
8587  [(set (reg:CCNO FLAGS_REG)
8588	(compare:CCNO
8589	  (and:DI (match_operand:DI 0 "nonimmediate_operand")
8590		  (match_operand:DI 1 "x86_64_szext_general_operand"))
8591	  (const_int 0)))]
8592  "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8593
8594(define_insn "*testdi_1"
8595  [(set (reg FLAGS_REG)
8596	(compare
8597	 (and:DI
8598	  (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8599	  (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8600	 (const_int 0)))]
8601  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8602   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8603  "@
8604   test{l}\t{%k1, %k0|%k0, %k1}
8605   test{l}\t{%k1, %k0|%k0, %k1}
8606   test{q}\t{%1, %0|%0, %1}
8607   test{q}\t{%1, %0|%0, %1}
8608   test{q}\t{%1, %0|%0, %1}"
8609  [(set_attr "type" "test")
8610   (set_attr "modrm" "0,1,0,1,1")
8611   (set_attr "mode" "SI,SI,DI,DI,DI")])
8612
8613(define_insn "*testqi_1_maybe_si"
8614  [(set (reg FLAGS_REG)
8615        (compare
8616	  (and:QI
8617	    (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8618	    (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8619	  (const_int 0)))]
8620   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8621    && ix86_match_ccmode (insn,
8622 			 CONST_INT_P (operands[1])
8623 			 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8624{
8625  if (which_alternative == 3)
8626    {
8627      if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8628	operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8629      return "test{l}\t{%1, %k0|%k0, %1}";
8630    }
8631  return "test{b}\t{%1, %0|%0, %1}";
8632}
8633  [(set_attr "type" "test")
8634   (set_attr "modrm" "0,1,1,1")
8635   (set_attr "mode" "QI,QI,QI,SI")
8636   (set_attr "pent_pair" "uv,np,uv,np")])
8637
8638(define_insn "*test<mode>_1"
8639  [(set (reg FLAGS_REG)
8640	(compare
8641	 (and:SWI124
8642	  (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8643	  (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8644	 (const_int 0)))]
8645  "ix86_match_ccmode (insn, CCNOmode)
8646   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8647  "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8648  [(set_attr "type" "test")
8649   (set_attr "modrm" "0,1,1")
8650   (set_attr "mode" "<MODE>")
8651   (set_attr "pent_pair" "uv,np,uv")])
8652
8653(define_expand "testqi_ext_1_ccno"
8654  [(set (reg:CCNO FLAGS_REG)
8655	(compare:CCNO
8656	  (and:QI
8657	    (subreg:QI
8658	      (zero_extract:SI (match_operand 0 "ext_register_operand")
8659			       (const_int 8)
8660			       (const_int 8)) 0)
8661	      (match_operand 1 "const_int_operand"))
8662	  (const_int 0)))])
8663
8664(define_insn "*testqi_ext_1"
8665  [(set (reg FLAGS_REG)
8666	(compare
8667	  (and:QI
8668	    (subreg:QI
8669	      (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8670			       (const_int 8)
8671			       (const_int 8)) 0)
8672	    (match_operand:QI 1 "general_operand" "QnBc,m"))
8673	  (const_int 0)))]
8674  "ix86_match_ccmode (insn, CCNOmode)"
8675  "test{b}\t{%1, %h0|%h0, %1}"
8676  [(set_attr "isa" "*,nox64")
8677   (set_attr "type" "test")
8678   (set_attr "mode" "QI")])
8679
8680(define_insn "*testqi_ext_2"
8681  [(set (reg FLAGS_REG)
8682	(compare
8683	  (and:QI
8684	    (subreg:QI
8685	      (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8686			       (const_int 8)
8687			       (const_int 8)) 0)
8688	    (subreg:QI
8689	      (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8690			       (const_int 8)
8691			       (const_int 8)) 0))
8692	  (const_int 0)))]
8693  "ix86_match_ccmode (insn, CCNOmode)"
8694  "test{b}\t{%h1, %h0|%h0, %h1}"
8695  [(set_attr "type" "test")
8696   (set_attr "mode" "QI")])
8697
8698;; Combine likes to form bit extractions for some tests.  Humor it.
8699(define_insn_and_split "*testqi_ext_3"
8700  [(set (match_operand 0 "flags_reg_operand")
8701        (match_operator 1 "compare_operator"
8702	  [(zero_extract:SWI248
8703	     (match_operand 2 "nonimmediate_operand" "rm")
8704	     (match_operand 3 "const_int_operand" "n")
8705	     (match_operand 4 "const_int_operand" "n"))
8706	   (const_int 0)]))]
8707  "ix86_match_ccmode (insn, CCNOmode)
8708   && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8709       || GET_MODE (operands[2]) == SImode
8710       || GET_MODE (operands[2]) == HImode
8711       || GET_MODE (operands[2]) == QImode)
8712   /* Ensure that resulting mask is zero or sign extended operand.  */
8713   && INTVAL (operands[4]) >= 0
8714   && ((INTVAL (operands[3]) > 0
8715	&& INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8716       || (<MODE>mode == DImode
8717	   && INTVAL (operands[3]) > 32
8718	   && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8719  "#"
8720  "&& 1"
8721  [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8722{
8723  rtx val = operands[2];
8724  HOST_WIDE_INT len = INTVAL (operands[3]);
8725  HOST_WIDE_INT pos = INTVAL (operands[4]);
8726  machine_mode mode = GET_MODE (val);
8727
8728  if (SUBREG_P (val))
8729    {
8730      machine_mode submode = GET_MODE (SUBREG_REG (val));
8731
8732      /* Narrow paradoxical subregs to prevent partial register stalls.  */
8733      if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8734	  && GET_MODE_CLASS (submode) == MODE_INT)
8735	{
8736	  val = SUBREG_REG (val);
8737	  mode = submode;
8738	}
8739    }
8740
8741  /* Small HImode tests can be converted to QImode.  */
8742  if (register_operand (val, HImode) && pos + len <= 8)
8743    {
8744      val = gen_lowpart (QImode, val);
8745      mode = QImode;
8746    }
8747
8748  gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8749
8750  wide_int mask
8751    = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8752
8753  operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8754})
8755
8756;; Convert HImode/SImode test instructions with immediate to QImode ones.
8757;; i386 does not allow to encode test with 8bit sign extended immediate, so
8758;; this is relatively important trick.
8759;; Do the conversion only post-reload to avoid limiting of the register class
8760;; to QI regs.
8761(define_split
8762  [(set (match_operand 0 "flags_reg_operand")
8763	(match_operator 1 "compare_operator"
8764	  [(and (match_operand 2 "QIreg_operand")
8765	        (match_operand 3 "const_int_operand"))
8766	   (const_int 0)]))]
8767   "reload_completed
8768    && GET_MODE (operands[2]) != QImode
8769    && ((ix86_match_ccmode (insn, CCZmode)
8770    	 && !(INTVAL (operands[3]) & ~(255 << 8)))
8771	|| (ix86_match_ccmode (insn, CCNOmode)
8772	    && !(INTVAL (operands[3]) & ~(127 << 8))))"
8773  [(set (match_dup 0)
8774	(match_op_dup 1
8775	  [(and:QI
8776	     (subreg:QI
8777	       (zero_extract:SI (match_dup 2)
8778				(const_int 8)
8779				(const_int 8)) 0)
8780	     (match_dup 3))
8781	   (const_int 0)]))]
8782{
8783  operands[2] = gen_lowpart (SImode, operands[2]);
8784  operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8785})
8786
8787(define_split
8788  [(set (match_operand 0 "flags_reg_operand")
8789	(match_operator 1 "compare_operator"
8790	  [(and (match_operand 2 "nonimmediate_operand")
8791	        (match_operand 3 "const_int_operand"))
8792	   (const_int 0)]))]
8793   "reload_completed
8794    && GET_MODE (operands[2]) != QImode
8795    && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8796    && ((ix86_match_ccmode (insn, CCZmode)
8797	 && !(INTVAL (operands[3]) & ~255))
8798	|| (ix86_match_ccmode (insn, CCNOmode)
8799	    && !(INTVAL (operands[3]) & ~127)))"
8800  [(set (match_dup 0)
8801	(match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8802			 (const_int 0)]))]
8803{
8804  operands[2] = gen_lowpart (QImode, operands[2]);
8805  operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8806})
8807
8808;; %%% This used to optimize known byte-wide and operations to memory,
8809;; and sometimes to QImode registers.  If this is considered useful,
8810;; it should be done with splitters.
8811
8812(define_expand "and<mode>3"
8813  [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8814	(and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8815		      (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8816  ""
8817{
8818  machine_mode mode = <MODE>mode;
8819  rtx (*insn) (rtx, rtx);
8820
8821  if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8822    {
8823      HOST_WIDE_INT ival = INTVAL (operands[2]);
8824
8825      if (ival == (HOST_WIDE_INT) 0xffffffff)
8826	mode = SImode;
8827      else if (ival == 0xffff)
8828	mode = HImode;
8829      else if (ival == 0xff)
8830	mode = QImode;
8831      }
8832
8833  if (mode == <MODE>mode)
8834    {
8835      ix86_expand_binary_operator (AND, <MODE>mode, operands);
8836      DONE;
8837    }
8838
8839  if (<MODE>mode == DImode)
8840    insn = (mode == SImode)
8841	   ? gen_zero_extendsidi2
8842	   : (mode == HImode)
8843	   ? gen_zero_extendhidi2
8844	   : gen_zero_extendqidi2;
8845  else if (<MODE>mode == SImode)
8846    insn = (mode == HImode)
8847	   ? gen_zero_extendhisi2
8848	   : gen_zero_extendqisi2;
8849  else if (<MODE>mode == HImode)
8850    insn = gen_zero_extendqihi2;
8851  else
8852    gcc_unreachable ();
8853
8854  emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8855  DONE;
8856})
8857
8858(define_insn_and_split "*anddi3_doubleword"
8859  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8860	(and:DI
8861	 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8862	 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8863   (clobber (reg:CC FLAGS_REG))]
8864  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8865   && ix86_binary_operator_ok (AND, DImode, operands)"
8866  "#"
8867  "&& reload_completed"
8868  [(const_int 0)]
8869{
8870  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8871  if (operands[2] == const0_rtx)
8872    {
8873      operands[1] = const0_rtx;
8874      ix86_expand_move (SImode, &operands[0]);
8875    }
8876  else if (operands[2] != constm1_rtx)
8877    ix86_expand_binary_operator (AND, SImode, &operands[0]);
8878  else if (operands[5] == constm1_rtx)
8879    emit_note (NOTE_INSN_DELETED);
8880  if (operands[5] == const0_rtx)
8881    {
8882      operands[4] = const0_rtx;
8883      ix86_expand_move (SImode, &operands[3]);
8884    }
8885  else if (operands[5] != constm1_rtx)
8886    ix86_expand_binary_operator (AND, SImode, &operands[3]);
8887  DONE;
8888})
8889
8890(define_insn "*anddi_1"
8891  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8892	(and:DI
8893	 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8894	 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8895   (clobber (reg:CC FLAGS_REG))]
8896  "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8897  "@
8898   and{l}\t{%k2, %k0|%k0, %k2}
8899   and{q}\t{%2, %0|%0, %2}
8900   and{q}\t{%2, %0|%0, %2}
8901   #"
8902  [(set_attr "type" "alu,alu,alu,imovx")
8903   (set_attr "length_immediate" "*,*,*,0")
8904   (set (attr "prefix_rex")
8905     (if_then_else
8906       (and (eq_attr "type" "imovx")
8907	    (and (match_test "INTVAL (operands[2]) == 0xff")
8908		 (match_operand 1 "ext_QIreg_operand")))
8909       (const_string "1")
8910       (const_string "*")))
8911   (set_attr "mode" "SI,DI,DI,SI")])
8912
8913(define_insn_and_split "*anddi_1_btr"
8914  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8915	(and:DI
8916	 (match_operand:DI 1 "nonimmediate_operand" "%0")
8917	 (match_operand:DI 2 "const_int_operand" "n")))
8918   (clobber (reg:CC FLAGS_REG))]
8919  "TARGET_64BIT && TARGET_USE_BT
8920   && ix86_binary_operator_ok (AND, DImode, operands)
8921   && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8922  "#"
8923  "&& reload_completed"
8924  [(parallel [(set (zero_extract:DI (match_dup 0)
8925				    (const_int 1)
8926				    (match_dup 3))
8927		   (const_int 0))
8928	      (clobber (reg:CC FLAGS_REG))])]
8929  "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8930  [(set_attr "type" "alu1")
8931   (set_attr "prefix_0f" "1")
8932   (set_attr "znver1_decode" "double")
8933   (set_attr "mode" "DI")])
8934
8935;; Turn *anddi_1 into *andsi_1_zext if possible.
8936(define_split
8937  [(set (match_operand:DI 0 "register_operand")
8938	(and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8939		(match_operand:DI 2 "x86_64_zext_immediate_operand")))
8940   (clobber (reg:CC FLAGS_REG))]
8941  "TARGET_64BIT"
8942  [(parallel [(set (match_dup 0)
8943		   (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8944	      (clobber (reg:CC FLAGS_REG))])]
8945{
8946  if (GET_CODE (operands[2]) == SYMBOL_REF
8947      || GET_CODE (operands[2]) == LABEL_REF)
8948    {
8949      operands[2] = shallow_copy_rtx (operands[2]);
8950      PUT_MODE (operands[2], SImode);
8951    }
8952  else if (GET_CODE (operands[2]) == CONST)
8953    {
8954      /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
8955      operands[2] = copy_rtx (operands[2]);
8956      PUT_MODE (operands[2], SImode);
8957      PUT_MODE (XEXP (operands[2], 0), SImode);
8958      PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
8959    }
8960  else
8961    operands[2] = gen_lowpart (SImode, operands[2]);
8962})
8963
8964;; See comment for addsi_1_zext why we do use nonimmediate_operand
8965(define_insn "*andsi_1_zext"
8966  [(set (match_operand:DI 0 "register_operand" "=r")
8967	(zero_extend:DI
8968	  (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8969		  (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8970   (clobber (reg:CC FLAGS_REG))]
8971  "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8972  "and{l}\t{%2, %k0|%k0, %2}"
8973  [(set_attr "type" "alu")
8974   (set_attr "mode" "SI")])
8975
8976(define_insn "*and<mode>_1"
8977  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8978	(and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8979		   (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8980   (clobber (reg:CC FLAGS_REG))]
8981  "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8982  "@
8983   and{<imodesuffix>}\t{%2, %0|%0, %2}
8984   and{<imodesuffix>}\t{%2, %0|%0, %2}
8985   #"
8986  [(set_attr "type" "alu,alu,imovx")
8987   (set_attr "length_immediate" "*,*,0")
8988   (set (attr "prefix_rex")
8989     (if_then_else
8990       (and (eq_attr "type" "imovx")
8991	    (and (match_test "INTVAL (operands[2]) == 0xff")
8992		 (match_operand 1 "ext_QIreg_operand")))
8993       (const_string "1")
8994       (const_string "*")))
8995   (set_attr "mode" "<MODE>,<MODE>,SI")])
8996
8997(define_insn "*andqi_1"
8998  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8999	(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9000		(match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9001   (clobber (reg:CC FLAGS_REG))]
9002  "ix86_binary_operator_ok (AND, QImode, operands)"
9003  "@
9004   and{b}\t{%2, %0|%0, %2}
9005   and{b}\t{%2, %0|%0, %2}
9006   and{l}\t{%k2, %k0|%k0, %k2}"
9007  [(set_attr "type" "alu")
9008   (set_attr "mode" "QI,QI,SI")
9009   ;; Potential partial reg stall on alternative 2.
9010   (set (attr "preferred_for_speed")
9011     (cond [(eq_attr "alternative" "2")
9012	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9013	   (symbol_ref "true")))])
9014
9015(define_insn "*andqi_1_slp"
9016  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9017	(and:QI (match_dup 0)
9018		(match_operand:QI 1 "general_operand" "qn,qmn")))
9019   (clobber (reg:CC FLAGS_REG))]
9020  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9021   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9022  "and{b}\t{%1, %0|%0, %1}"
9023  [(set_attr "type" "alu1")
9024   (set_attr "mode" "QI")])
9025
9026(define_split
9027  [(set (match_operand:SWI248 0 "register_operand")
9028	(and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9029		    (match_operand:SWI248 2 "const_int_operand")))
9030   (clobber (reg:CC FLAGS_REG))]
9031  "reload_completed
9032   && (!REG_P (operands[1])
9033       || REGNO (operands[0]) != REGNO (operands[1]))"
9034  [(const_int 0)]
9035{
9036  HOST_WIDE_INT ival = INTVAL (operands[2]);
9037  machine_mode mode;
9038  rtx (*insn) (rtx, rtx);
9039
9040  if (ival == (HOST_WIDE_INT) 0xffffffff)
9041    mode = SImode;
9042  else if (ival == 0xffff)
9043    mode = HImode;
9044  else
9045    {
9046      gcc_assert (ival == 0xff);
9047      mode = QImode;
9048    }
9049
9050  if (<MODE>mode == DImode)
9051    insn = (mode == SImode)
9052	   ? gen_zero_extendsidi2
9053	   : (mode == HImode)
9054	   ? gen_zero_extendhidi2
9055	   : gen_zero_extendqidi2;
9056  else
9057    {
9058      if (<MODE>mode != SImode)
9059	/* Zero extend to SImode to avoid partial register stalls.  */
9060	operands[0] = gen_lowpart (SImode, operands[0]);
9061
9062      insn = (mode == HImode)
9063	     ? gen_zero_extendhisi2
9064	     : gen_zero_extendqisi2;
9065    }
9066  emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
9067  DONE;
9068})
9069
9070(define_split
9071  [(set (match_operand:SWI48 0 "register_operand")
9072	(and:SWI48 (match_dup 0)
9073		   (const_int -65536)))
9074   (clobber (reg:CC FLAGS_REG))]
9075  "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9076    || optimize_function_for_size_p (cfun)"
9077  [(set (strict_low_part (match_dup 1)) (const_int 0))]
9078  "operands[1] = gen_lowpart (HImode, operands[0]);")
9079
9080(define_split
9081  [(set (match_operand:SWI248 0 "any_QIreg_operand")
9082	(and:SWI248 (match_dup 0)
9083		    (const_int -256)))
9084   (clobber (reg:CC FLAGS_REG))]
9085  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9086   && reload_completed"
9087  [(set (strict_low_part (match_dup 1)) (const_int 0))]
9088  "operands[1] = gen_lowpart (QImode, operands[0]);")
9089
9090(define_split
9091  [(set (match_operand:SWI248 0 "QIreg_operand")
9092	(and:SWI248 (match_dup 0)
9093		    (const_int -65281)))
9094   (clobber (reg:CC FLAGS_REG))]
9095  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9096   && reload_completed"
9097  [(parallel
9098     [(set (zero_extract:SI (match_dup 0)
9099			    (const_int 8)
9100			    (const_int 8))
9101	   (subreg:SI
9102	     (xor:QI
9103	       (subreg:QI
9104		 (zero_extract:SI (match_dup 0)
9105				  (const_int 8)
9106				  (const_int 8)) 0)
9107	       (subreg:QI
9108		 (zero_extract:SI (match_dup 0)
9109				  (const_int 8)
9110				  (const_int 8)) 0)) 0))
9111      (clobber (reg:CC FLAGS_REG))])]
9112  "operands[0] = gen_lowpart (SImode, operands[0]);")
9113
9114(define_insn "*anddi_2"
9115  [(set (reg FLAGS_REG)
9116	(compare
9117	 (and:DI
9118	  (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9119	  (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9120	 (const_int 0)))
9121   (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9122	(and:DI (match_dup 1) (match_dup 2)))]
9123  "TARGET_64BIT
9124   && ix86_match_ccmode
9125	(insn,
9126	 /* If we are going to emit andl instead of andq, and the operands[2]
9127	    constant might have the SImode sign bit set, make sure the sign
9128	    flag isn't tested, because the instruction will set the sign flag
9129	    based on bit 31 rather than bit 63.  If it isn't CONST_INT,
9130	    conservatively assume it might have bit 31 set.  */
9131	 (satisfies_constraint_Z (operands[2])
9132	  && (!CONST_INT_P (operands[2])
9133	      || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9134	 ? CCZmode : CCNOmode)
9135   && ix86_binary_operator_ok (AND, DImode, operands)"
9136  "@
9137   and{l}\t{%k2, %k0|%k0, %k2}
9138   and{q}\t{%2, %0|%0, %2}
9139   and{q}\t{%2, %0|%0, %2}"
9140  [(set_attr "type" "alu")
9141   (set_attr "mode" "SI,DI,DI")])
9142
9143;; See comment for addsi_1_zext why we do use nonimmediate_operand
9144(define_insn "*andsi_2_zext"
9145  [(set (reg FLAGS_REG)
9146	(compare (and:SI
9147		  (match_operand:SI 1 "nonimmediate_operand" "%0")
9148		  (match_operand:SI 2 "x86_64_general_operand" "rme"))
9149		 (const_int 0)))
9150   (set (match_operand:DI 0 "register_operand" "=r")
9151	(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9152  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9153   && ix86_binary_operator_ok (AND, SImode, operands)"
9154  "and{l}\t{%2, %k0|%k0, %2}"
9155  [(set_attr "type" "alu")
9156   (set_attr "mode" "SI")])
9157
9158(define_insn "*andqi_2_maybe_si"
9159  [(set (reg FLAGS_REG)
9160	(compare (and:QI
9161		  (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9162		  (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9163		 (const_int 0)))
9164   (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9165	(and:QI (match_dup 1) (match_dup 2)))]
9166  "ix86_binary_operator_ok (AND, QImode, operands)
9167   && ix86_match_ccmode (insn,
9168			 CONST_INT_P (operands[2])
9169			 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9170{
9171  if (which_alternative == 2)
9172    {
9173      if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9174        operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9175      return "and{l}\t{%2, %k0|%k0, %2}";
9176    }
9177  return "and{b}\t{%2, %0|%0, %2}";
9178}
9179  [(set_attr "type" "alu")
9180   (set_attr "mode" "QI,QI,SI")])
9181
9182(define_insn "*and<mode>_2"
9183  [(set (reg FLAGS_REG)
9184	(compare (and:SWI124
9185		  (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9186		  (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9187		 (const_int 0)))
9188   (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9189	(and:SWI124 (match_dup 1) (match_dup 2)))]
9190  "ix86_match_ccmode (insn, CCNOmode)
9191   && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9192  "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9193  [(set_attr "type" "alu")
9194   (set_attr "mode" "<MODE>")])
9195
9196(define_insn "*andqi_2_slp"
9197  [(set (reg FLAGS_REG)
9198	(compare (and:QI
9199		   (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9200		   (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9201		 (const_int 0)))
9202   (set (strict_low_part (match_dup 0))
9203	(and:QI (match_dup 0) (match_dup 1)))]
9204  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9205   && ix86_match_ccmode (insn, CCNOmode)
9206   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9207  "and{b}\t{%1, %0|%0, %1}"
9208  [(set_attr "type" "alu1")
9209   (set_attr "mode" "QI")])
9210
9211(define_insn "andqi_ext_1"
9212  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9213			 (const_int 8)
9214			 (const_int 8))
9215	(subreg:SI
9216	  (and:QI
9217	    (subreg:QI
9218	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9219			       (const_int 8)
9220			       (const_int 8)) 0)
9221	    (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9222   (clobber (reg:CC FLAGS_REG))]
9223  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9224   rtx_equal_p (operands[0], operands[1])"
9225  "and{b}\t{%2, %h0|%h0, %2}"
9226  [(set_attr "isa" "*,nox64")
9227   (set_attr "type" "alu")
9228   (set_attr "mode" "QI")])
9229
9230;; Generated by peephole translating test to and.  This shows up
9231;; often in fp comparisons.
9232(define_insn "*andqi_ext_1_cc"
9233  [(set (reg FLAGS_REG)
9234	(compare
9235	  (and:QI
9236	    (subreg:QI
9237	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9238			       (const_int 8)
9239			       (const_int 8)) 0)
9240	    (match_operand:QI 2 "general_operand" "QnBc,m"))
9241	  (const_int 0)))
9242   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9243			 (const_int 8)
9244			 (const_int 8))
9245	(subreg:SI
9246	  (and:QI
9247	    (subreg:QI
9248	      (zero_extract:SI (match_dup 1)
9249			       (const_int 8)
9250			       (const_int 8)) 0)
9251	    (match_dup 2)) 0))]
9252  "ix86_match_ccmode (insn, CCNOmode)
9253   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9254   && rtx_equal_p (operands[0], operands[1])"
9255  "and{b}\t{%2, %h0|%h0, %2}"
9256  [(set_attr "isa" "*,nox64")
9257   (set_attr "type" "alu")
9258   (set_attr "mode" "QI")])
9259
9260(define_insn "*andqi_ext_2"
9261  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9262			 (const_int 8)
9263			 (const_int 8))
9264	(subreg:SI
9265	  (and:QI
9266	    (subreg:QI
9267	      (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9268			       (const_int 8)
9269			       (const_int 8)) 0)
9270	    (subreg:QI
9271	      (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9272			       (const_int 8)
9273			       (const_int 8)) 0)) 0))
9274   (clobber (reg:CC FLAGS_REG))]
9275  "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9276   rtx_equal_p (operands[0], operands[1])
9277   || rtx_equal_p (operands[0], operands[2])"
9278  "and{b}\t{%h2, %h0|%h0, %h2}"
9279  [(set_attr "type" "alu")
9280   (set_attr "mode" "QI")])
9281
9282;; Convert wide AND instructions with immediate operand to shorter QImode
9283;; equivalents when possible.
9284;; Don't do the splitting with memory operands, since it introduces risk
9285;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9286;; for size, but that can (should?) be handled by generic code instead.
9287(define_split
9288  [(set (match_operand:SWI248 0 "QIreg_operand")
9289	(and:SWI248 (match_operand:SWI248 1 "register_operand")
9290		    (match_operand:SWI248 2 "const_int_operand")))
9291   (clobber (reg:CC FLAGS_REG))]
9292   "reload_completed
9293    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9294    && !(~INTVAL (operands[2]) & ~(255 << 8))"
9295  [(parallel
9296     [(set (zero_extract:SI (match_dup 0)
9297			    (const_int 8)
9298			    (const_int 8))
9299	   (subreg:SI
9300	     (and:QI
9301	       (subreg:QI
9302		 (zero_extract:SI (match_dup 1)
9303				  (const_int 8)
9304				  (const_int 8)) 0)
9305	       (match_dup 2)) 0))
9306      (clobber (reg:CC FLAGS_REG))])]
9307{
9308  operands[0] = gen_lowpart (SImode, operands[0]);
9309  operands[1] = gen_lowpart (SImode, operands[1]);
9310  operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9311})
9312
9313;; Since AND can be encoded with sign extended immediate, this is only
9314;; profitable when 7th bit is not set.
9315(define_split
9316  [(set (match_operand:SWI248 0 "any_QIreg_operand")
9317	(and:SWI248 (match_operand:SWI248 1 "general_operand")
9318		    (match_operand:SWI248 2 "const_int_operand")))
9319   (clobber (reg:CC FLAGS_REG))]
9320   "reload_completed
9321    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9322    && !(~INTVAL (operands[2]) & ~255)
9323    && !(INTVAL (operands[2]) & 128)"
9324  [(parallel [(set (strict_low_part (match_dup 0))
9325		   (and:QI (match_dup 1)
9326			   (match_dup 2)))
9327	      (clobber (reg:CC FLAGS_REG))])]
9328{
9329  operands[0] = gen_lowpart (QImode, operands[0]);
9330  operands[1] = gen_lowpart (QImode, operands[1]);
9331  operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9332})
9333
9334(define_insn "*andndi3_doubleword"
9335  [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9336	(and:DI
9337	  (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9338	  (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9339   (clobber (reg:CC FLAGS_REG))]
9340  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9341  "#"
9342  [(set_attr "isa" "bmi,bmi,bmi,*")])
9343
9344(define_split
9345  [(set (match_operand:DI 0 "register_operand")
9346	(and:DI
9347	  (not:DI (match_operand:DI 1 "register_operand"))
9348	  (match_operand:DI 2 "nonimmediate_operand")))
9349   (clobber (reg:CC FLAGS_REG))]
9350  "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9351   && reload_completed"
9352  [(parallel [(set (match_dup 0)
9353		   (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9354	      (clobber (reg:CC FLAGS_REG))])
9355   (parallel [(set (match_dup 3)
9356		   (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9357	      (clobber (reg:CC FLAGS_REG))])]
9358  "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9359
9360(define_split
9361  [(set (match_operand:DI 0 "register_operand")
9362	(and:DI
9363	  (not:DI (match_dup 0))
9364	  (match_operand:DI 1 "nonimmediate_operand")))
9365   (clobber (reg:CC FLAGS_REG))]
9366  "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9367   && reload_completed"
9368  [(set (match_dup 0) (not:SI (match_dup 0)))
9369   (parallel [(set (match_dup 0)
9370		   (and:SI (match_dup 0) (match_dup 1)))
9371	      (clobber (reg:CC FLAGS_REG))])
9372   (set (match_dup 2) (not:SI (match_dup 2)))
9373   (parallel [(set (match_dup 2)
9374		   (and:SI (match_dup 2) (match_dup 3)))
9375	      (clobber (reg:CC FLAGS_REG))])]
9376  "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9377
9378(define_insn "*andn<mode>_1"
9379  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9380	(and:SWI48
9381	  (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9382	  (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9383   (clobber (reg:CC FLAGS_REG))]
9384  "TARGET_BMI"
9385  "andn\t{%2, %1, %0|%0, %1, %2}"
9386  [(set_attr "type" "bitmanip")
9387   (set_attr "btver2_decode" "direct, double")
9388   (set_attr "mode" "<MODE>")])
9389
9390(define_insn "*andn<mode>_1"
9391  [(set (match_operand:SWI12 0 "register_operand" "=r")
9392	(and:SWI12
9393	  (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9394	  (match_operand:SWI12 2 "register_operand" "r")))
9395   (clobber (reg:CC FLAGS_REG))]
9396  "TARGET_BMI"
9397  "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9398  [(set_attr "type" "bitmanip")
9399   (set_attr "btver2_decode" "direct")
9400   (set_attr "mode" "SI")])
9401
9402(define_insn "*andn_<mode>_ccno"
9403  [(set (reg FLAGS_REG)
9404	(compare
9405	  (and:SWI48
9406	    (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9407	    (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9408	  (const_int 0)))
9409   (clobber (match_scratch:SWI48 0 "=r,r"))]
9410  "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9411  "andn\t{%2, %1, %0|%0, %1, %2}"
9412  [(set_attr "type" "bitmanip")
9413   (set_attr "btver2_decode" "direct, double")
9414   (set_attr "mode" "<MODE>")])
9415
9416;; Logical inclusive and exclusive OR instructions
9417
9418;; %%% This used to optimize known byte-wide and operations to memory.
9419;; If this is considered useful, it should be done with splitters.
9420
9421(define_expand "<code><mode>3"
9422  [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9423	(any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9424			     (match_operand:SWIM1248x 2 "<general_operand>")))]
9425  ""
9426  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9427
9428(define_insn_and_split "*<code>di3_doubleword"
9429  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9430	(any_or:DI
9431	 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9432	 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9433   (clobber (reg:CC FLAGS_REG))]
9434  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9435   && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9436  "#"
9437  "&& reload_completed"
9438  [(const_int 0)]
9439{
9440  split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9441  if (operands[2] == constm1_rtx)
9442    {
9443      if (<CODE> == IOR)
9444	{
9445	  operands[1] = constm1_rtx;
9446	  ix86_expand_move (SImode, &operands[0]);
9447	}
9448      else
9449	ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9450    }
9451  else if (operands[2] != const0_rtx)
9452    ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9453  else if (operands[5] == const0_rtx)
9454    emit_note (NOTE_INSN_DELETED);
9455  if (operands[5] == constm1_rtx)
9456    {
9457      if (<CODE> == IOR)
9458	{
9459	  operands[4] = constm1_rtx;
9460	  ix86_expand_move (SImode, &operands[3]);
9461	}
9462      else
9463	ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9464    }
9465  else if (operands[5] != const0_rtx)
9466    ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9467  DONE;
9468})
9469
9470(define_insn "*<code><mode>_1"
9471  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9472	(any_or:SWI248
9473	 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9474	 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9475   (clobber (reg:CC FLAGS_REG))]
9476  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9477  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9478  [(set_attr "type" "alu")
9479   (set_attr "mode" "<MODE>")])
9480
9481(define_insn_and_split "*iordi_1_bts"
9482  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9483	(ior:DI
9484	 (match_operand:DI 1 "nonimmediate_operand" "%0")
9485	 (match_operand:DI 2 "const_int_operand" "n")))
9486   (clobber (reg:CC FLAGS_REG))]
9487  "TARGET_64BIT && TARGET_USE_BT
9488   && ix86_binary_operator_ok (IOR, DImode, operands)
9489   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9490  "#"
9491  "&& reload_completed"
9492  [(parallel [(set (zero_extract:DI (match_dup 0)
9493				    (const_int 1)
9494				    (match_dup 3))
9495		   (const_int 1))
9496	      (clobber (reg:CC FLAGS_REG))])]
9497  "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9498  [(set_attr "type" "alu1")
9499   (set_attr "prefix_0f" "1")
9500   (set_attr "znver1_decode" "double")
9501   (set_attr "mode" "DI")])
9502
9503(define_insn_and_split "*xordi_1_btc"
9504  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9505	(xor:DI
9506	 (match_operand:DI 1 "nonimmediate_operand" "%0")
9507	 (match_operand:DI 2 "const_int_operand" "n")))
9508   (clobber (reg:CC FLAGS_REG))]
9509  "TARGET_64BIT && TARGET_USE_BT
9510   && ix86_binary_operator_ok (XOR, DImode, operands)
9511   && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9512  "#"
9513  "&& reload_completed"
9514  [(parallel [(set (zero_extract:DI (match_dup 0)
9515				    (const_int 1)
9516				    (match_dup 3))
9517		   (not:DI (zero_extract:DI (match_dup 0)
9518					    (const_int 1)
9519					    (match_dup 3))))
9520	      (clobber (reg:CC FLAGS_REG))])]
9521  "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9522  [(set_attr "type" "alu1")
9523   (set_attr "prefix_0f" "1")
9524   (set_attr "znver1_decode" "double")
9525   (set_attr "mode" "DI")])
9526
9527;; See comment for addsi_1_zext why we do use nonimmediate_operand
9528(define_insn "*<code>si_1_zext"
9529  [(set (match_operand:DI 0 "register_operand" "=r")
9530	(zero_extend:DI
9531	 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9532		    (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9533   (clobber (reg:CC FLAGS_REG))]
9534  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9535  "<logic>{l}\t{%2, %k0|%k0, %2}"
9536  [(set_attr "type" "alu")
9537   (set_attr "mode" "SI")])
9538
9539(define_insn "*<code>si_1_zext_imm"
9540  [(set (match_operand:DI 0 "register_operand" "=r")
9541	(any_or:DI
9542	 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9543	 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9544   (clobber (reg:CC FLAGS_REG))]
9545  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9546  "<logic>{l}\t{%2, %k0|%k0, %2}"
9547  [(set_attr "type" "alu")
9548   (set_attr "mode" "SI")])
9549
9550(define_insn "*<code>qi_1"
9551  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9552	(any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9553		   (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9554   (clobber (reg:CC FLAGS_REG))]
9555  "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9556  "@
9557   <logic>{b}\t{%2, %0|%0, %2}
9558   <logic>{b}\t{%2, %0|%0, %2}
9559   <logic>{l}\t{%k2, %k0|%k0, %k2}"
9560  [(set_attr "type" "alu")
9561   (set_attr "mode" "QI,QI,SI")
9562   ;; Potential partial reg stall on alternative 2.
9563   (set (attr "preferred_for_speed")
9564     (cond [(eq_attr "alternative" "2")
9565	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9566	   (symbol_ref "true")))])
9567
9568(define_insn "*<code>qi_1_slp"
9569  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9570	(any_or:QI (match_dup 0)
9571		   (match_operand:QI 1 "general_operand" "qmn,qn")))
9572   (clobber (reg:CC FLAGS_REG))]
9573  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9574   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9575  "<logic>{b}\t{%1, %0|%0, %1}"
9576  [(set_attr "type" "alu1")
9577   (set_attr "mode" "QI")])
9578
9579(define_insn "*<code><mode>_2"
9580  [(set (reg FLAGS_REG)
9581	(compare (any_or:SWI
9582		  (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9583		  (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9584		 (const_int 0)))
9585   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9586	(any_or:SWI (match_dup 1) (match_dup 2)))]
9587  "ix86_match_ccmode (insn, CCNOmode)
9588   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9589  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9590  [(set_attr "type" "alu")
9591   (set_attr "mode" "<MODE>")])
9592
9593;; See comment for addsi_1_zext why we do use nonimmediate_operand
9594;; ??? Special case for immediate operand is missing - it is tricky.
9595(define_insn "*<code>si_2_zext"
9596  [(set (reg FLAGS_REG)
9597	(compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9598			    (match_operand:SI 2 "x86_64_general_operand" "rme"))
9599		 (const_int 0)))
9600   (set (match_operand:DI 0 "register_operand" "=r")
9601	(zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9602  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9603   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9604  "<logic>{l}\t{%2, %k0|%k0, %2}"
9605  [(set_attr "type" "alu")
9606   (set_attr "mode" "SI")])
9607
9608(define_insn "*<code>si_2_zext_imm"
9609  [(set (reg FLAGS_REG)
9610	(compare (any_or:SI
9611		  (match_operand:SI 1 "nonimmediate_operand" "%0")
9612		  (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9613		 (const_int 0)))
9614   (set (match_operand:DI 0 "register_operand" "=r")
9615	(any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9616  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9617   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9618  "<logic>{l}\t{%2, %k0|%k0, %2}"
9619  [(set_attr "type" "alu")
9620   (set_attr "mode" "SI")])
9621
9622(define_insn "*<code>qi_2_slp"
9623  [(set (reg FLAGS_REG)
9624	(compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9625			    (match_operand:QI 1 "general_operand" "qmn,qn"))
9626		 (const_int 0)))
9627   (set (strict_low_part (match_dup 0))
9628	(any_or:QI (match_dup 0) (match_dup 1)))]
9629  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9630   && ix86_match_ccmode (insn, CCNOmode)
9631   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9632  "<logic>{b}\t{%1, %0|%0, %1}"
9633  [(set_attr "type" "alu1")
9634   (set_attr "mode" "QI")])
9635
9636(define_insn "*<code><mode>_3"
9637  [(set (reg FLAGS_REG)
9638	(compare (any_or:SWI
9639		  (match_operand:SWI 1 "nonimmediate_operand" "%0")
9640		  (match_operand:SWI 2 "<general_operand>" "<g>"))
9641		 (const_int 0)))
9642   (clobber (match_scratch:SWI 0 "=<r>"))]
9643  "ix86_match_ccmode (insn, CCNOmode)
9644   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9645  "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9646  [(set_attr "type" "alu")
9647   (set_attr "mode" "<MODE>")])
9648
9649(define_insn "*<code>qi_ext_1"
9650  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9651			 (const_int 8)
9652			 (const_int 8))
9653	(subreg:SI
9654	  (any_or:QI
9655	    (subreg:QI
9656	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9657			       (const_int 8)
9658			       (const_int 8)) 0)
9659	    (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9660   (clobber (reg:CC FLAGS_REG))]
9661  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9662   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9663   && rtx_equal_p (operands[0], operands[1])"
9664  "<logic>{b}\t{%2, %h0|%h0, %2}"
9665  [(set_attr "isa" "*,nox64")
9666   (set_attr "type" "alu")
9667   (set_attr "mode" "QI")])
9668
9669(define_insn "*<code>qi_ext_2"
9670  [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9671			 (const_int 8)
9672			 (const_int 8))
9673	(subreg:SI
9674	  (any_or:QI
9675	    (subreg:QI
9676	      (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9677			       (const_int 8)
9678			       (const_int 8)) 0)
9679	    (subreg:QI
9680	      (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9681			       (const_int 8)
9682			       (const_int 8)) 0)) 0))
9683   (clobber (reg:CC FLAGS_REG))]
9684  "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9685   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9686   && (rtx_equal_p (operands[0], operands[1])
9687       || rtx_equal_p (operands[0], operands[2]))"
9688  "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9689  [(set_attr "type" "alu")
9690   (set_attr "mode" "QI")])
9691
9692;; Convert wide OR instructions with immediate operand to shorter QImode
9693;; equivalents when possible.
9694;; Don't do the splitting with memory operands, since it introduces risk
9695;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9696;; for size, but that can (should?) be handled by generic code instead.
9697(define_split
9698  [(set (match_operand:SWI248 0 "QIreg_operand")
9699	(any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9700		       (match_operand:SWI248 2 "const_int_operand")))
9701   (clobber (reg:CC FLAGS_REG))]
9702   "reload_completed
9703    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9704    && !(INTVAL (operands[2]) & ~(255 << 8))"
9705  [(parallel
9706     [(set (zero_extract:SI (match_dup 0)
9707			    (const_int 8)
9708			    (const_int 8))
9709	   (subreg:SI
9710	     (any_or:QI
9711	       (subreg:QI
9712		 (zero_extract:SI (match_dup 1)
9713				  (const_int 8)
9714				  (const_int 8)) 0)
9715	       (match_dup 2)) 0))
9716      (clobber (reg:CC FLAGS_REG))])]
9717{
9718  operands[0] = gen_lowpart (SImode, operands[0]);
9719  operands[1] = gen_lowpart (SImode, operands[1]);
9720  operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9721})
9722
9723;; Since OR can be encoded with sign extended immediate, this is only
9724;; profitable when 7th bit is set.
9725(define_split
9726  [(set (match_operand:SWI248 0 "any_QIreg_operand")
9727	(any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9728		       (match_operand:SWI248 2 "const_int_operand")))
9729   (clobber (reg:CC FLAGS_REG))]
9730   "reload_completed
9731    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9732    && !(INTVAL (operands[2]) & ~255)
9733    && (INTVAL (operands[2]) & 128)"
9734  [(parallel [(set (strict_low_part (match_dup 0))
9735		   (any_or:QI (match_dup 1)
9736			      (match_dup 2)))
9737	      (clobber (reg:CC FLAGS_REG))])]
9738{
9739  operands[0] = gen_lowpart (QImode, operands[0]);
9740  operands[1] = gen_lowpart (QImode, operands[1]);
9741  operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9742})
9743
9744(define_expand "xorqi_ext_1_cc"
9745  [(parallel [
9746     (set (reg:CCNO FLAGS_REG)
9747	  (compare:CCNO
9748	    (xor:QI
9749	      (subreg:QI
9750		(zero_extract:SI (match_operand 1 "ext_register_operand")
9751				 (const_int 8)
9752				 (const_int 8)) 0)
9753	      (match_operand 2 "const_int_operand"))
9754	    (const_int 0)))
9755     (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9756			   (const_int 8)
9757			   (const_int 8))
9758	  (subreg:SI
9759	    (xor:QI
9760	      (subreg:QI
9761		(zero_extract:SI (match_dup 1)
9762				 (const_int 8)
9763				 (const_int 8)) 0)
9764	    (match_dup 2)) 0))])])
9765
9766(define_insn "*xorqi_ext_1_cc"
9767  [(set (reg FLAGS_REG)
9768	(compare
9769	  (xor:QI
9770	    (subreg:QI
9771	      (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9772			       (const_int 8)
9773			       (const_int 8)) 0)
9774	    (match_operand:QI 2 "general_operand" "QnBc,m"))
9775	  (const_int 0)))
9776   (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9777			 (const_int 8)
9778			 (const_int 8))
9779	(subreg:SI
9780	  (xor:QI
9781	    (subreg:QI
9782	      (zero_extract:SI (match_dup 1)
9783			       (const_int 8)
9784			       (const_int 8)) 0)
9785	  (match_dup 2)) 0))]
9786  "ix86_match_ccmode (insn, CCNOmode)
9787   /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9788   && rtx_equal_p (operands[0], operands[1])"
9789  "xor{b}\t{%2, %h0|%h0, %2}"
9790  [(set_attr "isa" "*,nox64")
9791   (set_attr "type" "alu")
9792   (set_attr "mode" "QI")])
9793
9794;; Negation instructions
9795
9796(define_expand "neg<mode>2"
9797  [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9798	(neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9799  ""
9800  "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9801
9802(define_insn_and_split "*neg<dwi>2_doubleword"
9803  [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9804	(neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9805   (clobber (reg:CC FLAGS_REG))]
9806  "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9807  "#"
9808  "reload_completed"
9809  [(parallel
9810    [(set (reg:CCZ FLAGS_REG)
9811	  (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9812     (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9813   (parallel
9814    [(set (match_dup 2)
9815	  (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9816				(match_dup 3))
9817		     (const_int 0)))
9818     (clobber (reg:CC FLAGS_REG))])
9819   (parallel
9820    [(set (match_dup 2)
9821	  (neg:DWIH (match_dup 2)))
9822     (clobber (reg:CC FLAGS_REG))])]
9823  "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9824
9825(define_insn "*neg<mode>2_1"
9826  [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9827	(neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9828   (clobber (reg:CC FLAGS_REG))]
9829  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9830  "neg{<imodesuffix>}\t%0"
9831  [(set_attr "type" "negnot")
9832   (set_attr "mode" "<MODE>")])
9833
9834;; Combine is quite creative about this pattern.
9835(define_insn "*negsi2_1_zext"
9836  [(set (match_operand:DI 0 "register_operand" "=r")
9837	(lshiftrt:DI
9838	  (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9839			     (const_int 32)))
9840	(const_int 32)))
9841   (clobber (reg:CC FLAGS_REG))]
9842  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9843  "neg{l}\t%k0"
9844  [(set_attr "type" "negnot")
9845   (set_attr "mode" "SI")])
9846
9847;; The problem with neg is that it does not perform (compare x 0),
9848;; it really performs (compare 0 x), which leaves us with the zero
9849;; flag being the only useful item.
9850
9851(define_insn "*neg<mode>2_cmpz"
9852  [(set (reg:CCZ FLAGS_REG)
9853	(compare:CCZ
9854	  (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9855		   (const_int 0)))
9856   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9857	(neg:SWI (match_dup 1)))]
9858  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9859  "neg{<imodesuffix>}\t%0"
9860  [(set_attr "type" "negnot")
9861   (set_attr "mode" "<MODE>")])
9862
9863(define_insn "*negsi2_cmpz_zext"
9864  [(set (reg:CCZ FLAGS_REG)
9865	(compare:CCZ
9866	  (lshiftrt:DI
9867	    (neg:DI (ashift:DI
9868		      (match_operand:DI 1 "register_operand" "0")
9869		      (const_int 32)))
9870	    (const_int 32))
9871	  (const_int 0)))
9872   (set (match_operand:DI 0 "register_operand" "=r")
9873	(lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9874					(const_int 32)))
9875		     (const_int 32)))]
9876  "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9877  "neg{l}\t%k0"
9878  [(set_attr "type" "negnot")
9879   (set_attr "mode" "SI")])
9880
9881;; Negate with jump on overflow.
9882(define_expand "negv<mode>3"
9883  [(parallel [(set (reg:CCO FLAGS_REG)
9884		   (ne:CCO (match_operand:SWI 1 "register_operand")
9885			   (match_dup 3)))
9886	      (set (match_operand:SWI 0 "register_operand")
9887		   (neg:SWI (match_dup 1)))])
9888   (set (pc) (if_then_else
9889	       (eq (reg:CCO FLAGS_REG) (const_int 0))
9890	       (label_ref (match_operand 2))
9891	       (pc)))]
9892  ""
9893{
9894  operands[3]
9895    = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9896		    <MODE>mode);
9897})
9898
9899(define_insn "*negv<mode>3"
9900  [(set (reg:CCO FLAGS_REG)
9901	(ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9902		(match_operand:SWI 2 "const_int_operand")))
9903   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9904	(neg:SWI (match_dup 1)))]
9905  "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9906   && mode_signbit_p (<MODE>mode, operands[2])"
9907  "neg{<imodesuffix>}\t%0"
9908  [(set_attr "type" "negnot")
9909   (set_attr "mode" "<MODE>")])
9910
9911;; Changing of sign for FP values is doable using integer unit too.
9912
9913(define_expand "<code><mode>2"
9914  [(set (match_operand:X87MODEF 0 "register_operand")
9915	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9916  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9917  "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9918
9919(define_insn "*absneg<mode>2"
9920  [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9921	(match_operator:MODEF 3 "absneg_operator"
9922	  [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9923   (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9924   (clobber (reg:CC FLAGS_REG))]
9925  "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9926  "#"
9927  [(set (attr "enabled")
9928     (if_then_else
9929       (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9930       (if_then_else
9931	 (eq_attr "alternative" "2")
9932	 (symbol_ref "TARGET_MIX_SSE_I387")
9933	 (symbol_ref "true"))
9934       (if_then_else
9935	 (eq_attr "alternative" "2,3")
9936	 (symbol_ref "true")
9937	 (symbol_ref "false"))))])
9938
9939(define_insn "*absnegxf2_i387"
9940  [(set (match_operand:XF 0 "register_operand" "=f,!r")
9941	(match_operator:XF 3 "absneg_operator"
9942	  [(match_operand:XF 1 "register_operand" "0,0")]))
9943   (use (match_operand 2))
9944   (clobber (reg:CC FLAGS_REG))]
9945  "TARGET_80387"
9946  "#")
9947
9948(define_expand "<code>tf2"
9949  [(set (match_operand:TF 0 "register_operand")
9950	(absneg:TF (match_operand:TF 1 "register_operand")))]
9951  "TARGET_SSE"
9952  "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9953
9954(define_insn "*absnegtf2_sse"
9955  [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9956	(match_operator:TF 3 "absneg_operator"
9957	  [(match_operand:TF 1 "register_operand" "0,Yv")]))
9958   (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9959   (clobber (reg:CC FLAGS_REG))]
9960  "TARGET_SSE"
9961  "#")
9962
9963;; Splitters for fp abs and neg.
9964
9965(define_split
9966  [(set (match_operand 0 "fp_register_operand")
9967	(match_operator 1 "absneg_operator" [(match_dup 0)]))
9968   (use (match_operand 2))
9969   (clobber (reg:CC FLAGS_REG))]
9970  "reload_completed"
9971  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9972
9973(define_split
9974  [(set (match_operand 0 "sse_reg_operand")
9975	(match_operator 3 "absneg_operator"
9976	  [(match_operand 1 "register_operand")]))
9977   (use (match_operand 2 "nonimmediate_operand"))
9978   (clobber (reg:CC FLAGS_REG))]
9979  "reload_completed"
9980  [(set (match_dup 0) (match_dup 3))]
9981{
9982  machine_mode mode = GET_MODE (operands[0]);
9983  machine_mode vmode = GET_MODE (operands[2]);
9984  rtx tmp;
9985
9986  operands[0] = lowpart_subreg (vmode, operands[0], mode);
9987  operands[1] = lowpart_subreg (vmode, operands[1], mode);
9988  if (operands_match_p (operands[0], operands[2]))
9989    std::swap (operands[1], operands[2]);
9990  if (GET_CODE (operands[3]) == ABS)
9991    tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9992  else
9993    tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9994  operands[3] = tmp;
9995})
9996
9997(define_split
9998  [(set (match_operand:SF 0 "general_reg_operand")
9999	(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10000   (use (match_operand:V4SF 2))
10001   (clobber (reg:CC FLAGS_REG))]
10002  "reload_completed"
10003  [(parallel [(set (match_dup 0) (match_dup 1))
10004	      (clobber (reg:CC FLAGS_REG))])]
10005{
10006  rtx tmp;
10007  operands[0] = gen_lowpart (SImode, operands[0]);
10008  if (GET_CODE (operands[1]) == ABS)
10009    {
10010      tmp = gen_int_mode (0x7fffffff, SImode);
10011      tmp = gen_rtx_AND (SImode, operands[0], tmp);
10012    }
10013  else
10014    {
10015      tmp = gen_int_mode (0x80000000, SImode);
10016      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10017    }
10018  operands[1] = tmp;
10019})
10020
10021(define_split
10022  [(set (match_operand:DF 0 "general_reg_operand")
10023	(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10024   (use (match_operand 2))
10025   (clobber (reg:CC FLAGS_REG))]
10026  "reload_completed"
10027  [(parallel [(set (match_dup 0) (match_dup 1))
10028	      (clobber (reg:CC FLAGS_REG))])]
10029{
10030  rtx tmp;
10031  if (TARGET_64BIT)
10032    {
10033      tmp = gen_lowpart (DImode, operands[0]);
10034      tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10035      operands[0] = tmp;
10036
10037      if (GET_CODE (operands[1]) == ABS)
10038	tmp = const0_rtx;
10039      else
10040	tmp = gen_rtx_NOT (DImode, tmp);
10041    }
10042  else
10043    {
10044      operands[0] = gen_highpart (SImode, operands[0]);
10045      if (GET_CODE (operands[1]) == ABS)
10046	{
10047	  tmp = gen_int_mode (0x7fffffff, SImode);
10048	  tmp = gen_rtx_AND (SImode, operands[0], tmp);
10049	}
10050      else
10051	{
10052	  tmp = gen_int_mode (0x80000000, SImode);
10053	  tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10054	}
10055    }
10056  operands[1] = tmp;
10057})
10058
10059(define_split
10060  [(set (match_operand:XF 0 "general_reg_operand")
10061	(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10062   (use (match_operand 2))
10063   (clobber (reg:CC FLAGS_REG))]
10064  "reload_completed"
10065  [(parallel [(set (match_dup 0) (match_dup 1))
10066	      (clobber (reg:CC FLAGS_REG))])]
10067{
10068  rtx tmp;
10069  operands[0] = gen_rtx_REG (SImode,
10070			     REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
10071  if (GET_CODE (operands[1]) == ABS)
10072    {
10073      tmp = GEN_INT (0x7fff);
10074      tmp = gen_rtx_AND (SImode, operands[0], tmp);
10075    }
10076  else
10077    {
10078      tmp = GEN_INT (0x8000);
10079      tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10080    }
10081  operands[1] = tmp;
10082})
10083
10084;; Conditionalize these after reload. If they match before reload, we
10085;; lose the clobber and ability to use integer instructions.
10086
10087(define_insn "*<code><mode>2_1"
10088  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10089	(absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10090  "TARGET_80387
10091   && (reload_completed
10092       || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10093  "f<absneg_mnemonic>"
10094  [(set_attr "type" "fsgn")
10095   (set_attr "mode" "<MODE>")])
10096
10097(define_insn "*<code>extendsfdf2"
10098  [(set (match_operand:DF 0 "register_operand" "=f")
10099	(absneg:DF (float_extend:DF
10100		     (match_operand:SF 1 "register_operand" "0"))))]
10101  "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10102  "f<absneg_mnemonic>"
10103  [(set_attr "type" "fsgn")
10104   (set_attr "mode" "DF")])
10105
10106(define_insn "*<code>extendsfxf2"
10107  [(set (match_operand:XF 0 "register_operand" "=f")
10108	(absneg:XF (float_extend:XF
10109		     (match_operand:SF 1 "register_operand" "0"))))]
10110  "TARGET_80387"
10111  "f<absneg_mnemonic>"
10112  [(set_attr "type" "fsgn")
10113   (set_attr "mode" "XF")])
10114
10115(define_insn "*<code>extenddfxf2"
10116  [(set (match_operand:XF 0 "register_operand" "=f")
10117	(absneg:XF (float_extend:XF
10118		     (match_operand:DF 1 "register_operand" "0"))))]
10119  "TARGET_80387"
10120  "f<absneg_mnemonic>"
10121  [(set_attr "type" "fsgn")
10122   (set_attr "mode" "XF")])
10123
10124;; Copysign instructions
10125
10126(define_mode_iterator CSGNMODE [SF DF TF])
10127(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10128
10129(define_expand "copysign<mode>3"
10130  [(match_operand:CSGNMODE 0 "register_operand")
10131   (match_operand:CSGNMODE 1 "nonmemory_operand")
10132   (match_operand:CSGNMODE 2 "register_operand")]
10133  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10134   || (TARGET_SSE && (<MODE>mode == TFmode))"
10135  "ix86_expand_copysign (operands); DONE;")
10136
10137(define_insn_and_split "copysign<mode>3_const"
10138  [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10139	(unspec:CSGNMODE
10140	  [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10141	   (match_operand:CSGNMODE 2 "register_operand" "0")
10142	   (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10143	  UNSPEC_COPYSIGN))]
10144  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10145   || (TARGET_SSE && (<MODE>mode == TFmode))"
10146  "#"
10147  "&& reload_completed"
10148  [(const_int 0)]
10149  "ix86_split_copysign_const (operands); DONE;")
10150
10151(define_insn "copysign<mode>3_var"
10152  [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10153	(unspec:CSGNMODE
10154	  [(match_operand:CSGNMODE 2 "register_operand"	"Yv,0,0,Yv,Yv")
10155	   (match_operand:CSGNMODE 3 "register_operand"	"1,1,Yv,1,Yv")
10156	   (match_operand:<CSGNVMODE> 4
10157	     "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10158	   (match_operand:<CSGNVMODE> 5
10159	     "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10160	  UNSPEC_COPYSIGN))
10161   (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10162  "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10163   || (TARGET_SSE && (<MODE>mode == TFmode))"
10164  "#")
10165
10166(define_split
10167  [(set (match_operand:CSGNMODE 0 "register_operand")
10168	(unspec:CSGNMODE
10169	  [(match_operand:CSGNMODE 2 "register_operand")
10170	   (match_operand:CSGNMODE 3 "register_operand")
10171	   (match_operand:<CSGNVMODE> 4)
10172	   (match_operand:<CSGNVMODE> 5)]
10173	  UNSPEC_COPYSIGN))
10174   (clobber (match_scratch:<CSGNVMODE> 1))]
10175  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10176    || (TARGET_SSE && (<MODE>mode == TFmode)))
10177   && reload_completed"
10178  [(const_int 0)]
10179  "ix86_split_copysign_var (operands); DONE;")
10180
10181;; One complement instructions
10182
10183(define_expand "one_cmpl<mode>2"
10184  [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10185	(not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10186  ""
10187  "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10188
10189(define_insn_and_split "*one_cmpldi2_doubleword"
10190  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10191	(not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10192  "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10193   && ix86_unary_operator_ok (NOT, DImode, operands)"
10194  "#"
10195  "&& reload_completed"
10196  [(set (match_dup 0)
10197	(not:SI (match_dup 1)))
10198   (set (match_dup 2)
10199	(not:SI (match_dup 3)))]
10200  "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10201
10202(define_insn "*one_cmpl<mode>2_1"
10203  [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10204	(not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10205  "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10206  "not{<imodesuffix>}\t%0"
10207  [(set_attr "type" "negnot")
10208   (set_attr "mode" "<MODE>")])
10209
10210;; ??? Currently never generated - xor is used instead.
10211(define_insn "*one_cmplsi2_1_zext"
10212  [(set (match_operand:DI 0 "register_operand" "=r")
10213	(zero_extend:DI
10214	  (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10215  "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10216  "not{l}\t%k0"
10217  [(set_attr "type" "negnot")
10218   (set_attr "mode" "SI")])
10219
10220(define_insn "*one_cmplqi2_1"
10221  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10222	(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10223  "ix86_unary_operator_ok (NOT, QImode, operands)"
10224  "@
10225   not{b}\t%0
10226   not{l}\t%k0"
10227  [(set_attr "type" "negnot")
10228   (set_attr "mode" "QI,SI")
10229   ;; Potential partial reg stall on alternative 1.
10230   (set (attr "preferred_for_speed")
10231     (cond [(eq_attr "alternative" "1")
10232	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10233	   (symbol_ref "true")))])
10234
10235(define_insn "*one_cmpl<mode>2_2"
10236  [(set (reg FLAGS_REG)
10237	(compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10238		 (const_int 0)))
10239   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10240	(not:SWI (match_dup 1)))]
10241  "ix86_match_ccmode (insn, CCNOmode)
10242   && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10243  "#"
10244  [(set_attr "type" "alu1")
10245   (set_attr "mode" "<MODE>")])
10246
10247(define_split
10248  [(set (match_operand 0 "flags_reg_operand")
10249	(match_operator 2 "compare_operator"
10250	  [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10251	   (const_int 0)]))
10252   (set (match_operand:SWI 1 "nonimmediate_operand")
10253	(not:SWI (match_dup 3)))]
10254  "ix86_match_ccmode (insn, CCNOmode)"
10255  [(parallel [(set (match_dup 0)
10256		   (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10257				    (const_int 0)]))
10258	      (set (match_dup 1)
10259		   (xor:SWI (match_dup 3) (const_int -1)))])])
10260
10261;; ??? Currently never generated - xor is used instead.
10262(define_insn "*one_cmplsi2_2_zext"
10263  [(set (reg FLAGS_REG)
10264	(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10265		 (const_int 0)))
10266   (set (match_operand:DI 0 "register_operand" "=r")
10267	(zero_extend:DI (not:SI (match_dup 1))))]
10268  "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10269   && ix86_unary_operator_ok (NOT, SImode, operands)"
10270  "#"
10271  [(set_attr "type" "alu1")
10272   (set_attr "mode" "SI")])
10273
10274(define_split
10275  [(set (match_operand 0 "flags_reg_operand")
10276	(match_operator 2 "compare_operator"
10277	  [(not:SI (match_operand:SI 3 "register_operand"))
10278	   (const_int 0)]))
10279   (set (match_operand:DI 1 "register_operand")
10280	(zero_extend:DI (not:SI (match_dup 3))))]
10281  "ix86_match_ccmode (insn, CCNOmode)"
10282  [(parallel [(set (match_dup 0)
10283		   (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10284				    (const_int 0)]))
10285	      (set (match_dup 1)
10286		   (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10287
10288;; Shift instructions
10289
10290;; DImode shifts are implemented using the i386 "shift double" opcode,
10291;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10292;; is variable, then the count is in %cl and the "imm" operand is dropped
10293;; from the assembler input.
10294;;
10295;; This instruction shifts the target reg/mem as usual, but instead of
10296;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10297;; is a left shift double, bits are taken from the high order bits of
10298;; reg, else if the insn is a shift right double, bits are taken from the
10299;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10300;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10301;;
10302;; Since sh[lr]d does not change the `reg' operand, that is done
10303;; separately, making all shifts emit pairs of shift double and normal
10304;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10305;; support a 63 bit shift, each shift where the count is in a reg expands
10306;; to a pair of shifts, a branch, a shift by 32 and a label.
10307;;
10308;; If the shift count is a constant, we need never emit more than one
10309;; shift pair, instead using moves and sign extension for counts greater
10310;; than 31.
10311
10312(define_expand "ashl<mode>3"
10313  [(set (match_operand:SDWIM 0 "<shift_operand>")
10314	(ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10315		      (match_operand:QI 2 "nonmemory_operand")))]
10316  ""
10317  "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10318
10319(define_insn "*ashl<mode>3_doubleword"
10320  [(set (match_operand:DWI 0 "register_operand" "=&r")
10321	(ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10322		    (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10323   (clobber (reg:CC FLAGS_REG))]
10324  ""
10325  "#"
10326  [(set_attr "type" "multi")])
10327
10328(define_split
10329  [(set (match_operand:DWI 0 "register_operand")
10330	(ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10331		    (match_operand:QI 2 "nonmemory_operand")))
10332   (clobber (reg:CC FLAGS_REG))]
10333  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10334  [(const_int 0)]
10335  "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10336
10337;; By default we don't ask for a scratch register, because when DWImode
10338;; values are manipulated, registers are already at a premium.  But if
10339;; we have one handy, we won't turn it away.
10340
10341(define_peephole2
10342  [(match_scratch:DWIH 3 "r")
10343   (parallel [(set (match_operand:<DWI> 0 "register_operand")
10344		   (ashift:<DWI>
10345		     (match_operand:<DWI> 1 "nonmemory_operand")
10346		     (match_operand:QI 2 "nonmemory_operand")))
10347	      (clobber (reg:CC FLAGS_REG))])
10348   (match_dup 3)]
10349  "TARGET_CMOVE"
10350  [(const_int 0)]
10351  "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10352
10353(define_insn "x86_64_shld"
10354  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10355        (ior:DI (ashift:DI (match_dup 0)
10356		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
10357		(lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10358		  (minus:QI (const_int 64) (match_dup 2)))))
10359   (clobber (reg:CC FLAGS_REG))]
10360  "TARGET_64BIT"
10361  "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10362  [(set_attr "type" "ishift")
10363   (set_attr "prefix_0f" "1")
10364   (set_attr "mode" "DI")
10365   (set_attr "athlon_decode" "vector")
10366   (set_attr "amdfam10_decode" "vector")
10367   (set_attr "bdver1_decode" "vector")])
10368
10369(define_insn "x86_shld"
10370  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10371        (ior:SI (ashift:SI (match_dup 0)
10372		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
10373		(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10374		  (minus:QI (const_int 32) (match_dup 2)))))
10375   (clobber (reg:CC FLAGS_REG))]
10376  ""
10377  "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10378  [(set_attr "type" "ishift")
10379   (set_attr "prefix_0f" "1")
10380   (set_attr "mode" "SI")
10381   (set_attr "pent_pair" "np")
10382   (set_attr "athlon_decode" "vector")
10383   (set_attr "amdfam10_decode" "vector")
10384   (set_attr "bdver1_decode" "vector")])
10385
10386(define_expand "x86_shift<mode>_adj_1"
10387  [(set (reg:CCZ FLAGS_REG)
10388	(compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10389			     (match_dup 4))
10390		     (const_int 0)))
10391   (set (match_operand:SWI48 0 "register_operand")
10392        (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10393			    (match_operand:SWI48 1 "register_operand")
10394			    (match_dup 0)))
10395   (set (match_dup 1)
10396	(if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10397			    (match_operand:SWI48 3 "register_operand")
10398			    (match_dup 1)))]
10399  "TARGET_CMOVE"
10400  "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10401
10402(define_expand "x86_shift<mode>_adj_2"
10403  [(use (match_operand:SWI48 0 "register_operand"))
10404   (use (match_operand:SWI48 1 "register_operand"))
10405   (use (match_operand:QI 2 "register_operand"))]
10406  ""
10407{
10408  rtx_code_label *label = gen_label_rtx ();
10409  rtx tmp;
10410
10411  emit_insn (gen_testqi_ccz_1 (operands[2],
10412			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10413
10414  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10415  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10416  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10417			      gen_rtx_LABEL_REF (VOIDmode, label),
10418			      pc_rtx);
10419  tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10420  JUMP_LABEL (tmp) = label;
10421
10422  emit_move_insn (operands[0], operands[1]);
10423  ix86_expand_clear (operands[1]);
10424
10425  emit_label (label);
10426  LABEL_NUSES (label) = 1;
10427
10428  DONE;
10429})
10430
10431;; Avoid useless masking of count operand.
10432(define_insn_and_split "*ashl<mode>3_mask"
10433  [(set (match_operand:SWI48 0 "nonimmediate_operand")
10434	(ashift:SWI48
10435	  (match_operand:SWI48 1 "nonimmediate_operand")
10436	  (subreg:QI
10437	    (and:SI
10438	      (match_operand:SI 2 "register_operand" "c,r")
10439	      (match_operand:SI 3 "const_int_operand")) 0)))
10440   (clobber (reg:CC FLAGS_REG))]
10441  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10442   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10443      == GET_MODE_BITSIZE (<MODE>mode)-1
10444   && can_create_pseudo_p ()"
10445  "#"
10446  "&& 1"
10447  [(parallel
10448     [(set (match_dup 0)
10449	   (ashift:SWI48 (match_dup 1)
10450			 (match_dup 2)))
10451      (clobber (reg:CC FLAGS_REG))])]
10452  "operands[2] = gen_lowpart (QImode, operands[2]);"
10453  [(set_attr "isa" "*,bmi2")])
10454
10455(define_insn_and_split "*ashl<mode>3_mask_1"
10456  [(set (match_operand:SWI48 0 "nonimmediate_operand")
10457	(ashift:SWI48
10458	  (match_operand:SWI48 1 "nonimmediate_operand")
10459	  (and:QI
10460	    (match_operand:QI 2 "register_operand" "c,r")
10461	    (match_operand:QI 3 "const_int_operand"))))
10462   (clobber (reg:CC FLAGS_REG))]
10463  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10464   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10465      == GET_MODE_BITSIZE (<MODE>mode)-1
10466   && can_create_pseudo_p ()"
10467  "#"
10468  "&& 1"
10469  [(parallel
10470     [(set (match_dup 0)
10471	   (ashift:SWI48 (match_dup 1)
10472			 (match_dup 2)))
10473      (clobber (reg:CC FLAGS_REG))])]
10474  ""
10475  [(set_attr "isa" "*,bmi2")])
10476
10477(define_insn "*bmi2_ashl<mode>3_1"
10478  [(set (match_operand:SWI48 0 "register_operand" "=r")
10479	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10480		      (match_operand:SWI48 2 "register_operand" "r")))]
10481  "TARGET_BMI2"
10482  "shlx\t{%2, %1, %0|%0, %1, %2}"
10483  [(set_attr "type" "ishiftx")
10484   (set_attr "mode" "<MODE>")])
10485
10486(define_insn "*ashl<mode>3_1"
10487  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10488	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10489		      (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10490   (clobber (reg:CC FLAGS_REG))]
10491  "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10492{
10493  switch (get_attr_type (insn))
10494    {
10495    case TYPE_LEA:
10496    case TYPE_ISHIFTX:
10497      return "#";
10498
10499    case TYPE_ALU:
10500      gcc_assert (operands[2] == const1_rtx);
10501      gcc_assert (rtx_equal_p (operands[0], operands[1]));
10502      return "add{<imodesuffix>}\t%0, %0";
10503
10504    default:
10505      if (operands[2] == const1_rtx
10506	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10507	return "sal{<imodesuffix>}\t%0";
10508      else
10509	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10510    }
10511}
10512  [(set_attr "isa" "*,*,bmi2")
10513   (set (attr "type")
10514     (cond [(eq_attr "alternative" "1")
10515	      (const_string "lea")
10516	    (eq_attr "alternative" "2")
10517	      (const_string "ishiftx")
10518            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10519		      (match_operand 0 "register_operand"))
10520		 (match_operand 2 "const1_operand"))
10521	      (const_string "alu")
10522	   ]
10523	   (const_string "ishift")))
10524   (set (attr "length_immediate")
10525     (if_then_else
10526       (ior (eq_attr "type" "alu")
10527	    (and (eq_attr "type" "ishift")
10528		 (and (match_operand 2 "const1_operand")
10529		      (ior (match_test "TARGET_SHIFT1")
10530			   (match_test "optimize_function_for_size_p (cfun)")))))
10531       (const_string "0")
10532       (const_string "*")))
10533   (set_attr "mode" "<MODE>")])
10534
10535;; Convert shift to the shiftx pattern to avoid flags dependency.
10536(define_split
10537  [(set (match_operand:SWI48 0 "register_operand")
10538	(ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10539		      (match_operand:QI 2 "register_operand")))
10540   (clobber (reg:CC FLAGS_REG))]
10541  "TARGET_BMI2 && reload_completed"
10542  [(set (match_dup 0)
10543	(ashift:SWI48 (match_dup 1) (match_dup 2)))]
10544  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10545
10546(define_insn "*bmi2_ashlsi3_1_zext"
10547  [(set (match_operand:DI 0 "register_operand" "=r")
10548	(zero_extend:DI
10549	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10550		     (match_operand:SI 2 "register_operand" "r"))))]
10551  "TARGET_64BIT && TARGET_BMI2"
10552  "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10553  [(set_attr "type" "ishiftx")
10554   (set_attr "mode" "SI")])
10555
10556(define_insn "*ashlsi3_1_zext"
10557  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10558	(zero_extend:DI
10559	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10560		     (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10561   (clobber (reg:CC FLAGS_REG))]
10562  "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10563{
10564  switch (get_attr_type (insn))
10565    {
10566    case TYPE_LEA:
10567    case TYPE_ISHIFTX:
10568      return "#";
10569
10570    case TYPE_ALU:
10571      gcc_assert (operands[2] == const1_rtx);
10572      return "add{l}\t%k0, %k0";
10573
10574    default:
10575      if (operands[2] == const1_rtx
10576	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10577	return "sal{l}\t%k0";
10578      else
10579	return "sal{l}\t{%2, %k0|%k0, %2}";
10580    }
10581}
10582  [(set_attr "isa" "*,*,bmi2")
10583   (set (attr "type")
10584     (cond [(eq_attr "alternative" "1")
10585	      (const_string "lea")
10586	    (eq_attr "alternative" "2")
10587	      (const_string "ishiftx")
10588            (and (match_test "TARGET_DOUBLE_WITH_ADD")
10589		 (match_operand 2 "const1_operand"))
10590	      (const_string "alu")
10591	   ]
10592	   (const_string "ishift")))
10593   (set (attr "length_immediate")
10594     (if_then_else
10595       (ior (eq_attr "type" "alu")
10596	    (and (eq_attr "type" "ishift")
10597		 (and (match_operand 2 "const1_operand")
10598		      (ior (match_test "TARGET_SHIFT1")
10599			   (match_test "optimize_function_for_size_p (cfun)")))))
10600       (const_string "0")
10601       (const_string "*")))
10602   (set_attr "mode" "SI")])
10603
10604;; Convert shift to the shiftx pattern to avoid flags dependency.
10605(define_split
10606  [(set (match_operand:DI 0 "register_operand")
10607	(zero_extend:DI
10608	  (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10609		     (match_operand:QI 2 "register_operand"))))
10610   (clobber (reg:CC FLAGS_REG))]
10611  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10612  [(set (match_dup 0)
10613	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10614  "operands[2] = gen_lowpart (SImode, operands[2]);")
10615
10616(define_insn "*ashlhi3_1"
10617  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10618	(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10619		   (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10620   (clobber (reg:CC FLAGS_REG))]
10621  "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10622{
10623  switch (get_attr_type (insn))
10624    {
10625    case TYPE_LEA:
10626      return "#";
10627
10628    case TYPE_ALU:
10629      gcc_assert (operands[2] == const1_rtx);
10630      return "add{w}\t%0, %0";
10631
10632    default:
10633      if (operands[2] == const1_rtx
10634	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10635	return "sal{w}\t%0";
10636      else
10637	return "sal{w}\t{%2, %0|%0, %2}";
10638    }
10639}
10640  [(set (attr "type")
10641     (cond [(eq_attr "alternative" "1")
10642	      (const_string "lea")
10643            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10644		      (match_operand 0 "register_operand"))
10645		 (match_operand 2 "const1_operand"))
10646	      (const_string "alu")
10647	   ]
10648	   (const_string "ishift")))
10649   (set (attr "length_immediate")
10650     (if_then_else
10651       (ior (eq_attr "type" "alu")
10652	    (and (eq_attr "type" "ishift")
10653		 (and (match_operand 2 "const1_operand")
10654		      (ior (match_test "TARGET_SHIFT1")
10655			   (match_test "optimize_function_for_size_p (cfun)")))))
10656       (const_string "0")
10657       (const_string "*")))
10658   (set_attr "mode" "HI,SI")])
10659
10660(define_insn "*ashlqi3_1"
10661  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10662	(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10663		   (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10664   (clobber (reg:CC FLAGS_REG))]
10665  "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10666{
10667  switch (get_attr_type (insn))
10668    {
10669    case TYPE_LEA:
10670      return "#";
10671
10672    case TYPE_ALU:
10673      gcc_assert (operands[2] == const1_rtx);
10674      if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10675        return "add{l}\t%k0, %k0";
10676      else
10677        return "add{b}\t%0, %0";
10678
10679    default:
10680      if (operands[2] == const1_rtx
10681	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10682	{
10683	  if (get_attr_mode (insn) == MODE_SI)
10684	    return "sal{l}\t%k0";
10685	  else
10686	    return "sal{b}\t%0";
10687	}
10688      else
10689	{
10690	  if (get_attr_mode (insn) == MODE_SI)
10691	    return "sal{l}\t{%2, %k0|%k0, %2}";
10692	  else
10693	    return "sal{b}\t{%2, %0|%0, %2}";
10694	}
10695    }
10696}
10697  [(set (attr "type")
10698     (cond [(eq_attr "alternative" "2")
10699	      (const_string "lea")
10700            (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10701		      (match_operand 0 "register_operand"))
10702		 (match_operand 2 "const1_operand"))
10703	      (const_string "alu")
10704	   ]
10705	   (const_string "ishift")))
10706   (set (attr "length_immediate")
10707     (if_then_else
10708       (ior (eq_attr "type" "alu")
10709	    (and (eq_attr "type" "ishift")
10710		 (and (match_operand 2 "const1_operand")
10711		      (ior (match_test "TARGET_SHIFT1")
10712			   (match_test "optimize_function_for_size_p (cfun)")))))
10713       (const_string "0")
10714       (const_string "*")))
10715   (set_attr "mode" "QI,SI,SI")
10716   ;; Potential partial reg stall on alternative 1.
10717   (set (attr "preferred_for_speed")
10718     (cond [(eq_attr "alternative" "1")
10719	      (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10720	   (symbol_ref "true")))])
10721
10722(define_insn "*ashlqi3_1_slp"
10723  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10724	(ashift:QI (match_dup 0)
10725		   (match_operand:QI 1 "nonmemory_operand" "cI")))
10726   (clobber (reg:CC FLAGS_REG))]
10727  "(optimize_function_for_size_p (cfun)
10728    || !TARGET_PARTIAL_FLAG_REG_STALL
10729    || (operands[1] == const1_rtx
10730	&& (TARGET_SHIFT1
10731	    || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10732{
10733  switch (get_attr_type (insn))
10734    {
10735    case TYPE_ALU1:
10736      gcc_assert (operands[1] == const1_rtx);
10737      return "add{b}\t%0, %0";
10738
10739    default:
10740      if (operands[1] == const1_rtx
10741	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10742	return "sal{b}\t%0";
10743      else
10744	return "sal{b}\t{%1, %0|%0, %1}";
10745    }
10746}
10747  [(set (attr "type")
10748     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10749		      (match_operand 0 "register_operand"))
10750		 (match_operand 1 "const1_operand"))
10751	      (const_string "alu1")
10752	   ]
10753	   (const_string "ishift1")))
10754   (set (attr "length_immediate")
10755     (if_then_else
10756       (ior (eq_attr "type" "alu1")
10757	    (and (eq_attr "type" "ishift1")
10758		 (and (match_operand 1 "const1_operand")
10759		      (ior (match_test "TARGET_SHIFT1")
10760			   (match_test "optimize_function_for_size_p (cfun)")))))
10761       (const_string "0")
10762       (const_string "*")))
10763   (set_attr "mode" "QI")])
10764
10765;; Convert ashift to the lea pattern to avoid flags dependency.
10766(define_split
10767  [(set (match_operand:SWI 0 "register_operand")
10768	(ashift:SWI (match_operand:SWI 1 "index_register_operand")
10769		    (match_operand 2 "const_0_to_3_operand")))
10770   (clobber (reg:CC FLAGS_REG))]
10771  "reload_completed
10772   && REGNO (operands[0]) != REGNO (operands[1])"
10773  [(set (match_dup 0)
10774	(mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10775{
10776  if (<MODE>mode != <LEAMODE>mode)
10777    {
10778      operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10779      operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10780    }
10781  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10782})
10783
10784;; Convert ashift to the lea pattern to avoid flags dependency.
10785(define_split
10786  [(set (match_operand:DI 0 "register_operand")
10787	(zero_extend:DI
10788	  (ashift:SI (match_operand:SI 1 "index_register_operand")
10789		     (match_operand 2 "const_0_to_3_operand"))))
10790   (clobber (reg:CC FLAGS_REG))]
10791  "TARGET_64BIT && reload_completed
10792   && REGNO (operands[0]) != REGNO (operands[1])"
10793  [(set (match_dup 0)
10794	(zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10795{
10796  operands[1] = gen_lowpart (SImode, operands[1]);
10797  operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10798})
10799
10800;; This pattern can't accept a variable shift count, since shifts by
10801;; zero don't affect the flags.  We assume that shifts by constant
10802;; zero are optimized away.
10803(define_insn "*ashl<mode>3_cmp"
10804  [(set (reg FLAGS_REG)
10805	(compare
10806	  (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10807		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10808	  (const_int 0)))
10809   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10810	(ashift:SWI (match_dup 1) (match_dup 2)))]
10811  "(optimize_function_for_size_p (cfun)
10812    || !TARGET_PARTIAL_FLAG_REG_STALL
10813    || (operands[2] == const1_rtx
10814	&& (TARGET_SHIFT1
10815	    || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10816   && ix86_match_ccmode (insn, CCGOCmode)
10817   && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10818{
10819  switch (get_attr_type (insn))
10820    {
10821    case TYPE_ALU:
10822      gcc_assert (operands[2] == const1_rtx);
10823      return "add{<imodesuffix>}\t%0, %0";
10824
10825    default:
10826      if (operands[2] == const1_rtx
10827	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10828	return "sal{<imodesuffix>}\t%0";
10829      else
10830	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10831    }
10832}
10833  [(set (attr "type")
10834     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10835		      (match_operand 0 "register_operand"))
10836		 (match_operand 2 "const1_operand"))
10837	      (const_string "alu")
10838	   ]
10839	   (const_string "ishift")))
10840   (set (attr "length_immediate")
10841     (if_then_else
10842       (ior (eq_attr "type" "alu")
10843	    (and (eq_attr "type" "ishift")
10844		 (and (match_operand 2 "const1_operand")
10845		      (ior (match_test "TARGET_SHIFT1")
10846			   (match_test "optimize_function_for_size_p (cfun)")))))
10847       (const_string "0")
10848       (const_string "*")))
10849   (set_attr "mode" "<MODE>")])
10850
10851(define_insn "*ashlsi3_cmp_zext"
10852  [(set (reg FLAGS_REG)
10853	(compare
10854	  (ashift:SI (match_operand:SI 1 "register_operand" "0")
10855		     (match_operand:QI 2 "const_1_to_31_operand" "I"))
10856	  (const_int 0)))
10857   (set (match_operand:DI 0 "register_operand" "=r")
10858	(zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10859  "TARGET_64BIT
10860   && (optimize_function_for_size_p (cfun)
10861       || !TARGET_PARTIAL_FLAG_REG_STALL
10862       || (operands[2] == const1_rtx
10863	   && (TARGET_SHIFT1
10864	       || TARGET_DOUBLE_WITH_ADD)))
10865   && ix86_match_ccmode (insn, CCGOCmode)
10866   && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10867{
10868  switch (get_attr_type (insn))
10869    {
10870    case TYPE_ALU:
10871      gcc_assert (operands[2] == const1_rtx);
10872      return "add{l}\t%k0, %k0";
10873
10874    default:
10875      if (operands[2] == const1_rtx
10876	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10877	return "sal{l}\t%k0";
10878      else
10879	return "sal{l}\t{%2, %k0|%k0, %2}";
10880    }
10881}
10882  [(set (attr "type")
10883     (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10884		 (match_operand 2 "const1_operand"))
10885	      (const_string "alu")
10886	   ]
10887	   (const_string "ishift")))
10888   (set (attr "length_immediate")
10889     (if_then_else
10890       (ior (eq_attr "type" "alu")
10891	    (and (eq_attr "type" "ishift")
10892		 (and (match_operand 2 "const1_operand")
10893		      (ior (match_test "TARGET_SHIFT1")
10894			   (match_test "optimize_function_for_size_p (cfun)")))))
10895       (const_string "0")
10896       (const_string "*")))
10897   (set_attr "mode" "SI")])
10898
10899(define_insn "*ashl<mode>3_cconly"
10900  [(set (reg FLAGS_REG)
10901	(compare
10902	  (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10903		      (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10904	  (const_int 0)))
10905   (clobber (match_scratch:SWI 0 "=<r>"))]
10906  "(optimize_function_for_size_p (cfun)
10907    || !TARGET_PARTIAL_FLAG_REG_STALL
10908    || (operands[2] == const1_rtx
10909	&& (TARGET_SHIFT1
10910	    || TARGET_DOUBLE_WITH_ADD)))
10911   && ix86_match_ccmode (insn, CCGOCmode)"
10912{
10913  switch (get_attr_type (insn))
10914    {
10915    case TYPE_ALU:
10916      gcc_assert (operands[2] == const1_rtx);
10917      return "add{<imodesuffix>}\t%0, %0";
10918
10919    default:
10920      if (operands[2] == const1_rtx
10921	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10922	return "sal{<imodesuffix>}\t%0";
10923      else
10924	return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10925    }
10926}
10927  [(set (attr "type")
10928     (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10929		      (match_operand 0 "register_operand"))
10930		 (match_operand 2 "const1_operand"))
10931	      (const_string "alu")
10932	   ]
10933	   (const_string "ishift")))
10934   (set (attr "length_immediate")
10935     (if_then_else
10936       (ior (eq_attr "type" "alu")
10937	    (and (eq_attr "type" "ishift")
10938		 (and (match_operand 2 "const1_operand")
10939		      (ior (match_test "TARGET_SHIFT1")
10940			   (match_test "optimize_function_for_size_p (cfun)")))))
10941       (const_string "0")
10942       (const_string "*")))
10943   (set_attr "mode" "<MODE>")])
10944
10945;; See comment above `ashl<mode>3' about how this works.
10946
10947(define_expand "<shift_insn><mode>3"
10948  [(set (match_operand:SDWIM 0 "<shift_operand>")
10949	(any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10950			   (match_operand:QI 2 "nonmemory_operand")))]
10951  ""
10952  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10953
10954;; Avoid useless masking of count operand.
10955(define_insn_and_split "*<shift_insn><mode>3_mask"
10956  [(set (match_operand:SWI48 0 "nonimmediate_operand")
10957	(any_shiftrt:SWI48
10958	  (match_operand:SWI48 1 "nonimmediate_operand")
10959	  (subreg:QI
10960	    (and:SI
10961	      (match_operand:SI 2 "register_operand" "c,r")
10962	      (match_operand:SI 3 "const_int_operand")) 0)))
10963   (clobber (reg:CC FLAGS_REG))]
10964  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10965   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10966      == GET_MODE_BITSIZE (<MODE>mode)-1
10967   && can_create_pseudo_p ()"
10968  "#"
10969  "&& 1"
10970  [(parallel
10971     [(set (match_dup 0)
10972	   (any_shiftrt:SWI48 (match_dup 1)
10973			      (match_dup 2)))
10974      (clobber (reg:CC FLAGS_REG))])]
10975  "operands[2] = gen_lowpart (QImode, operands[2]);"
10976  [(set_attr "isa" "*,bmi2")])
10977
10978(define_insn_and_split "*<shift_insn><mode>3_mask_1"
10979  [(set (match_operand:SWI48 0 "nonimmediate_operand")
10980	(any_shiftrt:SWI48
10981	  (match_operand:SWI48 1 "nonimmediate_operand")
10982	  (and:QI
10983	    (match_operand:QI 2 "register_operand" "c,r")
10984	    (match_operand:QI 3 "const_int_operand"))))
10985   (clobber (reg:CC FLAGS_REG))]
10986  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10987   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10988      == GET_MODE_BITSIZE (<MODE>mode)-1
10989   && can_create_pseudo_p ()"
10990  "#"
10991  "&& 1"
10992  [(parallel
10993     [(set (match_dup 0)
10994	   (any_shiftrt:SWI48 (match_dup 1)
10995			      (match_dup 2)))
10996      (clobber (reg:CC FLAGS_REG))])]
10997  ""
10998  [(set_attr "isa" "*,bmi2")])
10999
11000(define_insn_and_split "*<shift_insn><mode>3_doubleword"
11001  [(set (match_operand:DWI 0 "register_operand" "=&r")
11002	(any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11003			 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11004   (clobber (reg:CC FLAGS_REG))]
11005  ""
11006  "#"
11007  "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
11008  [(const_int 0)]
11009  "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11010  [(set_attr "type" "multi")])
11011
11012;; By default we don't ask for a scratch register, because when DWImode
11013;; values are manipulated, registers are already at a premium.  But if
11014;; we have one handy, we won't turn it away.
11015
11016(define_peephole2
11017  [(match_scratch:DWIH 3 "r")
11018   (parallel [(set (match_operand:<DWI> 0 "register_operand")
11019		   (any_shiftrt:<DWI>
11020		     (match_operand:<DWI> 1 "register_operand")
11021		     (match_operand:QI 2 "nonmemory_operand")))
11022	      (clobber (reg:CC FLAGS_REG))])
11023   (match_dup 3)]
11024  "TARGET_CMOVE"
11025  [(const_int 0)]
11026  "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11027
11028(define_insn "x86_64_shrd"
11029  [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11030        (ior:DI (lshiftrt:DI (match_dup 0)
11031		  (match_operand:QI 2 "nonmemory_operand" "Jc"))
11032		(ashift:DI (match_operand:DI 1 "register_operand" "r")
11033		  (minus:QI (const_int 64) (match_dup 2)))))
11034   (clobber (reg:CC FLAGS_REG))]
11035  "TARGET_64BIT"
11036  "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11037  [(set_attr "type" "ishift")
11038   (set_attr "prefix_0f" "1")
11039   (set_attr "mode" "DI")
11040   (set_attr "athlon_decode" "vector")
11041   (set_attr "amdfam10_decode" "vector")
11042   (set_attr "bdver1_decode" "vector")])
11043
11044(define_insn "x86_shrd"
11045  [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11046        (ior:SI (lshiftrt:SI (match_dup 0)
11047		  (match_operand:QI 2 "nonmemory_operand" "Ic"))
11048		(ashift:SI (match_operand:SI 1 "register_operand" "r")
11049		  (minus:QI (const_int 32) (match_dup 2)))))
11050   (clobber (reg:CC FLAGS_REG))]
11051  ""
11052  "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11053  [(set_attr "type" "ishift")
11054   (set_attr "prefix_0f" "1")
11055   (set_attr "mode" "SI")
11056   (set_attr "pent_pair" "np")
11057   (set_attr "athlon_decode" "vector")
11058   (set_attr "amdfam10_decode" "vector")
11059   (set_attr "bdver1_decode" "vector")])
11060
11061(define_insn "ashrdi3_cvt"
11062  [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11063	(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11064		     (match_operand:QI 2 "const_int_operand")))
11065   (clobber (reg:CC FLAGS_REG))]
11066  "TARGET_64BIT && INTVAL (operands[2]) == 63
11067   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11068   && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11069  "@
11070   {cqto|cqo}
11071   sar{q}\t{%2, %0|%0, %2}"
11072  [(set_attr "type" "imovx,ishift")
11073   (set_attr "prefix_0f" "0,*")
11074   (set_attr "length_immediate" "0,*")
11075   (set_attr "modrm" "0,1")
11076   (set_attr "mode" "DI")])
11077
11078(define_insn "*ashrsi3_cvt_zext"
11079  [(set (match_operand:DI 0 "register_operand" "=*d,r")
11080	(zero_extend:DI
11081	  (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11082		       (match_operand:QI 2 "const_int_operand"))))
11083   (clobber (reg:CC FLAGS_REG))]
11084  "TARGET_64BIT && INTVAL (operands[2]) == 31
11085   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11086   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11087  "@
11088   {cltd|cdq}
11089   sar{l}\t{%2, %k0|%k0, %2}"
11090  [(set_attr "type" "imovx,ishift")
11091   (set_attr "prefix_0f" "0,*")
11092   (set_attr "length_immediate" "0,*")
11093   (set_attr "modrm" "0,1")
11094   (set_attr "mode" "SI")])
11095
11096(define_insn "ashrsi3_cvt"
11097  [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11098	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11099		     (match_operand:QI 2 "const_int_operand")))
11100   (clobber (reg:CC FLAGS_REG))]
11101  "INTVAL (operands[2]) == 31
11102   && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11103   && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11104  "@
11105   {cltd|cdq}
11106   sar{l}\t{%2, %0|%0, %2}"
11107  [(set_attr "type" "imovx,ishift")
11108   (set_attr "prefix_0f" "0,*")
11109   (set_attr "length_immediate" "0,*")
11110   (set_attr "modrm" "0,1")
11111   (set_attr "mode" "SI")])
11112
11113(define_expand "x86_shift<mode>_adj_3"
11114  [(use (match_operand:SWI48 0 "register_operand"))
11115   (use (match_operand:SWI48 1 "register_operand"))
11116   (use (match_operand:QI 2 "register_operand"))]
11117  ""
11118{
11119  rtx_code_label *label = gen_label_rtx ();
11120  rtx tmp;
11121
11122  emit_insn (gen_testqi_ccz_1 (operands[2],
11123			       GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11124
11125  tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11126  tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11127  tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11128			      gen_rtx_LABEL_REF (VOIDmode, label),
11129			      pc_rtx);
11130  tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11131  JUMP_LABEL (tmp) = label;
11132
11133  emit_move_insn (operands[0], operands[1]);
11134  emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11135				  GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11136  emit_label (label);
11137  LABEL_NUSES (label) = 1;
11138
11139  DONE;
11140})
11141
11142(define_insn "*bmi2_<shift_insn><mode>3_1"
11143  [(set (match_operand:SWI48 0 "register_operand" "=r")
11144	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11145			   (match_operand:SWI48 2 "register_operand" "r")))]
11146  "TARGET_BMI2"
11147  "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11148  [(set_attr "type" "ishiftx")
11149   (set_attr "mode" "<MODE>")])
11150
11151(define_insn "*<shift_insn><mode>3_1"
11152  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11153	(any_shiftrt:SWI48
11154	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11155	  (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11156   (clobber (reg:CC FLAGS_REG))]
11157  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11158{
11159  switch (get_attr_type (insn))
11160    {
11161    case TYPE_ISHIFTX:
11162      return "#";
11163
11164    default:
11165      if (operands[2] == const1_rtx
11166	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11167	return "<shift>{<imodesuffix>}\t%0";
11168      else
11169	return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11170    }
11171}
11172  [(set_attr "isa" "*,bmi2")
11173   (set_attr "type" "ishift,ishiftx")
11174   (set (attr "length_immediate")
11175     (if_then_else
11176       (and (match_operand 2 "const1_operand")
11177	    (ior (match_test "TARGET_SHIFT1")
11178		 (match_test "optimize_function_for_size_p (cfun)")))
11179       (const_string "0")
11180       (const_string "*")))
11181   (set_attr "mode" "<MODE>")])
11182
11183;; Convert shift to the shiftx pattern to avoid flags dependency.
11184(define_split
11185  [(set (match_operand:SWI48 0 "register_operand")
11186	(any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11187			   (match_operand:QI 2 "register_operand")))
11188   (clobber (reg:CC FLAGS_REG))]
11189  "TARGET_BMI2 && reload_completed"
11190  [(set (match_dup 0)
11191	(any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11192  "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11193
11194(define_insn "*bmi2_<shift_insn>si3_1_zext"
11195  [(set (match_operand:DI 0 "register_operand" "=r")
11196	(zero_extend:DI
11197	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11198			  (match_operand:SI 2 "register_operand" "r"))))]
11199  "TARGET_64BIT && TARGET_BMI2"
11200  "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11201  [(set_attr "type" "ishiftx")
11202   (set_attr "mode" "SI")])
11203
11204(define_insn "*<shift_insn>si3_1_zext"
11205  [(set (match_operand:DI 0 "register_operand" "=r,r")
11206	(zero_extend:DI
11207	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11208			  (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11209   (clobber (reg:CC FLAGS_REG))]
11210  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11211{
11212  switch (get_attr_type (insn))
11213    {
11214    case TYPE_ISHIFTX:
11215      return "#";
11216
11217    default:
11218      if (operands[2] == const1_rtx
11219	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11220	return "<shift>{l}\t%k0";
11221      else
11222	return "<shift>{l}\t{%2, %k0|%k0, %2}";
11223    }
11224}
11225  [(set_attr "isa" "*,bmi2")
11226   (set_attr "type" "ishift,ishiftx")
11227   (set (attr "length_immediate")
11228     (if_then_else
11229       (and (match_operand 2 "const1_operand")
11230	    (ior (match_test "TARGET_SHIFT1")
11231		 (match_test "optimize_function_for_size_p (cfun)")))
11232       (const_string "0")
11233       (const_string "*")))
11234   (set_attr "mode" "SI")])
11235
11236;; Convert shift to the shiftx pattern to avoid flags dependency.
11237(define_split
11238  [(set (match_operand:DI 0 "register_operand")
11239	(zero_extend:DI
11240	  (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11241			  (match_operand:QI 2 "register_operand"))))
11242   (clobber (reg:CC FLAGS_REG))]
11243  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11244  [(set (match_dup 0)
11245	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11246  "operands[2] = gen_lowpart (SImode, operands[2]);")
11247
11248(define_insn "*<shift_insn><mode>3_1"
11249  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11250	(any_shiftrt:SWI12
11251	  (match_operand:SWI12 1 "nonimmediate_operand" "0")
11252	  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11253   (clobber (reg:CC FLAGS_REG))]
11254  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11255{
11256  if (operands[2] == const1_rtx
11257      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11258    return "<shift>{<imodesuffix>}\t%0";
11259  else
11260    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11261}
11262  [(set_attr "type" "ishift")
11263   (set (attr "length_immediate")
11264     (if_then_else
11265       (and (match_operand 2 "const1_operand")
11266	    (ior (match_test "TARGET_SHIFT1")
11267		 (match_test "optimize_function_for_size_p (cfun)")))
11268       (const_string "0")
11269       (const_string "*")))
11270   (set_attr "mode" "<MODE>")])
11271
11272(define_insn "*<shift_insn>qi3_1_slp"
11273  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11274	(any_shiftrt:QI (match_dup 0)
11275			(match_operand:QI 1 "nonmemory_operand" "cI")))
11276   (clobber (reg:CC FLAGS_REG))]
11277  "(optimize_function_for_size_p (cfun)
11278    || !TARGET_PARTIAL_REG_STALL
11279    || (operands[1] == const1_rtx
11280	&& TARGET_SHIFT1))"
11281{
11282  if (operands[1] == const1_rtx
11283      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11284    return "<shift>{b}\t%0";
11285  else
11286    return "<shift>{b}\t{%1, %0|%0, %1}";
11287}
11288  [(set_attr "type" "ishift1")
11289   (set (attr "length_immediate")
11290     (if_then_else
11291       (and (match_operand 1 "const1_operand")
11292	    (ior (match_test "TARGET_SHIFT1")
11293		 (match_test "optimize_function_for_size_p (cfun)")))
11294       (const_string "0")
11295       (const_string "*")))
11296   (set_attr "mode" "QI")])
11297
11298;; This pattern can't accept a variable shift count, since shifts by
11299;; zero don't affect the flags.  We assume that shifts by constant
11300;; zero are optimized away.
11301(define_insn "*<shift_insn><mode>3_cmp"
11302  [(set (reg FLAGS_REG)
11303	(compare
11304	  (any_shiftrt:SWI
11305	    (match_operand:SWI 1 "nonimmediate_operand" "0")
11306	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11307	  (const_int 0)))
11308   (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11309	(any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11310  "(optimize_function_for_size_p (cfun)
11311    || !TARGET_PARTIAL_FLAG_REG_STALL
11312    || (operands[2] == const1_rtx
11313	&& TARGET_SHIFT1))
11314   && ix86_match_ccmode (insn, CCGOCmode)
11315   && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11316{
11317  if (operands[2] == const1_rtx
11318      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11319    return "<shift>{<imodesuffix>}\t%0";
11320  else
11321    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11322}
11323  [(set_attr "type" "ishift")
11324   (set (attr "length_immediate")
11325     (if_then_else
11326       (and (match_operand 2 "const1_operand")
11327	    (ior (match_test "TARGET_SHIFT1")
11328		 (match_test "optimize_function_for_size_p (cfun)")))
11329       (const_string "0")
11330       (const_string "*")))
11331   (set_attr "mode" "<MODE>")])
11332
11333(define_insn "*<shift_insn>si3_cmp_zext"
11334  [(set (reg FLAGS_REG)
11335	(compare
11336	  (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11337			  (match_operand:QI 2 "const_1_to_31_operand" "I"))
11338	  (const_int 0)))
11339   (set (match_operand:DI 0 "register_operand" "=r")
11340	(zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11341  "TARGET_64BIT
11342   && (optimize_function_for_size_p (cfun)
11343       || !TARGET_PARTIAL_FLAG_REG_STALL
11344       || (operands[2] == const1_rtx
11345	   && TARGET_SHIFT1))
11346   && ix86_match_ccmode (insn, CCGOCmode)
11347   && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11348{
11349  if (operands[2] == const1_rtx
11350      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11351    return "<shift>{l}\t%k0";
11352  else
11353    return "<shift>{l}\t{%2, %k0|%k0, %2}";
11354}
11355  [(set_attr "type" "ishift")
11356   (set (attr "length_immediate")
11357     (if_then_else
11358       (and (match_operand 2 "const1_operand")
11359	    (ior (match_test "TARGET_SHIFT1")
11360		 (match_test "optimize_function_for_size_p (cfun)")))
11361       (const_string "0")
11362       (const_string "*")))
11363   (set_attr "mode" "SI")])
11364
11365(define_insn "*<shift_insn><mode>3_cconly"
11366  [(set (reg FLAGS_REG)
11367	(compare
11368	  (any_shiftrt:SWI
11369	    (match_operand:SWI 1 "register_operand" "0")
11370	    (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11371	  (const_int 0)))
11372   (clobber (match_scratch:SWI 0 "=<r>"))]
11373  "(optimize_function_for_size_p (cfun)
11374    || !TARGET_PARTIAL_FLAG_REG_STALL
11375    || (operands[2] == const1_rtx
11376	&& TARGET_SHIFT1))
11377   && ix86_match_ccmode (insn, CCGOCmode)"
11378{
11379  if (operands[2] == const1_rtx
11380      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11381    return "<shift>{<imodesuffix>}\t%0";
11382  else
11383    return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11384}
11385  [(set_attr "type" "ishift")
11386   (set (attr "length_immediate")
11387     (if_then_else
11388       (and (match_operand 2 "const1_operand")
11389	    (ior (match_test "TARGET_SHIFT1")
11390		 (match_test "optimize_function_for_size_p (cfun)")))
11391       (const_string "0")
11392       (const_string "*")))
11393   (set_attr "mode" "<MODE>")])
11394
11395;; Rotate instructions
11396
11397(define_expand "<rotate_insn>ti3"
11398  [(set (match_operand:TI 0 "register_operand")
11399	(any_rotate:TI (match_operand:TI 1 "register_operand")
11400		       (match_operand:QI 2 "nonmemory_operand")))]
11401  "TARGET_64BIT"
11402{
11403  if (const_1_to_63_operand (operands[2], VOIDmode))
11404    emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11405		(operands[0], operands[1], operands[2]));
11406  else
11407    FAIL;
11408
11409  DONE;
11410})
11411
11412(define_expand "<rotate_insn>di3"
11413  [(set (match_operand:DI 0 "shiftdi_operand")
11414	(any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11415		       (match_operand:QI 2 "nonmemory_operand")))]
11416 ""
11417{
11418  if (TARGET_64BIT)
11419    ix86_expand_binary_operator (<CODE>, DImode, operands);
11420  else if (const_1_to_31_operand (operands[2], VOIDmode))
11421    emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11422		(operands[0], operands[1], operands[2]));
11423  else
11424    FAIL;
11425
11426  DONE;
11427})
11428
11429(define_expand "<rotate_insn><mode>3"
11430  [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11431	(any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11432			    (match_operand:QI 2 "nonmemory_operand")))]
11433  ""
11434  "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11435
11436;; Avoid useless masking of count operand.
11437(define_insn_and_split "*<rotate_insn><mode>3_mask"
11438  [(set (match_operand:SWI48 0 "nonimmediate_operand")
11439	(any_rotate:SWI48
11440	  (match_operand:SWI48 1 "nonimmediate_operand")
11441	  (subreg:QI
11442	    (and:SI
11443	      (match_operand:SI 2 "register_operand" "c")
11444	      (match_operand:SI 3 "const_int_operand")) 0)))
11445   (clobber (reg:CC FLAGS_REG))]
11446  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11447   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11448      == GET_MODE_BITSIZE (<MODE>mode)-1
11449   && can_create_pseudo_p ()"
11450  "#"
11451  "&& 1"
11452  [(parallel
11453     [(set (match_dup 0)
11454	   (any_rotate:SWI48 (match_dup 1)
11455			     (match_dup 2)))
11456      (clobber (reg:CC FLAGS_REG))])]
11457  "operands[2] = gen_lowpart (QImode, operands[2]);")
11458
11459(define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11460  [(set (match_operand:SWI48 0 "nonimmediate_operand")
11461	(any_rotate:SWI48
11462	  (match_operand:SWI48 1 "nonimmediate_operand")
11463	  (and:QI
11464	    (match_operand:QI 2 "register_operand" "c")
11465	    (match_operand:QI 3 "const_int_operand"))))
11466   (clobber (reg:CC FLAGS_REG))]
11467  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11468   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11469      == GET_MODE_BITSIZE (<MODE>mode)-1
11470   && can_create_pseudo_p ()"
11471  "#"
11472  "&& 1"
11473  [(parallel
11474     [(set (match_dup 0)
11475	   (any_rotate:SWI48 (match_dup 1)
11476			     (match_dup 2)))
11477      (clobber (reg:CC FLAGS_REG))])])
11478
11479;; Implement rotation using two double-precision
11480;; shift instructions and a scratch register.
11481
11482(define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11483 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11484       (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11485		     (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11486  (clobber (reg:CC FLAGS_REG))
11487  (clobber (match_scratch:DWIH 3 "=&r"))]
11488 ""
11489 "#"
11490 "reload_completed"
11491 [(set (match_dup 3) (match_dup 4))
11492  (parallel
11493   [(set (match_dup 4)
11494	 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11495		   (lshiftrt:DWIH (match_dup 5)
11496				  (minus:QI (match_dup 6) (match_dup 2)))))
11497    (clobber (reg:CC FLAGS_REG))])
11498  (parallel
11499   [(set (match_dup 5)
11500	 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11501		   (lshiftrt:DWIH (match_dup 3)
11502				  (minus:QI (match_dup 6) (match_dup 2)))))
11503    (clobber (reg:CC FLAGS_REG))])]
11504{
11505  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11506
11507  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11508})
11509
11510(define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11511 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11512       (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11513		       (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11514  (clobber (reg:CC FLAGS_REG))
11515  (clobber (match_scratch:DWIH 3 "=&r"))]
11516 ""
11517 "#"
11518 "reload_completed"
11519 [(set (match_dup 3) (match_dup 4))
11520  (parallel
11521   [(set (match_dup 4)
11522	 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11523		   (ashift:DWIH (match_dup 5)
11524				(minus:QI (match_dup 6) (match_dup 2)))))
11525    (clobber (reg:CC FLAGS_REG))])
11526  (parallel
11527   [(set (match_dup 5)
11528	 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11529		   (ashift:DWIH (match_dup 3)
11530				(minus:QI (match_dup 6) (match_dup 2)))))
11531    (clobber (reg:CC FLAGS_REG))])]
11532{
11533  operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11534
11535  split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11536})
11537
11538(define_mode_attr rorx_immediate_operand
11539	[(SI "const_0_to_31_operand")
11540	 (DI "const_0_to_63_operand")])
11541
11542(define_insn "*bmi2_rorx<mode>3_1"
11543  [(set (match_operand:SWI48 0 "register_operand" "=r")
11544	(rotatert:SWI48
11545	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11546	  (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11547  "TARGET_BMI2"
11548  "rorx\t{%2, %1, %0|%0, %1, %2}"
11549  [(set_attr "type" "rotatex")
11550   (set_attr "mode" "<MODE>")])
11551
11552(define_insn "*<rotate_insn><mode>3_1"
11553  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11554	(any_rotate:SWI48
11555	  (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11556	  (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11557   (clobber (reg:CC FLAGS_REG))]
11558  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11559{
11560  switch (get_attr_type (insn))
11561    {
11562    case TYPE_ROTATEX:
11563      return "#";
11564
11565    default:
11566      if (operands[2] == const1_rtx
11567	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11568	return "<rotate>{<imodesuffix>}\t%0";
11569      else
11570	return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11571    }
11572}
11573  [(set_attr "isa" "*,bmi2")
11574   (set_attr "type" "rotate,rotatex")
11575   (set (attr "length_immediate")
11576     (if_then_else
11577       (and (eq_attr "type" "rotate")
11578	    (and (match_operand 2 "const1_operand")
11579		 (ior (match_test "TARGET_SHIFT1")
11580		      (match_test "optimize_function_for_size_p (cfun)"))))
11581       (const_string "0")
11582       (const_string "*")))
11583   (set_attr "mode" "<MODE>")])
11584
11585;; Convert rotate to the rotatex pattern to avoid flags dependency.
11586(define_split
11587  [(set (match_operand:SWI48 0 "register_operand")
11588	(rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11589		      (match_operand:QI 2 "const_int_operand")))
11590   (clobber (reg:CC FLAGS_REG))]
11591  "TARGET_BMI2 && reload_completed"
11592  [(set (match_dup 0)
11593	(rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11594{
11595  int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11596
11597  operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11598})
11599
11600(define_split
11601  [(set (match_operand:SWI48 0 "register_operand")
11602	(rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11603			(match_operand:QI 2 "const_int_operand")))
11604   (clobber (reg:CC FLAGS_REG))]
11605  "TARGET_BMI2 && reload_completed"
11606  [(set (match_dup 0)
11607	(rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11608
11609(define_insn "*bmi2_rorxsi3_1_zext"
11610  [(set (match_operand:DI 0 "register_operand" "=r")
11611	(zero_extend:DI
11612	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11613		       (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11614  "TARGET_64BIT && TARGET_BMI2"
11615  "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11616  [(set_attr "type" "rotatex")
11617   (set_attr "mode" "SI")])
11618
11619(define_insn "*<rotate_insn>si3_1_zext"
11620  [(set (match_operand:DI 0 "register_operand" "=r,r")
11621	(zero_extend:DI
11622	  (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11623			 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11624   (clobber (reg:CC FLAGS_REG))]
11625  "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11626{
11627  switch (get_attr_type (insn))
11628    {
11629    case TYPE_ROTATEX:
11630      return "#";
11631
11632    default:
11633      if (operands[2] == const1_rtx
11634	  && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11635	return "<rotate>{l}\t%k0";
11636      else
11637	return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11638    }
11639}
11640  [(set_attr "isa" "*,bmi2")
11641   (set_attr "type" "rotate,rotatex")
11642   (set (attr "length_immediate")
11643     (if_then_else
11644       (and (eq_attr "type" "rotate")
11645	    (and (match_operand 2 "const1_operand")
11646		 (ior (match_test "TARGET_SHIFT1")
11647		      (match_test "optimize_function_for_size_p (cfun)"))))
11648       (const_string "0")
11649       (const_string "*")))
11650   (set_attr "mode" "SI")])
11651
11652;; Convert rotate to the rotatex pattern to avoid flags dependency.
11653(define_split
11654  [(set (match_operand:DI 0 "register_operand")
11655	(zero_extend:DI
11656	  (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11657		     (match_operand:QI 2 "const_int_operand"))))
11658   (clobber (reg:CC FLAGS_REG))]
11659  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11660  [(set (match_dup 0)
11661	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11662{
11663  int bitsize = GET_MODE_BITSIZE (SImode);
11664
11665  operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11666})
11667
11668(define_split
11669  [(set (match_operand:DI 0 "register_operand")
11670	(zero_extend:DI
11671	  (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11672		       (match_operand:QI 2 "const_int_operand"))))
11673   (clobber (reg:CC FLAGS_REG))]
11674  "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11675  [(set (match_dup 0)
11676	(zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11677
11678(define_insn "*<rotate_insn><mode>3_1"
11679  [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11680	(any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11681			  (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11682   (clobber (reg:CC FLAGS_REG))]
11683  "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11684{
11685  if (operands[2] == const1_rtx
11686      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11687    return "<rotate>{<imodesuffix>}\t%0";
11688  else
11689    return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11690}
11691  [(set_attr "type" "rotate")
11692   (set (attr "length_immediate")
11693     (if_then_else
11694       (and (match_operand 2 "const1_operand")
11695	    (ior (match_test "TARGET_SHIFT1")
11696		 (match_test "optimize_function_for_size_p (cfun)")))
11697       (const_string "0")
11698       (const_string "*")))
11699   (set_attr "mode" "<MODE>")])
11700
11701(define_insn "*<rotate_insn>qi3_1_slp"
11702  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11703	(any_rotate:QI (match_dup 0)
11704		       (match_operand:QI 1 "nonmemory_operand" "cI")))
11705   (clobber (reg:CC FLAGS_REG))]
11706  "(optimize_function_for_size_p (cfun)
11707    || !TARGET_PARTIAL_REG_STALL
11708    || (operands[1] == const1_rtx
11709	&& TARGET_SHIFT1))"
11710{
11711  if (operands[1] == const1_rtx
11712      && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11713    return "<rotate>{b}\t%0";
11714  else
11715    return "<rotate>{b}\t{%1, %0|%0, %1}";
11716}
11717  [(set_attr "type" "rotate1")
11718   (set (attr "length_immediate")
11719     (if_then_else
11720       (and (match_operand 1 "const1_operand")
11721	    (ior (match_test "TARGET_SHIFT1")
11722		 (match_test "optimize_function_for_size_p (cfun)")))
11723       (const_string "0")
11724       (const_string "*")))
11725   (set_attr "mode" "QI")])
11726
11727(define_split
11728 [(set (match_operand:HI 0 "QIreg_operand")
11729       (any_rotate:HI (match_dup 0) (const_int 8)))
11730  (clobber (reg:CC FLAGS_REG))]
11731 "reload_completed
11732  && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11733 [(parallel [(set (strict_low_part (match_dup 0))
11734		  (bswap:HI (match_dup 0)))
11735	     (clobber (reg:CC FLAGS_REG))])])
11736
11737;; Bit set / bit test instructions
11738
11739;; %%% bts, btr, btc
11740
11741;; These instructions are *slow* when applied to memory.
11742
11743(define_code_attr btsc [(ior "bts") (xor "btc")])
11744
11745(define_insn "*<btsc><mode>"
11746  [(set (match_operand:SWI48 0 "register_operand" "=r")
11747	(any_or:SWI48
11748	  (ashift:SWI48 (const_int 1)
11749			(match_operand:QI 2 "register_operand" "r"))
11750	  (match_operand:SWI48 1 "register_operand" "0")))
11751   (clobber (reg:CC FLAGS_REG))]
11752  "TARGET_USE_BT"
11753  "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11754  [(set_attr "type" "alu1")
11755   (set_attr "prefix_0f" "1")
11756   (set_attr "znver1_decode" "double")
11757   (set_attr "mode" "<MODE>")])
11758
11759;; Avoid useless masking of count operand.
11760(define_insn_and_split "*<btsc><mode>_mask"
11761  [(set (match_operand:SWI48 0 "register_operand")
11762	(any_or:SWI48
11763	  (ashift:SWI48
11764	    (const_int 1)
11765	    (subreg:QI
11766	      (and:SI
11767		(match_operand:SI 1 "register_operand")
11768		(match_operand:SI 2 "const_int_operand")) 0))
11769	  (match_operand:SWI48 3 "register_operand")))
11770   (clobber (reg:CC FLAGS_REG))]
11771  "TARGET_USE_BT
11772   && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11773      == GET_MODE_BITSIZE (<MODE>mode)-1
11774   && can_create_pseudo_p ()"
11775  "#"
11776  "&& 1"
11777  [(parallel
11778     [(set (match_dup 0)
11779	   (any_or:SWI48
11780	     (ashift:SWI48 (const_int 1)
11781			   (match_dup 1))
11782	     (match_dup 3)))
11783      (clobber (reg:CC FLAGS_REG))])]
11784  "operands[1] = gen_lowpart (QImode, operands[1]);")
11785
11786(define_insn_and_split "*<btsc><mode>_mask_1"
11787  [(set (match_operand:SWI48 0 "register_operand")
11788	(any_or:SWI48
11789	  (ashift:SWI48
11790	    (const_int 1)
11791	    (and:QI
11792	      (match_operand:QI 1 "register_operand")
11793	      (match_operand:QI 2 "const_int_operand")))
11794	  (match_operand:SWI48 3 "register_operand")))
11795   (clobber (reg:CC FLAGS_REG))]
11796  "TARGET_USE_BT
11797   && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11798      == GET_MODE_BITSIZE (<MODE>mode)-1
11799   && can_create_pseudo_p ()"
11800  "#"
11801  "&& 1"
11802  [(parallel
11803     [(set (match_dup 0)
11804	   (any_or:SWI48
11805	     (ashift:SWI48 (const_int 1)
11806			   (match_dup 1))
11807	     (match_dup 3)))
11808      (clobber (reg:CC FLAGS_REG))])])
11809
11810(define_insn "*btr<mode>"
11811  [(set (match_operand:SWI48 0 "register_operand" "=r")
11812	(and:SWI48
11813	  (rotate:SWI48 (const_int -2)
11814			(match_operand:QI 2 "register_operand" "r"))
11815	(match_operand:SWI48 1 "register_operand" "0")))
11816   (clobber (reg:CC FLAGS_REG))]
11817  "TARGET_USE_BT"
11818  "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11819  [(set_attr "type" "alu1")
11820   (set_attr "prefix_0f" "1")
11821   (set_attr "znver1_decode" "double")
11822   (set_attr "mode" "<MODE>")])
11823
11824;; Avoid useless masking of count operand.
11825(define_insn_and_split "*btr<mode>_mask"
11826  [(set (match_operand:SWI48 0 "register_operand")
11827	(and:SWI48
11828	  (rotate:SWI48
11829	    (const_int -2)
11830	    (subreg:QI
11831	      (and:SI
11832		(match_operand:SI 1 "register_operand")
11833		(match_operand:SI 2 "const_int_operand")) 0))
11834	  (match_operand:SWI48 3 "register_operand")))
11835   (clobber (reg:CC FLAGS_REG))]
11836  "TARGET_USE_BT
11837   && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11838      == GET_MODE_BITSIZE (<MODE>mode)-1
11839   && can_create_pseudo_p ()"
11840  "#"
11841  "&& 1"
11842  [(parallel
11843     [(set (match_dup 0)
11844	   (and:SWI48
11845	     (rotate:SWI48 (const_int -2)
11846			   (match_dup 1))
11847	     (match_dup 3)))
11848      (clobber (reg:CC FLAGS_REG))])]
11849  "operands[1] = gen_lowpart (QImode, operands[1]);")
11850
11851(define_insn_and_split "*btr<mode>_mask_1"
11852  [(set (match_operand:SWI48 0 "register_operand")
11853	(and:SWI48
11854	  (rotate:SWI48
11855	    (const_int -2)
11856	    (and:QI
11857	      (match_operand:QI 1 "register_operand")
11858	      (match_operand:QI 2 "const_int_operand")))
11859	  (match_operand:SWI48 3 "register_operand")))
11860   (clobber (reg:CC FLAGS_REG))]
11861  "TARGET_USE_BT
11862   && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11863      == GET_MODE_BITSIZE (<MODE>mode)-1
11864   && can_create_pseudo_p ()"
11865  "#"
11866  "&& 1"
11867  [(parallel
11868     [(set (match_dup 0)
11869	   (and:SWI48
11870	     (rotate:SWI48 (const_int -2)
11871			   (match_dup 1))
11872	     (match_dup 3)))
11873      (clobber (reg:CC FLAGS_REG))])])
11874
11875;; These instructions are never faster than the corresponding
11876;; and/ior/xor operations when using immediate operand, so with
11877;; 32-bit there's no point.  But in 64-bit, we can't hold the
11878;; relevant immediates within the instruction itself, so operating
11879;; on bits in the high 32-bits of a register becomes easier.
11880;;
11881;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11882;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11883;; negdf respectively, so they can never be disabled entirely.
11884
11885(define_insn "*btsq_imm"
11886  [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11887			 (const_int 1)
11888			 (match_operand 1 "const_0_to_63_operand" "J"))
11889	(const_int 1))
11890   (clobber (reg:CC FLAGS_REG))]
11891  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11892  "bts{q}\t{%1, %0|%0, %1}"
11893  [(set_attr "type" "alu1")
11894   (set_attr "prefix_0f" "1")
11895   (set_attr "znver1_decode" "double")
11896   (set_attr "mode" "DI")])
11897
11898(define_insn "*btrq_imm"
11899  [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11900			 (const_int 1)
11901			 (match_operand 1 "const_0_to_63_operand" "J"))
11902	(const_int 0))
11903   (clobber (reg:CC FLAGS_REG))]
11904  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11905  "btr{q}\t{%1, %0|%0, %1}"
11906  [(set_attr "type" "alu1")
11907   (set_attr "prefix_0f" "1")
11908   (set_attr "znver1_decode" "double")
11909   (set_attr "mode" "DI")])
11910
11911(define_insn "*btcq_imm"
11912  [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11913			 (const_int 1)
11914			 (match_operand 1 "const_0_to_63_operand" "J"))
11915	(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11916   (clobber (reg:CC FLAGS_REG))]
11917  "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11918  "btc{q}\t{%1, %0|%0, %1}"
11919  [(set_attr "type" "alu1")
11920   (set_attr "prefix_0f" "1")
11921   (set_attr "znver1_decode" "double")
11922   (set_attr "mode" "DI")])
11923
11924;; Allow Nocona to avoid these instructions if a register is available.
11925
11926(define_peephole2
11927  [(match_scratch:DI 2 "r")
11928   (parallel [(set (zero_extract:DI
11929		     (match_operand:DI 0 "nonimmediate_operand")
11930		     (const_int 1)
11931		     (match_operand 1 "const_0_to_63_operand"))
11932		   (const_int 1))
11933	      (clobber (reg:CC FLAGS_REG))])]
11934  "TARGET_64BIT && !TARGET_USE_BT"
11935  [(parallel [(set (match_dup 0)
11936		   (ior:DI (match_dup 0) (match_dup 3)))
11937	      (clobber (reg:CC FLAGS_REG))])]
11938{
11939  int i = INTVAL (operands[1]);
11940
11941  operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11942
11943  if (!x86_64_immediate_operand (operands[3], DImode))
11944    {
11945      emit_move_insn (operands[2], operands[3]);
11946      operands[3] = operands[2];
11947    }
11948})
11949
11950(define_peephole2
11951  [(match_scratch:DI 2 "r")
11952   (parallel [(set (zero_extract:DI
11953		     (match_operand:DI 0 "nonimmediate_operand")
11954		     (const_int 1)
11955		     (match_operand 1 "const_0_to_63_operand"))
11956		   (const_int 0))
11957	      (clobber (reg:CC FLAGS_REG))])]
11958  "TARGET_64BIT && !TARGET_USE_BT"
11959  [(parallel [(set (match_dup 0)
11960		   (and:DI (match_dup 0) (match_dup 3)))
11961	      (clobber (reg:CC FLAGS_REG))])]
11962{
11963  int i = INTVAL (operands[1]);
11964
11965  operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11966
11967  if (!x86_64_immediate_operand (operands[3], DImode))
11968    {
11969      emit_move_insn (operands[2], operands[3]);
11970      operands[3] = operands[2];
11971    }
11972})
11973
11974(define_peephole2
11975  [(match_scratch:DI 2 "r")
11976   (parallel [(set (zero_extract:DI
11977		     (match_operand:DI 0 "nonimmediate_operand")
11978		     (const_int 1)
11979		     (match_operand 1 "const_0_to_63_operand"))
11980	      (not:DI (zero_extract:DI
11981			(match_dup 0) (const_int 1) (match_dup 1))))
11982	      (clobber (reg:CC FLAGS_REG))])]
11983  "TARGET_64BIT && !TARGET_USE_BT"
11984  [(parallel [(set (match_dup 0)
11985		   (xor:DI (match_dup 0) (match_dup 3)))
11986	      (clobber (reg:CC FLAGS_REG))])]
11987{
11988  int i = INTVAL (operands[1]);
11989
11990  operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11991
11992  if (!x86_64_immediate_operand (operands[3], DImode))
11993    {
11994      emit_move_insn (operands[2], operands[3]);
11995      operands[3] = operands[2];
11996    }
11997})
11998
11999;; %%% bt
12000
12001(define_insn "*bt<mode>"
12002  [(set (reg:CCC FLAGS_REG)
12003	(compare:CCC
12004	  (zero_extract:SWI48
12005	    (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12006	    (const_int 1)
12007	    (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12008	  (const_int 0)))]
12009  ""
12010{
12011  switch (get_attr_mode (insn))
12012    {
12013    case MODE_SI:
12014      return "bt{l}\t{%1, %k0|%k0, %1}";
12015
12016    case MODE_DI:
12017      return "bt{q}\t{%q1, %0|%0, %q1}";
12018
12019    default:
12020      gcc_unreachable ();
12021    }
12022}
12023  [(set_attr "type" "alu1")
12024   (set_attr "prefix_0f" "1")
12025   (set (attr "mode")
12026	(if_then_else
12027	  (and (match_test "CONST_INT_P (operands[1])")
12028	       (match_test "INTVAL (operands[1]) < 32"))
12029	  (const_string "SI")
12030	  (const_string "<MODE>")))])
12031
12032(define_insn_and_split "*jcc_bt<mode>"
12033  [(set (pc)
12034  	(if_then_else (match_operator 0 "bt_comparison_operator"
12035			[(zero_extract:SWI48
12036			   (match_operand:SWI48 1 "nonimmediate_operand")
12037			   (const_int 1)
12038			   (match_operand:SI 2 "nonmemory_operand"))
12039			 (const_int 0)])
12040		      (label_ref (match_operand 3))
12041		      (pc)))
12042   (clobber (reg:CC FLAGS_REG))]
12043  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12044   && (CONST_INT_P (operands[2])
12045       ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12046	  && INTVAL (operands[2])
12047	       >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12048       : !memory_operand (operands[1], <MODE>mode))
12049   && can_create_pseudo_p ()"
12050  "#"
12051  "&& 1"
12052  [(set (reg:CCC FLAGS_REG)
12053	(compare:CCC
12054	  (zero_extract:SWI48
12055	    (match_dup 1)
12056	    (const_int 1)
12057	    (match_dup 2))
12058	  (const_int 0)))
12059   (set (pc)
12060	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12061		      (label_ref (match_dup 3))
12062		      (pc)))]
12063{
12064  operands[0] = shallow_copy_rtx (operands[0]);
12065  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12066})
12067
12068(define_insn_and_split "*jcc_bt<mode>_1"
12069  [(set (pc)
12070  	(if_then_else (match_operator 0 "bt_comparison_operator"
12071			[(zero_extract:SWI48
12072			   (match_operand:SWI48 1 "register_operand")
12073			   (const_int 1)
12074			   (zero_extend:SI
12075			     (match_operand:QI 2 "register_operand")))
12076			 (const_int 0)])
12077		      (label_ref (match_operand 3))
12078		      (pc)))
12079   (clobber (reg:CC FLAGS_REG))]
12080  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12081   && can_create_pseudo_p ()"
12082  "#"
12083  "&& 1"
12084  [(set (reg:CCC FLAGS_REG)
12085	(compare:CCC
12086	  (zero_extract:SWI48
12087	    (match_dup 1)
12088	    (const_int 1)
12089	    (match_dup 2))
12090	  (const_int 0)))
12091   (set (pc)
12092	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12093		      (label_ref (match_dup 3))
12094		      (pc)))]
12095{
12096  operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12097  operands[0] = shallow_copy_rtx (operands[0]);
12098  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12099})
12100
12101;; Avoid useless masking of bit offset operand.
12102(define_insn_and_split "*jcc_bt<mode>_mask"
12103  [(set (pc)
12104  	(if_then_else (match_operator 0 "bt_comparison_operator"
12105			[(zero_extract:SWI48
12106			   (match_operand:SWI48 1 "register_operand")
12107			   (const_int 1)
12108			   (and:SI
12109			     (match_operand:SI 2 "register_operand")
12110			     (match_operand 3 "const_int_operand")))])
12111		      (label_ref (match_operand 4))
12112		      (pc)))
12113   (clobber (reg:CC FLAGS_REG))]
12114  "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12115   && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12116      == GET_MODE_BITSIZE (<MODE>mode)-1
12117   && can_create_pseudo_p ()"
12118  "#"
12119  "&& 1"
12120  [(set (reg:CCC FLAGS_REG)
12121	(compare:CCC
12122	  (zero_extract:SWI48
12123	    (match_dup 1)
12124	    (const_int 1)
12125	    (match_dup 2))
12126	  (const_int 0)))
12127   (set (pc)
12128	(if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12129		      (label_ref (match_dup 4))
12130		      (pc)))]
12131{
12132  operands[0] = shallow_copy_rtx (operands[0]);
12133  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12134})
12135
12136;; Store-flag instructions.
12137
12138;; For all sCOND expanders, also expand the compare or test insn that
12139;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12140
12141(define_insn_and_split "*setcc_di_1"
12142  [(set (match_operand:DI 0 "register_operand" "=q")
12143	(match_operator:DI 1 "ix86_comparison_operator"
12144	  [(reg FLAGS_REG) (const_int 0)]))]
12145  "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12146  "#"
12147  "&& reload_completed"
12148  [(set (match_dup 2) (match_dup 1))
12149   (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12150{
12151  operands[1] = shallow_copy_rtx (operands[1]);
12152  PUT_MODE (operands[1], QImode);
12153  operands[2] = gen_lowpart (QImode, operands[0]);
12154})
12155
12156(define_insn_and_split "*setcc_si_1_and"
12157  [(set (match_operand:SI 0 "register_operand" "=q")
12158	(match_operator:SI 1 "ix86_comparison_operator"
12159	  [(reg FLAGS_REG) (const_int 0)]))
12160   (clobber (reg:CC FLAGS_REG))]
12161  "!TARGET_PARTIAL_REG_STALL
12162   && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12163  "#"
12164  "&& reload_completed"
12165  [(set (match_dup 2) (match_dup 1))
12166   (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12167	      (clobber (reg:CC FLAGS_REG))])]
12168{
12169  operands[1] = shallow_copy_rtx (operands[1]);
12170  PUT_MODE (operands[1], QImode);
12171  operands[2] = gen_lowpart (QImode, operands[0]);
12172})
12173
12174(define_insn_and_split "*setcc_si_1_movzbl"
12175  [(set (match_operand:SI 0 "register_operand" "=q")
12176	(match_operator:SI 1 "ix86_comparison_operator"
12177	  [(reg FLAGS_REG) (const_int 0)]))]
12178  "!TARGET_PARTIAL_REG_STALL
12179   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12180  "#"
12181  "&& reload_completed"
12182  [(set (match_dup 2) (match_dup 1))
12183   (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12184{
12185  operands[1] = shallow_copy_rtx (operands[1]);
12186  PUT_MODE (operands[1], QImode);
12187  operands[2] = gen_lowpart (QImode, operands[0]);
12188})
12189
12190(define_insn "*setcc_qi"
12191  [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12192	(match_operator:QI 1 "ix86_comparison_operator"
12193	  [(reg FLAGS_REG) (const_int 0)]))]
12194  ""
12195  "set%C1\t%0"
12196  [(set_attr "type" "setcc")
12197   (set_attr "mode" "QI")])
12198
12199(define_insn "*setcc_qi_slp"
12200  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12201	(match_operator:QI 1 "ix86_comparison_operator"
12202	  [(reg FLAGS_REG) (const_int 0)]))]
12203  ""
12204  "set%C1\t%0"
12205  [(set_attr "type" "setcc")
12206   (set_attr "mode" "QI")])
12207
12208;; In general it is not safe to assume too much about CCmode registers,
12209;; so simplify-rtx stops when it sees a second one.  Under certain
12210;; conditions this is safe on x86, so help combine not create
12211;;
12212;;	seta	%al
12213;;	testb	%al, %al
12214;;	sete	%al
12215
12216(define_split
12217  [(set (match_operand:QI 0 "nonimmediate_operand")
12218	(ne:QI (match_operator 1 "ix86_comparison_operator"
12219	         [(reg FLAGS_REG) (const_int 0)])
12220	    (const_int 0)))]
12221  ""
12222  [(set (match_dup 0) (match_dup 1))]
12223{
12224  operands[1] = shallow_copy_rtx (operands[1]);
12225  PUT_MODE (operands[1], QImode);
12226})
12227
12228(define_split
12229  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12230	(ne:QI (match_operator 1 "ix86_comparison_operator"
12231	         [(reg FLAGS_REG) (const_int 0)])
12232	    (const_int 0)))]
12233  ""
12234  [(set (match_dup 0) (match_dup 1))]
12235{
12236  operands[1] = shallow_copy_rtx (operands[1]);
12237  PUT_MODE (operands[1], QImode);
12238})
12239
12240(define_split
12241  [(set (match_operand:QI 0 "nonimmediate_operand")
12242	(eq:QI (match_operator 1 "ix86_comparison_operator"
12243	         [(reg FLAGS_REG) (const_int 0)])
12244	    (const_int 0)))]
12245  ""
12246  [(set (match_dup 0) (match_dup 1))]
12247{
12248  operands[1] = shallow_copy_rtx (operands[1]);
12249  PUT_MODE (operands[1], QImode);
12250  PUT_CODE (operands[1],
12251	    ix86_reverse_condition (GET_CODE (operands[1]),
12252				    GET_MODE (XEXP (operands[1], 0))));
12253
12254  /* Make sure that (a) the CCmode we have for the flags is strong
12255     enough for the reversed compare or (b) we have a valid FP compare.  */
12256  if (! ix86_comparison_operator (operands[1], VOIDmode))
12257    FAIL;
12258})
12259
12260(define_split
12261  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12262	(eq:QI (match_operator 1 "ix86_comparison_operator"
12263	         [(reg FLAGS_REG) (const_int 0)])
12264	    (const_int 0)))]
12265  ""
12266  [(set (match_dup 0) (match_dup 1))]
12267{
12268  operands[1] = shallow_copy_rtx (operands[1]);
12269  PUT_MODE (operands[1], QImode);
12270  PUT_CODE (operands[1],
12271  	    ix86_reverse_condition (GET_CODE (operands[1]),
12272				    GET_MODE (XEXP (operands[1], 0))));
12273
12274  /* Make sure that (a) the CCmode we have for the flags is strong
12275     enough for the reversed compare or (b) we have a valid FP compare.  */
12276  if (! ix86_comparison_operator (operands[1], VOIDmode))
12277    FAIL;
12278})
12279
12280;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12281;; subsequent logical operations are used to imitate conditional moves.
12282;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12283;; it directly.
12284
12285(define_insn "setcc_<mode>_sse"
12286  [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12287	(match_operator:MODEF 3 "sse_comparison_operator"
12288	  [(match_operand:MODEF 1 "register_operand" "0,x")
12289	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12290  "SSE_FLOAT_MODE_P (<MODE>mode)"
12291  "@
12292   cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12293   vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12294  [(set_attr "isa" "noavx,avx")
12295   (set_attr "type" "ssecmp")
12296   (set_attr "length_immediate" "1")
12297   (set_attr "prefix" "orig,vex")
12298   (set_attr "mode" "<MODE>")])
12299
12300;; Basic conditional jump instructions.
12301;; We ignore the overflow flag for signed branch instructions.
12302
12303(define_insn "*jcc"
12304  [(set (pc)
12305	(if_then_else (match_operator 1 "ix86_comparison_operator"
12306				      [(reg FLAGS_REG) (const_int 0)])
12307		      (label_ref (match_operand 0))
12308		      (pc)))]
12309  ""
12310  "%!%+j%C1\t%l0"
12311  [(set_attr "type" "ibr")
12312   (set_attr "modrm" "0")
12313   (set (attr "length")
12314	(if_then_else
12315	  (and (ge (minus (match_dup 0) (pc))
12316		   (const_int -126))
12317	       (lt (minus (match_dup 0) (pc))
12318		   (const_int 128)))
12319	  (const_int 2)
12320	  (const_int 6)))
12321   (set_attr "maybe_prefix_bnd" "1")])
12322
12323;; In general it is not safe to assume too much about CCmode registers,
12324;; so simplify-rtx stops when it sees a second one.  Under certain
12325;; conditions this is safe on x86, so help combine not create
12326;;
12327;;	seta	%al
12328;;	testb	%al, %al
12329;;	je	Lfoo
12330
12331(define_split
12332  [(set (pc)
12333	(if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12334				      [(reg FLAGS_REG) (const_int 0)])
12335			  (const_int 0))
12336		      (label_ref (match_operand 1))
12337		      (pc)))]
12338  ""
12339  [(set (pc)
12340	(if_then_else (match_dup 0)
12341		      (label_ref (match_dup 1))
12342		      (pc)))]
12343{
12344  operands[0] = shallow_copy_rtx (operands[0]);
12345  PUT_MODE (operands[0], VOIDmode);
12346})
12347
12348(define_split
12349  [(set (pc)
12350	(if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12351				      [(reg FLAGS_REG) (const_int 0)])
12352			  (const_int 0))
12353		      (label_ref (match_operand 1))
12354		      (pc)))]
12355  ""
12356  [(set (pc)
12357	(if_then_else (match_dup 0)
12358		      (label_ref (match_dup 1))
12359		      (pc)))]
12360{
12361  operands[0] = shallow_copy_rtx (operands[0]);
12362  PUT_MODE (operands[0], VOIDmode);
12363  PUT_CODE (operands[0],
12364  	    ix86_reverse_condition (GET_CODE (operands[0]),
12365				    GET_MODE (XEXP (operands[0], 0))));
12366
12367  /* Make sure that (a) the CCmode we have for the flags is strong
12368     enough for the reversed compare or (b) we have a valid FP compare.  */
12369  if (! ix86_comparison_operator (operands[0], VOIDmode))
12370    FAIL;
12371})
12372
12373;; Unconditional and other jump instructions
12374
12375(define_insn "jump"
12376  [(set (pc)
12377	(label_ref (match_operand 0)))]
12378  ""
12379  "%!jmp\t%l0"
12380  [(set_attr "type" "ibr")
12381   (set_attr "modrm" "0")
12382   (set (attr "length")
12383	(if_then_else
12384	  (and (ge (minus (match_dup 0) (pc))
12385		   (const_int -126))
12386	       (lt (minus (match_dup 0) (pc))
12387		   (const_int 128)))
12388	  (const_int 2)
12389	  (const_int 5)))
12390   (set_attr "maybe_prefix_bnd" "1")])
12391
12392(define_expand "indirect_jump"
12393  [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12394  ""
12395{
12396  if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12397    operands[0] = convert_memory_address (word_mode, operands[0]);
12398  cfun->machine->has_local_indirect_jump = true;
12399})
12400
12401(define_insn "*indirect_jump"
12402  [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12403  ""
12404  "* return ix86_output_indirect_jmp (operands[0]);"
12405  [(set (attr "type")
12406     (if_then_else (match_test "(cfun->machine->indirect_branch_type
12407				 != indirect_branch_keep)")
12408	(const_string "multi")
12409	(const_string "ibr")))
12410   (set_attr "length_immediate" "0")
12411   (set_attr "maybe_prefix_bnd" "1")])
12412
12413(define_expand "tablejump"
12414  [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12415	      (use (label_ref (match_operand 1)))])]
12416  ""
12417{
12418  /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12419     relative.  Convert the relative address to an absolute address.  */
12420  if (flag_pic)
12421    {
12422      rtx op0, op1;
12423      enum rtx_code code;
12424
12425      /* We can't use @GOTOFF for text labels on VxWorks;
12426	 see gotoff_operand.  */
12427      if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12428	{
12429	  code = PLUS;
12430	  op0 = operands[0];
12431	  op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12432	}
12433      else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12434	{
12435	  code = PLUS;
12436	  op0 = operands[0];
12437	  op1 = pic_offset_table_rtx;
12438	}
12439      else
12440	{
12441	  code = MINUS;
12442	  op0 = pic_offset_table_rtx;
12443	  op1 = operands[0];
12444	}
12445
12446      operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12447					 OPTAB_DIRECT);
12448    }
12449
12450  if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12451    operands[0] = convert_memory_address (word_mode, operands[0]);
12452  cfun->machine->has_local_indirect_jump = true;
12453})
12454
12455(define_insn "*tablejump_1"
12456  [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12457   (use (label_ref (match_operand 1)))]
12458  ""
12459  "* return ix86_output_indirect_jmp (operands[0]);"
12460  [(set (attr "type")
12461     (if_then_else (match_test "(cfun->machine->indirect_branch_type
12462				 != indirect_branch_keep)")
12463	(const_string "multi")
12464	(const_string "ibr")))
12465   (set_attr "length_immediate" "0")
12466   (set_attr "maybe_prefix_bnd" "1")])
12467
12468;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12469
12470(define_peephole2
12471  [(set (reg FLAGS_REG) (match_operand 0))
12472   (set (match_operand:QI 1 "register_operand")
12473	(match_operator:QI 2 "ix86_comparison_operator"
12474	  [(reg FLAGS_REG) (const_int 0)]))
12475   (set (match_operand 3 "any_QIreg_operand")
12476	(zero_extend (match_dup 1)))]
12477  "(peep2_reg_dead_p (3, operands[1])
12478    || operands_match_p (operands[1], operands[3]))
12479   && ! reg_overlap_mentioned_p (operands[3], operands[0])
12480   && peep2_regno_dead_p (0, FLAGS_REG)"
12481  [(set (match_dup 4) (match_dup 0))
12482   (set (strict_low_part (match_dup 5))
12483	(match_dup 2))]
12484{
12485  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12486  operands[5] = gen_lowpart (QImode, operands[3]);
12487  ix86_expand_clear (operands[3]);
12488})
12489
12490(define_peephole2
12491  [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12492	      (match_operand 4)])
12493   (set (match_operand:QI 1 "register_operand")
12494	(match_operator:QI 2 "ix86_comparison_operator"
12495	  [(reg FLAGS_REG) (const_int 0)]))
12496   (set (match_operand 3 "any_QIreg_operand")
12497	(zero_extend (match_dup 1)))]
12498  "(peep2_reg_dead_p (3, operands[1])
12499    || operands_match_p (operands[1], operands[3]))
12500   && ! reg_overlap_mentioned_p (operands[3], operands[0])
12501   && ! reg_overlap_mentioned_p (operands[3], operands[4])
12502   && ! reg_set_p (operands[3], operands[4])
12503   && peep2_regno_dead_p (0, FLAGS_REG)"
12504  [(parallel [(set (match_dup 5) (match_dup 0))
12505	      (match_dup 4)])
12506   (set (strict_low_part (match_dup 6))
12507	(match_dup 2))]
12508{
12509  operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12510  operands[6] = gen_lowpart (QImode, operands[3]);
12511  ix86_expand_clear (operands[3]);
12512})
12513
12514(define_peephole2
12515  [(set (reg FLAGS_REG) (match_operand 0))
12516   (parallel [(set (reg FLAGS_REG) (match_operand 1))
12517	      (match_operand 5)])
12518   (set (match_operand:QI 2 "register_operand")
12519	(match_operator:QI 3 "ix86_comparison_operator"
12520	  [(reg FLAGS_REG) (const_int 0)]))
12521   (set (match_operand 4 "any_QIreg_operand")
12522	(zero_extend (match_dup 2)))]
12523  "(peep2_reg_dead_p (4, operands[2])
12524    || operands_match_p (operands[2], operands[4]))
12525   && ! reg_overlap_mentioned_p (operands[4], operands[0])
12526   && ! reg_overlap_mentioned_p (operands[4], operands[1])
12527   && ! reg_overlap_mentioned_p (operands[4], operands[5])
12528   && ! reg_set_p (operands[4], operands[5])
12529   && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12530   && peep2_regno_dead_p (0, FLAGS_REG)"
12531  [(set (match_dup 6) (match_dup 0))
12532   (parallel [(set (match_dup 7) (match_dup 1))
12533	      (match_dup 5)])
12534   (set (strict_low_part (match_dup 8))
12535	(match_dup 3))]
12536{
12537  operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12538  operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12539  operands[8] = gen_lowpart (QImode, operands[4]);
12540  ix86_expand_clear (operands[4]);
12541})
12542
12543;; Similar, but match zero extend with andsi3.
12544
12545(define_peephole2
12546  [(set (reg FLAGS_REG) (match_operand 0))
12547   (set (match_operand:QI 1 "register_operand")
12548	(match_operator:QI 2 "ix86_comparison_operator"
12549	  [(reg FLAGS_REG) (const_int 0)]))
12550   (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12551		   (and:SI (match_dup 3) (const_int 255)))
12552	      (clobber (reg:CC FLAGS_REG))])]
12553  "REGNO (operands[1]) == REGNO (operands[3])
12554   && ! reg_overlap_mentioned_p (operands[3], operands[0])
12555   && peep2_regno_dead_p (0, FLAGS_REG)"
12556  [(set (match_dup 4) (match_dup 0))
12557   (set (strict_low_part (match_dup 5))
12558	(match_dup 2))]
12559{
12560  operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12561  operands[5] = gen_lowpart (QImode, operands[3]);
12562  ix86_expand_clear (operands[3]);
12563})
12564
12565(define_peephole2
12566  [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12567	      (match_operand 4)])
12568   (set (match_operand:QI 1 "register_operand")
12569	(match_operator:QI 2 "ix86_comparison_operator"
12570	  [(reg FLAGS_REG) (const_int 0)]))
12571   (parallel [(set (match_operand 3 "any_QIreg_operand")
12572		   (zero_extend (match_dup 1)))
12573	      (clobber (reg:CC FLAGS_REG))])]
12574  "(peep2_reg_dead_p (3, operands[1])
12575    || operands_match_p (operands[1], operands[3]))
12576   && ! reg_overlap_mentioned_p (operands[3], operands[0])
12577   && ! reg_overlap_mentioned_p (operands[3], operands[4])
12578   && ! reg_set_p (operands[3], operands[4])
12579   && peep2_regno_dead_p (0, FLAGS_REG)"
12580  [(parallel [(set (match_dup 5) (match_dup 0))
12581	      (match_dup 4)])
12582   (set (strict_low_part (match_dup 6))
12583	(match_dup 2))]
12584{
12585  operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12586  operands[6] = gen_lowpart (QImode, operands[3]);
12587  ix86_expand_clear (operands[3]);
12588})
12589
12590(define_peephole2
12591  [(set (reg FLAGS_REG) (match_operand 0))
12592   (parallel [(set (reg FLAGS_REG) (match_operand 1))
12593	      (match_operand 5)])
12594   (set (match_operand:QI 2 "register_operand")
12595	(match_operator:QI 3 "ix86_comparison_operator"
12596	  [(reg FLAGS_REG) (const_int 0)]))
12597   (parallel [(set (match_operand 4 "any_QIreg_operand")
12598		   (zero_extend (match_dup 2)))
12599	      (clobber (reg:CC FLAGS_REG))])]
12600  "(peep2_reg_dead_p (4, operands[2])
12601    || operands_match_p (operands[2], operands[4]))
12602   && ! reg_overlap_mentioned_p (operands[4], operands[0])
12603   && ! reg_overlap_mentioned_p (operands[4], operands[1])
12604   && ! reg_overlap_mentioned_p (operands[4], operands[5])
12605   && ! reg_set_p (operands[4], operands[5])
12606   && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12607   && peep2_regno_dead_p (0, FLAGS_REG)"
12608  [(set (match_dup 6) (match_dup 0))
12609   (parallel [(set (match_dup 7) (match_dup 1))
12610	      (match_dup 5)])
12611   (set (strict_low_part (match_dup 8))
12612	(match_dup 3))]
12613{
12614  operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12615  operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12616  operands[8] = gen_lowpart (QImode, operands[4]);
12617  ix86_expand_clear (operands[4]);
12618})
12619
12620;; Call instructions.
12621
12622;; The predicates normally associated with named expanders are not properly
12623;; checked for calls.  This is a bug in the generic code, but it isn't that
12624;; easy to fix.  Ignore it for now and be prepared to fix things up.
12625
12626;; P6 processors will jump to the address after the decrement when %esp
12627;; is used as a call operand, so they will execute return address as a code.
12628;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12629
12630;; Register constraint for call instruction.
12631(define_mode_attr c [(SI "l") (DI "r")])
12632
12633;; Call subroutine returning no value.
12634
12635(define_expand "call"
12636  [(call (match_operand:QI 0)
12637	 (match_operand 1))
12638   (use (match_operand 2))]
12639  ""
12640{
12641  ix86_expand_call (NULL, operands[0], operands[1],
12642		    operands[2], NULL, false);
12643  DONE;
12644})
12645
12646(define_expand "sibcall"
12647  [(call (match_operand:QI 0)
12648	 (match_operand 1))
12649   (use (match_operand 2))]
12650  ""
12651{
12652  ix86_expand_call (NULL, operands[0], operands[1],
12653		    operands[2], NULL, true);
12654  DONE;
12655})
12656
12657(define_insn "*call"
12658  [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12659	 (match_operand 1))]
12660  "!SIBLING_CALL_P (insn)"
12661  "* return ix86_output_call_insn (insn, operands[0]);"
12662  [(set_attr "type" "call")])
12663
12664;; This covers both call and sibcall since only GOT slot is allowed.
12665(define_insn "*call_got_x32"
12666  [(call (mem:QI (zero_extend:DI
12667		   (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12668	 (match_operand 1))]
12669  "TARGET_X32"
12670{
12671  rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12672  return ix86_output_call_insn (insn, fnaddr);
12673}
12674  [(set_attr "type" "call")])
12675
12676;; Since sibcall never returns, we can only use call-clobbered register
12677;; as GOT base.
12678(define_insn "*sibcall_GOT_32"
12679  [(call (mem:QI
12680	   (mem:SI (plus:SI
12681		     (match_operand:SI 0 "register_no_elim_operand" "U")
12682		     (match_operand:SI 1 "GOT32_symbol_operand"))))
12683	 (match_operand 2))]
12684  "!TARGET_MACHO
12685  && !TARGET_64BIT
12686  && !TARGET_INDIRECT_BRANCH_REGISTER
12687  && SIBLING_CALL_P (insn)"
12688{
12689  rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12690  fnaddr = gen_const_mem (SImode, fnaddr);
12691  return ix86_output_call_insn (insn, fnaddr);
12692}
12693  [(set_attr "type" "call")])
12694
12695(define_insn "*sibcall"
12696  [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12697	 (match_operand 1))]
12698  "SIBLING_CALL_P (insn)"
12699  "* return ix86_output_call_insn (insn, operands[0]);"
12700  [(set_attr "type" "call")])
12701
12702(define_insn "*sibcall_memory"
12703  [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12704	 (match_operand 1))
12705   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12706  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12707  "* return ix86_output_call_insn (insn, operands[0]);"
12708  [(set_attr "type" "call")])
12709
12710(define_peephole2
12711  [(set (match_operand:W 0 "register_operand")
12712	(match_operand:W 1 "memory_operand"))
12713   (call (mem:QI (match_dup 0))
12714	 (match_operand 3))]
12715  "!TARGET_X32
12716   && !TARGET_INDIRECT_BRANCH_REGISTER
12717   && SIBLING_CALL_P (peep2_next_insn (1))
12718   && !reg_mentioned_p (operands[0],
12719			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12720  [(parallel [(call (mem:QI (match_dup 1))
12721		    (match_dup 3))
12722	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12723
12724(define_peephole2
12725  [(set (match_operand:W 0 "register_operand")
12726	(match_operand:W 1 "memory_operand"))
12727   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12728   (call (mem:QI (match_dup 0))
12729	 (match_operand 3))]
12730  "!TARGET_X32
12731   && !TARGET_INDIRECT_BRANCH_REGISTER
12732   && SIBLING_CALL_P (peep2_next_insn (2))
12733   && !reg_mentioned_p (operands[0],
12734			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12735  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12736   (parallel [(call (mem:QI (match_dup 1))
12737		    (match_dup 3))
12738	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12739
12740(define_expand "call_pop"
12741  [(parallel [(call (match_operand:QI 0)
12742		    (match_operand:SI 1))
12743	      (set (reg:SI SP_REG)
12744		   (plus:SI (reg:SI SP_REG)
12745			    (match_operand:SI 3)))])]
12746  "!TARGET_64BIT"
12747{
12748  ix86_expand_call (NULL, operands[0], operands[1],
12749		    operands[2], operands[3], false);
12750  DONE;
12751})
12752
12753(define_insn "*call_pop"
12754  [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12755	 (match_operand 1))
12756   (set (reg:SI SP_REG)
12757	(plus:SI (reg:SI SP_REG)
12758		 (match_operand:SI 2 "immediate_operand" "i")))]
12759  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12760  "* return ix86_output_call_insn (insn, operands[0]);"
12761  [(set_attr "type" "call")])
12762
12763(define_insn "*sibcall_pop"
12764  [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12765	 (match_operand 1))
12766   (set (reg:SI SP_REG)
12767	(plus:SI (reg:SI SP_REG)
12768		 (match_operand:SI 2 "immediate_operand" "i")))]
12769  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12770  "* return ix86_output_call_insn (insn, operands[0]);"
12771  [(set_attr "type" "call")])
12772
12773(define_insn "*sibcall_pop_memory"
12774  [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12775	 (match_operand 1))
12776   (set (reg:SI SP_REG)
12777	(plus:SI (reg:SI SP_REG)
12778		 (match_operand:SI 2 "immediate_operand" "i")))
12779   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12780  "!TARGET_64BIT"
12781  "* return ix86_output_call_insn (insn, operands[0]);"
12782  [(set_attr "type" "call")])
12783
12784(define_peephole2
12785  [(set (match_operand:SI 0 "register_operand")
12786	(match_operand:SI 1 "memory_operand"))
12787   (parallel [(call (mem:QI (match_dup 0))
12788		    (match_operand 3))
12789	      (set (reg:SI SP_REG)
12790		   (plus:SI (reg:SI SP_REG)
12791			    (match_operand:SI 4 "immediate_operand")))])]
12792  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12793   && !reg_mentioned_p (operands[0],
12794			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12795  [(parallel [(call (mem:QI (match_dup 1))
12796		    (match_dup 3))
12797	      (set (reg:SI SP_REG)
12798		   (plus:SI (reg:SI SP_REG)
12799			    (match_dup 4)))
12800	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12801
12802(define_peephole2
12803  [(set (match_operand:SI 0 "register_operand")
12804	(match_operand:SI 1 "memory_operand"))
12805   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12806   (parallel [(call (mem:QI (match_dup 0))
12807		    (match_operand 3))
12808	      (set (reg:SI SP_REG)
12809		   (plus:SI (reg:SI SP_REG)
12810			    (match_operand:SI 4 "immediate_operand")))])]
12811  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12812   && !reg_mentioned_p (operands[0],
12813			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12814  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12815   (parallel [(call (mem:QI (match_dup 1))
12816		    (match_dup 3))
12817	      (set (reg:SI SP_REG)
12818		   (plus:SI (reg:SI SP_REG)
12819			    (match_dup 4)))
12820	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12821
12822;; Combining simple memory jump instruction
12823
12824(define_peephole2
12825  [(set (match_operand:W 0 "register_operand")
12826        (match_operand:W 1 "memory_operand"))
12827   (set (pc) (match_dup 0))]
12828  "!TARGET_X32
12829   && !TARGET_INDIRECT_BRANCH_REGISTER
12830   && peep2_reg_dead_p (2, operands[0])"
12831  [(set (pc) (match_dup 1))])
12832
12833;; Call subroutine, returning value in operand 0
12834
12835(define_expand "call_value"
12836  [(set (match_operand 0)
12837	(call (match_operand:QI 1)
12838	      (match_operand 2)))
12839   (use (match_operand 3))]
12840  ""
12841{
12842  ix86_expand_call (operands[0], operands[1], operands[2],
12843		    operands[3], NULL, false);
12844  DONE;
12845})
12846
12847(define_expand "sibcall_value"
12848  [(set (match_operand 0)
12849	(call (match_operand:QI 1)
12850	      (match_operand 2)))
12851   (use (match_operand 3))]
12852  ""
12853{
12854  ix86_expand_call (operands[0], operands[1], operands[2],
12855		    operands[3], NULL, true);
12856  DONE;
12857})
12858
12859(define_insn "*call_value"
12860  [(set (match_operand 0)
12861	(call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12862	      (match_operand 2)))]
12863  "!SIBLING_CALL_P (insn)"
12864  "* return ix86_output_call_insn (insn, operands[1]);"
12865  [(set_attr "type" "callv")])
12866
12867;; This covers both call and sibcall since only GOT slot is allowed.
12868(define_insn "*call_value_got_x32"
12869  [(set (match_operand 0)
12870	(call (mem:QI
12871		(zero_extend:DI
12872		  (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12873	      (match_operand 2)))]
12874  "TARGET_X32"
12875{
12876  rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12877  return ix86_output_call_insn (insn, fnaddr);
12878}
12879  [(set_attr "type" "callv")])
12880
12881;; Since sibcall never returns, we can only use call-clobbered register
12882;; as GOT base.
12883(define_insn "*sibcall_value_GOT_32"
12884  [(set (match_operand 0)
12885        (call (mem:QI
12886		(mem:SI (plus:SI
12887			  (match_operand:SI 1 "register_no_elim_operand" "U")
12888			  (match_operand:SI 2 "GOT32_symbol_operand"))))
12889	 (match_operand 3)))]
12890  "!TARGET_MACHO
12891   && !TARGET_64BIT
12892   && !TARGET_INDIRECT_BRANCH_REGISTER
12893   && SIBLING_CALL_P (insn)"
12894{
12895  rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12896  fnaddr = gen_const_mem (SImode, fnaddr);
12897  return ix86_output_call_insn (insn, fnaddr);
12898}
12899  [(set_attr "type" "callv")])
12900
12901(define_insn "*sibcall_value"
12902  [(set (match_operand 0)
12903	(call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12904	      (match_operand 2)))]
12905  "SIBLING_CALL_P (insn)"
12906  "* return ix86_output_call_insn (insn, operands[1]);"
12907  [(set_attr "type" "callv")])
12908
12909(define_insn "*sibcall_value_memory"
12910  [(set (match_operand 0)
12911 	(call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12912	      (match_operand 2)))
12913   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12914  "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12915  "* return ix86_output_call_insn (insn, operands[1]);"
12916  [(set_attr "type" "callv")])
12917
12918(define_peephole2
12919  [(set (match_operand:W 0 "register_operand")
12920	(match_operand:W 1 "memory_operand"))
12921   (set (match_operand 2)
12922   (call (mem:QI (match_dup 0))
12923		 (match_operand 3)))]
12924  "!TARGET_X32
12925   && !TARGET_INDIRECT_BRANCH_REGISTER
12926   && SIBLING_CALL_P (peep2_next_insn (1))
12927   && !reg_mentioned_p (operands[0],
12928			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12929  [(parallel [(set (match_dup 2)
12930		   (call (mem:QI (match_dup 1))
12931			 (match_dup 3)))
12932	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12933
12934(define_peephole2
12935  [(set (match_operand:W 0 "register_operand")
12936	(match_operand:W 1 "memory_operand"))
12937   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12938   (set (match_operand 2)
12939	(call (mem:QI (match_dup 0))
12940	      (match_operand 3)))]
12941  "!TARGET_X32
12942   && !TARGET_INDIRECT_BRANCH_REGISTER
12943   && SIBLING_CALL_P (peep2_next_insn (2))
12944   && !reg_mentioned_p (operands[0],
12945			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12946  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12947   (parallel [(set (match_dup 2)
12948		   (call (mem:QI (match_dup 1))
12949			 (match_dup 3)))
12950	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12951
12952(define_expand "call_value_pop"
12953  [(parallel [(set (match_operand 0)
12954		   (call (match_operand:QI 1)
12955			 (match_operand:SI 2)))
12956	      (set (reg:SI SP_REG)
12957		   (plus:SI (reg:SI SP_REG)
12958			    (match_operand:SI 4)))])]
12959  "!TARGET_64BIT"
12960{
12961  ix86_expand_call (operands[0], operands[1], operands[2],
12962		    operands[3], operands[4], false);
12963  DONE;
12964})
12965
12966(define_insn "*call_value_pop"
12967  [(set (match_operand 0)
12968	(call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12969	      (match_operand 2)))
12970   (set (reg:SI SP_REG)
12971	(plus:SI (reg:SI SP_REG)
12972		 (match_operand:SI 3 "immediate_operand" "i")))]
12973  "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12974  "* return ix86_output_call_insn (insn, operands[1]);"
12975  [(set_attr "type" "callv")])
12976
12977(define_insn "*sibcall_value_pop"
12978  [(set (match_operand 0)
12979	(call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12980	      (match_operand 2)))
12981   (set (reg:SI SP_REG)
12982	(plus:SI (reg:SI SP_REG)
12983		 (match_operand:SI 3 "immediate_operand" "i")))]
12984  "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12985  "* return ix86_output_call_insn (insn, operands[1]);"
12986  [(set_attr "type" "callv")])
12987
12988(define_insn "*sibcall_value_pop_memory"
12989  [(set (match_operand 0)
12990 	(call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12991	      (match_operand 2)))
12992   (set (reg:SI SP_REG)
12993	(plus:SI (reg:SI SP_REG)
12994		 (match_operand:SI 3 "immediate_operand" "i")))
12995   (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12996  "!TARGET_64BIT"
12997  "* return ix86_output_call_insn (insn, operands[1]);"
12998  [(set_attr "type" "callv")])
12999
13000(define_peephole2
13001  [(set (match_operand:SI 0 "register_operand")
13002	(match_operand:SI 1 "memory_operand"))
13003   (parallel [(set (match_operand 2)
13004		   (call (mem:QI (match_dup 0))
13005			 (match_operand 3)))
13006	      (set (reg:SI SP_REG)
13007		   (plus:SI (reg:SI SP_REG)
13008			    (match_operand:SI 4 "immediate_operand")))])]
13009  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13010   && !reg_mentioned_p (operands[0],
13011			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13012  [(parallel [(set (match_dup 2)
13013		   (call (mem:QI (match_dup 1))
13014			 (match_dup 3)))
13015	      (set (reg:SI SP_REG)
13016		   (plus:SI (reg:SI SP_REG)
13017			    (match_dup 4)))
13018	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13019
13020(define_peephole2
13021  [(set (match_operand:SI 0 "register_operand")
13022	(match_operand:SI 1 "memory_operand"))
13023   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13024   (parallel [(set (match_operand 2)
13025		   (call (mem:QI (match_dup 0))
13026			 (match_operand 3)))
13027	      (set (reg:SI SP_REG)
13028		   (plus:SI (reg:SI SP_REG)
13029			    (match_operand:SI 4 "immediate_operand")))])]
13030  "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13031   && !reg_mentioned_p (operands[0],
13032			CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13033  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13034   (parallel [(set (match_dup 2)
13035		   (call (mem:QI (match_dup 1))
13036			 (match_dup 3)))
13037	      (set (reg:SI SP_REG)
13038		   (plus:SI (reg:SI SP_REG)
13039			    (match_dup 4)))
13040	      (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13041
13042;; Call subroutine returning any type.
13043
13044(define_expand "untyped_call"
13045  [(parallel [(call (match_operand 0)
13046		    (const_int 0))
13047	      (match_operand 1)
13048	      (match_operand 2)])]
13049  ""
13050{
13051  int i;
13052
13053  /* In order to give reg-stack an easier job in validating two
13054     coprocessor registers as containing a possible return value,
13055     simply pretend the untyped call returns a complex long double
13056     value.
13057
13058     We can't use SSE_REGPARM_MAX here since callee is unprototyped
13059     and should have the default ABI.  */
13060
13061  ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13062		     ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13063		    operands[0], const0_rtx,
13064		    GEN_INT ((TARGET_64BIT
13065			      ? (ix86_abi == SYSV_ABI
13066				 ? X86_64_SSE_REGPARM_MAX
13067				 : X86_64_MS_SSE_REGPARM_MAX)
13068			      : X86_32_SSE_REGPARM_MAX)
13069		    	     - 1),
13070		    NULL, false);
13071
13072  for (i = 0; i < XVECLEN (operands[2], 0); i++)
13073    {
13074      rtx set = XVECEXP (operands[2], 0, i);
13075      emit_move_insn (SET_DEST (set), SET_SRC (set));
13076    }
13077
13078  /* The optimizer does not know that the call sets the function value
13079     registers we stored in the result block.  We avoid problems by
13080     claiming that all hard registers are used and clobbered at this
13081     point.  */
13082  emit_insn (gen_blockage ());
13083
13084  DONE;
13085})
13086
13087;; Prologue and epilogue instructions
13088
13089;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13090;; all of memory.  This blocks insns from being moved across this point.
13091
13092(define_insn "blockage"
13093  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13094  ""
13095  ""
13096  [(set_attr "length" "0")])
13097
13098;; Do not schedule instructions accessing memory across this point.
13099
13100(define_expand "memory_blockage"
13101  [(set (match_dup 0)
13102	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13103  ""
13104{
13105  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13106  MEM_VOLATILE_P (operands[0]) = 1;
13107})
13108
13109(define_insn "*memory_blockage"
13110  [(set (match_operand:BLK 0)
13111	(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13112  ""
13113  ""
13114  [(set_attr "length" "0")])
13115
13116;; As USE insns aren't meaningful after reload, this is used instead
13117;; to prevent deleting instructions setting registers for PIC code
13118(define_insn "prologue_use"
13119  [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13120  ""
13121  ""
13122  [(set_attr "length" "0")])
13123
13124;; Insn emitted into the body of a function to return from a function.
13125;; This is only done if the function's epilogue is known to be simple.
13126;; See comments for ix86_can_use_return_insn_p in i386.c.
13127
13128(define_expand "return"
13129  [(simple_return)]
13130  "ix86_can_use_return_insn_p ()"
13131{
13132  if (crtl->args.pops_args)
13133    {
13134      rtx popc = GEN_INT (crtl->args.pops_args);
13135      emit_jump_insn (gen_simple_return_pop_internal (popc));
13136      DONE;
13137    }
13138})
13139
13140;; We need to disable this for TARGET_SEH, as otherwise
13141;; shrink-wrapped prologue gets enabled too.  This might exceed
13142;; the maximum size of prologue in unwind information.
13143;; Also disallow shrink-wrapping if using stack slot to pass the
13144;; static chain pointer - the first instruction has to be pushl %esi
13145;; and it can't be moved around, as we use alternate entry points
13146;; in that case.
13147
13148(define_expand "simple_return"
13149  [(simple_return)]
13150  "!TARGET_SEH && !ix86_static_chain_on_stack"
13151{
13152  if (crtl->args.pops_args)
13153    {
13154      rtx popc = GEN_INT (crtl->args.pops_args);
13155      emit_jump_insn (gen_simple_return_pop_internal (popc));
13156      DONE;
13157    }
13158})
13159
13160(define_insn "simple_return_internal"
13161  [(simple_return)]
13162  "reload_completed"
13163  "* return ix86_output_function_return (false);"
13164  [(set_attr "length" "1")
13165   (set_attr "atom_unit" "jeu")
13166   (set_attr "length_immediate" "0")
13167   (set_attr "modrm" "0")
13168   (set_attr "maybe_prefix_bnd" "1")])
13169
13170(define_insn "interrupt_return"
13171  [(simple_return)
13172   (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13173  "reload_completed"
13174{
13175  return TARGET_64BIT ? "iretq" : "iret";
13176})
13177
13178;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13179;; instruction Athlon and K8 have.
13180
13181(define_insn "simple_return_internal_long"
13182  [(simple_return)
13183   (unspec [(const_int 0)] UNSPEC_REP)]
13184  "reload_completed"
13185  "* return ix86_output_function_return (true);"
13186  [(set_attr "length" "2")
13187   (set_attr "atom_unit" "jeu")
13188   (set_attr "length_immediate" "0")
13189   (set_attr "prefix_rep" "1")
13190   (set_attr "modrm" "0")])
13191
13192(define_insn_and_split "simple_return_pop_internal"
13193  [(simple_return)
13194   (use (match_operand:SI 0 "const_int_operand"))]
13195  "reload_completed"
13196  "%!ret\t%0"
13197  "&& cfun->machine->function_return_type != indirect_branch_keep"
13198  [(const_int 0)]
13199  "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13200  [(set_attr "length" "3")
13201   (set_attr "atom_unit" "jeu")
13202   (set_attr "length_immediate" "2")
13203   (set_attr "modrm" "0")
13204   (set_attr "maybe_prefix_bnd" "1")])
13205
13206(define_insn "simple_return_indirect_internal"
13207  [(simple_return)
13208   (use (match_operand 0 "register_operand" "r"))]
13209  "reload_completed"
13210  "* return ix86_output_indirect_function_return (operands[0]);"
13211  [(set (attr "type")
13212     (if_then_else (match_test "(cfun->machine->indirect_branch_type
13213				 != indirect_branch_keep)")
13214	(const_string "multi")
13215	(const_string "ibr")))
13216   (set_attr "length_immediate" "0")
13217   (set_attr "maybe_prefix_bnd" "1")])
13218
13219(define_insn "nop"
13220  [(const_int 0)]
13221  ""
13222  "nop"
13223  [(set_attr "length" "1")
13224   (set_attr "length_immediate" "0")
13225   (set_attr "modrm" "0")])
13226
13227;; Generate nops.  Operand 0 is the number of nops, up to 8.
13228(define_insn "nops"
13229  [(unspec_volatile [(match_operand 0 "const_int_operand")]
13230		    UNSPECV_NOPS)]
13231  "reload_completed"
13232{
13233  int num = INTVAL (operands[0]);
13234
13235  gcc_assert (IN_RANGE (num, 1, 8));
13236
13237  while (num--)
13238    fputs ("\tnop\n", asm_out_file);
13239
13240  return "";
13241}
13242  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13243   (set_attr "length_immediate" "0")
13244   (set_attr "modrm" "0")])
13245
13246;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13247;; branch prediction penalty for the third jump in a 16-byte
13248;; block on K8.
13249
13250(define_insn "pad"
13251  [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13252  ""
13253{
13254#ifdef ASM_OUTPUT_MAX_SKIP_PAD
13255  ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13256#else
13257  /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13258     The align insn is used to avoid 3 jump instructions in the row to improve
13259     branch prediction and the benefits hardly outweigh the cost of extra 8
13260     nops on the average inserted by full alignment pseudo operation.  */
13261#endif
13262  return "";
13263}
13264  [(set_attr "length" "16")])
13265
13266(define_expand "prologue"
13267  [(const_int 0)]
13268  ""
13269  "ix86_expand_prologue (); DONE;")
13270
13271(define_expand "set_got"
13272  [(parallel
13273     [(set (match_operand:SI 0 "register_operand")
13274	   (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13275      (clobber (reg:CC FLAGS_REG))])]
13276  "!TARGET_64BIT"
13277{
13278  if (flag_pic && !TARGET_VXWORKS_RTP)
13279    ix86_pc_thunk_call_expanded = true;
13280})
13281
13282(define_insn "*set_got"
13283  [(set (match_operand:SI 0 "register_operand" "=r")
13284	(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13285   (clobber (reg:CC FLAGS_REG))]
13286  "!TARGET_64BIT"
13287  "* return output_set_got (operands[0], NULL_RTX);"
13288  [(set_attr "type" "multi")
13289   (set_attr "length" "12")])
13290
13291(define_expand "set_got_labelled"
13292  [(parallel
13293     [(set (match_operand:SI 0 "register_operand")
13294	   (unspec:SI [(label_ref (match_operand 1))]
13295		      UNSPEC_SET_GOT))
13296      (clobber (reg:CC FLAGS_REG))])]
13297  "!TARGET_64BIT"
13298{
13299  if (flag_pic && !TARGET_VXWORKS_RTP)
13300    ix86_pc_thunk_call_expanded = true;
13301})
13302
13303(define_insn "*set_got_labelled"
13304  [(set (match_operand:SI 0 "register_operand" "=r")
13305	(unspec:SI [(label_ref (match_operand 1))]
13306	 UNSPEC_SET_GOT))
13307   (clobber (reg:CC FLAGS_REG))]
13308  "!TARGET_64BIT"
13309  "* return output_set_got (operands[0], operands[1]);"
13310  [(set_attr "type" "multi")
13311   (set_attr "length" "12")])
13312
13313(define_insn "set_got_rex64"
13314  [(set (match_operand:DI 0 "register_operand" "=r")
13315	(unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13316  "TARGET_64BIT"
13317  "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13318  [(set_attr "type" "lea")
13319   (set_attr "length_address" "4")
13320   (set_attr "modrm_class" "unknown")
13321   (set_attr "mode" "DI")])
13322
13323(define_insn "set_rip_rex64"
13324  [(set (match_operand:DI 0 "register_operand" "=r")
13325	(unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13326  "TARGET_64BIT"
13327  "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13328  [(set_attr "type" "lea")
13329   (set_attr "length_address" "4")
13330   (set_attr "mode" "DI")])
13331
13332(define_insn "set_got_offset_rex64"
13333  [(set (match_operand:DI 0 "register_operand" "=r")
13334	(unspec:DI
13335	  [(label_ref (match_operand 1))]
13336	  UNSPEC_SET_GOT_OFFSET))]
13337  "TARGET_LP64"
13338  "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13339  [(set_attr "type" "imov")
13340   (set_attr "length_immediate" "0")
13341   (set_attr "length_address" "8")
13342   (set_attr "mode" "DI")])
13343
13344(define_expand "epilogue"
13345  [(const_int 0)]
13346  ""
13347  "ix86_expand_epilogue (1); DONE;")
13348
13349(define_expand "sibcall_epilogue"
13350  [(const_int 0)]
13351  ""
13352  "ix86_expand_epilogue (0); DONE;")
13353
13354(define_expand "eh_return"
13355  [(use (match_operand 0 "register_operand"))]
13356  ""
13357{
13358  rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13359
13360  /* Tricky bit: we write the address of the handler to which we will
13361     be returning into someone else's stack frame, one word below the
13362     stack address we wish to restore.  */
13363  tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13364  tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13365  /* Return address is always in word_mode.  */
13366  tmp = gen_rtx_MEM (word_mode, tmp);
13367  if (GET_MODE (ra) != word_mode)
13368    ra = convert_to_mode (word_mode, ra, 1);
13369  emit_move_insn (tmp, ra);
13370
13371  emit_jump_insn (gen_eh_return_internal ());
13372  emit_barrier ();
13373  DONE;
13374})
13375
13376(define_insn_and_split "eh_return_internal"
13377  [(eh_return)]
13378  ""
13379  "#"
13380  "epilogue_completed"
13381  [(const_int 0)]
13382  "ix86_expand_epilogue (2); DONE;")
13383
13384(define_insn "leave"
13385  [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13386   (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13387   (clobber (mem:BLK (scratch)))]
13388  "!TARGET_64BIT"
13389  "leave"
13390  [(set_attr "type" "leave")])
13391
13392(define_insn "leave_rex64"
13393  [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13394   (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13395   (clobber (mem:BLK (scratch)))]
13396  "TARGET_64BIT"
13397  "leave"
13398  [(set_attr "type" "leave")])
13399
13400;; Handle -fsplit-stack.
13401
13402(define_expand "split_stack_prologue"
13403  [(const_int 0)]
13404  ""
13405{
13406  ix86_expand_split_stack_prologue ();
13407  DONE;
13408})
13409
13410;; In order to support the call/return predictor, we use a return
13411;; instruction which the middle-end doesn't see.
13412(define_insn "split_stack_return"
13413  [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13414		     UNSPECV_SPLIT_STACK_RETURN)]
13415  ""
13416{
13417  if (operands[0] == const0_rtx)
13418    return "ret";
13419  else
13420    return "ret\t%0";
13421}
13422  [(set_attr "atom_unit" "jeu")
13423   (set_attr "modrm" "0")
13424   (set (attr "length")
13425	(if_then_else (match_operand:SI 0 "const0_operand")
13426		      (const_int 1)
13427		      (const_int 3)))
13428   (set (attr "length_immediate")
13429	(if_then_else (match_operand:SI 0 "const0_operand")
13430		      (const_int 0)
13431		      (const_int 2)))])
13432
13433;; If there are operand 0 bytes available on the stack, jump to
13434;; operand 1.
13435
13436(define_expand "split_stack_space_check"
13437  [(set (pc) (if_then_else
13438	      (ltu (minus (reg SP_REG)
13439			  (match_operand 0 "register_operand"))
13440		   (match_dup 2))
13441	      (label_ref (match_operand 1))
13442	      (pc)))]
13443  ""
13444{
13445  rtx reg = gen_reg_rtx (Pmode);
13446
13447  emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13448
13449  operands[2] = ix86_split_stack_guard ();
13450  ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13451
13452  DONE;
13453})
13454
13455;; Bit manipulation instructions.
13456
13457(define_expand "ffs<mode>2"
13458  [(set (match_dup 2) (const_int -1))
13459   (parallel [(set (match_dup 3) (match_dup 4))
13460	      (set (match_operand:SWI48 0 "register_operand")
13461		   (ctz:SWI48
13462		     (match_operand:SWI48 1 "nonimmediate_operand")))])
13463   (set (match_dup 0) (if_then_else:SWI48
13464			(eq (match_dup 3) (const_int 0))
13465			(match_dup 2)
13466			(match_dup 0)))
13467   (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13468	      (clobber (reg:CC FLAGS_REG))])]
13469  ""
13470{
13471  machine_mode flags_mode;
13472
13473  if (<MODE>mode == SImode && !TARGET_CMOVE)
13474    {
13475      emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13476      DONE;
13477    }
13478
13479  flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13480
13481  operands[2] = gen_reg_rtx (<MODE>mode);
13482  operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13483  operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13484})
13485
13486(define_insn_and_split "ffssi2_no_cmove"
13487  [(set (match_operand:SI 0 "register_operand" "=r")
13488	(ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13489   (clobber (match_scratch:SI 2 "=&q"))
13490   (clobber (reg:CC FLAGS_REG))]
13491  "!TARGET_CMOVE"
13492  "#"
13493  "&& reload_completed"
13494  [(parallel [(set (match_dup 4) (match_dup 5))
13495	      (set (match_dup 0) (ctz:SI (match_dup 1)))])
13496   (set (strict_low_part (match_dup 3))
13497	(eq:QI (match_dup 4) (const_int 0)))
13498   (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13499	      (clobber (reg:CC FLAGS_REG))])
13500   (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13501	      (clobber (reg:CC FLAGS_REG))])
13502   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13503	      (clobber (reg:CC FLAGS_REG))])]
13504{
13505  machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13506
13507  operands[3] = gen_lowpart (QImode, operands[2]);
13508  operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13509  operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13510
13511  ix86_expand_clear (operands[2]);
13512})
13513
13514(define_insn_and_split "*tzcnt<mode>_1"
13515  [(set (reg:CCC FLAGS_REG)
13516	(compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13517		     (const_int 0)))
13518   (set (match_operand:SWI48 0 "register_operand" "=r")
13519	(ctz:SWI48 (match_dup 1)))]
13520  "TARGET_BMI"
13521  "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13522  "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13523   && optimize_function_for_speed_p (cfun)
13524   && !reg_mentioned_p (operands[0], operands[1])"
13525  [(parallel
13526    [(set (reg:CCC FLAGS_REG)
13527	  (compare:CCC (match_dup 1) (const_int 0)))
13528     (set (match_dup 0)
13529	  (ctz:SWI48 (match_dup 1)))
13530     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13531  "ix86_expand_clear (operands[0]);"
13532  [(set_attr "type" "alu1")
13533   (set_attr "prefix_0f" "1")
13534   (set_attr "prefix_rep" "1")
13535   (set_attr "btver2_decode" "double")
13536   (set_attr "mode" "<MODE>")])
13537
13538; False dependency happens when destination is only updated by tzcnt,
13539; lzcnt or popcnt.  There is no false dependency when destination is
13540; also used in source.
13541(define_insn "*tzcnt<mode>_1_falsedep"
13542  [(set (reg:CCC FLAGS_REG)
13543	(compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13544		     (const_int 0)))
13545   (set (match_operand:SWI48 0 "register_operand" "=r")
13546	(ctz:SWI48 (match_dup 1)))
13547   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13548	   UNSPEC_INSN_FALSE_DEP)]
13549  "TARGET_BMI"
13550  "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13551  [(set_attr "type" "alu1")
13552   (set_attr "prefix_0f" "1")
13553   (set_attr "prefix_rep" "1")
13554   (set_attr "btver2_decode" "double")
13555   (set_attr "mode" "<MODE>")])
13556
13557(define_insn "*bsf<mode>_1"
13558  [(set (reg:CCZ FLAGS_REG)
13559	(compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13560		     (const_int 0)))
13561   (set (match_operand:SWI48 0 "register_operand" "=r")
13562	(ctz:SWI48 (match_dup 1)))]
13563  ""
13564  "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13565  [(set_attr "type" "alu1")
13566   (set_attr "prefix_0f" "1")
13567   (set_attr "btver2_decode" "double")
13568   (set_attr "znver1_decode" "vector")
13569   (set_attr "mode" "<MODE>")])
13570
13571(define_insn_and_split "ctz<mode>2"
13572  [(set (match_operand:SWI48 0 "register_operand" "=r")
13573	(ctz:SWI48
13574	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13575   (clobber (reg:CC FLAGS_REG))]
13576  ""
13577{
13578  if (TARGET_BMI)
13579    return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13580  else if (optimize_function_for_size_p (cfun))
13581    ;
13582  else if (TARGET_GENERIC)
13583    /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13584    return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13585
13586  return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13587}
13588  "(TARGET_BMI || TARGET_GENERIC)
13589   && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13590   && optimize_function_for_speed_p (cfun)
13591   && !reg_mentioned_p (operands[0], operands[1])"
13592  [(parallel
13593    [(set (match_dup 0)
13594	  (ctz:SWI48 (match_dup 1)))
13595     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13596     (clobber (reg:CC FLAGS_REG))])]
13597  "ix86_expand_clear (operands[0]);"
13598  [(set_attr "type" "alu1")
13599   (set_attr "prefix_0f" "1")
13600   (set (attr "prefix_rep")
13601     (if_then_else
13602       (ior (match_test "TARGET_BMI")
13603	    (and (not (match_test "optimize_function_for_size_p (cfun)"))
13604		 (match_test "TARGET_GENERIC")))
13605       (const_string "1")
13606       (const_string "0")))
13607   (set_attr "mode" "<MODE>")])
13608
13609; False dependency happens when destination is only updated by tzcnt,
13610; lzcnt or popcnt.  There is no false dependency when destination is
13611; also used in source.
13612(define_insn "*ctz<mode>2_falsedep"
13613  [(set (match_operand:SWI48 0 "register_operand" "=r")
13614	(ctz:SWI48
13615	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13616   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13617	   UNSPEC_INSN_FALSE_DEP)
13618   (clobber (reg:CC FLAGS_REG))]
13619  ""
13620{
13621  if (TARGET_BMI)
13622    return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13623  else if (TARGET_GENERIC)
13624    /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13625    return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13626  else
13627    gcc_unreachable ();
13628}
13629  [(set_attr "type" "alu1")
13630   (set_attr "prefix_0f" "1")
13631   (set_attr "prefix_rep" "1")
13632   (set_attr "mode" "<MODE>")])
13633
13634(define_insn "bsr_rex64"
13635  [(set (match_operand:DI 0 "register_operand" "=r")
13636	(minus:DI (const_int 63)
13637		  (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13638   (clobber (reg:CC FLAGS_REG))]
13639  "TARGET_64BIT"
13640  "bsr{q}\t{%1, %0|%0, %1}"
13641  [(set_attr "type" "alu1")
13642   (set_attr "prefix_0f" "1")
13643   (set_attr "znver1_decode" "vector")
13644   (set_attr "mode" "DI")])
13645
13646(define_insn "bsr"
13647  [(set (match_operand:SI 0 "register_operand" "=r")
13648	(minus:SI (const_int 31)
13649		  (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13650   (clobber (reg:CC FLAGS_REG))]
13651  ""
13652  "bsr{l}\t{%1, %0|%0, %1}"
13653  [(set_attr "type" "alu1")
13654   (set_attr "prefix_0f" "1")
13655   (set_attr "znver1_decode" "vector")
13656   (set_attr "mode" "SI")])
13657
13658(define_insn "*bsrhi"
13659  [(set (match_operand:HI 0 "register_operand" "=r")
13660	(minus:HI (const_int 15)
13661		  (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13662   (clobber (reg:CC FLAGS_REG))]
13663  ""
13664  "bsr{w}\t{%1, %0|%0, %1}"
13665  [(set_attr "type" "alu1")
13666   (set_attr "prefix_0f" "1")
13667   (set_attr "znver1_decode" "vector")
13668   (set_attr "mode" "HI")])
13669
13670(define_expand "clz<mode>2"
13671  [(parallel
13672     [(set (match_operand:SWI48 0 "register_operand")
13673	   (minus:SWI48
13674	     (match_dup 2)
13675	     (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13676      (clobber (reg:CC FLAGS_REG))])
13677   (parallel
13678     [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13679      (clobber (reg:CC FLAGS_REG))])]
13680  ""
13681{
13682  if (TARGET_LZCNT)
13683    {
13684      emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13685      DONE;
13686    }
13687  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13688})
13689
13690(define_insn_and_split "clz<mode>2_lzcnt"
13691  [(set (match_operand:SWI48 0 "register_operand" "=r")
13692	(clz:SWI48
13693	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13694   (clobber (reg:CC FLAGS_REG))]
13695  "TARGET_LZCNT"
13696  "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13697  "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13698   && optimize_function_for_speed_p (cfun)
13699   && !reg_mentioned_p (operands[0], operands[1])"
13700  [(parallel
13701    [(set (match_dup 0)
13702	  (clz:SWI48 (match_dup 1)))
13703     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13704     (clobber (reg:CC FLAGS_REG))])]
13705  "ix86_expand_clear (operands[0]);"
13706  [(set_attr "prefix_rep" "1")
13707   (set_attr "type" "bitmanip")
13708   (set_attr "mode" "<MODE>")])
13709
13710; False dependency happens when destination is only updated by tzcnt,
13711; lzcnt or popcnt.  There is no false dependency when destination is
13712; also used in source.
13713(define_insn "*clz<mode>2_lzcnt_falsedep"
13714  [(set (match_operand:SWI48 0 "register_operand" "=r")
13715	(clz:SWI48
13716	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13717   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13718	   UNSPEC_INSN_FALSE_DEP)
13719   (clobber (reg:CC FLAGS_REG))]
13720  "TARGET_LZCNT"
13721  "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13722  [(set_attr "prefix_rep" "1")
13723   (set_attr "type" "bitmanip")
13724   (set_attr "mode" "<MODE>")])
13725
13726(define_int_iterator LT_ZCNT
13727	[(UNSPEC_TZCNT "TARGET_BMI")
13728	 (UNSPEC_LZCNT "TARGET_LZCNT")])
13729
13730(define_int_attr lt_zcnt
13731	[(UNSPEC_TZCNT "tzcnt")
13732	 (UNSPEC_LZCNT "lzcnt")])
13733
13734(define_int_attr lt_zcnt_type
13735	[(UNSPEC_TZCNT "alu1")
13736	 (UNSPEC_LZCNT "bitmanip")])
13737
13738;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
13739;; provides operand size as output when source operand is zero.
13740
13741(define_insn_and_split "<lt_zcnt>_<mode>"
13742  [(set (match_operand:SWI48 0 "register_operand" "=r")
13743	(unspec:SWI48
13744	  [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13745   (clobber (reg:CC FLAGS_REG))]
13746  ""
13747  "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13748  "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13749   && optimize_function_for_speed_p (cfun)
13750   && !reg_mentioned_p (operands[0], operands[1])"
13751  [(parallel
13752    [(set (match_dup 0)
13753	  (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13754     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13755     (clobber (reg:CC FLAGS_REG))])]
13756  "ix86_expand_clear (operands[0]);"
13757  [(set_attr "type" "<lt_zcnt_type>")
13758   (set_attr "prefix_0f" "1")
13759   (set_attr "prefix_rep" "1")
13760   (set_attr "mode" "<MODE>")])
13761
13762; False dependency happens when destination is only updated by tzcnt,
13763; lzcnt or popcnt.  There is no false dependency when destination is
13764; also used in source.
13765(define_insn "*<lt_zcnt>_<mode>_falsedep"
13766  [(set (match_operand:SWI48 0 "register_operand" "=r")
13767	(unspec:SWI48
13768	  [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13769   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13770	   UNSPEC_INSN_FALSE_DEP)
13771   (clobber (reg:CC FLAGS_REG))]
13772  ""
13773  "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13774  [(set_attr "type" "<lt_zcnt_type>")
13775   (set_attr "prefix_0f" "1")
13776   (set_attr "prefix_rep" "1")
13777   (set_attr "mode" "<MODE>")])
13778
13779(define_insn "<lt_zcnt>_hi"
13780  [(set (match_operand:HI 0 "register_operand" "=r")
13781	(unspec:HI
13782	  [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13783   (clobber (reg:CC FLAGS_REG))]
13784  ""
13785  "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13786  [(set_attr "type" "<lt_zcnt_type>")
13787   (set_attr "prefix_0f" "1")
13788   (set_attr "prefix_rep" "1")
13789   (set_attr "mode" "HI")])
13790
13791;; BMI instructions.
13792
13793(define_insn "bmi_bextr_<mode>"
13794  [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13795	(unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13796		       (match_operand:SWI48 2 "register_operand" "r,r")]
13797		      UNSPEC_BEXTR))
13798   (clobber (reg:CC FLAGS_REG))]
13799  "TARGET_BMI"
13800  "bextr\t{%2, %1, %0|%0, %1, %2}"
13801  [(set_attr "type" "bitmanip")
13802   (set_attr "btver2_decode" "direct, double")
13803   (set_attr "mode" "<MODE>")])
13804
13805(define_insn "*bmi_bextr_<mode>_ccz"
13806  [(set (reg:CCZ FLAGS_REG)
13807	(compare:CCZ
13808	  (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13809			 (match_operand:SWI48 2 "register_operand" "r,r")]
13810			UNSPEC_BEXTR)
13811	  (const_int 0)))
13812   (clobber (match_scratch:SWI48 0 "=r,r"))]
13813  "TARGET_BMI"
13814  "bextr\t{%2, %1, %0|%0, %1, %2}"
13815  [(set_attr "type" "bitmanip")
13816   (set_attr "btver2_decode" "direct, double")
13817   (set_attr "mode" "<MODE>")])
13818
13819(define_insn "*bmi_blsi_<mode>"
13820  [(set (match_operand:SWI48 0 "register_operand" "=r")
13821        (and:SWI48
13822          (neg:SWI48
13823            (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13824          (match_dup 1)))
13825   (clobber (reg:CC FLAGS_REG))]
13826  "TARGET_BMI"
13827  "blsi\t{%1, %0|%0, %1}"
13828  [(set_attr "type" "bitmanip")
13829   (set_attr "btver2_decode" "double")
13830   (set_attr "mode" "<MODE>")])
13831
13832(define_insn "*bmi_blsmsk_<mode>"
13833  [(set (match_operand:SWI48 0 "register_operand" "=r")
13834        (xor:SWI48
13835          (plus:SWI48
13836            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13837            (const_int -1))
13838          (match_dup 1)))
13839   (clobber (reg:CC FLAGS_REG))]
13840  "TARGET_BMI"
13841  "blsmsk\t{%1, %0|%0, %1}"
13842  [(set_attr "type" "bitmanip")
13843   (set_attr "btver2_decode" "double")
13844   (set_attr "mode" "<MODE>")])
13845
13846(define_insn "*bmi_blsr_<mode>"
13847  [(set (match_operand:SWI48 0 "register_operand" "=r")
13848        (and:SWI48
13849          (plus:SWI48
13850            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13851            (const_int -1))
13852          (match_dup 1)))
13853   (clobber (reg:CC FLAGS_REG))]
13854   "TARGET_BMI"
13855   "blsr\t{%1, %0|%0, %1}"
13856  [(set_attr "type" "bitmanip")
13857   (set_attr "btver2_decode" "double")
13858   (set_attr "mode" "<MODE>")])
13859
13860(define_insn "*bmi_blsr_<mode>_cmp"
13861  [(set (reg:CCZ FLAGS_REG)
13862	(compare:CCZ
13863	  (and:SWI48
13864	    (plus:SWI48
13865	      (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13866	      (const_int -1))
13867	    (match_dup 1))
13868	  (const_int 0)))
13869   (set (match_operand:SWI48 0 "register_operand" "=r")
13870	(and:SWI48
13871	  (plus:SWI48
13872	    (match_dup 1)
13873	    (const_int -1))
13874	  (match_dup 1)))]
13875   "TARGET_BMI"
13876   "blsr\t{%1, %0|%0, %1}"
13877  [(set_attr "type" "bitmanip")
13878   (set_attr "btver2_decode" "double")
13879   (set_attr "mode" "<MODE>")])
13880
13881(define_insn "*bmi_blsr_<mode>_ccz"
13882  [(set (reg:CCZ FLAGS_REG)
13883	(compare:CCZ
13884	  (and:SWI48
13885	    (plus:SWI48
13886	      (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13887	      (const_int -1))
13888	    (match_dup 1))
13889	  (const_int 0)))
13890   (clobber (match_scratch:SWI48 0 "=r"))]
13891   "TARGET_BMI"
13892   "blsr\t{%1, %0|%0, %1}"
13893  [(set_attr "type" "bitmanip")
13894   (set_attr "btver2_decode" "double")
13895   (set_attr "mode" "<MODE>")])
13896
13897;; BMI2 instructions.
13898(define_expand "bmi2_bzhi_<mode>3"
13899  [(parallel
13900    [(set (match_operand:SWI48 0 "register_operand")
13901	  (zero_extract:SWI48
13902	    (match_operand:SWI48 1 "nonimmediate_operand")
13903	    (umin:SWI48
13904	      (and:SWI48 (match_operand:SWI48 2 "register_operand")
13905			 (const_int 255))
13906	      (match_dup 3))
13907	    (const_int 0)))
13908     (clobber (reg:CC FLAGS_REG))])]
13909  "TARGET_BMI2"
13910  "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13911
13912(define_insn "*bmi2_bzhi_<mode>3"
13913  [(set (match_operand:SWI48 0 "register_operand" "=r")
13914	(zero_extract:SWI48
13915	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13916	  (umin:SWI48
13917	    (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13918		       (const_int 255))
13919	    (match_operand:SWI48 3 "const_int_operand" "n"))
13920	  (const_int 0)))
13921   (clobber (reg:CC FLAGS_REG))]
13922  "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13923  "bzhi\t{%2, %1, %0|%0, %1, %2}"
13924  [(set_attr "type" "bitmanip")
13925   (set_attr "prefix" "vex")
13926   (set_attr "mode" "<MODE>")])
13927
13928(define_insn "*bmi2_bzhi_<mode>3_1"
13929  [(set (match_operand:SWI48 0 "register_operand" "=r")
13930	(zero_extract:SWI48
13931	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13932	  (umin:SWI48
13933	    (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13934	    (match_operand:SWI48 3 "const_int_operand" "n"))
13935	  (const_int 0)))
13936   (clobber (reg:CC FLAGS_REG))]
13937  "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13938  "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13939  [(set_attr "type" "bitmanip")
13940   (set_attr "prefix" "vex")
13941   (set_attr "mode" "<MODE>")])
13942
13943(define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13944  [(set (reg:CCZ FLAGS_REG)
13945	(compare:CCZ
13946	  (zero_extract:SWI48
13947	    (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13948	    (umin:SWI48
13949	      (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13950	      (match_operand:SWI48 3 "const_int_operand" "n"))
13951	    (const_int 0))
13952	(const_int 0)))
13953   (clobber (match_scratch:SWI48 0 "=r"))]
13954  "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13955  "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13956  [(set_attr "type" "bitmanip")
13957   (set_attr "prefix" "vex")
13958   (set_attr "mode" "<MODE>")])
13959
13960(define_insn "bmi2_pdep_<mode>3"
13961  [(set (match_operand:SWI48 0 "register_operand" "=r")
13962        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13963                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13964                       UNSPEC_PDEP))]
13965  "TARGET_BMI2"
13966  "pdep\t{%2, %1, %0|%0, %1, %2}"
13967  [(set_attr "type" "bitmanip")
13968   (set_attr "prefix" "vex")
13969   (set_attr "mode" "<MODE>")])
13970
13971(define_insn "bmi2_pext_<mode>3"
13972  [(set (match_operand:SWI48 0 "register_operand" "=r")
13973        (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13974                       (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13975                       UNSPEC_PEXT))]
13976  "TARGET_BMI2"
13977  "pext\t{%2, %1, %0|%0, %1, %2}"
13978  [(set_attr "type" "bitmanip")
13979   (set_attr "prefix" "vex")
13980   (set_attr "mode" "<MODE>")])
13981
13982;; TBM instructions.
13983(define_insn "tbm_bextri_<mode>"
13984  [(set (match_operand:SWI48 0 "register_operand" "=r")
13985        (zero_extract:SWI48
13986          (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13987          (match_operand 2 "const_0_to_255_operand" "N")
13988          (match_operand 3 "const_0_to_255_operand" "N")))
13989   (clobber (reg:CC FLAGS_REG))]
13990   "TARGET_TBM"
13991{
13992  operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13993  return "bextr\t{%2, %1, %0|%0, %1, %2}";
13994}
13995  [(set_attr "type" "bitmanip")
13996   (set_attr "mode" "<MODE>")])
13997
13998(define_insn "*tbm_blcfill_<mode>"
13999  [(set (match_operand:SWI48 0 "register_operand" "=r")
14000        (and:SWI48
14001          (plus:SWI48
14002            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14003            (const_int 1))
14004          (match_dup 1)))
14005   (clobber (reg:CC FLAGS_REG))]
14006   "TARGET_TBM"
14007   "blcfill\t{%1, %0|%0, %1}"
14008  [(set_attr "type" "bitmanip")
14009   (set_attr "mode" "<MODE>")])
14010
14011(define_insn "*tbm_blci_<mode>"
14012  [(set (match_operand:SWI48 0 "register_operand" "=r")
14013        (ior:SWI48
14014          (not: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_TBM"
14021   "blci\t{%1, %0|%0, %1}"
14022  [(set_attr "type" "bitmanip")
14023   (set_attr "mode" "<MODE>")])
14024
14025(define_insn "*tbm_blcic_<mode>"
14026  [(set (match_operand:SWI48 0 "register_operand" "=r")
14027        (and:SWI48
14028          (plus:SWI48
14029            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14030            (const_int 1))
14031          (not:SWI48
14032            (match_dup 1))))
14033   (clobber (reg:CC FLAGS_REG))]
14034   "TARGET_TBM"
14035   "blcic\t{%1, %0|%0, %1}"
14036  [(set_attr "type" "bitmanip")
14037   (set_attr "mode" "<MODE>")])
14038
14039(define_insn "*tbm_blcmsk_<mode>"
14040  [(set (match_operand:SWI48 0 "register_operand" "=r")
14041        (xor:SWI48
14042          (plus:SWI48
14043            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14044            (const_int 1))
14045          (match_dup 1)))
14046   (clobber (reg:CC FLAGS_REG))]
14047   "TARGET_TBM"
14048   "blcmsk\t{%1, %0|%0, %1}"
14049  [(set_attr "type" "bitmanip")
14050   (set_attr "mode" "<MODE>")])
14051
14052(define_insn "*tbm_blcs_<mode>"
14053  [(set (match_operand:SWI48 0 "register_operand" "=r")
14054        (ior:SWI48
14055          (plus:SWI48
14056            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14057            (const_int 1))
14058          (match_dup 1)))
14059   (clobber (reg:CC FLAGS_REG))]
14060   "TARGET_TBM"
14061   "blcs\t{%1, %0|%0, %1}"
14062  [(set_attr "type" "bitmanip")
14063   (set_attr "mode" "<MODE>")])
14064
14065(define_insn "*tbm_blsfill_<mode>"
14066  [(set (match_operand:SWI48 0 "register_operand" "=r")
14067        (ior:SWI48
14068          (plus:SWI48
14069            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14070            (const_int -1))
14071          (match_dup 1)))
14072   (clobber (reg:CC FLAGS_REG))]
14073   "TARGET_TBM"
14074   "blsfill\t{%1, %0|%0, %1}"
14075  [(set_attr "type" "bitmanip")
14076   (set_attr "mode" "<MODE>")])
14077
14078(define_insn "*tbm_blsic_<mode>"
14079  [(set (match_operand:SWI48 0 "register_operand" "=r")
14080        (ior:SWI48
14081          (plus:SWI48
14082            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14083            (const_int -1))
14084          (not:SWI48
14085            (match_dup 1))))
14086   (clobber (reg:CC FLAGS_REG))]
14087   "TARGET_TBM"
14088   "blsic\t{%1, %0|%0, %1}"
14089  [(set_attr "type" "bitmanip")
14090   (set_attr "mode" "<MODE>")])
14091
14092(define_insn "*tbm_t1mskc_<mode>"
14093  [(set (match_operand:SWI48 0 "register_operand" "=r")
14094        (ior:SWI48
14095          (plus:SWI48
14096            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14097            (const_int 1))
14098          (not:SWI48
14099            (match_dup 1))))
14100   (clobber (reg:CC FLAGS_REG))]
14101   "TARGET_TBM"
14102   "t1mskc\t{%1, %0|%0, %1}"
14103  [(set_attr "type" "bitmanip")
14104   (set_attr "mode" "<MODE>")])
14105
14106(define_insn "*tbm_tzmsk_<mode>"
14107  [(set (match_operand:SWI48 0 "register_operand" "=r")
14108        (and:SWI48
14109          (plus:SWI48
14110            (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14111            (const_int -1))
14112          (not:SWI48
14113            (match_dup 1))))
14114   (clobber (reg:CC FLAGS_REG))]
14115   "TARGET_TBM"
14116   "tzmsk\t{%1, %0|%0, %1}"
14117  [(set_attr "type" "bitmanip")
14118   (set_attr "mode" "<MODE>")])
14119
14120(define_insn_and_split "popcount<mode>2"
14121  [(set (match_operand:SWI48 0 "register_operand" "=r")
14122	(popcount:SWI48
14123	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14124   (clobber (reg:CC FLAGS_REG))]
14125  "TARGET_POPCNT"
14126{
14127#if TARGET_MACHO
14128  return "popcnt\t{%1, %0|%0, %1}";
14129#else
14130  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14131#endif
14132}
14133  "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14134   && optimize_function_for_speed_p (cfun)
14135   && !reg_mentioned_p (operands[0], operands[1])"
14136  [(parallel
14137    [(set (match_dup 0)
14138	  (popcount:SWI48 (match_dup 1)))
14139     (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14140     (clobber (reg:CC FLAGS_REG))])]
14141  "ix86_expand_clear (operands[0]);"
14142  [(set_attr "prefix_rep" "1")
14143   (set_attr "type" "bitmanip")
14144   (set_attr "mode" "<MODE>")])
14145
14146; False dependency happens when destination is only updated by tzcnt,
14147; lzcnt or popcnt.  There is no false dependency when destination is
14148; also used in source.
14149(define_insn "*popcount<mode>2_falsedep"
14150  [(set (match_operand:SWI48 0 "register_operand" "=r")
14151	(popcount:SWI48
14152	  (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14153   (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14154	   UNSPEC_INSN_FALSE_DEP)
14155   (clobber (reg:CC FLAGS_REG))]
14156  "TARGET_POPCNT"
14157{
14158#if TARGET_MACHO
14159  return "popcnt\t{%1, %0|%0, %1}";
14160#else
14161  return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14162#endif
14163}
14164  [(set_attr "prefix_rep" "1")
14165   (set_attr "type" "bitmanip")
14166   (set_attr "mode" "<MODE>")])
14167
14168(define_insn_and_split "*popcounthi2_1"
14169  [(set (match_operand:SI 0 "register_operand")
14170	(popcount:SI
14171	  (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14172   (clobber (reg:CC FLAGS_REG))]
14173  "TARGET_POPCNT
14174   && can_create_pseudo_p ()"
14175  "#"
14176  "&& 1"
14177  [(const_int 0)]
14178{
14179  rtx tmp = gen_reg_rtx (HImode);
14180
14181  emit_insn (gen_popcounthi2 (tmp, operands[1]));
14182  emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14183  DONE;
14184})
14185
14186(define_insn "popcounthi2"
14187  [(set (match_operand:HI 0 "register_operand" "=r")
14188	(popcount:HI
14189	  (match_operand:HI 1 "nonimmediate_operand" "rm")))
14190   (clobber (reg:CC FLAGS_REG))]
14191  "TARGET_POPCNT"
14192{
14193#if TARGET_MACHO
14194  return "popcnt\t{%1, %0|%0, %1}";
14195#else
14196  return "popcnt{w}\t{%1, %0|%0, %1}";
14197#endif
14198}
14199  [(set_attr "prefix_rep" "1")
14200   (set_attr "type" "bitmanip")
14201   (set_attr "mode" "HI")])
14202
14203(define_expand "bswapdi2"
14204  [(set (match_operand:DI 0 "register_operand")
14205	(bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14206  "TARGET_64BIT"
14207{
14208  if (!TARGET_MOVBE)
14209    operands[1] = force_reg (DImode, operands[1]);
14210})
14211
14212(define_expand "bswapsi2"
14213  [(set (match_operand:SI 0 "register_operand")
14214	(bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14215  ""
14216{
14217  if (TARGET_MOVBE)
14218    ;
14219  else if (TARGET_BSWAP)
14220    operands[1] = force_reg (SImode, operands[1]);
14221  else
14222    {
14223      rtx x = operands[0];
14224
14225      emit_move_insn (x, operands[1]);
14226      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14227      emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14228      emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14229      DONE;
14230    }
14231})
14232
14233(define_insn "*bswap<mode>2_movbe"
14234  [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14235	(bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14236  "TARGET_MOVBE
14237   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14238  "@
14239    bswap\t%0
14240    movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14241    movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14242  [(set_attr "type" "bitmanip,imov,imov")
14243   (set_attr "modrm" "0,1,1")
14244   (set_attr "prefix_0f" "*,1,1")
14245   (set_attr "prefix_extra" "*,1,1")
14246   (set_attr "mode" "<MODE>")])
14247
14248(define_insn "*bswap<mode>2"
14249  [(set (match_operand:SWI48 0 "register_operand" "=r")
14250	(bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14251  "TARGET_BSWAP"
14252  "bswap\t%0"
14253  [(set_attr "type" "bitmanip")
14254   (set_attr "modrm" "0")
14255   (set_attr "mode" "<MODE>")])
14256
14257(define_expand "bswaphi2"
14258  [(set (match_operand:HI 0 "register_operand")
14259	(bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14260  "TARGET_MOVBE")
14261
14262(define_insn "*bswaphi2_movbe"
14263  [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14264	(bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14265  "TARGET_MOVBE
14266   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14267  "@
14268    xchg{b}\t{%h0, %b0|%b0, %h0}
14269    movbe{w}\t{%1, %0|%0, %1}
14270    movbe{w}\t{%1, %0|%0, %1}"
14271  [(set_attr "type" "imov")
14272   (set_attr "modrm" "*,1,1")
14273   (set_attr "prefix_0f" "*,1,1")
14274   (set_attr "prefix_extra" "*,1,1")
14275   (set_attr "pent_pair" "np,*,*")
14276   (set_attr "athlon_decode" "vector,*,*")
14277   (set_attr "amdfam10_decode" "double,*,*")
14278   (set_attr "bdver1_decode" "double,*,*")
14279   (set_attr "mode" "QI,HI,HI")])
14280
14281(define_peephole2
14282  [(set (match_operand:HI 0 "general_reg_operand")
14283	(bswap:HI (match_dup 0)))]
14284  "TARGET_MOVBE
14285   && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14286   && peep2_regno_dead_p (0, FLAGS_REG)"
14287  [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14288	      (clobber (reg:CC FLAGS_REG))])])
14289
14290(define_insn "bswaphi_lowpart"
14291  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14292	(bswap:HI (match_dup 0)))
14293   (clobber (reg:CC FLAGS_REG))]
14294  ""
14295  "@
14296    xchg{b}\t{%h0, %b0|%b0, %h0}
14297    rol{w}\t{$8, %0|%0, 8}"
14298  [(set (attr "preferred_for_size")
14299     (cond [(eq_attr "alternative" "0")
14300	      (symbol_ref "true")]
14301	   (symbol_ref "false")))
14302   (set (attr "preferred_for_speed")
14303     (cond [(eq_attr "alternative" "0")
14304	      (symbol_ref "TARGET_USE_XCHGB")]
14305	   (symbol_ref "!TARGET_USE_XCHGB")))
14306   (set_attr "length" "2,4")
14307   (set_attr "mode" "QI,HI")])
14308
14309(define_expand "paritydi2"
14310  [(set (match_operand:DI 0 "register_operand")
14311	(parity:DI (match_operand:DI 1 "register_operand")))]
14312  "! TARGET_POPCNT"
14313{
14314  rtx scratch = gen_reg_rtx (QImode);
14315
14316  emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14317				NULL_RTX, operands[1]));
14318
14319  ix86_expand_setcc (scratch, ORDERED,
14320		     gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14321
14322  if (TARGET_64BIT)
14323    emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14324  else
14325    {
14326      rtx tmp = gen_reg_rtx (SImode);
14327
14328      emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14329      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14330    }
14331  DONE;
14332})
14333
14334(define_expand "paritysi2"
14335  [(set (match_operand:SI 0 "register_operand")
14336	(parity:SI (match_operand:SI 1 "register_operand")))]
14337  "! TARGET_POPCNT"
14338{
14339  rtx scratch = gen_reg_rtx (QImode);
14340
14341  emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14342
14343  ix86_expand_setcc (scratch, ORDERED,
14344		     gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14345
14346  emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14347  DONE;
14348})
14349
14350(define_insn_and_split "paritydi2_cmp"
14351  [(set (reg:CC FLAGS_REG)
14352	(unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14353		   UNSPEC_PARITY))
14354   (clobber (match_scratch:DI 0 "=r"))
14355   (clobber (match_scratch:SI 1 "=&r"))
14356   (clobber (match_scratch:HI 2 "=Q"))]
14357  "! TARGET_POPCNT"
14358  "#"
14359  "&& reload_completed"
14360  [(parallel
14361     [(set (match_dup 1)
14362	   (xor:SI (match_dup 1) (match_dup 4)))
14363      (clobber (reg:CC FLAGS_REG))])
14364   (parallel
14365     [(set (reg:CC FLAGS_REG)
14366	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14367      (clobber (match_dup 1))
14368      (clobber (match_dup 2))])]
14369{
14370  operands[4] = gen_lowpart (SImode, operands[3]);
14371
14372  if (TARGET_64BIT)
14373    {
14374      emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14375      emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14376    }
14377  else
14378    operands[1] = gen_highpart (SImode, operands[3]);
14379})
14380
14381(define_insn_and_split "paritysi2_cmp"
14382  [(set (reg:CC FLAGS_REG)
14383	(unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14384		   UNSPEC_PARITY))
14385   (clobber (match_scratch:SI 0 "=r"))
14386   (clobber (match_scratch:HI 1 "=&Q"))]
14387  "! TARGET_POPCNT"
14388  "#"
14389  "&& reload_completed"
14390  [(parallel
14391     [(set (match_dup 1)
14392	   (xor:HI (match_dup 1) (match_dup 3)))
14393      (clobber (reg:CC FLAGS_REG))])
14394   (parallel
14395     [(set (reg:CC FLAGS_REG)
14396	   (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14397      (clobber (match_dup 1))])]
14398{
14399  operands[3] = gen_lowpart (HImode, operands[2]);
14400
14401  emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14402  emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14403})
14404
14405(define_insn "*parityhi2_cmp"
14406  [(set (reg:CC FLAGS_REG)
14407	(unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14408		   UNSPEC_PARITY))
14409   (clobber (match_scratch:HI 0 "=Q"))]
14410  "! TARGET_POPCNT"
14411  "xor{b}\t{%h0, %b0|%b0, %h0}"
14412  [(set_attr "length" "2")
14413   (set_attr "mode" "HI")])
14414
14415
14416;; Thread-local storage patterns for ELF.
14417;;
14418;; Note that these code sequences must appear exactly as shown
14419;; in order to allow linker relaxation.
14420
14421(define_insn "*tls_global_dynamic_32_gnu"
14422  [(set (match_operand:SI 0 "register_operand" "=a")
14423	(unspec:SI
14424	 [(match_operand:SI 1 "register_operand" "Yb")
14425	  (match_operand 2 "tls_symbolic_operand")
14426	  (match_operand 3 "constant_call_address_operand" "Bz")
14427	  (reg:SI SP_REG)]
14428	 UNSPEC_TLS_GD))
14429   (clobber (match_scratch:SI 4 "=d"))
14430   (clobber (match_scratch:SI 5 "=c"))
14431   (clobber (reg:CC FLAGS_REG))]
14432  "!TARGET_64BIT && TARGET_GNU_TLS"
14433{
14434  if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14435    output_asm_insn
14436      ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14437  else
14438    output_asm_insn
14439      ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14440  if (TARGET_SUN_TLS)
14441#ifdef HAVE_AS_IX86_TLSGDPLT
14442    return "call\t%a2@tlsgdplt";
14443#else
14444    return "call\t%p3@plt";
14445#endif
14446  if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14447    return "call\t%P3";
14448  return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14449}
14450  [(set_attr "type" "multi")
14451   (set_attr "length" "12")])
14452
14453(define_expand "tls_global_dynamic_32"
14454  [(parallel
14455    [(set (match_operand:SI 0 "register_operand")
14456	  (unspec:SI [(match_operand:SI 2 "register_operand")
14457		      (match_operand 1 "tls_symbolic_operand")
14458		      (match_operand 3 "constant_call_address_operand")
14459		      (reg:SI SP_REG)]
14460		     UNSPEC_TLS_GD))
14461     (clobber (match_scratch:SI 4))
14462     (clobber (match_scratch:SI 5))
14463     (clobber (reg:CC FLAGS_REG))])]
14464  ""
14465  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14466
14467(define_insn "*tls_global_dynamic_64_<mode>"
14468  [(set (match_operand:P 0 "register_operand" "=a")
14469	(call:P
14470	 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14471	 (match_operand 3)))
14472   (unspec:P [(match_operand 1 "tls_symbolic_operand")
14473	      (reg:P SP_REG)]
14474	     UNSPEC_TLS_GD)]
14475  "TARGET_64BIT"
14476{
14477  if (!TARGET_X32)
14478    fputs (ASM_BYTE "0x66\n", asm_out_file);
14479  output_asm_insn
14480    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14481  if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14482    fputs (ASM_SHORT "0x6666\n", asm_out_file);
14483  else
14484    fputs (ASM_BYTE "0x66\n", asm_out_file);
14485  fputs ("\trex64\n", asm_out_file);
14486  if (TARGET_SUN_TLS)
14487    return "call\t%p2@plt";
14488  if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14489    return "call\t%P2";
14490  return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14491}
14492  [(set_attr "type" "multi")
14493   (set (attr "length")
14494	(symbol_ref "TARGET_X32 ? 15 : 16"))])
14495
14496(define_insn "*tls_global_dynamic_64_largepic"
14497  [(set (match_operand:DI 0 "register_operand" "=a")
14498	(call:DI
14499	 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14500			  (match_operand:DI 3 "immediate_operand" "i")))
14501	 (match_operand 4)))
14502   (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14503	       (reg:DI SP_REG)]
14504	      UNSPEC_TLS_GD)]
14505  "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14506   && GET_CODE (operands[3]) == CONST
14507   && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14508   && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14509{
14510  output_asm_insn
14511    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14512  output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14513  output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14514  return "call\t{*%%rax|rax}";
14515}
14516  [(set_attr "type" "multi")
14517   (set_attr "length" "22")])
14518
14519(define_expand "tls_global_dynamic_64_<mode>"
14520  [(parallel
14521    [(set (match_operand:P 0 "register_operand")
14522	  (call:P
14523	   (mem:QI (match_operand 2))
14524	   (const_int 0)))
14525     (unspec:P [(match_operand 1 "tls_symbolic_operand")
14526		(reg:P SP_REG)]
14527	       UNSPEC_TLS_GD)])]
14528  "TARGET_64BIT"
14529  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14530
14531(define_insn "*tls_local_dynamic_base_32_gnu"
14532  [(set (match_operand:SI 0 "register_operand" "=a")
14533	(unspec:SI
14534	 [(match_operand:SI 1 "register_operand" "Yb")
14535	  (match_operand 2 "constant_call_address_operand" "Bz")
14536	  (reg:SI SP_REG)]
14537	 UNSPEC_TLS_LD_BASE))
14538   (clobber (match_scratch:SI 3 "=d"))
14539   (clobber (match_scratch:SI 4 "=c"))
14540   (clobber (reg:CC FLAGS_REG))]
14541  "!TARGET_64BIT && TARGET_GNU_TLS"
14542{
14543  output_asm_insn
14544    ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14545  if (TARGET_SUN_TLS)
14546    {
14547      if (HAVE_AS_IX86_TLSLDMPLT)
14548	return "call\t%&@tlsldmplt";
14549      else
14550	return "call\t%p2@plt";
14551    }
14552  if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14553    return "call\t%P2";
14554  return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14555}
14556  [(set_attr "type" "multi")
14557   (set_attr "length" "11")])
14558
14559(define_expand "tls_local_dynamic_base_32"
14560  [(parallel
14561     [(set (match_operand:SI 0 "register_operand")
14562	   (unspec:SI
14563	    [(match_operand:SI 1 "register_operand")
14564	     (match_operand 2 "constant_call_address_operand")
14565	     (reg:SI SP_REG)]
14566	    UNSPEC_TLS_LD_BASE))
14567      (clobber (match_scratch:SI 3))
14568      (clobber (match_scratch:SI 4))
14569      (clobber (reg:CC FLAGS_REG))])]
14570  ""
14571  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14572
14573(define_insn "*tls_local_dynamic_base_64_<mode>"
14574  [(set (match_operand:P 0 "register_operand" "=a")
14575	(call:P
14576	 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14577	 (match_operand 2)))
14578   (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14579  "TARGET_64BIT"
14580{
14581  output_asm_insn
14582    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14583  if (TARGET_SUN_TLS)
14584    return "call\t%p1@plt";
14585  if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14586    return "call\t%P1";
14587  return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14588}
14589  [(set_attr "type" "multi")
14590   (set_attr "length" "12")])
14591
14592(define_insn "*tls_local_dynamic_base_64_largepic"
14593  [(set (match_operand:DI 0 "register_operand" "=a")
14594	(call:DI
14595	 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14596			  (match_operand:DI 2 "immediate_operand" "i")))
14597	 (match_operand 3)))
14598   (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14599  "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14600   && GET_CODE (operands[2]) == CONST
14601   && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14602   && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14603{
14604  output_asm_insn
14605    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14606  output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14607  output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14608  return "call\t{*%%rax|rax}";
14609}
14610  [(set_attr "type" "multi")
14611   (set_attr "length" "22")])
14612
14613(define_expand "tls_local_dynamic_base_64_<mode>"
14614  [(parallel
14615     [(set (match_operand:P 0 "register_operand")
14616	   (call:P
14617	    (mem:QI (match_operand 1))
14618	    (const_int 0)))
14619      (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14620  "TARGET_64BIT"
14621  "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14622
14623;; Local dynamic of a single variable is a lose.  Show combine how
14624;; to convert that back to global dynamic.
14625
14626(define_insn_and_split "*tls_local_dynamic_32_once"
14627  [(set (match_operand:SI 0 "register_operand" "=a")
14628	(plus:SI
14629	 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14630		     (match_operand 2 "constant_call_address_operand" "Bz")
14631		     (reg:SI SP_REG)]
14632		    UNSPEC_TLS_LD_BASE)
14633	 (const:SI (unspec:SI
14634		    [(match_operand 3 "tls_symbolic_operand")]
14635		    UNSPEC_DTPOFF))))
14636   (clobber (match_scratch:SI 4 "=d"))
14637   (clobber (match_scratch:SI 5 "=c"))
14638   (clobber (reg:CC FLAGS_REG))]
14639  ""
14640  "#"
14641  ""
14642  [(parallel
14643     [(set (match_dup 0)
14644	   (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14645		       (reg:SI SP_REG)]
14646		      UNSPEC_TLS_GD))
14647      (clobber (match_dup 4))
14648      (clobber (match_dup 5))
14649      (clobber (reg:CC FLAGS_REG))])])
14650
14651;; Load and add the thread base pointer from %<tp_seg>:0.
14652(define_insn_and_split "*load_tp_<mode>"
14653  [(set (match_operand:PTR 0 "register_operand" "=r")
14654	(unspec:PTR [(const_int 0)] UNSPEC_TP))]
14655  ""
14656  "#"
14657  ""
14658  [(set (match_dup 0)
14659	(match_dup 1))]
14660{
14661  addr_space_t as = DEFAULT_TLS_SEG_REG;
14662
14663  operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14664  set_mem_addr_space (operands[1], as);
14665})
14666
14667(define_insn_and_split "*load_tp_x32_zext"
14668  [(set (match_operand:DI 0 "register_operand" "=r")
14669	(zero_extend:DI
14670	  (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14671  "TARGET_X32"
14672  "#"
14673  ""
14674  [(set (match_dup 0)
14675	(zero_extend:DI (match_dup 1)))]
14676{
14677  addr_space_t as = DEFAULT_TLS_SEG_REG;
14678
14679  operands[1] = gen_const_mem (SImode, const0_rtx);
14680  set_mem_addr_space (operands[1], as);
14681})
14682
14683(define_insn_and_split "*add_tp_<mode>"
14684  [(set (match_operand:PTR 0 "register_operand" "=r")
14685	(plus:PTR
14686	  (unspec:PTR [(const_int 0)] UNSPEC_TP)
14687	  (match_operand:PTR 1 "register_operand" "0")))
14688   (clobber (reg:CC FLAGS_REG))]
14689  ""
14690  "#"
14691  ""
14692  [(parallel
14693     [(set (match_dup 0)
14694	   (plus:PTR (match_dup 1) (match_dup 2)))
14695      (clobber (reg:CC FLAGS_REG))])]
14696{
14697  addr_space_t as = DEFAULT_TLS_SEG_REG;
14698
14699  operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14700  set_mem_addr_space (operands[2], as);
14701})
14702
14703(define_insn_and_split "*add_tp_x32_zext"
14704  [(set (match_operand:DI 0 "register_operand" "=r")
14705	(zero_extend:DI
14706	  (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14707		   (match_operand:SI 1 "register_operand" "0"))))
14708   (clobber (reg:CC FLAGS_REG))]
14709  "TARGET_X32"
14710  "#"
14711  ""
14712  [(parallel
14713     [(set (match_dup 0)
14714     	   (zero_extend:DI
14715	     (plus:SI (match_dup 1) (match_dup 2))))
14716      (clobber (reg:CC FLAGS_REG))])]
14717{
14718  addr_space_t as = DEFAULT_TLS_SEG_REG;
14719
14720  operands[2] = gen_const_mem (SImode, const0_rtx);
14721  set_mem_addr_space (operands[2], as);
14722})
14723
14724;; The Sun linker took the AMD64 TLS spec literally and can only handle
14725;; %rax as destination of the initial executable code sequence.
14726(define_insn "tls_initial_exec_64_sun"
14727  [(set (match_operand:DI 0 "register_operand" "=a")
14728	(unspec:DI
14729	 [(match_operand 1 "tls_symbolic_operand")]
14730	 UNSPEC_TLS_IE_SUN))
14731   (clobber (reg:CC FLAGS_REG))]
14732  "TARGET_64BIT && TARGET_SUN_TLS"
14733{
14734  output_asm_insn
14735    ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14736  return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14737}
14738  [(set_attr "type" "multi")])
14739
14740;; GNU2 TLS patterns can be split.
14741
14742(define_expand "tls_dynamic_gnu2_32"
14743  [(set (match_dup 3)
14744	(plus:SI (match_operand:SI 2 "register_operand")
14745		 (const:SI
14746		  (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14747			     UNSPEC_TLSDESC))))
14748   (parallel
14749    [(set (match_operand:SI 0 "register_operand")
14750	  (unspec:SI [(match_dup 1) (match_dup 3)
14751		      (match_dup 2) (reg:SI SP_REG)]
14752		      UNSPEC_TLSDESC))
14753     (clobber (reg:CC FLAGS_REG))])]
14754  "!TARGET_64BIT && TARGET_GNU2_TLS"
14755{
14756  operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14757  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14758})
14759
14760(define_insn "*tls_dynamic_gnu2_lea_32"
14761  [(set (match_operand:SI 0 "register_operand" "=r")
14762	(plus:SI (match_operand:SI 1 "register_operand" "b")
14763		 (const:SI
14764		  (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14765			      UNSPEC_TLSDESC))))]
14766  "!TARGET_64BIT && TARGET_GNU2_TLS"
14767  "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14768  [(set_attr "type" "lea")
14769   (set_attr "mode" "SI")
14770   (set_attr "length" "6")
14771   (set_attr "length_address" "4")])
14772
14773(define_insn "*tls_dynamic_gnu2_call_32"
14774  [(set (match_operand:SI 0 "register_operand" "=a")
14775	(unspec:SI [(match_operand 1 "tls_symbolic_operand")
14776		    (match_operand:SI 2 "register_operand" "0")
14777		    ;; we have to make sure %ebx still points to the GOT
14778		    (match_operand:SI 3 "register_operand" "b")
14779		    (reg:SI SP_REG)]
14780		   UNSPEC_TLSDESC))
14781   (clobber (reg:CC FLAGS_REG))]
14782  "!TARGET_64BIT && TARGET_GNU2_TLS"
14783  "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14784  [(set_attr "type" "call")
14785   (set_attr "length" "2")
14786   (set_attr "length_address" "0")])
14787
14788(define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14789  [(set (match_operand:SI 0 "register_operand" "=&a")
14790	(plus:SI
14791	 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14792		     (match_operand:SI 4)
14793		     (match_operand:SI 2 "register_operand" "b")
14794		     (reg:SI SP_REG)]
14795		    UNSPEC_TLSDESC)
14796	 (const:SI (unspec:SI
14797		    [(match_operand 1 "tls_symbolic_operand")]
14798		    UNSPEC_DTPOFF))))
14799   (clobber (reg:CC FLAGS_REG))]
14800  "!TARGET_64BIT && TARGET_GNU2_TLS"
14801  "#"
14802  ""
14803  [(set (match_dup 0) (match_dup 5))]
14804{
14805  operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14806  emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14807})
14808
14809(define_expand "tls_dynamic_gnu2_64"
14810  [(set (match_dup 2)
14811	(unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14812		   UNSPEC_TLSDESC))
14813   (parallel
14814    [(set (match_operand:DI 0 "register_operand")
14815	  (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14816		     UNSPEC_TLSDESC))
14817     (clobber (reg:CC FLAGS_REG))])]
14818  "TARGET_64BIT && TARGET_GNU2_TLS"
14819{
14820  operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14821  ix86_tls_descriptor_calls_expanded_in_cfun = true;
14822})
14823
14824(define_insn "*tls_dynamic_gnu2_lea_64"
14825  [(set (match_operand:DI 0 "register_operand" "=r")
14826	(unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14827		   UNSPEC_TLSDESC))]
14828  "TARGET_64BIT && TARGET_GNU2_TLS"
14829  "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14830  [(set_attr "type" "lea")
14831   (set_attr "mode" "DI")
14832   (set_attr "length" "7")
14833   (set_attr "length_address" "4")])
14834
14835(define_insn "*tls_dynamic_gnu2_call_64"
14836  [(set (match_operand:DI 0 "register_operand" "=a")
14837	(unspec:DI [(match_operand 1 "tls_symbolic_operand")
14838		    (match_operand:DI 2 "register_operand" "0")
14839		    (reg:DI SP_REG)]
14840		   UNSPEC_TLSDESC))
14841   (clobber (reg:CC FLAGS_REG))]
14842  "TARGET_64BIT && TARGET_GNU2_TLS"
14843  "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14844  [(set_attr "type" "call")
14845   (set_attr "length" "2")
14846   (set_attr "length_address" "0")])
14847
14848(define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14849  [(set (match_operand:DI 0 "register_operand" "=&a")
14850	(plus:DI
14851	 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14852		     (match_operand:DI 3)
14853		     (reg:DI SP_REG)]
14854		    UNSPEC_TLSDESC)
14855	 (const:DI (unspec:DI
14856		    [(match_operand 1 "tls_symbolic_operand")]
14857		    UNSPEC_DTPOFF))))
14858   (clobber (reg:CC FLAGS_REG))]
14859  "TARGET_64BIT && TARGET_GNU2_TLS"
14860  "#"
14861  ""
14862  [(set (match_dup 0) (match_dup 4))]
14863{
14864  operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14865  emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14866})
14867
14868(define_split
14869  [(match_operand 0 "tls_address_pattern")]
14870  "TARGET_TLS_DIRECT_SEG_REFS"
14871  [(match_dup 0)]
14872  "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14873
14874
14875;; These patterns match the binary 387 instructions for addM3, subM3,
14876;; mulM3 and divM3.  There are three patterns for each of DFmode and
14877;; SFmode.  The first is the normal insn, the second the same insn but
14878;; with one operand a conversion, and the third the same insn but with
14879;; the other operand a conversion.  The conversion may be SFmode or
14880;; SImode if the target mode DFmode, but only SImode if the target mode
14881;; is SFmode.
14882
14883;; Gcc is slightly more smart about handling normal two address instructions
14884;; so use special patterns for add and mull.
14885
14886(define_insn "*fop_<mode>_comm"
14887  [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14888	(match_operator:MODEF 3 "binary_fp_operator"
14889	  [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14890	   (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14891  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14892    || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14893   && COMMUTATIVE_ARITH_P (operands[3])
14894   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14895  "* return output_387_binary_op (insn, operands);"
14896  [(set (attr "type")
14897	(if_then_else (eq_attr "alternative" "1,2")
14898	   (if_then_else (match_operand:MODEF 3 "mult_operator")
14899	      (const_string "ssemul")
14900	      (const_string "sseadd"))
14901	   (if_then_else (match_operand:MODEF 3 "mult_operator")
14902	      (const_string "fmul")
14903	      (const_string "fop"))))
14904   (set_attr "isa" "*,noavx,avx")
14905   (set_attr "prefix" "orig,orig,vex")
14906   (set_attr "mode" "<MODE>")
14907   (set (attr "enabled")
14908     (if_then_else
14909       (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14910       (if_then_else
14911	 (eq_attr "alternative" "0")
14912	 (symbol_ref "TARGET_MIX_SSE_I387
14913		      && X87_ENABLE_ARITH (<MODE>mode)")
14914	 (const_string "*"))
14915       (if_then_else
14916	 (eq_attr "alternative" "0")
14917	 (symbol_ref "true")
14918	 (symbol_ref "false"))))])
14919
14920(define_insn "*rcpsf2_sse"
14921  [(set (match_operand:SF 0 "register_operand" "=x")
14922	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14923		   UNSPEC_RCP))]
14924  "TARGET_SSE && TARGET_SSE_MATH"
14925  "%vrcpss\t{%1, %d0|%d0, %1}"
14926  [(set_attr "type" "sse")
14927   (set_attr "atom_sse_attr" "rcp")
14928   (set_attr "btver2_sse_attr" "rcp")
14929   (set_attr "prefix" "maybe_vex")
14930   (set_attr "mode" "SF")])
14931
14932(define_insn "*fop_<mode>_1"
14933  [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14934	(match_operator:MODEF 3 "binary_fp_operator"
14935	  [(match_operand:MODEF 1
14936	     "x87nonimm_ssenomem_operand" "0,fm,0,v")
14937	   (match_operand:MODEF 2
14938	     "nonimmediate_operand"	  "fm,0,xm,vm")]))]
14939  "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14940    || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14941   && !COMMUTATIVE_ARITH_P (operands[3])
14942   && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14943  "* return output_387_binary_op (insn, operands);"
14944  [(set (attr "type")
14945	(if_then_else (eq_attr "alternative" "2,3")
14946	   (if_then_else (match_operand:MODEF 3 "div_operator")
14947	      (const_string "ssediv")
14948	      (const_string "sseadd"))
14949	   (if_then_else (match_operand:MODEF 3 "div_operator")
14950	      (const_string "fdiv")
14951	      (const_string "fop"))))
14952   (set_attr "isa" "*,*,noavx,avx")
14953   (set_attr "prefix" "orig,orig,orig,vex")
14954   (set_attr "mode" "<MODE>")
14955   (set (attr "enabled")
14956     (if_then_else
14957       (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14958       (if_then_else
14959	 (eq_attr "alternative" "0,1")
14960	 (symbol_ref "TARGET_MIX_SSE_I387
14961		      && X87_ENABLE_ARITH (<MODE>mode)")
14962	 (const_string "*"))
14963       (if_then_else
14964	 (eq_attr "alternative" "0,1")
14965	 (symbol_ref "true")
14966	 (symbol_ref "false"))))])
14967
14968;; ??? Add SSE splitters for these!
14969(define_insn "*fop_<MODEF:mode>_2_i387"
14970  [(set (match_operand:MODEF 0 "register_operand" "=f")
14971	(match_operator:MODEF 3 "binary_fp_operator"
14972	  [(float:MODEF
14973	     (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14974	   (match_operand:MODEF 2 "register_operand" "0")]))]
14975  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14976   && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14977   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14978       || optimize_function_for_size_p (cfun))"
14979  "* return output_387_binary_op (insn, operands);"
14980  [(set (attr "type")
14981        (cond [(match_operand:MODEF 3 "mult_operator")
14982                 (const_string "fmul")
14983               (match_operand:MODEF 3 "div_operator")
14984                 (const_string "fdiv")
14985              ]
14986              (const_string "fop")))
14987   (set_attr "fp_int_src" "true")
14988   (set_attr "mode" "<SWI24:MODE>")])
14989
14990(define_insn "*fop_<MODEF:mode>_3_i387"
14991  [(set (match_operand:MODEF 0 "register_operand" "=f")
14992	(match_operator:MODEF 3 "binary_fp_operator"
14993	  [(match_operand:MODEF 1 "register_operand" "0")
14994	   (float:MODEF
14995	     (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14996  "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14997   && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14998   && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14999       || optimize_function_for_size_p (cfun))"
15000  "* return output_387_binary_op (insn, operands);"
15001  [(set (attr "type")
15002        (cond [(match_operand:MODEF 3 "mult_operator")
15003                 (const_string "fmul")
15004               (match_operand:MODEF 3 "div_operator")
15005                 (const_string "fdiv")
15006              ]
15007              (const_string "fop")))
15008   (set_attr "fp_int_src" "true")
15009   (set_attr "mode" "<MODE>")])
15010
15011(define_insn "*fop_df_4_i387"
15012  [(set (match_operand:DF 0 "register_operand" "=f,f")
15013	(match_operator:DF 3 "binary_fp_operator"
15014	   [(float_extend:DF
15015	     (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15016	    (match_operand:DF 2 "register_operand" "0,f")]))]
15017  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15018   && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15019  "* return output_387_binary_op (insn, operands);"
15020  [(set (attr "type")
15021        (cond [(match_operand:DF 3 "mult_operator")
15022                 (const_string "fmul")
15023               (match_operand:DF 3 "div_operator")
15024                 (const_string "fdiv")
15025              ]
15026              (const_string "fop")))
15027   (set_attr "mode" "SF")])
15028
15029(define_insn "*fop_df_5_i387"
15030  [(set (match_operand:DF 0 "register_operand" "=f,f")
15031	(match_operator:DF 3 "binary_fp_operator"
15032	  [(match_operand:DF 1 "register_operand" "0,f")
15033	   (float_extend:DF
15034	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15035  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15036   && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15037  "* return output_387_binary_op (insn, operands);"
15038  [(set (attr "type")
15039        (cond [(match_operand:DF 3 "mult_operator")
15040                 (const_string "fmul")
15041               (match_operand:DF 3 "div_operator")
15042                 (const_string "fdiv")
15043              ]
15044              (const_string "fop")))
15045   (set_attr "mode" "SF")])
15046
15047(define_insn "*fop_df_6_i387"
15048  [(set (match_operand:DF 0 "register_operand" "=f,f")
15049	(match_operator:DF 3 "binary_fp_operator"
15050	  [(float_extend:DF
15051	    (match_operand:SF 1 "register_operand" "0,f"))
15052	   (float_extend:DF
15053	    (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15054  "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15055   && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15056  "* return output_387_binary_op (insn, operands);"
15057  [(set (attr "type")
15058        (cond [(match_operand:DF 3 "mult_operator")
15059                 (const_string "fmul")
15060               (match_operand:DF 3 "div_operator")
15061                 (const_string "fdiv")
15062              ]
15063              (const_string "fop")))
15064   (set_attr "mode" "SF")])
15065
15066(define_insn "*fop_xf_comm_i387"
15067  [(set (match_operand:XF 0 "register_operand" "=f")
15068	(match_operator:XF 3 "binary_fp_operator"
15069			[(match_operand:XF 1 "register_operand" "%0")
15070			 (match_operand:XF 2 "register_operand" "f")]))]
15071  "TARGET_80387
15072   && COMMUTATIVE_ARITH_P (operands[3])"
15073  "* return output_387_binary_op (insn, operands);"
15074  [(set (attr "type")
15075        (if_then_else (match_operand:XF 3 "mult_operator")
15076           (const_string "fmul")
15077           (const_string "fop")))
15078   (set_attr "mode" "XF")])
15079
15080(define_insn "*fop_xf_1_i387"
15081  [(set (match_operand:XF 0 "register_operand" "=f,f")
15082	(match_operator:XF 3 "binary_fp_operator"
15083			[(match_operand:XF 1 "register_operand" "0,f")
15084			 (match_operand:XF 2 "register_operand" "f,0")]))]
15085  "TARGET_80387
15086   && !COMMUTATIVE_ARITH_P (operands[3])"
15087  "* return output_387_binary_op (insn, operands);"
15088  [(set (attr "type")
15089        (if_then_else (match_operand:XF 3 "div_operator")
15090           (const_string "fdiv")
15091           (const_string "fop")))
15092   (set_attr "mode" "XF")])
15093
15094(define_insn "*fop_xf_2_i387"
15095  [(set (match_operand:XF 0 "register_operand" "=f")
15096	(match_operator:XF 3 "binary_fp_operator"
15097	  [(float:XF
15098	     (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15099	   (match_operand:XF 2 "register_operand" "0")]))]
15100  "TARGET_80387
15101   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15102  "* return output_387_binary_op (insn, operands);"
15103  [(set (attr "type")
15104        (cond [(match_operand:XF 3 "mult_operator")
15105                 (const_string "fmul")
15106               (match_operand:XF 3 "div_operator")
15107                 (const_string "fdiv")
15108              ]
15109              (const_string "fop")))
15110   (set_attr "fp_int_src" "true")
15111   (set_attr "mode" "<MODE>")])
15112
15113(define_insn "*fop_xf_3_i387"
15114  [(set (match_operand:XF 0 "register_operand" "=f")
15115	(match_operator:XF 3 "binary_fp_operator"
15116	  [(match_operand:XF 1 "register_operand" "0")
15117	   (float:XF
15118	     (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15119  "TARGET_80387
15120   && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15121  "* return output_387_binary_op (insn, operands);"
15122  [(set (attr "type")
15123        (cond [(match_operand:XF 3 "mult_operator")
15124                 (const_string "fmul")
15125               (match_operand:XF 3 "div_operator")
15126                 (const_string "fdiv")
15127              ]
15128              (const_string "fop")))
15129   (set_attr "fp_int_src" "true")
15130   (set_attr "mode" "<MODE>")])
15131
15132(define_insn "*fop_xf_4_i387"
15133  [(set (match_operand:XF 0 "register_operand" "=f,f")
15134	(match_operator:XF 3 "binary_fp_operator"
15135	   [(float_extend:XF
15136	      (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15137	    (match_operand:XF 2 "register_operand" "0,f")]))]
15138  "TARGET_80387"
15139  "* return output_387_binary_op (insn, operands);"
15140  [(set (attr "type")
15141        (cond [(match_operand:XF 3 "mult_operator")
15142                 (const_string "fmul")
15143               (match_operand:XF 3 "div_operator")
15144                 (const_string "fdiv")
15145              ]
15146              (const_string "fop")))
15147   (set_attr "mode" "<MODE>")])
15148
15149(define_insn "*fop_xf_5_i387"
15150  [(set (match_operand:XF 0 "register_operand" "=f,f")
15151	(match_operator:XF 3 "binary_fp_operator"
15152	  [(match_operand:XF 1 "register_operand" "0,f")
15153	   (float_extend:XF
15154	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15155  "TARGET_80387"
15156  "* return output_387_binary_op (insn, operands);"
15157  [(set (attr "type")
15158        (cond [(match_operand:XF 3 "mult_operator")
15159                 (const_string "fmul")
15160               (match_operand:XF 3 "div_operator")
15161                 (const_string "fdiv")
15162              ]
15163              (const_string "fop")))
15164   (set_attr "mode" "<MODE>")])
15165
15166(define_insn "*fop_xf_6_i387"
15167  [(set (match_operand:XF 0 "register_operand" "=f,f")
15168	(match_operator:XF 3 "binary_fp_operator"
15169	  [(float_extend:XF
15170	     (match_operand:MODEF 1 "register_operand" "0,f"))
15171	   (float_extend:XF
15172	     (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15173  "TARGET_80387"
15174  "* return output_387_binary_op (insn, operands);"
15175  [(set (attr "type")
15176        (cond [(match_operand:XF 3 "mult_operator")
15177                 (const_string "fmul")
15178               (match_operand:XF 3 "div_operator")
15179                 (const_string "fdiv")
15180              ]
15181              (const_string "fop")))
15182   (set_attr "mode" "<MODE>")])
15183
15184;; FPU special functions.
15185
15186;; This pattern implements a no-op XFmode truncation for
15187;; all fancy i386 XFmode math functions.
15188
15189(define_insn "truncxf<mode>2_i387_noop_unspec"
15190  [(set (match_operand:MODEF 0 "register_operand" "=f")
15191	(unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15192	UNSPEC_TRUNC_NOOP))]
15193  "TARGET_USE_FANCY_MATH_387"
15194  "* return output_387_reg_move (insn, operands);"
15195  [(set_attr "type" "fmov")
15196   (set_attr "mode" "<MODE>")])
15197
15198(define_insn "sqrtxf2"
15199  [(set (match_operand:XF 0 "register_operand" "=f")
15200	(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15201  "TARGET_USE_FANCY_MATH_387"
15202  "fsqrt"
15203  [(set_attr "type" "fpspc")
15204   (set_attr "mode" "XF")
15205   (set_attr "athlon_decode" "direct")
15206   (set_attr "amdfam10_decode" "direct")
15207   (set_attr "bdver1_decode" "direct")])
15208
15209(define_insn "sqrt_extend<mode>xf2_i387"
15210  [(set (match_operand:XF 0 "register_operand" "=f")
15211	(sqrt:XF
15212	  (float_extend:XF
15213	    (match_operand:MODEF 1 "register_operand" "0"))))]
15214  "TARGET_USE_FANCY_MATH_387"
15215  "fsqrt"
15216  [(set_attr "type" "fpspc")
15217   (set_attr "mode" "XF")
15218   (set_attr "athlon_decode" "direct")
15219   (set_attr "amdfam10_decode" "direct")
15220   (set_attr "bdver1_decode" "direct")])
15221
15222(define_insn "*rsqrtsf2_sse"
15223  [(set (match_operand:SF 0 "register_operand" "=x")
15224	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15225		   UNSPEC_RSQRT))]
15226  "TARGET_SSE && TARGET_SSE_MATH"
15227  "%vrsqrtss\t{%1, %d0|%d0, %1}"
15228  [(set_attr "type" "sse")
15229   (set_attr "atom_sse_attr" "rcp")
15230   (set_attr "btver2_sse_attr" "rcp")
15231   (set_attr "prefix" "maybe_vex")
15232   (set_attr "mode" "SF")])
15233
15234(define_expand "rsqrtsf2"
15235  [(set (match_operand:SF 0 "register_operand")
15236	(unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15237		   UNSPEC_RSQRT))]
15238  "TARGET_SSE && TARGET_SSE_MATH"
15239{
15240  ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15241  DONE;
15242})
15243
15244(define_insn "*sqrt<mode>2_sse"
15245  [(set (match_operand:MODEF 0 "register_operand" "=v")
15246	(sqrt:MODEF
15247	  (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15248  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15249  "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15250  [(set_attr "type" "sse")
15251   (set_attr "atom_sse_attr" "sqrt")
15252   (set_attr "btver2_sse_attr" "sqrt")
15253   (set_attr "prefix" "maybe_vex")
15254   (set_attr "mode" "<MODE>")
15255   (set_attr "athlon_decode" "*")
15256   (set_attr "amdfam10_decode" "*")
15257   (set_attr "bdver1_decode" "*")])
15258
15259(define_expand "sqrt<mode>2"
15260  [(set (match_operand:MODEF 0 "register_operand")
15261	(sqrt:MODEF
15262	  (match_operand:MODEF 1 "nonimmediate_operand")))]
15263  "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15264   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15265{
15266  if (<MODE>mode == SFmode
15267      && TARGET_SSE && TARGET_SSE_MATH
15268      && TARGET_RECIP_SQRT
15269      && !optimize_function_for_size_p (cfun)
15270      && flag_finite_math_only && !flag_trapping_math
15271      && flag_unsafe_math_optimizations)
15272    {
15273      ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15274      DONE;
15275    }
15276
15277  if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15278    {
15279      rtx op0 = gen_reg_rtx (XFmode);
15280      rtx op1 = force_reg (<MODE>mode, operands[1]);
15281
15282      emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15283      emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15284      DONE;
15285   }
15286})
15287
15288(define_insn "fpremxf4_i387"
15289  [(set (match_operand:XF 0 "register_operand" "=f")
15290	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15291		    (match_operand:XF 3 "register_operand" "1")]
15292		   UNSPEC_FPREM_F))
15293   (set (match_operand:XF 1 "register_operand" "=u")
15294	(unspec:XF [(match_dup 2) (match_dup 3)]
15295		   UNSPEC_FPREM_U))
15296   (set (reg:CCFP FPSR_REG)
15297	(unspec:CCFP [(match_dup 2) (match_dup 3)]
15298		     UNSPEC_C2_FLAG))]
15299  "TARGET_USE_FANCY_MATH_387
15300   && flag_finite_math_only"
15301  "fprem"
15302  [(set_attr "type" "fpspc")
15303   (set_attr "znver1_decode" "vector")
15304   (set_attr "mode" "XF")])
15305
15306(define_expand "fmodxf3"
15307  [(use (match_operand:XF 0 "register_operand"))
15308   (use (match_operand:XF 1 "general_operand"))
15309   (use (match_operand:XF 2 "general_operand"))]
15310  "TARGET_USE_FANCY_MATH_387
15311   && flag_finite_math_only"
15312{
15313  rtx_code_label *label = gen_label_rtx ();
15314
15315  rtx op1 = gen_reg_rtx (XFmode);
15316  rtx op2 = gen_reg_rtx (XFmode);
15317
15318  emit_move_insn (op2, operands[2]);
15319  emit_move_insn (op1, operands[1]);
15320
15321  emit_label (label);
15322  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15323  ix86_emit_fp_unordered_jump (label);
15324  LABEL_NUSES (label) = 1;
15325
15326  emit_move_insn (operands[0], op1);
15327  DONE;
15328})
15329
15330(define_expand "fmod<mode>3"
15331  [(use (match_operand:MODEF 0 "register_operand"))
15332   (use (match_operand:MODEF 1 "general_operand"))
15333   (use (match_operand:MODEF 2 "general_operand"))]
15334  "TARGET_USE_FANCY_MATH_387
15335   && flag_finite_math_only"
15336{
15337  rtx (*gen_truncxf) (rtx, rtx);
15338
15339  rtx_code_label *label = gen_label_rtx ();
15340
15341  rtx op1 = gen_reg_rtx (XFmode);
15342  rtx op2 = gen_reg_rtx (XFmode);
15343
15344  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15345  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15346
15347  emit_label (label);
15348  emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15349  ix86_emit_fp_unordered_jump (label);
15350  LABEL_NUSES (label) = 1;
15351
15352  /* Truncate the result properly for strict SSE math.  */
15353  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15354      && !TARGET_MIX_SSE_I387)
15355    gen_truncxf = gen_truncxf<mode>2;
15356  else
15357    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15358
15359  emit_insn (gen_truncxf (operands[0], op1));
15360  DONE;
15361})
15362
15363(define_insn "fprem1xf4_i387"
15364  [(set (match_operand:XF 0 "register_operand" "=f")
15365	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
15366		    (match_operand:XF 3 "register_operand" "1")]
15367		   UNSPEC_FPREM1_F))
15368   (set (match_operand:XF 1 "register_operand" "=u")
15369	(unspec:XF [(match_dup 2) (match_dup 3)]
15370		   UNSPEC_FPREM1_U))
15371   (set (reg:CCFP FPSR_REG)
15372	(unspec:CCFP [(match_dup 2) (match_dup 3)]
15373		     UNSPEC_C2_FLAG))]
15374  "TARGET_USE_FANCY_MATH_387
15375   && flag_finite_math_only"
15376  "fprem1"
15377  [(set_attr "type" "fpspc")
15378   (set_attr "znver1_decode" "vector")
15379   (set_attr "mode" "XF")])
15380
15381(define_expand "remainderxf3"
15382  [(use (match_operand:XF 0 "register_operand"))
15383   (use (match_operand:XF 1 "general_operand"))
15384   (use (match_operand:XF 2 "general_operand"))]
15385  "TARGET_USE_FANCY_MATH_387
15386   && flag_finite_math_only"
15387{
15388  rtx_code_label *label = gen_label_rtx ();
15389
15390  rtx op1 = gen_reg_rtx (XFmode);
15391  rtx op2 = gen_reg_rtx (XFmode);
15392
15393  emit_move_insn (op2, operands[2]);
15394  emit_move_insn (op1, operands[1]);
15395
15396  emit_label (label);
15397  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15398  ix86_emit_fp_unordered_jump (label);
15399  LABEL_NUSES (label) = 1;
15400
15401  emit_move_insn (operands[0], op1);
15402  DONE;
15403})
15404
15405(define_expand "remainder<mode>3"
15406  [(use (match_operand:MODEF 0 "register_operand"))
15407   (use (match_operand:MODEF 1 "general_operand"))
15408   (use (match_operand:MODEF 2 "general_operand"))]
15409  "TARGET_USE_FANCY_MATH_387
15410   && flag_finite_math_only"
15411{
15412  rtx (*gen_truncxf) (rtx, rtx);
15413
15414  rtx_code_label *label = gen_label_rtx ();
15415
15416  rtx op1 = gen_reg_rtx (XFmode);
15417  rtx op2 = gen_reg_rtx (XFmode);
15418
15419  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15420  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15421
15422  emit_label (label);
15423
15424  emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15425  ix86_emit_fp_unordered_jump (label);
15426  LABEL_NUSES (label) = 1;
15427
15428  /* Truncate the result properly for strict SSE math.  */
15429  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15430      && !TARGET_MIX_SSE_I387)
15431    gen_truncxf = gen_truncxf<mode>2;
15432  else
15433    gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15434
15435  emit_insn (gen_truncxf (operands[0], op1));
15436  DONE;
15437})
15438
15439(define_int_iterator SINCOS
15440	[UNSPEC_SIN
15441	 UNSPEC_COS])
15442
15443(define_int_attr sincos
15444	[(UNSPEC_SIN "sin")
15445	 (UNSPEC_COS "cos")])
15446
15447(define_insn "*<sincos>xf2_i387"
15448  [(set (match_operand:XF 0 "register_operand" "=f")
15449	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15450		   SINCOS))]
15451  "TARGET_USE_FANCY_MATH_387
15452   && flag_unsafe_math_optimizations"
15453  "f<sincos>"
15454  [(set_attr "type" "fpspc")
15455   (set_attr "znver1_decode" "vector")
15456   (set_attr "mode" "XF")])
15457
15458(define_insn "*<sincos>_extend<mode>xf2_i387"
15459  [(set (match_operand:XF 0 "register_operand" "=f")
15460	(unspec:XF [(float_extend:XF
15461		      (match_operand:MODEF 1 "register_operand" "0"))]
15462		   SINCOS))]
15463  "TARGET_USE_FANCY_MATH_387
15464   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15465       || TARGET_MIX_SSE_I387)
15466   && flag_unsafe_math_optimizations"
15467  "f<sincos>"
15468  [(set_attr "type" "fpspc")
15469   (set_attr "znver1_decode" "vector")
15470   (set_attr "mode" "XF")])
15471
15472;; When sincos pattern is defined, sin and cos builtin functions will be
15473;; expanded to sincos pattern with one of its outputs left unused.
15474;; CSE pass will figure out if two sincos patterns can be combined,
15475;; otherwise sincos pattern will be split back to sin or cos pattern,
15476;; depending on the unused output.
15477
15478(define_insn "sincosxf3"
15479  [(set (match_operand:XF 0 "register_operand" "=f")
15480	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15481		   UNSPEC_SINCOS_COS))
15482   (set (match_operand:XF 1 "register_operand" "=u")
15483        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15484  "TARGET_USE_FANCY_MATH_387
15485   && flag_unsafe_math_optimizations"
15486  "fsincos"
15487  [(set_attr "type" "fpspc")
15488   (set_attr "znver1_decode" "vector")
15489   (set_attr "mode" "XF")])
15490
15491(define_split
15492  [(set (match_operand:XF 0 "register_operand")
15493	(unspec:XF [(match_operand:XF 2 "register_operand")]
15494		   UNSPEC_SINCOS_COS))
15495   (set (match_operand:XF 1 "register_operand")
15496	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15497  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15498   && can_create_pseudo_p ()"
15499  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15500
15501(define_split
15502  [(set (match_operand:XF 0 "register_operand")
15503	(unspec:XF [(match_operand:XF 2 "register_operand")]
15504		   UNSPEC_SINCOS_COS))
15505   (set (match_operand:XF 1 "register_operand")
15506	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15507  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15508   && can_create_pseudo_p ()"
15509  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15510
15511(define_insn "sincos_extend<mode>xf3_i387"
15512  [(set (match_operand:XF 0 "register_operand" "=f")
15513	(unspec:XF [(float_extend:XF
15514		      (match_operand:MODEF 2 "register_operand" "0"))]
15515		   UNSPEC_SINCOS_COS))
15516   (set (match_operand:XF 1 "register_operand" "=u")
15517        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15518  "TARGET_USE_FANCY_MATH_387
15519   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15520       || TARGET_MIX_SSE_I387)
15521   && flag_unsafe_math_optimizations"
15522  "fsincos"
15523  [(set_attr "type" "fpspc")
15524   (set_attr "znver1_decode" "vector")
15525   (set_attr "mode" "XF")])
15526
15527(define_split
15528  [(set (match_operand:XF 0 "register_operand")
15529	(unspec:XF [(float_extend:XF
15530		      (match_operand:MODEF 2 "register_operand"))]
15531		   UNSPEC_SINCOS_COS))
15532   (set (match_operand:XF 1 "register_operand")
15533	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15534  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15535   && can_create_pseudo_p ()"
15536  [(set (match_dup 1)
15537	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15538
15539(define_split
15540  [(set (match_operand:XF 0 "register_operand")
15541	(unspec:XF [(float_extend:XF
15542		      (match_operand:MODEF 2 "register_operand"))]
15543		   UNSPEC_SINCOS_COS))
15544   (set (match_operand:XF 1 "register_operand")
15545	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15546  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15547   && can_create_pseudo_p ()"
15548  [(set (match_dup 0)
15549	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15550
15551(define_expand "sincos<mode>3"
15552  [(use (match_operand:MODEF 0 "register_operand"))
15553   (use (match_operand:MODEF 1 "register_operand"))
15554   (use (match_operand:MODEF 2 "register_operand"))]
15555  "TARGET_USE_FANCY_MATH_387
15556   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15557       || TARGET_MIX_SSE_I387)
15558   && flag_unsafe_math_optimizations"
15559{
15560  rtx op0 = gen_reg_rtx (XFmode);
15561  rtx op1 = gen_reg_rtx (XFmode);
15562
15563  emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15564  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15565  emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15566  DONE;
15567})
15568
15569(define_insn "fptanxf4_i387"
15570  [(set (match_operand:XF 0 "register_operand" "=f")
15571	(match_operand:XF 3 "const_double_operand" "F"))
15572   (set (match_operand:XF 1 "register_operand" "=u")
15573        (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15574		   UNSPEC_TAN))]
15575  "TARGET_USE_FANCY_MATH_387
15576   && flag_unsafe_math_optimizations
15577   && standard_80387_constant_p (operands[3]) == 2"
15578  "fptan"
15579  [(set_attr "type" "fpspc")
15580   (set_attr "znver1_decode" "vector")
15581   (set_attr "mode" "XF")])
15582
15583(define_insn "fptan_extend<mode>xf4_i387"
15584  [(set (match_operand:MODEF 0 "register_operand" "=f")
15585	(match_operand:MODEF 3 "const_double_operand" "F"))
15586   (set (match_operand:XF 1 "register_operand" "=u")
15587        (unspec:XF [(float_extend:XF
15588		      (match_operand:MODEF 2 "register_operand" "0"))]
15589		   UNSPEC_TAN))]
15590  "TARGET_USE_FANCY_MATH_387
15591   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15592       || TARGET_MIX_SSE_I387)
15593   && flag_unsafe_math_optimizations
15594   && standard_80387_constant_p (operands[3]) == 2"
15595  "fptan"
15596  [(set_attr "type" "fpspc")
15597   (set_attr "znver1_decode" "vector")
15598   (set_attr "mode" "XF")])
15599
15600(define_expand "tanxf2"
15601  [(use (match_operand:XF 0 "register_operand"))
15602   (use (match_operand:XF 1 "register_operand"))]
15603  "TARGET_USE_FANCY_MATH_387
15604   && flag_unsafe_math_optimizations"
15605{
15606  rtx one = gen_reg_rtx (XFmode);
15607  rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15608
15609  emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15610  DONE;
15611})
15612
15613(define_expand "tan<mode>2"
15614  [(use (match_operand:MODEF 0 "register_operand"))
15615   (use (match_operand:MODEF 1 "register_operand"))]
15616  "TARGET_USE_FANCY_MATH_387
15617   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15618       || TARGET_MIX_SSE_I387)
15619   && flag_unsafe_math_optimizations"
15620{
15621  rtx op0 = gen_reg_rtx (XFmode);
15622
15623  rtx one = gen_reg_rtx (<MODE>mode);
15624  rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15625
15626  emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15627					     operands[1], op2));
15628  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15629  DONE;
15630})
15631
15632(define_insn "*fpatanxf3_i387"
15633  [(set (match_operand:XF 0 "register_operand" "=f")
15634        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15635	            (match_operand:XF 2 "register_operand" "u")]
15636	           UNSPEC_FPATAN))
15637   (clobber (match_scratch:XF 3 "=2"))]
15638  "TARGET_USE_FANCY_MATH_387
15639   && flag_unsafe_math_optimizations"
15640  "fpatan"
15641  [(set_attr "type" "fpspc")
15642   (set_attr "znver1_decode" "vector")
15643   (set_attr "mode" "XF")])
15644
15645(define_insn "fpatan_extend<mode>xf3_i387"
15646  [(set (match_operand:XF 0 "register_operand" "=f")
15647        (unspec:XF [(float_extend:XF
15648		      (match_operand:MODEF 1 "register_operand" "0"))
15649		    (float_extend:XF
15650		      (match_operand:MODEF 2 "register_operand" "u"))]
15651	           UNSPEC_FPATAN))
15652   (clobber (match_scratch:XF 3 "=2"))]
15653  "TARGET_USE_FANCY_MATH_387
15654   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15655       || TARGET_MIX_SSE_I387)
15656   && flag_unsafe_math_optimizations"
15657  "fpatan"
15658  [(set_attr "type" "fpspc")
15659   (set_attr "znver1_decode" "vector")
15660   (set_attr "mode" "XF")])
15661
15662(define_expand "atan2xf3"
15663  [(parallel [(set (match_operand:XF 0 "register_operand")
15664		   (unspec:XF [(match_operand:XF 2 "register_operand")
15665			       (match_operand:XF 1 "register_operand")]
15666			      UNSPEC_FPATAN))
15667	      (clobber (match_scratch:XF 3))])]
15668  "TARGET_USE_FANCY_MATH_387
15669   && flag_unsafe_math_optimizations")
15670
15671(define_expand "atan2<mode>3"
15672  [(use (match_operand:MODEF 0 "register_operand"))
15673   (use (match_operand:MODEF 1 "register_operand"))
15674   (use (match_operand:MODEF 2 "register_operand"))]
15675  "TARGET_USE_FANCY_MATH_387
15676   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15677       || TARGET_MIX_SSE_I387)
15678   && flag_unsafe_math_optimizations"
15679{
15680  rtx op0 = gen_reg_rtx (XFmode);
15681
15682  emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15683  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15684  DONE;
15685})
15686
15687(define_expand "atanxf2"
15688  [(parallel [(set (match_operand:XF 0 "register_operand")
15689		   (unspec:XF [(match_dup 2)
15690			       (match_operand:XF 1 "register_operand")]
15691			      UNSPEC_FPATAN))
15692	      (clobber (match_scratch:XF 3))])]
15693  "TARGET_USE_FANCY_MATH_387
15694   && flag_unsafe_math_optimizations"
15695{
15696  operands[2] = gen_reg_rtx (XFmode);
15697  emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15698})
15699
15700(define_expand "atan<mode>2"
15701  [(use (match_operand:MODEF 0 "register_operand"))
15702   (use (match_operand:MODEF 1 "register_operand"))]
15703  "TARGET_USE_FANCY_MATH_387
15704   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15705       || TARGET_MIX_SSE_I387)
15706   && flag_unsafe_math_optimizations"
15707{
15708  rtx op0 = gen_reg_rtx (XFmode);
15709
15710  rtx op2 = gen_reg_rtx (<MODE>mode);
15711  emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15712
15713  emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15714  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15715  DONE;
15716})
15717
15718(define_expand "asinxf2"
15719  [(set (match_dup 2)
15720	(mult:XF (match_operand:XF 1 "register_operand")
15721		 (match_dup 1)))
15722   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15723   (set (match_dup 5) (sqrt:XF (match_dup 4)))
15724   (parallel [(set (match_operand:XF 0 "register_operand")
15725        	   (unspec:XF [(match_dup 5) (match_dup 1)]
15726			      UNSPEC_FPATAN))
15727   	      (clobber (match_scratch:XF 6))])]
15728  "TARGET_USE_FANCY_MATH_387
15729   && flag_unsafe_math_optimizations"
15730{
15731  int i;
15732
15733  for (i = 2; i < 6; i++)
15734    operands[i] = gen_reg_rtx (XFmode);
15735
15736  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15737})
15738
15739(define_expand "asin<mode>2"
15740  [(use (match_operand:MODEF 0 "register_operand"))
15741   (use (match_operand:MODEF 1 "general_operand"))]
15742  "TARGET_USE_FANCY_MATH_387
15743   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15744       || TARGET_MIX_SSE_I387)
15745   && flag_unsafe_math_optimizations"
15746{
15747  rtx op0 = gen_reg_rtx (XFmode);
15748  rtx op1 = gen_reg_rtx (XFmode);
15749
15750  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15751  emit_insn (gen_asinxf2 (op0, op1));
15752  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15753  DONE;
15754})
15755
15756(define_expand "acosxf2"
15757  [(set (match_dup 2)
15758	(mult:XF (match_operand:XF 1 "register_operand")
15759		 (match_dup 1)))
15760   (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15761   (set (match_dup 5) (sqrt:XF (match_dup 4)))
15762   (parallel [(set (match_operand:XF 0 "register_operand")
15763        	   (unspec:XF [(match_dup 1) (match_dup 5)]
15764			      UNSPEC_FPATAN))
15765   	      (clobber (match_scratch:XF 6))])]
15766  "TARGET_USE_FANCY_MATH_387
15767   && flag_unsafe_math_optimizations"
15768{
15769  int i;
15770
15771  for (i = 2; i < 6; i++)
15772    operands[i] = gen_reg_rtx (XFmode);
15773
15774  emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15775})
15776
15777(define_expand "acos<mode>2"
15778  [(use (match_operand:MODEF 0 "register_operand"))
15779   (use (match_operand:MODEF 1 "general_operand"))]
15780  "TARGET_USE_FANCY_MATH_387
15781   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15782       || TARGET_MIX_SSE_I387)
15783   && flag_unsafe_math_optimizations"
15784{
15785  rtx op0 = gen_reg_rtx (XFmode);
15786  rtx op1 = gen_reg_rtx (XFmode);
15787
15788  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15789  emit_insn (gen_acosxf2 (op0, op1));
15790  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15791  DONE;
15792})
15793
15794(define_insn "fyl2xxf3_i387"
15795  [(set (match_operand:XF 0 "register_operand" "=f")
15796        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15797		    (match_operand:XF 2 "register_operand" "u")]
15798	           UNSPEC_FYL2X))
15799   (clobber (match_scratch:XF 3 "=2"))]
15800  "TARGET_USE_FANCY_MATH_387
15801   && flag_unsafe_math_optimizations"
15802  "fyl2x"
15803  [(set_attr "type" "fpspc")
15804   (set_attr "znver1_decode" "vector")
15805   (set_attr "mode" "XF")])
15806
15807(define_insn "fyl2x_extend<mode>xf3_i387"
15808  [(set (match_operand:XF 0 "register_operand" "=f")
15809        (unspec:XF [(float_extend:XF
15810		      (match_operand:MODEF 1 "register_operand" "0"))
15811		    (match_operand:XF 2 "register_operand" "u")]
15812	           UNSPEC_FYL2X))
15813   (clobber (match_scratch:XF 3 "=2"))]
15814  "TARGET_USE_FANCY_MATH_387
15815   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15816       || TARGET_MIX_SSE_I387)
15817   && flag_unsafe_math_optimizations"
15818  "fyl2x"
15819  [(set_attr "type" "fpspc")
15820   (set_attr "znver1_decode" "vector")
15821   (set_attr "mode" "XF")])
15822
15823(define_expand "logxf2"
15824  [(parallel [(set (match_operand:XF 0 "register_operand")
15825		   (unspec:XF [(match_operand:XF 1 "register_operand")
15826			       (match_dup 2)] UNSPEC_FYL2X))
15827	      (clobber (match_scratch:XF 3))])]
15828  "TARGET_USE_FANCY_MATH_387
15829   && flag_unsafe_math_optimizations"
15830{
15831  operands[2] = gen_reg_rtx (XFmode);
15832  emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15833})
15834
15835(define_expand "log<mode>2"
15836  [(use (match_operand:MODEF 0 "register_operand"))
15837   (use (match_operand:MODEF 1 "register_operand"))]
15838  "TARGET_USE_FANCY_MATH_387
15839   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15840       || TARGET_MIX_SSE_I387)
15841   && flag_unsafe_math_optimizations"
15842{
15843  rtx op0 = gen_reg_rtx (XFmode);
15844
15845  rtx op2 = gen_reg_rtx (XFmode);
15846  emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15847
15848  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15849  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15850  DONE;
15851})
15852
15853(define_expand "log10xf2"
15854  [(parallel [(set (match_operand:XF 0 "register_operand")
15855		   (unspec:XF [(match_operand:XF 1 "register_operand")
15856			       (match_dup 2)] UNSPEC_FYL2X))
15857	      (clobber (match_scratch:XF 3))])]
15858  "TARGET_USE_FANCY_MATH_387
15859   && flag_unsafe_math_optimizations"
15860{
15861  operands[2] = gen_reg_rtx (XFmode);
15862  emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15863})
15864
15865(define_expand "log10<mode>2"
15866  [(use (match_operand:MODEF 0 "register_operand"))
15867   (use (match_operand:MODEF 1 "register_operand"))]
15868  "TARGET_USE_FANCY_MATH_387
15869   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15870       || TARGET_MIX_SSE_I387)
15871   && flag_unsafe_math_optimizations"
15872{
15873  rtx op0 = gen_reg_rtx (XFmode);
15874
15875  rtx op2 = gen_reg_rtx (XFmode);
15876  emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15877
15878  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15879  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15880  DONE;
15881})
15882
15883(define_expand "log2xf2"
15884  [(parallel [(set (match_operand:XF 0 "register_operand")
15885		   (unspec:XF [(match_operand:XF 1 "register_operand")
15886			       (match_dup 2)] UNSPEC_FYL2X))
15887	      (clobber (match_scratch:XF 3))])]
15888  "TARGET_USE_FANCY_MATH_387
15889   && flag_unsafe_math_optimizations"
15890{
15891  operands[2] = gen_reg_rtx (XFmode);
15892  emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15893})
15894
15895(define_expand "log2<mode>2"
15896  [(use (match_operand:MODEF 0 "register_operand"))
15897   (use (match_operand:MODEF 1 "register_operand"))]
15898  "TARGET_USE_FANCY_MATH_387
15899   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15900       || TARGET_MIX_SSE_I387)
15901   && flag_unsafe_math_optimizations"
15902{
15903  rtx op0 = gen_reg_rtx (XFmode);
15904
15905  rtx op2 = gen_reg_rtx (XFmode);
15906  emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15907
15908  emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15909  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15910  DONE;
15911})
15912
15913(define_insn "fyl2xp1xf3_i387"
15914  [(set (match_operand:XF 0 "register_operand" "=f")
15915        (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15916		    (match_operand:XF 2 "register_operand" "u")]
15917	           UNSPEC_FYL2XP1))
15918   (clobber (match_scratch:XF 3 "=2"))]
15919  "TARGET_USE_FANCY_MATH_387
15920   && flag_unsafe_math_optimizations"
15921  "fyl2xp1"
15922  [(set_attr "type" "fpspc")
15923   (set_attr "znver1_decode" "vector")
15924   (set_attr "mode" "XF")])
15925
15926(define_insn "fyl2xp1_extend<mode>xf3_i387"
15927  [(set (match_operand:XF 0 "register_operand" "=f")
15928        (unspec:XF [(float_extend:XF
15929		      (match_operand:MODEF 1 "register_operand" "0"))
15930		    (match_operand:XF 2 "register_operand" "u")]
15931	           UNSPEC_FYL2XP1))
15932   (clobber (match_scratch:XF 3 "=2"))]
15933  "TARGET_USE_FANCY_MATH_387
15934   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15935       || TARGET_MIX_SSE_I387)
15936   && flag_unsafe_math_optimizations"
15937  "fyl2xp1"
15938  [(set_attr "type" "fpspc")
15939   (set_attr "znver1_decode" "vector")
15940   (set_attr "mode" "XF")])
15941
15942(define_expand "log1pxf2"
15943  [(use (match_operand:XF 0 "register_operand"))
15944   (use (match_operand:XF 1 "register_operand"))]
15945  "TARGET_USE_FANCY_MATH_387
15946   && flag_unsafe_math_optimizations"
15947{
15948  ix86_emit_i387_log1p (operands[0], operands[1]);
15949  DONE;
15950})
15951
15952(define_expand "log1p<mode>2"
15953  [(use (match_operand:MODEF 0 "register_operand"))
15954   (use (match_operand:MODEF 1 "register_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;
15961
15962  op0 = gen_reg_rtx (XFmode);
15963
15964  operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15965
15966  ix86_emit_i387_log1p (op0, operands[1]);
15967  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15968  DONE;
15969})
15970
15971(define_insn "fxtractxf3_i387"
15972  [(set (match_operand:XF 0 "register_operand" "=f")
15973	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15974		   UNSPEC_XTRACT_FRACT))
15975   (set (match_operand:XF 1 "register_operand" "=u")
15976        (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15977  "TARGET_USE_FANCY_MATH_387
15978   && flag_unsafe_math_optimizations"
15979  "fxtract"
15980  [(set_attr "type" "fpspc")
15981   (set_attr "znver1_decode" "vector")
15982   (set_attr "mode" "XF")])
15983
15984(define_insn "fxtract_extend<mode>xf3_i387"
15985  [(set (match_operand:XF 0 "register_operand" "=f")
15986	(unspec:XF [(float_extend:XF
15987		      (match_operand:MODEF 2 "register_operand" "0"))]
15988		   UNSPEC_XTRACT_FRACT))
15989   (set (match_operand:XF 1 "register_operand" "=u")
15990        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15991  "TARGET_USE_FANCY_MATH_387
15992   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15993       || TARGET_MIX_SSE_I387)
15994   && flag_unsafe_math_optimizations"
15995  "fxtract"
15996  [(set_attr "type" "fpspc")
15997   (set_attr "znver1_decode" "vector")
15998   (set_attr "mode" "XF")])
15999
16000(define_expand "logbxf2"
16001  [(parallel [(set (match_dup 2)
16002		   (unspec:XF [(match_operand:XF 1 "register_operand")]
16003			      UNSPEC_XTRACT_FRACT))
16004	      (set (match_operand:XF 0 "register_operand")
16005		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16006  "TARGET_USE_FANCY_MATH_387
16007   && flag_unsafe_math_optimizations"
16008  "operands[2] = gen_reg_rtx (XFmode);")
16009
16010(define_expand "logb<mode>2"
16011  [(use (match_operand:MODEF 0 "register_operand"))
16012   (use (match_operand:MODEF 1 "register_operand"))]
16013  "TARGET_USE_FANCY_MATH_387
16014   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16015       || TARGET_MIX_SSE_I387)
16016   && flag_unsafe_math_optimizations"
16017{
16018  rtx op0 = gen_reg_rtx (XFmode);
16019  rtx op1 = gen_reg_rtx (XFmode);
16020
16021  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16022  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16023  DONE;
16024})
16025
16026(define_expand "ilogbxf2"
16027  [(use (match_operand:SI 0 "register_operand"))
16028   (use (match_operand:XF 1 "register_operand"))]
16029  "TARGET_USE_FANCY_MATH_387
16030   && flag_unsafe_math_optimizations"
16031{
16032  rtx op0, op1;
16033
16034  if (optimize_insn_for_size_p ())
16035    FAIL;
16036
16037  op0 = gen_reg_rtx (XFmode);
16038  op1 = gen_reg_rtx (XFmode);
16039
16040  emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16041  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16042  DONE;
16043})
16044
16045(define_expand "ilogb<mode>2"
16046  [(use (match_operand:SI 0 "register_operand"))
16047   (use (match_operand:MODEF 1 "register_operand"))]
16048  "TARGET_USE_FANCY_MATH_387
16049   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16050       || TARGET_MIX_SSE_I387)
16051   && flag_unsafe_math_optimizations"
16052{
16053  rtx op0, op1;
16054
16055  if (optimize_insn_for_size_p ())
16056    FAIL;
16057
16058  op0 = gen_reg_rtx (XFmode);
16059  op1 = gen_reg_rtx (XFmode);
16060
16061  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16062  emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16063  DONE;
16064})
16065
16066(define_insn "*f2xm1xf2_i387"
16067  [(set (match_operand:XF 0 "register_operand" "=f")
16068	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16069		   UNSPEC_F2XM1))]
16070  "TARGET_USE_FANCY_MATH_387
16071   && flag_unsafe_math_optimizations"
16072  "f2xm1"
16073  [(set_attr "type" "fpspc")
16074   (set_attr "znver1_decode" "vector")
16075   (set_attr "mode" "XF")])
16076
16077(define_insn "fscalexf4_i387"
16078  [(set (match_operand:XF 0 "register_operand" "=f")
16079	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
16080		    (match_operand:XF 3 "register_operand" "1")]
16081		   UNSPEC_FSCALE_FRACT))
16082   (set (match_operand:XF 1 "register_operand" "=u")
16083	(unspec:XF [(match_dup 2) (match_dup 3)]
16084		   UNSPEC_FSCALE_EXP))]
16085  "TARGET_USE_FANCY_MATH_387
16086   && flag_unsafe_math_optimizations"
16087  "fscale"
16088  [(set_attr "type" "fpspc")
16089   (set_attr "znver1_decode" "vector")
16090   (set_attr "mode" "XF")])
16091
16092(define_expand "expNcorexf3"
16093  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16094			       (match_operand:XF 2 "register_operand")))
16095   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16096   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16097   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16098   (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16099   (parallel [(set (match_operand:XF 0 "register_operand")
16100		   (unspec:XF [(match_dup 8) (match_dup 4)]
16101			      UNSPEC_FSCALE_FRACT))
16102	      (set (match_dup 9)
16103		   (unspec:XF [(match_dup 8) (match_dup 4)]
16104			      UNSPEC_FSCALE_EXP))])]
16105  "TARGET_USE_FANCY_MATH_387
16106   && flag_unsafe_math_optimizations"
16107{
16108  int i;
16109
16110  for (i = 3; i < 10; i++)
16111    operands[i] = gen_reg_rtx (XFmode);
16112
16113  emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16114})
16115
16116(define_expand "expxf2"
16117  [(use (match_operand:XF 0 "register_operand"))
16118   (use (match_operand:XF 1 "register_operand"))]
16119  "TARGET_USE_FANCY_MATH_387
16120   && flag_unsafe_math_optimizations"
16121{
16122  rtx op2;
16123
16124  op2 = gen_reg_rtx (XFmode);
16125  emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16126
16127  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16128  DONE;
16129})
16130
16131(define_expand "exp<mode>2"
16132  [(use (match_operand:MODEF 0 "register_operand"))
16133   (use (match_operand:MODEF 1 "general_operand"))]
16134  "TARGET_USE_FANCY_MATH_387
16135   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16136       || TARGET_MIX_SSE_I387)
16137   && flag_unsafe_math_optimizations"
16138{
16139  rtx op0, op1;
16140
16141  op0 = gen_reg_rtx (XFmode);
16142  op1 = gen_reg_rtx (XFmode);
16143
16144  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16145  emit_insn (gen_expxf2 (op0, op1));
16146  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16147  DONE;
16148})
16149
16150(define_expand "exp10xf2"
16151  [(use (match_operand:XF 0 "register_operand"))
16152   (use (match_operand:XF 1 "register_operand"))]
16153  "TARGET_USE_FANCY_MATH_387
16154   && flag_unsafe_math_optimizations"
16155{
16156  rtx op2;
16157
16158  op2 = gen_reg_rtx (XFmode);
16159  emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16160
16161  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16162  DONE;
16163})
16164
16165(define_expand "exp10<mode>2"
16166  [(use (match_operand:MODEF 0 "register_operand"))
16167   (use (match_operand:MODEF 1 "general_operand"))]
16168  "TARGET_USE_FANCY_MATH_387
16169   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16170       || TARGET_MIX_SSE_I387)
16171   && flag_unsafe_math_optimizations"
16172{
16173  rtx op0, op1;
16174
16175  op0 = gen_reg_rtx (XFmode);
16176  op1 = gen_reg_rtx (XFmode);
16177
16178  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16179  emit_insn (gen_exp10xf2 (op0, op1));
16180  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16181  DONE;
16182})
16183
16184(define_expand "exp2xf2"
16185  [(use (match_operand:XF 0 "register_operand"))
16186   (use (match_operand:XF 1 "register_operand"))]
16187  "TARGET_USE_FANCY_MATH_387
16188   && flag_unsafe_math_optimizations"
16189{
16190  rtx op2;
16191
16192  op2 = gen_reg_rtx (XFmode);
16193  emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16194
16195  emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16196  DONE;
16197})
16198
16199(define_expand "exp2<mode>2"
16200  [(use (match_operand:MODEF 0 "register_operand"))
16201   (use (match_operand:MODEF 1 "general_operand"))]
16202  "TARGET_USE_FANCY_MATH_387
16203   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16204       || TARGET_MIX_SSE_I387)
16205   && flag_unsafe_math_optimizations"
16206{
16207  rtx op0, op1;
16208
16209  op0 = gen_reg_rtx (XFmode);
16210  op1 = gen_reg_rtx (XFmode);
16211
16212  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16213  emit_insn (gen_exp2xf2 (op0, op1));
16214  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16215  DONE;
16216})
16217
16218(define_expand "expm1xf2"
16219  [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16220			       (match_dup 2)))
16221   (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16222   (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16223   (set (match_dup 9) (float_extend:XF (match_dup 13)))
16224   (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16225   (parallel [(set (match_dup 7)
16226		   (unspec:XF [(match_dup 6) (match_dup 4)]
16227			      UNSPEC_FSCALE_FRACT))
16228	      (set (match_dup 8)
16229		   (unspec:XF [(match_dup 6) (match_dup 4)]
16230			      UNSPEC_FSCALE_EXP))])
16231   (parallel [(set (match_dup 10)
16232		   (unspec:XF [(match_dup 9) (match_dup 8)]
16233			      UNSPEC_FSCALE_FRACT))
16234	      (set (match_dup 11)
16235		   (unspec:XF [(match_dup 9) (match_dup 8)]
16236			      UNSPEC_FSCALE_EXP))])
16237   (set (match_dup 12) (minus:XF (match_dup 10)
16238				 (float_extend:XF (match_dup 13))))
16239   (set (match_operand:XF 0 "register_operand")
16240	(plus:XF (match_dup 12) (match_dup 7)))]
16241  "TARGET_USE_FANCY_MATH_387
16242   && flag_unsafe_math_optimizations"
16243{
16244  int i;
16245
16246  for (i = 2; i < 13; i++)
16247    operands[i] = gen_reg_rtx (XFmode);
16248
16249  operands[13]
16250    = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16251
16252  emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16253})
16254
16255(define_expand "expm1<mode>2"
16256  [(use (match_operand:MODEF 0 "register_operand"))
16257   (use (match_operand:MODEF 1 "general_operand"))]
16258  "TARGET_USE_FANCY_MATH_387
16259   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16260       || TARGET_MIX_SSE_I387)
16261   && flag_unsafe_math_optimizations"
16262{
16263  rtx op0, op1;
16264
16265  op0 = gen_reg_rtx (XFmode);
16266  op1 = gen_reg_rtx (XFmode);
16267
16268  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16269  emit_insn (gen_expm1xf2 (op0, op1));
16270  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16271  DONE;
16272})
16273
16274(define_expand "ldexpxf3"
16275  [(match_operand:XF 0 "register_operand")
16276   (match_operand:XF 1 "register_operand")
16277   (match_operand:SI 2 "register_operand")]
16278  "TARGET_USE_FANCY_MATH_387
16279   && flag_unsafe_math_optimizations"
16280{
16281  rtx tmp1, tmp2;
16282
16283  tmp1 = gen_reg_rtx (XFmode);
16284  tmp2 = gen_reg_rtx (XFmode);
16285
16286  emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16287  emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16288                                 operands[1], tmp1));
16289  DONE;
16290})
16291
16292(define_expand "ldexp<mode>3"
16293  [(use (match_operand:MODEF 0 "register_operand"))
16294   (use (match_operand:MODEF 1 "general_operand"))
16295   (use (match_operand:SI 2 "register_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, op1;
16302
16303  op0 = gen_reg_rtx (XFmode);
16304  op1 = gen_reg_rtx (XFmode);
16305
16306  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16307  emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16308  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16309  DONE;
16310})
16311
16312(define_expand "scalbxf3"
16313  [(parallel [(set (match_operand:XF 0 " register_operand")
16314		   (unspec:XF [(match_operand:XF 1 "register_operand")
16315			       (match_operand:XF 2 "register_operand")]
16316			      UNSPEC_FSCALE_FRACT))
16317	      (set (match_dup 3)
16318		   (unspec:XF [(match_dup 1) (match_dup 2)]
16319			      UNSPEC_FSCALE_EXP))])]
16320  "TARGET_USE_FANCY_MATH_387
16321   && flag_unsafe_math_optimizations"
16322{
16323  operands[3] = gen_reg_rtx (XFmode);
16324})
16325
16326(define_expand "scalb<mode>3"
16327  [(use (match_operand:MODEF 0 "register_operand"))
16328   (use (match_operand:MODEF 1 "general_operand"))
16329   (use (match_operand:MODEF 2 "general_operand"))]
16330  "TARGET_USE_FANCY_MATH_387
16331   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16332       || TARGET_MIX_SSE_I387)
16333   && flag_unsafe_math_optimizations"
16334{
16335  rtx op0, op1, op2;
16336
16337  op0 = gen_reg_rtx (XFmode);
16338  op1 = gen_reg_rtx (XFmode);
16339  op2 = gen_reg_rtx (XFmode);
16340
16341  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16342  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16343  emit_insn (gen_scalbxf3 (op0, op1, op2));
16344  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16345  DONE;
16346})
16347
16348(define_expand "significandxf2"
16349  [(parallel [(set (match_operand:XF 0 "register_operand")
16350		   (unspec:XF [(match_operand:XF 1 "register_operand")]
16351			      UNSPEC_XTRACT_FRACT))
16352	      (set (match_dup 2)
16353		   (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16354  "TARGET_USE_FANCY_MATH_387
16355   && flag_unsafe_math_optimizations"
16356  "operands[2] = gen_reg_rtx (XFmode);")
16357
16358(define_expand "significand<mode>2"
16359  [(use (match_operand:MODEF 0 "register_operand"))
16360   (use (match_operand:MODEF 1 "register_operand"))]
16361  "TARGET_USE_FANCY_MATH_387
16362   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16363       || TARGET_MIX_SSE_I387)
16364   && flag_unsafe_math_optimizations"
16365{
16366  rtx op0 = gen_reg_rtx (XFmode);
16367  rtx op1 = gen_reg_rtx (XFmode);
16368
16369  emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16370  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16371  DONE;
16372})
16373
16374
16375(define_insn "sse4_1_round<mode>2"
16376  [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16377	(unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
16378		       (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16379		      UNSPEC_ROUND))]
16380  "TARGET_SSE4_1"
16381  "@
16382   %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16383   vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16384  [(set_attr "type" "ssecvt")
16385   (set_attr "prefix_extra" "1,*")
16386   (set_attr "length_immediate" "*,1")
16387   (set_attr "prefix" "maybe_vex,evex")
16388   (set_attr "isa" "noavx512f,avx512f")
16389   (set_attr "mode" "<MODE>")])
16390
16391(define_insn "rintxf2"
16392  [(set (match_operand:XF 0 "register_operand" "=f")
16393	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16394		   UNSPEC_FRNDINT))]
16395  "TARGET_USE_FANCY_MATH_387"
16396  "frndint"
16397  [(set_attr "type" "fpspc")
16398   (set_attr "znver1_decode" "vector")
16399   (set_attr "mode" "XF")])
16400
16401(define_insn "rint<mode>2_frndint"
16402  [(set (match_operand:MODEF 0 "register_operand" "=f")
16403	(unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16404		      UNSPEC_FRNDINT))]
16405  "TARGET_USE_FANCY_MATH_387"
16406  "frndint"
16407  [(set_attr "type" "fpspc")
16408   (set_attr "znver1_decode" "vector")
16409   (set_attr "mode" "<MODE>")])
16410
16411(define_expand "rint<mode>2"
16412  [(use (match_operand:MODEF 0 "register_operand"))
16413   (use (match_operand:MODEF 1 "register_operand"))]
16414  "(TARGET_USE_FANCY_MATH_387
16415    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16416	|| TARGET_MIX_SSE_I387))
16417   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16418{
16419  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16420    {
16421      if (TARGET_SSE4_1)
16422	emit_insn (gen_sse4_1_round<mode>2
16423		   (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16424      else
16425	ix86_expand_rint (operands[0], operands[1]);
16426    }
16427  else
16428    emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16429  DONE;
16430})
16431
16432(define_expand "round<mode>2"
16433  [(match_operand:X87MODEF 0 "register_operand")
16434   (match_operand:X87MODEF 1 "nonimmediate_operand")]
16435  "(TARGET_USE_FANCY_MATH_387
16436    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16437	|| TARGET_MIX_SSE_I387)
16438    && flag_unsafe_math_optimizations
16439    && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16440   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16441       && !flag_trapping_math && !flag_rounding_math)"
16442{
16443  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16444      && !flag_trapping_math && !flag_rounding_math)
16445    {
16446      if (TARGET_SSE4_1)
16447        {
16448	  operands[1] = force_reg (<MODE>mode, operands[1]);
16449	  ix86_expand_round_sse4 (operands[0], operands[1]);
16450	}
16451      else if (TARGET_64BIT || (<MODE>mode != DFmode))
16452	ix86_expand_round (operands[0], operands[1]);
16453      else
16454	ix86_expand_rounddf_32 (operands[0], operands[1]);
16455    }
16456  else
16457    {
16458      operands[1] = force_reg (<MODE>mode, operands[1]);
16459      ix86_emit_i387_round (operands[0], operands[1]);
16460    }
16461  DONE;
16462})
16463
16464(define_insn_and_split "*fistdi2_1"
16465  [(set (match_operand:DI 0 "nonimmediate_operand")
16466	(unspec:DI [(match_operand:XF 1 "register_operand")]
16467		   UNSPEC_FIST))]
16468  "TARGET_USE_FANCY_MATH_387
16469   && can_create_pseudo_p ()"
16470  "#"
16471  "&& 1"
16472  [(const_int 0)]
16473{
16474  if (memory_operand (operands[0], VOIDmode))
16475    emit_insn (gen_fistdi2 (operands[0], operands[1]));
16476  else
16477    {
16478      operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16479      emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16480					 operands[2]));
16481    }
16482  DONE;
16483}
16484  [(set_attr "type" "fpspc")
16485   (set_attr "mode" "DI")])
16486
16487(define_insn "fistdi2"
16488  [(set (match_operand:DI 0 "memory_operand" "=m")
16489	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16490		   UNSPEC_FIST))
16491   (clobber (match_scratch:XF 2 "=&1f"))]
16492  "TARGET_USE_FANCY_MATH_387"
16493  "* return output_fix_trunc (insn, operands, false);"
16494  [(set_attr "type" "fpspc")
16495   (set_attr "mode" "DI")])
16496
16497(define_insn "fistdi2_with_temp"
16498  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16499	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16500		   UNSPEC_FIST))
16501   (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16502   (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16503  "TARGET_USE_FANCY_MATH_387"
16504  "#"
16505  [(set_attr "type" "fpspc")
16506   (set_attr "mode" "DI")])
16507
16508(define_split
16509  [(set (match_operand:DI 0 "register_operand")
16510	(unspec:DI [(match_operand:XF 1 "register_operand")]
16511		   UNSPEC_FIST))
16512   (clobber (match_operand:DI 2 "memory_operand"))
16513   (clobber (match_scratch 3))]
16514  "reload_completed"
16515  [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16516	      (clobber (match_dup 3))])
16517   (set (match_dup 0) (match_dup 2))])
16518
16519(define_split
16520  [(set (match_operand:DI 0 "memory_operand")
16521	(unspec:DI [(match_operand:XF 1 "register_operand")]
16522		   UNSPEC_FIST))
16523   (clobber (match_operand:DI 2 "memory_operand"))
16524   (clobber (match_scratch 3))]
16525  "reload_completed"
16526  [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16527	      (clobber (match_dup 3))])])
16528
16529(define_insn_and_split "*fist<mode>2_1"
16530  [(set (match_operand:SWI24 0 "register_operand")
16531	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16532		      UNSPEC_FIST))]
16533  "TARGET_USE_FANCY_MATH_387
16534   && can_create_pseudo_p ()"
16535  "#"
16536  "&& 1"
16537  [(const_int 0)]
16538{
16539  operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16540  emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16541					operands[2]));
16542  DONE;
16543}
16544  [(set_attr "type" "fpspc")
16545   (set_attr "mode" "<MODE>")])
16546
16547(define_insn "fist<mode>2"
16548  [(set (match_operand:SWI24 0 "memory_operand" "=m")
16549	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16550		      UNSPEC_FIST))]
16551  "TARGET_USE_FANCY_MATH_387"
16552  "* return output_fix_trunc (insn, operands, false);"
16553  [(set_attr "type" "fpspc")
16554   (set_attr "mode" "<MODE>")])
16555
16556(define_insn "fist<mode>2_with_temp"
16557  [(set (match_operand:SWI24 0 "register_operand" "=r")
16558	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16559		      UNSPEC_FIST))
16560   (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16561  "TARGET_USE_FANCY_MATH_387"
16562  "#"
16563  [(set_attr "type" "fpspc")
16564   (set_attr "mode" "<MODE>")])
16565
16566(define_split
16567  [(set (match_operand:SWI24 0 "register_operand")
16568	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16569		      UNSPEC_FIST))
16570   (clobber (match_operand:SWI24 2 "memory_operand"))]
16571  "reload_completed"
16572  [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16573   (set (match_dup 0) (match_dup 2))])
16574
16575(define_split
16576  [(set (match_operand:SWI24 0 "memory_operand")
16577	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16578		      UNSPEC_FIST))
16579   (clobber (match_operand:SWI24 2 "memory_operand"))]
16580  "reload_completed"
16581  [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16582
16583(define_expand "lrintxf<mode>2"
16584  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16585     (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16586		     UNSPEC_FIST))]
16587  "TARGET_USE_FANCY_MATH_387")
16588
16589(define_expand "lrint<MODEF:mode><SWI48:mode>2"
16590  [(set (match_operand:SWI48 0 "nonimmediate_operand")
16591     (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16592		   UNSPEC_FIX_NOTRUNC))]
16593  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16594
16595(define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16596  [(match_operand:SWI248x 0 "nonimmediate_operand")
16597   (match_operand:X87MODEF 1 "register_operand")]
16598  "(TARGET_USE_FANCY_MATH_387
16599    && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16600	|| TARGET_MIX_SSE_I387)
16601    && flag_unsafe_math_optimizations)
16602   || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16603       && <SWI248x:MODE>mode != HImode
16604       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16605       && !flag_trapping_math && !flag_rounding_math)"
16606{
16607  if (optimize_insn_for_size_p ())
16608    FAIL;
16609
16610  if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16611      && <SWI248x:MODE>mode != HImode
16612      && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16613      && !flag_trapping_math && !flag_rounding_math)
16614    ix86_expand_lround (operands[0], operands[1]);
16615  else
16616    ix86_emit_i387_round (operands[0], operands[1]);
16617  DONE;
16618})
16619
16620(define_int_iterator FRNDINT_ROUNDING
16621	[UNSPEC_FRNDINT_FLOOR
16622	 UNSPEC_FRNDINT_CEIL
16623	 UNSPEC_FRNDINT_TRUNC])
16624
16625(define_int_iterator FIST_ROUNDING
16626	[UNSPEC_FIST_FLOOR
16627	 UNSPEC_FIST_CEIL])
16628
16629;; Base name for define_insn
16630(define_int_attr rounding_insn
16631	[(UNSPEC_FRNDINT_FLOOR "floor")
16632	 (UNSPEC_FRNDINT_CEIL "ceil")
16633	 (UNSPEC_FRNDINT_TRUNC "btrunc")
16634	 (UNSPEC_FIST_FLOOR "floor")
16635	 (UNSPEC_FIST_CEIL "ceil")])
16636
16637(define_int_attr rounding
16638	[(UNSPEC_FRNDINT_FLOOR "floor")
16639	 (UNSPEC_FRNDINT_CEIL "ceil")
16640	 (UNSPEC_FRNDINT_TRUNC "trunc")
16641	 (UNSPEC_FIST_FLOOR "floor")
16642	 (UNSPEC_FIST_CEIL "ceil")])
16643
16644(define_int_attr ROUNDING
16645	[(UNSPEC_FRNDINT_FLOOR "FLOOR")
16646	 (UNSPEC_FRNDINT_CEIL "CEIL")
16647	 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16648	 (UNSPEC_FIST_FLOOR "FLOOR")
16649	 (UNSPEC_FIST_CEIL "CEIL")])
16650
16651;; Rounding mode control word calculation could clobber FLAGS_REG.
16652(define_insn_and_split "frndint<mode>2_<rounding>"
16653  [(set (match_operand:X87MODEF 0 "register_operand")
16654	(unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16655		   FRNDINT_ROUNDING))
16656   (clobber (reg:CC FLAGS_REG))]
16657  "TARGET_USE_FANCY_MATH_387
16658   && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16659   && can_create_pseudo_p ()"
16660  "#"
16661  "&& 1"
16662  [(const_int 0)]
16663{
16664  ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16665
16666  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16667  operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16668
16669  emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16670						 operands[2], operands[3]));
16671  DONE;
16672}
16673  [(set_attr "type" "frndint")
16674   (set_attr "i387_cw" "<rounding>")
16675   (set_attr "mode" "<MODE>")])
16676
16677(define_insn "frndint<mode>2_<rounding>_i387"
16678  [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16679	(unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16680			 FRNDINT_ROUNDING))
16681   (use (match_operand:HI 2 "memory_operand" "m"))
16682   (use (match_operand:HI 3 "memory_operand" "m"))]
16683  "TARGET_USE_FANCY_MATH_387
16684   && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16685  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16686  [(set_attr "type" "frndint")
16687   (set_attr "i387_cw" "<rounding>")
16688   (set_attr "mode" "<MODE>")])
16689
16690(define_expand "<rounding_insn>xf2"
16691  [(parallel [(set (match_operand:XF 0 "register_operand")
16692		   (unspec:XF [(match_operand:XF 1 "register_operand")]
16693			      FRNDINT_ROUNDING))
16694	      (clobber (reg:CC FLAGS_REG))])]
16695  "TARGET_USE_FANCY_MATH_387
16696   && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16697
16698(define_expand "<rounding_insn><mode>2"
16699  [(parallel [(set (match_operand:MODEF 0 "register_operand")
16700		   (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16701				 FRNDINT_ROUNDING))
16702	      (clobber (reg:CC FLAGS_REG))])]
16703  "(TARGET_USE_FANCY_MATH_387
16704    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16705	|| TARGET_MIX_SSE_I387)
16706    && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16707   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16708       && (TARGET_SSE4_1 || !flag_trapping_math
16709	   || flag_fp_int_builtin_inexact))"
16710{
16711  if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16712      && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16713    {
16714      if (TARGET_SSE4_1)
16715	emit_insn (gen_sse4_1_round<mode>2
16716		   (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16717						       | ROUND_NO_EXC)));
16718      else if (TARGET_64BIT || (<MODE>mode != DFmode))
16719	{
16720	  if (ROUND_<ROUNDING> == ROUND_FLOOR)
16721	    ix86_expand_floorceil (operands[0], operands[1], true);
16722	  else if (ROUND_<ROUNDING> == ROUND_CEIL)
16723	    ix86_expand_floorceil (operands[0], operands[1], false);
16724	  else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16725	    ix86_expand_trunc (operands[0], operands[1]);
16726	  else
16727	    gcc_unreachable ();
16728	}
16729      else
16730	{
16731	  if (ROUND_<ROUNDING> == ROUND_FLOOR)
16732	    ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16733	  else if (ROUND_<ROUNDING> == ROUND_CEIL)
16734	    ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16735	  else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16736	    ix86_expand_truncdf_32 (operands[0], operands[1]);
16737	  else
16738	    gcc_unreachable ();
16739	}
16740    }
16741  else
16742    emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16743  DONE;
16744})
16745
16746;; Rounding mode control word calculation could clobber FLAGS_REG.
16747(define_insn_and_split "frndintxf2_mask_pm"
16748  [(set (match_operand:XF 0 "register_operand")
16749	(unspec:XF [(match_operand:XF 1 "register_operand")]
16750		   UNSPEC_FRNDINT_MASK_PM))
16751   (clobber (reg:CC FLAGS_REG))]
16752  "TARGET_USE_FANCY_MATH_387
16753   && flag_unsafe_math_optimizations
16754   && can_create_pseudo_p ()"
16755  "#"
16756  "&& 1"
16757  [(const_int 0)]
16758{
16759  ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16760
16761  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16762  operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16763
16764  emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16765					  operands[2], operands[3]));
16766  DONE;
16767}
16768  [(set_attr "type" "frndint")
16769   (set_attr "i387_cw" "mask_pm")
16770   (set_attr "mode" "XF")])
16771
16772(define_insn "frndintxf2_mask_pm_i387"
16773  [(set (match_operand:XF 0 "register_operand" "=f")
16774	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16775		   UNSPEC_FRNDINT_MASK_PM))
16776   (use (match_operand:HI 2 "memory_operand" "m"))
16777   (use (match_operand:HI 3 "memory_operand" "m"))]
16778  "TARGET_USE_FANCY_MATH_387
16779   && flag_unsafe_math_optimizations"
16780  "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16781  [(set_attr "type" "frndint")
16782   (set_attr "i387_cw" "mask_pm")
16783   (set_attr "mode" "XF")])
16784
16785(define_expand "nearbyintxf2"
16786  [(parallel [(set (match_operand:XF 0 "register_operand")
16787		   (unspec:XF [(match_operand:XF 1 "register_operand")]
16788			      UNSPEC_FRNDINT_MASK_PM))
16789	      (clobber (reg:CC FLAGS_REG))])]
16790  "TARGET_USE_FANCY_MATH_387
16791   && flag_unsafe_math_optimizations")
16792
16793(define_expand "nearbyint<mode>2"
16794  [(use (match_operand:MODEF 0 "register_operand"))
16795   (use (match_operand:MODEF 1 "register_operand"))]
16796  "TARGET_USE_FANCY_MATH_387
16797   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16798       || TARGET_MIX_SSE_I387)
16799   && flag_unsafe_math_optimizations"
16800{
16801  rtx op0 = gen_reg_rtx (XFmode);
16802  rtx op1 = gen_reg_rtx (XFmode);
16803
16804  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16805  emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16806
16807  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16808  DONE;
16809})
16810
16811;; Rounding mode control word calculation could clobber FLAGS_REG.
16812(define_insn_and_split "*fist<mode>2_<rounding>_1"
16813  [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16814	(unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16815			FIST_ROUNDING))
16816   (clobber (reg:CC FLAGS_REG))]
16817  "TARGET_USE_FANCY_MATH_387
16818   && flag_unsafe_math_optimizations
16819   && can_create_pseudo_p ()"
16820  "#"
16821  "&& 1"
16822  [(const_int 0)]
16823{
16824  ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16825
16826  operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16827  operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16828  if (memory_operand (operands[0], VOIDmode))
16829    emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16830					   operands[2], operands[3]));
16831  else
16832    {
16833      operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16834      emit_insn (gen_fist<mode>2_<rounding>_with_temp
16835		  (operands[0], operands[1], operands[2],
16836		   operands[3], operands[4]));
16837    }
16838  DONE;
16839}
16840  [(set_attr "type" "fistp")
16841   (set_attr "i387_cw" "<rounding>")
16842   (set_attr "mode" "<MODE>")])
16843
16844(define_insn "fistdi2_<rounding>"
16845  [(set (match_operand:DI 0 "memory_operand" "=m")
16846	(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16847		   FIST_ROUNDING))
16848   (use (match_operand:HI 2 "memory_operand" "m"))
16849   (use (match_operand:HI 3 "memory_operand" "m"))
16850   (clobber (match_scratch:XF 4 "=&1f"))]
16851  "TARGET_USE_FANCY_MATH_387
16852   && flag_unsafe_math_optimizations"
16853  "* return output_fix_trunc (insn, operands, false);"
16854  [(set_attr "type" "fistp")
16855   (set_attr "i387_cw" "<rounding>")
16856   (set_attr "mode" "DI")])
16857
16858(define_insn "fistdi2_<rounding>_with_temp"
16859  [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16860	(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16861		   FIST_ROUNDING))
16862   (use (match_operand:HI 2 "memory_operand" "m,m"))
16863   (use (match_operand:HI 3 "memory_operand" "m,m"))
16864   (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16865   (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16866  "TARGET_USE_FANCY_MATH_387
16867   && flag_unsafe_math_optimizations"
16868  "#"
16869  [(set_attr "type" "fistp")
16870   (set_attr "i387_cw" "<rounding>")
16871   (set_attr "mode" "DI")])
16872
16873(define_split
16874  [(set (match_operand:DI 0 "register_operand")
16875	(unspec:DI [(match_operand:XF 1 "register_operand")]
16876		   FIST_ROUNDING))
16877   (use (match_operand:HI 2 "memory_operand"))
16878   (use (match_operand:HI 3 "memory_operand"))
16879   (clobber (match_operand:DI 4 "memory_operand"))
16880   (clobber (match_scratch 5))]
16881  "reload_completed"
16882  [(parallel [(set (match_dup 4)
16883		   (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16884	      (use (match_dup 2))
16885	      (use (match_dup 3))
16886	      (clobber (match_dup 5))])
16887   (set (match_dup 0) (match_dup 4))])
16888
16889(define_split
16890  [(set (match_operand:DI 0 "memory_operand")
16891	(unspec:DI [(match_operand:XF 1 "register_operand")]
16892		   FIST_ROUNDING))
16893   (use (match_operand:HI 2 "memory_operand"))
16894   (use (match_operand:HI 3 "memory_operand"))
16895   (clobber (match_operand:DI 4 "memory_operand"))
16896   (clobber (match_scratch 5))]
16897  "reload_completed"
16898  [(parallel [(set (match_dup 0)
16899		   (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16900	      (use (match_dup 2))
16901	      (use (match_dup 3))
16902	      (clobber (match_dup 5))])])
16903
16904(define_insn "fist<mode>2_<rounding>"
16905  [(set (match_operand:SWI24 0 "memory_operand" "=m")
16906	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16907		      FIST_ROUNDING))
16908   (use (match_operand:HI 2 "memory_operand" "m"))
16909   (use (match_operand:HI 3 "memory_operand" "m"))]
16910  "TARGET_USE_FANCY_MATH_387
16911   && flag_unsafe_math_optimizations"
16912  "* return output_fix_trunc (insn, operands, false);"
16913  [(set_attr "type" "fistp")
16914   (set_attr "i387_cw" "<rounding>")
16915   (set_attr "mode" "<MODE>")])
16916
16917(define_insn "fist<mode>2_<rounding>_with_temp"
16918  [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16919	(unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16920		      FIST_ROUNDING))
16921   (use (match_operand:HI 2 "memory_operand" "m,m"))
16922   (use (match_operand:HI 3 "memory_operand" "m,m"))
16923   (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16924  "TARGET_USE_FANCY_MATH_387
16925   && flag_unsafe_math_optimizations"
16926  "#"
16927  [(set_attr "type" "fistp")
16928   (set_attr "i387_cw" "<rounding>")
16929   (set_attr "mode" "<MODE>")])
16930
16931(define_split
16932  [(set (match_operand:SWI24 0 "register_operand")
16933	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16934		      FIST_ROUNDING))
16935   (use (match_operand:HI 2 "memory_operand"))
16936   (use (match_operand:HI 3 "memory_operand"))
16937   (clobber (match_operand:SWI24 4 "memory_operand"))]
16938  "reload_completed"
16939  [(parallel [(set (match_dup 4)
16940		   (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16941	      (use (match_dup 2))
16942	      (use (match_dup 3))])
16943   (set (match_dup 0) (match_dup 4))])
16944
16945(define_split
16946  [(set (match_operand:SWI24 0 "memory_operand")
16947	(unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16948		      FIST_ROUNDING))
16949   (use (match_operand:HI 2 "memory_operand"))
16950   (use (match_operand:HI 3 "memory_operand"))
16951   (clobber (match_operand:SWI24 4 "memory_operand"))]
16952  "reload_completed"
16953  [(parallel [(set (match_dup 0)
16954		   (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16955	      (use (match_dup 2))
16956	      (use (match_dup 3))])])
16957
16958(define_expand "l<rounding_insn>xf<mode>2"
16959  [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16960		   (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16961				   FIST_ROUNDING))
16962	      (clobber (reg:CC FLAGS_REG))])]
16963  "TARGET_USE_FANCY_MATH_387
16964   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16965   && flag_unsafe_math_optimizations")
16966
16967(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16968  [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16969		   (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16970				 FIST_ROUNDING))
16971	      (clobber (reg:CC FLAGS_REG))])]
16972  "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16973   && (TARGET_SSE4_1 || !flag_trapping_math)"
16974{
16975  if (TARGET_SSE4_1)
16976    {
16977      rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16978
16979      emit_insn (gen_sse4_1_round<mode>2
16980		 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16981					     | ROUND_NO_EXC)));
16982      emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16983		 (operands[0], tmp));
16984    }
16985  else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16986    ix86_expand_lfloorceil (operands[0], operands[1], true);
16987  else if (ROUND_<ROUNDING> == ROUND_CEIL)
16988    ix86_expand_lfloorceil (operands[0], operands[1], false);
16989  else
16990    gcc_unreachable ();
16991
16992  DONE;
16993})
16994
16995(define_insn "fxam<mode>2_i387"
16996  [(set (match_operand:HI 0 "register_operand" "=a")
16997	(unspec:HI
16998	  [(match_operand:X87MODEF 1 "register_operand" "f")]
16999	  UNSPEC_FXAM))]
17000  "TARGET_USE_FANCY_MATH_387"
17001  "fxam\n\tfnstsw\t%0"
17002  [(set_attr "type" "multi")
17003   (set_attr "length" "4")
17004   (set_attr "unit" "i387")
17005   (set_attr "mode" "<MODE>")])
17006
17007(define_insn_and_split "fxam<mode>2_i387_with_temp"
17008  [(set (match_operand:HI 0 "register_operand")
17009	(unspec:HI
17010	  [(match_operand:MODEF 1 "memory_operand")]
17011	  UNSPEC_FXAM_MEM))]
17012  "TARGET_USE_FANCY_MATH_387
17013   && can_create_pseudo_p ()"
17014  "#"
17015  "&& 1"
17016  [(set (match_dup 2)(match_dup 1))
17017   (set (match_dup 0)
17018	(unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17019{
17020  operands[2] = gen_reg_rtx (<MODE>mode);
17021
17022  MEM_VOLATILE_P (operands[1]) = 1;
17023}
17024  [(set_attr "type" "multi")
17025   (set_attr "unit" "i387")
17026   (set_attr "mode" "<MODE>")])
17027
17028(define_expand "isinfxf2"
17029  [(use (match_operand:SI 0 "register_operand"))
17030   (use (match_operand:XF 1 "register_operand"))]
17031  "TARGET_USE_FANCY_MATH_387
17032   && ix86_libc_has_function (function_c99_misc)"
17033{
17034  rtx mask = GEN_INT (0x45);
17035  rtx val = GEN_INT (0x05);
17036
17037  rtx scratch = gen_reg_rtx (HImode);
17038  rtx res = gen_reg_rtx (QImode);
17039
17040  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17041
17042  emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17043  emit_insn (gen_cmpqi_ext_3 (scratch, val));
17044  ix86_expand_setcc (res, EQ,
17045		     gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17046  emit_insn (gen_zero_extendqisi2 (operands[0], res));
17047  DONE;
17048})
17049
17050(define_expand "isinf<mode>2"
17051  [(use (match_operand:SI 0 "register_operand"))
17052   (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17053  "TARGET_USE_FANCY_MATH_387
17054   && ix86_libc_has_function (function_c99_misc)
17055   && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17056{
17057  rtx mask = GEN_INT (0x45);
17058  rtx val = GEN_INT (0x05);
17059
17060  rtx scratch = gen_reg_rtx (HImode);
17061  rtx res = gen_reg_rtx (QImode);
17062
17063  /* Remove excess precision by forcing value through memory. */
17064  if (memory_operand (operands[1], VOIDmode))
17065    emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17066  else
17067    {
17068      rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17069
17070      emit_move_insn (temp, operands[1]);
17071      emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17072    }
17073
17074  emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17075  emit_insn (gen_cmpqi_ext_3 (scratch, val));
17076  ix86_expand_setcc (res, EQ,
17077		     gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17078  emit_insn (gen_zero_extendqisi2 (operands[0], res));
17079  DONE;
17080})
17081
17082(define_expand "signbittf2"
17083  [(use (match_operand:SI 0 "register_operand"))
17084   (use (match_operand:TF 1 "register_operand"))]
17085  "TARGET_SSE"
17086{
17087  if (TARGET_SSE4_1)
17088    {
17089      rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17090      rtx scratch = gen_reg_rtx (QImode);
17091
17092      emit_insn (gen_ptesttf2 (operands[1], mask));
17093	ix86_expand_setcc (scratch, NE,
17094			   gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17095
17096      emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17097    }
17098  else
17099    {
17100      emit_insn (gen_sse_movmskps (operands[0],
17101				   gen_lowpart (V4SFmode, operands[1])));
17102      emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17103    }
17104  DONE;
17105})
17106
17107(define_expand "signbitxf2"
17108  [(use (match_operand:SI 0 "register_operand"))
17109   (use (match_operand:XF 1 "register_operand"))]
17110  "TARGET_USE_FANCY_MATH_387"
17111{
17112  rtx scratch = gen_reg_rtx (HImode);
17113
17114  emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17115  emit_insn (gen_andsi3 (operands[0],
17116	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17117  DONE;
17118})
17119
17120(define_insn "movmsk_df"
17121  [(set (match_operand:SI 0 "register_operand" "=r")
17122	(unspec:SI
17123	  [(match_operand:DF 1 "register_operand" "x")]
17124	  UNSPEC_MOVMSK))]
17125  "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17126  "%vmovmskpd\t{%1, %0|%0, %1}"
17127  [(set_attr "type" "ssemov")
17128   (set_attr "prefix" "maybe_vex")
17129   (set_attr "mode" "DF")])
17130
17131;; Use movmskpd in SSE mode to avoid store forwarding stall
17132;; for 32bit targets and movq+shrq sequence for 64bit targets.
17133(define_expand "signbitdf2"
17134  [(use (match_operand:SI 0 "register_operand"))
17135   (use (match_operand:DF 1 "register_operand"))]
17136  "TARGET_USE_FANCY_MATH_387
17137   || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17138{
17139  if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17140    {
17141      emit_insn (gen_movmsk_df (operands[0], operands[1]));
17142      emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17143    }
17144  else
17145    {
17146      rtx scratch = gen_reg_rtx (HImode);
17147
17148      emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17149      emit_insn (gen_andsi3 (operands[0],
17150		 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17151    }
17152  DONE;
17153})
17154
17155(define_expand "signbitsf2"
17156  [(use (match_operand:SI 0 "register_operand"))
17157   (use (match_operand:SF 1 "register_operand"))]
17158  "TARGET_USE_FANCY_MATH_387
17159   && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17160{
17161  rtx scratch = gen_reg_rtx (HImode);
17162
17163  emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17164  emit_insn (gen_andsi3 (operands[0],
17165	     gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17166  DONE;
17167})
17168
17169;; Block operation instructions
17170
17171(define_insn "cld"
17172  [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17173  ""
17174  "cld"
17175  [(set_attr "length" "1")
17176   (set_attr "length_immediate" "0")
17177   (set_attr "modrm" "0")])
17178
17179(define_expand "movmem<mode>"
17180  [(use (match_operand:BLK 0 "memory_operand"))
17181   (use (match_operand:BLK 1 "memory_operand"))
17182   (use (match_operand:SWI48 2 "nonmemory_operand"))
17183   (use (match_operand:SWI48 3 "const_int_operand"))
17184   (use (match_operand:SI 4 "const_int_operand"))
17185   (use (match_operand:SI 5 "const_int_operand"))
17186   (use (match_operand:SI 6 ""))
17187   (use (match_operand:SI 7 ""))
17188   (use (match_operand:SI 8 ""))]
17189  ""
17190{
17191 if (ix86_expand_set_or_movmem (operands[0], operands[1],
17192			        operands[2], NULL, operands[3],
17193			        operands[4], operands[5],
17194				operands[6], operands[7],
17195				operands[8], false))
17196   DONE;
17197 else
17198   FAIL;
17199})
17200
17201;; Most CPUs don't like single string operations
17202;; Handle this case here to simplify previous expander.
17203
17204(define_expand "strmov"
17205  [(set (match_dup 4) (match_operand 3 "memory_operand"))
17206   (set (match_operand 1 "memory_operand") (match_dup 4))
17207   (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17208	      (clobber (reg:CC FLAGS_REG))])
17209   (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17210	      (clobber (reg:CC FLAGS_REG))])]
17211  ""
17212{
17213  /* Can't use this for non-default address spaces.  */
17214  if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17215    FAIL;
17216
17217  rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17218
17219  /* If .md ever supports :P for Pmode, these can be directly
17220     in the pattern above.  */
17221  operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17222  operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17223
17224  /* Can't use this if the user has appropriated esi or edi.  */
17225  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17226      && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17227    {
17228      emit_insn (gen_strmov_singleop (operands[0], operands[1],
17229				      operands[2], operands[3],
17230				      operands[5], operands[6]));
17231      DONE;
17232    }
17233
17234  operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17235})
17236
17237(define_expand "strmov_singleop"
17238  [(parallel [(set (match_operand 1 "memory_operand")
17239		   (match_operand 3 "memory_operand"))
17240	      (set (match_operand 0 "register_operand")
17241		   (match_operand 4))
17242	      (set (match_operand 2 "register_operand")
17243		   (match_operand 5))])]
17244  ""
17245{
17246  if (TARGET_CLD)
17247    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17248})
17249
17250(define_insn "*strmovdi_rex_1"
17251  [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17252	(mem:DI (match_operand:P 3 "register_operand" "1")))
17253   (set (match_operand:P 0 "register_operand" "=D")
17254	(plus:P (match_dup 2)
17255		(const_int 8)))
17256   (set (match_operand:P 1 "register_operand" "=S")
17257	(plus:P (match_dup 3)
17258		(const_int 8)))]
17259  "TARGET_64BIT
17260   && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17261   && ix86_check_no_addr_space (insn)"
17262  "%^movsq"
17263  [(set_attr "type" "str")
17264   (set_attr "memory" "both")
17265   (set_attr "mode" "DI")])
17266
17267(define_insn "*strmovsi_1"
17268  [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17269	(mem:SI (match_operand:P 3 "register_operand" "1")))
17270   (set (match_operand:P 0 "register_operand" "=D")
17271	(plus:P (match_dup 2)
17272		(const_int 4)))
17273   (set (match_operand:P 1 "register_operand" "=S")
17274	(plus:P (match_dup 3)
17275		(const_int 4)))]
17276  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17277   && ix86_check_no_addr_space (insn)"
17278  "%^movs{l|d}"
17279  [(set_attr "type" "str")
17280   (set_attr "memory" "both")
17281   (set_attr "mode" "SI")])
17282
17283(define_insn "*strmovhi_1"
17284  [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17285	(mem:HI (match_operand:P 3 "register_operand" "1")))
17286   (set (match_operand:P 0 "register_operand" "=D")
17287	(plus:P (match_dup 2)
17288		(const_int 2)))
17289   (set (match_operand:P 1 "register_operand" "=S")
17290	(plus:P (match_dup 3)
17291		(const_int 2)))]
17292  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17293   && ix86_check_no_addr_space (insn)"
17294  "%^movsw"
17295  [(set_attr "type" "str")
17296   (set_attr "memory" "both")
17297   (set_attr "mode" "HI")])
17298
17299(define_insn "*strmovqi_1"
17300  [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17301	(mem:QI (match_operand:P 3 "register_operand" "1")))
17302   (set (match_operand:P 0 "register_operand" "=D")
17303	(plus:P (match_dup 2)
17304		(const_int 1)))
17305   (set (match_operand:P 1 "register_operand" "=S")
17306	(plus:P (match_dup 3)
17307		(const_int 1)))]
17308  "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17309   && ix86_check_no_addr_space (insn)"
17310  "%^movsb"
17311  [(set_attr "type" "str")
17312   (set_attr "memory" "both")
17313   (set (attr "prefix_rex")
17314	(if_then_else
17315	  (match_test "<P:MODE>mode == DImode")
17316	  (const_string "0")
17317	  (const_string "*")))
17318   (set_attr "mode" "QI")])
17319
17320(define_expand "rep_mov"
17321  [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17322	      (set (match_operand 0 "register_operand")
17323		   (match_operand 5))
17324	      (set (match_operand 2 "register_operand")
17325		   (match_operand 6))
17326	      (set (match_operand 1 "memory_operand")
17327		   (match_operand 3 "memory_operand"))
17328	      (use (match_dup 4))])]
17329  ""
17330{
17331  if (TARGET_CLD)
17332    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17333})
17334
17335(define_insn "*rep_movdi_rex64"
17336  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17337   (set (match_operand:P 0 "register_operand" "=D")
17338        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17339			  (const_int 3))
17340		(match_operand:P 3 "register_operand" "0")))
17341   (set (match_operand:P 1 "register_operand" "=S")
17342        (plus:P (ashift:P (match_dup 5) (const_int 3))
17343		(match_operand:P 4 "register_operand" "1")))
17344   (set (mem:BLK (match_dup 3))
17345	(mem:BLK (match_dup 4)))
17346   (use (match_dup 5))]
17347  "TARGET_64BIT
17348   && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17349   && ix86_check_no_addr_space (insn)"
17350  "%^rep{%;} movsq"
17351  [(set_attr "type" "str")
17352   (set_attr "prefix_rep" "1")
17353   (set_attr "memory" "both")
17354   (set_attr "mode" "DI")])
17355
17356(define_insn "*rep_movsi"
17357  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17358   (set (match_operand:P 0 "register_operand" "=D")
17359        (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17360			  (const_int 2))
17361		 (match_operand:P 3 "register_operand" "0")))
17362   (set (match_operand:P 1 "register_operand" "=S")
17363        (plus:P (ashift:P (match_dup 5) (const_int 2))
17364		(match_operand:P 4 "register_operand" "1")))
17365   (set (mem:BLK (match_dup 3))
17366	(mem:BLK (match_dup 4)))
17367   (use (match_dup 5))]
17368  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17369   && ix86_check_no_addr_space (insn)"
17370  "%^rep{%;} movs{l|d}"
17371  [(set_attr "type" "str")
17372   (set_attr "prefix_rep" "1")
17373   (set_attr "memory" "both")
17374   (set_attr "mode" "SI")])
17375
17376(define_insn "*rep_movqi"
17377  [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17378   (set (match_operand:P 0 "register_operand" "=D")
17379        (plus:P (match_operand:P 3 "register_operand" "0")
17380		(match_operand:P 5 "register_operand" "2")))
17381   (set (match_operand:P 1 "register_operand" "=S")
17382        (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17383   (set (mem:BLK (match_dup 3))
17384	(mem:BLK (match_dup 4)))
17385   (use (match_dup 5))]
17386  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17387   && ix86_check_no_addr_space (insn)"
17388  "%^rep{%;} movsb"
17389  [(set_attr "type" "str")
17390   (set_attr "prefix_rep" "1")
17391   (set_attr "memory" "both")
17392   (set_attr "mode" "QI")])
17393
17394(define_expand "setmem<mode>"
17395   [(use (match_operand:BLK 0 "memory_operand"))
17396    (use (match_operand:SWI48 1 "nonmemory_operand"))
17397    (use (match_operand:QI 2 "nonmemory_operand"))
17398    (use (match_operand 3 "const_int_operand"))
17399    (use (match_operand:SI 4 "const_int_operand"))
17400    (use (match_operand:SI 5 "const_int_operand"))
17401    (use (match_operand:SI 6 ""))
17402    (use (match_operand:SI 7 ""))
17403    (use (match_operand:SI 8 ""))]
17404  ""
17405{
17406 if (ix86_expand_set_or_movmem (operands[0], NULL,
17407			        operands[1], operands[2],
17408				operands[3], operands[4],
17409			        operands[5], operands[6],
17410				operands[7], operands[8], true))
17411   DONE;
17412 else
17413   FAIL;
17414})
17415
17416;; Most CPUs don't like single string operations
17417;; Handle this case here to simplify previous expander.
17418
17419(define_expand "strset"
17420  [(set (match_operand 1 "memory_operand")
17421	(match_operand 2 "register_operand"))
17422   (parallel [(set (match_operand 0 "register_operand")
17423		   (match_dup 3))
17424	      (clobber (reg:CC FLAGS_REG))])]
17425  ""
17426{
17427  /* Can't use this for non-default address spaces.  */
17428  if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17429    FAIL;
17430
17431  if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17432    operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17433
17434  /* If .md ever supports :P for Pmode, this can be directly
17435     in the pattern above.  */
17436  operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17437			      GEN_INT (GET_MODE_SIZE (GET_MODE
17438						      (operands[2]))));
17439  /* Can't use this if the user has appropriated eax or edi.  */
17440  if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17441      && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17442    {
17443      emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17444				      operands[3]));
17445      DONE;
17446    }
17447})
17448
17449(define_expand "strset_singleop"
17450  [(parallel [(set (match_operand 1 "memory_operand")
17451		   (match_operand 2 "register_operand"))
17452	      (set (match_operand 0 "register_operand")
17453		   (match_operand 3))
17454	      (unspec [(const_int 0)] UNSPEC_STOS)])]
17455  ""
17456{
17457  if (TARGET_CLD)
17458    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17459})
17460
17461(define_insn "*strsetdi_rex_1"
17462  [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17463	(match_operand:DI 2 "register_operand" "a"))
17464   (set (match_operand:P 0 "register_operand" "=D")
17465	(plus:P (match_dup 1)
17466		(const_int 8)))
17467   (unspec [(const_int 0)] UNSPEC_STOS)]
17468  "TARGET_64BIT
17469   && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17470   && ix86_check_no_addr_space (insn)"
17471  "%^stosq"
17472  [(set_attr "type" "str")
17473   (set_attr "memory" "store")
17474   (set_attr "mode" "DI")])
17475
17476(define_insn "*strsetsi_1"
17477  [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17478	(match_operand:SI 2 "register_operand" "a"))
17479   (set (match_operand:P 0 "register_operand" "=D")
17480	(plus:P (match_dup 1)
17481		(const_int 4)))
17482   (unspec [(const_int 0)] UNSPEC_STOS)]
17483  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17484   && ix86_check_no_addr_space (insn)"
17485  "%^stos{l|d}"
17486  [(set_attr "type" "str")
17487   (set_attr "memory" "store")
17488   (set_attr "mode" "SI")])
17489
17490(define_insn "*strsethi_1"
17491  [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17492	(match_operand:HI 2 "register_operand" "a"))
17493   (set (match_operand:P 0 "register_operand" "=D")
17494	(plus:P (match_dup 1)
17495		(const_int 2)))
17496   (unspec [(const_int 0)] UNSPEC_STOS)]
17497  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17498   && ix86_check_no_addr_space (insn)"
17499  "%^stosw"
17500  [(set_attr "type" "str")
17501   (set_attr "memory" "store")
17502   (set_attr "mode" "HI")])
17503
17504(define_insn "*strsetqi_1"
17505  [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17506	(match_operand:QI 2 "register_operand" "a"))
17507   (set (match_operand:P 0 "register_operand" "=D")
17508	(plus:P (match_dup 1)
17509		(const_int 1)))
17510   (unspec [(const_int 0)] UNSPEC_STOS)]
17511  "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17512   && ix86_check_no_addr_space (insn)"
17513  "%^stosb"
17514  [(set_attr "type" "str")
17515   (set_attr "memory" "store")
17516   (set (attr "prefix_rex")
17517	(if_then_else
17518	  (match_test "<P:MODE>mode == DImode")
17519	  (const_string "0")
17520	  (const_string "*")))
17521   (set_attr "mode" "QI")])
17522
17523(define_expand "rep_stos"
17524  [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17525	      (set (match_operand 0 "register_operand")
17526		   (match_operand 4))
17527	      (set (match_operand 2 "memory_operand") (const_int 0))
17528	      (use (match_operand 3 "register_operand"))
17529	      (use (match_dup 1))])]
17530  ""
17531{
17532  if (TARGET_CLD)
17533    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17534})
17535
17536(define_insn "*rep_stosdi_rex64"
17537  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17538   (set (match_operand:P 0 "register_operand" "=D")
17539        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17540			  (const_int 3))
17541		 (match_operand:P 3 "register_operand" "0")))
17542   (set (mem:BLK (match_dup 3))
17543	(const_int 0))
17544   (use (match_operand:DI 2 "register_operand" "a"))
17545   (use (match_dup 4))]
17546  "TARGET_64BIT
17547   && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17548   && ix86_check_no_addr_space (insn)"
17549  "%^rep{%;} stosq"
17550  [(set_attr "type" "str")
17551   (set_attr "prefix_rep" "1")
17552   (set_attr "memory" "store")
17553   (set_attr "mode" "DI")])
17554
17555(define_insn "*rep_stossi"
17556  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17557   (set (match_operand:P 0 "register_operand" "=D")
17558        (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17559			  (const_int 2))
17560		 (match_operand:P 3 "register_operand" "0")))
17561   (set (mem:BLK (match_dup 3))
17562	(const_int 0))
17563   (use (match_operand:SI 2 "register_operand" "a"))
17564   (use (match_dup 4))]
17565  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17566   && ix86_check_no_addr_space (insn)"
17567  "%^rep{%;} stos{l|d}"
17568  [(set_attr "type" "str")
17569   (set_attr "prefix_rep" "1")
17570   (set_attr "memory" "store")
17571   (set_attr "mode" "SI")])
17572
17573(define_insn "*rep_stosqi"
17574  [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17575   (set (match_operand:P 0 "register_operand" "=D")
17576        (plus:P (match_operand:P 3 "register_operand" "0")
17577		(match_operand:P 4 "register_operand" "1")))
17578   (set (mem:BLK (match_dup 3))
17579	(const_int 0))
17580   (use (match_operand:QI 2 "register_operand" "a"))
17581   (use (match_dup 4))]
17582  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17583   && ix86_check_no_addr_space (insn)"
17584  "%^rep{%;} stosb"
17585  [(set_attr "type" "str")
17586   (set_attr "prefix_rep" "1")
17587   (set_attr "memory" "store")
17588   (set (attr "prefix_rex")
17589	(if_then_else
17590	  (match_test "<P:MODE>mode == DImode")
17591	  (const_string "0")
17592	  (const_string "*")))
17593   (set_attr "mode" "QI")])
17594
17595(define_expand "cmpstrnsi"
17596  [(set (match_operand:SI 0 "register_operand")
17597	(compare:SI (match_operand:BLK 1 "general_operand")
17598		    (match_operand:BLK 2 "general_operand")))
17599   (use (match_operand 3 "general_operand"))
17600   (use (match_operand 4 "immediate_operand"))]
17601  ""
17602{
17603  rtx addr1, addr2, out, outlow, count, countreg, align;
17604
17605  if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17606    FAIL;
17607
17608  /* Can't use this if the user has appropriated ecx, esi or edi.  */
17609  if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17610    FAIL;
17611
17612  /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
17613     will have rewritten the length arg to be the minimum of the const string
17614     length and the actual length arg.  If both strings are the same and
17615     shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17616     will incorrectly base the results on chars past the 0 byte.  */
17617  tree t1 = MEM_EXPR (operands[1]);
17618  tree t2 = MEM_EXPR (operands[2]);
17619  if (!((t1 && TREE_CODE (t1) == MEM_REF
17620         && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17621         && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17622      || (t2 && TREE_CODE (t2) == MEM_REF
17623          && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17624          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17625    FAIL;
17626
17627  out = operands[0];
17628  if (!REG_P (out))
17629    out = gen_reg_rtx (SImode);
17630
17631  addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17632  addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17633  if (addr1 != XEXP (operands[1], 0))
17634    operands[1] = replace_equiv_address_nv (operands[1], addr1);
17635  if (addr2 != XEXP (operands[2], 0))
17636    operands[2] = replace_equiv_address_nv (operands[2], addr2);
17637
17638  count = operands[3];
17639  countreg = ix86_zero_extend_to_Pmode (count);
17640
17641  /* %%% Iff we are testing strict equality, we can use known alignment
17642     to good advantage.  This may be possible with combine, particularly
17643     once cc0 is dead.  */
17644  align = operands[4];
17645
17646  if (CONST_INT_P (count))
17647    {
17648      if (INTVAL (count) == 0)
17649	{
17650	  emit_move_insn (operands[0], const0_rtx);
17651	  DONE;
17652	}
17653      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17654				     operands[1], operands[2]));
17655    }
17656  else
17657    {
17658      rtx (*gen_cmp) (rtx, rtx);
17659
17660      gen_cmp = (TARGET_64BIT
17661		 ? gen_cmpdi_1 : gen_cmpsi_1);
17662
17663      emit_insn (gen_cmp (countreg, countreg));
17664      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17665				  operands[1], operands[2]));
17666    }
17667
17668  outlow = gen_lowpart (QImode, out);
17669  emit_insn (gen_cmpintqi (outlow));
17670  emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17671
17672  if (operands[0] != out)
17673    emit_move_insn (operands[0], out);
17674
17675  DONE;
17676})
17677
17678;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17679
17680(define_expand "cmpintqi"
17681  [(set (match_dup 1)
17682	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17683   (set (match_dup 2)
17684	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17685   (parallel [(set (match_operand:QI 0 "register_operand")
17686		   (minus:QI (match_dup 1)
17687			     (match_dup 2)))
17688	      (clobber (reg:CC FLAGS_REG))])]
17689  ""
17690{
17691  operands[1] = gen_reg_rtx (QImode);
17692  operands[2] = gen_reg_rtx (QImode);
17693})
17694
17695;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17696;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17697
17698(define_expand "cmpstrnqi_nz_1"
17699  [(parallel [(set (reg:CC FLAGS_REG)
17700		   (compare:CC (match_operand 4 "memory_operand")
17701			       (match_operand 5 "memory_operand")))
17702	      (use (match_operand 2 "register_operand"))
17703	      (use (match_operand:SI 3 "immediate_operand"))
17704	      (clobber (match_operand 0 "register_operand"))
17705	      (clobber (match_operand 1 "register_operand"))
17706	      (clobber (match_dup 2))])]
17707  ""
17708{
17709  if (TARGET_CLD)
17710    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17711})
17712
17713(define_insn "*cmpstrnqi_nz_1"
17714  [(set (reg:CC FLAGS_REG)
17715	(compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17716		    (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17717   (use (match_operand:P 6 "register_operand" "2"))
17718   (use (match_operand:SI 3 "immediate_operand" "i"))
17719   (clobber (match_operand:P 0 "register_operand" "=S"))
17720   (clobber (match_operand:P 1 "register_operand" "=D"))
17721   (clobber (match_operand:P 2 "register_operand" "=c"))]
17722  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17723   && ix86_check_no_addr_space (insn)"
17724  "%^repz{%;} cmpsb"
17725  [(set_attr "type" "str")
17726   (set_attr "mode" "QI")
17727   (set (attr "prefix_rex")
17728	(if_then_else
17729	  (match_test "<P:MODE>mode == DImode")
17730	  (const_string "0")
17731	  (const_string "*")))
17732   (set_attr "prefix_rep" "1")])
17733
17734;; The same, but the count is not known to not be zero.
17735
17736(define_expand "cmpstrnqi_1"
17737  [(parallel [(set (reg:CC FLAGS_REG)
17738		(if_then_else:CC (ne (match_operand 2 "register_operand")
17739				     (const_int 0))
17740		  (compare:CC (match_operand 4 "memory_operand")
17741			      (match_operand 5 "memory_operand"))
17742		  (const_int 0)))
17743	      (use (match_operand:SI 3 "immediate_operand"))
17744	      (use (reg:CC FLAGS_REG))
17745	      (clobber (match_operand 0 "register_operand"))
17746	      (clobber (match_operand 1 "register_operand"))
17747	      (clobber (match_dup 2))])]
17748  ""
17749{
17750  if (TARGET_CLD)
17751    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17752})
17753
17754(define_insn "*cmpstrnqi_1"
17755  [(set (reg:CC FLAGS_REG)
17756	(if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17757			     (const_int 0))
17758	  (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17759		      (mem:BLK (match_operand:P 5 "register_operand" "1")))
17760	  (const_int 0)))
17761   (use (match_operand:SI 3 "immediate_operand" "i"))
17762   (use (reg:CC FLAGS_REG))
17763   (clobber (match_operand:P 0 "register_operand" "=S"))
17764   (clobber (match_operand:P 1 "register_operand" "=D"))
17765   (clobber (match_operand:P 2 "register_operand" "=c"))]
17766  "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17767   && ix86_check_no_addr_space (insn)"
17768  "%^repz{%;} cmpsb"
17769  [(set_attr "type" "str")
17770   (set_attr "mode" "QI")
17771   (set (attr "prefix_rex")
17772	(if_then_else
17773	  (match_test "<P:MODE>mode == DImode")
17774	  (const_string "0")
17775	  (const_string "*")))
17776   (set_attr "prefix_rep" "1")])
17777
17778(define_expand "strlen<mode>"
17779  [(set (match_operand:P 0 "register_operand")
17780	(unspec:P [(match_operand:BLK 1 "general_operand")
17781		   (match_operand:QI 2 "immediate_operand")
17782		   (match_operand 3 "immediate_operand")]
17783		  UNSPEC_SCAS))]
17784  ""
17785{
17786 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17787   DONE;
17788 else
17789   FAIL;
17790})
17791
17792(define_expand "strlenqi_1"
17793  [(parallel [(set (match_operand 0 "register_operand")
17794		   (match_operand 2))
17795	      (clobber (match_operand 1 "register_operand"))
17796	      (clobber (reg:CC FLAGS_REG))])]
17797  ""
17798{
17799  if (TARGET_CLD)
17800    ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17801})
17802
17803(define_insn "*strlenqi_1"
17804  [(set (match_operand:P 0 "register_operand" "=&c")
17805	(unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17806		   (match_operand:QI 2 "register_operand" "a")
17807		   (match_operand:P 3 "immediate_operand" "i")
17808		   (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17809   (clobber (match_operand:P 1 "register_operand" "=D"))
17810   (clobber (reg:CC FLAGS_REG))]
17811  "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17812   && ix86_check_no_addr_space (insn)"
17813  "%^repnz{%;} scasb"
17814  [(set_attr "type" "str")
17815   (set_attr "mode" "QI")
17816   (set (attr "prefix_rex")
17817	(if_then_else
17818	  (match_test "<P:MODE>mode == DImode")
17819	  (const_string "0")
17820	  (const_string "*")))
17821   (set_attr "prefix_rep" "1")])
17822
17823;; Peephole optimizations to clean up after cmpstrn*.  This should be
17824;; handled in combine, but it is not currently up to the task.
17825;; When used for their truth value, the cmpstrn* expanders generate
17826;; code like this:
17827;;
17828;;   repz cmpsb
17829;;   seta 	%al
17830;;   setb 	%dl
17831;;   cmpb 	%al, %dl
17832;;   jcc	label
17833;;
17834;; The intermediate three instructions are unnecessary.
17835
17836;; This one handles cmpstrn*_nz_1...
17837(define_peephole2
17838  [(parallel[
17839     (set (reg:CC FLAGS_REG)
17840	  (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17841		      (mem:BLK (match_operand 5 "register_operand"))))
17842     (use (match_operand 6 "register_operand"))
17843     (use (match_operand:SI 3 "immediate_operand"))
17844     (clobber (match_operand 0 "register_operand"))
17845     (clobber (match_operand 1 "register_operand"))
17846     (clobber (match_operand 2 "register_operand"))])
17847   (set (match_operand:QI 7 "register_operand")
17848	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17849   (set (match_operand:QI 8 "register_operand")
17850	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17851   (set (reg FLAGS_REG)
17852	(compare (match_dup 7) (match_dup 8)))
17853  ]
17854  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17855  [(parallel[
17856     (set (reg:CC FLAGS_REG)
17857	  (compare:CC (mem:BLK (match_dup 4))
17858		      (mem:BLK (match_dup 5))))
17859     (use (match_dup 6))
17860     (use (match_dup 3))
17861     (clobber (match_dup 0))
17862     (clobber (match_dup 1))
17863     (clobber (match_dup 2))])])
17864
17865;; ...and this one handles cmpstrn*_1.
17866(define_peephole2
17867  [(parallel[
17868     (set (reg:CC FLAGS_REG)
17869	  (if_then_else:CC (ne (match_operand 6 "register_operand")
17870			       (const_int 0))
17871	    (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17872		        (mem:BLK (match_operand 5 "register_operand")))
17873	    (const_int 0)))
17874     (use (match_operand:SI 3 "immediate_operand"))
17875     (use (reg:CC FLAGS_REG))
17876     (clobber (match_operand 0 "register_operand"))
17877     (clobber (match_operand 1 "register_operand"))
17878     (clobber (match_operand 2 "register_operand"))])
17879   (set (match_operand:QI 7 "register_operand")
17880	(gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17881   (set (match_operand:QI 8 "register_operand")
17882	(ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17883   (set (reg FLAGS_REG)
17884	(compare (match_dup 7) (match_dup 8)))
17885  ]
17886  "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17887  [(parallel[
17888     (set (reg:CC FLAGS_REG)
17889	  (if_then_else:CC (ne (match_dup 6)
17890			       (const_int 0))
17891	    (compare:CC (mem:BLK (match_dup 4))
17892			(mem:BLK (match_dup 5)))
17893	    (const_int 0)))
17894     (use (match_dup 3))
17895     (use (reg:CC FLAGS_REG))
17896     (clobber (match_dup 0))
17897     (clobber (match_dup 1))
17898     (clobber (match_dup 2))])])
17899
17900;; Conditional move instructions.
17901
17902(define_expand "mov<mode>cc"
17903  [(set (match_operand:SWIM 0 "register_operand")
17904	(if_then_else:SWIM (match_operand 1 "comparison_operator")
17905			   (match_operand:SWIM 2 "<general_operand>")
17906			   (match_operand:SWIM 3 "<general_operand>")))]
17907  ""
17908  "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17909
17910;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17911;; the register first winds up with `sbbl $0,reg', which is also weird.
17912;; So just document what we're doing explicitly.
17913
17914(define_expand "x86_mov<mode>cc_0_m1"
17915  [(parallel
17916    [(set (match_operand:SWI48 0 "register_operand")
17917	  (if_then_else:SWI48
17918	    (match_operator:SWI48 2 "ix86_carry_flag_operator"
17919	     [(match_operand 1 "flags_reg_operand")
17920	      (const_int 0)])
17921	    (const_int -1)
17922	    (const_int 0)))
17923     (clobber (reg:CC FLAGS_REG))])])
17924
17925(define_insn "*x86_mov<mode>cc_0_m1"
17926  [(set (match_operand:SWI48 0 "register_operand" "=r")
17927	(if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17928			     [(reg FLAGS_REG) (const_int 0)])
17929	  (const_int -1)
17930	  (const_int 0)))
17931   (clobber (reg:CC FLAGS_REG))]
17932  ""
17933  "sbb{<imodesuffix>}\t%0, %0"
17934  ; Since we don't have the proper number of operands for an alu insn,
17935  ; fill in all the blanks.
17936  [(set_attr "type" "alu")
17937   (set_attr "modrm_class" "op0")
17938   (set_attr "use_carry" "1")
17939   (set_attr "pent_pair" "pu")
17940   (set_attr "memory" "none")
17941   (set_attr "imm_disp" "false")
17942   (set_attr "mode" "<MODE>")
17943   (set_attr "length_immediate" "0")])
17944
17945(define_insn "*x86_mov<mode>cc_0_m1_se"
17946  [(set (match_operand:SWI48 0 "register_operand" "=r")
17947	(sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17948			     [(reg FLAGS_REG) (const_int 0)])
17949			    (const_int 1)
17950			    (const_int 0)))
17951   (clobber (reg:CC FLAGS_REG))]
17952  ""
17953  "sbb{<imodesuffix>}\t%0, %0"
17954  [(set_attr "type" "alu")
17955   (set_attr "modrm_class" "op0")
17956   (set_attr "use_carry" "1")
17957   (set_attr "pent_pair" "pu")
17958   (set_attr "memory" "none")
17959   (set_attr "imm_disp" "false")
17960   (set_attr "mode" "<MODE>")
17961   (set_attr "length_immediate" "0")])
17962
17963(define_insn "*x86_mov<mode>cc_0_m1_neg"
17964  [(set (match_operand:SWI48 0 "register_operand" "=r")
17965	(neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17966		    [(reg FLAGS_REG) (const_int 0)])))
17967   (clobber (reg:CC FLAGS_REG))]
17968  ""
17969  "sbb{<imodesuffix>}\t%0, %0"
17970  [(set_attr "type" "alu")
17971   (set_attr "modrm_class" "op0")
17972   (set_attr "use_carry" "1")
17973   (set_attr "pent_pair" "pu")
17974   (set_attr "memory" "none")
17975   (set_attr "imm_disp" "false")
17976   (set_attr "mode" "<MODE>")
17977   (set_attr "length_immediate" "0")])
17978
17979(define_insn "*mov<mode>cc_noc"
17980  [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17981	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17982			       [(reg FLAGS_REG) (const_int 0)])
17983	  (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17984	  (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17985  "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17986  "@
17987   cmov%O2%C1\t{%2, %0|%0, %2}
17988   cmov%O2%c1\t{%3, %0|%0, %3}"
17989  [(set_attr "type" "icmov")
17990   (set_attr "mode" "<MODE>")])
17991
17992(define_insn "*movsicc_noc_zext"
17993  [(set (match_operand:DI 0 "register_operand" "=r,r")
17994	(if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17995			   [(reg FLAGS_REG) (const_int 0)])
17996	  (zero_extend:DI
17997	    (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17998	  (zero_extend:DI
17999	    (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18000  "TARGET_64BIT
18001   && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18002  "@
18003   cmov%O2%C1\t{%2, %k0|%k0, %2}
18004   cmov%O2%c1\t{%3, %k0|%k0, %3}"
18005  [(set_attr "type" "icmov")
18006   (set_attr "mode" "SI")])
18007
18008;; Don't do conditional moves with memory inputs.  This splitter helps
18009;; register starved x86_32 by forcing inputs into registers before reload.
18010(define_split
18011  [(set (match_operand:SWI248 0 "register_operand")
18012	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18013			       [(reg FLAGS_REG) (const_int 0)])
18014	  (match_operand:SWI248 2 "nonimmediate_operand")
18015	  (match_operand:SWI248 3 "nonimmediate_operand")))]
18016  "!TARGET_64BIT && TARGET_CMOVE
18017   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18018   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18019   && can_create_pseudo_p ()
18020   && optimize_insn_for_speed_p ()"
18021  [(set (match_dup 0)
18022	(if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18023{
18024  if (MEM_P (operands[2]))
18025    operands[2] = force_reg (<MODE>mode, operands[2]);
18026  if (MEM_P (operands[3]))
18027    operands[3] = force_reg (<MODE>mode, operands[3]);
18028})
18029
18030(define_insn "*movqicc_noc"
18031  [(set (match_operand:QI 0 "register_operand" "=r,r")
18032	(if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18033			   [(reg FLAGS_REG) (const_int 0)])
18034		      (match_operand:QI 2 "register_operand" "r,0")
18035		      (match_operand:QI 3 "register_operand" "0,r")))]
18036  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18037  "#"
18038  [(set_attr "type" "icmov")
18039   (set_attr "mode" "QI")])
18040
18041(define_split
18042  [(set (match_operand:SWI12 0 "register_operand")
18043	(if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18044			      [(reg FLAGS_REG) (const_int 0)])
18045		      (match_operand:SWI12 2 "register_operand")
18046		      (match_operand:SWI12 3 "register_operand")))]
18047  "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18048   && reload_completed"
18049  [(set (match_dup 0)
18050	(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18051{
18052  operands[0] = gen_lowpart (SImode, operands[0]);
18053  operands[2] = gen_lowpart (SImode, operands[2]);
18054  operands[3] = gen_lowpart (SImode, operands[3]);
18055})
18056
18057;; Don't do conditional moves with memory inputs
18058(define_peephole2
18059  [(match_scratch:SWI248 4 "r")
18060   (set (match_operand:SWI248 0 "register_operand")
18061	(if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18062			       [(reg FLAGS_REG) (const_int 0)])
18063	  (match_operand:SWI248 2 "nonimmediate_operand")
18064	  (match_operand:SWI248 3 "nonimmediate_operand")))]
18065  "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18066   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18067   && optimize_insn_for_speed_p ()"
18068  [(set (match_dup 4) (match_dup 5))
18069   (set (match_dup 0)
18070	(if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18071{
18072  if (MEM_P (operands[2]))
18073    {
18074      operands[5] = operands[2];
18075      operands[2] = operands[4];
18076    }
18077  else if (MEM_P (operands[3]))
18078    {
18079      operands[5] = operands[3];
18080      operands[3] = operands[4];
18081    }
18082  else
18083    gcc_unreachable ();
18084})
18085
18086(define_peephole2
18087  [(match_scratch:SI 4 "r")
18088   (set (match_operand:DI 0 "register_operand")
18089	(if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18090			   [(reg FLAGS_REG) (const_int 0)])
18091	  (zero_extend:DI
18092	    (match_operand:SI 2 "nonimmediate_operand"))
18093	  (zero_extend:DI
18094	    (match_operand:SI 3 "nonimmediate_operand"))))]
18095  "TARGET_64BIT
18096   && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18097   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18098   && optimize_insn_for_speed_p ()"
18099  [(set (match_dup 4) (match_dup 5))
18100   (set (match_dup 0)
18101	(if_then_else:DI (match_dup 1)
18102	  (zero_extend:DI (match_dup 2))
18103	  (zero_extend:DI (match_dup 3))))]
18104{
18105  if (MEM_P (operands[2]))
18106    {
18107      operands[5] = operands[2];
18108      operands[2] = operands[4];
18109    }
18110  else if (MEM_P (operands[3]))
18111    {
18112      operands[5] = operands[3];
18113      operands[3] = operands[4];
18114    }
18115  else
18116    gcc_unreachable ();
18117})
18118
18119(define_expand "mov<mode>cc"
18120  [(set (match_operand:X87MODEF 0 "register_operand")
18121	(if_then_else:X87MODEF
18122	  (match_operand 1 "comparison_operator")
18123	  (match_operand:X87MODEF 2 "register_operand")
18124	  (match_operand:X87MODEF 3 "register_operand")))]
18125  "(TARGET_80387 && TARGET_CMOVE)
18126   || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18127  "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18128
18129(define_insn "*movxfcc_1"
18130  [(set (match_operand:XF 0 "register_operand" "=f,f")
18131	(if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18132				[(reg FLAGS_REG) (const_int 0)])
18133		      (match_operand:XF 2 "register_operand" "f,0")
18134		      (match_operand:XF 3 "register_operand" "0,f")))]
18135  "TARGET_80387 && TARGET_CMOVE"
18136  "@
18137   fcmov%F1\t{%2, %0|%0, %2}
18138   fcmov%f1\t{%3, %0|%0, %3}"
18139  [(set_attr "type" "fcmov")
18140   (set_attr "mode" "XF")])
18141
18142(define_insn "*movdfcc_1"
18143  [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18144	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18145				[(reg FLAGS_REG) (const_int 0)])
18146		      (match_operand:DF 2 "nonimmediate_operand"
18147					       "f ,0,rm,0 ,rm,0")
18148		      (match_operand:DF 3 "nonimmediate_operand"
18149					       "0 ,f,0 ,rm,0, rm")))]
18150  "TARGET_80387 && TARGET_CMOVE
18151   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18152  "@
18153   fcmov%F1\t{%2, %0|%0, %2}
18154   fcmov%f1\t{%3, %0|%0, %3}
18155   #
18156   #
18157   cmov%O2%C1\t{%2, %0|%0, %2}
18158   cmov%O2%c1\t{%3, %0|%0, %3}"
18159  [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18160   (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18161   (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18162
18163(define_split
18164  [(set (match_operand:DF 0 "general_reg_operand")
18165	(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18166				[(reg FLAGS_REG) (const_int 0)])
18167		      (match_operand:DF 2 "nonimmediate_operand")
18168		      (match_operand:DF 3 "nonimmediate_operand")))]
18169  "!TARGET_64BIT && reload_completed"
18170  [(set (match_dup 2)
18171	(if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18172   (set (match_dup 3)
18173	(if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18174{
18175  split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18176  split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18177})
18178
18179(define_insn "*movsfcc_1_387"
18180  [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18181	(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18182				[(reg FLAGS_REG) (const_int 0)])
18183		      (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18184		      (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18185  "TARGET_80387 && TARGET_CMOVE
18186   && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18187  "@
18188   fcmov%F1\t{%2, %0|%0, %2}
18189   fcmov%f1\t{%3, %0|%0, %3}
18190   cmov%O2%C1\t{%2, %0|%0, %2}
18191   cmov%O2%c1\t{%3, %0|%0, %3}"
18192  [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18193   (set_attr "mode" "SF,SF,SI,SI")])
18194
18195;; Don't do conditional moves with memory inputs.  This splitter helps
18196;; register starved x86_32 by forcing inputs into registers before reload.
18197(define_split
18198  [(set (match_operand:MODEF 0 "register_operand")
18199	(if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18200			      [(reg FLAGS_REG) (const_int 0)])
18201	  (match_operand:MODEF 2 "nonimmediate_operand")
18202	  (match_operand:MODEF 3 "nonimmediate_operand")))]
18203  "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18204   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18205   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18206   && can_create_pseudo_p ()
18207   && optimize_insn_for_speed_p ()"
18208  [(set (match_dup 0)
18209	(if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18210{
18211  if (MEM_P (operands[2]))
18212    operands[2] = force_reg (<MODE>mode, operands[2]);
18213  if (MEM_P (operands[3]))
18214    operands[3] = force_reg (<MODE>mode, operands[3]);
18215})
18216
18217;; Don't do conditional moves with memory inputs
18218(define_peephole2
18219  [(match_scratch:MODEF 4 "r")
18220   (set (match_operand:MODEF 0 "general_reg_operand")
18221	(if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18222			      [(reg FLAGS_REG) (const_int 0)])
18223	  (match_operand:MODEF 2 "nonimmediate_operand")
18224	  (match_operand:MODEF 3 "nonimmediate_operand")))]
18225  "(<MODE>mode != DFmode || TARGET_64BIT)
18226   && TARGET_80387 && TARGET_CMOVE
18227   && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18228   && (MEM_P (operands[2]) || MEM_P (operands[3]))
18229   && optimize_insn_for_speed_p ()"
18230  [(set (match_dup 4) (match_dup 5))
18231   (set (match_dup 0)
18232	(if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18233{
18234  if (MEM_P (operands[2]))
18235    {
18236      operands[5] = operands[2];
18237      operands[2] = operands[4];
18238    }
18239  else if (MEM_P (operands[3]))
18240    {
18241      operands[5] = operands[3];
18242      operands[3] = operands[4];
18243    }
18244  else
18245    gcc_unreachable ();
18246})
18247
18248;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18249;; the scalar versions to have only XMM registers as operands.
18250
18251;; XOP conditional move
18252(define_insn "*xop_pcmov_<mode>"
18253  [(set (match_operand:MODEF 0 "register_operand" "=x")
18254	(if_then_else:MODEF
18255	  (match_operand:MODEF 1 "register_operand" "x")
18256	  (match_operand:MODEF 2 "register_operand" "x")
18257	  (match_operand:MODEF 3 "register_operand" "x")))]
18258  "TARGET_XOP"
18259  "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18260  [(set_attr "type" "sse4arg")])
18261
18262;; These versions of the min/max patterns are intentionally ignorant of
18263;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18264;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18265;; are undefined in this condition, we're certain this is correct.
18266
18267(define_insn "<code><mode>3"
18268  [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18269	(smaxmin:MODEF
18270	  (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18271	  (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18272  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18273  "@
18274   <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18275   v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18276  [(set_attr "isa" "noavx,avx")
18277   (set_attr "prefix" "orig,vex")
18278   (set_attr "type" "sseadd")
18279   (set_attr "mode" "<MODE>")])
18280
18281;; These versions of the min/max patterns implement exactly the operations
18282;;   min = (op1 < op2 ? op1 : op2)
18283;;   max = (!(op1 < op2) ? op1 : op2)
18284;; Their operands are not commutative, and thus they may be used in the
18285;; presence of -0.0 and NaN.
18286
18287(define_insn "*ieee_s<ieee_maxmin><mode>3"
18288  [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18289	(unspec:MODEF
18290	  [(match_operand:MODEF 1 "register_operand" "0,v")
18291	   (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18292	  IEEE_MAXMIN))]
18293  "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18294  "@
18295   <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18296   v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18297  [(set_attr "isa" "noavx,avx")
18298   (set_attr "prefix" "orig,maybe_evex")
18299   (set_attr "type" "sseadd")
18300   (set_attr "mode" "<MODE>")])
18301
18302;; Make two stack loads independent:
18303;;   fld aa              fld aa
18304;;   fld %st(0)     ->   fld bb
18305;;   fmul bb             fmul %st(1), %st
18306;;
18307;; Actually we only match the last two instructions for simplicity.
18308
18309(define_peephole2
18310  [(set (match_operand 0 "fp_register_operand")
18311	(match_operand 1 "fp_register_operand"))
18312   (set (match_dup 0)
18313	(match_operator 2 "binary_fp_operator"
18314	   [(match_dup 0)
18315	    (match_operand 3 "memory_operand")]))]
18316  "REGNO (operands[0]) != REGNO (operands[1])"
18317  [(set (match_dup 0) (match_dup 3))
18318   (set (match_dup 0)
18319	(match_op_dup 2
18320	  [(match_dup 5) (match_dup 4)]))]
18321{
18322  operands[4] = operands[0];
18323  operands[5] = operands[1];
18324
18325  /* The % modifier is not operational anymore in peephole2's, so we have to
18326     swap the operands manually in the case of addition and multiplication. */
18327  if (COMMUTATIVE_ARITH_P (operands[2]))
18328    std::swap (operands[4], operands[5]);
18329})
18330
18331(define_peephole2
18332  [(set (match_operand 0 "fp_register_operand")
18333	(match_operand 1 "fp_register_operand"))
18334   (set (match_dup 0)
18335	(match_operator 2 "binary_fp_operator"
18336	   [(match_operand 3 "memory_operand")
18337	    (match_dup 0)]))]
18338  "REGNO (operands[0]) != REGNO (operands[1])"
18339  [(set (match_dup 0) (match_dup 3))
18340   (set (match_dup 0)
18341	(match_op_dup 2
18342	  [(match_dup 4) (match_dup 5)]))]
18343{
18344  operands[4] = operands[0];
18345  operands[5] = operands[1];
18346
18347  /* The % modifier is not operational anymore in peephole2's, so we have to
18348     swap the operands manually in the case of addition and multiplication. */
18349  if (COMMUTATIVE_ARITH_P (operands[2]))
18350    std::swap (operands[4], operands[5]);
18351})
18352
18353;; Conditional addition patterns
18354(define_expand "add<mode>cc"
18355  [(match_operand:SWI 0 "register_operand")
18356   (match_operand 1 "ordered_comparison_operator")
18357   (match_operand:SWI 2 "register_operand")
18358   (match_operand:SWI 3 "const_int_operand")]
18359  ""
18360  "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18361
18362;; Misc patterns (?)
18363
18364;; This pattern exists to put a dependency on all ebp-based memory accesses.
18365;; Otherwise there will be nothing to keep
18366;;
18367;; [(set (reg ebp) (reg esp))]
18368;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18369;;  (clobber (eflags)]
18370;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18371;;
18372;; in proper program order.
18373
18374(define_insn "pro_epilogue_adjust_stack_<mode>_add"
18375  [(set (match_operand:P 0 "register_operand" "=r,r")
18376	(plus:P (match_operand:P 1 "register_operand" "0,r")
18377	        (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18378   (clobber (reg:CC FLAGS_REG))
18379   (clobber (mem:BLK (scratch)))]
18380  ""
18381{
18382  switch (get_attr_type (insn))
18383    {
18384    case TYPE_IMOV:
18385      return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18386
18387    case TYPE_ALU:
18388      gcc_assert (rtx_equal_p (operands[0], operands[1]));
18389      if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18390	return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18391
18392      return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18393
18394    default:
18395      operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18396      return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18397    }
18398}
18399  [(set (attr "type")
18400	(cond [(and (eq_attr "alternative" "0")
18401		    (not (match_test "TARGET_OPT_AGU")))
18402		 (const_string "alu")
18403	       (match_operand:<MODE> 2 "const0_operand")
18404		 (const_string "imov")
18405	      ]
18406	      (const_string "lea")))
18407   (set (attr "length_immediate")
18408	(cond [(eq_attr "type" "imov")
18409		 (const_string "0")
18410	       (and (eq_attr "type" "alu")
18411		    (match_operand 2 "const128_operand"))
18412		 (const_string "1")
18413	      ]
18414	      (const_string "*")))
18415   (set_attr "mode" "<MODE>")])
18416
18417(define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18418  [(set (match_operand:P 0 "register_operand" "=r")
18419	(minus:P (match_operand:P 1 "register_operand" "0")
18420		 (match_operand:P 2 "register_operand" "r")))
18421   (clobber (reg:CC FLAGS_REG))
18422   (clobber (mem:BLK (scratch)))]
18423  ""
18424  "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18425  [(set_attr "type" "alu")
18426   (set_attr "mode" "<MODE>")])
18427
18428(define_insn "allocate_stack_worker_probe_<mode>"
18429  [(set (match_operand:P 0 "register_operand" "=a")
18430	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18431			    UNSPECV_STACK_PROBE))
18432   (clobber (reg:CC FLAGS_REG))]
18433  "ix86_target_stack_probe ()"
18434  "call\t___chkstk_ms"
18435  [(set_attr "type" "multi")
18436   (set_attr "length" "5")])
18437
18438(define_expand "allocate_stack"
18439  [(match_operand 0 "register_operand")
18440   (match_operand 1 "general_operand")]
18441  "ix86_target_stack_probe ()"
18442{
18443  rtx x;
18444
18445#ifndef CHECK_STACK_LIMIT
18446#define CHECK_STACK_LIMIT 0
18447#endif
18448
18449  if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18450      && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18451    x = operands[1];
18452  else
18453    {
18454      rtx (*insn) (rtx, rtx);
18455
18456      x = copy_to_mode_reg (Pmode, operands[1]);
18457
18458      insn = (TARGET_64BIT
18459	      ? gen_allocate_stack_worker_probe_di
18460	      : gen_allocate_stack_worker_probe_si);
18461
18462      emit_insn (insn (x, x));
18463    }
18464
18465  x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18466			   stack_pointer_rtx, 0, OPTAB_DIRECT);
18467
18468  if (x != stack_pointer_rtx)
18469    emit_move_insn (stack_pointer_rtx, x);
18470
18471  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18472  DONE;
18473})
18474
18475(define_expand "probe_stack"
18476  [(match_operand 0 "memory_operand")]
18477  ""
18478{
18479  rtx (*insn) (rtx, rtx)
18480    = (GET_MODE (operands[0]) == DImode
18481       ? gen_probe_stack_di : gen_probe_stack_si);
18482
18483  emit_insn (insn (operands[0], const0_rtx));
18484  DONE;
18485})
18486
18487;; Use OR for stack probes, this is shorter.
18488(define_insn "probe_stack_<mode>"
18489  [(set (match_operand:W 0 "memory_operand" "=m")
18490	(unspec:W [(match_operand:W 1 "const0_operand")]
18491		  UNSPEC_PROBE_STACK))
18492   (clobber (reg:CC FLAGS_REG))]
18493  ""
18494  "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18495  [(set_attr "type" "alu1")
18496   (set_attr "mode" "<MODE>")
18497   (set_attr "length_immediate" "1")])
18498
18499(define_insn "adjust_stack_and_probe<mode>"
18500  [(set (match_operand:P 0 "register_operand" "=r")
18501	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18502			    UNSPECV_PROBE_STACK_RANGE))
18503   (set (reg:P SP_REG)
18504        (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18505   (clobber (reg:CC FLAGS_REG))
18506   (clobber (mem:BLK (scratch)))]
18507  ""
18508  "* return output_adjust_stack_and_probe (operands[0]);"
18509  [(set_attr "type" "multi")])
18510
18511(define_insn "probe_stack_range<mode>"
18512  [(set (match_operand:P 0 "register_operand" "=r")
18513	(unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18514			    (match_operand:P 2 "const_int_operand" "n")]
18515			    UNSPECV_PROBE_STACK_RANGE))
18516   (clobber (reg:CC FLAGS_REG))]
18517  ""
18518  "* return output_probe_stack_range (operands[0], operands[2]);"
18519  [(set_attr "type" "multi")])
18520
18521(define_expand "builtin_setjmp_receiver"
18522  [(label_ref (match_operand 0))]
18523  "!TARGET_64BIT && flag_pic"
18524{
18525#if TARGET_MACHO
18526  if (TARGET_MACHO)
18527    {
18528      rtx xops[3];
18529      rtx_code_label *label_rtx = gen_label_rtx ();
18530      emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18531      xops[0] = xops[1] = pic_offset_table_rtx;
18532      xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18533      ix86_expand_binary_operator (MINUS, SImode, xops);
18534    }
18535  else
18536#endif
18537    emit_insn (gen_set_got (pic_offset_table_rtx));
18538  DONE;
18539})
18540
18541(define_expand "save_stack_nonlocal"
18542  [(set (match_operand 0 "memory_operand")
18543        (match_operand 1 "register_operand"))]
18544  ""
18545{
18546  rtx stack_slot;
18547  if ((flag_cf_protection & CF_RETURN))
18548    {
18549      /* Copy shadow stack pointer to the first slot and stack ppointer
18550	 to the second slot.  */
18551      rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18552      stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18553      rtx ssp = gen_reg_rtx (word_mode);
18554      emit_insn ((word_mode == SImode)
18555		 ? gen_rdsspsi (ssp)
18556		 : gen_rdsspdi (ssp));
18557      emit_move_insn (ssp_slot, ssp);
18558    }
18559  else
18560    stack_slot = adjust_address (operands[0], Pmode, 0);
18561  emit_move_insn (stack_slot, operands[1]);
18562  DONE;
18563})
18564
18565(define_expand "restore_stack_nonlocal"
18566  [(set (match_operand 0 "register_operand" "")
18567	(match_operand 1 "memory_operand" ""))]
18568  ""
18569{
18570  rtx stack_slot;
18571  if ((flag_cf_protection & CF_RETURN))
18572    {
18573      /* Restore shadow stack pointer from the first slot and stack
18574	 pointer from the second slot.  */
18575      rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18576      stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18577
18578      rtx flags, jump, noadj_label, inc_label, loop_label;
18579      rtx reg_adj, reg_ssp, tmp, clob;
18580
18581      /* Get the current shadow stack pointer.  The code below will check if
18582	 SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
18583	 is a NOP.  */
18584      reg_ssp = gen_reg_rtx (word_mode);
18585      emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18586      emit_insn ((word_mode == SImode)
18587		 ? gen_rdsspsi (reg_ssp)
18588		 : gen_rdsspdi (reg_ssp));
18589
18590      /* Compare through substraction the saved and the current ssp to decide
18591	 if ssp has to be adjusted.  */
18592      tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18593						 ssp_slot));
18594      clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18595      tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18596      emit_insn (tmp);
18597
18598      /* Compare and jump over adjustment code.  */
18599      noadj_label = gen_label_rtx ();
18600      flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18601      tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18602      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18603				  gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18604				  pc_rtx);
18605      jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18606      JUMP_LABEL (jump) = noadj_label;
18607
18608      /* Compute the numebr of frames to adjust.  */
18609      reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18610      tmp = gen_rtx_SET (reg_adj,
18611			 gen_rtx_LSHIFTRT (ptr_mode,
18612					   negate_rtx (ptr_mode, reg_adj),
18613					   GEN_INT ((word_mode == SImode)
18614						    ? 2
18615						    : 3)));
18616      clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18617      tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18618      emit_insn (tmp);
18619
18620      /* Check if number of frames <= 255 so no loop is needed.  */
18621      tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18622      flags = gen_rtx_REG (CCmode, FLAGS_REG);
18623      emit_insn (gen_rtx_SET (flags, tmp));
18624
18625      inc_label = gen_label_rtx ();
18626      tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18627      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18628				  gen_rtx_LABEL_REF (VOIDmode, inc_label),
18629				  pc_rtx);
18630      jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18631      JUMP_LABEL (jump) = inc_label;
18632
18633      rtx reg_255 = gen_reg_rtx (word_mode);
18634      emit_move_insn (reg_255, GEN_INT (255));
18635
18636      /* Adjust the ssp in a loop.  */
18637      loop_label = gen_label_rtx ();
18638      emit_label (loop_label);
18639      LABEL_NUSES (loop_label) = 1;
18640
18641      emit_insn ((word_mode == SImode)
18642		 ? gen_incsspsi (reg_255)
18643		 : gen_incsspdi (reg_255));
18644      tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18645						 reg_adj,
18646						 GEN_INT (255)));
18647      clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18648      tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18649      emit_insn (tmp);
18650
18651      tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18652      flags = gen_rtx_REG (CCmode, FLAGS_REG);
18653      emit_insn (gen_rtx_SET (flags, tmp));
18654
18655      /* Jump to the loop label.  */
18656      tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18657      tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18658				  gen_rtx_LABEL_REF (VOIDmode, loop_label),
18659				  pc_rtx);
18660      jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18661      JUMP_LABEL (jump) = loop_label;
18662
18663      emit_label (inc_label);
18664      LABEL_NUSES (inc_label) = 1;
18665      emit_insn ((word_mode == SImode)
18666		 ? gen_incsspsi (reg_ssp)
18667		 : gen_incsspdi (reg_ssp));
18668
18669      emit_label (noadj_label);
18670      LABEL_NUSES (noadj_label) = 1;
18671    }
18672  else
18673    stack_slot = adjust_address (operands[1], Pmode, 0);
18674  emit_move_insn (operands[0], stack_slot);
18675  DONE;
18676})
18677
18678
18679;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18680;; Do not split instructions with mask registers.
18681(define_split
18682  [(set (match_operand 0 "general_reg_operand")
18683	(match_operator 3 "promotable_binary_operator"
18684	   [(match_operand 1 "general_reg_operand")
18685	    (match_operand 2 "aligned_operand")]))
18686   (clobber (reg:CC FLAGS_REG))]
18687  "! TARGET_PARTIAL_REG_STALL && reload_completed
18688   && ((GET_MODE (operands[0]) == HImode
18689	&& ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18690            /* ??? next two lines just !satisfies_constraint_K (...) */
18691	    || !CONST_INT_P (operands[2])
18692	    || satisfies_constraint_K (operands[2])))
18693       || (GET_MODE (operands[0]) == QImode
18694	   && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18695  [(parallel [(set (match_dup 0)
18696		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18697	      (clobber (reg:CC FLAGS_REG))])]
18698{
18699  operands[0] = gen_lowpart (SImode, operands[0]);
18700  operands[1] = gen_lowpart (SImode, operands[1]);
18701  if (GET_CODE (operands[3]) != ASHIFT)
18702    operands[2] = gen_lowpart (SImode, operands[2]);
18703  operands[3] = shallow_copy_rtx (operands[3]);
18704  PUT_MODE (operands[3], SImode);
18705})
18706
18707; Promote the QImode tests, as i386 has encoding of the AND
18708; instruction with 32-bit sign-extended immediate and thus the
18709; instruction size is unchanged, except in the %eax case for
18710; which it is increased by one byte, hence the ! optimize_size.
18711(define_split
18712  [(set (match_operand 0 "flags_reg_operand")
18713	(match_operator 2 "compare_operator"
18714	  [(and (match_operand 3 "aligned_operand")
18715		(match_operand 4 "const_int_operand"))
18716	   (const_int 0)]))
18717   (set (match_operand 1 "register_operand")
18718	(and (match_dup 3) (match_dup 4)))]
18719  "! TARGET_PARTIAL_REG_STALL && reload_completed
18720   && optimize_insn_for_speed_p ()
18721   && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18722       || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18723   /* Ensure that the operand will remain sign-extended immediate.  */
18724   && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18725  [(parallel [(set (match_dup 0)
18726		   (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18727			            (const_int 0)]))
18728	      (set (match_dup 1)
18729		   (and:SI (match_dup 3) (match_dup 4)))])]
18730{
18731  operands[4]
18732    = gen_int_mode (INTVAL (operands[4])
18733		    & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18734  operands[1] = gen_lowpart (SImode, operands[1]);
18735  operands[3] = gen_lowpart (SImode, operands[3]);
18736})
18737
18738; Don't promote the QImode tests, as i386 doesn't have encoding of
18739; the TEST instruction with 32-bit sign-extended immediate and thus
18740; the instruction size would at least double, which is not what we
18741; want even with ! optimize_size.
18742(define_split
18743  [(set (match_operand 0 "flags_reg_operand")
18744	(match_operator 1 "compare_operator"
18745	  [(and (match_operand:HI 2 "aligned_operand")
18746		(match_operand:HI 3 "const_int_operand"))
18747	   (const_int 0)]))]
18748  "! TARGET_PARTIAL_REG_STALL && reload_completed
18749   && ! TARGET_FAST_PREFIX
18750   && optimize_insn_for_speed_p ()
18751   /* Ensure that the operand will remain sign-extended immediate.  */
18752   && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18753  [(set (match_dup 0)
18754	(match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18755		         (const_int 0)]))]
18756{
18757  operands[3]
18758    = gen_int_mode (INTVAL (operands[3])
18759		    & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18760  operands[2] = gen_lowpart (SImode, operands[2]);
18761})
18762
18763(define_split
18764  [(set (match_operand 0 "register_operand")
18765	(neg (match_operand 1 "register_operand")))
18766   (clobber (reg:CC FLAGS_REG))]
18767  "! TARGET_PARTIAL_REG_STALL && reload_completed
18768   && (GET_MODE (operands[0]) == HImode
18769       || (GET_MODE (operands[0]) == QImode
18770	   && (TARGET_PROMOTE_QImode
18771	       || optimize_insn_for_size_p ())))"
18772  [(parallel [(set (match_dup 0)
18773		   (neg:SI (match_dup 1)))
18774	      (clobber (reg:CC FLAGS_REG))])]
18775{
18776  operands[0] = gen_lowpart (SImode, operands[0]);
18777  operands[1] = gen_lowpart (SImode, operands[1]);
18778})
18779
18780;; Do not split instructions with mask regs.
18781(define_split
18782  [(set (match_operand 0 "general_reg_operand")
18783	(not (match_operand 1 "general_reg_operand")))]
18784  "! TARGET_PARTIAL_REG_STALL && reload_completed
18785   && (GET_MODE (operands[0]) == HImode
18786       || (GET_MODE (operands[0]) == QImode
18787	   && (TARGET_PROMOTE_QImode
18788	       || optimize_insn_for_size_p ())))"
18789  [(set (match_dup 0)
18790	(not:SI (match_dup 1)))]
18791{
18792  operands[0] = gen_lowpart (SImode, operands[0]);
18793  operands[1] = gen_lowpart (SImode, operands[1]);
18794})
18795
18796;; RTL Peephole optimizations, run before sched2.  These primarily look to
18797;; transform a complex memory operation into two memory to register operations.
18798
18799;; Don't push memory operands
18800(define_peephole2
18801  [(set (match_operand:SWI 0 "push_operand")
18802	(match_operand:SWI 1 "memory_operand"))
18803   (match_scratch:SWI 2 "<r>")]
18804  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18805   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18806  [(set (match_dup 2) (match_dup 1))
18807   (set (match_dup 0) (match_dup 2))])
18808
18809;; We need to handle SFmode only, because DFmode and XFmode are split to
18810;; SImode pushes.
18811(define_peephole2
18812  [(set (match_operand:SF 0 "push_operand")
18813	(match_operand:SF 1 "memory_operand"))
18814   (match_scratch:SF 2 "r")]
18815  "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18816   && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18817  [(set (match_dup 2) (match_dup 1))
18818   (set (match_dup 0) (match_dup 2))])
18819
18820;; Don't move an immediate directly to memory when the instruction
18821;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18822(define_peephole2
18823  [(match_scratch:SWI124 1 "<r>")
18824   (set (match_operand:SWI124 0 "memory_operand")
18825        (const_int 0))]
18826  "optimize_insn_for_speed_p ()
18827   && ((<MODE>mode == HImode
18828       && TARGET_LCP_STALL)
18829       || (!TARGET_USE_MOV0
18830          && TARGET_SPLIT_LONG_MOVES
18831          && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18832   && peep2_regno_dead_p (0, FLAGS_REG)"
18833  [(parallel [(set (match_dup 2) (const_int 0))
18834	      (clobber (reg:CC FLAGS_REG))])
18835   (set (match_dup 0) (match_dup 1))]
18836  "operands[2] = gen_lowpart (SImode, operands[1]);")
18837
18838(define_peephole2
18839  [(match_scratch:SWI124 2 "<r>")
18840   (set (match_operand:SWI124 0 "memory_operand")
18841        (match_operand:SWI124 1 "immediate_operand"))]
18842  "optimize_insn_for_speed_p ()
18843   && ((<MODE>mode == HImode
18844       && TARGET_LCP_STALL)
18845       || (TARGET_SPLIT_LONG_MOVES
18846          && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18847  [(set (match_dup 2) (match_dup 1))
18848   (set (match_dup 0) (match_dup 2))])
18849
18850;; Don't compare memory with zero, load and use a test instead.
18851(define_peephole2
18852  [(set (match_operand 0 "flags_reg_operand")
18853 	(match_operator 1 "compare_operator"
18854	  [(match_operand:SI 2 "memory_operand")
18855	   (const_int 0)]))
18856   (match_scratch:SI 3 "r")]
18857  "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18858  [(set (match_dup 3) (match_dup 2))
18859   (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18860
18861;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18862;; Don't split NOTs with a displacement operand, because resulting XOR
18863;; will not be pairable anyway.
18864;;
18865;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18866;; represented using a modRM byte.  The XOR replacement is long decoded,
18867;; so this split helps here as well.
18868;;
18869;; Note: Can't do this as a regular split because we can't get proper
18870;; lifetime information then.
18871
18872(define_peephole2
18873  [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18874	(not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18875  "optimize_insn_for_speed_p ()
18876   && ((TARGET_NOT_UNPAIRABLE
18877	&& (!MEM_P (operands[0])
18878	    || !memory_displacement_operand (operands[0], <MODE>mode)))
18879       || (TARGET_NOT_VECTORMODE
18880	   && long_memory_operand (operands[0], <MODE>mode)))
18881   && peep2_regno_dead_p (0, FLAGS_REG)"
18882  [(parallel [(set (match_dup 0)
18883		   (xor:SWI124 (match_dup 1) (const_int -1)))
18884	      (clobber (reg:CC FLAGS_REG))])])
18885
18886;; Non pairable "test imm, reg" instructions can be translated to
18887;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18888;; byte opcode instead of two, have a short form for byte operands),
18889;; so do it for other CPUs as well.  Given that the value was dead,
18890;; this should not create any new dependencies.  Pass on the sub-word
18891;; versions if we're concerned about partial register stalls.
18892
18893(define_peephole2
18894  [(set (match_operand 0 "flags_reg_operand")
18895	(match_operator 1 "compare_operator"
18896	  [(and:SI (match_operand:SI 2 "register_operand")
18897		   (match_operand:SI 3 "immediate_operand"))
18898	   (const_int 0)]))]
18899  "ix86_match_ccmode (insn, CCNOmode)
18900   && (REGNO (operands[2]) != AX_REG
18901       || satisfies_constraint_K (operands[3]))
18902   && peep2_reg_dead_p (1, operands[2])"
18903  [(parallel
18904     [(set (match_dup 0)
18905	   (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18906		            (const_int 0)]))
18907      (set (match_dup 2)
18908	   (and:SI (match_dup 2) (match_dup 3)))])])
18909
18910;; We don't need to handle HImode case, because it will be promoted to SImode
18911;; on ! TARGET_PARTIAL_REG_STALL
18912
18913(define_peephole2
18914  [(set (match_operand 0 "flags_reg_operand")
18915	(match_operator 1 "compare_operator"
18916	  [(and:QI (match_operand:QI 2 "register_operand")
18917		   (match_operand:QI 3 "immediate_operand"))
18918	   (const_int 0)]))]
18919  "! TARGET_PARTIAL_REG_STALL
18920   && ix86_match_ccmode (insn, CCNOmode)
18921   && REGNO (operands[2]) != AX_REG
18922   && peep2_reg_dead_p (1, operands[2])"
18923  [(parallel
18924     [(set (match_dup 0)
18925	   (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18926		            (const_int 0)]))
18927      (set (match_dup 2)
18928	   (and:QI (match_dup 2) (match_dup 3)))])])
18929
18930(define_peephole2
18931  [(set (match_operand 0 "flags_reg_operand")
18932	(match_operator 1 "compare_operator"
18933	  [(and:QI
18934	     (subreg:QI
18935	       (zero_extract:SI (match_operand 2 "QIreg_operand")
18936				(const_int 8)
18937				(const_int 8)) 0)
18938	     (match_operand 3 "const_int_operand"))
18939	   (const_int 0)]))]
18940  "! TARGET_PARTIAL_REG_STALL
18941   && ix86_match_ccmode (insn, CCNOmode)
18942   && REGNO (operands[2]) != AX_REG
18943   && peep2_reg_dead_p (1, operands[2])"
18944  [(parallel
18945     [(set (match_dup 0)
18946	   (match_op_dup 1
18947	     [(and:QI
18948		(subreg:QI
18949		  (zero_extract:SI (match_dup 2)
18950				   (const_int 8)
18951				   (const_int 8)) 0)
18952		(match_dup 3))
18953	      (const_int 0)]))
18954      (set (zero_extract:SI (match_dup 2)
18955			    (const_int 8)
18956			    (const_int 8))
18957	   (subreg:SI
18958	     (and:QI
18959	       (subreg:QI
18960		 (zero_extract:SI (match_dup 2)
18961				  (const_int 8)
18962				  (const_int 8)) 0)
18963	       (match_dup 3)) 0))])])
18964
18965;; Don't do logical operations with memory inputs.
18966(define_peephole2
18967  [(match_scratch:SWI 2 "<r>")
18968   (parallel [(set (match_operand:SWI 0 "register_operand")
18969		   (match_operator:SWI 3 "arith_or_logical_operator"
18970		     [(match_dup 0)
18971		      (match_operand:SWI 1 "memory_operand")]))
18972	      (clobber (reg:CC FLAGS_REG))])]
18973  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18974  [(set (match_dup 2) (match_dup 1))
18975   (parallel [(set (match_dup 0)
18976		   (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18977	      (clobber (reg:CC FLAGS_REG))])])
18978
18979(define_peephole2
18980  [(match_scratch:SWI 2 "<r>")
18981   (parallel [(set (match_operand:SWI 0 "register_operand")
18982		   (match_operator:SWI 3 "arith_or_logical_operator"
18983		     [(match_operand:SWI 1 "memory_operand")
18984		      (match_dup 0)]))
18985	      (clobber (reg:CC FLAGS_REG))])]
18986  "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18987  [(set (match_dup 2) (match_dup 1))
18988   (parallel [(set (match_dup 0)
18989		   (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18990	      (clobber (reg:CC FLAGS_REG))])])
18991
18992;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
18993;; the memory address refers to the destination of the load!
18994
18995(define_peephole2
18996  [(set (match_operand:SWI 0 "general_reg_operand")
18997	(match_operand:SWI 1 "general_reg_operand"))
18998   (parallel [(set (match_dup 0)
18999		   (match_operator:SWI 3 "commutative_operator"
19000		     [(match_dup 0)
19001		      (match_operand:SWI 2 "memory_operand")]))
19002	      (clobber (reg:CC FLAGS_REG))])]
19003  "REGNO (operands[0]) != REGNO (operands[1])
19004   && (<MODE>mode != QImode
19005       || any_QIreg_operand (operands[1], QImode))"
19006  [(set (match_dup 0) (match_dup 4))
19007   (parallel [(set (match_dup 0)
19008		   (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19009	      (clobber (reg:CC FLAGS_REG))])]
19010  "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19011
19012(define_peephole2
19013  [(set (match_operand 0 "mmx_reg_operand")
19014	(match_operand 1 "mmx_reg_operand"))
19015   (set (match_dup 0)
19016	(match_operator 3 "commutative_operator"
19017	  [(match_dup 0)
19018	   (match_operand 2 "memory_operand")]))]
19019  "REGNO (operands[0]) != REGNO (operands[1])"
19020  [(set (match_dup 0) (match_dup 2))
19021   (set (match_dup 0)
19022	(match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19023
19024(define_peephole2
19025  [(set (match_operand 0 "sse_reg_operand")
19026	(match_operand 1 "sse_reg_operand"))
19027   (set (match_dup 0)
19028	(match_operator 3 "commutative_operator"
19029	  [(match_dup 0)
19030	   (match_operand 2 "memory_operand")]))]
19031  "REGNO (operands[0]) != REGNO (operands[1])"
19032  [(set (match_dup 0) (match_dup 2))
19033   (set (match_dup 0)
19034	(match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19035
19036; Don't do logical operations with memory outputs
19037;
19038; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19039; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19040; the same decoder scheduling characteristics as the original.
19041
19042(define_peephole2
19043  [(match_scratch:SWI 2 "<r>")
19044   (parallel [(set (match_operand:SWI 0 "memory_operand")
19045		   (match_operator:SWI 3 "arith_or_logical_operator"
19046		     [(match_dup 0)
19047		      (match_operand:SWI 1 "<nonmemory_operand>")]))
19048	      (clobber (reg:CC FLAGS_REG))])]
19049  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19050  [(set (match_dup 2) (match_dup 0))
19051   (parallel [(set (match_dup 2)
19052		   (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19053	      (clobber (reg:CC FLAGS_REG))])
19054   (set (match_dup 0) (match_dup 2))])
19055
19056(define_peephole2
19057  [(match_scratch:SWI 2 "<r>")
19058   (parallel [(set (match_operand:SWI 0 "memory_operand")
19059		   (match_operator:SWI 3 "arith_or_logical_operator"
19060		     [(match_operand:SWI 1 "<nonmemory_operand>")
19061		      (match_dup 0)]))
19062	      (clobber (reg:CC FLAGS_REG))])]
19063  "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19064  [(set (match_dup 2) (match_dup 0))
19065   (parallel [(set (match_dup 2)
19066		   (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19067	      (clobber (reg:CC FLAGS_REG))])
19068   (set (match_dup 0) (match_dup 2))])
19069
19070;; Attempt to use arith or logical operations with memory outputs with
19071;; setting of flags.
19072(define_peephole2
19073  [(set (match_operand:SWI 0 "register_operand")
19074	(match_operand:SWI 1 "memory_operand"))
19075   (parallel [(set (match_dup 0)
19076		   (match_operator:SWI 3 "plusminuslogic_operator"
19077		     [(match_dup 0)
19078		      (match_operand:SWI 2 "<nonmemory_operand>")]))
19079	      (clobber (reg:CC FLAGS_REG))])
19080   (set (match_dup 1) (match_dup 0))
19081   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19082  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19083   && peep2_reg_dead_p (4, operands[0])
19084   && !reg_overlap_mentioned_p (operands[0], operands[1])
19085   && !reg_overlap_mentioned_p (operands[0], operands[2])
19086   && (<MODE>mode != QImode
19087       || immediate_operand (operands[2], QImode)
19088       || any_QIreg_operand (operands[2], QImode))
19089   && ix86_match_ccmode (peep2_next_insn (3),
19090			 (GET_CODE (operands[3]) == PLUS
19091			  || GET_CODE (operands[3]) == MINUS)
19092			 ? CCGOCmode : CCNOmode)"
19093  [(parallel [(set (match_dup 4) (match_dup 6))
19094	      (set (match_dup 1) (match_dup 5))])]
19095{
19096  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19097  operands[5]
19098    = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19099		      copy_rtx (operands[1]),
19100		      operands[2]);
19101  operands[6]
19102    = gen_rtx_COMPARE (GET_MODE (operands[4]),
19103		       copy_rtx (operands[5]),
19104		       const0_rtx);
19105})
19106
19107;; Likewise for cmpelim optimized pattern.
19108(define_peephole2
19109  [(set (match_operand:SWI 0 "register_operand")
19110	(match_operand:SWI 1 "memory_operand"))
19111   (parallel [(set (reg FLAGS_REG)
19112		   (compare (match_operator:SWI 3 "plusminuslogic_operator"
19113			      [(match_dup 0)
19114			       (match_operand:SWI 2 "<nonmemory_operand>")])
19115			    (const_int 0)))
19116	      (set (match_dup 0) (match_dup 3))])
19117   (set (match_dup 1) (match_dup 0))]
19118  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19119   && peep2_reg_dead_p (3, operands[0])
19120   && !reg_overlap_mentioned_p (operands[0], operands[1])
19121   && !reg_overlap_mentioned_p (operands[0], operands[2])
19122   && ix86_match_ccmode (peep2_next_insn (1),
19123			 (GET_CODE (operands[3]) == PLUS
19124			  || GET_CODE (operands[3]) == MINUS)
19125			 ? CCGOCmode : CCNOmode)"
19126  [(parallel [(set (match_dup 4) (match_dup 6))
19127	      (set (match_dup 1) (match_dup 5))])]
19128{
19129  operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19130  operands[5]
19131    = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19132		      copy_rtx (operands[1]), operands[2]);
19133  operands[6]
19134    = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19135		       const0_rtx);
19136})
19137
19138;; Likewise for instances where we have a lea pattern.
19139(define_peephole2
19140  [(set (match_operand:SWI 0 "register_operand")
19141	(match_operand:SWI 1 "memory_operand"))
19142   (set (match_operand:SWI 3 "register_operand")
19143	(plus:SWI (match_dup 0)
19144		  (match_operand:SWI 2 "<nonmemory_operand>")))
19145   (set (match_dup 1) (match_dup 3))
19146   (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19147  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19148   && peep2_reg_dead_p (4, operands[3])
19149   && (rtx_equal_p (operands[0], operands[3])
19150       || peep2_reg_dead_p (2, operands[0]))
19151   && !reg_overlap_mentioned_p (operands[0], operands[1])
19152   && !reg_overlap_mentioned_p (operands[3], operands[1])
19153   && !reg_overlap_mentioned_p (operands[0], operands[2])
19154   && (<MODE>mode != QImode
19155       || immediate_operand (operands[2], QImode)
19156       || any_QIreg_operand (operands[2], QImode))
19157   && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19158  [(parallel [(set (match_dup 4) (match_dup 6))
19159	      (set (match_dup 1) (match_dup 5))])]
19160{
19161  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19162  operands[5]
19163    = gen_rtx_PLUS (<MODE>mode,
19164		    copy_rtx (operands[1]),
19165		    operands[2]);
19166  operands[6]
19167    = gen_rtx_COMPARE (GET_MODE (operands[4]),
19168		       copy_rtx (operands[5]),
19169		       const0_rtx);
19170})
19171
19172(define_peephole2
19173  [(parallel [(set (match_operand:SWI 0 "register_operand")
19174		   (match_operator:SWI 2 "plusminuslogic_operator"
19175		     [(match_dup 0)
19176		      (match_operand:SWI 1 "memory_operand")]))
19177	      (clobber (reg:CC FLAGS_REG))])
19178   (set (match_dup 1) (match_dup 0))
19179   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19180  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19181   && COMMUTATIVE_ARITH_P (operands[2])
19182   && peep2_reg_dead_p (3, operands[0])
19183   && !reg_overlap_mentioned_p (operands[0], operands[1])
19184   && ix86_match_ccmode (peep2_next_insn (2),
19185			 GET_CODE (operands[2]) == PLUS
19186			 ? CCGOCmode : CCNOmode)"
19187  [(parallel [(set (match_dup 3) (match_dup 5))
19188	      (set (match_dup 1) (match_dup 4))])]
19189{
19190  operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19191  operands[4]
19192    = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19193		      copy_rtx (operands[1]),
19194		      operands[0]);
19195  operands[5]
19196    = gen_rtx_COMPARE (GET_MODE (operands[3]),
19197		       copy_rtx (operands[4]),
19198		       const0_rtx);
19199})
19200
19201;; Likewise for cmpelim optimized pattern.
19202(define_peephole2
19203  [(parallel [(set (reg FLAGS_REG)
19204		   (compare (match_operator:SWI 2 "plusminuslogic_operator"
19205			      [(match_operand:SWI 0 "register_operand")
19206			       (match_operand:SWI 1 "memory_operand")])
19207			    (const_int 0)))
19208	      (set (match_dup 0) (match_dup 2))])
19209   (set (match_dup 1) (match_dup 0))]
19210  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19211   && COMMUTATIVE_ARITH_P (operands[2])
19212   && peep2_reg_dead_p (2, operands[0])
19213   && !reg_overlap_mentioned_p (operands[0], operands[1])
19214   && ix86_match_ccmode (peep2_next_insn (0),
19215			 GET_CODE (operands[2]) == PLUS
19216			 ? CCGOCmode : CCNOmode)"
19217  [(parallel [(set (match_dup 3) (match_dup 5))
19218	      (set (match_dup 1) (match_dup 4))])]
19219{
19220  operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19221  operands[4]
19222    = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19223		      copy_rtx (operands[1]), operands[0]);
19224  operands[5]
19225    = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19226		       const0_rtx);
19227})
19228
19229(define_peephole2
19230  [(set (match_operand:SWI12 0 "register_operand")
19231	(match_operand:SWI12 1 "memory_operand"))
19232   (parallel [(set (match_operand:SI 4 "register_operand")
19233		   (match_operator:SI 3 "plusminuslogic_operator"
19234		     [(match_dup 4)
19235		      (match_operand:SI 2 "nonmemory_operand")]))
19236	      (clobber (reg:CC FLAGS_REG))])
19237   (set (match_dup 1) (match_dup 0))
19238   (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19239  "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19240   && REGNO (operands[0]) == REGNO (operands[4])
19241   && peep2_reg_dead_p (4, operands[0])
19242   && (<MODE>mode != QImode
19243       || immediate_operand (operands[2], SImode)
19244       || any_QIreg_operand (operands[2], SImode))
19245   && !reg_overlap_mentioned_p (operands[0], operands[1])
19246   && !reg_overlap_mentioned_p (operands[0], operands[2])
19247   && ix86_match_ccmode (peep2_next_insn (3),
19248			 (GET_CODE (operands[3]) == PLUS
19249			  || GET_CODE (operands[3]) == MINUS)
19250			 ? CCGOCmode : CCNOmode)"
19251  [(parallel [(set (match_dup 4) (match_dup 6))
19252	      (set (match_dup 1) (match_dup 5))])]
19253{
19254  operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19255  operands[5]
19256    = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19257		      copy_rtx (operands[1]),
19258		      gen_lowpart (<MODE>mode, operands[2]));
19259  operands[6]
19260    = gen_rtx_COMPARE (GET_MODE (operands[4]),
19261		       copy_rtx (operands[5]),
19262		       const0_rtx);
19263})
19264
19265;; Attempt to always use XOR for zeroing registers (including FP modes).
19266(define_peephole2
19267  [(set (match_operand 0 "general_reg_operand")
19268	(match_operand 1 "const0_operand"))]
19269  "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19270   && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19271   && peep2_regno_dead_p (0, FLAGS_REG)"
19272  [(parallel [(set (match_dup 0) (const_int 0))
19273	      (clobber (reg:CC FLAGS_REG))])]
19274  "operands[0] = gen_lowpart (word_mode, operands[0]);")
19275
19276(define_peephole2
19277  [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19278	(const_int 0))]
19279  "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19280   && peep2_regno_dead_p (0, FLAGS_REG)"
19281  [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19282	      (clobber (reg:CC FLAGS_REG))])])
19283
19284;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19285(define_peephole2
19286  [(set (match_operand:SWI248 0 "general_reg_operand")
19287	(const_int -1))]
19288  "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19289   && peep2_regno_dead_p (0, FLAGS_REG)"
19290  [(parallel [(set (match_dup 0) (const_int -1))
19291	      (clobber (reg:CC FLAGS_REG))])]
19292{
19293  if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19294    operands[0] = gen_lowpart (SImode, operands[0]);
19295})
19296
19297;; Attempt to convert simple lea to add/shift.
19298;; These can be created by move expanders.
19299;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19300;; relevant lea instructions were already split.
19301
19302(define_peephole2
19303  [(set (match_operand:SWI48 0 "register_operand")
19304  	(plus:SWI48 (match_dup 0)
19305		    (match_operand:SWI48 1 "<nonmemory_operand>")))]
19306  "!TARGET_OPT_AGU
19307   && peep2_regno_dead_p (0, FLAGS_REG)"
19308  [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19309	      (clobber (reg:CC FLAGS_REG))])])
19310
19311(define_peephole2
19312  [(set (match_operand:SWI48 0 "register_operand")
19313  	(plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19314		    (match_dup 0)))]
19315  "!TARGET_OPT_AGU
19316   && peep2_regno_dead_p (0, FLAGS_REG)"
19317  [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19318	      (clobber (reg:CC FLAGS_REG))])])
19319
19320(define_peephole2
19321  [(set (match_operand:DI 0 "register_operand")
19322  	(zero_extend:DI
19323	  (plus:SI (match_operand:SI 1 "register_operand")
19324		   (match_operand:SI 2 "nonmemory_operand"))))]
19325  "TARGET_64BIT && !TARGET_OPT_AGU
19326   && REGNO (operands[0]) == REGNO (operands[1])
19327   && peep2_regno_dead_p (0, FLAGS_REG)"
19328  [(parallel [(set (match_dup 0)
19329		   (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19330	      (clobber (reg:CC FLAGS_REG))])])
19331
19332(define_peephole2
19333  [(set (match_operand:DI 0 "register_operand")
19334  	(zero_extend:DI
19335	  (plus:SI (match_operand:SI 1 "nonmemory_operand")
19336		   (match_operand:SI 2 "register_operand"))))]
19337  "TARGET_64BIT && !TARGET_OPT_AGU
19338   && REGNO (operands[0]) == REGNO (operands[2])
19339   && peep2_regno_dead_p (0, FLAGS_REG)"
19340  [(parallel [(set (match_dup 0)
19341		   (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19342	      (clobber (reg:CC FLAGS_REG))])])
19343
19344(define_peephole2
19345  [(set (match_operand:SWI48 0 "register_operand")
19346  	(mult:SWI48 (match_dup 0)
19347		    (match_operand:SWI48 1 "const_int_operand")))]
19348  "pow2p_hwi (INTVAL (operands[1]))
19349   && peep2_regno_dead_p (0, FLAGS_REG)"
19350  [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19351	      (clobber (reg:CC FLAGS_REG))])]
19352  "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19353
19354(define_peephole2
19355  [(set (match_operand:DI 0 "register_operand")
19356  	(zero_extend:DI
19357	  (mult:SI (match_operand:SI 1 "register_operand")
19358		   (match_operand:SI 2 "const_int_operand"))))]
19359  "TARGET_64BIT
19360   && pow2p_hwi (INTVAL (operands[2]))
19361   && REGNO (operands[0]) == REGNO (operands[1])
19362   && peep2_regno_dead_p (0, FLAGS_REG)"
19363  [(parallel [(set (match_dup 0)
19364		   (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19365	      (clobber (reg:CC FLAGS_REG))])]
19366  "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19367
19368;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19369;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19370;; On many CPUs it is also faster, since special hardware to avoid esp
19371;; dependencies is present.
19372
19373;; While some of these conversions may be done using splitters, we use
19374;; peepholes in order to allow combine_stack_adjustments pass to see
19375;; nonobfuscated RTL.
19376
19377;; Convert prologue esp subtractions to push.
19378;; We need register to push.  In order to keep verify_flow_info happy we have
19379;; two choices
19380;; - use scratch and clobber it in order to avoid dependencies
19381;; - use already live register
19382;; We can't use the second way right now, since there is no reliable way how to
19383;; verify that given register is live.  First choice will also most likely in
19384;; fewer dependencies.  On the place of esp adjustments it is very likely that
19385;; call clobbered registers are dead.  We may want to use base pointer as an
19386;; alternative when no register is available later.
19387
19388(define_peephole2
19389  [(match_scratch:W 1 "r")
19390   (parallel [(set (reg:P SP_REG)
19391		   (plus:P (reg:P SP_REG)
19392			   (match_operand:P 0 "const_int_operand")))
19393	      (clobber (reg:CC FLAGS_REG))
19394	      (clobber (mem:BLK (scratch)))])]
19395  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19396   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19397   && ix86_red_zone_size == 0"
19398  [(clobber (match_dup 1))
19399   (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19400	      (clobber (mem:BLK (scratch)))])])
19401
19402(define_peephole2
19403  [(match_scratch:W 1 "r")
19404   (parallel [(set (reg:P SP_REG)
19405		   (plus:P (reg:P SP_REG)
19406			   (match_operand:P 0 "const_int_operand")))
19407	      (clobber (reg:CC FLAGS_REG))
19408	      (clobber (mem:BLK (scratch)))])]
19409  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19410   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19411   && ix86_red_zone_size == 0"
19412  [(clobber (match_dup 1))
19413   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19414   (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19415	      (clobber (mem:BLK (scratch)))])])
19416
19417;; Convert esp subtractions to push.
19418(define_peephole2
19419  [(match_scratch:W 1 "r")
19420   (parallel [(set (reg:P SP_REG)
19421		   (plus:P (reg:P SP_REG)
19422			   (match_operand:P 0 "const_int_operand")))
19423	      (clobber (reg:CC FLAGS_REG))])]
19424  "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19425   && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19426   && ix86_red_zone_size == 0"
19427  [(clobber (match_dup 1))
19428   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19429
19430(define_peephole2
19431  [(match_scratch:W 1 "r")
19432   (parallel [(set (reg:P SP_REG)
19433		   (plus:P (reg:P SP_REG)
19434			   (match_operand:P 0 "const_int_operand")))
19435	      (clobber (reg:CC FLAGS_REG))])]
19436  "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19437   && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19438   && ix86_red_zone_size == 0"
19439  [(clobber (match_dup 1))
19440   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19441   (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19442
19443;; Convert epilogue deallocator to pop.
19444(define_peephole2
19445  [(match_scratch:W 1 "r")
19446   (parallel [(set (reg:P SP_REG)
19447		   (plus:P (reg:P SP_REG)
19448			   (match_operand:P 0 "const_int_operand")))
19449	      (clobber (reg:CC FLAGS_REG))
19450	      (clobber (mem:BLK (scratch)))])]
19451  "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19452   && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19453  [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19454	      (clobber (mem:BLK (scratch)))])])
19455
19456;; Two pops case is tricky, since pop causes dependency
19457;; on destination register.  We use two registers if available.
19458(define_peephole2
19459  [(match_scratch:W 1 "r")
19460   (match_scratch:W 2 "r")
19461   (parallel [(set (reg:P SP_REG)
19462		   (plus:P (reg:P SP_REG)
19463			   (match_operand:P 0 "const_int_operand")))
19464	      (clobber (reg:CC FLAGS_REG))
19465	      (clobber (mem:BLK (scratch)))])]
19466  "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19467   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19468  [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19469	      (clobber (mem:BLK (scratch)))])
19470   (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19471
19472(define_peephole2
19473  [(match_scratch:W 1 "r")
19474   (parallel [(set (reg:P SP_REG)
19475		   (plus:P (reg:P SP_REG)
19476			   (match_operand:P 0 "const_int_operand")))
19477	      (clobber (reg:CC FLAGS_REG))
19478	      (clobber (mem:BLK (scratch)))])]
19479  "optimize_insn_for_size_p ()
19480   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19481  [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19482	      (clobber (mem:BLK (scratch)))])
19483   (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19484
19485;; Convert esp additions to pop.
19486(define_peephole2
19487  [(match_scratch:W 1 "r")
19488   (parallel [(set (reg:P SP_REG)
19489		   (plus:P (reg:P SP_REG)
19490			   (match_operand:P 0 "const_int_operand")))
19491	      (clobber (reg:CC FLAGS_REG))])]
19492  "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19493  [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19494
19495;; Two pops case is tricky, since pop causes dependency
19496;; on destination register.  We use two registers if available.
19497(define_peephole2
19498  [(match_scratch:W 1 "r")
19499   (match_scratch:W 2 "r")
19500   (parallel [(set (reg:P SP_REG)
19501		   (plus:P (reg:P SP_REG)
19502			   (match_operand:P 0 "const_int_operand")))
19503	      (clobber (reg:CC FLAGS_REG))])]
19504  "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19505  [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19506   (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19507
19508(define_peephole2
19509  [(match_scratch:W 1 "r")
19510   (parallel [(set (reg:P SP_REG)
19511		   (plus:P (reg:P SP_REG)
19512			   (match_operand:P 0 "const_int_operand")))
19513	      (clobber (reg:CC FLAGS_REG))])]
19514  "optimize_insn_for_size_p ()
19515   && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19516  [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19517   (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19518
19519;; Convert compares with 1 to shorter inc/dec operations when CF is not
19520;; required and register dies.  Similarly for 128 to -128.
19521(define_peephole2
19522  [(set (match_operand 0 "flags_reg_operand")
19523	(match_operator 1 "compare_operator"
19524	  [(match_operand 2 "register_operand")
19525	   (match_operand 3 "const_int_operand")]))]
19526  "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19527     && incdec_operand (operands[3], GET_MODE (operands[3])))
19528    || (!TARGET_FUSE_CMP_AND_BRANCH
19529	&& INTVAL (operands[3]) == 128))
19530   && ix86_match_ccmode (insn, CCGCmode)
19531   && peep2_reg_dead_p (1, operands[2])"
19532  [(parallel [(set (match_dup 0)
19533		   (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19534	      (clobber (match_dup 2))])])
19535
19536;; Convert imul by three, five and nine into lea
19537(define_peephole2
19538  [(parallel
19539    [(set (match_operand:SWI48 0 "register_operand")
19540	  (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19541		      (match_operand:SWI48 2 "const359_operand")))
19542     (clobber (reg:CC FLAGS_REG))])]
19543  "!TARGET_PARTIAL_REG_STALL
19544   || <MODE>mode == SImode
19545   || optimize_function_for_size_p (cfun)"
19546  [(set (match_dup 0)
19547	(plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19548		    (match_dup 1)))]
19549  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19550
19551(define_peephole2
19552  [(parallel
19553    [(set (match_operand:SWI48 0 "register_operand")
19554	  (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19555		      (match_operand:SWI48 2 "const359_operand")))
19556     (clobber (reg:CC FLAGS_REG))])]
19557  "optimize_insn_for_speed_p ()
19558   && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19559  [(set (match_dup 0) (match_dup 1))
19560   (set (match_dup 0)
19561	(plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19562		    (match_dup 0)))]
19563  "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19564
19565;; imul $32bit_imm, mem, reg is vector decoded, while
19566;; imul $32bit_imm, reg, reg is direct decoded.
19567(define_peephole2
19568  [(match_scratch:SWI48 3 "r")
19569   (parallel [(set (match_operand:SWI48 0 "register_operand")
19570		   (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19571			       (match_operand:SWI48 2 "immediate_operand")))
19572	      (clobber (reg:CC FLAGS_REG))])]
19573  "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19574   && !satisfies_constraint_K (operands[2])"
19575  [(set (match_dup 3) (match_dup 1))
19576   (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19577	      (clobber (reg:CC FLAGS_REG))])])
19578
19579(define_peephole2
19580  [(match_scratch:SI 3 "r")
19581   (parallel [(set (match_operand:DI 0 "register_operand")
19582		   (zero_extend:DI
19583		     (mult:SI (match_operand:SI 1 "memory_operand")
19584			      (match_operand:SI 2 "immediate_operand"))))
19585	      (clobber (reg:CC FLAGS_REG))])]
19586  "TARGET_64BIT
19587   && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19588   && !satisfies_constraint_K (operands[2])"
19589  [(set (match_dup 3) (match_dup 1))
19590   (parallel [(set (match_dup 0)
19591		   (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19592	      (clobber (reg:CC FLAGS_REG))])])
19593
19594;; imul $8/16bit_imm, regmem, reg is vector decoded.
19595;; Convert it into imul reg, reg
19596;; It would be better to force assembler to encode instruction using long
19597;; immediate, but there is apparently no way to do so.
19598(define_peephole2
19599  [(parallel [(set (match_operand:SWI248 0 "register_operand")
19600		   (mult:SWI248
19601		    (match_operand:SWI248 1 "nonimmediate_operand")
19602		    (match_operand:SWI248 2 "const_int_operand")))
19603	      (clobber (reg:CC FLAGS_REG))])
19604   (match_scratch:SWI248 3 "r")]
19605  "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19606   && satisfies_constraint_K (operands[2])"
19607  [(set (match_dup 3) (match_dup 2))
19608   (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19609	      (clobber (reg:CC FLAGS_REG))])]
19610{
19611  if (!rtx_equal_p (operands[0], operands[1]))
19612    emit_move_insn (operands[0], operands[1]);
19613})
19614
19615;; After splitting up read-modify operations, array accesses with memory
19616;; operands might end up in form:
19617;;  sall    $2, %eax
19618;;  movl    4(%esp), %edx
19619;;  addl    %edx, %eax
19620;; instead of pre-splitting:
19621;;  sall    $2, %eax
19622;;  addl    4(%esp), %eax
19623;; Turn it into:
19624;;  movl    4(%esp), %edx
19625;;  leal    (%edx,%eax,4), %eax
19626
19627(define_peephole2
19628  [(match_scratch:W 5 "r")
19629   (parallel [(set (match_operand 0 "register_operand")
19630		   (ashift (match_operand 1 "register_operand")
19631			   (match_operand 2 "const_int_operand")))
19632	       (clobber (reg:CC FLAGS_REG))])
19633   (parallel [(set (match_operand 3 "register_operand")
19634		   (plus (match_dup 0)
19635			 (match_operand 4 "x86_64_general_operand")))
19636		   (clobber (reg:CC FLAGS_REG))])]
19637  "IN_RANGE (INTVAL (operands[2]), 1, 3)
19638   /* Validate MODE for lea.  */
19639   && ((!TARGET_PARTIAL_REG_STALL
19640	&& (GET_MODE (operands[0]) == QImode
19641	    || GET_MODE (operands[0]) == HImode))
19642       || GET_MODE (operands[0]) == SImode
19643       || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19644   && (rtx_equal_p (operands[0], operands[3])
19645       || peep2_reg_dead_p (2, operands[0]))
19646   /* We reorder load and the shift.  */
19647   && !reg_overlap_mentioned_p (operands[0], operands[4])"
19648  [(set (match_dup 5) (match_dup 4))
19649   (set (match_dup 0) (match_dup 1))]
19650{
19651  machine_mode op1mode = GET_MODE (operands[1]);
19652  machine_mode mode = op1mode == DImode ? DImode : SImode;
19653  int scale = 1 << INTVAL (operands[2]);
19654  rtx index = gen_lowpart (word_mode, operands[1]);
19655  rtx base = gen_lowpart (word_mode, operands[5]);
19656  rtx dest = gen_lowpart (mode, operands[3]);
19657
19658  operands[1] = gen_rtx_PLUS (word_mode, base,
19659			      gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19660  if (mode != word_mode)
19661    operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19662
19663  operands[5] = base;
19664  if (op1mode != word_mode)
19665    operands[5] = gen_lowpart (op1mode, operands[5]);
19666
19667  operands[0] = dest;
19668})
19669
19670;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19671;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19672;; caught for use by garbage collectors and the like.  Using an insn that
19673;; maps to SIGILL makes it more likely the program will rightfully die.
19674;; Keeping with tradition, "6" is in honor of #UD.
19675(define_insn "trap"
19676  [(trap_if (const_int 1) (const_int 6))]
19677  ""
19678{
19679#ifdef HAVE_AS_IX86_UD2
19680  return "ud2";
19681#else
19682  return ASM_SHORT "0x0b0f";
19683#endif
19684}
19685  [(set_attr "length" "2")])
19686
19687(define_insn "ud2"
19688  [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19689  ""
19690{
19691#ifdef HAVE_AS_IX86_UD2
19692  return "ud2";
19693#else
19694  return ASM_SHORT "0x0b0f";
19695#endif
19696}
19697  [(set_attr "length" "2")])
19698
19699(define_expand "prefetch"
19700  [(prefetch (match_operand 0 "address_operand")
19701	     (match_operand:SI 1 "const_int_operand")
19702	     (match_operand:SI 2 "const_int_operand"))]
19703  "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19704{
19705  bool write = INTVAL (operands[1]) != 0;
19706  int locality = INTVAL (operands[2]);
19707
19708  gcc_assert (IN_RANGE (locality, 0, 3));
19709
19710  /* Use 3dNOW prefetch in case we are asking for write prefetch not
19711     supported by SSE counterpart (non-SSE2 athlon machines) or the
19712     SSE prefetch is not available (K6 machines).  Otherwise use SSE
19713     prefetch as it allows specifying of locality.  */
19714
19715  if (write)
19716    {
19717      if (TARGET_PREFETCHWT1)
19718	operands[2] = GEN_INT (MAX (locality, 2));
19719      else if (TARGET_PRFCHW)
19720	operands[2] = GEN_INT (3);
19721      else if (TARGET_3DNOW && !TARGET_SSE2)
19722	operands[2] = GEN_INT (3);
19723      else if (TARGET_PREFETCH_SSE)
19724	operands[1] = const0_rtx;
19725      else
19726	{
19727	  gcc_assert (TARGET_3DNOW);
19728	  operands[2] = GEN_INT (3);
19729	}
19730    }
19731  else
19732    {
19733      if (TARGET_PREFETCH_SSE)
19734	;
19735      else
19736	{
19737	  gcc_assert (TARGET_3DNOW);
19738	  operands[2] = GEN_INT (3);
19739	}
19740    }
19741})
19742
19743(define_insn "*prefetch_sse"
19744  [(prefetch (match_operand 0 "address_operand" "p")
19745	     (const_int 0)
19746	     (match_operand:SI 1 "const_int_operand"))]
19747  "TARGET_PREFETCH_SSE"
19748{
19749  static const char * const patterns[4] = {
19750   "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19751  };
19752
19753  int locality = INTVAL (operands[1]);
19754  gcc_assert (IN_RANGE (locality, 0, 3));
19755
19756  return patterns[locality];
19757}
19758  [(set_attr "type" "sse")
19759   (set_attr "atom_sse_attr" "prefetch")
19760   (set (attr "length_address")
19761	(symbol_ref "memory_address_length (operands[0], false)"))
19762   (set_attr "memory" "none")])
19763
19764(define_insn "*prefetch_3dnow"
19765  [(prefetch (match_operand 0 "address_operand" "p")
19766	     (match_operand:SI 1 "const_int_operand" "n")
19767	     (const_int 3))]
19768  "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19769{
19770  if (INTVAL (operands[1]) == 0)
19771    return "prefetch\t%a0";
19772  else
19773    return "prefetchw\t%a0";
19774}
19775  [(set_attr "type" "mmx")
19776   (set (attr "length_address")
19777	(symbol_ref "memory_address_length (operands[0], false)"))
19778   (set_attr "memory" "none")])
19779
19780(define_insn "*prefetch_prefetchwt1"
19781  [(prefetch (match_operand 0 "address_operand" "p")
19782	     (const_int 1)
19783	     (const_int 2))]
19784  "TARGET_PREFETCHWT1"
19785  "prefetchwt1\t%a0";
19786  [(set_attr "type" "sse")
19787   (set (attr "length_address")
19788	(symbol_ref "memory_address_length (operands[0], false)"))
19789   (set_attr "memory" "none")])
19790
19791(define_expand "stack_protect_set"
19792  [(match_operand 0 "memory_operand")
19793   (match_operand 1 "memory_operand")]
19794  ""
19795{
19796  rtx (*insn)(rtx, rtx);
19797
19798  insn = (TARGET_LP64
19799	  ? gen_stack_protect_set_di
19800	  : gen_stack_protect_set_si);
19801
19802  emit_insn (insn (operands[0], operands[1]));
19803  DONE;
19804})
19805
19806(define_insn "stack_protect_set_<mode>"
19807  [(set (match_operand:PTR 0 "memory_operand" "=m")
19808	(unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19809		    UNSPEC_SP_SET))
19810   (set (match_scratch:PTR 2 "=&r") (const_int 0))
19811   (clobber (reg:CC FLAGS_REG))]
19812  ""
19813  "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19814  [(set_attr "type" "multi")])
19815
19816(define_expand "stack_protect_test"
19817  [(match_operand 0 "memory_operand")
19818   (match_operand 1 "memory_operand")
19819   (match_operand 2)]
19820  ""
19821{
19822  rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19823
19824  rtx (*insn)(rtx, rtx, rtx);
19825
19826  insn = (TARGET_LP64
19827	  ? gen_stack_protect_test_di
19828	  : gen_stack_protect_test_si);
19829
19830  emit_insn (insn (flags, operands[0], operands[1]));
19831
19832  emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19833				  flags, const0_rtx, operands[2]));
19834  DONE;
19835})
19836
19837(define_insn "stack_protect_test_<mode>"
19838  [(set (match_operand:CCZ 0 "flags_reg_operand")
19839	(unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19840		     (match_operand:PTR 2 "memory_operand" "m")]
19841		    UNSPEC_SP_TEST))
19842   (clobber (match_scratch:PTR 3 "=&r"))]
19843  ""
19844  "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19845  [(set_attr "type" "multi")])
19846
19847(define_insn "sse4_2_crc32<mode>"
19848  [(set (match_operand:SI 0 "register_operand" "=r")
19849	(unspec:SI
19850	  [(match_operand:SI 1 "register_operand" "0")
19851	   (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19852	  UNSPEC_CRC32))]
19853  "TARGET_SSE4_2 || TARGET_CRC32"
19854  "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19855  [(set_attr "type" "sselog1")
19856   (set_attr "prefix_rep" "1")
19857   (set_attr "prefix_extra" "1")
19858   (set (attr "prefix_data16")
19859     (if_then_else (match_operand:HI 2)
19860       (const_string "1")
19861       (const_string "*")))
19862   (set (attr "prefix_rex")
19863     (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19864       (const_string "1")
19865       (const_string "*")))
19866   (set_attr "mode" "SI")])
19867
19868(define_insn "sse4_2_crc32di"
19869  [(set (match_operand:DI 0 "register_operand" "=r")
19870	(unspec:DI
19871	  [(match_operand:DI 1 "register_operand" "0")
19872	   (match_operand:DI 2 "nonimmediate_operand" "rm")]
19873	  UNSPEC_CRC32))]
19874  "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19875  "crc32{q}\t{%2, %0|%0, %2}"
19876  [(set_attr "type" "sselog1")
19877   (set_attr "prefix_rep" "1")
19878   (set_attr "prefix_extra" "1")
19879   (set_attr "mode" "DI")])
19880
19881(define_insn "rdpmc"
19882  [(set (match_operand:DI 0 "register_operand" "=A")
19883  	(unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19884			    UNSPECV_RDPMC))]
19885  "!TARGET_64BIT"
19886  "rdpmc"
19887  [(set_attr "type" "other")
19888   (set_attr "length" "2")])
19889
19890(define_insn "rdpmc_rex64"
19891  [(set (match_operand:DI 0 "register_operand" "=a")
19892  	(unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19893			    UNSPECV_RDPMC))
19894   (set (match_operand:DI 1 "register_operand" "=d")
19895	(unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19896  "TARGET_64BIT"
19897  "rdpmc"
19898  [(set_attr "type" "other")
19899   (set_attr "length" "2")])
19900
19901(define_insn "rdtsc"
19902  [(set (match_operand:DI 0 "register_operand" "=A")
19903	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19904  "!TARGET_64BIT"
19905  "rdtsc"
19906  [(set_attr "type" "other")
19907   (set_attr "length" "2")])
19908
19909(define_insn "rdtsc_rex64"
19910  [(set (match_operand:DI 0 "register_operand" "=a")
19911	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19912   (set (match_operand:DI 1 "register_operand" "=d")
19913	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19914  "TARGET_64BIT"
19915  "rdtsc"
19916  [(set_attr "type" "other")
19917   (set_attr "length" "2")])
19918
19919(define_insn "rdtscp"
19920  [(set (match_operand:DI 0 "register_operand" "=A")
19921	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19922   (set (match_operand:SI 1 "register_operand" "=c")
19923	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19924  "!TARGET_64BIT"
19925  "rdtscp"
19926  [(set_attr "type" "other")
19927   (set_attr "length" "3")])
19928
19929(define_insn "rdtscp_rex64"
19930  [(set (match_operand:DI 0 "register_operand" "=a")
19931	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19932   (set (match_operand:DI 1 "register_operand" "=d")
19933	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19934   (set (match_operand:SI 2 "register_operand" "=c")
19935	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19936  "TARGET_64BIT"
19937  "rdtscp"
19938  [(set_attr "type" "other")
19939   (set_attr "length" "3")])
19940
19941;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19942;;
19943;; FXSR, XSAVE and XSAVEOPT instructions
19944;;
19945;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19946
19947(define_insn "fxsave"
19948  [(set (match_operand:BLK 0 "memory_operand" "=m")
19949	(unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19950  "TARGET_FXSR"
19951  "fxsave\t%0"
19952  [(set_attr "type" "other")
19953   (set_attr "memory" "store")
19954   (set (attr "length")
19955        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19956
19957(define_insn "fxsave64"
19958  [(set (match_operand:BLK 0 "memory_operand" "=m")
19959	(unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19960  "TARGET_64BIT && TARGET_FXSR"
19961  "fxsave64\t%0"
19962  [(set_attr "type" "other")
19963   (set_attr "memory" "store")
19964   (set (attr "length")
19965        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19966
19967(define_insn "fxrstor"
19968  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19969		    UNSPECV_FXRSTOR)]
19970  "TARGET_FXSR"
19971  "fxrstor\t%0"
19972  [(set_attr "type" "other")
19973   (set_attr "memory" "load")
19974   (set (attr "length")
19975        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19976
19977(define_insn "fxrstor64"
19978  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19979		    UNSPECV_FXRSTOR64)]
19980  "TARGET_64BIT && TARGET_FXSR"
19981  "fxrstor64\t%0"
19982  [(set_attr "type" "other")
19983   (set_attr "memory" "load")
19984   (set (attr "length")
19985        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19986
19987(define_int_iterator ANY_XSAVE
19988	[UNSPECV_XSAVE
19989	 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19990	 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19991	 (UNSPECV_XSAVES "TARGET_XSAVES")])
19992
19993(define_int_iterator ANY_XSAVE64
19994	[UNSPECV_XSAVE64
19995	 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19996	 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19997	 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19998
19999(define_int_attr xsave
20000	[(UNSPECV_XSAVE "xsave")
20001	 (UNSPECV_XSAVE64 "xsave64")
20002	 (UNSPECV_XSAVEOPT "xsaveopt")
20003	 (UNSPECV_XSAVEOPT64 "xsaveopt64")
20004	 (UNSPECV_XSAVEC "xsavec")
20005	 (UNSPECV_XSAVEC64 "xsavec64")
20006	 (UNSPECV_XSAVES "xsaves")
20007	 (UNSPECV_XSAVES64 "xsaves64")])
20008
20009(define_int_iterator ANY_XRSTOR
20010	[UNSPECV_XRSTOR
20011	 (UNSPECV_XRSTORS "TARGET_XSAVES")])
20012
20013(define_int_iterator ANY_XRSTOR64
20014	[UNSPECV_XRSTOR64
20015	 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20016
20017(define_int_attr xrstor
20018	[(UNSPECV_XRSTOR "xrstor")
20019	 (UNSPECV_XRSTOR64 "xrstor")
20020	 (UNSPECV_XRSTORS "xrstors")
20021	 (UNSPECV_XRSTORS64 "xrstors")])
20022
20023(define_insn "<xsave>"
20024  [(set (match_operand:BLK 0 "memory_operand" "=m")
20025	(unspec_volatile:BLK
20026	 [(match_operand:DI 1 "register_operand" "A")]
20027	 ANY_XSAVE))]
20028  "!TARGET_64BIT && TARGET_XSAVE"
20029  "<xsave>\t%0"
20030  [(set_attr "type" "other")
20031   (set_attr "memory" "store")
20032   (set (attr "length")
20033        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20034
20035(define_insn "<xsave>_rex64"
20036  [(set (match_operand:BLK 0 "memory_operand" "=m")
20037	(unspec_volatile:BLK
20038	 [(match_operand:SI 1 "register_operand" "a")
20039	  (match_operand:SI 2 "register_operand" "d")]
20040	 ANY_XSAVE))]
20041  "TARGET_64BIT && TARGET_XSAVE"
20042  "<xsave>\t%0"
20043  [(set_attr "type" "other")
20044   (set_attr "memory" "store")
20045   (set (attr "length")
20046        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20047
20048(define_insn "<xsave>"
20049  [(set (match_operand:BLK 0 "memory_operand" "=m")
20050	(unspec_volatile:BLK
20051	 [(match_operand:SI 1 "register_operand" "a")
20052	  (match_operand:SI 2 "register_operand" "d")]
20053	 ANY_XSAVE64))]
20054  "TARGET_64BIT && TARGET_XSAVE"
20055  "<xsave>\t%0"
20056  [(set_attr "type" "other")
20057   (set_attr "memory" "store")
20058   (set (attr "length")
20059        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20060
20061(define_insn "<xrstor>"
20062   [(unspec_volatile:BLK
20063     [(match_operand:BLK 0 "memory_operand" "m")
20064      (match_operand:DI 1 "register_operand" "A")]
20065     ANY_XRSTOR)]
20066  "!TARGET_64BIT && TARGET_XSAVE"
20067  "<xrstor>\t%0"
20068  [(set_attr "type" "other")
20069   (set_attr "memory" "load")
20070   (set (attr "length")
20071        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20072
20073(define_insn "<xrstor>_rex64"
20074   [(unspec_volatile:BLK
20075     [(match_operand:BLK 0 "memory_operand" "m")
20076      (match_operand:SI 1 "register_operand" "a")
20077      (match_operand:SI 2 "register_operand" "d")]
20078     ANY_XRSTOR)]
20079  "TARGET_64BIT && TARGET_XSAVE"
20080  "<xrstor>\t%0"
20081  [(set_attr "type" "other")
20082   (set_attr "memory" "load")
20083   (set (attr "length")
20084        (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20085
20086(define_insn "<xrstor>64"
20087   [(unspec_volatile:BLK
20088     [(match_operand:BLK 0 "memory_operand" "m")
20089      (match_operand:SI 1 "register_operand" "a")
20090      (match_operand:SI 2 "register_operand" "d")]
20091     ANY_XRSTOR64)]
20092  "TARGET_64BIT && TARGET_XSAVE"
20093  "<xrstor>64\t%0"
20094  [(set_attr "type" "other")
20095   (set_attr "memory" "load")
20096   (set (attr "length")
20097        (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20098
20099(define_insn "xsetbv"
20100  [(unspec_volatile:SI
20101	 [(match_operand:SI 0 "register_operand" "c")
20102	  (match_operand:DI 1 "register_operand" "A")]
20103	 UNSPECV_XSETBV)]
20104  "!TARGET_64BIT && TARGET_XSAVE"
20105  "xsetbv"
20106  [(set_attr "type" "other")])
20107
20108(define_insn "xsetbv_rex64"
20109  [(unspec_volatile:SI
20110	 [(match_operand:SI 0 "register_operand" "c")
20111	  (match_operand:SI 1 "register_operand" "a")
20112	  (match_operand:SI 2 "register_operand" "d")]
20113	 UNSPECV_XSETBV)]
20114  "TARGET_64BIT && TARGET_XSAVE"
20115  "xsetbv"
20116  [(set_attr "type" "other")])
20117
20118(define_insn "xgetbv"
20119  [(set (match_operand:DI 0 "register_operand" "=A")
20120  	(unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20121			    UNSPECV_XGETBV))]
20122  "!TARGET_64BIT && TARGET_XSAVE"
20123  "xgetbv"
20124  [(set_attr "type" "other")])
20125
20126(define_insn "xgetbv_rex64"
20127  [(set (match_operand:DI 0 "register_operand" "=a")
20128  	(unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20129			    UNSPECV_XGETBV))
20130   (set (match_operand:DI 1 "register_operand" "=d")
20131	(unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20132  "TARGET_64BIT && TARGET_XSAVE"
20133  "xgetbv"
20134  [(set_attr "type" "other")])
20135
20136;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20137;;
20138;; Floating-point instructions for atomic compound assignments
20139;;
20140;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20141
20142; Clobber all floating-point registers on environment save and restore
20143; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20144(define_insn "fnstenv"
20145  [(set (match_operand:BLK 0 "memory_operand" "=m")
20146	(unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20147   (clobber (reg:HI FPCR_REG))
20148   (clobber (reg:XF ST0_REG))
20149   (clobber (reg:XF ST1_REG))
20150   (clobber (reg:XF ST2_REG))
20151   (clobber (reg:XF ST3_REG))
20152   (clobber (reg:XF ST4_REG))
20153   (clobber (reg:XF ST5_REG))
20154   (clobber (reg:XF ST6_REG))
20155   (clobber (reg:XF ST7_REG))]
20156  "TARGET_80387"
20157  "fnstenv\t%0"
20158  [(set_attr "type" "other")
20159   (set_attr "memory" "store")
20160   (set (attr "length")
20161        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20162
20163(define_insn "fldenv"
20164  [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20165		    UNSPECV_FLDENV)
20166   (clobber (reg:CCFP FPSR_REG))
20167   (clobber (reg:HI FPCR_REG))
20168   (clobber (reg:XF ST0_REG))
20169   (clobber (reg:XF ST1_REG))
20170   (clobber (reg:XF ST2_REG))
20171   (clobber (reg:XF ST3_REG))
20172   (clobber (reg:XF ST4_REG))
20173   (clobber (reg:XF ST5_REG))
20174   (clobber (reg:XF ST6_REG))
20175   (clobber (reg:XF ST7_REG))]
20176  "TARGET_80387"
20177  "fldenv\t%0"
20178  [(set_attr "type" "other")
20179   (set_attr "memory" "load")
20180   (set (attr "length")
20181        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20182
20183(define_insn "fnstsw"
20184  [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20185	(unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20186  "TARGET_80387"
20187  "fnstsw\t%0"
20188  [(set_attr "type" "other,other")
20189   (set_attr "memory" "none,store")
20190   (set (attr "length")
20191        (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20192
20193(define_insn "fnclex"
20194  [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20195  "TARGET_80387"
20196  "fnclex"
20197  [(set_attr "type" "other")
20198   (set_attr "memory" "none")
20199   (set_attr "length" "2")])
20200
20201;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20202;;
20203;; LWP instructions
20204;;
20205;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20206
20207(define_expand "lwp_llwpcb"
20208  [(unspec_volatile [(match_operand 0 "register_operand")]
20209		    UNSPECV_LLWP_INTRINSIC)]
20210  "TARGET_LWP")
20211
20212(define_insn "*lwp_llwpcb<mode>1"
20213  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20214		    UNSPECV_LLWP_INTRINSIC)]
20215  "TARGET_LWP"
20216  "llwpcb\t%0"
20217  [(set_attr "type" "lwp")
20218   (set_attr "mode" "<MODE>")
20219   (set_attr "length" "5")])
20220
20221(define_expand "lwp_slwpcb"
20222  [(set (match_operand 0 "register_operand")
20223	(unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20224  "TARGET_LWP"
20225{
20226  rtx (*insn)(rtx);
20227
20228  insn = (Pmode == DImode
20229	  ? gen_lwp_slwpcbdi
20230	  : gen_lwp_slwpcbsi);
20231
20232  emit_insn (insn (operands[0]));
20233  DONE;
20234})
20235
20236(define_insn "lwp_slwpcb<mode>"
20237  [(set (match_operand:P 0 "register_operand" "=r")
20238	(unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20239  "TARGET_LWP"
20240  "slwpcb\t%0"
20241  [(set_attr "type" "lwp")
20242   (set_attr "mode" "<MODE>")
20243   (set_attr "length" "5")])
20244
20245(define_expand "lwp_lwpval<mode>3"
20246  [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20247    	    	     (match_operand:SI 2 "nonimmediate_operand")
20248		     (match_operand:SI 3 "const_int_operand")]
20249		    UNSPECV_LWPVAL_INTRINSIC)]
20250  "TARGET_LWP"
20251  ;; Avoid unused variable warning.
20252  "(void) operands[0];")
20253
20254(define_insn "*lwp_lwpval<mode>3_1"
20255  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20256    	    	     (match_operand:SI 1 "nonimmediate_operand" "rm")
20257		     (match_operand:SI 2 "const_int_operand" "i")]
20258		    UNSPECV_LWPVAL_INTRINSIC)]
20259  "TARGET_LWP"
20260  "lwpval\t{%2, %1, %0|%0, %1, %2}"
20261  [(set_attr "type" "lwp")
20262   (set_attr "mode" "<MODE>")
20263   (set (attr "length")
20264        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20265
20266(define_expand "lwp_lwpins<mode>3"
20267  [(set (reg:CCC FLAGS_REG)
20268	(unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20269			      (match_operand:SI 2 "nonimmediate_operand")
20270			      (match_operand:SI 3 "const_int_operand")]
20271			     UNSPECV_LWPINS_INTRINSIC))
20272   (set (match_operand:QI 0 "nonimmediate_operand")
20273	(eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20274  "TARGET_LWP")
20275
20276(define_insn "*lwp_lwpins<mode>3_1"
20277  [(set (reg:CCC FLAGS_REG)
20278	(unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20279			      (match_operand:SI 1 "nonimmediate_operand" "rm")
20280			      (match_operand:SI 2 "const_int_operand" "i")]
20281			     UNSPECV_LWPINS_INTRINSIC))]
20282  "TARGET_LWP"
20283  "lwpins\t{%2, %1, %0|%0, %1, %2}"
20284  [(set_attr "type" "lwp")
20285   (set_attr "mode" "<MODE>")
20286   (set (attr "length")
20287        (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20288
20289(define_int_iterator RDFSGSBASE
20290	[UNSPECV_RDFSBASE
20291	 UNSPECV_RDGSBASE])
20292
20293(define_int_iterator WRFSGSBASE
20294	[UNSPECV_WRFSBASE
20295	 UNSPECV_WRGSBASE])
20296
20297(define_int_attr fsgs
20298	[(UNSPECV_RDFSBASE "fs")
20299	 (UNSPECV_RDGSBASE "gs")
20300	 (UNSPECV_WRFSBASE "fs")
20301	 (UNSPECV_WRGSBASE "gs")])
20302
20303(define_insn "rd<fsgs>base<mode>"
20304  [(set (match_operand:SWI48 0 "register_operand" "=r")
20305	(unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20306  "TARGET_64BIT && TARGET_FSGSBASE"
20307  "rd<fsgs>base\t%0"
20308  [(set_attr "type" "other")
20309   (set_attr "prefix_extra" "2")])
20310
20311(define_insn "wr<fsgs>base<mode>"
20312  [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20313		    WRFSGSBASE)]
20314  "TARGET_64BIT && TARGET_FSGSBASE"
20315  "wr<fsgs>base\t%0"
20316  [(set_attr "type" "other")
20317   (set_attr "prefix_extra" "2")])
20318
20319(define_insn "rdrand<mode>_1"
20320  [(set (match_operand:SWI248 0 "register_operand" "=r")
20321	(unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20322   (set (reg:CCC FLAGS_REG)
20323	(unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20324  "TARGET_RDRND"
20325  "rdrand\t%0"
20326  [(set_attr "type" "other")
20327   (set_attr "prefix_extra" "1")])
20328
20329(define_insn "rdseed<mode>_1"
20330  [(set (match_operand:SWI248 0 "register_operand" "=r")
20331	(unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20332   (set (reg:CCC FLAGS_REG)
20333	(unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20334  "TARGET_RDSEED"
20335  "rdseed\t%0"
20336  [(set_attr "type" "other")
20337   (set_attr "prefix_extra" "1")])
20338
20339(define_expand "pause"
20340  [(set (match_dup 0)
20341	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20342  ""
20343{
20344  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20345  MEM_VOLATILE_P (operands[0]) = 1;
20346})
20347
20348;; Use "rep; nop", instead of "pause", to support older assemblers.
20349;; They have the same encoding.
20350(define_insn "*pause"
20351  [(set (match_operand:BLK 0)
20352	(unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20353  ""
20354  "rep%; nop"
20355  [(set_attr "length" "2")
20356   (set_attr "memory" "unknown")])
20357
20358;; CET instructions
20359(define_insn "rdssp<mode>"
20360  [(set (match_operand:SWI48x 0 "register_operand" "=r")
20361	(unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20362  "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20363  "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20364  [(set_attr "length" "6")
20365   (set_attr "type" "other")])
20366
20367(define_insn "incssp<mode>"
20368  [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20369		   UNSPECV_INCSSP)]
20370  "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20371  "incssp<mskmodesuffix>\t%0"
20372  [(set_attr "length" "4")
20373   (set_attr "type" "other")])
20374
20375(define_insn "saveprevssp"
20376  [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20377  "TARGET_SHSTK"
20378  "saveprevssp"
20379  [(set_attr "length" "5")
20380   (set_attr "type" "other")])
20381
20382(define_insn "rstorssp"
20383  [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20384		   UNSPECV_RSTORSSP)]
20385  "TARGET_SHSTK"
20386  "rstorssp\t%0"
20387  [(set_attr "length" "5")
20388   (set_attr "type" "other")])
20389
20390(define_insn "wrss<mode>"
20391  [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20392		     (match_operand:SWI48x 1 "memory_operand" "m")]
20393		   UNSPECV_WRSS)]
20394  "TARGET_SHSTK"
20395  "wrss<mskmodesuffix>\t%0, %1"
20396  [(set_attr "length" "3")
20397   (set_attr "type" "other")])
20398
20399(define_insn "wruss<mode>"
20400  [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20401		     (match_operand:SWI48x 1 "memory_operand" "m")]
20402		   UNSPECV_WRUSS)]
20403  "TARGET_SHSTK"
20404  "wruss<mskmodesuffix>\t%0, %1"
20405  [(set_attr "length" "4")
20406   (set_attr "type" "other")])
20407
20408(define_insn "setssbsy"
20409  [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20410  "TARGET_SHSTK"
20411  "setssbsy"
20412  [(set_attr "length" "4")
20413   (set_attr "type" "other")])
20414
20415(define_insn "clrssbsy"
20416  [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20417		   UNSPECV_CLRSSBSY)]
20418  "TARGET_SHSTK"
20419  "clrssbsy\t%0"
20420  [(set_attr "length" "4")
20421   (set_attr "type" "other")])
20422
20423(define_insn "nop_endbr"
20424  [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20425  "(flag_cf_protection & CF_BRANCH)"
20426  "*
20427{ return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20428  [(set_attr "length" "4")
20429   (set_attr "length_immediate" "0")
20430   (set_attr "modrm" "0")])
20431
20432;; For RTM support
20433(define_expand "xbegin"
20434  [(set (match_operand:SI 0 "register_operand")
20435	(unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20436  "TARGET_RTM"
20437{
20438  rtx_code_label *label = gen_label_rtx ();
20439
20440  /* xbegin is emitted as jump_insn, so reload won't be able
20441     to reload its operand.  Force the value into AX hard register.  */
20442  rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20443  emit_move_insn (ax_reg, constm1_rtx);
20444
20445  emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20446
20447  emit_label (label);
20448  LABEL_NUSES (label) = 1;
20449
20450  emit_move_insn (operands[0], ax_reg);
20451
20452  DONE;
20453})
20454
20455(define_insn "xbegin_1"
20456  [(set (pc)
20457	(if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20458			  (const_int 0))
20459		      (label_ref (match_operand 1))
20460		      (pc)))
20461   (set (match_operand:SI 0 "register_operand" "+a")
20462	(unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20463  "TARGET_RTM"
20464  "xbegin\t%l1"
20465  [(set_attr "type" "other")
20466   (set_attr "length" "6")])
20467
20468(define_insn "xend"
20469  [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20470  "TARGET_RTM"
20471  "xend"
20472  [(set_attr "type" "other")
20473   (set_attr "length" "3")])
20474
20475(define_insn "xabort"
20476  [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20477		    UNSPECV_XABORT)]
20478  "TARGET_RTM"
20479  "xabort\t%0"
20480  [(set_attr "type" "other")
20481   (set_attr "length" "3")])
20482
20483(define_expand "xtest"
20484  [(set (match_operand:QI 0 "register_operand")
20485	(unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20486  "TARGET_RTM"
20487{
20488  emit_insn (gen_xtest_1 ());
20489
20490  ix86_expand_setcc (operands[0], NE,
20491		     gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20492  DONE;
20493})
20494
20495(define_insn "xtest_1"
20496  [(set (reg:CCZ FLAGS_REG)
20497	(unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20498  "TARGET_RTM"
20499  "xtest"
20500  [(set_attr "type" "other")
20501   (set_attr "length" "3")])
20502
20503(define_insn "clwb"
20504  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20505                   UNSPECV_CLWB)]
20506  "TARGET_CLWB"
20507  "clwb\t%a0"
20508  [(set_attr "type" "sse")
20509   (set_attr "atom_sse_attr" "fence")
20510   (set_attr "memory" "unknown")])
20511
20512(define_insn "clflushopt"
20513  [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20514                   UNSPECV_CLFLUSHOPT)]
20515  "TARGET_CLFLUSHOPT"
20516  "clflushopt\t%a0"
20517  [(set_attr "type" "sse")
20518   (set_attr "atom_sse_attr" "fence")
20519   (set_attr "memory" "unknown")])
20520
20521;; MONITORX and MWAITX
20522(define_insn "mwaitx"
20523  [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20524		     (match_operand:SI 1 "register_operand" "a")
20525		     (match_operand:SI 2 "register_operand" "b")]
20526		   UNSPECV_MWAITX)]
20527  "TARGET_MWAITX"
20528;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20529;; Since 32bit register operands are implicitly zero extended to 64bit,
20530;; we only need to set up 32bit registers.
20531  "mwaitx"
20532  [(set_attr "length" "3")])
20533
20534(define_insn "monitorx_<mode>"
20535  [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20536		     (match_operand:SI 1 "register_operand" "c")
20537		     (match_operand:SI 2 "register_operand" "d")]
20538		   UNSPECV_MONITORX)]
20539  "TARGET_MWAITX"
20540;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20541;; RCX and RDX are used.  Since 32bit register operands are implicitly
20542;; zero extended to 64bit, we only need to set up 32bit registers.
20543  "%^monitorx"
20544  [(set (attr "length")
20545     (symbol_ref ("(Pmode != word_mode) + 3")))])
20546
20547;; CLZERO
20548(define_insn "clzero_<mode>"
20549  [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20550                   UNSPECV_CLZERO)]
20551  "TARGET_CLZERO"
20552  "clzero"
20553  [(set_attr "length" "3")
20554  (set_attr "memory" "unknown")])
20555
20556;; MPX instructions
20557
20558(define_expand "<mode>_mk"
20559  [(set (match_operand:BND 0 "register_operand")
20560	(unspec:BND
20561	  [(mem:<bnd_ptr>
20562	   (match_par_dup 3
20563	     [(match_operand:<bnd_ptr> 1 "register_operand")
20564	      (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20565	  UNSPEC_BNDMK))]
20566  "TARGET_MPX"
20567{
20568  operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20569						  operands[2]),
20570				UNSPEC_BNDMK_ADDR);
20571})
20572
20573(define_insn "*<mode>_mk"
20574  [(set (match_operand:BND 0 "register_operand" "=w")
20575	(unspec:BND
20576	  [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20577	     [(unspec:<bnd_ptr>
20578		[(match_operand:<bnd_ptr> 1 "register_operand" "r")
20579		 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20580	        UNSPEC_BNDMK_ADDR)])]
20581	  UNSPEC_BNDMK))]
20582  "TARGET_MPX"
20583  "bndmk\t{%3, %0|%0, %3}"
20584  [(set_attr "type" "mpxmk")])
20585
20586(define_expand "mov<mode>"
20587  [(set (match_operand:BND 0 "general_operand")
20588	(match_operand:BND 1 "general_operand"))]
20589  "TARGET_MPX"
20590  "ix86_expand_move (<MODE>mode, operands); DONE;")
20591
20592(define_insn "*mov<mode>_internal_mpx"
20593  [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20594	(match_operand:BND 1 "general_operand" "wm,w"))]
20595  "TARGET_MPX"
20596  "bndmov\t{%1, %0|%0, %1}"
20597  [(set_attr "type" "mpxmov")])
20598
20599(define_expand "<mode>_<bndcheck>"
20600  [(parallel
20601     [(unspec
20602	[(match_operand:BND 0 "register_operand")
20603	 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20604      (set (match_dup 2)
20605	   (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20606  "TARGET_MPX"
20607{
20608  operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20609  MEM_VOLATILE_P (operands[2]) = 1;
20610})
20611
20612(define_insn "*<mode>_<bndcheck>"
20613  [(unspec
20614     [(match_operand:BND 0 "register_operand" "w")
20615      (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20616   (set (match_operand:BLK 2 "bnd_mem_operator")
20617	(unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20618  "TARGET_MPX"
20619  "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20620  [(set_attr "type" "mpxchk")])
20621
20622(define_expand "<mode>_ldx"
20623  [(parallel
20624     [(set (match_operand:BND 0 "register_operand")
20625	   (unspec:BND
20626	     [(mem:<bnd_ptr>
20627		(match_par_dup 3
20628		  [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20629		   (match_operand:<bnd_ptr> 2 "register_operand")]))]
20630	     UNSPEC_BNDLDX))
20631      (use (mem:BLK (match_dup 1)))])]
20632  "TARGET_MPX"
20633{
20634  /* Avoid registers which cannot be used as index.  */
20635  if (!index_register_operand (operands[2], Pmode))
20636    operands[2] = copy_addr_to_reg (operands[2]);
20637
20638  operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20639						  operands[2]),
20640				UNSPEC_BNDLDX_ADDR);
20641})
20642
20643(define_insn "*<mode>_ldx"
20644  [(set (match_operand:BND 0 "register_operand" "=w")
20645	(unspec:BND
20646	  [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20647	     [(unspec:<bnd_ptr>
20648		[(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20649		 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20650		UNSPEC_BNDLDX_ADDR)])]
20651	  UNSPEC_BNDLDX))
20652   (use (mem:BLK (match_dup 1)))]
20653  "TARGET_MPX"
20654  "bndldx\t{%3, %0|%0, %3}"
20655  [(set_attr "type" "mpxld")])
20656
20657(define_expand "<mode>_stx"
20658  [(parallel
20659     [(unspec
20660	[(mem:<bnd_ptr>
20661	   (match_par_dup 3
20662	     [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20663	      (match_operand:<bnd_ptr> 1 "register_operand")]))
20664	 (match_operand:BND 2 "register_operand")]
20665	UNSPEC_BNDSTX)
20666      (set (match_dup 4)
20667	   (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20668  "TARGET_MPX"
20669{
20670  /* Avoid registers which cannot be used as index.  */
20671  if (!index_register_operand (operands[1], Pmode))
20672    operands[1] = copy_addr_to_reg (operands[1]);
20673
20674  operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20675						  operands[1]),
20676				UNSPEC_BNDLDX_ADDR);
20677  operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20678  MEM_VOLATILE_P (operands[4]) = 1;
20679})
20680
20681(define_insn "*<mode>_stx"
20682  [(unspec
20683     [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20684	[(unspec:<bnd_ptr>
20685	   [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20686	    (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20687	   UNSPEC_BNDLDX_ADDR)])
20688	 (match_operand:BND 2 "register_operand" "w")]
20689	UNSPEC_BNDSTX)
20690   (set (match_operand:BLK 4 "bnd_mem_operator")
20691	(unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20692  "TARGET_MPX"
20693  "bndstx\t{%2, %3|%3, %2}"
20694  [(set_attr "type" "mpxst")])
20695
20696(define_insn "move_size_reloc_<mode>"
20697  [(set (match_operand:SWI48 0 "register_operand" "=r")
20698	(unspec:SWI48
20699	  [(match_operand:SWI48 1 "symbol_operand")]
20700	UNSPEC_SIZEOF))]
20701  "TARGET_MPX"
20702{
20703  if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20704    return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20705  else
20706    return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20707}
20708  [(set_attr "type" "imov")
20709   (set_attr "mode" "<MODE>")])
20710
20711;; RDPKRU and WRPKRU
20712
20713(define_expand "rdpkru"
20714  [(parallel
20715     [(set (match_operand:SI 0 "register_operand")
20716	   (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20717      (set (match_dup 2) (const_int 0))])]
20718  "TARGET_PKU"
20719{
20720  operands[1] = force_reg (SImode, const0_rtx);
20721  operands[2] = gen_reg_rtx (SImode);
20722})
20723
20724(define_insn "*rdpkru"
20725  [(set (match_operand:SI 0 "register_operand" "=a")
20726	(unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20727			    UNSPECV_PKU))
20728   (set (match_operand:SI 1 "register_operand" "=d")
20729	(const_int 0))]
20730  "TARGET_PKU"
20731  "rdpkru"
20732  [(set_attr "type" "other")])
20733
20734(define_expand "wrpkru"
20735  [(unspec_volatile:SI
20736     [(match_operand:SI 0 "register_operand")
20737      (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20738  "TARGET_PKU"
20739{
20740  operands[1] = force_reg (SImode, const0_rtx);
20741  operands[2] = force_reg (SImode, const0_rtx);
20742})
20743
20744(define_insn "*wrpkru"
20745  [(unspec_volatile:SI
20746     [(match_operand:SI 0 "register_operand" "a")
20747      (match_operand:SI 1 "register_operand" "d")
20748      (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20749  "TARGET_PKU"
20750  "wrpkru"
20751  [(set_attr "type" "other")])
20752
20753(define_insn "rdpid"
20754  [(set (match_operand:SI 0 "register_operand" "=r")
20755	(unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20756  "!TARGET_64BIT && TARGET_RDPID"
20757  "rdpid\t%0"
20758  [(set_attr "type" "other")])
20759
20760(define_insn "rdpid_rex64"
20761  [(set (match_operand:DI 0 "register_operand" "=r")
20762	(unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20763  "TARGET_64BIT && TARGET_RDPID"
20764  "rdpid\t%0"
20765  [(set_attr "type" "other")])
20766
20767;; Intirinsics for > i486
20768
20769(define_insn "wbinvd"
20770  [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20771  ""
20772  "wbinvd"
20773  [(set_attr "type" "other")])
20774
20775(define_insn "wbnoinvd"
20776  [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20777  "TARGET_WBNOINVD"
20778  "wbnoinvd"
20779  [(set_attr "type" "other")])
20780
20781(define_insn "movdiri<mode>"
20782  [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m")
20783	(match_operand:SWI48 1 "register_operand" "r")]
20784		   UNSPECV_MOVDIRI)]
20785  "TARGET_MOVDIRI"
20786  "movdiri\t{%1, %0|%0, %1}"
20787  [(set_attr "type" "other")])
20788
20789(define_insn "movdir64b_<mode>"
20790  [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r")
20791	(match_operand:XI 1 "memory_operand")]
20792		 UNSPECV_MOVDIR64B)]
20793  "TARGET_MOVDIR64B"
20794  "movdir64b\t{%1, %0|%0, %1}"
20795  [(set_attr "type" "other")])
20796
20797(include "mmx.md")
20798(include "sse.md")
20799(include "sync.md")
20800