i386: Set cfun->machine->max_used_stack_alignment if needed
[official-gcc.git] / gcc / config / i386 / i386.md
blob73948c12618df2c06846574d63775b5d2a79412a
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.
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.
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/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
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 NOTRACK prefix for jxx/call/ret instructions if required.
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
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
91   ;; TLS support
92   UNSPEC_TP
93   UNSPEC_TLS_GD
94   UNSPEC_TLS_LD_BASE
95   UNSPEC_TLSDESC
96   UNSPEC_TLS_IE_SUN
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
118   ;; For SSE/MMX support:
119   UNSPEC_FIX_NOTRUNC
120   UNSPEC_MASKMOV
121   UNSPEC_MOVMSK
122   UNSPEC_RCP
123   UNSPEC_RSQRT
124   UNSPEC_PSADBW
126   ;; Generic math support
127   UNSPEC_COPYSIGN
128   UNSPEC_IEEE_MIN       ; not commutative
129   UNSPEC_IEEE_MAX       ; not commutative
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
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
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
163   UNSPEC_C2_FLAG
164   UNSPEC_FXAM_MEM
166   ;; SSP patterns
167   UNSPEC_SP_SET
168   UNSPEC_SP_TEST
170   ;; For ROUND support
171   UNSPEC_ROUND
173   ;; For CRC32 support
174   UNSPEC_CRC32
176   ;; For LZCNT suppoprt
177   UNSPEC_LZCNT
179   ;; For BMI support
180   UNSPEC_TZCNT
181   UNSPEC_BEXTR
183   ;; For BMI2 support
184   UNSPEC_PDEP
185   UNSPEC_PEXT
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
197   ;; IRET support
198   UNSPEC_INTERRUPT_RETURN
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
243   ;; For atomic compound assignments.
244   UNSPECV_FNSTENV
245   UNSPECV_FLDENV
246   UNSPECV_FNSTSW
247   UNSPECV_FNCLEX
249   ;; For RDRAND support
250   UNSPECV_RDRAND
252   ;; For RDSEED support
253   UNSPECV_RDSEED
255   ;; For RTM support
256   UNSPECV_XBEGIN
257   UNSPECV_XEND
258   UNSPECV_XABORT
259   UNSPECV_XTEST
261   UNSPECV_NLGR
263   ;; For CLWB support
264   UNSPECV_CLWB
266   ;; For CLFLUSHOPT support
267   UNSPECV_CLFLUSHOPT
269   ;; For MONITORX and MWAITX support 
270   UNSPECV_MONITORX
271   UNSPECV_MWAITX
273   ;; For CLZERO support
274   UNSPECV_CLZERO
276   ;; For RDPKRU and WRPKRU support
277   UNSPECV_PKU
279   ;; For RDPID support
280   UNSPECV_RDPID
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
293   ;; For MOVDIRI and MOVDIR64B support
294   UNSPECV_MOVDIRI
295   UNSPECV_MOVDIR64B
297   ;; For WAITPKG support
298   UNSPECV_UMWAIT
299   UNSPECV_UMONITOR
300   UNSPECV_TPAUSE
302   ;; For CLDEMOTE support
303   UNSPECV_CLDEMOTE
305   ;; For Speculation Barrier support
306   UNSPECV_SPECULATION_BARRIER
309 ;; Constants to represent rounding modes in the ROUND instruction
310 (define_constants
311   [(ROUND_FLOOR                 0x1)
312    (ROUND_CEIL                  0x2)
313    (ROUND_TRUNC                 0x3)
314    (ROUND_MXCSR                 0x4)
315    (ROUND_NO_EXC                0x8)
316   ])
318 ;; Constants to represent AVX512F embeded rounding
319 (define_constants
320   [(ROUND_NEAREST_INT                   0)
321    (ROUND_NEG_INF                       1)
322    (ROUND_POS_INF                       2)
323    (ROUND_ZERO                          3)
324    (NO_ROUND                            4)
325    (ROUND_SAE                           8)
326   ])
328 ;; Constants to represent pcomtrue/pcomfalse variants
329 (define_constants
330   [(PCOM_FALSE                  0)
331    (PCOM_TRUE                   1)
332    (COM_FALSE_S                 2)
333    (COM_FALSE_P                 3)
334    (COM_TRUE_S                  4)
335    (COM_TRUE_P                  5)
336   ])
338 ;; Constants used in the XOP pperm instruction
339 (define_constants
340   [(PPERM_SRC                   0x00)   /* copy source */
341    (PPERM_INVERT                0x20)   /* invert source */
342    (PPERM_REVERSE               0x40)   /* bit reverse source */
343    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
344    (PPERM_ZERO                  0x80)   /* all 0's */
345    (PPERM_ONES                  0xa0)   /* all 1's */
346    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
347    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
348    (PPERM_SRC1                  0x00)   /* use first source byte */
349    (PPERM_SRC2                  0x10)   /* use second source byte */
350    ])
352 ;; Registers by name.
353 (define_constants
354   [(AX_REG                       0)
355    (DX_REG                       1)
356    (CX_REG                       2)
357    (BX_REG                       3)
358    (SI_REG                       4)
359    (DI_REG                       5)
360    (BP_REG                       6)
361    (SP_REG                       7)
362    (ST0_REG                      8)
363    (ST1_REG                      9)
364    (ST2_REG                     10)
365    (ST3_REG                     11)
366    (ST4_REG                     12)
367    (ST5_REG                     13)
368    (ST6_REG                     14)
369    (ST7_REG                     15)
370    (ARGP_REG                    16)
371    (FLAGS_REG                   17)
372    (FPSR_REG                    18)
373    (FPCR_REG                    19)
374    (FRAME_REG                   20)
375    (XMM0_REG                    21)
376    (XMM1_REG                    22)
377    (XMM2_REG                    23)
378    (XMM3_REG                    24)
379    (XMM4_REG                    25)
380    (XMM5_REG                    26)
381    (XMM6_REG                    27)
382    (XMM7_REG                    28)
383    (MM0_REG                     29)
384    (MM1_REG                     30)
385    (MM2_REG                     31)
386    (MM3_REG                     32)
387    (MM4_REG                     33)
388    (MM5_REG                     34)
389    (MM6_REG                     35)
390    (MM7_REG                     36)
391    (R8_REG                      37)
392    (R9_REG                      38)
393    (R10_REG                     39)
394    (R11_REG                     40)
395    (R12_REG                     41)
396    (R13_REG                     42)
397    (R14_REG                     43)
398    (R15_REG                     44)
399    (XMM8_REG                    45)
400    (XMM9_REG                    46)
401    (XMM10_REG                   47)
402    (XMM11_REG                   48)
403    (XMM12_REG                   49)
404    (XMM13_REG                   50)
405    (XMM14_REG                   51)
406    (XMM15_REG                   52)
407    (XMM16_REG                   53)
408    (XMM17_REG                   54)
409    (XMM18_REG                   55)
410    (XMM19_REG                   56)
411    (XMM20_REG                   57)
412    (XMM21_REG                   58)
413    (XMM22_REG                   59)
414    (XMM23_REG                   60)
415    (XMM24_REG                   61)
416    (XMM25_REG                   62)
417    (XMM26_REG                   63)
418    (XMM27_REG                   64)
419    (XMM28_REG                   65)
420    (XMM29_REG                   66)
421    (XMM30_REG                   67)
422    (XMM31_REG                   68)
423    (MASK0_REG                   69)
424    (MASK1_REG                   70)
425    (MASK2_REG                   71)
426    (MASK3_REG                   72)
427    (MASK4_REG                   73)
428    (MASK5_REG                   74)
429    (MASK6_REG                   75)
430    (MASK7_REG                   76)
431    (BND0_REG                    77)
432    (BND1_REG                    78)
433    (BND2_REG                    79)
434    (BND3_REG                    80)
435    (FIRST_PSEUDO_REG            81)
436   ])
438 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
439 ;; from i386.c.
441 ;; In C guard expressions, put expressions which may be compile-time
442 ;; constants first.  This allows for better optimization.  For
443 ;; example, write "TARGET_64BIT && reload_completed", not
444 ;; "reload_completed && TARGET_64BIT".
447 ;; Processor type.
448 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
449                     atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
450                     bdver4,btver2,znver1"
451   (const (symbol_ref "ix86_schedule")))
453 ;; A basic instruction type.  Refinements due to arguments to be
454 ;; provided in other attributes.
455 (define_attr "type"
456   "other,multi,
457    alu,alu1,negnot,imov,imovx,lea,
458    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
459    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
460    push,pop,call,callv,leave,
461    str,bitmanip,
462    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
463    fxch,fistp,fisttp,frndint,
464    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
465    ssemul,sseimul,ssediv,sselog,sselog1,
466    sseishft,sseishft1,ssecmp,ssecomi,
467    ssecvt,ssecvt1,sseicvt,sseins,
468    sseshuf,sseshuf1,ssemuladd,sse4arg,
469    lwp,mskmov,msklog,
470    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
471    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
472   (const_string "other"))
474 ;; Main data type used by the insn
475 (define_attr "mode"
476   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
477   V2DF,V2SF,V1DF,V8DF"
478   (const_string "unknown"))
480 ;; The CPU unit operations uses.
481 (define_attr "unit" "integer,i387,sse,mmx,unknown"
482   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
483                           fxch,fistp,fisttp,frndint")
484            (const_string "i387")
485          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
486                           ssemul,sseimul,ssediv,sselog,sselog1,
487                           sseishft,sseishft1,ssecmp,ssecomi,
488                           ssecvt,ssecvt1,sseicvt,sseins,
489                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
490            (const_string "sse")
491          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
492            (const_string "mmx")
493          (eq_attr "type" "other")
494            (const_string "unknown")]
495          (const_string "integer")))
497 ;; The (bounding maximum) length of an instruction immediate.
498 (define_attr "length_immediate" ""
499   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
500                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
501                           mpxld,mpxst")
502            (const_int 0)
503          (eq_attr "unit" "i387,sse,mmx")
504            (const_int 0)
505          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
506                           rotate,rotatex,rotate1,imul,icmp,push,pop")
507            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
508          (eq_attr "type" "imov,test")
509            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
510          (eq_attr "type" "call")
511            (if_then_else (match_operand 0 "constant_call_address_operand")
512              (const_int 4)
513              (const_int 0))
514          (eq_attr "type" "callv")
515            (if_then_else (match_operand 1 "constant_call_address_operand")
516              (const_int 4)
517              (const_int 0))
518          ;; We don't know the size before shorten_branches.  Expect
519          ;; the instruction to fit for better scheduling.
520          (eq_attr "type" "ibr")
521            (const_int 1)
522          ]
523          (symbol_ref "/* Update immediate_length and other attributes! */
524                       gcc_unreachable (),1")))
526 ;; The (bounding maximum) length of an instruction address.
527 (define_attr "length_address" ""
528   (cond [(eq_attr "type" "str,other,multi,fxch")
529            (const_int 0)
530          (and (eq_attr "type" "call")
531               (match_operand 0 "constant_call_address_operand"))
532              (const_int 0)
533          (and (eq_attr "type" "callv")
534               (match_operand 1 "constant_call_address_operand"))
535              (const_int 0)
536          ]
537          (symbol_ref "ix86_attr_length_address_default (insn)")))
539 ;; Set when length prefix is used.
540 (define_attr "prefix_data16" ""
541   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
542            (const_int 0)
543          (eq_attr "mode" "HI")
544            (const_int 1)
545          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
546            (const_int 1)
547         ]
548         (const_int 0)))
550 ;; Set when string REP prefix is used.
551 (define_attr "prefix_rep" ""
552   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
553            (const_int 0)
554          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
555            (const_int 1)
556         ]
557         (const_int 0)))
559 ;; Set when 0f opcode prefix is used.
560 (define_attr "prefix_0f" ""
561   (if_then_else
562     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
563                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
564          (eq_attr "unit" "sse,mmx"))
565     (const_int 1)
566     (const_int 0)))
568 ;; Set when REX opcode prefix is used.
569 (define_attr "prefix_rex" ""
570   (cond [(not (match_test "TARGET_64BIT"))
571            (const_int 0)
572          (and (eq_attr "mode" "DI")
573               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
574                    (eq_attr "unit" "!mmx")))
575            (const_int 1)
576          (and (eq_attr "mode" "QI")
577               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
578            (const_int 1)
579          (match_test "x86_extended_reg_mentioned_p (insn)")
580            (const_int 1)
581          (and (eq_attr "type" "imovx")
582               (match_operand:QI 1 "ext_QIreg_operand"))
583            (const_int 1)
584         ]
585         (const_int 0)))
587 ;; There are also additional prefixes in 3DNOW, SSSE3.
588 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
589 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
590 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
591 (define_attr "prefix_extra" ""
592   (cond [(eq_attr "type" "ssemuladd,sse4arg")
593            (const_int 2)
594          (eq_attr "type" "sseiadd1,ssecvt1")
595            (const_int 1)
596         ]
597         (const_int 0)))
599 ;; Prefix used: original, VEX or maybe VEX.
600 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
601   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
602            (const_string "vex")
603          (eq_attr "mode" "XI,V16SF,V8DF")
604            (const_string "evex")
605         ]
606         (const_string "orig")))
608 ;; VEX W bit is used.
609 (define_attr "prefix_vex_w" "" (const_int 0))
611 ;; The length of VEX prefix
612 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
613 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
614 ;; still prefix_0f 1, with prefix_extra 1.
615 (define_attr "length_vex" ""
616   (if_then_else (and (eq_attr "prefix_0f" "1")
617                      (eq_attr "prefix_extra" "0"))
618     (if_then_else (eq_attr "prefix_vex_w" "1")
619       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
620       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
621     (if_then_else (eq_attr "prefix_vex_w" "1")
622       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
623       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
625 ;; 4-bytes evex prefix and 1 byte opcode.
626 (define_attr "length_evex" "" (const_int 5))
628 ;; Set when modrm byte is used.
629 (define_attr "modrm" ""
630   (cond [(eq_attr "type" "str,leave")
631            (const_int 0)
632          (eq_attr "unit" "i387")
633            (const_int 0)
634          (and (eq_attr "type" "incdec")
635               (and (not (match_test "TARGET_64BIT"))
636                    (ior (match_operand:SI 1 "register_operand")
637                         (match_operand:HI 1 "register_operand"))))
638            (const_int 0)
639          (and (eq_attr "type" "push")
640               (not (match_operand 1 "memory_operand")))
641            (const_int 0)
642          (and (eq_attr "type" "pop")
643               (not (match_operand 0 "memory_operand")))
644            (const_int 0)
645          (and (eq_attr "type" "imov")
646               (and (not (eq_attr "mode" "DI"))
647                    (ior (and (match_operand 0 "register_operand")
648                              (match_operand 1 "immediate_operand"))
649                         (ior (and (match_operand 0 "ax_reg_operand")
650                                   (match_operand 1 "memory_displacement_only_operand"))
651                              (and (match_operand 0 "memory_displacement_only_operand")
652                                   (match_operand 1 "ax_reg_operand"))))))
653            (const_int 0)
654          (and (eq_attr "type" "call")
655               (match_operand 0 "constant_call_address_operand"))
656              (const_int 0)
657          (and (eq_attr "type" "callv")
658               (match_operand 1 "constant_call_address_operand"))
659              (const_int 0)
660          (and (eq_attr "type" "alu,alu1,icmp,test")
661               (match_operand 0 "ax_reg_operand"))
662              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
663          ]
664          (const_int 1)))
666 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
667   (cond [(eq_attr "modrm" "0")
668            (const_string "none")
669          (eq_attr "type" "alu,imul,ishift")
670            (const_string "op02")
671          (eq_attr "type" "imov,imovx,lea,alu1,icmp")
672            (const_string "op01")
673          (eq_attr "type" "incdec")
674            (const_string "incdec")
675          (eq_attr "type" "push,pop")
676            (const_string "pushpop")]
677          (const_string "unknown")))
679 ;; The (bounding maximum) length of an instruction in bytes.
680 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
681 ;; Later we may want to split them and compute proper length as for
682 ;; other insns.
683 (define_attr "length" ""
684   (cond [(eq_attr "type" "other,multi,fistp,frndint")
685            (const_int 16)
686          (eq_attr "type" "fcmp")
687            (const_int 4)
688          (eq_attr "unit" "i387")
689            (plus (const_int 2)
690                  (plus (attr "prefix_data16")
691                        (attr "length_address")))
692          (ior (eq_attr "prefix" "evex")
693               (and (ior (eq_attr "prefix" "maybe_evex")
694                         (eq_attr "prefix" "maybe_vex"))
695                    (match_test "TARGET_AVX512F")))
696            (plus (attr "length_evex")
697                  (plus (attr "length_immediate")
698                        (plus (attr "modrm")
699                              (attr "length_address"))))
700          (ior (eq_attr "prefix" "vex")
701               (and (ior (eq_attr "prefix" "maybe_vex")
702                         (eq_attr "prefix" "maybe_evex"))
703                    (match_test "TARGET_AVX")))
704            (plus (attr "length_vex")
705                  (plus (attr "length_immediate")
706                        (plus (attr "modrm")
707                              (attr "length_address"))))]
708          (plus (plus (attr "modrm")
709                      (plus (attr "prefix_0f")
710                            (plus (attr "prefix_rex")
711                                  (plus (attr "prefix_extra")
712                                        (const_int 1)))))
713                (plus (attr "prefix_rep")
714                      (plus (attr "prefix_data16")
715                            (plus (attr "length_immediate")
716                                  (attr "length_address")))))))
718 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
719 ;; `store' if there is a simple memory reference therein, or `unknown'
720 ;; if the instruction is complex.
722 (define_attr "memory" "none,load,store,both,unknown"
723   (cond [(eq_attr "type" "other,multi,str,lwp")
724            (const_string "unknown")
725          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
726            (const_string "none")
727          (eq_attr "type" "fistp,leave")
728            (const_string "both")
729          (eq_attr "type" "frndint")
730            (const_string "load")
731          (eq_attr "type" "mpxld")
732            (const_string "load")
733          (eq_attr "type" "mpxst")
734            (const_string "store")
735          (eq_attr "type" "push")
736            (if_then_else (match_operand 1 "memory_operand")
737              (const_string "both")
738              (const_string "store"))
739          (eq_attr "type" "pop")
740            (if_then_else (match_operand 0 "memory_operand")
741              (const_string "both")
742              (const_string "load"))
743          (eq_attr "type" "setcc")
744            (if_then_else (match_operand 0 "memory_operand")
745              (const_string "store")
746              (const_string "none"))
747          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
748            (if_then_else (ior (match_operand 0 "memory_operand")
749                               (match_operand 1 "memory_operand"))
750              (const_string "load")
751              (const_string "none"))
752          (eq_attr "type" "ibr")
753            (if_then_else (match_operand 0 "memory_operand")
754              (const_string "load")
755              (const_string "none"))
756          (eq_attr "type" "call")
757            (if_then_else (match_operand 0 "constant_call_address_operand")
758              (const_string "none")
759              (const_string "load"))
760          (eq_attr "type" "callv")
761            (if_then_else (match_operand 1 "constant_call_address_operand")
762              (const_string "none")
763              (const_string "load"))
764          (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
765               (match_operand 1 "memory_operand"))
766            (const_string "both")
767          (and (match_operand 0 "memory_operand")
768               (match_operand 1 "memory_operand"))
769            (const_string "both")
770          (match_operand 0 "memory_operand")
771            (const_string "store")
772          (match_operand 1 "memory_operand")
773            (const_string "load")
774          (and (eq_attr "type"
775                  "!alu1,negnot,ishift1,rotate1,
776                    imov,imovx,icmp,test,bitmanip,
777                    fmov,fcmp,fsgn,
778                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
779                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
780                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
781               (match_operand 2 "memory_operand"))
782            (const_string "load")
783          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
784               (match_operand 3 "memory_operand"))
785            (const_string "load")
786         ]
787         (const_string "none")))
789 ;; Indicates if an instruction has both an immediate and a displacement.
791 (define_attr "imm_disp" "false,true,unknown"
792   (cond [(eq_attr "type" "other,multi")
793            (const_string "unknown")
794          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
795               (and (match_operand 0 "memory_displacement_operand")
796                    (match_operand 1 "immediate_operand")))
797            (const_string "true")
798          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
799               (and (match_operand 0 "memory_displacement_operand")
800                    (match_operand 2 "immediate_operand")))
801            (const_string "true")
802         ]
803         (const_string "false")))
805 ;; Indicates if an FP operation has an integer source.
807 (define_attr "fp_int_src" "false,true"
808   (const_string "false"))
810 ;; Defines rounding mode of an FP operation.
812 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
813   (const_string "any"))
815 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
816 (define_attr "use_carry" "0,1" (const_string "0"))
818 ;; Define attribute to indicate unaligned ssemov insns
819 (define_attr "movu" "0,1" (const_string "0"))
821 ;; Used to control the "enabled" attribute on a per-instruction basis.
822 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
823                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
824                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
825                     avx512bw,noavx512bw,avx512dq,noavx512dq,
826                     avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
827   (const_string "base"))
829 (define_attr "enabled" ""
830   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
831          (eq_attr "isa" "x64_sse2")
832            (symbol_ref "TARGET_64BIT && TARGET_SSE2")
833          (eq_attr "isa" "x64_sse4")
834            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
835          (eq_attr "isa" "x64_sse4_noavx")
836            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
837          (eq_attr "isa" "x64_avx")
838            (symbol_ref "TARGET_64BIT && TARGET_AVX")
839          (eq_attr "isa" "x64_avx512dq")
840            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
841          (eq_attr "isa" "x64_avx512bw")
842            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
843          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
844          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
845          (eq_attr "isa" "sse2_noavx")
846            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
847          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
848          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
849          (eq_attr "isa" "sse4_noavx")
850            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
851          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
852          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
853          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
854          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
855          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
856          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
857          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
858          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
859          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
860          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
861          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
862          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
863          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
864          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
865          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
866          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
867         ]
868         (const_int 1)))
870 (define_attr "preferred_for_size" "" (const_int 1))
871 (define_attr "preferred_for_speed" "" (const_int 1))
873 ;; Describe a user's asm statement.
874 (define_asm_attributes
875   [(set_attr "length" "128")
876    (set_attr "type" "multi")])
878 (define_code_iterator plusminus [plus minus])
880 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
882 (define_code_iterator multdiv [mult div])
884 ;; Base name for define_insn
885 (define_code_attr plusminus_insn
886   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
887    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
889 ;; Base name for insn mnemonic.
890 (define_code_attr plusminus_mnemonic
891   [(plus "add") (ss_plus "adds") (us_plus "addus")
892    (minus "sub") (ss_minus "subs") (us_minus "subus")])
893 (define_code_attr multdiv_mnemonic
894   [(mult "mul") (div "div")])
896 ;; Mark commutative operators as such in constraints.
897 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
898                         (minus "") (ss_minus "") (us_minus "")])
900 ;; Mapping of max and min
901 (define_code_iterator maxmin [smax smin umax umin])
903 ;; Mapping of signed max and min
904 (define_code_iterator smaxmin [smax smin])
906 ;; Mapping of unsigned max and min
907 (define_code_iterator umaxmin [umax umin])
909 ;; Base name for integer and FP insn mnemonic
910 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
911                               (umax "maxu") (umin "minu")])
912 (define_code_attr maxmin_float [(smax "max") (smin "min")])
914 (define_int_iterator IEEE_MAXMIN
915         [UNSPEC_IEEE_MAX
916          UNSPEC_IEEE_MIN])
918 (define_int_attr ieee_maxmin
919         [(UNSPEC_IEEE_MAX "max")
920          (UNSPEC_IEEE_MIN "min")])
922 ;; Mapping of logic operators
923 (define_code_iterator any_logic [and ior xor])
924 (define_code_iterator any_or [ior xor])
925 (define_code_iterator fpint_logic [and xor])
927 ;; Base name for insn mnemonic.
928 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
930 ;; Mapping of logic-shift operators
931 (define_code_iterator any_lshift [ashift lshiftrt])
933 ;; Mapping of shift-right operators
934 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
936 ;; Mapping of all shift operators
937 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
939 ;; Base name for define_insn
940 (define_code_attr shift_insn
941   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
943 ;; Base name for insn mnemonic.
944 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
945 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
947 ;; Mapping of rotate operators
948 (define_code_iterator any_rotate [rotate rotatert])
950 ;; Base name for define_insn
951 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
953 ;; Base name for insn mnemonic.
954 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
956 ;; Mapping of abs neg operators
957 (define_code_iterator absneg [abs neg])
959 ;; Base name for x87 insn mnemonic.
960 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
962 ;; Used in signed and unsigned widening multiplications.
963 (define_code_iterator any_extend [sign_extend zero_extend])
965 ;; Prefix for insn menmonic.
966 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
968 ;; Prefix for define_insn
969 (define_code_attr u [(sign_extend "") (zero_extend "u")])
970 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
971 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
973 ;; Used in signed and unsigned truncations.
974 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
975 ;; Instruction suffix for truncations.
976 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
978 ;; Used in signed and unsigned fix.
979 (define_code_iterator any_fix [fix unsigned_fix])
980 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
981 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
982 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
984 ;; Used in signed and unsigned float.
985 (define_code_iterator any_float [float unsigned_float])
986 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
987 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
988 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
990 ;; All integer modes.
991 (define_mode_iterator SWI1248x [QI HI SI DI])
993 ;; All integer modes without QImode.
994 (define_mode_iterator SWI248x [HI SI DI])
996 ;; All integer modes without QImode and HImode.
997 (define_mode_iterator SWI48x [SI DI])
999 ;; All integer modes without SImode and DImode.
1000 (define_mode_iterator SWI12 [QI HI])
1002 ;; All integer modes without DImode.
1003 (define_mode_iterator SWI124 [QI HI SI])
1005 ;; All integer modes without QImode and DImode.
1006 (define_mode_iterator SWI24 [HI SI])
1008 ;; Single word integer modes.
1009 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1011 ;; Single word integer modes without QImode.
1012 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1014 ;; Single word integer modes without QImode and HImode.
1015 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1017 ;; All math-dependant single and double word integer modes.
1018 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1019                              (HI "TARGET_HIMODE_MATH")
1020                              SI DI (TI "TARGET_64BIT")])
1022 ;; Math-dependant single word integer modes.
1023 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1024                             (HI "TARGET_HIMODE_MATH")
1025                             SI (DI "TARGET_64BIT")])
1027 ;; Math-dependant integer modes without DImode.
1028 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1029                                (HI "TARGET_HIMODE_MATH")
1030                                SI])
1032 ;; Math-dependant integer modes with DImode.
1033 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1034                                  (HI "TARGET_HIMODE_MATH")
1035                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1037 ;; Math-dependant single word integer modes without QImode.
1038 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1039                                SI (DI "TARGET_64BIT")])
1041 ;; Double word integer modes.
1042 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1043                            (TI "TARGET_64BIT")])
1045 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1046 ;; compile time constant, it is faster to use <MODE_SIZE> than
1047 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1048 ;; command line options just use GET_MODE_SIZE macro.
1049 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1050                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1051                              (V16QI "16") (V32QI "32") (V64QI "64")
1052                              (V8HI "16") (V16HI "32") (V32HI "64")
1053                              (V4SI "16") (V8SI "32") (V16SI "64")
1054                              (V2DI "16") (V4DI "32") (V8DI "64")
1055                              (V1TI "16") (V2TI "32") (V4TI "64")
1056                              (V2DF "16") (V4DF "32") (V8DF "64")
1057                              (V4SF "16") (V8SF "32") (V16SF "64")])
1059 ;; Double word integer modes as mode attribute.
1060 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1061 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1063 ;; LEA mode corresponding to an integer mode
1064 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1066 ;; Half mode for double word integer modes.
1067 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1068                             (DI "TARGET_64BIT")])
1070 ;; Bound modes.
1071 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1072                            (BND64 "TARGET_LP64")])
1074 ;; Instruction suffix for integer modes.
1075 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1077 ;; Instruction suffix for masks.
1078 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1080 ;; Pointer size prefix for integer modes (Intel asm dialect)
1081 (define_mode_attr iptrsize [(QI "BYTE")
1082                             (HI "WORD")
1083                             (SI "DWORD")
1084                             (DI "QWORD")])
1086 ;; Register class for integer modes.
1087 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1089 ;; Immediate operand constraint for integer modes.
1090 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1092 ;; General operand constraint for word modes.
1093 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1095 ;; Immediate operand constraint for double integer modes.
1096 (define_mode_attr di [(SI "nF") (DI "Wd")])
1098 ;; Immediate operand constraint for shifts.
1099 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1101 ;; Print register name in the specified mode.
1102 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1104 ;; General operand predicate for integer modes.
1105 (define_mode_attr general_operand
1106         [(QI "general_operand")
1107          (HI "general_operand")
1108          (SI "x86_64_general_operand")
1109          (DI "x86_64_general_operand")
1110          (TI "x86_64_general_operand")])
1112 ;; General operand predicate for integer modes, where for TImode
1113 ;; we need both words of the operand to be general operands.
1114 (define_mode_attr general_hilo_operand
1115         [(QI "general_operand")
1116          (HI "general_operand")
1117          (SI "x86_64_general_operand")
1118          (DI "x86_64_general_operand")
1119          (TI "x86_64_hilo_general_operand")])
1121 ;; General sign extend operand predicate for integer modes,
1122 ;; which disallows VOIDmode operands and thus it is suitable
1123 ;; for use inside sign_extend.
1124 (define_mode_attr general_sext_operand
1125         [(QI "sext_operand")
1126          (HI "sext_operand")
1127          (SI "x86_64_sext_operand")
1128          (DI "x86_64_sext_operand")])
1130 ;; General sign/zero extend operand predicate for integer modes.
1131 (define_mode_attr general_szext_operand
1132         [(QI "general_operand")
1133          (HI "general_operand")
1134          (SI "x86_64_szext_general_operand")
1135          (DI "x86_64_szext_general_operand")])
1137 ;; Immediate operand predicate for integer modes.
1138 (define_mode_attr immediate_operand
1139         [(QI "immediate_operand")
1140          (HI "immediate_operand")
1141          (SI "x86_64_immediate_operand")
1142          (DI "x86_64_immediate_operand")])
1144 ;; Nonmemory operand predicate for integer modes.
1145 (define_mode_attr nonmemory_operand
1146         [(QI "nonmemory_operand")
1147          (HI "nonmemory_operand")
1148          (SI "x86_64_nonmemory_operand")
1149          (DI "x86_64_nonmemory_operand")])
1151 ;; Operand predicate for shifts.
1152 (define_mode_attr shift_operand
1153         [(QI "nonimmediate_operand")
1154          (HI "nonimmediate_operand")
1155          (SI "nonimmediate_operand")
1156          (DI "shiftdi_operand")
1157          (TI "register_operand")])
1159 ;; Operand predicate for shift argument.
1160 (define_mode_attr shift_immediate_operand
1161         [(QI "const_1_to_31_operand")
1162          (HI "const_1_to_31_operand")
1163          (SI "const_1_to_31_operand")
1164          (DI "const_1_to_63_operand")])
1166 ;; Input operand predicate for arithmetic left shifts.
1167 (define_mode_attr ashl_input_operand
1168         [(QI "nonimmediate_operand")
1169          (HI "nonimmediate_operand")
1170          (SI "nonimmediate_operand")
1171          (DI "ashldi_input_operand")
1172          (TI "reg_or_pm1_operand")])
1174 ;; SSE and x87 SFmode and DFmode floating point modes
1175 (define_mode_iterator MODEF [SF DF])
1177 ;; All x87 floating point modes
1178 (define_mode_iterator X87MODEF [SF DF XF])
1180 ;; SSE instruction suffix for various modes
1181 (define_mode_attr ssemodesuffix
1182   [(SF "ss") (DF "sd")
1183    (V16SF "ps") (V8DF "pd")
1184    (V8SF "ps") (V4DF "pd")
1185    (V4SF "ps") (V2DF "pd")
1186    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1187    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1188    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1190 ;; SSE vector suffix for floating point modes
1191 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1193 ;; SSE vector mode corresponding to a scalar mode
1194 (define_mode_attr ssevecmode
1195   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1196 (define_mode_attr ssevecmodelower
1197   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1199 ;; AVX512F vector mode corresponding to a scalar mode
1200 (define_mode_attr avx512fvecmode
1201   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1203 ;; Instruction suffix for REX 64bit operators.
1204 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1205 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1207 ;; This mode iterator allows :P to be used for patterns that operate on
1208 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1209 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1211 ;; This mode iterator allows :W to be used for patterns that operate on
1212 ;; word_mode sized quantities.
1213 (define_mode_iterator W
1214   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1216 ;; This mode iterator allows :PTR to be used for patterns that operate on
1217 ;; ptr_mode sized quantities.
1218 (define_mode_iterator PTR
1219   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1221 ;; Scheduling descriptions
1223 (include "pentium.md")
1224 (include "ppro.md")
1225 (include "k6.md")
1226 (include "athlon.md")
1227 (include "bdver1.md")
1228 (include "bdver3.md")
1229 (include "btver2.md")
1230 (include "znver1.md")
1231 (include "geode.md")
1232 (include "atom.md")
1233 (include "slm.md")
1234 (include "glm.md")
1235 (include "core2.md")
1236 (include "haswell.md")
1239 ;; Operand and operator predicates and constraints
1241 (include "predicates.md")
1242 (include "constraints.md")
1245 ;; Compare and branch/compare and store instructions.
1247 (define_expand "cbranch<mode>4"
1248   [(set (reg:CC FLAGS_REG)
1249         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1250                     (match_operand:SDWIM 2 "<general_operand>")))
1251    (set (pc) (if_then_else
1252                (match_operator 0 "ordered_comparison_operator"
1253                 [(reg:CC FLAGS_REG) (const_int 0)])
1254                (label_ref (match_operand 3))
1255                (pc)))]
1256   ""
1258   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1259     operands[1] = force_reg (<MODE>mode, operands[1]);
1260   ix86_expand_branch (GET_CODE (operands[0]),
1261                       operands[1], operands[2], operands[3]);
1262   DONE;
1265 (define_expand "cstore<mode>4"
1266   [(set (reg:CC FLAGS_REG)
1267         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1268                     (match_operand:SWIM 3 "<general_operand>")))
1269    (set (match_operand:QI 0 "register_operand")
1270         (match_operator 1 "ordered_comparison_operator"
1271           [(reg:CC FLAGS_REG) (const_int 0)]))]
1272   ""
1274   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1275     operands[2] = force_reg (<MODE>mode, operands[2]);
1276   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1277                      operands[2], operands[3]);
1278   DONE;
1281 (define_expand "cmp<mode>_1"
1282   [(set (reg:CC FLAGS_REG)
1283         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1284                     (match_operand:SWI48 1 "<general_operand>")))])
1286 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1287   [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1288    (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1290 (define_insn "*cmp<mode>_ccz_1"
1291   [(set (reg FLAGS_REG)
1292         (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1293                         "nonimmediate_operand" "<r>,?m<r>,$k")
1294                  (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1295   "ix86_match_ccmode (insn, CCZmode)"
1296   "@
1297    test{<imodesuffix>}\t%0, %0
1298    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1299    ktest<mskmodesuffix>\t%0, %0"
1300   [(set_attr "type" "test,icmp,msklog")
1301    (set_attr "length_immediate" "0,1,*")
1302    (set_attr "modrm_class" "op0,unknown,*")
1303    (set_attr "prefix" "*,*,vex")
1304    (set_attr "mode" "<MODE>")])
1306 (define_insn "*cmp<mode>_ccno_1"
1307   [(set (reg FLAGS_REG)
1308         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1309                  (match_operand:SWI 1 "const0_operand")))]
1310   "ix86_match_ccmode (insn, CCNOmode)"
1311   "@
1312    test{<imodesuffix>}\t%0, %0
1313    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1314   [(set_attr "type" "test,icmp")
1315    (set_attr "length_immediate" "0,1")
1316    (set_attr "modrm_class" "op0,unknown")
1317    (set_attr "mode" "<MODE>")])
1319 (define_insn "*cmp<mode>_1"
1320   [(set (reg FLAGS_REG)
1321         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1322                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1323   "ix86_match_ccmode (insn, CCmode)"
1324   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1325   [(set_attr "type" "icmp")
1326    (set_attr "mode" "<MODE>")])
1328 (define_insn "*cmp<mode>_minus_1"
1329   [(set (reg FLAGS_REG)
1330         (compare
1331           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1332                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1333           (const_int 0)))]
1334   "ix86_match_ccmode (insn, CCGOCmode)"
1335   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1336   [(set_attr "type" "icmp")
1337    (set_attr "mode" "<MODE>")])
1339 (define_insn "*cmpqi_ext_1"
1340   [(set (reg FLAGS_REG)
1341         (compare
1342           (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1343           (subreg:QI
1344             (zero_extract:SI
1345               (match_operand 1 "ext_register_operand" "Q,Q")
1346               (const_int 8)
1347               (const_int 8)) 0)))]
1348   "ix86_match_ccmode (insn, CCmode)"
1349   "cmp{b}\t{%h1, %0|%0, %h1}"
1350   [(set_attr "isa" "*,nox64")
1351    (set_attr "type" "icmp")
1352    (set_attr "mode" "QI")])
1354 (define_insn "*cmpqi_ext_2"
1355   [(set (reg FLAGS_REG)
1356         (compare
1357           (subreg:QI
1358             (zero_extract:SI
1359               (match_operand 0 "ext_register_operand" "Q")
1360               (const_int 8)
1361               (const_int 8)) 0)
1362           (match_operand:QI 1 "const0_operand")))]
1363   "ix86_match_ccmode (insn, CCNOmode)"
1364   "test{b}\t%h0, %h0"
1365   [(set_attr "type" "test")
1366    (set_attr "length_immediate" "0")
1367    (set_attr "mode" "QI")])
1369 (define_expand "cmpqi_ext_3"
1370   [(set (reg:CC FLAGS_REG)
1371         (compare:CC
1372           (subreg:QI
1373             (zero_extract:SI
1374               (match_operand 0 "ext_register_operand")
1375               (const_int 8)
1376               (const_int 8)) 0)
1377           (match_operand:QI 1 "const_int_operand")))])
1379 (define_insn "*cmpqi_ext_3"
1380   [(set (reg FLAGS_REG)
1381         (compare
1382           (subreg:QI
1383             (zero_extract:SI
1384               (match_operand 0 "ext_register_operand" "Q,Q")
1385               (const_int 8)
1386               (const_int 8)) 0)
1387           (match_operand:QI 1 "general_operand" "QnBc,m")))]
1388   "ix86_match_ccmode (insn, CCmode)"
1389   "cmp{b}\t{%1, %h0|%h0, %1}"
1390   [(set_attr "isa" "*,nox64")
1391    (set_attr "type" "icmp")
1392    (set_attr "mode" "QI")])
1394 (define_insn "*cmpqi_ext_4"
1395   [(set (reg FLAGS_REG)
1396         (compare
1397           (subreg:QI
1398             (zero_extract:SI
1399               (match_operand 0 "ext_register_operand" "Q")
1400               (const_int 8)
1401               (const_int 8)) 0)
1402           (subreg:QI
1403             (zero_extract:SI
1404               (match_operand 1 "ext_register_operand" "Q")
1405               (const_int 8)
1406               (const_int 8)) 0)))]
1407   "ix86_match_ccmode (insn, CCmode)"
1408   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1409   [(set_attr "type" "icmp")
1410    (set_attr "mode" "QI")])
1412 ;; These implement float point compares.
1413 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1414 ;; which would allow mix and match FP modes on the compares.  Which is what
1415 ;; the old patterns did, but with many more of them.
1417 (define_expand "cbranchxf4"
1418   [(set (reg:CC FLAGS_REG)
1419         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1420                     (match_operand:XF 2 "nonmemory_operand")))
1421    (set (pc) (if_then_else
1422               (match_operator 0 "ix86_fp_comparison_operator"
1423                [(reg:CC FLAGS_REG)
1424                 (const_int 0)])
1425               (label_ref (match_operand 3))
1426               (pc)))]
1427   "TARGET_80387"
1429   ix86_expand_branch (GET_CODE (operands[0]),
1430                       operands[1], operands[2], operands[3]);
1431   DONE;
1434 (define_expand "cstorexf4"
1435   [(set (reg:CC FLAGS_REG)
1436         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1437                     (match_operand:XF 3 "nonmemory_operand")))
1438    (set (match_operand:QI 0 "register_operand")
1439               (match_operator 1 "ix86_fp_comparison_operator"
1440                [(reg:CC FLAGS_REG)
1441                 (const_int 0)]))]
1442   "TARGET_80387"
1444   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1445                      operands[2], operands[3]);
1446   DONE;
1449 (define_expand "cbranch<mode>4"
1450   [(set (reg:CC FLAGS_REG)
1451         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1452                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1453    (set (pc) (if_then_else
1454               (match_operator 0 "ix86_fp_comparison_operator"
1455                [(reg:CC FLAGS_REG)
1456                 (const_int 0)])
1457               (label_ref (match_operand 3))
1458               (pc)))]
1459   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1461   ix86_expand_branch (GET_CODE (operands[0]),
1462                       operands[1], operands[2], operands[3]);
1463   DONE;
1466 (define_expand "cstore<mode>4"
1467   [(set (reg:CC FLAGS_REG)
1468         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1469                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1470    (set (match_operand:QI 0 "register_operand")
1471               (match_operator 1 "ix86_fp_comparison_operator"
1472                [(reg:CC FLAGS_REG)
1473                 (const_int 0)]))]
1474   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1476   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1477                      operands[2], operands[3]);
1478   DONE;
1481 (define_expand "cbranchcc4"
1482   [(set (pc) (if_then_else
1483               (match_operator 0 "comparison_operator"
1484                [(match_operand 1 "flags_reg_operand")
1485                 (match_operand 2 "const0_operand")])
1486               (label_ref (match_operand 3))
1487               (pc)))]
1488   ""
1490   ix86_expand_branch (GET_CODE (operands[0]),
1491                       operands[1], operands[2], operands[3]);
1492   DONE;
1495 (define_expand "cstorecc4"
1496   [(set (match_operand:QI 0 "register_operand")
1497               (match_operator 1 "comparison_operator"
1498                [(match_operand 2 "flags_reg_operand")
1499                 (match_operand 3 "const0_operand")]))]
1500   ""
1502   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1503                      operands[2], operands[3]);
1504   DONE;
1508 ;; FP compares, step 1:
1509 ;; Set the FP condition codes.
1511 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1512 ;; used to manage the reg stack popping would not be preserved.
1514 (define_insn "*cmp<mode>_0_i387"
1515   [(set (match_operand:HI 0 "register_operand" "=a")
1516         (unspec:HI
1517           [(compare:CCFP
1518              (match_operand:X87MODEF 1 "register_operand" "f")
1519              (match_operand:X87MODEF 2 "const0_operand"))]
1520         UNSPEC_FNSTSW))]
1521   "TARGET_80387"
1522   "* return output_fp_compare (insn, operands, false, false);"
1523   [(set_attr "type" "multi")
1524    (set_attr "unit" "i387")
1525    (set_attr "mode" "<MODE>")])
1527 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1528   [(set (reg:CCFP FLAGS_REG)
1529         (compare:CCFP
1530           (match_operand:X87MODEF 1 "register_operand" "f")
1531           (match_operand:X87MODEF 2 "const0_operand")))
1532    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1533   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1534   "#"
1535   "&& reload_completed"
1536   [(set (match_dup 0)
1537         (unspec:HI
1538           [(compare:CCFP (match_dup 1)(match_dup 2))]
1539         UNSPEC_FNSTSW))
1540    (set (reg:CC FLAGS_REG)
1541         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1542   ""
1543   [(set_attr "type" "multi")
1544    (set_attr "unit" "i387")
1545    (set_attr "mode" "<MODE>")])
1547 (define_insn "*cmpxf_i387"
1548   [(set (match_operand:HI 0 "register_operand" "=a")
1549         (unspec:HI
1550           [(compare:CCFP
1551              (match_operand:XF 1 "register_operand" "f")
1552              (match_operand:XF 2 "register_operand" "f"))]
1553           UNSPEC_FNSTSW))]
1554   "TARGET_80387"
1555   "* return output_fp_compare (insn, operands, false, false);"
1556   [(set_attr "type" "multi")
1557    (set_attr "unit" "i387")
1558    (set_attr "mode" "XF")])
1560 (define_insn_and_split "*cmpxf_cc_i387"
1561   [(set (reg:CCFP FLAGS_REG)
1562         (compare:CCFP
1563           (match_operand:XF 1 "register_operand" "f")
1564           (match_operand:XF 2 "register_operand" "f")))
1565    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1566   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1567   "#"
1568   "&& reload_completed"
1569   [(set (match_dup 0)
1570         (unspec:HI
1571           [(compare:CCFP (match_dup 1)(match_dup 2))]
1572         UNSPEC_FNSTSW))
1573    (set (reg:CC FLAGS_REG)
1574         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1575   ""
1576   [(set_attr "type" "multi")
1577    (set_attr "unit" "i387")
1578    (set_attr "mode" "XF")])
1580 (define_insn "*cmp<mode>_i387"
1581   [(set (match_operand:HI 0 "register_operand" "=a")
1582         (unspec:HI
1583           [(compare:CCFP
1584              (match_operand:MODEF 1 "register_operand" "f")
1585              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1586           UNSPEC_FNSTSW))]
1587   "TARGET_80387"
1588   "* return output_fp_compare (insn, operands, false, false);"
1589   [(set_attr "type" "multi")
1590    (set_attr "unit" "i387")
1591    (set_attr "mode" "<MODE>")])
1593 (define_insn_and_split "*cmp<mode>_cc_i387"
1594   [(set (reg:CCFP FLAGS_REG)
1595         (compare:CCFP
1596           (match_operand:MODEF 1 "register_operand" "f")
1597           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1598    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1599   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1600   "#"
1601   "&& reload_completed"
1602   [(set (match_dup 0)
1603         (unspec:HI
1604           [(compare:CCFP (match_dup 1)(match_dup 2))]
1605         UNSPEC_FNSTSW))
1606    (set (reg:CC FLAGS_REG)
1607         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1608   ""
1609   [(set_attr "type" "multi")
1610    (set_attr "unit" "i387")
1611    (set_attr "mode" "<MODE>")])
1613 (define_insn "*cmpu<mode>_i387"
1614   [(set (match_operand:HI 0 "register_operand" "=a")
1615         (unspec:HI
1616           [(unspec:CCFP
1617              [(compare:CCFP
1618                 (match_operand:X87MODEF 1 "register_operand" "f")
1619                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1620              UNSPEC_NOTRAP)]
1621           UNSPEC_FNSTSW))]
1622   "TARGET_80387"
1623   "* return output_fp_compare (insn, operands, false, true);"
1624   [(set_attr "type" "multi")
1625    (set_attr "unit" "i387")
1626    (set_attr "mode" "<MODE>")])
1628 (define_insn_and_split "*cmpu<mode>_cc_i387"
1629   [(set (reg:CCFP FLAGS_REG)
1630         (unspec:CCFP
1631           [(compare:CCFP
1632              (match_operand:X87MODEF 1 "register_operand" "f")
1633              (match_operand:X87MODEF 2 "register_operand" "f"))]
1634           UNSPEC_NOTRAP))
1635    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1636   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1637   "#"
1638   "&& reload_completed"
1639   [(set (match_dup 0)
1640         (unspec:HI
1641           [(unspec:CCFP
1642              [(compare:CCFP (match_dup 1)(match_dup 2))]
1643              UNSPEC_NOTRAP)]
1644           UNSPEC_FNSTSW))
1645    (set (reg:CC FLAGS_REG)
1646         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1647   ""
1648   [(set_attr "type" "multi")
1649    (set_attr "unit" "i387")
1650    (set_attr "mode" "<MODE>")])
1652 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1653   [(set (match_operand:HI 0 "register_operand" "=a")
1654         (unspec:HI
1655           [(compare:CCFP
1656              (match_operand:X87MODEF 1 "register_operand" "f")
1657              (float:X87MODEF
1658                (match_operand:SWI24 2 "memory_operand" "m")))]
1659           UNSPEC_FNSTSW))]
1660   "TARGET_80387
1661    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1662        || optimize_function_for_size_p (cfun))"
1663   "* return output_fp_compare (insn, operands, false, false);"
1664   [(set_attr "type" "multi")
1665    (set_attr "unit" "i387")
1666    (set_attr "fp_int_src" "true")
1667    (set_attr "mode" "<SWI24:MODE>")])
1669 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1670   [(set (reg:CCFP FLAGS_REG)
1671         (compare:CCFP
1672           (match_operand:X87MODEF 1 "register_operand" "f")
1673           (float:X87MODEF
1674             (match_operand:SWI24 2 "memory_operand" "m"))))
1675    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1676   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1677    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1678        || optimize_function_for_size_p (cfun))"
1679   "#"
1680   "&& reload_completed"
1681   [(set (match_dup 0)
1682         (unspec:HI
1683           [(compare:CCFP
1684              (match_dup 1)
1685              (float:X87MODEF (match_dup 2)))]
1686         UNSPEC_FNSTSW))
1687    (set (reg:CC FLAGS_REG)
1688         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1689   ""
1690   [(set_attr "type" "multi")
1691    (set_attr "unit" "i387")
1692    (set_attr "fp_int_src" "true")
1693    (set_attr "mode" "<SWI24:MODE>")])
1695 ;; FP compares, step 2
1696 ;; Move the fpsw to ax.
1698 (define_insn "x86_fnstsw_1"
1699   [(set (match_operand:HI 0 "register_operand" "=a")
1700         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1701   "TARGET_80387"
1702   "fnstsw\t%0"
1703   [(set_attr "length" "2")
1704    (set_attr "mode" "SI")
1705    (set_attr "unit" "i387")])
1707 ;; FP compares, step 3
1708 ;; Get ax into flags, general case.
1710 (define_insn "x86_sahf_1"
1711   [(set (reg:CC FLAGS_REG)
1712         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1713                    UNSPEC_SAHF))]
1714   "TARGET_SAHF"
1716 #ifndef HAVE_AS_IX86_SAHF
1717   if (TARGET_64BIT)
1718     return ASM_BYTE "0x9e";
1719   else
1720 #endif
1721   return "sahf";
1723   [(set_attr "length" "1")
1724    (set_attr "athlon_decode" "vector")
1725    (set_attr "amdfam10_decode" "direct")
1726    (set_attr "bdver1_decode" "direct")
1727    (set_attr "mode" "SI")])
1729 ;; Pentium Pro can do steps 1 through 3 in one go.
1730 ;; (these instructions set flags directly)
1732 (define_subst_attr "unord" "unord_subst" "" "u")
1733 (define_subst_attr "unordered" "unord_subst" "false" "true")
1735 (define_subst "unord_subst"
1736   [(set (match_operand:CCFP 0)
1737         (match_operand:CCFP 1))]
1738   ""
1739   [(set (match_dup 0)
1740         (unspec:CCFP
1741           [(match_dup 1)]
1742           UNSPEC_NOTRAP))])
1744 (define_insn "*cmpi<unord><MODEF:mode>"
1745   [(set (reg:CCFP FLAGS_REG)
1746         (compare:CCFP
1747           (match_operand:MODEF 0 "register_operand" "f,v")
1748           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1749   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1750    || (TARGET_80387 && TARGET_CMOVE)"
1751   "@
1752    * return output_fp_compare (insn, operands, true, <unordered>);
1753    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1754   [(set_attr "type" "fcmp,ssecomi")
1755    (set_attr "prefix" "orig,maybe_vex")
1756    (set_attr "mode" "<MODEF:MODE>")
1757    (set_attr "prefix_rep" "*,0")
1758    (set (attr "prefix_data16")
1759         (cond [(eq_attr "alternative" "0")
1760                  (const_string "*")
1761                (eq_attr "mode" "DF")
1762                  (const_string "1")
1763               ]
1764               (const_string "0")))
1765    (set_attr "athlon_decode" "vector")
1766    (set_attr "amdfam10_decode" "direct")
1767    (set_attr "bdver1_decode" "double")
1768    (set_attr "znver1_decode" "double")
1769    (set (attr "enabled")
1770      (if_then_else
1771        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1772        (if_then_else
1773          (eq_attr "alternative" "0")
1774          (symbol_ref "TARGET_MIX_SSE_I387")
1775          (symbol_ref "true"))
1776        (if_then_else
1777          (eq_attr "alternative" "0")
1778          (symbol_ref "true")
1779          (symbol_ref "false"))))])
1781 (define_insn "*cmpi<unord>xf_i387"
1782   [(set (reg:CCFP FLAGS_REG)
1783         (compare:CCFP
1784           (match_operand:XF 0 "register_operand" "f")
1785           (match_operand:XF 1 "register_operand" "f")))]
1786   "TARGET_80387 && TARGET_CMOVE"
1787   "* return output_fp_compare (insn, operands, true, <unordered>);"
1788   [(set_attr "type" "fcmp")
1789    (set_attr "mode" "XF")
1790    (set_attr "athlon_decode" "vector")
1791    (set_attr "amdfam10_decode" "direct")
1792    (set_attr "bdver1_decode" "double")
1793    (set_attr "znver1_decode" "double")])
1795 ;; Push/pop instructions.
1797 (define_insn "*push<mode>2"
1798   [(set (match_operand:DWI 0 "push_operand" "=<")
1799         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1800   ""
1801   "#"
1802   [(set_attr "type" "multi")
1803    (set_attr "mode" "<MODE>")])
1805 (define_split
1806   [(set (match_operand:DWI 0 "push_operand")
1807         (match_operand:DWI 1 "general_gr_operand"))]
1808   "reload_completed"
1809   [(const_int 0)]
1810   "ix86_split_long_move (operands); DONE;")
1812 (define_insn "*pushdi2_rex64"
1813   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1814         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1815   "TARGET_64BIT"
1816   "@
1817    push{q}\t%1
1818    #"
1819   [(set_attr "type" "push,multi")
1820    (set_attr "mode" "DI")])
1822 ;; Convert impossible pushes of immediate to existing instructions.
1823 ;; First try to get scratch register and go through it.  In case this
1824 ;; fails, push sign extended lower part first and then overwrite
1825 ;; upper part by 32bit move.
1826 (define_peephole2
1827   [(match_scratch:DI 2 "r")
1828    (set (match_operand:DI 0 "push_operand")
1829         (match_operand:DI 1 "immediate_operand"))]
1830   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1831    && !x86_64_immediate_operand (operands[1], DImode)"
1832   [(set (match_dup 2) (match_dup 1))
1833    (set (match_dup 0) (match_dup 2))])
1835 ;; We need to define this as both peepholer and splitter for case
1836 ;; peephole2 pass is not run.
1837 ;; "&& 1" is needed to keep it from matching the previous pattern.
1838 (define_peephole2
1839   [(set (match_operand:DI 0 "push_operand")
1840         (match_operand:DI 1 "immediate_operand"))]
1841   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1842    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1843   [(set (match_dup 0) (match_dup 1))
1844    (set (match_dup 2) (match_dup 3))]
1846   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1848   operands[1] = gen_lowpart (DImode, operands[2]);
1849   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1850                                                    GEN_INT (4)));
1853 (define_split
1854   [(set (match_operand:DI 0 "push_operand")
1855         (match_operand:DI 1 "immediate_operand"))]
1856   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1857                     ? epilogue_completed : reload_completed)
1858    && !symbolic_operand (operands[1], DImode)
1859    && !x86_64_immediate_operand (operands[1], DImode)"
1860   [(set (match_dup 0) (match_dup 1))
1861    (set (match_dup 2) (match_dup 3))]
1863   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1865   operands[1] = gen_lowpart (DImode, operands[2]);
1866   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1867                                                    GEN_INT (4)));
1870 (define_insn "*pushsi2"
1871   [(set (match_operand:SI 0 "push_operand" "=<")
1872         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1873   "!TARGET_64BIT"
1874   "push{l}\t%1"
1875   [(set_attr "type" "push")
1876    (set_attr "mode" "SI")])
1878 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1879 ;; "push a byte/word".  But actually we use pushl, which has the effect
1880 ;; of rounding the amount pushed up to a word.
1882 ;; For TARGET_64BIT we always round up to 8 bytes.
1883 (define_insn "*push<mode>2_rex64"
1884   [(set (match_operand:SWI124 0 "push_operand" "=X")
1885         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1886   "TARGET_64BIT"
1887   "push{q}\t%q1"
1888   [(set_attr "type" "push")
1889    (set_attr "mode" "DI")])
1891 (define_insn "*push<mode>2"
1892   [(set (match_operand:SWI12 0 "push_operand" "=X")
1893         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1894   "!TARGET_64BIT"
1895   "push{l}\t%k1"
1896   [(set_attr "type" "push")
1897    (set_attr "mode" "SI")])
1899 (define_insn "*push<mode>2_prologue"
1900   [(set (match_operand:W 0 "push_operand" "=<")
1901         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1902    (clobber (mem:BLK (scratch)))]
1903   ""
1904   "push{<imodesuffix>}\t%1"
1905   [(set_attr "type" "push")
1906    (set_attr "mode" "<MODE>")])
1908 (define_insn "*pop<mode>1"
1909   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1910         (match_operand:W 1 "pop_operand" ">"))]
1911   ""
1912   "pop{<imodesuffix>}\t%0"
1913   [(set_attr "type" "pop")
1914    (set_attr "mode" "<MODE>")])
1916 (define_insn "*pop<mode>1_epilogue"
1917   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1918         (match_operand:W 1 "pop_operand" ">"))
1919    (clobber (mem:BLK (scratch)))]
1920   ""
1921   "pop{<imodesuffix>}\t%0"
1922   [(set_attr "type" "pop")
1923    (set_attr "mode" "<MODE>")])
1925 (define_insn "*pushfl<mode>2"
1926   [(set (match_operand:W 0 "push_operand" "=<")
1927         (match_operand:W 1 "flags_reg_operand"))]
1928   ""
1929   "pushf{<imodesuffix>}"
1930   [(set_attr "type" "push")
1931    (set_attr "mode" "<MODE>")])
1933 (define_insn "*popfl<mode>1"
1934   [(set (match_operand:W 0 "flags_reg_operand")
1935         (match_operand:W 1 "pop_operand" ">"))]
1936   ""
1937   "popf{<imodesuffix>}"
1938   [(set_attr "type" "pop")
1939    (set_attr "mode" "<MODE>")])
1942 ;; Reload patterns to support multi-word load/store
1943 ;; with non-offsetable address.
1944 (define_expand "reload_noff_store"
1945   [(parallel [(match_operand 0 "memory_operand" "=m")
1946               (match_operand 1 "register_operand" "r")
1947               (match_operand:DI 2 "register_operand" "=&r")])]
1948   "TARGET_64BIT"
1950   rtx mem = operands[0];
1951   rtx addr = XEXP (mem, 0);
1953   emit_move_insn (operands[2], addr);
1954   mem = replace_equiv_address_nv (mem, operands[2]);
1956   emit_insn (gen_rtx_SET (mem, operands[1]));
1957   DONE;
1960 (define_expand "reload_noff_load"
1961   [(parallel [(match_operand 0 "register_operand" "=r")
1962               (match_operand 1 "memory_operand" "m")
1963               (match_operand:DI 2 "register_operand" "=r")])]
1964   "TARGET_64BIT"
1966   rtx mem = operands[1];
1967   rtx addr = XEXP (mem, 0);
1969   emit_move_insn (operands[2], addr);
1970   mem = replace_equiv_address_nv (mem, operands[2]);
1972   emit_insn (gen_rtx_SET (operands[0], mem));
1973   DONE;
1976 ;; Move instructions.
1978 (define_expand "movxi"
1979   [(set (match_operand:XI 0 "nonimmediate_operand")
1980         (match_operand:XI 1 "general_operand"))]
1981   "TARGET_AVX512F"
1982   "ix86_expand_vector_move (XImode, operands); DONE;")
1984 (define_expand "movoi"
1985   [(set (match_operand:OI 0 "nonimmediate_operand")
1986         (match_operand:OI 1 "general_operand"))]
1987   "TARGET_AVX"
1988   "ix86_expand_vector_move (OImode, operands); DONE;")
1990 (define_expand "movti"
1991   [(set (match_operand:TI 0 "nonimmediate_operand")
1992         (match_operand:TI 1 "general_operand"))]
1993   "TARGET_64BIT || TARGET_SSE"
1995   if (TARGET_64BIT)
1996     ix86_expand_move (TImode, operands);
1997   else
1998     ix86_expand_vector_move (TImode, operands);
1999   DONE;
2002 ;; This expands to what emit_move_complex would generate if we didn't
2003 ;; have a movti pattern.  Having this avoids problems with reload on
2004 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2005 ;; to have around all the time.
2006 (define_expand "movcdi"
2007   [(set (match_operand:CDI 0 "nonimmediate_operand")
2008         (match_operand:CDI 1 "general_operand"))]
2009   ""
2011   if (push_operand (operands[0], CDImode))
2012     emit_move_complex_push (CDImode, operands[0], operands[1]);
2013   else
2014     emit_move_complex_parts (operands[0], operands[1]);
2015   DONE;
2018 (define_expand "mov<mode>"
2019   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2020         (match_operand:SWI1248x 1 "general_operand"))]
2021   ""
2022   "ix86_expand_move (<MODE>mode, operands); DONE;")
2024 (define_insn "*mov<mode>_xor"
2025   [(set (match_operand:SWI48 0 "register_operand" "=r")
2026         (match_operand:SWI48 1 "const0_operand"))
2027    (clobber (reg:CC FLAGS_REG))]
2028   "reload_completed"
2029   "xor{l}\t%k0, %k0"
2030   [(set_attr "type" "alu1")
2031    (set_attr "modrm_class" "op0")
2032    (set_attr "mode" "SI")
2033    (set_attr "length_immediate" "0")])
2035 (define_insn "*mov<mode>_or"
2036   [(set (match_operand:SWI48 0 "register_operand" "=r")
2037         (match_operand:SWI48 1 "constm1_operand"))
2038    (clobber (reg:CC FLAGS_REG))]
2039   "reload_completed"
2040   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2041   [(set_attr "type" "alu1")
2042    (set_attr "mode" "<MODE>")
2043    (set_attr "length_immediate" "1")])
2045 (define_insn "*movxi_internal_avx512f"
2046   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2047         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2048   "TARGET_AVX512F
2049    && (register_operand (operands[0], XImode)
2050        || register_operand (operands[1], XImode))"
2052   switch (get_attr_type (insn))
2053     {
2054     case TYPE_SSELOG1:
2055       return standard_sse_constant_opcode (insn, operands);
2057     case TYPE_SSEMOV:
2058       if (misaligned_operand (operands[0], XImode)
2059           || misaligned_operand (operands[1], XImode))
2060         return "vmovdqu32\t{%1, %0|%0, %1}";
2061       else
2062         return "vmovdqa32\t{%1, %0|%0, %1}";
2064     default:
2065       gcc_unreachable ();
2066     }
2068   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2069    (set_attr "prefix" "evex")
2070    (set_attr "mode" "XI")])
2072 (define_insn "*movoi_internal_avx"
2073   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2074         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2075   "TARGET_AVX
2076    && (register_operand (operands[0], OImode)
2077        || register_operand (operands[1], OImode))"
2079   switch (get_attr_type (insn))
2080     {
2081     case TYPE_SSELOG1:
2082       return standard_sse_constant_opcode (insn, operands);
2084     case TYPE_SSEMOV:
2085       if (misaligned_operand (operands[0], OImode)
2086           || misaligned_operand (operands[1], OImode))
2087         {
2088           if (get_attr_mode (insn) == MODE_V8SF)
2089             return "vmovups\t{%1, %0|%0, %1}";
2090           else if (get_attr_mode (insn) == MODE_XI)
2091             return "vmovdqu32\t{%1, %0|%0, %1}";
2092           else
2093             return "vmovdqu\t{%1, %0|%0, %1}";
2094         }
2095       else
2096         {
2097           if (get_attr_mode (insn) == MODE_V8SF)
2098             return "vmovaps\t{%1, %0|%0, %1}";
2099           else if (get_attr_mode (insn) == MODE_XI)
2100             return "vmovdqa32\t{%1, %0|%0, %1}";
2101           else
2102             return "vmovdqa\t{%1, %0|%0, %1}";
2103         }
2105     default:
2106       gcc_unreachable ();
2107     }
2109   [(set_attr "isa" "*,avx2,*,*")
2110    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2111    (set_attr "prefix" "vex")
2112    (set (attr "mode")
2113         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2114                     (match_operand 1 "ext_sse_reg_operand"))
2115                  (const_string "XI")
2116                (and (eq_attr "alternative" "1")
2117                     (match_test "TARGET_AVX512VL"))
2118                  (const_string "XI")
2119                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2120                     (and (eq_attr "alternative" "3")
2121                          (match_test "TARGET_SSE_TYPELESS_STORES")))
2122                  (const_string "V8SF")
2123               ]
2124               (const_string "OI")))])
2126 (define_insn "*movti_internal"
2127   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2128         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,r"))]
2129   "(TARGET_64BIT
2130     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2131    || (TARGET_SSE
2132        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2133        && (register_operand (operands[0], TImode)
2134            || register_operand (operands[1], TImode)))"
2136   switch (get_attr_type (insn))
2137     {
2138     case TYPE_MULTI:
2139       return "#";
2141     case TYPE_SSELOG1:
2142       return standard_sse_constant_opcode (insn, operands);
2144     case TYPE_SSEMOV:
2145       /* TDmode values are passed as TImode on the stack.  Moving them
2146          to stack may result in unaligned memory access.  */
2147       if (misaligned_operand (operands[0], TImode)
2148           || misaligned_operand (operands[1], TImode))
2149         {
2150           if (get_attr_mode (insn) == MODE_V4SF)
2151             return "%vmovups\t{%1, %0|%0, %1}";
2152           else if (get_attr_mode (insn) == MODE_XI)
2153             return "vmovdqu32\t{%1, %0|%0, %1}";
2154           else
2155             return "%vmovdqu\t{%1, %0|%0, %1}";
2156         }
2157       else
2158         {
2159           if (get_attr_mode (insn) == MODE_V4SF)
2160             return "%vmovaps\t{%1, %0|%0, %1}";
2161           else if (get_attr_mode (insn) == MODE_XI)
2162             return "vmovdqa32\t{%1, %0|%0, %1}";
2163           else
2164             return "%vmovdqa\t{%1, %0|%0, %1}";
2165         }
2167     default:
2168       gcc_unreachable ();
2169     }
2171   [(set (attr "isa")
2172      (cond [(eq_attr "alternative" "0,1,6,7")
2173               (const_string "x64")
2174             (eq_attr "alternative" "3")
2175               (const_string "sse2")
2176            ]
2177            (const_string "*")))
2178    (set (attr "type")
2179      (cond [(eq_attr "alternative" "0,1,6,7")
2180               (const_string "multi")
2181             (eq_attr "alternative" "2,3")
2182               (const_string "sselog1")
2183            ]
2184            (const_string "ssemov")))
2185    (set (attr "prefix")
2186      (if_then_else (eq_attr "type" "sselog1,ssemov")
2187        (const_string "maybe_vex")
2188        (const_string "orig")))
2189    (set (attr "mode")
2190         (cond [(eq_attr "alternative" "0,1")
2191                  (const_string "DI")
2192                (ior (match_operand 0 "ext_sse_reg_operand")
2193                     (match_operand 1 "ext_sse_reg_operand"))
2194                  (const_string "XI")
2195                (and (eq_attr "alternative" "3")
2196                     (match_test "TARGET_AVX512VL"))
2197                  (const_string "XI")
2198                (ior (not (match_test "TARGET_SSE2"))
2199                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2200                          (and (eq_attr "alternative" "5")
2201                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2202                  (const_string "V4SF")
2203                (match_test "TARGET_AVX")
2204                  (const_string "TI")
2205                (match_test "optimize_function_for_size_p (cfun)")
2206                  (const_string "V4SF")
2207                ]
2208                (const_string "TI")))
2209    (set (attr "preferred_for_speed")
2210      (cond [(eq_attr "alternative" "6")
2211               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2212             (eq_attr "alternative" "7")
2213               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2214            ]
2215            (symbol_ref "true")))])
2217 (define_split
2218   [(set (match_operand:TI 0 "sse_reg_operand")
2219         (match_operand:TI 1 "general_reg_operand"))]
2220   "TARGET_64BIT && TARGET_SSE4_1
2221    && reload_completed"
2222   [(set (match_dup 2)
2223         (vec_merge:V2DI
2224           (vec_duplicate:V2DI (match_dup 3))
2225           (match_dup 2)
2226           (const_int 2)))]
2228   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2229   operands[3] = gen_highpart (DImode, operands[1]);
2231   emit_move_insn (gen_lowpart (DImode, operands[0]),
2232                   gen_lowpart (DImode, operands[1]));
2235 (define_insn "*movdi_internal"
2236   [(set (match_operand:DI 0 "nonimmediate_operand"
2237     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m")
2238         (match_operand:DI 1 "general_operand"
2239     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,v,*Yd,r   ,*v,r  ,*x ,*y ,*r,*km,*k,*k"))]
2240   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2242   switch (get_attr_type (insn))
2243     {
2244     case TYPE_MSKMOV:
2245       return "kmovq\t{%1, %0|%0, %1}";
2247     case TYPE_MULTI:
2248       return "#";
2250     case TYPE_MMX:
2251       return "pxor\t%0, %0";
2253     case TYPE_MMXMOV:
2254       /* Handle broken assemblers that require movd instead of movq.  */
2255       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2256           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2257         return "movd\t{%1, %0|%0, %1}";
2258       return "movq\t{%1, %0|%0, %1}";
2260     case TYPE_SSELOG1:
2261       return standard_sse_constant_opcode (insn, operands);
2263     case TYPE_SSEMOV:
2264       switch (get_attr_mode (insn))
2265         {
2266         case MODE_DI:
2267           /* Handle broken assemblers that require movd instead of movq.  */
2268           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2269               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2270             return "%vmovd\t{%1, %0|%0, %1}";
2271           return "%vmovq\t{%1, %0|%0, %1}";
2273         case MODE_TI:
2274           /* Handle AVX512 registers set.  */
2275           if (EXT_REX_SSE_REG_P (operands[0])
2276               || EXT_REX_SSE_REG_P (operands[1]))
2277             return "vmovdqa64\t{%1, %0|%0, %1}";
2278           return "%vmovdqa\t{%1, %0|%0, %1}";
2280         case MODE_V2SF:
2281           gcc_assert (!TARGET_AVX);
2282           return "movlps\t{%1, %0|%0, %1}";
2283         case MODE_V4SF:
2284           return "%vmovaps\t{%1, %0|%0, %1}";
2286         default:
2287           gcc_unreachable ();
2288         }
2290     case TYPE_SSECVT:
2291       if (SSE_REG_P (operands[0]))
2292         return "movq2dq\t{%1, %0|%0, %1}";
2293       else
2294         return "movdq2q\t{%1, %0|%0, %1}";
2296     case TYPE_LEA:
2297       return "lea{q}\t{%E1, %0|%0, %E1}";
2299     case TYPE_IMOV:
2300       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2301       if (get_attr_mode (insn) == MODE_SI)
2302         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2303       else if (which_alternative == 4)
2304         return "movabs{q}\t{%1, %0|%0, %1}";
2305       else if (ix86_use_lea_for_mov (insn, operands))
2306         return "lea{q}\t{%E1, %0|%0, %E1}";
2307       else
2308         return "mov{q}\t{%1, %0|%0, %1}";
2310     default:
2311       gcc_unreachable ();
2312     }
2314   [(set (attr "isa")
2315      (cond [(eq_attr "alternative" "0,1,17,18")
2316               (const_string "nox64")
2317             (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2318               (const_string "x64")
2319             (eq_attr "alternative" "19,20")
2320               (const_string "x64_sse2")
2321             (eq_attr "alternative" "21,22")
2322               (const_string "sse2")
2323            ]
2324            (const_string "*")))
2325    (set (attr "type")
2326      (cond [(eq_attr "alternative" "0,1,17,18")
2327               (const_string "multi")
2328             (eq_attr "alternative" "6")
2329               (const_string "mmx")
2330             (eq_attr "alternative" "7,8,9,10,11")
2331               (const_string "mmxmov")
2332             (eq_attr "alternative" "12")
2333               (const_string "sselog1")
2334             (eq_attr "alternative" "13,14,15,16,19,20")
2335               (const_string "ssemov")
2336             (eq_attr "alternative" "21,22")
2337               (const_string "ssecvt")
2338             (eq_attr "alternative" "23,24,25,26")
2339               (const_string "mskmov")
2340             (and (match_operand 0 "register_operand")
2341                  (match_operand 1 "pic_32bit_operand"))
2342               (const_string "lea")
2343            ]
2344            (const_string "imov")))
2345    (set (attr "modrm")
2346      (if_then_else
2347        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2348        (const_string "0")
2349        (const_string "*")))
2350    (set (attr "length_immediate")
2351      (if_then_else
2352        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2353        (const_string "8")
2354        (const_string "*")))
2355    (set (attr "prefix_rex")
2356      (if_then_else
2357        (eq_attr "alternative" "10,11,19,20")
2358        (const_string "1")
2359        (const_string "*")))
2360    (set (attr "prefix")
2361      (if_then_else (eq_attr "type" "sselog1,ssemov")
2362        (const_string "maybe_vex")
2363        (const_string "orig")))
2364    (set (attr "prefix_data16")
2365      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2366        (const_string "1")
2367        (const_string "*")))
2368    (set (attr "mode")
2369      (cond [(eq_attr "alternative" "2")
2370               (const_string "SI")
2371             (eq_attr "alternative" "12,13")
2372               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2373                           (match_operand 1 "ext_sse_reg_operand"))
2374                        (const_string "TI")
2375                      (ior (not (match_test "TARGET_SSE2"))
2376                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2377                        (const_string "V4SF")
2378                      (match_test "TARGET_AVX")
2379                        (const_string "TI")
2380                      (match_test "optimize_function_for_size_p (cfun)")
2381                        (const_string "V4SF")
2382                     ]
2383                     (const_string "TI"))
2385             (and (eq_attr "alternative" "14,15,16")
2386                  (not (match_test "TARGET_SSE2")))
2387               (const_string "V2SF")
2388            ]
2389            (const_string "DI")))
2390    (set (attr "preferred_for_speed")
2391      (cond [(eq_attr "alternative" "10,17,19")
2392               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2393             (eq_attr "alternative" "11,18,20")
2394               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2395            ]
2396            (symbol_ref "true")))
2397    (set (attr "enabled")
2398      (cond [(eq_attr "alternative" "15")
2399               (if_then_else
2400                 (match_test "TARGET_STV && TARGET_SSE2")
2401                 (symbol_ref "false")
2402                 (const_string "*"))
2403             (eq_attr "alternative" "16")
2404               (if_then_else
2405                 (match_test "TARGET_STV && TARGET_SSE2")
2406                 (symbol_ref "true")
2407                 (symbol_ref "false"))
2408            ]
2409            (const_string "*")))])
2411 (define_split
2412   [(set (match_operand:<DWI> 0 "general_reg_operand")
2413         (match_operand:<DWI> 1 "sse_reg_operand"))]
2414   "TARGET_SSE4_1
2415    && reload_completed"
2416   [(set (match_dup 2)
2417         (vec_select:DWIH
2418           (match_dup 3)
2419           (parallel [(const_int 1)])))]
2421   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2422   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2424   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2425                   gen_lowpart (<MODE>mode, operands[1]));
2428 (define_split
2429   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2430         (match_operand:DWI 1 "general_gr_operand"))]
2431   "reload_completed"
2432   [(const_int 0)]
2433   "ix86_split_long_move (operands); DONE;")
2435 (define_split
2436   [(set (match_operand:DI 0 "sse_reg_operand")
2437         (match_operand:DI 1 "general_reg_operand"))]
2438   "!TARGET_64BIT && TARGET_SSE4_1
2439    && reload_completed"
2440   [(set (match_dup 2)
2441         (vec_merge:V4SI
2442           (vec_duplicate:V4SI (match_dup 3))
2443           (match_dup 2)
2444           (const_int 2)))]
2446   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2447   operands[3] = gen_highpart (SImode, operands[1]);
2449   emit_move_insn (gen_lowpart (SImode, operands[0]),
2450                   gen_lowpart (SImode, operands[1]));
2453 ;; movabsq $0x0012345678000000, %rax is longer
2454 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2455 (define_peephole2
2456   [(set (match_operand:DI 0 "register_operand")
2457         (match_operand:DI 1 "const_int_operand"))]
2458   "TARGET_64BIT
2459    && optimize_insn_for_size_p ()
2460    && LEGACY_INT_REG_P (operands[0])
2461    && !x86_64_immediate_operand (operands[1], DImode)
2462    && !x86_64_zext_immediate_operand (operands[1], DImode)
2463    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2464         & ~(HOST_WIDE_INT) 0xffffffff)
2465    && peep2_regno_dead_p (0, FLAGS_REG)"
2466   [(set (match_dup 0) (match_dup 1))
2467    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2468               (clobber (reg:CC FLAGS_REG))])]
2470   int shift = ctz_hwi (UINTVAL (operands[1]));
2471   operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2472   operands[2] = gen_int_mode (shift, QImode);
2475 (define_insn "*movsi_internal"
2476   [(set (match_operand:SI 0 "nonimmediate_operand"
2477     "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm")
2478         (match_operand:SI 1 "general_operand"
2479     "g ,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,*v,r  ,*r,*km,*k"))]
2480   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482   switch (get_attr_type (insn))
2483     {
2484     case TYPE_SSELOG1:
2485       return standard_sse_constant_opcode (insn, operands);
2487     case TYPE_MSKMOV:
2488       return "kmovd\t{%1, %0|%0, %1}";
2490     case TYPE_SSEMOV:
2491       switch (get_attr_mode (insn))
2492         {
2493         case MODE_SI:
2494           return "%vmovd\t{%1, %0|%0, %1}";
2495         case MODE_TI:
2496           return "%vmovdqa\t{%1, %0|%0, %1}";
2497         case MODE_XI:
2498           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2500         case MODE_V4SF:
2501           return "%vmovaps\t{%1, %0|%0, %1}";
2503         case MODE_SF:
2504           gcc_assert (!TARGET_AVX);
2505           return "movss\t{%1, %0|%0, %1}";
2507         default:
2508           gcc_unreachable ();
2509         }
2511     case TYPE_MMX:
2512       return "pxor\t%0, %0";
2514     case TYPE_MMXMOV:
2515       switch (get_attr_mode (insn))
2516         {
2517         case MODE_DI:
2518           return "movq\t{%1, %0|%0, %1}";
2519         case MODE_SI:
2520           return "movd\t{%1, %0|%0, %1}";
2522         default:
2523           gcc_unreachable ();
2524         }
2526     case TYPE_LEA:
2527       return "lea{l}\t{%E1, %0|%0, %E1}";
2529     case TYPE_IMOV:
2530       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2531       if (ix86_use_lea_for_mov (insn, operands))
2532         return "lea{l}\t{%E1, %0|%0, %E1}";
2533       else
2534         return "mov{l}\t{%1, %0|%0, %1}";
2536     default:
2537       gcc_unreachable ();
2538     }
2540   [(set (attr "isa")
2541      (cond [(eq_attr "alternative" "12,13")
2542               (const_string "sse2")
2543            ]
2544            (const_string "*")))
2545    (set (attr "type")
2546      (cond [(eq_attr "alternative" "2")
2547               (const_string "mmx")
2548             (eq_attr "alternative" "3,4,5,6,7")
2549               (const_string "mmxmov")
2550             (eq_attr "alternative" "8")
2551               (const_string "sselog1")
2552             (eq_attr "alternative" "9,10,11,12,13")
2553               (const_string "ssemov")
2554             (eq_attr "alternative" "14,15,16")
2555               (const_string "mskmov")
2556             (and (match_operand 0 "register_operand")
2557                  (match_operand 1 "pic_32bit_operand"))
2558               (const_string "lea")
2559            ]
2560            (const_string "imov")))
2561    (set (attr "prefix")
2562      (if_then_else (eq_attr "type" "sselog1,ssemov")
2563        (const_string "maybe_vex")
2564        (const_string "orig")))
2565    (set (attr "prefix_data16")
2566      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2567        (const_string "1")
2568        (const_string "*")))
2569    (set (attr "mode")
2570      (cond [(eq_attr "alternative" "2,3")
2571               (const_string "DI")
2572             (eq_attr "alternative" "8,9")
2573               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2574                           (match_operand 1 "ext_sse_reg_operand"))
2575                        (const_string "XI")
2576                      (ior (not (match_test "TARGET_SSE2"))
2577                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2578                        (const_string "V4SF")
2579                      (match_test "TARGET_AVX")
2580                        (const_string "TI")
2581                      (match_test "optimize_function_for_size_p (cfun)")
2582                        (const_string "V4SF")
2583                     ]
2584                     (const_string "TI"))
2586             (and (eq_attr "alternative" "10,11")
2587                  (not (match_test "TARGET_SSE2")))
2588               (const_string "SF")
2589            ]
2590            (const_string "SI")))
2591    (set (attr "preferred_for_speed")
2592      (cond [(eq_attr "alternative" "6,12")
2593               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2594             (eq_attr "alternative" "7,13")
2595               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2596            ]
2597            (symbol_ref "true")))])
2599 (define_insn "*movhi_internal"
2600   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2601         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2602   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2604   switch (get_attr_type (insn))
2605     {
2606     case TYPE_IMOVX:
2607       /* movzwl is faster than movw on p2 due to partial word stalls,
2608          though not as fast as an aligned movl.  */
2609       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2611     case TYPE_MSKMOV:
2612       switch (which_alternative)
2613         {
2614         case 4:
2615           return "kmovw\t{%k1, %0|%0, %k1}";
2616         case 6:
2617           return "kmovw\t{%1, %k0|%k0, %1}";
2618         case 5:
2619         case 7:
2620           return "kmovw\t{%1, %0|%0, %1}";
2621         default:
2622           gcc_unreachable ();
2623         }
2625     default:
2626       if (get_attr_mode (insn) == MODE_SI)
2627         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2628       else
2629         return "mov{w}\t{%1, %0|%0, %1}";
2630     }
2632   [(set (attr "type")
2633      (cond [(eq_attr "alternative" "4,5,6,7")
2634               (const_string "mskmov")
2635             (match_test "optimize_function_for_size_p (cfun)")
2636               (const_string "imov")
2637             (and (eq_attr "alternative" "0")
2638                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2639                       (not (match_test "TARGET_HIMODE_MATH"))))
2640               (const_string "imov")
2641             (and (eq_attr "alternative" "1,2")
2642                  (match_operand:HI 1 "aligned_operand"))
2643               (const_string "imov")
2644             (and (match_test "TARGET_MOVX")
2645                  (eq_attr "alternative" "0,2"))
2646               (const_string "imovx")
2647            ]
2648            (const_string "imov")))
2649     (set (attr "prefix")
2650       (if_then_else (eq_attr "alternative" "4,5,6,7")
2651         (const_string "vex")
2652         (const_string "orig")))
2653     (set (attr "mode")
2654       (cond [(eq_attr "type" "imovx")
2655                (const_string "SI")
2656              (and (eq_attr "alternative" "1,2")
2657                   (match_operand:HI 1 "aligned_operand"))
2658                (const_string "SI")
2659              (and (eq_attr "alternative" "0")
2660                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2661                        (not (match_test "TARGET_HIMODE_MATH"))))
2662                (const_string "SI")
2663             ]
2664             (const_string "HI")))])
2666 ;; Situation is quite tricky about when to choose full sized (SImode) move
2667 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2668 ;; partial register dependency machines (such as AMD Athlon), where QImode
2669 ;; moves issue extra dependency and for partial register stalls machines
2670 ;; that don't use QImode patterns (and QImode move cause stall on the next
2671 ;; instruction).
2673 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2674 ;; register stall machines with, where we use QImode instructions, since
2675 ;; partial register stall can be caused there.  Then we use movzx.
2677 (define_insn "*movqi_internal"
2678   [(set (match_operand:QI 0 "nonimmediate_operand"
2679                         "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2680         (match_operand:QI 1 "general_operand"
2681                         "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2682   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2684   static char buf[128];
2685   const char *ops;
2686   const char *suffix;
2688   switch (get_attr_type (insn))
2689     {
2690     case TYPE_IMOVX:
2691       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2692       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2694     case TYPE_MSKMOV:
2695       switch (which_alternative)
2696         {
2697         case 9:
2698           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2699           break;
2700         case 11:
2701           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2702           break;
2703         case 12:
2704         case 13:
2705           gcc_assert (TARGET_AVX512DQ);
2706           /* FALLTHRU */
2707         case 10:
2708           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2709           break;
2710         default:
2711           gcc_unreachable ();
2712         }
2714       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2716       snprintf (buf, sizeof (buf), ops, suffix);
2717       return buf;
2719     default:
2720       if (get_attr_mode (insn) == MODE_SI)
2721         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2722       else
2723         return "mov{b}\t{%1, %0|%0, %1}";
2724     }
2726   [(set (attr "isa")
2727      (cond [(eq_attr "alternative" "1,2")
2728               (const_string "x64")
2729             (eq_attr "alternative" "12,13")
2730               (const_string "avx512dq")
2731            ]
2732            (const_string "*")))
2733    (set (attr "type")
2734      (cond [(eq_attr "alternative" "9,10,11,12,13")
2735               (const_string "mskmov")
2736             (and (eq_attr "alternative" "7")
2737                  (not (match_operand:QI 1 "aligned_operand")))
2738               (const_string "imovx")
2739             (match_test "optimize_function_for_size_p (cfun)")
2740               (const_string "imov")
2741             (and (eq_attr "alternative" "5")
2742                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2743                       (not (match_test "TARGET_QIMODE_MATH"))))
2744               (const_string "imov")
2745             (eq_attr "alternative" "5,7")
2746               (const_string "imovx")
2747             (and (match_test "TARGET_MOVX")
2748                  (eq_attr "alternative" "4"))
2749               (const_string "imovx")
2750            ]
2751            (const_string "imov")))
2752    (set (attr "prefix")
2753      (if_then_else (eq_attr "alternative" "9,10,11")
2754        (const_string "vex")
2755        (const_string "orig")))
2756    (set (attr "mode")
2757       (cond [(eq_attr "alternative" "5,6,7")
2758                (const_string "SI")
2759              (eq_attr "alternative" "8")
2760                (const_string "QI")
2761              (and (eq_attr "alternative" "9,10,11")
2762                   (not (match_test "TARGET_AVX512DQ")))
2763                (const_string "HI")
2764              (eq_attr "type" "imovx")
2765                (const_string "SI")
2766              ;; For -Os, 8-bit immediates are always shorter than 32-bit
2767              ;; ones.
2768              (and (eq_attr "type" "imov")
2769                   (and (eq_attr "alternative" "3")
2770                        (match_test "optimize_function_for_size_p (cfun)")))
2771                (const_string "QI")
2772              ;; For -Os, movl where one or both operands are NON_Q_REGS
2773              ;; and both are LEGACY_REGS is shorter than movb.
2774              ;; Otherwise movb and movl sizes are the same, so decide purely
2775              ;; based on speed factors.
2776              (and (eq_attr "type" "imov")
2777                   (and (eq_attr "alternative" "1")
2778                        (match_test "optimize_function_for_size_p (cfun)")))
2779                (const_string "SI")
2780              (and (eq_attr "type" "imov")
2781                   (and (eq_attr "alternative" "0,1,2,3")
2782                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2783                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2784                (const_string "SI")
2785              ;; Avoid partial register stalls when not using QImode arithmetic
2786              (and (eq_attr "type" "imov")
2787                   (and (eq_attr "alternative" "0,1,2,3")
2788                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2789                             (not (match_test "TARGET_QIMODE_MATH")))))
2790                (const_string "SI")
2791            ]
2792            (const_string "QI")))])
2794 ;; Stores and loads of ax to arbitrary constant address.
2795 ;; We fake an second form of instruction to force reload to load address
2796 ;; into register when rax is not available
2797 (define_insn "*movabs<mode>_1"
2798   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2799         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2800   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2802   /* Recover the full memory rtx.  */
2803   operands[0] = SET_DEST (PATTERN (insn));
2804   switch (which_alternative)
2805     {
2806     case 0:
2807       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2808     case 1:
2809       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2810     default:
2811       gcc_unreachable ();
2812     }
2814   [(set_attr "type" "imov")
2815    (set_attr "modrm" "0,*")
2816    (set_attr "length_address" "8,0")
2817    (set_attr "length_immediate" "0,*")
2818    (set_attr "memory" "store")
2819    (set_attr "mode" "<MODE>")])
2821 (define_insn "*movabs<mode>_2"
2822   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2823         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2824   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2826   /* Recover the full memory rtx.  */
2827   operands[1] = SET_SRC (PATTERN (insn));
2828   switch (which_alternative)
2829     {
2830     case 0:
2831       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2832     case 1:
2833       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2834     default:
2835       gcc_unreachable ();
2836     }
2838   [(set_attr "type" "imov")
2839    (set_attr "modrm" "0,*")
2840    (set_attr "length_address" "8,0")
2841    (set_attr "length_immediate" "0")
2842    (set_attr "memory" "load")
2843    (set_attr "mode" "<MODE>")])
2845 (define_insn "*swap<mode>"
2846   [(set (match_operand:SWI48 0 "register_operand" "+r")
2847         (match_operand:SWI48 1 "register_operand" "+r"))
2848    (set (match_dup 1)
2849         (match_dup 0))]
2850   ""
2851   "xchg{<imodesuffix>}\t%1, %0"
2852   [(set_attr "type" "imov")
2853    (set_attr "mode" "<MODE>")
2854    (set_attr "pent_pair" "np")
2855    (set_attr "athlon_decode" "vector")
2856    (set_attr "amdfam10_decode" "double")
2857    (set_attr "bdver1_decode" "double")])
2859 (define_insn "*swap<mode>"
2860   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2861         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2862    (set (match_dup 1)
2863         (match_dup 0))]
2864   ""
2865   "@
2866    xchg{<imodesuffix>}\t%1, %0
2867    xchg{l}\t%k1, %k0"
2868   [(set_attr "type" "imov")
2869    (set_attr "mode" "<MODE>,SI")
2870    (set (attr "preferred_for_size")
2871      (cond [(eq_attr "alternative" "0")
2872               (symbol_ref "false")]
2873            (symbol_ref "true")))
2874    ;; Potential partial reg stall on alternative 1.
2875    (set (attr "preferred_for_speed")
2876      (cond [(eq_attr "alternative" "1")
2877               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2878            (symbol_ref "true")))
2879    (set_attr "pent_pair" "np")
2880    (set_attr "athlon_decode" "vector")
2881    (set_attr "amdfam10_decode" "double")
2882    (set_attr "bdver1_decode" "double")])
2884 (define_expand "movstrict<mode>"
2885   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2886         (match_operand:SWI12 1 "general_operand"))]
2887   ""
2889   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2890     FAIL;
2891   if (SUBREG_P (operands[0])
2892       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2893     FAIL;
2894   /* Don't generate memory->memory moves, go through a register */
2895   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2896     operands[1] = force_reg (<MODE>mode, operands[1]);
2899 (define_insn "*movstrict<mode>_1"
2900   [(set (strict_low_part
2901           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2902         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2903   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2904    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2905   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2906   [(set_attr "type" "imov")
2907    (set_attr "mode" "<MODE>")])
2909 (define_insn "*movstrict<mode>_xor"
2910   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2911         (match_operand:SWI12 1 "const0_operand"))
2912    (clobber (reg:CC FLAGS_REG))]
2913   "reload_completed"
2914   "xor{<imodesuffix>}\t%0, %0"
2915   [(set_attr "type" "alu1")
2916    (set_attr "modrm_class" "op0")
2917    (set_attr "mode" "<MODE>")
2918    (set_attr "length_immediate" "0")])
2920 (define_expand "extv<mode>"
2921   [(set (match_operand:SWI24 0 "register_operand")
2922         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2923                             (match_operand:SI 2 "const_int_operand")
2924                             (match_operand:SI 3 "const_int_operand")))]
2925   ""
2927   /* Handle extractions from %ah et al.  */
2928   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2929     FAIL;
2931   unsigned int regno = reg_or_subregno (operands[1]);
2933   /* Be careful to expand only with registers having upper parts.  */
2934   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2935     operands[1] = copy_to_reg (operands[1]);
2938 (define_insn "*extv<mode>"
2939   [(set (match_operand:SWI24 0 "register_operand" "=R")
2940         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2941                             (const_int 8)
2942                             (const_int 8)))]
2943   ""
2944   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2945   [(set_attr "type" "imovx")
2946    (set_attr "mode" "SI")])
2948 (define_expand "extzv<mode>"
2949   [(set (match_operand:SWI248 0 "register_operand")
2950         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2951                              (match_operand:SI 2 "const_int_operand")
2952                              (match_operand:SI 3 "const_int_operand")))]
2953   ""
2955   if (ix86_expand_pextr (operands))
2956     DONE;
2958   /* Handle extractions from %ah et al.  */
2959   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2960     FAIL;
2962   unsigned int regno = reg_or_subregno (operands[1]);
2964   /* Be careful to expand only with registers having upper parts.  */
2965   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2966     operands[1] = copy_to_reg (operands[1]);
2969 (define_insn "*extzvqi_mem_rex64"
2970   [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2971         (subreg:QI
2972           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2973                            (const_int 8)
2974                            (const_int 8)) 0))]
2975   "TARGET_64BIT && reload_completed"
2976   "mov{b}\t{%h1, %0|%0, %h1}"
2977   [(set_attr "type" "imov")
2978    (set_attr "mode" "QI")])
2980 (define_insn "*extzv<mode>"
2981   [(set (match_operand:SWI248 0 "register_operand" "=R")
2982         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2983                              (const_int 8)
2984                              (const_int 8)))]
2985   ""
2986   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2987   [(set_attr "type" "imovx")
2988    (set_attr "mode" "SI")])
2990 (define_insn "*extzvqi"
2991   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2992         (subreg:QI
2993           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2994                            (const_int 8)
2995                            (const_int 8)) 0))]
2996   ""
2998   switch (get_attr_type (insn))
2999     {
3000     case TYPE_IMOVX:
3001       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3002     default:
3003       return "mov{b}\t{%h1, %0|%0, %h1}";
3004     }
3006   [(set_attr "isa" "*,*,nox64")
3007    (set (attr "type")
3008      (if_then_else (and (match_operand:QI 0 "register_operand")
3009                         (ior (not (match_operand:QI 0 "QIreg_operand"))
3010                              (match_test "TARGET_MOVX")))
3011         (const_string "imovx")
3012         (const_string "imov")))
3013    (set (attr "mode")
3014      (if_then_else (eq_attr "type" "imovx")
3015         (const_string "SI")
3016         (const_string "QI")))])
3018 (define_peephole2
3019   [(set (match_operand:QI 0 "register_operand")
3020         (subreg:QI
3021           (zero_extract:SI (match_operand 1 "ext_register_operand")
3022                            (const_int 8)
3023                            (const_int 8)) 0))
3024    (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3025   "TARGET_64BIT
3026    && peep2_reg_dead_p (2, operands[0])"
3027   [(set (match_dup 2)
3028         (subreg:QI
3029           (zero_extract:SI (match_dup 1)
3030                            (const_int 8)
3031                            (const_int 8)) 0))])
3033 (define_expand "insv<mode>"
3034   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3035                              (match_operand:SI 1 "const_int_operand")
3036                              (match_operand:SI 2 "const_int_operand"))
3037         (match_operand:SWI248 3 "register_operand"))]
3038   ""
3040   rtx dst;
3042   if (ix86_expand_pinsr (operands))
3043     DONE;
3045   /* Handle insertions to %ah et al.  */
3046   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3047     FAIL;
3049   unsigned int regno = reg_or_subregno (operands[0]);
3051   /* Be careful to expand only with registers having upper parts.  */
3052   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3053     dst = copy_to_reg (operands[0]);
3054   else
3055     dst = operands[0];
3057   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3059   /* Fix up the destination if needed.  */
3060   if (dst != operands[0])
3061     emit_move_insn (operands[0], dst);
3063   DONE;
3066 (define_insn "*insvqi_1_mem_rex64"
3067   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3068                          (const_int 8)
3069                          (const_int 8))
3070         (subreg:SI
3071           (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3072   "TARGET_64BIT && reload_completed"
3073   "mov{b}\t{%1, %h0|%h0, %1}"
3074   [(set_attr "type" "imov")
3075    (set_attr "mode" "QI")])
3077 (define_insn "insv<mode>_1"
3078   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3079                              (const_int 8)
3080                              (const_int 8))
3081         (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3082   ""
3084   if (CONST_INT_P (operands[1]))
3085     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3086   return "mov{b}\t{%b1, %h0|%h0, %b1}";
3088   [(set_attr "isa" "*,nox64")
3089    (set_attr "type" "imov")
3090    (set_attr "mode" "QI")])
3092 (define_insn "*insvqi_1"
3093   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3094                          (const_int 8)
3095                          (const_int 8))
3096         (subreg:SI
3097           (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3098   ""
3099   "mov{b}\t{%1, %h0|%h0, %1}"
3100   [(set_attr "isa" "*,nox64")
3101    (set_attr "type" "imov")
3102    (set_attr "mode" "QI")])
3104 (define_peephole2
3105   [(set (match_operand:QI 0 "register_operand")
3106         (match_operand:QI 1 "norex_memory_operand"))
3107    (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3108                          (const_int 8)
3109                          (const_int 8))
3110         (subreg:SI (match_dup 0) 0))]
3111   "TARGET_64BIT
3112    && peep2_reg_dead_p (2, operands[0])"
3113   [(set (zero_extract:SI (match_dup 2)
3114                          (const_int 8)
3115                          (const_int 8))
3116            (subreg:SI (match_dup 1) 0))])
3118 (define_code_iterator any_extract [sign_extract zero_extract])
3120 (define_insn "*insvqi_2"
3121   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3122                          (const_int 8)
3123                          (const_int 8))
3124         (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3125                         (const_int 8)
3126                         (const_int 8)))]
3127   ""
3128   "mov{b}\t{%h1, %h0|%h0, %h1}"
3129   [(set_attr "type" "imov")
3130    (set_attr "mode" "QI")])
3132 (define_insn "*insvqi_3"
3133   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3134                          (const_int 8)
3135                          (const_int 8))
3136         (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3137                         (const_int 8)))]
3138   ""
3139   "mov{b}\t{%h1, %h0|%h0, %h1}"
3140   [(set_attr "type" "imov")
3141    (set_attr "mode" "QI")])
3143 ;; Floating point push instructions.
3145 (define_insn "*pushtf"
3146   [(set (match_operand:TF 0 "push_operand" "=<,<")
3147         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3148   "TARGET_64BIT || TARGET_SSE"
3150   /* This insn should be already split before reg-stack.  */
3151   gcc_unreachable ();
3153   [(set_attr "isa" "*,x64")
3154    (set_attr "type" "multi")
3155    (set_attr "unit" "sse,*")
3156    (set_attr "mode" "TF,DI")])
3158 ;; %%% Kill this when call knows how to work this out.
3159 (define_split
3160   [(set (match_operand:TF 0 "push_operand")
3161         (match_operand:TF 1 "sse_reg_operand"))]
3162   "TARGET_SSE && reload_completed"
3163   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3164    (set (match_dup 0) (match_dup 1))]
3166   /* Preserve memory attributes. */
3167   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3170 (define_insn_and_split "*pushxf_rounded"
3171   [(set (mem:XF
3172           (pre_modify:P
3173             (reg:P SP_REG)
3174             (plus:P (reg:P SP_REG) (const_int -16))))
3175         (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3176   "TARGET_64BIT"
3177   "#"
3178   "&& 1"
3179   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3180    (set (match_dup 1) (match_dup 0))]
3182   rtx pat = PATTERN (curr_insn);
3183   operands[1] = SET_DEST (pat);
3185   /* Preserve memory attributes. */
3186   operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3188   [(set_attr "type" "multi")
3189    (set_attr "unit" "i387,*,*,*")
3190    (set (attr "mode")
3191         (cond [(eq_attr "alternative" "1,2,3")
3192                  (const_string "DI")
3193               ]
3194               (const_string "XF")))
3195    (set (attr "preferred_for_size")
3196      (cond [(eq_attr "alternative" "1")
3197               (symbol_ref "false")]
3198            (symbol_ref "true")))])
3200 (define_insn "*pushxf"
3201   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3202         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3203   ""
3205   /* This insn should be already split before reg-stack.  */
3206   gcc_unreachable ();
3208   [(set_attr "isa" "*,*,*,nox64,x64")
3209    (set_attr "type" "multi")
3210    (set_attr "unit" "i387,*,*,*,*")
3211    (set (attr "mode")
3212         (cond [(eq_attr "alternative" "1,2,3,4")
3213                  (if_then_else (match_test "TARGET_64BIT")
3214                    (const_string "DI")
3215                    (const_string "SI"))
3216               ]
3217               (const_string "XF")))
3218    (set (attr "preferred_for_size")
3219      (cond [(eq_attr "alternative" "1")
3220               (symbol_ref "false")]
3221            (symbol_ref "true")))])
3223 ;; %%% Kill this when call knows how to work this out.
3224 (define_split
3225   [(set (match_operand:XF 0 "push_operand")
3226         (match_operand:XF 1 "fp_register_operand"))]
3227   "reload_completed"
3228   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3229    (set (match_dup 0) (match_dup 1))]
3231   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3232   /* Preserve memory attributes. */
3233   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3236 (define_insn "*pushdf"
3237   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3238         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3239   ""
3241   /* This insn should be already split before reg-stack.  */
3242   gcc_unreachable ();
3244   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3245    (set_attr "type" "multi")
3246    (set_attr "unit" "i387,*,*,*,*,sse")
3247    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3248    (set (attr "preferred_for_size")
3249      (cond [(eq_attr "alternative" "1")
3250               (symbol_ref "false")]
3251            (symbol_ref "true")))
3252    (set (attr "preferred_for_speed")
3253      (cond [(eq_attr "alternative" "1")
3254               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3255            (symbol_ref "true")))])
3256    
3257 ;; %%% Kill this when call knows how to work this out.
3258 (define_split
3259   [(set (match_operand:DF 0 "push_operand")
3260         (match_operand:DF 1 "any_fp_register_operand"))]
3261   "reload_completed"
3262   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3263    (set (match_dup 0) (match_dup 1))]
3265   /* Preserve memory attributes. */
3266   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3269 (define_insn "*pushsf_rex64"
3270   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3271         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3272   "TARGET_64BIT"
3274   /* Anything else should be already split before reg-stack.  */
3275   gcc_assert (which_alternative == 1);
3276   return "push{q}\t%q1";
3278   [(set_attr "type" "multi,push,multi")
3279    (set_attr "unit" "i387,*,*")
3280    (set_attr "mode" "SF,DI,SF")])
3282 (define_insn "*pushsf"
3283   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3284         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3285   "!TARGET_64BIT"
3287   /* Anything else should be already split before reg-stack.  */
3288   gcc_assert (which_alternative == 1);
3289   return "push{l}\t%1";
3291   [(set_attr "type" "multi,push,multi")
3292    (set_attr "unit" "i387,*,*")
3293    (set_attr "mode" "SF,SI,SF")])
3295 ;; %%% Kill this when call knows how to work this out.
3296 (define_split
3297   [(set (match_operand:SF 0 "push_operand")
3298         (match_operand:SF 1 "any_fp_register_operand"))]
3299   "reload_completed"
3300   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3301    (set (match_dup 0) (match_dup 1))]
3303   rtx op = XEXP (operands[0], 0);
3304   if (GET_CODE (op) == PRE_DEC)
3305     {
3306       gcc_assert (!TARGET_64BIT);
3307       op = GEN_INT (-4);
3308     }
3309   else
3310     {
3311       op = XEXP (XEXP (op, 1), 1);
3312       gcc_assert (CONST_INT_P (op));
3313     }
3314   operands[2] = op;
3315   /* Preserve memory attributes. */
3316   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3319 (define_split
3320   [(set (match_operand:SF 0 "push_operand")
3321         (match_operand:SF 1 "memory_operand"))]
3322   "reload_completed
3323    && find_constant_src (insn)"
3324   [(set (match_dup 0) (match_dup 2))]
3325   "operands[2] = find_constant_src (curr_insn);")
3327 (define_split
3328   [(set (match_operand 0 "push_operand")
3329         (match_operand 1 "general_gr_operand"))]
3330   "reload_completed
3331    && (GET_MODE (operands[0]) == TFmode
3332        || GET_MODE (operands[0]) == XFmode
3333        || GET_MODE (operands[0]) == DFmode)"
3334   [(const_int 0)]
3335   "ix86_split_long_move (operands); DONE;")
3337 ;; Floating point move instructions.
3339 (define_expand "movtf"
3340   [(set (match_operand:TF 0 "nonimmediate_operand")
3341         (match_operand:TF 1 "nonimmediate_operand"))]
3342   "TARGET_64BIT || TARGET_SSE"
3343   "ix86_expand_move (TFmode, operands); DONE;")
3345 (define_expand "mov<mode>"
3346   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3347         (match_operand:X87MODEF 1 "general_operand"))]
3348   ""
3349   "ix86_expand_move (<MODE>mode, operands); DONE;")
3351 (define_insn "*movtf_internal"
3352   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3353         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3354   "(TARGET_64BIT || TARGET_SSE)
3355    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3356    && (lra_in_progress || reload_completed
3357        || !CONST_DOUBLE_P (operands[1])
3358        || ((optimize_function_for_size_p (cfun)
3359             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3360            && standard_sse_constant_p (operands[1], TFmode) == 1
3361            && !memory_operand (operands[0], TFmode))
3362        || (!TARGET_MEMORY_MISMATCH_STALL
3363            && memory_operand (operands[0], TFmode)))"
3365   switch (get_attr_type (insn))
3366     {
3367     case TYPE_SSELOG1:
3368       return standard_sse_constant_opcode (insn, operands);
3370     case TYPE_SSEMOV:
3371       /* Handle misaligned load/store since we
3372          don't have movmisaligntf pattern. */
3373       if (misaligned_operand (operands[0], TFmode)
3374           || misaligned_operand (operands[1], TFmode))
3375         {
3376           if (get_attr_mode (insn) == MODE_V4SF)
3377             return "%vmovups\t{%1, %0|%0, %1}";
3378           else if (TARGET_AVX512VL
3379                    && (EXT_REX_SSE_REG_P (operands[0])
3380                        || EXT_REX_SSE_REG_P (operands[1])))
3381             return "vmovdqu64\t{%1, %0|%0, %1}";
3382           else
3383             return "%vmovdqu\t{%1, %0|%0, %1}";
3384         }
3385       else
3386         {
3387           if (get_attr_mode (insn) == MODE_V4SF)
3388             return "%vmovaps\t{%1, %0|%0, %1}";
3389           else if (TARGET_AVX512VL
3390                    && (EXT_REX_SSE_REG_P (operands[0])
3391                        || EXT_REX_SSE_REG_P (operands[1])))
3392             return "vmovdqa64\t{%1, %0|%0, %1}";
3393           else
3394             return "%vmovdqa\t{%1, %0|%0, %1}";
3395         }
3397     case TYPE_MULTI:
3398         return "#";
3400     default:
3401       gcc_unreachable ();
3402     }
3404   [(set_attr "isa" "*,*,*,x64,x64")
3405    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3406    (set (attr "prefix")
3407      (if_then_else (eq_attr "type" "sselog1,ssemov")
3408        (const_string "maybe_vex")
3409        (const_string "orig")))
3410    (set (attr "mode")
3411         (cond [(eq_attr "alternative" "3,4")
3412                  (const_string "DI")
3413                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3414                  (const_string "V4SF")
3415                (and (eq_attr "alternative" "2")
3416                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3417                  (const_string "V4SF")
3418                (match_test "TARGET_AVX")
3419                  (const_string "TI")
3420                (ior (not (match_test "TARGET_SSE2"))
3421                     (match_test "optimize_function_for_size_p (cfun)"))
3422                  (const_string "V4SF")
3423                ]
3424                (const_string "TI")))])
3426 (define_split
3427   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3428         (match_operand:TF 1 "general_gr_operand"))]
3429   "reload_completed"
3430   [(const_int 0)]
3431   "ix86_split_long_move (operands); DONE;")
3433 ;; Possible store forwarding (partial memory) stall
3434 ;; in alternatives 4, 6, 7 and 8.
3435 (define_insn "*movxf_internal"
3436   [(set (match_operand:XF 0 "nonimmediate_operand"
3437          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3438         (match_operand:XF 1 "general_operand"
3439          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3440   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3441    && (lra_in_progress || reload_completed
3442        || !CONST_DOUBLE_P (operands[1])
3443        || ((optimize_function_for_size_p (cfun)
3444             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3445            && standard_80387_constant_p (operands[1]) > 0
3446            && !memory_operand (operands[0], XFmode))
3447        || (!TARGET_MEMORY_MISMATCH_STALL
3448            && memory_operand (operands[0], XFmode))
3449        || !TARGET_HARD_XF_REGS)"
3451   switch (get_attr_type (insn))
3452     {
3453     case TYPE_FMOV:
3454       if (which_alternative == 2)
3455         return standard_80387_constant_opcode (operands[1]);
3456       return output_387_reg_move (insn, operands);
3458     case TYPE_MULTI:
3459       return "#";
3461     default:
3462       gcc_unreachable ();
3463     }
3465   [(set (attr "isa")
3466         (cond [(eq_attr "alternative" "7,10")
3467                  (const_string "nox64")
3468                (eq_attr "alternative" "8,11")
3469                  (const_string "x64")
3470               ]
3471               (const_string "*")))
3472    (set (attr "type")
3473         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3474                  (const_string "multi")
3475               ]
3476               (const_string "fmov")))
3477    (set (attr "mode")
3478         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3479                  (if_then_else (match_test "TARGET_64BIT")
3480                    (const_string "DI")
3481                    (const_string "SI"))
3482               ]
3483               (const_string "XF")))
3484    (set (attr "preferred_for_size")
3485      (cond [(eq_attr "alternative" "3,4")
3486               (symbol_ref "false")]
3487            (symbol_ref "true")))
3488    (set (attr "enabled")
3489      (cond [(eq_attr "alternative" "9,10,11")
3490               (if_then_else
3491                 (match_test "TARGET_HARD_XF_REGS")
3492                 (symbol_ref "false")
3493                 (const_string "*"))
3494             (not (match_test "TARGET_HARD_XF_REGS"))
3495               (symbol_ref "false")
3496            ]
3497            (const_string "*")))])
3498    
3499 (define_split
3500   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3501         (match_operand:XF 1 "general_gr_operand"))]
3502   "reload_completed"
3503   [(const_int 0)]
3504   "ix86_split_long_move (operands); DONE;")
3506 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3507 (define_insn "*movdf_internal"
3508   [(set (match_operand:DF 0 "nonimmediate_operand"
3509     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r  ,o ,r  ,m")
3510         (match_operand:DF 1 "general_operand"
3511     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))]
3512   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3513    && (lra_in_progress || reload_completed
3514        || !CONST_DOUBLE_P (operands[1])
3515        || ((optimize_function_for_size_p (cfun)
3516             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3517            && ((IS_STACK_MODE (DFmode)
3518                 && standard_80387_constant_p (operands[1]) > 0)
3519                || (TARGET_SSE2 && TARGET_SSE_MATH
3520                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3521            && !memory_operand (operands[0], DFmode))
3522        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3523            && memory_operand (operands[0], DFmode))
3524        || !TARGET_HARD_DF_REGS)"
3526   switch (get_attr_type (insn))
3527     {
3528     case TYPE_FMOV:
3529       if (which_alternative == 2)
3530         return standard_80387_constant_opcode (operands[1]);
3531       return output_387_reg_move (insn, operands);
3533     case TYPE_MULTI:
3534       return "#";
3536     case TYPE_IMOV:
3537       if (get_attr_mode (insn) == MODE_SI)
3538         return "mov{l}\t{%1, %k0|%k0, %1}";
3539       else if (which_alternative == 11)
3540         return "movabs{q}\t{%1, %0|%0, %1}";
3541       else
3542         return "mov{q}\t{%1, %0|%0, %1}";
3544     case TYPE_SSELOG1:
3545       return standard_sse_constant_opcode (insn, operands);
3547     case TYPE_SSEMOV:
3548       switch (get_attr_mode (insn))
3549         {
3550         case MODE_DF:
3551           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3552             return "vmovsd\t{%d1, %0|%0, %d1}";
3553           return "%vmovsd\t{%1, %0|%0, %1}";
3555         case MODE_V4SF:
3556           return "%vmovaps\t{%1, %0|%0, %1}";
3557         case MODE_V8DF:
3558           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3559         case MODE_V2DF:
3560           return "%vmovapd\t{%1, %0|%0, %1}";
3562         case MODE_V2SF:
3563           gcc_assert (!TARGET_AVX);
3564           return "movlps\t{%1, %0|%0, %1}";
3565         case MODE_V1DF:
3566           gcc_assert (!TARGET_AVX);
3567           return "movlpd\t{%1, %0|%0, %1}";
3569         case MODE_DI:
3570           /* Handle broken assemblers that require movd instead of movq.  */
3571           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3572               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3573             return "%vmovd\t{%1, %0|%0, %1}";
3574           return "%vmovq\t{%1, %0|%0, %1}";
3576         default:
3577           gcc_unreachable ();
3578         }
3580     default:
3581       gcc_unreachable ();
3582     }
3584   [(set (attr "isa")
3585         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3586                  (const_string "nox64")
3587                (eq_attr "alternative" "8,9,10,11,24,25")
3588                  (const_string "x64")
3589                (eq_attr "alternative" "12,13,14,15")
3590                  (const_string "sse2")
3591                (eq_attr "alternative" "20,21")
3592                  (const_string "x64_sse2")
3593               ]
3594               (const_string "*")))
3595    (set (attr "type")
3596         (cond [(eq_attr "alternative" "0,1,2")
3597                  (const_string "fmov")
3598                (eq_attr "alternative" "3,4,5,6,7,22,23")
3599                  (const_string "multi")
3600                (eq_attr "alternative" "8,9,10,11,24,25")
3601                  (const_string "imov")
3602                (eq_attr "alternative" "12,16")
3603                  (const_string "sselog1")
3604               ]
3605               (const_string "ssemov")))
3606    (set (attr "modrm")
3607      (if_then_else (eq_attr "alternative" "11")
3608        (const_string "0")
3609        (const_string "*")))
3610    (set (attr "length_immediate")
3611      (if_then_else (eq_attr "alternative" "11")
3612        (const_string "8")
3613        (const_string "*")))
3614    (set (attr "prefix")
3615      (if_then_else (eq_attr "type" "sselog1,ssemov")
3616        (const_string "maybe_vex")
3617        (const_string "orig")))
3618    (set (attr "prefix_data16")
3619      (if_then_else
3620        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3621             (eq_attr "mode" "V1DF"))
3622        (const_string "1")
3623        (const_string "*")))
3624    (set (attr "mode")
3625         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3626                  (const_string "SI")
3627                (eq_attr "alternative" "8,9,11,20,21,24,25")
3628                  (const_string "DI")
3630                /* xorps is one byte shorter for non-AVX targets.  */
3631                (eq_attr "alternative" "12,16")
3632                  (cond [(not (match_test "TARGET_SSE2"))
3633                           (const_string "V4SF")
3634                         (and (match_test "TARGET_AVX512F")
3635                           (not (match_test "TARGET_PREFER_AVX256")))
3636                           (const_string "XI")
3637                         (match_test "TARGET_AVX")
3638                           (const_string "V2DF")
3639                         (match_test "optimize_function_for_size_p (cfun)")
3640                           (const_string "V4SF")
3641                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3642                           (const_string "TI")
3643                        ]
3644                        (const_string "V2DF"))
3646                /* For architectures resolving dependencies on
3647                   whole SSE registers use movapd to break dependency
3648                   chains, otherwise use short move to avoid extra work.  */
3650                /* movaps is one byte shorter for non-AVX targets.  */
3651                (eq_attr "alternative" "13,17")
3652                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3653                                   (not (match_test "TARGET_AVX512VL")))
3654                              (ior (match_operand 0 "ext_sse_reg_operand")
3655                                   (match_operand 1 "ext_sse_reg_operand")))
3656                           (const_string "V8DF")
3657                         (ior (not (match_test "TARGET_SSE2"))
3658                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3659                           (const_string "V4SF")
3660                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3661                           (const_string "V2DF")
3662                         (match_test "TARGET_AVX")
3663                           (const_string "DF")
3664                         (match_test "optimize_function_for_size_p (cfun)")
3665                           (const_string "V4SF")
3666                        ]
3667                        (const_string "DF"))
3669                /* For architectures resolving dependencies on register
3670                   parts we may avoid extra work to zero out upper part
3671                   of register.  */
3672                (eq_attr "alternative" "14,18")
3673                  (cond [(not (match_test "TARGET_SSE2"))
3674                           (const_string "V2SF")
3675                         (match_test "TARGET_AVX")
3676                           (const_string "DF")
3677                         (match_test "TARGET_SSE_SPLIT_REGS")
3678                           (const_string "V1DF")
3679                        ]
3680                        (const_string "DF"))
3682                (and (eq_attr "alternative" "15,19")
3683                     (not (match_test "TARGET_SSE2")))
3684                  (const_string "V2SF")
3685               ]
3686               (const_string "DF")))
3687    (set (attr "preferred_for_size")
3688      (cond [(eq_attr "alternative" "3,4")
3689               (symbol_ref "false")]
3690            (symbol_ref "true")))
3691    (set (attr "preferred_for_speed")
3692      (cond [(eq_attr "alternative" "3,4")
3693               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3694             (eq_attr "alternative" "20")
3695               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3696             (eq_attr "alternative" "21")
3697               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3698            ]
3699            (symbol_ref "true")))
3700    (set (attr "enabled")
3701      (cond [(eq_attr "alternative" "22,23,24,25")
3702               (if_then_else
3703                 (match_test "TARGET_HARD_DF_REGS")
3704                 (symbol_ref "false")
3705                 (const_string "*"))
3706             (not (match_test "TARGET_HARD_DF_REGS"))
3707               (symbol_ref "false")
3708            ]
3709            (const_string "*")))])
3711 (define_split
3712   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3713         (match_operand:DF 1 "general_gr_operand"))]
3714   "!TARGET_64BIT && reload_completed"
3715   [(const_int 0)]
3716   "ix86_split_long_move (operands); DONE;")
3718 (define_insn "*movsf_internal"
3719   [(set (match_operand:SF 0 "nonimmediate_operand"
3720           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
3721         (match_operand:SF 1 "general_operand"
3722           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
3723   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3724    && (lra_in_progress || reload_completed
3725        || !CONST_DOUBLE_P (operands[1])
3726        || ((optimize_function_for_size_p (cfun)
3727             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3728            && ((IS_STACK_MODE (SFmode)
3729                 && standard_80387_constant_p (operands[1]) > 0)
3730                || (TARGET_SSE && TARGET_SSE_MATH
3731                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3732        || memory_operand (operands[0], SFmode)
3733        || !TARGET_HARD_SF_REGS)"
3735   switch (get_attr_type (insn))
3736     {
3737     case TYPE_FMOV:
3738       if (which_alternative == 2)
3739         return standard_80387_constant_opcode (operands[1]);
3740       return output_387_reg_move (insn, operands);
3742     case TYPE_IMOV:
3743       return "mov{l}\t{%1, %0|%0, %1}";
3745     case TYPE_SSELOG1:
3746       return standard_sse_constant_opcode (insn, operands);
3748     case TYPE_SSEMOV:
3749       switch (get_attr_mode (insn))
3750         {
3751         case MODE_SF:
3752           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3753             return "vmovss\t{%d1, %0|%0, %d1}";
3754           return "%vmovss\t{%1, %0|%0, %1}";
3756         case MODE_V16SF:
3757           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3758         case MODE_V4SF:
3759           return "%vmovaps\t{%1, %0|%0, %1}";
3761         case MODE_SI:
3762           return "%vmovd\t{%1, %0|%0, %1}";
3764         default:
3765           gcc_unreachable ();
3766         }
3768     case TYPE_MMXMOV:
3769       switch (get_attr_mode (insn))
3770         {
3771         case MODE_DI:
3772           return "movq\t{%1, %0|%0, %1}";
3773         case MODE_SI:
3774           return "movd\t{%1, %0|%0, %1}";
3776         default:
3777           gcc_unreachable ();
3778         }
3780     default:
3781       gcc_unreachable ();
3782     }
3784   [(set (attr "isa")
3785      (cond [(eq_attr "alternative" "14,15")
3786               (const_string "sse2")
3787            ]
3788            (const_string "*")))
3789    (set (attr "type")
3790         (cond [(eq_attr "alternative" "0,1,2")
3791                  (const_string "fmov")
3792                (eq_attr "alternative" "3,4,16,17")
3793                  (const_string "imov")
3794                (eq_attr "alternative" "5")
3795                  (const_string "sselog1")
3796                (eq_attr "alternative" "11,12,13,14,15")
3797                  (const_string "mmxmov")
3798               ]
3799               (const_string "ssemov")))
3800    (set (attr "prefix")
3801      (if_then_else (eq_attr "type" "sselog1,ssemov")
3802        (const_string "maybe_vex")
3803        (const_string "orig")))
3804    (set (attr "prefix_data16")
3805      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3806        (const_string "1")
3807        (const_string "*")))
3808    (set (attr "mode")
3809         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3810                  (const_string "SI")
3811                (eq_attr "alternative" "11")
3812                  (const_string "DI")
3813                (eq_attr "alternative" "5")
3814                  (cond [(not (match_test "TARGET_SSE2"))
3815                           (const_string "V4SF")
3816                         (and (match_test "TARGET_AVX512F")
3817                           (not (match_test "TARGET_PREFER_AVX256")))
3818                           (const_string "V16SF")
3819                         (match_test "TARGET_AVX")
3820                           (const_string "V4SF")
3821                         (match_test "optimize_function_for_size_p (cfun)")
3822                           (const_string "V4SF")
3823                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3824                           (const_string "TI")
3825                        ]
3826                        (const_string "V4SF"))
3828                /* For architectures resolving dependencies on
3829                   whole SSE registers use APS move to break dependency
3830                   chains, otherwise use short move to avoid extra work.
3832                   Do the same for architectures resolving dependencies on
3833                   the parts.  While in DF mode it is better to always handle
3834                   just register parts, the SF mode is different due to lack
3835                   of instructions to load just part of the register.  It is
3836                   better to maintain the whole registers in single format
3837                   to avoid problems on using packed logical operations.  */
3838                (eq_attr "alternative" "6")
3839                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3840                                   (not (match_test "TARGET_AVX512VL")))
3841                              (ior (match_operand 0 "ext_sse_reg_operand")
3842                                   (match_operand 1 "ext_sse_reg_operand")))
3843                           (const_string "V16SF")
3844                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3845                              (match_test "TARGET_SSE_SPLIT_REGS"))
3846                           (const_string "V4SF")
3847                        ]
3848                        (const_string "SF"))
3849               ]
3850               (const_string "SF")))
3851    (set (attr "preferred_for_speed")
3852      (cond [(eq_attr "alternative" "9,14")
3853               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3854             (eq_attr "alternative" "10,15")
3855               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3856            ]
3857            (symbol_ref "true")))
3858    (set (attr "enabled")
3859      (cond [(eq_attr "alternative" "16,17")
3860               (if_then_else
3861                 (match_test "TARGET_HARD_SF_REGS")
3862                 (symbol_ref "false")
3863                 (const_string "*"))
3864             (not (match_test "TARGET_HARD_SF_REGS"))
3865               (symbol_ref "false")
3866            ]
3867            (const_string "*")))])
3869 (define_split
3870   [(set (match_operand 0 "any_fp_register_operand")
3871         (match_operand 1 "nonimmediate_operand"))]
3872   "reload_completed
3873    && (GET_MODE (operands[0]) == TFmode
3874        || GET_MODE (operands[0]) == XFmode
3875        || GET_MODE (operands[0]) == DFmode
3876        || GET_MODE (operands[0]) == SFmode)
3877    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3878   [(set (match_dup 0) (match_dup 2))]
3879   "operands[2] = find_constant_src (curr_insn);")
3881 (define_split
3882   [(set (match_operand 0 "any_fp_register_operand")
3883         (float_extend (match_operand 1 "nonimmediate_operand")))]
3884   "reload_completed
3885    && (GET_MODE (operands[0]) == TFmode
3886        || GET_MODE (operands[0]) == XFmode
3887        || GET_MODE (operands[0]) == DFmode)
3888    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3889   [(set (match_dup 0) (match_dup 2))]
3890   "operands[2] = find_constant_src (curr_insn);")
3892 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3893 (define_split
3894   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3895         (match_operand:X87MODEF 1 "immediate_operand"))]
3896   "reload_completed
3897    && (standard_80387_constant_p (operands[1]) == 8
3898        || standard_80387_constant_p (operands[1]) == 9)"
3899   [(set (match_dup 0)(match_dup 1))
3900    (set (match_dup 0)
3901         (neg:X87MODEF (match_dup 0)))]
3903   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3904     operands[1] = CONST0_RTX (<MODE>mode);
3905   else
3906     operands[1] = CONST1_RTX (<MODE>mode);
3909 (define_insn "swapxf"
3910   [(set (match_operand:XF 0 "register_operand" "+f")
3911         (match_operand:XF 1 "register_operand" "+f"))
3912    (set (match_dup 1)
3913         (match_dup 0))]
3914   "TARGET_80387"
3916   if (STACK_TOP_P (operands[0]))
3917     return "fxch\t%1";
3918   else
3919     return "fxch\t%0";
3921   [(set_attr "type" "fxch")
3922    (set_attr "mode" "XF")])
3924 (define_insn "*swap<mode>"
3925   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3926         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3927    (set (match_dup 1)
3928         (match_dup 0))]
3929   "TARGET_80387 || reload_completed"
3931   if (STACK_TOP_P (operands[0]))
3932     return "fxch\t%1";
3933   else
3934     return "fxch\t%0";
3936   [(set_attr "type" "fxch")
3937    (set_attr "mode" "<MODE>")])
3939 ;; Zero extension instructions
3941 (define_expand "zero_extendsidi2"
3942   [(set (match_operand:DI 0 "nonimmediate_operand")
3943         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3945 (define_insn "*zero_extendsidi2"
3946   [(set (match_operand:DI 0 "nonimmediate_operand"
3947                 "=r,?r,?o,r   ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r")
3948         (zero_extend:DI
3949          (match_operand:SI 1 "x86_64_zext_operand"
3950                 "0 ,rm,r ,rmWz,0,r  ,m   ,v ,r ,m ,*x,*v,*k")))]
3951   ""
3953   switch (get_attr_type (insn))
3954     {
3955     case TYPE_IMOVX:
3956       if (ix86_use_lea_for_mov (insn, operands))
3957         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3958       else
3959         return "mov{l}\t{%1, %k0|%k0, %1}";
3961     case TYPE_MULTI:
3962       return "#";
3964     case TYPE_MMXMOV:
3965       return "movd\t{%1, %0|%0, %1}";
3967     case TYPE_SSEMOV:
3968       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3969         {
3970           if (EXT_REX_SSE_REG_P (operands[0])
3971               || EXT_REX_SSE_REG_P (operands[1]))
3972             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3973           else
3974             return "%vpmovzxdq\t{%1, %0|%0, %1}";
3975         }
3977       if (GENERAL_REG_P (operands[0]))
3978         return "%vmovd\t{%1, %k0|%k0, %1}";
3980       return "%vmovd\t{%1, %0|%0, %1}";
3982     case TYPE_MSKMOV:
3983       return "kmovd\t{%1, %k0|%k0, %1}";
3985     default:
3986       gcc_unreachable ();
3987     }
3989   [(set (attr "isa")
3990      (cond [(eq_attr "alternative" "0,1,2")
3991               (const_string "nox64")
3992             (eq_attr "alternative" "3")
3993               (const_string "x64")
3994             (eq_attr "alternative" "7,8,9")
3995               (const_string "sse2")
3996             (eq_attr "alternative" "10")
3997               (const_string "sse4")
3998             (eq_attr "alternative" "11")
3999               (const_string "avx512f")
4000             (eq_attr "alternative" "12")
4001               (const_string "x64_avx512bw")
4002            ]
4003            (const_string "*")))
4004    (set (attr "type")
4005      (cond [(eq_attr "alternative" "0,1,2,4")
4006               (const_string "multi")
4007             (eq_attr "alternative" "5,6")
4008               (const_string "mmxmov")
4009             (eq_attr "alternative" "7")
4010               (if_then_else (match_test "TARGET_64BIT")
4011                 (const_string "ssemov")
4012                 (const_string "multi"))
4013             (eq_attr "alternative" "8,9,10,11")
4014               (const_string "ssemov")
4015             (eq_attr "alternative" "12")
4016               (const_string "mskmov")
4017            ]
4018            (const_string "imovx")))
4019    (set (attr "prefix_extra")
4020      (if_then_else (eq_attr "alternative" "10,11")
4021        (const_string "1")
4022        (const_string "*")))
4023    (set (attr "prefix")
4024      (if_then_else (eq_attr "type" "ssemov")
4025        (const_string "maybe_vex")
4026        (const_string "orig")))
4027    (set (attr "prefix_0f")
4028      (if_then_else (eq_attr "type" "imovx")
4029        (const_string "0")
4030        (const_string "*")))
4031    (set (attr "mode")
4032      (cond [(eq_attr "alternative" "5,6")
4033               (const_string "DI")
4034             (and (eq_attr "alternative" "7")
4035                  (match_test "TARGET_64BIT"))
4036               (const_string "TI")
4037             (eq_attr "alternative" "8,10,11")
4038               (const_string "TI")
4039            ]
4040            (const_string "SI")))
4041    (set (attr "preferred_for_speed")
4042      (cond [(eq_attr "alternative" "7")
4043               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4044             (eq_attr "alternative" "5,8")
4045               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4046            ]
4047            (symbol_ref "true")))])
4049 (define_split
4050   [(set (match_operand:DI 0 "memory_operand")
4051         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4052   "reload_completed"
4053   [(set (match_dup 4) (const_int 0))]
4054   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4056 (define_split
4057   [(set (match_operand:DI 0 "general_reg_operand")
4058         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4059   "!TARGET_64BIT && reload_completed
4060    && REGNO (operands[0]) == REGNO (operands[1])"
4061   [(set (match_dup 4) (const_int 0))]
4062   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4064 (define_split
4065   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4066         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4067   "!TARGET_64BIT && reload_completed
4068    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4069   [(set (match_dup 3) (match_dup 1))
4070    (set (match_dup 4) (const_int 0))]
4071   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4073 (define_mode_attr kmov_isa
4074   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4076 (define_insn "zero_extend<mode>di2"
4077   [(set (match_operand:DI 0 "register_operand" "=r,*r")
4078         (zero_extend:DI
4079          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4080   "TARGET_64BIT"
4081   "@
4082    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4083    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4084   [(set_attr "isa" "*,<kmov_isa>")
4085    (set_attr "type" "imovx,mskmov")
4086    (set_attr "mode" "SI,<MODE>")])
4088 (define_expand "zero_extend<mode>si2"
4089   [(set (match_operand:SI 0 "register_operand")
4090         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4091   ""
4093   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4094     {
4095       operands[1] = force_reg (<MODE>mode, operands[1]);
4096       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4097       DONE;
4098     }
4101 (define_insn_and_split "zero_extend<mode>si2_and"
4102   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4103         (zero_extend:SI
4104           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4105    (clobber (reg:CC FLAGS_REG))]
4106   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4107   "#"
4108   "&& reload_completed"
4109   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4110               (clobber (reg:CC FLAGS_REG))])]
4112   if (!REG_P (operands[1])
4113       || REGNO (operands[0]) != REGNO (operands[1]))
4114     {
4115       ix86_expand_clear (operands[0]);
4117       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4118       emit_insn (gen_movstrict<mode>
4119                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4120       DONE;
4121     }
4123   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4125   [(set_attr "type" "alu1")
4126    (set_attr "mode" "SI")])
4128 (define_insn "*zero_extend<mode>si2"
4129   [(set (match_operand:SI 0 "register_operand" "=r,*r")
4130         (zero_extend:SI
4131           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4132   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4133   "@
4134    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4135    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4136   [(set_attr "isa" "*,<kmov_isa>")
4137    (set_attr "type" "imovx,mskmov")
4138    (set_attr "mode" "SI,<MODE>")])
4140 (define_expand "zero_extendqihi2"
4141   [(set (match_operand:HI 0 "register_operand")
4142         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4143   ""
4145   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4146     {
4147       operands[1] = force_reg (QImode, operands[1]);
4148       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4149       DONE;
4150     }
4153 (define_insn_and_split "zero_extendqihi2_and"
4154   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4155         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4156    (clobber (reg:CC FLAGS_REG))]
4157   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4158   "#"
4159   "&& reload_completed"
4160   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4161               (clobber (reg:CC FLAGS_REG))])]
4163   if (!REG_P (operands[1])
4164       || REGNO (operands[0]) != REGNO (operands[1]))
4165     {
4166       ix86_expand_clear (operands[0]);
4168       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4169       emit_insn (gen_movstrictqi
4170                   (gen_lowpart (QImode, operands[0]), operands[1]));
4171       DONE;
4172     }
4174   operands[0] = gen_lowpart (SImode, operands[0]);
4176   [(set_attr "type" "alu1")
4177    (set_attr "mode" "SI")])
4179 ; zero extend to SImode to avoid partial register stalls
4180 (define_insn "*zero_extendqihi2"
4181   [(set (match_operand:HI 0 "register_operand" "=r,*r")
4182         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4183   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4184   "@
4185    movz{bl|x}\t{%1, %k0|%k0, %1}
4186    kmovb\t{%1, %k0|%k0, %1}"
4187   [(set_attr "isa" "*,avx512dq")
4188    (set_attr "type" "imovx,mskmov")
4189    (set_attr "mode" "SI,QI")])
4191 (define_insn_and_split "*zext<mode>_doubleword_and"
4192   [(set (match_operand:DI 0 "register_operand" "=&<r>")
4193         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4194   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4195    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4196   "#"
4197   "&& reload_completed && GENERAL_REG_P (operands[0])"
4198   [(set (match_dup 2) (const_int 0))]
4200   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4202   emit_move_insn (operands[0], const0_rtx);
4204   gcc_assert (!TARGET_PARTIAL_REG_STALL);
4205   emit_insn (gen_movstrict<mode>
4206              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4209 (define_insn_and_split "*zext<mode>_doubleword"
4210   [(set (match_operand:DI 0 "register_operand" "=r")
4211         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4212   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4213    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4214   "#"
4215   "&& reload_completed && GENERAL_REG_P (operands[0])"
4216   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4217    (set (match_dup 2) (const_int 0))]
4218   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4220 (define_insn_and_split "*zextsi_doubleword"
4221   [(set (match_operand:DI 0 "register_operand" "=r")
4222         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4223   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4224   "#"
4225   "&& reload_completed && GENERAL_REG_P (operands[0])"
4226   [(set (match_dup 0) (match_dup 1))
4227    (set (match_dup 2) (const_int 0))]
4228   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4230 ;; Sign extension instructions
4232 (define_expand "extendsidi2"
4233   [(set (match_operand:DI 0 "register_operand")
4234         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4235   ""
4237   if (!TARGET_64BIT)
4238     {
4239       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4240       DONE;
4241     }
4244 (define_insn "*extendsidi2_rex64"
4245   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4246         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4247   "TARGET_64BIT"
4248   "@
4249    {cltq|cdqe}
4250    movs{lq|x}\t{%1, %0|%0, %1}"
4251   [(set_attr "type" "imovx")
4252    (set_attr "mode" "DI")
4253    (set_attr "prefix_0f" "0")
4254    (set_attr "modrm" "0,1")])
4256 (define_insn "extendsidi2_1"
4257   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4258         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4259    (clobber (reg:CC FLAGS_REG))
4260    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4261   "!TARGET_64BIT"
4262   "#")
4264 ;; Split the memory case.  If the source register doesn't die, it will stay
4265 ;; this way, if it does die, following peephole2s take care of it.
4266 (define_split
4267   [(set (match_operand:DI 0 "memory_operand")
4268         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4269    (clobber (reg:CC FLAGS_REG))
4270    (clobber (match_operand:SI 2 "register_operand"))]
4271   "reload_completed"
4272   [(const_int 0)]
4274   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4276   emit_move_insn (operands[3], operands[1]);
4278   /* Generate a cltd if possible and doing so it profitable.  */
4279   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4280       && REGNO (operands[1]) == AX_REG
4281       && REGNO (operands[2]) == DX_REG)
4282     {
4283       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4284     }
4285   else
4286     {
4287       emit_move_insn (operands[2], operands[1]);
4288       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4289     }
4290   emit_move_insn (operands[4], operands[2]);
4291   DONE;
4294 ;; Peepholes for the case where the source register does die, after
4295 ;; being split with the above splitter.
4296 (define_peephole2
4297   [(set (match_operand:SI 0 "memory_operand")
4298         (match_operand:SI 1 "general_reg_operand"))
4299    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4300    (parallel [(set (match_dup 2)
4301                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4302                (clobber (reg:CC FLAGS_REG))])
4303    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4304   "REGNO (operands[1]) != REGNO (operands[2])
4305    && peep2_reg_dead_p (2, operands[1])
4306    && peep2_reg_dead_p (4, operands[2])
4307    && !reg_mentioned_p (operands[2], operands[3])"
4308   [(set (match_dup 0) (match_dup 1))
4309    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4310               (clobber (reg:CC FLAGS_REG))])
4311    (set (match_dup 3) (match_dup 1))])
4313 (define_peephole2
4314   [(set (match_operand:SI 0 "memory_operand")
4315         (match_operand:SI 1 "general_reg_operand"))
4316    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4317                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4318                (clobber (reg:CC FLAGS_REG))])
4319    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4320   "/* cltd is shorter than sarl $31, %eax */
4321    !optimize_function_for_size_p (cfun)
4322    && REGNO (operands[1]) == AX_REG
4323    && REGNO (operands[2]) == DX_REG
4324    && peep2_reg_dead_p (2, operands[1])
4325    && peep2_reg_dead_p (3, operands[2])
4326    && !reg_mentioned_p (operands[2], operands[3])"
4327   [(set (match_dup 0) (match_dup 1))
4328    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4329               (clobber (reg:CC FLAGS_REG))])
4330    (set (match_dup 3) (match_dup 1))])
4332 ;; Extend to register case.  Optimize case where source and destination
4333 ;; registers match and cases where we can use cltd.
4334 (define_split
4335   [(set (match_operand:DI 0 "register_operand")
4336         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4337    (clobber (reg:CC FLAGS_REG))
4338    (clobber (match_scratch:SI 2))]
4339   "reload_completed"
4340   [(const_int 0)]
4342   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4344   if (REGNO (operands[3]) != REGNO (operands[1]))
4345     emit_move_insn (operands[3], operands[1]);
4347   /* Generate a cltd if possible and doing so it profitable.  */
4348   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4349       && REGNO (operands[3]) == AX_REG
4350       && REGNO (operands[4]) == DX_REG)
4351     {
4352       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4353       DONE;
4354     }
4356   if (REGNO (operands[4]) != REGNO (operands[1]))
4357     emit_move_insn (operands[4], operands[1]);
4359   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4360   DONE;
4363 (define_insn "extend<mode>di2"
4364   [(set (match_operand:DI 0 "register_operand" "=r")
4365         (sign_extend:DI
4366          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4367   "TARGET_64BIT"
4368   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4369   [(set_attr "type" "imovx")
4370    (set_attr "mode" "DI")])
4372 (define_insn "extendhisi2"
4373   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4374         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4375   ""
4377   switch (get_attr_prefix_0f (insn))
4378     {
4379     case 0:
4380       return "{cwtl|cwde}";
4381     default:
4382       return "movs{wl|x}\t{%1, %0|%0, %1}";
4383     }
4385   [(set_attr "type" "imovx")
4386    (set_attr "mode" "SI")
4387    (set (attr "prefix_0f")
4388      ;; movsx is short decodable while cwtl is vector decoded.
4389      (if_then_else (and (eq_attr "cpu" "!k6")
4390                         (eq_attr "alternative" "0"))
4391         (const_string "0")
4392         (const_string "1")))
4393    (set (attr "znver1_decode")
4394      (if_then_else (eq_attr "prefix_0f" "0")
4395         (const_string "double")
4396         (const_string "direct")))
4397    (set (attr "modrm")
4398      (if_then_else (eq_attr "prefix_0f" "0")
4399         (const_string "0")
4400         (const_string "1")))])
4402 (define_insn "*extendhisi2_zext"
4403   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4404         (zero_extend:DI
4405          (sign_extend:SI
4406           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4407   "TARGET_64BIT"
4409   switch (get_attr_prefix_0f (insn))
4410     {
4411     case 0:
4412       return "{cwtl|cwde}";
4413     default:
4414       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4415     }
4417   [(set_attr "type" "imovx")
4418    (set_attr "mode" "SI")
4419    (set (attr "prefix_0f")
4420      ;; movsx is short decodable while cwtl is vector decoded.
4421      (if_then_else (and (eq_attr "cpu" "!k6")
4422                         (eq_attr "alternative" "0"))
4423         (const_string "0")
4424         (const_string "1")))
4425    (set (attr "modrm")
4426      (if_then_else (eq_attr "prefix_0f" "0")
4427         (const_string "0")
4428         (const_string "1")))])
4430 (define_insn "extendqisi2"
4431   [(set (match_operand:SI 0 "register_operand" "=r")
4432         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4433   ""
4434   "movs{bl|x}\t{%1, %0|%0, %1}"
4435    [(set_attr "type" "imovx")
4436     (set_attr "mode" "SI")])
4438 (define_insn "*extendqisi2_zext"
4439   [(set (match_operand:DI 0 "register_operand" "=r")
4440         (zero_extend:DI
4441           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4442   "TARGET_64BIT"
4443   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4444    [(set_attr "type" "imovx")
4445     (set_attr "mode" "SI")])
4447 (define_insn "extendqihi2"
4448   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4449         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4450   ""
4452   switch (get_attr_prefix_0f (insn))
4453     {
4454     case 0:
4455       return "{cbtw|cbw}";
4456     default:
4457       return "movs{bw|x}\t{%1, %0|%0, %1}";
4458     }
4460   [(set_attr "type" "imovx")
4461    (set_attr "mode" "HI")
4462    (set (attr "prefix_0f")
4463      ;; movsx is short decodable while cwtl is vector decoded.
4464      (if_then_else (and (eq_attr "cpu" "!k6")
4465                         (eq_attr "alternative" "0"))
4466         (const_string "0")
4467         (const_string "1")))
4468    (set (attr "modrm")
4469      (if_then_else (eq_attr "prefix_0f" "0")
4470         (const_string "0")
4471         (const_string "1")))])
4473 ;; Conversions between float and double.
4475 ;; These are all no-ops in the model used for the 80387.
4476 ;; So just emit moves.
4478 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4479 (define_split
4480   [(set (match_operand:DF 0 "push_operand")
4481         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4482   "reload_completed"
4483   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4484    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4486 (define_split
4487   [(set (match_operand:XF 0 "push_operand")
4488         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4489   "reload_completed"
4490   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4491    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4492   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4494 (define_expand "extendsfdf2"
4495   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4496         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4497   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4499   /* ??? Needed for compress_float_constant since all fp constants
4500      are TARGET_LEGITIMATE_CONSTANT_P.  */
4501   if (CONST_DOUBLE_P (operands[1]))
4502     {
4503       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4504           && standard_80387_constant_p (operands[1]) > 0)
4505         {
4506           operands[1] = simplify_const_unary_operation
4507             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4508           emit_move_insn_1 (operands[0], operands[1]);
4509           DONE;
4510         }
4511       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4512     }
4515 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4516    cvtss2sd:
4517       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4518       cvtps2pd xmm2,xmm1
4519    We do the conversion post reload to avoid producing of 128bit spills
4520    that might lead to ICE on 32bit target.  The sequence unlikely combine
4521    anyway.  */
4522 (define_split
4523   [(set (match_operand:DF 0 "sse_reg_operand")
4524         (float_extend:DF
4525           (match_operand:SF 1 "nonimmediate_operand")))]
4526   "TARGET_USE_VECTOR_FP_CONVERTS
4527    && optimize_insn_for_speed_p ()
4528    && reload_completed
4529    && (!EXT_REX_SSE_REG_P (operands[0])
4530        || TARGET_AVX512VL)"
4531    [(set (match_dup 2)
4532          (float_extend:V2DF
4533            (vec_select:V2SF
4534              (match_dup 3)
4535              (parallel [(const_int 0) (const_int 1)]))))]
4537   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4538   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4539   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4540      Try to avoid move when unpacking can be done in source.  */
4541   if (REG_P (operands[1]))
4542     {
4543       /* If it is unsafe to overwrite upper half of source, we need
4544          to move to destination and unpack there.  */
4545       if (REGNO (operands[0]) != REGNO (operands[1])
4546           || (EXT_REX_SSE_REG_P (operands[1])
4547               && !TARGET_AVX512VL))
4548         {
4549           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4550           emit_move_insn (tmp, operands[1]);
4551         }
4552       else
4553         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4554       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4555          =v, v, then vbroadcastss will be only needed for AVX512F without
4556          AVX512VL.  */
4557       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4558         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4559                                                operands[3]));
4560       else
4561         {
4562           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4563           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4564         }
4565     }
4566   else
4567     emit_insn (gen_vec_setv4sf_0 (operands[3],
4568                                   CONST0_RTX (V4SFmode), operands[1]));
4571 ;; It's more profitable to split and then extend in the same register.
4572 (define_peephole2
4573   [(set (match_operand:DF 0 "sse_reg_operand")
4574         (float_extend:DF
4575           (match_operand:SF 1 "memory_operand")))]
4576   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4577    && optimize_insn_for_speed_p ()"
4578   [(set (match_dup 2) (match_dup 1))
4579    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4580   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4582 (define_insn "*extendsfdf2"
4583   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4584         (float_extend:DF
4585           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4586   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4588   switch (which_alternative)
4589     {
4590     case 0:
4591     case 1:
4592       return output_387_reg_move (insn, operands);
4594     case 2:
4595       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4597     default:
4598       gcc_unreachable ();
4599     }
4601   [(set_attr "type" "fmov,fmov,ssecvt")
4602    (set_attr "prefix" "orig,orig,maybe_vex")
4603    (set_attr "mode" "SF,XF,DF")
4604    (set (attr "enabled")
4605      (if_then_else
4606        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4607        (if_then_else
4608          (eq_attr "alternative" "0,1")
4609          (symbol_ref "TARGET_MIX_SSE_I387")
4610          (symbol_ref "true"))
4611        (if_then_else
4612          (eq_attr "alternative" "0,1")
4613          (symbol_ref "true")
4614          (symbol_ref "false"))))])
4616 (define_expand "extend<mode>xf2"
4617   [(set (match_operand:XF 0 "nonimmediate_operand")
4618         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4619   "TARGET_80387"
4621   /* ??? Needed for compress_float_constant since all fp constants
4622      are TARGET_LEGITIMATE_CONSTANT_P.  */
4623   if (CONST_DOUBLE_P (operands[1]))
4624     {
4625       if (standard_80387_constant_p (operands[1]) > 0)
4626         {
4627           operands[1] = simplify_const_unary_operation
4628             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4629           emit_move_insn_1 (operands[0], operands[1]);
4630           DONE;
4631         }
4632       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4633     }
4636 (define_insn "*extend<mode>xf2_i387"
4637   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4638         (float_extend:XF
4639           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4640   "TARGET_80387"
4641   "* return output_387_reg_move (insn, operands);"
4642   [(set_attr "type" "fmov")
4643    (set_attr "mode" "<MODE>,XF")])
4645 ;; %%% This seems like bad news.
4646 ;; This cannot output into an f-reg because there is no way to be sure
4647 ;; of truncating in that case.  Otherwise this is just like a simple move
4648 ;; insn.  So we pretend we can output to a reg in order to get better
4649 ;; register preferencing, but we really use a stack slot.
4651 ;; Conversion from DFmode to SFmode.
4653 (define_expand "truncdfsf2"
4654   [(set (match_operand:SF 0 "nonimmediate_operand")
4655         (float_truncate:SF
4656           (match_operand:DF 1 "nonimmediate_operand")))]
4657   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4659   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4660     ;
4661   else if (flag_unsafe_math_optimizations)
4662     ;
4663   else
4664     {
4665       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4666       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4667       DONE;
4668     }
4671 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4672    cvtsd2ss:
4673       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4674       cvtpd2ps xmm2,xmm1
4675    We do the conversion post reload to avoid producing of 128bit spills
4676    that might lead to ICE on 32bit target.  The sequence unlikely combine
4677    anyway.  */
4678 (define_split
4679   [(set (match_operand:SF 0 "sse_reg_operand")
4680         (float_truncate:SF
4681           (match_operand:DF 1 "nonimmediate_operand")))]
4682   "TARGET_USE_VECTOR_FP_CONVERTS
4683    && optimize_insn_for_speed_p ()
4684    && reload_completed
4685    && (!EXT_REX_SSE_REG_P (operands[0])
4686        || TARGET_AVX512VL)"
4687    [(set (match_dup 2)
4688          (vec_concat:V4SF
4689            (float_truncate:V2SF
4690              (match_dup 4))
4691            (match_dup 3)))]
4693   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4694   operands[3] = CONST0_RTX (V2SFmode);
4695   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4696   /* Use movsd for loading from memory, unpcklpd for registers.
4697      Try to avoid move when unpacking can be done in source, or SSE3
4698      movddup is available.  */
4699   if (REG_P (operands[1]))
4700     {
4701       if (!TARGET_SSE3
4702           && REGNO (operands[0]) != REGNO (operands[1]))
4703         {
4704           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4705           emit_move_insn (tmp, operands[1]);
4706           operands[1] = tmp;
4707         }
4708       else if (!TARGET_SSE3)
4709         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4710       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4711     }
4712   else
4713     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4714                                    CONST0_RTX (DFmode)));
4717 ;; It's more profitable to split and then extend in the same register.
4718 (define_peephole2
4719   [(set (match_operand:SF 0 "sse_reg_operand")
4720         (float_truncate:SF
4721           (match_operand:DF 1 "memory_operand")))]
4722   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4723    && optimize_insn_for_speed_p ()"
4724   [(set (match_dup 2) (match_dup 1))
4725    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4726   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4728 (define_expand "truncdfsf2_with_temp"
4729   [(parallel [(set (match_operand:SF 0)
4730                    (float_truncate:SF (match_operand:DF 1)))
4731               (clobber (match_operand:SF 2))])])
4733 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4734 ;; because nothing we do there is unsafe.
4735 (define_insn "*truncdfsf_fast_mixed"
4736   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4737         (float_truncate:SF
4738           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4739   "TARGET_SSE2 && TARGET_SSE_MATH"
4741   switch (which_alternative)
4742     {
4743     case 0:
4744       return output_387_reg_move (insn, operands);
4745     case 1:
4746       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4747     default:
4748       gcc_unreachable ();
4749     }
4751   [(set_attr "type" "fmov,ssecvt")
4752    (set_attr "prefix" "orig,maybe_vex")
4753    (set_attr "mode" "SF")
4754    (set (attr "enabled")
4755      (cond [(eq_attr "alternative" "0")
4756               (symbol_ref "TARGET_MIX_SSE_I387
4757                            && flag_unsafe_math_optimizations")
4758            ]
4759            (symbol_ref "true")))])
4761 (define_insn "*truncdfsf_fast_i387"
4762   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4763         (float_truncate:SF
4764           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4765   "TARGET_80387 && flag_unsafe_math_optimizations"
4766   "* return output_387_reg_move (insn, operands);"
4767   [(set_attr "type" "fmov")
4768    (set_attr "mode" "SF")])
4770 (define_insn "*truncdfsf_mixed"
4771   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
4772         (float_truncate:SF
4773           (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4774    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4775   "TARGET_MIX_SSE_I387"
4777   switch (which_alternative)
4778     {
4779     case 0:
4780       return output_387_reg_move (insn, operands);
4781     case 1:
4782       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4784     default:
4785       return "#";
4786     }
4788   [(set_attr "isa" "*,sse2,*,*,*")
4789    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4790    (set_attr "unit" "*,*,i387,i387,i387")
4791    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4792    (set_attr "mode" "SF")])
4794 (define_insn "*truncdfsf_i387"
4795   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
4796         (float_truncate:SF
4797           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4798    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4799   "TARGET_80387"
4801   switch (which_alternative)
4802     {
4803     case 0:
4804       return output_387_reg_move (insn, operands);
4806     default:
4807       return "#";
4808     }
4810   [(set_attr "type" "fmov,multi,multi,multi")
4811    (set_attr "unit" "*,i387,i387,i387")
4812    (set_attr "mode" "SF")])
4814 (define_insn "*truncdfsf2_i387_1"
4815   [(set (match_operand:SF 0 "memory_operand" "=m")
4816         (float_truncate:SF
4817           (match_operand:DF 1 "register_operand" "f")))]
4818   "TARGET_80387
4819    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4820    && !TARGET_MIX_SSE_I387"
4821   "* return output_387_reg_move (insn, operands);"
4822   [(set_attr "type" "fmov")
4823    (set_attr "mode" "SF")])
4825 (define_split
4826   [(set (match_operand:SF 0 "register_operand")
4827         (float_truncate:SF
4828          (match_operand:DF 1 "fp_register_operand")))
4829    (clobber (match_operand 2))]
4830   "reload_completed"
4831   [(set (match_dup 2) (match_dup 1))
4832    (set (match_dup 0) (match_dup 2))]
4833   "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4835 ;; Conversion from XFmode to {SF,DF}mode
4837 (define_expand "truncxf<mode>2"
4838   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4839                    (float_truncate:MODEF
4840                      (match_operand:XF 1 "register_operand")))
4841               (clobber (match_dup 2))])]
4842   "TARGET_80387"
4844   if (flag_unsafe_math_optimizations)
4845     {
4846       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4847       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4848       if (reg != operands[0])
4849         emit_move_insn (operands[0], reg);
4850       DONE;
4851     }
4852   else
4853     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4856 (define_insn "*truncxfsf2_mixed"
4857   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4858         (float_truncate:SF
4859           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4860    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4861   "TARGET_80387"
4863   gcc_assert (!which_alternative);
4864   return output_387_reg_move (insn, operands);
4866   [(set_attr "type" "fmov,multi,multi,multi")
4867    (set_attr "unit" "*,i387,i387,i387")
4868    (set_attr "mode" "SF")])
4870 (define_insn "*truncxfdf2_mixed"
4871   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4872         (float_truncate:DF
4873           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4874    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4875   "TARGET_80387"
4877   gcc_assert (!which_alternative);
4878   return output_387_reg_move (insn, operands);
4880   [(set_attr "isa" "*,*,sse2,*")
4881    (set_attr "type" "fmov,multi,multi,multi")
4882    (set_attr "unit" "*,i387,i387,i387")
4883    (set_attr "mode" "DF")])
4885 (define_insn "truncxf<mode>2_i387_noop"
4886   [(set (match_operand:MODEF 0 "register_operand" "=f")
4887         (float_truncate:MODEF
4888           (match_operand:XF 1 "register_operand" "f")))]
4889   "TARGET_80387 && flag_unsafe_math_optimizations"
4890   "* return output_387_reg_move (insn, operands);"
4891   [(set_attr "type" "fmov")
4892    (set_attr "mode" "<MODE>")])
4894 (define_insn "*truncxf<mode>2_i387"
4895   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4896         (float_truncate:MODEF
4897           (match_operand:XF 1 "register_operand" "f")))]
4898   "TARGET_80387"
4899   "* return output_387_reg_move (insn, operands);"
4900   [(set_attr "type" "fmov")
4901    (set_attr "mode" "<MODE>")])
4903 (define_split
4904   [(set (match_operand:MODEF 0 "register_operand")
4905         (float_truncate:MODEF
4906           (match_operand:XF 1 "register_operand")))
4907    (clobber (match_operand:MODEF 2 "memory_operand"))]
4908   "TARGET_80387 && reload_completed"
4909   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4910    (set (match_dup 0) (match_dup 2))])
4912 (define_split
4913   [(set (match_operand:MODEF 0 "memory_operand")
4914         (float_truncate:MODEF
4915           (match_operand:XF 1 "register_operand")))
4916    (clobber (match_operand:MODEF 2 "memory_operand"))]
4917   "TARGET_80387"
4918   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4920 ;; Signed conversion to DImode.
4922 (define_expand "fix_truncxfdi2"
4923   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4924                    (fix:DI (match_operand:XF 1 "register_operand")))
4925               (clobber (reg:CC FLAGS_REG))])]
4926   "TARGET_80387"
4928   if (TARGET_FISTTP)
4929    {
4930      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4931      DONE;
4932    }
4935 (define_expand "fix_trunc<mode>di2"
4936   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4937                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4938               (clobber (reg:CC FLAGS_REG))])]
4939   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4941   if (TARGET_FISTTP
4942       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4943    {
4944      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4945      DONE;
4946    }
4947   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4948    {
4949      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4950      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4951      if (out != operands[0])
4952         emit_move_insn (operands[0], out);
4953      DONE;
4954    }
4957 ;; Signed conversion to SImode.
4959 (define_expand "fix_truncxfsi2"
4960   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4961                    (fix:SI (match_operand:XF 1 "register_operand")))
4962               (clobber (reg:CC FLAGS_REG))])]
4963   "TARGET_80387"
4965   if (TARGET_FISTTP)
4966    {
4967      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4968      DONE;
4969    }
4972 (define_expand "fix_trunc<mode>si2"
4973   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4974                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4975               (clobber (reg:CC FLAGS_REG))])]
4976   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4978   if (TARGET_FISTTP
4979       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4980    {
4981      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4982      DONE;
4983    }
4984   if (SSE_FLOAT_MODE_P (<MODE>mode))
4985    {
4986      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4987      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4988      if (out != operands[0])
4989         emit_move_insn (operands[0], out);
4990      DONE;
4991    }
4994 ;; Signed conversion to HImode.
4996 (define_expand "fix_trunc<mode>hi2"
4997   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4998                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4999               (clobber (reg:CC FLAGS_REG))])]
5000   "TARGET_80387
5001    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5003   if (TARGET_FISTTP)
5004    {
5005      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5006      DONE;
5007    }
5010 ;; Unsigned conversion to DImode
5012 (define_insn "fixuns_trunc<mode>di2"
5013   [(set (match_operand:DI 0 "register_operand" "=r")
5014         (unsigned_fix:DI
5015           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5016   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5017   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5018   [(set_attr "type" "sseicvt")
5019    (set_attr "prefix" "evex")
5020    (set_attr "mode" "DI")])
5022 ;; Unsigned conversion to SImode.
5024 (define_expand "fixuns_trunc<mode>si2"
5025   [(parallel
5026     [(set (match_operand:SI 0 "register_operand")
5027           (unsigned_fix:SI
5028             (match_operand:MODEF 1 "nonimmediate_operand")))
5029      (use (match_dup 2))
5030      (clobber (match_scratch:<ssevecmode> 3))
5031      (clobber (match_scratch:<ssevecmode> 4))])]
5032   "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5034   machine_mode mode = <MODE>mode;
5035   machine_mode vecmode = <ssevecmode>mode;
5036   REAL_VALUE_TYPE TWO31r;
5037   rtx two31;
5039   if (TARGET_AVX512F)
5040     {
5041       emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5042       DONE;
5043     }
5045   if (optimize_insn_for_size_p ())
5046     FAIL;
5048   real_ldexp (&TWO31r, &dconst1, 31);
5049   two31 = const_double_from_real_value (TWO31r, mode);
5050   two31 = ix86_build_const_vector (vecmode, true, two31);
5051   operands[2] = force_reg (vecmode, two31);
5054 (define_insn "fixuns_trunc<mode>si2_avx512f"
5055   [(set (match_operand:SI 0 "register_operand" "=r")
5056         (unsigned_fix:SI
5057           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5058   "TARGET_AVX512F && TARGET_SSE_MATH"
5059   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5060   [(set_attr "type" "sseicvt")
5061    (set_attr "prefix" "evex")
5062    (set_attr "mode" "SI")])
5064 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5065   [(set (match_operand:DI 0 "register_operand" "=r")
5066         (zero_extend:DI
5067           (unsigned_fix:SI
5068             (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5069   "TARGET_64BIT && TARGET_AVX512F"
5070   "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5071   [(set_attr "type" "sseicvt")
5072    (set_attr "prefix" "evex")
5073    (set_attr "mode" "SI")])
5075 (define_insn_and_split "*fixuns_trunc<mode>_1"
5076   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5077         (unsigned_fix:SI
5078           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5079    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5080    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5081    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5082   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5083    && optimize_function_for_speed_p (cfun)"
5084   "#"
5085   "&& reload_completed"
5086   [(const_int 0)]
5088   ix86_split_convert_uns_si_sse (operands);
5089   DONE;
5092 ;; Unsigned conversion to HImode.
5093 ;; Without these patterns, we'll try the unsigned SI conversion which
5094 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5096 (define_expand "fixuns_trunc<mode>hi2"
5097   [(set (match_dup 2)
5098         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5099    (set (match_operand:HI 0 "nonimmediate_operand")
5100         (subreg:HI (match_dup 2) 0))]
5101   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5102   "operands[2] = gen_reg_rtx (SImode);")
5104 ;; When SSE is available, it is always faster to use it!
5105 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5106   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5107         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5108   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5109    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5110   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5111   [(set_attr "type" "sseicvt")
5112    (set_attr "prefix" "maybe_vex")
5113    (set (attr "prefix_rex")
5114         (if_then_else
5115           (match_test "<SWI48:MODE>mode == DImode")
5116           (const_string "1")
5117           (const_string "*")))
5118    (set_attr "mode" "<MODEF:MODE>")
5119    (set_attr "athlon_decode" "double,vector")
5120    (set_attr "amdfam10_decode" "double,double")
5121    (set_attr "bdver1_decode" "double,double")])
5123 ;; Avoid vector decoded forms of the instruction.
5124 (define_peephole2
5125   [(match_scratch:MODEF 2 "x")
5126    (set (match_operand:SWI48 0 "register_operand")
5127         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5128   "TARGET_AVOID_VECTOR_DECODE
5129    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5130    && optimize_insn_for_speed_p ()"
5131   [(set (match_dup 2) (match_dup 1))
5132    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5134 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5135   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5136         (fix:SWI248x (match_operand 1 "register_operand")))]
5137   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5138    && TARGET_FISTTP
5139    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5140          && (TARGET_64BIT || <MODE>mode != DImode))
5141         && TARGET_SSE_MATH)
5142    && can_create_pseudo_p ()"
5143   "#"
5144   "&& 1"
5145   [(const_int 0)]
5147   if (memory_operand (operands[0], VOIDmode))
5148     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5149   else
5150     {
5151       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5152       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5153                                                             operands[1],
5154                                                             operands[2]));
5155     }
5156   DONE;
5158   [(set_attr "type" "fisttp")
5159    (set_attr "mode" "<MODE>")])
5161 (define_insn "fix_trunc<mode>_i387_fisttp"
5162   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5163         (fix:SWI248x (match_operand 1 "register_operand" "f")))
5164    (clobber (match_scratch:XF 2 "=&1f"))]
5165   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5166    && TARGET_FISTTP
5167    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5168          && (TARGET_64BIT || <MODE>mode != DImode))
5169         && TARGET_SSE_MATH)"
5170   "* return output_fix_trunc (insn, operands, true);"
5171   [(set_attr "type" "fisttp")
5172    (set_attr "mode" "<MODE>")])
5174 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5175   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5176         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5177    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5178    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5179   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5180    && TARGET_FISTTP
5181    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5182         && (TARGET_64BIT || <MODE>mode != DImode))
5183         && TARGET_SSE_MATH)"
5184   "#"
5185   [(set_attr "type" "fisttp")
5186    (set_attr "mode" "<MODE>")])
5188 (define_split
5189   [(set (match_operand:SWI248x 0 "register_operand")
5190         (fix:SWI248x (match_operand 1 "register_operand")))
5191    (clobber (match_operand:SWI248x 2 "memory_operand"))
5192    (clobber (match_scratch 3))]
5193   "reload_completed"
5194   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5195               (clobber (match_dup 3))])
5196    (set (match_dup 0) (match_dup 2))])
5198 (define_split
5199   [(set (match_operand:SWI248x 0 "memory_operand")
5200         (fix:SWI248x (match_operand 1 "register_operand")))
5201    (clobber (match_operand:SWI248x 2 "memory_operand"))
5202    (clobber (match_scratch 3))]
5203   "reload_completed"
5204   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5205               (clobber (match_dup 3))])])
5207 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5208 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5209 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5210 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5211 ;; function in i386.c.
5212 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5213   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5214         (fix:SWI248x (match_operand 1 "register_operand")))
5215    (clobber (reg:CC FLAGS_REG))]
5216   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5217    && !TARGET_FISTTP
5218    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5219          && (TARGET_64BIT || <MODE>mode != DImode))
5220    && can_create_pseudo_p ()"
5221   "#"
5222   "&& 1"
5223   [(const_int 0)]
5225   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5227   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5228   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5229   if (memory_operand (operands[0], VOIDmode))
5230     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5231                                          operands[2], operands[3]));
5232   else
5233     {
5234       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5235       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5236                                                      operands[2], operands[3],
5237                                                      operands[4]));
5238     }
5239   DONE;
5241   [(set_attr "type" "fistp")
5242    (set_attr "i387_cw" "trunc")
5243    (set_attr "mode" "<MODE>")])
5245 (define_insn "fix_truncdi_i387"
5246   [(set (match_operand:DI 0 "memory_operand" "=m")
5247         (fix:DI (match_operand 1 "register_operand" "f")))
5248    (use (match_operand:HI 2 "memory_operand" "m"))
5249    (use (match_operand:HI 3 "memory_operand" "m"))
5250    (clobber (match_scratch:XF 4 "=&1f"))]
5251   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5252    && !TARGET_FISTTP
5253    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5254   "* return output_fix_trunc (insn, operands, false);"
5255   [(set_attr "type" "fistp")
5256    (set_attr "i387_cw" "trunc")
5257    (set_attr "mode" "DI")])
5259 (define_insn "fix_truncdi_i387_with_temp"
5260   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5261         (fix:DI (match_operand 1 "register_operand" "f,f")))
5262    (use (match_operand:HI 2 "memory_operand" "m,m"))
5263    (use (match_operand:HI 3 "memory_operand" "m,m"))
5264    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5265    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5266   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5267    && !TARGET_FISTTP
5268    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5269   "#"
5270   [(set_attr "type" "fistp")
5271    (set_attr "i387_cw" "trunc")
5272    (set_attr "mode" "DI")])
5274 (define_split
5275   [(set (match_operand:DI 0 "register_operand")
5276         (fix:DI (match_operand 1 "register_operand")))
5277    (use (match_operand:HI 2 "memory_operand"))
5278    (use (match_operand:HI 3 "memory_operand"))
5279    (clobber (match_operand:DI 4 "memory_operand"))
5280    (clobber (match_scratch 5))]
5281   "reload_completed"
5282   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5283               (use (match_dup 2))
5284               (use (match_dup 3))
5285               (clobber (match_dup 5))])
5286    (set (match_dup 0) (match_dup 4))])
5288 (define_split
5289   [(set (match_operand:DI 0 "memory_operand")
5290         (fix:DI (match_operand 1 "register_operand")))
5291    (use (match_operand:HI 2 "memory_operand"))
5292    (use (match_operand:HI 3 "memory_operand"))
5293    (clobber (match_operand:DI 4 "memory_operand"))
5294    (clobber (match_scratch 5))]
5295   "reload_completed"
5296   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5297               (use (match_dup 2))
5298               (use (match_dup 3))
5299               (clobber (match_dup 5))])])
5301 (define_insn "fix_trunc<mode>_i387"
5302   [(set (match_operand:SWI24 0 "memory_operand" "=m")
5303         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5304    (use (match_operand:HI 2 "memory_operand" "m"))
5305    (use (match_operand:HI 3 "memory_operand" "m"))]
5306   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5307    && !TARGET_FISTTP
5308    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5309   "* return output_fix_trunc (insn, operands, false);"
5310   [(set_attr "type" "fistp")
5311    (set_attr "i387_cw" "trunc")
5312    (set_attr "mode" "<MODE>")])
5314 (define_insn "fix_trunc<mode>_i387_with_temp"
5315   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5316         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5317    (use (match_operand:HI 2 "memory_operand" "m,m"))
5318    (use (match_operand:HI 3 "memory_operand" "m,m"))
5319    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5320   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5321    && !TARGET_FISTTP
5322    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5323   "#"
5324   [(set_attr "type" "fistp")
5325    (set_attr "i387_cw" "trunc")
5326    (set_attr "mode" "<MODE>")])
5328 (define_split
5329   [(set (match_operand:SWI24 0 "register_operand")
5330         (fix:SWI24 (match_operand 1 "register_operand")))
5331    (use (match_operand:HI 2 "memory_operand"))
5332    (use (match_operand:HI 3 "memory_operand"))
5333    (clobber (match_operand:SWI24 4 "memory_operand"))]
5334   "reload_completed"
5335   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5336               (use (match_dup 2))
5337               (use (match_dup 3))])
5338    (set (match_dup 0) (match_dup 4))])
5340 (define_split
5341   [(set (match_operand:SWI24 0 "memory_operand")
5342         (fix:SWI24 (match_operand 1 "register_operand")))
5343    (use (match_operand:HI 2 "memory_operand"))
5344    (use (match_operand:HI 3 "memory_operand"))
5345    (clobber (match_operand:SWI24 4 "memory_operand"))]
5346   "reload_completed"
5347   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5348               (use (match_dup 2))
5349               (use (match_dup 3))])])
5351 (define_insn "x86_fnstcw_1"
5352   [(set (match_operand:HI 0 "memory_operand" "=m")
5353         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5354   "TARGET_80387"
5355   "fnstcw\t%0"
5356   [(set (attr "length")
5357         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5358    (set_attr "mode" "HI")
5359    (set_attr "unit" "i387")
5360    (set_attr "bdver1_decode" "vector")])
5362 (define_insn "x86_fldcw_1"
5363   [(set (reg:HI FPCR_REG)
5364         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5365   "TARGET_80387"
5366   "fldcw\t%0"
5367   [(set (attr "length")
5368         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5369    (set_attr "mode" "HI")
5370    (set_attr "unit" "i387")
5371    (set_attr "athlon_decode" "vector")
5372    (set_attr "amdfam10_decode" "vector")
5373    (set_attr "bdver1_decode" "vector")])
5375 ;; Conversion between fixed point and floating point.
5377 ;; Even though we only accept memory inputs, the backend _really_
5378 ;; wants to be able to do this between registers.  Thankfully, LRA
5379 ;; will fix this up for us during register allocation.
5381 (define_insn "floathi<mode>2"
5382   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5383         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5384   "TARGET_80387
5385    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5386        || TARGET_MIX_SSE_I387)"
5387   "fild%Z1\t%1"
5388   [(set_attr "type" "fmov")
5389    (set_attr "mode" "<MODE>")
5390    (set_attr "znver1_decode" "double")
5391    (set_attr "fp_int_src" "true")])
5393 (define_insn "float<SWI48x:mode>xf2"
5394   [(set (match_operand:XF 0 "register_operand" "=f")
5395         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5396   "TARGET_80387"
5397   "fild%Z1\t%1"
5398   [(set_attr "type" "fmov")
5399    (set_attr "mode" "XF")
5400    (set_attr "znver1_decode" "double")
5401    (set_attr "fp_int_src" "true")])
5403 (define_expand "float<SWI48:mode><MODEF:mode>2"
5404   [(set (match_operand:MODEF 0 "register_operand")
5405         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5406   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5408   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5409       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5410     {
5411       rtx reg = gen_reg_rtx (XFmode);
5412       rtx (*insn)(rtx, rtx);
5414       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5416       if (<MODEF:MODE>mode == SFmode)
5417         insn = gen_truncxfsf2;
5418       else if (<MODEF:MODE>mode == DFmode)
5419         insn = gen_truncxfdf2;
5420       else
5421         gcc_unreachable ();
5423       emit_insn (insn (operands[0], reg));
5424       DONE;
5425     }
5428 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5429   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5430         (float:MODEF
5431           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5432   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5433   "@
5434    fild%Z1\t%1
5435    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5436    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5437   [(set_attr "type" "fmov,sseicvt,sseicvt")
5438    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5439    (set_attr "mode" "<MODEF:MODE>")
5440    (set (attr "prefix_rex")
5441      (if_then_else
5442        (and (eq_attr "prefix" "maybe_vex")
5443             (match_test "<SWI48:MODE>mode == DImode"))
5444        (const_string "1")
5445        (const_string "*")))
5446    (set_attr "unit" "i387,*,*")
5447    (set_attr "athlon_decode" "*,double,direct")
5448    (set_attr "amdfam10_decode" "*,vector,double")
5449    (set_attr "bdver1_decode" "*,double,direct")
5450    (set_attr "znver1_decode" "double,*,*")
5451    (set_attr "fp_int_src" "true")
5452    (set (attr "enabled")
5453      (cond [(eq_attr "alternative" "0")
5454               (symbol_ref "TARGET_MIX_SSE_I387
5455                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5456                                                 <SWI48:MODE>mode)")
5457            ]
5458            (symbol_ref "true")))
5459    (set (attr "preferred_for_speed")
5460      (cond [(eq_attr "alternative" "1")
5461               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5462            (symbol_ref "true")))])
5464 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5465   [(set (match_operand:MODEF 0 "register_operand" "=f")
5466         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5467   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5468   "fild%Z1\t%1"
5469   [(set_attr "type" "fmov")
5470    (set_attr "mode" "<MODEF:MODE>")
5471    (set_attr "znver1_decode" "double")
5472    (set_attr "fp_int_src" "true")])
5474 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5475 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5476 ;; alternative in sse2_loadld.
5477 (define_split
5478   [(set (match_operand:MODEF 0 "sse_reg_operand")
5479         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5480   "TARGET_SSE2
5481    && TARGET_USE_VECTOR_CONVERTS
5482    && optimize_function_for_speed_p (cfun)
5483    && reload_completed
5484    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5485    && (!EXT_REX_SSE_REG_P (operands[0])
5486        || TARGET_AVX512VL)"
5487   [(const_int 0)]
5489   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5490   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5492   emit_insn (gen_sse2_loadld (operands[4],
5493                               CONST0_RTX (V4SImode), operands[1]));
5495   if (<ssevecmode>mode == V4SFmode)
5496     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5497   else
5498     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5499   DONE;
5502 ;; Avoid partial SSE register dependency stalls.  This splitter should split
5503 ;; late in the pass sequence (after register rename pass), so allocated
5504 ;; registers won't change anymore
5506 (define_split
5507   [(set (match_operand:MODEF 0 "sse_reg_operand")
5508         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5509   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5510    && optimize_function_for_speed_p (cfun)
5511    && (!EXT_REX_SSE_REG_P (operands[0])
5512        || TARGET_AVX512VL)"
5513   [(set (match_dup 0)
5514         (vec_merge:<MODEF:ssevecmode>
5515           (vec_duplicate:<MODEF:ssevecmode>
5516             (float:MODEF
5517               (match_dup 1)))
5518           (match_dup 0)
5519           (const_int 1)))]
5521   const machine_mode vmode = <MODEF:ssevecmode>mode;
5523   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5524   emit_move_insn (operands[0], CONST0_RTX (vmode));
5527 ;; Break partial reg stall for cvtsd2ss.  This splitter should split
5528 ;; late in the pass sequence (after register rename pass),
5529 ;; so allocated registers won't change anymore.
5531 (define_split
5532   [(set (match_operand:SF 0 "sse_reg_operand")
5533         (float_truncate:SF
5534           (match_operand:DF 1 "nonimmediate_operand")))]
5535   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5536    && optimize_function_for_speed_p (cfun)
5537    && (!REG_P (operands[1])
5538        || REGNO (operands[0]) != REGNO (operands[1]))
5539    && (!EXT_REX_SSE_REG_P (operands[0])
5540        || TARGET_AVX512VL)"
5541   [(set (match_dup 0)
5542         (vec_merge:V4SF
5543           (vec_duplicate:V4SF
5544             (float_truncate:SF
5545               (match_dup 1)))
5546           (match_dup 0)
5547           (const_int 1)))]
5549   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5550   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5553 ;; Break partial reg stall for cvtss2sd.  This splitter should split
5554 ;; late in the pass sequence (after register rename pass),
5555 ;; so allocated registers won't change anymore.
5557 (define_split
5558   [(set (match_operand:DF 0 "sse_reg_operand")
5559         (float_extend:DF
5560           (match_operand:SF 1 "nonimmediate_operand")))]
5561   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5562    && optimize_function_for_speed_p (cfun)
5563    && (!REG_P (operands[1])
5564        || REGNO (operands[0]) != REGNO (operands[1]))
5565    && (!EXT_REX_SSE_REG_P (operands[0])
5566        || TARGET_AVX512VL)"
5567   [(set (match_dup 0)
5568         (vec_merge:V2DF
5569           (vec_duplicate:V2DF
5570             (float_extend:DF
5571               (match_dup 1)))
5572           (match_dup 0)
5573           (const_int 1)))]
5575   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5576   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5579 ;; Avoid store forwarding (partial memory) stall penalty
5580 ;; by passing DImode value through XMM registers.  */
5582 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5583   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5584         (float:X87MODEF
5585           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5586    (clobber (match_scratch:V4SI 3 "=X,x"))
5587    (clobber (match_scratch:V4SI 4 "=X,x"))
5588    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5589   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5590    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5591    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5592   "#"
5593   [(set_attr "type" "multi")
5594    (set_attr "mode" "<X87MODEF:MODE>")
5595    (set_attr "unit" "i387")
5596    (set_attr "fp_int_src" "true")])
5598 (define_split
5599   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5600         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5601    (clobber (match_scratch:V4SI 3))
5602    (clobber (match_scratch:V4SI 4))
5603    (clobber (match_operand:DI 2 "memory_operand"))]
5604   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5605    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5606    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5607    && reload_completed"
5608   [(set (match_dup 2) (match_dup 3))
5609    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5611   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5612      Assemble the 64-bit DImode value in an xmm register.  */
5613   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5614                               gen_lowpart (SImode, operands[1])));
5615   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5616                               gen_highpart (SImode, operands[1])));
5617   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5618                                          operands[4]));
5620   operands[3] = gen_lowpart (DImode, operands[3]);
5623 (define_split
5624   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5625         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5626    (clobber (match_scratch:V4SI 3))
5627    (clobber (match_scratch:V4SI 4))
5628    (clobber (match_operand:DI 2 "memory_operand"))]
5629   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5630    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5631    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5632    && reload_completed"
5633   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5635 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5636   [(set (match_operand:MODEF 0 "register_operand")
5637         (unsigned_float:MODEF
5638           (match_operand:SWI12 1 "nonimmediate_operand")))]
5639   "!TARGET_64BIT
5640    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5642   operands[1] = convert_to_mode (SImode, operands[1], 1);
5643   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5644   DONE;
5647 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5648   [(set (match_operand:MODEF 0 "register_operand" "=v")
5649         (unsigned_float:MODEF
5650           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5651   "TARGET_AVX512F && TARGET_SSE_MATH"
5652   "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5653   [(set_attr "type" "sseicvt")
5654    (set_attr "prefix" "evex")
5655    (set_attr "mode" "<MODEF:MODE>")])
5657 ;; Avoid store forwarding (partial memory) stall penalty by extending
5658 ;; SImode value to DImode through XMM register instead of pushing two
5659 ;; SImode values to stack. Also note that fild loads from memory only.
5661 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5662   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5663         (unsigned_float:X87MODEF
5664           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5665    (clobber (match_operand:DI 2 "memory_operand" "=m"))
5666    (clobber (match_scratch:DI 3 "=x"))]
5667   "!TARGET_64BIT
5668    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5669    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5670   "#"
5671   "&& reload_completed"
5672   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5673    (set (match_dup 2) (match_dup 3))
5674    (set (match_dup 0)
5675         (float:X87MODEF (match_dup 2)))]
5676   ""
5677   [(set_attr "type" "multi")
5678    (set_attr "mode" "<MODE>")])
5680 (define_expand "floatunssi<mode>2"
5681   [(set (match_operand:X87MODEF 0 "register_operand")
5682         (unsigned_float:X87MODEF
5683           (match_operand:SI 1 "nonimmediate_operand")))]
5684   "(!TARGET_64BIT
5685     && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5686     && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5687    || ((!TARGET_64BIT || TARGET_AVX512F)
5688        && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5690   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5691     {
5692       emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5693                   (operands[0], operands[1],
5694                    assign_386_stack_local (DImode, SLOT_TEMP)));
5695       DONE;
5696     }
5697   if (!TARGET_AVX512F)
5698     {
5699       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5700       DONE;
5701     }
5704 (define_expand "floatunsdisf2"
5705   [(set (match_operand:SF 0 "register_operand")
5706         (unsigned_float:SF
5707           (match_operand:DI 1 "nonimmediate_operand")))]
5708   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5710   if (!TARGET_AVX512F)
5711     {
5712       x86_emit_floatuns (operands);
5713       DONE;
5714     }
5717 (define_expand "floatunsdidf2"
5718   [(set (match_operand:DF 0 "register_operand")
5719         (unsigned_float:DF
5720           (match_operand:DI 1 "nonimmediate_operand")))]
5721   "(TARGET_KEEPS_VECTOR_ALIGNED_STACK || TARGET_AVX512F)
5722    && TARGET_SSE2 && TARGET_SSE_MATH"
5724   if (!TARGET_64BIT)
5725     {
5726       ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5727       DONE;
5728     }
5729   if (!TARGET_AVX512F)
5730     {
5731       x86_emit_floatuns (operands);
5732       DONE;
5733     }
5736 ;; Load effective address instructions
5738 (define_insn_and_split "*lea<mode>"
5739   [(set (match_operand:SWI48 0 "register_operand" "=r")
5740         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5741   ""
5743   if (SImode_address_operand (operands[1], VOIDmode))
5744     {
5745       gcc_assert (TARGET_64BIT);
5746       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5747     }
5748   else 
5749     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5751   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5752   [(const_int 0)]
5754   machine_mode mode = <MODE>mode;
5755   rtx pat;
5757   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5758      change operands[] array behind our back.  */
5759   pat = PATTERN (curr_insn);
5761   operands[0] = SET_DEST (pat);
5762   operands[1] = SET_SRC (pat);
5764   /* Emit all operations in SImode for zero-extended addresses.  */
5765   if (SImode_address_operand (operands[1], VOIDmode))
5766     mode = SImode;
5768   ix86_split_lea_for_addr (curr_insn, operands, mode);
5770   /* Zero-extend return register to DImode for zero-extended addresses.  */
5771   if (mode != <MODE>mode)
5772     emit_insn (gen_zero_extendsidi2
5773                (operands[0], gen_lowpart (mode, operands[0])));
5775   DONE;
5777   [(set_attr "type" "lea")
5778    (set (attr "mode")
5779      (if_then_else
5780        (match_operand 1 "SImode_address_operand")
5781        (const_string "SI")
5782        (const_string "<MODE>")))])
5784 ;; Add instructions
5786 (define_expand "add<mode>3"
5787   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5788         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5789                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5790   ""
5791   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5793 (define_insn_and_split "*add<dwi>3_doubleword"
5794   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5795         (plus:<DWI>
5796           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5797           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5798                                                         "ro<di>,r<di>")))
5799    (clobber (reg:CC FLAGS_REG))]
5800   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5801   "#"
5802   "reload_completed"
5803   [(parallel [(set (reg:CCC FLAGS_REG)
5804                    (compare:CCC
5805                      (plus:DWIH (match_dup 1) (match_dup 2))
5806                      (match_dup 1)))
5807               (set (match_dup 0)
5808                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5809    (parallel [(set (match_dup 3)
5810                    (plus:DWIH
5811                      (plus:DWIH
5812                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5813                        (match_dup 4))
5814                      (match_dup 5)))
5815               (clobber (reg:CC FLAGS_REG))])]
5817   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5818   if (operands[2] == const0_rtx)
5819     {
5820       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5821       DONE;
5822     }
5825 (define_insn "*add<mode>_1"
5826   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5827         (plus:SWI48
5828           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5829           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5830    (clobber (reg:CC FLAGS_REG))]
5831   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5833   switch (get_attr_type (insn))
5834     {
5835     case TYPE_LEA:
5836       return "#";
5838     case TYPE_INCDEC:
5839       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840       if (operands[2] == const1_rtx)
5841         return "inc{<imodesuffix>}\t%0";
5842       else
5843         {
5844           gcc_assert (operands[2] == constm1_rtx);
5845           return "dec{<imodesuffix>}\t%0";
5846         }
5848     default:
5849       /* For most processors, ADD is faster than LEA.  This alternative
5850          was added to use ADD as much as possible.  */
5851       if (which_alternative == 2)
5852         std::swap (operands[1], operands[2]);
5853         
5854       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5855       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5856         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5858       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5859     }
5861   [(set (attr "type")
5862      (cond [(eq_attr "alternative" "3")
5863               (const_string "lea")
5864             (match_operand:SWI48 2 "incdec_operand")
5865               (const_string "incdec")
5866            ]
5867            (const_string "alu")))
5868    (set (attr "length_immediate")
5869       (if_then_else
5870         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5871         (const_string "1")
5872         (const_string "*")))
5873    (set_attr "mode" "<MODE>")])
5875 ;; It may seem that nonimmediate operand is proper one for operand 1.
5876 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5877 ;; we take care in ix86_binary_operator_ok to not allow two memory
5878 ;; operands so proper swapping will be done in reload.  This allow
5879 ;; patterns constructed from addsi_1 to match.
5881 (define_insn "addsi_1_zext"
5882   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5883         (zero_extend:DI
5884           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5885                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5886    (clobber (reg:CC FLAGS_REG))]
5887   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5889   switch (get_attr_type (insn))
5890     {
5891     case TYPE_LEA:
5892       return "#";
5894     case TYPE_INCDEC:
5895       if (operands[2] == const1_rtx)
5896         return "inc{l}\t%k0";
5897       else
5898         {
5899           gcc_assert (operands[2] == constm1_rtx);
5900           return "dec{l}\t%k0";
5901         }
5903     default:
5904       /* For most processors, ADD is faster than LEA.  This alternative
5905          was added to use ADD as much as possible.  */
5906       if (which_alternative == 1)
5907         std::swap (operands[1], operands[2]);
5909       if (x86_maybe_negate_const_int (&operands[2], SImode))
5910         return "sub{l}\t{%2, %k0|%k0, %2}";
5912       return "add{l}\t{%2, %k0|%k0, %2}";
5913     }
5915   [(set (attr "type")
5916      (cond [(eq_attr "alternative" "2")
5917               (const_string "lea")
5918             (match_operand:SI 2 "incdec_operand")
5919               (const_string "incdec")
5920            ]
5921            (const_string "alu")))
5922    (set (attr "length_immediate")
5923       (if_then_else
5924         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5925         (const_string "1")
5926         (const_string "*")))
5927    (set_attr "mode" "SI")])
5929 (define_insn "*addhi_1"
5930   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5931         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5932                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5933    (clobber (reg:CC FLAGS_REG))]
5934   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5936   switch (get_attr_type (insn))
5937     {
5938     case TYPE_LEA:
5939       return "#";
5941     case TYPE_INCDEC:
5942       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5943       if (operands[2] == const1_rtx)
5944         return "inc{w}\t%0";
5945       else
5946         {
5947           gcc_assert (operands[2] == constm1_rtx);
5948           return "dec{w}\t%0";
5949         }
5951     default:
5952       /* For most processors, ADD is faster than LEA.  This alternative
5953          was added to use ADD as much as possible.  */
5954       if (which_alternative == 2)
5955         std::swap (operands[1], operands[2]);
5957       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5958       if (x86_maybe_negate_const_int (&operands[2], HImode))
5959         return "sub{w}\t{%2, %0|%0, %2}";
5961       return "add{w}\t{%2, %0|%0, %2}";
5962     }
5964   [(set (attr "type")
5965      (cond [(eq_attr "alternative" "3")
5966               (const_string "lea")
5967             (match_operand:HI 2 "incdec_operand")
5968               (const_string "incdec")
5969            ]
5970            (const_string "alu")))
5971    (set (attr "length_immediate")
5972       (if_then_else
5973         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5974         (const_string "1")
5975         (const_string "*")))
5976    (set_attr "mode" "HI,HI,HI,SI")])
5978 (define_insn "*addqi_1"
5979   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5980         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5981                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5982    (clobber (reg:CC FLAGS_REG))]
5983   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5985   bool widen = (get_attr_mode (insn) != MODE_QI);
5987   switch (get_attr_type (insn))
5988     {
5989     case TYPE_LEA:
5990       return "#";
5992     case TYPE_INCDEC:
5993       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5994       if (operands[2] == const1_rtx)
5995         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5996       else
5997         {
5998           gcc_assert (operands[2] == constm1_rtx);
5999           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6000         }
6002     default:
6003       /* For most processors, ADD is faster than LEA.  These alternatives
6004          were added to use ADD as much as possible.  */
6005       if (which_alternative == 2 || which_alternative == 4)
6006         std::swap (operands[1], operands[2]);
6008       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6009       if (x86_maybe_negate_const_int (&operands[2], QImode))
6010         {
6011           if (widen)
6012             return "sub{l}\t{%2, %k0|%k0, %2}";
6013           else
6014             return "sub{b}\t{%2, %0|%0, %2}";
6015         }
6016       if (widen)
6017         return "add{l}\t{%k2, %k0|%k0, %k2}";
6018       else
6019         return "add{b}\t{%2, %0|%0, %2}";
6020     }
6022   [(set (attr "type")
6023      (cond [(eq_attr "alternative" "5")
6024               (const_string "lea")
6025             (match_operand:QI 2 "incdec_operand")
6026               (const_string "incdec")
6027            ]
6028            (const_string "alu")))
6029    (set (attr "length_immediate")
6030       (if_then_else
6031         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6032         (const_string "1")
6033         (const_string "*")))
6034    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6035    ;; Potential partial reg stall on alternatives 3 and 4.
6036    (set (attr "preferred_for_speed")
6037      (cond [(eq_attr "alternative" "3,4")
6038               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6039            (symbol_ref "true")))])
6041 (define_insn "*addqi_1_slp"
6042   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6043         (plus:QI (match_dup 0)
6044                  (match_operand:QI 1 "general_operand" "qn,qm")))
6045    (clobber (reg:CC FLAGS_REG))]
6046   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6047    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6049   switch (get_attr_type (insn))
6050     {
6051     case TYPE_INCDEC:
6052       if (operands[1] == const1_rtx)
6053         return "inc{b}\t%0";
6054       else
6055         {
6056           gcc_assert (operands[1] == constm1_rtx);
6057           return "dec{b}\t%0";
6058         }
6060     default:
6061       if (x86_maybe_negate_const_int (&operands[1], QImode))
6062         return "sub{b}\t{%1, %0|%0, %1}";
6064       return "add{b}\t{%1, %0|%0, %1}";
6065     }
6067   [(set (attr "type")
6068      (if_then_else (match_operand:QI 1 "incdec_operand")
6069         (const_string "incdec")
6070         (const_string "alu1")))
6071    (set (attr "memory")
6072      (if_then_else (match_operand 1 "memory_operand")
6073         (const_string "load")
6074         (const_string "none")))
6075    (set_attr "mode" "QI")])
6077 ;; Split non destructive adds if we cannot use lea.
6078 (define_split
6079   [(set (match_operand:SWI48 0 "register_operand")
6080         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6081                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6082    (clobber (reg:CC FLAGS_REG))]
6083   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6084   [(set (match_dup 0) (match_dup 1))
6085    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6086               (clobber (reg:CC FLAGS_REG))])])
6088 ;; Split non destructive adds if we cannot use lea.
6089 (define_split
6090   [(set (match_operand:DI 0 "register_operand")
6091         (zero_extend:DI
6092           (plus:SI (match_operand:SI 1 "register_operand")
6093                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6094    (clobber (reg:CC FLAGS_REG))]
6095   "TARGET_64BIT
6096    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6097   [(set (match_dup 3) (match_dup 1))
6098    (parallel [(set (match_dup 0)
6099                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6100               (clobber (reg:CC FLAGS_REG))])]
6101   "operands[3] = gen_lowpart (SImode, operands[0]);")
6103 ;; Convert add to the lea pattern to avoid flags dependency.
6104 (define_split
6105   [(set (match_operand:SWI 0 "register_operand")
6106         (plus:SWI (match_operand:SWI 1 "register_operand")
6107                   (match_operand:SWI 2 "<nonmemory_operand>")))
6108    (clobber (reg:CC FLAGS_REG))]
6109   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6110   [(set (match_dup 0)
6111         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6113   if (<MODE>mode != <LEAMODE>mode)
6114     {
6115       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6116       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6117       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6118     }
6121 ;; Convert add to the lea pattern to avoid flags dependency.
6122 (define_split
6123   [(set (match_operand:DI 0 "register_operand")
6124         (zero_extend:DI
6125           (plus:SI (match_operand:SI 1 "register_operand")
6126                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6127    (clobber (reg:CC FLAGS_REG))]
6128   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6129   [(set (match_dup 0)
6130         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6132 (define_insn "*add<mode>_2"
6133   [(set (reg FLAGS_REG)
6134         (compare
6135           (plus:SWI
6136             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6137             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6138           (const_int 0)))
6139    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6140         (plus:SWI (match_dup 1) (match_dup 2)))]
6141   "ix86_match_ccmode (insn, CCGOCmode)
6142    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6144   switch (get_attr_type (insn))
6145     {
6146     case TYPE_INCDEC:
6147       if (operands[2] == const1_rtx)
6148         return "inc{<imodesuffix>}\t%0";
6149       else
6150         {
6151           gcc_assert (operands[2] == constm1_rtx);
6152           return "dec{<imodesuffix>}\t%0";
6153         }
6155     default:
6156       if (which_alternative == 2)
6157         std::swap (operands[1], operands[2]);
6158         
6159       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6160       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6161         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6163       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6164     }
6166   [(set (attr "type")
6167      (if_then_else (match_operand:SWI 2 "incdec_operand")
6168         (const_string "incdec")
6169         (const_string "alu")))
6170    (set (attr "length_immediate")
6171       (if_then_else
6172         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6173         (const_string "1")
6174         (const_string "*")))
6175    (set_attr "mode" "<MODE>")])
6177 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6178 (define_insn "*addsi_2_zext"
6179   [(set (reg FLAGS_REG)
6180         (compare
6181           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6182                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6183           (const_int 0)))
6184    (set (match_operand:DI 0 "register_operand" "=r,r")
6185         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6186   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6187    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6189   switch (get_attr_type (insn))
6190     {
6191     case TYPE_INCDEC:
6192       if (operands[2] == const1_rtx)
6193         return "inc{l}\t%k0";
6194       else
6195         {
6196           gcc_assert (operands[2] == constm1_rtx);
6197           return "dec{l}\t%k0";
6198         }
6200     default:
6201       if (which_alternative == 1)
6202         std::swap (operands[1], operands[2]);
6204       if (x86_maybe_negate_const_int (&operands[2], SImode))
6205         return "sub{l}\t{%2, %k0|%k0, %2}";
6207       return "add{l}\t{%2, %k0|%k0, %2}";
6208     }
6210   [(set (attr "type")
6211      (if_then_else (match_operand:SI 2 "incdec_operand")
6212         (const_string "incdec")
6213         (const_string "alu")))
6214    (set (attr "length_immediate")
6215       (if_then_else
6216         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6217         (const_string "1")
6218         (const_string "*")))
6219    (set_attr "mode" "SI")])
6221 (define_insn "*add<mode>_3"
6222   [(set (reg FLAGS_REG)
6223         (compare
6224           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6225           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6226    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6227   "ix86_match_ccmode (insn, CCZmode)
6228    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6230   switch (get_attr_type (insn))
6231     {
6232     case TYPE_INCDEC:
6233       if (operands[2] == const1_rtx)
6234         return "inc{<imodesuffix>}\t%0";
6235       else
6236         {
6237           gcc_assert (operands[2] == constm1_rtx);
6238           return "dec{<imodesuffix>}\t%0";
6239         }
6241     default:
6242       if (which_alternative == 1)
6243         std::swap (operands[1], operands[2]);
6245       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6246       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6247         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6249       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6250     }
6252   [(set (attr "type")
6253      (if_then_else (match_operand:SWI 2 "incdec_operand")
6254         (const_string "incdec")
6255         (const_string "alu")))
6256    (set (attr "length_immediate")
6257       (if_then_else
6258         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6259         (const_string "1")
6260         (const_string "*")))
6261    (set_attr "mode" "<MODE>")])
6263 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6264 (define_insn "*addsi_3_zext"
6265   [(set (reg FLAGS_REG)
6266         (compare
6267           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6268           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6269    (set (match_operand:DI 0 "register_operand" "=r,r")
6270         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6271   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6272    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6274   switch (get_attr_type (insn))
6275     {
6276     case TYPE_INCDEC:
6277       if (operands[2] == const1_rtx)
6278         return "inc{l}\t%k0";
6279       else
6280         {
6281           gcc_assert (operands[2] == constm1_rtx);
6282           return "dec{l}\t%k0";
6283         }
6285     default:
6286       if (which_alternative == 1)
6287         std::swap (operands[1], operands[2]);
6289       if (x86_maybe_negate_const_int (&operands[2], SImode))
6290         return "sub{l}\t{%2, %k0|%k0, %2}";
6292       return "add{l}\t{%2, %k0|%k0, %2}";
6293     }
6295   [(set (attr "type")
6296      (if_then_else (match_operand:SI 2 "incdec_operand")
6297         (const_string "incdec")
6298         (const_string "alu")))
6299    (set (attr "length_immediate")
6300       (if_then_else
6301         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6302         (const_string "1")
6303         (const_string "*")))
6304    (set_attr "mode" "SI")])
6306 ; For comparisons against 1, -1 and 128, we may generate better code
6307 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6308 ; is matched then.  We can't accept general immediate, because for
6309 ; case of overflows,  the result is messed up.
6310 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6311 ; only for comparisons not depending on it.
6313 (define_insn "*adddi_4"
6314   [(set (reg FLAGS_REG)
6315         (compare
6316           (match_operand:DI 1 "nonimmediate_operand" "0")
6317           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6318    (clobber (match_scratch:DI 0 "=rm"))]
6319   "TARGET_64BIT
6320    && ix86_match_ccmode (insn, CCGCmode)"
6322   switch (get_attr_type (insn))
6323     {
6324     case TYPE_INCDEC:
6325       if (operands[2] == constm1_rtx)
6326         return "inc{q}\t%0";
6327       else
6328         {
6329           gcc_assert (operands[2] == const1_rtx);
6330           return "dec{q}\t%0";
6331         }
6333     default:
6334       if (x86_maybe_negate_const_int (&operands[2], DImode))
6335         return "add{q}\t{%2, %0|%0, %2}";
6337       return "sub{q}\t{%2, %0|%0, %2}";
6338     }
6340   [(set (attr "type")
6341      (if_then_else (match_operand:DI 2 "incdec_operand")
6342         (const_string "incdec")
6343         (const_string "alu")))
6344    (set (attr "length_immediate")
6345       (if_then_else
6346         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6347         (const_string "1")
6348         (const_string "*")))
6349    (set_attr "mode" "DI")])
6351 ; For comparisons against 1, -1 and 128, we may generate better code
6352 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6353 ; is matched then.  We can't accept general immediate, because for
6354 ; case of overflows,  the result is messed up.
6355 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6356 ; only for comparisons not depending on it.
6358 (define_insn "*add<mode>_4"
6359   [(set (reg FLAGS_REG)
6360         (compare
6361           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6362           (match_operand:SWI124 2 "const_int_operand" "n")))
6363    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6364   "ix86_match_ccmode (insn, CCGCmode)"
6366   switch (get_attr_type (insn))
6367     {
6368     case TYPE_INCDEC:
6369       if (operands[2] == constm1_rtx)
6370         return "inc{<imodesuffix>}\t%0";
6371       else
6372         {
6373           gcc_assert (operands[2] == const1_rtx);
6374           return "dec{<imodesuffix>}\t%0";
6375         }
6377     default:
6378       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6379         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6381       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6382     }
6384   [(set (attr "type")
6385      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6386         (const_string "incdec")
6387         (const_string "alu")))
6388    (set (attr "length_immediate")
6389       (if_then_else
6390         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6391         (const_string "1")
6392         (const_string "*")))
6393    (set_attr "mode" "<MODE>")])
6395 (define_insn "*add<mode>_5"
6396   [(set (reg FLAGS_REG)
6397         (compare
6398           (plus:SWI
6399             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6400             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6401           (const_int 0)))
6402    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6403   "ix86_match_ccmode (insn, CCGOCmode)
6404    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6406   switch (get_attr_type (insn))
6407     {
6408     case TYPE_INCDEC:
6409       if (operands[2] == const1_rtx)
6410         return "inc{<imodesuffix>}\t%0";
6411       else
6412         {
6413           gcc_assert (operands[2] == constm1_rtx);
6414           return "dec{<imodesuffix>}\t%0";
6415         }
6417     default:
6418       if (which_alternative == 1)
6419         std::swap (operands[1], operands[2]);
6421       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6422       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6423         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6425       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6426     }
6428   [(set (attr "type")
6429      (if_then_else (match_operand:SWI 2 "incdec_operand")
6430         (const_string "incdec")
6431         (const_string "alu")))
6432    (set (attr "length_immediate")
6433       (if_then_else
6434         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6435         (const_string "1")
6436         (const_string "*")))
6437    (set_attr "mode" "<MODE>")])
6439 (define_insn "addqi_ext_1"
6440   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6441                          (const_int 8)
6442                          (const_int 8))
6443         (subreg:SI
6444           (plus:QI
6445             (subreg:QI
6446               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6447                                (const_int 8)
6448                                (const_int 8)) 0)
6449             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6450    (clobber (reg:CC FLAGS_REG))]
6451   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6452    rtx_equal_p (operands[0], operands[1])"
6454   switch (get_attr_type (insn))
6455     {
6456     case TYPE_INCDEC:
6457       if (operands[2] == const1_rtx)
6458         return "inc{b}\t%h0";
6459       else
6460         {
6461           gcc_assert (operands[2] == constm1_rtx);
6462           return "dec{b}\t%h0";
6463         }
6465     default:
6466       return "add{b}\t{%2, %h0|%h0, %2}";
6467     }
6469   [(set_attr "isa" "*,nox64")
6470    (set (attr "type")
6471      (if_then_else (match_operand:QI 2 "incdec_operand")
6472         (const_string "incdec")
6473         (const_string "alu")))
6474    (set_attr "mode" "QI")])
6476 (define_insn "*addqi_ext_2"
6477   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6478                          (const_int 8)
6479                          (const_int 8))
6480         (subreg:SI
6481           (plus:QI
6482             (subreg:QI
6483               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6484                                (const_int 8)
6485                                (const_int 8)) 0)
6486             (subreg:QI
6487               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6488                                (const_int 8)
6489                                (const_int 8)) 0)) 0))
6490   (clobber (reg:CC FLAGS_REG))]
6491   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6492    rtx_equal_p (operands[0], operands[1])
6493    || rtx_equal_p (operands[0], operands[2])"
6494   "add{b}\t{%h2, %h0|%h0, %h2}"
6495   [(set_attr "type" "alu")
6496    (set_attr "mode" "QI")])
6498 ;; Add with jump on overflow.
6499 (define_expand "addv<mode>4"
6500   [(parallel [(set (reg:CCO FLAGS_REG)
6501                    (eq:CCO (plus:<DWI>
6502                               (sign_extend:<DWI>
6503                                  (match_operand:SWI 1 "nonimmediate_operand"))
6504                               (match_dup 4))
6505                            (sign_extend:<DWI>
6506                               (plus:SWI (match_dup 1)
6507                                         (match_operand:SWI 2
6508                                            "<general_operand>")))))
6509               (set (match_operand:SWI 0 "register_operand")
6510                    (plus:SWI (match_dup 1) (match_dup 2)))])
6511    (set (pc) (if_then_else
6512                (eq (reg:CCO FLAGS_REG) (const_int 0))
6513                (label_ref (match_operand 3))
6514                (pc)))]
6515   ""
6517   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6518   if (CONST_INT_P (operands[2]))
6519     operands[4] = operands[2];
6520   else
6521     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6524 (define_insn "*addv<mode>4"
6525   [(set (reg:CCO FLAGS_REG)
6526         (eq:CCO (plus:<DWI>
6527                    (sign_extend:<DWI>
6528                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6529                    (sign_extend:<DWI>
6530                       (match_operand:SWI 2 "<general_sext_operand>"
6531                                            "<r>mWe,<r>We")))
6532                 (sign_extend:<DWI>
6533                    (plus:SWI (match_dup 1) (match_dup 2)))))
6534    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6535         (plus:SWI (match_dup 1) (match_dup 2)))]
6536   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6537   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6538   [(set_attr "type" "alu")
6539    (set_attr "mode" "<MODE>")])
6541 (define_insn "*addv<mode>4_1"
6542   [(set (reg:CCO FLAGS_REG)
6543         (eq:CCO (plus:<DWI>
6544                    (sign_extend:<DWI>
6545                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6546                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6547                 (sign_extend:<DWI>
6548                    (plus:SWI (match_dup 1)
6549                              (match_operand:SWI 2 "x86_64_immediate_operand"
6550                                                   "<i>")))))
6551    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6552         (plus:SWI (match_dup 1) (match_dup 2)))]
6553   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6554    && CONST_INT_P (operands[2])
6555    && INTVAL (operands[2]) == INTVAL (operands[3])"
6556   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6557   [(set_attr "type" "alu")
6558    (set_attr "mode" "<MODE>")
6559    (set (attr "length_immediate")
6560         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6561                   (const_string "1")
6562                (match_test "<MODE_SIZE> == 8")
6563                   (const_string "4")]
6564               (const_string "<MODE_SIZE>")))])
6566 (define_expand "uaddv<mode>4"
6567   [(parallel [(set (reg:CCC FLAGS_REG)
6568                    (compare:CCC
6569                      (plus:SWI
6570                        (match_operand:SWI 1 "nonimmediate_operand")
6571                        (match_operand:SWI 2 "<general_operand>"))
6572                      (match_dup 1)))
6573               (set (match_operand:SWI 0 "register_operand")
6574                    (plus:SWI (match_dup 1) (match_dup 2)))])
6575    (set (pc) (if_then_else
6576                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6577                (label_ref (match_operand 3))
6578                (pc)))]
6579   ""
6580   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6582 ;; The lea patterns for modes less than 32 bits need to be matched by
6583 ;; several insns converted to real lea by splitters.
6585 (define_insn_and_split "*lea<mode>_general_1"
6586   [(set (match_operand:SWI12 0 "register_operand" "=r")
6587         (plus:SWI12
6588           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6589                       (match_operand:SWI12 2 "register_operand" "r"))
6590           (match_operand:SWI12 3 "immediate_operand" "i")))]
6591   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6592   "#"
6593   "&& reload_completed"
6594   [(set (match_dup 0)
6595         (plus:SI
6596           (plus:SI (match_dup 1) (match_dup 2))
6597           (match_dup 3)))]
6599   operands[0] = gen_lowpart (SImode, operands[0]);
6600   operands[1] = gen_lowpart (SImode, operands[1]);
6601   operands[2] = gen_lowpart (SImode, operands[2]);
6602   operands[3] = gen_lowpart (SImode, operands[3]);
6604   [(set_attr "type" "lea")
6605    (set_attr "mode" "SI")])
6607 (define_insn_and_split "*lea<mode>_general_2"
6608   [(set (match_operand:SWI12 0 "register_operand" "=r")
6609         (plus:SWI12
6610           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6611                       (match_operand 2 "const248_operand" "n"))
6612           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6613   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6614   "#"
6615   "&& reload_completed"
6616   [(set (match_dup 0)
6617         (plus:SI
6618           (mult:SI (match_dup 1) (match_dup 2))
6619           (match_dup 3)))]
6621   operands[0] = gen_lowpart (SImode, operands[0]);
6622   operands[1] = gen_lowpart (SImode, operands[1]);
6623   operands[3] = gen_lowpart (SImode, operands[3]);
6625   [(set_attr "type" "lea")
6626    (set_attr "mode" "SI")])
6628 (define_insn_and_split "*lea<mode>_general_2b"
6629   [(set (match_operand:SWI12 0 "register_operand" "=r")
6630         (plus:SWI12
6631           (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6632                         (match_operand 2 "const123_operand" "n"))
6633           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6634   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6635   "#"
6636   "&& reload_completed"
6637   [(set (match_dup 0)
6638         (plus:SI
6639           (ashift:SI (match_dup 1) (match_dup 2))
6640           (match_dup 3)))]
6642   operands[0] = gen_lowpart (SImode, operands[0]);
6643   operands[1] = gen_lowpart (SImode, operands[1]);
6644   operands[3] = gen_lowpart (SImode, operands[3]);
6646   [(set_attr "type" "lea")
6647    (set_attr "mode" "SI")])
6649 (define_insn_and_split "*lea<mode>_general_3"
6650   [(set (match_operand:SWI12 0 "register_operand" "=r")
6651         (plus:SWI12
6652           (plus:SWI12
6653             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6654                         (match_operand 2 "const248_operand" "n"))
6655             (match_operand:SWI12 3 "register_operand" "r"))
6656           (match_operand:SWI12 4 "immediate_operand" "i")))]
6657   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6658   "#"
6659   "&& reload_completed"
6660   [(set (match_dup 0)
6661         (plus:SI
6662           (plus:SI
6663             (mult:SI (match_dup 1) (match_dup 2))
6664             (match_dup 3))
6665           (match_dup 4)))]
6667   operands[0] = gen_lowpart (SImode, operands[0]);
6668   operands[1] = gen_lowpart (SImode, operands[1]);
6669   operands[3] = gen_lowpart (SImode, operands[3]);
6670   operands[4] = gen_lowpart (SImode, operands[4]);
6672   [(set_attr "type" "lea")
6673    (set_attr "mode" "SI")])
6675 (define_insn_and_split "*lea<mode>_general_3b"
6676   [(set (match_operand:SWI12 0 "register_operand" "=r")
6677         (plus:SWI12
6678           (plus:SWI12
6679             (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6680                           (match_operand 2 "const123_operand" "n"))
6681             (match_operand:SWI12 3 "register_operand" "r"))
6682           (match_operand:SWI12 4 "immediate_operand" "i")))]
6683   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6684   "#"
6685   "&& reload_completed"
6686   [(set (match_dup 0)
6687         (plus:SI
6688           (plus:SI
6689             (ashift:SI (match_dup 1) (match_dup 2))
6690             (match_dup 3))
6691           (match_dup 4)))]
6693   operands[0] = gen_lowpart (SImode, operands[0]);
6694   operands[1] = gen_lowpart (SImode, operands[1]);
6695   operands[3] = gen_lowpart (SImode, operands[3]);
6696   operands[4] = gen_lowpart (SImode, operands[4]);
6698   [(set_attr "type" "lea")
6699    (set_attr "mode" "SI")])
6701 (define_insn_and_split "*lea<mode>_general_4"
6702   [(set (match_operand:SWI12 0 "register_operand" "=r")
6703         (any_or:SWI12
6704           (ashift:SWI12
6705             (match_operand:SWI12 1 "index_register_operand" "l")
6706             (match_operand 2 "const_0_to_3_operand" "n"))
6707           (match_operand 3 "const_int_operand" "n")))]
6708   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6709    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6710        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6711   "#"
6712   "&& reload_completed"
6713   [(set (match_dup 0)
6714         (plus:SI
6715           (mult:SI (match_dup 1) (match_dup 2))
6716           (match_dup 3)))]
6718   operands[0] = gen_lowpart (SImode, operands[0]);
6719   operands[1] = gen_lowpart (SImode, operands[1]);
6720   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6722   [(set_attr "type" "lea")
6723    (set_attr "mode" "SI")])
6725 (define_insn_and_split "*lea<mode>_general_4"
6726   [(set (match_operand:SWI48 0 "register_operand" "=r")
6727         (any_or:SWI48
6728           (ashift:SWI48
6729             (match_operand:SWI48 1 "index_register_operand" "l")
6730             (match_operand 2 "const_0_to_3_operand" "n"))
6731           (match_operand 3 "const_int_operand" "n")))]
6732   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6733    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6734   "#"
6735   "&& reload_completed"
6736   [(set (match_dup 0)
6737         (plus:SWI48
6738           (mult:SWI48 (match_dup 1) (match_dup 2))
6739           (match_dup 3)))]
6740   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6741   [(set_attr "type" "lea")
6742    (set_attr "mode" "<MODE>")])
6744 ;; Subtract instructions
6746 (define_expand "sub<mode>3"
6747   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6748         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6749                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6750   ""
6751   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6753 (define_insn_and_split "*sub<dwi>3_doubleword"
6754   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6755         (minus:<DWI>
6756           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6757           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6758                                                         "ro<di>,r<di>")))
6759    (clobber (reg:CC FLAGS_REG))]
6760   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6761   "#"
6762   "reload_completed"
6763   [(parallel [(set (reg:CC FLAGS_REG)
6764                    (compare:CC (match_dup 1) (match_dup 2)))
6765               (set (match_dup 0)
6766                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6767    (parallel [(set (match_dup 3)
6768                    (minus:DWIH
6769                      (minus:DWIH
6770                        (match_dup 4)
6771                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6772                      (match_dup 5)))
6773               (clobber (reg:CC FLAGS_REG))])]
6775   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6776   if (operands[2] == const0_rtx)
6777     {
6778       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6779       DONE;
6780     }
6783 (define_insn "*sub<mode>_1"
6784   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6785         (minus:SWI
6786           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6787           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6788    (clobber (reg:CC FLAGS_REG))]
6789   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6790   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6791   [(set_attr "type" "alu")
6792    (set_attr "mode" "<MODE>")])
6794 (define_insn "*subsi_1_zext"
6795   [(set (match_operand:DI 0 "register_operand" "=r")
6796         (zero_extend:DI
6797           (minus:SI (match_operand:SI 1 "register_operand" "0")
6798                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6799    (clobber (reg:CC FLAGS_REG))]
6800   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6801   "sub{l}\t{%2, %k0|%k0, %2}"
6802   [(set_attr "type" "alu")
6803    (set_attr "mode" "SI")])
6805 (define_insn "*subqi_1_slp"
6806   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6807         (minus:QI (match_dup 0)
6808                   (match_operand:QI 1 "general_operand" "qn,qm")))
6809    (clobber (reg:CC FLAGS_REG))]
6810   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6811    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6812   "sub{b}\t{%1, %0|%0, %1}"
6813   [(set_attr "type" "alu1")
6814    (set_attr "mode" "QI")])
6816 (define_insn "*sub<mode>_2"
6817   [(set (reg FLAGS_REG)
6818         (compare
6819           (minus:SWI
6820             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6821             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6822           (const_int 0)))
6823    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6824         (minus:SWI (match_dup 1) (match_dup 2)))]
6825   "ix86_match_ccmode (insn, CCGOCmode)
6826    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6827   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6828   [(set_attr "type" "alu")
6829    (set_attr "mode" "<MODE>")])
6831 (define_insn "*subsi_2_zext"
6832   [(set (reg FLAGS_REG)
6833         (compare
6834           (minus:SI (match_operand:SI 1 "register_operand" "0")
6835                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6836           (const_int 0)))
6837    (set (match_operand:DI 0 "register_operand" "=r")
6838         (zero_extend:DI
6839           (minus:SI (match_dup 1)
6840                     (match_dup 2))))]
6841   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6842    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6843   "sub{l}\t{%2, %k0|%k0, %2}"
6844   [(set_attr "type" "alu")
6845    (set_attr "mode" "SI")])
6847 ;; Subtract with jump on overflow.
6848 (define_expand "subv<mode>4"
6849   [(parallel [(set (reg:CCO FLAGS_REG)
6850                    (eq:CCO (minus:<DWI>
6851                               (sign_extend:<DWI>
6852                                  (match_operand:SWI 1 "nonimmediate_operand"))
6853                               (match_dup 4))
6854                            (sign_extend:<DWI>
6855                               (minus:SWI (match_dup 1)
6856                                          (match_operand:SWI 2
6857                                             "<general_operand>")))))
6858               (set (match_operand:SWI 0 "register_operand")
6859                    (minus:SWI (match_dup 1) (match_dup 2)))])
6860    (set (pc) (if_then_else
6861                (eq (reg:CCO FLAGS_REG) (const_int 0))
6862                (label_ref (match_operand 3))
6863                (pc)))]
6864   ""
6866   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6867   if (CONST_INT_P (operands[2]))
6868     operands[4] = operands[2];
6869   else
6870     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6873 (define_insn "*subv<mode>4"
6874   [(set (reg:CCO FLAGS_REG)
6875         (eq:CCO (minus:<DWI>
6876                    (sign_extend:<DWI>
6877                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6878                    (sign_extend:<DWI>
6879                       (match_operand:SWI 2 "<general_sext_operand>"
6880                                            "<r>We,<r>m")))
6881                 (sign_extend:<DWI>
6882                    (minus:SWI (match_dup 1) (match_dup 2)))))
6883    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6884         (minus:SWI (match_dup 1) (match_dup 2)))]
6885   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6886   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6887   [(set_attr "type" "alu")
6888    (set_attr "mode" "<MODE>")])
6890 (define_insn "*subv<mode>4_1"
6891   [(set (reg:CCO FLAGS_REG)
6892         (eq:CCO (minus:<DWI>
6893                    (sign_extend:<DWI>
6894                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6895                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6896                 (sign_extend:<DWI>
6897                    (minus:SWI (match_dup 1)
6898                               (match_operand:SWI 2 "x86_64_immediate_operand"
6899                                                    "<i>")))))
6900    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6901         (minus:SWI (match_dup 1) (match_dup 2)))]
6902   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6903    && CONST_INT_P (operands[2])
6904    && INTVAL (operands[2]) == INTVAL (operands[3])"
6905   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6906   [(set_attr "type" "alu")
6907    (set_attr "mode" "<MODE>")
6908    (set (attr "length_immediate")
6909         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6910                   (const_string "1")
6911                (match_test "<MODE_SIZE> == 8")
6912                   (const_string "4")]
6913               (const_string "<MODE_SIZE>")))])
6915 (define_expand "usubv<mode>4"
6916   [(parallel [(set (reg:CC FLAGS_REG)
6917                    (compare:CC
6918                      (match_operand:SWI 1 "nonimmediate_operand")
6919                      (match_operand:SWI 2 "<general_operand>")))
6920               (set (match_operand:SWI 0 "register_operand")
6921                    (minus:SWI (match_dup 1) (match_dup 2)))])
6922    (set (pc) (if_then_else
6923                (ltu (reg:CC FLAGS_REG) (const_int 0))
6924                (label_ref (match_operand 3))
6925                (pc)))]
6926   ""
6927   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6929 (define_insn "*sub<mode>_3"
6930   [(set (reg FLAGS_REG)
6931         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6932                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6933    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6934         (minus:SWI (match_dup 1) (match_dup 2)))]
6935   "ix86_match_ccmode (insn, CCmode)
6936    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6937   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6938   [(set_attr "type" "alu")
6939    (set_attr "mode" "<MODE>")])
6941 (define_peephole2
6942   [(parallel
6943      [(set (reg:CC FLAGS_REG)
6944            (compare:CC (match_operand:SWI 0 "general_reg_operand")
6945                        (match_operand:SWI 1 "general_gr_operand")))
6946       (set (match_dup 0)
6947            (minus:SWI (match_dup 0) (match_dup 1)))])]
6948   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6949   [(set (reg:CC FLAGS_REG)
6950         (compare:CC (match_dup 0) (match_dup 1)))])
6952 (define_insn "*subsi_3_zext"
6953   [(set (reg FLAGS_REG)
6954         (compare (match_operand:SI 1 "register_operand" "0")
6955                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6956    (set (match_operand:DI 0 "register_operand" "=r")
6957         (zero_extend:DI
6958           (minus:SI (match_dup 1)
6959                     (match_dup 2))))]
6960   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6961    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6962   "sub{l}\t{%2, %1|%1, %2}"
6963   [(set_attr "type" "alu")
6964    (set_attr "mode" "SI")])
6966 ;; Add with carry and subtract with borrow
6968 (define_insn "add<mode>3_carry"
6969   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6970         (plus:SWI
6971           (plus:SWI
6972             (match_operator:SWI 4 "ix86_carry_flag_operator"
6973              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6974             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6975           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6976    (clobber (reg:CC FLAGS_REG))]
6977   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6978   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6979   [(set_attr "type" "alu")
6980    (set_attr "use_carry" "1")
6981    (set_attr "pent_pair" "pu")
6982    (set_attr "mode" "<MODE>")])
6984 (define_insn "*add<mode>3_carry_0"
6985   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6986         (plus:SWI
6987           (match_operator:SWI 3 "ix86_carry_flag_operator"
6988             [(match_operand 2 "flags_reg_operand") (const_int 0)])
6989           (match_operand:SWI 1 "nonimmediate_operand" "0")))
6990    (clobber (reg:CC FLAGS_REG))]
6991   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6992   "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6993   [(set_attr "type" "alu")
6994    (set_attr "use_carry" "1")
6995    (set_attr "pent_pair" "pu")
6996    (set_attr "mode" "<MODE>")])
6998 (define_insn "*addsi3_carry_zext"
6999   [(set (match_operand:DI 0 "register_operand" "=r")
7000         (zero_extend:DI
7001           (plus:SI
7002             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
7003                       [(reg FLAGS_REG) (const_int 0)])
7004                      (match_operand:SI 1 "register_operand" "%0"))
7005             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7006    (clobber (reg:CC FLAGS_REG))]
7007   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7008   "adc{l}\t{%2, %k0|%k0, %2}"
7009   [(set_attr "type" "alu")
7010    (set_attr "use_carry" "1")
7011    (set_attr "pent_pair" "pu")
7012    (set_attr "mode" "SI")])
7014 (define_insn "*addsi3_carry_zext_0"
7015   [(set (match_operand:DI 0 "register_operand" "=r")
7016         (zero_extend:DI
7017           (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
7018                     [(reg FLAGS_REG) (const_int 0)])
7019                    (match_operand:SI 1 "register_operand" "0"))))
7020    (clobber (reg:CC FLAGS_REG))]
7021   "TARGET_64BIT"
7022   "adc{l}\t{$0, %k0|%k0, 0}"
7023   [(set_attr "type" "alu")
7024    (set_attr "use_carry" "1")
7025    (set_attr "pent_pair" "pu")
7026    (set_attr "mode" "SI")])
7028 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
7030 (define_insn "addcarry<mode>"
7031   [(set (reg:CCC FLAGS_REG)
7032         (compare:CCC
7033           (zero_extend:<DWI>
7034             (plus:SWI48
7035               (plus:SWI48
7036                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7037                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
7038                 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
7039               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
7040           (plus:<DWI>
7041             (zero_extend:<DWI> (match_dup 2))
7042             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7043               [(match_dup 3) (const_int 0)]))))
7044    (set (match_operand:SWI48 0 "register_operand" "=r")
7045         (plus:SWI48 (plus:SWI48 (match_op_dup 5
7046                                  [(match_dup 3) (const_int 0)])
7047                                 (match_dup 1))
7048                     (match_dup 2)))]
7049   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7050   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7051   [(set_attr "type" "alu")
7052    (set_attr "use_carry" "1")
7053    (set_attr "pent_pair" "pu")
7054    (set_attr "mode" "<MODE>")])
7056 (define_expand "addcarry<mode>_0"
7057   [(parallel
7058      [(set (reg:CCC FLAGS_REG)
7059            (compare:CCC
7060              (plus:SWI48
7061                (match_operand:SWI48 1 "nonimmediate_operand")
7062                (match_operand:SWI48 2 "x86_64_general_operand"))
7063              (match_dup 1)))
7064       (set (match_operand:SWI48 0 "register_operand")
7065            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
7066   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
7068 (define_insn "sub<mode>3_carry"
7069   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7070         (minus:SWI
7071           (minus:SWI
7072             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7073             (match_operator:SWI 4 "ix86_carry_flag_operator"
7074              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7075           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7076    (clobber (reg:CC FLAGS_REG))]
7077   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7078   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7079   [(set_attr "type" "alu")
7080    (set_attr "use_carry" "1")
7081    (set_attr "pent_pair" "pu")
7082    (set_attr "mode" "<MODE>")])
7084 (define_insn "*sub<mode>3_carry_0"
7085   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7086         (minus:SWI
7087           (match_operand:SWI 1 "nonimmediate_operand" "0")
7088           (match_operator:SWI 3 "ix86_carry_flag_operator"
7089             [(match_operand 2 "flags_reg_operand") (const_int 0)])))
7090    (clobber (reg:CC FLAGS_REG))]
7091   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
7092   "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
7093   [(set_attr "type" "alu")
7094    (set_attr "use_carry" "1")
7095    (set_attr "pent_pair" "pu")
7096    (set_attr "mode" "<MODE>")])
7098 (define_insn "*subsi3_carry_zext"
7099   [(set (match_operand:DI 0 "register_operand" "=r")
7100         (zero_extend:DI
7101           (minus:SI
7102             (minus:SI
7103               (match_operand:SI 1 "register_operand" "0")
7104               (match_operator:SI 3 "ix86_carry_flag_operator"
7105                [(reg FLAGS_REG) (const_int 0)]))
7106             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7107    (clobber (reg:CC FLAGS_REG))]
7108   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7109   "sbb{l}\t{%2, %k0|%k0, %2}"
7110   [(set_attr "type" "alu")
7111    (set_attr "use_carry" "1")
7112    (set_attr "pent_pair" "pu")
7113    (set_attr "mode" "SI")])
7115 (define_insn "*subsi3_carry_zext_0"
7116   [(set (match_operand:DI 0 "register_operand" "=r")
7117         (zero_extend:DI
7118           (minus:SI
7119             (match_operand:SI 1 "register_operand" "0")
7120             (match_operator:SI 2 "ix86_carry_flag_operator"
7121               [(reg FLAGS_REG) (const_int 0)]))))
7122    (clobber (reg:CC FLAGS_REG))]
7123   "TARGET_64BIT"
7124   "sbb{l}\t{$0, %k0|%k0, 0}"
7125   [(set_attr "type" "alu")
7126    (set_attr "use_carry" "1")
7127    (set_attr "pent_pair" "pu")
7128    (set_attr "mode" "SI")])
7130 (define_insn "sub<mode>3_carry_ccc"
7131   [(set (reg:CCC FLAGS_REG)
7132         (compare:CCC
7133           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7134           (plus:<DWI>
7135             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7136             (zero_extend:<DWI>
7137               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
7138    (clobber (match_scratch:DWIH 0 "=r"))]
7139   ""
7140   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7141   [(set_attr "type" "alu")
7142    (set_attr "mode" "<MODE>")])
7144 (define_insn "*sub<mode>3_carry_ccc_1"
7145   [(set (reg:CCC FLAGS_REG)
7146         (compare:CCC
7147           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7148           (plus:<DWI>
7149             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7150             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7151    (clobber (match_scratch:DWIH 0 "=r"))]
7152   ""
7154   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7155   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7157   [(set_attr "type" "alu")
7158    (set_attr "mode" "<MODE>")])
7160 ;; The sign flag is set from the
7161 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7162 ;; result, the overflow flag likewise, but the overflow flag is also
7163 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7164 (define_insn "sub<mode>3_carry_ccgz"
7165   [(set (reg:CCGZ FLAGS_REG)
7166         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7167                       (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7168                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7169                      UNSPEC_SBB))
7170    (clobber (match_scratch:DWIH 0 "=r"))]
7171   ""
7172   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7173   [(set_attr "type" "alu")
7174    (set_attr "mode" "<MODE>")])
7176 (define_insn "subborrow<mode>"
7177   [(set (reg:CCC FLAGS_REG)
7178         (compare:CCC
7179           (zero_extend:<DWI>
7180             (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7181           (plus:<DWI>
7182             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7183               [(match_operand 3 "flags_reg_operand") (const_int 0)])
7184             (zero_extend:<DWI>
7185               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7186    (set (match_operand:SWI48 0 "register_operand" "=r")
7187         (minus:SWI48 (minus:SWI48
7188                        (match_dup 1)
7189                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
7190                          [(match_dup 3) (const_int 0)]))
7191                      (match_dup 2)))]
7192   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7193   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7194   [(set_attr "type" "alu")
7195    (set_attr "use_carry" "1")
7196    (set_attr "pent_pair" "pu")
7197    (set_attr "mode" "<MODE>")])
7199 (define_expand "subborrow<mode>_0"
7200   [(parallel
7201      [(set (reg:CC FLAGS_REG)
7202            (compare:CC
7203              (match_operand:SWI48 1 "nonimmediate_operand")
7204              (match_operand:SWI48 2 "<general_operand>")))
7205       (set (match_operand:SWI48 0 "register_operand")
7206            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7207   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7209 ;; Overflow setting add instructions
7211 (define_expand "addqi3_cconly_overflow"
7212   [(parallel
7213      [(set (reg:CCC FLAGS_REG)
7214            (compare:CCC
7215              (plus:QI
7216                (match_operand:QI 0 "nonimmediate_operand")
7217                (match_operand:QI 1 "general_operand"))
7218              (match_dup 0)))
7219       (clobber (match_scratch:QI 2))])]
7220   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7222 (define_insn "*add<mode>3_cconly_overflow_1"
7223   [(set (reg:CCC FLAGS_REG)
7224         (compare:CCC
7225           (plus:SWI
7226             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7227             (match_operand:SWI 2 "<general_operand>" "<g>"))
7228           (match_dup 1)))
7229    (clobber (match_scratch:SWI 0 "=<r>"))]
7230   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7231   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7232   [(set_attr "type" "alu")
7233    (set_attr "mode" "<MODE>")])
7235 (define_insn "*add<mode>3_cc_overflow_1"
7236   [(set (reg:CCC FLAGS_REG)
7237         (compare:CCC
7238             (plus:SWI
7239                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7240                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7241             (match_dup 1)))
7242    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7243         (plus:SWI (match_dup 1) (match_dup 2)))]
7244   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7245   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7246   [(set_attr "type" "alu")
7247    (set_attr "mode" "<MODE>")])
7249 (define_insn "*addsi3_zext_cc_overflow_1"
7250   [(set (reg:CCC FLAGS_REG)
7251         (compare:CCC
7252           (plus:SI
7253             (match_operand:SI 1 "nonimmediate_operand" "%0")
7254             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7255           (match_dup 1)))
7256    (set (match_operand:DI 0 "register_operand" "=r")
7257         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7258   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7259   "add{l}\t{%2, %k0|%k0, %2}"
7260   [(set_attr "type" "alu")
7261    (set_attr "mode" "SI")])
7263 (define_insn "*add<mode>3_cconly_overflow_2"
7264   [(set (reg:CCC FLAGS_REG)
7265         (compare:CCC
7266           (plus:SWI
7267             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7268             (match_operand:SWI 2 "<general_operand>" "<g>"))
7269           (match_dup 2)))
7270    (clobber (match_scratch:SWI 0 "=<r>"))]
7271   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7272   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7273   [(set_attr "type" "alu")
7274    (set_attr "mode" "<MODE>")])
7276 (define_insn "*add<mode>3_cc_overflow_2"
7277   [(set (reg:CCC FLAGS_REG)
7278         (compare:CCC
7279             (plus:SWI
7280                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7281                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7282             (match_dup 2)))
7283    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7284         (plus:SWI (match_dup 1) (match_dup 2)))]
7285   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7286   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7287   [(set_attr "type" "alu")
7288    (set_attr "mode" "<MODE>")])
7290 (define_insn "*addsi3_zext_cc_overflow_2"
7291   [(set (reg:CCC FLAGS_REG)
7292         (compare:CCC
7293           (plus:SI
7294             (match_operand:SI 1 "nonimmediate_operand" "%0")
7295             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7296           (match_dup 2)))
7297    (set (match_operand:DI 0 "register_operand" "=r")
7298         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7299   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7300   "add{l}\t{%2, %k0|%k0, %2}"
7301   [(set_attr "type" "alu")
7302    (set_attr "mode" "SI")])
7304 ;; The patterns that match these are at the end of this file.
7306 (define_expand "<plusminus_insn>xf3"
7307   [(set (match_operand:XF 0 "register_operand")
7308         (plusminus:XF
7309           (match_operand:XF 1 "register_operand")
7310           (match_operand:XF 2 "register_operand")))]
7311   "TARGET_80387")
7313 (define_expand "<plusminus_insn><mode>3"
7314   [(set (match_operand:MODEF 0 "register_operand")
7315         (plusminus:MODEF
7316           (match_operand:MODEF 1 "register_operand")
7317           (match_operand:MODEF 2 "nonimmediate_operand")))]
7318   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7319     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7321 ;; Multiply instructions
7323 (define_expand "mul<mode>3"
7324   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7325                    (mult:SWIM248
7326                      (match_operand:SWIM248 1 "register_operand")
7327                      (match_operand:SWIM248 2 "<general_operand>")))
7328               (clobber (reg:CC FLAGS_REG))])])
7330 (define_expand "mulqi3"
7331   [(parallel [(set (match_operand:QI 0 "register_operand")
7332                    (mult:QI
7333                      (match_operand:QI 1 "register_operand")
7334                      (match_operand:QI 2 "nonimmediate_operand")))
7335               (clobber (reg:CC FLAGS_REG))])]
7336   "TARGET_QIMODE_MATH")
7338 ;; On AMDFAM10
7339 ;; IMUL reg32/64, reg32/64, imm8        Direct
7340 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7341 ;; IMUL reg32/64, reg32/64, imm32       Direct
7342 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7343 ;; IMUL reg32/64, reg32/64              Direct
7344 ;; IMUL reg32/64, mem32/64              Direct
7346 ;; On BDVER1, all above IMULs use DirectPath
7348 ;; On AMDFAM10
7349 ;; IMUL reg16, reg16, imm8      VectorPath
7350 ;; IMUL reg16, mem16, imm8      VectorPath
7351 ;; IMUL reg16, reg16, imm16     VectorPath
7352 ;; IMUL reg16, mem16, imm16     VectorPath
7353 ;; IMUL reg16, reg16            Direct
7354 ;; IMUL reg16, mem16            Direct
7356 ;; On BDVER1, all HI MULs use DoublePath
7358 (define_insn "*mul<mode>3_1"
7359   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7360         (mult:SWIM248
7361           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7362           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7363    (clobber (reg:CC FLAGS_REG))]
7364   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7365   "@
7366    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7367    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7368    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7369   [(set_attr "type" "imul")
7370    (set_attr "prefix_0f" "0,0,1")
7371    (set (attr "athlon_decode")
7372         (cond [(eq_attr "cpu" "athlon")
7373                   (const_string "vector")
7374                (eq_attr "alternative" "1")
7375                   (const_string "vector")
7376                (and (eq_attr "alternative" "2")
7377                     (ior (match_test "<MODE>mode == HImode")
7378                          (match_operand 1 "memory_operand")))
7379                   (const_string "vector")]
7380               (const_string "direct")))
7381    (set (attr "amdfam10_decode")
7382         (cond [(and (eq_attr "alternative" "0,1")
7383                     (ior (match_test "<MODE>mode == HImode")
7384                          (match_operand 1 "memory_operand")))
7385                   (const_string "vector")]
7386               (const_string "direct")))
7387    (set (attr "bdver1_decode")
7388         (if_then_else
7389           (match_test "<MODE>mode == HImode")
7390             (const_string "double")
7391             (const_string "direct")))
7392    (set_attr "mode" "<MODE>")])
7394 (define_insn "*mulsi3_1_zext"
7395   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7396         (zero_extend:DI
7397           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7398                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7399    (clobber (reg:CC FLAGS_REG))]
7400   "TARGET_64BIT
7401    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7402   "@
7403    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7404    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7405    imul{l}\t{%2, %k0|%k0, %2}"
7406   [(set_attr "type" "imul")
7407    (set_attr "prefix_0f" "0,0,1")
7408    (set (attr "athlon_decode")
7409         (cond [(eq_attr "cpu" "athlon")
7410                   (const_string "vector")
7411                (eq_attr "alternative" "1")
7412                   (const_string "vector")
7413                (and (eq_attr "alternative" "2")
7414                     (match_operand 1 "memory_operand"))
7415                   (const_string "vector")]
7416               (const_string "direct")))
7417    (set (attr "amdfam10_decode")
7418         (cond [(and (eq_attr "alternative" "0,1")
7419                     (match_operand 1 "memory_operand"))
7420                   (const_string "vector")]
7421               (const_string "direct")))
7422    (set_attr "bdver1_decode" "direct")
7423    (set_attr "mode" "SI")])
7425 ;;On AMDFAM10 and BDVER1
7426 ;; MUL reg8     Direct
7427 ;; MUL mem8     Direct
7429 (define_insn "*mulqi3_1"
7430   [(set (match_operand:QI 0 "register_operand" "=a")
7431         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7432                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7433    (clobber (reg:CC FLAGS_REG))]
7434   "TARGET_QIMODE_MATH
7435    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7436   "mul{b}\t%2"
7437   [(set_attr "type" "imul")
7438    (set_attr "length_immediate" "0")
7439    (set (attr "athlon_decode")
7440      (if_then_else (eq_attr "cpu" "athlon")
7441         (const_string "vector")
7442         (const_string "direct")))
7443    (set_attr "amdfam10_decode" "direct")
7444    (set_attr "bdver1_decode" "direct")
7445    (set_attr "mode" "QI")])
7447 ;; Multiply with jump on overflow.
7448 (define_expand "mulv<mode>4"
7449   [(parallel [(set (reg:CCO FLAGS_REG)
7450                    (eq:CCO (mult:<DWI>
7451                               (sign_extend:<DWI>
7452                                  (match_operand:SWI248 1 "register_operand"))
7453                               (match_dup 4))
7454                            (sign_extend:<DWI>
7455                               (mult:SWI248 (match_dup 1)
7456                                            (match_operand:SWI248 2
7457                                               "<general_operand>")))))
7458               (set (match_operand:SWI248 0 "register_operand")
7459                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
7460    (set (pc) (if_then_else
7461                (eq (reg:CCO FLAGS_REG) (const_int 0))
7462                (label_ref (match_operand 3))
7463                (pc)))]
7464   ""
7466   if (CONST_INT_P (operands[2]))
7467     operands[4] = operands[2];
7468   else
7469     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7472 (define_insn "*mulv<mode>4"
7473   [(set (reg:CCO FLAGS_REG)
7474         (eq:CCO (mult:<DWI>
7475                    (sign_extend:<DWI>
7476                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7477                    (sign_extend:<DWI>
7478                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7479                 (sign_extend:<DWI>
7480                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
7481    (set (match_operand:SWI48 0 "register_operand" "=r,r")
7482         (mult:SWI48 (match_dup 1) (match_dup 2)))]
7483   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7484   "@
7485    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7486    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7487   [(set_attr "type" "imul")
7488    (set_attr "prefix_0f" "0,1")
7489    (set (attr "athlon_decode")
7490         (cond [(eq_attr "cpu" "athlon")
7491                   (const_string "vector")
7492                (eq_attr "alternative" "0")
7493                   (const_string "vector")
7494                (and (eq_attr "alternative" "1")
7495                     (match_operand 1 "memory_operand"))
7496                   (const_string "vector")]
7497               (const_string "direct")))
7498    (set (attr "amdfam10_decode")
7499         (cond [(and (eq_attr "alternative" "1")
7500                     (match_operand 1 "memory_operand"))
7501                   (const_string "vector")]
7502               (const_string "direct")))
7503    (set_attr "bdver1_decode" "direct")
7504    (set_attr "mode" "<MODE>")])
7506 (define_insn "*mulvhi4"
7507   [(set (reg:CCO FLAGS_REG)
7508         (eq:CCO (mult:SI
7509                    (sign_extend:SI
7510                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
7511                    (sign_extend:SI
7512                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
7513                 (sign_extend:SI
7514                    (mult:HI (match_dup 1) (match_dup 2)))))
7515    (set (match_operand:HI 0 "register_operand" "=r")
7516         (mult:HI (match_dup 1) (match_dup 2)))]
7517   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7518   "imul{w}\t{%2, %0|%0, %2}"
7519   [(set_attr "type" "imul")
7520    (set_attr "prefix_0f" "1")
7521    (set_attr "athlon_decode" "vector")
7522    (set_attr "amdfam10_decode" "direct")
7523    (set_attr "bdver1_decode" "double")
7524    (set_attr "mode" "HI")])
7526 (define_insn "*mulv<mode>4_1"
7527   [(set (reg:CCO FLAGS_REG)
7528         (eq:CCO (mult:<DWI>
7529                    (sign_extend:<DWI>
7530                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7531                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7532                 (sign_extend:<DWI>
7533                    (mult:SWI248 (match_dup 1)
7534                                 (match_operand:SWI248 2
7535                                    "<immediate_operand>" "K,<i>")))))
7536    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7537         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7538   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7539    && CONST_INT_P (operands[2])
7540    && INTVAL (operands[2]) == INTVAL (operands[3])"
7541   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7542   [(set_attr "type" "imul")
7543    (set (attr "prefix_0f")
7544         (if_then_else
7545           (match_test "<MODE>mode == HImode")
7546             (const_string "0")
7547             (const_string "*")))
7548    (set (attr "athlon_decode")
7549         (cond [(eq_attr "cpu" "athlon")
7550                   (const_string "vector")
7551                (eq_attr "alternative" "1")
7552                   (const_string "vector")]
7553               (const_string "direct")))
7554    (set (attr "amdfam10_decode")
7555         (cond [(ior (match_test "<MODE>mode == HImode")
7556                     (match_operand 1 "memory_operand"))
7557                   (const_string "vector")]
7558               (const_string "direct")))
7559    (set (attr "bdver1_decode")
7560         (if_then_else
7561           (match_test "<MODE>mode == HImode")
7562             (const_string "double")
7563             (const_string "direct")))
7564    (set_attr "mode" "<MODE>")
7565    (set (attr "length_immediate")
7566         (cond [(eq_attr "alternative" "0")
7567                   (const_string "1")
7568                (match_test "<MODE_SIZE> == 8")
7569                   (const_string "4")]
7570               (const_string "<MODE_SIZE>")))])
7572 (define_expand "umulv<mode>4"
7573   [(parallel [(set (reg:CCO FLAGS_REG)
7574                    (eq:CCO (mult:<DWI>
7575                               (zero_extend:<DWI>
7576                                  (match_operand:SWI248 1
7577                                                       "nonimmediate_operand"))
7578                               (zero_extend:<DWI>
7579                                  (match_operand:SWI248 2
7580                                                       "nonimmediate_operand")))
7581                            (zero_extend:<DWI>
7582                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7583               (set (match_operand:SWI248 0 "register_operand")
7584                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7585               (clobber (match_scratch:SWI248 4))])
7586    (set (pc) (if_then_else
7587                (eq (reg:CCO FLAGS_REG) (const_int 0))
7588                (label_ref (match_operand 3))
7589                (pc)))]
7590   ""
7592   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7593     operands[1] = force_reg (<MODE>mode, operands[1]);
7596 (define_insn "*umulv<mode>4"
7597   [(set (reg:CCO FLAGS_REG)
7598         (eq:CCO (mult:<DWI>
7599                    (zero_extend:<DWI>
7600                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7601                    (zero_extend:<DWI>
7602                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7603                 (zero_extend:<DWI>
7604                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7605    (set (match_operand:SWI248 0 "register_operand" "=a")
7606         (mult:SWI248 (match_dup 1) (match_dup 2)))
7607    (clobber (match_scratch:SWI248 3 "=d"))]
7608   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7609   "mul{<imodesuffix>}\t%2"
7610   [(set_attr "type" "imul")
7611    (set_attr "length_immediate" "0")
7612    (set (attr "athlon_decode")
7613      (if_then_else (eq_attr "cpu" "athlon")
7614        (const_string "vector")
7615        (const_string "double")))
7616    (set_attr "amdfam10_decode" "double")
7617    (set_attr "bdver1_decode" "direct")
7618    (set_attr "mode" "<MODE>")])
7620 (define_expand "<u>mulvqi4"
7621   [(parallel [(set (reg:CCO FLAGS_REG)
7622                    (eq:CCO (mult:HI
7623                               (any_extend:HI
7624                                  (match_operand:QI 1 "nonimmediate_operand"))
7625                               (any_extend:HI
7626                                  (match_operand:QI 2 "nonimmediate_operand")))
7627                            (any_extend:HI
7628                               (mult:QI (match_dup 1) (match_dup 2)))))
7629               (set (match_operand:QI 0 "register_operand")
7630                    (mult:QI (match_dup 1) (match_dup 2)))])
7631    (set (pc) (if_then_else
7632                (eq (reg:CCO FLAGS_REG) (const_int 0))
7633                (label_ref (match_operand 3))
7634                (pc)))]
7635   "TARGET_QIMODE_MATH"
7637   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7638     operands[1] = force_reg (QImode, operands[1]);
7641 (define_insn "*<u>mulvqi4"
7642   [(set (reg:CCO FLAGS_REG)
7643         (eq:CCO (mult:HI
7644                    (any_extend:HI
7645                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7646                    (any_extend:HI
7647                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7648                 (any_extend:HI
7649                    (mult:QI (match_dup 1) (match_dup 2)))))
7650    (set (match_operand:QI 0 "register_operand" "=a")
7651         (mult:QI (match_dup 1) (match_dup 2)))]
7652   "TARGET_QIMODE_MATH
7653    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7654   "<sgnprefix>mul{b}\t%2"
7655   [(set_attr "type" "imul")
7656    (set_attr "length_immediate" "0")
7657    (set (attr "athlon_decode")
7658      (if_then_else (eq_attr "cpu" "athlon")
7659         (const_string "vector")
7660         (const_string "direct")))
7661    (set_attr "amdfam10_decode" "direct")
7662    (set_attr "bdver1_decode" "direct")
7663    (set_attr "mode" "QI")])
7665 (define_expand "<u>mul<mode><dwi>3"
7666   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7667                    (mult:<DWI>
7668                      (any_extend:<DWI>
7669                        (match_operand:DWIH 1 "nonimmediate_operand"))
7670                      (any_extend:<DWI>
7671                        (match_operand:DWIH 2 "register_operand"))))
7672               (clobber (reg:CC FLAGS_REG))])])
7674 (define_expand "<u>mulqihi3"
7675   [(parallel [(set (match_operand:HI 0 "register_operand")
7676                    (mult:HI
7677                      (any_extend:HI
7678                        (match_operand:QI 1 "nonimmediate_operand"))
7679                      (any_extend:HI
7680                        (match_operand:QI 2 "register_operand"))))
7681               (clobber (reg:CC FLAGS_REG))])]
7682   "TARGET_QIMODE_MATH")
7684 (define_insn "*bmi2_umul<mode><dwi>3_1"
7685   [(set (match_operand:DWIH 0 "register_operand" "=r")
7686         (mult:DWIH
7687           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7688           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7689    (set (match_operand:DWIH 1 "register_operand" "=r")
7690         (truncate:DWIH
7691           (lshiftrt:<DWI>
7692             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7693                         (zero_extend:<DWI> (match_dup 3)))
7694             (match_operand:QI 4 "const_int_operand" "n"))))]
7695   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7696    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7697   "mulx\t{%3, %0, %1|%1, %0, %3}"
7698   [(set_attr "type" "imulx")
7699    (set_attr "prefix" "vex")
7700    (set_attr "mode" "<MODE>")])
7702 (define_insn "*umul<mode><dwi>3_1"
7703   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7704         (mult:<DWI>
7705           (zero_extend:<DWI>
7706             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7707           (zero_extend:<DWI>
7708             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7709    (clobber (reg:CC FLAGS_REG))]
7710   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7711   "@
7712    #
7713    mul{<imodesuffix>}\t%2"
7714   [(set_attr "isa" "bmi2,*")
7715    (set_attr "type" "imulx,imul")
7716    (set_attr "length_immediate" "*,0")
7717    (set (attr "athlon_decode")
7718         (cond [(eq_attr "alternative" "1")
7719                  (if_then_else (eq_attr "cpu" "athlon")
7720                    (const_string "vector")
7721                    (const_string "double"))]
7722               (const_string "*")))
7723    (set_attr "amdfam10_decode" "*,double")
7724    (set_attr "bdver1_decode" "*,direct")
7725    (set_attr "prefix" "vex,orig")
7726    (set_attr "mode" "<MODE>")])
7728 ;; Convert mul to the mulx pattern to avoid flags dependency.
7729 (define_split
7730  [(set (match_operand:<DWI> 0 "register_operand")
7731        (mult:<DWI>
7732          (zero_extend:<DWI>
7733            (match_operand:DWIH 1 "register_operand"))
7734          (zero_extend:<DWI>
7735            (match_operand:DWIH 2 "nonimmediate_operand"))))
7736   (clobber (reg:CC FLAGS_REG))]
7737  "TARGET_BMI2 && reload_completed
7738   && REGNO (operands[1]) == DX_REG"
7739   [(parallel [(set (match_dup 3)
7740                    (mult:DWIH (match_dup 1) (match_dup 2)))
7741               (set (match_dup 4)
7742                    (truncate:DWIH
7743                      (lshiftrt:<DWI>
7744                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7745                                    (zero_extend:<DWI> (match_dup 2)))
7746                        (match_dup 5))))])]
7748   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7750   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7753 (define_insn "*mul<mode><dwi>3_1"
7754   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7755         (mult:<DWI>
7756           (sign_extend:<DWI>
7757             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7758           (sign_extend:<DWI>
7759             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7760    (clobber (reg:CC FLAGS_REG))]
7761   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7762   "imul{<imodesuffix>}\t%2"
7763   [(set_attr "type" "imul")
7764    (set_attr "length_immediate" "0")
7765    (set (attr "athlon_decode")
7766      (if_then_else (eq_attr "cpu" "athlon")
7767         (const_string "vector")
7768         (const_string "double")))
7769    (set_attr "amdfam10_decode" "double")
7770    (set_attr "bdver1_decode" "direct")
7771    (set_attr "mode" "<MODE>")])
7773 (define_insn "*<u>mulqihi3_1"
7774   [(set (match_operand:HI 0 "register_operand" "=a")
7775         (mult:HI
7776           (any_extend:HI
7777             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7778           (any_extend:HI
7779             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7780    (clobber (reg:CC FLAGS_REG))]
7781   "TARGET_QIMODE_MATH
7782    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7783   "<sgnprefix>mul{b}\t%2"
7784   [(set_attr "type" "imul")
7785    (set_attr "length_immediate" "0")
7786    (set (attr "athlon_decode")
7787      (if_then_else (eq_attr "cpu" "athlon")
7788         (const_string "vector")
7789         (const_string "direct")))
7790    (set_attr "amdfam10_decode" "direct")
7791    (set_attr "bdver1_decode" "direct")
7792    (set_attr "mode" "QI")])
7794 (define_expand "<s>mul<mode>3_highpart"
7795   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7796                    (truncate:SWI48
7797                      (lshiftrt:<DWI>
7798                        (mult:<DWI>
7799                          (any_extend:<DWI>
7800                            (match_operand:SWI48 1 "nonimmediate_operand"))
7801                          (any_extend:<DWI>
7802                            (match_operand:SWI48 2 "register_operand")))
7803                        (match_dup 3))))
7804               (clobber (match_scratch:SWI48 4))
7805               (clobber (reg:CC FLAGS_REG))])]
7806   ""
7807   "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7809 (define_insn "*<s>muldi3_highpart_1"
7810   [(set (match_operand:DI 0 "register_operand" "=d")
7811         (truncate:DI
7812           (lshiftrt:TI
7813             (mult:TI
7814               (any_extend:TI
7815                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7816               (any_extend:TI
7817                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7818             (const_int 64))))
7819    (clobber (match_scratch:DI 3 "=1"))
7820    (clobber (reg:CC FLAGS_REG))]
7821   "TARGET_64BIT
7822    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7823   "<sgnprefix>mul{q}\t%2"
7824   [(set_attr "type" "imul")
7825    (set_attr "length_immediate" "0")
7826    (set (attr "athlon_decode")
7827      (if_then_else (eq_attr "cpu" "athlon")
7828         (const_string "vector")
7829         (const_string "double")))
7830    (set_attr "amdfam10_decode" "double")
7831    (set_attr "bdver1_decode" "direct")
7832    (set_attr "mode" "DI")])
7834 (define_insn "*<s>mulsi3_highpart_zext"
7835   [(set (match_operand:DI 0 "register_operand" "=d")
7836         (zero_extend:DI (truncate:SI
7837           (lshiftrt:DI
7838             (mult:DI (any_extend:DI
7839                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7840                      (any_extend:DI
7841                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7842             (const_int 32)))))
7843    (clobber (match_scratch:SI 3 "=1"))
7844    (clobber (reg:CC FLAGS_REG))]
7845   "TARGET_64BIT
7846    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7847   "<sgnprefix>mul{l}\t%2"
7848   [(set_attr "type" "imul")
7849    (set_attr "length_immediate" "0")
7850    (set (attr "athlon_decode")
7851      (if_then_else (eq_attr "cpu" "athlon")
7852         (const_string "vector")
7853         (const_string "double")))
7854    (set_attr "amdfam10_decode" "double")
7855    (set_attr "bdver1_decode" "direct")
7856    (set_attr "mode" "SI")])
7858 (define_insn "*<s>mulsi3_highpart_1"
7859   [(set (match_operand:SI 0 "register_operand" "=d")
7860         (truncate:SI
7861           (lshiftrt:DI
7862             (mult:DI
7863               (any_extend:DI
7864                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7865               (any_extend:DI
7866                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7867             (const_int 32))))
7868    (clobber (match_scratch:SI 3 "=1"))
7869    (clobber (reg:CC FLAGS_REG))]
7870   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7871   "<sgnprefix>mul{l}\t%2"
7872   [(set_attr "type" "imul")
7873    (set_attr "length_immediate" "0")
7874    (set (attr "athlon_decode")
7875      (if_then_else (eq_attr "cpu" "athlon")
7876         (const_string "vector")
7877         (const_string "double")))
7878    (set_attr "amdfam10_decode" "double")
7879    (set_attr "bdver1_decode" "direct")
7880    (set_attr "mode" "SI")])
7882 ;; The patterns that match these are at the end of this file.
7884 (define_expand "mulxf3"
7885   [(set (match_operand:XF 0 "register_operand")
7886         (mult:XF (match_operand:XF 1 "register_operand")
7887                  (match_operand:XF 2 "register_operand")))]
7888   "TARGET_80387")
7890 (define_expand "mul<mode>3"
7891   [(set (match_operand:MODEF 0 "register_operand")
7892         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7893                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7894   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7895     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7897 ;; Divide instructions
7899 ;; The patterns that match these are at the end of this file.
7901 (define_expand "divxf3"
7902   [(set (match_operand:XF 0 "register_operand")
7903         (div:XF (match_operand:XF 1 "register_operand")
7904                 (match_operand:XF 2 "register_operand")))]
7905   "TARGET_80387")
7907 (define_expand "div<mode>3"
7908   [(set (match_operand:MODEF 0 "register_operand")
7909         (div:MODEF (match_operand:MODEF 1 "register_operand")
7910                    (match_operand:MODEF 2 "nonimmediate_operand")))]
7911   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7912     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7914   if (<MODE>mode == SFmode
7915       && TARGET_SSE && TARGET_SSE_MATH
7916       && TARGET_RECIP_DIV
7917       && optimize_insn_for_speed_p ()
7918       && flag_finite_math_only && !flag_trapping_math
7919       && flag_unsafe_math_optimizations)
7920     {
7921       ix86_emit_swdivsf (operands[0], operands[1],
7922                          operands[2], SFmode);
7923       DONE;
7924     }
7927 ;; Divmod instructions.
7929 (define_expand "divmod<mode>4"
7930   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7931                    (div:SWIM248
7932                      (match_operand:SWIM248 1 "register_operand")
7933                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7934               (set (match_operand:SWIM248 3 "register_operand")
7935                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7936               (clobber (reg:CC FLAGS_REG))])])
7938 ;; Split with 8bit unsigned divide:
7939 ;;      if (dividend an divisor are in [0-255])
7940 ;;         use 8bit unsigned integer divide
7941 ;;       else
7942 ;;         use original integer divide
7943 (define_split
7944   [(set (match_operand:SWI48 0 "register_operand")
7945         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7946                     (match_operand:SWI48 3 "nonimmediate_operand")))
7947    (set (match_operand:SWI48 1 "register_operand")
7948         (mod:SWI48 (match_dup 2) (match_dup 3)))
7949    (clobber (reg:CC FLAGS_REG))]
7950   "TARGET_USE_8BIT_IDIV
7951    && TARGET_QIMODE_MATH
7952    && can_create_pseudo_p ()
7953    && !optimize_insn_for_size_p ()"
7954   [(const_int 0)]
7955   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7957 (define_split
7958   [(set (match_operand:DI 0 "register_operand")
7959         (zero_extend:DI
7960           (div:SI (match_operand:SI 2 "register_operand")
7961                   (match_operand:SI 3 "nonimmediate_operand"))))
7962    (set (match_operand:SI 1 "register_operand")
7963         (mod:SI (match_dup 2) (match_dup 3)))
7964    (clobber (reg:CC FLAGS_REG))]
7965   "TARGET_USE_8BIT_IDIV
7966    && TARGET_QIMODE_MATH
7967    && can_create_pseudo_p ()
7968    && !optimize_insn_for_size_p ()"
7969   [(const_int 0)]
7970   "ix86_split_idivmod (SImode, operands, true); DONE;")
7972 (define_split
7973   [(set (match_operand:DI 1 "register_operand")
7974         (zero_extend:DI
7975           (mod:SI (match_operand:SI 2 "register_operand")
7976                   (match_operand:SI 3 "nonimmediate_operand"))))
7977    (set (match_operand:SI 0 "register_operand")
7978         (div:SI  (match_dup 2) (match_dup 3)))
7979    (clobber (reg:CC FLAGS_REG))]
7980   "TARGET_USE_8BIT_IDIV
7981    && TARGET_QIMODE_MATH
7982    && can_create_pseudo_p ()
7983    && !optimize_insn_for_size_p ()"
7984   [(const_int 0)]
7985   "ix86_split_idivmod (SImode, operands, true); DONE;")
7987 (define_insn_and_split "divmod<mode>4_1"
7988   [(set (match_operand:SWI48 0 "register_operand" "=a")
7989         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7990                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7991    (set (match_operand:SWI48 1 "register_operand" "=&d")
7992         (mod:SWI48 (match_dup 2) (match_dup 3)))
7993    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7994    (clobber (reg:CC FLAGS_REG))]
7995   ""
7996   "#"
7997   "reload_completed"
7998   [(parallel [(set (match_dup 1)
7999                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
8000               (clobber (reg:CC FLAGS_REG))])
8001    (parallel [(set (match_dup 0)
8002                    (div:SWI48 (match_dup 2) (match_dup 3)))
8003               (set (match_dup 1)
8004                    (mod:SWI48 (match_dup 2) (match_dup 3)))
8005               (use (match_dup 1))
8006               (clobber (reg:CC FLAGS_REG))])]
8008   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8010   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8011     operands[4] = operands[2];
8012   else
8013     {
8014       /* Avoid use of cltd in favor of a mov+shift.  */
8015       emit_move_insn (operands[1], operands[2]);
8016       operands[4] = operands[1];
8017     }
8019   [(set_attr "type" "multi")
8020    (set_attr "mode" "<MODE>")])
8022 (define_insn_and_split "divmodsi4_zext_1"
8023   [(set (match_operand:DI 0 "register_operand" "=a")
8024         (zero_extend:DI
8025           (div:SI (match_operand:SI 2 "register_operand" "0")
8026                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8027    (set (match_operand:SI 1 "register_operand" "=&d")
8028         (mod:SI (match_dup 2) (match_dup 3)))
8029    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8030    (clobber (reg:CC FLAGS_REG))]
8031   "TARGET_64BIT"
8032   "#"
8033   "reload_completed"
8034   [(parallel [(set (match_dup 1)
8035                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8036               (clobber (reg:CC FLAGS_REG))])
8037    (parallel [(set (match_dup 0)
8038                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8039               (set (match_dup 1)
8040                    (mod:SI (match_dup 2) (match_dup 3)))
8041               (use (match_dup 1))
8042               (clobber (reg:CC FLAGS_REG))])]
8044   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8046   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8047     operands[4] = operands[2];
8048   else
8049     {
8050       /* Avoid use of cltd in favor of a mov+shift.  */
8051       emit_move_insn (operands[1], operands[2]);
8052       operands[4] = operands[1];
8053     }
8055   [(set_attr "type" "multi")
8056    (set_attr "mode" "SI")])
8058 (define_insn_and_split "divmodsi4_zext_2"
8059   [(set (match_operand:DI 1 "register_operand" "=&d")
8060         (zero_extend:DI
8061           (mod:SI (match_operand:SI 2 "register_operand" "0")
8062                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8063    (set (match_operand:SI 0 "register_operand" "=a")
8064         (div:SI (match_dup 2) (match_dup 3)))
8065    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8066    (clobber (reg:CC FLAGS_REG))]
8067   "TARGET_64BIT"
8068   "#"
8069   "reload_completed"
8070   [(parallel [(set (match_dup 6)
8071                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8072               (clobber (reg:CC FLAGS_REG))])
8073    (parallel [(set (match_dup 1)
8074                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8075               (set (match_dup 0)
8076                    (div:SI (match_dup 2) (match_dup 3)))
8077               (use (match_dup 6))
8078               (clobber (reg:CC FLAGS_REG))])]
8080   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8081   operands[6] = gen_lowpart (SImode, operands[1]);
8083   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8084     operands[4] = operands[2];
8085   else
8086     {
8087       /* Avoid use of cltd in favor of a mov+shift.  */
8088       emit_move_insn (operands[6], operands[2]);
8089       operands[4] = operands[6];
8090     }
8092   [(set_attr "type" "multi")
8093    (set_attr "mode" "SI")])
8095 (define_insn_and_split "*divmod<mode>4"
8096   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8097         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8098                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8099    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8100         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8101    (clobber (reg:CC FLAGS_REG))]
8102   ""
8103   "#"
8104   "reload_completed"
8105   [(parallel [(set (match_dup 1)
8106                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8107               (clobber (reg:CC FLAGS_REG))])
8108    (parallel [(set (match_dup 0)
8109                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8110               (set (match_dup 1)
8111                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8112               (use (match_dup 1))
8113               (clobber (reg:CC FLAGS_REG))])]
8115   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8117   if (<MODE>mode != HImode
8118       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8119     operands[4] = operands[2];
8120   else
8121     {
8122       /* Avoid use of cltd in favor of a mov+shift.  */
8123       emit_move_insn (operands[1], operands[2]);
8124       operands[4] = operands[1];
8125     }
8127   [(set_attr "type" "multi")
8128    (set_attr "mode" "<MODE>")])
8130 (define_insn_and_split "*divmodsi4_zext_1"
8131   [(set (match_operand:DI 0 "register_operand" "=a")
8132         (zero_extend:DI
8133           (div:SI (match_operand:SI 2 "register_operand" "0")
8134                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8135    (set (match_operand:SI 1 "register_operand" "=&d")
8136         (mod:SI (match_dup 2) (match_dup 3)))
8137    (clobber (reg:CC FLAGS_REG))]
8138   "TARGET_64BIT"
8139   "#"
8140   "reload_completed"
8141   [(parallel [(set (match_dup 1)
8142                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8143               (clobber (reg:CC FLAGS_REG))])
8144    (parallel [(set (match_dup 0)
8145                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8146               (set (match_dup 1)
8147                    (mod:SI (match_dup 2) (match_dup 3)))
8148               (use (match_dup 1))
8149               (clobber (reg:CC FLAGS_REG))])]
8151   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8153   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8154     operands[4] = operands[2];
8155   else
8156     {
8157       /* Avoid use of cltd in favor of a mov+shift.  */
8158       emit_move_insn (operands[1], operands[2]);
8159       operands[4] = operands[1];
8160     }
8162   [(set_attr "type" "multi")
8163    (set_attr "mode" "SI")])
8165 (define_insn_and_split "*divmodsi4_zext_2"
8166   [(set (match_operand:DI 1 "register_operand" "=&d")
8167         (zero_extend:DI
8168           (mod:SI (match_operand:SI 2 "register_operand" "0")
8169                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8170    (set (match_operand:SI 0 "register_operand" "=a")
8171         (div:SI (match_dup 2) (match_dup 3)))
8172    (clobber (reg:CC FLAGS_REG))]
8173   "TARGET_64BIT"
8174   "#"
8175   "reload_completed"
8176   [(parallel [(set (match_dup 6)
8177                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8178               (clobber (reg:CC FLAGS_REG))])
8179    (parallel [(set (match_dup 1)
8180                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8181               (set (match_dup 0)
8182                    (div:SI (match_dup 2) (match_dup 3)))
8183               (use (match_dup 6))
8184               (clobber (reg:CC FLAGS_REG))])]
8186   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8187   operands[6] = gen_lowpart (SImode, operands[1]);
8189   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8190     operands[4] = operands[2];
8191   else
8192     {
8193       /* Avoid use of cltd in favor of a mov+shift.  */
8194       emit_move_insn (operands[6], operands[2]);
8195       operands[4] = operands[6];
8196     }
8198   [(set_attr "type" "multi")
8199    (set_attr "mode" "SI")])
8201 (define_insn "*divmod<mode>4_noext"
8202   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8203         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8204                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8205    (set (match_operand:SWIM248 1 "register_operand" "=d")
8206         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8207    (use (match_operand:SWIM248 4 "register_operand" "1"))
8208    (clobber (reg:CC FLAGS_REG))]
8209   ""
8210   "idiv{<imodesuffix>}\t%3"
8211   [(set_attr "type" "idiv")
8212    (set_attr "mode" "<MODE>")])
8214 (define_insn "*divmodsi4_noext_zext_1"
8215   [(set (match_operand:DI 0 "register_operand" "=a")
8216         (zero_extend:DI
8217           (div:SI (match_operand:SI 2 "register_operand" "0")
8218                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8219    (set (match_operand:SI 1 "register_operand" "=d")
8220         (mod:SI (match_dup 2) (match_dup 3)))
8221    (use (match_operand:SI 4 "register_operand" "1"))
8222    (clobber (reg:CC FLAGS_REG))]
8223   "TARGET_64BIT"
8224   "idiv{l}\t%3"
8225   [(set_attr "type" "idiv")
8226    (set_attr "mode" "SI")])
8228 (define_insn "*divmodsi4_noext_zext_2"
8229   [(set (match_operand:DI 1 "register_operand" "=d")
8230         (zero_extend:DI
8231           (mod:SI (match_operand:SI 2 "register_operand" "0")
8232                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8233    (set (match_operand:SI 0 "register_operand" "=a")
8234         (div:SI (match_dup 2) (match_dup 3)))
8235    (use (match_operand:SI 4 "register_operand" "1"))
8236    (clobber (reg:CC FLAGS_REG))]
8237   "TARGET_64BIT"
8238   "idiv{l}\t%3"
8239   [(set_attr "type" "idiv")
8240    (set_attr "mode" "SI")])
8242 (define_expand "divmodqi4"
8243   [(parallel [(set (match_operand:QI 0 "register_operand")
8244                    (div:QI
8245                      (match_operand:QI 1 "register_operand")
8246                      (match_operand:QI 2 "nonimmediate_operand")))
8247               (set (match_operand:QI 3 "register_operand")
8248                    (mod:QI (match_dup 1) (match_dup 2)))
8249               (clobber (reg:CC FLAGS_REG))])]
8250   "TARGET_QIMODE_MATH"
8252   rtx div, mod;
8253   rtx tmp0, tmp1;
8254   
8255   tmp0 = gen_reg_rtx (HImode);
8256   tmp1 = gen_reg_rtx (HImode);
8258   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8259   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8260   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8262   /* Extract remainder from AH.  */
8263   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8264   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8265   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8267   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8268   set_unique_reg_note (insn, REG_EQUAL, mod);
8270   /* Extract quotient from AL.  */
8271   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8273   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8274   set_unique_reg_note (insn, REG_EQUAL, div);
8276   DONE;
8279 ;; Divide AX by r/m8, with result stored in
8280 ;; AL <- Quotient
8281 ;; AH <- Remainder
8282 ;; Change div/mod to HImode and extend the second argument to HImode
8283 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
8284 ;; combine may fail.
8285 (define_insn "divmodhiqi3"
8286   [(set (match_operand:HI 0 "register_operand" "=a")
8287         (ior:HI
8288           (ashift:HI
8289             (zero_extend:HI
8290               (truncate:QI
8291                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8292                         (sign_extend:HI
8293                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8294             (const_int 8))
8295           (zero_extend:HI
8296             (truncate:QI
8297               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8298    (clobber (reg:CC FLAGS_REG))]
8299   "TARGET_QIMODE_MATH"
8300   "idiv{b}\t%2"
8301   [(set_attr "type" "idiv")
8302    (set_attr "mode" "QI")])
8304 (define_expand "udivmod<mode>4"
8305   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8306                    (udiv:SWIM248
8307                      (match_operand:SWIM248 1 "register_operand")
8308                      (match_operand:SWIM248 2 "nonimmediate_operand")))
8309               (set (match_operand:SWIM248 3 "register_operand")
8310                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8311               (clobber (reg:CC FLAGS_REG))])])
8313 ;; Split with 8bit unsigned divide:
8314 ;;      if (dividend an divisor are in [0-255])
8315 ;;         use 8bit unsigned integer divide
8316 ;;       else
8317 ;;         use original integer divide
8318 (define_split
8319   [(set (match_operand:SWI48 0 "register_operand")
8320         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8321                     (match_operand:SWI48 3 "nonimmediate_operand")))
8322    (set (match_operand:SWI48 1 "register_operand")
8323         (umod:SWI48 (match_dup 2) (match_dup 3)))
8324    (clobber (reg:CC FLAGS_REG))]
8325   "TARGET_USE_8BIT_IDIV
8326    && TARGET_QIMODE_MATH
8327    && can_create_pseudo_p ()
8328    && !optimize_insn_for_size_p ()"
8329   [(const_int 0)]
8330   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8332 (define_split
8333   [(set (match_operand:DI 0 "register_operand")
8334         (zero_extend:DI
8335           (udiv:SI (match_operand:SI 2 "register_operand")
8336                    (match_operand:SI 3 "nonimmediate_operand"))))
8337    (set (match_operand:SI 1 "register_operand")
8338         (umod:SI (match_dup 2) (match_dup 3)))
8339    (clobber (reg:CC FLAGS_REG))]
8340   "TARGET_64BIT
8341    && TARGET_USE_8BIT_IDIV
8342    && TARGET_QIMODE_MATH
8343    && can_create_pseudo_p ()
8344    && !optimize_insn_for_size_p ()"
8345   [(const_int 0)]
8346   "ix86_split_idivmod (SImode, operands, false); DONE;")
8348 (define_split
8349   [(set (match_operand:DI 1 "register_operand")
8350         (zero_extend:DI
8351           (umod:SI (match_operand:SI 2 "register_operand")
8352                    (match_operand:SI 3 "nonimmediate_operand"))))
8353    (set (match_operand:SI 0 "register_operand")
8354         (udiv:SI (match_dup 2) (match_dup 3)))
8355    (clobber (reg:CC FLAGS_REG))]
8356   "TARGET_64BIT
8357    && TARGET_USE_8BIT_IDIV
8358    && TARGET_QIMODE_MATH
8359    && can_create_pseudo_p ()
8360    && !optimize_insn_for_size_p ()"
8361   [(const_int 0)]
8362   "ix86_split_idivmod (SImode, operands, false); DONE;")
8364 (define_insn_and_split "udivmod<mode>4_1"
8365   [(set (match_operand:SWI48 0 "register_operand" "=a")
8366         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8367                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8368    (set (match_operand:SWI48 1 "register_operand" "=&d")
8369         (umod:SWI48 (match_dup 2) (match_dup 3)))
8370    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8371    (clobber (reg:CC FLAGS_REG))]
8372   ""
8373   "#"
8374   "reload_completed"
8375   [(set (match_dup 1) (const_int 0))
8376    (parallel [(set (match_dup 0)
8377                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
8378               (set (match_dup 1)
8379                    (umod:SWI48 (match_dup 2) (match_dup 3)))
8380               (use (match_dup 1))
8381               (clobber (reg:CC FLAGS_REG))])]
8382   ""
8383   [(set_attr "type" "multi")
8384    (set_attr "mode" "<MODE>")])
8386 (define_insn_and_split "udivmodsi4_zext_1"
8387   [(set (match_operand:DI 0 "register_operand" "=a")
8388         (zero_extend:DI
8389           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8390                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8391    (set (match_operand:SI 1 "register_operand" "=&d")
8392         (umod:SI (match_dup 2) (match_dup 3)))
8393    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8394    (clobber (reg:CC FLAGS_REG))]
8395   "TARGET_64BIT"
8396   "#"
8397   "reload_completed"
8398   [(set (match_dup 1) (const_int 0))
8399    (parallel [(set (match_dup 0)
8400                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8401               (set (match_dup 1)
8402                    (umod:SI (match_dup 2) (match_dup 3)))
8403               (use (match_dup 1))
8404               (clobber (reg:CC FLAGS_REG))])]
8405   ""
8406   [(set_attr "type" "multi")
8407    (set_attr "mode" "SI")])
8409 (define_insn_and_split "udivmodsi4_zext_2"
8410   [(set (match_operand:DI 1 "register_operand" "=&d")
8411         (zero_extend:DI
8412           (umod:SI (match_operand:SI 2 "register_operand" "0")
8413                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8414    (set (match_operand:SI 0 "register_operand" "=a")
8415         (udiv:SI (match_dup 2) (match_dup 3)))
8416    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8417    (clobber (reg:CC FLAGS_REG))]
8418   "TARGET_64BIT"
8419   "#"
8420   "reload_completed"
8421   [(set (match_dup 4) (const_int 0))
8422    (parallel [(set (match_dup 1)
8423                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8424               (set (match_dup 0)
8425                    (udiv:SI (match_dup 2) (match_dup 3)))
8426               (use (match_dup 4))
8427               (clobber (reg:CC FLAGS_REG))])]
8428   "operands[4] = gen_lowpart (SImode, operands[1]);"
8429   [(set_attr "type" "multi")
8430    (set_attr "mode" "SI")])
8432 (define_insn_and_split "*udivmod<mode>4"
8433   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8434         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8435                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8436    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8437         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8438    (clobber (reg:CC FLAGS_REG))]
8439   ""
8440   "#"
8441   "reload_completed"
8442   [(set (match_dup 1) (const_int 0))
8443    (parallel [(set (match_dup 0)
8444                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8445               (set (match_dup 1)
8446                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8447               (use (match_dup 1))
8448               (clobber (reg:CC FLAGS_REG))])]
8449   ""
8450   [(set_attr "type" "multi")
8451    (set_attr "mode" "<MODE>")])
8453 (define_insn_and_split "*udivmodsi4_zext_1"
8454   [(set (match_operand:DI 0 "register_operand" "=a")
8455         (zero_extend:DI
8456           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8457                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8458    (set (match_operand:SI 1 "register_operand" "=&d")
8459         (umod:SI (match_dup 2) (match_dup 3)))
8460    (clobber (reg:CC FLAGS_REG))]
8461   "TARGET_64BIT"
8462   "#"
8463   "reload_completed"
8464   [(set (match_dup 1) (const_int 0))
8465    (parallel [(set (match_dup 0)
8466                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8467               (set (match_dup 1)
8468                    (umod:SI (match_dup 2) (match_dup 3)))
8469               (use (match_dup 1))
8470               (clobber (reg:CC FLAGS_REG))])]
8471   ""
8472   [(set_attr "type" "multi")
8473    (set_attr "mode" "SI")])
8475 (define_insn_and_split "*udivmodsi4_zext_2"
8476   [(set (match_operand:DI 1 "register_operand" "=&d")
8477         (zero_extend:DI
8478           (umod:SI (match_operand:SI 2 "register_operand" "0")
8479                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8480    (set (match_operand:SI 0 "register_operand" "=a")
8481         (udiv:SI (match_dup 2) (match_dup 3)))
8482    (clobber (reg:CC FLAGS_REG))]
8483   "TARGET_64BIT"
8484   "#"
8485   "reload_completed"
8486   [(set (match_dup 4) (const_int 0))
8487    (parallel [(set (match_dup 1)
8488                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8489               (set (match_dup 0)
8490                    (udiv:SI (match_dup 2) (match_dup 3)))
8491               (use (match_dup 4))
8492               (clobber (reg:CC FLAGS_REG))])]
8493   "operands[4] = gen_lowpart (SImode, operands[1]);"
8494   [(set_attr "type" "multi")
8495    (set_attr "mode" "SI")])
8497 ;; Optimize division or modulo by constant power of 2, if the constant
8498 ;; materializes only after expansion.
8499 (define_insn_and_split "*udivmod<mode>4_pow2"
8500   [(set (match_operand:SWI48 0 "register_operand" "=r")
8501         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8502                     (match_operand:SWI48 3 "const_int_operand" "n")))
8503    (set (match_operand:SWI48 1 "register_operand" "=r")
8504         (umod:SWI48 (match_dup 2) (match_dup 3)))
8505    (clobber (reg:CC FLAGS_REG))]
8506   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8507    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8508   "#"
8509   "&& 1"
8510   [(set (match_dup 1) (match_dup 2))
8511    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8512               (clobber (reg:CC FLAGS_REG))])
8513    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8514               (clobber (reg:CC FLAGS_REG))])]
8516   int v = exact_log2 (UINTVAL (operands[3]));
8517   operands[4] = GEN_INT (v);
8518   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8520   [(set_attr "type" "multi")
8521    (set_attr "mode" "<MODE>")])
8523 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8524   [(set (match_operand:DI 0 "register_operand" "=r")
8525         (zero_extend:DI
8526           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8527                    (match_operand:SI 3 "const_int_operand" "n"))))
8528    (set (match_operand:SI 1 "register_operand" "=r")
8529         (umod:SI (match_dup 2) (match_dup 3)))
8530    (clobber (reg:CC FLAGS_REG))]
8531   "TARGET_64BIT
8532    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8533    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8534   "#"
8535   "&& 1"
8536   [(set (match_dup 1) (match_dup 2))
8537    (parallel [(set (match_dup 0)
8538                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8539               (clobber (reg:CC FLAGS_REG))])
8540    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8541               (clobber (reg:CC FLAGS_REG))])]
8543   int v = exact_log2 (UINTVAL (operands[3]));
8544   operands[4] = GEN_INT (v);
8545   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8547   [(set_attr "type" "multi")
8548    (set_attr "mode" "SI")])
8550 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8551   [(set (match_operand:DI 1 "register_operand" "=r")
8552         (zero_extend:DI
8553           (umod:SI (match_operand:SI 2 "register_operand" "0")
8554                    (match_operand:SI 3 "const_int_operand" "n"))))
8555    (set (match_operand:SI 0 "register_operand" "=r")
8556         (umod:SI (match_dup 2) (match_dup 3)))
8557    (clobber (reg:CC FLAGS_REG))]
8558   "TARGET_64BIT
8559    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8560    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8561   "#"
8562   "&& 1"
8563   [(set (match_dup 1) (match_dup 2))
8564    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8565               (clobber (reg:CC FLAGS_REG))])
8566    (parallel [(set (match_dup 1)
8567                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8568               (clobber (reg:CC FLAGS_REG))])]
8570   int v = exact_log2 (UINTVAL (operands[3]));
8571   operands[4] = GEN_INT (v);
8572   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8574   [(set_attr "type" "multi")
8575    (set_attr "mode" "SI")])
8577 (define_insn "*udivmod<mode>4_noext"
8578   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8579         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8580                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8581    (set (match_operand:SWIM248 1 "register_operand" "=d")
8582         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8583    (use (match_operand:SWIM248 4 "register_operand" "1"))
8584    (clobber (reg:CC FLAGS_REG))]
8585   ""
8586   "div{<imodesuffix>}\t%3"
8587   [(set_attr "type" "idiv")
8588    (set_attr "mode" "<MODE>")])
8590 (define_insn "*udivmodsi4_noext_zext_1"
8591   [(set (match_operand:DI 0 "register_operand" "=a")
8592         (zero_extend:DI
8593           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8594                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8595    (set (match_operand:SI 1 "register_operand" "=d")
8596         (umod:SI (match_dup 2) (match_dup 3)))
8597    (use (match_operand:SI 4 "register_operand" "1"))
8598    (clobber (reg:CC FLAGS_REG))]
8599   "TARGET_64BIT"
8600   "div{l}\t%3"
8601   [(set_attr "type" "idiv")
8602    (set_attr "mode" "SI")])
8604 (define_insn "*udivmodsi4_noext_zext_2"
8605   [(set (match_operand:DI 1 "register_operand" "=d")
8606         (zero_extend:DI
8607           (umod:SI (match_operand:SI 2 "register_operand" "0")
8608                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8609    (set (match_operand:SI 0 "register_operand" "=a")
8610         (udiv:SI (match_dup 2) (match_dup 3)))
8611    (use (match_operand:SI 4 "register_operand" "1"))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "TARGET_64BIT"
8614   "div{l}\t%3"
8615   [(set_attr "type" "idiv")
8616    (set_attr "mode" "SI")])
8618 (define_expand "udivmodqi4"
8619   [(parallel [(set (match_operand:QI 0 "register_operand")
8620                    (udiv:QI
8621                      (match_operand:QI 1 "register_operand")
8622                      (match_operand:QI 2 "nonimmediate_operand")))
8623               (set (match_operand:QI 3 "register_operand")
8624                    (umod:QI (match_dup 1) (match_dup 2)))
8625               (clobber (reg:CC FLAGS_REG))])]
8626   "TARGET_QIMODE_MATH"
8628   rtx div, mod;
8629   rtx tmp0, tmp1;
8630   
8631   tmp0 = gen_reg_rtx (HImode);
8632   tmp1 = gen_reg_rtx (HImode);
8634   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8635   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8636   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8638   /* Extract remainder from AH.  */
8639   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8640   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8641   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8643   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8644   set_unique_reg_note (insn, REG_EQUAL, mod);
8646   /* Extract quotient from AL.  */
8647   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8649   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8650   set_unique_reg_note (insn, REG_EQUAL, div);
8652   DONE;
8655 (define_insn "udivmodhiqi3"
8656   [(set (match_operand:HI 0 "register_operand" "=a")
8657         (ior:HI
8658           (ashift:HI
8659             (zero_extend:HI
8660               (truncate:QI
8661                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8662                         (zero_extend:HI
8663                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8664             (const_int 8))
8665           (zero_extend:HI
8666             (truncate:QI
8667               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8668    (clobber (reg:CC FLAGS_REG))]
8669   "TARGET_QIMODE_MATH"
8670   "div{b}\t%2"
8671   [(set_attr "type" "idiv")
8672    (set_attr "mode" "QI")])
8674 ;; We cannot use div/idiv for double division, because it causes
8675 ;; "division by zero" on the overflow and that's not what we expect
8676 ;; from truncate.  Because true (non truncating) double division is
8677 ;; never generated, we can't create this insn anyway.
8679 ;(define_insn ""
8680 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8681 ;       (truncate:SI
8682 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8683 ;                  (zero_extend:DI
8684 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8685 ;   (set (match_operand:SI 3 "register_operand" "=d")
8686 ;       (truncate:SI
8687 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8688 ;   (clobber (reg:CC FLAGS_REG))]
8689 ;  ""
8690 ;  "div{l}\t{%2, %0|%0, %2}"
8691 ;  [(set_attr "type" "idiv")])
8693 ;;- Logical AND instructions
8695 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8696 ;; Note that this excludes ah.
8698 (define_expand "testsi_ccno_1"
8699   [(set (reg:CCNO FLAGS_REG)
8700         (compare:CCNO
8701           (and:SI (match_operand:SI 0 "nonimmediate_operand")
8702                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
8703           (const_int 0)))])
8705 (define_expand "testqi_ccz_1"
8706   [(set (reg:CCZ FLAGS_REG)
8707         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8708                              (match_operand:QI 1 "nonmemory_operand"))
8709                  (const_int 0)))])
8711 (define_expand "testdi_ccno_1"
8712   [(set (reg:CCNO FLAGS_REG)
8713         (compare:CCNO
8714           (and:DI (match_operand:DI 0 "nonimmediate_operand")
8715                   (match_operand:DI 1 "x86_64_szext_general_operand"))
8716           (const_int 0)))]
8717   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8719 (define_insn "*testdi_1"
8720   [(set (reg FLAGS_REG)
8721         (compare
8722          (and:DI
8723           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8724           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8725          (const_int 0)))]
8726   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8727    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8728   "@
8729    test{l}\t{%k1, %k0|%k0, %k1}
8730    test{l}\t{%k1, %k0|%k0, %k1}
8731    test{q}\t{%1, %0|%0, %1}
8732    test{q}\t{%1, %0|%0, %1}
8733    test{q}\t{%1, %0|%0, %1}"
8734   [(set_attr "type" "test")
8735    (set_attr "modrm" "0,1,0,1,1")
8736    (set_attr "mode" "SI,SI,DI,DI,DI")])
8738 (define_insn "*testqi_1_maybe_si"
8739   [(set (reg FLAGS_REG)
8740         (compare
8741           (and:QI
8742             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8743             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8744           (const_int 0)))]
8745    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8746     && ix86_match_ccmode (insn,
8747                          CONST_INT_P (operands[1])
8748                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8750   if (which_alternative == 3)
8751     {
8752       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8753         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8754       return "test{l}\t{%1, %k0|%k0, %1}";
8755     }
8756   return "test{b}\t{%1, %0|%0, %1}";
8758   [(set_attr "type" "test")
8759    (set_attr "modrm" "0,1,1,1")
8760    (set_attr "mode" "QI,QI,QI,SI")
8761    (set_attr "pent_pair" "uv,np,uv,np")])
8763 (define_insn "*test<mode>_1"
8764   [(set (reg FLAGS_REG)
8765         (compare
8766          (and:SWI124
8767           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8768           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8769          (const_int 0)))]
8770   "ix86_match_ccmode (insn, CCNOmode)
8771    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8772   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8773   [(set_attr "type" "test")
8774    (set_attr "modrm" "0,1,1")
8775    (set_attr "mode" "<MODE>")
8776    (set_attr "pent_pair" "uv,np,uv")])
8778 (define_expand "testqi_ext_1_ccno"
8779   [(set (reg:CCNO FLAGS_REG)
8780         (compare:CCNO
8781           (and:QI
8782             (subreg:QI
8783               (zero_extract:SI (match_operand 0 "ext_register_operand")
8784                                (const_int 8)
8785                                (const_int 8)) 0)
8786               (match_operand 1 "const_int_operand"))
8787           (const_int 0)))])
8789 (define_insn "*testqi_ext_1"
8790   [(set (reg FLAGS_REG)
8791         (compare
8792           (and:QI
8793             (subreg:QI
8794               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8795                                (const_int 8)
8796                                (const_int 8)) 0)
8797             (match_operand:QI 1 "general_operand" "QnBc,m"))
8798           (const_int 0)))]
8799   "ix86_match_ccmode (insn, CCNOmode)"
8800   "test{b}\t{%1, %h0|%h0, %1}"
8801   [(set_attr "isa" "*,nox64")
8802    (set_attr "type" "test")
8803    (set_attr "mode" "QI")])
8805 (define_insn "*testqi_ext_2"
8806   [(set (reg FLAGS_REG)
8807         (compare
8808           (and:QI
8809             (subreg:QI
8810               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8811                                (const_int 8)
8812                                (const_int 8)) 0)
8813             (subreg:QI
8814               (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8815                                (const_int 8)
8816                                (const_int 8)) 0))
8817           (const_int 0)))]
8818   "ix86_match_ccmode (insn, CCNOmode)"
8819   "test{b}\t{%h1, %h0|%h0, %h1}"
8820   [(set_attr "type" "test")
8821    (set_attr "mode" "QI")])
8823 ;; Combine likes to form bit extractions for some tests.  Humor it.
8824 (define_insn_and_split "*testqi_ext_3"
8825   [(set (match_operand 0 "flags_reg_operand")
8826         (match_operator 1 "compare_operator"
8827           [(zero_extract:SWI248
8828              (match_operand 2 "nonimmediate_operand" "rm")
8829              (match_operand 3 "const_int_operand" "n")
8830              (match_operand 4 "const_int_operand" "n"))
8831            (const_int 0)]))]
8832   "ix86_match_ccmode (insn, CCNOmode)
8833    && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8834        || GET_MODE (operands[2]) == SImode
8835        || GET_MODE (operands[2]) == HImode
8836        || GET_MODE (operands[2]) == QImode)
8837    /* Ensure that resulting mask is zero or sign extended operand.  */
8838    && INTVAL (operands[4]) >= 0
8839    && ((INTVAL (operands[3]) > 0
8840         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8841        || (<MODE>mode == DImode
8842            && INTVAL (operands[3]) > 32
8843            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8844   "#"
8845   "&& 1"
8846   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8848   rtx val = operands[2];
8849   HOST_WIDE_INT len = INTVAL (operands[3]);
8850   HOST_WIDE_INT pos = INTVAL (operands[4]);
8851   machine_mode mode = GET_MODE (val);
8853   if (SUBREG_P (val))
8854     {
8855       machine_mode submode = GET_MODE (SUBREG_REG (val));
8857       /* Narrow paradoxical subregs to prevent partial register stalls.  */
8858       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8859           && GET_MODE_CLASS (submode) == MODE_INT)
8860         {
8861           val = SUBREG_REG (val);
8862           mode = submode;
8863         }
8864     }
8866   /* Small HImode tests can be converted to QImode.  */
8867   if (register_operand (val, HImode) && pos + len <= 8)
8868     {
8869       val = gen_lowpart (QImode, val);
8870       mode = QImode;
8871     }
8873   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8875   wide_int mask
8876     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8878   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8881 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8882 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8883 ;; this is relatively important trick.
8884 ;; Do the conversion only post-reload to avoid limiting of the register class
8885 ;; to QI regs.
8886 (define_split
8887   [(set (match_operand 0 "flags_reg_operand")
8888         (match_operator 1 "compare_operator"
8889           [(and (match_operand 2 "QIreg_operand")
8890                 (match_operand 3 "const_int_operand"))
8891            (const_int 0)]))]
8892    "reload_completed
8893     && GET_MODE (operands[2]) != QImode
8894     && ((ix86_match_ccmode (insn, CCZmode)
8895          && !(INTVAL (operands[3]) & ~(255 << 8)))
8896         || (ix86_match_ccmode (insn, CCNOmode)
8897             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8898   [(set (match_dup 0)
8899         (match_op_dup 1
8900           [(and:QI
8901              (subreg:QI
8902                (zero_extract:SI (match_dup 2)
8903                                 (const_int 8)
8904                                 (const_int 8)) 0)
8905              (match_dup 3))
8906            (const_int 0)]))]
8908   operands[2] = gen_lowpart (SImode, operands[2]);
8909   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8912 (define_split
8913   [(set (match_operand 0 "flags_reg_operand")
8914         (match_operator 1 "compare_operator"
8915           [(and (match_operand 2 "nonimmediate_operand")
8916                 (match_operand 3 "const_int_operand"))
8917            (const_int 0)]))]
8918    "reload_completed
8919     && GET_MODE (operands[2]) != QImode
8920     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8921     && ((ix86_match_ccmode (insn, CCZmode)
8922          && !(INTVAL (operands[3]) & ~255))
8923         || (ix86_match_ccmode (insn, CCNOmode)
8924             && !(INTVAL (operands[3]) & ~127)))"
8925   [(set (match_dup 0)
8926         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8927                          (const_int 0)]))]
8929   operands[2] = gen_lowpart (QImode, operands[2]);
8930   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8933 ;; %%% This used to optimize known byte-wide and operations to memory,
8934 ;; and sometimes to QImode registers.  If this is considered useful,
8935 ;; it should be done with splitters.
8937 (define_expand "and<mode>3"
8938   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8939         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8940                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8941   ""
8943   machine_mode mode = <MODE>mode;
8944   rtx (*insn) (rtx, rtx);
8946   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8947     {
8948       HOST_WIDE_INT ival = INTVAL (operands[2]);
8950       if (ival == (HOST_WIDE_INT) 0xffffffff)
8951         mode = SImode;
8952       else if (ival == 0xffff)
8953         mode = HImode;
8954       else if (ival == 0xff)
8955         mode = QImode;
8956       }
8958   if (mode == <MODE>mode)
8959     {
8960       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8961       DONE;
8962     }
8964   if (<MODE>mode == DImode)
8965     insn = (mode == SImode)
8966            ? gen_zero_extendsidi2
8967            : (mode == HImode)
8968            ? gen_zero_extendhidi2
8969            : gen_zero_extendqidi2;
8970   else if (<MODE>mode == SImode)
8971     insn = (mode == HImode)
8972            ? gen_zero_extendhisi2
8973            : gen_zero_extendqisi2;
8974   else if (<MODE>mode == HImode)
8975     insn = gen_zero_extendqihi2;
8976   else
8977     gcc_unreachable ();
8979   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8980   DONE;
8983 (define_insn_and_split "*anddi3_doubleword"
8984   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8985         (and:DI
8986          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8987          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8988    (clobber (reg:CC FLAGS_REG))]
8989   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8990    && ix86_binary_operator_ok (AND, DImode, operands)"
8991   "#"
8992   "&& reload_completed"
8993   [(const_int 0)]
8995   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8996   if (operands[2] == const0_rtx)
8997     {
8998       operands[1] = const0_rtx;
8999       ix86_expand_move (SImode, &operands[0]);
9000     }
9001   else if (operands[2] != constm1_rtx)
9002     ix86_expand_binary_operator (AND, SImode, &operands[0]);
9003   else if (operands[5] == constm1_rtx)
9004     emit_note (NOTE_INSN_DELETED);
9005   if (operands[5] == const0_rtx)
9006     {
9007       operands[4] = const0_rtx;
9008       ix86_expand_move (SImode, &operands[3]);
9009     }
9010   else if (operands[5] != constm1_rtx)
9011     ix86_expand_binary_operator (AND, SImode, &operands[3]);
9012   DONE;
9015 (define_insn "*anddi_1"
9016   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9017         (and:DI
9018          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9019          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9020    (clobber (reg:CC FLAGS_REG))]
9021   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9022   "@
9023    and{l}\t{%k2, %k0|%k0, %k2}
9024    and{q}\t{%2, %0|%0, %2}
9025    and{q}\t{%2, %0|%0, %2}
9026    #"
9027   [(set_attr "type" "alu,alu,alu,imovx")
9028    (set_attr "length_immediate" "*,*,*,0")
9029    (set (attr "prefix_rex")
9030      (if_then_else
9031        (and (eq_attr "type" "imovx")
9032             (and (match_test "INTVAL (operands[2]) == 0xff")
9033                  (match_operand 1 "ext_QIreg_operand")))
9034        (const_string "1")
9035        (const_string "*")))
9036    (set_attr "mode" "SI,DI,DI,SI")])
9038 (define_insn_and_split "*anddi_1_btr"
9039   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9040         (and:DI
9041          (match_operand:DI 1 "nonimmediate_operand" "%0")
9042          (match_operand:DI 2 "const_int_operand" "n")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "TARGET_64BIT && TARGET_USE_BT
9045    && ix86_binary_operator_ok (AND, DImode, operands)
9046    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
9047   "#"
9048   "&& reload_completed"
9049   [(parallel [(set (zero_extract:DI (match_dup 0)
9050                                     (const_int 1)
9051                                     (match_dup 3))
9052                    (const_int 0))
9053               (clobber (reg:CC FLAGS_REG))])]
9054   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
9055   [(set_attr "type" "alu1")
9056    (set_attr "prefix_0f" "1")
9057    (set_attr "znver1_decode" "double")
9058    (set_attr "mode" "DI")])
9060 ;; Turn *anddi_1 into *andsi_1_zext if possible.
9061 (define_split
9062   [(set (match_operand:DI 0 "register_operand")
9063         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
9064                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
9065    (clobber (reg:CC FLAGS_REG))]
9066   "TARGET_64BIT"
9067   [(parallel [(set (match_dup 0)
9068                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9069               (clobber (reg:CC FLAGS_REG))])]
9070   "operands[2] = gen_lowpart (SImode, operands[2]);")
9072 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9073 (define_insn "*andsi_1_zext"
9074   [(set (match_operand:DI 0 "register_operand" "=r")
9075         (zero_extend:DI
9076           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9077                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9078    (clobber (reg:CC FLAGS_REG))]
9079   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9080   "and{l}\t{%2, %k0|%k0, %2}"
9081   [(set_attr "type" "alu")
9082    (set_attr "mode" "SI")])
9084 (define_insn "*and<mode>_1"
9085   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
9086         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
9087                    (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
9088    (clobber (reg:CC FLAGS_REG))]
9089   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9090   "@
9091    and{<imodesuffix>}\t{%2, %0|%0, %2}
9092    and{<imodesuffix>}\t{%2, %0|%0, %2}
9093    #"
9094   [(set_attr "type" "alu,alu,imovx")
9095    (set_attr "length_immediate" "*,*,0")
9096    (set (attr "prefix_rex")
9097      (if_then_else
9098        (and (eq_attr "type" "imovx")
9099             (and (match_test "INTVAL (operands[2]) == 0xff")
9100                  (match_operand 1 "ext_QIreg_operand")))
9101        (const_string "1")
9102        (const_string "*")))
9103    (set_attr "mode" "<MODE>,<MODE>,SI")])
9105 (define_insn "*andqi_1"
9106   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9107         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9108                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9109    (clobber (reg:CC FLAGS_REG))]
9110   "ix86_binary_operator_ok (AND, QImode, operands)"
9111   "@
9112    and{b}\t{%2, %0|%0, %2}
9113    and{b}\t{%2, %0|%0, %2}
9114    and{l}\t{%k2, %k0|%k0, %k2}"
9115   [(set_attr "type" "alu")
9116    (set_attr "mode" "QI,QI,SI")
9117    ;; Potential partial reg stall on alternative 2.
9118    (set (attr "preferred_for_speed")
9119      (cond [(eq_attr "alternative" "2")
9120               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9121            (symbol_ref "true")))])
9123 (define_insn "*andqi_1_slp"
9124   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9125         (and:QI (match_dup 0)
9126                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9127    (clobber (reg:CC FLAGS_REG))]
9128   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9129    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9130   "and{b}\t{%1, %0|%0, %1}"
9131   [(set_attr "type" "alu1")
9132    (set_attr "mode" "QI")])
9134 (define_split
9135   [(set (match_operand:SWI248 0 "register_operand")
9136         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9137                     (match_operand:SWI248 2 "const_int_operand")))
9138    (clobber (reg:CC FLAGS_REG))]
9139   "reload_completed
9140    && (!REG_P (operands[1])
9141        || REGNO (operands[0]) != REGNO (operands[1]))"
9142   [(const_int 0)]
9144   HOST_WIDE_INT ival = INTVAL (operands[2]);
9145   machine_mode mode;
9146   rtx (*insn) (rtx, rtx);
9148   if (ival == (HOST_WIDE_INT) 0xffffffff)
9149     mode = SImode;
9150   else if (ival == 0xffff)
9151     mode = HImode;
9152   else
9153     {
9154       gcc_assert (ival == 0xff);
9155       mode = QImode;
9156     }
9158   if (<MODE>mode == DImode)
9159     insn = (mode == SImode)
9160            ? gen_zero_extendsidi2
9161            : (mode == HImode)
9162            ? gen_zero_extendhidi2
9163            : gen_zero_extendqidi2;
9164   else
9165     {
9166       if (<MODE>mode != SImode)
9167         /* Zero extend to SImode to avoid partial register stalls.  */
9168         operands[0] = gen_lowpart (SImode, operands[0]);
9170       insn = (mode == HImode)
9171              ? gen_zero_extendhisi2
9172              : gen_zero_extendqisi2;
9173     }
9174   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
9175   DONE;
9178 (define_split
9179   [(set (match_operand:SWI48 0 "register_operand")
9180         (and:SWI48 (match_dup 0)
9181                    (const_int -65536)))
9182    (clobber (reg:CC FLAGS_REG))]
9183   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9184     || optimize_function_for_size_p (cfun)"
9185   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9186   "operands[1] = gen_lowpart (HImode, operands[0]);")
9188 (define_split
9189   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9190         (and:SWI248 (match_dup 0)
9191                     (const_int -256)))
9192    (clobber (reg:CC FLAGS_REG))]
9193   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9194    && reload_completed"
9195   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9196   "operands[1] = gen_lowpart (QImode, operands[0]);")
9198 (define_split
9199   [(set (match_operand:SWI248 0 "QIreg_operand")
9200         (and:SWI248 (match_dup 0)
9201                     (const_int -65281)))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9204    && reload_completed"
9205   [(parallel
9206      [(set (zero_extract:SI (match_dup 0)
9207                             (const_int 8)
9208                             (const_int 8))
9209            (subreg:SI
9210              (xor:QI
9211                (subreg:QI
9212                  (zero_extract:SI (match_dup 0)
9213                                   (const_int 8)
9214                                   (const_int 8)) 0)
9215                (subreg:QI
9216                  (zero_extract:SI (match_dup 0)
9217                                   (const_int 8)
9218                                   (const_int 8)) 0)) 0))
9219       (clobber (reg:CC FLAGS_REG))])]
9220   "operands[0] = gen_lowpart (SImode, operands[0]);")
9222 (define_insn "*anddi_2"
9223   [(set (reg FLAGS_REG)
9224         (compare
9225          (and:DI
9226           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9227           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9228          (const_int 0)))
9229    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9230         (and:DI (match_dup 1) (match_dup 2)))]
9231   "TARGET_64BIT
9232    && ix86_match_ccmode
9233         (insn,
9234          /* If we are going to emit andl instead of andq, and the operands[2]
9235             constant might have the SImode sign bit set, make sure the sign
9236             flag isn't tested, because the instruction will set the sign flag
9237             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
9238             conservatively assume it might have bit 31 set.  */
9239          (satisfies_constraint_Z (operands[2])
9240           && (!CONST_INT_P (operands[2])
9241               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9242          ? CCZmode : CCNOmode)
9243    && ix86_binary_operator_ok (AND, DImode, operands)"
9244   "@
9245    and{l}\t{%k2, %k0|%k0, %k2}
9246    and{q}\t{%2, %0|%0, %2}
9247    and{q}\t{%2, %0|%0, %2}"
9248   [(set_attr "type" "alu")
9249    (set_attr "mode" "SI,DI,DI")])
9251 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9252 (define_insn "*andsi_2_zext"
9253   [(set (reg FLAGS_REG)
9254         (compare (and:SI
9255                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9256                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
9257                  (const_int 0)))
9258    (set (match_operand:DI 0 "register_operand" "=r")
9259         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9260   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9261    && ix86_binary_operator_ok (AND, SImode, operands)"
9262   "and{l}\t{%2, %k0|%k0, %2}"
9263   [(set_attr "type" "alu")
9264    (set_attr "mode" "SI")])
9266 (define_insn "*andqi_2_maybe_si"
9267   [(set (reg FLAGS_REG)
9268         (compare (and:QI
9269                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9270                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9271                  (const_int 0)))
9272    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9273         (and:QI (match_dup 1) (match_dup 2)))]
9274   "ix86_binary_operator_ok (AND, QImode, operands)
9275    && ix86_match_ccmode (insn,
9276                          CONST_INT_P (operands[2])
9277                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9279   if (which_alternative == 2)
9280     {
9281       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9282         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9283       return "and{l}\t{%2, %k0|%k0, %2}";
9284     }
9285   return "and{b}\t{%2, %0|%0, %2}";
9287   [(set_attr "type" "alu")
9288    (set_attr "mode" "QI,QI,SI")])
9290 (define_insn "*and<mode>_2"
9291   [(set (reg FLAGS_REG)
9292         (compare (and:SWI124
9293                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9294                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9295                  (const_int 0)))
9296    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9297         (and:SWI124 (match_dup 1) (match_dup 2)))]
9298   "ix86_match_ccmode (insn, CCNOmode)
9299    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9300   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9301   [(set_attr "type" "alu")
9302    (set_attr "mode" "<MODE>")])
9304 (define_insn "*andqi_2_slp"
9305   [(set (reg FLAGS_REG)
9306         (compare (and:QI
9307                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9308                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9309                  (const_int 0)))
9310    (set (strict_low_part (match_dup 0))
9311         (and:QI (match_dup 0) (match_dup 1)))]
9312   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9313    && ix86_match_ccmode (insn, CCNOmode)
9314    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9315   "and{b}\t{%1, %0|%0, %1}"
9316   [(set_attr "type" "alu1")
9317    (set_attr "mode" "QI")])
9319 (define_insn "andqi_ext_1"
9320   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9321                          (const_int 8)
9322                          (const_int 8))
9323         (subreg:SI
9324           (and:QI
9325             (subreg:QI
9326               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9327                                (const_int 8)
9328                                (const_int 8)) 0)
9329             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9330    (clobber (reg:CC FLAGS_REG))]
9331   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9332    rtx_equal_p (operands[0], operands[1])"
9333   "and{b}\t{%2, %h0|%h0, %2}"
9334   [(set_attr "isa" "*,nox64")
9335    (set_attr "type" "alu")
9336    (set_attr "mode" "QI")])
9338 ;; Generated by peephole translating test to and.  This shows up
9339 ;; often in fp comparisons.
9340 (define_insn "*andqi_ext_1_cc"
9341   [(set (reg FLAGS_REG)
9342         (compare
9343           (and:QI
9344             (subreg:QI
9345               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9346                                (const_int 8)
9347                                (const_int 8)) 0)
9348             (match_operand:QI 2 "general_operand" "QnBc,m"))
9349           (const_int 0)))
9350    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9351                          (const_int 8)
9352                          (const_int 8))
9353         (subreg:SI
9354           (and:QI
9355             (subreg:QI
9356               (zero_extract:SI (match_dup 1)
9357                                (const_int 8)
9358                                (const_int 8)) 0)
9359             (match_dup 2)) 0))]
9360   "ix86_match_ccmode (insn, CCNOmode)
9361    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9362    && rtx_equal_p (operands[0], operands[1])"
9363   "and{b}\t{%2, %h0|%h0, %2}"
9364   [(set_attr "isa" "*,nox64")
9365    (set_attr "type" "alu")
9366    (set_attr "mode" "QI")])
9368 (define_insn "*andqi_ext_2"
9369   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9370                          (const_int 8)
9371                          (const_int 8))
9372         (subreg:SI
9373           (and:QI
9374             (subreg:QI
9375               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9376                                (const_int 8)
9377                                (const_int 8)) 0)
9378             (subreg:QI
9379               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9380                                (const_int 8)
9381                                (const_int 8)) 0)) 0))
9382    (clobber (reg:CC FLAGS_REG))]
9383   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9384    rtx_equal_p (operands[0], operands[1])
9385    || rtx_equal_p (operands[0], operands[2])"
9386   "and{b}\t{%h2, %h0|%h0, %h2}"
9387   [(set_attr "type" "alu")
9388    (set_attr "mode" "QI")])
9390 ;; Convert wide AND instructions with immediate operand to shorter QImode
9391 ;; equivalents when possible.
9392 ;; Don't do the splitting with memory operands, since it introduces risk
9393 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9394 ;; for size, but that can (should?) be handled by generic code instead.
9395 (define_split
9396   [(set (match_operand:SWI248 0 "QIreg_operand")
9397         (and:SWI248 (match_operand:SWI248 1 "register_operand")
9398                     (match_operand:SWI248 2 "const_int_operand")))
9399    (clobber (reg:CC FLAGS_REG))]
9400    "reload_completed
9401     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9402     && !(~INTVAL (operands[2]) & ~(255 << 8))"
9403   [(parallel
9404      [(set (zero_extract:SI (match_dup 0)
9405                             (const_int 8)
9406                             (const_int 8))
9407            (subreg:SI
9408              (and:QI
9409                (subreg:QI
9410                  (zero_extract:SI (match_dup 1)
9411                                   (const_int 8)
9412                                   (const_int 8)) 0)
9413                (match_dup 2)) 0))
9414       (clobber (reg:CC FLAGS_REG))])]
9416   operands[0] = gen_lowpart (SImode, operands[0]);
9417   operands[1] = gen_lowpart (SImode, operands[1]);
9418   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9421 ;; Since AND can be encoded with sign extended immediate, this is only
9422 ;; profitable when 7th bit is not set.
9423 (define_split
9424   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9425         (and:SWI248 (match_operand:SWI248 1 "general_operand")
9426                     (match_operand:SWI248 2 "const_int_operand")))
9427    (clobber (reg:CC FLAGS_REG))]
9428    "reload_completed
9429     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9430     && !(~INTVAL (operands[2]) & ~255)
9431     && !(INTVAL (operands[2]) & 128)"
9432   [(parallel [(set (strict_low_part (match_dup 0))
9433                    (and:QI (match_dup 1)
9434                            (match_dup 2)))
9435               (clobber (reg:CC FLAGS_REG))])]
9437   operands[0] = gen_lowpart (QImode, operands[0]);
9438   operands[1] = gen_lowpart (QImode, operands[1]);
9439   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9442 (define_insn "*andndi3_doubleword"
9443   [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9444         (and:DI
9445           (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9446           (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9447    (clobber (reg:CC FLAGS_REG))]
9448   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9449   "#"
9450   [(set_attr "isa" "bmi,bmi,bmi,*")])
9452 (define_split
9453   [(set (match_operand:DI 0 "register_operand")
9454         (and:DI
9455           (not:DI (match_operand:DI 1 "register_operand"))
9456           (match_operand:DI 2 "nonimmediate_operand")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9459    && reload_completed"
9460   [(parallel [(set (match_dup 0)
9461                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9462               (clobber (reg:CC FLAGS_REG))])
9463    (parallel [(set (match_dup 3)
9464                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9465               (clobber (reg:CC FLAGS_REG))])]
9466   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9468 (define_split
9469   [(set (match_operand:DI 0 "register_operand")
9470         (and:DI
9471           (not:DI (match_dup 0))
9472           (match_operand:DI 1 "nonimmediate_operand")))
9473    (clobber (reg:CC FLAGS_REG))]
9474   "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9475    && reload_completed"
9476   [(set (match_dup 0) (not:SI (match_dup 0)))
9477    (parallel [(set (match_dup 0)
9478                    (and:SI (match_dup 0) (match_dup 1)))
9479               (clobber (reg:CC FLAGS_REG))])
9480    (set (match_dup 2) (not:SI (match_dup 2)))
9481    (parallel [(set (match_dup 2)
9482                    (and:SI (match_dup 2) (match_dup 3)))
9483               (clobber (reg:CC FLAGS_REG))])]
9484   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9486 (define_insn "*andn<mode>_1"
9487   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9488         (and:SWI48
9489           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9490           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9491    (clobber (reg:CC FLAGS_REG))]
9492   "TARGET_BMI"
9493   "andn\t{%2, %1, %0|%0, %1, %2}"
9494   [(set_attr "type" "bitmanip")
9495    (set_attr "btver2_decode" "direct, double")
9496    (set_attr "mode" "<MODE>")])
9498 (define_insn "*andn<mode>_1"
9499   [(set (match_operand:SWI12 0 "register_operand" "=r")
9500         (and:SWI12
9501           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9502           (match_operand:SWI12 2 "register_operand" "r")))
9503    (clobber (reg:CC FLAGS_REG))]
9504   "TARGET_BMI"
9505   "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9506   [(set_attr "type" "bitmanip")
9507    (set_attr "btver2_decode" "direct")
9508    (set_attr "mode" "SI")])
9510 (define_insn "*andn_<mode>_ccno"
9511   [(set (reg FLAGS_REG)
9512         (compare
9513           (and:SWI48
9514             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9515             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9516           (const_int 0)))
9517    (clobber (match_scratch:SWI48 0 "=r,r"))]
9518   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9519   "andn\t{%2, %1, %0|%0, %1, %2}"
9520   [(set_attr "type" "bitmanip")
9521    (set_attr "btver2_decode" "direct, double")
9522    (set_attr "mode" "<MODE>")])
9524 ;; Logical inclusive and exclusive OR instructions
9526 ;; %%% This used to optimize known byte-wide and operations to memory.
9527 ;; If this is considered useful, it should be done with splitters.
9529 (define_expand "<code><mode>3"
9530   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9531         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9532                              (match_operand:SWIM1248x 2 "<general_operand>")))]
9533   ""
9534   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9536 (define_insn_and_split "*<code>di3_doubleword"
9537   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9538         (any_or:DI
9539          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9540          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9541    (clobber (reg:CC FLAGS_REG))]
9542   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9543    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9544   "#"
9545   "&& reload_completed"
9546   [(const_int 0)]
9548   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9549   if (operands[2] == constm1_rtx)
9550     {
9551       if (<CODE> == IOR)
9552         {
9553           operands[1] = constm1_rtx;
9554           ix86_expand_move (SImode, &operands[0]);
9555         }
9556       else
9557         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9558     }
9559   else if (operands[2] != const0_rtx)
9560     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9561   else if (operands[5] == const0_rtx)
9562     emit_note (NOTE_INSN_DELETED);
9563   if (operands[5] == constm1_rtx)
9564     {
9565       if (<CODE> == IOR)
9566         {
9567           operands[4] = constm1_rtx;
9568           ix86_expand_move (SImode, &operands[3]);
9569         }
9570       else
9571         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9572     }
9573   else if (operands[5] != const0_rtx)
9574     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9575   DONE;
9578 (define_insn "*<code><mode>_1"
9579   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9580         (any_or:SWI248
9581          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9582          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9583    (clobber (reg:CC FLAGS_REG))]
9584   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9585   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9586   [(set_attr "type" "alu")
9587    (set_attr "mode" "<MODE>")])
9589 (define_insn_and_split "*iordi_1_bts"
9590   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9591         (ior:DI
9592          (match_operand:DI 1 "nonimmediate_operand" "%0")
9593          (match_operand:DI 2 "const_int_operand" "n")))
9594    (clobber (reg:CC FLAGS_REG))]
9595   "TARGET_64BIT && TARGET_USE_BT
9596    && ix86_binary_operator_ok (IOR, DImode, operands)
9597    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9598   "#"
9599   "&& reload_completed"
9600   [(parallel [(set (zero_extract:DI (match_dup 0)
9601                                     (const_int 1)
9602                                     (match_dup 3))
9603                    (const_int 1))
9604               (clobber (reg:CC FLAGS_REG))])]
9605   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9606   [(set_attr "type" "alu1")
9607    (set_attr "prefix_0f" "1")
9608    (set_attr "znver1_decode" "double")
9609    (set_attr "mode" "DI")])
9611 (define_insn_and_split "*xordi_1_btc"
9612   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9613         (xor:DI
9614          (match_operand:DI 1 "nonimmediate_operand" "%0")
9615          (match_operand:DI 2 "const_int_operand" "n")))
9616    (clobber (reg:CC FLAGS_REG))]
9617   "TARGET_64BIT && TARGET_USE_BT
9618    && ix86_binary_operator_ok (XOR, DImode, operands)
9619    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9620   "#"
9621   "&& reload_completed"
9622   [(parallel [(set (zero_extract:DI (match_dup 0)
9623                                     (const_int 1)
9624                                     (match_dup 3))
9625                    (not:DI (zero_extract:DI (match_dup 0)
9626                                             (const_int 1)
9627                                             (match_dup 3))))
9628               (clobber (reg:CC FLAGS_REG))])]
9629   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9630   [(set_attr "type" "alu1")
9631    (set_attr "prefix_0f" "1")
9632    (set_attr "znver1_decode" "double")
9633    (set_attr "mode" "DI")])
9635 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9636 (define_insn "*<code>si_1_zext"
9637   [(set (match_operand:DI 0 "register_operand" "=r")
9638         (zero_extend:DI
9639          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9640                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9641    (clobber (reg:CC FLAGS_REG))]
9642   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9643   "<logic>{l}\t{%2, %k0|%k0, %2}"
9644   [(set_attr "type" "alu")
9645    (set_attr "mode" "SI")])
9647 (define_insn "*<code>si_1_zext_imm"
9648   [(set (match_operand:DI 0 "register_operand" "=r")
9649         (any_or:DI
9650          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9651          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9652    (clobber (reg:CC FLAGS_REG))]
9653   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9654   "<logic>{l}\t{%2, %k0|%k0, %2}"
9655   [(set_attr "type" "alu")
9656    (set_attr "mode" "SI")])
9658 (define_insn "*<code>qi_1"
9659   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9660         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9661                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9662    (clobber (reg:CC FLAGS_REG))]
9663   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9664   "@
9665    <logic>{b}\t{%2, %0|%0, %2}
9666    <logic>{b}\t{%2, %0|%0, %2}
9667    <logic>{l}\t{%k2, %k0|%k0, %k2}"
9668   [(set_attr "type" "alu")
9669    (set_attr "mode" "QI,QI,SI")
9670    ;; Potential partial reg stall on alternative 2.
9671    (set (attr "preferred_for_speed")
9672      (cond [(eq_attr "alternative" "2")
9673               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9674            (symbol_ref "true")))])
9676 (define_insn "*<code>qi_1_slp"
9677   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9678         (any_or:QI (match_dup 0)
9679                    (match_operand:QI 1 "general_operand" "qmn,qn")))
9680    (clobber (reg:CC FLAGS_REG))]
9681   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9682    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9683   "<logic>{b}\t{%1, %0|%0, %1}"
9684   [(set_attr "type" "alu1")
9685    (set_attr "mode" "QI")])
9687 (define_insn "*<code><mode>_2"
9688   [(set (reg FLAGS_REG)
9689         (compare (any_or:SWI
9690                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9691                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9692                  (const_int 0)))
9693    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9694         (any_or:SWI (match_dup 1) (match_dup 2)))]
9695   "ix86_match_ccmode (insn, CCNOmode)
9696    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9697   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9698   [(set_attr "type" "alu")
9699    (set_attr "mode" "<MODE>")])
9701 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9702 ;; ??? Special case for immediate operand is missing - it is tricky.
9703 (define_insn "*<code>si_2_zext"
9704   [(set (reg FLAGS_REG)
9705         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9706                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
9707                  (const_int 0)))
9708    (set (match_operand:DI 0 "register_operand" "=r")
9709         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9710   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9711    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9712   "<logic>{l}\t{%2, %k0|%k0, %2}"
9713   [(set_attr "type" "alu")
9714    (set_attr "mode" "SI")])
9716 (define_insn "*<code>si_2_zext_imm"
9717   [(set (reg FLAGS_REG)
9718         (compare (any_or:SI
9719                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9720                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9721                  (const_int 0)))
9722    (set (match_operand:DI 0 "register_operand" "=r")
9723         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9724   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9725    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9726   "<logic>{l}\t{%2, %k0|%k0, %2}"
9727   [(set_attr "type" "alu")
9728    (set_attr "mode" "SI")])
9730 (define_insn "*<code>qi_2_slp"
9731   [(set (reg FLAGS_REG)
9732         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9733                             (match_operand:QI 1 "general_operand" "qmn,qn"))
9734                  (const_int 0)))
9735    (set (strict_low_part (match_dup 0))
9736         (any_or:QI (match_dup 0) (match_dup 1)))]
9737   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9738    && ix86_match_ccmode (insn, CCNOmode)
9739    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9740   "<logic>{b}\t{%1, %0|%0, %1}"
9741   [(set_attr "type" "alu1")
9742    (set_attr "mode" "QI")])
9744 (define_insn "*<code><mode>_3"
9745   [(set (reg FLAGS_REG)
9746         (compare (any_or:SWI
9747                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
9748                   (match_operand:SWI 2 "<general_operand>" "<g>"))
9749                  (const_int 0)))
9750    (clobber (match_scratch:SWI 0 "=<r>"))]
9751   "ix86_match_ccmode (insn, CCNOmode)
9752    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9753   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9754   [(set_attr "type" "alu")
9755    (set_attr "mode" "<MODE>")])
9757 (define_insn "*<code>qi_ext_1"
9758   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9759                          (const_int 8)
9760                          (const_int 8))
9761         (subreg:SI
9762           (any_or:QI
9763             (subreg:QI
9764               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9765                                (const_int 8)
9766                                (const_int 8)) 0)
9767             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9768    (clobber (reg:CC FLAGS_REG))]
9769   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9770    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9771    && rtx_equal_p (operands[0], operands[1])"
9772   "<logic>{b}\t{%2, %h0|%h0, %2}"
9773   [(set_attr "isa" "*,nox64")
9774    (set_attr "type" "alu")
9775    (set_attr "mode" "QI")])
9777 (define_insn "*<code>qi_ext_2"
9778   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9779                          (const_int 8)
9780                          (const_int 8))
9781         (subreg:SI
9782           (any_or:QI
9783             (subreg:QI
9784               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9785                                (const_int 8)
9786                                (const_int 8)) 0)
9787             (subreg:QI
9788               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9789                                (const_int 8)
9790                                (const_int 8)) 0)) 0))
9791    (clobber (reg:CC FLAGS_REG))]
9792   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9793    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9794    && (rtx_equal_p (operands[0], operands[1])
9795        || rtx_equal_p (operands[0], operands[2]))"
9796   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9797   [(set_attr "type" "alu")
9798    (set_attr "mode" "QI")])
9800 ;; Convert wide OR instructions with immediate operand to shorter QImode
9801 ;; equivalents when possible.
9802 ;; Don't do the splitting with memory operands, since it introduces risk
9803 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9804 ;; for size, but that can (should?) be handled by generic code instead.
9805 (define_split
9806   [(set (match_operand:SWI248 0 "QIreg_operand")
9807         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9808                        (match_operand:SWI248 2 "const_int_operand")))
9809    (clobber (reg:CC FLAGS_REG))]
9810    "reload_completed
9811     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9812     && !(INTVAL (operands[2]) & ~(255 << 8))"
9813   [(parallel
9814      [(set (zero_extract:SI (match_dup 0)
9815                             (const_int 8)
9816                             (const_int 8))
9817            (subreg:SI
9818              (any_or:QI
9819                (subreg:QI
9820                  (zero_extract:SI (match_dup 1)
9821                                   (const_int 8)
9822                                   (const_int 8)) 0)
9823                (match_dup 2)) 0))
9824       (clobber (reg:CC FLAGS_REG))])]
9826   operands[0] = gen_lowpart (SImode, operands[0]);
9827   operands[1] = gen_lowpart (SImode, operands[1]);
9828   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9831 ;; Since OR can be encoded with sign extended immediate, this is only
9832 ;; profitable when 7th bit is set.
9833 (define_split
9834   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9835         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9836                        (match_operand:SWI248 2 "const_int_operand")))
9837    (clobber (reg:CC FLAGS_REG))]
9838    "reload_completed
9839     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9840     && !(INTVAL (operands[2]) & ~255)
9841     && (INTVAL (operands[2]) & 128)"
9842   [(parallel [(set (strict_low_part (match_dup 0))
9843                    (any_or:QI (match_dup 1)
9844                               (match_dup 2)))
9845               (clobber (reg:CC FLAGS_REG))])]
9847   operands[0] = gen_lowpart (QImode, operands[0]);
9848   operands[1] = gen_lowpart (QImode, operands[1]);
9849   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9852 (define_expand "xorqi_ext_1_cc"
9853   [(parallel [
9854      (set (reg:CCNO FLAGS_REG)
9855           (compare:CCNO
9856             (xor:QI
9857               (subreg:QI
9858                 (zero_extract:SI (match_operand 1 "ext_register_operand")
9859                                  (const_int 8)
9860                                  (const_int 8)) 0)
9861               (match_operand 2 "const_int_operand"))
9862             (const_int 0)))
9863      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9864                            (const_int 8)
9865                            (const_int 8))
9866           (subreg:SI
9867             (xor:QI
9868               (subreg:QI
9869                 (zero_extract:SI (match_dup 1)
9870                                  (const_int 8)
9871                                  (const_int 8)) 0)
9872             (match_dup 2)) 0))])])
9874 (define_insn "*xorqi_ext_1_cc"
9875   [(set (reg FLAGS_REG)
9876         (compare
9877           (xor:QI
9878             (subreg:QI
9879               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9880                                (const_int 8)
9881                                (const_int 8)) 0)
9882             (match_operand:QI 2 "general_operand" "QnBc,m"))
9883           (const_int 0)))
9884    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9885                          (const_int 8)
9886                          (const_int 8))
9887         (subreg:SI
9888           (xor:QI
9889             (subreg:QI
9890               (zero_extract:SI (match_dup 1)
9891                                (const_int 8)
9892                                (const_int 8)) 0)
9893           (match_dup 2)) 0))]
9894   "ix86_match_ccmode (insn, CCNOmode)
9895    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9896    && rtx_equal_p (operands[0], operands[1])"
9897   "xor{b}\t{%2, %h0|%h0, %2}"
9898   [(set_attr "isa" "*,nox64")
9899    (set_attr "type" "alu")
9900    (set_attr "mode" "QI")])
9902 ;; Negation instructions
9904 (define_expand "neg<mode>2"
9905   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9906         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9907   ""
9908   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9910 (define_insn_and_split "*neg<dwi>2_doubleword"
9911   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9912         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9913    (clobber (reg:CC FLAGS_REG))]
9914   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9915   "#"
9916   "reload_completed"
9917   [(parallel
9918     [(set (reg:CCZ FLAGS_REG)
9919           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9920      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9921    (parallel
9922     [(set (match_dup 2)
9923           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9924                                 (match_dup 3))
9925                      (const_int 0)))
9926      (clobber (reg:CC FLAGS_REG))])
9927    (parallel
9928     [(set (match_dup 2)
9929           (neg:DWIH (match_dup 2)))
9930      (clobber (reg:CC FLAGS_REG))])]
9931   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9933 (define_insn "*neg<mode>2_1"
9934   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9935         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9936    (clobber (reg:CC FLAGS_REG))]
9937   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9938   "neg{<imodesuffix>}\t%0"
9939   [(set_attr "type" "negnot")
9940    (set_attr "mode" "<MODE>")])
9942 ;; Combine is quite creative about this pattern.
9943 (define_insn "*negsi2_1_zext"
9944   [(set (match_operand:DI 0 "register_operand" "=r")
9945         (lshiftrt:DI
9946           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9947                              (const_int 32)))
9948         (const_int 32)))
9949    (clobber (reg:CC FLAGS_REG))]
9950   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9951   "neg{l}\t%k0"
9952   [(set_attr "type" "negnot")
9953    (set_attr "mode" "SI")])
9955 ;; The problem with neg is that it does not perform (compare x 0),
9956 ;; it really performs (compare 0 x), which leaves us with the zero
9957 ;; flag being the only useful item.
9959 (define_insn "*neg<mode>2_cmpz"
9960   [(set (reg:CCZ FLAGS_REG)
9961         (compare:CCZ
9962           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9963                    (const_int 0)))
9964    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9965         (neg:SWI (match_dup 1)))]
9966   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9967   "neg{<imodesuffix>}\t%0"
9968   [(set_attr "type" "negnot")
9969    (set_attr "mode" "<MODE>")])
9971 (define_insn "*negsi2_cmpz_zext"
9972   [(set (reg:CCZ FLAGS_REG)
9973         (compare:CCZ
9974           (lshiftrt:DI
9975             (neg:DI (ashift:DI
9976                       (match_operand:DI 1 "register_operand" "0")
9977                       (const_int 32)))
9978             (const_int 32))
9979           (const_int 0)))
9980    (set (match_operand:DI 0 "register_operand" "=r")
9981         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9982                                         (const_int 32)))
9983                      (const_int 32)))]
9984   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9985   "neg{l}\t%k0"
9986   [(set_attr "type" "negnot")
9987    (set_attr "mode" "SI")])
9989 ;; Negate with jump on overflow.
9990 (define_expand "negv<mode>3"
9991   [(parallel [(set (reg:CCO FLAGS_REG)
9992                    (ne:CCO (match_operand:SWI 1 "register_operand")
9993                            (match_dup 3)))
9994               (set (match_operand:SWI 0 "register_operand")
9995                    (neg:SWI (match_dup 1)))])
9996    (set (pc) (if_then_else
9997                (eq (reg:CCO FLAGS_REG) (const_int 0))
9998                (label_ref (match_operand 2))
9999                (pc)))]
10000   ""
10002   operands[3]
10003     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
10004                     <MODE>mode);
10007 (define_insn "*negv<mode>3"
10008   [(set (reg:CCO FLAGS_REG)
10009         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
10010                 (match_operand:SWI 2 "const_int_operand")))
10011    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10012         (neg:SWI (match_dup 1)))]
10013   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
10014    && mode_signbit_p (<MODE>mode, operands[2])"
10015   "neg{<imodesuffix>}\t%0"
10016   [(set_attr "type" "negnot")
10017    (set_attr "mode" "<MODE>")])
10019 ;; Changing of sign for FP values is doable using integer unit too.
10021 (define_expand "<code><mode>2"
10022   [(set (match_operand:X87MODEF 0 "register_operand")
10023         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
10024   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10025   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10027 (define_insn "*absneg<mode>2"
10028   [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
10029         (match_operator:MODEF 3 "absneg_operator"
10030           [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
10031    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
10032    (clobber (reg:CC FLAGS_REG))]
10033   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10034   "#"
10035   [(set (attr "enabled")
10036      (if_then_else
10037        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
10038        (if_then_else
10039          (eq_attr "alternative" "2")
10040          (symbol_ref "TARGET_MIX_SSE_I387")
10041          (symbol_ref "true"))
10042        (if_then_else
10043          (eq_attr "alternative" "2,3")
10044          (symbol_ref "true")
10045          (symbol_ref "false"))))])
10047 (define_insn "*absnegxf2_i387"
10048   [(set (match_operand:XF 0 "register_operand" "=f,!r")
10049         (match_operator:XF 3 "absneg_operator"
10050           [(match_operand:XF 1 "register_operand" "0,0")]))
10051    (use (match_operand 2))
10052    (clobber (reg:CC FLAGS_REG))]
10053   "TARGET_80387"
10054   "#")
10056 (define_expand "<code>tf2"
10057   [(set (match_operand:TF 0 "register_operand")
10058         (absneg:TF (match_operand:TF 1 "register_operand")))]
10059   "TARGET_SSE"
10060   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10062 (define_insn "*absnegtf2_sse"
10063   [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
10064         (match_operator:TF 3 "absneg_operator"
10065           [(match_operand:TF 1 "register_operand" "0,Yv")]))
10066    (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
10067    (clobber (reg:CC FLAGS_REG))]
10068   "TARGET_SSE"
10069   "#")
10071 ;; Splitters for fp abs and neg.
10073 (define_split
10074   [(set (match_operand 0 "fp_register_operand")
10075         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10076    (use (match_operand 2))
10077    (clobber (reg:CC FLAGS_REG))]
10078   "reload_completed"
10079   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10081 (define_split
10082   [(set (match_operand 0 "sse_reg_operand")
10083         (match_operator 3 "absneg_operator"
10084           [(match_operand 1 "register_operand")]))
10085    (use (match_operand 2 "nonimmediate_operand"))
10086    (clobber (reg:CC FLAGS_REG))]
10087   "reload_completed"
10088   [(set (match_dup 0) (match_dup 3))]
10090   machine_mode mode = GET_MODE (operands[0]);
10091   machine_mode vmode = GET_MODE (operands[2]);
10092   rtx tmp;
10094   operands[0] = lowpart_subreg (vmode, operands[0], mode);
10095   operands[1] = lowpart_subreg (vmode, operands[1], mode);
10096   if (operands_match_p (operands[0], operands[2]))
10097     std::swap (operands[1], operands[2]);
10098   if (GET_CODE (operands[3]) == ABS)
10099     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10100   else
10101     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10102   operands[3] = tmp;
10105 (define_split
10106   [(set (match_operand:SF 0 "general_reg_operand")
10107         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10108    (use (match_operand:V4SF 2))
10109    (clobber (reg:CC FLAGS_REG))]
10110   "reload_completed"
10111   [(parallel [(set (match_dup 0) (match_dup 1))
10112               (clobber (reg:CC FLAGS_REG))])]
10114   rtx tmp;
10115   operands[0] = gen_lowpart (SImode, operands[0]);
10116   if (GET_CODE (operands[1]) == ABS)
10117     {
10118       tmp = gen_int_mode (0x7fffffff, SImode);
10119       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10120     }
10121   else
10122     {
10123       tmp = gen_int_mode (0x80000000, SImode);
10124       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10125     }
10126   operands[1] = tmp;
10129 (define_split
10130   [(set (match_operand:DF 0 "general_reg_operand")
10131         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10132    (use (match_operand 2))
10133    (clobber (reg:CC FLAGS_REG))]
10134   "reload_completed"
10135   [(parallel [(set (match_dup 0) (match_dup 1))
10136               (clobber (reg:CC FLAGS_REG))])]
10138   rtx tmp;
10139   if (TARGET_64BIT)
10140     {
10141       tmp = gen_lowpart (DImode, operands[0]);
10142       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10143       operands[0] = tmp;
10145       if (GET_CODE (operands[1]) == ABS)
10146         tmp = const0_rtx;
10147       else
10148         tmp = gen_rtx_NOT (DImode, tmp);
10149     }
10150   else
10151     {
10152       operands[0] = gen_highpart (SImode, operands[0]);
10153       if (GET_CODE (operands[1]) == ABS)
10154         {
10155           tmp = gen_int_mode (0x7fffffff, SImode);
10156           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10157         }
10158       else
10159         {
10160           tmp = gen_int_mode (0x80000000, SImode);
10161           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10162         }
10163     }
10164   operands[1] = tmp;
10167 (define_split
10168   [(set (match_operand:XF 0 "general_reg_operand")
10169         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10170    (use (match_operand 2))
10171    (clobber (reg:CC FLAGS_REG))]
10172   "reload_completed"
10173   [(parallel [(set (match_dup 0) (match_dup 1))
10174               (clobber (reg:CC FLAGS_REG))])]
10176   rtx tmp;
10177   operands[0] = gen_rtx_REG (SImode,
10178                              REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
10179   if (GET_CODE (operands[1]) == ABS)
10180     {
10181       tmp = GEN_INT (0x7fff);
10182       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10183     }
10184   else
10185     {
10186       tmp = GEN_INT (0x8000);
10187       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10188     }
10189   operands[1] = tmp;
10192 ;; Conditionalize these after reload. If they match before reload, we
10193 ;; lose the clobber and ability to use integer instructions.
10195 (define_insn "*<code><mode>2_1"
10196   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10197         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10198   "TARGET_80387
10199    && (reload_completed
10200        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10201   "f<absneg_mnemonic>"
10202   [(set_attr "type" "fsgn")
10203    (set_attr "mode" "<MODE>")])
10205 (define_insn "*<code>extendsfdf2"
10206   [(set (match_operand:DF 0 "register_operand" "=f")
10207         (absneg:DF (float_extend:DF
10208                      (match_operand:SF 1 "register_operand" "0"))))]
10209   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10210   "f<absneg_mnemonic>"
10211   [(set_attr "type" "fsgn")
10212    (set_attr "mode" "DF")])
10214 (define_insn "*<code>extendsfxf2"
10215   [(set (match_operand:XF 0 "register_operand" "=f")
10216         (absneg:XF (float_extend:XF
10217                      (match_operand:SF 1 "register_operand" "0"))))]
10218   "TARGET_80387"
10219   "f<absneg_mnemonic>"
10220   [(set_attr "type" "fsgn")
10221    (set_attr "mode" "XF")])
10223 (define_insn "*<code>extenddfxf2"
10224   [(set (match_operand:XF 0 "register_operand" "=f")
10225         (absneg:XF (float_extend:XF
10226                      (match_operand:DF 1 "register_operand" "0"))))]
10227   "TARGET_80387"
10228   "f<absneg_mnemonic>"
10229   [(set_attr "type" "fsgn")
10230    (set_attr "mode" "XF")])
10232 ;; Copysign instructions
10234 (define_mode_iterator CSGNMODE [SF DF TF])
10235 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10237 (define_expand "copysign<mode>3"
10238   [(match_operand:CSGNMODE 0 "register_operand")
10239    (match_operand:CSGNMODE 1 "nonmemory_operand")
10240    (match_operand:CSGNMODE 2 "register_operand")]
10241   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10242    || (TARGET_SSE && (<MODE>mode == TFmode))"
10243   "ix86_expand_copysign (operands); DONE;")
10245 (define_insn_and_split "copysign<mode>3_const"
10246   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10247         (unspec:CSGNMODE
10248           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10249            (match_operand:CSGNMODE 2 "register_operand" "0")
10250            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10251           UNSPEC_COPYSIGN))]
10252   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10253    || (TARGET_SSE && (<MODE>mode == TFmode))"
10254   "#"
10255   "&& reload_completed"
10256   [(const_int 0)]
10257   "ix86_split_copysign_const (operands); DONE;")
10259 (define_insn "copysign<mode>3_var"
10260   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10261         (unspec:CSGNMODE
10262           [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10263            (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10264            (match_operand:<CSGNVMODE> 4
10265              "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10266            (match_operand:<CSGNVMODE> 5
10267              "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10268           UNSPEC_COPYSIGN))
10269    (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10270   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10271    || (TARGET_SSE && (<MODE>mode == TFmode))"
10272   "#")
10274 (define_split
10275   [(set (match_operand:CSGNMODE 0 "register_operand")
10276         (unspec:CSGNMODE
10277           [(match_operand:CSGNMODE 2 "register_operand")
10278            (match_operand:CSGNMODE 3 "register_operand")
10279            (match_operand:<CSGNVMODE> 4)
10280            (match_operand:<CSGNVMODE> 5)]
10281           UNSPEC_COPYSIGN))
10282    (clobber (match_scratch:<CSGNVMODE> 1))]
10283   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10284     || (TARGET_SSE && (<MODE>mode == TFmode)))
10285    && reload_completed"
10286   [(const_int 0)]
10287   "ix86_split_copysign_var (operands); DONE;")
10289 ;; One complement instructions
10291 (define_expand "one_cmpl<mode>2"
10292   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10293         (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10294   ""
10295   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10297 (define_insn_and_split "*one_cmpldi2_doubleword"
10298   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10299         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10300   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10301    && ix86_unary_operator_ok (NOT, DImode, operands)"
10302   "#"
10303   "&& reload_completed"
10304   [(set (match_dup 0)
10305         (not:SI (match_dup 1)))
10306    (set (match_dup 2)
10307         (not:SI (match_dup 3)))]
10308   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10310 (define_insn "*one_cmpl<mode>2_1"
10311   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10312         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10313   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10314   "not{<imodesuffix>}\t%0"
10315   [(set_attr "type" "negnot")
10316    (set_attr "mode" "<MODE>")])
10318 ;; ??? Currently never generated - xor is used instead.
10319 (define_insn "*one_cmplsi2_1_zext"
10320   [(set (match_operand:DI 0 "register_operand" "=r")
10321         (zero_extend:DI
10322           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10323   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10324   "not{l}\t%k0"
10325   [(set_attr "type" "negnot")
10326    (set_attr "mode" "SI")])
10328 (define_insn "*one_cmplqi2_1"
10329   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10330         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10331   "ix86_unary_operator_ok (NOT, QImode, operands)"
10332   "@
10333    not{b}\t%0
10334    not{l}\t%k0"
10335   [(set_attr "type" "negnot")
10336    (set_attr "mode" "QI,SI")
10337    ;; Potential partial reg stall on alternative 1.
10338    (set (attr "preferred_for_speed")
10339      (cond [(eq_attr "alternative" "1")
10340               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10341            (symbol_ref "true")))])
10343 (define_insn "*one_cmpl<mode>2_2"
10344   [(set (reg FLAGS_REG)
10345         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10346                  (const_int 0)))
10347    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10348         (not:SWI (match_dup 1)))]
10349   "ix86_match_ccmode (insn, CCNOmode)
10350    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10351   "#"
10352   [(set_attr "type" "alu1")
10353    (set_attr "mode" "<MODE>")])
10355 (define_split
10356   [(set (match_operand 0 "flags_reg_operand")
10357         (match_operator 2 "compare_operator"
10358           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10359            (const_int 0)]))
10360    (set (match_operand:SWI 1 "nonimmediate_operand")
10361         (not:SWI (match_dup 3)))]
10362   "ix86_match_ccmode (insn, CCNOmode)"
10363   [(parallel [(set (match_dup 0)
10364                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10365                                     (const_int 0)]))
10366               (set (match_dup 1)
10367                    (xor:SWI (match_dup 3) (const_int -1)))])])
10369 ;; ??? Currently never generated - xor is used instead.
10370 (define_insn "*one_cmplsi2_2_zext"
10371   [(set (reg FLAGS_REG)
10372         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10373                  (const_int 0)))
10374    (set (match_operand:DI 0 "register_operand" "=r")
10375         (zero_extend:DI (not:SI (match_dup 1))))]
10376   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10377    && ix86_unary_operator_ok (NOT, SImode, operands)"
10378   "#"
10379   [(set_attr "type" "alu1")
10380    (set_attr "mode" "SI")])
10382 (define_split
10383   [(set (match_operand 0 "flags_reg_operand")
10384         (match_operator 2 "compare_operator"
10385           [(not:SI (match_operand:SI 3 "register_operand"))
10386            (const_int 0)]))
10387    (set (match_operand:DI 1 "register_operand")
10388         (zero_extend:DI (not:SI (match_dup 3))))]
10389   "ix86_match_ccmode (insn, CCNOmode)"
10390   [(parallel [(set (match_dup 0)
10391                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10392                                     (const_int 0)]))
10393               (set (match_dup 1)
10394                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10396 ;; Shift instructions
10398 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10399 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10400 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10401 ;; from the assembler input.
10403 ;; This instruction shifts the target reg/mem as usual, but instead of
10404 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10405 ;; is a left shift double, bits are taken from the high order bits of
10406 ;; reg, else if the insn is a shift right double, bits are taken from the
10407 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10408 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10410 ;; Since sh[lr]d does not change the `reg' operand, that is done
10411 ;; separately, making all shifts emit pairs of shift double and normal
10412 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10413 ;; support a 63 bit shift, each shift where the count is in a reg expands
10414 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10416 ;; If the shift count is a constant, we need never emit more than one
10417 ;; shift pair, instead using moves and sign extension for counts greater
10418 ;; than 31.
10420 (define_expand "ashl<mode>3"
10421   [(set (match_operand:SDWIM 0 "<shift_operand>")
10422         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10423                       (match_operand:QI 2 "nonmemory_operand")))]
10424   ""
10425   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10427 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10428   [(set (match_operand:<DWI> 0 "register_operand")
10429         (ashift:<DWI>
10430           (match_operand:<DWI> 1 "register_operand")
10431           (subreg:QI
10432             (and:SI
10433               (match_operand:SI 2 "register_operand" "c")
10434               (match_operand:SI 3 "const_int_operand")) 0)))
10435    (clobber (reg:CC FLAGS_REG))]
10436   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10437    && can_create_pseudo_p ()"
10438   "#"
10439   "&& 1"
10440   [(parallel
10441      [(set (match_dup 6)
10442            (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10443                      (lshiftrt:DWIH (match_dup 5)
10444                        (minus:QI (match_dup 8) (match_dup 2)))))
10445       (clobber (reg:CC FLAGS_REG))])
10446    (parallel
10447      [(set (match_dup 4)
10448            (ashift:DWIH (match_dup 5) (match_dup 2)))
10449       (clobber (reg:CC FLAGS_REG))])]
10451   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10453   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10455   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10456       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10457     {
10458       rtx tem = gen_reg_rtx (SImode);
10459       emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10460       operands[2] = tem;
10461     }
10463   operands[2] = gen_lowpart (QImode, operands[2]);
10465   if (!rtx_equal_p (operands[6], operands[7]))
10466     emit_move_insn (operands[6], operands[7]);
10469 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10470   [(set (match_operand:<DWI> 0 "register_operand")
10471         (ashift:<DWI>
10472           (match_operand:<DWI> 1 "register_operand")
10473           (and:QI
10474             (match_operand:QI 2 "register_operand" "c")
10475             (match_operand:QI 3 "const_int_operand"))))
10476    (clobber (reg:CC FLAGS_REG))]
10477   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10478    && can_create_pseudo_p ()"
10479   "#"
10480   "&& 1"
10481   [(parallel
10482      [(set (match_dup 6)
10483            (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10484                      (lshiftrt:DWIH (match_dup 5)
10485                        (minus:QI (match_dup 8) (match_dup 2)))))
10486       (clobber (reg:CC FLAGS_REG))])
10487    (parallel
10488      [(set (match_dup 4)
10489            (ashift:DWIH (match_dup 5) (match_dup 2)))
10490       (clobber (reg:CC FLAGS_REG))])]
10492   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10494   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10496   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10497       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10498     {
10499       rtx tem = gen_reg_rtx (QImode);
10500       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10501       operands[2] = tem;
10502     }
10504   if (!rtx_equal_p (operands[6], operands[7]))
10505     emit_move_insn (operands[6], operands[7]);
10508 (define_insn "*ashl<mode>3_doubleword"
10509   [(set (match_operand:DWI 0 "register_operand" "=&r")
10510         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10511                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10512    (clobber (reg:CC FLAGS_REG))]
10513   ""
10514   "#"
10515   [(set_attr "type" "multi")])
10517 (define_split
10518   [(set (match_operand:DWI 0 "register_operand")
10519         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10520                     (match_operand:QI 2 "nonmemory_operand")))
10521    (clobber (reg:CC FLAGS_REG))]
10522   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10523   [(const_int 0)]
10524   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10526 ;; By default we don't ask for a scratch register, because when DWImode
10527 ;; values are manipulated, registers are already at a premium.  But if
10528 ;; we have one handy, we won't turn it away.
10530 (define_peephole2
10531   [(match_scratch:DWIH 3 "r")
10532    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10533                    (ashift:<DWI>
10534                      (match_operand:<DWI> 1 "nonmemory_operand")
10535                      (match_operand:QI 2 "nonmemory_operand")))
10536               (clobber (reg:CC FLAGS_REG))])
10537    (match_dup 3)]
10538   "TARGET_CMOVE"
10539   [(const_int 0)]
10540   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10542 (define_insn "x86_64_shld"
10543   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10544         (ior:DI (ashift:DI (match_dup 0)
10545                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10546                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10547                   (minus:QI (const_int 64) (match_dup 2)))))
10548    (clobber (reg:CC FLAGS_REG))]
10549   "TARGET_64BIT"
10550   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10551   [(set_attr "type" "ishift")
10552    (set_attr "prefix_0f" "1")
10553    (set_attr "mode" "DI")
10554    (set_attr "athlon_decode" "vector")
10555    (set_attr "amdfam10_decode" "vector")
10556    (set_attr "bdver1_decode" "vector")])
10558 (define_insn "x86_shld"
10559   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10560         (ior:SI (ashift:SI (match_dup 0)
10561                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10562                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10563                   (minus:QI (const_int 32) (match_dup 2)))))
10564    (clobber (reg:CC FLAGS_REG))]
10565   ""
10566   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10567   [(set_attr "type" "ishift")
10568    (set_attr "prefix_0f" "1")
10569    (set_attr "mode" "SI")
10570    (set_attr "pent_pair" "np")
10571    (set_attr "athlon_decode" "vector")
10572    (set_attr "amdfam10_decode" "vector")
10573    (set_attr "bdver1_decode" "vector")])
10575 (define_expand "x86_shift<mode>_adj_1"
10576   [(set (reg:CCZ FLAGS_REG)
10577         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10578                              (match_dup 4))
10579                      (const_int 0)))
10580    (set (match_operand:SWI48 0 "register_operand")
10581         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10582                             (match_operand:SWI48 1 "register_operand")
10583                             (match_dup 0)))
10584    (set (match_dup 1)
10585         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10586                             (match_operand:SWI48 3 "register_operand")
10587                             (match_dup 1)))]
10588   "TARGET_CMOVE"
10589   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10591 (define_expand "x86_shift<mode>_adj_2"
10592   [(use (match_operand:SWI48 0 "register_operand"))
10593    (use (match_operand:SWI48 1 "register_operand"))
10594    (use (match_operand:QI 2 "register_operand"))]
10595   ""
10597   rtx_code_label *label = gen_label_rtx ();
10598   rtx tmp;
10600   emit_insn (gen_testqi_ccz_1 (operands[2],
10601                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10603   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10604   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10605   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10606                               gen_rtx_LABEL_REF (VOIDmode, label),
10607                               pc_rtx);
10608   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10609   JUMP_LABEL (tmp) = label;
10611   emit_move_insn (operands[0], operands[1]);
10612   ix86_expand_clear (operands[1]);
10614   emit_label (label);
10615   LABEL_NUSES (label) = 1;
10617   DONE;
10620 ;; Avoid useless masking of count operand.
10621 (define_insn_and_split "*ashl<mode>3_mask"
10622   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10623         (ashift:SWI48
10624           (match_operand:SWI48 1 "nonimmediate_operand")
10625           (subreg:QI
10626             (and:SI
10627               (match_operand:SI 2 "register_operand" "c,r")
10628               (match_operand:SI 3 "const_int_operand")) 0)))
10629    (clobber (reg:CC FLAGS_REG))]
10630   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10631    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10632       == GET_MODE_BITSIZE (<MODE>mode)-1
10633    && can_create_pseudo_p ()"
10634   "#"
10635   "&& 1"
10636   [(parallel
10637      [(set (match_dup 0)
10638            (ashift:SWI48 (match_dup 1)
10639                          (match_dup 2)))
10640       (clobber (reg:CC FLAGS_REG))])]
10641   "operands[2] = gen_lowpart (QImode, operands[2]);"
10642   [(set_attr "isa" "*,bmi2")])
10644 (define_insn_and_split "*ashl<mode>3_mask_1"
10645   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10646         (ashift:SWI48
10647           (match_operand:SWI48 1 "nonimmediate_operand")
10648           (and:QI
10649             (match_operand:QI 2 "register_operand" "c,r")
10650             (match_operand:QI 3 "const_int_operand"))))
10651    (clobber (reg:CC FLAGS_REG))]
10652   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10653    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10654       == GET_MODE_BITSIZE (<MODE>mode)-1
10655    && can_create_pseudo_p ()"
10656   "#"
10657   "&& 1"
10658   [(parallel
10659      [(set (match_dup 0)
10660            (ashift:SWI48 (match_dup 1)
10661                          (match_dup 2)))
10662       (clobber (reg:CC FLAGS_REG))])]
10663   ""
10664   [(set_attr "isa" "*,bmi2")])
10666 (define_insn "*bmi2_ashl<mode>3_1"
10667   [(set (match_operand:SWI48 0 "register_operand" "=r")
10668         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10669                       (match_operand:SWI48 2 "register_operand" "r")))]
10670   "TARGET_BMI2"
10671   "shlx\t{%2, %1, %0|%0, %1, %2}"
10672   [(set_attr "type" "ishiftx")
10673    (set_attr "mode" "<MODE>")])
10675 (define_insn "*ashl<mode>3_1"
10676   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10677         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10678                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10679    (clobber (reg:CC FLAGS_REG))]
10680   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10682   switch (get_attr_type (insn))
10683     {
10684     case TYPE_LEA:
10685     case TYPE_ISHIFTX:
10686       return "#";
10688     case TYPE_ALU:
10689       gcc_assert (operands[2] == const1_rtx);
10690       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10691       return "add{<imodesuffix>}\t%0, %0";
10693     default:
10694       if (operands[2] == const1_rtx
10695           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10696         return "sal{<imodesuffix>}\t%0";
10697       else
10698         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10699     }
10701   [(set_attr "isa" "*,*,bmi2")
10702    (set (attr "type")
10703      (cond [(eq_attr "alternative" "1")
10704               (const_string "lea")
10705             (eq_attr "alternative" "2")
10706               (const_string "ishiftx")
10707             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10708                       (match_operand 0 "register_operand"))
10709                  (match_operand 2 "const1_operand"))
10710               (const_string "alu")
10711            ]
10712            (const_string "ishift")))
10713    (set (attr "length_immediate")
10714      (if_then_else
10715        (ior (eq_attr "type" "alu")
10716             (and (eq_attr "type" "ishift")
10717                  (and (match_operand 2 "const1_operand")
10718                       (ior (match_test "TARGET_SHIFT1")
10719                            (match_test "optimize_function_for_size_p (cfun)")))))
10720        (const_string "0")
10721        (const_string "*")))
10722    (set_attr "mode" "<MODE>")])
10724 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10725 (define_split
10726   [(set (match_operand:SWI48 0 "register_operand")
10727         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10728                       (match_operand:QI 2 "register_operand")))
10729    (clobber (reg:CC FLAGS_REG))]
10730   "TARGET_BMI2 && reload_completed"
10731   [(set (match_dup 0)
10732         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10733   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10735 (define_insn "*bmi2_ashlsi3_1_zext"
10736   [(set (match_operand:DI 0 "register_operand" "=r")
10737         (zero_extend:DI
10738           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10739                      (match_operand:SI 2 "register_operand" "r"))))]
10740   "TARGET_64BIT && TARGET_BMI2"
10741   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10742   [(set_attr "type" "ishiftx")
10743    (set_attr "mode" "SI")])
10745 (define_insn "*ashlsi3_1_zext"
10746   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10747         (zero_extend:DI
10748           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10749                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10750    (clobber (reg:CC FLAGS_REG))]
10751   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10753   switch (get_attr_type (insn))
10754     {
10755     case TYPE_LEA:
10756     case TYPE_ISHIFTX:
10757       return "#";
10759     case TYPE_ALU:
10760       gcc_assert (operands[2] == const1_rtx);
10761       return "add{l}\t%k0, %k0";
10763     default:
10764       if (operands[2] == const1_rtx
10765           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10766         return "sal{l}\t%k0";
10767       else
10768         return "sal{l}\t{%2, %k0|%k0, %2}";
10769     }
10771   [(set_attr "isa" "*,*,bmi2")
10772    (set (attr "type")
10773      (cond [(eq_attr "alternative" "1")
10774               (const_string "lea")
10775             (eq_attr "alternative" "2")
10776               (const_string "ishiftx")
10777             (and (match_test "TARGET_DOUBLE_WITH_ADD")
10778                  (match_operand 2 "const1_operand"))
10779               (const_string "alu")
10780            ]
10781            (const_string "ishift")))
10782    (set (attr "length_immediate")
10783      (if_then_else
10784        (ior (eq_attr "type" "alu")
10785             (and (eq_attr "type" "ishift")
10786                  (and (match_operand 2 "const1_operand")
10787                       (ior (match_test "TARGET_SHIFT1")
10788                            (match_test "optimize_function_for_size_p (cfun)")))))
10789        (const_string "0")
10790        (const_string "*")))
10791    (set_attr "mode" "SI")])
10793 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10794 (define_split
10795   [(set (match_operand:DI 0 "register_operand")
10796         (zero_extend:DI
10797           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10798                      (match_operand:QI 2 "register_operand"))))
10799    (clobber (reg:CC FLAGS_REG))]
10800   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10801   [(set (match_dup 0)
10802         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10803   "operands[2] = gen_lowpart (SImode, operands[2]);")
10805 (define_insn "*ashlhi3_1"
10806   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10807         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10808                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10809    (clobber (reg:CC FLAGS_REG))]
10810   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10812   switch (get_attr_type (insn))
10813     {
10814     case TYPE_LEA:
10815       return "#";
10817     case TYPE_ALU:
10818       gcc_assert (operands[2] == const1_rtx);
10819       return "add{w}\t%0, %0";
10821     default:
10822       if (operands[2] == const1_rtx
10823           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10824         return "sal{w}\t%0";
10825       else
10826         return "sal{w}\t{%2, %0|%0, %2}";
10827     }
10829   [(set (attr "type")
10830      (cond [(eq_attr "alternative" "1")
10831               (const_string "lea")
10832             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10833                       (match_operand 0 "register_operand"))
10834                  (match_operand 2 "const1_operand"))
10835               (const_string "alu")
10836            ]
10837            (const_string "ishift")))
10838    (set (attr "length_immediate")
10839      (if_then_else
10840        (ior (eq_attr "type" "alu")
10841             (and (eq_attr "type" "ishift")
10842                  (and (match_operand 2 "const1_operand")
10843                       (ior (match_test "TARGET_SHIFT1")
10844                            (match_test "optimize_function_for_size_p (cfun)")))))
10845        (const_string "0")
10846        (const_string "*")))
10847    (set_attr "mode" "HI,SI")])
10849 (define_insn "*ashlqi3_1"
10850   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10851         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10852                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10853    (clobber (reg:CC FLAGS_REG))]
10854   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10856   switch (get_attr_type (insn))
10857     {
10858     case TYPE_LEA:
10859       return "#";
10861     case TYPE_ALU:
10862       gcc_assert (operands[2] == const1_rtx);
10863       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10864         return "add{l}\t%k0, %k0";
10865       else
10866         return "add{b}\t%0, %0";
10868     default:
10869       if (operands[2] == const1_rtx
10870           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10871         {
10872           if (get_attr_mode (insn) == MODE_SI)
10873             return "sal{l}\t%k0";
10874           else
10875             return "sal{b}\t%0";
10876         }
10877       else
10878         {
10879           if (get_attr_mode (insn) == MODE_SI)
10880             return "sal{l}\t{%2, %k0|%k0, %2}";
10881           else
10882             return "sal{b}\t{%2, %0|%0, %2}";
10883         }
10884     }
10886   [(set (attr "type")
10887      (cond [(eq_attr "alternative" "2")
10888               (const_string "lea")
10889             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10890                       (match_operand 0 "register_operand"))
10891                  (match_operand 2 "const1_operand"))
10892               (const_string "alu")
10893            ]
10894            (const_string "ishift")))
10895    (set (attr "length_immediate")
10896      (if_then_else
10897        (ior (eq_attr "type" "alu")
10898             (and (eq_attr "type" "ishift")
10899                  (and (match_operand 2 "const1_operand")
10900                       (ior (match_test "TARGET_SHIFT1")
10901                            (match_test "optimize_function_for_size_p (cfun)")))))
10902        (const_string "0")
10903        (const_string "*")))
10904    (set_attr "mode" "QI,SI,SI")
10905    ;; Potential partial reg stall on alternative 1.
10906    (set (attr "preferred_for_speed")
10907      (cond [(eq_attr "alternative" "1")
10908               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10909            (symbol_ref "true")))])
10911 (define_insn "*ashlqi3_1_slp"
10912   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10913         (ashift:QI (match_dup 0)
10914                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10915    (clobber (reg:CC FLAGS_REG))]
10916   "(optimize_function_for_size_p (cfun)
10917     || !TARGET_PARTIAL_FLAG_REG_STALL
10918     || (operands[1] == const1_rtx
10919         && (TARGET_SHIFT1
10920             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10922   switch (get_attr_type (insn))
10923     {
10924     case TYPE_ALU1:
10925       gcc_assert (operands[1] == const1_rtx);
10926       return "add{b}\t%0, %0";
10928     default:
10929       if (operands[1] == const1_rtx
10930           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10931         return "sal{b}\t%0";
10932       else
10933         return "sal{b}\t{%1, %0|%0, %1}";
10934     }
10936   [(set (attr "type")
10937      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10938                       (match_operand 0 "register_operand"))
10939                  (match_operand 1 "const1_operand"))
10940               (const_string "alu1")
10941            ]
10942            (const_string "ishift1")))
10943    (set (attr "length_immediate")
10944      (if_then_else
10945        (ior (eq_attr "type" "alu1")
10946             (and (eq_attr "type" "ishift1")
10947                  (and (match_operand 1 "const1_operand")
10948                       (ior (match_test "TARGET_SHIFT1")
10949                            (match_test "optimize_function_for_size_p (cfun)")))))
10950        (const_string "0")
10951        (const_string "*")))
10952    (set_attr "mode" "QI")])
10954 ;; Convert ashift to the lea pattern to avoid flags dependency.
10955 (define_split
10956   [(set (match_operand:SWI 0 "register_operand")
10957         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10958                     (match_operand 2 "const_0_to_3_operand")))
10959    (clobber (reg:CC FLAGS_REG))]
10960   "reload_completed
10961    && REGNO (operands[0]) != REGNO (operands[1])"
10962   [(set (match_dup 0)
10963         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10965   if (<MODE>mode != <LEAMODE>mode)
10966     {
10967       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10968       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10969     }
10970   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10973 ;; Convert ashift to the lea pattern to avoid flags dependency.
10974 (define_split
10975   [(set (match_operand:DI 0 "register_operand")
10976         (zero_extend:DI
10977           (ashift:SI (match_operand:SI 1 "index_register_operand")
10978                      (match_operand 2 "const_0_to_3_operand"))))
10979    (clobber (reg:CC FLAGS_REG))]
10980   "TARGET_64BIT && reload_completed
10981    && REGNO (operands[0]) != REGNO (operands[1])"
10982   [(set (match_dup 0)
10983         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10985   operands[1] = gen_lowpart (SImode, operands[1]);
10986   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10989 ;; This pattern can't accept a variable shift count, since shifts by
10990 ;; zero don't affect the flags.  We assume that shifts by constant
10991 ;; zero are optimized away.
10992 (define_insn "*ashl<mode>3_cmp"
10993   [(set (reg FLAGS_REG)
10994         (compare
10995           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10996                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10997           (const_int 0)))
10998    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10999         (ashift:SWI (match_dup 1) (match_dup 2)))]
11000   "(optimize_function_for_size_p (cfun)
11001     || !TARGET_PARTIAL_FLAG_REG_STALL
11002     || (operands[2] == const1_rtx
11003         && (TARGET_SHIFT1
11004             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11005    && ix86_match_ccmode (insn, CCGOCmode)
11006    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
11008   switch (get_attr_type (insn))
11009     {
11010     case TYPE_ALU:
11011       gcc_assert (operands[2] == const1_rtx);
11012       return "add{<imodesuffix>}\t%0, %0";
11014     default:
11015       if (operands[2] == const1_rtx
11016           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11017         return "sal{<imodesuffix>}\t%0";
11018       else
11019         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11020     }
11022   [(set (attr "type")
11023      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11024                       (match_operand 0 "register_operand"))
11025                  (match_operand 2 "const1_operand"))
11026               (const_string "alu")
11027            ]
11028            (const_string "ishift")))
11029    (set (attr "length_immediate")
11030      (if_then_else
11031        (ior (eq_attr "type" "alu")
11032             (and (eq_attr "type" "ishift")
11033                  (and (match_operand 2 "const1_operand")
11034                       (ior (match_test "TARGET_SHIFT1")
11035                            (match_test "optimize_function_for_size_p (cfun)")))))
11036        (const_string "0")
11037        (const_string "*")))
11038    (set_attr "mode" "<MODE>")])
11040 (define_insn "*ashlsi3_cmp_zext"
11041   [(set (reg FLAGS_REG)
11042         (compare
11043           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11044                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11045           (const_int 0)))
11046    (set (match_operand:DI 0 "register_operand" "=r")
11047         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11048   "TARGET_64BIT
11049    && (optimize_function_for_size_p (cfun)
11050        || !TARGET_PARTIAL_FLAG_REG_STALL
11051        || (operands[2] == const1_rtx
11052            && (TARGET_SHIFT1
11053                || TARGET_DOUBLE_WITH_ADD)))
11054    && ix86_match_ccmode (insn, CCGOCmode)
11055    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11057   switch (get_attr_type (insn))
11058     {
11059     case TYPE_ALU:
11060       gcc_assert (operands[2] == const1_rtx);
11061       return "add{l}\t%k0, %k0";
11063     default:
11064       if (operands[2] == const1_rtx
11065           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11066         return "sal{l}\t%k0";
11067       else
11068         return "sal{l}\t{%2, %k0|%k0, %2}";
11069     }
11071   [(set (attr "type")
11072      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11073                  (match_operand 2 "const1_operand"))
11074               (const_string "alu")
11075            ]
11076            (const_string "ishift")))
11077    (set (attr "length_immediate")
11078      (if_then_else
11079        (ior (eq_attr "type" "alu")
11080             (and (eq_attr "type" "ishift")
11081                  (and (match_operand 2 "const1_operand")
11082                       (ior (match_test "TARGET_SHIFT1")
11083                            (match_test "optimize_function_for_size_p (cfun)")))))
11084        (const_string "0")
11085        (const_string "*")))
11086    (set_attr "mode" "SI")])
11088 (define_insn "*ashl<mode>3_cconly"
11089   [(set (reg FLAGS_REG)
11090         (compare
11091           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11092                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11093           (const_int 0)))
11094    (clobber (match_scratch:SWI 0 "=<r>"))]
11095   "(optimize_function_for_size_p (cfun)
11096     || !TARGET_PARTIAL_FLAG_REG_STALL
11097     || (operands[2] == const1_rtx
11098         && (TARGET_SHIFT1
11099             || TARGET_DOUBLE_WITH_ADD)))
11100    && ix86_match_ccmode (insn, CCGOCmode)"
11102   switch (get_attr_type (insn))
11103     {
11104     case TYPE_ALU:
11105       gcc_assert (operands[2] == const1_rtx);
11106       return "add{<imodesuffix>}\t%0, %0";
11108     default:
11109       if (operands[2] == const1_rtx
11110           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11111         return "sal{<imodesuffix>}\t%0";
11112       else
11113         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11114     }
11116   [(set (attr "type")
11117      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11118                       (match_operand 0 "register_operand"))
11119                  (match_operand 2 "const1_operand"))
11120               (const_string "alu")
11121            ]
11122            (const_string "ishift")))
11123    (set (attr "length_immediate")
11124      (if_then_else
11125        (ior (eq_attr "type" "alu")
11126             (and (eq_attr "type" "ishift")
11127                  (and (match_operand 2 "const1_operand")
11128                       (ior (match_test "TARGET_SHIFT1")
11129                            (match_test "optimize_function_for_size_p (cfun)")))))
11130        (const_string "0")
11131        (const_string "*")))
11132    (set_attr "mode" "<MODE>")])
11134 ;; See comment above `ashl<mode>3' about how this works.
11136 (define_expand "<shift_insn><mode>3"
11137   [(set (match_operand:SDWIM 0 "<shift_operand>")
11138         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11139                            (match_operand:QI 2 "nonmemory_operand")))]
11140   ""
11141   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11143 ;; Avoid useless masking of count operand.
11144 (define_insn_and_split "*<shift_insn><mode>3_mask"
11145   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11146         (any_shiftrt:SWI48
11147           (match_operand:SWI48 1 "nonimmediate_operand")
11148           (subreg:QI
11149             (and:SI
11150               (match_operand:SI 2 "register_operand" "c,r")
11151               (match_operand:SI 3 "const_int_operand")) 0)))
11152    (clobber (reg:CC FLAGS_REG))]
11153   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11154    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11155       == GET_MODE_BITSIZE (<MODE>mode)-1
11156    && can_create_pseudo_p ()"
11157   "#"
11158   "&& 1"
11159   [(parallel
11160      [(set (match_dup 0)
11161            (any_shiftrt:SWI48 (match_dup 1)
11162                               (match_dup 2)))
11163       (clobber (reg:CC FLAGS_REG))])]
11164   "operands[2] = gen_lowpart (QImode, operands[2]);"
11165   [(set_attr "isa" "*,bmi2")])
11167 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
11168   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11169         (any_shiftrt:SWI48
11170           (match_operand:SWI48 1 "nonimmediate_operand")
11171           (and:QI
11172             (match_operand:QI 2 "register_operand" "c,r")
11173             (match_operand:QI 3 "const_int_operand"))))
11174    (clobber (reg:CC FLAGS_REG))]
11175   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11176    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11177       == GET_MODE_BITSIZE (<MODE>mode)-1
11178    && can_create_pseudo_p ()"
11179   "#"
11180   "&& 1"
11181   [(parallel
11182      [(set (match_dup 0)
11183            (any_shiftrt:SWI48 (match_dup 1)
11184                               (match_dup 2)))
11185       (clobber (reg:CC FLAGS_REG))])]
11186   ""
11187   [(set_attr "isa" "*,bmi2")])
11189 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
11190   [(set (match_operand:<DWI> 0 "register_operand")
11191         (any_shiftrt:<DWI>
11192           (match_operand:<DWI> 1 "register_operand")
11193           (subreg:QI
11194             (and:SI
11195               (match_operand:SI 2 "register_operand" "c")
11196               (match_operand:SI 3 "const_int_operand")) 0)))
11197    (clobber (reg:CC FLAGS_REG))]
11198   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11199    && can_create_pseudo_p ()"
11200   "#"
11201   "&& 1"
11202   [(parallel
11203      [(set (match_dup 4)
11204            (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11205                      (ashift:DWIH (match_dup 7)
11206                        (minus:QI (match_dup 8) (match_dup 2)))))
11207       (clobber (reg:CC FLAGS_REG))])
11208    (parallel
11209      [(set (match_dup 6)
11210            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11211       (clobber (reg:CC FLAGS_REG))])]
11213   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11215   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11217   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11218       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11219     {
11220       rtx tem = gen_reg_rtx (SImode);
11221       emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11222       operands[2] = tem;
11223     }
11225   operands[2] = gen_lowpart (QImode, operands[2]);
11227   if (!rtx_equal_p (operands[4], operands[5]))
11228     emit_move_insn (operands[4], operands[5]);
11231 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
11232   [(set (match_operand:<DWI> 0 "register_operand")
11233         (any_shiftrt:<DWI>
11234           (match_operand:<DWI> 1 "register_operand")
11235           (and:QI
11236             (match_operand:QI 2 "register_operand" "c")
11237             (match_operand:QI 3 "const_int_operand"))))
11238    (clobber (reg:CC FLAGS_REG))]
11239   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11240    && can_create_pseudo_p ()"
11241   "#"
11242   "&& 1"
11243   [(parallel
11244      [(set (match_dup 4)
11245            (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11246                      (ashift:DWIH (match_dup 7)
11247                        (minus:QI (match_dup 8) (match_dup 2)))))
11248       (clobber (reg:CC FLAGS_REG))])
11249    (parallel
11250      [(set (match_dup 6)
11251            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11252       (clobber (reg:CC FLAGS_REG))])]
11254   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11256   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11258   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11259       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11260     {
11261       rtx tem = gen_reg_rtx (QImode);
11262       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11263       operands[2] = tem;
11264     }
11266   if (!rtx_equal_p (operands[4], operands[5]))
11267     emit_move_insn (operands[4], operands[5]);
11270 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
11271   [(set (match_operand:DWI 0 "register_operand" "=&r")
11272         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11273                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11274    (clobber (reg:CC FLAGS_REG))]
11275   ""
11276   "#"
11277   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
11278   [(const_int 0)]
11279   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11280   [(set_attr "type" "multi")])
11282 ;; By default we don't ask for a scratch register, because when DWImode
11283 ;; values are manipulated, registers are already at a premium.  But if
11284 ;; we have one handy, we won't turn it away.
11286 (define_peephole2
11287   [(match_scratch:DWIH 3 "r")
11288    (parallel [(set (match_operand:<DWI> 0 "register_operand")
11289                    (any_shiftrt:<DWI>
11290                      (match_operand:<DWI> 1 "register_operand")
11291                      (match_operand:QI 2 "nonmemory_operand")))
11292               (clobber (reg:CC FLAGS_REG))])
11293    (match_dup 3)]
11294   "TARGET_CMOVE"
11295   [(const_int 0)]
11296   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11298 (define_insn "x86_64_shrd"
11299   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11300         (ior:DI (lshiftrt:DI (match_dup 0)
11301                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11302                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11303                   (minus:QI (const_int 64) (match_dup 2)))))
11304    (clobber (reg:CC FLAGS_REG))]
11305   "TARGET_64BIT"
11306   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11307   [(set_attr "type" "ishift")
11308    (set_attr "prefix_0f" "1")
11309    (set_attr "mode" "DI")
11310    (set_attr "athlon_decode" "vector")
11311    (set_attr "amdfam10_decode" "vector")
11312    (set_attr "bdver1_decode" "vector")])
11314 (define_insn "x86_shrd"
11315   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11316         (ior:SI (lshiftrt:SI (match_dup 0)
11317                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11318                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11319                   (minus:QI (const_int 32) (match_dup 2)))))
11320    (clobber (reg:CC FLAGS_REG))]
11321   ""
11322   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11323   [(set_attr "type" "ishift")
11324    (set_attr "prefix_0f" "1")
11325    (set_attr "mode" "SI")
11326    (set_attr "pent_pair" "np")
11327    (set_attr "athlon_decode" "vector")
11328    (set_attr "amdfam10_decode" "vector")
11329    (set_attr "bdver1_decode" "vector")])
11331 (define_insn "ashrdi3_cvt"
11332   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11333         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11334                      (match_operand:QI 2 "const_int_operand")))
11335    (clobber (reg:CC FLAGS_REG))]
11336   "TARGET_64BIT && INTVAL (operands[2]) == 63
11337    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11338    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11339   "@
11340    {cqto|cqo}
11341    sar{q}\t{%2, %0|%0, %2}"
11342   [(set_attr "type" "imovx,ishift")
11343    (set_attr "prefix_0f" "0,*")
11344    (set_attr "length_immediate" "0,*")
11345    (set_attr "modrm" "0,1")
11346    (set_attr "mode" "DI")])
11348 (define_insn "*ashrsi3_cvt_zext"
11349   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11350         (zero_extend:DI
11351           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11352                        (match_operand:QI 2 "const_int_operand"))))
11353    (clobber (reg:CC FLAGS_REG))]
11354   "TARGET_64BIT && INTVAL (operands[2]) == 31
11355    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11356    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11357   "@
11358    {cltd|cdq}
11359    sar{l}\t{%2, %k0|%k0, %2}"
11360   [(set_attr "type" "imovx,ishift")
11361    (set_attr "prefix_0f" "0,*")
11362    (set_attr "length_immediate" "0,*")
11363    (set_attr "modrm" "0,1")
11364    (set_attr "mode" "SI")])
11366 (define_insn "ashrsi3_cvt"
11367   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11368         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11369                      (match_operand:QI 2 "const_int_operand")))
11370    (clobber (reg:CC FLAGS_REG))]
11371   "INTVAL (operands[2]) == 31
11372    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11373    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11374   "@
11375    {cltd|cdq}
11376    sar{l}\t{%2, %0|%0, %2}"
11377   [(set_attr "type" "imovx,ishift")
11378    (set_attr "prefix_0f" "0,*")
11379    (set_attr "length_immediate" "0,*")
11380    (set_attr "modrm" "0,1")
11381    (set_attr "mode" "SI")])
11383 (define_expand "x86_shift<mode>_adj_3"
11384   [(use (match_operand:SWI48 0 "register_operand"))
11385    (use (match_operand:SWI48 1 "register_operand"))
11386    (use (match_operand:QI 2 "register_operand"))]
11387   ""
11389   rtx_code_label *label = gen_label_rtx ();
11390   rtx tmp;
11392   emit_insn (gen_testqi_ccz_1 (operands[2],
11393                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11395   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11396   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11397   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11398                               gen_rtx_LABEL_REF (VOIDmode, label),
11399                               pc_rtx);
11400   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11401   JUMP_LABEL (tmp) = label;
11403   emit_move_insn (operands[0], operands[1]);
11404   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11405                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11406   emit_label (label);
11407   LABEL_NUSES (label) = 1;
11409   DONE;
11412 (define_insn "*bmi2_<shift_insn><mode>3_1"
11413   [(set (match_operand:SWI48 0 "register_operand" "=r")
11414         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11415                            (match_operand:SWI48 2 "register_operand" "r")))]
11416   "TARGET_BMI2"
11417   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11418   [(set_attr "type" "ishiftx")
11419    (set_attr "mode" "<MODE>")])
11421 (define_insn "*<shift_insn><mode>3_1"
11422   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11423         (any_shiftrt:SWI48
11424           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11425           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11426    (clobber (reg:CC FLAGS_REG))]
11427   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11429   switch (get_attr_type (insn))
11430     {
11431     case TYPE_ISHIFTX:
11432       return "#";
11434     default:
11435       if (operands[2] == const1_rtx
11436           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11437         return "<shift>{<imodesuffix>}\t%0";
11438       else
11439         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11440     }
11442   [(set_attr "isa" "*,bmi2")
11443    (set_attr "type" "ishift,ishiftx")
11444    (set (attr "length_immediate")
11445      (if_then_else
11446        (and (match_operand 2 "const1_operand")
11447             (ior (match_test "TARGET_SHIFT1")
11448                  (match_test "optimize_function_for_size_p (cfun)")))
11449        (const_string "0")
11450        (const_string "*")))
11451    (set_attr "mode" "<MODE>")])
11453 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11454 (define_split
11455   [(set (match_operand:SWI48 0 "register_operand")
11456         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11457                            (match_operand:QI 2 "register_operand")))
11458    (clobber (reg:CC FLAGS_REG))]
11459   "TARGET_BMI2 && reload_completed"
11460   [(set (match_dup 0)
11461         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11462   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11464 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11465   [(set (match_operand:DI 0 "register_operand" "=r")
11466         (zero_extend:DI
11467           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11468                           (match_operand:SI 2 "register_operand" "r"))))]
11469   "TARGET_64BIT && TARGET_BMI2"
11470   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11471   [(set_attr "type" "ishiftx")
11472    (set_attr "mode" "SI")])
11474 (define_insn "*<shift_insn>si3_1_zext"
11475   [(set (match_operand:DI 0 "register_operand" "=r,r")
11476         (zero_extend:DI
11477           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11478                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11479    (clobber (reg:CC FLAGS_REG))]
11480   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11482   switch (get_attr_type (insn))
11483     {
11484     case TYPE_ISHIFTX:
11485       return "#";
11487     default:
11488       if (operands[2] == const1_rtx
11489           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11490         return "<shift>{l}\t%k0";
11491       else
11492         return "<shift>{l}\t{%2, %k0|%k0, %2}";
11493     }
11495   [(set_attr "isa" "*,bmi2")
11496    (set_attr "type" "ishift,ishiftx")
11497    (set (attr "length_immediate")
11498      (if_then_else
11499        (and (match_operand 2 "const1_operand")
11500             (ior (match_test "TARGET_SHIFT1")
11501                  (match_test "optimize_function_for_size_p (cfun)")))
11502        (const_string "0")
11503        (const_string "*")))
11504    (set_attr "mode" "SI")])
11506 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11507 (define_split
11508   [(set (match_operand:DI 0 "register_operand")
11509         (zero_extend:DI
11510           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11511                           (match_operand:QI 2 "register_operand"))))
11512    (clobber (reg:CC FLAGS_REG))]
11513   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11514   [(set (match_dup 0)
11515         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11516   "operands[2] = gen_lowpart (SImode, operands[2]);")
11518 (define_insn "*<shift_insn><mode>3_1"
11519   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11520         (any_shiftrt:SWI12
11521           (match_operand:SWI12 1 "nonimmediate_operand" "0")
11522           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11523    (clobber (reg:CC FLAGS_REG))]
11524   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11526   if (operands[2] == const1_rtx
11527       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11528     return "<shift>{<imodesuffix>}\t%0";
11529   else
11530     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11532   [(set_attr "type" "ishift")
11533    (set (attr "length_immediate")
11534      (if_then_else
11535        (and (match_operand 2 "const1_operand")
11536             (ior (match_test "TARGET_SHIFT1")
11537                  (match_test "optimize_function_for_size_p (cfun)")))
11538        (const_string "0")
11539        (const_string "*")))
11540    (set_attr "mode" "<MODE>")])
11542 (define_insn "*<shift_insn>qi3_1_slp"
11543   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11544         (any_shiftrt:QI (match_dup 0)
11545                         (match_operand:QI 1 "nonmemory_operand" "cI")))
11546    (clobber (reg:CC FLAGS_REG))]
11547   "(optimize_function_for_size_p (cfun)
11548     || !TARGET_PARTIAL_REG_STALL
11549     || (operands[1] == const1_rtx
11550         && TARGET_SHIFT1))"
11552   if (operands[1] == const1_rtx
11553       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11554     return "<shift>{b}\t%0";
11555   else
11556     return "<shift>{b}\t{%1, %0|%0, %1}";
11558   [(set_attr "type" "ishift1")
11559    (set (attr "length_immediate")
11560      (if_then_else
11561        (and (match_operand 1 "const1_operand")
11562             (ior (match_test "TARGET_SHIFT1")
11563                  (match_test "optimize_function_for_size_p (cfun)")))
11564        (const_string "0")
11565        (const_string "*")))
11566    (set_attr "mode" "QI")])
11568 ;; This pattern can't accept a variable shift count, since shifts by
11569 ;; zero don't affect the flags.  We assume that shifts by constant
11570 ;; zero are optimized away.
11571 (define_insn "*<shift_insn><mode>3_cmp"
11572   [(set (reg FLAGS_REG)
11573         (compare
11574           (any_shiftrt:SWI
11575             (match_operand:SWI 1 "nonimmediate_operand" "0")
11576             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11577           (const_int 0)))
11578    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11579         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11580   "(optimize_function_for_size_p (cfun)
11581     || !TARGET_PARTIAL_FLAG_REG_STALL
11582     || (operands[2] == const1_rtx
11583         && TARGET_SHIFT1))
11584    && ix86_match_ccmode (insn, CCGOCmode)
11585    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11587   if (operands[2] == const1_rtx
11588       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11589     return "<shift>{<imodesuffix>}\t%0";
11590   else
11591     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11593   [(set_attr "type" "ishift")
11594    (set (attr "length_immediate")
11595      (if_then_else
11596        (and (match_operand 2 "const1_operand")
11597             (ior (match_test "TARGET_SHIFT1")
11598                  (match_test "optimize_function_for_size_p (cfun)")))
11599        (const_string "0")
11600        (const_string "*")))
11601    (set_attr "mode" "<MODE>")])
11603 (define_insn "*<shift_insn>si3_cmp_zext"
11604   [(set (reg FLAGS_REG)
11605         (compare
11606           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11607                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
11608           (const_int 0)))
11609    (set (match_operand:DI 0 "register_operand" "=r")
11610         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11611   "TARGET_64BIT
11612    && (optimize_function_for_size_p (cfun)
11613        || !TARGET_PARTIAL_FLAG_REG_STALL
11614        || (operands[2] == const1_rtx
11615            && TARGET_SHIFT1))
11616    && ix86_match_ccmode (insn, CCGOCmode)
11617    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11619   if (operands[2] == const1_rtx
11620       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11621     return "<shift>{l}\t%k0";
11622   else
11623     return "<shift>{l}\t{%2, %k0|%k0, %2}";
11625   [(set_attr "type" "ishift")
11626    (set (attr "length_immediate")
11627      (if_then_else
11628        (and (match_operand 2 "const1_operand")
11629             (ior (match_test "TARGET_SHIFT1")
11630                  (match_test "optimize_function_for_size_p (cfun)")))
11631        (const_string "0")
11632        (const_string "*")))
11633    (set_attr "mode" "SI")])
11635 (define_insn "*<shift_insn><mode>3_cconly"
11636   [(set (reg FLAGS_REG)
11637         (compare
11638           (any_shiftrt:SWI
11639             (match_operand:SWI 1 "register_operand" "0")
11640             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11641           (const_int 0)))
11642    (clobber (match_scratch:SWI 0 "=<r>"))]
11643   "(optimize_function_for_size_p (cfun)
11644     || !TARGET_PARTIAL_FLAG_REG_STALL
11645     || (operands[2] == const1_rtx
11646         && TARGET_SHIFT1))
11647    && ix86_match_ccmode (insn, CCGOCmode)"
11649   if (operands[2] == const1_rtx
11650       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11651     return "<shift>{<imodesuffix>}\t%0";
11652   else
11653     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11655   [(set_attr "type" "ishift")
11656    (set (attr "length_immediate")
11657      (if_then_else
11658        (and (match_operand 2 "const1_operand")
11659             (ior (match_test "TARGET_SHIFT1")
11660                  (match_test "optimize_function_for_size_p (cfun)")))
11661        (const_string "0")
11662        (const_string "*")))
11663    (set_attr "mode" "<MODE>")])
11665 ;; Rotate instructions
11667 (define_expand "<rotate_insn>ti3"
11668   [(set (match_operand:TI 0 "register_operand")
11669         (any_rotate:TI (match_operand:TI 1 "register_operand")
11670                        (match_operand:QI 2 "nonmemory_operand")))]
11671   "TARGET_64BIT"
11673   if (const_1_to_63_operand (operands[2], VOIDmode))
11674     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11675                 (operands[0], operands[1], operands[2]));
11676   else
11677     FAIL;
11679   DONE;
11682 (define_expand "<rotate_insn>di3"
11683   [(set (match_operand:DI 0 "shiftdi_operand")
11684         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11685                        (match_operand:QI 2 "nonmemory_operand")))]
11686  ""
11688   if (TARGET_64BIT)
11689     ix86_expand_binary_operator (<CODE>, DImode, operands);
11690   else if (const_1_to_31_operand (operands[2], VOIDmode))
11691     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11692                 (operands[0], operands[1], operands[2]));
11693   else
11694     FAIL;
11696   DONE;
11699 (define_expand "<rotate_insn><mode>3"
11700   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11701         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11702                             (match_operand:QI 2 "nonmemory_operand")))]
11703   ""
11704   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11706 ;; Avoid useless masking of count operand.
11707 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11708   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11709         (any_rotate:SWI48
11710           (match_operand:SWI48 1 "nonimmediate_operand")
11711           (subreg:QI
11712             (and:SI
11713               (match_operand:SI 2 "register_operand" "c")
11714               (match_operand:SI 3 "const_int_operand")) 0)))
11715    (clobber (reg:CC FLAGS_REG))]
11716   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11717    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11718       == GET_MODE_BITSIZE (<MODE>mode)-1
11719    && can_create_pseudo_p ()"
11720   "#"
11721   "&& 1"
11722   [(parallel
11723      [(set (match_dup 0)
11724            (any_rotate:SWI48 (match_dup 1)
11725                              (match_dup 2)))
11726       (clobber (reg:CC FLAGS_REG))])]
11727   "operands[2] = gen_lowpart (QImode, operands[2]);")
11729 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11730   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11731         (any_rotate:SWI48
11732           (match_operand:SWI48 1 "nonimmediate_operand")
11733           (and:QI
11734             (match_operand:QI 2 "register_operand" "c")
11735             (match_operand:QI 3 "const_int_operand"))))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11738    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11739       == GET_MODE_BITSIZE (<MODE>mode)-1
11740    && can_create_pseudo_p ()"
11741   "#"
11742   "&& 1"
11743   [(parallel
11744      [(set (match_dup 0)
11745            (any_rotate:SWI48 (match_dup 1)
11746                              (match_dup 2)))
11747       (clobber (reg:CC FLAGS_REG))])])
11749 ;; Implement rotation using two double-precision
11750 ;; shift instructions and a scratch register.
11752 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11753  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11754        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11755                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11756   (clobber (reg:CC FLAGS_REG))
11757   (clobber (match_scratch:DWIH 3 "=&r"))]
11758  ""
11759  "#"
11760  "reload_completed"
11761  [(set (match_dup 3) (match_dup 4))
11762   (parallel
11763    [(set (match_dup 4)
11764          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11765                    (lshiftrt:DWIH (match_dup 5)
11766                                   (minus:QI (match_dup 6) (match_dup 2)))))
11767     (clobber (reg:CC FLAGS_REG))])
11768   (parallel
11769    [(set (match_dup 5)
11770          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11771                    (lshiftrt:DWIH (match_dup 3)
11772                                   (minus:QI (match_dup 6) (match_dup 2)))))
11773     (clobber (reg:CC FLAGS_REG))])]
11775   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11777   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11780 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11781  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11782        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11783                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11784   (clobber (reg:CC FLAGS_REG))
11785   (clobber (match_scratch:DWIH 3 "=&r"))]
11786  ""
11787  "#"
11788  "reload_completed"
11789  [(set (match_dup 3) (match_dup 4))
11790   (parallel
11791    [(set (match_dup 4)
11792          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11793                    (ashift:DWIH (match_dup 5)
11794                                 (minus:QI (match_dup 6) (match_dup 2)))))
11795     (clobber (reg:CC FLAGS_REG))])
11796   (parallel
11797    [(set (match_dup 5)
11798          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11799                    (ashift:DWIH (match_dup 3)
11800                                 (minus:QI (match_dup 6) (match_dup 2)))))
11801     (clobber (reg:CC FLAGS_REG))])]
11803   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11805   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11808 (define_mode_attr rorx_immediate_operand
11809         [(SI "const_0_to_31_operand")
11810          (DI "const_0_to_63_operand")])
11812 (define_insn "*bmi2_rorx<mode>3_1"
11813   [(set (match_operand:SWI48 0 "register_operand" "=r")
11814         (rotatert:SWI48
11815           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11816           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11817   "TARGET_BMI2"
11818   "rorx\t{%2, %1, %0|%0, %1, %2}"
11819   [(set_attr "type" "rotatex")
11820    (set_attr "mode" "<MODE>")])
11822 (define_insn "*<rotate_insn><mode>3_1"
11823   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11824         (any_rotate:SWI48
11825           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11826           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11827    (clobber (reg:CC FLAGS_REG))]
11828   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11830   switch (get_attr_type (insn))
11831     {
11832     case TYPE_ROTATEX:
11833       return "#";
11835     default:
11836       if (operands[2] == const1_rtx
11837           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11838         return "<rotate>{<imodesuffix>}\t%0";
11839       else
11840         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11841     }
11843   [(set_attr "isa" "*,bmi2")
11844    (set_attr "type" "rotate,rotatex")
11845    (set (attr "length_immediate")
11846      (if_then_else
11847        (and (eq_attr "type" "rotate")
11848             (and (match_operand 2 "const1_operand")
11849                  (ior (match_test "TARGET_SHIFT1")
11850                       (match_test "optimize_function_for_size_p (cfun)"))))
11851        (const_string "0")
11852        (const_string "*")))
11853    (set_attr "mode" "<MODE>")])
11855 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11856 (define_split
11857   [(set (match_operand:SWI48 0 "register_operand")
11858         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11859                       (match_operand:QI 2 "const_int_operand")))
11860    (clobber (reg:CC FLAGS_REG))]
11861   "TARGET_BMI2 && reload_completed"
11862   [(set (match_dup 0)
11863         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11865   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11867   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11870 (define_split
11871   [(set (match_operand:SWI48 0 "register_operand")
11872         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11873                         (match_operand:QI 2 "const_int_operand")))
11874    (clobber (reg:CC FLAGS_REG))]
11875   "TARGET_BMI2 && reload_completed"
11876   [(set (match_dup 0)
11877         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11879 (define_insn "*bmi2_rorxsi3_1_zext"
11880   [(set (match_operand:DI 0 "register_operand" "=r")
11881         (zero_extend:DI
11882           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11883                        (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11884   "TARGET_64BIT && TARGET_BMI2"
11885   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11886   [(set_attr "type" "rotatex")
11887    (set_attr "mode" "SI")])
11889 (define_insn "*<rotate_insn>si3_1_zext"
11890   [(set (match_operand:DI 0 "register_operand" "=r,r")
11891         (zero_extend:DI
11892           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11893                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11894    (clobber (reg:CC FLAGS_REG))]
11895   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11897   switch (get_attr_type (insn))
11898     {
11899     case TYPE_ROTATEX:
11900       return "#";
11902     default:
11903       if (operands[2] == const1_rtx
11904           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11905         return "<rotate>{l}\t%k0";
11906       else
11907         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11908     }
11910   [(set_attr "isa" "*,bmi2")
11911    (set_attr "type" "rotate,rotatex")
11912    (set (attr "length_immediate")
11913      (if_then_else
11914        (and (eq_attr "type" "rotate")
11915             (and (match_operand 2 "const1_operand")
11916                  (ior (match_test "TARGET_SHIFT1")
11917                       (match_test "optimize_function_for_size_p (cfun)"))))
11918        (const_string "0")
11919        (const_string "*")))
11920    (set_attr "mode" "SI")])
11922 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11923 (define_split
11924   [(set (match_operand:DI 0 "register_operand")
11925         (zero_extend:DI
11926           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11927                      (match_operand:QI 2 "const_int_operand"))))
11928    (clobber (reg:CC FLAGS_REG))]
11929   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11930   [(set (match_dup 0)
11931         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11933   int bitsize = GET_MODE_BITSIZE (SImode);
11935   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11938 (define_split
11939   [(set (match_operand:DI 0 "register_operand")
11940         (zero_extend:DI
11941           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11942                        (match_operand:QI 2 "const_int_operand"))))
11943    (clobber (reg:CC FLAGS_REG))]
11944   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11945   [(set (match_dup 0)
11946         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11948 (define_insn "*<rotate_insn><mode>3_1"
11949   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11950         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11951                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11952    (clobber (reg:CC FLAGS_REG))]
11953   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11955   if (operands[2] == const1_rtx
11956       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11957     return "<rotate>{<imodesuffix>}\t%0";
11958   else
11959     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11961   [(set_attr "type" "rotate")
11962    (set (attr "length_immediate")
11963      (if_then_else
11964        (and (match_operand 2 "const1_operand")
11965             (ior (match_test "TARGET_SHIFT1")
11966                  (match_test "optimize_function_for_size_p (cfun)")))
11967        (const_string "0")
11968        (const_string "*")))
11969    (set_attr "mode" "<MODE>")])
11971 (define_insn "*<rotate_insn>qi3_1_slp"
11972   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11973         (any_rotate:QI (match_dup 0)
11974                        (match_operand:QI 1 "nonmemory_operand" "cI")))
11975    (clobber (reg:CC FLAGS_REG))]
11976   "(optimize_function_for_size_p (cfun)
11977     || !TARGET_PARTIAL_REG_STALL
11978     || (operands[1] == const1_rtx
11979         && TARGET_SHIFT1))"
11981   if (operands[1] == const1_rtx
11982       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11983     return "<rotate>{b}\t%0";
11984   else
11985     return "<rotate>{b}\t{%1, %0|%0, %1}";
11987   [(set_attr "type" "rotate1")
11988    (set (attr "length_immediate")
11989      (if_then_else
11990        (and (match_operand 1 "const1_operand")
11991             (ior (match_test "TARGET_SHIFT1")
11992                  (match_test "optimize_function_for_size_p (cfun)")))
11993        (const_string "0")
11994        (const_string "*")))
11995    (set_attr "mode" "QI")])
11997 (define_split
11998  [(set (match_operand:HI 0 "QIreg_operand")
11999        (any_rotate:HI (match_dup 0) (const_int 8)))
12000   (clobber (reg:CC FLAGS_REG))]
12001  "reload_completed
12002   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
12003  [(parallel [(set (strict_low_part (match_dup 0))
12004                   (bswap:HI (match_dup 0)))
12005              (clobber (reg:CC FLAGS_REG))])])
12007 ;; Bit set / bit test instructions
12009 ;; %%% bts, btr, btc
12011 ;; These instructions are *slow* when applied to memory.
12013 (define_code_attr btsc [(ior "bts") (xor "btc")])
12015 (define_insn "*<btsc><mode>"
12016   [(set (match_operand:SWI48 0 "register_operand" "=r")
12017         (any_or:SWI48
12018           (ashift:SWI48 (const_int 1)
12019                         (match_operand:QI 2 "register_operand" "r"))
12020           (match_operand:SWI48 1 "register_operand" "0")))
12021    (clobber (reg:CC FLAGS_REG))]
12022   "TARGET_USE_BT"
12023   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12024   [(set_attr "type" "alu1")
12025    (set_attr "prefix_0f" "1")
12026    (set_attr "znver1_decode" "double")
12027    (set_attr "mode" "<MODE>")])
12029 ;; Avoid useless masking of count operand.
12030 (define_insn_and_split "*<btsc><mode>_mask"
12031   [(set (match_operand:SWI48 0 "register_operand")
12032         (any_or:SWI48
12033           (ashift:SWI48
12034             (const_int 1)
12035             (subreg:QI
12036               (and:SI
12037                 (match_operand:SI 1 "register_operand")
12038                 (match_operand:SI 2 "const_int_operand")) 0))
12039           (match_operand:SWI48 3 "register_operand")))
12040    (clobber (reg:CC FLAGS_REG))]
12041   "TARGET_USE_BT
12042    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12043       == GET_MODE_BITSIZE (<MODE>mode)-1
12044    && can_create_pseudo_p ()"
12045   "#"
12046   "&& 1"
12047   [(parallel
12048      [(set (match_dup 0)
12049            (any_or:SWI48
12050              (ashift:SWI48 (const_int 1)
12051                            (match_dup 1))
12052              (match_dup 3)))
12053       (clobber (reg:CC FLAGS_REG))])]
12054   "operands[1] = gen_lowpart (QImode, operands[1]);")
12056 (define_insn_and_split "*<btsc><mode>_mask_1"
12057   [(set (match_operand:SWI48 0 "register_operand")
12058         (any_or:SWI48
12059           (ashift:SWI48
12060             (const_int 1)
12061             (and:QI
12062               (match_operand:QI 1 "register_operand")
12063               (match_operand:QI 2 "const_int_operand")))
12064           (match_operand:SWI48 3 "register_operand")))
12065    (clobber (reg:CC FLAGS_REG))]
12066   "TARGET_USE_BT
12067    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12068       == GET_MODE_BITSIZE (<MODE>mode)-1
12069    && can_create_pseudo_p ()"
12070   "#"
12071   "&& 1"
12072   [(parallel
12073      [(set (match_dup 0)
12074            (any_or:SWI48
12075              (ashift:SWI48 (const_int 1)
12076                            (match_dup 1))
12077              (match_dup 3)))
12078       (clobber (reg:CC FLAGS_REG))])])
12080 (define_insn "*btr<mode>"
12081   [(set (match_operand:SWI48 0 "register_operand" "=r")
12082         (and:SWI48
12083           (rotate:SWI48 (const_int -2)
12084                         (match_operand:QI 2 "register_operand" "r"))
12085         (match_operand:SWI48 1 "register_operand" "0")))
12086    (clobber (reg:CC FLAGS_REG))]
12087   "TARGET_USE_BT"
12088   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12089   [(set_attr "type" "alu1")
12090    (set_attr "prefix_0f" "1")
12091    (set_attr "znver1_decode" "double")
12092    (set_attr "mode" "<MODE>")])
12094 ;; Avoid useless masking of count operand.
12095 (define_insn_and_split "*btr<mode>_mask"
12096   [(set (match_operand:SWI48 0 "register_operand")
12097         (and:SWI48
12098           (rotate:SWI48
12099             (const_int -2)
12100             (subreg:QI
12101               (and:SI
12102                 (match_operand:SI 1 "register_operand")
12103                 (match_operand:SI 2 "const_int_operand")) 0))
12104           (match_operand:SWI48 3 "register_operand")))
12105    (clobber (reg:CC FLAGS_REG))]
12106   "TARGET_USE_BT
12107    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12108       == GET_MODE_BITSIZE (<MODE>mode)-1
12109    && can_create_pseudo_p ()"
12110   "#"
12111   "&& 1"
12112   [(parallel
12113      [(set (match_dup 0)
12114            (and:SWI48
12115              (rotate:SWI48 (const_int -2)
12116                            (match_dup 1))
12117              (match_dup 3)))
12118       (clobber (reg:CC FLAGS_REG))])]
12119   "operands[1] = gen_lowpart (QImode, operands[1]);")
12121 (define_insn_and_split "*btr<mode>_mask_1"
12122   [(set (match_operand:SWI48 0 "register_operand")
12123         (and:SWI48
12124           (rotate:SWI48
12125             (const_int -2)
12126             (and:QI
12127               (match_operand:QI 1 "register_operand")
12128               (match_operand:QI 2 "const_int_operand")))
12129           (match_operand:SWI48 3 "register_operand")))
12130    (clobber (reg:CC FLAGS_REG))]
12131   "TARGET_USE_BT
12132    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12133       == GET_MODE_BITSIZE (<MODE>mode)-1
12134    && can_create_pseudo_p ()"
12135   "#"
12136   "&& 1"
12137   [(parallel
12138      [(set (match_dup 0)
12139            (and:SWI48
12140              (rotate:SWI48 (const_int -2)
12141                            (match_dup 1))
12142              (match_dup 3)))
12143       (clobber (reg:CC FLAGS_REG))])])
12145 ;; These instructions are never faster than the corresponding
12146 ;; and/ior/xor operations when using immediate operand, so with
12147 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
12148 ;; relevant immediates within the instruction itself, so operating
12149 ;; on bits in the high 32-bits of a register becomes easier.
12151 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12152 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12153 ;; negdf respectively, so they can never be disabled entirely.
12155 (define_insn "*btsq_imm"
12156   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12157                          (const_int 1)
12158                          (match_operand 1 "const_0_to_63_operand" "J"))
12159         (const_int 1))
12160    (clobber (reg:CC FLAGS_REG))]
12161   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12162   "bts{q}\t{%1, %0|%0, %1}"
12163   [(set_attr "type" "alu1")
12164    (set_attr "prefix_0f" "1")
12165    (set_attr "znver1_decode" "double")
12166    (set_attr "mode" "DI")])
12168 (define_insn "*btrq_imm"
12169   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12170                          (const_int 1)
12171                          (match_operand 1 "const_0_to_63_operand" "J"))
12172         (const_int 0))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12175   "btr{q}\t{%1, %0|%0, %1}"
12176   [(set_attr "type" "alu1")
12177    (set_attr "prefix_0f" "1")
12178    (set_attr "znver1_decode" "double")
12179    (set_attr "mode" "DI")])
12181 (define_insn "*btcq_imm"
12182   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12183                          (const_int 1)
12184                          (match_operand 1 "const_0_to_63_operand" "J"))
12185         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12186    (clobber (reg:CC FLAGS_REG))]
12187   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12188   "btc{q}\t{%1, %0|%0, %1}"
12189   [(set_attr "type" "alu1")
12190    (set_attr "prefix_0f" "1")
12191    (set_attr "znver1_decode" "double")
12192    (set_attr "mode" "DI")])
12194 ;; Allow Nocona to avoid these instructions if a register is available.
12196 (define_peephole2
12197   [(match_scratch:DI 2 "r")
12198    (parallel [(set (zero_extract:DI
12199                      (match_operand:DI 0 "nonimmediate_operand")
12200                      (const_int 1)
12201                      (match_operand 1 "const_0_to_63_operand"))
12202                    (const_int 1))
12203               (clobber (reg:CC FLAGS_REG))])]
12204   "TARGET_64BIT && !TARGET_USE_BT"
12205   [(parallel [(set (match_dup 0)
12206                    (ior:DI (match_dup 0) (match_dup 3)))
12207               (clobber (reg:CC FLAGS_REG))])]
12209   int i = INTVAL (operands[1]);
12211   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12213   if (!x86_64_immediate_operand (operands[3], DImode))
12214     {
12215       emit_move_insn (operands[2], operands[3]);
12216       operands[3] = operands[2];
12217     }
12220 (define_peephole2
12221   [(match_scratch:DI 2 "r")
12222    (parallel [(set (zero_extract:DI
12223                      (match_operand:DI 0 "nonimmediate_operand")
12224                      (const_int 1)
12225                      (match_operand 1 "const_0_to_63_operand"))
12226                    (const_int 0))
12227               (clobber (reg:CC FLAGS_REG))])]
12228   "TARGET_64BIT && !TARGET_USE_BT"
12229   [(parallel [(set (match_dup 0)
12230                    (and:DI (match_dup 0) (match_dup 3)))
12231               (clobber (reg:CC FLAGS_REG))])]
12233   int i = INTVAL (operands[1]);
12235   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12237   if (!x86_64_immediate_operand (operands[3], DImode))
12238     {
12239       emit_move_insn (operands[2], operands[3]);
12240       operands[3] = operands[2];
12241     }
12244 (define_peephole2
12245   [(match_scratch:DI 2 "r")
12246    (parallel [(set (zero_extract:DI
12247                      (match_operand:DI 0 "nonimmediate_operand")
12248                      (const_int 1)
12249                      (match_operand 1 "const_0_to_63_operand"))
12250               (not:DI (zero_extract:DI
12251                         (match_dup 0) (const_int 1) (match_dup 1))))
12252               (clobber (reg:CC FLAGS_REG))])]
12253   "TARGET_64BIT && !TARGET_USE_BT"
12254   [(parallel [(set (match_dup 0)
12255                    (xor:DI (match_dup 0) (match_dup 3)))
12256               (clobber (reg:CC FLAGS_REG))])]
12258   int i = INTVAL (operands[1]);
12260   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12262   if (!x86_64_immediate_operand (operands[3], DImode))
12263     {
12264       emit_move_insn (operands[2], operands[3]);
12265       operands[3] = operands[2];
12266     }
12269 ;; %%% bt
12271 (define_insn "*bt<mode>"
12272   [(set (reg:CCC FLAGS_REG)
12273         (compare:CCC
12274           (zero_extract:SWI48
12275             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12276             (const_int 1)
12277             (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12278           (const_int 0)))]
12279   ""
12281   switch (get_attr_mode (insn))
12282     {
12283     case MODE_SI:
12284       return "bt{l}\t{%1, %k0|%k0, %1}";
12286     case MODE_DI:
12287       return "bt{q}\t{%q1, %0|%0, %q1}";
12289     default:
12290       gcc_unreachable ();
12291     }
12293   [(set_attr "type" "alu1")
12294    (set_attr "prefix_0f" "1")
12295    (set (attr "mode")
12296         (if_then_else
12297           (and (match_test "CONST_INT_P (operands[1])")
12298                (match_test "INTVAL (operands[1]) < 32"))
12299           (const_string "SI")
12300           (const_string "<MODE>")))])
12302 (define_insn_and_split "*jcc_bt<mode>"
12303   [(set (pc)
12304         (if_then_else (match_operator 0 "bt_comparison_operator"
12305                         [(zero_extract:SWI48
12306                            (match_operand:SWI48 1 "nonimmediate_operand")
12307                            (const_int 1)
12308                            (match_operand:SI 2 "nonmemory_operand"))
12309                          (const_int 0)])
12310                       (label_ref (match_operand 3))
12311                       (pc)))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12314    && (CONST_INT_P (operands[2])
12315        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12316           && INTVAL (operands[2])
12317                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12318        : !memory_operand (operands[1], <MODE>mode))
12319    && can_create_pseudo_p ()"
12320   "#"
12321   "&& 1"
12322   [(set (reg:CCC FLAGS_REG)
12323         (compare:CCC
12324           (zero_extract:SWI48
12325             (match_dup 1)
12326             (const_int 1)
12327             (match_dup 2))
12328           (const_int 0)))
12329    (set (pc)
12330         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12331                       (label_ref (match_dup 3))
12332                       (pc)))]
12334   operands[0] = shallow_copy_rtx (operands[0]);
12335   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12338 (define_insn_and_split "*jcc_bt<mode>_1"
12339   [(set (pc)
12340         (if_then_else (match_operator 0 "bt_comparison_operator"
12341                         [(zero_extract:SWI48
12342                            (match_operand:SWI48 1 "register_operand")
12343                            (const_int 1)
12344                            (zero_extend:SI
12345                              (match_operand:QI 2 "register_operand")))
12346                          (const_int 0)])
12347                       (label_ref (match_operand 3))
12348                       (pc)))
12349    (clobber (reg:CC FLAGS_REG))]
12350   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12351    && can_create_pseudo_p ()"
12352   "#"
12353   "&& 1"
12354   [(set (reg:CCC FLAGS_REG)
12355         (compare:CCC
12356           (zero_extract:SWI48
12357             (match_dup 1)
12358             (const_int 1)
12359             (match_dup 2))
12360           (const_int 0)))
12361    (set (pc)
12362         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12363                       (label_ref (match_dup 3))
12364                       (pc)))]
12366   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12367   operands[0] = shallow_copy_rtx (operands[0]);
12368   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12371 ;; Avoid useless masking of bit offset operand.
12372 (define_insn_and_split "*jcc_bt<mode>_mask"
12373   [(set (pc)
12374         (if_then_else (match_operator 0 "bt_comparison_operator"
12375                         [(zero_extract:SWI48
12376                            (match_operand:SWI48 1 "register_operand")
12377                            (const_int 1)
12378                            (and:SI
12379                              (match_operand:SI 2 "register_operand")
12380                              (match_operand 3 "const_int_operand")))])
12381                       (label_ref (match_operand 4))
12382                       (pc)))
12383    (clobber (reg:CC FLAGS_REG))]
12384   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12385    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12386       == GET_MODE_BITSIZE (<MODE>mode)-1
12387    && can_create_pseudo_p ()"
12388   "#"
12389   "&& 1"
12390   [(set (reg:CCC FLAGS_REG)
12391         (compare:CCC
12392           (zero_extract:SWI48
12393             (match_dup 1)
12394             (const_int 1)
12395             (match_dup 2))
12396           (const_int 0)))
12397    (set (pc)
12398         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12399                       (label_ref (match_dup 4))
12400                       (pc)))]
12402   operands[0] = shallow_copy_rtx (operands[0]);
12403   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12406 ;; Store-flag instructions.
12408 ;; For all sCOND expanders, also expand the compare or test insn that
12409 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12411 (define_insn_and_split "*setcc_di_1"
12412   [(set (match_operand:DI 0 "register_operand" "=q")
12413         (match_operator:DI 1 "ix86_comparison_operator"
12414           [(reg FLAGS_REG) (const_int 0)]))]
12415   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12416   "#"
12417   "&& reload_completed"
12418   [(set (match_dup 2) (match_dup 1))
12419    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12421   operands[1] = shallow_copy_rtx (operands[1]);
12422   PUT_MODE (operands[1], QImode);
12423   operands[2] = gen_lowpart (QImode, operands[0]);
12426 (define_insn_and_split "*setcc_si_1_and"
12427   [(set (match_operand:SI 0 "register_operand" "=q")
12428         (match_operator:SI 1 "ix86_comparison_operator"
12429           [(reg FLAGS_REG) (const_int 0)]))
12430    (clobber (reg:CC FLAGS_REG))]
12431   "!TARGET_PARTIAL_REG_STALL
12432    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12433   "#"
12434   "&& reload_completed"
12435   [(set (match_dup 2) (match_dup 1))
12436    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12437               (clobber (reg:CC FLAGS_REG))])]
12439   operands[1] = shallow_copy_rtx (operands[1]);
12440   PUT_MODE (operands[1], QImode);
12441   operands[2] = gen_lowpart (QImode, operands[0]);
12444 (define_insn_and_split "*setcc_si_1_movzbl"
12445   [(set (match_operand:SI 0 "register_operand" "=q")
12446         (match_operator:SI 1 "ix86_comparison_operator"
12447           [(reg FLAGS_REG) (const_int 0)]))]
12448   "!TARGET_PARTIAL_REG_STALL
12449    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12450   "#"
12451   "&& reload_completed"
12452   [(set (match_dup 2) (match_dup 1))
12453    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12455   operands[1] = shallow_copy_rtx (operands[1]);
12456   PUT_MODE (operands[1], QImode);
12457   operands[2] = gen_lowpart (QImode, operands[0]);
12460 (define_insn "*setcc_qi"
12461   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12462         (match_operator:QI 1 "ix86_comparison_operator"
12463           [(reg FLAGS_REG) (const_int 0)]))]
12464   ""
12465   "set%C1\t%0"
12466   [(set_attr "type" "setcc")
12467    (set_attr "mode" "QI")])
12469 (define_insn "*setcc_qi_slp"
12470   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12471         (match_operator:QI 1 "ix86_comparison_operator"
12472           [(reg FLAGS_REG) (const_int 0)]))]
12473   ""
12474   "set%C1\t%0"
12475   [(set_attr "type" "setcc")
12476    (set_attr "mode" "QI")])
12478 ;; In general it is not safe to assume too much about CCmode registers,
12479 ;; so simplify-rtx stops when it sees a second one.  Under certain
12480 ;; conditions this is safe on x86, so help combine not create
12482 ;;      seta    %al
12483 ;;      testb   %al, %al
12484 ;;      sete    %al
12486 (define_split
12487   [(set (match_operand:QI 0 "nonimmediate_operand")
12488         (ne:QI (match_operator 1 "ix86_comparison_operator"
12489                  [(reg FLAGS_REG) (const_int 0)])
12490             (const_int 0)))]
12491   ""
12492   [(set (match_dup 0) (match_dup 1))]
12494   operands[1] = shallow_copy_rtx (operands[1]);
12495   PUT_MODE (operands[1], QImode);
12498 (define_split
12499   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12500         (ne:QI (match_operator 1 "ix86_comparison_operator"
12501                  [(reg FLAGS_REG) (const_int 0)])
12502             (const_int 0)))]
12503   ""
12504   [(set (match_dup 0) (match_dup 1))]
12506   operands[1] = shallow_copy_rtx (operands[1]);
12507   PUT_MODE (operands[1], QImode);
12510 (define_split
12511   [(set (match_operand:QI 0 "nonimmediate_operand")
12512         (eq:QI (match_operator 1 "ix86_comparison_operator"
12513                  [(reg FLAGS_REG) (const_int 0)])
12514             (const_int 0)))]
12515   ""
12516   [(set (match_dup 0) (match_dup 1))]
12518   operands[1] = shallow_copy_rtx (operands[1]);
12519   PUT_MODE (operands[1], QImode);
12520   PUT_CODE (operands[1],
12521             ix86_reverse_condition (GET_CODE (operands[1]),
12522                                     GET_MODE (XEXP (operands[1], 0))));
12524   /* Make sure that (a) the CCmode we have for the flags is strong
12525      enough for the reversed compare or (b) we have a valid FP compare.  */
12526   if (! ix86_comparison_operator (operands[1], VOIDmode))
12527     FAIL;
12530 (define_split
12531   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12532         (eq:QI (match_operator 1 "ix86_comparison_operator"
12533                  [(reg FLAGS_REG) (const_int 0)])
12534             (const_int 0)))]
12535   ""
12536   [(set (match_dup 0) (match_dup 1))]
12538   operands[1] = shallow_copy_rtx (operands[1]);
12539   PUT_MODE (operands[1], QImode);
12540   PUT_CODE (operands[1],
12541             ix86_reverse_condition (GET_CODE (operands[1]),
12542                                     GET_MODE (XEXP (operands[1], 0))));
12544   /* Make sure that (a) the CCmode we have for the flags is strong
12545      enough for the reversed compare or (b) we have a valid FP compare.  */
12546   if (! ix86_comparison_operator (operands[1], VOIDmode))
12547     FAIL;
12550 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12551 ;; subsequent logical operations are used to imitate conditional moves.
12552 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12553 ;; it directly.
12555 (define_insn "setcc_<mode>_sse"
12556   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12557         (match_operator:MODEF 3 "sse_comparison_operator"
12558           [(match_operand:MODEF 1 "register_operand" "0,x")
12559            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12560   "SSE_FLOAT_MODE_P (<MODE>mode)"
12561   "@
12562    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12563    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12564   [(set_attr "isa" "noavx,avx")
12565    (set_attr "type" "ssecmp")
12566    (set_attr "length_immediate" "1")
12567    (set_attr "prefix" "orig,vex")
12568    (set_attr "mode" "<MODE>")])
12570 ;; Basic conditional jump instructions.
12571 ;; We ignore the overflow flag for signed branch instructions.
12573 (define_insn "*jcc"
12574   [(set (pc)
12575         (if_then_else (match_operator 1 "ix86_comparison_operator"
12576                                       [(reg FLAGS_REG) (const_int 0)])
12577                       (label_ref (match_operand 0))
12578                       (pc)))]
12579   ""
12580   "%!%+j%C1\t%l0"
12581   [(set_attr "type" "ibr")
12582    (set_attr "modrm" "0")
12583    (set (attr "length")
12584         (if_then_else
12585           (and (ge (minus (match_dup 0) (pc))
12586                    (const_int -126))
12587                (lt (minus (match_dup 0) (pc))
12588                    (const_int 128)))
12589           (const_int 2)
12590           (const_int 6)))])
12592 ;; In general it is not safe to assume too much about CCmode registers,
12593 ;; so simplify-rtx stops when it sees a second one.  Under certain
12594 ;; conditions this is safe on x86, so help combine not create
12596 ;;      seta    %al
12597 ;;      testb   %al, %al
12598 ;;      je      Lfoo
12600 (define_split
12601   [(set (pc)
12602         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12603                                       [(reg FLAGS_REG) (const_int 0)])
12604                           (const_int 0))
12605                       (label_ref (match_operand 1))
12606                       (pc)))]
12607   ""
12608   [(set (pc)
12609         (if_then_else (match_dup 0)
12610                       (label_ref (match_dup 1))
12611                       (pc)))]
12613   operands[0] = shallow_copy_rtx (operands[0]);
12614   PUT_MODE (operands[0], VOIDmode);
12617 (define_split
12618   [(set (pc)
12619         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12620                                       [(reg FLAGS_REG) (const_int 0)])
12621                           (const_int 0))
12622                       (label_ref (match_operand 1))
12623                       (pc)))]
12624   ""
12625   [(set (pc)
12626         (if_then_else (match_dup 0)
12627                       (label_ref (match_dup 1))
12628                       (pc)))]
12630   operands[0] = shallow_copy_rtx (operands[0]);
12631   PUT_MODE (operands[0], VOIDmode);
12632   PUT_CODE (operands[0],
12633             ix86_reverse_condition (GET_CODE (operands[0]),
12634                                     GET_MODE (XEXP (operands[0], 0))));
12636   /* Make sure that (a) the CCmode we have for the flags is strong
12637      enough for the reversed compare or (b) we have a valid FP compare.  */
12638   if (! ix86_comparison_operator (operands[0], VOIDmode))
12639     FAIL;
12642 ;; Unconditional and other jump instructions
12644 (define_insn "jump"
12645   [(set (pc)
12646         (label_ref (match_operand 0)))]
12647   ""
12648   "%!jmp\t%l0"
12649   [(set_attr "type" "ibr")
12650    (set_attr "modrm" "0")
12651    (set (attr "length")
12652         (if_then_else
12653           (and (ge (minus (match_dup 0) (pc))
12654                    (const_int -126))
12655                (lt (minus (match_dup 0) (pc))
12656                    (const_int 128)))
12657           (const_int 2)
12658           (const_int 5)))])
12660 (define_expand "indirect_jump"
12661   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12662   ""
12664   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12665     operands[0] = convert_memory_address (word_mode, operands[0]);
12666   cfun->machine->has_local_indirect_jump = true;
12669 (define_insn "*indirect_jump"
12670   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12671   ""
12672   "* return ix86_output_indirect_jmp (operands[0]);"
12673   [(set (attr "type")
12674      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12675                                  != indirect_branch_keep)")
12676         (const_string "multi")
12677         (const_string "ibr")))
12678    (set_attr "length_immediate" "0")])
12680 (define_expand "tablejump"
12681   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12682               (use (label_ref (match_operand 1)))])]
12683   ""
12685   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12686      relative.  Convert the relative address to an absolute address.  */
12687   if (flag_pic)
12688     {
12689       rtx op0, op1;
12690       enum rtx_code code;
12692       /* We can't use @GOTOFF for text labels on VxWorks;
12693          see gotoff_operand.  */
12694       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12695         {
12696           code = PLUS;
12697           op0 = operands[0];
12698           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12699         }
12700       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12701         {
12702           code = PLUS;
12703           op0 = operands[0];
12704           op1 = pic_offset_table_rtx;
12705         }
12706       else
12707         {
12708           code = MINUS;
12709           op0 = pic_offset_table_rtx;
12710           op1 = operands[0];
12711         }
12713       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12714                                          OPTAB_DIRECT);
12715     }
12717   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12718     operands[0] = convert_memory_address (word_mode, operands[0]);
12719   cfun->machine->has_local_indirect_jump = true;
12722 (define_insn "*tablejump_1"
12723   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12724    (use (label_ref (match_operand 1)))]
12725   ""
12726   "* return ix86_output_indirect_jmp (operands[0]);"
12727   [(set (attr "type")
12728      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12729                                  != indirect_branch_keep)")
12730         (const_string "multi")
12731         (const_string "ibr")))
12732    (set_attr "length_immediate" "0")])
12734 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12736 (define_peephole2
12737   [(set (reg FLAGS_REG) (match_operand 0))
12738    (set (match_operand:QI 1 "register_operand")
12739         (match_operator:QI 2 "ix86_comparison_operator"
12740           [(reg FLAGS_REG) (const_int 0)]))
12741    (set (match_operand 3 "any_QIreg_operand")
12742         (zero_extend (match_dup 1)))]
12743   "(peep2_reg_dead_p (3, operands[1])
12744     || operands_match_p (operands[1], operands[3]))
12745    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12746    && peep2_regno_dead_p (0, FLAGS_REG)"
12747   [(set (match_dup 4) (match_dup 0))
12748    (set (strict_low_part (match_dup 5))
12749         (match_dup 2))]
12751   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12752   operands[5] = gen_lowpart (QImode, operands[3]);
12753   ix86_expand_clear (operands[3]);
12756 (define_peephole2
12757   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12758               (match_operand 4)])
12759    (set (match_operand:QI 1 "register_operand")
12760         (match_operator:QI 2 "ix86_comparison_operator"
12761           [(reg FLAGS_REG) (const_int 0)]))
12762    (set (match_operand 3 "any_QIreg_operand")
12763         (zero_extend (match_dup 1)))]
12764   "(peep2_reg_dead_p (3, operands[1])
12765     || operands_match_p (operands[1], operands[3]))
12766    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12767    && ! reg_overlap_mentioned_p (operands[3], operands[4])
12768    && ! reg_set_p (operands[3], operands[4])
12769    && peep2_regno_dead_p (0, FLAGS_REG)"
12770   [(parallel [(set (match_dup 5) (match_dup 0))
12771               (match_dup 4)])
12772    (set (strict_low_part (match_dup 6))
12773         (match_dup 2))]
12775   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12776   operands[6] = gen_lowpart (QImode, operands[3]);
12777   ix86_expand_clear (operands[3]);
12780 (define_peephole2
12781   [(set (reg FLAGS_REG) (match_operand 0))
12782    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12783               (match_operand 5)])
12784    (set (match_operand:QI 2 "register_operand")
12785         (match_operator:QI 3 "ix86_comparison_operator"
12786           [(reg FLAGS_REG) (const_int 0)]))
12787    (set (match_operand 4 "any_QIreg_operand")
12788         (zero_extend (match_dup 2)))]
12789   "(peep2_reg_dead_p (4, operands[2])
12790     || operands_match_p (operands[2], operands[4]))
12791    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12792    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12793    && ! reg_overlap_mentioned_p (operands[4], operands[5])
12794    && ! reg_set_p (operands[4], operands[5])
12795    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12796    && peep2_regno_dead_p (0, FLAGS_REG)"
12797   [(set (match_dup 6) (match_dup 0))
12798    (parallel [(set (match_dup 7) (match_dup 1))
12799               (match_dup 5)])
12800    (set (strict_low_part (match_dup 8))
12801         (match_dup 3))]
12803   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12804   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12805   operands[8] = gen_lowpart (QImode, operands[4]);
12806   ix86_expand_clear (operands[4]);
12809 ;; Similar, but match zero extend with andsi3.
12811 (define_peephole2
12812   [(set (reg FLAGS_REG) (match_operand 0))
12813    (set (match_operand:QI 1 "register_operand")
12814         (match_operator:QI 2 "ix86_comparison_operator"
12815           [(reg FLAGS_REG) (const_int 0)]))
12816    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12817                    (and:SI (match_dup 3) (const_int 255)))
12818               (clobber (reg:CC FLAGS_REG))])]
12819   "REGNO (operands[1]) == REGNO (operands[3])
12820    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12821    && peep2_regno_dead_p (0, FLAGS_REG)"
12822   [(set (match_dup 4) (match_dup 0))
12823    (set (strict_low_part (match_dup 5))
12824         (match_dup 2))]
12826   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12827   operands[5] = gen_lowpart (QImode, operands[3]);
12828   ix86_expand_clear (operands[3]);
12831 (define_peephole2
12832   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12833               (match_operand 4)])
12834    (set (match_operand:QI 1 "register_operand")
12835         (match_operator:QI 2 "ix86_comparison_operator"
12836           [(reg FLAGS_REG) (const_int 0)]))
12837    (parallel [(set (match_operand 3 "any_QIreg_operand")
12838                    (zero_extend (match_dup 1)))
12839               (clobber (reg:CC FLAGS_REG))])]
12840   "(peep2_reg_dead_p (3, operands[1])
12841     || operands_match_p (operands[1], operands[3]))
12842    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12843    && ! reg_overlap_mentioned_p (operands[3], operands[4])
12844    && ! reg_set_p (operands[3], operands[4])
12845    && peep2_regno_dead_p (0, FLAGS_REG)"
12846   [(parallel [(set (match_dup 5) (match_dup 0))
12847               (match_dup 4)])
12848    (set (strict_low_part (match_dup 6))
12849         (match_dup 2))]
12851   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12852   operands[6] = gen_lowpart (QImode, operands[3]);
12853   ix86_expand_clear (operands[3]);
12856 (define_peephole2
12857   [(set (reg FLAGS_REG) (match_operand 0))
12858    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12859               (match_operand 5)])
12860    (set (match_operand:QI 2 "register_operand")
12861         (match_operator:QI 3 "ix86_comparison_operator"
12862           [(reg FLAGS_REG) (const_int 0)]))
12863    (parallel [(set (match_operand 4 "any_QIreg_operand")
12864                    (zero_extend (match_dup 2)))
12865               (clobber (reg:CC FLAGS_REG))])]
12866   "(peep2_reg_dead_p (4, operands[2])
12867     || operands_match_p (operands[2], operands[4]))
12868    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12869    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12870    && ! reg_overlap_mentioned_p (operands[4], operands[5])
12871    && ! reg_set_p (operands[4], operands[5])
12872    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12873    && peep2_regno_dead_p (0, FLAGS_REG)"
12874   [(set (match_dup 6) (match_dup 0))
12875    (parallel [(set (match_dup 7) (match_dup 1))
12876               (match_dup 5)])
12877    (set (strict_low_part (match_dup 8))
12878         (match_dup 3))]
12880   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12881   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12882   operands[8] = gen_lowpart (QImode, operands[4]);
12883   ix86_expand_clear (operands[4]);
12886 ;; Call instructions.
12888 ;; The predicates normally associated with named expanders are not properly
12889 ;; checked for calls.  This is a bug in the generic code, but it isn't that
12890 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
12892 ;; P6 processors will jump to the address after the decrement when %esp
12893 ;; is used as a call operand, so they will execute return address as a code.
12894 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12896 ;; Register constraint for call instruction.
12897 (define_mode_attr c [(SI "l") (DI "r")])
12899 ;; Call subroutine returning no value.
12901 (define_expand "call"
12902   [(call (match_operand:QI 0)
12903          (match_operand 1))
12904    (use (match_operand 2))]
12905   ""
12907   ix86_expand_call (NULL, operands[0], operands[1],
12908                     operands[2], NULL, false);
12909   DONE;
12912 (define_expand "sibcall"
12913   [(call (match_operand:QI 0)
12914          (match_operand 1))
12915    (use (match_operand 2))]
12916   ""
12918   ix86_expand_call (NULL, operands[0], operands[1],
12919                     operands[2], NULL, true);
12920   DONE;
12923 (define_insn "*call"
12924   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12925          (match_operand 1))]
12926   "!SIBLING_CALL_P (insn)"
12927   "* return ix86_output_call_insn (insn, operands[0]);"
12928   [(set_attr "type" "call")])
12930 ;; This covers both call and sibcall since only GOT slot is allowed.
12931 (define_insn "*call_got_x32"
12932   [(call (mem:QI (zero_extend:DI
12933                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12934          (match_operand 1))]
12935   "TARGET_X32"
12937   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12938   return ix86_output_call_insn (insn, fnaddr);
12940   [(set_attr "type" "call")])
12942 ;; Since sibcall never returns, we can only use call-clobbered register
12943 ;; as GOT base.
12944 (define_insn "*sibcall_GOT_32"
12945   [(call (mem:QI
12946            (mem:SI (plus:SI
12947                      (match_operand:SI 0 "register_no_elim_operand" "U")
12948                      (match_operand:SI 1 "GOT32_symbol_operand"))))
12949          (match_operand 2))]
12950   "!TARGET_MACHO
12951   && !TARGET_64BIT
12952   && !TARGET_INDIRECT_BRANCH_REGISTER
12953   && SIBLING_CALL_P (insn)"
12955   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12956   fnaddr = gen_const_mem (SImode, fnaddr);
12957   return ix86_output_call_insn (insn, fnaddr);
12959   [(set_attr "type" "call")])
12961 (define_insn "*sibcall"
12962   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12963          (match_operand 1))]
12964   "SIBLING_CALL_P (insn)"
12965   "* return ix86_output_call_insn (insn, operands[0]);"
12966   [(set_attr "type" "call")])
12968 (define_insn "*sibcall_memory"
12969   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12970          (match_operand 1))
12971    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12972   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12973   "* return ix86_output_call_insn (insn, operands[0]);"
12974   [(set_attr "type" "call")])
12976 (define_peephole2
12977   [(set (match_operand:W 0 "register_operand")
12978         (match_operand:W 1 "memory_operand"))
12979    (call (mem:QI (match_dup 0))
12980          (match_operand 3))]
12981   "!TARGET_X32
12982    && !TARGET_INDIRECT_BRANCH_REGISTER
12983    && SIBLING_CALL_P (peep2_next_insn (1))
12984    && !reg_mentioned_p (operands[0],
12985                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12986   [(parallel [(call (mem:QI (match_dup 1))
12987                     (match_dup 3))
12988               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12990 (define_peephole2
12991   [(set (match_operand:W 0 "register_operand")
12992         (match_operand:W 1 "memory_operand"))
12993    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12994    (call (mem:QI (match_dup 0))
12995          (match_operand 3))]
12996   "!TARGET_X32
12997    && !TARGET_INDIRECT_BRANCH_REGISTER
12998    && SIBLING_CALL_P (peep2_next_insn (2))
12999    && !reg_mentioned_p (operands[0],
13000                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13001   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13002    (parallel [(call (mem:QI (match_dup 1))
13003                     (match_dup 3))
13004               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13006 (define_expand "call_pop"
13007   [(parallel [(call (match_operand:QI 0)
13008                     (match_operand:SI 1))
13009               (set (reg:SI SP_REG)
13010                    (plus:SI (reg:SI SP_REG)
13011                             (match_operand:SI 3)))])]
13012   "!TARGET_64BIT"
13014   ix86_expand_call (NULL, operands[0], operands[1],
13015                     operands[2], operands[3], false);
13016   DONE;
13019 (define_insn "*call_pop"
13020   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
13021          (match_operand 1))
13022    (set (reg:SI SP_REG)
13023         (plus:SI (reg:SI SP_REG)
13024                  (match_operand:SI 2 "immediate_operand" "i")))]
13025   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13026   "* return ix86_output_call_insn (insn, operands[0]);"
13027   [(set_attr "type" "call")])
13029 (define_insn "*sibcall_pop"
13030   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
13031          (match_operand 1))
13032    (set (reg:SI SP_REG)
13033         (plus:SI (reg:SI SP_REG)
13034                  (match_operand:SI 2 "immediate_operand" "i")))]
13035   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13036   "* return ix86_output_call_insn (insn, operands[0]);"
13037   [(set_attr "type" "call")])
13039 (define_insn "*sibcall_pop_memory"
13040   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
13041          (match_operand 1))
13042    (set (reg:SI SP_REG)
13043         (plus:SI (reg:SI SP_REG)
13044                  (match_operand:SI 2 "immediate_operand" "i")))
13045    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13046   "!TARGET_64BIT"
13047   "* return ix86_output_call_insn (insn, operands[0]);"
13048   [(set_attr "type" "call")])
13050 (define_peephole2
13051   [(set (match_operand:SI 0 "register_operand")
13052         (match_operand:SI 1 "memory_operand"))
13053    (parallel [(call (mem:QI (match_dup 0))
13054                     (match_operand 3))
13055               (set (reg:SI SP_REG)
13056                    (plus:SI (reg:SI SP_REG)
13057                             (match_operand:SI 4 "immediate_operand")))])]
13058   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13059    && !reg_mentioned_p (operands[0],
13060                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13061   [(parallel [(call (mem:QI (match_dup 1))
13062                     (match_dup 3))
13063               (set (reg:SI SP_REG)
13064                    (plus:SI (reg:SI SP_REG)
13065                             (match_dup 4)))
13066               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13068 (define_peephole2
13069   [(set (match_operand:SI 0 "register_operand")
13070         (match_operand:SI 1 "memory_operand"))
13071    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13072    (parallel [(call (mem:QI (match_dup 0))
13073                     (match_operand 3))
13074               (set (reg:SI SP_REG)
13075                    (plus:SI (reg:SI SP_REG)
13076                             (match_operand:SI 4 "immediate_operand")))])]
13077   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13078    && !reg_mentioned_p (operands[0],
13079                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13080   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13081    (parallel [(call (mem:QI (match_dup 1))
13082                     (match_dup 3))
13083               (set (reg:SI SP_REG)
13084                    (plus:SI (reg:SI SP_REG)
13085                             (match_dup 4)))
13086               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13088 ;; Combining simple memory jump instruction
13090 (define_peephole2
13091   [(set (match_operand:W 0 "register_operand")
13092         (match_operand:W 1 "memory_operand"))
13093    (set (pc) (match_dup 0))]
13094   "!TARGET_X32
13095    && !TARGET_INDIRECT_BRANCH_REGISTER
13096    && peep2_reg_dead_p (2, operands[0])"
13097   [(set (pc) (match_dup 1))])
13099 ;; Call subroutine, returning value in operand 0
13101 (define_expand "call_value"
13102   [(set (match_operand 0)
13103         (call (match_operand:QI 1)
13104               (match_operand 2)))
13105    (use (match_operand 3))]
13106   ""
13108   ix86_expand_call (operands[0], operands[1], operands[2],
13109                     operands[3], NULL, false);
13110   DONE;
13113 (define_expand "sibcall_value"
13114   [(set (match_operand 0)
13115         (call (match_operand:QI 1)
13116               (match_operand 2)))
13117    (use (match_operand 3))]
13118   ""
13120   ix86_expand_call (operands[0], operands[1], operands[2],
13121                     operands[3], NULL, true);
13122   DONE;
13125 (define_insn "*call_value"
13126   [(set (match_operand 0)
13127         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13128               (match_operand 2)))]
13129   "!SIBLING_CALL_P (insn)"
13130   "* return ix86_output_call_insn (insn, operands[1]);"
13131   [(set_attr "type" "callv")])
13133 ;; This covers both call and sibcall since only GOT slot is allowed.
13134 (define_insn "*call_value_got_x32"
13135   [(set (match_operand 0)
13136         (call (mem:QI
13137                 (zero_extend:DI
13138                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13139               (match_operand 2)))]
13140   "TARGET_X32"
13142   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13143   return ix86_output_call_insn (insn, fnaddr);
13145   [(set_attr "type" "callv")])
13147 ;; Since sibcall never returns, we can only use call-clobbered register
13148 ;; as GOT base.
13149 (define_insn "*sibcall_value_GOT_32"
13150   [(set (match_operand 0)
13151         (call (mem:QI
13152                 (mem:SI (plus:SI
13153                           (match_operand:SI 1 "register_no_elim_operand" "U")
13154                           (match_operand:SI 2 "GOT32_symbol_operand"))))
13155          (match_operand 3)))]
13156   "!TARGET_MACHO
13157    && !TARGET_64BIT
13158    && !TARGET_INDIRECT_BRANCH_REGISTER
13159    && SIBLING_CALL_P (insn)"
13161   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13162   fnaddr = gen_const_mem (SImode, fnaddr);
13163   return ix86_output_call_insn (insn, fnaddr);
13165   [(set_attr "type" "callv")])
13167 (define_insn "*sibcall_value"
13168   [(set (match_operand 0)
13169         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13170               (match_operand 2)))]
13171   "SIBLING_CALL_P (insn)"
13172   "* return ix86_output_call_insn (insn, operands[1]);"
13173   [(set_attr "type" "callv")])
13175 (define_insn "*sibcall_value_memory"
13176   [(set (match_operand 0)
13177         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13178               (match_operand 2)))
13179    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13180   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13181   "* return ix86_output_call_insn (insn, operands[1]);"
13182   [(set_attr "type" "callv")])
13184 (define_peephole2
13185   [(set (match_operand:W 0 "register_operand")
13186         (match_operand:W 1 "memory_operand"))
13187    (set (match_operand 2)
13188    (call (mem:QI (match_dup 0))
13189                  (match_operand 3)))]
13190   "!TARGET_X32
13191    && !TARGET_INDIRECT_BRANCH_REGISTER
13192    && SIBLING_CALL_P (peep2_next_insn (1))
13193    && !reg_mentioned_p (operands[0],
13194                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13195   [(parallel [(set (match_dup 2)
13196                    (call (mem:QI (match_dup 1))
13197                          (match_dup 3)))
13198               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13200 (define_peephole2
13201   [(set (match_operand:W 0 "register_operand")
13202         (match_operand:W 1 "memory_operand"))
13203    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13204    (set (match_operand 2)
13205         (call (mem:QI (match_dup 0))
13206               (match_operand 3)))]
13207   "!TARGET_X32
13208    && !TARGET_INDIRECT_BRANCH_REGISTER
13209    && SIBLING_CALL_P (peep2_next_insn (2))
13210    && !reg_mentioned_p (operands[0],
13211                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13212   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13213    (parallel [(set (match_dup 2)
13214                    (call (mem:QI (match_dup 1))
13215                          (match_dup 3)))
13216               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13218 (define_expand "call_value_pop"
13219   [(parallel [(set (match_operand 0)
13220                    (call (match_operand:QI 1)
13221                          (match_operand:SI 2)))
13222               (set (reg:SI SP_REG)
13223                    (plus:SI (reg:SI SP_REG)
13224                             (match_operand:SI 4)))])]
13225   "!TARGET_64BIT"
13227   ix86_expand_call (operands[0], operands[1], operands[2],
13228                     operands[3], operands[4], false);
13229   DONE;
13232 (define_insn "*call_value_pop"
13233   [(set (match_operand 0)
13234         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13235               (match_operand 2)))
13236    (set (reg:SI SP_REG)
13237         (plus:SI (reg:SI SP_REG)
13238                  (match_operand:SI 3 "immediate_operand" "i")))]
13239   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13240   "* return ix86_output_call_insn (insn, operands[1]);"
13241   [(set_attr "type" "callv")])
13243 (define_insn "*sibcall_value_pop"
13244   [(set (match_operand 0)
13245         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13246               (match_operand 2)))
13247    (set (reg:SI SP_REG)
13248         (plus:SI (reg:SI SP_REG)
13249                  (match_operand:SI 3 "immediate_operand" "i")))]
13250   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13251   "* return ix86_output_call_insn (insn, operands[1]);"
13252   [(set_attr "type" "callv")])
13254 (define_insn "*sibcall_value_pop_memory"
13255   [(set (match_operand 0)
13256         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13257               (match_operand 2)))
13258    (set (reg:SI SP_REG)
13259         (plus:SI (reg:SI SP_REG)
13260                  (match_operand:SI 3 "immediate_operand" "i")))
13261    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13262   "!TARGET_64BIT"
13263   "* return ix86_output_call_insn (insn, operands[1]);"
13264   [(set_attr "type" "callv")])
13266 (define_peephole2
13267   [(set (match_operand:SI 0 "register_operand")
13268         (match_operand:SI 1 "memory_operand"))
13269    (parallel [(set (match_operand 2)
13270                    (call (mem:QI (match_dup 0))
13271                          (match_operand 3)))
13272               (set (reg:SI SP_REG)
13273                    (plus:SI (reg:SI SP_REG)
13274                             (match_operand:SI 4 "immediate_operand")))])]
13275   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13276    && !reg_mentioned_p (operands[0],
13277                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13278   [(parallel [(set (match_dup 2)
13279                    (call (mem:QI (match_dup 1))
13280                          (match_dup 3)))
13281               (set (reg:SI SP_REG)
13282                    (plus:SI (reg:SI SP_REG)
13283                             (match_dup 4)))
13284               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13286 (define_peephole2
13287   [(set (match_operand:SI 0 "register_operand")
13288         (match_operand:SI 1 "memory_operand"))
13289    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13290    (parallel [(set (match_operand 2)
13291                    (call (mem:QI (match_dup 0))
13292                          (match_operand 3)))
13293               (set (reg:SI SP_REG)
13294                    (plus:SI (reg:SI SP_REG)
13295                             (match_operand:SI 4 "immediate_operand")))])]
13296   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13297    && !reg_mentioned_p (operands[0],
13298                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13299   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13300    (parallel [(set (match_dup 2)
13301                    (call (mem:QI (match_dup 1))
13302                          (match_dup 3)))
13303               (set (reg:SI SP_REG)
13304                    (plus:SI (reg:SI SP_REG)
13305                             (match_dup 4)))
13306               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13308 ;; Call subroutine returning any type.
13310 (define_expand "untyped_call"
13311   [(parallel [(call (match_operand 0)
13312                     (const_int 0))
13313               (match_operand 1)
13314               (match_operand 2)])]
13315   ""
13317   int i;
13319   /* In order to give reg-stack an easier job in validating two
13320      coprocessor registers as containing a possible return value,
13321      simply pretend the untyped call returns a complex long double
13322      value. 
13324      We can't use SSE_REGPARM_MAX here since callee is unprototyped
13325      and should have the default ABI.  */
13327   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13328                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13329                     operands[0], const0_rtx,
13330                     GEN_INT ((TARGET_64BIT
13331                               ? (ix86_abi == SYSV_ABI
13332                                  ? X86_64_SSE_REGPARM_MAX
13333                                  : X86_64_MS_SSE_REGPARM_MAX)
13334                               : X86_32_SSE_REGPARM_MAX)
13335                              - 1),
13336                     NULL, false);
13338   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13339     {
13340       rtx set = XVECEXP (operands[2], 0, i);
13341       emit_move_insn (SET_DEST (set), SET_SRC (set));
13342     }
13344   /* The optimizer does not know that the call sets the function value
13345      registers we stored in the result block.  We avoid problems by
13346      claiming that all hard registers are used and clobbered at this
13347      point.  */
13348   emit_insn (gen_blockage ());
13350   DONE;
13353 ;; Prologue and epilogue instructions
13355 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13356 ;; all of memory.  This blocks insns from being moved across this point.
13358 (define_insn "blockage"
13359   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13360   ""
13361   ""
13362   [(set_attr "length" "0")])
13364 ;; Do not schedule instructions accessing memory across this point.
13366 (define_expand "memory_blockage"
13367   [(set (match_dup 0)
13368         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13369   ""
13371   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13372   MEM_VOLATILE_P (operands[0]) = 1;
13375 (define_insn "*memory_blockage"
13376   [(set (match_operand:BLK 0)
13377         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13378   ""
13379   ""
13380   [(set_attr "length" "0")])
13382 ;; As USE insns aren't meaningful after reload, this is used instead
13383 ;; to prevent deleting instructions setting registers for PIC code
13384 (define_insn "prologue_use"
13385   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13386   ""
13387   ""
13388   [(set_attr "length" "0")])
13390 ;; Insn emitted into the body of a function to return from a function.
13391 ;; This is only done if the function's epilogue is known to be simple.
13392 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13394 (define_expand "return"
13395   [(simple_return)]
13396   "ix86_can_use_return_insn_p ()"
13398   if (crtl->args.pops_args)
13399     {
13400       rtx popc = GEN_INT (crtl->args.pops_args);
13401       emit_jump_insn (gen_simple_return_pop_internal (popc));
13402       DONE;
13403     }
13406 ;; We need to disable this for TARGET_SEH, as otherwise
13407 ;; shrink-wrapped prologue gets enabled too.  This might exceed
13408 ;; the maximum size of prologue in unwind information.
13409 ;; Also disallow shrink-wrapping if using stack slot to pass the
13410 ;; static chain pointer - the first instruction has to be pushl %esi
13411 ;; and it can't be moved around, as we use alternate entry points
13412 ;; in that case.
13414 (define_expand "simple_return"
13415   [(simple_return)]
13416   "!TARGET_SEH && !ix86_static_chain_on_stack"
13418   if (crtl->args.pops_args)
13419     {
13420       rtx popc = GEN_INT (crtl->args.pops_args);
13421       emit_jump_insn (gen_simple_return_pop_internal (popc));
13422       DONE;
13423     }
13426 (define_insn "simple_return_internal"
13427   [(simple_return)]
13428   "reload_completed"
13429   "* return ix86_output_function_return (false);"
13430   [(set_attr "length" "1")
13431    (set_attr "atom_unit" "jeu")
13432    (set_attr "length_immediate" "0")
13433    (set_attr "modrm" "0")])
13435 (define_insn "interrupt_return"
13436   [(simple_return)
13437    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13438   "reload_completed"
13440   return TARGET_64BIT ? "iretq" : "iret";
13443 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13444 ;; instruction Athlon and K8 have.
13446 (define_insn "simple_return_internal_long"
13447   [(simple_return)
13448    (unspec [(const_int 0)] UNSPEC_REP)]
13449   "reload_completed"
13450   "* return ix86_output_function_return (true);"
13451   [(set_attr "length" "2")
13452    (set_attr "atom_unit" "jeu")
13453    (set_attr "length_immediate" "0")
13454    (set_attr "prefix_rep" "1")
13455    (set_attr "modrm" "0")])
13457 (define_insn_and_split "simple_return_pop_internal"
13458   [(simple_return)
13459    (use (match_operand:SI 0 "const_int_operand"))]
13460   "reload_completed"
13461   "%!ret\t%0"
13462   "&& cfun->machine->function_return_type != indirect_branch_keep"
13463   [(const_int 0)]
13464   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13465   [(set_attr "length" "3")
13466    (set_attr "atom_unit" "jeu")
13467    (set_attr "length_immediate" "2")
13468    (set_attr "modrm" "0")])
13470 (define_expand "simple_return_indirect_internal"
13471   [(parallel
13472      [(simple_return)
13473       (use (match_operand 0 "register_operand"))])])
13475 (define_insn "*simple_return_indirect_internal<mode>"
13476   [(simple_return)
13477    (use (match_operand:W 0 "register_operand" "r"))]
13478   "reload_completed"
13479   "* return ix86_output_indirect_function_return (operands[0]);"
13480   [(set (attr "type")
13481      (if_then_else (match_test "(cfun->machine->indirect_branch_type
13482                                  != indirect_branch_keep)")
13483         (const_string "multi")
13484         (const_string "ibr")))
13485    (set_attr "length_immediate" "0")])
13487 (define_insn "nop"
13488   [(const_int 0)]
13489   ""
13490   "nop"
13491   [(set_attr "length" "1")
13492    (set_attr "length_immediate" "0")
13493    (set_attr "modrm" "0")])
13495 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
13496 (define_insn "nops"
13497   [(unspec_volatile [(match_operand 0 "const_int_operand")]
13498                     UNSPECV_NOPS)]
13499   "reload_completed"
13501   int num = INTVAL (operands[0]);
13503   gcc_assert (IN_RANGE (num, 1, 8));
13505   while (num--)
13506     fputs ("\tnop\n", asm_out_file);
13508   return "";
13510   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13511    (set_attr "length_immediate" "0")
13512    (set_attr "modrm" "0")])
13514 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13515 ;; branch prediction penalty for the third jump in a 16-byte
13516 ;; block on K8.
13518 (define_insn "pad"
13519   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13520   ""
13522 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13523   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13524 #else
13525   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13526      The align insn is used to avoid 3 jump instructions in the row to improve
13527      branch prediction and the benefits hardly outweigh the cost of extra 8
13528      nops on the average inserted by full alignment pseudo operation.  */
13529 #endif
13530   return "";
13532   [(set_attr "length" "16")])
13534 (define_expand "prologue"
13535   [(const_int 0)]
13536   ""
13537   "ix86_expand_prologue (); DONE;")
13539 (define_expand "set_got"
13540   [(parallel
13541      [(set (match_operand:SI 0 "register_operand")
13542            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13543       (clobber (reg:CC FLAGS_REG))])]
13544   "!TARGET_64BIT"
13546   if (flag_pic && !TARGET_VXWORKS_RTP)
13547     ix86_pc_thunk_call_expanded = true;
13550 (define_insn "*set_got"
13551   [(set (match_operand:SI 0 "register_operand" "=r")
13552         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13553    (clobber (reg:CC FLAGS_REG))]
13554   "!TARGET_64BIT"
13555   "* return output_set_got (operands[0], NULL_RTX);"
13556   [(set_attr "type" "multi")
13557    (set_attr "length" "12")])
13559 (define_expand "set_got_labelled"
13560   [(parallel
13561      [(set (match_operand:SI 0 "register_operand")
13562            (unspec:SI [(label_ref (match_operand 1))]
13563                       UNSPEC_SET_GOT))
13564       (clobber (reg:CC FLAGS_REG))])]
13565   "!TARGET_64BIT"
13567   if (flag_pic && !TARGET_VXWORKS_RTP)
13568     ix86_pc_thunk_call_expanded = true;
13571 (define_insn "*set_got_labelled"
13572   [(set (match_operand:SI 0 "register_operand" "=r")
13573         (unspec:SI [(label_ref (match_operand 1))]
13574          UNSPEC_SET_GOT))
13575    (clobber (reg:CC FLAGS_REG))]
13576   "!TARGET_64BIT"
13577   "* return output_set_got (operands[0], operands[1]);"
13578   [(set_attr "type" "multi")
13579    (set_attr "length" "12")])
13581 (define_insn "set_got_rex64"
13582   [(set (match_operand:DI 0 "register_operand" "=r")
13583         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13584   "TARGET_64BIT"
13585   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13586   [(set_attr "type" "lea")
13587    (set_attr "length_address" "4")
13588    (set_attr "modrm_class" "unknown")
13589    (set_attr "mode" "DI")])
13591 (define_insn "set_rip_rex64"
13592   [(set (match_operand:DI 0 "register_operand" "=r")
13593         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13594   "TARGET_64BIT"
13595   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13596   [(set_attr "type" "lea")
13597    (set_attr "length_address" "4")
13598    (set_attr "mode" "DI")])
13600 (define_insn "set_got_offset_rex64"
13601   [(set (match_operand:DI 0 "register_operand" "=r")
13602         (unspec:DI
13603           [(label_ref (match_operand 1))]
13604           UNSPEC_SET_GOT_OFFSET))]
13605   "TARGET_LP64"
13606   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13607   [(set_attr "type" "imov")
13608    (set_attr "length_immediate" "0")
13609    (set_attr "length_address" "8")
13610    (set_attr "mode" "DI")])
13612 (define_expand "epilogue"
13613   [(const_int 0)]
13614   ""
13615   "ix86_expand_epilogue (1); DONE;")
13617 (define_expand "sibcall_epilogue"
13618   [(const_int 0)]
13619   ""
13620   "ix86_expand_epilogue (0); DONE;")
13622 (define_expand "eh_return"
13623   [(use (match_operand 0 "register_operand"))]
13624   ""
13626   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13628   /* Tricky bit: we write the address of the handler to which we will
13629      be returning into someone else's stack frame, one word below the
13630      stack address we wish to restore.  */
13631   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13632   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13633   tmp = gen_rtx_MEM (Pmode, tmp);
13634   emit_move_insn (tmp, ra);
13636   emit_jump_insn (gen_eh_return_internal ());
13637   emit_barrier ();
13638   DONE;
13641 (define_insn_and_split "eh_return_internal"
13642   [(eh_return)]
13643   ""
13644   "#"
13645   "epilogue_completed"
13646   [(const_int 0)]
13647   "ix86_expand_epilogue (2); DONE;")
13649 (define_insn "leave"
13650   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13651    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13652    (clobber (mem:BLK (scratch)))]
13653   "!TARGET_64BIT"
13654   "leave"
13655   [(set_attr "type" "leave")])
13657 (define_insn "leave_rex64"
13658   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13659    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13660    (clobber (mem:BLK (scratch)))]
13661   "TARGET_64BIT"
13662   "leave"
13663   [(set_attr "type" "leave")])
13665 ;; Handle -fsplit-stack.
13667 (define_expand "split_stack_prologue"
13668   [(const_int 0)]
13669   ""
13671   ix86_expand_split_stack_prologue ();
13672   DONE;
13675 ;; In order to support the call/return predictor, we use a return
13676 ;; instruction which the middle-end doesn't see.
13677 (define_insn "split_stack_return"
13678   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13679                      UNSPECV_SPLIT_STACK_RETURN)]
13680   ""
13682   if (operands[0] == const0_rtx)
13683     return "ret";
13684   else
13685     return "ret\t%0";
13687   [(set_attr "atom_unit" "jeu")
13688    (set_attr "modrm" "0")
13689    (set (attr "length")
13690         (if_then_else (match_operand:SI 0 "const0_operand")
13691                       (const_int 1)
13692                       (const_int 3)))
13693    (set (attr "length_immediate")
13694         (if_then_else (match_operand:SI 0 "const0_operand")
13695                       (const_int 0)
13696                       (const_int 2)))])
13698 ;; If there are operand 0 bytes available on the stack, jump to
13699 ;; operand 1.
13701 (define_expand "split_stack_space_check"
13702   [(set (pc) (if_then_else
13703               (ltu (minus (reg SP_REG)
13704                           (match_operand 0 "register_operand"))
13705                    (match_dup 2))
13706               (label_ref (match_operand 1))
13707               (pc)))]
13708   ""
13710   rtx reg = gen_reg_rtx (Pmode);
13712   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13714   operands[2] = ix86_split_stack_guard ();
13715   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13717   DONE;
13720 ;; Bit manipulation instructions.
13722 (define_expand "ffs<mode>2"
13723   [(set (match_dup 2) (const_int -1))
13724    (parallel [(set (match_dup 3) (match_dup 4))
13725               (set (match_operand:SWI48 0 "register_operand")
13726                    (ctz:SWI48
13727                      (match_operand:SWI48 1 "nonimmediate_operand")))])
13728    (set (match_dup 0) (if_then_else:SWI48
13729                         (eq (match_dup 3) (const_int 0))
13730                         (match_dup 2)
13731                         (match_dup 0)))
13732    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13733               (clobber (reg:CC FLAGS_REG))])]
13734   ""
13736   machine_mode flags_mode;
13738   if (<MODE>mode == SImode && !TARGET_CMOVE)
13739     {
13740       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13741       DONE;
13742     }
13744   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13746   operands[2] = gen_reg_rtx (<MODE>mode);
13747   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13748   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13751 (define_insn_and_split "ffssi2_no_cmove"
13752   [(set (match_operand:SI 0 "register_operand" "=r")
13753         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13754    (clobber (match_scratch:SI 2 "=&q"))
13755    (clobber (reg:CC FLAGS_REG))]
13756   "!TARGET_CMOVE"
13757   "#"
13758   "&& reload_completed"
13759   [(parallel [(set (match_dup 4) (match_dup 5))
13760               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13761    (set (strict_low_part (match_dup 3))
13762         (eq:QI (match_dup 4) (const_int 0)))
13763    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13764               (clobber (reg:CC FLAGS_REG))])
13765    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13766               (clobber (reg:CC FLAGS_REG))])
13767    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13768               (clobber (reg:CC FLAGS_REG))])]
13770   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13772   operands[3] = gen_lowpart (QImode, operands[2]);
13773   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13774   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13776   ix86_expand_clear (operands[2]);
13779 (define_insn_and_split "*tzcnt<mode>_1"
13780   [(set (reg:CCC FLAGS_REG)
13781         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13782                      (const_int 0)))
13783    (set (match_operand:SWI48 0 "register_operand" "=r")
13784         (ctz:SWI48 (match_dup 1)))]
13785   "TARGET_BMI"
13786   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13787   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13788    && optimize_function_for_speed_p (cfun)
13789    && !reg_mentioned_p (operands[0], operands[1])"
13790   [(parallel
13791     [(set (reg:CCC FLAGS_REG)
13792           (compare:CCC (match_dup 1) (const_int 0)))
13793      (set (match_dup 0)
13794           (ctz:SWI48 (match_dup 1)))
13795      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13796   "ix86_expand_clear (operands[0]);"
13797   [(set_attr "type" "alu1")
13798    (set_attr "prefix_0f" "1")
13799    (set_attr "prefix_rep" "1")
13800    (set_attr "btver2_decode" "double")
13801    (set_attr "mode" "<MODE>")])
13803 ; False dependency happens when destination is only updated by tzcnt,
13804 ; lzcnt or popcnt.  There is no false dependency when destination is
13805 ; also used in source.
13806 (define_insn "*tzcnt<mode>_1_falsedep"
13807   [(set (reg:CCC FLAGS_REG)
13808         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13809                      (const_int 0)))
13810    (set (match_operand:SWI48 0 "register_operand" "=r")
13811         (ctz:SWI48 (match_dup 1)))
13812    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13813            UNSPEC_INSN_FALSE_DEP)]
13814   "TARGET_BMI"
13815   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13816   [(set_attr "type" "alu1")
13817    (set_attr "prefix_0f" "1")
13818    (set_attr "prefix_rep" "1")
13819    (set_attr "btver2_decode" "double")
13820    (set_attr "mode" "<MODE>")])
13822 (define_insn "*bsf<mode>_1"
13823   [(set (reg:CCZ FLAGS_REG)
13824         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13825                      (const_int 0)))
13826    (set (match_operand:SWI48 0 "register_operand" "=r")
13827         (ctz:SWI48 (match_dup 1)))]
13828   ""
13829   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13830   [(set_attr "type" "alu1")
13831    (set_attr "prefix_0f" "1")
13832    (set_attr "btver2_decode" "double")
13833    (set_attr "znver1_decode" "vector")
13834    (set_attr "mode" "<MODE>")])
13836 (define_insn_and_split "ctz<mode>2"
13837   [(set (match_operand:SWI48 0 "register_operand" "=r")
13838         (ctz:SWI48
13839           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13840    (clobber (reg:CC FLAGS_REG))]
13841   ""
13843   if (TARGET_BMI)
13844     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13845   else if (optimize_function_for_size_p (cfun))
13846     ;
13847   else if (TARGET_GENERIC)
13848     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13849     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13851   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13853   "(TARGET_BMI || TARGET_GENERIC)
13854    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13855    && optimize_function_for_speed_p (cfun)
13856    && !reg_mentioned_p (operands[0], operands[1])"
13857   [(parallel
13858     [(set (match_dup 0)
13859           (ctz:SWI48 (match_dup 1)))
13860      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13861      (clobber (reg:CC FLAGS_REG))])]
13862   "ix86_expand_clear (operands[0]);"
13863   [(set_attr "type" "alu1")
13864    (set_attr "prefix_0f" "1")
13865    (set (attr "prefix_rep")
13866      (if_then_else
13867        (ior (match_test "TARGET_BMI")
13868             (and (not (match_test "optimize_function_for_size_p (cfun)"))
13869                  (match_test "TARGET_GENERIC")))
13870        (const_string "1")
13871        (const_string "0")))
13872    (set_attr "mode" "<MODE>")])
13874 ; False dependency happens when destination is only updated by tzcnt,
13875 ; lzcnt or popcnt.  There is no false dependency when destination is
13876 ; also used in source.
13877 (define_insn "*ctz<mode>2_falsedep"
13878   [(set (match_operand:SWI48 0 "register_operand" "=r")
13879         (ctz:SWI48
13880           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13881    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13882            UNSPEC_INSN_FALSE_DEP)
13883    (clobber (reg:CC FLAGS_REG))]
13884   ""
13886   if (TARGET_BMI)
13887     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13888   else if (TARGET_GENERIC)
13889     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13890     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13891   else
13892     gcc_unreachable ();
13894   [(set_attr "type" "alu1")
13895    (set_attr "prefix_0f" "1")
13896    (set_attr "prefix_rep" "1")
13897    (set_attr "mode" "<MODE>")])
13899 (define_insn "bsr_rex64"
13900   [(set (match_operand:DI 0 "register_operand" "=r")
13901         (minus:DI (const_int 63)
13902                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13903    (clobber (reg:CC FLAGS_REG))]
13904   "TARGET_64BIT"
13905   "bsr{q}\t{%1, %0|%0, %1}"
13906   [(set_attr "type" "alu1")
13907    (set_attr "prefix_0f" "1")
13908    (set_attr "znver1_decode" "vector")
13909    (set_attr "mode" "DI")])
13911 (define_insn "bsr"
13912   [(set (match_operand:SI 0 "register_operand" "=r")
13913         (minus:SI (const_int 31)
13914                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13915    (clobber (reg:CC FLAGS_REG))]
13916   ""
13917   "bsr{l}\t{%1, %0|%0, %1}"
13918   [(set_attr "type" "alu1")
13919    (set_attr "prefix_0f" "1")
13920    (set_attr "znver1_decode" "vector")
13921    (set_attr "mode" "SI")])
13923 (define_insn "*bsrhi"
13924   [(set (match_operand:HI 0 "register_operand" "=r")
13925         (minus:HI (const_int 15)
13926                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13927    (clobber (reg:CC FLAGS_REG))]
13928   ""
13929   "bsr{w}\t{%1, %0|%0, %1}"
13930   [(set_attr "type" "alu1")
13931    (set_attr "prefix_0f" "1")
13932    (set_attr "znver1_decode" "vector")
13933    (set_attr "mode" "HI")])
13935 (define_expand "clz<mode>2"
13936   [(parallel
13937      [(set (match_operand:SWI48 0 "register_operand")
13938            (minus:SWI48
13939              (match_dup 2)
13940              (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13941       (clobber (reg:CC FLAGS_REG))])
13942    (parallel
13943      [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13944       (clobber (reg:CC FLAGS_REG))])]
13945   ""
13947   if (TARGET_LZCNT)
13948     {
13949       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13950       DONE;
13951     }
13952   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13955 (define_insn_and_split "clz<mode>2_lzcnt"
13956   [(set (match_operand:SWI48 0 "register_operand" "=r")
13957         (clz:SWI48
13958           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13959    (clobber (reg:CC FLAGS_REG))]
13960   "TARGET_LZCNT"
13961   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13962   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13963    && optimize_function_for_speed_p (cfun)
13964    && !reg_mentioned_p (operands[0], operands[1])"
13965   [(parallel
13966     [(set (match_dup 0)
13967           (clz:SWI48 (match_dup 1)))
13968      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13969      (clobber (reg:CC FLAGS_REG))])]
13970   "ix86_expand_clear (operands[0]);"
13971   [(set_attr "prefix_rep" "1")
13972    (set_attr "type" "bitmanip")
13973    (set_attr "mode" "<MODE>")])
13975 ; False dependency happens when destination is only updated by tzcnt,
13976 ; lzcnt or popcnt.  There is no false dependency when destination is
13977 ; also used in source.
13978 (define_insn "*clz<mode>2_lzcnt_falsedep"
13979   [(set (match_operand:SWI48 0 "register_operand" "=r")
13980         (clz:SWI48
13981           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13982    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13983            UNSPEC_INSN_FALSE_DEP)
13984    (clobber (reg:CC FLAGS_REG))]
13985   "TARGET_LZCNT"
13986   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13987   [(set_attr "prefix_rep" "1")
13988    (set_attr "type" "bitmanip")
13989    (set_attr "mode" "<MODE>")])
13991 (define_int_iterator LT_ZCNT
13992         [(UNSPEC_TZCNT "TARGET_BMI")
13993          (UNSPEC_LZCNT "TARGET_LZCNT")])
13995 (define_int_attr lt_zcnt
13996         [(UNSPEC_TZCNT "tzcnt")
13997          (UNSPEC_LZCNT "lzcnt")])
13999 (define_int_attr lt_zcnt_type
14000         [(UNSPEC_TZCNT "alu1")
14001          (UNSPEC_LZCNT "bitmanip")])
14003 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
14004 ;; provides operand size as output when source operand is zero. 
14006 (define_insn_and_split "<lt_zcnt>_<mode>"
14007   [(set (match_operand:SWI48 0 "register_operand" "=r")
14008         (unspec:SWI48
14009           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14010    (clobber (reg:CC FLAGS_REG))]
14011   ""
14012   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14013   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14014    && optimize_function_for_speed_p (cfun)
14015    && !reg_mentioned_p (operands[0], operands[1])"
14016   [(parallel
14017     [(set (match_dup 0)
14018           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
14019      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14020      (clobber (reg:CC FLAGS_REG))])]
14021   "ix86_expand_clear (operands[0]);"
14022   [(set_attr "type" "<lt_zcnt_type>")
14023    (set_attr "prefix_0f" "1")
14024    (set_attr "prefix_rep" "1")
14025    (set_attr "mode" "<MODE>")])
14027 ; False dependency happens when destination is only updated by tzcnt,
14028 ; lzcnt or popcnt.  There is no false dependency when destination is
14029 ; also used in source.
14030 (define_insn "*<lt_zcnt>_<mode>_falsedep"
14031   [(set (match_operand:SWI48 0 "register_operand" "=r")
14032         (unspec:SWI48
14033           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14034    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14035            UNSPEC_INSN_FALSE_DEP)
14036    (clobber (reg:CC FLAGS_REG))]
14037   ""
14038   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14039   [(set_attr "type" "<lt_zcnt_type>")
14040    (set_attr "prefix_0f" "1")
14041    (set_attr "prefix_rep" "1")
14042    (set_attr "mode" "<MODE>")])
14044 (define_insn "<lt_zcnt>_hi"
14045   [(set (match_operand:HI 0 "register_operand" "=r")
14046         (unspec:HI
14047           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14048    (clobber (reg:CC FLAGS_REG))]
14049   ""
14050   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
14051   [(set_attr "type" "<lt_zcnt_type>")
14052    (set_attr "prefix_0f" "1")
14053    (set_attr "prefix_rep" "1")
14054    (set_attr "mode" "HI")])
14056 ;; BMI instructions.
14058 (define_insn "bmi_bextr_<mode>"
14059   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
14060         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14061                        (match_operand:SWI48 2 "register_operand" "r,r")]
14062                       UNSPEC_BEXTR))
14063    (clobber (reg:CC FLAGS_REG))]
14064   "TARGET_BMI"
14065   "bextr\t{%2, %1, %0|%0, %1, %2}"
14066   [(set_attr "type" "bitmanip")
14067    (set_attr "btver2_decode" "direct, double")
14068    (set_attr "mode" "<MODE>")])
14070 (define_insn "*bmi_bextr_<mode>_ccz"
14071   [(set (reg:CCZ FLAGS_REG)
14072         (compare:CCZ
14073           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14074                          (match_operand:SWI48 2 "register_operand" "r,r")]
14075                         UNSPEC_BEXTR)
14076           (const_int 0)))
14077    (clobber (match_scratch:SWI48 0 "=r,r"))]
14078   "TARGET_BMI"
14079   "bextr\t{%2, %1, %0|%0, %1, %2}"
14080   [(set_attr "type" "bitmanip")
14081    (set_attr "btver2_decode" "direct, double")
14082    (set_attr "mode" "<MODE>")])
14084 (define_insn "*bmi_blsi_<mode>"
14085   [(set (match_operand:SWI48 0 "register_operand" "=r")
14086         (and:SWI48
14087           (neg:SWI48
14088             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14089           (match_dup 1)))
14090    (clobber (reg:CC FLAGS_REG))]
14091   "TARGET_BMI"
14092   "blsi\t{%1, %0|%0, %1}"
14093   [(set_attr "type" "bitmanip")
14094    (set_attr "btver2_decode" "double")
14095    (set_attr "mode" "<MODE>")])
14097 (define_insn "*bmi_blsmsk_<mode>"
14098   [(set (match_operand:SWI48 0 "register_operand" "=r")
14099         (xor:SWI48
14100           (plus:SWI48
14101             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14102             (const_int -1))
14103           (match_dup 1)))
14104    (clobber (reg:CC FLAGS_REG))]
14105   "TARGET_BMI"
14106   "blsmsk\t{%1, %0|%0, %1}"
14107   [(set_attr "type" "bitmanip")
14108    (set_attr "btver2_decode" "double")
14109    (set_attr "mode" "<MODE>")])
14111 (define_insn "*bmi_blsr_<mode>"
14112   [(set (match_operand:SWI48 0 "register_operand" "=r")
14113         (and:SWI48
14114           (plus:SWI48
14115             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14116             (const_int -1))
14117           (match_dup 1)))
14118    (clobber (reg:CC FLAGS_REG))]
14119    "TARGET_BMI"
14120    "blsr\t{%1, %0|%0, %1}"
14121   [(set_attr "type" "bitmanip")
14122    (set_attr "btver2_decode" "double")
14123    (set_attr "mode" "<MODE>")])
14125 (define_insn "*bmi_blsr_<mode>_cmp"
14126   [(set (reg:CCZ FLAGS_REG)
14127         (compare:CCZ
14128           (and:SWI48
14129             (plus:SWI48
14130               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14131               (const_int -1))
14132             (match_dup 1))
14133           (const_int 0)))
14134    (set (match_operand:SWI48 0 "register_operand" "=r")
14135         (and:SWI48
14136           (plus:SWI48
14137             (match_dup 1)
14138             (const_int -1))
14139           (match_dup 1)))]
14140    "TARGET_BMI"
14141    "blsr\t{%1, %0|%0, %1}"
14142   [(set_attr "type" "bitmanip")
14143    (set_attr "btver2_decode" "double")
14144    (set_attr "mode" "<MODE>")])
14146 (define_insn "*bmi_blsr_<mode>_ccz"
14147   [(set (reg:CCZ FLAGS_REG)
14148         (compare:CCZ
14149           (and:SWI48
14150             (plus:SWI48
14151               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14152               (const_int -1))
14153             (match_dup 1))
14154           (const_int 0)))
14155    (clobber (match_scratch:SWI48 0 "=r"))]
14156    "TARGET_BMI"
14157    "blsr\t{%1, %0|%0, %1}"
14158   [(set_attr "type" "bitmanip")
14159    (set_attr "btver2_decode" "double")
14160    (set_attr "mode" "<MODE>")])
14162 ;; BMI2 instructions.
14163 (define_expand "bmi2_bzhi_<mode>3"
14164   [(parallel
14165     [(set (match_operand:SWI48 0 "register_operand")
14166           (zero_extract:SWI48
14167             (match_operand:SWI48 1 "nonimmediate_operand")
14168             (umin:SWI48
14169               (and:SWI48 (match_operand:SWI48 2 "register_operand")
14170                          (const_int 255))
14171               (match_dup 3))
14172             (const_int 0)))
14173      (clobber (reg:CC FLAGS_REG))])]
14174   "TARGET_BMI2"
14175   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14177 (define_insn "*bmi2_bzhi_<mode>3"
14178   [(set (match_operand:SWI48 0 "register_operand" "=r")
14179         (zero_extract:SWI48
14180           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14181           (umin:SWI48
14182             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14183                        (const_int 255))
14184             (match_operand:SWI48 3 "const_int_operand" "n"))
14185           (const_int 0)))
14186    (clobber (reg:CC FLAGS_REG))]
14187   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14188   "bzhi\t{%2, %1, %0|%0, %1, %2}"
14189   [(set_attr "type" "bitmanip")
14190    (set_attr "prefix" "vex")
14191    (set_attr "mode" "<MODE>")])
14193 (define_insn "*bmi2_bzhi_<mode>3_1"
14194   [(set (match_operand:SWI48 0 "register_operand" "=r")
14195         (zero_extract:SWI48
14196           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14197           (umin:SWI48
14198             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14199             (match_operand:SWI48 3 "const_int_operand" "n"))
14200           (const_int 0)))
14201    (clobber (reg:CC FLAGS_REG))]
14202   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14203   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14204   [(set_attr "type" "bitmanip")
14205    (set_attr "prefix" "vex")
14206    (set_attr "mode" "<MODE>")])
14208 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14209   [(set (reg:CCZ FLAGS_REG)
14210         (compare:CCZ
14211           (zero_extract:SWI48
14212             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14213             (umin:SWI48
14214               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14215               (match_operand:SWI48 3 "const_int_operand" "n"))
14216             (const_int 0))
14217         (const_int 0)))
14218    (clobber (match_scratch:SWI48 0 "=r"))]
14219   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14220   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14221   [(set_attr "type" "bitmanip")
14222    (set_attr "prefix" "vex")
14223    (set_attr "mode" "<MODE>")])
14225 (define_insn "bmi2_pdep_<mode>3"
14226   [(set (match_operand:SWI48 0 "register_operand" "=r")
14227         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14228                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14229                        UNSPEC_PDEP))]
14230   "TARGET_BMI2"
14231   "pdep\t{%2, %1, %0|%0, %1, %2}"
14232   [(set_attr "type" "bitmanip")
14233    (set_attr "prefix" "vex")
14234    (set_attr "mode" "<MODE>")])
14236 (define_insn "bmi2_pext_<mode>3"
14237   [(set (match_operand:SWI48 0 "register_operand" "=r")
14238         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14239                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14240                        UNSPEC_PEXT))]
14241   "TARGET_BMI2"
14242   "pext\t{%2, %1, %0|%0, %1, %2}"
14243   [(set_attr "type" "bitmanip")
14244    (set_attr "prefix" "vex")
14245    (set_attr "mode" "<MODE>")])
14247 ;; TBM instructions.
14248 (define_insn "tbm_bextri_<mode>"
14249   [(set (match_operand:SWI48 0 "register_operand" "=r")
14250         (zero_extract:SWI48
14251           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14252           (match_operand 2 "const_0_to_255_operand" "N")
14253           (match_operand 3 "const_0_to_255_operand" "N")))
14254    (clobber (reg:CC FLAGS_REG))]
14255    "TARGET_TBM"
14257   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14258   return "bextr\t{%2, %1, %0|%0, %1, %2}";
14260   [(set_attr "type" "bitmanip")
14261    (set_attr "mode" "<MODE>")])
14263 (define_insn "*tbm_blcfill_<mode>"
14264   [(set (match_operand:SWI48 0 "register_operand" "=r")
14265         (and:SWI48
14266           (plus:SWI48
14267             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14268             (const_int 1))
14269           (match_dup 1)))
14270    (clobber (reg:CC FLAGS_REG))]
14271    "TARGET_TBM"
14272    "blcfill\t{%1, %0|%0, %1}"
14273   [(set_attr "type" "bitmanip")
14274    (set_attr "mode" "<MODE>")])
14276 (define_insn "*tbm_blci_<mode>"
14277   [(set (match_operand:SWI48 0 "register_operand" "=r")
14278         (ior:SWI48
14279           (not:SWI48
14280             (plus:SWI48
14281               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14282               (const_int 1)))
14283           (match_dup 1)))
14284    (clobber (reg:CC FLAGS_REG))]
14285    "TARGET_TBM"
14286    "blci\t{%1, %0|%0, %1}"
14287   [(set_attr "type" "bitmanip")
14288    (set_attr "mode" "<MODE>")])
14290 (define_insn "*tbm_blcic_<mode>"
14291   [(set (match_operand:SWI48 0 "register_operand" "=r")
14292         (and:SWI48
14293           (plus:SWI48
14294             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14295             (const_int 1))
14296           (not:SWI48
14297             (match_dup 1))))
14298    (clobber (reg:CC FLAGS_REG))]
14299    "TARGET_TBM"
14300    "blcic\t{%1, %0|%0, %1}"
14301   [(set_attr "type" "bitmanip")
14302    (set_attr "mode" "<MODE>")])
14304 (define_insn "*tbm_blcmsk_<mode>"
14305   [(set (match_operand:SWI48 0 "register_operand" "=r")
14306         (xor:SWI48
14307           (plus:SWI48
14308             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14309             (const_int 1))
14310           (match_dup 1)))
14311    (clobber (reg:CC FLAGS_REG))]
14312    "TARGET_TBM"
14313    "blcmsk\t{%1, %0|%0, %1}"
14314   [(set_attr "type" "bitmanip")
14315    (set_attr "mode" "<MODE>")])
14317 (define_insn "*tbm_blcs_<mode>"
14318   [(set (match_operand:SWI48 0 "register_operand" "=r")
14319         (ior:SWI48
14320           (plus:SWI48
14321             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14322             (const_int 1))
14323           (match_dup 1)))
14324    (clobber (reg:CC FLAGS_REG))]
14325    "TARGET_TBM"
14326    "blcs\t{%1, %0|%0, %1}"
14327   [(set_attr "type" "bitmanip")
14328    (set_attr "mode" "<MODE>")])
14330 (define_insn "*tbm_blsfill_<mode>"
14331   [(set (match_operand:SWI48 0 "register_operand" "=r")
14332         (ior:SWI48
14333           (plus:SWI48
14334             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14335             (const_int -1))
14336           (match_dup 1)))
14337    (clobber (reg:CC FLAGS_REG))]
14338    "TARGET_TBM"
14339    "blsfill\t{%1, %0|%0, %1}"
14340   [(set_attr "type" "bitmanip")
14341    (set_attr "mode" "<MODE>")])
14343 (define_insn "*tbm_blsic_<mode>"
14344   [(set (match_operand:SWI48 0 "register_operand" "=r")
14345         (ior:SWI48
14346           (plus:SWI48
14347             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14348             (const_int -1))
14349           (not:SWI48
14350             (match_dup 1))))
14351    (clobber (reg:CC FLAGS_REG))]
14352    "TARGET_TBM"
14353    "blsic\t{%1, %0|%0, %1}"
14354   [(set_attr "type" "bitmanip")
14355    (set_attr "mode" "<MODE>")])
14357 (define_insn "*tbm_t1mskc_<mode>"
14358   [(set (match_operand:SWI48 0 "register_operand" "=r")
14359         (ior:SWI48
14360           (plus:SWI48
14361             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14362             (const_int 1))
14363           (not:SWI48
14364             (match_dup 1))))
14365    (clobber (reg:CC FLAGS_REG))]
14366    "TARGET_TBM"
14367    "t1mskc\t{%1, %0|%0, %1}"
14368   [(set_attr "type" "bitmanip")
14369    (set_attr "mode" "<MODE>")])
14371 (define_insn "*tbm_tzmsk_<mode>"
14372   [(set (match_operand:SWI48 0 "register_operand" "=r")
14373         (and:SWI48
14374           (plus:SWI48
14375             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14376             (const_int -1))
14377           (not:SWI48
14378             (match_dup 1))))
14379    (clobber (reg:CC FLAGS_REG))]
14380    "TARGET_TBM"
14381    "tzmsk\t{%1, %0|%0, %1}"
14382   [(set_attr "type" "bitmanip")
14383    (set_attr "mode" "<MODE>")])
14385 (define_insn_and_split "popcount<mode>2"
14386   [(set (match_operand:SWI48 0 "register_operand" "=r")
14387         (popcount:SWI48
14388           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14389    (clobber (reg:CC FLAGS_REG))]
14390   "TARGET_POPCNT"
14392 #if TARGET_MACHO
14393   return "popcnt\t{%1, %0|%0, %1}";
14394 #else
14395   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14396 #endif
14398   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14399    && optimize_function_for_speed_p (cfun)
14400    && !reg_mentioned_p (operands[0], operands[1])"
14401   [(parallel
14402     [(set (match_dup 0)
14403           (popcount:SWI48 (match_dup 1)))
14404      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14405      (clobber (reg:CC FLAGS_REG))])]
14406   "ix86_expand_clear (operands[0]);"
14407   [(set_attr "prefix_rep" "1")
14408    (set_attr "type" "bitmanip")
14409    (set_attr "mode" "<MODE>")])
14411 ; False dependency happens when destination is only updated by tzcnt,
14412 ; lzcnt or popcnt.  There is no false dependency when destination is
14413 ; also used in source.
14414 (define_insn "*popcount<mode>2_falsedep"
14415   [(set (match_operand:SWI48 0 "register_operand" "=r")
14416         (popcount:SWI48
14417           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14418    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14419            UNSPEC_INSN_FALSE_DEP)
14420    (clobber (reg:CC FLAGS_REG))]
14421   "TARGET_POPCNT"
14423 #if TARGET_MACHO
14424   return "popcnt\t{%1, %0|%0, %1}";
14425 #else
14426   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14427 #endif
14429   [(set_attr "prefix_rep" "1")
14430    (set_attr "type" "bitmanip")
14431    (set_attr "mode" "<MODE>")])
14433 (define_insn_and_split "*popcounthi2_1"
14434   [(set (match_operand:SI 0 "register_operand")
14435         (popcount:SI
14436           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14437    (clobber (reg:CC FLAGS_REG))]
14438   "TARGET_POPCNT
14439    && can_create_pseudo_p ()"
14440   "#"
14441   "&& 1"
14442   [(const_int 0)]
14444   rtx tmp = gen_reg_rtx (HImode);
14446   emit_insn (gen_popcounthi2 (tmp, operands[1]));
14447   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14448   DONE;
14451 (define_insn "popcounthi2"
14452   [(set (match_operand:HI 0 "register_operand" "=r")
14453         (popcount:HI
14454           (match_operand:HI 1 "nonimmediate_operand" "rm")))
14455    (clobber (reg:CC FLAGS_REG))]
14456   "TARGET_POPCNT"
14458 #if TARGET_MACHO
14459   return "popcnt\t{%1, %0|%0, %1}";
14460 #else
14461   return "popcnt{w}\t{%1, %0|%0, %1}";
14462 #endif
14464   [(set_attr "prefix_rep" "1")
14465    (set_attr "type" "bitmanip")
14466    (set_attr "mode" "HI")])
14468 (define_expand "bswapdi2"
14469   [(set (match_operand:DI 0 "register_operand")
14470         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14471   "TARGET_64BIT"
14473   if (!TARGET_MOVBE)
14474     operands[1] = force_reg (DImode, operands[1]);
14477 (define_expand "bswapsi2"
14478   [(set (match_operand:SI 0 "register_operand")
14479         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14480   ""
14482   if (TARGET_MOVBE)
14483     ;
14484   else if (TARGET_BSWAP)
14485     operands[1] = force_reg (SImode, operands[1]);
14486   else
14487     {
14488       rtx x = operands[0];
14490       emit_move_insn (x, operands[1]);
14491       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14492       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14493       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14494       DONE;
14495     }
14498 (define_insn "*bswap<mode>2_movbe"
14499   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14500         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14501   "TARGET_MOVBE
14502    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14503   "@
14504     bswap\t%0
14505     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14506     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14507   [(set_attr "type" "bitmanip,imov,imov")
14508    (set_attr "modrm" "0,1,1")
14509    (set_attr "prefix_0f" "*,1,1")
14510    (set_attr "prefix_extra" "*,1,1")
14511    (set_attr "mode" "<MODE>")])
14513 (define_insn "*bswap<mode>2"
14514   [(set (match_operand:SWI48 0 "register_operand" "=r")
14515         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14516   "TARGET_BSWAP"
14517   "bswap\t%0"
14518   [(set_attr "type" "bitmanip")
14519    (set_attr "modrm" "0")
14520    (set_attr "mode" "<MODE>")])
14522 (define_expand "bswaphi2"
14523   [(set (match_operand:HI 0 "register_operand")
14524         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14525   "TARGET_MOVBE")
14527 (define_insn "*bswaphi2_movbe"
14528   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14529         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14530   "TARGET_MOVBE
14531    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14532   "@
14533     xchg{b}\t{%h0, %b0|%b0, %h0}
14534     movbe{w}\t{%1, %0|%0, %1}
14535     movbe{w}\t{%1, %0|%0, %1}"
14536   [(set_attr "type" "imov")
14537    (set_attr "modrm" "*,1,1")
14538    (set_attr "prefix_0f" "*,1,1")
14539    (set_attr "prefix_extra" "*,1,1")
14540    (set_attr "pent_pair" "np,*,*")
14541    (set_attr "athlon_decode" "vector,*,*")
14542    (set_attr "amdfam10_decode" "double,*,*")
14543    (set_attr "bdver1_decode" "double,*,*")
14544    (set_attr "mode" "QI,HI,HI")])
14546 (define_peephole2
14547   [(set (match_operand:HI 0 "general_reg_operand")
14548         (bswap:HI (match_dup 0)))]
14549   "TARGET_MOVBE
14550    && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14551    && peep2_regno_dead_p (0, FLAGS_REG)"
14552   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14553               (clobber (reg:CC FLAGS_REG))])])
14555 (define_insn "bswaphi_lowpart"
14556   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14557         (bswap:HI (match_dup 0)))
14558    (clobber (reg:CC FLAGS_REG))]
14559   ""
14560   "@
14561     xchg{b}\t{%h0, %b0|%b0, %h0}
14562     rol{w}\t{$8, %0|%0, 8}"
14563   [(set (attr "preferred_for_size")
14564      (cond [(eq_attr "alternative" "0")
14565               (symbol_ref "true")]
14566            (symbol_ref "false")))
14567    (set (attr "preferred_for_speed")
14568      (cond [(eq_attr "alternative" "0")
14569               (symbol_ref "TARGET_USE_XCHGB")]
14570            (symbol_ref "!TARGET_USE_XCHGB")))
14571    (set_attr "length" "2,4")
14572    (set_attr "mode" "QI,HI")])
14574 (define_expand "paritydi2"
14575   [(set (match_operand:DI 0 "register_operand")
14576         (parity:DI (match_operand:DI 1 "register_operand")))]
14577   "! TARGET_POPCNT"
14579   rtx scratch = gen_reg_rtx (QImode);
14581   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14582                                 NULL_RTX, operands[1]));
14584   ix86_expand_setcc (scratch, ORDERED,
14585                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14587   if (TARGET_64BIT)
14588     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14589   else
14590     {
14591       rtx tmp = gen_reg_rtx (SImode);
14593       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14594       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14595     }
14596   DONE;
14599 (define_expand "paritysi2"
14600   [(set (match_operand:SI 0 "register_operand")
14601         (parity:SI (match_operand:SI 1 "register_operand")))]
14602   "! TARGET_POPCNT"
14604   rtx scratch = gen_reg_rtx (QImode);
14606   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14608   ix86_expand_setcc (scratch, ORDERED,
14609                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14611   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14612   DONE;
14615 (define_insn_and_split "paritydi2_cmp"
14616   [(set (reg:CC FLAGS_REG)
14617         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14618                    UNSPEC_PARITY))
14619    (clobber (match_scratch:DI 0 "=r"))
14620    (clobber (match_scratch:SI 1 "=&r"))
14621    (clobber (match_scratch:HI 2 "=Q"))]
14622   "! TARGET_POPCNT"
14623   "#"
14624   "&& reload_completed"
14625   [(parallel
14626      [(set (match_dup 1)
14627            (xor:SI (match_dup 1) (match_dup 4)))
14628       (clobber (reg:CC FLAGS_REG))])
14629    (parallel
14630      [(set (reg:CC FLAGS_REG)
14631            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14632       (clobber (match_dup 1))
14633       (clobber (match_dup 2))])]
14635   operands[4] = gen_lowpart (SImode, operands[3]);
14637   if (TARGET_64BIT)
14638     {
14639       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14640       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14641     }
14642   else
14643     operands[1] = gen_highpart (SImode, operands[3]);
14646 (define_insn_and_split "paritysi2_cmp"
14647   [(set (reg:CC FLAGS_REG)
14648         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14649                    UNSPEC_PARITY))
14650    (clobber (match_scratch:SI 0 "=r"))
14651    (clobber (match_scratch:HI 1 "=&Q"))]
14652   "! TARGET_POPCNT"
14653   "#"
14654   "&& reload_completed"
14655   [(parallel
14656      [(set (match_dup 1)
14657            (xor:HI (match_dup 1) (match_dup 3)))
14658       (clobber (reg:CC FLAGS_REG))])
14659    (parallel
14660      [(set (reg:CC FLAGS_REG)
14661            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14662       (clobber (match_dup 1))])]
14664   operands[3] = gen_lowpart (HImode, operands[2]);
14666   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14667   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14670 (define_insn "*parityhi2_cmp"
14671   [(set (reg:CC FLAGS_REG)
14672         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14673                    UNSPEC_PARITY))
14674    (clobber (match_scratch:HI 0 "=Q"))]
14675   "! TARGET_POPCNT"
14676   "xor{b}\t{%h0, %b0|%b0, %h0}"
14677   [(set_attr "length" "2")
14678    (set_attr "mode" "HI")])
14681 ;; Thread-local storage patterns for ELF.
14683 ;; Note that these code sequences must appear exactly as shown
14684 ;; in order to allow linker relaxation.
14686 (define_insn "*tls_global_dynamic_32_gnu"
14687   [(set (match_operand:SI 0 "register_operand" "=a")
14688         (unspec:SI
14689          [(match_operand:SI 1 "register_operand" "Yb")
14690           (match_operand 2 "tls_symbolic_operand")
14691           (match_operand 3 "constant_call_address_operand" "Bz")
14692           (reg:SI SP_REG)]
14693          UNSPEC_TLS_GD))
14694    (clobber (match_scratch:SI 4 "=d"))
14695    (clobber (match_scratch:SI 5 "=c"))
14696    (clobber (reg:CC FLAGS_REG))]
14697   "!TARGET_64BIT && TARGET_GNU_TLS"
14699   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14700     output_asm_insn
14701       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14702   else
14703     output_asm_insn
14704       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14705   if (TARGET_SUN_TLS)
14706 #ifdef HAVE_AS_IX86_TLSGDPLT
14707     return "call\t%a2@tlsgdplt";
14708 #else
14709     return "call\t%p3@plt";
14710 #endif
14711   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14712     return "call\t%P3";
14713   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14715   [(set_attr "type" "multi")
14716    (set_attr "length" "12")])
14718 (define_expand "tls_global_dynamic_32"
14719   [(parallel
14720     [(set (match_operand:SI 0 "register_operand")
14721           (unspec:SI [(match_operand:SI 2 "register_operand")
14722                       (match_operand 1 "tls_symbolic_operand")
14723                       (match_operand 3 "constant_call_address_operand")
14724                       (reg:SI SP_REG)]
14725                      UNSPEC_TLS_GD))
14726      (clobber (match_scratch:SI 4))
14727      (clobber (match_scratch:SI 5))
14728      (clobber (reg:CC FLAGS_REG))])]
14729   ""
14730   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14732 (define_insn "*tls_global_dynamic_64_<mode>"
14733   [(set (match_operand:P 0 "register_operand" "=a")
14734         (call:P
14735          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14736          (match_operand 3)))
14737    (unspec:P [(match_operand 1 "tls_symbolic_operand")
14738               (reg:P SP_REG)]
14739              UNSPEC_TLS_GD)]
14740   "TARGET_64BIT"
14742   if (!TARGET_X32)
14743     /* The .loc directive has effect for 'the immediately following assembly
14744        instruction'.  So for a sequence:
14745          .loc f l
14746          .byte x
14747          insn1
14748        the 'immediately following assembly instruction' is insn1.
14749        We want to emit an insn prefix here, but if we use .byte (as shown in
14750        'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14751        inside the insn sequence, rather than to the start.  After relaxation
14752        of the sequence by the linker, the .loc might point inside an insn.
14753        Use data16 prefix instead, which doesn't have this problem.  */
14754     fputs ("\tdata16", asm_out_file);
14755   output_asm_insn
14756     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14757   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14758     fputs (ASM_SHORT "0x6666\n", asm_out_file);
14759   else
14760     fputs (ASM_BYTE "0x66\n", asm_out_file);
14761   fputs ("\trex64\n", asm_out_file);
14762   if (TARGET_SUN_TLS)
14763     return "call\t%p2@plt";
14764   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14765     return "call\t%P2";
14766   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14768   [(set_attr "type" "multi")
14769    (set (attr "length")
14770         (symbol_ref "TARGET_X32 ? 15 : 16"))])
14772 (define_insn "*tls_global_dynamic_64_largepic"
14773   [(set (match_operand:DI 0 "register_operand" "=a")
14774         (call:DI
14775          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14776                           (match_operand:DI 3 "immediate_operand" "i")))
14777          (match_operand 4)))
14778    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14779                (reg:DI SP_REG)]
14780               UNSPEC_TLS_GD)]
14781   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14782    && GET_CODE (operands[3]) == CONST
14783    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14784    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14786   output_asm_insn
14787     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14788   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14789   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14790   return "call\t{*%%rax|rax}";
14792   [(set_attr "type" "multi")
14793    (set_attr "length" "22")])
14795 (define_expand "tls_global_dynamic_64_<mode>"
14796   [(parallel
14797     [(set (match_operand:P 0 "register_operand")
14798           (call:P
14799            (mem:QI (match_operand 2))
14800            (const_int 0)))
14801      (unspec:P [(match_operand 1 "tls_symbolic_operand")
14802                 (reg:P SP_REG)]
14803                UNSPEC_TLS_GD)])]
14804   "TARGET_64BIT"
14805   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14807 (define_insn "*tls_local_dynamic_base_32_gnu"
14808   [(set (match_operand:SI 0 "register_operand" "=a")
14809         (unspec:SI
14810          [(match_operand:SI 1 "register_operand" "Yb")
14811           (match_operand 2 "constant_call_address_operand" "Bz")
14812           (reg:SI SP_REG)]
14813          UNSPEC_TLS_LD_BASE))
14814    (clobber (match_scratch:SI 3 "=d"))
14815    (clobber (match_scratch:SI 4 "=c"))
14816    (clobber (reg:CC FLAGS_REG))]
14817   "!TARGET_64BIT && TARGET_GNU_TLS"
14819   output_asm_insn
14820     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14821   if (TARGET_SUN_TLS)
14822     {
14823       if (HAVE_AS_IX86_TLSLDMPLT)
14824         return "call\t%&@tlsldmplt";
14825       else
14826         return "call\t%p2@plt";
14827     }
14828   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14829     return "call\t%P2";
14830   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14832   [(set_attr "type" "multi")
14833    (set_attr "length" "11")])
14835 (define_expand "tls_local_dynamic_base_32"
14836   [(parallel
14837      [(set (match_operand:SI 0 "register_operand")
14838            (unspec:SI
14839             [(match_operand:SI 1 "register_operand")
14840              (match_operand 2 "constant_call_address_operand")
14841              (reg:SI SP_REG)]
14842             UNSPEC_TLS_LD_BASE))
14843       (clobber (match_scratch:SI 3))
14844       (clobber (match_scratch:SI 4))
14845       (clobber (reg:CC FLAGS_REG))])]
14846   ""
14847   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14849 (define_insn "*tls_local_dynamic_base_64_<mode>"
14850   [(set (match_operand:P 0 "register_operand" "=a")
14851         (call:P
14852          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14853          (match_operand 2)))
14854    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14855   "TARGET_64BIT"
14857   output_asm_insn
14858     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14859   if (TARGET_SUN_TLS)
14860     return "call\t%p1@plt";
14861   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14862     return "call\t%P1";
14863   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14865   [(set_attr "type" "multi")
14866    (set_attr "length" "12")])
14868 (define_insn "*tls_local_dynamic_base_64_largepic"
14869   [(set (match_operand:DI 0 "register_operand" "=a")
14870         (call:DI
14871          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14872                           (match_operand:DI 2 "immediate_operand" "i")))
14873          (match_operand 3)))
14874    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14875   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14876    && GET_CODE (operands[2]) == CONST
14877    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14878    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14880   output_asm_insn
14881     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14882   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14883   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14884   return "call\t{*%%rax|rax}";
14886   [(set_attr "type" "multi")
14887    (set_attr "length" "22")])
14889 (define_expand "tls_local_dynamic_base_64_<mode>"
14890   [(parallel
14891      [(set (match_operand:P 0 "register_operand")
14892            (call:P
14893             (mem:QI (match_operand 1))
14894             (const_int 0)))
14895       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14896   "TARGET_64BIT"
14897   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14899 ;; Local dynamic of a single variable is a lose.  Show combine how
14900 ;; to convert that back to global dynamic.
14902 (define_insn_and_split "*tls_local_dynamic_32_once"
14903   [(set (match_operand:SI 0 "register_operand" "=a")
14904         (plus:SI
14905          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14906                      (match_operand 2 "constant_call_address_operand" "Bz")
14907                      (reg:SI SP_REG)]
14908                     UNSPEC_TLS_LD_BASE)
14909          (const:SI (unspec:SI
14910                     [(match_operand 3 "tls_symbolic_operand")]
14911                     UNSPEC_DTPOFF))))
14912    (clobber (match_scratch:SI 4 "=d"))
14913    (clobber (match_scratch:SI 5 "=c"))
14914    (clobber (reg:CC FLAGS_REG))]
14915   ""
14916   "#"
14917   ""
14918   [(parallel
14919      [(set (match_dup 0)
14920            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14921                        (reg:SI SP_REG)]
14922                       UNSPEC_TLS_GD))
14923       (clobber (match_dup 4))
14924       (clobber (match_dup 5))
14925       (clobber (reg:CC FLAGS_REG))])])
14927 ;; Load and add the thread base pointer from %<tp_seg>:0.
14928 (define_insn_and_split "*load_tp_<mode>"
14929   [(set (match_operand:PTR 0 "register_operand" "=r")
14930         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14931   ""
14932   "#"
14933   ""
14934   [(set (match_dup 0)
14935         (match_dup 1))]
14937   addr_space_t as = DEFAULT_TLS_SEG_REG;
14939   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14940   set_mem_addr_space (operands[1], as);
14943 (define_insn_and_split "*load_tp_x32_zext"
14944   [(set (match_operand:DI 0 "register_operand" "=r")
14945         (zero_extend:DI
14946           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14947   "TARGET_X32"
14948   "#"
14949   ""
14950   [(set (match_dup 0)
14951         (zero_extend:DI (match_dup 1)))]
14953   addr_space_t as = DEFAULT_TLS_SEG_REG;
14955   operands[1] = gen_const_mem (SImode, const0_rtx);
14956   set_mem_addr_space (operands[1], as);
14959 (define_insn_and_split "*add_tp_<mode>"
14960   [(set (match_operand:PTR 0 "register_operand" "=r")
14961         (plus:PTR
14962           (unspec:PTR [(const_int 0)] UNSPEC_TP)
14963           (match_operand:PTR 1 "register_operand" "0")))
14964    (clobber (reg:CC FLAGS_REG))]
14965   ""
14966   "#"
14967   ""
14968   [(parallel
14969      [(set (match_dup 0)
14970            (plus:PTR (match_dup 1) (match_dup 2)))
14971       (clobber (reg:CC FLAGS_REG))])]
14973   addr_space_t as = DEFAULT_TLS_SEG_REG;
14975   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14976   set_mem_addr_space (operands[2], as);
14979 (define_insn_and_split "*add_tp_x32_zext"
14980   [(set (match_operand:DI 0 "register_operand" "=r")
14981         (zero_extend:DI
14982           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14983                    (match_operand:SI 1 "register_operand" "0"))))
14984    (clobber (reg:CC FLAGS_REG))]
14985   "TARGET_X32"
14986   "#"
14987   ""
14988   [(parallel
14989      [(set (match_dup 0)
14990            (zero_extend:DI
14991              (plus:SI (match_dup 1) (match_dup 2))))
14992       (clobber (reg:CC FLAGS_REG))])]
14994   addr_space_t as = DEFAULT_TLS_SEG_REG;
14996   operands[2] = gen_const_mem (SImode, const0_rtx);
14997   set_mem_addr_space (operands[2], as);
15000 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
15001 ;; %rax as destination of the initial executable code sequence.
15002 (define_insn "tls_initial_exec_64_sun"
15003   [(set (match_operand:DI 0 "register_operand" "=a")
15004         (unspec:DI
15005          [(match_operand 1 "tls_symbolic_operand")]
15006          UNSPEC_TLS_IE_SUN))
15007    (clobber (reg:CC FLAGS_REG))]
15008   "TARGET_64BIT && TARGET_SUN_TLS"
15010   output_asm_insn
15011     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
15012   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
15014   [(set_attr "type" "multi")])
15016 ;; GNU2 TLS patterns can be split.
15018 (define_expand "tls_dynamic_gnu2_32"
15019   [(set (match_dup 3)
15020         (plus:SI (match_operand:SI 2 "register_operand")
15021                  (const:SI
15022                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
15023                              UNSPEC_TLSDESC))))
15024    (parallel
15025     [(set (match_operand:SI 0 "register_operand")
15026           (unspec:SI [(match_dup 1) (match_dup 3)
15027                       (match_dup 2) (reg:SI SP_REG)]
15028                       UNSPEC_TLSDESC))
15029      (clobber (reg:CC FLAGS_REG))])]
15030   "!TARGET_64BIT && TARGET_GNU2_TLS"
15032   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15033   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15036 (define_insn "*tls_dynamic_gnu2_lea_32"
15037   [(set (match_operand:SI 0 "register_operand" "=r")
15038         (plus:SI (match_operand:SI 1 "register_operand" "b")
15039                  (const:SI
15040                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
15041                               UNSPEC_TLSDESC))))]
15042   "!TARGET_64BIT && TARGET_GNU2_TLS"
15043   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
15044   [(set_attr "type" "lea")
15045    (set_attr "mode" "SI")
15046    (set_attr "length" "6")
15047    (set_attr "length_address" "4")])
15049 (define_insn "*tls_dynamic_gnu2_call_32"
15050   [(set (match_operand:SI 0 "register_operand" "=a")
15051         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
15052                     (match_operand:SI 2 "register_operand" "0")
15053                     ;; we have to make sure %ebx still points to the GOT
15054                     (match_operand:SI 3 "register_operand" "b")
15055                     (reg:SI SP_REG)]
15056                    UNSPEC_TLSDESC))
15057    (clobber (reg:CC FLAGS_REG))]
15058   "!TARGET_64BIT && TARGET_GNU2_TLS"
15059   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15060   [(set_attr "type" "call")
15061    (set_attr "length" "2")
15062    (set_attr "length_address" "0")])
15064 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15065   [(set (match_operand:SI 0 "register_operand" "=&a")
15066         (plus:SI
15067          (unspec:SI [(match_operand 3 "tls_modbase_operand")
15068                      (match_operand:SI 4)
15069                      (match_operand:SI 2 "register_operand" "b")
15070                      (reg:SI SP_REG)]
15071                     UNSPEC_TLSDESC)
15072          (const:SI (unspec:SI
15073                     [(match_operand 1 "tls_symbolic_operand")]
15074                     UNSPEC_DTPOFF))))
15075    (clobber (reg:CC FLAGS_REG))]
15076   "!TARGET_64BIT && TARGET_GNU2_TLS"
15077   "#"
15078   ""
15079   [(set (match_dup 0) (match_dup 5))]
15081   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15082   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15085 (define_expand "tls_dynamic_gnu2_64"
15086   [(set (match_dup 2)
15087         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15088                    UNSPEC_TLSDESC))
15089    (parallel
15090     [(set (match_operand:DI 0 "register_operand")
15091           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15092                      UNSPEC_TLSDESC))
15093      (clobber (reg:CC FLAGS_REG))])]
15094   "TARGET_64BIT && TARGET_GNU2_TLS"
15096   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15097   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15100 (define_insn "*tls_dynamic_gnu2_lea_64"
15101   [(set (match_operand:DI 0 "register_operand" "=r")
15102         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15103                    UNSPEC_TLSDESC))]
15104   "TARGET_64BIT && TARGET_GNU2_TLS"
15105   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15106   [(set_attr "type" "lea")
15107    (set_attr "mode" "DI")
15108    (set_attr "length" "7")
15109    (set_attr "length_address" "4")])
15111 (define_insn "*tls_dynamic_gnu2_call_64"
15112   [(set (match_operand:DI 0 "register_operand" "=a")
15113         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
15114                     (match_operand:DI 2 "register_operand" "0")
15115                     (reg:DI SP_REG)]
15116                    UNSPEC_TLSDESC))
15117    (clobber (reg:CC FLAGS_REG))]
15118   "TARGET_64BIT && TARGET_GNU2_TLS"
15119   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15120   [(set_attr "type" "call")
15121    (set_attr "length" "2")
15122    (set_attr "length_address" "0")])
15124 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15125   [(set (match_operand:DI 0 "register_operand" "=&a")
15126         (plus:DI
15127          (unspec:DI [(match_operand 2 "tls_modbase_operand")
15128                      (match_operand:DI 3)
15129                      (reg:DI SP_REG)]
15130                     UNSPEC_TLSDESC)
15131          (const:DI (unspec:DI
15132                     [(match_operand 1 "tls_symbolic_operand")]
15133                     UNSPEC_DTPOFF))))
15134    (clobber (reg:CC FLAGS_REG))]
15135   "TARGET_64BIT && TARGET_GNU2_TLS"
15136   "#"
15137   ""
15138   [(set (match_dup 0) (match_dup 4))]
15140   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15141   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15144 (define_split
15145   [(match_operand 0 "tls_address_pattern")]
15146   "TARGET_TLS_DIRECT_SEG_REFS"
15147   [(match_dup 0)]
15148   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15151 ;; These patterns match the binary 387 instructions for addM3, subM3,
15152 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15153 ;; SFmode.  The first is the normal insn, the second the same insn but
15154 ;; with one operand a conversion, and the third the same insn but with
15155 ;; the other operand a conversion.  The conversion may be SFmode or
15156 ;; SImode if the target mode DFmode, but only SImode if the target mode
15157 ;; is SFmode.
15159 ;; Gcc is slightly more smart about handling normal two address instructions
15160 ;; so use special patterns for add and mull.
15162 (define_insn "*fop_<mode>_comm"
15163   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15164         (match_operator:MODEF 3 "binary_fp_operator"
15165           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15166            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15167   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15168     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15169    && COMMUTATIVE_ARITH_P (operands[3])
15170    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15171   "* return output_387_binary_op (insn, operands);"
15172   [(set (attr "type")
15173         (if_then_else (eq_attr "alternative" "1,2")
15174            (if_then_else (match_operand:MODEF 3 "mult_operator")
15175               (const_string "ssemul")
15176               (const_string "sseadd"))
15177            (if_then_else (match_operand:MODEF 3 "mult_operator")
15178               (const_string "fmul")
15179               (const_string "fop"))))
15180    (set_attr "isa" "*,noavx,avx")
15181    (set_attr "prefix" "orig,orig,vex")
15182    (set_attr "mode" "<MODE>")
15183    (set (attr "enabled")
15184      (if_then_else
15185        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15186        (if_then_else
15187          (eq_attr "alternative" "0")
15188          (symbol_ref "TARGET_MIX_SSE_I387
15189                       && X87_ENABLE_ARITH (<MODE>mode)")
15190          (const_string "*"))
15191        (if_then_else
15192          (eq_attr "alternative" "0")
15193          (symbol_ref "true")
15194          (symbol_ref "false"))))])
15196 (define_insn "*rcpsf2_sse"
15197   [(set (match_operand:SF 0 "register_operand" "=x,x")
15198         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
15199                    UNSPEC_RCP))]
15200   "TARGET_SSE && TARGET_SSE_MATH"
15201   "@
15202    %vrcpss\t{%d1, %0|%0, %d1}
15203    %vrcpss\t{%1, %d0|%d0, %1}"
15204   [(set_attr "type" "sse")
15205    (set_attr "atom_sse_attr" "rcp")
15206    (set_attr "btver2_sse_attr" "rcp")
15207    (set_attr "prefix" "maybe_vex")
15208    (set_attr "mode" "SF")])
15210 (define_insn "*fop_<mode>_1"
15211   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
15212         (match_operator:MODEF 3 "binary_fp_operator"
15213           [(match_operand:MODEF 1
15214              "x87nonimm_ssenomem_operand" "0,fm,0,v")
15215            (match_operand:MODEF 2
15216              "nonimmediate_operand"       "fm,0,xm,vm")]))]
15217   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15218     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15219    && !COMMUTATIVE_ARITH_P (operands[3])
15220    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15221   "* return output_387_binary_op (insn, operands);"
15222   [(set (attr "type")
15223         (if_then_else (eq_attr "alternative" "2,3")
15224            (if_then_else (match_operand:MODEF 3 "div_operator")
15225               (const_string "ssediv")
15226               (const_string "sseadd"))
15227            (if_then_else (match_operand:MODEF 3 "div_operator")
15228               (const_string "fdiv")
15229               (const_string "fop"))))
15230    (set_attr "isa" "*,*,noavx,avx")
15231    (set_attr "prefix" "orig,orig,orig,vex")
15232    (set_attr "mode" "<MODE>")
15233    (set (attr "enabled")
15234      (if_then_else
15235        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15236        (if_then_else
15237          (eq_attr "alternative" "0,1")
15238          (symbol_ref "TARGET_MIX_SSE_I387
15239                       && X87_ENABLE_ARITH (<MODE>mode)")
15240          (const_string "*"))
15241        (if_then_else
15242          (eq_attr "alternative" "0,1")
15243          (symbol_ref "true")
15244          (symbol_ref "false"))))])
15246 ;; ??? Add SSE splitters for these!
15247 (define_insn "*fop_<MODEF:mode>_2_i387"
15248   [(set (match_operand:MODEF 0 "register_operand" "=f")
15249         (match_operator:MODEF 3 "binary_fp_operator"
15250           [(float:MODEF
15251              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15252            (match_operand:MODEF 2 "register_operand" "0")]))]
15253   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15254    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15255    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15256        || optimize_function_for_size_p (cfun))"
15257   "* return output_387_binary_op (insn, operands);"
15258   [(set (attr "type")
15259         (cond [(match_operand:MODEF 3 "mult_operator")
15260                  (const_string "fmul")
15261                (match_operand:MODEF 3 "div_operator")
15262                  (const_string "fdiv")
15263               ]
15264               (const_string "fop")))
15265    (set_attr "fp_int_src" "true")
15266    (set_attr "mode" "<SWI24:MODE>")])
15268 (define_insn "*fop_<MODEF:mode>_3_i387"
15269   [(set (match_operand:MODEF 0 "register_operand" "=f")
15270         (match_operator:MODEF 3 "binary_fp_operator"
15271           [(match_operand:MODEF 1 "register_operand" "0")
15272            (float:MODEF
15273              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15274   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15275    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15276    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15277        || optimize_function_for_size_p (cfun))"
15278   "* return output_387_binary_op (insn, operands);"
15279   [(set (attr "type")
15280         (cond [(match_operand:MODEF 3 "mult_operator")
15281                  (const_string "fmul")
15282                (match_operand:MODEF 3 "div_operator")
15283                  (const_string "fdiv")
15284               ]
15285               (const_string "fop")))
15286    (set_attr "fp_int_src" "true")
15287    (set_attr "mode" "<MODE>")])
15289 (define_insn "*fop_df_4_i387"
15290   [(set (match_operand:DF 0 "register_operand" "=f,f")
15291         (match_operator:DF 3 "binary_fp_operator"
15292            [(float_extend:DF
15293              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15294             (match_operand:DF 2 "register_operand" "0,f")]))]
15295   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15296    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15297   "* return output_387_binary_op (insn, operands);"
15298   [(set (attr "type")
15299         (cond [(match_operand:DF 3 "mult_operator")
15300                  (const_string "fmul")
15301                (match_operand:DF 3 "div_operator")
15302                  (const_string "fdiv")
15303               ]
15304               (const_string "fop")))
15305    (set_attr "mode" "SF")])
15307 (define_insn "*fop_df_5_i387"
15308   [(set (match_operand:DF 0 "register_operand" "=f,f")
15309         (match_operator:DF 3 "binary_fp_operator"
15310           [(match_operand:DF 1 "register_operand" "0,f")
15311            (float_extend:DF
15312             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15313   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15314    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15315   "* return output_387_binary_op (insn, operands);"
15316   [(set (attr "type")
15317         (cond [(match_operand:DF 3 "mult_operator")
15318                  (const_string "fmul")
15319                (match_operand:DF 3 "div_operator")
15320                  (const_string "fdiv")
15321               ]
15322               (const_string "fop")))
15323    (set_attr "mode" "SF")])
15325 (define_insn "*fop_df_6_i387"
15326   [(set (match_operand:DF 0 "register_operand" "=f,f")
15327         (match_operator:DF 3 "binary_fp_operator"
15328           [(float_extend:DF
15329             (match_operand:SF 1 "register_operand" "0,f"))
15330            (float_extend:DF
15331             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15332   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15333    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15334   "* return output_387_binary_op (insn, operands);"
15335   [(set (attr "type")
15336         (cond [(match_operand:DF 3 "mult_operator")
15337                  (const_string "fmul")
15338                (match_operand:DF 3 "div_operator")
15339                  (const_string "fdiv")
15340               ]
15341               (const_string "fop")))
15342    (set_attr "mode" "SF")])
15344 (define_insn "*fop_xf_comm_i387"
15345   [(set (match_operand:XF 0 "register_operand" "=f")
15346         (match_operator:XF 3 "binary_fp_operator"
15347                         [(match_operand:XF 1 "register_operand" "%0")
15348                          (match_operand:XF 2 "register_operand" "f")]))]
15349   "TARGET_80387
15350    && COMMUTATIVE_ARITH_P (operands[3])"
15351   "* return output_387_binary_op (insn, operands);"
15352   [(set (attr "type")
15353         (if_then_else (match_operand:XF 3 "mult_operator")
15354            (const_string "fmul")
15355            (const_string "fop")))
15356    (set_attr "mode" "XF")])
15358 (define_insn "*fop_xf_1_i387"
15359   [(set (match_operand:XF 0 "register_operand" "=f,f")
15360         (match_operator:XF 3 "binary_fp_operator"
15361                         [(match_operand:XF 1 "register_operand" "0,f")
15362                          (match_operand:XF 2 "register_operand" "f,0")]))]
15363   "TARGET_80387
15364    && !COMMUTATIVE_ARITH_P (operands[3])"
15365   "* return output_387_binary_op (insn, operands);"
15366   [(set (attr "type")
15367         (if_then_else (match_operand:XF 3 "div_operator")
15368            (const_string "fdiv")
15369            (const_string "fop")))
15370    (set_attr "mode" "XF")])
15372 (define_insn "*fop_xf_2_i387"
15373   [(set (match_operand:XF 0 "register_operand" "=f")
15374         (match_operator:XF 3 "binary_fp_operator"
15375           [(float:XF
15376              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15377            (match_operand:XF 2 "register_operand" "0")]))]
15378   "TARGET_80387
15379    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15380   "* return output_387_binary_op (insn, operands);"
15381   [(set (attr "type")
15382         (cond [(match_operand:XF 3 "mult_operator")
15383                  (const_string "fmul")
15384                (match_operand:XF 3 "div_operator")
15385                  (const_string "fdiv")
15386               ]
15387               (const_string "fop")))
15388    (set_attr "fp_int_src" "true")
15389    (set_attr "mode" "<MODE>")])
15391 (define_insn "*fop_xf_3_i387"
15392   [(set (match_operand:XF 0 "register_operand" "=f")
15393         (match_operator:XF 3 "binary_fp_operator"
15394           [(match_operand:XF 1 "register_operand" "0")
15395            (float:XF
15396              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15397   "TARGET_80387
15398    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15399   "* return output_387_binary_op (insn, operands);"
15400   [(set (attr "type")
15401         (cond [(match_operand:XF 3 "mult_operator")
15402                  (const_string "fmul")
15403                (match_operand:XF 3 "div_operator")
15404                  (const_string "fdiv")
15405               ]
15406               (const_string "fop")))
15407    (set_attr "fp_int_src" "true")
15408    (set_attr "mode" "<MODE>")])
15410 (define_insn "*fop_xf_4_i387"
15411   [(set (match_operand:XF 0 "register_operand" "=f,f")
15412         (match_operator:XF 3 "binary_fp_operator"
15413            [(float_extend:XF
15414               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15415             (match_operand:XF 2 "register_operand" "0,f")]))]
15416   "TARGET_80387"
15417   "* return output_387_binary_op (insn, operands);"
15418   [(set (attr "type")
15419         (cond [(match_operand:XF 3 "mult_operator")
15420                  (const_string "fmul")
15421                (match_operand:XF 3 "div_operator")
15422                  (const_string "fdiv")
15423               ]
15424               (const_string "fop")))
15425    (set_attr "mode" "<MODE>")])
15427 (define_insn "*fop_xf_5_i387"
15428   [(set (match_operand:XF 0 "register_operand" "=f,f")
15429         (match_operator:XF 3 "binary_fp_operator"
15430           [(match_operand:XF 1 "register_operand" "0,f")
15431            (float_extend:XF
15432              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15433   "TARGET_80387"
15434   "* return output_387_binary_op (insn, operands);"
15435   [(set (attr "type")
15436         (cond [(match_operand:XF 3 "mult_operator")
15437                  (const_string "fmul")
15438                (match_operand:XF 3 "div_operator")
15439                  (const_string "fdiv")
15440               ]
15441               (const_string "fop")))
15442    (set_attr "mode" "<MODE>")])
15444 (define_insn "*fop_xf_6_i387"
15445   [(set (match_operand:XF 0 "register_operand" "=f,f")
15446         (match_operator:XF 3 "binary_fp_operator"
15447           [(float_extend:XF
15448              (match_operand:MODEF 1 "register_operand" "0,f"))
15449            (float_extend:XF
15450              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15451   "TARGET_80387"
15452   "* return output_387_binary_op (insn, operands);"
15453   [(set (attr "type")
15454         (cond [(match_operand:XF 3 "mult_operator")
15455                  (const_string "fmul")
15456                (match_operand:XF 3 "div_operator")
15457                  (const_string "fdiv")
15458               ]
15459               (const_string "fop")))
15460    (set_attr "mode" "<MODE>")])
15462 ;; FPU special functions.
15464 ;; This pattern implements a no-op XFmode truncation for
15465 ;; all fancy i386 XFmode math functions.
15467 (define_insn "truncxf<mode>2_i387_noop_unspec"
15468   [(set (match_operand:MODEF 0 "register_operand" "=f")
15469         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15470         UNSPEC_TRUNC_NOOP))]
15471   "TARGET_USE_FANCY_MATH_387"
15472   "* return output_387_reg_move (insn, operands);"
15473   [(set_attr "type" "fmov")
15474    (set_attr "mode" "<MODE>")])
15476 (define_insn "sqrtxf2"
15477   [(set (match_operand:XF 0 "register_operand" "=f")
15478         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15479   "TARGET_USE_FANCY_MATH_387"
15480   "fsqrt"
15481   [(set_attr "type" "fpspc")
15482    (set_attr "mode" "XF")
15483    (set_attr "athlon_decode" "direct")
15484    (set_attr "amdfam10_decode" "direct")
15485    (set_attr "bdver1_decode" "direct")])
15487 (define_insn "sqrt_extend<mode>xf2_i387"
15488   [(set (match_operand:XF 0 "register_operand" "=f")
15489         (sqrt:XF
15490           (float_extend:XF
15491             (match_operand:MODEF 1 "register_operand" "0"))))]
15492   "TARGET_USE_FANCY_MATH_387"
15493   "fsqrt"
15494   [(set_attr "type" "fpspc")
15495    (set_attr "mode" "XF")
15496    (set_attr "athlon_decode" "direct")
15497    (set_attr "amdfam10_decode" "direct")
15498    (set_attr "bdver1_decode" "direct")])
15500 (define_insn "*rsqrtsf2_sse"
15501   [(set (match_operand:SF 0 "register_operand" "=x,x")
15502         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
15503                    UNSPEC_RSQRT))]
15504   "TARGET_SSE && TARGET_SSE_MATH"
15505   "@
15506    %vrsqrtss\t{%d1, %0|%0, %d1}
15507    %vrsqrtss\t{%1, %d0|%d0, %1}"
15508   [(set_attr "type" "sse")
15509    (set_attr "atom_sse_attr" "rcp")
15510    (set_attr "btver2_sse_attr" "rcp")
15511    (set_attr "prefix" "maybe_vex")
15512    (set_attr "mode" "SF")])
15514 (define_expand "rsqrtsf2"
15515   [(set (match_operand:SF 0 "register_operand")
15516         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15517                    UNSPEC_RSQRT))]
15518   "TARGET_SSE && TARGET_SSE_MATH"
15520   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15521   DONE;
15524 (define_insn "*sqrt<mode>2_sse"
15525   [(set (match_operand:MODEF 0 "register_operand" "=v,v")
15526         (sqrt:MODEF
15527           (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
15528   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15529   "@
15530    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15531    %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15532   [(set_attr "type" "sse")
15533    (set_attr "atom_sse_attr" "sqrt")
15534    (set_attr "btver2_sse_attr" "sqrt")
15535    (set_attr "prefix" "maybe_vex")
15536    (set_attr "mode" "<MODE>")
15537    (set_attr "athlon_decode" "*")
15538    (set_attr "amdfam10_decode" "*")
15539    (set_attr "bdver1_decode" "*")])
15541 (define_expand "sqrt<mode>2"
15542   [(set (match_operand:MODEF 0 "register_operand")
15543         (sqrt:MODEF
15544           (match_operand:MODEF 1 "nonimmediate_operand")))]
15545   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15546    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15548   if (<MODE>mode == SFmode
15549       && TARGET_SSE && TARGET_SSE_MATH
15550       && TARGET_RECIP_SQRT
15551       && !optimize_function_for_size_p (cfun)
15552       && flag_finite_math_only && !flag_trapping_math
15553       && flag_unsafe_math_optimizations)
15554     {
15555       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15556       DONE;
15557     }
15559   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15560     {
15561       rtx op0 = gen_reg_rtx (XFmode);
15562       rtx op1 = force_reg (<MODE>mode, operands[1]);
15564       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15565       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15566       DONE;
15567    }
15570 (define_insn "fpremxf4_i387"
15571   [(set (match_operand:XF 0 "register_operand" "=f")
15572         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15573                     (match_operand:XF 3 "register_operand" "1")]
15574                    UNSPEC_FPREM_F))
15575    (set (match_operand:XF 1 "register_operand" "=u")
15576         (unspec:XF [(match_dup 2) (match_dup 3)]
15577                    UNSPEC_FPREM_U))
15578    (set (reg:CCFP FPSR_REG)
15579         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15580                      UNSPEC_C2_FLAG))]
15581   "TARGET_USE_FANCY_MATH_387
15582    && flag_finite_math_only"
15583   "fprem"
15584   [(set_attr "type" "fpspc")
15585    (set_attr "znver1_decode" "vector")
15586    (set_attr "mode" "XF")])
15588 (define_expand "fmodxf3"
15589   [(use (match_operand:XF 0 "register_operand"))
15590    (use (match_operand:XF 1 "general_operand"))
15591    (use (match_operand:XF 2 "general_operand"))]
15592   "TARGET_USE_FANCY_MATH_387
15593    && flag_finite_math_only"
15595   rtx_code_label *label = gen_label_rtx ();
15597   rtx op1 = gen_reg_rtx (XFmode);
15598   rtx op2 = gen_reg_rtx (XFmode);
15600   emit_move_insn (op2, operands[2]);
15601   emit_move_insn (op1, operands[1]);
15603   emit_label (label);
15604   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15605   ix86_emit_fp_unordered_jump (label);
15606   LABEL_NUSES (label) = 1;
15608   emit_move_insn (operands[0], op1);
15609   DONE;
15612 (define_expand "fmod<mode>3"
15613   [(use (match_operand:MODEF 0 "register_operand"))
15614    (use (match_operand:MODEF 1 "general_operand"))
15615    (use (match_operand:MODEF 2 "general_operand"))]
15616   "TARGET_USE_FANCY_MATH_387
15617    && flag_finite_math_only"
15619   rtx (*gen_truncxf) (rtx, rtx);
15621   rtx_code_label *label = gen_label_rtx ();
15623   rtx op1 = gen_reg_rtx (XFmode);
15624   rtx op2 = gen_reg_rtx (XFmode);
15626   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15627   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15629   emit_label (label);
15630   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15631   ix86_emit_fp_unordered_jump (label);
15632   LABEL_NUSES (label) = 1;
15634   /* Truncate the result properly for strict SSE math.  */
15635   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15636       && !TARGET_MIX_SSE_I387)
15637     gen_truncxf = gen_truncxf<mode>2;
15638   else
15639     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15641   emit_insn (gen_truncxf (operands[0], op1));
15642   DONE;
15645 (define_insn "fprem1xf4_i387"
15646   [(set (match_operand:XF 0 "register_operand" "=f")
15647         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15648                     (match_operand:XF 3 "register_operand" "1")]
15649                    UNSPEC_FPREM1_F))
15650    (set (match_operand:XF 1 "register_operand" "=u")
15651         (unspec:XF [(match_dup 2) (match_dup 3)]
15652                    UNSPEC_FPREM1_U))
15653    (set (reg:CCFP FPSR_REG)
15654         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15655                      UNSPEC_C2_FLAG))]
15656   "TARGET_USE_FANCY_MATH_387
15657    && flag_finite_math_only"
15658   "fprem1"
15659   [(set_attr "type" "fpspc")
15660    (set_attr "znver1_decode" "vector")
15661    (set_attr "mode" "XF")])
15663 (define_expand "remainderxf3"
15664   [(use (match_operand:XF 0 "register_operand"))
15665    (use (match_operand:XF 1 "general_operand"))
15666    (use (match_operand:XF 2 "general_operand"))]
15667   "TARGET_USE_FANCY_MATH_387
15668    && flag_finite_math_only"
15670   rtx_code_label *label = gen_label_rtx ();
15672   rtx op1 = gen_reg_rtx (XFmode);
15673   rtx op2 = gen_reg_rtx (XFmode);
15675   emit_move_insn (op2, operands[2]);
15676   emit_move_insn (op1, operands[1]);
15678   emit_label (label);
15679   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15680   ix86_emit_fp_unordered_jump (label);
15681   LABEL_NUSES (label) = 1;
15683   emit_move_insn (operands[0], op1);
15684   DONE;
15687 (define_expand "remainder<mode>3"
15688   [(use (match_operand:MODEF 0 "register_operand"))
15689    (use (match_operand:MODEF 1 "general_operand"))
15690    (use (match_operand:MODEF 2 "general_operand"))]
15691   "TARGET_USE_FANCY_MATH_387
15692    && flag_finite_math_only"
15694   rtx (*gen_truncxf) (rtx, rtx);
15696   rtx_code_label *label = gen_label_rtx ();
15698   rtx op1 = gen_reg_rtx (XFmode);
15699   rtx op2 = gen_reg_rtx (XFmode);
15701   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15702   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15704   emit_label (label);
15706   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15707   ix86_emit_fp_unordered_jump (label);
15708   LABEL_NUSES (label) = 1;
15710   /* Truncate the result properly for strict SSE math.  */
15711   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15712       && !TARGET_MIX_SSE_I387)
15713     gen_truncxf = gen_truncxf<mode>2;
15714   else
15715     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15717   emit_insn (gen_truncxf (operands[0], op1));
15718   DONE;
15721 (define_int_iterator SINCOS
15722         [UNSPEC_SIN
15723          UNSPEC_COS])
15725 (define_int_attr sincos
15726         [(UNSPEC_SIN "sin")
15727          (UNSPEC_COS "cos")])
15729 (define_insn "*<sincos>xf2_i387"
15730   [(set (match_operand:XF 0 "register_operand" "=f")
15731         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15732                    SINCOS))]
15733   "TARGET_USE_FANCY_MATH_387
15734    && flag_unsafe_math_optimizations"
15735   "f<sincos>"
15736   [(set_attr "type" "fpspc")
15737    (set_attr "znver1_decode" "vector")
15738    (set_attr "mode" "XF")])
15740 (define_insn "*<sincos>_extend<mode>xf2_i387"
15741   [(set (match_operand:XF 0 "register_operand" "=f")
15742         (unspec:XF [(float_extend:XF
15743                       (match_operand:MODEF 1 "register_operand" "0"))]
15744                    SINCOS))]
15745   "TARGET_USE_FANCY_MATH_387
15746    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15747        || TARGET_MIX_SSE_I387)
15748    && flag_unsafe_math_optimizations"
15749   "f<sincos>"
15750   [(set_attr "type" "fpspc")
15751    (set_attr "znver1_decode" "vector")
15752    (set_attr "mode" "XF")])
15754 ;; When sincos pattern is defined, sin and cos builtin functions will be
15755 ;; expanded to sincos pattern with one of its outputs left unused.
15756 ;; CSE pass will figure out if two sincos patterns can be combined,
15757 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15758 ;; depending on the unused output.
15760 (define_insn "sincosxf3"
15761   [(set (match_operand:XF 0 "register_operand" "=f")
15762         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15763                    UNSPEC_SINCOS_COS))
15764    (set (match_operand:XF 1 "register_operand" "=u")
15765         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15766   "TARGET_USE_FANCY_MATH_387
15767    && flag_unsafe_math_optimizations"
15768   "fsincos"
15769   [(set_attr "type" "fpspc")
15770    (set_attr "znver1_decode" "vector")
15771    (set_attr "mode" "XF")])
15773 (define_split
15774   [(set (match_operand:XF 0 "register_operand")
15775         (unspec:XF [(match_operand:XF 2 "register_operand")]
15776                    UNSPEC_SINCOS_COS))
15777    (set (match_operand:XF 1 "register_operand")
15778         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15779   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15780    && can_create_pseudo_p ()"
15781   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15783 (define_split
15784   [(set (match_operand:XF 0 "register_operand")
15785         (unspec:XF [(match_operand:XF 2 "register_operand")]
15786                    UNSPEC_SINCOS_COS))
15787    (set (match_operand:XF 1 "register_operand")
15788         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15789   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15790    && can_create_pseudo_p ()"
15791   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15793 (define_insn "sincos_extend<mode>xf3_i387"
15794   [(set (match_operand:XF 0 "register_operand" "=f")
15795         (unspec:XF [(float_extend:XF
15796                       (match_operand:MODEF 2 "register_operand" "0"))]
15797                    UNSPEC_SINCOS_COS))
15798    (set (match_operand:XF 1 "register_operand" "=u")
15799         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15800   "TARGET_USE_FANCY_MATH_387
15801    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15802        || TARGET_MIX_SSE_I387)
15803    && flag_unsafe_math_optimizations"
15804   "fsincos"
15805   [(set_attr "type" "fpspc")
15806    (set_attr "znver1_decode" "vector")
15807    (set_attr "mode" "XF")])
15809 (define_split
15810   [(set (match_operand:XF 0 "register_operand")
15811         (unspec:XF [(float_extend:XF
15812                       (match_operand:MODEF 2 "register_operand"))]
15813                    UNSPEC_SINCOS_COS))
15814    (set (match_operand:XF 1 "register_operand")
15815         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15816   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15817    && can_create_pseudo_p ()"
15818   [(set (match_dup 1)
15819         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15821 (define_split
15822   [(set (match_operand:XF 0 "register_operand")
15823         (unspec:XF [(float_extend:XF
15824                       (match_operand:MODEF 2 "register_operand"))]
15825                    UNSPEC_SINCOS_COS))
15826    (set (match_operand:XF 1 "register_operand")
15827         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15828   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15829    && can_create_pseudo_p ()"
15830   [(set (match_dup 0)
15831         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15833 (define_expand "sincos<mode>3"
15834   [(use (match_operand:MODEF 0 "register_operand"))
15835    (use (match_operand:MODEF 1 "register_operand"))
15836    (use (match_operand:MODEF 2 "register_operand"))]
15837   "TARGET_USE_FANCY_MATH_387
15838    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15839        || TARGET_MIX_SSE_I387)
15840    && flag_unsafe_math_optimizations"
15842   rtx op0 = gen_reg_rtx (XFmode);
15843   rtx op1 = gen_reg_rtx (XFmode);
15845   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15846   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15847   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15848   DONE;
15851 (define_insn "fptanxf4_i387"
15852   [(set (match_operand:XF 0 "register_operand" "=f")
15853         (match_operand:XF 3 "const_double_operand" "F"))
15854    (set (match_operand:XF 1 "register_operand" "=u")
15855         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15856                    UNSPEC_TAN))]
15857   "TARGET_USE_FANCY_MATH_387
15858    && flag_unsafe_math_optimizations
15859    && standard_80387_constant_p (operands[3]) == 2"
15860   "fptan"
15861   [(set_attr "type" "fpspc")
15862    (set_attr "znver1_decode" "vector")
15863    (set_attr "mode" "XF")])
15865 (define_insn "fptan_extend<mode>xf4_i387"
15866   [(set (match_operand:MODEF 0 "register_operand" "=f")
15867         (match_operand:MODEF 3 "const_double_operand" "F"))
15868    (set (match_operand:XF 1 "register_operand" "=u")
15869         (unspec:XF [(float_extend:XF
15870                       (match_operand:MODEF 2 "register_operand" "0"))]
15871                    UNSPEC_TAN))]
15872   "TARGET_USE_FANCY_MATH_387
15873    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15874        || TARGET_MIX_SSE_I387)
15875    && flag_unsafe_math_optimizations
15876    && standard_80387_constant_p (operands[3]) == 2"
15877   "fptan"
15878   [(set_attr "type" "fpspc")
15879    (set_attr "znver1_decode" "vector")
15880    (set_attr "mode" "XF")])
15882 (define_expand "tanxf2"
15883   [(use (match_operand:XF 0 "register_operand"))
15884    (use (match_operand:XF 1 "register_operand"))]
15885   "TARGET_USE_FANCY_MATH_387
15886    && flag_unsafe_math_optimizations"
15888   rtx one = gen_reg_rtx (XFmode);
15889   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15891   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15892   DONE;
15895 (define_expand "tan<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"
15903   rtx op0 = gen_reg_rtx (XFmode);
15905   rtx one = gen_reg_rtx (<MODE>mode);
15906   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15908   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15909                                              operands[1], op2));
15910   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15911   DONE;
15914 (define_insn "*fpatanxf3_i387"
15915   [(set (match_operand:XF 0 "register_operand" "=f")
15916         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15917                     (match_operand:XF 2 "register_operand" "u")]
15918                    UNSPEC_FPATAN))
15919    (clobber (match_scratch:XF 3 "=2"))]
15920   "TARGET_USE_FANCY_MATH_387
15921    && flag_unsafe_math_optimizations"
15922   "fpatan"
15923   [(set_attr "type" "fpspc")
15924    (set_attr "znver1_decode" "vector")
15925    (set_attr "mode" "XF")])
15927 (define_insn "fpatan_extend<mode>xf3_i387"
15928   [(set (match_operand:XF 0 "register_operand" "=f")
15929         (unspec:XF [(float_extend:XF
15930                       (match_operand:MODEF 1 "register_operand" "0"))
15931                     (float_extend:XF
15932                       (match_operand:MODEF 2 "register_operand" "u"))]
15933                    UNSPEC_FPATAN))
15934    (clobber (match_scratch:XF 3 "=2"))]
15935   "TARGET_USE_FANCY_MATH_387
15936    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15937        || TARGET_MIX_SSE_I387)
15938    && flag_unsafe_math_optimizations"
15939   "fpatan"
15940   [(set_attr "type" "fpspc")
15941    (set_attr "znver1_decode" "vector")
15942    (set_attr "mode" "XF")])
15944 (define_expand "atan2xf3"
15945   [(parallel [(set (match_operand:XF 0 "register_operand")
15946                    (unspec:XF [(match_operand:XF 2 "register_operand")
15947                                (match_operand:XF 1 "register_operand")]
15948                               UNSPEC_FPATAN))
15949               (clobber (match_scratch:XF 3))])]
15950   "TARGET_USE_FANCY_MATH_387
15951    && flag_unsafe_math_optimizations")
15953 (define_expand "atan2<mode>3"
15954   [(use (match_operand:MODEF 0 "register_operand"))
15955    (use (match_operand:MODEF 1 "register_operand"))
15956    (use (match_operand:MODEF 2 "register_operand"))]
15957   "TARGET_USE_FANCY_MATH_387
15958    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15959        || TARGET_MIX_SSE_I387)
15960    && flag_unsafe_math_optimizations"
15962   rtx op0 = gen_reg_rtx (XFmode);
15964   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15965   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15966   DONE;
15969 (define_expand "atanxf2"
15970   [(parallel [(set (match_operand:XF 0 "register_operand")
15971                    (unspec:XF [(match_dup 2)
15972                                (match_operand:XF 1 "register_operand")]
15973                               UNSPEC_FPATAN))
15974               (clobber (match_scratch:XF 3))])]
15975   "TARGET_USE_FANCY_MATH_387
15976    && flag_unsafe_math_optimizations"
15978   operands[2] = gen_reg_rtx (XFmode);
15979   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15982 (define_expand "atan<mode>2"
15983   [(use (match_operand:MODEF 0 "register_operand"))
15984    (use (match_operand:MODEF 1 "register_operand"))]
15985   "TARGET_USE_FANCY_MATH_387
15986    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15987        || TARGET_MIX_SSE_I387)
15988    && flag_unsafe_math_optimizations"
15990   rtx op0 = gen_reg_rtx (XFmode);
15992   rtx op2 = gen_reg_rtx (<MODE>mode);
15993   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15995   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15996   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15997   DONE;
16000 (define_expand "asinxf2"
16001   [(set (match_dup 2)
16002         (mult:XF (match_operand:XF 1 "register_operand")
16003                  (match_dup 1)))
16004    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16005    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16006    (parallel [(set (match_operand:XF 0 "register_operand")
16007                    (unspec:XF [(match_dup 5) (match_dup 1)]
16008                               UNSPEC_FPATAN))
16009               (clobber (match_scratch:XF 6))])]
16010   "TARGET_USE_FANCY_MATH_387
16011    && flag_unsafe_math_optimizations"
16013   int i;
16015   for (i = 2; i < 6; i++)
16016     operands[i] = gen_reg_rtx (XFmode);
16018   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16021 (define_expand "asin<mode>2"
16022   [(use (match_operand:MODEF 0 "register_operand"))
16023    (use (match_operand:MODEF 1 "general_operand"))]
16024   "TARGET_USE_FANCY_MATH_387
16025    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16026        || TARGET_MIX_SSE_I387)
16027    && flag_unsafe_math_optimizations"
16029   rtx op0 = gen_reg_rtx (XFmode);
16030   rtx op1 = gen_reg_rtx (XFmode);
16032   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16033   emit_insn (gen_asinxf2 (op0, op1));
16034   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16035   DONE;
16038 (define_expand "acosxf2"
16039   [(set (match_dup 2)
16040         (mult:XF (match_operand:XF 1 "register_operand")
16041                  (match_dup 1)))
16042    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16043    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16044    (parallel [(set (match_operand:XF 0 "register_operand")
16045                    (unspec:XF [(match_dup 1) (match_dup 5)]
16046                               UNSPEC_FPATAN))
16047               (clobber (match_scratch:XF 6))])]
16048   "TARGET_USE_FANCY_MATH_387
16049    && flag_unsafe_math_optimizations"
16051   int i;
16053   for (i = 2; i < 6; i++)
16054     operands[i] = gen_reg_rtx (XFmode);
16056   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16059 (define_expand "acos<mode>2"
16060   [(use (match_operand:MODEF 0 "register_operand"))
16061    (use (match_operand:MODEF 1 "general_operand"))]
16062   "TARGET_USE_FANCY_MATH_387
16063    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16064        || TARGET_MIX_SSE_I387)
16065    && flag_unsafe_math_optimizations"
16067   rtx op0 = gen_reg_rtx (XFmode);
16068   rtx op1 = gen_reg_rtx (XFmode);
16070   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16071   emit_insn (gen_acosxf2 (op0, op1));
16072   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16073   DONE;
16076 (define_insn "fyl2xxf3_i387"
16077   [(set (match_operand:XF 0 "register_operand" "=f")
16078         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16079                     (match_operand:XF 2 "register_operand" "u")]
16080                    UNSPEC_FYL2X))
16081    (clobber (match_scratch:XF 3 "=2"))]
16082   "TARGET_USE_FANCY_MATH_387
16083    && flag_unsafe_math_optimizations"
16084   "fyl2x"
16085   [(set_attr "type" "fpspc")
16086    (set_attr "znver1_decode" "vector")
16087    (set_attr "mode" "XF")])
16089 (define_insn "fyl2x_extend<mode>xf3_i387"
16090   [(set (match_operand:XF 0 "register_operand" "=f")
16091         (unspec:XF [(float_extend:XF
16092                       (match_operand:MODEF 1 "register_operand" "0"))
16093                     (match_operand:XF 2 "register_operand" "u")]
16094                    UNSPEC_FYL2X))
16095    (clobber (match_scratch:XF 3 "=2"))]
16096   "TARGET_USE_FANCY_MATH_387
16097    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16098        || TARGET_MIX_SSE_I387)
16099    && flag_unsafe_math_optimizations"
16100   "fyl2x"
16101   [(set_attr "type" "fpspc")
16102    (set_attr "znver1_decode" "vector")
16103    (set_attr "mode" "XF")])
16105 (define_expand "logxf2"
16106   [(parallel [(set (match_operand:XF 0 "register_operand")
16107                    (unspec:XF [(match_operand:XF 1 "register_operand")
16108                                (match_dup 2)] UNSPEC_FYL2X))
16109               (clobber (match_scratch:XF 3))])]
16110   "TARGET_USE_FANCY_MATH_387
16111    && flag_unsafe_math_optimizations"
16113   operands[2] = gen_reg_rtx (XFmode);
16114   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16117 (define_expand "log<mode>2"
16118   [(use (match_operand:MODEF 0 "register_operand"))
16119    (use (match_operand:MODEF 1 "register_operand"))]
16120   "TARGET_USE_FANCY_MATH_387
16121    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16122        || TARGET_MIX_SSE_I387)
16123    && flag_unsafe_math_optimizations"
16125   rtx op0 = gen_reg_rtx (XFmode);
16127   rtx op2 = gen_reg_rtx (XFmode);
16128   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16130   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16131   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16132   DONE;
16135 (define_expand "log10xf2"
16136   [(parallel [(set (match_operand:XF 0 "register_operand")
16137                    (unspec:XF [(match_operand:XF 1 "register_operand")
16138                                (match_dup 2)] UNSPEC_FYL2X))
16139               (clobber (match_scratch:XF 3))])]
16140   "TARGET_USE_FANCY_MATH_387
16141    && flag_unsafe_math_optimizations"
16143   operands[2] = gen_reg_rtx (XFmode);
16144   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16147 (define_expand "log10<mode>2"
16148   [(use (match_operand:MODEF 0 "register_operand"))
16149    (use (match_operand:MODEF 1 "register_operand"))]
16150   "TARGET_USE_FANCY_MATH_387
16151    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16152        || TARGET_MIX_SSE_I387)
16153    && flag_unsafe_math_optimizations"
16155   rtx op0 = gen_reg_rtx (XFmode);
16157   rtx op2 = gen_reg_rtx (XFmode);
16158   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16160   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16161   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16162   DONE;
16165 (define_expand "log2xf2"
16166   [(parallel [(set (match_operand:XF 0 "register_operand")
16167                    (unspec:XF [(match_operand:XF 1 "register_operand")
16168                                (match_dup 2)] UNSPEC_FYL2X))
16169               (clobber (match_scratch:XF 3))])]
16170   "TARGET_USE_FANCY_MATH_387
16171    && flag_unsafe_math_optimizations"
16173   operands[2] = gen_reg_rtx (XFmode);
16174   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16177 (define_expand "log2<mode>2"
16178   [(use (match_operand:MODEF 0 "register_operand"))
16179    (use (match_operand:MODEF 1 "register_operand"))]
16180   "TARGET_USE_FANCY_MATH_387
16181    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16182        || TARGET_MIX_SSE_I387)
16183    && flag_unsafe_math_optimizations"
16185   rtx op0 = gen_reg_rtx (XFmode);
16187   rtx op2 = gen_reg_rtx (XFmode);
16188   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16190   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16191   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16192   DONE;
16195 (define_insn "fyl2xp1xf3_i387"
16196   [(set (match_operand:XF 0 "register_operand" "=f")
16197         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16198                     (match_operand:XF 2 "register_operand" "u")]
16199                    UNSPEC_FYL2XP1))
16200    (clobber (match_scratch:XF 3 "=2"))]
16201   "TARGET_USE_FANCY_MATH_387
16202    && flag_unsafe_math_optimizations"
16203   "fyl2xp1"
16204   [(set_attr "type" "fpspc")
16205    (set_attr "znver1_decode" "vector")
16206    (set_attr "mode" "XF")])
16208 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16209   [(set (match_operand:XF 0 "register_operand" "=f")
16210         (unspec:XF [(float_extend:XF
16211                       (match_operand:MODEF 1 "register_operand" "0"))
16212                     (match_operand:XF 2 "register_operand" "u")]
16213                    UNSPEC_FYL2XP1))
16214    (clobber (match_scratch:XF 3 "=2"))]
16215   "TARGET_USE_FANCY_MATH_387
16216    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16217        || TARGET_MIX_SSE_I387)
16218    && flag_unsafe_math_optimizations"
16219   "fyl2xp1"
16220   [(set_attr "type" "fpspc")
16221    (set_attr "znver1_decode" "vector")
16222    (set_attr "mode" "XF")])
16224 (define_expand "log1pxf2"
16225   [(use (match_operand:XF 0 "register_operand"))
16226    (use (match_operand:XF 1 "register_operand"))]
16227   "TARGET_USE_FANCY_MATH_387
16228    && flag_unsafe_math_optimizations"
16230   ix86_emit_i387_log1p (operands[0], operands[1]);
16231   DONE;
16234 (define_expand "log1p<mode>2"
16235   [(use (match_operand:MODEF 0 "register_operand"))
16236    (use (match_operand:MODEF 1 "register_operand"))]
16237   "TARGET_USE_FANCY_MATH_387
16238    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16239        || TARGET_MIX_SSE_I387)
16240    && flag_unsafe_math_optimizations"
16242   rtx op0;
16244   op0 = gen_reg_rtx (XFmode);
16246   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16248   ix86_emit_i387_log1p (op0, operands[1]);
16249   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16250   DONE;
16253 (define_insn "fxtractxf3_i387"
16254   [(set (match_operand:XF 0 "register_operand" "=f")
16255         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16256                    UNSPEC_XTRACT_FRACT))
16257    (set (match_operand:XF 1 "register_operand" "=u")
16258         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16259   "TARGET_USE_FANCY_MATH_387
16260    && flag_unsafe_math_optimizations"
16261   "fxtract"
16262   [(set_attr "type" "fpspc")
16263    (set_attr "znver1_decode" "vector")
16264    (set_attr "mode" "XF")])
16266 (define_insn "fxtract_extend<mode>xf3_i387"
16267   [(set (match_operand:XF 0 "register_operand" "=f")
16268         (unspec:XF [(float_extend:XF
16269                       (match_operand:MODEF 2 "register_operand" "0"))]
16270                    UNSPEC_XTRACT_FRACT))
16271    (set (match_operand:XF 1 "register_operand" "=u")
16272         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16273   "TARGET_USE_FANCY_MATH_387
16274    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16275        || TARGET_MIX_SSE_I387)
16276    && flag_unsafe_math_optimizations"
16277   "fxtract"
16278   [(set_attr "type" "fpspc")
16279    (set_attr "znver1_decode" "vector")
16280    (set_attr "mode" "XF")])
16282 (define_expand "logbxf2"
16283   [(parallel [(set (match_dup 2)
16284                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16285                               UNSPEC_XTRACT_FRACT))
16286               (set (match_operand:XF 0 "register_operand")
16287                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16288   "TARGET_USE_FANCY_MATH_387
16289    && flag_unsafe_math_optimizations"
16290   "operands[2] = gen_reg_rtx (XFmode);")
16292 (define_expand "logb<mode>2"
16293   [(use (match_operand:MODEF 0 "register_operand"))
16294    (use (match_operand:MODEF 1 "register_operand"))]
16295   "TARGET_USE_FANCY_MATH_387
16296    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16297        || TARGET_MIX_SSE_I387)
16298    && flag_unsafe_math_optimizations"
16300   rtx op0 = gen_reg_rtx (XFmode);
16301   rtx op1 = gen_reg_rtx (XFmode);
16303   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16304   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16305   DONE;
16308 (define_expand "ilogbxf2"
16309   [(use (match_operand:SI 0 "register_operand"))
16310    (use (match_operand:XF 1 "register_operand"))]
16311   "TARGET_USE_FANCY_MATH_387
16312    && flag_unsafe_math_optimizations"
16314   rtx op0, op1;
16316   if (optimize_insn_for_size_p ())
16317     FAIL;
16319   op0 = gen_reg_rtx (XFmode);
16320   op1 = gen_reg_rtx (XFmode);
16322   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16323   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16324   DONE;
16327 (define_expand "ilogb<mode>2"
16328   [(use (match_operand:SI 0 "register_operand"))
16329    (use (match_operand:MODEF 1 "register_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"
16335   rtx op0, op1;
16337   if (optimize_insn_for_size_p ())
16338     FAIL;
16340   op0 = gen_reg_rtx (XFmode);
16341   op1 = gen_reg_rtx (XFmode);
16343   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16344   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16345   DONE;
16348 (define_insn "*f2xm1xf2_i387"
16349   [(set (match_operand:XF 0 "register_operand" "=f")
16350         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16351                    UNSPEC_F2XM1))]
16352   "TARGET_USE_FANCY_MATH_387
16353    && flag_unsafe_math_optimizations"
16354   "f2xm1"
16355   [(set_attr "type" "fpspc")
16356    (set_attr "znver1_decode" "vector")
16357    (set_attr "mode" "XF")])
16359 (define_insn "fscalexf4_i387"
16360   [(set (match_operand:XF 0 "register_operand" "=f")
16361         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16362                     (match_operand:XF 3 "register_operand" "1")]
16363                    UNSPEC_FSCALE_FRACT))
16364    (set (match_operand:XF 1 "register_operand" "=u")
16365         (unspec:XF [(match_dup 2) (match_dup 3)]
16366                    UNSPEC_FSCALE_EXP))]
16367   "TARGET_USE_FANCY_MATH_387
16368    && flag_unsafe_math_optimizations"
16369   "fscale"
16370   [(set_attr "type" "fpspc")
16371    (set_attr "znver1_decode" "vector")
16372    (set_attr "mode" "XF")])
16374 (define_expand "expNcorexf3"
16375   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16376                                (match_operand:XF 2 "register_operand")))
16377    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16378    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16379    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16380    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16381    (parallel [(set (match_operand:XF 0 "register_operand")
16382                    (unspec:XF [(match_dup 8) (match_dup 4)]
16383                               UNSPEC_FSCALE_FRACT))
16384               (set (match_dup 9)
16385                    (unspec:XF [(match_dup 8) (match_dup 4)]
16386                               UNSPEC_FSCALE_EXP))])]
16387   "TARGET_USE_FANCY_MATH_387
16388    && flag_unsafe_math_optimizations"
16390   int i;
16392   for (i = 3; i < 10; i++)
16393     operands[i] = gen_reg_rtx (XFmode);
16395   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16398 (define_expand "expxf2"
16399   [(use (match_operand:XF 0 "register_operand"))
16400    (use (match_operand:XF 1 "register_operand"))]
16401   "TARGET_USE_FANCY_MATH_387
16402    && flag_unsafe_math_optimizations"
16404   rtx op2;
16406   op2 = gen_reg_rtx (XFmode);
16407   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16409   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16410   DONE;
16413 (define_expand "exp<mode>2"
16414   [(use (match_operand:MODEF 0 "register_operand"))
16415    (use (match_operand:MODEF 1 "general_operand"))]
16416   "TARGET_USE_FANCY_MATH_387
16417    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16418        || TARGET_MIX_SSE_I387)
16419    && flag_unsafe_math_optimizations"
16421   rtx op0, op1;
16423   op0 = gen_reg_rtx (XFmode);
16424   op1 = gen_reg_rtx (XFmode);
16426   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16427   emit_insn (gen_expxf2 (op0, op1));
16428   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16429   DONE;
16432 (define_expand "exp10xf2"
16433   [(use (match_operand:XF 0 "register_operand"))
16434    (use (match_operand:XF 1 "register_operand"))]
16435   "TARGET_USE_FANCY_MATH_387
16436    && flag_unsafe_math_optimizations"
16438   rtx op2;
16440   op2 = gen_reg_rtx (XFmode);
16441   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16443   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16444   DONE;
16447 (define_expand "exp10<mode>2"
16448   [(use (match_operand:MODEF 0 "register_operand"))
16449    (use (match_operand:MODEF 1 "general_operand"))]
16450   "TARGET_USE_FANCY_MATH_387
16451    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16452        || TARGET_MIX_SSE_I387)
16453    && flag_unsafe_math_optimizations"
16455   rtx op0, op1;
16457   op0 = gen_reg_rtx (XFmode);
16458   op1 = gen_reg_rtx (XFmode);
16460   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16461   emit_insn (gen_exp10xf2 (op0, op1));
16462   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16463   DONE;
16466 (define_expand "exp2xf2"
16467   [(use (match_operand:XF 0 "register_operand"))
16468    (use (match_operand:XF 1 "register_operand"))]
16469   "TARGET_USE_FANCY_MATH_387
16470    && flag_unsafe_math_optimizations"
16472   rtx op2;
16474   op2 = gen_reg_rtx (XFmode);
16475   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16477   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16478   DONE;
16481 (define_expand "exp2<mode>2"
16482   [(use (match_operand:MODEF 0 "register_operand"))
16483    (use (match_operand:MODEF 1 "general_operand"))]
16484   "TARGET_USE_FANCY_MATH_387
16485    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16486        || TARGET_MIX_SSE_I387)
16487    && flag_unsafe_math_optimizations"
16489   rtx op0, op1;
16491   op0 = gen_reg_rtx (XFmode);
16492   op1 = gen_reg_rtx (XFmode);
16494   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16495   emit_insn (gen_exp2xf2 (op0, op1));
16496   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16497   DONE;
16500 (define_expand "expm1xf2"
16501   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16502                                (match_dup 2)))
16503    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16504    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16505    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16506    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16507    (parallel [(set (match_dup 7)
16508                    (unspec:XF [(match_dup 6) (match_dup 4)]
16509                               UNSPEC_FSCALE_FRACT))
16510               (set (match_dup 8)
16511                    (unspec:XF [(match_dup 6) (match_dup 4)]
16512                               UNSPEC_FSCALE_EXP))])
16513    (parallel [(set (match_dup 10)
16514                    (unspec:XF [(match_dup 9) (match_dup 8)]
16515                               UNSPEC_FSCALE_FRACT))
16516               (set (match_dup 11)
16517                    (unspec:XF [(match_dup 9) (match_dup 8)]
16518                               UNSPEC_FSCALE_EXP))])
16519    (set (match_dup 12) (minus:XF (match_dup 10)
16520                                  (float_extend:XF (match_dup 13))))
16521    (set (match_operand:XF 0 "register_operand")
16522         (plus:XF (match_dup 12) (match_dup 7)))]
16523   "TARGET_USE_FANCY_MATH_387
16524    && flag_unsafe_math_optimizations"
16526   int i;
16528   for (i = 2; i < 13; i++)
16529     operands[i] = gen_reg_rtx (XFmode);
16531   operands[13]
16532     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16534   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16537 (define_expand "expm1<mode>2"
16538   [(use (match_operand:MODEF 0 "register_operand"))
16539    (use (match_operand:MODEF 1 "general_operand"))]
16540   "TARGET_USE_FANCY_MATH_387
16541    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16542        || TARGET_MIX_SSE_I387)
16543    && flag_unsafe_math_optimizations"
16545   rtx op0, op1;
16547   op0 = gen_reg_rtx (XFmode);
16548   op1 = gen_reg_rtx (XFmode);
16550   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16551   emit_insn (gen_expm1xf2 (op0, op1));
16552   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16553   DONE;
16556 (define_expand "ldexpxf3"
16557   [(match_operand:XF 0 "register_operand")
16558    (match_operand:XF 1 "register_operand")
16559    (match_operand:SI 2 "register_operand")]
16560   "TARGET_USE_FANCY_MATH_387
16561    && flag_unsafe_math_optimizations"
16563   rtx tmp1, tmp2;
16565   tmp1 = gen_reg_rtx (XFmode);
16566   tmp2 = gen_reg_rtx (XFmode);
16568   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16569   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16570                                  operands[1], tmp1));
16571   DONE;
16574 (define_expand "ldexp<mode>3"
16575   [(use (match_operand:MODEF 0 "register_operand"))
16576    (use (match_operand:MODEF 1 "general_operand"))
16577    (use (match_operand:SI 2 "register_operand"))]
16578   "TARGET_USE_FANCY_MATH_387
16579    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16580        || TARGET_MIX_SSE_I387)
16581    && flag_unsafe_math_optimizations"
16583   rtx op0, op1;
16585   op0 = gen_reg_rtx (XFmode);
16586   op1 = gen_reg_rtx (XFmode);
16588   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16589   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16590   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16591   DONE;
16594 (define_expand "scalbxf3"
16595   [(parallel [(set (match_operand:XF 0 " register_operand")
16596                    (unspec:XF [(match_operand:XF 1 "register_operand")
16597                                (match_operand:XF 2 "register_operand")]
16598                               UNSPEC_FSCALE_FRACT))
16599               (set (match_dup 3)
16600                    (unspec:XF [(match_dup 1) (match_dup 2)]
16601                               UNSPEC_FSCALE_EXP))])]
16602   "TARGET_USE_FANCY_MATH_387
16603    && flag_unsafe_math_optimizations"
16605   operands[3] = gen_reg_rtx (XFmode);
16608 (define_expand "scalb<mode>3"
16609   [(use (match_operand:MODEF 0 "register_operand"))
16610    (use (match_operand:MODEF 1 "general_operand"))
16611    (use (match_operand:MODEF 2 "general_operand"))]
16612   "TARGET_USE_FANCY_MATH_387
16613    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16614        || TARGET_MIX_SSE_I387)
16615    && flag_unsafe_math_optimizations"
16617   rtx op0, op1, op2;
16619   op0 = gen_reg_rtx (XFmode);
16620   op1 = gen_reg_rtx (XFmode);
16621   op2 = gen_reg_rtx (XFmode);
16623   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16624   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16625   emit_insn (gen_scalbxf3 (op0, op1, op2));
16626   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16627   DONE;
16630 (define_expand "significandxf2"
16631   [(parallel [(set (match_operand:XF 0 "register_operand")
16632                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16633                               UNSPEC_XTRACT_FRACT))
16634               (set (match_dup 2)
16635                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16636   "TARGET_USE_FANCY_MATH_387
16637    && flag_unsafe_math_optimizations"
16638   "operands[2] = gen_reg_rtx (XFmode);")
16640 (define_expand "significand<mode>2"
16641   [(use (match_operand:MODEF 0 "register_operand"))
16642    (use (match_operand:MODEF 1 "register_operand"))]
16643   "TARGET_USE_FANCY_MATH_387
16644    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16645        || TARGET_MIX_SSE_I387)
16646    && flag_unsafe_math_optimizations"
16648   rtx op0 = gen_reg_rtx (XFmode);
16649   rtx op1 = gen_reg_rtx (XFmode);
16651   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16652   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16653   DONE;
16657 (define_insn "sse4_1_round<mode>2"
16658   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16659         (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
16660                        (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16661                       UNSPEC_ROUND))]
16662   "TARGET_SSE4_1"
16663   "@
16664    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16665    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16666   [(set_attr "type" "ssecvt")
16667    (set_attr "prefix_extra" "1,*")
16668    (set_attr "length_immediate" "*,1")
16669    (set_attr "prefix" "maybe_vex,evex")
16670    (set_attr "isa" "noavx512f,avx512f")
16671    (set_attr "mode" "<MODE>")])
16673 (define_insn "rintxf2"
16674   [(set (match_operand:XF 0 "register_operand" "=f")
16675         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16676                    UNSPEC_FRNDINT))]
16677   "TARGET_USE_FANCY_MATH_387"
16678   "frndint"
16679   [(set_attr "type" "fpspc")
16680    (set_attr "znver1_decode" "vector")
16681    (set_attr "mode" "XF")])
16683 (define_insn "rint<mode>2_frndint"
16684   [(set (match_operand:MODEF 0 "register_operand" "=f")
16685         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16686                       UNSPEC_FRNDINT))]
16687   "TARGET_USE_FANCY_MATH_387"
16688   "frndint"
16689   [(set_attr "type" "fpspc")
16690    (set_attr "znver1_decode" "vector")
16691    (set_attr "mode" "<MODE>")])
16693 (define_expand "rint<mode>2"
16694   [(use (match_operand:MODEF 0 "register_operand"))
16695    (use (match_operand:MODEF 1 "register_operand"))]
16696   "(TARGET_USE_FANCY_MATH_387
16697     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16698         || TARGET_MIX_SSE_I387))
16699    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16701   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16702     {
16703       if (TARGET_SSE4_1)
16704         emit_insn (gen_sse4_1_round<mode>2
16705                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16706       else
16707         ix86_expand_rint (operands[0], operands[1]);
16708     }
16709   else
16710     emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16711   DONE;
16714 (define_expand "round<mode>2"
16715   [(match_operand:X87MODEF 0 "register_operand")
16716    (match_operand:X87MODEF 1 "nonimmediate_operand")]
16717   "(TARGET_USE_FANCY_MATH_387
16718     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16719         || TARGET_MIX_SSE_I387)
16720     && flag_unsafe_math_optimizations
16721     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16722    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16723        && !flag_trapping_math && !flag_rounding_math)"
16725   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16726       && !flag_trapping_math && !flag_rounding_math)
16727     {
16728       if (TARGET_SSE4_1)
16729         {
16730           operands[1] = force_reg (<MODE>mode, operands[1]);
16731           ix86_expand_round_sse4 (operands[0], operands[1]);
16732         }
16733       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16734         ix86_expand_round (operands[0], operands[1]);
16735       else
16736         ix86_expand_rounddf_32 (operands[0], operands[1]);
16737     }
16738   else
16739     {
16740       operands[1] = force_reg (<MODE>mode, operands[1]);
16741       ix86_emit_i387_round (operands[0], operands[1]);
16742     }
16743   DONE;
16746 (define_insn_and_split "*fistdi2_1"
16747   [(set (match_operand:DI 0 "nonimmediate_operand")
16748         (unspec:DI [(match_operand:XF 1 "register_operand")]
16749                    UNSPEC_FIST))]
16750   "TARGET_USE_FANCY_MATH_387
16751    && can_create_pseudo_p ()"
16752   "#"
16753   "&& 1"
16754   [(const_int 0)]
16756   if (memory_operand (operands[0], VOIDmode))
16757     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16758   else
16759     {
16760       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16761       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16762                                          operands[2]));
16763     }
16764   DONE;
16766   [(set_attr "type" "fpspc")
16767    (set_attr "mode" "DI")])
16769 (define_insn "fistdi2"
16770   [(set (match_operand:DI 0 "memory_operand" "=m")
16771         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16772                    UNSPEC_FIST))
16773    (clobber (match_scratch:XF 2 "=&1f"))]
16774   "TARGET_USE_FANCY_MATH_387"
16775   "* return output_fix_trunc (insn, operands, false);"
16776   [(set_attr "type" "fpspc")
16777    (set_attr "mode" "DI")])
16779 (define_insn "fistdi2_with_temp"
16780   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16781         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16782                    UNSPEC_FIST))
16783    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16784    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16785   "TARGET_USE_FANCY_MATH_387"
16786   "#"
16787   [(set_attr "type" "fpspc")
16788    (set_attr "mode" "DI")])
16790 (define_split
16791   [(set (match_operand:DI 0 "register_operand")
16792         (unspec:DI [(match_operand:XF 1 "register_operand")]
16793                    UNSPEC_FIST))
16794    (clobber (match_operand:DI 2 "memory_operand"))
16795    (clobber (match_scratch 3))]
16796   "reload_completed"
16797   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16798               (clobber (match_dup 3))])
16799    (set (match_dup 0) (match_dup 2))])
16801 (define_split
16802   [(set (match_operand:DI 0 "memory_operand")
16803         (unspec:DI [(match_operand:XF 1 "register_operand")]
16804                    UNSPEC_FIST))
16805    (clobber (match_operand:DI 2 "memory_operand"))
16806    (clobber (match_scratch 3))]
16807   "reload_completed"
16808   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16809               (clobber (match_dup 3))])])
16811 (define_insn_and_split "*fist<mode>2_1"
16812   [(set (match_operand:SWI24 0 "register_operand")
16813         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16814                       UNSPEC_FIST))]
16815   "TARGET_USE_FANCY_MATH_387
16816    && can_create_pseudo_p ()"
16817   "#"
16818   "&& 1"
16819   [(const_int 0)]
16821   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16822   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16823                                         operands[2]));
16824   DONE;
16826   [(set_attr "type" "fpspc")
16827    (set_attr "mode" "<MODE>")])
16829 (define_insn "fist<mode>2"
16830   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16831         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16832                       UNSPEC_FIST))]
16833   "TARGET_USE_FANCY_MATH_387"
16834   "* return output_fix_trunc (insn, operands, false);"
16835   [(set_attr "type" "fpspc")
16836    (set_attr "mode" "<MODE>")])
16838 (define_insn "fist<mode>2_with_temp"
16839   [(set (match_operand:SWI24 0 "register_operand" "=r")
16840         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16841                       UNSPEC_FIST))
16842    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16843   "TARGET_USE_FANCY_MATH_387"
16844   "#"
16845   [(set_attr "type" "fpspc")
16846    (set_attr "mode" "<MODE>")])
16848 (define_split
16849   [(set (match_operand:SWI24 0 "register_operand")
16850         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16851                       UNSPEC_FIST))
16852    (clobber (match_operand:SWI24 2 "memory_operand"))]
16853   "reload_completed"
16854   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16855    (set (match_dup 0) (match_dup 2))])
16857 (define_split
16858   [(set (match_operand:SWI24 0 "memory_operand")
16859         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16860                       UNSPEC_FIST))
16861    (clobber (match_operand:SWI24 2 "memory_operand"))]
16862   "reload_completed"
16863   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16865 (define_expand "lrintxf<mode>2"
16866   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16867      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16868                      UNSPEC_FIST))]
16869   "TARGET_USE_FANCY_MATH_387")
16871 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16872   [(set (match_operand:SWI48 0 "nonimmediate_operand")
16873      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16874                    UNSPEC_FIX_NOTRUNC))]
16875   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16877 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16878   [(match_operand:SWI248x 0 "nonimmediate_operand")
16879    (match_operand:X87MODEF 1 "register_operand")]
16880   "(TARGET_USE_FANCY_MATH_387
16881     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16882         || TARGET_MIX_SSE_I387)
16883     && flag_unsafe_math_optimizations)
16884    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16885        && <SWI248x:MODE>mode != HImode 
16886        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16887        && !flag_trapping_math && !flag_rounding_math)"
16889   if (optimize_insn_for_size_p ())
16890     FAIL;
16892   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16893       && <SWI248x:MODE>mode != HImode
16894       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16895       && !flag_trapping_math && !flag_rounding_math)
16896     ix86_expand_lround (operands[0], operands[1]);
16897   else
16898     ix86_emit_i387_round (operands[0], operands[1]);
16899   DONE;
16902 (define_int_iterator FRNDINT_ROUNDING
16903         [UNSPEC_FRNDINT_FLOOR
16904          UNSPEC_FRNDINT_CEIL
16905          UNSPEC_FRNDINT_TRUNC])
16907 (define_int_iterator FIST_ROUNDING
16908         [UNSPEC_FIST_FLOOR
16909          UNSPEC_FIST_CEIL])
16911 ;; Base name for define_insn
16912 (define_int_attr rounding_insn
16913         [(UNSPEC_FRNDINT_FLOOR "floor")
16914          (UNSPEC_FRNDINT_CEIL "ceil")
16915          (UNSPEC_FRNDINT_TRUNC "btrunc")
16916          (UNSPEC_FIST_FLOOR "floor")
16917          (UNSPEC_FIST_CEIL "ceil")])
16919 (define_int_attr rounding
16920         [(UNSPEC_FRNDINT_FLOOR "floor")
16921          (UNSPEC_FRNDINT_CEIL "ceil")
16922          (UNSPEC_FRNDINT_TRUNC "trunc")
16923          (UNSPEC_FIST_FLOOR "floor")
16924          (UNSPEC_FIST_CEIL "ceil")])
16926 (define_int_attr ROUNDING
16927         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16928          (UNSPEC_FRNDINT_CEIL "CEIL")
16929          (UNSPEC_FRNDINT_TRUNC "TRUNC")
16930          (UNSPEC_FIST_FLOOR "FLOOR")
16931          (UNSPEC_FIST_CEIL "CEIL")])
16933 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16934 (define_insn_and_split "frndint<mode>2_<rounding>"
16935   [(set (match_operand:X87MODEF 0 "register_operand")
16936         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16937                    FRNDINT_ROUNDING))
16938    (clobber (reg:CC FLAGS_REG))]
16939   "TARGET_USE_FANCY_MATH_387
16940    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16941    && can_create_pseudo_p ()"
16942   "#"
16943   "&& 1"
16944   [(const_int 0)]
16946   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16948   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16949   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16951   emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16952                                                  operands[2], operands[3]));
16953   DONE;
16955   [(set_attr "type" "frndint")
16956    (set_attr "i387_cw" "<rounding>")
16957    (set_attr "mode" "<MODE>")])
16959 (define_insn "frndint<mode>2_<rounding>_i387"
16960   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16961         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16962                          FRNDINT_ROUNDING))
16963    (use (match_operand:HI 2 "memory_operand" "m"))
16964    (use (match_operand:HI 3 "memory_operand" "m"))]
16965   "TARGET_USE_FANCY_MATH_387
16966    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16967   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16968   [(set_attr "type" "frndint")
16969    (set_attr "i387_cw" "<rounding>")
16970    (set_attr "mode" "<MODE>")])
16972 (define_expand "<rounding_insn>xf2"
16973   [(parallel [(set (match_operand:XF 0 "register_operand")
16974                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16975                               FRNDINT_ROUNDING))
16976               (clobber (reg:CC FLAGS_REG))])]
16977   "TARGET_USE_FANCY_MATH_387
16978    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16980 (define_expand "<rounding_insn><mode>2"
16981   [(parallel [(set (match_operand:MODEF 0 "register_operand")
16982                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16983                                  FRNDINT_ROUNDING))
16984               (clobber (reg:CC FLAGS_REG))])]
16985   "(TARGET_USE_FANCY_MATH_387
16986     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16987         || TARGET_MIX_SSE_I387)
16988     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16989    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16990        && (TARGET_SSE4_1 || !flag_trapping_math
16991            || flag_fp_int_builtin_inexact))"
16993   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16994       && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16995     {
16996       if (TARGET_SSE4_1)
16997         emit_insn (gen_sse4_1_round<mode>2
16998                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16999                                                        | ROUND_NO_EXC)));
17000       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17001         {
17002           if (ROUND_<ROUNDING> == ROUND_FLOOR)
17003             ix86_expand_floorceil (operands[0], operands[1], true);
17004           else if (ROUND_<ROUNDING> == ROUND_CEIL)
17005             ix86_expand_floorceil (operands[0], operands[1], false);
17006           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17007             ix86_expand_trunc (operands[0], operands[1]);
17008           else
17009             gcc_unreachable ();
17010         }
17011       else
17012         {
17013           if (ROUND_<ROUNDING> == ROUND_FLOOR)
17014             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
17015           else if (ROUND_<ROUNDING> == ROUND_CEIL)
17016             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
17017           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17018             ix86_expand_truncdf_32 (operands[0], operands[1]);
17019           else
17020             gcc_unreachable ();
17021         }
17022     }
17023   else
17024     emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
17025   DONE;
17028 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17029 (define_insn_and_split "frndintxf2_mask_pm"
17030   [(set (match_operand:XF 0 "register_operand")
17031         (unspec:XF [(match_operand:XF 1 "register_operand")]
17032                    UNSPEC_FRNDINT_MASK_PM))
17033    (clobber (reg:CC FLAGS_REG))]
17034   "TARGET_USE_FANCY_MATH_387
17035    && flag_unsafe_math_optimizations
17036    && can_create_pseudo_p ()"
17037   "#"
17038   "&& 1"
17039   [(const_int 0)]
17041   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17043   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17044   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17046   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17047                                           operands[2], operands[3]));
17048   DONE;
17050   [(set_attr "type" "frndint")
17051    (set_attr "i387_cw" "mask_pm")
17052    (set_attr "mode" "XF")])
17054 (define_insn "frndintxf2_mask_pm_i387"
17055   [(set (match_operand:XF 0 "register_operand" "=f")
17056         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17057                    UNSPEC_FRNDINT_MASK_PM))
17058    (use (match_operand:HI 2 "memory_operand" "m"))
17059    (use (match_operand:HI 3 "memory_operand" "m"))]
17060   "TARGET_USE_FANCY_MATH_387
17061    && flag_unsafe_math_optimizations"
17062   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17063   [(set_attr "type" "frndint")
17064    (set_attr "i387_cw" "mask_pm")
17065    (set_attr "mode" "XF")])
17067 (define_expand "nearbyintxf2"
17068   [(parallel [(set (match_operand:XF 0 "register_operand")
17069                    (unspec:XF [(match_operand:XF 1 "register_operand")]
17070                               UNSPEC_FRNDINT_MASK_PM))
17071               (clobber (reg:CC FLAGS_REG))])]
17072   "TARGET_USE_FANCY_MATH_387
17073    && flag_unsafe_math_optimizations")
17075 (define_expand "nearbyint<mode>2"
17076   [(use (match_operand:MODEF 0 "register_operand"))
17077    (use (match_operand:MODEF 1 "register_operand"))]
17078   "TARGET_USE_FANCY_MATH_387
17079    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17080        || TARGET_MIX_SSE_I387)
17081    && flag_unsafe_math_optimizations"
17083   rtx op0 = gen_reg_rtx (XFmode);
17084   rtx op1 = gen_reg_rtx (XFmode);
17086   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17087   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17089   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17090   DONE;
17093 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17094 (define_insn_and_split "*fist<mode>2_<rounding>_1"
17095   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17096         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17097                         FIST_ROUNDING))
17098    (clobber (reg:CC FLAGS_REG))]
17099   "TARGET_USE_FANCY_MATH_387
17100    && flag_unsafe_math_optimizations
17101    && can_create_pseudo_p ()"
17102   "#"
17103   "&& 1"
17104   [(const_int 0)]
17106   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17108   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17109   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17110   if (memory_operand (operands[0], VOIDmode))
17111     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17112                                            operands[2], operands[3]));
17113   else
17114     {
17115       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17116       emit_insn (gen_fist<mode>2_<rounding>_with_temp
17117                   (operands[0], operands[1], operands[2],
17118                    operands[3], operands[4]));
17119     }
17120   DONE;
17122   [(set_attr "type" "fistp")
17123    (set_attr "i387_cw" "<rounding>")
17124    (set_attr "mode" "<MODE>")])
17126 (define_insn "fistdi2_<rounding>"
17127   [(set (match_operand:DI 0 "memory_operand" "=m")
17128         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17129                    FIST_ROUNDING))
17130    (use (match_operand:HI 2 "memory_operand" "m"))
17131    (use (match_operand:HI 3 "memory_operand" "m"))
17132    (clobber (match_scratch:XF 4 "=&1f"))]
17133   "TARGET_USE_FANCY_MATH_387
17134    && flag_unsafe_math_optimizations"
17135   "* return output_fix_trunc (insn, operands, false);"
17136   [(set_attr "type" "fistp")
17137    (set_attr "i387_cw" "<rounding>")
17138    (set_attr "mode" "DI")])
17140 (define_insn "fistdi2_<rounding>_with_temp"
17141   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17142         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17143                    FIST_ROUNDING))
17144    (use (match_operand:HI 2 "memory_operand" "m,m"))
17145    (use (match_operand:HI 3 "memory_operand" "m,m"))
17146    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17147    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17148   "TARGET_USE_FANCY_MATH_387
17149    && flag_unsafe_math_optimizations"
17150   "#"
17151   [(set_attr "type" "fistp")
17152    (set_attr "i387_cw" "<rounding>")
17153    (set_attr "mode" "DI")])
17155 (define_split
17156   [(set (match_operand:DI 0 "register_operand")
17157         (unspec:DI [(match_operand:XF 1 "register_operand")]
17158                    FIST_ROUNDING))
17159    (use (match_operand:HI 2 "memory_operand"))
17160    (use (match_operand:HI 3 "memory_operand"))
17161    (clobber (match_operand:DI 4 "memory_operand"))
17162    (clobber (match_scratch 5))]
17163   "reload_completed"
17164   [(parallel [(set (match_dup 4)
17165                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17166               (use (match_dup 2))
17167               (use (match_dup 3))
17168               (clobber (match_dup 5))])
17169    (set (match_dup 0) (match_dup 4))])
17171 (define_split
17172   [(set (match_operand:DI 0 "memory_operand")
17173         (unspec:DI [(match_operand:XF 1 "register_operand")]
17174                    FIST_ROUNDING))
17175    (use (match_operand:HI 2 "memory_operand"))
17176    (use (match_operand:HI 3 "memory_operand"))
17177    (clobber (match_operand:DI 4 "memory_operand"))
17178    (clobber (match_scratch 5))]
17179   "reload_completed"
17180   [(parallel [(set (match_dup 0)
17181                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17182               (use (match_dup 2))
17183               (use (match_dup 3))
17184               (clobber (match_dup 5))])])
17186 (define_insn "fist<mode>2_<rounding>"
17187   [(set (match_operand:SWI24 0 "memory_operand" "=m")
17188         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17189                       FIST_ROUNDING))
17190    (use (match_operand:HI 2 "memory_operand" "m"))
17191    (use (match_operand:HI 3 "memory_operand" "m"))]
17192   "TARGET_USE_FANCY_MATH_387
17193    && flag_unsafe_math_optimizations"
17194   "* return output_fix_trunc (insn, operands, false);"
17195   [(set_attr "type" "fistp")
17196    (set_attr "i387_cw" "<rounding>")
17197    (set_attr "mode" "<MODE>")])
17199 (define_insn "fist<mode>2_<rounding>_with_temp"
17200   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
17201         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
17202                       FIST_ROUNDING))
17203    (use (match_operand:HI 2 "memory_operand" "m,m"))
17204    (use (match_operand:HI 3 "memory_operand" "m,m"))
17205    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
17206   "TARGET_USE_FANCY_MATH_387
17207    && flag_unsafe_math_optimizations"
17208   "#"
17209   [(set_attr "type" "fistp")
17210    (set_attr "i387_cw" "<rounding>")
17211    (set_attr "mode" "<MODE>")])
17213 (define_split
17214   [(set (match_operand:SWI24 0 "register_operand")
17215         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17216                       FIST_ROUNDING))
17217    (use (match_operand:HI 2 "memory_operand"))
17218    (use (match_operand:HI 3 "memory_operand"))
17219    (clobber (match_operand:SWI24 4 "memory_operand"))]
17220   "reload_completed"
17221   [(parallel [(set (match_dup 4)
17222                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17223               (use (match_dup 2))
17224               (use (match_dup 3))])
17225    (set (match_dup 0) (match_dup 4))])
17227 (define_split
17228   [(set (match_operand:SWI24 0 "memory_operand")
17229         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17230                       FIST_ROUNDING))
17231    (use (match_operand:HI 2 "memory_operand"))
17232    (use (match_operand:HI 3 "memory_operand"))
17233    (clobber (match_operand:SWI24 4 "memory_operand"))]
17234   "reload_completed"
17235   [(parallel [(set (match_dup 0)
17236                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17237               (use (match_dup 2))
17238               (use (match_dup 3))])])
17240 (define_expand "l<rounding_insn>xf<mode>2"
17241   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17242                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17243                                    FIST_ROUNDING))
17244               (clobber (reg:CC FLAGS_REG))])]
17245   "TARGET_USE_FANCY_MATH_387
17246    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17247    && flag_unsafe_math_optimizations")
17249 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17250   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17251                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17252                                  FIST_ROUNDING))
17253               (clobber (reg:CC FLAGS_REG))])]
17254   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17255    && (TARGET_SSE4_1 || !flag_trapping_math)"
17257   if (TARGET_SSE4_1)
17258     {
17259       rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
17261       emit_insn (gen_sse4_1_round<mode>2
17262                  (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
17263                                              | ROUND_NO_EXC)));
17264       emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
17265                  (operands[0], tmp));
17266     }
17267   else if (ROUND_<ROUNDING> == ROUND_FLOOR)
17268     ix86_expand_lfloorceil (operands[0], operands[1], true);
17269   else if (ROUND_<ROUNDING> == ROUND_CEIL)
17270     ix86_expand_lfloorceil (operands[0], operands[1], false);
17271   else
17272     gcc_unreachable ();
17274   DONE;
17277 (define_insn "fxam<mode>2_i387"
17278   [(set (match_operand:HI 0 "register_operand" "=a")
17279         (unspec:HI
17280           [(match_operand:X87MODEF 1 "register_operand" "f")]
17281           UNSPEC_FXAM))]
17282   "TARGET_USE_FANCY_MATH_387"
17283   "fxam\n\tfnstsw\t%0"
17284   [(set_attr "type" "multi")
17285    (set_attr "length" "4")
17286    (set_attr "unit" "i387")
17287    (set_attr "mode" "<MODE>")])
17289 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17290   [(set (match_operand:HI 0 "register_operand")
17291         (unspec:HI
17292           [(match_operand:MODEF 1 "memory_operand")]
17293           UNSPEC_FXAM_MEM))]
17294   "TARGET_USE_FANCY_MATH_387
17295    && can_create_pseudo_p ()"
17296   "#"
17297   "&& 1"
17298   [(set (match_dup 2)(match_dup 1))
17299    (set (match_dup 0)
17300         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17302   operands[2] = gen_reg_rtx (<MODE>mode);
17304   MEM_VOLATILE_P (operands[1]) = 1;
17306   [(set_attr "type" "multi")
17307    (set_attr "unit" "i387")
17308    (set_attr "mode" "<MODE>")])
17310 (define_expand "isinfxf2"
17311   [(use (match_operand:SI 0 "register_operand"))
17312    (use (match_operand:XF 1 "register_operand"))]
17313   "TARGET_USE_FANCY_MATH_387
17314    && ix86_libc_has_function (function_c99_misc)"
17316   rtx mask = GEN_INT (0x45);
17317   rtx val = GEN_INT (0x05);
17319   rtx scratch = gen_reg_rtx (HImode);
17320   rtx res = gen_reg_rtx (QImode);
17322   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17324   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17325   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17326   ix86_expand_setcc (res, EQ,
17327                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17328   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17329   DONE;
17332 (define_expand "isinf<mode>2"
17333   [(use (match_operand:SI 0 "register_operand"))
17334    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17335   "TARGET_USE_FANCY_MATH_387
17336    && ix86_libc_has_function (function_c99_misc)
17337    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17339   rtx mask = GEN_INT (0x45);
17340   rtx val = GEN_INT (0x05);
17342   rtx scratch = gen_reg_rtx (HImode);
17343   rtx res = gen_reg_rtx (QImode);
17345   /* Remove excess precision by forcing value through memory. */
17346   if (memory_operand (operands[1], VOIDmode))
17347     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17348   else
17349     {
17350       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17352       emit_move_insn (temp, operands[1]);
17353       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17354     }
17356   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17357   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17358   ix86_expand_setcc (res, EQ,
17359                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17360   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17361   DONE;
17364 (define_expand "signbittf2"
17365   [(use (match_operand:SI 0 "register_operand"))
17366    (use (match_operand:TF 1 "register_operand"))]
17367   "TARGET_SSE"
17369   if (TARGET_SSE4_1)
17370     {
17371       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17372       rtx scratch = gen_reg_rtx (QImode);
17374       emit_insn (gen_ptesttf2 (operands[1], mask));
17375         ix86_expand_setcc (scratch, NE,
17376                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17378       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17379     }
17380   else
17381     {
17382       emit_insn (gen_sse_movmskps (operands[0],
17383                                    gen_lowpart (V4SFmode, operands[1])));
17384       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17385     }
17386   DONE;
17389 (define_expand "signbitxf2"
17390   [(use (match_operand:SI 0 "register_operand"))
17391    (use (match_operand:XF 1 "register_operand"))]
17392   "TARGET_USE_FANCY_MATH_387"
17394   rtx scratch = gen_reg_rtx (HImode);
17396   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17397   emit_insn (gen_andsi3 (operands[0],
17398              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17399   DONE;
17402 (define_insn "movmsk_df"
17403   [(set (match_operand:SI 0 "register_operand" "=r")
17404         (unspec:SI
17405           [(match_operand:DF 1 "register_operand" "x")]
17406           UNSPEC_MOVMSK))]
17407   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17408   "%vmovmskpd\t{%1, %0|%0, %1}"
17409   [(set_attr "type" "ssemov")
17410    (set_attr "prefix" "maybe_vex")
17411    (set_attr "mode" "DF")])
17413 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17414 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17415 (define_expand "signbitdf2"
17416   [(use (match_operand:SI 0 "register_operand"))
17417    (use (match_operand:DF 1 "register_operand"))]
17418   "TARGET_USE_FANCY_MATH_387
17419    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17421   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17422     {
17423       emit_insn (gen_movmsk_df (operands[0], operands[1]));
17424       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17425     }
17426   else
17427     {
17428       rtx scratch = gen_reg_rtx (HImode);
17430       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17431       emit_insn (gen_andsi3 (operands[0],
17432                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17433     }
17434   DONE;
17437 (define_expand "signbitsf2"
17438   [(use (match_operand:SI 0 "register_operand"))
17439    (use (match_operand:SF 1 "register_operand"))]
17440   "TARGET_USE_FANCY_MATH_387
17441    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17443   rtx scratch = gen_reg_rtx (HImode);
17445   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17446   emit_insn (gen_andsi3 (operands[0],
17447              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17448   DONE;
17451 ;; Block operation instructions
17453 (define_insn "cld"
17454   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17455   ""
17456   "cld"
17457   [(set_attr "length" "1")
17458    (set_attr "length_immediate" "0")
17459    (set_attr "modrm" "0")])
17461 (define_expand "movmem<mode>"
17462   [(use (match_operand:BLK 0 "memory_operand"))
17463    (use (match_operand:BLK 1 "memory_operand"))
17464    (use (match_operand:SWI48 2 "nonmemory_operand"))
17465    (use (match_operand:SWI48 3 "const_int_operand"))
17466    (use (match_operand:SI 4 "const_int_operand"))
17467    (use (match_operand:SI 5 "const_int_operand"))
17468    (use (match_operand:SI 6 ""))
17469    (use (match_operand:SI 7 ""))
17470    (use (match_operand:SI 8 ""))]
17471   ""
17473  if (ix86_expand_set_or_movmem (operands[0], operands[1],
17474                                 operands[2], NULL, operands[3],
17475                                 operands[4], operands[5],
17476                                 operands[6], operands[7],
17477                                 operands[8], false))
17478    DONE;
17479  else
17480    FAIL;
17483 ;; Most CPUs don't like single string operations
17484 ;; Handle this case here to simplify previous expander.
17486 (define_expand "strmov"
17487   [(set (match_dup 4) (match_operand 3 "memory_operand"))
17488    (set (match_operand 1 "memory_operand") (match_dup 4))
17489    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17490               (clobber (reg:CC FLAGS_REG))])
17491    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17492               (clobber (reg:CC FLAGS_REG))])]
17493   ""
17495   /* Can't use this for non-default address spaces.  */
17496   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17497     FAIL;
17499   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17501   /* If .md ever supports :P for Pmode, these can be directly
17502      in the pattern above.  */
17503   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17504   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17506   /* Can't use this if the user has appropriated esi or edi.  */
17507   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17508       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17509     {
17510       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17511                                       operands[2], operands[3],
17512                                       operands[5], operands[6]));
17513       DONE;
17514     }
17516   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17519 (define_expand "strmov_singleop"
17520   [(parallel [(set (match_operand 1 "memory_operand")
17521                    (match_operand 3 "memory_operand"))
17522               (set (match_operand 0 "register_operand")
17523                    (match_operand 4))
17524               (set (match_operand 2 "register_operand")
17525                    (match_operand 5))])]
17526   ""
17528   if (TARGET_CLD)
17529     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17532 (define_insn "*strmovdi_rex_1"
17533   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17534         (mem:DI (match_operand:P 3 "register_operand" "1")))
17535    (set (match_operand:P 0 "register_operand" "=D")
17536         (plus:P (match_dup 2)
17537                 (const_int 8)))
17538    (set (match_operand:P 1 "register_operand" "=S")
17539         (plus:P (match_dup 3)
17540                 (const_int 8)))]
17541   "TARGET_64BIT
17542    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17543    && ix86_check_no_addr_space (insn)"
17544   "%^movsq"
17545   [(set_attr "type" "str")
17546    (set_attr "memory" "both")
17547    (set_attr "mode" "DI")])
17549 (define_insn "*strmovsi_1"
17550   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17551         (mem:SI (match_operand:P 3 "register_operand" "1")))
17552    (set (match_operand:P 0 "register_operand" "=D")
17553         (plus:P (match_dup 2)
17554                 (const_int 4)))
17555    (set (match_operand:P 1 "register_operand" "=S")
17556         (plus:P (match_dup 3)
17557                 (const_int 4)))]
17558   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17559    && ix86_check_no_addr_space (insn)"
17560   "%^movs{l|d}"
17561   [(set_attr "type" "str")
17562    (set_attr "memory" "both")
17563    (set_attr "mode" "SI")])
17565 (define_insn "*strmovhi_1"
17566   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17567         (mem:HI (match_operand:P 3 "register_operand" "1")))
17568    (set (match_operand:P 0 "register_operand" "=D")
17569         (plus:P (match_dup 2)
17570                 (const_int 2)))
17571    (set (match_operand:P 1 "register_operand" "=S")
17572         (plus:P (match_dup 3)
17573                 (const_int 2)))]
17574   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17575    && ix86_check_no_addr_space (insn)"
17576   "%^movsw"
17577   [(set_attr "type" "str")
17578    (set_attr "memory" "both")
17579    (set_attr "mode" "HI")])
17581 (define_insn "*strmovqi_1"
17582   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17583         (mem:QI (match_operand:P 3 "register_operand" "1")))
17584    (set (match_operand:P 0 "register_operand" "=D")
17585         (plus:P (match_dup 2)
17586                 (const_int 1)))
17587    (set (match_operand:P 1 "register_operand" "=S")
17588         (plus:P (match_dup 3)
17589                 (const_int 1)))]
17590   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17591    && ix86_check_no_addr_space (insn)"
17592   "%^movsb"
17593   [(set_attr "type" "str")
17594    (set_attr "memory" "both")
17595    (set (attr "prefix_rex")
17596         (if_then_else
17597           (match_test "<P:MODE>mode == DImode")
17598           (const_string "0")
17599           (const_string "*")))
17600    (set_attr "mode" "QI")])
17602 (define_expand "rep_mov"
17603   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17604               (set (match_operand 0 "register_operand")
17605                    (match_operand 5))
17606               (set (match_operand 2 "register_operand")
17607                    (match_operand 6))
17608               (set (match_operand 1 "memory_operand")
17609                    (match_operand 3 "memory_operand"))
17610               (use (match_dup 4))])]
17611   ""
17613   if (TARGET_CLD)
17614     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17617 (define_insn "*rep_movdi_rex64"
17618   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17619    (set (match_operand:P 0 "register_operand" "=D")
17620         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17621                           (const_int 3))
17622                 (match_operand:P 3 "register_operand" "0")))
17623    (set (match_operand:P 1 "register_operand" "=S")
17624         (plus:P (ashift:P (match_dup 5) (const_int 3))
17625                 (match_operand:P 4 "register_operand" "1")))
17626    (set (mem:BLK (match_dup 3))
17627         (mem:BLK (match_dup 4)))
17628    (use (match_dup 5))]
17629   "TARGET_64BIT
17630    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17631    && ix86_check_no_addr_space (insn)"
17632   "%^rep{%;} movsq"
17633   [(set_attr "type" "str")
17634    (set_attr "prefix_rep" "1")
17635    (set_attr "memory" "both")
17636    (set_attr "mode" "DI")])
17638 (define_insn "*rep_movsi"
17639   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17640    (set (match_operand:P 0 "register_operand" "=D")
17641         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17642                           (const_int 2))
17643                  (match_operand:P 3 "register_operand" "0")))
17644    (set (match_operand:P 1 "register_operand" "=S")
17645         (plus:P (ashift:P (match_dup 5) (const_int 2))
17646                 (match_operand:P 4 "register_operand" "1")))
17647    (set (mem:BLK (match_dup 3))
17648         (mem:BLK (match_dup 4)))
17649    (use (match_dup 5))]
17650   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17651    && ix86_check_no_addr_space (insn)"
17652   "%^rep{%;} movs{l|d}"
17653   [(set_attr "type" "str")
17654    (set_attr "prefix_rep" "1")
17655    (set_attr "memory" "both")
17656    (set_attr "mode" "SI")])
17658 (define_insn "*rep_movqi"
17659   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17660    (set (match_operand:P 0 "register_operand" "=D")
17661         (plus:P (match_operand:P 3 "register_operand" "0")
17662                 (match_operand:P 5 "register_operand" "2")))
17663    (set (match_operand:P 1 "register_operand" "=S")
17664         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17665    (set (mem:BLK (match_dup 3))
17666         (mem:BLK (match_dup 4)))
17667    (use (match_dup 5))]
17668   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17669    && ix86_check_no_addr_space (insn)"
17670   "%^rep{%;} movsb"
17671   [(set_attr "type" "str")
17672    (set_attr "prefix_rep" "1")
17673    (set_attr "memory" "both")
17674    (set_attr "mode" "QI")])
17676 (define_expand "setmem<mode>"
17677    [(use (match_operand:BLK 0 "memory_operand"))
17678     (use (match_operand:SWI48 1 "nonmemory_operand"))
17679     (use (match_operand:QI 2 "nonmemory_operand"))
17680     (use (match_operand 3 "const_int_operand"))
17681     (use (match_operand:SI 4 "const_int_operand"))
17682     (use (match_operand:SI 5 "const_int_operand"))
17683     (use (match_operand:SI 6 ""))
17684     (use (match_operand:SI 7 ""))
17685     (use (match_operand:SI 8 ""))]
17686   ""
17688  if (ix86_expand_set_or_movmem (operands[0], NULL,
17689                                 operands[1], operands[2],
17690                                 operands[3], operands[4],
17691                                 operands[5], operands[6],
17692                                 operands[7], operands[8], true))
17693    DONE;
17694  else
17695    FAIL;
17698 ;; Most CPUs don't like single string operations
17699 ;; Handle this case here to simplify previous expander.
17701 (define_expand "strset"
17702   [(set (match_operand 1 "memory_operand")
17703         (match_operand 2 "register_operand"))
17704    (parallel [(set (match_operand 0 "register_operand")
17705                    (match_dup 3))
17706               (clobber (reg:CC FLAGS_REG))])]
17707   ""
17709   /* Can't use this for non-default address spaces.  */
17710   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17711     FAIL;
17713   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17714     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17716   /* If .md ever supports :P for Pmode, this can be directly
17717      in the pattern above.  */
17718   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17719                               GEN_INT (GET_MODE_SIZE (GET_MODE
17720                                                       (operands[2]))));
17721   /* Can't use this if the user has appropriated eax or edi.  */
17722   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17723       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17724     {
17725       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17726                                       operands[3]));
17727       DONE;
17728     }
17731 (define_expand "strset_singleop"
17732   [(parallel [(set (match_operand 1 "memory_operand")
17733                    (match_operand 2 "register_operand"))
17734               (set (match_operand 0 "register_operand")
17735                    (match_operand 3))
17736               (unspec [(const_int 0)] UNSPEC_STOS)])]
17737   ""
17739   if (TARGET_CLD)
17740     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17743 (define_insn "*strsetdi_rex_1"
17744   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17745         (match_operand:DI 2 "register_operand" "a"))
17746    (set (match_operand:P 0 "register_operand" "=D")
17747         (plus:P (match_dup 1)
17748                 (const_int 8)))
17749    (unspec [(const_int 0)] UNSPEC_STOS)]
17750   "TARGET_64BIT
17751    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17752    && ix86_check_no_addr_space (insn)"
17753   "%^stosq"
17754   [(set_attr "type" "str")
17755    (set_attr "memory" "store")
17756    (set_attr "mode" "DI")])
17758 (define_insn "*strsetsi_1"
17759   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17760         (match_operand:SI 2 "register_operand" "a"))
17761    (set (match_operand:P 0 "register_operand" "=D")
17762         (plus:P (match_dup 1)
17763                 (const_int 4)))
17764    (unspec [(const_int 0)] UNSPEC_STOS)]
17765   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17766    && ix86_check_no_addr_space (insn)"
17767   "%^stos{l|d}"
17768   [(set_attr "type" "str")
17769    (set_attr "memory" "store")
17770    (set_attr "mode" "SI")])
17772 (define_insn "*strsethi_1"
17773   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17774         (match_operand:HI 2 "register_operand" "a"))
17775    (set (match_operand:P 0 "register_operand" "=D")
17776         (plus:P (match_dup 1)
17777                 (const_int 2)))
17778    (unspec [(const_int 0)] UNSPEC_STOS)]
17779   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17780    && ix86_check_no_addr_space (insn)"
17781   "%^stosw"
17782   [(set_attr "type" "str")
17783    (set_attr "memory" "store")
17784    (set_attr "mode" "HI")])
17786 (define_insn "*strsetqi_1"
17787   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17788         (match_operand:QI 2 "register_operand" "a"))
17789    (set (match_operand:P 0 "register_operand" "=D")
17790         (plus:P (match_dup 1)
17791                 (const_int 1)))
17792    (unspec [(const_int 0)] UNSPEC_STOS)]
17793   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17794    && ix86_check_no_addr_space (insn)"
17795   "%^stosb"
17796   [(set_attr "type" "str")
17797    (set_attr "memory" "store")
17798    (set (attr "prefix_rex")
17799         (if_then_else
17800           (match_test "<P:MODE>mode == DImode")
17801           (const_string "0")
17802           (const_string "*")))
17803    (set_attr "mode" "QI")])
17805 (define_expand "rep_stos"
17806   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17807               (set (match_operand 0 "register_operand")
17808                    (match_operand 4))
17809               (set (match_operand 2 "memory_operand") (const_int 0))
17810               (use (match_operand 3 "register_operand"))
17811               (use (match_dup 1))])]
17812   ""
17814   if (TARGET_CLD)
17815     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17818 (define_insn "*rep_stosdi_rex64"
17819   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17820    (set (match_operand:P 0 "register_operand" "=D")
17821         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17822                           (const_int 3))
17823                  (match_operand:P 3 "register_operand" "0")))
17824    (set (mem:BLK (match_dup 3))
17825         (const_int 0))
17826    (use (match_operand:DI 2 "register_operand" "a"))
17827    (use (match_dup 4))]
17828   "TARGET_64BIT
17829    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17830    && ix86_check_no_addr_space (insn)"
17831   "%^rep{%;} stosq"
17832   [(set_attr "type" "str")
17833    (set_attr "prefix_rep" "1")
17834    (set_attr "memory" "store")
17835    (set_attr "mode" "DI")])
17837 (define_insn "*rep_stossi"
17838   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17839    (set (match_operand:P 0 "register_operand" "=D")
17840         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17841                           (const_int 2))
17842                  (match_operand:P 3 "register_operand" "0")))
17843    (set (mem:BLK (match_dup 3))
17844         (const_int 0))
17845    (use (match_operand:SI 2 "register_operand" "a"))
17846    (use (match_dup 4))]
17847   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17848    && ix86_check_no_addr_space (insn)"
17849   "%^rep{%;} stos{l|d}"
17850   [(set_attr "type" "str")
17851    (set_attr "prefix_rep" "1")
17852    (set_attr "memory" "store")
17853    (set_attr "mode" "SI")])
17855 (define_insn "*rep_stosqi"
17856   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17857    (set (match_operand:P 0 "register_operand" "=D")
17858         (plus:P (match_operand:P 3 "register_operand" "0")
17859                 (match_operand:P 4 "register_operand" "1")))
17860    (set (mem:BLK (match_dup 3))
17861         (const_int 0))
17862    (use (match_operand:QI 2 "register_operand" "a"))
17863    (use (match_dup 4))]
17864   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17865    && ix86_check_no_addr_space (insn)"
17866   "%^rep{%;} stosb"
17867   [(set_attr "type" "str")
17868    (set_attr "prefix_rep" "1")
17869    (set_attr "memory" "store")
17870    (set (attr "prefix_rex")
17871         (if_then_else
17872           (match_test "<P:MODE>mode == DImode")
17873           (const_string "0")
17874           (const_string "*")))
17875    (set_attr "mode" "QI")])
17877 (define_expand "cmpstrnsi"
17878   [(set (match_operand:SI 0 "register_operand")
17879         (compare:SI (match_operand:BLK 1 "general_operand")
17880                     (match_operand:BLK 2 "general_operand")))
17881    (use (match_operand 3 "general_operand"))
17882    (use (match_operand 4 "immediate_operand"))]
17883   ""
17885   rtx addr1, addr2, out, outlow, count, countreg, align;
17887   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17888     FAIL;
17890   /* Can't use this if the user has appropriated ecx, esi or edi.  */
17891   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17892     FAIL;
17894   /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
17895      will have rewritten the length arg to be the minimum of the const string
17896      length and the actual length arg.  If both strings are the same and
17897      shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17898      will incorrectly base the results on chars past the 0 byte.  */
17899   tree t1 = MEM_EXPR (operands[1]);
17900   tree t2 = MEM_EXPR (operands[2]);
17901   if (!((t1 && TREE_CODE (t1) == MEM_REF
17902          && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17903          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17904       || (t2 && TREE_CODE (t2) == MEM_REF
17905           && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17906           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17907     FAIL;
17909   out = operands[0];
17910   if (!REG_P (out))
17911     out = gen_reg_rtx (SImode);
17913   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17914   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17915   if (addr1 != XEXP (operands[1], 0))
17916     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17917   if (addr2 != XEXP (operands[2], 0))
17918     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17920   count = operands[3];
17921   countreg = ix86_zero_extend_to_Pmode (count);
17923   /* %%% Iff we are testing strict equality, we can use known alignment
17924      to good advantage.  This may be possible with combine, particularly
17925      once cc0 is dead.  */
17926   align = operands[4];
17928   if (CONST_INT_P (count))
17929     {
17930       if (INTVAL (count) == 0)
17931         {
17932           emit_move_insn (operands[0], const0_rtx);
17933           DONE;
17934         }
17935       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17936                                      operands[1], operands[2]));
17937     }
17938   else
17939     {
17940       rtx (*gen_cmp) (rtx, rtx);
17942       gen_cmp = (TARGET_64BIT
17943                  ? gen_cmpdi_1 : gen_cmpsi_1);
17945       emit_insn (gen_cmp (countreg, countreg));
17946       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17947                                   operands[1], operands[2]));
17948     }
17950   outlow = gen_lowpart (QImode, out);
17951   emit_insn (gen_cmpintqi (outlow));
17952   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17954   if (operands[0] != out)
17955     emit_move_insn (operands[0], out);
17957   DONE;
17960 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17962 (define_expand "cmpintqi"
17963   [(set (match_dup 1)
17964         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17965    (set (match_dup 2)
17966         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17967    (parallel [(set (match_operand:QI 0 "register_operand")
17968                    (minus:QI (match_dup 1)
17969                              (match_dup 2)))
17970               (clobber (reg:CC FLAGS_REG))])]
17971   ""
17973   operands[1] = gen_reg_rtx (QImode);
17974   operands[2] = gen_reg_rtx (QImode);
17977 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17978 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17980 (define_expand "cmpstrnqi_nz_1"
17981   [(parallel [(set (reg:CC FLAGS_REG)
17982                    (compare:CC (match_operand 4 "memory_operand")
17983                                (match_operand 5 "memory_operand")))
17984               (use (match_operand 2 "register_operand"))
17985               (use (match_operand:SI 3 "immediate_operand"))
17986               (clobber (match_operand 0 "register_operand"))
17987               (clobber (match_operand 1 "register_operand"))
17988               (clobber (match_dup 2))])]
17989   ""
17991   if (TARGET_CLD)
17992     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17995 (define_insn "*cmpstrnqi_nz_1"
17996   [(set (reg:CC FLAGS_REG)
17997         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17998                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17999    (use (match_operand:P 6 "register_operand" "2"))
18000    (use (match_operand:SI 3 "immediate_operand" "i"))
18001    (clobber (match_operand:P 0 "register_operand" "=S"))
18002    (clobber (match_operand:P 1 "register_operand" "=D"))
18003    (clobber (match_operand:P 2 "register_operand" "=c"))]
18004   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18005    && ix86_check_no_addr_space (insn)"
18006   "%^repz{%;} cmpsb"
18007   [(set_attr "type" "str")
18008    (set_attr "mode" "QI")
18009    (set (attr "prefix_rex")
18010         (if_then_else
18011           (match_test "<P:MODE>mode == DImode")
18012           (const_string "0")
18013           (const_string "*")))
18014    (set_attr "prefix_rep" "1")])
18016 ;; The same, but the count is not known to not be zero.
18018 (define_expand "cmpstrnqi_1"
18019   [(parallel [(set (reg:CC FLAGS_REG)
18020                 (if_then_else:CC (ne (match_operand 2 "register_operand")
18021                                      (const_int 0))
18022                   (compare:CC (match_operand 4 "memory_operand")
18023                               (match_operand 5 "memory_operand"))
18024                   (const_int 0)))
18025               (use (match_operand:SI 3 "immediate_operand"))
18026               (use (reg:CC FLAGS_REG))
18027               (clobber (match_operand 0 "register_operand"))
18028               (clobber (match_operand 1 "register_operand"))
18029               (clobber (match_dup 2))])]
18030   ""
18032   if (TARGET_CLD)
18033     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18036 (define_insn "*cmpstrnqi_1"
18037   [(set (reg:CC FLAGS_REG)
18038         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
18039                              (const_int 0))
18040           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18041                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
18042           (const_int 0)))
18043    (use (match_operand:SI 3 "immediate_operand" "i"))
18044    (use (reg:CC FLAGS_REG))
18045    (clobber (match_operand:P 0 "register_operand" "=S"))
18046    (clobber (match_operand:P 1 "register_operand" "=D"))
18047    (clobber (match_operand:P 2 "register_operand" "=c"))]
18048   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18049    && ix86_check_no_addr_space (insn)"
18050   "%^repz{%;} cmpsb"
18051   [(set_attr "type" "str")
18052    (set_attr "mode" "QI")
18053    (set (attr "prefix_rex")
18054         (if_then_else
18055           (match_test "<P:MODE>mode == DImode")
18056           (const_string "0")
18057           (const_string "*")))
18058    (set_attr "prefix_rep" "1")])
18060 (define_expand "strlen<mode>"
18061   [(set (match_operand:P 0 "register_operand")
18062         (unspec:P [(match_operand:BLK 1 "general_operand")
18063                    (match_operand:QI 2 "immediate_operand")
18064                    (match_operand 3 "immediate_operand")]
18065                   UNSPEC_SCAS))]
18066   ""
18068  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18069    DONE;
18070  else
18071    FAIL;
18074 (define_expand "strlenqi_1"
18075   [(parallel [(set (match_operand 0 "register_operand")
18076                    (match_operand 2))
18077               (clobber (match_operand 1 "register_operand"))
18078               (clobber (reg:CC FLAGS_REG))])]
18079   ""
18081   if (TARGET_CLD)
18082     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18085 (define_insn "*strlenqi_1"
18086   [(set (match_operand:P 0 "register_operand" "=&c")
18087         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
18088                    (match_operand:QI 2 "register_operand" "a")
18089                    (match_operand:P 3 "immediate_operand" "i")
18090                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
18091    (clobber (match_operand:P 1 "register_operand" "=D"))
18092    (clobber (reg:CC FLAGS_REG))]
18093   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18094    && ix86_check_no_addr_space (insn)"
18095   "%^repnz{%;} scasb"
18096   [(set_attr "type" "str")
18097    (set_attr "mode" "QI")
18098    (set (attr "prefix_rex")
18099         (if_then_else
18100           (match_test "<P:MODE>mode == DImode")
18101           (const_string "0")
18102           (const_string "*")))
18103    (set_attr "prefix_rep" "1")])
18105 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18106 ;; handled in combine, but it is not currently up to the task.
18107 ;; When used for their truth value, the cmpstrn* expanders generate
18108 ;; code like this:
18110 ;;   repz cmpsb
18111 ;;   seta       %al
18112 ;;   setb       %dl
18113 ;;   cmpb       %al, %dl
18114 ;;   jcc        label
18116 ;; The intermediate three instructions are unnecessary.
18118 ;; This one handles cmpstrn*_nz_1...
18119 (define_peephole2
18120   [(parallel[
18121      (set (reg:CC FLAGS_REG)
18122           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18123                       (mem:BLK (match_operand 5 "register_operand"))))
18124      (use (match_operand 6 "register_operand"))
18125      (use (match_operand:SI 3 "immediate_operand"))
18126      (clobber (match_operand 0 "register_operand"))
18127      (clobber (match_operand 1 "register_operand"))
18128      (clobber (match_operand 2 "register_operand"))])
18129    (set (match_operand:QI 7 "register_operand")
18130         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18131    (set (match_operand:QI 8 "register_operand")
18132         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18133    (set (reg FLAGS_REG)
18134         (compare (match_dup 7) (match_dup 8)))
18135   ]
18136   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18137   [(parallel[
18138      (set (reg:CC FLAGS_REG)
18139           (compare:CC (mem:BLK (match_dup 4))
18140                       (mem:BLK (match_dup 5))))
18141      (use (match_dup 6))
18142      (use (match_dup 3))
18143      (clobber (match_dup 0))
18144      (clobber (match_dup 1))
18145      (clobber (match_dup 2))])])
18147 ;; ...and this one handles cmpstrn*_1.
18148 (define_peephole2
18149   [(parallel[
18150      (set (reg:CC FLAGS_REG)
18151           (if_then_else:CC (ne (match_operand 6 "register_operand")
18152                                (const_int 0))
18153             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18154                         (mem:BLK (match_operand 5 "register_operand")))
18155             (const_int 0)))
18156      (use (match_operand:SI 3 "immediate_operand"))
18157      (use (reg:CC FLAGS_REG))
18158      (clobber (match_operand 0 "register_operand"))
18159      (clobber (match_operand 1 "register_operand"))
18160      (clobber (match_operand 2 "register_operand"))])
18161    (set (match_operand:QI 7 "register_operand")
18162         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18163    (set (match_operand:QI 8 "register_operand")
18164         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18165    (set (reg FLAGS_REG)
18166         (compare (match_dup 7) (match_dup 8)))
18167   ]
18168   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18169   [(parallel[
18170      (set (reg:CC FLAGS_REG)
18171           (if_then_else:CC (ne (match_dup 6)
18172                                (const_int 0))
18173             (compare:CC (mem:BLK (match_dup 4))
18174                         (mem:BLK (match_dup 5)))
18175             (const_int 0)))
18176      (use (match_dup 3))
18177      (use (reg:CC FLAGS_REG))
18178      (clobber (match_dup 0))
18179      (clobber (match_dup 1))
18180      (clobber (match_dup 2))])])
18182 ;; Conditional move instructions.
18184 (define_expand "mov<mode>cc"
18185   [(set (match_operand:SWIM 0 "register_operand")
18186         (if_then_else:SWIM (match_operand 1 "comparison_operator")
18187                            (match_operand:SWIM 2 "<general_operand>")
18188                            (match_operand:SWIM 3 "<general_operand>")))]
18189   ""
18190   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18192 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18193 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18194 ;; So just document what we're doing explicitly.
18196 (define_expand "x86_mov<mode>cc_0_m1"
18197   [(parallel
18198     [(set (match_operand:SWI48 0 "register_operand")
18199           (if_then_else:SWI48
18200             (match_operator:SWI48 2 "ix86_carry_flag_operator"
18201              [(match_operand 1 "flags_reg_operand")
18202               (const_int 0)])
18203             (const_int -1)
18204             (const_int 0)))
18205      (clobber (reg:CC FLAGS_REG))])])
18207 (define_insn "*x86_mov<mode>cc_0_m1"
18208   [(set (match_operand:SWI48 0 "register_operand" "=r")
18209         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18210                              [(reg FLAGS_REG) (const_int 0)])
18211           (const_int -1)
18212           (const_int 0)))
18213    (clobber (reg:CC FLAGS_REG))]
18214   ""
18215   "sbb{<imodesuffix>}\t%0, %0"
18216   [(set_attr "type" "alu1")
18217    (set_attr "modrm_class" "op0")
18218    (set_attr "use_carry" "1")
18219    (set_attr "pent_pair" "pu")
18220    (set_attr "mode" "<MODE>")
18221    (set_attr "length_immediate" "0")])
18223 (define_insn "*x86_mov<mode>cc_0_m1_se"
18224   [(set (match_operand:SWI48 0 "register_operand" "=r")
18225         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18226                              [(reg FLAGS_REG) (const_int 0)])
18227                             (const_int 1)
18228                             (const_int 0)))
18229    (clobber (reg:CC FLAGS_REG))]
18230   ""
18231   "sbb{<imodesuffix>}\t%0, %0"
18232   [(set_attr "type" "alu1")
18233    (set_attr "modrm_class" "op0")
18234    (set_attr "use_carry" "1")
18235    (set_attr "pent_pair" "pu")
18236    (set_attr "mode" "<MODE>")
18237    (set_attr "length_immediate" "0")])
18239 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18240   [(set (match_operand:SWI48 0 "register_operand" "=r")
18241         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18242                     [(reg FLAGS_REG) (const_int 0)])))
18243    (clobber (reg:CC FLAGS_REG))]
18244   ""
18245   "sbb{<imodesuffix>}\t%0, %0"
18246   [(set_attr "type" "alu1")
18247    (set_attr "modrm_class" "op0")
18248    (set_attr "use_carry" "1")
18249    (set_attr "pent_pair" "pu")
18250    (set_attr "mode" "<MODE>")
18251    (set_attr "length_immediate" "0")])
18253 (define_insn "*mov<mode>cc_noc"
18254   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18255         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18256                                [(reg FLAGS_REG) (const_int 0)])
18257           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18258           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18259   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18260   "@
18261    cmov%O2%C1\t{%2, %0|%0, %2}
18262    cmov%O2%c1\t{%3, %0|%0, %3}"
18263   [(set_attr "type" "icmov")
18264    (set_attr "mode" "<MODE>")])
18266 (define_insn "*movsicc_noc_zext"
18267   [(set (match_operand:DI 0 "register_operand" "=r,r")
18268         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18269                            [(reg FLAGS_REG) (const_int 0)])
18270           (zero_extend:DI
18271             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18272           (zero_extend:DI
18273             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18274   "TARGET_64BIT
18275    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18276   "@
18277    cmov%O2%C1\t{%2, %k0|%k0, %2}
18278    cmov%O2%c1\t{%3, %k0|%k0, %3}"
18279   [(set_attr "type" "icmov")
18280    (set_attr "mode" "SI")])
18282 ;; Don't do conditional moves with memory inputs.  This splitter helps
18283 ;; register starved x86_32 by forcing inputs into registers before reload.
18284 (define_split
18285   [(set (match_operand:SWI248 0 "register_operand")
18286         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18287                                [(reg FLAGS_REG) (const_int 0)])
18288           (match_operand:SWI248 2 "nonimmediate_operand")
18289           (match_operand:SWI248 3 "nonimmediate_operand")))]
18290   "!TARGET_64BIT && TARGET_CMOVE
18291    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18292    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18293    && can_create_pseudo_p ()
18294    && optimize_insn_for_speed_p ()"
18295   [(set (match_dup 0)
18296         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18298   if (MEM_P (operands[2]))
18299     operands[2] = force_reg (<MODE>mode, operands[2]);
18300   if (MEM_P (operands[3]))
18301     operands[3] = force_reg (<MODE>mode, operands[3]);
18304 (define_insn "*movqicc_noc"
18305   [(set (match_operand:QI 0 "register_operand" "=r,r")
18306         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18307                            [(reg FLAGS_REG) (const_int 0)])
18308                       (match_operand:QI 2 "register_operand" "r,0")
18309                       (match_operand:QI 3 "register_operand" "0,r")))]
18310   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18311   "#"
18312   [(set_attr "type" "icmov")
18313    (set_attr "mode" "QI")])
18315 (define_split
18316   [(set (match_operand:SWI12 0 "register_operand")
18317         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18318                               [(reg FLAGS_REG) (const_int 0)])
18319                       (match_operand:SWI12 2 "register_operand")
18320                       (match_operand:SWI12 3 "register_operand")))]
18321   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18322    && reload_completed"
18323   [(set (match_dup 0)
18324         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18326   operands[0] = gen_lowpart (SImode, operands[0]);
18327   operands[2] = gen_lowpart (SImode, operands[2]);
18328   operands[3] = gen_lowpart (SImode, operands[3]);
18331 ;; Don't do conditional moves with memory inputs
18332 (define_peephole2
18333   [(match_scratch:SWI248 4 "r")
18334    (set (match_operand:SWI248 0 "register_operand")
18335         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18336                                [(reg FLAGS_REG) (const_int 0)])
18337           (match_operand:SWI248 2 "nonimmediate_operand")
18338           (match_operand:SWI248 3 "nonimmediate_operand")))]
18339   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18340    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18341    && optimize_insn_for_speed_p ()"
18342   [(set (match_dup 4) (match_dup 5))
18343    (set (match_dup 0)
18344         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18346   if (MEM_P (operands[2]))
18347     {
18348       operands[5] = operands[2];
18349       operands[2] = operands[4];
18350     }
18351   else if (MEM_P (operands[3]))
18352     {
18353       operands[5] = operands[3];
18354       operands[3] = operands[4];
18355     }
18356   else
18357     gcc_unreachable ();
18360 (define_peephole2
18361   [(match_scratch:SI 4 "r")
18362    (set (match_operand:DI 0 "register_operand")
18363         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18364                            [(reg FLAGS_REG) (const_int 0)])
18365           (zero_extend:DI
18366             (match_operand:SI 2 "nonimmediate_operand"))
18367           (zero_extend:DI
18368             (match_operand:SI 3 "nonimmediate_operand"))))]
18369   "TARGET_64BIT
18370    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18371    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18372    && optimize_insn_for_speed_p ()"
18373   [(set (match_dup 4) (match_dup 5))
18374    (set (match_dup 0)
18375         (if_then_else:DI (match_dup 1)
18376           (zero_extend:DI (match_dup 2))
18377           (zero_extend:DI (match_dup 3))))]
18379   if (MEM_P (operands[2]))
18380     {
18381       operands[5] = operands[2];
18382       operands[2] = operands[4];
18383     }
18384   else if (MEM_P (operands[3]))
18385     {
18386       operands[5] = operands[3];
18387       operands[3] = operands[4];
18388     }
18389   else
18390     gcc_unreachable ();
18393 (define_expand "mov<mode>cc"
18394   [(set (match_operand:X87MODEF 0 "register_operand")
18395         (if_then_else:X87MODEF
18396           (match_operand 1 "comparison_operator")
18397           (match_operand:X87MODEF 2 "register_operand")
18398           (match_operand:X87MODEF 3 "register_operand")))]
18399   "(TARGET_80387 && TARGET_CMOVE)
18400    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18401   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18403 (define_insn "*movxfcc_1"
18404   [(set (match_operand:XF 0 "register_operand" "=f,f")
18405         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18406                                 [(reg FLAGS_REG) (const_int 0)])
18407                       (match_operand:XF 2 "register_operand" "f,0")
18408                       (match_operand:XF 3 "register_operand" "0,f")))]
18409   "TARGET_80387 && TARGET_CMOVE"
18410   "@
18411    fcmov%F1\t{%2, %0|%0, %2}
18412    fcmov%f1\t{%3, %0|%0, %3}"
18413   [(set_attr "type" "fcmov")
18414    (set_attr "mode" "XF")])
18416 (define_insn "*movdfcc_1"
18417   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18418         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18419                                 [(reg FLAGS_REG) (const_int 0)])
18420                       (match_operand:DF 2 "nonimmediate_operand"
18421                                                "f ,0,rm,0 ,rm,0")
18422                       (match_operand:DF 3 "nonimmediate_operand"
18423                                                "0 ,f,0 ,rm,0, rm")))]
18424   "TARGET_80387 && TARGET_CMOVE
18425    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18426   "@
18427    fcmov%F1\t{%2, %0|%0, %2}
18428    fcmov%f1\t{%3, %0|%0, %3}
18429    #
18430    #
18431    cmov%O2%C1\t{%2, %0|%0, %2}
18432    cmov%O2%c1\t{%3, %0|%0, %3}"
18433   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18434    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18435    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18437 (define_split
18438   [(set (match_operand:DF 0 "general_reg_operand")
18439         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18440                                 [(reg FLAGS_REG) (const_int 0)])
18441                       (match_operand:DF 2 "nonimmediate_operand")
18442                       (match_operand:DF 3 "nonimmediate_operand")))]
18443   "!TARGET_64BIT && reload_completed"
18444   [(set (match_dup 2)
18445         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18446    (set (match_dup 3)
18447         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18449   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18450   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18453 (define_insn "*movsfcc_1_387"
18454   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18455         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18456                                 [(reg FLAGS_REG) (const_int 0)])
18457                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18458                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18459   "TARGET_80387 && TARGET_CMOVE
18460    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18461   "@
18462    fcmov%F1\t{%2, %0|%0, %2}
18463    fcmov%f1\t{%3, %0|%0, %3}
18464    cmov%O2%C1\t{%2, %0|%0, %2}
18465    cmov%O2%c1\t{%3, %0|%0, %3}"
18466   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18467    (set_attr "mode" "SF,SF,SI,SI")])
18469 ;; Don't do conditional moves with memory inputs.  This splitter helps
18470 ;; register starved x86_32 by forcing inputs into registers before reload.
18471 (define_split
18472   [(set (match_operand:MODEF 0 "register_operand")
18473         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18474                               [(reg FLAGS_REG) (const_int 0)])
18475           (match_operand:MODEF 2 "nonimmediate_operand")
18476           (match_operand:MODEF 3 "nonimmediate_operand")))]
18477   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18478    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18479    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18480    && can_create_pseudo_p ()
18481    && optimize_insn_for_speed_p ()"
18482   [(set (match_dup 0)
18483         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18485   if (MEM_P (operands[2]))
18486     operands[2] = force_reg (<MODE>mode, operands[2]);
18487   if (MEM_P (operands[3]))
18488     operands[3] = force_reg (<MODE>mode, operands[3]);
18491 ;; Don't do conditional moves with memory inputs
18492 (define_peephole2
18493   [(match_scratch:MODEF 4 "r")
18494    (set (match_operand:MODEF 0 "general_reg_operand")
18495         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18496                               [(reg FLAGS_REG) (const_int 0)])
18497           (match_operand:MODEF 2 "nonimmediate_operand")
18498           (match_operand:MODEF 3 "nonimmediate_operand")))]
18499   "(<MODE>mode != DFmode || TARGET_64BIT)
18500    && TARGET_80387 && TARGET_CMOVE
18501    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18502    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18503    && optimize_insn_for_speed_p ()"
18504   [(set (match_dup 4) (match_dup 5))
18505    (set (match_dup 0)
18506         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18508   if (MEM_P (operands[2]))
18509     {
18510       operands[5] = operands[2];
18511       operands[2] = operands[4];
18512     }
18513   else if (MEM_P (operands[3]))
18514     {
18515       operands[5] = operands[3];
18516       operands[3] = operands[4];
18517     }
18518   else
18519     gcc_unreachable ();
18522 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18523 ;; the scalar versions to have only XMM registers as operands.
18525 ;; XOP conditional move
18526 (define_insn "*xop_pcmov_<mode>"
18527   [(set (match_operand:MODEF 0 "register_operand" "=x")
18528         (if_then_else:MODEF
18529           (match_operand:MODEF 1 "register_operand" "x")
18530           (match_operand:MODEF 2 "register_operand" "x")
18531           (match_operand:MODEF 3 "register_operand" "x")))]
18532   "TARGET_XOP"
18533   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18534   [(set_attr "type" "sse4arg")])
18536 ;; These versions of the min/max patterns are intentionally ignorant of
18537 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18538 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18539 ;; are undefined in this condition, we're certain this is correct.
18541 (define_insn "<code><mode>3"
18542   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18543         (smaxmin:MODEF
18544           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18545           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18546   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18547   "@
18548    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18549    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18550   [(set_attr "isa" "noavx,avx")
18551    (set_attr "prefix" "orig,vex")
18552    (set_attr "type" "sseadd")
18553    (set_attr "mode" "<MODE>")])
18555 ;; These versions of the min/max patterns implement exactly the operations
18556 ;;   min = (op1 < op2 ? op1 : op2)
18557 ;;   max = (!(op1 < op2) ? op1 : op2)
18558 ;; Their operands are not commutative, and thus they may be used in the
18559 ;; presence of -0.0 and NaN.
18561 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18562   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18563         (unspec:MODEF
18564           [(match_operand:MODEF 1 "register_operand" "0,v")
18565            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18566           IEEE_MAXMIN))]
18567   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18568   "@
18569    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18570    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18571   [(set_attr "isa" "noavx,avx")
18572    (set_attr "prefix" "orig,maybe_evex")
18573    (set_attr "type" "sseadd")
18574    (set_attr "mode" "<MODE>")])
18576 ;; Make two stack loads independent:
18577 ;;   fld aa              fld aa
18578 ;;   fld %st(0)     ->   fld bb
18579 ;;   fmul bb             fmul %st(1), %st
18581 ;; Actually we only match the last two instructions for simplicity.
18583 (define_peephole2
18584   [(set (match_operand 0 "fp_register_operand")
18585         (match_operand 1 "fp_register_operand"))
18586    (set (match_dup 0)
18587         (match_operator 2 "binary_fp_operator"
18588            [(match_dup 0)
18589             (match_operand 3 "memory_operand")]))]
18590   "REGNO (operands[0]) != REGNO (operands[1])"
18591   [(set (match_dup 0) (match_dup 3))
18592    (set (match_dup 0)
18593         (match_op_dup 2
18594           [(match_dup 5) (match_dup 4)]))]
18596   operands[4] = operands[0];
18597   operands[5] = operands[1];
18599   /* The % modifier is not operational anymore in peephole2's, so we have to
18600      swap the operands manually in the case of addition and multiplication. */
18601   if (COMMUTATIVE_ARITH_P (operands[2]))
18602     std::swap (operands[4], operands[5]);
18605 (define_peephole2
18606   [(set (match_operand 0 "fp_register_operand")
18607         (match_operand 1 "fp_register_operand"))
18608    (set (match_dup 0)
18609         (match_operator 2 "binary_fp_operator"
18610            [(match_operand 3 "memory_operand")
18611             (match_dup 0)]))]
18612   "REGNO (operands[0]) != REGNO (operands[1])"
18613   [(set (match_dup 0) (match_dup 3))
18614    (set (match_dup 0)
18615         (match_op_dup 2
18616           [(match_dup 4) (match_dup 5)]))]
18618   operands[4] = operands[0];
18619   operands[5] = operands[1];
18621   /* The % modifier is not operational anymore in peephole2's, so we have to
18622      swap the operands manually in the case of addition and multiplication. */
18623   if (COMMUTATIVE_ARITH_P (operands[2]))
18624     std::swap (operands[4], operands[5]);
18627 ;; Conditional addition patterns
18628 (define_expand "add<mode>cc"
18629   [(match_operand:SWI 0 "register_operand")
18630    (match_operand 1 "ordered_comparison_operator")
18631    (match_operand:SWI 2 "register_operand")
18632    (match_operand:SWI 3 "const_int_operand")]
18633   ""
18634   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18636 ;; Misc patterns (?)
18638 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18639 ;; Otherwise there will be nothing to keep
18641 ;; [(set (reg ebp) (reg esp))]
18642 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18643 ;;  (clobber (eflags)]
18644 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18646 ;; in proper program order.
18648 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18649   [(set (match_operand:P 0 "register_operand" "=r,r")
18650         (plus:P (match_operand:P 1 "register_operand" "0,r")
18651                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18652    (clobber (reg:CC FLAGS_REG))
18653    (clobber (mem:BLK (scratch)))]
18654   ""
18656   switch (get_attr_type (insn))
18657     {
18658     case TYPE_IMOV:
18659       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18661     case TYPE_ALU:
18662       gcc_assert (rtx_equal_p (operands[0], operands[1]));
18663       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18664         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18666       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18668     default:
18669       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18670       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18671     }
18673   [(set (attr "type")
18674         (cond [(and (eq_attr "alternative" "0")
18675                     (not (match_test "TARGET_OPT_AGU")))
18676                  (const_string "alu")
18677                (match_operand:<MODE> 2 "const0_operand")
18678                  (const_string "imov")
18679               ]
18680               (const_string "lea")))
18681    (set (attr "length_immediate")
18682         (cond [(eq_attr "type" "imov")
18683                  (const_string "0")
18684                (and (eq_attr "type" "alu")
18685                     (match_operand 2 "const128_operand"))
18686                  (const_string "1")
18687               ]
18688               (const_string "*")))
18689    (set_attr "mode" "<MODE>")])
18691 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18692   [(set (match_operand:P 0 "register_operand" "=r")
18693         (minus:P (match_operand:P 1 "register_operand" "0")
18694                  (match_operand:P 2 "register_operand" "r")))
18695    (clobber (reg:CC FLAGS_REG))
18696    (clobber (mem:BLK (scratch)))]
18697   ""
18698   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18699   [(set_attr "type" "alu")
18700    (set_attr "mode" "<MODE>")])
18702 (define_insn "allocate_stack_worker_probe_<mode>"
18703   [(set (match_operand:P 0 "register_operand" "=a")
18704         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18705                             UNSPECV_STACK_PROBE))
18706    (clobber (reg:CC FLAGS_REG))]
18707   "ix86_target_stack_probe ()"
18708   "call\t___chkstk_ms"
18709   [(set_attr "type" "multi")
18710    (set_attr "length" "5")])
18712 (define_expand "allocate_stack"
18713   [(match_operand 0 "register_operand")
18714    (match_operand 1 "general_operand")]
18715   "ix86_target_stack_probe ()"
18717   rtx x;
18719 #ifndef CHECK_STACK_LIMIT
18720 #define CHECK_STACK_LIMIT 0
18721 #endif
18723   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18724       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18725     x = operands[1];
18726   else
18727     {
18728       rtx (*insn) (rtx, rtx);
18730       x = copy_to_mode_reg (Pmode, operands[1]);
18732       insn = (TARGET_64BIT
18733               ? gen_allocate_stack_worker_probe_di
18734               : gen_allocate_stack_worker_probe_si);
18736       emit_insn (insn (x, x));
18737     }
18739   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18740                            stack_pointer_rtx, 0, OPTAB_DIRECT);
18742   if (x != stack_pointer_rtx)
18743     emit_move_insn (stack_pointer_rtx, x);
18745   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18746   DONE;
18749 (define_expand "probe_stack"
18750   [(match_operand 0 "memory_operand")]
18751   ""
18753   rtx (*insn) (rtx, rtx)
18754     = (GET_MODE (operands[0]) == DImode
18755        ? gen_probe_stack_di : gen_probe_stack_si);
18757   emit_insn (insn (operands[0], const0_rtx));
18758   DONE;
18761 ;; Use OR for stack probes, this is shorter.
18762 (define_insn "probe_stack_<mode>"
18763   [(set (match_operand:W 0 "memory_operand" "=m")
18764         (unspec:W [(match_operand:W 1 "const0_operand")]
18765                   UNSPEC_PROBE_STACK))
18766    (clobber (reg:CC FLAGS_REG))]
18767   ""
18768   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18769   [(set_attr "type" "alu1")
18770    (set_attr "mode" "<MODE>")
18771    (set_attr "length_immediate" "1")])
18772   
18773 (define_insn "adjust_stack_and_probe<mode>"
18774   [(set (match_operand:P 0 "register_operand" "=r")
18775         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18776                             UNSPECV_PROBE_STACK_RANGE))
18777    (set (reg:P SP_REG)
18778         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18779    (clobber (reg:CC FLAGS_REG))
18780    (clobber (mem:BLK (scratch)))]
18781   ""
18782   "* return output_adjust_stack_and_probe (operands[0]);"
18783   [(set_attr "type" "multi")])
18785 (define_insn "probe_stack_range<mode>"
18786   [(set (match_operand:P 0 "register_operand" "=r")
18787         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18788                             (match_operand:P 2 "const_int_operand" "n")]
18789                             UNSPECV_PROBE_STACK_RANGE))
18790    (clobber (reg:CC FLAGS_REG))]
18791   ""
18792   "* return output_probe_stack_range (operands[0], operands[2]);"
18793   [(set_attr "type" "multi")])
18795 (define_expand "builtin_setjmp_receiver"
18796   [(label_ref (match_operand 0))]
18797   "!TARGET_64BIT && flag_pic"
18799 #if TARGET_MACHO
18800   if (TARGET_MACHO)
18801     {
18802       rtx xops[3];
18803       rtx_code_label *label_rtx = gen_label_rtx ();
18804       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18805       xops[0] = xops[1] = pic_offset_table_rtx;
18806       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18807       ix86_expand_binary_operator (MINUS, SImode, xops);
18808     }
18809   else
18810 #endif
18811     emit_insn (gen_set_got (pic_offset_table_rtx));
18812   DONE;
18815 (define_expand "save_stack_nonlocal"
18816   [(set (match_operand 0 "memory_operand")
18817         (match_operand 1 "register_operand"))]
18818   ""
18820   rtx stack_slot;
18821   if ((flag_cf_protection & CF_RETURN))
18822     {
18823       /* Copy shadow stack pointer to the first slot and stack ppointer
18824          to the second slot.  */
18825       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18826       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18827       rtx ssp = gen_reg_rtx (word_mode);
18828       emit_insn ((word_mode == SImode)
18829                  ? gen_rdsspsi (ssp)
18830                  : gen_rdsspdi (ssp));
18831       emit_move_insn (ssp_slot, ssp);
18832     }
18833   else
18834     stack_slot = adjust_address (operands[0], Pmode, 0);
18835   emit_move_insn (stack_slot, operands[1]);
18836   DONE;
18839 (define_expand "restore_stack_nonlocal"
18840   [(set (match_operand 0 "register_operand" "")
18841         (match_operand 1 "memory_operand" ""))]
18842   ""
18844   rtx stack_slot;
18845   if ((flag_cf_protection & CF_RETURN))
18846     {
18847       /* Restore shadow stack pointer from the first slot and stack
18848          pointer from the second slot.  */
18849       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18850       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18852       rtx flags, jump, noadj_label, inc_label, loop_label;
18853       rtx reg_adj, reg_ssp, tmp, clob;
18855       /* Get the current shadow stack pointer.  The code below will check if
18856          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
18857          is a NOP.  */
18858       reg_ssp = gen_reg_rtx (word_mode);
18859       emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18860       emit_insn ((word_mode == SImode)
18861                  ? gen_rdsspsi (reg_ssp)
18862                  : gen_rdsspdi (reg_ssp));
18864       /* Compare through substraction the saved and the current ssp to decide
18865          if ssp has to be adjusted.  */
18866       tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18867                                                  ssp_slot));
18868       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18869       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18870       emit_insn (tmp);
18872       /* Compare and jump over adjustment code.  */
18873       noadj_label = gen_label_rtx ();
18874       flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18875       tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18876       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18877                                   gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18878                                   pc_rtx);
18879       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18880       JUMP_LABEL (jump) = noadj_label;
18882       /* Compute the numebr of frames to adjust.  */
18883       reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18884       tmp = gen_rtx_SET (reg_adj,
18885                          gen_rtx_LSHIFTRT (ptr_mode,
18886                                            negate_rtx (ptr_mode, reg_adj),
18887                                            GEN_INT ((word_mode == SImode)
18888                                                     ? 2
18889                                                     : 3)));
18890       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18891       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18892       emit_insn (tmp);
18894       /* Check if number of frames <= 255 so no loop is needed.  */
18895       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18896       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18897       emit_insn (gen_rtx_SET (flags, tmp));
18899       inc_label = gen_label_rtx ();
18900       tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18901       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18902                                   gen_rtx_LABEL_REF (VOIDmode, inc_label),
18903                                   pc_rtx);
18904       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18905       JUMP_LABEL (jump) = inc_label;
18907       rtx reg_255 = gen_reg_rtx (word_mode);
18908       emit_move_insn (reg_255, GEN_INT (255));
18910       /* Adjust the ssp in a loop.  */
18911       loop_label = gen_label_rtx ();
18912       emit_label (loop_label);
18913       LABEL_NUSES (loop_label) = 1;
18915       emit_insn ((word_mode == SImode)
18916                  ? gen_incsspsi (reg_255)
18917                  : gen_incsspdi (reg_255));
18918       tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18919                                                  reg_adj,
18920                                                  GEN_INT (255)));
18921       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18922       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18923       emit_insn (tmp);
18925       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18926       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18927       emit_insn (gen_rtx_SET (flags, tmp));
18929       /* Jump to the loop label.  */
18930       tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18931       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18932                                   gen_rtx_LABEL_REF (VOIDmode, loop_label),
18933                                   pc_rtx);
18934       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18935       JUMP_LABEL (jump) = loop_label;
18937       emit_label (inc_label);
18938       LABEL_NUSES (inc_label) = 1;
18939       emit_insn ((word_mode == SImode)
18940                  ? gen_incsspsi (reg_ssp)
18941                  : gen_incsspdi (reg_ssp));
18943       emit_label (noadj_label);
18944       LABEL_NUSES (noadj_label) = 1;
18945     }
18946   else
18947     stack_slot = adjust_address (operands[1], Pmode, 0);
18948   emit_move_insn (operands[0], stack_slot);
18949   DONE;
18953 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18954 ;; Do not split instructions with mask registers.
18955 (define_split
18956   [(set (match_operand 0 "general_reg_operand")
18957         (match_operator 3 "promotable_binary_operator"
18958            [(match_operand 1 "general_reg_operand")
18959             (match_operand 2 "aligned_operand")]))
18960    (clobber (reg:CC FLAGS_REG))]
18961   "! TARGET_PARTIAL_REG_STALL && reload_completed
18962    && ((GET_MODE (operands[0]) == HImode
18963         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18964             /* ??? next two lines just !satisfies_constraint_K (...) */
18965             || !CONST_INT_P (operands[2])
18966             || satisfies_constraint_K (operands[2])))
18967        || (GET_MODE (operands[0]) == QImode
18968            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18969   [(parallel [(set (match_dup 0)
18970                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18971               (clobber (reg:CC FLAGS_REG))])]
18973   operands[0] = gen_lowpart (SImode, operands[0]);
18974   operands[1] = gen_lowpart (SImode, operands[1]);
18975   if (GET_CODE (operands[3]) != ASHIFT)
18976     operands[2] = gen_lowpart (SImode, operands[2]);
18977   operands[3] = shallow_copy_rtx (operands[3]);
18978   PUT_MODE (operands[3], SImode);
18981 ; Promote the QImode tests, as i386 has encoding of the AND
18982 ; instruction with 32-bit sign-extended immediate and thus the
18983 ; instruction size is unchanged, except in the %eax case for
18984 ; which it is increased by one byte, hence the ! optimize_size.
18985 (define_split
18986   [(set (match_operand 0 "flags_reg_operand")
18987         (match_operator 2 "compare_operator"
18988           [(and (match_operand 3 "aligned_operand")
18989                 (match_operand 4 "const_int_operand"))
18990            (const_int 0)]))
18991    (set (match_operand 1 "register_operand")
18992         (and (match_dup 3) (match_dup 4)))]
18993   "! TARGET_PARTIAL_REG_STALL && reload_completed
18994    && optimize_insn_for_speed_p ()
18995    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18996        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18997    /* Ensure that the operand will remain sign-extended immediate.  */
18998    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18999   [(parallel [(set (match_dup 0)
19000                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19001                                     (const_int 0)]))
19002               (set (match_dup 1)
19003                    (and:SI (match_dup 3) (match_dup 4)))])]
19005   operands[4]
19006     = gen_int_mode (INTVAL (operands[4])
19007                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19008   operands[1] = gen_lowpart (SImode, operands[1]);
19009   operands[3] = gen_lowpart (SImode, operands[3]);
19012 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19013 ; the TEST instruction with 32-bit sign-extended immediate and thus
19014 ; the instruction size would at least double, which is not what we
19015 ; want even with ! optimize_size.
19016 (define_split
19017   [(set (match_operand 0 "flags_reg_operand")
19018         (match_operator 1 "compare_operator"
19019           [(and (match_operand:HI 2 "aligned_operand")
19020                 (match_operand:HI 3 "const_int_operand"))
19021            (const_int 0)]))]
19022   "! TARGET_PARTIAL_REG_STALL && reload_completed
19023    && ! TARGET_FAST_PREFIX
19024    && optimize_insn_for_speed_p ()
19025    /* Ensure that the operand will remain sign-extended immediate.  */
19026    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19027   [(set (match_dup 0)
19028         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19029                          (const_int 0)]))]
19031   operands[3]
19032     = gen_int_mode (INTVAL (operands[3])
19033                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19034   operands[2] = gen_lowpart (SImode, operands[2]);
19037 (define_split
19038   [(set (match_operand 0 "register_operand")
19039         (neg (match_operand 1 "register_operand")))
19040    (clobber (reg:CC FLAGS_REG))]
19041   "! TARGET_PARTIAL_REG_STALL && reload_completed
19042    && (GET_MODE (operands[0]) == HImode
19043        || (GET_MODE (operands[0]) == QImode
19044            && (TARGET_PROMOTE_QImode
19045                || optimize_insn_for_size_p ())))"
19046   [(parallel [(set (match_dup 0)
19047                    (neg:SI (match_dup 1)))
19048               (clobber (reg:CC FLAGS_REG))])]
19050   operands[0] = gen_lowpart (SImode, operands[0]);
19051   operands[1] = gen_lowpart (SImode, operands[1]);
19054 ;; Do not split instructions with mask regs.
19055 (define_split
19056   [(set (match_operand 0 "general_reg_operand")
19057         (not (match_operand 1 "general_reg_operand")))]
19058   "! TARGET_PARTIAL_REG_STALL && reload_completed
19059    && (GET_MODE (operands[0]) == HImode
19060        || (GET_MODE (operands[0]) == QImode
19061            && (TARGET_PROMOTE_QImode
19062                || optimize_insn_for_size_p ())))"
19063   [(set (match_dup 0)
19064         (not:SI (match_dup 1)))]
19066   operands[0] = gen_lowpart (SImode, operands[0]);
19067   operands[1] = gen_lowpart (SImode, operands[1]);
19070 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19071 ;; transform a complex memory operation into two memory to register operations.
19073 ;; Don't push memory operands
19074 (define_peephole2
19075   [(set (match_operand:SWI 0 "push_operand")
19076         (match_operand:SWI 1 "memory_operand"))
19077    (match_scratch:SWI 2 "<r>")]
19078   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19079    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19080   [(set (match_dup 2) (match_dup 1))
19081    (set (match_dup 0) (match_dup 2))])
19083 ;; We need to handle SFmode only, because DFmode and XFmode are split to
19084 ;; SImode pushes.
19085 (define_peephole2
19086   [(set (match_operand:SF 0 "push_operand")
19087         (match_operand:SF 1 "memory_operand"))
19088    (match_scratch:SF 2 "r")]
19089   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19090    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19091   [(set (match_dup 2) (match_dup 1))
19092    (set (match_dup 0) (match_dup 2))])
19094 ;; Don't move an immediate directly to memory when the instruction
19095 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
19096 (define_peephole2
19097   [(match_scratch:SWI124 1 "<r>")
19098    (set (match_operand:SWI124 0 "memory_operand")
19099         (const_int 0))]
19100   "optimize_insn_for_speed_p ()
19101    && ((<MODE>mode == HImode
19102        && TARGET_LCP_STALL)
19103        || (!TARGET_USE_MOV0
19104           && TARGET_SPLIT_LONG_MOVES
19105           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
19106    && peep2_regno_dead_p (0, FLAGS_REG)"
19107   [(parallel [(set (match_dup 2) (const_int 0))
19108               (clobber (reg:CC FLAGS_REG))])
19109    (set (match_dup 0) (match_dup 1))]
19110   "operands[2] = gen_lowpart (SImode, operands[1]);")
19112 (define_peephole2
19113   [(match_scratch:SWI124 2 "<r>")
19114    (set (match_operand:SWI124 0 "memory_operand")
19115         (match_operand:SWI124 1 "immediate_operand"))]
19116   "optimize_insn_for_speed_p ()
19117    && ((<MODE>mode == HImode
19118        && TARGET_LCP_STALL)
19119        || (TARGET_SPLIT_LONG_MOVES
19120           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
19121   [(set (match_dup 2) (match_dup 1))
19122    (set (match_dup 0) (match_dup 2))])
19124 ;; Don't compare memory with zero, load and use a test instead.
19125 (define_peephole2
19126   [(set (match_operand 0 "flags_reg_operand")
19127         (match_operator 1 "compare_operator"
19128           [(match_operand:SI 2 "memory_operand")
19129            (const_int 0)]))
19130    (match_scratch:SI 3 "r")]
19131   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19132   [(set (match_dup 3) (match_dup 2))
19133    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
19135 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19136 ;; Don't split NOTs with a displacement operand, because resulting XOR
19137 ;; will not be pairable anyway.
19139 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19140 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19141 ;; so this split helps here as well.
19143 ;; Note: Can't do this as a regular split because we can't get proper
19144 ;; lifetime information then.
19146 (define_peephole2
19147   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
19148         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
19149   "optimize_insn_for_speed_p ()
19150    && ((TARGET_NOT_UNPAIRABLE
19151         && (!MEM_P (operands[0])
19152             || !memory_displacement_operand (operands[0], <MODE>mode)))
19153        || (TARGET_NOT_VECTORMODE
19154            && long_memory_operand (operands[0], <MODE>mode)))
19155    && peep2_regno_dead_p (0, FLAGS_REG)"
19156   [(parallel [(set (match_dup 0)
19157                    (xor:SWI124 (match_dup 1) (const_int -1)))
19158               (clobber (reg:CC FLAGS_REG))])])
19160 ;; Non pairable "test imm, reg" instructions can be translated to
19161 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19162 ;; byte opcode instead of two, have a short form for byte operands),
19163 ;; so do it for other CPUs as well.  Given that the value was dead,
19164 ;; this should not create any new dependencies.  Pass on the sub-word
19165 ;; versions if we're concerned about partial register stalls.
19167 (define_peephole2
19168   [(set (match_operand 0 "flags_reg_operand")
19169         (match_operator 1 "compare_operator"
19170           [(and:SI (match_operand:SI 2 "register_operand")
19171                    (match_operand:SI 3 "immediate_operand"))
19172            (const_int 0)]))]
19173   "ix86_match_ccmode (insn, CCNOmode)
19174    && (REGNO (operands[2]) != AX_REG
19175        || satisfies_constraint_K (operands[3]))
19176    && peep2_reg_dead_p (1, operands[2])"
19177   [(parallel
19178      [(set (match_dup 0)
19179            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19180                             (const_int 0)]))
19181       (set (match_dup 2)
19182            (and:SI (match_dup 2) (match_dup 3)))])])
19184 ;; We don't need to handle HImode case, because it will be promoted to SImode
19185 ;; on ! TARGET_PARTIAL_REG_STALL
19187 (define_peephole2
19188   [(set (match_operand 0 "flags_reg_operand")
19189         (match_operator 1 "compare_operator"
19190           [(and:QI (match_operand:QI 2 "register_operand")
19191                    (match_operand:QI 3 "immediate_operand"))
19192            (const_int 0)]))]
19193   "! TARGET_PARTIAL_REG_STALL
19194    && ix86_match_ccmode (insn, CCNOmode)
19195    && REGNO (operands[2]) != AX_REG
19196    && peep2_reg_dead_p (1, operands[2])"
19197   [(parallel
19198      [(set (match_dup 0)
19199            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19200                             (const_int 0)]))
19201       (set (match_dup 2)
19202            (and:QI (match_dup 2) (match_dup 3)))])])
19204 (define_peephole2
19205   [(set (match_operand 0 "flags_reg_operand")
19206         (match_operator 1 "compare_operator"
19207           [(and:QI
19208              (subreg:QI
19209                (zero_extract:SI (match_operand 2 "QIreg_operand")
19210                                 (const_int 8)
19211                                 (const_int 8)) 0)
19212              (match_operand 3 "const_int_operand"))
19213            (const_int 0)]))]
19214   "! TARGET_PARTIAL_REG_STALL
19215    && ix86_match_ccmode (insn, CCNOmode)
19216    && REGNO (operands[2]) != AX_REG
19217    && peep2_reg_dead_p (1, operands[2])"
19218   [(parallel
19219      [(set (match_dup 0)
19220            (match_op_dup 1
19221              [(and:QI
19222                 (subreg:QI
19223                   (zero_extract:SI (match_dup 2)
19224                                    (const_int 8)
19225                                    (const_int 8)) 0)
19226                 (match_dup 3))
19227               (const_int 0)]))
19228       (set (zero_extract:SI (match_dup 2)
19229                             (const_int 8)
19230                             (const_int 8))
19231            (subreg:SI
19232              (and:QI
19233                (subreg:QI
19234                  (zero_extract:SI (match_dup 2)
19235                                   (const_int 8)
19236                                   (const_int 8)) 0)
19237                (match_dup 3)) 0))])])
19239 ;; Don't do logical operations with memory inputs.
19240 (define_peephole2
19241   [(match_scratch:SWI 2 "<r>")
19242    (parallel [(set (match_operand:SWI 0 "register_operand")
19243                    (match_operator:SWI 3 "arith_or_logical_operator"
19244                      [(match_dup 0)
19245                       (match_operand:SWI 1 "memory_operand")]))
19246               (clobber (reg:CC FLAGS_REG))])]
19247   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19248   [(set (match_dup 2) (match_dup 1))
19249    (parallel [(set (match_dup 0)
19250                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19251               (clobber (reg:CC FLAGS_REG))])])
19253 (define_peephole2
19254   [(match_scratch:SWI 2 "<r>")
19255    (parallel [(set (match_operand:SWI 0 "register_operand")
19256                    (match_operator:SWI 3 "arith_or_logical_operator"
19257                      [(match_operand:SWI 1 "memory_operand")
19258                       (match_dup 0)]))
19259               (clobber (reg:CC FLAGS_REG))])]
19260   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19261   [(set (match_dup 2) (match_dup 1))
19262    (parallel [(set (match_dup 0)
19263                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19264               (clobber (reg:CC FLAGS_REG))])])
19266 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
19267 ;; the memory address refers to the destination of the load!
19269 (define_peephole2
19270   [(set (match_operand:SWI 0 "general_reg_operand")
19271         (match_operand:SWI 1 "general_reg_operand"))
19272    (parallel [(set (match_dup 0)
19273                    (match_operator:SWI 3 "commutative_operator"
19274                      [(match_dup 0)
19275                       (match_operand:SWI 2 "memory_operand")]))
19276               (clobber (reg:CC FLAGS_REG))])]
19277   "REGNO (operands[0]) != REGNO (operands[1])
19278    && (<MODE>mode != QImode
19279        || any_QIreg_operand (operands[1], QImode))"
19280   [(set (match_dup 0) (match_dup 4))
19281    (parallel [(set (match_dup 0)
19282                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19283               (clobber (reg:CC FLAGS_REG))])]
19284   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19286 (define_peephole2
19287   [(set (match_operand 0 "mmx_reg_operand")
19288         (match_operand 1 "mmx_reg_operand"))
19289    (set (match_dup 0)
19290         (match_operator 3 "commutative_operator"
19291           [(match_dup 0)
19292            (match_operand 2 "memory_operand")]))]
19293   "REGNO (operands[0]) != REGNO (operands[1])"
19294   [(set (match_dup 0) (match_dup 2))
19295    (set (match_dup 0)
19296         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19298 (define_peephole2
19299   [(set (match_operand 0 "sse_reg_operand")
19300         (match_operand 1 "sse_reg_operand"))
19301    (set (match_dup 0)
19302         (match_operator 3 "commutative_operator"
19303           [(match_dup 0)
19304            (match_operand 2 "memory_operand")]))]
19305   "REGNO (operands[0]) != REGNO (operands[1])"
19306   [(set (match_dup 0) (match_dup 2))
19307    (set (match_dup 0)
19308         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19310 ; Don't do logical operations with memory outputs
19312 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19313 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19314 ; the same decoder scheduling characteristics as the original.
19316 (define_peephole2
19317   [(match_scratch:SWI 2 "<r>")
19318    (parallel [(set (match_operand:SWI 0 "memory_operand")
19319                    (match_operator:SWI 3 "arith_or_logical_operator"
19320                      [(match_dup 0)
19321                       (match_operand:SWI 1 "<nonmemory_operand>")]))
19322               (clobber (reg:CC FLAGS_REG))])]
19323   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19324   [(set (match_dup 2) (match_dup 0))
19325    (parallel [(set (match_dup 2)
19326                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19327               (clobber (reg:CC FLAGS_REG))])
19328    (set (match_dup 0) (match_dup 2))])
19330 (define_peephole2
19331   [(match_scratch:SWI 2 "<r>")
19332    (parallel [(set (match_operand:SWI 0 "memory_operand")
19333                    (match_operator:SWI 3 "arith_or_logical_operator"
19334                      [(match_operand:SWI 1 "<nonmemory_operand>")
19335                       (match_dup 0)]))
19336               (clobber (reg:CC FLAGS_REG))])]
19337   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19338   [(set (match_dup 2) (match_dup 0))
19339    (parallel [(set (match_dup 2)
19340                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19341               (clobber (reg:CC FLAGS_REG))])
19342    (set (match_dup 0) (match_dup 2))])
19344 ;; Attempt to use arith or logical operations with memory outputs with
19345 ;; setting of flags.
19346 (define_peephole2
19347   [(set (match_operand:SWI 0 "register_operand")
19348         (match_operand:SWI 1 "memory_operand"))
19349    (parallel [(set (match_dup 0)
19350                    (match_operator:SWI 3 "plusminuslogic_operator"
19351                      [(match_dup 0)
19352                       (match_operand:SWI 2 "<nonmemory_operand>")]))
19353               (clobber (reg:CC FLAGS_REG))])
19354    (set (match_dup 1) (match_dup 0))
19355    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19356   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19357    && peep2_reg_dead_p (4, operands[0])
19358    && !reg_overlap_mentioned_p (operands[0], operands[1])
19359    && !reg_overlap_mentioned_p (operands[0], operands[2])
19360    && (<MODE>mode != QImode
19361        || immediate_operand (operands[2], QImode)
19362        || any_QIreg_operand (operands[2], QImode))
19363    && ix86_match_ccmode (peep2_next_insn (3),
19364                          (GET_CODE (operands[3]) == PLUS
19365                           || GET_CODE (operands[3]) == MINUS)
19366                          ? CCGOCmode : CCNOmode)"
19367   [(parallel [(set (match_dup 4) (match_dup 6))
19368               (set (match_dup 1) (match_dup 5))])]
19370   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19371   operands[5]
19372     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19373                       copy_rtx (operands[1]),
19374                       operands[2]);
19375   operands[6]
19376     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19377                        copy_rtx (operands[5]),
19378                        const0_rtx);
19381 ;; Likewise for cmpelim optimized pattern.
19382 (define_peephole2
19383   [(set (match_operand:SWI 0 "register_operand")
19384         (match_operand:SWI 1 "memory_operand"))
19385    (parallel [(set (reg FLAGS_REG)
19386                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
19387                               [(match_dup 0)
19388                                (match_operand:SWI 2 "<nonmemory_operand>")])
19389                             (const_int 0)))
19390               (set (match_dup 0) (match_dup 3))])
19391    (set (match_dup 1) (match_dup 0))]
19392   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19393    && peep2_reg_dead_p (3, operands[0])
19394    && !reg_overlap_mentioned_p (operands[0], operands[1])
19395    && !reg_overlap_mentioned_p (operands[0], operands[2])
19396    && ix86_match_ccmode (peep2_next_insn (1),
19397                          (GET_CODE (operands[3]) == PLUS
19398                           || GET_CODE (operands[3]) == MINUS)
19399                          ? CCGOCmode : CCNOmode)"
19400   [(parallel [(set (match_dup 4) (match_dup 6))
19401               (set (match_dup 1) (match_dup 5))])]
19403   operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19404   operands[5]
19405     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19406                       copy_rtx (operands[1]), operands[2]);
19407   operands[6]
19408     = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19409                        const0_rtx);
19412 ;; Likewise for instances where we have a lea pattern.
19413 (define_peephole2
19414   [(set (match_operand:SWI 0 "register_operand")
19415         (match_operand:SWI 1 "memory_operand"))
19416    (set (match_operand:SWI 3 "register_operand")
19417         (plus:SWI (match_dup 0)
19418                   (match_operand:SWI 2 "<nonmemory_operand>")))
19419    (set (match_dup 1) (match_dup 3))
19420    (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19421   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19422    && peep2_reg_dead_p (4, operands[3])
19423    && (rtx_equal_p (operands[0], operands[3])
19424        || peep2_reg_dead_p (2, operands[0]))
19425    && !reg_overlap_mentioned_p (operands[0], operands[1])
19426    && !reg_overlap_mentioned_p (operands[3], operands[1])
19427    && !reg_overlap_mentioned_p (operands[0], operands[2])
19428    && (<MODE>mode != QImode
19429        || immediate_operand (operands[2], QImode)
19430        || any_QIreg_operand (operands[2], QImode))
19431    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19432   [(parallel [(set (match_dup 4) (match_dup 6))
19433               (set (match_dup 1) (match_dup 5))])]
19435   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19436   operands[5]
19437     = gen_rtx_PLUS (<MODE>mode,
19438                     copy_rtx (operands[1]),
19439                     operands[2]);
19440   operands[6]
19441     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19442                        copy_rtx (operands[5]),
19443                        const0_rtx);
19446 (define_peephole2
19447   [(parallel [(set (match_operand:SWI 0 "register_operand")
19448                    (match_operator:SWI 2 "plusminuslogic_operator"
19449                      [(match_dup 0)
19450                       (match_operand:SWI 1 "memory_operand")]))
19451               (clobber (reg:CC FLAGS_REG))])
19452    (set (match_dup 1) (match_dup 0))
19453    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19454   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19455    && COMMUTATIVE_ARITH_P (operands[2])
19456    && peep2_reg_dead_p (3, operands[0])
19457    && !reg_overlap_mentioned_p (operands[0], operands[1])
19458    && ix86_match_ccmode (peep2_next_insn (2),
19459                          GET_CODE (operands[2]) == PLUS
19460                          ? CCGOCmode : CCNOmode)"
19461   [(parallel [(set (match_dup 3) (match_dup 5))
19462               (set (match_dup 1) (match_dup 4))])]
19464   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19465   operands[4]
19466     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19467                       copy_rtx (operands[1]),
19468                       operands[0]);
19469   operands[5]
19470     = gen_rtx_COMPARE (GET_MODE (operands[3]),
19471                        copy_rtx (operands[4]),
19472                        const0_rtx);
19475 ;; Likewise for cmpelim optimized pattern.
19476 (define_peephole2
19477   [(parallel [(set (reg FLAGS_REG)
19478                    (compare (match_operator:SWI 2 "plusminuslogic_operator"
19479                               [(match_operand:SWI 0 "register_operand")
19480                                (match_operand:SWI 1 "memory_operand")])
19481                             (const_int 0)))
19482               (set (match_dup 0) (match_dup 2))])
19483    (set (match_dup 1) (match_dup 0))]
19484   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19485    && COMMUTATIVE_ARITH_P (operands[2])
19486    && peep2_reg_dead_p (2, operands[0])
19487    && !reg_overlap_mentioned_p (operands[0], operands[1])
19488    && ix86_match_ccmode (peep2_next_insn (0),
19489                          GET_CODE (operands[2]) == PLUS
19490                          ? CCGOCmode : CCNOmode)"
19491   [(parallel [(set (match_dup 3) (match_dup 5))
19492               (set (match_dup 1) (match_dup 4))])]
19494   operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19495   operands[4]
19496     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19497                       copy_rtx (operands[1]), operands[0]);
19498   operands[5]
19499     = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19500                        const0_rtx);
19503 (define_peephole2
19504   [(set (match_operand:SWI12 0 "register_operand")
19505         (match_operand:SWI12 1 "memory_operand"))
19506    (parallel [(set (match_operand:SI 4 "register_operand")
19507                    (match_operator:SI 3 "plusminuslogic_operator"
19508                      [(match_dup 4)
19509                       (match_operand:SI 2 "nonmemory_operand")]))
19510               (clobber (reg:CC FLAGS_REG))])
19511    (set (match_dup 1) (match_dup 0))
19512    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19513   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19514    && REGNO (operands[0]) == REGNO (operands[4])
19515    && peep2_reg_dead_p (4, operands[0])
19516    && (<MODE>mode != QImode
19517        || immediate_operand (operands[2], SImode)
19518        || any_QIreg_operand (operands[2], SImode))
19519    && !reg_overlap_mentioned_p (operands[0], operands[1])
19520    && !reg_overlap_mentioned_p (operands[0], operands[2])
19521    && ix86_match_ccmode (peep2_next_insn (3),
19522                          (GET_CODE (operands[3]) == PLUS
19523                           || GET_CODE (operands[3]) == MINUS)
19524                          ? CCGOCmode : CCNOmode)"
19525   [(parallel [(set (match_dup 4) (match_dup 6))
19526               (set (match_dup 1) (match_dup 5))])]
19528   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19529   operands[5]
19530     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19531                       copy_rtx (operands[1]),
19532                       gen_lowpart (<MODE>mode, operands[2]));
19533   operands[6]
19534     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19535                        copy_rtx (operands[5]),
19536                        const0_rtx);
19539 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19540 (define_peephole2
19541   [(set (match_operand 0 "general_reg_operand")
19542         (match_operand 1 "const0_operand"))]
19543   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19544    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19545    && peep2_regno_dead_p (0, FLAGS_REG)"
19546   [(parallel [(set (match_dup 0) (const_int 0))
19547               (clobber (reg:CC FLAGS_REG))])]
19548   "operands[0] = gen_lowpart (word_mode, operands[0]);")
19550 (define_peephole2
19551   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19552         (const_int 0))]
19553   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19554    && peep2_regno_dead_p (0, FLAGS_REG)"
19555   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19556               (clobber (reg:CC FLAGS_REG))])])
19558 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19559 (define_peephole2
19560   [(set (match_operand:SWI248 0 "general_reg_operand")
19561         (const_int -1))]
19562   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19563    && peep2_regno_dead_p (0, FLAGS_REG)"
19564   [(parallel [(set (match_dup 0) (const_int -1))
19565               (clobber (reg:CC FLAGS_REG))])]
19567   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19568     operands[0] = gen_lowpart (SImode, operands[0]);
19571 ;; Attempt to convert simple lea to add/shift.
19572 ;; These can be created by move expanders.
19573 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19574 ;; relevant lea instructions were already split.
19576 (define_peephole2
19577   [(set (match_operand:SWI48 0 "register_operand")
19578         (plus:SWI48 (match_dup 0)
19579                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
19580   "!TARGET_OPT_AGU
19581    && peep2_regno_dead_p (0, FLAGS_REG)"
19582   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19583               (clobber (reg:CC FLAGS_REG))])])
19585 (define_peephole2
19586   [(set (match_operand:SWI48 0 "register_operand")
19587         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19588                     (match_dup 0)))]
19589   "!TARGET_OPT_AGU
19590    && peep2_regno_dead_p (0, FLAGS_REG)"
19591   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19592               (clobber (reg:CC FLAGS_REG))])])
19594 (define_peephole2
19595   [(set (match_operand:DI 0 "register_operand")
19596         (zero_extend:DI
19597           (plus:SI (match_operand:SI 1 "register_operand")
19598                    (match_operand:SI 2 "nonmemory_operand"))))]
19599   "TARGET_64BIT && !TARGET_OPT_AGU
19600    && REGNO (operands[0]) == REGNO (operands[1])
19601    && peep2_regno_dead_p (0, FLAGS_REG)"
19602   [(parallel [(set (match_dup 0)
19603                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19604               (clobber (reg:CC FLAGS_REG))])])
19606 (define_peephole2
19607   [(set (match_operand:DI 0 "register_operand")
19608         (zero_extend:DI
19609           (plus:SI (match_operand:SI 1 "nonmemory_operand")
19610                    (match_operand:SI 2 "register_operand"))))]
19611   "TARGET_64BIT && !TARGET_OPT_AGU
19612    && REGNO (operands[0]) == REGNO (operands[2])
19613    && peep2_regno_dead_p (0, FLAGS_REG)"
19614   [(parallel [(set (match_dup 0)
19615                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19616               (clobber (reg:CC FLAGS_REG))])])
19618 (define_peephole2
19619   [(set (match_operand:SWI48 0 "register_operand")
19620         (mult:SWI48 (match_dup 0)
19621                     (match_operand:SWI48 1 "const_int_operand")))]
19622   "pow2p_hwi (INTVAL (operands[1]))
19623    && peep2_regno_dead_p (0, FLAGS_REG)"
19624   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19625               (clobber (reg:CC FLAGS_REG))])]
19626   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19628 (define_peephole2
19629   [(set (match_operand:DI 0 "register_operand")
19630         (zero_extend:DI
19631           (mult:SI (match_operand:SI 1 "register_operand")
19632                    (match_operand:SI 2 "const_int_operand"))))]
19633   "TARGET_64BIT
19634    && pow2p_hwi (INTVAL (operands[2]))
19635    && REGNO (operands[0]) == REGNO (operands[1])
19636    && peep2_regno_dead_p (0, FLAGS_REG)"
19637   [(parallel [(set (match_dup 0)
19638                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19639               (clobber (reg:CC FLAGS_REG))])]
19640   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19642 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19643 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19644 ;; On many CPUs it is also faster, since special hardware to avoid esp
19645 ;; dependencies is present.
19647 ;; While some of these conversions may be done using splitters, we use
19648 ;; peepholes in order to allow combine_stack_adjustments pass to see
19649 ;; nonobfuscated RTL.
19651 ;; Convert prologue esp subtractions to push.
19652 ;; We need register to push.  In order to keep verify_flow_info happy we have
19653 ;; two choices
19654 ;; - use scratch and clobber it in order to avoid dependencies
19655 ;; - use already live register
19656 ;; We can't use the second way right now, since there is no reliable way how to
19657 ;; verify that given register is live.  First choice will also most likely in
19658 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19659 ;; call clobbered registers are dead.  We may want to use base pointer as an
19660 ;; alternative when no register is available later.
19662 (define_peephole2
19663   [(match_scratch:W 1 "r")
19664    (parallel [(set (reg:P SP_REG)
19665                    (plus:P (reg:P SP_REG)
19666                            (match_operand:P 0 "const_int_operand")))
19667               (clobber (reg:CC FLAGS_REG))
19668               (clobber (mem:BLK (scratch)))])]
19669   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19670    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19671    && ix86_red_zone_size == 0"
19672   [(clobber (match_dup 1))
19673    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19674               (clobber (mem:BLK (scratch)))])])
19676 (define_peephole2
19677   [(match_scratch:W 1 "r")
19678    (parallel [(set (reg:P SP_REG)
19679                    (plus:P (reg:P SP_REG)
19680                            (match_operand:P 0 "const_int_operand")))
19681               (clobber (reg:CC FLAGS_REG))
19682               (clobber (mem:BLK (scratch)))])]
19683   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19684    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19685    && ix86_red_zone_size == 0"
19686   [(clobber (match_dup 1))
19687    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19688    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19689               (clobber (mem:BLK (scratch)))])])
19691 ;; Convert esp subtractions to push.
19692 (define_peephole2
19693   [(match_scratch:W 1 "r")
19694    (parallel [(set (reg:P SP_REG)
19695                    (plus:P (reg:P SP_REG)
19696                            (match_operand:P 0 "const_int_operand")))
19697               (clobber (reg:CC FLAGS_REG))])]
19698   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19699    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19700    && ix86_red_zone_size == 0"
19701   [(clobber (match_dup 1))
19702    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19704 (define_peephole2
19705   [(match_scratch:W 1 "r")
19706    (parallel [(set (reg:P SP_REG)
19707                    (plus:P (reg:P SP_REG)
19708                            (match_operand:P 0 "const_int_operand")))
19709               (clobber (reg:CC FLAGS_REG))])]
19710   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19711    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19712    && ix86_red_zone_size == 0"
19713   [(clobber (match_dup 1))
19714    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19715    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19717 ;; Convert epilogue deallocator to pop.
19718 (define_peephole2
19719   [(match_scratch:W 1 "r")
19720    (parallel [(set (reg:P SP_REG)
19721                    (plus:P (reg:P SP_REG)
19722                            (match_operand:P 0 "const_int_operand")))
19723               (clobber (reg:CC FLAGS_REG))
19724               (clobber (mem:BLK (scratch)))])]
19725   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19726    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19727   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19728               (clobber (mem:BLK (scratch)))])])
19730 ;; Two pops case is tricky, since pop causes dependency
19731 ;; on destination register.  We use two registers if available.
19732 (define_peephole2
19733   [(match_scratch:W 1 "r")
19734    (match_scratch:W 2 "r")
19735    (parallel [(set (reg:P SP_REG)
19736                    (plus:P (reg:P SP_REG)
19737                            (match_operand:P 0 "const_int_operand")))
19738               (clobber (reg:CC FLAGS_REG))
19739               (clobber (mem:BLK (scratch)))])]
19740   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19741    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19742   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19743               (clobber (mem:BLK (scratch)))])
19744    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19746 (define_peephole2
19747   [(match_scratch:W 1 "r")
19748    (parallel [(set (reg:P SP_REG)
19749                    (plus:P (reg:P SP_REG)
19750                            (match_operand:P 0 "const_int_operand")))
19751               (clobber (reg:CC FLAGS_REG))
19752               (clobber (mem:BLK (scratch)))])]
19753   "optimize_insn_for_size_p ()
19754    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19755   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19756               (clobber (mem:BLK (scratch)))])
19757    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19759 ;; Convert esp additions to pop.
19760 (define_peephole2
19761   [(match_scratch:W 1 "r")
19762    (parallel [(set (reg:P SP_REG)
19763                    (plus:P (reg:P SP_REG)
19764                            (match_operand:P 0 "const_int_operand")))
19765               (clobber (reg:CC FLAGS_REG))])]
19766   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19767   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19769 ;; Two pops case is tricky, since pop causes dependency
19770 ;; on destination register.  We use two registers if available.
19771 (define_peephole2
19772   [(match_scratch:W 1 "r")
19773    (match_scratch:W 2 "r")
19774    (parallel [(set (reg:P SP_REG)
19775                    (plus:P (reg:P SP_REG)
19776                            (match_operand:P 0 "const_int_operand")))
19777               (clobber (reg:CC FLAGS_REG))])]
19778   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19779   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19780    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19782 (define_peephole2
19783   [(match_scratch:W 1 "r")
19784    (parallel [(set (reg:P SP_REG)
19785                    (plus:P (reg:P SP_REG)
19786                            (match_operand:P 0 "const_int_operand")))
19787               (clobber (reg:CC FLAGS_REG))])]
19788   "optimize_insn_for_size_p ()
19789    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19790   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19791    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19793 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19794 ;; required and register dies.  Similarly for 128 to -128.
19795 (define_peephole2
19796   [(set (match_operand 0 "flags_reg_operand")
19797         (match_operator 1 "compare_operator"
19798           [(match_operand 2 "register_operand")
19799            (match_operand 3 "const_int_operand")]))]
19800   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19801      && incdec_operand (operands[3], GET_MODE (operands[3])))
19802     || (!TARGET_FUSE_CMP_AND_BRANCH
19803         && INTVAL (operands[3]) == 128))
19804    && ix86_match_ccmode (insn, CCGCmode)
19805    && peep2_reg_dead_p (1, operands[2])"
19806   [(parallel [(set (match_dup 0)
19807                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19808               (clobber (match_dup 2))])])
19810 ;; Convert imul by three, five and nine into lea
19811 (define_peephole2
19812   [(parallel
19813     [(set (match_operand:SWI48 0 "register_operand")
19814           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19815                       (match_operand:SWI48 2 "const359_operand")))
19816      (clobber (reg:CC FLAGS_REG))])]
19817   "!TARGET_PARTIAL_REG_STALL
19818    || <MODE>mode == SImode
19819    || optimize_function_for_size_p (cfun)"
19820   [(set (match_dup 0)
19821         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19822                     (match_dup 1)))]
19823   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19825 (define_peephole2
19826   [(parallel
19827     [(set (match_operand:SWI48 0 "register_operand")
19828           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19829                       (match_operand:SWI48 2 "const359_operand")))
19830      (clobber (reg:CC FLAGS_REG))])]
19831   "optimize_insn_for_speed_p ()
19832    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19833   [(set (match_dup 0) (match_dup 1))
19834    (set (match_dup 0)
19835         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19836                     (match_dup 0)))]
19837   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19839 ;; imul $32bit_imm, mem, reg is vector decoded, while
19840 ;; imul $32bit_imm, reg, reg is direct decoded.
19841 (define_peephole2
19842   [(match_scratch:SWI48 3 "r")
19843    (parallel [(set (match_operand:SWI48 0 "register_operand")
19844                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19845                                (match_operand:SWI48 2 "immediate_operand")))
19846               (clobber (reg:CC FLAGS_REG))])]
19847   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19848    && !satisfies_constraint_K (operands[2])"
19849   [(set (match_dup 3) (match_dup 1))
19850    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19851               (clobber (reg:CC FLAGS_REG))])])
19853 (define_peephole2
19854   [(match_scratch:SI 3 "r")
19855    (parallel [(set (match_operand:DI 0 "register_operand")
19856                    (zero_extend:DI
19857                      (mult:SI (match_operand:SI 1 "memory_operand")
19858                               (match_operand:SI 2 "immediate_operand"))))
19859               (clobber (reg:CC FLAGS_REG))])]
19860   "TARGET_64BIT
19861    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19862    && !satisfies_constraint_K (operands[2])"
19863   [(set (match_dup 3) (match_dup 1))
19864    (parallel [(set (match_dup 0)
19865                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19866               (clobber (reg:CC FLAGS_REG))])])
19868 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19869 ;; Convert it into imul reg, reg
19870 ;; It would be better to force assembler to encode instruction using long
19871 ;; immediate, but there is apparently no way to do so.
19872 (define_peephole2
19873   [(parallel [(set (match_operand:SWI248 0 "register_operand")
19874                    (mult:SWI248
19875                     (match_operand:SWI248 1 "nonimmediate_operand")
19876                     (match_operand:SWI248 2 "const_int_operand")))
19877               (clobber (reg:CC FLAGS_REG))])
19878    (match_scratch:SWI248 3 "r")]
19879   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19880    && satisfies_constraint_K (operands[2])"
19881   [(set (match_dup 3) (match_dup 2))
19882    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19883               (clobber (reg:CC FLAGS_REG))])]
19885   if (!rtx_equal_p (operands[0], operands[1]))
19886     emit_move_insn (operands[0], operands[1]);
19889 ;; After splitting up read-modify operations, array accesses with memory
19890 ;; operands might end up in form:
19891 ;;  sall    $2, %eax
19892 ;;  movl    4(%esp), %edx
19893 ;;  addl    %edx, %eax
19894 ;; instead of pre-splitting:
19895 ;;  sall    $2, %eax
19896 ;;  addl    4(%esp), %eax
19897 ;; Turn it into:
19898 ;;  movl    4(%esp), %edx
19899 ;;  leal    (%edx,%eax,4), %eax
19901 (define_peephole2
19902   [(match_scratch:W 5 "r")
19903    (parallel [(set (match_operand 0 "register_operand")
19904                    (ashift (match_operand 1 "register_operand")
19905                            (match_operand 2 "const_int_operand")))
19906                (clobber (reg:CC FLAGS_REG))])
19907    (parallel [(set (match_operand 3 "register_operand")
19908                    (plus (match_dup 0)
19909                          (match_operand 4 "x86_64_general_operand")))
19910                    (clobber (reg:CC FLAGS_REG))])]
19911   "IN_RANGE (INTVAL (operands[2]), 1, 3)
19912    /* Validate MODE for lea.  */
19913    && ((!TARGET_PARTIAL_REG_STALL
19914         && (GET_MODE (operands[0]) == QImode
19915             || GET_MODE (operands[0]) == HImode))
19916        || GET_MODE (operands[0]) == SImode
19917        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19918    && (rtx_equal_p (operands[0], operands[3])
19919        || peep2_reg_dead_p (2, operands[0]))
19920    /* We reorder load and the shift.  */
19921    && !reg_overlap_mentioned_p (operands[0], operands[4])"
19922   [(set (match_dup 5) (match_dup 4))
19923    (set (match_dup 0) (match_dup 1))]
19925   machine_mode op1mode = GET_MODE (operands[1]);
19926   machine_mode mode = op1mode == DImode ? DImode : SImode;
19927   int scale = 1 << INTVAL (operands[2]);
19928   rtx index = gen_lowpart (word_mode, operands[1]);
19929   rtx base = gen_lowpart (word_mode, operands[5]);
19930   rtx dest = gen_lowpart (mode, operands[3]);
19932   operands[1] = gen_rtx_PLUS (word_mode, base,
19933                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19934   if (mode != word_mode)
19935     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19937   operands[5] = base;
19938   if (op1mode != word_mode)
19939     operands[5] = gen_lowpart (op1mode, operands[5]);
19941   operands[0] = dest;
19944 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19945 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19946 ;; caught for use by garbage collectors and the like.  Using an insn that
19947 ;; maps to SIGILL makes it more likely the program will rightfully die.
19948 ;; Keeping with tradition, "6" is in honor of #UD.
19949 (define_insn "trap"
19950   [(trap_if (const_int 1) (const_int 6))]
19951   ""
19953 #ifdef HAVE_AS_IX86_UD2
19954   return "ud2";
19955 #else
19956   return ASM_SHORT "0x0b0f";
19957 #endif
19959   [(set_attr "length" "2")])
19961 (define_insn "ud2"
19962   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19963   ""
19965 #ifdef HAVE_AS_IX86_UD2
19966   return "ud2";
19967 #else
19968   return ASM_SHORT "0x0b0f";
19969 #endif
19971   [(set_attr "length" "2")])
19973 (define_expand "prefetch"
19974   [(prefetch (match_operand 0 "address_operand")
19975              (match_operand:SI 1 "const_int_operand")
19976              (match_operand:SI 2 "const_int_operand"))]
19977   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19979   bool write = INTVAL (operands[1]) != 0;
19980   int locality = INTVAL (operands[2]);
19982   gcc_assert (IN_RANGE (locality, 0, 3));
19984   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19985      supported by SSE counterpart (non-SSE2 athlon machines) or the
19986      SSE prefetch is not available (K6 machines).  Otherwise use SSE
19987      prefetch as it allows specifying of locality.  */
19989   if (write)
19990     {
19991       if (TARGET_PREFETCHWT1)
19992         operands[2] = GEN_INT (MAX (locality, 2)); 
19993       else if (TARGET_PRFCHW)
19994         operands[2] = GEN_INT (3);
19995       else if (TARGET_3DNOW && !TARGET_SSE2)
19996         operands[2] = GEN_INT (3);
19997       else if (TARGET_PREFETCH_SSE)
19998         operands[1] = const0_rtx;
19999       else
20000         {
20001           gcc_assert (TARGET_3DNOW);
20002           operands[2] = GEN_INT (3);
20003         }
20004     }
20005   else
20006     {
20007       if (TARGET_PREFETCH_SSE)
20008         ;
20009       else
20010         {
20011           gcc_assert (TARGET_3DNOW);
20012           operands[2] = GEN_INT (3);
20013         }
20014     }
20017 (define_insn "*prefetch_sse"
20018   [(prefetch (match_operand 0 "address_operand" "p")
20019              (const_int 0)
20020              (match_operand:SI 1 "const_int_operand"))]
20021   "TARGET_PREFETCH_SSE"
20023   static const char * const patterns[4] = {
20024    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20025   };
20027   int locality = INTVAL (operands[1]);
20028   gcc_assert (IN_RANGE (locality, 0, 3));
20030   return patterns[locality];
20032   [(set_attr "type" "sse")
20033    (set_attr "atom_sse_attr" "prefetch")
20034    (set (attr "length_address")
20035         (symbol_ref "memory_address_length (operands[0], false)"))
20036    (set_attr "memory" "none")])
20038 (define_insn "*prefetch_3dnow"
20039   [(prefetch (match_operand 0 "address_operand" "p")
20040              (match_operand:SI 1 "const_int_operand" "n")
20041              (const_int 3))]
20042   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20044   if (INTVAL (operands[1]) == 0)
20045     return "prefetch\t%a0";
20046   else
20047     return "prefetchw\t%a0";
20049   [(set_attr "type" "mmx")
20050    (set (attr "length_address")
20051         (symbol_ref "memory_address_length (operands[0], false)"))
20052    (set_attr "memory" "none")])
20054 (define_insn "*prefetch_prefetchwt1"
20055   [(prefetch (match_operand 0 "address_operand" "p")
20056              (const_int 1)
20057              (const_int 2))]
20058   "TARGET_PREFETCHWT1"
20059   "prefetchwt1\t%a0";
20060   [(set_attr "type" "sse")
20061    (set (attr "length_address")
20062         (symbol_ref "memory_address_length (operands[0], false)"))
20063    (set_attr "memory" "none")])
20065 (define_expand "stack_protect_set"
20066   [(match_operand 0 "memory_operand")
20067    (match_operand 1 "memory_operand")]
20068   "TARGET_SSP_TLS_GUARD"
20070   rtx (*insn)(rtx, rtx);
20072   insn = (TARGET_LP64
20073           ? gen_stack_protect_set_di
20074           : gen_stack_protect_set_si);
20076   emit_insn (insn (operands[0], operands[1]));
20077   DONE;
20080 (define_insn "stack_protect_set_<mode>"
20081   [(set (match_operand:PTR 0 "memory_operand" "=m")
20082         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
20083                     UNSPEC_SP_SET))
20084    (set (match_scratch:PTR 2 "=&r") (const_int 0))
20085    (clobber (reg:CC FLAGS_REG))]
20086   "TARGET_SSP_TLS_GUARD"
20087   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20088   [(set_attr "type" "multi")])
20090 (define_expand "stack_protect_test"
20091   [(match_operand 0 "memory_operand")
20092    (match_operand 1 "memory_operand")
20093    (match_operand 2)]
20094   "TARGET_SSP_TLS_GUARD"
20096   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20098   rtx (*insn)(rtx, rtx, rtx);
20100   insn = (TARGET_LP64
20101           ? gen_stack_protect_test_di
20102           : gen_stack_protect_test_si);
20104   emit_insn (insn (flags, operands[0], operands[1]));
20106   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20107                                   flags, const0_rtx, operands[2]));
20108   DONE;
20111 (define_insn "stack_protect_test_<mode>"
20112   [(set (match_operand:CCZ 0 "flags_reg_operand")
20113         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20114                      (match_operand:PTR 2 "memory_operand" "m")]
20115                     UNSPEC_SP_TEST))
20116    (clobber (match_scratch:PTR 3 "=&r"))]
20117   "TARGET_SSP_TLS_GUARD"
20118   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
20119   [(set_attr "type" "multi")])
20121 (define_insn "sse4_2_crc32<mode>"
20122   [(set (match_operand:SI 0 "register_operand" "=r")
20123         (unspec:SI
20124           [(match_operand:SI 1 "register_operand" "0")
20125            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20126           UNSPEC_CRC32))]
20127   "TARGET_SSE4_2 || TARGET_CRC32"
20128   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20129   [(set_attr "type" "sselog1")
20130    (set_attr "prefix_rep" "1")
20131    (set_attr "prefix_extra" "1")
20132    (set (attr "prefix_data16")
20133      (if_then_else (match_operand:HI 2)
20134        (const_string "1")
20135        (const_string "*")))
20136    (set (attr "prefix_rex")
20137      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20138        (const_string "1")
20139        (const_string "*")))
20140    (set_attr "mode" "SI")])
20142 (define_insn "sse4_2_crc32di"
20143   [(set (match_operand:DI 0 "register_operand" "=r")
20144         (unspec:DI
20145           [(match_operand:DI 1 "register_operand" "0")
20146            (match_operand:DI 2 "nonimmediate_operand" "rm")]
20147           UNSPEC_CRC32))]
20148   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20149   "crc32{q}\t{%2, %0|%0, %2}"
20150   [(set_attr "type" "sselog1")
20151    (set_attr "prefix_rep" "1")
20152    (set_attr "prefix_extra" "1")
20153    (set_attr "mode" "DI")])
20155 (define_insn "rdpmc"
20156   [(set (match_operand:DI 0 "register_operand" "=A")
20157         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20158                             UNSPECV_RDPMC))]
20159   "!TARGET_64BIT"
20160   "rdpmc"
20161   [(set_attr "type" "other")
20162    (set_attr "length" "2")])
20164 (define_insn "rdpmc_rex64"
20165   [(set (match_operand:DI 0 "register_operand" "=a")
20166         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20167                             UNSPECV_RDPMC))
20168    (set (match_operand:DI 1 "register_operand" "=d")
20169         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
20170   "TARGET_64BIT"
20171   "rdpmc"
20172   [(set_attr "type" "other")
20173    (set_attr "length" "2")])
20175 (define_insn "rdtsc"
20176   [(set (match_operand:DI 0 "register_operand" "=A")
20177         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20178   "!TARGET_64BIT"
20179   "rdtsc"
20180   [(set_attr "type" "other")
20181    (set_attr "length" "2")])
20183 (define_insn "rdtsc_rex64"
20184   [(set (match_operand:DI 0 "register_operand" "=a")
20185         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20186    (set (match_operand:DI 1 "register_operand" "=d")
20187         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20188   "TARGET_64BIT"
20189   "rdtsc"
20190   [(set_attr "type" "other")
20191    (set_attr "length" "2")])
20193 (define_insn "rdtscp"
20194   [(set (match_operand:DI 0 "register_operand" "=A")
20195         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20196    (set (match_operand:SI 1 "register_operand" "=c")
20197         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20198   "!TARGET_64BIT"
20199   "rdtscp"
20200   [(set_attr "type" "other")
20201    (set_attr "length" "3")])
20203 (define_insn "rdtscp_rex64"
20204   [(set (match_operand:DI 0 "register_operand" "=a")
20205         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20206    (set (match_operand:DI 1 "register_operand" "=d")
20207         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20208    (set (match_operand:SI 2 "register_operand" "=c")
20209         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20210   "TARGET_64BIT"
20211   "rdtscp"
20212   [(set_attr "type" "other")
20213    (set_attr "length" "3")])
20215 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20217 ;; FXSR, XSAVE and XSAVEOPT instructions
20219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20221 (define_insn "fxsave"
20222   [(set (match_operand:BLK 0 "memory_operand" "=m")
20223         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20224   "TARGET_FXSR"
20225   "fxsave\t%0"
20226   [(set_attr "type" "other")
20227    (set_attr "memory" "store")
20228    (set (attr "length")
20229         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20231 (define_insn "fxsave64"
20232   [(set (match_operand:BLK 0 "memory_operand" "=m")
20233         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20234   "TARGET_64BIT && TARGET_FXSR"
20235   "fxsave64\t%0"
20236   [(set_attr "type" "other")
20237    (set_attr "memory" "store")
20238    (set (attr "length")
20239         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20241 (define_insn "fxrstor"
20242   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20243                     UNSPECV_FXRSTOR)]
20244   "TARGET_FXSR"
20245   "fxrstor\t%0"
20246   [(set_attr "type" "other")
20247    (set_attr "memory" "load")
20248    (set (attr "length")
20249         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20251 (define_insn "fxrstor64"
20252   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20253                     UNSPECV_FXRSTOR64)]
20254   "TARGET_64BIT && TARGET_FXSR"
20255   "fxrstor64\t%0"
20256   [(set_attr "type" "other")
20257    (set_attr "memory" "load")
20258    (set (attr "length")
20259         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20261 (define_int_iterator ANY_XSAVE
20262         [UNSPECV_XSAVE
20263          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20264          (UNSPECV_XSAVEC "TARGET_XSAVEC")
20265          (UNSPECV_XSAVES "TARGET_XSAVES")])
20267 (define_int_iterator ANY_XSAVE64
20268         [UNSPECV_XSAVE64
20269          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20270          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20271          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20273 (define_int_attr xsave
20274         [(UNSPECV_XSAVE "xsave")
20275          (UNSPECV_XSAVE64 "xsave64")
20276          (UNSPECV_XSAVEOPT "xsaveopt")
20277          (UNSPECV_XSAVEOPT64 "xsaveopt64")
20278          (UNSPECV_XSAVEC "xsavec")
20279          (UNSPECV_XSAVEC64 "xsavec64")
20280          (UNSPECV_XSAVES "xsaves")
20281          (UNSPECV_XSAVES64 "xsaves64")])
20283 (define_int_iterator ANY_XRSTOR
20284         [UNSPECV_XRSTOR
20285          (UNSPECV_XRSTORS "TARGET_XSAVES")])
20287 (define_int_iterator ANY_XRSTOR64
20288         [UNSPECV_XRSTOR64
20289          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20291 (define_int_attr xrstor
20292         [(UNSPECV_XRSTOR "xrstor")
20293          (UNSPECV_XRSTOR64 "xrstor")
20294          (UNSPECV_XRSTORS "xrstors")
20295          (UNSPECV_XRSTORS64 "xrstors")])
20297 (define_insn "<xsave>"
20298   [(set (match_operand:BLK 0 "memory_operand" "=m")
20299         (unspec_volatile:BLK
20300          [(match_operand:DI 1 "register_operand" "A")]
20301          ANY_XSAVE))]
20302   "!TARGET_64BIT && TARGET_XSAVE"
20303   "<xsave>\t%0"
20304   [(set_attr "type" "other")
20305    (set_attr "memory" "store")
20306    (set (attr "length")
20307         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20309 (define_insn "<xsave>_rex64"
20310   [(set (match_operand:BLK 0 "memory_operand" "=m")
20311         (unspec_volatile:BLK
20312          [(match_operand:SI 1 "register_operand" "a")
20313           (match_operand:SI 2 "register_operand" "d")]
20314          ANY_XSAVE))]
20315   "TARGET_64BIT && TARGET_XSAVE"
20316   "<xsave>\t%0"
20317   [(set_attr "type" "other")
20318    (set_attr "memory" "store")
20319    (set (attr "length")
20320         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20322 (define_insn "<xsave>"
20323   [(set (match_operand:BLK 0 "memory_operand" "=m")
20324         (unspec_volatile:BLK
20325          [(match_operand:SI 1 "register_operand" "a")
20326           (match_operand:SI 2 "register_operand" "d")]
20327          ANY_XSAVE64))]
20328   "TARGET_64BIT && TARGET_XSAVE"
20329   "<xsave>\t%0"
20330   [(set_attr "type" "other")
20331    (set_attr "memory" "store")
20332    (set (attr "length")
20333         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20335 (define_insn "<xrstor>"
20336    [(unspec_volatile:BLK
20337      [(match_operand:BLK 0 "memory_operand" "m")
20338       (match_operand:DI 1 "register_operand" "A")]
20339      ANY_XRSTOR)]
20340   "!TARGET_64BIT && TARGET_XSAVE"
20341   "<xrstor>\t%0"
20342   [(set_attr "type" "other")
20343    (set_attr "memory" "load")
20344    (set (attr "length")
20345         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20347 (define_insn "<xrstor>_rex64"
20348    [(unspec_volatile:BLK
20349      [(match_operand:BLK 0 "memory_operand" "m")
20350       (match_operand:SI 1 "register_operand" "a")
20351       (match_operand:SI 2 "register_operand" "d")]
20352      ANY_XRSTOR)]
20353   "TARGET_64BIT && TARGET_XSAVE"
20354   "<xrstor>\t%0"
20355   [(set_attr "type" "other")
20356    (set_attr "memory" "load")
20357    (set (attr "length")
20358         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20360 (define_insn "<xrstor>64"
20361    [(unspec_volatile:BLK
20362      [(match_operand:BLK 0 "memory_operand" "m")
20363       (match_operand:SI 1 "register_operand" "a")
20364       (match_operand:SI 2 "register_operand" "d")]
20365      ANY_XRSTOR64)]
20366   "TARGET_64BIT && TARGET_XSAVE"
20367   "<xrstor>64\t%0"
20368   [(set_attr "type" "other")
20369    (set_attr "memory" "load")
20370    (set (attr "length")
20371         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20373 (define_insn "xsetbv"
20374   [(unspec_volatile:SI
20375          [(match_operand:SI 0 "register_operand" "c")
20376           (match_operand:DI 1 "register_operand" "A")]
20377          UNSPECV_XSETBV)]
20378   "!TARGET_64BIT && TARGET_XSAVE"
20379   "xsetbv"
20380   [(set_attr "type" "other")])
20382 (define_insn "xsetbv_rex64"
20383   [(unspec_volatile:SI
20384          [(match_operand:SI 0 "register_operand" "c")
20385           (match_operand:SI 1 "register_operand" "a")
20386           (match_operand:SI 2 "register_operand" "d")]
20387          UNSPECV_XSETBV)]
20388   "TARGET_64BIT && TARGET_XSAVE"
20389   "xsetbv"
20390   [(set_attr "type" "other")])
20392 (define_insn "xgetbv"
20393   [(set (match_operand:DI 0 "register_operand" "=A")
20394         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20395                             UNSPECV_XGETBV))]
20396   "!TARGET_64BIT && TARGET_XSAVE"
20397   "xgetbv"
20398   [(set_attr "type" "other")])
20400 (define_insn "xgetbv_rex64"
20401   [(set (match_operand:DI 0 "register_operand" "=a")
20402         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20403                             UNSPECV_XGETBV))
20404    (set (match_operand:DI 1 "register_operand" "=d")
20405         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20406   "TARGET_64BIT && TARGET_XSAVE"
20407   "xgetbv"
20408   [(set_attr "type" "other")])
20410 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20412 ;; Floating-point instructions for atomic compound assignments
20414 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20416 ; Clobber all floating-point registers on environment save and restore
20417 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20418 (define_insn "fnstenv"
20419   [(set (match_operand:BLK 0 "memory_operand" "=m")
20420         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20421    (clobber (reg:HI FPCR_REG))
20422    (clobber (reg:XF ST0_REG))
20423    (clobber (reg:XF ST1_REG))
20424    (clobber (reg:XF ST2_REG))
20425    (clobber (reg:XF ST3_REG))
20426    (clobber (reg:XF ST4_REG))
20427    (clobber (reg:XF ST5_REG))
20428    (clobber (reg:XF ST6_REG))
20429    (clobber (reg:XF ST7_REG))]
20430   "TARGET_80387"
20431   "fnstenv\t%0"
20432   [(set_attr "type" "other")
20433    (set_attr "memory" "store")
20434    (set (attr "length")
20435         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20437 (define_insn "fldenv"
20438   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20439                     UNSPECV_FLDENV)
20440    (clobber (reg:CCFP FPSR_REG))
20441    (clobber (reg:HI FPCR_REG))
20442    (clobber (reg:XF ST0_REG))
20443    (clobber (reg:XF ST1_REG))
20444    (clobber (reg:XF ST2_REG))
20445    (clobber (reg:XF ST3_REG))
20446    (clobber (reg:XF ST4_REG))
20447    (clobber (reg:XF ST5_REG))
20448    (clobber (reg:XF ST6_REG))
20449    (clobber (reg:XF ST7_REG))]
20450   "TARGET_80387"
20451   "fldenv\t%0"
20452   [(set_attr "type" "other")
20453    (set_attr "memory" "load")
20454    (set (attr "length")
20455         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20457 (define_insn "fnstsw"
20458   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20459         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20460   "TARGET_80387"
20461   "fnstsw\t%0"
20462   [(set_attr "type" "other,other")
20463    (set_attr "memory" "none,store")
20464    (set (attr "length")
20465         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20467 (define_insn "fnclex"
20468   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20469   "TARGET_80387"
20470   "fnclex"
20471   [(set_attr "type" "other")
20472    (set_attr "memory" "none")
20473    (set_attr "length" "2")])
20475 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20477 ;; LWP instructions
20479 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20481 (define_expand "lwp_llwpcb"
20482   [(unspec_volatile [(match_operand 0 "register_operand")]
20483                     UNSPECV_LLWP_INTRINSIC)]
20484   "TARGET_LWP")
20486 (define_insn "*lwp_llwpcb<mode>1"
20487   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20488                     UNSPECV_LLWP_INTRINSIC)]
20489   "TARGET_LWP"
20490   "llwpcb\t%0"
20491   [(set_attr "type" "lwp")
20492    (set_attr "mode" "<MODE>")
20493    (set_attr "length" "5")])
20495 (define_expand "lwp_slwpcb"
20496   [(set (match_operand 0 "register_operand")
20497         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20498   "TARGET_LWP"
20500   rtx (*insn)(rtx);
20502   insn = (Pmode == DImode
20503           ? gen_lwp_slwpcbdi
20504           : gen_lwp_slwpcbsi);
20506   emit_insn (insn (operands[0]));
20507   DONE;
20510 (define_insn "lwp_slwpcb<mode>"
20511   [(set (match_operand:P 0 "register_operand" "=r")
20512         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20513   "TARGET_LWP"
20514   "slwpcb\t%0"
20515   [(set_attr "type" "lwp")
20516    (set_attr "mode" "<MODE>")
20517    (set_attr "length" "5")])
20519 (define_expand "lwp_lwpval<mode>3"
20520   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20521                      (match_operand:SI 2 "nonimmediate_operand")
20522                      (match_operand:SI 3 "const_int_operand")]
20523                     UNSPECV_LWPVAL_INTRINSIC)]
20524   "TARGET_LWP"
20525   ;; Avoid unused variable warning.
20526   "(void) operands[0];")
20528 (define_insn "*lwp_lwpval<mode>3_1"
20529   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20530                      (match_operand:SI 1 "nonimmediate_operand" "rm")
20531                      (match_operand:SI 2 "const_int_operand" "i")]
20532                     UNSPECV_LWPVAL_INTRINSIC)]
20533   "TARGET_LWP"
20534   "lwpval\t{%2, %1, %0|%0, %1, %2}"
20535   [(set_attr "type" "lwp")
20536    (set_attr "mode" "<MODE>")
20537    (set (attr "length")
20538         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20540 (define_expand "lwp_lwpins<mode>3"
20541   [(set (reg:CCC FLAGS_REG)
20542         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20543                               (match_operand:SI 2 "nonimmediate_operand")
20544                               (match_operand:SI 3 "const_int_operand")]
20545                              UNSPECV_LWPINS_INTRINSIC))
20546    (set (match_operand:QI 0 "nonimmediate_operand")
20547         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20548   "TARGET_LWP")
20550 (define_insn "*lwp_lwpins<mode>3_1"
20551   [(set (reg:CCC FLAGS_REG)
20552         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20553                               (match_operand:SI 1 "nonimmediate_operand" "rm")
20554                               (match_operand:SI 2 "const_int_operand" "i")]
20555                              UNSPECV_LWPINS_INTRINSIC))]
20556   "TARGET_LWP"
20557   "lwpins\t{%2, %1, %0|%0, %1, %2}"
20558   [(set_attr "type" "lwp")
20559    (set_attr "mode" "<MODE>")
20560    (set (attr "length")
20561         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20563 (define_int_iterator RDFSGSBASE
20564         [UNSPECV_RDFSBASE
20565          UNSPECV_RDGSBASE])
20567 (define_int_iterator WRFSGSBASE
20568         [UNSPECV_WRFSBASE
20569          UNSPECV_WRGSBASE])
20571 (define_int_attr fsgs
20572         [(UNSPECV_RDFSBASE "fs")
20573          (UNSPECV_RDGSBASE "gs")
20574          (UNSPECV_WRFSBASE "fs")
20575          (UNSPECV_WRGSBASE "gs")])
20577 (define_insn "rd<fsgs>base<mode>"
20578   [(set (match_operand:SWI48 0 "register_operand" "=r")
20579         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20580   "TARGET_64BIT && TARGET_FSGSBASE"
20581   "rd<fsgs>base\t%0"
20582   [(set_attr "type" "other")
20583    (set_attr "prefix_extra" "2")])
20585 (define_insn "wr<fsgs>base<mode>"
20586   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20587                     WRFSGSBASE)]
20588   "TARGET_64BIT && TARGET_FSGSBASE"
20589   "wr<fsgs>base\t%0"
20590   [(set_attr "type" "other")
20591    (set_attr "prefix_extra" "2")])
20593 (define_insn "rdrand<mode>_1"
20594   [(set (match_operand:SWI248 0 "register_operand" "=r")
20595         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20596    (set (reg:CCC FLAGS_REG)
20597         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20598   "TARGET_RDRND"
20599   "rdrand\t%0"
20600   [(set_attr "type" "other")
20601    (set_attr "prefix_extra" "1")])
20603 (define_insn "rdseed<mode>_1"
20604   [(set (match_operand:SWI248 0 "register_operand" "=r")
20605         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20606    (set (reg:CCC FLAGS_REG)
20607         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20608   "TARGET_RDSEED"
20609   "rdseed\t%0"
20610   [(set_attr "type" "other")
20611    (set_attr "prefix_extra" "1")])
20613 (define_expand "pause"
20614   [(set (match_dup 0)
20615         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20616   ""
20618   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20619   MEM_VOLATILE_P (operands[0]) = 1;
20622 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20623 ;; They have the same encoding.
20624 (define_insn "*pause"
20625   [(set (match_operand:BLK 0)
20626         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20627   ""
20628   "rep%; nop"
20629   [(set_attr "length" "2")
20630    (set_attr "memory" "unknown")])
20632 ;; CET instructions
20633 (define_insn "rdssp<mode>"
20634   [(set (match_operand:SWI48x 0 "register_operand" "=r")
20635         (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20636   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20637   "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20638   [(set_attr "length" "6")
20639    (set_attr "type" "other")])
20641 (define_insn "incssp<mode>"
20642   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20643                     UNSPECV_INCSSP)]
20644   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20645   "incssp<mskmodesuffix>\t%0"
20646   [(set_attr "length" "4")
20647    (set_attr "type" "other")])
20649 (define_insn "saveprevssp"
20650   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20651   "TARGET_SHSTK"
20652   "saveprevssp"
20653   [(set_attr "length" "5")
20654    (set_attr "type" "other")])
20656 (define_expand "rstorssp"
20657   [(unspec_volatile [(match_operand 0 "memory_operand")]
20658                     UNSPECV_RSTORSSP)]
20659   "TARGET_SHSTK")
20661 (define_insn "*rstorssp<mode>"
20662   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20663                     UNSPECV_RSTORSSP)]
20664   "TARGET_SHSTK"
20665   "rstorssp\t%0"
20666   [(set_attr "length" "5")
20667    (set_attr "type" "other")])
20669 (define_insn "wrss<mode>"
20670   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20671                      (match_operand:SWI48x 1 "memory_operand" "m")]
20672                     UNSPECV_WRSS)]
20673   "TARGET_SHSTK"
20674   "wrss<mskmodesuffix>\t%0, %1"
20675   [(set_attr "length" "3")
20676    (set_attr "type" "other")])
20678 (define_insn "wruss<mode>"
20679   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20680                      (match_operand:SWI48x 1 "memory_operand" "m")]
20681                     UNSPECV_WRUSS)]
20682   "TARGET_SHSTK"
20683   "wruss<mskmodesuffix>\t%0, %1"
20684   [(set_attr "length" "4")
20685    (set_attr "type" "other")])
20687 (define_insn "setssbsy"
20688   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20689   "TARGET_SHSTK"
20690   "setssbsy"
20691   [(set_attr "length" "4")
20692    (set_attr "type" "other")])
20694 (define_expand "clrssbsy"
20695   [(unspec_volatile [(match_operand 0 "memory_operand")]
20696                     UNSPECV_CLRSSBSY)]
20697   "TARGET_SHSTK")
20699 (define_insn "*clrssbsy<mode>"
20700   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20701                     UNSPECV_CLRSSBSY)]
20702   "TARGET_SHSTK"
20703   "clrssbsy\t%0"
20704   [(set_attr "length" "4")
20705    (set_attr "type" "other")])
20707 (define_insn "nop_endbr"
20708   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20709   "(flag_cf_protection & CF_BRANCH)"
20711   return TARGET_64BIT ? "endbr64" : "endbr32";
20713   [(set_attr "length" "4")
20714    (set_attr "length_immediate" "0")
20715    (set_attr "modrm" "0")])
20717 ;; For RTM support
20718 (define_expand "xbegin"
20719   [(set (match_operand:SI 0 "register_operand")
20720         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20721   "TARGET_RTM"
20723   rtx_code_label *label = gen_label_rtx ();
20725   /* xbegin is emitted as jump_insn, so reload won't be able
20726      to reload its operand.  Force the value into AX hard register.  */
20727   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20728   emit_move_insn (ax_reg, constm1_rtx);
20730   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20732   emit_label (label);
20733   LABEL_NUSES (label) = 1;
20735   emit_move_insn (operands[0], ax_reg);
20737   DONE;
20740 (define_insn "xbegin_1"
20741   [(set (pc)
20742         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20743                           (const_int 0))
20744                       (label_ref (match_operand 1))
20745                       (pc)))
20746    (set (match_operand:SI 0 "register_operand" "+a")
20747         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20748   "TARGET_RTM"
20749   "xbegin\t%l1"
20750   [(set_attr "type" "other")
20751    (set_attr "length" "6")])
20753 (define_insn "xend"
20754   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20755   "TARGET_RTM"
20756   "xend"
20757   [(set_attr "type" "other")
20758    (set_attr "length" "3")])
20760 (define_insn "xabort"
20761   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20762                     UNSPECV_XABORT)]
20763   "TARGET_RTM"
20764   "xabort\t%0"
20765   [(set_attr "type" "other")
20766    (set_attr "length" "3")])
20768 (define_expand "xtest"
20769   [(set (match_operand:QI 0 "register_operand")
20770         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20771   "TARGET_RTM"
20773   emit_insn (gen_xtest_1 ());
20775   ix86_expand_setcc (operands[0], NE,
20776                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20777   DONE;
20780 (define_insn "xtest_1"
20781   [(set (reg:CCZ FLAGS_REG)
20782         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20783   "TARGET_RTM"
20784   "xtest"
20785   [(set_attr "type" "other")
20786    (set_attr "length" "3")])
20788 (define_insn "clwb"
20789   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20790                    UNSPECV_CLWB)]
20791   "TARGET_CLWB"
20792   "clwb\t%a0"
20793   [(set_attr "type" "sse")
20794    (set_attr "atom_sse_attr" "fence")
20795    (set_attr "memory" "unknown")])
20797 (define_insn "clflushopt"
20798   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20799                    UNSPECV_CLFLUSHOPT)]
20800   "TARGET_CLFLUSHOPT"
20801   "clflushopt\t%a0"
20802   [(set_attr "type" "sse")
20803    (set_attr "atom_sse_attr" "fence")
20804    (set_attr "memory" "unknown")])
20806 ;; MONITORX and MWAITX
20807 (define_insn "mwaitx"
20808   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20809                      (match_operand:SI 1 "register_operand" "a")
20810                      (match_operand:SI 2 "register_operand" "b")]
20811                    UNSPECV_MWAITX)]
20812   "TARGET_MWAITX"
20813 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20814 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20815 ;; we only need to set up 32bit registers.
20816   "mwaitx"
20817   [(set_attr "length" "3")])
20819 (define_insn "monitorx_<mode>"
20820   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20821                      (match_operand:SI 1 "register_operand" "c")
20822                      (match_operand:SI 2 "register_operand" "d")]
20823                    UNSPECV_MONITORX)]
20824   "TARGET_MWAITX"
20825 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20826 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
20827 ;; zero extended to 64bit, we only need to set up 32bit registers.
20828   "%^monitorx"
20829   [(set (attr "length")
20830      (symbol_ref ("(Pmode != word_mode) + 3")))])
20832 ;; CLZERO
20833 (define_insn "clzero_<mode>"
20834   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20835                    UNSPECV_CLZERO)]
20836   "TARGET_CLZERO"
20837   "clzero"
20838   [(set_attr "length" "3")
20839   (set_attr "memory" "unknown")])
20841 ;; RDPKRU and WRPKRU
20843 (define_expand "rdpkru"
20844   [(parallel
20845      [(set (match_operand:SI 0 "register_operand")
20846            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20847       (set (match_dup 2) (const_int 0))])]
20848   "TARGET_PKU"
20850   operands[1] = force_reg (SImode, const0_rtx);
20851   operands[2] = gen_reg_rtx (SImode);
20854 (define_insn "*rdpkru"
20855   [(set (match_operand:SI 0 "register_operand" "=a")
20856         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20857                             UNSPECV_PKU))
20858    (set (match_operand:SI 1 "register_operand" "=d")
20859         (const_int 0))]
20860   "TARGET_PKU"
20861   "rdpkru"
20862   [(set_attr "type" "other")])
20864 (define_expand "wrpkru"
20865   [(unspec_volatile:SI
20866      [(match_operand:SI 0 "register_operand")
20867       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20868   "TARGET_PKU"
20870   operands[1] = force_reg (SImode, const0_rtx);
20871   operands[2] = force_reg (SImode, const0_rtx);
20874 (define_insn "*wrpkru"
20875   [(unspec_volatile:SI
20876      [(match_operand:SI 0 "register_operand" "a")
20877       (match_operand:SI 1 "register_operand" "d")
20878       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20879   "TARGET_PKU"
20880   "wrpkru"
20881   [(set_attr "type" "other")])
20883 (define_insn "rdpid"
20884   [(set (match_operand:SI 0 "register_operand" "=r")
20885         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20886   "!TARGET_64BIT && TARGET_RDPID"
20887   "rdpid\t%0"
20888   [(set_attr "type" "other")])
20890 (define_insn "rdpid_rex64"
20891   [(set (match_operand:DI 0 "register_operand" "=r")
20892         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20893   "TARGET_64BIT && TARGET_RDPID"
20894   "rdpid\t%0"
20895   [(set_attr "type" "other")])
20897 ;; Intirinsics for > i486
20899 (define_insn "wbinvd"
20900   [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20901   ""
20902   "wbinvd"
20903   [(set_attr "type" "other")])
20905 (define_insn "wbnoinvd"
20906   [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20907   "TARGET_WBNOINVD"
20908   "wbnoinvd"
20909   [(set_attr "type" "other")])
20911 ;; MOVDIRI and MOVDIR64B
20913 (define_insn "movdiri<mode>"
20914   [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20915                            (match_operand:SWI48 1 "register_operand" "r")]
20916                           UNSPECV_MOVDIRI)]
20917   "TARGET_MOVDIRI"
20918   "movdiri\t{%1, %0|%0, %1}"
20919   [(set_attr "type" "other")])
20921 (define_insn "movdir64b_<mode>"
20922   [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20923                         (match_operand:XI 1 "memory_operand")]
20924                        UNSPECV_MOVDIR64B)]
20925   "TARGET_MOVDIR64B"
20926   "movdir64b\t{%1, %0|%0, %1}"
20927   [(set_attr "type" "other")])
20929 ;; WAITPKG
20931 (define_insn "umwait"
20932   [(set (reg:CCC FLAGS_REG)
20933         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20934                               (match_operand:DI 1 "register_operand" "A")]
20935                              UNSPECV_UMWAIT))]
20936   "!TARGET_64BIT && TARGET_WAITPKG"
20937   "umwait\t%0"
20938   [(set_attr "length" "3")])
20940 (define_insn "umwait_rex64"
20941   [(set (reg:CCC FLAGS_REG)
20942         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20943                               (match_operand:SI 1 "register_operand" "a")
20944                               (match_operand:SI 2 "register_operand" "d")]
20945                              UNSPECV_UMWAIT))]
20946   "TARGET_64BIT && TARGET_WAITPKG"
20947   "umwait\t%0"
20948   [(set_attr "length" "3")])
20950 (define_insn "umonitor_<mode>"
20951   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20952                     UNSPECV_UMONITOR)]
20953   "TARGET_WAITPKG"
20954   "umonitor\t%0"
20955   [(set (attr "length")
20956      (symbol_ref ("(Pmode != word_mode) + 3")))])
20958 (define_insn "tpause"
20959   [(set (reg:CCC FLAGS_REG)
20960         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20961                               (match_operand:DI 1 "register_operand" "A")]
20962                              UNSPECV_TPAUSE))]
20963   "!TARGET_64BIT && TARGET_WAITPKG"
20964   "tpause\t%0"
20965   [(set_attr "length" "3")])
20967 (define_insn "tpause_rex64"
20968   [(set (reg:CCC FLAGS_REG)
20969         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20970                               (match_operand:SI 1 "register_operand" "a")
20971                               (match_operand:SI 2 "register_operand" "d")]
20972                              UNSPECV_TPAUSE))]
20973   "TARGET_64BIT && TARGET_WAITPKG"
20974   "tpause\t%0"
20975   [(set_attr "length" "3")])
20977 (define_insn "cldemote"
20978   [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20979                  UNSPECV_CLDEMOTE)]
20980   "TARGET_CLDEMOTE"
20981   "cldemote\t%a0"
20982   [(set_attr "type" "other")
20983    (set_attr "memory" "unknown")])
20985 (define_insn "speculation_barrier"
20986   [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
20987   ""
20988   "lfence"
20989   [(set_attr "type" "other")
20990    (set_attr "length" "3")])
20992 (include "mmx.md")
20993 (include "sse.md")
20994 (include "sync.md")