PR target/86314
[official-gcc.git] / gcc / config / i386 / i386.md
blob559ad9334a77429b911a0deef284ed10b702b731
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
306 ;; Constants to represent rounding modes in the ROUND instruction
307 (define_constants
308   [(ROUND_FLOOR                 0x1)
309    (ROUND_CEIL                  0x2)
310    (ROUND_TRUNC                 0x3)
311    (ROUND_MXCSR                 0x4)
312    (ROUND_NO_EXC                0x8)
313   ])
315 ;; Constants to represent AVX512F embeded rounding
316 (define_constants
317   [(ROUND_NEAREST_INT                   0)
318    (ROUND_NEG_INF                       1)
319    (ROUND_POS_INF                       2)
320    (ROUND_ZERO                          3)
321    (NO_ROUND                            4)
322    (ROUND_SAE                           8)
323   ])
325 ;; Constants to represent pcomtrue/pcomfalse variants
326 (define_constants
327   [(PCOM_FALSE                  0)
328    (PCOM_TRUE                   1)
329    (COM_FALSE_S                 2)
330    (COM_FALSE_P                 3)
331    (COM_TRUE_S                  4)
332    (COM_TRUE_P                  5)
333   ])
335 ;; Constants used in the XOP pperm instruction
336 (define_constants
337   [(PPERM_SRC                   0x00)   /* copy source */
338    (PPERM_INVERT                0x20)   /* invert source */
339    (PPERM_REVERSE               0x40)   /* bit reverse source */
340    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
341    (PPERM_ZERO                  0x80)   /* all 0's */
342    (PPERM_ONES                  0xa0)   /* all 1's */
343    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
344    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
345    (PPERM_SRC1                  0x00)   /* use first source byte */
346    (PPERM_SRC2                  0x10)   /* use second source byte */
347    ])
349 ;; Registers by name.
350 (define_constants
351   [(AX_REG                       0)
352    (DX_REG                       1)
353    (CX_REG                       2)
354    (BX_REG                       3)
355    (SI_REG                       4)
356    (DI_REG                       5)
357    (BP_REG                       6)
358    (SP_REG                       7)
359    (ST0_REG                      8)
360    (ST1_REG                      9)
361    (ST2_REG                     10)
362    (ST3_REG                     11)
363    (ST4_REG                     12)
364    (ST5_REG                     13)
365    (ST6_REG                     14)
366    (ST7_REG                     15)
367    (ARGP_REG                    16)
368    (FLAGS_REG                   17)
369    (FPSR_REG                    18)
370    (FPCR_REG                    19)
371    (FRAME_REG                   20)
372    (XMM0_REG                    21)
373    (XMM1_REG                    22)
374    (XMM2_REG                    23)
375    (XMM3_REG                    24)
376    (XMM4_REG                    25)
377    (XMM5_REG                    26)
378    (XMM6_REG                    27)
379    (XMM7_REG                    28)
380    (MM0_REG                     29)
381    (MM1_REG                     30)
382    (MM2_REG                     31)
383    (MM3_REG                     32)
384    (MM4_REG                     33)
385    (MM5_REG                     34)
386    (MM6_REG                     35)
387    (MM7_REG                     36)
388    (R8_REG                      37)
389    (R9_REG                      38)
390    (R10_REG                     39)
391    (R11_REG                     40)
392    (R12_REG                     41)
393    (R13_REG                     42)
394    (R14_REG                     43)
395    (R15_REG                     44)
396    (XMM8_REG                    45)
397    (XMM9_REG                    46)
398    (XMM10_REG                   47)
399    (XMM11_REG                   48)
400    (XMM12_REG                   49)
401    (XMM13_REG                   50)
402    (XMM14_REG                   51)
403    (XMM15_REG                   52)
404    (XMM16_REG                   53)
405    (XMM17_REG                   54)
406    (XMM18_REG                   55)
407    (XMM19_REG                   56)
408    (XMM20_REG                   57)
409    (XMM21_REG                   58)
410    (XMM22_REG                   59)
411    (XMM23_REG                   60)
412    (XMM24_REG                   61)
413    (XMM25_REG                   62)
414    (XMM26_REG                   63)
415    (XMM27_REG                   64)
416    (XMM28_REG                   65)
417    (XMM29_REG                   66)
418    (XMM30_REG                   67)
419    (XMM31_REG                   68)
420    (MASK0_REG                   69)
421    (MASK1_REG                   70)
422    (MASK2_REG                   71)
423    (MASK3_REG                   72)
424    (MASK4_REG                   73)
425    (MASK5_REG                   74)
426    (MASK6_REG                   75)
427    (MASK7_REG                   76)
428    (BND0_REG                    77)
429    (BND1_REG                    78)
430    (BND2_REG                    79)
431    (BND3_REG                    80)
432    (FIRST_PSEUDO_REG            81)
433   ])
435 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
436 ;; from i386.c.
438 ;; In C guard expressions, put expressions which may be compile-time
439 ;; constants first.  This allows for better optimization.  For
440 ;; example, write "TARGET_64BIT && reload_completed", not
441 ;; "reload_completed && TARGET_64BIT".
444 ;; Processor type.
445 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
446                     atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
447                     bdver4,btver2,znver1"
448   (const (symbol_ref "ix86_schedule")))
450 ;; A basic instruction type.  Refinements due to arguments to be
451 ;; provided in other attributes.
452 (define_attr "type"
453   "other,multi,
454    alu,alu1,negnot,imov,imovx,lea,
455    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
456    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
457    push,pop,call,callv,leave,
458    str,bitmanip,
459    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
460    fxch,fistp,fisttp,frndint,
461    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
462    ssemul,sseimul,ssediv,sselog,sselog1,
463    sseishft,sseishft1,ssecmp,ssecomi,
464    ssecvt,ssecvt1,sseicvt,sseins,
465    sseshuf,sseshuf1,ssemuladd,sse4arg,
466    lwp,mskmov,msklog,
467    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
468    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
469   (const_string "other"))
471 ;; Main data type used by the insn
472 (define_attr "mode"
473   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
474   V2DF,V2SF,V1DF,V8DF"
475   (const_string "unknown"))
477 ;; The CPU unit operations uses.
478 (define_attr "unit" "integer,i387,sse,mmx,unknown"
479   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
480                           fxch,fistp,fisttp,frndint")
481            (const_string "i387")
482          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
483                           ssemul,sseimul,ssediv,sselog,sselog1,
484                           sseishft,sseishft1,ssecmp,ssecomi,
485                           ssecvt,ssecvt1,sseicvt,sseins,
486                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
487            (const_string "sse")
488          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
489            (const_string "mmx")
490          (eq_attr "type" "other")
491            (const_string "unknown")]
492          (const_string "integer")))
494 ;; The (bounding maximum) length of an instruction immediate.
495 (define_attr "length_immediate" ""
496   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
497                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
498                           mpxld,mpxst")
499            (const_int 0)
500          (eq_attr "unit" "i387,sse,mmx")
501            (const_int 0)
502          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
503                           rotate,rotatex,rotate1,imul,icmp,push,pop")
504            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
505          (eq_attr "type" "imov,test")
506            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
507          (eq_attr "type" "call")
508            (if_then_else (match_operand 0 "constant_call_address_operand")
509              (const_int 4)
510              (const_int 0))
511          (eq_attr "type" "callv")
512            (if_then_else (match_operand 1 "constant_call_address_operand")
513              (const_int 4)
514              (const_int 0))
515          ;; We don't know the size before shorten_branches.  Expect
516          ;; the instruction to fit for better scheduling.
517          (eq_attr "type" "ibr")
518            (const_int 1)
519          ]
520          (symbol_ref "/* Update immediate_length and other attributes! */
521                       gcc_unreachable (),1")))
523 ;; The (bounding maximum) length of an instruction address.
524 (define_attr "length_address" ""
525   (cond [(eq_attr "type" "str,other,multi,fxch")
526            (const_int 0)
527          (and (eq_attr "type" "call")
528               (match_operand 0 "constant_call_address_operand"))
529              (const_int 0)
530          (and (eq_attr "type" "callv")
531               (match_operand 1 "constant_call_address_operand"))
532              (const_int 0)
533          ]
534          (symbol_ref "ix86_attr_length_address_default (insn)")))
536 ;; Set when length prefix is used.
537 (define_attr "prefix_data16" ""
538   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
539            (const_int 0)
540          (eq_attr "mode" "HI")
541            (const_int 1)
542          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
543            (const_int 1)
544         ]
545         (const_int 0)))
547 ;; Set when string REP prefix is used.
548 (define_attr "prefix_rep" ""
549   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
550            (const_int 0)
551          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
552            (const_int 1)
553         ]
554         (const_int 0)))
556 ;; Set when 0f opcode prefix is used.
557 (define_attr "prefix_0f" ""
558   (if_then_else
559     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
560                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
561          (eq_attr "unit" "sse,mmx"))
562     (const_int 1)
563     (const_int 0)))
565 ;; Set when REX opcode prefix is used.
566 (define_attr "prefix_rex" ""
567   (cond [(not (match_test "TARGET_64BIT"))
568            (const_int 0)
569          (and (eq_attr "mode" "DI")
570               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
571                    (eq_attr "unit" "!mmx")))
572            (const_int 1)
573          (and (eq_attr "mode" "QI")
574               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
575            (const_int 1)
576          (match_test "x86_extended_reg_mentioned_p (insn)")
577            (const_int 1)
578          (and (eq_attr "type" "imovx")
579               (match_operand:QI 1 "ext_QIreg_operand"))
580            (const_int 1)
581         ]
582         (const_int 0)))
584 ;; There are also additional prefixes in 3DNOW, SSSE3.
585 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
586 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
587 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
588 (define_attr "prefix_extra" ""
589   (cond [(eq_attr "type" "ssemuladd,sse4arg")
590            (const_int 2)
591          (eq_attr "type" "sseiadd1,ssecvt1")
592            (const_int 1)
593         ]
594         (const_int 0)))
596 ;; Prefix used: original, VEX or maybe VEX.
597 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
598   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
599            (const_string "vex")
600          (eq_attr "mode" "XI,V16SF,V8DF")
601            (const_string "evex")
602         ]
603         (const_string "orig")))
605 ;; VEX W bit is used.
606 (define_attr "prefix_vex_w" "" (const_int 0))
608 ;; The length of VEX prefix
609 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
610 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
611 ;; still prefix_0f 1, with prefix_extra 1.
612 (define_attr "length_vex" ""
613   (if_then_else (and (eq_attr "prefix_0f" "1")
614                      (eq_attr "prefix_extra" "0"))
615     (if_then_else (eq_attr "prefix_vex_w" "1")
616       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
617       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
618     (if_then_else (eq_attr "prefix_vex_w" "1")
619       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
620       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
622 ;; 4-bytes evex prefix and 1 byte opcode.
623 (define_attr "length_evex" "" (const_int 5))
625 ;; Set when modrm byte is used.
626 (define_attr "modrm" ""
627   (cond [(eq_attr "type" "str,leave")
628            (const_int 0)
629          (eq_attr "unit" "i387")
630            (const_int 0)
631          (and (eq_attr "type" "incdec")
632               (and (not (match_test "TARGET_64BIT"))
633                    (ior (match_operand:SI 1 "register_operand")
634                         (match_operand:HI 1 "register_operand"))))
635            (const_int 0)
636          (and (eq_attr "type" "push")
637               (not (match_operand 1 "memory_operand")))
638            (const_int 0)
639          (and (eq_attr "type" "pop")
640               (not (match_operand 0 "memory_operand")))
641            (const_int 0)
642          (and (eq_attr "type" "imov")
643               (and (not (eq_attr "mode" "DI"))
644                    (ior (and (match_operand 0 "register_operand")
645                              (match_operand 1 "immediate_operand"))
646                         (ior (and (match_operand 0 "ax_reg_operand")
647                                   (match_operand 1 "memory_displacement_only_operand"))
648                              (and (match_operand 0 "memory_displacement_only_operand")
649                                   (match_operand 1 "ax_reg_operand"))))))
650            (const_int 0)
651          (and (eq_attr "type" "call")
652               (match_operand 0 "constant_call_address_operand"))
653              (const_int 0)
654          (and (eq_attr "type" "callv")
655               (match_operand 1 "constant_call_address_operand"))
656              (const_int 0)
657          (and (eq_attr "type" "alu,alu1,icmp,test")
658               (match_operand 0 "ax_reg_operand"))
659              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
660          ]
661          (const_int 1)))
663 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
664   (cond [(eq_attr "modrm" "0")
665            (const_string "none")
666          (eq_attr "type" "alu,imul,ishift")
667            (const_string "op02")
668          (eq_attr "type" "imov,imovx,lea,alu1,icmp")
669            (const_string "op01")
670          (eq_attr "type" "incdec")
671            (const_string "incdec")
672          (eq_attr "type" "push,pop")
673            (const_string "pushpop")]
674          (const_string "unknown")))
676 ;; The (bounding maximum) length of an instruction in bytes.
677 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
678 ;; Later we may want to split them and compute proper length as for
679 ;; other insns.
680 (define_attr "length" ""
681   (cond [(eq_attr "type" "other,multi,fistp,frndint")
682            (const_int 16)
683          (eq_attr "type" "fcmp")
684            (const_int 4)
685          (eq_attr "unit" "i387")
686            (plus (const_int 2)
687                  (plus (attr "prefix_data16")
688                        (attr "length_address")))
689          (ior (eq_attr "prefix" "evex")
690               (and (ior (eq_attr "prefix" "maybe_evex")
691                         (eq_attr "prefix" "maybe_vex"))
692                    (match_test "TARGET_AVX512F")))
693            (plus (attr "length_evex")
694                  (plus (attr "length_immediate")
695                        (plus (attr "modrm")
696                              (attr "length_address"))))
697          (ior (eq_attr "prefix" "vex")
698               (and (ior (eq_attr "prefix" "maybe_vex")
699                         (eq_attr "prefix" "maybe_evex"))
700                    (match_test "TARGET_AVX")))
701            (plus (attr "length_vex")
702                  (plus (attr "length_immediate")
703                        (plus (attr "modrm")
704                              (attr "length_address"))))]
705          (plus (plus (attr "modrm")
706                      (plus (attr "prefix_0f")
707                            (plus (attr "prefix_rex")
708                                  (plus (attr "prefix_extra")
709                                        (const_int 1)))))
710                (plus (attr "prefix_rep")
711                      (plus (attr "prefix_data16")
712                            (plus (attr "length_immediate")
713                                  (attr "length_address")))))))
715 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
716 ;; `store' if there is a simple memory reference therein, or `unknown'
717 ;; if the instruction is complex.
719 (define_attr "memory" "none,load,store,both,unknown"
720   (cond [(eq_attr "type" "other,multi,str,lwp")
721            (const_string "unknown")
722          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
723            (const_string "none")
724          (eq_attr "type" "fistp,leave")
725            (const_string "both")
726          (eq_attr "type" "frndint")
727            (const_string "load")
728          (eq_attr "type" "mpxld")
729            (const_string "load")
730          (eq_attr "type" "mpxst")
731            (const_string "store")
732          (eq_attr "type" "push")
733            (if_then_else (match_operand 1 "memory_operand")
734              (const_string "both")
735              (const_string "store"))
736          (eq_attr "type" "pop")
737            (if_then_else (match_operand 0 "memory_operand")
738              (const_string "both")
739              (const_string "load"))
740          (eq_attr "type" "setcc")
741            (if_then_else (match_operand 0 "memory_operand")
742              (const_string "store")
743              (const_string "none"))
744          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
745            (if_then_else (ior (match_operand 0 "memory_operand")
746                               (match_operand 1 "memory_operand"))
747              (const_string "load")
748              (const_string "none"))
749          (eq_attr "type" "ibr")
750            (if_then_else (match_operand 0 "memory_operand")
751              (const_string "load")
752              (const_string "none"))
753          (eq_attr "type" "call")
754            (if_then_else (match_operand 0 "constant_call_address_operand")
755              (const_string "none")
756              (const_string "load"))
757          (eq_attr "type" "callv")
758            (if_then_else (match_operand 1 "constant_call_address_operand")
759              (const_string "none")
760              (const_string "load"))
761          (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
762               (match_operand 1 "memory_operand"))
763            (const_string "both")
764          (and (match_operand 0 "memory_operand")
765               (match_operand 1 "memory_operand"))
766            (const_string "both")
767          (match_operand 0 "memory_operand")
768            (const_string "store")
769          (match_operand 1 "memory_operand")
770            (const_string "load")
771          (and (eq_attr "type"
772                  "!alu1,negnot,ishift1,rotate1,
773                    imov,imovx,icmp,test,bitmanip,
774                    fmov,fcmp,fsgn,
775                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
776                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
777                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
778               (match_operand 2 "memory_operand"))
779            (const_string "load")
780          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
781               (match_operand 3 "memory_operand"))
782            (const_string "load")
783         ]
784         (const_string "none")))
786 ;; Indicates if an instruction has both an immediate and a displacement.
788 (define_attr "imm_disp" "false,true,unknown"
789   (cond [(eq_attr "type" "other,multi")
790            (const_string "unknown")
791          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
792               (and (match_operand 0 "memory_displacement_operand")
793                    (match_operand 1 "immediate_operand")))
794            (const_string "true")
795          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
796               (and (match_operand 0 "memory_displacement_operand")
797                    (match_operand 2 "immediate_operand")))
798            (const_string "true")
799         ]
800         (const_string "false")))
802 ;; Indicates if an FP operation has an integer source.
804 (define_attr "fp_int_src" "false,true"
805   (const_string "false"))
807 ;; Defines rounding mode of an FP operation.
809 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
810   (const_string "any"))
812 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
813 (define_attr "use_carry" "0,1" (const_string "0"))
815 ;; Define attribute to indicate unaligned ssemov insns
816 (define_attr "movu" "0,1" (const_string "0"))
818 ;; Used to control the "enabled" attribute on a per-instruction basis.
819 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
820                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
821                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
822                     avx512bw,noavx512bw,avx512dq,noavx512dq,
823                     avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
824   (const_string "base"))
826 (define_attr "enabled" ""
827   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
828          (eq_attr "isa" "x64_sse2")
829            (symbol_ref "TARGET_64BIT && TARGET_SSE2")
830          (eq_attr "isa" "x64_sse4")
831            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
832          (eq_attr "isa" "x64_sse4_noavx")
833            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
834          (eq_attr "isa" "x64_avx")
835            (symbol_ref "TARGET_64BIT && TARGET_AVX")
836          (eq_attr "isa" "x64_avx512dq")
837            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
838          (eq_attr "isa" "x64_avx512bw")
839            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
840          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
841          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
842          (eq_attr "isa" "sse2_noavx")
843            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
844          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
845          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
846          (eq_attr "isa" "sse4_noavx")
847            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
848          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
849          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
850          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
851          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
852          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
853          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
854          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
855          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
856          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
857          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
858          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
859          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
860          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
861          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
862          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
863          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
864         ]
865         (const_int 1)))
867 (define_attr "preferred_for_size" "" (const_int 1))
868 (define_attr "preferred_for_speed" "" (const_int 1))
870 ;; Describe a user's asm statement.
871 (define_asm_attributes
872   [(set_attr "length" "128")
873    (set_attr "type" "multi")])
875 (define_code_iterator plusminus [plus minus])
877 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
879 (define_code_iterator multdiv [mult div])
881 ;; Base name for define_insn
882 (define_code_attr plusminus_insn
883   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
884    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
886 ;; Base name for insn mnemonic.
887 (define_code_attr plusminus_mnemonic
888   [(plus "add") (ss_plus "adds") (us_plus "addus")
889    (minus "sub") (ss_minus "subs") (us_minus "subus")])
890 (define_code_attr multdiv_mnemonic
891   [(mult "mul") (div "div")])
893 ;; Mark commutative operators as such in constraints.
894 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
895                         (minus "") (ss_minus "") (us_minus "")])
897 ;; Mapping of max and min
898 (define_code_iterator maxmin [smax smin umax umin])
900 ;; Mapping of signed max and min
901 (define_code_iterator smaxmin [smax smin])
903 ;; Mapping of unsigned max and min
904 (define_code_iterator umaxmin [umax umin])
906 ;; Base name for integer and FP insn mnemonic
907 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
908                               (umax "maxu") (umin "minu")])
909 (define_code_attr maxmin_float [(smax "max") (smin "min")])
911 (define_int_iterator IEEE_MAXMIN
912         [UNSPEC_IEEE_MAX
913          UNSPEC_IEEE_MIN])
915 (define_int_attr ieee_maxmin
916         [(UNSPEC_IEEE_MAX "max")
917          (UNSPEC_IEEE_MIN "min")])
919 ;; Mapping of logic operators
920 (define_code_iterator any_logic [and ior xor])
921 (define_code_iterator any_or [ior xor])
922 (define_code_iterator fpint_logic [and xor])
924 ;; Base name for insn mnemonic.
925 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
927 ;; Mapping of logic-shift operators
928 (define_code_iterator any_lshift [ashift lshiftrt])
930 ;; Mapping of shift-right operators
931 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
933 ;; Mapping of all shift operators
934 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
936 ;; Base name for define_insn
937 (define_code_attr shift_insn
938   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
940 ;; Base name for insn mnemonic.
941 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
942 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
944 ;; Mapping of rotate operators
945 (define_code_iterator any_rotate [rotate rotatert])
947 ;; Base name for define_insn
948 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
950 ;; Base name for insn mnemonic.
951 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
953 ;; Mapping of abs neg operators
954 (define_code_iterator absneg [abs neg])
956 ;; Base name for x87 insn mnemonic.
957 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
959 ;; Used in signed and unsigned widening multiplications.
960 (define_code_iterator any_extend [sign_extend zero_extend])
962 ;; Prefix for insn menmonic.
963 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
965 ;; Prefix for define_insn
966 (define_code_attr u [(sign_extend "") (zero_extend "u")])
967 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
968 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
970 ;; Used in signed and unsigned truncations.
971 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
972 ;; Instruction suffix for truncations.
973 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
975 ;; Used in signed and unsigned fix.
976 (define_code_iterator any_fix [fix unsigned_fix])
977 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
978 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
979 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
981 ;; Used in signed and unsigned float.
982 (define_code_iterator any_float [float unsigned_float])
983 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
984 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
985 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
987 ;; All integer modes.
988 (define_mode_iterator SWI1248x [QI HI SI DI])
990 ;; All integer modes without QImode.
991 (define_mode_iterator SWI248x [HI SI DI])
993 ;; All integer modes without QImode and HImode.
994 (define_mode_iterator SWI48x [SI DI])
996 ;; All integer modes without SImode and DImode.
997 (define_mode_iterator SWI12 [QI HI])
999 ;; All integer modes without DImode.
1000 (define_mode_iterator SWI124 [QI HI SI])
1002 ;; All integer modes without QImode and DImode.
1003 (define_mode_iterator SWI24 [HI SI])
1005 ;; Single word integer modes.
1006 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1008 ;; Single word integer modes without QImode.
1009 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1011 ;; Single word integer modes without QImode and HImode.
1012 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1014 ;; All math-dependant single and double word integer modes.
1015 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1016                              (HI "TARGET_HIMODE_MATH")
1017                              SI DI (TI "TARGET_64BIT")])
1019 ;; Math-dependant single word integer modes.
1020 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1021                             (HI "TARGET_HIMODE_MATH")
1022                             SI (DI "TARGET_64BIT")])
1024 ;; Math-dependant integer modes without DImode.
1025 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1026                                (HI "TARGET_HIMODE_MATH")
1027                                SI])
1029 ;; Math-dependant integer modes with DImode.
1030 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1031                                  (HI "TARGET_HIMODE_MATH")
1032                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1034 ;; Math-dependant single word integer modes without QImode.
1035 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1036                                SI (DI "TARGET_64BIT")])
1038 ;; Double word integer modes.
1039 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1040                            (TI "TARGET_64BIT")])
1042 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1043 ;; compile time constant, it is faster to use <MODE_SIZE> than
1044 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1045 ;; command line options just use GET_MODE_SIZE macro.
1046 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1047                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1048                              (V16QI "16") (V32QI "32") (V64QI "64")
1049                              (V8HI "16") (V16HI "32") (V32HI "64")
1050                              (V4SI "16") (V8SI "32") (V16SI "64")
1051                              (V2DI "16") (V4DI "32") (V8DI "64")
1052                              (V1TI "16") (V2TI "32") (V4TI "64")
1053                              (V2DF "16") (V4DF "32") (V8DF "64")
1054                              (V4SF "16") (V8SF "32") (V16SF "64")])
1056 ;; Double word integer modes as mode attribute.
1057 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1058 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1060 ;; LEA mode corresponding to an integer mode
1061 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1063 ;; Half mode for double word integer modes.
1064 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1065                             (DI "TARGET_64BIT")])
1067 ;; Bound modes.
1068 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1069                            (BND64 "TARGET_LP64")])
1071 ;; Instruction suffix for integer modes.
1072 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1074 ;; Instruction suffix for masks.
1075 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1077 ;; Pointer size prefix for integer modes (Intel asm dialect)
1078 (define_mode_attr iptrsize [(QI "BYTE")
1079                             (HI "WORD")
1080                             (SI "DWORD")
1081                             (DI "QWORD")])
1083 ;; Register class for integer modes.
1084 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1086 ;; Immediate operand constraint for integer modes.
1087 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1089 ;; General operand constraint for word modes.
1090 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1092 ;; Immediate operand constraint for double integer modes.
1093 (define_mode_attr di [(SI "nF") (DI "Wd")])
1095 ;; Immediate operand constraint for shifts.
1096 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1098 ;; Print register name in the specified mode.
1099 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1101 ;; General operand predicate for integer modes.
1102 (define_mode_attr general_operand
1103         [(QI "general_operand")
1104          (HI "general_operand")
1105          (SI "x86_64_general_operand")
1106          (DI "x86_64_general_operand")
1107          (TI "x86_64_general_operand")])
1109 ;; General operand predicate for integer modes, where for TImode
1110 ;; we need both words of the operand to be general operands.
1111 (define_mode_attr general_hilo_operand
1112         [(QI "general_operand")
1113          (HI "general_operand")
1114          (SI "x86_64_general_operand")
1115          (DI "x86_64_general_operand")
1116          (TI "x86_64_hilo_general_operand")])
1118 ;; General sign extend operand predicate for integer modes,
1119 ;; which disallows VOIDmode operands and thus it is suitable
1120 ;; for use inside sign_extend.
1121 (define_mode_attr general_sext_operand
1122         [(QI "sext_operand")
1123          (HI "sext_operand")
1124          (SI "x86_64_sext_operand")
1125          (DI "x86_64_sext_operand")])
1127 ;; General sign/zero extend operand predicate for integer modes.
1128 (define_mode_attr general_szext_operand
1129         [(QI "general_operand")
1130          (HI "general_operand")
1131          (SI "x86_64_szext_general_operand")
1132          (DI "x86_64_szext_general_operand")])
1134 ;; Immediate operand predicate for integer modes.
1135 (define_mode_attr immediate_operand
1136         [(QI "immediate_operand")
1137          (HI "immediate_operand")
1138          (SI "x86_64_immediate_operand")
1139          (DI "x86_64_immediate_operand")])
1141 ;; Nonmemory operand predicate for integer modes.
1142 (define_mode_attr nonmemory_operand
1143         [(QI "nonmemory_operand")
1144          (HI "nonmemory_operand")
1145          (SI "x86_64_nonmemory_operand")
1146          (DI "x86_64_nonmemory_operand")])
1148 ;; Operand predicate for shifts.
1149 (define_mode_attr shift_operand
1150         [(QI "nonimmediate_operand")
1151          (HI "nonimmediate_operand")
1152          (SI "nonimmediate_operand")
1153          (DI "shiftdi_operand")
1154          (TI "register_operand")])
1156 ;; Operand predicate for shift argument.
1157 (define_mode_attr shift_immediate_operand
1158         [(QI "const_1_to_31_operand")
1159          (HI "const_1_to_31_operand")
1160          (SI "const_1_to_31_operand")
1161          (DI "const_1_to_63_operand")])
1163 ;; Input operand predicate for arithmetic left shifts.
1164 (define_mode_attr ashl_input_operand
1165         [(QI "nonimmediate_operand")
1166          (HI "nonimmediate_operand")
1167          (SI "nonimmediate_operand")
1168          (DI "ashldi_input_operand")
1169          (TI "reg_or_pm1_operand")])
1171 ;; SSE and x87 SFmode and DFmode floating point modes
1172 (define_mode_iterator MODEF [SF DF])
1174 ;; All x87 floating point modes
1175 (define_mode_iterator X87MODEF [SF DF XF])
1177 ;; SSE instruction suffix for various modes
1178 (define_mode_attr ssemodesuffix
1179   [(SF "ss") (DF "sd")
1180    (V16SF "ps") (V8DF "pd")
1181    (V8SF "ps") (V4DF "pd")
1182    (V4SF "ps") (V2DF "pd")
1183    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1184    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1185    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1187 ;; SSE vector suffix for floating point modes
1188 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1190 ;; SSE vector mode corresponding to a scalar mode
1191 (define_mode_attr ssevecmode
1192   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1193 (define_mode_attr ssevecmodelower
1194   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1196 ;; AVX512F vector mode corresponding to a scalar mode
1197 (define_mode_attr avx512fvecmode
1198   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1200 ;; Instruction suffix for REX 64bit operators.
1201 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1202 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1204 ;; This mode iterator allows :P to be used for patterns that operate on
1205 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1206 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1208 ;; This mode iterator allows :W to be used for patterns that operate on
1209 ;; word_mode sized quantities.
1210 (define_mode_iterator W
1211   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1213 ;; This mode iterator allows :PTR to be used for patterns that operate on
1214 ;; ptr_mode sized quantities.
1215 (define_mode_iterator PTR
1216   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1218 ;; Scheduling descriptions
1220 (include "pentium.md")
1221 (include "ppro.md")
1222 (include "k6.md")
1223 (include "athlon.md")
1224 (include "bdver1.md")
1225 (include "bdver3.md")
1226 (include "btver2.md")
1227 (include "znver1.md")
1228 (include "geode.md")
1229 (include "atom.md")
1230 (include "slm.md")
1231 (include "glm.md")
1232 (include "core2.md")
1233 (include "haswell.md")
1236 ;; Operand and operator predicates and constraints
1238 (include "predicates.md")
1239 (include "constraints.md")
1242 ;; Compare and branch/compare and store instructions.
1244 (define_expand "cbranch<mode>4"
1245   [(set (reg:CC FLAGS_REG)
1246         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1247                     (match_operand:SDWIM 2 "<general_operand>")))
1248    (set (pc) (if_then_else
1249                (match_operator 0 "ordered_comparison_operator"
1250                 [(reg:CC FLAGS_REG) (const_int 0)])
1251                (label_ref (match_operand 3))
1252                (pc)))]
1253   ""
1255   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1256     operands[1] = force_reg (<MODE>mode, operands[1]);
1257   ix86_expand_branch (GET_CODE (operands[0]),
1258                       operands[1], operands[2], operands[3]);
1259   DONE;
1262 (define_expand "cstore<mode>4"
1263   [(set (reg:CC FLAGS_REG)
1264         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1265                     (match_operand:SWIM 3 "<general_operand>")))
1266    (set (match_operand:QI 0 "register_operand")
1267         (match_operator 1 "ordered_comparison_operator"
1268           [(reg:CC FLAGS_REG) (const_int 0)]))]
1269   ""
1271   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1272     operands[2] = force_reg (<MODE>mode, operands[2]);
1273   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1274                      operands[2], operands[3]);
1275   DONE;
1278 (define_expand "cmp<mode>_1"
1279   [(set (reg:CC FLAGS_REG)
1280         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1281                     (match_operand:SWI48 1 "<general_operand>")))])
1283 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1284   [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1285    (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1287 (define_insn "*cmp<mode>_ccz_1"
1288   [(set (reg FLAGS_REG)
1289         (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1290                         "nonimmediate_operand" "<r>,?m<r>,$k")
1291                  (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1292   "ix86_match_ccmode (insn, CCZmode)"
1293   "@
1294    test{<imodesuffix>}\t%0, %0
1295    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1296    ktest<mskmodesuffix>\t%0, %0"
1297   [(set_attr "type" "test,icmp,msklog")
1298    (set_attr "length_immediate" "0,1,*")
1299    (set_attr "modrm_class" "op0,unknown,*")
1300    (set_attr "prefix" "*,*,vex")
1301    (set_attr "mode" "<MODE>")])
1303 (define_insn "*cmp<mode>_ccno_1"
1304   [(set (reg FLAGS_REG)
1305         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1306                  (match_operand:SWI 1 "const0_operand")))]
1307   "ix86_match_ccmode (insn, CCNOmode)"
1308   "@
1309    test{<imodesuffix>}\t%0, %0
1310    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1311   [(set_attr "type" "test,icmp")
1312    (set_attr "length_immediate" "0,1")
1313    (set_attr "modrm_class" "op0,unknown")
1314    (set_attr "mode" "<MODE>")])
1316 (define_insn "*cmp<mode>_1"
1317   [(set (reg FLAGS_REG)
1318         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1319                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1320   "ix86_match_ccmode (insn, CCmode)"
1321   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1322   [(set_attr "type" "icmp")
1323    (set_attr "mode" "<MODE>")])
1325 (define_insn "*cmp<mode>_minus_1"
1326   [(set (reg FLAGS_REG)
1327         (compare
1328           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1329                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1330           (const_int 0)))]
1331   "ix86_match_ccmode (insn, CCGOCmode)"
1332   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1333   [(set_attr "type" "icmp")
1334    (set_attr "mode" "<MODE>")])
1336 (define_insn "*cmpqi_ext_1"
1337   [(set (reg FLAGS_REG)
1338         (compare
1339           (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1340           (subreg:QI
1341             (zero_extract:SI
1342               (match_operand 1 "ext_register_operand" "Q,Q")
1343               (const_int 8)
1344               (const_int 8)) 0)))]
1345   "ix86_match_ccmode (insn, CCmode)"
1346   "cmp{b}\t{%h1, %0|%0, %h1}"
1347   [(set_attr "isa" "*,nox64")
1348    (set_attr "type" "icmp")
1349    (set_attr "mode" "QI")])
1351 (define_insn "*cmpqi_ext_2"
1352   [(set (reg FLAGS_REG)
1353         (compare
1354           (subreg:QI
1355             (zero_extract:SI
1356               (match_operand 0 "ext_register_operand" "Q")
1357               (const_int 8)
1358               (const_int 8)) 0)
1359           (match_operand:QI 1 "const0_operand")))]
1360   "ix86_match_ccmode (insn, CCNOmode)"
1361   "test{b}\t%h0, %h0"
1362   [(set_attr "type" "test")
1363    (set_attr "length_immediate" "0")
1364    (set_attr "mode" "QI")])
1366 (define_expand "cmpqi_ext_3"
1367   [(set (reg:CC FLAGS_REG)
1368         (compare:CC
1369           (subreg:QI
1370             (zero_extract:SI
1371               (match_operand 0 "ext_register_operand")
1372               (const_int 8)
1373               (const_int 8)) 0)
1374           (match_operand:QI 1 "const_int_operand")))])
1376 (define_insn "*cmpqi_ext_3"
1377   [(set (reg FLAGS_REG)
1378         (compare
1379           (subreg:QI
1380             (zero_extract:SI
1381               (match_operand 0 "ext_register_operand" "Q,Q")
1382               (const_int 8)
1383               (const_int 8)) 0)
1384           (match_operand:QI 1 "general_operand" "QnBc,m")))]
1385   "ix86_match_ccmode (insn, CCmode)"
1386   "cmp{b}\t{%1, %h0|%h0, %1}"
1387   [(set_attr "isa" "*,nox64")
1388    (set_attr "type" "icmp")
1389    (set_attr "mode" "QI")])
1391 (define_insn "*cmpqi_ext_4"
1392   [(set (reg FLAGS_REG)
1393         (compare
1394           (subreg:QI
1395             (zero_extract:SI
1396               (match_operand 0 "ext_register_operand" "Q")
1397               (const_int 8)
1398               (const_int 8)) 0)
1399           (subreg:QI
1400             (zero_extract:SI
1401               (match_operand 1 "ext_register_operand" "Q")
1402               (const_int 8)
1403               (const_int 8)) 0)))]
1404   "ix86_match_ccmode (insn, CCmode)"
1405   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1406   [(set_attr "type" "icmp")
1407    (set_attr "mode" "QI")])
1409 ;; These implement float point compares.
1410 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1411 ;; which would allow mix and match FP modes on the compares.  Which is what
1412 ;; the old patterns did, but with many more of them.
1414 (define_expand "cbranchxf4"
1415   [(set (reg:CC FLAGS_REG)
1416         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1417                     (match_operand:XF 2 "nonmemory_operand")))
1418    (set (pc) (if_then_else
1419               (match_operator 0 "ix86_fp_comparison_operator"
1420                [(reg:CC FLAGS_REG)
1421                 (const_int 0)])
1422               (label_ref (match_operand 3))
1423               (pc)))]
1424   "TARGET_80387"
1426   ix86_expand_branch (GET_CODE (operands[0]),
1427                       operands[1], operands[2], operands[3]);
1428   DONE;
1431 (define_expand "cstorexf4"
1432   [(set (reg:CC FLAGS_REG)
1433         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1434                     (match_operand:XF 3 "nonmemory_operand")))
1435    (set (match_operand:QI 0 "register_operand")
1436               (match_operator 1 "ix86_fp_comparison_operator"
1437                [(reg:CC FLAGS_REG)
1438                 (const_int 0)]))]
1439   "TARGET_80387"
1441   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1442                      operands[2], operands[3]);
1443   DONE;
1446 (define_expand "cbranch<mode>4"
1447   [(set (reg:CC FLAGS_REG)
1448         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1449                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1450    (set (pc) (if_then_else
1451               (match_operator 0 "ix86_fp_comparison_operator"
1452                [(reg:CC FLAGS_REG)
1453                 (const_int 0)])
1454               (label_ref (match_operand 3))
1455               (pc)))]
1456   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1458   ix86_expand_branch (GET_CODE (operands[0]),
1459                       operands[1], operands[2], operands[3]);
1460   DONE;
1463 (define_expand "cstore<mode>4"
1464   [(set (reg:CC FLAGS_REG)
1465         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1466                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1467    (set (match_operand:QI 0 "register_operand")
1468               (match_operator 1 "ix86_fp_comparison_operator"
1469                [(reg:CC FLAGS_REG)
1470                 (const_int 0)]))]
1471   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1473   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1474                      operands[2], operands[3]);
1475   DONE;
1478 (define_expand "cbranchcc4"
1479   [(set (pc) (if_then_else
1480               (match_operator 0 "comparison_operator"
1481                [(match_operand 1 "flags_reg_operand")
1482                 (match_operand 2 "const0_operand")])
1483               (label_ref (match_operand 3))
1484               (pc)))]
1485   ""
1487   ix86_expand_branch (GET_CODE (operands[0]),
1488                       operands[1], operands[2], operands[3]);
1489   DONE;
1492 (define_expand "cstorecc4"
1493   [(set (match_operand:QI 0 "register_operand")
1494               (match_operator 1 "comparison_operator"
1495                [(match_operand 2 "flags_reg_operand")
1496                 (match_operand 3 "const0_operand")]))]
1497   ""
1499   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1500                      operands[2], operands[3]);
1501   DONE;
1505 ;; FP compares, step 1:
1506 ;; Set the FP condition codes.
1508 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1509 ;; used to manage the reg stack popping would not be preserved.
1511 (define_insn "*cmp<mode>_0_i387"
1512   [(set (match_operand:HI 0 "register_operand" "=a")
1513         (unspec:HI
1514           [(compare:CCFP
1515              (match_operand:X87MODEF 1 "register_operand" "f")
1516              (match_operand:X87MODEF 2 "const0_operand"))]
1517         UNSPEC_FNSTSW))]
1518   "TARGET_80387"
1519   "* return output_fp_compare (insn, operands, false, false);"
1520   [(set_attr "type" "multi")
1521    (set_attr "unit" "i387")
1522    (set_attr "mode" "<MODE>")])
1524 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1525   [(set (reg:CCFP FLAGS_REG)
1526         (compare:CCFP
1527           (match_operand:X87MODEF 1 "register_operand" "f")
1528           (match_operand:X87MODEF 2 "const0_operand")))
1529    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1530   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1531   "#"
1532   "&& reload_completed"
1533   [(set (match_dup 0)
1534         (unspec:HI
1535           [(compare:CCFP (match_dup 1)(match_dup 2))]
1536         UNSPEC_FNSTSW))
1537    (set (reg:CC FLAGS_REG)
1538         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1539   ""
1540   [(set_attr "type" "multi")
1541    (set_attr "unit" "i387")
1542    (set_attr "mode" "<MODE>")])
1544 (define_insn "*cmpxf_i387"
1545   [(set (match_operand:HI 0 "register_operand" "=a")
1546         (unspec:HI
1547           [(compare:CCFP
1548              (match_operand:XF 1 "register_operand" "f")
1549              (match_operand:XF 2 "register_operand" "f"))]
1550           UNSPEC_FNSTSW))]
1551   "TARGET_80387"
1552   "* return output_fp_compare (insn, operands, false, false);"
1553   [(set_attr "type" "multi")
1554    (set_attr "unit" "i387")
1555    (set_attr "mode" "XF")])
1557 (define_insn_and_split "*cmpxf_cc_i387"
1558   [(set (reg:CCFP FLAGS_REG)
1559         (compare:CCFP
1560           (match_operand:XF 1 "register_operand" "f")
1561           (match_operand:XF 2 "register_operand" "f")))
1562    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1563   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1564   "#"
1565   "&& reload_completed"
1566   [(set (match_dup 0)
1567         (unspec:HI
1568           [(compare:CCFP (match_dup 1)(match_dup 2))]
1569         UNSPEC_FNSTSW))
1570    (set (reg:CC FLAGS_REG)
1571         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1572   ""
1573   [(set_attr "type" "multi")
1574    (set_attr "unit" "i387")
1575    (set_attr "mode" "XF")])
1577 (define_insn "*cmp<mode>_i387"
1578   [(set (match_operand:HI 0 "register_operand" "=a")
1579         (unspec:HI
1580           [(compare:CCFP
1581              (match_operand:MODEF 1 "register_operand" "f")
1582              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1583           UNSPEC_FNSTSW))]
1584   "TARGET_80387"
1585   "* return output_fp_compare (insn, operands, false, false);"
1586   [(set_attr "type" "multi")
1587    (set_attr "unit" "i387")
1588    (set_attr "mode" "<MODE>")])
1590 (define_insn_and_split "*cmp<mode>_cc_i387"
1591   [(set (reg:CCFP FLAGS_REG)
1592         (compare:CCFP
1593           (match_operand:MODEF 1 "register_operand" "f")
1594           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1595    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1596   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1597   "#"
1598   "&& reload_completed"
1599   [(set (match_dup 0)
1600         (unspec:HI
1601           [(compare:CCFP (match_dup 1)(match_dup 2))]
1602         UNSPEC_FNSTSW))
1603    (set (reg:CC FLAGS_REG)
1604         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1605   ""
1606   [(set_attr "type" "multi")
1607    (set_attr "unit" "i387")
1608    (set_attr "mode" "<MODE>")])
1610 (define_insn "*cmpu<mode>_i387"
1611   [(set (match_operand:HI 0 "register_operand" "=a")
1612         (unspec:HI
1613           [(unspec:CCFP
1614              [(compare:CCFP
1615                 (match_operand:X87MODEF 1 "register_operand" "f")
1616                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1617              UNSPEC_NOTRAP)]
1618           UNSPEC_FNSTSW))]
1619   "TARGET_80387"
1620   "* return output_fp_compare (insn, operands, false, true);"
1621   [(set_attr "type" "multi")
1622    (set_attr "unit" "i387")
1623    (set_attr "mode" "<MODE>")])
1625 (define_insn_and_split "*cmpu<mode>_cc_i387"
1626   [(set (reg:CCFP FLAGS_REG)
1627         (unspec:CCFP
1628           [(compare:CCFP
1629              (match_operand:X87MODEF 1 "register_operand" "f")
1630              (match_operand:X87MODEF 2 "register_operand" "f"))]
1631           UNSPEC_NOTRAP))
1632    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1633   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1634   "#"
1635   "&& reload_completed"
1636   [(set (match_dup 0)
1637         (unspec:HI
1638           [(unspec:CCFP
1639              [(compare:CCFP (match_dup 1)(match_dup 2))]
1640              UNSPEC_NOTRAP)]
1641           UNSPEC_FNSTSW))
1642    (set (reg:CC FLAGS_REG)
1643         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1644   ""
1645   [(set_attr "type" "multi")
1646    (set_attr "unit" "i387")
1647    (set_attr "mode" "<MODE>")])
1649 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1650   [(set (match_operand:HI 0 "register_operand" "=a")
1651         (unspec:HI
1652           [(compare:CCFP
1653              (match_operand:X87MODEF 1 "register_operand" "f")
1654              (float:X87MODEF
1655                (match_operand:SWI24 2 "memory_operand" "m")))]
1656           UNSPEC_FNSTSW))]
1657   "TARGET_80387
1658    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1659        || optimize_function_for_size_p (cfun))"
1660   "* return output_fp_compare (insn, operands, false, false);"
1661   [(set_attr "type" "multi")
1662    (set_attr "unit" "i387")
1663    (set_attr "fp_int_src" "true")
1664    (set_attr "mode" "<SWI24:MODE>")])
1666 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1667   [(set (reg:CCFP FLAGS_REG)
1668         (compare:CCFP
1669           (match_operand:X87MODEF 1 "register_operand" "f")
1670           (float:X87MODEF
1671             (match_operand:SWI24 2 "memory_operand" "m"))))
1672    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1673   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1674    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1675        || optimize_function_for_size_p (cfun))"
1676   "#"
1677   "&& reload_completed"
1678   [(set (match_dup 0)
1679         (unspec:HI
1680           [(compare:CCFP
1681              (match_dup 1)
1682              (float:X87MODEF (match_dup 2)))]
1683         UNSPEC_FNSTSW))
1684    (set (reg:CC FLAGS_REG)
1685         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1686   ""
1687   [(set_attr "type" "multi")
1688    (set_attr "unit" "i387")
1689    (set_attr "fp_int_src" "true")
1690    (set_attr "mode" "<SWI24:MODE>")])
1692 ;; FP compares, step 2
1693 ;; Move the fpsw to ax.
1695 (define_insn "x86_fnstsw_1"
1696   [(set (match_operand:HI 0 "register_operand" "=a")
1697         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1698   "TARGET_80387"
1699   "fnstsw\t%0"
1700   [(set_attr "length" "2")
1701    (set_attr "mode" "SI")
1702    (set_attr "unit" "i387")])
1704 ;; FP compares, step 3
1705 ;; Get ax into flags, general case.
1707 (define_insn "x86_sahf_1"
1708   [(set (reg:CC FLAGS_REG)
1709         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1710                    UNSPEC_SAHF))]
1711   "TARGET_SAHF"
1713 #ifndef HAVE_AS_IX86_SAHF
1714   if (TARGET_64BIT)
1715     return ASM_BYTE "0x9e";
1716   else
1717 #endif
1718   return "sahf";
1720   [(set_attr "length" "1")
1721    (set_attr "athlon_decode" "vector")
1722    (set_attr "amdfam10_decode" "direct")
1723    (set_attr "bdver1_decode" "direct")
1724    (set_attr "mode" "SI")])
1726 ;; Pentium Pro can do steps 1 through 3 in one go.
1727 ;; (these instructions set flags directly)
1729 (define_subst_attr "unord" "unord_subst" "" "u")
1730 (define_subst_attr "unordered" "unord_subst" "false" "true")
1732 (define_subst "unord_subst"
1733   [(set (match_operand:CCFP 0)
1734         (match_operand:CCFP 1))]
1735   ""
1736   [(set (match_dup 0)
1737         (unspec:CCFP
1738           [(match_dup 1)]
1739           UNSPEC_NOTRAP))])
1741 (define_insn "*cmpi<unord><MODEF:mode>"
1742   [(set (reg:CCFP FLAGS_REG)
1743         (compare:CCFP
1744           (match_operand:MODEF 0 "register_operand" "f,v")
1745           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1746   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1747    || (TARGET_80387 && TARGET_CMOVE)"
1748   "@
1749    * return output_fp_compare (insn, operands, true, <unordered>);
1750    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1751   [(set_attr "type" "fcmp,ssecomi")
1752    (set_attr "prefix" "orig,maybe_vex")
1753    (set_attr "mode" "<MODEF:MODE>")
1754    (set_attr "prefix_rep" "*,0")
1755    (set (attr "prefix_data16")
1756         (cond [(eq_attr "alternative" "0")
1757                  (const_string "*")
1758                (eq_attr "mode" "DF")
1759                  (const_string "1")
1760               ]
1761               (const_string "0")))
1762    (set_attr "athlon_decode" "vector")
1763    (set_attr "amdfam10_decode" "direct")
1764    (set_attr "bdver1_decode" "double")
1765    (set_attr "znver1_decode" "double")
1766    (set (attr "enabled")
1767      (if_then_else
1768        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1769        (if_then_else
1770          (eq_attr "alternative" "0")
1771          (symbol_ref "TARGET_MIX_SSE_I387")
1772          (symbol_ref "true"))
1773        (if_then_else
1774          (eq_attr "alternative" "0")
1775          (symbol_ref "true")
1776          (symbol_ref "false"))))])
1778 (define_insn "*cmpi<unord>xf_i387"
1779   [(set (reg:CCFP FLAGS_REG)
1780         (compare:CCFP
1781           (match_operand:XF 0 "register_operand" "f")
1782           (match_operand:XF 1 "register_operand" "f")))]
1783   "TARGET_80387 && TARGET_CMOVE"
1784   "* return output_fp_compare (insn, operands, true, <unordered>);"
1785   [(set_attr "type" "fcmp")
1786    (set_attr "mode" "XF")
1787    (set_attr "athlon_decode" "vector")
1788    (set_attr "amdfam10_decode" "direct")
1789    (set_attr "bdver1_decode" "double")
1790    (set_attr "znver1_decode" "double")])
1792 ;; Push/pop instructions.
1794 (define_insn "*push<mode>2"
1795   [(set (match_operand:DWI 0 "push_operand" "=<")
1796         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1797   ""
1798   "#"
1799   [(set_attr "type" "multi")
1800    (set_attr "mode" "<MODE>")])
1802 (define_split
1803   [(set (match_operand:DWI 0 "push_operand")
1804         (match_operand:DWI 1 "general_gr_operand"))]
1805   "reload_completed"
1806   [(const_int 0)]
1807   "ix86_split_long_move (operands); DONE;")
1809 (define_insn "*pushdi2_rex64"
1810   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1811         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1812   "TARGET_64BIT"
1813   "@
1814    push{q}\t%1
1815    #"
1816   [(set_attr "type" "push,multi")
1817    (set_attr "mode" "DI")])
1819 ;; Convert impossible pushes of immediate to existing instructions.
1820 ;; First try to get scratch register and go through it.  In case this
1821 ;; fails, push sign extended lower part first and then overwrite
1822 ;; upper part by 32bit move.
1823 (define_peephole2
1824   [(match_scratch:DI 2 "r")
1825    (set (match_operand:DI 0 "push_operand")
1826         (match_operand:DI 1 "immediate_operand"))]
1827   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1828    && !x86_64_immediate_operand (operands[1], DImode)"
1829   [(set (match_dup 2) (match_dup 1))
1830    (set (match_dup 0) (match_dup 2))])
1832 ;; We need to define this as both peepholer and splitter for case
1833 ;; peephole2 pass is not run.
1834 ;; "&& 1" is needed to keep it from matching the previous pattern.
1835 (define_peephole2
1836   [(set (match_operand:DI 0 "push_operand")
1837         (match_operand:DI 1 "immediate_operand"))]
1838   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1839    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1840   [(set (match_dup 0) (match_dup 1))
1841    (set (match_dup 2) (match_dup 3))]
1843   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1845   operands[1] = gen_lowpart (DImode, operands[2]);
1846   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1847                                                    GEN_INT (4)));
1850 (define_split
1851   [(set (match_operand:DI 0 "push_operand")
1852         (match_operand:DI 1 "immediate_operand"))]
1853   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1854                     ? epilogue_completed : reload_completed)
1855    && !symbolic_operand (operands[1], DImode)
1856    && !x86_64_immediate_operand (operands[1], DImode)"
1857   [(set (match_dup 0) (match_dup 1))
1858    (set (match_dup 2) (match_dup 3))]
1860   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1862   operands[1] = gen_lowpart (DImode, operands[2]);
1863   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1864                                                    GEN_INT (4)));
1867 (define_insn "*pushsi2"
1868   [(set (match_operand:SI 0 "push_operand" "=<")
1869         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1870   "!TARGET_64BIT"
1871   "push{l}\t%1"
1872   [(set_attr "type" "push")
1873    (set_attr "mode" "SI")])
1875 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1876 ;; "push a byte/word".  But actually we use pushl, which has the effect
1877 ;; of rounding the amount pushed up to a word.
1879 ;; For TARGET_64BIT we always round up to 8 bytes.
1880 (define_insn "*push<mode>2_rex64"
1881   [(set (match_operand:SWI124 0 "push_operand" "=X")
1882         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1883   "TARGET_64BIT"
1884   "push{q}\t%q1"
1885   [(set_attr "type" "push")
1886    (set_attr "mode" "DI")])
1888 (define_insn "*push<mode>2"
1889   [(set (match_operand:SWI12 0 "push_operand" "=X")
1890         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1891   "!TARGET_64BIT"
1892   "push{l}\t%k1"
1893   [(set_attr "type" "push")
1894    (set_attr "mode" "SI")])
1896 (define_insn "*push<mode>2_prologue"
1897   [(set (match_operand:W 0 "push_operand" "=<")
1898         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1899    (clobber (mem:BLK (scratch)))]
1900   ""
1901   "push{<imodesuffix>}\t%1"
1902   [(set_attr "type" "push")
1903    (set_attr "mode" "<MODE>")])
1905 (define_insn "*pop<mode>1"
1906   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1907         (match_operand:W 1 "pop_operand" ">"))]
1908   ""
1909   "pop{<imodesuffix>}\t%0"
1910   [(set_attr "type" "pop")
1911    (set_attr "mode" "<MODE>")])
1913 (define_insn "*pop<mode>1_epilogue"
1914   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1915         (match_operand:W 1 "pop_operand" ">"))
1916    (clobber (mem:BLK (scratch)))]
1917   ""
1918   "pop{<imodesuffix>}\t%0"
1919   [(set_attr "type" "pop")
1920    (set_attr "mode" "<MODE>")])
1922 (define_insn "*pushfl<mode>2"
1923   [(set (match_operand:W 0 "push_operand" "=<")
1924         (match_operand:W 1 "flags_reg_operand"))]
1925   ""
1926   "pushf{<imodesuffix>}"
1927   [(set_attr "type" "push")
1928    (set_attr "mode" "<MODE>")])
1930 (define_insn "*popfl<mode>1"
1931   [(set (match_operand:W 0 "flags_reg_operand")
1932         (match_operand:W 1 "pop_operand" ">"))]
1933   ""
1934   "popf{<imodesuffix>}"
1935   [(set_attr "type" "pop")
1936    (set_attr "mode" "<MODE>")])
1939 ;; Reload patterns to support multi-word load/store
1940 ;; with non-offsetable address.
1941 (define_expand "reload_noff_store"
1942   [(parallel [(match_operand 0 "memory_operand" "=m")
1943               (match_operand 1 "register_operand" "r")
1944               (match_operand:DI 2 "register_operand" "=&r")])]
1945   "TARGET_64BIT"
1947   rtx mem = operands[0];
1948   rtx addr = XEXP (mem, 0);
1950   emit_move_insn (operands[2], addr);
1951   mem = replace_equiv_address_nv (mem, operands[2]);
1953   emit_insn (gen_rtx_SET (mem, operands[1]));
1954   DONE;
1957 (define_expand "reload_noff_load"
1958   [(parallel [(match_operand 0 "register_operand" "=r")
1959               (match_operand 1 "memory_operand" "m")
1960               (match_operand:DI 2 "register_operand" "=r")])]
1961   "TARGET_64BIT"
1963   rtx mem = operands[1];
1964   rtx addr = XEXP (mem, 0);
1966   emit_move_insn (operands[2], addr);
1967   mem = replace_equiv_address_nv (mem, operands[2]);
1969   emit_insn (gen_rtx_SET (operands[0], mem));
1970   DONE;
1973 ;; Move instructions.
1975 (define_expand "movxi"
1976   [(set (match_operand:XI 0 "nonimmediate_operand")
1977         (match_operand:XI 1 "general_operand"))]
1978   "TARGET_AVX512F"
1979   "ix86_expand_vector_move (XImode, operands); DONE;")
1981 (define_expand "movoi"
1982   [(set (match_operand:OI 0 "nonimmediate_operand")
1983         (match_operand:OI 1 "general_operand"))]
1984   "TARGET_AVX"
1985   "ix86_expand_vector_move (OImode, operands); DONE;")
1987 (define_expand "movti"
1988   [(set (match_operand:TI 0 "nonimmediate_operand")
1989         (match_operand:TI 1 "general_operand"))]
1990   "TARGET_64BIT || TARGET_SSE"
1992   if (TARGET_64BIT)
1993     ix86_expand_move (TImode, operands);
1994   else
1995     ix86_expand_vector_move (TImode, operands);
1996   DONE;
1999 ;; This expands to what emit_move_complex would generate if we didn't
2000 ;; have a movti pattern.  Having this avoids problems with reload on
2001 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2002 ;; to have around all the time.
2003 (define_expand "movcdi"
2004   [(set (match_operand:CDI 0 "nonimmediate_operand")
2005         (match_operand:CDI 1 "general_operand"))]
2006   ""
2008   if (push_operand (operands[0], CDImode))
2009     emit_move_complex_push (CDImode, operands[0], operands[1]);
2010   else
2011     emit_move_complex_parts (operands[0], operands[1]);
2012   DONE;
2015 (define_expand "mov<mode>"
2016   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2017         (match_operand:SWI1248x 1 "general_operand"))]
2018   ""
2019   "ix86_expand_move (<MODE>mode, operands); DONE;")
2021 (define_insn "*mov<mode>_xor"
2022   [(set (match_operand:SWI48 0 "register_operand" "=r")
2023         (match_operand:SWI48 1 "const0_operand"))
2024    (clobber (reg:CC FLAGS_REG))]
2025   "reload_completed"
2026   "xor{l}\t%k0, %k0"
2027   [(set_attr "type" "alu1")
2028    (set_attr "modrm_class" "op0")
2029    (set_attr "mode" "SI")
2030    (set_attr "length_immediate" "0")])
2032 (define_insn "*mov<mode>_or"
2033   [(set (match_operand:SWI48 0 "register_operand" "=r")
2034         (match_operand:SWI48 1 "constm1_operand"))
2035    (clobber (reg:CC FLAGS_REG))]
2036   "reload_completed"
2037   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2038   [(set_attr "type" "alu1")
2039    (set_attr "mode" "<MODE>")
2040    (set_attr "length_immediate" "1")])
2042 (define_insn "*movxi_internal_avx512f"
2043   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2044         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2045   "TARGET_AVX512F
2046    && (register_operand (operands[0], XImode)
2047        || register_operand (operands[1], XImode))"
2049   switch (get_attr_type (insn))
2050     {
2051     case TYPE_SSELOG1:
2052       return standard_sse_constant_opcode (insn, operands);
2054     case TYPE_SSEMOV:
2055       if (misaligned_operand (operands[0], XImode)
2056           || misaligned_operand (operands[1], XImode))
2057         return "vmovdqu32\t{%1, %0|%0, %1}";
2058       else
2059         return "vmovdqa32\t{%1, %0|%0, %1}";
2061     default:
2062       gcc_unreachable ();
2063     }
2065   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2066    (set_attr "prefix" "evex")
2067    (set_attr "mode" "XI")])
2069 (define_insn "*movoi_internal_avx"
2070   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2071         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2072   "TARGET_AVX
2073    && (register_operand (operands[0], OImode)
2074        || register_operand (operands[1], OImode))"
2076   switch (get_attr_type (insn))
2077     {
2078     case TYPE_SSELOG1:
2079       return standard_sse_constant_opcode (insn, operands);
2081     case TYPE_SSEMOV:
2082       if (misaligned_operand (operands[0], OImode)
2083           || misaligned_operand (operands[1], OImode))
2084         {
2085           if (get_attr_mode (insn) == MODE_V8SF)
2086             return "vmovups\t{%1, %0|%0, %1}";
2087           else if (get_attr_mode (insn) == MODE_XI)
2088             return "vmovdqu32\t{%1, %0|%0, %1}";
2089           else
2090             return "vmovdqu\t{%1, %0|%0, %1}";
2091         }
2092       else
2093         {
2094           if (get_attr_mode (insn) == MODE_V8SF)
2095             return "vmovaps\t{%1, %0|%0, %1}";
2096           else if (get_attr_mode (insn) == MODE_XI)
2097             return "vmovdqa32\t{%1, %0|%0, %1}";
2098           else
2099             return "vmovdqa\t{%1, %0|%0, %1}";
2100         }
2102     default:
2103       gcc_unreachable ();
2104     }
2106   [(set_attr "isa" "*,avx2,*,*")
2107    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2108    (set_attr "prefix" "vex")
2109    (set (attr "mode")
2110         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2111                     (match_operand 1 "ext_sse_reg_operand"))
2112                  (const_string "XI")
2113                (and (eq_attr "alternative" "1")
2114                     (match_test "TARGET_AVX512VL"))
2115                  (const_string "XI")
2116                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2117                     (and (eq_attr "alternative" "3")
2118                          (match_test "TARGET_SSE_TYPELESS_STORES")))
2119                  (const_string "V8SF")
2120               ]
2121               (const_string "OI")))])
2123 (define_insn "*movti_internal"
2124   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2125         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Yd,r"))]
2126   "(TARGET_64BIT
2127     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2128    || (TARGET_SSE
2129        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2130        && (register_operand (operands[0], TImode)
2131            || register_operand (operands[1], TImode)))"
2133   switch (get_attr_type (insn))
2134     {
2135     case TYPE_MULTI:
2136       return "#";
2138     case TYPE_SSELOG1:
2139       return standard_sse_constant_opcode (insn, operands);
2141     case TYPE_SSEMOV:
2142       /* TDmode values are passed as TImode on the stack.  Moving them
2143          to stack may result in unaligned memory access.  */
2144       if (misaligned_operand (operands[0], TImode)
2145           || misaligned_operand (operands[1], TImode))
2146         {
2147           if (get_attr_mode (insn) == MODE_V4SF)
2148             return "%vmovups\t{%1, %0|%0, %1}";
2149           else if (get_attr_mode (insn) == MODE_XI)
2150             return "vmovdqu32\t{%1, %0|%0, %1}";
2151           else
2152             return "%vmovdqu\t{%1, %0|%0, %1}";
2153         }
2154       else
2155         {
2156           if (get_attr_mode (insn) == MODE_V4SF)
2157             return "%vmovaps\t{%1, %0|%0, %1}";
2158           else if (get_attr_mode (insn) == MODE_XI)
2159             return "vmovdqa32\t{%1, %0|%0, %1}";
2160           else
2161             return "%vmovdqa\t{%1, %0|%0, %1}";
2162         }
2164     default:
2165       gcc_unreachable ();
2166     }
2168   [(set (attr "isa")
2169      (cond [(eq_attr "alternative" "0,1,6,7")
2170               (const_string "x64")
2171             (eq_attr "alternative" "3")
2172               (const_string "sse2")
2173            ]
2174            (const_string "*")))
2175    (set (attr "type")
2176      (cond [(eq_attr "alternative" "0,1,6,7")
2177               (const_string "multi")
2178             (eq_attr "alternative" "2,3")
2179               (const_string "sselog1")
2180            ]
2181            (const_string "ssemov")))
2182    (set (attr "prefix")
2183      (if_then_else (eq_attr "type" "sselog1,ssemov")
2184        (const_string "maybe_vex")
2185        (const_string "orig")))
2186    (set (attr "mode")
2187         (cond [(eq_attr "alternative" "0,1")
2188                  (const_string "DI")
2189                (ior (match_operand 0 "ext_sse_reg_operand")
2190                     (match_operand 1 "ext_sse_reg_operand"))
2191                  (const_string "XI")
2192                (and (eq_attr "alternative" "3")
2193                     (match_test "TARGET_AVX512VL"))
2194                  (const_string "XI")
2195                (ior (not (match_test "TARGET_SSE2"))
2196                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2197                          (and (eq_attr "alternative" "5")
2198                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2199                  (const_string "V4SF")
2200                (match_test "TARGET_AVX")
2201                  (const_string "TI")
2202                (match_test "optimize_function_for_size_p (cfun)")
2203                  (const_string "V4SF")
2204                ]
2205                (const_string "TI")))
2206    (set (attr "preferred_for_speed")
2207      (cond [(eq_attr "alternative" "6")
2208               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2209             (eq_attr "alternative" "7")
2210               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2211            ]
2212            (symbol_ref "true")))])
2214 (define_split
2215   [(set (match_operand:TI 0 "sse_reg_operand")
2216         (match_operand:TI 1 "general_reg_operand"))]
2217   "TARGET_64BIT && TARGET_SSE4_1
2218    && reload_completed"
2219   [(set (match_dup 2)
2220         (vec_merge:V2DI
2221           (vec_duplicate:V2DI (match_dup 3))
2222           (match_dup 2)
2223           (const_int 2)))]
2225   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2226   operands[3] = gen_highpart (DImode, operands[1]);
2228   emit_move_insn (gen_lowpart (DImode, operands[0]),
2229                   gen_lowpart (DImode, operands[1]));
2232 (define_insn "*movdi_internal"
2233   [(set (match_operand:DI 0 "nonimmediate_operand"
2234     "=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")
2235         (match_operand:DI 1 "general_operand"
2236     "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"))]
2237   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2239   switch (get_attr_type (insn))
2240     {
2241     case TYPE_MSKMOV:
2242       return "kmovq\t{%1, %0|%0, %1}";
2244     case TYPE_MULTI:
2245       return "#";
2247     case TYPE_MMX:
2248       return "pxor\t%0, %0";
2250     case TYPE_MMXMOV:
2251       /* Handle broken assemblers that require movd instead of movq.  */
2252       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2253           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2254         return "movd\t{%1, %0|%0, %1}";
2255       return "movq\t{%1, %0|%0, %1}";
2257     case TYPE_SSELOG1:
2258       return standard_sse_constant_opcode (insn, operands);
2260     case TYPE_SSEMOV:
2261       switch (get_attr_mode (insn))
2262         {
2263         case MODE_DI:
2264           /* Handle broken assemblers that require movd instead of movq.  */
2265           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2266               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2267             return "%vmovd\t{%1, %0|%0, %1}";
2268           return "%vmovq\t{%1, %0|%0, %1}";
2270         case MODE_TI:
2271           /* Handle AVX512 registers set.  */
2272           if (EXT_REX_SSE_REG_P (operands[0])
2273               || EXT_REX_SSE_REG_P (operands[1]))
2274             return "vmovdqa64\t{%1, %0|%0, %1}";
2275           return "%vmovdqa\t{%1, %0|%0, %1}";
2277         case MODE_V2SF:
2278           gcc_assert (!TARGET_AVX);
2279           return "movlps\t{%1, %0|%0, %1}";
2280         case MODE_V4SF:
2281           return "%vmovaps\t{%1, %0|%0, %1}";
2283         default:
2284           gcc_unreachable ();
2285         }
2287     case TYPE_SSECVT:
2288       if (SSE_REG_P (operands[0]))
2289         return "movq2dq\t{%1, %0|%0, %1}";
2290       else
2291         return "movdq2q\t{%1, %0|%0, %1}";
2293     case TYPE_LEA:
2294       return "lea{q}\t{%E1, %0|%0, %E1}";
2296     case TYPE_IMOV:
2297       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2298       if (get_attr_mode (insn) == MODE_SI)
2299         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2300       else if (which_alternative == 4)
2301         return "movabs{q}\t{%1, %0|%0, %1}";
2302       else if (ix86_use_lea_for_mov (insn, operands))
2303         return "lea{q}\t{%E1, %0|%0, %E1}";
2304       else
2305         return "mov{q}\t{%1, %0|%0, %1}";
2307     default:
2308       gcc_unreachable ();
2309     }
2311   [(set (attr "isa")
2312      (cond [(eq_attr "alternative" "0,1,17,18")
2313               (const_string "nox64")
2314             (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2315               (const_string "x64")
2316             (eq_attr "alternative" "19,20")
2317               (const_string "x64_sse2")
2318             (eq_attr "alternative" "21,22")
2319               (const_string "sse2")
2320            ]
2321            (const_string "*")))
2322    (set (attr "type")
2323      (cond [(eq_attr "alternative" "0,1,17,18")
2324               (const_string "multi")
2325             (eq_attr "alternative" "6")
2326               (const_string "mmx")
2327             (eq_attr "alternative" "7,8,9,10,11")
2328               (const_string "mmxmov")
2329             (eq_attr "alternative" "12")
2330               (const_string "sselog1")
2331             (eq_attr "alternative" "13,14,15,16,19,20")
2332               (const_string "ssemov")
2333             (eq_attr "alternative" "21,22")
2334               (const_string "ssecvt")
2335             (eq_attr "alternative" "23,24,25,26")
2336               (const_string "mskmov")
2337             (and (match_operand 0 "register_operand")
2338                  (match_operand 1 "pic_32bit_operand"))
2339               (const_string "lea")
2340            ]
2341            (const_string "imov")))
2342    (set (attr "modrm")
2343      (if_then_else
2344        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2345        (const_string "0")
2346        (const_string "*")))
2347    (set (attr "length_immediate")
2348      (if_then_else
2349        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2350        (const_string "8")
2351        (const_string "*")))
2352    (set (attr "prefix_rex")
2353      (if_then_else
2354        (eq_attr "alternative" "10,11,19,20")
2355        (const_string "1")
2356        (const_string "*")))
2357    (set (attr "prefix")
2358      (if_then_else (eq_attr "type" "sselog1,ssemov")
2359        (const_string "maybe_vex")
2360        (const_string "orig")))
2361    (set (attr "prefix_data16")
2362      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2363        (const_string "1")
2364        (const_string "*")))
2365    (set (attr "mode")
2366      (cond [(eq_attr "alternative" "2")
2367               (const_string "SI")
2368             (eq_attr "alternative" "12,13")
2369               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2370                           (match_operand 1 "ext_sse_reg_operand"))
2371                        (const_string "TI")
2372                      (ior (not (match_test "TARGET_SSE2"))
2373                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2374                        (const_string "V4SF")
2375                      (match_test "TARGET_AVX")
2376                        (const_string "TI")
2377                      (match_test "optimize_function_for_size_p (cfun)")
2378                        (const_string "V4SF")
2379                     ]
2380                     (const_string "TI"))
2382             (and (eq_attr "alternative" "14,15,16")
2383                  (not (match_test "TARGET_SSE2")))
2384               (const_string "V2SF")
2385            ]
2386            (const_string "DI")))
2387    (set (attr "preferred_for_speed")
2388      (cond [(eq_attr "alternative" "10,17,19")
2389               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2390             (eq_attr "alternative" "11,18,20")
2391               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2392            ]
2393            (symbol_ref "true")))
2394    (set (attr "enabled")
2395      (cond [(eq_attr "alternative" "15")
2396               (if_then_else
2397                 (match_test "TARGET_STV && TARGET_SSE2")
2398                 (symbol_ref "false")
2399                 (const_string "*"))
2400             (eq_attr "alternative" "16")
2401               (if_then_else
2402                 (match_test "TARGET_STV && TARGET_SSE2")
2403                 (symbol_ref "true")
2404                 (symbol_ref "false"))
2405            ]
2406            (const_string "*")))])
2408 (define_split
2409   [(set (match_operand:<DWI> 0 "general_reg_operand")
2410         (match_operand:<DWI> 1 "sse_reg_operand"))]
2411   "TARGET_SSE4_1
2412    && reload_completed"
2413   [(set (match_dup 2)
2414         (vec_select:DWIH
2415           (match_dup 3)
2416           (parallel [(const_int 1)])))]
2418   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2419   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2421   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2422                   gen_lowpart (<MODE>mode, operands[1]));
2425 (define_split
2426   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2427         (match_operand:DWI 1 "general_gr_operand"))]
2428   "reload_completed"
2429   [(const_int 0)]
2430   "ix86_split_long_move (operands); DONE;")
2432 (define_split
2433   [(set (match_operand:DI 0 "sse_reg_operand")
2434         (match_operand:DI 1 "general_reg_operand"))]
2435   "!TARGET_64BIT && TARGET_SSE4_1
2436    && reload_completed"
2437   [(set (match_dup 2)
2438         (vec_merge:V4SI
2439           (vec_duplicate:V4SI (match_dup 3))
2440           (match_dup 2)
2441           (const_int 2)))]
2443   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2444   operands[3] = gen_highpart (SImode, operands[1]);
2446   emit_move_insn (gen_lowpart (SImode, operands[0]),
2447                   gen_lowpart (SImode, operands[1]));
2450 ;; movabsq $0x0012345678000000, %rax is longer
2451 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2452 (define_peephole2
2453   [(set (match_operand:DI 0 "register_operand")
2454         (match_operand:DI 1 "const_int_operand"))]
2455   "TARGET_64BIT
2456    && optimize_insn_for_size_p ()
2457    && LEGACY_INT_REG_P (operands[0])
2458    && !x86_64_immediate_operand (operands[1], DImode)
2459    && !x86_64_zext_immediate_operand (operands[1], DImode)
2460    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2461         & ~(HOST_WIDE_INT) 0xffffffff)
2462    && peep2_regno_dead_p (0, FLAGS_REG)"
2463   [(set (match_dup 0) (match_dup 1))
2464    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2465               (clobber (reg:CC FLAGS_REG))])]
2467   int shift = ctz_hwi (UINTVAL (operands[1]));
2468   operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2469   operands[2] = gen_int_mode (shift, QImode);
2472 (define_insn "*movsi_internal"
2473   [(set (match_operand:SI 0 "nonimmediate_operand"
2474     "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm")
2475         (match_operand:SI 1 "general_operand"
2476     "g ,re,C ,*y,m  ,*y,*y,r  ,C ,*v,m ,*v,*v,r  ,*r,*km,*k"))]
2477   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2479   switch (get_attr_type (insn))
2480     {
2481     case TYPE_SSELOG1:
2482       return standard_sse_constant_opcode (insn, operands);
2484     case TYPE_MSKMOV:
2485       return "kmovd\t{%1, %0|%0, %1}";
2487     case TYPE_SSEMOV:
2488       switch (get_attr_mode (insn))
2489         {
2490         case MODE_SI:
2491           return "%vmovd\t{%1, %0|%0, %1}";
2492         case MODE_TI:
2493           return "%vmovdqa\t{%1, %0|%0, %1}";
2494         case MODE_XI:
2495           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2497         case MODE_V4SF:
2498           return "%vmovaps\t{%1, %0|%0, %1}";
2500         case MODE_SF:
2501           gcc_assert (!TARGET_AVX);
2502           return "movss\t{%1, %0|%0, %1}";
2504         default:
2505           gcc_unreachable ();
2506         }
2508     case TYPE_MMX:
2509       return "pxor\t%0, %0";
2511     case TYPE_MMXMOV:
2512       switch (get_attr_mode (insn))
2513         {
2514         case MODE_DI:
2515           return "movq\t{%1, %0|%0, %1}";
2516         case MODE_SI:
2517           return "movd\t{%1, %0|%0, %1}";
2519         default:
2520           gcc_unreachable ();
2521         }
2523     case TYPE_LEA:
2524       return "lea{l}\t{%E1, %0|%0, %E1}";
2526     case TYPE_IMOV:
2527       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2528       if (ix86_use_lea_for_mov (insn, operands))
2529         return "lea{l}\t{%E1, %0|%0, %E1}";
2530       else
2531         return "mov{l}\t{%1, %0|%0, %1}";
2533     default:
2534       gcc_unreachable ();
2535     }
2537   [(set (attr "isa")
2538      (cond [(eq_attr "alternative" "12,13")
2539               (const_string "sse2")
2540            ]
2541            (const_string "*")))
2542    (set (attr "type")
2543      (cond [(eq_attr "alternative" "2")
2544               (const_string "mmx")
2545             (eq_attr "alternative" "3,4,5,6,7")
2546               (const_string "mmxmov")
2547             (eq_attr "alternative" "8")
2548               (const_string "sselog1")
2549             (eq_attr "alternative" "9,10,11,12,13")
2550               (const_string "ssemov")
2551             (eq_attr "alternative" "14,15,16")
2552               (const_string "mskmov")
2553             (and (match_operand 0 "register_operand")
2554                  (match_operand 1 "pic_32bit_operand"))
2555               (const_string "lea")
2556            ]
2557            (const_string "imov")))
2558    (set (attr "prefix")
2559      (if_then_else (eq_attr "type" "sselog1,ssemov")
2560        (const_string "maybe_vex")
2561        (const_string "orig")))
2562    (set (attr "prefix_data16")
2563      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2564        (const_string "1")
2565        (const_string "*")))
2566    (set (attr "mode")
2567      (cond [(eq_attr "alternative" "2,3")
2568               (const_string "DI")
2569             (eq_attr "alternative" "8,9")
2570               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2571                           (match_operand 1 "ext_sse_reg_operand"))
2572                        (const_string "XI")
2573                      (ior (not (match_test "TARGET_SSE2"))
2574                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2575                        (const_string "V4SF")
2576                      (match_test "TARGET_AVX")
2577                        (const_string "TI")
2578                      (match_test "optimize_function_for_size_p (cfun)")
2579                        (const_string "V4SF")
2580                     ]
2581                     (const_string "TI"))
2583             (and (eq_attr "alternative" "10,11")
2584                  (not (match_test "TARGET_SSE2")))
2585               (const_string "SF")
2586            ]
2587            (const_string "SI")))
2588    (set (attr "preferred_for_speed")
2589      (cond [(eq_attr "alternative" "6,12")
2590               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2591             (eq_attr "alternative" "7,13")
2592               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2593            ]
2594            (symbol_ref "true")))])
2596 (define_insn "*movhi_internal"
2597   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2598         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2599   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2601   switch (get_attr_type (insn))
2602     {
2603     case TYPE_IMOVX:
2604       /* movzwl is faster than movw on p2 due to partial word stalls,
2605          though not as fast as an aligned movl.  */
2606       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2608     case TYPE_MSKMOV:
2609       switch (which_alternative)
2610         {
2611         case 4:
2612           return "kmovw\t{%k1, %0|%0, %k1}";
2613         case 6:
2614           return "kmovw\t{%1, %k0|%k0, %1}";
2615         case 5:
2616         case 7:
2617           return "kmovw\t{%1, %0|%0, %1}";
2618         default:
2619           gcc_unreachable ();
2620         }
2622     default:
2623       if (get_attr_mode (insn) == MODE_SI)
2624         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2625       else
2626         return "mov{w}\t{%1, %0|%0, %1}";
2627     }
2629   [(set (attr "type")
2630      (cond [(eq_attr "alternative" "4,5,6,7")
2631               (const_string "mskmov")
2632             (match_test "optimize_function_for_size_p (cfun)")
2633               (const_string "imov")
2634             (and (eq_attr "alternative" "0")
2635                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2636                       (not (match_test "TARGET_HIMODE_MATH"))))
2637               (const_string "imov")
2638             (and (eq_attr "alternative" "1,2")
2639                  (match_operand:HI 1 "aligned_operand"))
2640               (const_string "imov")
2641             (and (match_test "TARGET_MOVX")
2642                  (eq_attr "alternative" "0,2"))
2643               (const_string "imovx")
2644            ]
2645            (const_string "imov")))
2646     (set (attr "prefix")
2647       (if_then_else (eq_attr "alternative" "4,5,6,7")
2648         (const_string "vex")
2649         (const_string "orig")))
2650     (set (attr "mode")
2651       (cond [(eq_attr "type" "imovx")
2652                (const_string "SI")
2653              (and (eq_attr "alternative" "1,2")
2654                   (match_operand:HI 1 "aligned_operand"))
2655                (const_string "SI")
2656              (and (eq_attr "alternative" "0")
2657                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2658                        (not (match_test "TARGET_HIMODE_MATH"))))
2659                (const_string "SI")
2660             ]
2661             (const_string "HI")))])
2663 ;; Situation is quite tricky about when to choose full sized (SImode) move
2664 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2665 ;; partial register dependency machines (such as AMD Athlon), where QImode
2666 ;; moves issue extra dependency and for partial register stalls machines
2667 ;; that don't use QImode patterns (and QImode move cause stall on the next
2668 ;; instruction).
2670 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2671 ;; register stall machines with, where we use QImode instructions, since
2672 ;; partial register stall can be caused there.  Then we use movzx.
2674 (define_insn "*movqi_internal"
2675   [(set (match_operand:QI 0 "nonimmediate_operand"
2676                         "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2677         (match_operand:QI 1 "general_operand"
2678                         "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2679   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2681   static char buf[128];
2682   const char *ops;
2683   const char *suffix;
2685   switch (get_attr_type (insn))
2686     {
2687     case TYPE_IMOVX:
2688       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2689       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2691     case TYPE_MSKMOV:
2692       switch (which_alternative)
2693         {
2694         case 9:
2695           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2696           break;
2697         case 11:
2698           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2699           break;
2700         case 12:
2701         case 13:
2702           gcc_assert (TARGET_AVX512DQ);
2703           /* FALLTHRU */
2704         case 10:
2705           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2706           break;
2707         default:
2708           gcc_unreachable ();
2709         }
2711       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2713       snprintf (buf, sizeof (buf), ops, suffix);
2714       return buf;
2716     default:
2717       if (get_attr_mode (insn) == MODE_SI)
2718         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2719       else
2720         return "mov{b}\t{%1, %0|%0, %1}";
2721     }
2723   [(set (attr "isa")
2724      (cond [(eq_attr "alternative" "1,2")
2725               (const_string "x64")
2726             (eq_attr "alternative" "12,13")
2727               (const_string "avx512dq")
2728            ]
2729            (const_string "*")))
2730    (set (attr "type")
2731      (cond [(eq_attr "alternative" "9,10,11,12,13")
2732               (const_string "mskmov")
2733             (and (eq_attr "alternative" "7")
2734                  (not (match_operand:QI 1 "aligned_operand")))
2735               (const_string "imovx")
2736             (match_test "optimize_function_for_size_p (cfun)")
2737               (const_string "imov")
2738             (and (eq_attr "alternative" "5")
2739                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2740                       (not (match_test "TARGET_QIMODE_MATH"))))
2741               (const_string "imov")
2742             (eq_attr "alternative" "5,7")
2743               (const_string "imovx")
2744             (and (match_test "TARGET_MOVX")
2745                  (eq_attr "alternative" "4"))
2746               (const_string "imovx")
2747            ]
2748            (const_string "imov")))
2749    (set (attr "prefix")
2750      (if_then_else (eq_attr "alternative" "9,10,11")
2751        (const_string "vex")
2752        (const_string "orig")))
2753    (set (attr "mode")
2754       (cond [(eq_attr "alternative" "5,6,7")
2755                (const_string "SI")
2756              (eq_attr "alternative" "8")
2757                (const_string "QI")
2758              (and (eq_attr "alternative" "9,10,11")
2759                   (not (match_test "TARGET_AVX512DQ")))
2760                (const_string "HI")
2761              (eq_attr "type" "imovx")
2762                (const_string "SI")
2763              ;; For -Os, 8-bit immediates are always shorter than 32-bit
2764              ;; ones.
2765              (and (eq_attr "type" "imov")
2766                   (and (eq_attr "alternative" "3")
2767                        (match_test "optimize_function_for_size_p (cfun)")))
2768                (const_string "QI")
2769              ;; For -Os, movl where one or both operands are NON_Q_REGS
2770              ;; and both are LEGACY_REGS is shorter than movb.
2771              ;; Otherwise movb and movl sizes are the same, so decide purely
2772              ;; based on speed factors.
2773              (and (eq_attr "type" "imov")
2774                   (and (eq_attr "alternative" "1")
2775                        (match_test "optimize_function_for_size_p (cfun)")))
2776                (const_string "SI")
2777              (and (eq_attr "type" "imov")
2778                   (and (eq_attr "alternative" "0,1,2,3")
2779                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2780                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2781                (const_string "SI")
2782              ;; Avoid partial register stalls when not using QImode arithmetic
2783              (and (eq_attr "type" "imov")
2784                   (and (eq_attr "alternative" "0,1,2,3")
2785                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2786                             (not (match_test "TARGET_QIMODE_MATH")))))
2787                (const_string "SI")
2788            ]
2789            (const_string "QI")))])
2791 ;; Stores and loads of ax to arbitrary constant address.
2792 ;; We fake an second form of instruction to force reload to load address
2793 ;; into register when rax is not available
2794 (define_insn "*movabs<mode>_1"
2795   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2796         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2797   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2799   /* Recover the full memory rtx.  */
2800   operands[0] = SET_DEST (PATTERN (insn));
2801   switch (which_alternative)
2802     {
2803     case 0:
2804       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2805     case 1:
2806       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2807     default:
2808       gcc_unreachable ();
2809     }
2811   [(set_attr "type" "imov")
2812    (set_attr "modrm" "0,*")
2813    (set_attr "length_address" "8,0")
2814    (set_attr "length_immediate" "0,*")
2815    (set_attr "memory" "store")
2816    (set_attr "mode" "<MODE>")])
2818 (define_insn "*movabs<mode>_2"
2819   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2820         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2821   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2823   /* Recover the full memory rtx.  */
2824   operands[1] = SET_SRC (PATTERN (insn));
2825   switch (which_alternative)
2826     {
2827     case 0:
2828       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2829     case 1:
2830       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2831     default:
2832       gcc_unreachable ();
2833     }
2835   [(set_attr "type" "imov")
2836    (set_attr "modrm" "0,*")
2837    (set_attr "length_address" "8,0")
2838    (set_attr "length_immediate" "0")
2839    (set_attr "memory" "load")
2840    (set_attr "mode" "<MODE>")])
2842 (define_insn "*swap<mode>"
2843   [(set (match_operand:SWI48 0 "register_operand" "+r")
2844         (match_operand:SWI48 1 "register_operand" "+r"))
2845    (set (match_dup 1)
2846         (match_dup 0))]
2847   ""
2848   "xchg{<imodesuffix>}\t%1, %0"
2849   [(set_attr "type" "imov")
2850    (set_attr "mode" "<MODE>")
2851    (set_attr "pent_pair" "np")
2852    (set_attr "athlon_decode" "vector")
2853    (set_attr "amdfam10_decode" "double")
2854    (set_attr "bdver1_decode" "double")])
2856 (define_insn "*swap<mode>"
2857   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2858         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2859    (set (match_dup 1)
2860         (match_dup 0))]
2861   ""
2862   "@
2863    xchg{<imodesuffix>}\t%1, %0
2864    xchg{l}\t%k1, %k0"
2865   [(set_attr "type" "imov")
2866    (set_attr "mode" "<MODE>,SI")
2867    (set (attr "preferred_for_size")
2868      (cond [(eq_attr "alternative" "0")
2869               (symbol_ref "false")]
2870            (symbol_ref "true")))
2871    ;; Potential partial reg stall on alternative 1.
2872    (set (attr "preferred_for_speed")
2873      (cond [(eq_attr "alternative" "1")
2874               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2875            (symbol_ref "true")))
2876    (set_attr "pent_pair" "np")
2877    (set_attr "athlon_decode" "vector")
2878    (set_attr "amdfam10_decode" "double")
2879    (set_attr "bdver1_decode" "double")])
2881 (define_expand "movstrict<mode>"
2882   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2883         (match_operand:SWI12 1 "general_operand"))]
2884   ""
2886   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2887     FAIL;
2888   if (SUBREG_P (operands[0])
2889       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2890     FAIL;
2891   /* Don't generate memory->memory moves, go through a register */
2892   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2893     operands[1] = force_reg (<MODE>mode, operands[1]);
2896 (define_insn "*movstrict<mode>_1"
2897   [(set (strict_low_part
2898           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2899         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2900   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2901    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2902   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2903   [(set_attr "type" "imov")
2904    (set_attr "mode" "<MODE>")])
2906 (define_insn "*movstrict<mode>_xor"
2907   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2908         (match_operand:SWI12 1 "const0_operand"))
2909    (clobber (reg:CC FLAGS_REG))]
2910   "reload_completed"
2911   "xor{<imodesuffix>}\t%0, %0"
2912   [(set_attr "type" "alu1")
2913    (set_attr "modrm_class" "op0")
2914    (set_attr "mode" "<MODE>")
2915    (set_attr "length_immediate" "0")])
2917 (define_expand "extv<mode>"
2918   [(set (match_operand:SWI24 0 "register_operand")
2919         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2920                             (match_operand:SI 2 "const_int_operand")
2921                             (match_operand:SI 3 "const_int_operand")))]
2922   ""
2924   /* Handle extractions from %ah et al.  */
2925   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2926     FAIL;
2928   unsigned int regno = reg_or_subregno (operands[1]);
2930   /* Be careful to expand only with registers having upper parts.  */
2931   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2932     operands[1] = copy_to_reg (operands[1]);
2935 (define_insn "*extv<mode>"
2936   [(set (match_operand:SWI24 0 "register_operand" "=R")
2937         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2938                             (const_int 8)
2939                             (const_int 8)))]
2940   ""
2941   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2942   [(set_attr "type" "imovx")
2943    (set_attr "mode" "SI")])
2945 (define_expand "extzv<mode>"
2946   [(set (match_operand:SWI248 0 "register_operand")
2947         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2948                              (match_operand:SI 2 "const_int_operand")
2949                              (match_operand:SI 3 "const_int_operand")))]
2950   ""
2952   if (ix86_expand_pextr (operands))
2953     DONE;
2955   /* Handle extractions from %ah et al.  */
2956   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2957     FAIL;
2959   unsigned int regno = reg_or_subregno (operands[1]);
2961   /* Be careful to expand only with registers having upper parts.  */
2962   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2963     operands[1] = copy_to_reg (operands[1]);
2966 (define_insn "*extzvqi_mem_rex64"
2967   [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2968         (subreg:QI
2969           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2970                            (const_int 8)
2971                            (const_int 8)) 0))]
2972   "TARGET_64BIT && reload_completed"
2973   "mov{b}\t{%h1, %0|%0, %h1}"
2974   [(set_attr "type" "imov")
2975    (set_attr "mode" "QI")])
2977 (define_insn "*extzv<mode>"
2978   [(set (match_operand:SWI248 0 "register_operand" "=R")
2979         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2980                              (const_int 8)
2981                              (const_int 8)))]
2982   ""
2983   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2984   [(set_attr "type" "imovx")
2985    (set_attr "mode" "SI")])
2987 (define_insn "*extzvqi"
2988   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2989         (subreg:QI
2990           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2991                            (const_int 8)
2992                            (const_int 8)) 0))]
2993   ""
2995   switch (get_attr_type (insn))
2996     {
2997     case TYPE_IMOVX:
2998       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2999     default:
3000       return "mov{b}\t{%h1, %0|%0, %h1}";
3001     }
3003   [(set_attr "isa" "*,*,nox64")
3004    (set (attr "type")
3005      (if_then_else (and (match_operand:QI 0 "register_operand")
3006                         (ior (not (match_operand:QI 0 "QIreg_operand"))
3007                              (match_test "TARGET_MOVX")))
3008         (const_string "imovx")
3009         (const_string "imov")))
3010    (set (attr "mode")
3011      (if_then_else (eq_attr "type" "imovx")
3012         (const_string "SI")
3013         (const_string "QI")))])
3015 (define_peephole2
3016   [(set (match_operand:QI 0 "register_operand")
3017         (subreg:QI
3018           (zero_extract:SI (match_operand 1 "ext_register_operand")
3019                            (const_int 8)
3020                            (const_int 8)) 0))
3021    (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3022   "TARGET_64BIT
3023    && peep2_reg_dead_p (2, operands[0])"
3024   [(set (match_dup 2)
3025         (subreg:QI
3026           (zero_extract:SI (match_dup 1)
3027                            (const_int 8)
3028                            (const_int 8)) 0))])
3030 (define_expand "insv<mode>"
3031   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3032                              (match_operand:SI 1 "const_int_operand")
3033                              (match_operand:SI 2 "const_int_operand"))
3034         (match_operand:SWI248 3 "register_operand"))]
3035   ""
3037   rtx dst;
3039   if (ix86_expand_pinsr (operands))
3040     DONE;
3042   /* Handle insertions to %ah et al.  */
3043   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3044     FAIL;
3046   unsigned int regno = reg_or_subregno (operands[0]);
3048   /* Be careful to expand only with registers having upper parts.  */
3049   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3050     dst = copy_to_reg (operands[0]);
3051   else
3052     dst = operands[0];
3054   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3056   /* Fix up the destination if needed.  */
3057   if (dst != operands[0])
3058     emit_move_insn (operands[0], dst);
3060   DONE;
3063 (define_insn "*insvqi_1_mem_rex64"
3064   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3065                          (const_int 8)
3066                          (const_int 8))
3067         (subreg:SI
3068           (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3069   "TARGET_64BIT && reload_completed"
3070   "mov{b}\t{%1, %h0|%h0, %1}"
3071   [(set_attr "type" "imov")
3072    (set_attr "mode" "QI")])
3074 (define_insn "insv<mode>_1"
3075   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3076                              (const_int 8)
3077                              (const_int 8))
3078         (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3079   ""
3081   if (CONST_INT_P (operands[1]))
3082     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3083   return "mov{b}\t{%b1, %h0|%h0, %b1}";
3085   [(set_attr "isa" "*,nox64")
3086    (set_attr "type" "imov")
3087    (set_attr "mode" "QI")])
3089 (define_insn "*insvqi_1"
3090   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3091                          (const_int 8)
3092                          (const_int 8))
3093         (subreg:SI
3094           (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3095   ""
3096   "mov{b}\t{%1, %h0|%h0, %1}"
3097   [(set_attr "isa" "*,nox64")
3098    (set_attr "type" "imov")
3099    (set_attr "mode" "QI")])
3101 (define_peephole2
3102   [(set (match_operand:QI 0 "register_operand")
3103         (match_operand:QI 1 "norex_memory_operand"))
3104    (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3105                          (const_int 8)
3106                          (const_int 8))
3107         (subreg:SI (match_dup 0) 0))]
3108   "TARGET_64BIT
3109    && peep2_reg_dead_p (2, operands[0])"
3110   [(set (zero_extract:SI (match_dup 2)
3111                          (const_int 8)
3112                          (const_int 8))
3113            (subreg:SI (match_dup 1) 0))])
3115 (define_code_iterator any_extract [sign_extract zero_extract])
3117 (define_insn "*insvqi_2"
3118   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3119                          (const_int 8)
3120                          (const_int 8))
3121         (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3122                         (const_int 8)
3123                         (const_int 8)))]
3124   ""
3125   "mov{b}\t{%h1, %h0|%h0, %h1}"
3126   [(set_attr "type" "imov")
3127    (set_attr "mode" "QI")])
3129 (define_insn "*insvqi_3"
3130   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3131                          (const_int 8)
3132                          (const_int 8))
3133         (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3134                         (const_int 8)))]
3135   ""
3136   "mov{b}\t{%h1, %h0|%h0, %h1}"
3137   [(set_attr "type" "imov")
3138    (set_attr "mode" "QI")])
3140 ;; Floating point push instructions.
3142 (define_insn "*pushtf"
3143   [(set (match_operand:TF 0 "push_operand" "=<,<")
3144         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3145   "TARGET_64BIT || TARGET_SSE"
3147   /* This insn should be already split before reg-stack.  */
3148   gcc_unreachable ();
3150   [(set_attr "isa" "*,x64")
3151    (set_attr "type" "multi")
3152    (set_attr "unit" "sse,*")
3153    (set_attr "mode" "TF,DI")])
3155 ;; %%% Kill this when call knows how to work this out.
3156 (define_split
3157   [(set (match_operand:TF 0 "push_operand")
3158         (match_operand:TF 1 "sse_reg_operand"))]
3159   "TARGET_SSE && reload_completed"
3160   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3161    (set (match_dup 0) (match_dup 1))]
3163   /* Preserve memory attributes. */
3164   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3167 (define_insn_and_split "*pushxf_rounded"
3168   [(set (mem:XF
3169           (pre_modify:P
3170             (reg:P SP_REG)
3171             (plus:P (reg:P SP_REG) (const_int -16))))
3172         (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3173   "TARGET_64BIT"
3174   "#"
3175   "&& 1"
3176   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3177    (set (match_dup 1) (match_dup 0))]
3179   rtx pat = PATTERN (curr_insn);
3180   operands[1] = SET_DEST (pat);
3182   /* Preserve memory attributes. */
3183   operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3185   [(set_attr "type" "multi")
3186    (set_attr "unit" "i387,*,*,*")
3187    (set (attr "mode")
3188         (cond [(eq_attr "alternative" "1,2,3")
3189                  (const_string "DI")
3190               ]
3191               (const_string "XF")))
3192    (set (attr "preferred_for_size")
3193      (cond [(eq_attr "alternative" "1")
3194               (symbol_ref "false")]
3195            (symbol_ref "true")))])
3197 (define_insn "*pushxf"
3198   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3199         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3200   ""
3202   /* This insn should be already split before reg-stack.  */
3203   gcc_unreachable ();
3205   [(set_attr "isa" "*,*,*,nox64,x64")
3206    (set_attr "type" "multi")
3207    (set_attr "unit" "i387,*,*,*,*")
3208    (set (attr "mode")
3209         (cond [(eq_attr "alternative" "1,2,3,4")
3210                  (if_then_else (match_test "TARGET_64BIT")
3211                    (const_string "DI")
3212                    (const_string "SI"))
3213               ]
3214               (const_string "XF")))
3215    (set (attr "preferred_for_size")
3216      (cond [(eq_attr "alternative" "1")
3217               (symbol_ref "false")]
3218            (symbol_ref "true")))])
3220 ;; %%% Kill this when call knows how to work this out.
3221 (define_split
3222   [(set (match_operand:XF 0 "push_operand")
3223         (match_operand:XF 1 "fp_register_operand"))]
3224   "reload_completed"
3225   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3226    (set (match_dup 0) (match_dup 1))]
3228   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3229   /* Preserve memory attributes. */
3230   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3233 (define_insn "*pushdf"
3234   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3235         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3236   ""
3238   /* This insn should be already split before reg-stack.  */
3239   gcc_unreachable ();
3241   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3242    (set_attr "type" "multi")
3243    (set_attr "unit" "i387,*,*,*,*,sse")
3244    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3245    (set (attr "preferred_for_size")
3246      (cond [(eq_attr "alternative" "1")
3247               (symbol_ref "false")]
3248            (symbol_ref "true")))
3249    (set (attr "preferred_for_speed")
3250      (cond [(eq_attr "alternative" "1")
3251               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3252            (symbol_ref "true")))])
3253    
3254 ;; %%% Kill this when call knows how to work this out.
3255 (define_split
3256   [(set (match_operand:DF 0 "push_operand")
3257         (match_operand:DF 1 "any_fp_register_operand"))]
3258   "reload_completed"
3259   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3260    (set (match_dup 0) (match_dup 1))]
3262   /* Preserve memory attributes. */
3263   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3266 (define_insn "*pushsf_rex64"
3267   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3268         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3269   "TARGET_64BIT"
3271   /* Anything else should be already split before reg-stack.  */
3272   gcc_assert (which_alternative == 1);
3273   return "push{q}\t%q1";
3275   [(set_attr "type" "multi,push,multi")
3276    (set_attr "unit" "i387,*,*")
3277    (set_attr "mode" "SF,DI,SF")])
3279 (define_insn "*pushsf"
3280   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3281         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3282   "!TARGET_64BIT"
3284   /* Anything else should be already split before reg-stack.  */
3285   gcc_assert (which_alternative == 1);
3286   return "push{l}\t%1";
3288   [(set_attr "type" "multi,push,multi")
3289    (set_attr "unit" "i387,*,*")
3290    (set_attr "mode" "SF,SI,SF")])
3292 ;; %%% Kill this when call knows how to work this out.
3293 (define_split
3294   [(set (match_operand:SF 0 "push_operand")
3295         (match_operand:SF 1 "any_fp_register_operand"))]
3296   "reload_completed"
3297   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3298    (set (match_dup 0) (match_dup 1))]
3300   rtx op = XEXP (operands[0], 0);
3301   if (GET_CODE (op) == PRE_DEC)
3302     {
3303       gcc_assert (!TARGET_64BIT);
3304       op = GEN_INT (-4);
3305     }
3306   else
3307     {
3308       op = XEXP (XEXP (op, 1), 1);
3309       gcc_assert (CONST_INT_P (op));
3310     }
3311   operands[2] = op;
3312   /* Preserve memory attributes. */
3313   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3316 (define_split
3317   [(set (match_operand:SF 0 "push_operand")
3318         (match_operand:SF 1 "memory_operand"))]
3319   "reload_completed
3320    && find_constant_src (insn)"
3321   [(set (match_dup 0) (match_dup 2))]
3322   "operands[2] = find_constant_src (curr_insn);")
3324 (define_split
3325   [(set (match_operand 0 "push_operand")
3326         (match_operand 1 "general_gr_operand"))]
3327   "reload_completed
3328    && (GET_MODE (operands[0]) == TFmode
3329        || GET_MODE (operands[0]) == XFmode
3330        || GET_MODE (operands[0]) == DFmode)"
3331   [(const_int 0)]
3332   "ix86_split_long_move (operands); DONE;")
3334 ;; Floating point move instructions.
3336 (define_expand "movtf"
3337   [(set (match_operand:TF 0 "nonimmediate_operand")
3338         (match_operand:TF 1 "nonimmediate_operand"))]
3339   "TARGET_64BIT || TARGET_SSE"
3340   "ix86_expand_move (TFmode, operands); DONE;")
3342 (define_expand "mov<mode>"
3343   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3344         (match_operand:X87MODEF 1 "general_operand"))]
3345   ""
3346   "ix86_expand_move (<MODE>mode, operands); DONE;")
3348 (define_insn "*movtf_internal"
3349   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3350         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3351   "(TARGET_64BIT || TARGET_SSE)
3352    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3353    && (lra_in_progress || reload_completed
3354        || !CONST_DOUBLE_P (operands[1])
3355        || ((optimize_function_for_size_p (cfun)
3356             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3357            && standard_sse_constant_p (operands[1], TFmode) == 1
3358            && !memory_operand (operands[0], TFmode))
3359        || (!TARGET_MEMORY_MISMATCH_STALL
3360            && memory_operand (operands[0], TFmode)))"
3362   switch (get_attr_type (insn))
3363     {
3364     case TYPE_SSELOG1:
3365       return standard_sse_constant_opcode (insn, operands);
3367     case TYPE_SSEMOV:
3368       /* Handle misaligned load/store since we
3369          don't have movmisaligntf pattern. */
3370       if (misaligned_operand (operands[0], TFmode)
3371           || misaligned_operand (operands[1], TFmode))
3372         {
3373           if (get_attr_mode (insn) == MODE_V4SF)
3374             return "%vmovups\t{%1, %0|%0, %1}";
3375           else if (TARGET_AVX512VL
3376                    && (EXT_REX_SSE_REG_P (operands[0])
3377                        || EXT_REX_SSE_REG_P (operands[1])))
3378             return "vmovdqu64\t{%1, %0|%0, %1}";
3379           else
3380             return "%vmovdqu\t{%1, %0|%0, %1}";
3381         }
3382       else
3383         {
3384           if (get_attr_mode (insn) == MODE_V4SF)
3385             return "%vmovaps\t{%1, %0|%0, %1}";
3386           else if (TARGET_AVX512VL
3387                    && (EXT_REX_SSE_REG_P (operands[0])
3388                        || EXT_REX_SSE_REG_P (operands[1])))
3389             return "vmovdqa64\t{%1, %0|%0, %1}";
3390           else
3391             return "%vmovdqa\t{%1, %0|%0, %1}";
3392         }
3394     case TYPE_MULTI:
3395         return "#";
3397     default:
3398       gcc_unreachable ();
3399     }
3401   [(set_attr "isa" "*,*,*,x64,x64")
3402    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3403    (set (attr "prefix")
3404      (if_then_else (eq_attr "type" "sselog1,ssemov")
3405        (const_string "maybe_vex")
3406        (const_string "orig")))
3407    (set (attr "mode")
3408         (cond [(eq_attr "alternative" "3,4")
3409                  (const_string "DI")
3410                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3411                  (const_string "V4SF")
3412                (and (eq_attr "alternative" "2")
3413                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3414                  (const_string "V4SF")
3415                (match_test "TARGET_AVX")
3416                  (const_string "TI")
3417                (ior (not (match_test "TARGET_SSE2"))
3418                     (match_test "optimize_function_for_size_p (cfun)"))
3419                  (const_string "V4SF")
3420                ]
3421                (const_string "TI")))])
3423 (define_split
3424   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3425         (match_operand:TF 1 "general_gr_operand"))]
3426   "reload_completed"
3427   [(const_int 0)]
3428   "ix86_split_long_move (operands); DONE;")
3430 ;; Possible store forwarding (partial memory) stall
3431 ;; in alternatives 4, 6, 7 and 8.
3432 (define_insn "*movxf_internal"
3433   [(set (match_operand:XF 0 "nonimmediate_operand"
3434          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3435         (match_operand:XF 1 "general_operand"
3436          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3437   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3438    && (lra_in_progress || reload_completed
3439        || !CONST_DOUBLE_P (operands[1])
3440        || ((optimize_function_for_size_p (cfun)
3441             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3442            && standard_80387_constant_p (operands[1]) > 0
3443            && !memory_operand (operands[0], XFmode))
3444        || (!TARGET_MEMORY_MISMATCH_STALL
3445            && memory_operand (operands[0], XFmode))
3446        || !TARGET_HARD_XF_REGS)"
3448   switch (get_attr_type (insn))
3449     {
3450     case TYPE_FMOV:
3451       if (which_alternative == 2)
3452         return standard_80387_constant_opcode (operands[1]);
3453       return output_387_reg_move (insn, operands);
3455     case TYPE_MULTI:
3456       return "#";
3458     default:
3459       gcc_unreachable ();
3460     }
3462   [(set (attr "isa")
3463         (cond [(eq_attr "alternative" "7,10")
3464                  (const_string "nox64")
3465                (eq_attr "alternative" "8,11")
3466                  (const_string "x64")
3467               ]
3468               (const_string "*")))
3469    (set (attr "type")
3470         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3471                  (const_string "multi")
3472               ]
3473               (const_string "fmov")))
3474    (set (attr "mode")
3475         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3476                  (if_then_else (match_test "TARGET_64BIT")
3477                    (const_string "DI")
3478                    (const_string "SI"))
3479               ]
3480               (const_string "XF")))
3481    (set (attr "preferred_for_size")
3482      (cond [(eq_attr "alternative" "3,4")
3483               (symbol_ref "false")]
3484            (symbol_ref "true")))
3485    (set (attr "enabled")
3486      (cond [(eq_attr "alternative" "9,10,11")
3487               (if_then_else
3488                 (match_test "TARGET_HARD_XF_REGS")
3489                 (symbol_ref "false")
3490                 (const_string "*"))
3491             (not (match_test "TARGET_HARD_XF_REGS"))
3492               (symbol_ref "false")
3493            ]
3494            (const_string "*")))])
3495    
3496 (define_split
3497   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3498         (match_operand:XF 1 "general_gr_operand"))]
3499   "reload_completed"
3500   [(const_int 0)]
3501   "ix86_split_long_move (operands); DONE;")
3503 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3504 (define_insn "*movdf_internal"
3505   [(set (match_operand:DF 0 "nonimmediate_operand"
3506     "=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")
3507         (match_operand:DF 1 "general_operand"
3508     "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"))]
3509   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3510    && (lra_in_progress || reload_completed
3511        || !CONST_DOUBLE_P (operands[1])
3512        || ((optimize_function_for_size_p (cfun)
3513             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3514            && ((IS_STACK_MODE (DFmode)
3515                 && standard_80387_constant_p (operands[1]) > 0)
3516                || (TARGET_SSE2 && TARGET_SSE_MATH
3517                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3518            && !memory_operand (operands[0], DFmode))
3519        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3520            && memory_operand (operands[0], DFmode))
3521        || !TARGET_HARD_DF_REGS)"
3523   switch (get_attr_type (insn))
3524     {
3525     case TYPE_FMOV:
3526       if (which_alternative == 2)
3527         return standard_80387_constant_opcode (operands[1]);
3528       return output_387_reg_move (insn, operands);
3530     case TYPE_MULTI:
3531       return "#";
3533     case TYPE_IMOV:
3534       if (get_attr_mode (insn) == MODE_SI)
3535         return "mov{l}\t{%1, %k0|%k0, %1}";
3536       else if (which_alternative == 11)
3537         return "movabs{q}\t{%1, %0|%0, %1}";
3538       else
3539         return "mov{q}\t{%1, %0|%0, %1}";
3541     case TYPE_SSELOG1:
3542       return standard_sse_constant_opcode (insn, operands);
3544     case TYPE_SSEMOV:
3545       switch (get_attr_mode (insn))
3546         {
3547         case MODE_DF:
3548           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3549             return "vmovsd\t{%d1, %0|%0, %d1}";
3550           return "%vmovsd\t{%1, %0|%0, %1}";
3552         case MODE_V4SF:
3553           return "%vmovaps\t{%1, %0|%0, %1}";
3554         case MODE_V8DF:
3555           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3556         case MODE_V2DF:
3557           return "%vmovapd\t{%1, %0|%0, %1}";
3559         case MODE_V2SF:
3560           gcc_assert (!TARGET_AVX);
3561           return "movlps\t{%1, %0|%0, %1}";
3562         case MODE_V1DF:
3563           gcc_assert (!TARGET_AVX);
3564           return "movlpd\t{%1, %0|%0, %1}";
3566         case MODE_DI:
3567           /* Handle broken assemblers that require movd instead of movq.  */
3568           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3569               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3570             return "%vmovd\t{%1, %0|%0, %1}";
3571           return "%vmovq\t{%1, %0|%0, %1}";
3573         default:
3574           gcc_unreachable ();
3575         }
3577     default:
3578       gcc_unreachable ();
3579     }
3581   [(set (attr "isa")
3582         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3583                  (const_string "nox64")
3584                (eq_attr "alternative" "8,9,10,11,24,25")
3585                  (const_string "x64")
3586                (eq_attr "alternative" "12,13,14,15")
3587                  (const_string "sse2")
3588                (eq_attr "alternative" "20,21")
3589                  (const_string "x64_sse2")
3590               ]
3591               (const_string "*")))
3592    (set (attr "type")
3593         (cond [(eq_attr "alternative" "0,1,2")
3594                  (const_string "fmov")
3595                (eq_attr "alternative" "3,4,5,6,7,22,23")
3596                  (const_string "multi")
3597                (eq_attr "alternative" "8,9,10,11,24,25")
3598                  (const_string "imov")
3599                (eq_attr "alternative" "12,16")
3600                  (const_string "sselog1")
3601               ]
3602               (const_string "ssemov")))
3603    (set (attr "modrm")
3604      (if_then_else (eq_attr "alternative" "11")
3605        (const_string "0")
3606        (const_string "*")))
3607    (set (attr "length_immediate")
3608      (if_then_else (eq_attr "alternative" "11")
3609        (const_string "8")
3610        (const_string "*")))
3611    (set (attr "prefix")
3612      (if_then_else (eq_attr "type" "sselog1,ssemov")
3613        (const_string "maybe_vex")
3614        (const_string "orig")))
3615    (set (attr "prefix_data16")
3616      (if_then_else
3617        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3618             (eq_attr "mode" "V1DF"))
3619        (const_string "1")
3620        (const_string "*")))
3621    (set (attr "mode")
3622         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3623                  (const_string "SI")
3624                (eq_attr "alternative" "8,9,11,20,21,24,25")
3625                  (const_string "DI")
3627                /* xorps is one byte shorter for non-AVX targets.  */
3628                (eq_attr "alternative" "12,16")
3629                  (cond [(not (match_test "TARGET_SSE2"))
3630                           (const_string "V4SF")
3631                         (and (match_test "TARGET_AVX512F")
3632                           (not (match_test "TARGET_PREFER_AVX256")))
3633                           (const_string "XI")
3634                         (match_test "TARGET_AVX")
3635                           (const_string "V2DF")
3636                         (match_test "optimize_function_for_size_p (cfun)")
3637                           (const_string "V4SF")
3638                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3639                           (const_string "TI")
3640                        ]
3641                        (const_string "V2DF"))
3643                /* For architectures resolving dependencies on
3644                   whole SSE registers use movapd to break dependency
3645                   chains, otherwise use short move to avoid extra work.  */
3647                /* movaps is one byte shorter for non-AVX targets.  */
3648                (eq_attr "alternative" "13,17")
3649                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3650                                   (not (match_test "TARGET_AVX512VL")))
3651                              (ior (match_operand 0 "ext_sse_reg_operand")
3652                                   (match_operand 1 "ext_sse_reg_operand")))
3653                           (const_string "V8DF")
3654                         (ior (not (match_test "TARGET_SSE2"))
3655                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3656                           (const_string "V4SF")
3657                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3658                           (const_string "V2DF")
3659                         (match_test "TARGET_AVX")
3660                           (const_string "DF")
3661                         (match_test "optimize_function_for_size_p (cfun)")
3662                           (const_string "V4SF")
3663                        ]
3664                        (const_string "DF"))
3666                /* For architectures resolving dependencies on register
3667                   parts we may avoid extra work to zero out upper part
3668                   of register.  */
3669                (eq_attr "alternative" "14,18")
3670                  (cond [(not (match_test "TARGET_SSE2"))
3671                           (const_string "V2SF")
3672                         (match_test "TARGET_AVX")
3673                           (const_string "DF")
3674                         (match_test "TARGET_SSE_SPLIT_REGS")
3675                           (const_string "V1DF")
3676                        ]
3677                        (const_string "DF"))
3679                (and (eq_attr "alternative" "15,19")
3680                     (not (match_test "TARGET_SSE2")))
3681                  (const_string "V2SF")
3682               ]
3683               (const_string "DF")))
3684    (set (attr "preferred_for_size")
3685      (cond [(eq_attr "alternative" "3,4")
3686               (symbol_ref "false")]
3687            (symbol_ref "true")))
3688    (set (attr "preferred_for_speed")
3689      (cond [(eq_attr "alternative" "3,4")
3690               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3691             (eq_attr "alternative" "20")
3692               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3693             (eq_attr "alternative" "21")
3694               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3695            ]
3696            (symbol_ref "true")))
3697    (set (attr "enabled")
3698      (cond [(eq_attr "alternative" "22,23,24,25")
3699               (if_then_else
3700                 (match_test "TARGET_HARD_DF_REGS")
3701                 (symbol_ref "false")
3702                 (const_string "*"))
3703             (not (match_test "TARGET_HARD_DF_REGS"))
3704               (symbol_ref "false")
3705            ]
3706            (const_string "*")))])
3708 (define_split
3709   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3710         (match_operand:DF 1 "general_gr_operand"))]
3711   "!TARGET_64BIT && reload_completed"
3712   [(const_int 0)]
3713   "ix86_split_long_move (operands); DONE;")
3715 (define_insn "*movsf_internal"
3716   [(set (match_operand:SF 0 "nonimmediate_operand"
3717           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r  ,m")
3718         (match_operand:SF 1 "general_operand"
3719           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,v ,r ,*y ,m  ,*y,*y,r  ,rmF,rF"))]
3720   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3721    && (lra_in_progress || reload_completed
3722        || !CONST_DOUBLE_P (operands[1])
3723        || ((optimize_function_for_size_p (cfun)
3724             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3725            && ((IS_STACK_MODE (SFmode)
3726                 && standard_80387_constant_p (operands[1]) > 0)
3727                || (TARGET_SSE && TARGET_SSE_MATH
3728                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3729        || memory_operand (operands[0], SFmode)
3730        || !TARGET_HARD_SF_REGS)"
3732   switch (get_attr_type (insn))
3733     {
3734     case TYPE_FMOV:
3735       if (which_alternative == 2)
3736         return standard_80387_constant_opcode (operands[1]);
3737       return output_387_reg_move (insn, operands);
3739     case TYPE_IMOV:
3740       return "mov{l}\t{%1, %0|%0, %1}";
3742     case TYPE_SSELOG1:
3743       return standard_sse_constant_opcode (insn, operands);
3745     case TYPE_SSEMOV:
3746       switch (get_attr_mode (insn))
3747         {
3748         case MODE_SF:
3749           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3750             return "vmovss\t{%d1, %0|%0, %d1}";
3751           return "%vmovss\t{%1, %0|%0, %1}";
3753         case MODE_V16SF:
3754           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3755         case MODE_V4SF:
3756           return "%vmovaps\t{%1, %0|%0, %1}";
3758         case MODE_SI:
3759           return "%vmovd\t{%1, %0|%0, %1}";
3761         default:
3762           gcc_unreachable ();
3763         }
3765     case TYPE_MMXMOV:
3766       switch (get_attr_mode (insn))
3767         {
3768         case MODE_DI:
3769           return "movq\t{%1, %0|%0, %1}";
3770         case MODE_SI:
3771           return "movd\t{%1, %0|%0, %1}";
3773         default:
3774           gcc_unreachable ();
3775         }
3777     default:
3778       gcc_unreachable ();
3779     }
3781   [(set (attr "isa")
3782      (cond [(eq_attr "alternative" "14,15")
3783               (const_string "sse2")
3784            ]
3785            (const_string "*")))
3786    (set (attr "type")
3787         (cond [(eq_attr "alternative" "0,1,2")
3788                  (const_string "fmov")
3789                (eq_attr "alternative" "3,4,16,17")
3790                  (const_string "imov")
3791                (eq_attr "alternative" "5")
3792                  (const_string "sselog1")
3793                (eq_attr "alternative" "11,12,13,14,15")
3794                  (const_string "mmxmov")
3795               ]
3796               (const_string "ssemov")))
3797    (set (attr "prefix")
3798      (if_then_else (eq_attr "type" "sselog1,ssemov")
3799        (const_string "maybe_vex")
3800        (const_string "orig")))
3801    (set (attr "prefix_data16")
3802      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3803        (const_string "1")
3804        (const_string "*")))
3805    (set (attr "mode")
3806         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3807                  (const_string "SI")
3808                (eq_attr "alternative" "11")
3809                  (const_string "DI")
3810                (eq_attr "alternative" "5")
3811                  (cond [(not (match_test "TARGET_SSE2"))
3812                           (const_string "V4SF")
3813                         (and (match_test "TARGET_AVX512F")
3814                           (not (match_test "TARGET_PREFER_AVX256")))
3815                           (const_string "V16SF")
3816                         (match_test "TARGET_AVX")
3817                           (const_string "V4SF")
3818                         (match_test "optimize_function_for_size_p (cfun)")
3819                           (const_string "V4SF")
3820                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3821                           (const_string "TI")
3822                        ]
3823                        (const_string "V4SF"))
3825                /* For architectures resolving dependencies on
3826                   whole SSE registers use APS move to break dependency
3827                   chains, otherwise use short move to avoid extra work.
3829                   Do the same for architectures resolving dependencies on
3830                   the parts.  While in DF mode it is better to always handle
3831                   just register parts, the SF mode is different due to lack
3832                   of instructions to load just part of the register.  It is
3833                   better to maintain the whole registers in single format
3834                   to avoid problems on using packed logical operations.  */
3835                (eq_attr "alternative" "6")
3836                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3837                                   (not (match_test "TARGET_AVX512VL")))
3838                              (ior (match_operand 0 "ext_sse_reg_operand")
3839                                   (match_operand 1 "ext_sse_reg_operand")))
3840                           (const_string "V16SF")
3841                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3842                              (match_test "TARGET_SSE_SPLIT_REGS"))
3843                           (const_string "V4SF")
3844                        ]
3845                        (const_string "SF"))
3846               ]
3847               (const_string "SF")))
3848    (set (attr "preferred_for_speed")
3849      (cond [(eq_attr "alternative" "9,14")
3850               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3851             (eq_attr "alternative" "10,15")
3852               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3853            ]
3854            (symbol_ref "true")))
3855    (set (attr "enabled")
3856      (cond [(eq_attr "alternative" "16,17")
3857               (if_then_else
3858                 (match_test "TARGET_HARD_SF_REGS")
3859                 (symbol_ref "false")
3860                 (const_string "*"))
3861             (not (match_test "TARGET_HARD_SF_REGS"))
3862               (symbol_ref "false")
3863            ]
3864            (const_string "*")))])
3866 (define_split
3867   [(set (match_operand 0 "any_fp_register_operand")
3868         (match_operand 1 "nonimmediate_operand"))]
3869   "reload_completed
3870    && (GET_MODE (operands[0]) == TFmode
3871        || GET_MODE (operands[0]) == XFmode
3872        || GET_MODE (operands[0]) == DFmode
3873        || GET_MODE (operands[0]) == SFmode)
3874    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3875   [(set (match_dup 0) (match_dup 2))]
3876   "operands[2] = find_constant_src (curr_insn);")
3878 (define_split
3879   [(set (match_operand 0 "any_fp_register_operand")
3880         (float_extend (match_operand 1 "nonimmediate_operand")))]
3881   "reload_completed
3882    && (GET_MODE (operands[0]) == TFmode
3883        || GET_MODE (operands[0]) == XFmode
3884        || GET_MODE (operands[0]) == DFmode)
3885    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3886   [(set (match_dup 0) (match_dup 2))]
3887   "operands[2] = find_constant_src (curr_insn);")
3889 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3890 (define_split
3891   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3892         (match_operand:X87MODEF 1 "immediate_operand"))]
3893   "reload_completed
3894    && (standard_80387_constant_p (operands[1]) == 8
3895        || standard_80387_constant_p (operands[1]) == 9)"
3896   [(set (match_dup 0)(match_dup 1))
3897    (set (match_dup 0)
3898         (neg:X87MODEF (match_dup 0)))]
3900   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3901     operands[1] = CONST0_RTX (<MODE>mode);
3902   else
3903     operands[1] = CONST1_RTX (<MODE>mode);
3906 (define_insn "swapxf"
3907   [(set (match_operand:XF 0 "register_operand" "+f")
3908         (match_operand:XF 1 "register_operand" "+f"))
3909    (set (match_dup 1)
3910         (match_dup 0))]
3911   "TARGET_80387"
3913   if (STACK_TOP_P (operands[0]))
3914     return "fxch\t%1";
3915   else
3916     return "fxch\t%0";
3918   [(set_attr "type" "fxch")
3919    (set_attr "mode" "XF")])
3921 (define_insn "*swap<mode>"
3922   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3923         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3924    (set (match_dup 1)
3925         (match_dup 0))]
3926   "TARGET_80387 || reload_completed"
3928   if (STACK_TOP_P (operands[0]))
3929     return "fxch\t%1";
3930   else
3931     return "fxch\t%0";
3933   [(set_attr "type" "fxch")
3934    (set_attr "mode" "<MODE>")])
3936 ;; Zero extension instructions
3938 (define_expand "zero_extendsidi2"
3939   [(set (match_operand:DI 0 "nonimmediate_operand")
3940         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3942 (define_insn "*zero_extendsidi2"
3943   [(set (match_operand:DI 0 "nonimmediate_operand"
3944                 "=r,?r,?o,r   ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r")
3945         (zero_extend:DI
3946          (match_operand:SI 1 "x86_64_zext_operand"
3947                 "0 ,rm,r ,rmWz,0,r  ,m   ,v ,r ,m ,*x,*v,*k")))]
3948   ""
3950   switch (get_attr_type (insn))
3951     {
3952     case TYPE_IMOVX:
3953       if (ix86_use_lea_for_mov (insn, operands))
3954         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3955       else
3956         return "mov{l}\t{%1, %k0|%k0, %1}";
3958     case TYPE_MULTI:
3959       return "#";
3961     case TYPE_MMXMOV:
3962       return "movd\t{%1, %0|%0, %1}";
3964     case TYPE_SSEMOV:
3965       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3966         {
3967           if (EXT_REX_SSE_REG_P (operands[0])
3968               || EXT_REX_SSE_REG_P (operands[1]))
3969             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3970           else
3971             return "%vpmovzxdq\t{%1, %0|%0, %1}";
3972         }
3974       if (GENERAL_REG_P (operands[0]))
3975         return "%vmovd\t{%1, %k0|%k0, %1}";
3977       return "%vmovd\t{%1, %0|%0, %1}";
3979     case TYPE_MSKMOV:
3980       return "kmovd\t{%1, %k0|%k0, %1}";
3982     default:
3983       gcc_unreachable ();
3984     }
3986   [(set (attr "isa")
3987      (cond [(eq_attr "alternative" "0,1,2")
3988               (const_string "nox64")
3989             (eq_attr "alternative" "3")
3990               (const_string "x64")
3991             (eq_attr "alternative" "7,8,9")
3992               (const_string "sse2")
3993             (eq_attr "alternative" "10")
3994               (const_string "sse4")
3995             (eq_attr "alternative" "11")
3996               (const_string "avx512f")
3997             (eq_attr "alternative" "12")
3998               (const_string "x64_avx512bw")
3999            ]
4000            (const_string "*")))
4001    (set (attr "type")
4002      (cond [(eq_attr "alternative" "0,1,2,4")
4003               (const_string "multi")
4004             (eq_attr "alternative" "5,6")
4005               (const_string "mmxmov")
4006             (eq_attr "alternative" "7")
4007               (if_then_else (match_test "TARGET_64BIT")
4008                 (const_string "ssemov")
4009                 (const_string "multi"))
4010             (eq_attr "alternative" "8,9,10,11")
4011               (const_string "ssemov")
4012             (eq_attr "alternative" "12")
4013               (const_string "mskmov")
4014            ]
4015            (const_string "imovx")))
4016    (set (attr "prefix_extra")
4017      (if_then_else (eq_attr "alternative" "10,11")
4018        (const_string "1")
4019        (const_string "*")))
4020    (set (attr "prefix")
4021      (if_then_else (eq_attr "type" "ssemov")
4022        (const_string "maybe_vex")
4023        (const_string "orig")))
4024    (set (attr "prefix_0f")
4025      (if_then_else (eq_attr "type" "imovx")
4026        (const_string "0")
4027        (const_string "*")))
4028    (set (attr "mode")
4029      (cond [(eq_attr "alternative" "5,6")
4030               (const_string "DI")
4031             (and (eq_attr "alternative" "7")
4032                  (match_test "TARGET_64BIT"))
4033               (const_string "TI")
4034             (eq_attr "alternative" "8,10,11")
4035               (const_string "TI")
4036            ]
4037            (const_string "SI")))
4038    (set (attr "preferred_for_speed")
4039      (cond [(eq_attr "alternative" "7")
4040               (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4041             (eq_attr "alternative" "5,8")
4042               (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4043            ]
4044            (symbol_ref "true")))])
4046 (define_split
4047   [(set (match_operand:DI 0 "memory_operand")
4048         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4049   "reload_completed"
4050   [(set (match_dup 4) (const_int 0))]
4051   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4053 (define_split
4054   [(set (match_operand:DI 0 "general_reg_operand")
4055         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4056   "!TARGET_64BIT && reload_completed
4057    && REGNO (operands[0]) == REGNO (operands[1])"
4058   [(set (match_dup 4) (const_int 0))]
4059   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4061 (define_split
4062   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4063         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4064   "!TARGET_64BIT && reload_completed
4065    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4066   [(set (match_dup 3) (match_dup 1))
4067    (set (match_dup 4) (const_int 0))]
4068   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4070 (define_mode_attr kmov_isa
4071   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4073 (define_insn "zero_extend<mode>di2"
4074   [(set (match_operand:DI 0 "register_operand" "=r,*r")
4075         (zero_extend:DI
4076          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4077   "TARGET_64BIT"
4078   "@
4079    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4080    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4081   [(set_attr "isa" "*,<kmov_isa>")
4082    (set_attr "type" "imovx,mskmov")
4083    (set_attr "mode" "SI,<MODE>")])
4085 (define_expand "zero_extend<mode>si2"
4086   [(set (match_operand:SI 0 "register_operand")
4087         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4088   ""
4090   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4091     {
4092       operands[1] = force_reg (<MODE>mode, operands[1]);
4093       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4094       DONE;
4095     }
4098 (define_insn_and_split "zero_extend<mode>si2_and"
4099   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4100         (zero_extend:SI
4101           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4102    (clobber (reg:CC FLAGS_REG))]
4103   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4104   "#"
4105   "&& reload_completed"
4106   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4107               (clobber (reg:CC FLAGS_REG))])]
4109   if (!REG_P (operands[1])
4110       || REGNO (operands[0]) != REGNO (operands[1]))
4111     {
4112       ix86_expand_clear (operands[0]);
4114       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4115       emit_insn (gen_movstrict<mode>
4116                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4117       DONE;
4118     }
4120   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4122   [(set_attr "type" "alu1")
4123    (set_attr "mode" "SI")])
4125 (define_insn "*zero_extend<mode>si2"
4126   [(set (match_operand:SI 0 "register_operand" "=r,*r")
4127         (zero_extend:SI
4128           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4129   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4130   "@
4131    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4132    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4133   [(set_attr "isa" "*,<kmov_isa>")
4134    (set_attr "type" "imovx,mskmov")
4135    (set_attr "mode" "SI,<MODE>")])
4137 (define_expand "zero_extendqihi2"
4138   [(set (match_operand:HI 0 "register_operand")
4139         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4140   ""
4142   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4143     {
4144       operands[1] = force_reg (QImode, operands[1]);
4145       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4146       DONE;
4147     }
4150 (define_insn_and_split "zero_extendqihi2_and"
4151   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4152         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4153    (clobber (reg:CC FLAGS_REG))]
4154   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4155   "#"
4156   "&& reload_completed"
4157   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4158               (clobber (reg:CC FLAGS_REG))])]
4160   if (!REG_P (operands[1])
4161       || REGNO (operands[0]) != REGNO (operands[1]))
4162     {
4163       ix86_expand_clear (operands[0]);
4165       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4166       emit_insn (gen_movstrictqi
4167                   (gen_lowpart (QImode, operands[0]), operands[1]));
4168       DONE;
4169     }
4171   operands[0] = gen_lowpart (SImode, operands[0]);
4173   [(set_attr "type" "alu1")
4174    (set_attr "mode" "SI")])
4176 ; zero extend to SImode to avoid partial register stalls
4177 (define_insn "*zero_extendqihi2"
4178   [(set (match_operand:HI 0 "register_operand" "=r,*r")
4179         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4180   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4181   "@
4182    movz{bl|x}\t{%1, %k0|%k0, %1}
4183    kmovb\t{%1, %k0|%k0, %1}"
4184   [(set_attr "isa" "*,avx512dq")
4185    (set_attr "type" "imovx,mskmov")
4186    (set_attr "mode" "SI,QI")])
4188 (define_insn_and_split "*zext<mode>_doubleword_and"
4189   [(set (match_operand:DI 0 "register_operand" "=&<r>")
4190         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4191   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4192    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4193   "#"
4194   "&& reload_completed && GENERAL_REG_P (operands[0])"
4195   [(set (match_dup 2) (const_int 0))]
4197   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4199   emit_move_insn (operands[0], const0_rtx);
4201   gcc_assert (!TARGET_PARTIAL_REG_STALL);
4202   emit_insn (gen_movstrict<mode>
4203              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4206 (define_insn_and_split "*zext<mode>_doubleword"
4207   [(set (match_operand:DI 0 "register_operand" "=r")
4208         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4209   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4210    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4211   "#"
4212   "&& reload_completed && GENERAL_REG_P (operands[0])"
4213   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4214    (set (match_dup 2) (const_int 0))]
4215   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4217 (define_insn_and_split "*zextsi_doubleword"
4218   [(set (match_operand:DI 0 "register_operand" "=r")
4219         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4220   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4221   "#"
4222   "&& reload_completed && GENERAL_REG_P (operands[0])"
4223   [(set (match_dup 0) (match_dup 1))
4224    (set (match_dup 2) (const_int 0))]
4225   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4227 ;; Sign extension instructions
4229 (define_expand "extendsidi2"
4230   [(set (match_operand:DI 0 "register_operand")
4231         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4232   ""
4234   if (!TARGET_64BIT)
4235     {
4236       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4237       DONE;
4238     }
4241 (define_insn "*extendsidi2_rex64"
4242   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4243         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4244   "TARGET_64BIT"
4245   "@
4246    {cltq|cdqe}
4247    movs{lq|x}\t{%1, %0|%0, %1}"
4248   [(set_attr "type" "imovx")
4249    (set_attr "mode" "DI")
4250    (set_attr "prefix_0f" "0")
4251    (set_attr "modrm" "0,1")])
4253 (define_insn "extendsidi2_1"
4254   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4255         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4256    (clobber (reg:CC FLAGS_REG))
4257    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4258   "!TARGET_64BIT"
4259   "#")
4261 ;; Split the memory case.  If the source register doesn't die, it will stay
4262 ;; this way, if it does die, following peephole2s take care of it.
4263 (define_split
4264   [(set (match_operand:DI 0 "memory_operand")
4265         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4266    (clobber (reg:CC FLAGS_REG))
4267    (clobber (match_operand:SI 2 "register_operand"))]
4268   "reload_completed"
4269   [(const_int 0)]
4271   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4273   emit_move_insn (operands[3], operands[1]);
4275   /* Generate a cltd if possible and doing so it profitable.  */
4276   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4277       && REGNO (operands[1]) == AX_REG
4278       && REGNO (operands[2]) == DX_REG)
4279     {
4280       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4281     }
4282   else
4283     {
4284       emit_move_insn (operands[2], operands[1]);
4285       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4286     }
4287   emit_move_insn (operands[4], operands[2]);
4288   DONE;
4291 ;; Peepholes for the case where the source register does die, after
4292 ;; being split with the above splitter.
4293 (define_peephole2
4294   [(set (match_operand:SI 0 "memory_operand")
4295         (match_operand:SI 1 "general_reg_operand"))
4296    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4297    (parallel [(set (match_dup 2)
4298                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4299                (clobber (reg:CC FLAGS_REG))])
4300    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4301   "REGNO (operands[1]) != REGNO (operands[2])
4302    && peep2_reg_dead_p (2, operands[1])
4303    && peep2_reg_dead_p (4, operands[2])
4304    && !reg_mentioned_p (operands[2], operands[3])"
4305   [(set (match_dup 0) (match_dup 1))
4306    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4307               (clobber (reg:CC FLAGS_REG))])
4308    (set (match_dup 3) (match_dup 1))])
4310 (define_peephole2
4311   [(set (match_operand:SI 0 "memory_operand")
4312         (match_operand:SI 1 "general_reg_operand"))
4313    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4314                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4315                (clobber (reg:CC FLAGS_REG))])
4316    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4317   "/* cltd is shorter than sarl $31, %eax */
4318    !optimize_function_for_size_p (cfun)
4319    && REGNO (operands[1]) == AX_REG
4320    && REGNO (operands[2]) == DX_REG
4321    && peep2_reg_dead_p (2, operands[1])
4322    && peep2_reg_dead_p (3, operands[2])
4323    && !reg_mentioned_p (operands[2], operands[3])"
4324   [(set (match_dup 0) (match_dup 1))
4325    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4326               (clobber (reg:CC FLAGS_REG))])
4327    (set (match_dup 3) (match_dup 1))])
4329 ;; Extend to register case.  Optimize case where source and destination
4330 ;; registers match and cases where we can use cltd.
4331 (define_split
4332   [(set (match_operand:DI 0 "register_operand")
4333         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4334    (clobber (reg:CC FLAGS_REG))
4335    (clobber (match_scratch:SI 2))]
4336   "reload_completed"
4337   [(const_int 0)]
4339   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4341   if (REGNO (operands[3]) != REGNO (operands[1]))
4342     emit_move_insn (operands[3], operands[1]);
4344   /* Generate a cltd if possible and doing so it profitable.  */
4345   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4346       && REGNO (operands[3]) == AX_REG
4347       && REGNO (operands[4]) == DX_REG)
4348     {
4349       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4350       DONE;
4351     }
4353   if (REGNO (operands[4]) != REGNO (operands[1]))
4354     emit_move_insn (operands[4], operands[1]);
4356   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4357   DONE;
4360 (define_insn "extend<mode>di2"
4361   [(set (match_operand:DI 0 "register_operand" "=r")
4362         (sign_extend:DI
4363          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4364   "TARGET_64BIT"
4365   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4366   [(set_attr "type" "imovx")
4367    (set_attr "mode" "DI")])
4369 (define_insn "extendhisi2"
4370   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4371         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4372   ""
4374   switch (get_attr_prefix_0f (insn))
4375     {
4376     case 0:
4377       return "{cwtl|cwde}";
4378     default:
4379       return "movs{wl|x}\t{%1, %0|%0, %1}";
4380     }
4382   [(set_attr "type" "imovx")
4383    (set_attr "mode" "SI")
4384    (set (attr "prefix_0f")
4385      ;; movsx is short decodable while cwtl is vector decoded.
4386      (if_then_else (and (eq_attr "cpu" "!k6")
4387                         (eq_attr "alternative" "0"))
4388         (const_string "0")
4389         (const_string "1")))
4390    (set (attr "znver1_decode")
4391      (if_then_else (eq_attr "prefix_0f" "0")
4392         (const_string "double")
4393         (const_string "direct")))
4394    (set (attr "modrm")
4395      (if_then_else (eq_attr "prefix_0f" "0")
4396         (const_string "0")
4397         (const_string "1")))])
4399 (define_insn "*extendhisi2_zext"
4400   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4401         (zero_extend:DI
4402          (sign_extend:SI
4403           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4404   "TARGET_64BIT"
4406   switch (get_attr_prefix_0f (insn))
4407     {
4408     case 0:
4409       return "{cwtl|cwde}";
4410     default:
4411       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4412     }
4414   [(set_attr "type" "imovx")
4415    (set_attr "mode" "SI")
4416    (set (attr "prefix_0f")
4417      ;; movsx is short decodable while cwtl is vector decoded.
4418      (if_then_else (and (eq_attr "cpu" "!k6")
4419                         (eq_attr "alternative" "0"))
4420         (const_string "0")
4421         (const_string "1")))
4422    (set (attr "modrm")
4423      (if_then_else (eq_attr "prefix_0f" "0")
4424         (const_string "0")
4425         (const_string "1")))])
4427 (define_insn "extendqisi2"
4428   [(set (match_operand:SI 0 "register_operand" "=r")
4429         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4430   ""
4431   "movs{bl|x}\t{%1, %0|%0, %1}"
4432    [(set_attr "type" "imovx")
4433     (set_attr "mode" "SI")])
4435 (define_insn "*extendqisi2_zext"
4436   [(set (match_operand:DI 0 "register_operand" "=r")
4437         (zero_extend:DI
4438           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4439   "TARGET_64BIT"
4440   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4441    [(set_attr "type" "imovx")
4442     (set_attr "mode" "SI")])
4444 (define_insn "extendqihi2"
4445   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4446         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4447   ""
4449   switch (get_attr_prefix_0f (insn))
4450     {
4451     case 0:
4452       return "{cbtw|cbw}";
4453     default:
4454       return "movs{bw|x}\t{%1, %0|%0, %1}";
4455     }
4457   [(set_attr "type" "imovx")
4458    (set_attr "mode" "HI")
4459    (set (attr "prefix_0f")
4460      ;; movsx is short decodable while cwtl is vector decoded.
4461      (if_then_else (and (eq_attr "cpu" "!k6")
4462                         (eq_attr "alternative" "0"))
4463         (const_string "0")
4464         (const_string "1")))
4465    (set (attr "modrm")
4466      (if_then_else (eq_attr "prefix_0f" "0")
4467         (const_string "0")
4468         (const_string "1")))])
4470 ;; Conversions between float and double.
4472 ;; These are all no-ops in the model used for the 80387.
4473 ;; So just emit moves.
4475 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4476 (define_split
4477   [(set (match_operand:DF 0 "push_operand")
4478         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4479   "reload_completed"
4480   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4481    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4483 (define_split
4484   [(set (match_operand:XF 0 "push_operand")
4485         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4486   "reload_completed"
4487   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4488    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4489   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4491 (define_expand "extendsfdf2"
4492   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4493         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4494   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4496   /* ??? Needed for compress_float_constant since all fp constants
4497      are TARGET_LEGITIMATE_CONSTANT_P.  */
4498   if (CONST_DOUBLE_P (operands[1]))
4499     {
4500       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4501           && standard_80387_constant_p (operands[1]) > 0)
4502         {
4503           operands[1] = simplify_const_unary_operation
4504             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4505           emit_move_insn_1 (operands[0], operands[1]);
4506           DONE;
4507         }
4508       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4509     }
4512 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4513    cvtss2sd:
4514       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4515       cvtps2pd xmm2,xmm1
4516    We do the conversion post reload to avoid producing of 128bit spills
4517    that might lead to ICE on 32bit target.  The sequence unlikely combine
4518    anyway.  */
4519 (define_split
4520   [(set (match_operand:DF 0 "sse_reg_operand")
4521         (float_extend:DF
4522           (match_operand:SF 1 "nonimmediate_operand")))]
4523   "TARGET_USE_VECTOR_FP_CONVERTS
4524    && optimize_insn_for_speed_p ()
4525    && reload_completed
4526    && (!EXT_REX_SSE_REG_P (operands[0])
4527        || TARGET_AVX512VL)"
4528    [(set (match_dup 2)
4529          (float_extend:V2DF
4530            (vec_select:V2SF
4531              (match_dup 3)
4532              (parallel [(const_int 0) (const_int 1)]))))]
4534   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4535   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4536   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4537      Try to avoid move when unpacking can be done in source.  */
4538   if (REG_P (operands[1]))
4539     {
4540       /* If it is unsafe to overwrite upper half of source, we need
4541          to move to destination and unpack there.  */
4542       if (REGNO (operands[0]) != REGNO (operands[1])
4543           || (EXT_REX_SSE_REG_P (operands[1])
4544               && !TARGET_AVX512VL))
4545         {
4546           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4547           emit_move_insn (tmp, operands[1]);
4548         }
4549       else
4550         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4551       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4552          =v, v, then vbroadcastss will be only needed for AVX512F without
4553          AVX512VL.  */
4554       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4555         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4556                                                operands[3]));
4557       else
4558         {
4559           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4560           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4561         }
4562     }
4563   else
4564     emit_insn (gen_vec_setv4sf_0 (operands[3],
4565                                   CONST0_RTX (V4SFmode), operands[1]));
4568 ;; It's more profitable to split and then extend in the same register.
4569 (define_peephole2
4570   [(set (match_operand:DF 0 "sse_reg_operand")
4571         (float_extend:DF
4572           (match_operand:SF 1 "memory_operand")))]
4573   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4574    && optimize_insn_for_speed_p ()"
4575   [(set (match_dup 2) (match_dup 1))
4576    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4577   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4579 (define_insn "*extendsfdf2"
4580   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4581         (float_extend:DF
4582           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4583   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4585   switch (which_alternative)
4586     {
4587     case 0:
4588     case 1:
4589       return output_387_reg_move (insn, operands);
4591     case 2:
4592       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4594     default:
4595       gcc_unreachable ();
4596     }
4598   [(set_attr "type" "fmov,fmov,ssecvt")
4599    (set_attr "prefix" "orig,orig,maybe_vex")
4600    (set_attr "mode" "SF,XF,DF")
4601    (set (attr "enabled")
4602      (if_then_else
4603        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4604        (if_then_else
4605          (eq_attr "alternative" "0,1")
4606          (symbol_ref "TARGET_MIX_SSE_I387")
4607          (symbol_ref "true"))
4608        (if_then_else
4609          (eq_attr "alternative" "0,1")
4610          (symbol_ref "true")
4611          (symbol_ref "false"))))])
4613 (define_expand "extend<mode>xf2"
4614   [(set (match_operand:XF 0 "nonimmediate_operand")
4615         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4616   "TARGET_80387"
4618   /* ??? Needed for compress_float_constant since all fp constants
4619      are TARGET_LEGITIMATE_CONSTANT_P.  */
4620   if (CONST_DOUBLE_P (operands[1]))
4621     {
4622       if (standard_80387_constant_p (operands[1]) > 0)
4623         {
4624           operands[1] = simplify_const_unary_operation
4625             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4626           emit_move_insn_1 (operands[0], operands[1]);
4627           DONE;
4628         }
4629       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4630     }
4633 (define_insn "*extend<mode>xf2_i387"
4634   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4635         (float_extend:XF
4636           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4637   "TARGET_80387"
4638   "* return output_387_reg_move (insn, operands);"
4639   [(set_attr "type" "fmov")
4640    (set_attr "mode" "<MODE>,XF")])
4642 ;; %%% This seems like bad news.
4643 ;; This cannot output into an f-reg because there is no way to be sure
4644 ;; of truncating in that case.  Otherwise this is just like a simple move
4645 ;; insn.  So we pretend we can output to a reg in order to get better
4646 ;; register preferencing, but we really use a stack slot.
4648 ;; Conversion from DFmode to SFmode.
4650 (define_expand "truncdfsf2"
4651   [(set (match_operand:SF 0 "nonimmediate_operand")
4652         (float_truncate:SF
4653           (match_operand:DF 1 "nonimmediate_operand")))]
4654   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4656   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4657     ;
4658   else if (flag_unsafe_math_optimizations)
4659     ;
4660   else
4661     {
4662       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4663       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4664       DONE;
4665     }
4668 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4669    cvtsd2ss:
4670       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4671       cvtpd2ps xmm2,xmm1
4672    We do the conversion post reload to avoid producing of 128bit spills
4673    that might lead to ICE on 32bit target.  The sequence unlikely combine
4674    anyway.  */
4675 (define_split
4676   [(set (match_operand:SF 0 "sse_reg_operand")
4677         (float_truncate:SF
4678           (match_operand:DF 1 "nonimmediate_operand")))]
4679   "TARGET_USE_VECTOR_FP_CONVERTS
4680    && optimize_insn_for_speed_p ()
4681    && reload_completed
4682    && (!EXT_REX_SSE_REG_P (operands[0])
4683        || TARGET_AVX512VL)"
4684    [(set (match_dup 2)
4685          (vec_concat:V4SF
4686            (float_truncate:V2SF
4687              (match_dup 4))
4688            (match_dup 3)))]
4690   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4691   operands[3] = CONST0_RTX (V2SFmode);
4692   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4693   /* Use movsd for loading from memory, unpcklpd for registers.
4694      Try to avoid move when unpacking can be done in source, or SSE3
4695      movddup is available.  */
4696   if (REG_P (operands[1]))
4697     {
4698       if (!TARGET_SSE3
4699           && REGNO (operands[0]) != REGNO (operands[1]))
4700         {
4701           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4702           emit_move_insn (tmp, operands[1]);
4703           operands[1] = tmp;
4704         }
4705       else if (!TARGET_SSE3)
4706         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4707       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4708     }
4709   else
4710     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4711                                    CONST0_RTX (DFmode)));
4714 ;; It's more profitable to split and then extend in the same register.
4715 (define_peephole2
4716   [(set (match_operand:SF 0 "sse_reg_operand")
4717         (float_truncate:SF
4718           (match_operand:DF 1 "memory_operand")))]
4719   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4720    && optimize_insn_for_speed_p ()"
4721   [(set (match_dup 2) (match_dup 1))
4722    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4723   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4725 (define_expand "truncdfsf2_with_temp"
4726   [(parallel [(set (match_operand:SF 0)
4727                    (float_truncate:SF (match_operand:DF 1)))
4728               (clobber (match_operand:SF 2))])])
4730 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4731 ;; because nothing we do there is unsafe.
4732 (define_insn "*truncdfsf_fast_mixed"
4733   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4734         (float_truncate:SF
4735           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4736   "TARGET_SSE2 && TARGET_SSE_MATH"
4738   switch (which_alternative)
4739     {
4740     case 0:
4741       return output_387_reg_move (insn, operands);
4742     case 1:
4743       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4744     default:
4745       gcc_unreachable ();
4746     }
4748   [(set_attr "type" "fmov,ssecvt")
4749    (set_attr "prefix" "orig,maybe_vex")
4750    (set_attr "mode" "SF")
4751    (set (attr "enabled")
4752      (cond [(eq_attr "alternative" "0")
4753               (symbol_ref "TARGET_MIX_SSE_I387
4754                            && flag_unsafe_math_optimizations")
4755            ]
4756            (symbol_ref "true")))])
4758 (define_insn "*truncdfsf_fast_i387"
4759   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4760         (float_truncate:SF
4761           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4762   "TARGET_80387 && flag_unsafe_math_optimizations"
4763   "* return output_387_reg_move (insn, operands);"
4764   [(set_attr "type" "fmov")
4765    (set_attr "mode" "SF")])
4767 (define_insn "*truncdfsf_mixed"
4768   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
4769         (float_truncate:SF
4770           (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4771    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4772   "TARGET_MIX_SSE_I387"
4774   switch (which_alternative)
4775     {
4776     case 0:
4777       return output_387_reg_move (insn, operands);
4778     case 1:
4779       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4781     default:
4782       return "#";
4783     }
4785   [(set_attr "isa" "*,sse2,*,*,*")
4786    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4787    (set_attr "unit" "*,*,i387,i387,i387")
4788    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4789    (set_attr "mode" "SF")])
4791 (define_insn "*truncdfsf_i387"
4792   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
4793         (float_truncate:SF
4794           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4795    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4796   "TARGET_80387"
4798   switch (which_alternative)
4799     {
4800     case 0:
4801       return output_387_reg_move (insn, operands);
4803     default:
4804       return "#";
4805     }
4807   [(set_attr "type" "fmov,multi,multi,multi")
4808    (set_attr "unit" "*,i387,i387,i387")
4809    (set_attr "mode" "SF")])
4811 (define_insn "*truncdfsf2_i387_1"
4812   [(set (match_operand:SF 0 "memory_operand" "=m")
4813         (float_truncate:SF
4814           (match_operand:DF 1 "register_operand" "f")))]
4815   "TARGET_80387
4816    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4817    && !TARGET_MIX_SSE_I387"
4818   "* return output_387_reg_move (insn, operands);"
4819   [(set_attr "type" "fmov")
4820    (set_attr "mode" "SF")])
4822 (define_split
4823   [(set (match_operand:SF 0 "register_operand")
4824         (float_truncate:SF
4825          (match_operand:DF 1 "fp_register_operand")))
4826    (clobber (match_operand 2))]
4827   "reload_completed"
4828   [(set (match_dup 2) (match_dup 1))
4829    (set (match_dup 0) (match_dup 2))]
4830   "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4832 ;; Conversion from XFmode to {SF,DF}mode
4834 (define_expand "truncxf<mode>2"
4835   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4836                    (float_truncate:MODEF
4837                      (match_operand:XF 1 "register_operand")))
4838               (clobber (match_dup 2))])]
4839   "TARGET_80387"
4841   if (flag_unsafe_math_optimizations)
4842     {
4843       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4844       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4845       if (reg != operands[0])
4846         emit_move_insn (operands[0], reg);
4847       DONE;
4848     }
4849   else
4850     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4853 (define_insn "*truncxfsf2_mixed"
4854   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4855         (float_truncate:SF
4856           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4857    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4858   "TARGET_80387"
4860   gcc_assert (!which_alternative);
4861   return output_387_reg_move (insn, operands);
4863   [(set_attr "type" "fmov,multi,multi,multi")
4864    (set_attr "unit" "*,i387,i387,i387")
4865    (set_attr "mode" "SF")])
4867 (define_insn "*truncxfdf2_mixed"
4868   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4869         (float_truncate:DF
4870           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4871    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4872   "TARGET_80387"
4874   gcc_assert (!which_alternative);
4875   return output_387_reg_move (insn, operands);
4877   [(set_attr "isa" "*,*,sse2,*")
4878    (set_attr "type" "fmov,multi,multi,multi")
4879    (set_attr "unit" "*,i387,i387,i387")
4880    (set_attr "mode" "DF")])
4882 (define_insn "truncxf<mode>2_i387_noop"
4883   [(set (match_operand:MODEF 0 "register_operand" "=f")
4884         (float_truncate:MODEF
4885           (match_operand:XF 1 "register_operand" "f")))]
4886   "TARGET_80387 && flag_unsafe_math_optimizations"
4887   "* return output_387_reg_move (insn, operands);"
4888   [(set_attr "type" "fmov")
4889    (set_attr "mode" "<MODE>")])
4891 (define_insn "*truncxf<mode>2_i387"
4892   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4893         (float_truncate:MODEF
4894           (match_operand:XF 1 "register_operand" "f")))]
4895   "TARGET_80387"
4896   "* return output_387_reg_move (insn, operands);"
4897   [(set_attr "type" "fmov")
4898    (set_attr "mode" "<MODE>")])
4900 (define_split
4901   [(set (match_operand:MODEF 0 "register_operand")
4902         (float_truncate:MODEF
4903           (match_operand:XF 1 "register_operand")))
4904    (clobber (match_operand:MODEF 2 "memory_operand"))]
4905   "TARGET_80387 && reload_completed"
4906   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4907    (set (match_dup 0) (match_dup 2))])
4909 (define_split
4910   [(set (match_operand:MODEF 0 "memory_operand")
4911         (float_truncate:MODEF
4912           (match_operand:XF 1 "register_operand")))
4913    (clobber (match_operand:MODEF 2 "memory_operand"))]
4914   "TARGET_80387"
4915   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4917 ;; Signed conversion to DImode.
4919 (define_expand "fix_truncxfdi2"
4920   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4921                    (fix:DI (match_operand:XF 1 "register_operand")))
4922               (clobber (reg:CC FLAGS_REG))])]
4923   "TARGET_80387"
4925   if (TARGET_FISTTP)
4926    {
4927      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4928      DONE;
4929    }
4932 (define_expand "fix_trunc<mode>di2"
4933   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4934                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4935               (clobber (reg:CC FLAGS_REG))])]
4936   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4938   if (TARGET_FISTTP
4939       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4940    {
4941      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4942      DONE;
4943    }
4944   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4945    {
4946      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4947      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4948      if (out != operands[0])
4949         emit_move_insn (operands[0], out);
4950      DONE;
4951    }
4954 ;; Signed conversion to SImode.
4956 (define_expand "fix_truncxfsi2"
4957   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4958                    (fix:SI (match_operand:XF 1 "register_operand")))
4959               (clobber (reg:CC FLAGS_REG))])]
4960   "TARGET_80387"
4962   if (TARGET_FISTTP)
4963    {
4964      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4965      DONE;
4966    }
4969 (define_expand "fix_trunc<mode>si2"
4970   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4971                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4972               (clobber (reg:CC FLAGS_REG))])]
4973   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4975   if (TARGET_FISTTP
4976       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4977    {
4978      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4979      DONE;
4980    }
4981   if (SSE_FLOAT_MODE_P (<MODE>mode))
4982    {
4983      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4984      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4985      if (out != operands[0])
4986         emit_move_insn (operands[0], out);
4987      DONE;
4988    }
4991 ;; Signed conversion to HImode.
4993 (define_expand "fix_trunc<mode>hi2"
4994   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4995                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4996               (clobber (reg:CC FLAGS_REG))])]
4997   "TARGET_80387
4998    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5000   if (TARGET_FISTTP)
5001    {
5002      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5003      DONE;
5004    }
5007 ;; Unsigned conversion to DImode
5009 (define_insn "fixuns_trunc<mode>di2"
5010   [(set (match_operand:DI 0 "register_operand" "=r")
5011         (unsigned_fix:DI
5012           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5013   "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5014   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5015   [(set_attr "type" "sseicvt")
5016    (set_attr "prefix" "evex")
5017    (set_attr "mode" "DI")])
5019 ;; Unsigned conversion to SImode.
5021 (define_expand "fixuns_trunc<mode>si2"
5022   [(parallel
5023     [(set (match_operand:SI 0 "register_operand")
5024           (unsigned_fix:SI
5025             (match_operand:MODEF 1 "nonimmediate_operand")))
5026      (use (match_dup 2))
5027      (clobber (match_scratch:<ssevecmode> 3))
5028      (clobber (match_scratch:<ssevecmode> 4))])]
5029   "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5031   machine_mode mode = <MODE>mode;
5032   machine_mode vecmode = <ssevecmode>mode;
5033   REAL_VALUE_TYPE TWO31r;
5034   rtx two31;
5036   if (TARGET_AVX512F)
5037     {
5038       emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5039       DONE;
5040     }
5042   if (optimize_insn_for_size_p ())
5043     FAIL;
5045   real_ldexp (&TWO31r, &dconst1, 31);
5046   two31 = const_double_from_real_value (TWO31r, mode);
5047   two31 = ix86_build_const_vector (vecmode, true, two31);
5048   operands[2] = force_reg (vecmode, two31);
5051 (define_insn "fixuns_trunc<mode>si2_avx512f"
5052   [(set (match_operand:SI 0 "register_operand" "=r")
5053         (unsigned_fix:SI
5054           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5055   "TARGET_AVX512F && TARGET_SSE_MATH"
5056   "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5057   [(set_attr "type" "sseicvt")
5058    (set_attr "prefix" "evex")
5059    (set_attr "mode" "SI")])
5061 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5062   [(set (match_operand:DI 0 "register_operand" "=r")
5063         (zero_extend:DI
5064           (unsigned_fix:SI
5065             (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5066   "TARGET_64BIT && TARGET_AVX512F"
5067   "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5068   [(set_attr "type" "sseicvt")
5069    (set_attr "prefix" "evex")
5070    (set_attr "mode" "SI")])
5072 (define_insn_and_split "*fixuns_trunc<mode>_1"
5073   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5074         (unsigned_fix:SI
5075           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5076    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5077    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5078    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5079   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5080    && optimize_function_for_speed_p (cfun)"
5081   "#"
5082   "&& reload_completed"
5083   [(const_int 0)]
5085   ix86_split_convert_uns_si_sse (operands);
5086   DONE;
5089 ;; Unsigned conversion to HImode.
5090 ;; Without these patterns, we'll try the unsigned SI conversion which
5091 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5093 (define_expand "fixuns_trunc<mode>hi2"
5094   [(set (match_dup 2)
5095         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5096    (set (match_operand:HI 0 "nonimmediate_operand")
5097         (subreg:HI (match_dup 2) 0))]
5098   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5099   "operands[2] = gen_reg_rtx (SImode);")
5101 ;; When SSE is available, it is always faster to use it!
5102 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5103   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5104         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5105   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5106    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5107   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5108   [(set_attr "type" "sseicvt")
5109    (set_attr "prefix" "maybe_vex")
5110    (set (attr "prefix_rex")
5111         (if_then_else
5112           (match_test "<SWI48:MODE>mode == DImode")
5113           (const_string "1")
5114           (const_string "*")))
5115    (set_attr "mode" "<MODEF:MODE>")
5116    (set_attr "athlon_decode" "double,vector")
5117    (set_attr "amdfam10_decode" "double,double")
5118    (set_attr "bdver1_decode" "double,double")])
5120 ;; Avoid vector decoded forms of the instruction.
5121 (define_peephole2
5122   [(match_scratch:MODEF 2 "x")
5123    (set (match_operand:SWI48 0 "register_operand")
5124         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5125   "TARGET_AVOID_VECTOR_DECODE
5126    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5127    && optimize_insn_for_speed_p ()"
5128   [(set (match_dup 2) (match_dup 1))
5129    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5131 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5132   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5133         (fix:SWI248x (match_operand 1 "register_operand")))]
5134   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5135    && TARGET_FISTTP
5136    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5137          && (TARGET_64BIT || <MODE>mode != DImode))
5138         && TARGET_SSE_MATH)
5139    && can_create_pseudo_p ()"
5140   "#"
5141   "&& 1"
5142   [(const_int 0)]
5144   if (memory_operand (operands[0], VOIDmode))
5145     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5146   else
5147     {
5148       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5149       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5150                                                             operands[1],
5151                                                             operands[2]));
5152     }
5153   DONE;
5155   [(set_attr "type" "fisttp")
5156    (set_attr "mode" "<MODE>")])
5158 (define_insn "fix_trunc<mode>_i387_fisttp"
5159   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5160         (fix:SWI248x (match_operand 1 "register_operand" "f")))
5161    (clobber (match_scratch:XF 2 "=&1f"))]
5162   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5163    && TARGET_FISTTP
5164    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5165          && (TARGET_64BIT || <MODE>mode != DImode))
5166         && TARGET_SSE_MATH)"
5167   "* return output_fix_trunc (insn, operands, true);"
5168   [(set_attr "type" "fisttp")
5169    (set_attr "mode" "<MODE>")])
5171 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5172   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5173         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5174    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5175    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5176   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5177    && TARGET_FISTTP
5178    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5179         && (TARGET_64BIT || <MODE>mode != DImode))
5180         && TARGET_SSE_MATH)"
5181   "#"
5182   [(set_attr "type" "fisttp")
5183    (set_attr "mode" "<MODE>")])
5185 (define_split
5186   [(set (match_operand:SWI248x 0 "register_operand")
5187         (fix:SWI248x (match_operand 1 "register_operand")))
5188    (clobber (match_operand:SWI248x 2 "memory_operand"))
5189    (clobber (match_scratch 3))]
5190   "reload_completed"
5191   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5192               (clobber (match_dup 3))])
5193    (set (match_dup 0) (match_dup 2))])
5195 (define_split
5196   [(set (match_operand:SWI248x 0 "memory_operand")
5197         (fix:SWI248x (match_operand 1 "register_operand")))
5198    (clobber (match_operand:SWI248x 2 "memory_operand"))
5199    (clobber (match_scratch 3))]
5200   "reload_completed"
5201   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5202               (clobber (match_dup 3))])])
5204 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5205 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5206 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5207 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5208 ;; function in i386.c.
5209 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5210   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5211         (fix:SWI248x (match_operand 1 "register_operand")))
5212    (clobber (reg:CC FLAGS_REG))]
5213   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5214    && !TARGET_FISTTP
5215    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5216          && (TARGET_64BIT || <MODE>mode != DImode))
5217    && can_create_pseudo_p ()"
5218   "#"
5219   "&& 1"
5220   [(const_int 0)]
5222   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5224   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5225   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5226   if (memory_operand (operands[0], VOIDmode))
5227     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5228                                          operands[2], operands[3]));
5229   else
5230     {
5231       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5232       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5233                                                      operands[2], operands[3],
5234                                                      operands[4]));
5235     }
5236   DONE;
5238   [(set_attr "type" "fistp")
5239    (set_attr "i387_cw" "trunc")
5240    (set_attr "mode" "<MODE>")])
5242 (define_insn "fix_truncdi_i387"
5243   [(set (match_operand:DI 0 "memory_operand" "=m")
5244         (fix:DI (match_operand 1 "register_operand" "f")))
5245    (use (match_operand:HI 2 "memory_operand" "m"))
5246    (use (match_operand:HI 3 "memory_operand" "m"))
5247    (clobber (match_scratch:XF 4 "=&1f"))]
5248   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5249    && !TARGET_FISTTP
5250    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5251   "* return output_fix_trunc (insn, operands, false);"
5252   [(set_attr "type" "fistp")
5253    (set_attr "i387_cw" "trunc")
5254    (set_attr "mode" "DI")])
5256 (define_insn "fix_truncdi_i387_with_temp"
5257   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5258         (fix:DI (match_operand 1 "register_operand" "f,f")))
5259    (use (match_operand:HI 2 "memory_operand" "m,m"))
5260    (use (match_operand:HI 3 "memory_operand" "m,m"))
5261    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5262    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5263   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5264    && !TARGET_FISTTP
5265    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5266   "#"
5267   [(set_attr "type" "fistp")
5268    (set_attr "i387_cw" "trunc")
5269    (set_attr "mode" "DI")])
5271 (define_split
5272   [(set (match_operand:DI 0 "register_operand")
5273         (fix:DI (match_operand 1 "register_operand")))
5274    (use (match_operand:HI 2 "memory_operand"))
5275    (use (match_operand:HI 3 "memory_operand"))
5276    (clobber (match_operand:DI 4 "memory_operand"))
5277    (clobber (match_scratch 5))]
5278   "reload_completed"
5279   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5280               (use (match_dup 2))
5281               (use (match_dup 3))
5282               (clobber (match_dup 5))])
5283    (set (match_dup 0) (match_dup 4))])
5285 (define_split
5286   [(set (match_operand:DI 0 "memory_operand")
5287         (fix:DI (match_operand 1 "register_operand")))
5288    (use (match_operand:HI 2 "memory_operand"))
5289    (use (match_operand:HI 3 "memory_operand"))
5290    (clobber (match_operand:DI 4 "memory_operand"))
5291    (clobber (match_scratch 5))]
5292   "reload_completed"
5293   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5294               (use (match_dup 2))
5295               (use (match_dup 3))
5296               (clobber (match_dup 5))])])
5298 (define_insn "fix_trunc<mode>_i387"
5299   [(set (match_operand:SWI24 0 "memory_operand" "=m")
5300         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5301    (use (match_operand:HI 2 "memory_operand" "m"))
5302    (use (match_operand:HI 3 "memory_operand" "m"))]
5303   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5304    && !TARGET_FISTTP
5305    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5306   "* return output_fix_trunc (insn, operands, false);"
5307   [(set_attr "type" "fistp")
5308    (set_attr "i387_cw" "trunc")
5309    (set_attr "mode" "<MODE>")])
5311 (define_insn "fix_trunc<mode>_i387_with_temp"
5312   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5313         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5314    (use (match_operand:HI 2 "memory_operand" "m,m"))
5315    (use (match_operand:HI 3 "memory_operand" "m,m"))
5316    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5317   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5318    && !TARGET_FISTTP
5319    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5320   "#"
5321   [(set_attr "type" "fistp")
5322    (set_attr "i387_cw" "trunc")
5323    (set_attr "mode" "<MODE>")])
5325 (define_split
5326   [(set (match_operand:SWI24 0 "register_operand")
5327         (fix:SWI24 (match_operand 1 "register_operand")))
5328    (use (match_operand:HI 2 "memory_operand"))
5329    (use (match_operand:HI 3 "memory_operand"))
5330    (clobber (match_operand:SWI24 4 "memory_operand"))]
5331   "reload_completed"
5332   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5333               (use (match_dup 2))
5334               (use (match_dup 3))])
5335    (set (match_dup 0) (match_dup 4))])
5337 (define_split
5338   [(set (match_operand:SWI24 0 "memory_operand")
5339         (fix:SWI24 (match_operand 1 "register_operand")))
5340    (use (match_operand:HI 2 "memory_operand"))
5341    (use (match_operand:HI 3 "memory_operand"))
5342    (clobber (match_operand:SWI24 4 "memory_operand"))]
5343   "reload_completed"
5344   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5345               (use (match_dup 2))
5346               (use (match_dup 3))])])
5348 (define_insn "x86_fnstcw_1"
5349   [(set (match_operand:HI 0 "memory_operand" "=m")
5350         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5351   "TARGET_80387"
5352   "fnstcw\t%0"
5353   [(set (attr "length")
5354         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5355    (set_attr "mode" "HI")
5356    (set_attr "unit" "i387")
5357    (set_attr "bdver1_decode" "vector")])
5359 (define_insn "x86_fldcw_1"
5360   [(set (reg:HI FPCR_REG)
5361         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5362   "TARGET_80387"
5363   "fldcw\t%0"
5364   [(set (attr "length")
5365         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5366    (set_attr "mode" "HI")
5367    (set_attr "unit" "i387")
5368    (set_attr "athlon_decode" "vector")
5369    (set_attr "amdfam10_decode" "vector")
5370    (set_attr "bdver1_decode" "vector")])
5372 ;; Conversion between fixed point and floating point.
5374 ;; Even though we only accept memory inputs, the backend _really_
5375 ;; wants to be able to do this between registers.  Thankfully, LRA
5376 ;; will fix this up for us during register allocation.
5378 (define_insn "floathi<mode>2"
5379   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5380         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5381   "TARGET_80387
5382    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5383        || TARGET_MIX_SSE_I387)"
5384   "fild%Z1\t%1"
5385   [(set_attr "type" "fmov")
5386    (set_attr "mode" "<MODE>")
5387    (set_attr "znver1_decode" "double")
5388    (set_attr "fp_int_src" "true")])
5390 (define_insn "float<SWI48x:mode>xf2"
5391   [(set (match_operand:XF 0 "register_operand" "=f")
5392         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5393   "TARGET_80387"
5394   "fild%Z1\t%1"
5395   [(set_attr "type" "fmov")
5396    (set_attr "mode" "XF")
5397    (set_attr "znver1_decode" "double")
5398    (set_attr "fp_int_src" "true")])
5400 (define_expand "float<SWI48:mode><MODEF:mode>2"
5401   [(set (match_operand:MODEF 0 "register_operand")
5402         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5403   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5405   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5406       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5407     {
5408       rtx reg = gen_reg_rtx (XFmode);
5409       rtx (*insn)(rtx, rtx);
5411       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5413       if (<MODEF:MODE>mode == SFmode)
5414         insn = gen_truncxfsf2;
5415       else if (<MODEF:MODE>mode == DFmode)
5416         insn = gen_truncxfdf2;
5417       else
5418         gcc_unreachable ();
5420       emit_insn (insn (operands[0], reg));
5421       DONE;
5422     }
5425 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5426   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5427         (float:MODEF
5428           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5429   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5430   "@
5431    fild%Z1\t%1
5432    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5433    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5434   [(set_attr "type" "fmov,sseicvt,sseicvt")
5435    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5436    (set_attr "mode" "<MODEF:MODE>")
5437    (set (attr "prefix_rex")
5438      (if_then_else
5439        (and (eq_attr "prefix" "maybe_vex")
5440             (match_test "<SWI48:MODE>mode == DImode"))
5441        (const_string "1")
5442        (const_string "*")))
5443    (set_attr "unit" "i387,*,*")
5444    (set_attr "athlon_decode" "*,double,direct")
5445    (set_attr "amdfam10_decode" "*,vector,double")
5446    (set_attr "bdver1_decode" "*,double,direct")
5447    (set_attr "znver1_decode" "double,*,*")
5448    (set_attr "fp_int_src" "true")
5449    (set (attr "enabled")
5450      (cond [(eq_attr "alternative" "0")
5451               (symbol_ref "TARGET_MIX_SSE_I387
5452                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5453                                                 <SWI48:MODE>mode)")
5454            ]
5455            (symbol_ref "true")))
5456    (set (attr "preferred_for_speed")
5457      (cond [(eq_attr "alternative" "1")
5458               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5459            (symbol_ref "true")))])
5461 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5462   [(set (match_operand:MODEF 0 "register_operand" "=f")
5463         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5464   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5465   "fild%Z1\t%1"
5466   [(set_attr "type" "fmov")
5467    (set_attr "mode" "<MODEF:MODE>")
5468    (set_attr "znver1_decode" "double")
5469    (set_attr "fp_int_src" "true")])
5471 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5472 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5473 ;; alternative in sse2_loadld.
5474 (define_split
5475   [(set (match_operand:MODEF 0 "sse_reg_operand")
5476         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5477   "TARGET_SSE2
5478    && TARGET_USE_VECTOR_CONVERTS
5479    && optimize_function_for_speed_p (cfun)
5480    && reload_completed
5481    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5482    && (!EXT_REX_SSE_REG_P (operands[0])
5483        || TARGET_AVX512VL)"
5484   [(const_int 0)]
5486   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5487   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5489   emit_insn (gen_sse2_loadld (operands[4],
5490                               CONST0_RTX (V4SImode), operands[1]));
5492   if (<ssevecmode>mode == V4SFmode)
5493     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5494   else
5495     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5496   DONE;
5499 ;; Avoid partial SSE register dependency stalls.  This splitter should split
5500 ;; late in the pass sequence (after register rename pass), so allocated
5501 ;; registers won't change anymore
5503 (define_split
5504   [(set (match_operand:MODEF 0 "sse_reg_operand")
5505         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5506   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5507    && optimize_function_for_speed_p (cfun)
5508    && (!EXT_REX_SSE_REG_P (operands[0])
5509        || TARGET_AVX512VL)"
5510   [(set (match_dup 0)
5511         (vec_merge:<MODEF:ssevecmode>
5512           (vec_duplicate:<MODEF:ssevecmode>
5513             (float:MODEF
5514               (match_dup 1)))
5515           (match_dup 0)
5516           (const_int 1)))]
5518   const machine_mode vmode = <MODEF:ssevecmode>mode;
5520   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5521   emit_move_insn (operands[0], CONST0_RTX (vmode));
5524 ;; Break partial reg stall for cvtsd2ss.  This splitter should split
5525 ;; late in the pass sequence (after register rename pass),
5526 ;; so allocated registers won't change anymore.
5528 (define_split
5529   [(set (match_operand:SF 0 "sse_reg_operand")
5530         (float_truncate:SF
5531           (match_operand:DF 1 "nonimmediate_operand")))]
5532   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5533    && optimize_function_for_speed_p (cfun)
5534    && (!REG_P (operands[1])
5535        || REGNO (operands[0]) != REGNO (operands[1]))
5536    && (!EXT_REX_SSE_REG_P (operands[0])
5537        || TARGET_AVX512VL)"
5538   [(set (match_dup 0)
5539         (vec_merge:V4SF
5540           (vec_duplicate:V4SF
5541             (float_truncate:SF
5542               (match_dup 1)))
5543           (match_dup 0)
5544           (const_int 1)))]
5546   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5547   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5550 ;; Break partial reg stall for cvtss2sd.  This splitter should split
5551 ;; late in the pass sequence (after register rename pass),
5552 ;; so allocated registers won't change anymore.
5554 (define_split
5555   [(set (match_operand:DF 0 "sse_reg_operand")
5556         (float_extend:DF
5557           (match_operand:SF 1 "nonimmediate_operand")))]
5558   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5559    && optimize_function_for_speed_p (cfun)
5560    && (!REG_P (operands[1])
5561        || REGNO (operands[0]) != REGNO (operands[1]))
5562    && (!EXT_REX_SSE_REG_P (operands[0])
5563        || TARGET_AVX512VL)"
5564   [(set (match_dup 0)
5565         (vec_merge:V2DF
5566           (vec_duplicate:V2DF
5567             (float_extend:DF
5568               (match_dup 1)))
5569           (match_dup 0)
5570           (const_int 1)))]
5572   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5573   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5576 ;; Avoid store forwarding (partial memory) stall penalty
5577 ;; by passing DImode value through XMM registers.  */
5579 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5580   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5581         (float:X87MODEF
5582           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5583    (clobber (match_scratch:V4SI 3 "=X,x"))
5584    (clobber (match_scratch:V4SI 4 "=X,x"))
5585    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5586   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5587    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5588    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5589   "#"
5590   [(set_attr "type" "multi")
5591    (set_attr "mode" "<X87MODEF:MODE>")
5592    (set_attr "unit" "i387")
5593    (set_attr "fp_int_src" "true")])
5595 (define_split
5596   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5597         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5598    (clobber (match_scratch:V4SI 3))
5599    (clobber (match_scratch:V4SI 4))
5600    (clobber (match_operand:DI 2 "memory_operand"))]
5601   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5602    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5603    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5604    && reload_completed"
5605   [(set (match_dup 2) (match_dup 3))
5606    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5608   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5609      Assemble the 64-bit DImode value in an xmm register.  */
5610   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5611                               gen_lowpart (SImode, operands[1])));
5612   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5613                               gen_highpart (SImode, operands[1])));
5614   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5615                                          operands[4]));
5617   operands[3] = gen_lowpart (DImode, operands[3]);
5620 (define_split
5621   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5622         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5623    (clobber (match_scratch:V4SI 3))
5624    (clobber (match_scratch:V4SI 4))
5625    (clobber (match_operand:DI 2 "memory_operand"))]
5626   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5627    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5628    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5629    && reload_completed"
5630   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5632 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5633   [(set (match_operand:MODEF 0 "register_operand")
5634         (unsigned_float:MODEF
5635           (match_operand:SWI12 1 "nonimmediate_operand")))]
5636   "!TARGET_64BIT
5637    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5639   operands[1] = convert_to_mode (SImode, operands[1], 1);
5640   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5641   DONE;
5644 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5645   [(set (match_operand:MODEF 0 "register_operand" "=v")
5646         (unsigned_float:MODEF
5647           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5648   "TARGET_AVX512F && TARGET_SSE_MATH"
5649   "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5650   [(set_attr "type" "sseicvt")
5651    (set_attr "prefix" "evex")
5652    (set_attr "mode" "<MODEF:MODE>")])
5654 ;; Avoid store forwarding (partial memory) stall penalty by extending
5655 ;; SImode value to DImode through XMM register instead of pushing two
5656 ;; SImode values to stack. Also note that fild loads from memory only.
5658 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5659   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5660         (unsigned_float:X87MODEF
5661           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5662    (clobber (match_operand:DI 2 "memory_operand" "=m"))
5663    (clobber (match_scratch:DI 3 "=x"))]
5664   "!TARGET_64BIT
5665    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5666    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5667   "#"
5668   "&& reload_completed"
5669   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5670    (set (match_dup 2) (match_dup 3))
5671    (set (match_dup 0)
5672         (float:X87MODEF (match_dup 2)))]
5673   ""
5674   [(set_attr "type" "multi")
5675    (set_attr "mode" "<MODE>")])
5677 (define_expand "floatunssi<mode>2"
5678   [(set (match_operand:X87MODEF 0 "register_operand")
5679         (unsigned_float:X87MODEF
5680           (match_operand:SI 1 "nonimmediate_operand")))]
5681   "(!TARGET_64BIT
5682     && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5683     && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5684    || ((!TARGET_64BIT || TARGET_AVX512F)
5685        && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5687   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5688     {
5689       emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5690                   (operands[0], operands[1],
5691                    assign_386_stack_local (DImode, SLOT_TEMP)));
5692       DONE;
5693     }
5694   if (!TARGET_AVX512F)
5695     {
5696       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5697       DONE;
5698     }
5701 (define_expand "floatunsdisf2"
5702   [(set (match_operand:SF 0 "register_operand")
5703         (unsigned_float:SF
5704           (match_operand:DI 1 "nonimmediate_operand")))]
5705   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5707   if (!TARGET_AVX512F)
5708     {
5709       x86_emit_floatuns (operands);
5710       DONE;
5711     }
5714 (define_expand "floatunsdidf2"
5715   [(set (match_operand:DF 0 "register_operand")
5716         (unsigned_float:DF
5717           (match_operand:DI 1 "nonimmediate_operand")))]
5718   "(TARGET_KEEPS_VECTOR_ALIGNED_STACK || TARGET_AVX512F)
5719    && TARGET_SSE2 && TARGET_SSE_MATH"
5721   if (!TARGET_64BIT)
5722     {
5723       ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5724       DONE;
5725     }
5726   if (!TARGET_AVX512F)
5727     {
5728       x86_emit_floatuns (operands);
5729       DONE;
5730     }
5733 ;; Load effective address instructions
5735 (define_insn_and_split "*lea<mode>"
5736   [(set (match_operand:SWI48 0 "register_operand" "=r")
5737         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5738   ""
5740   if (SImode_address_operand (operands[1], VOIDmode))
5741     {
5742       gcc_assert (TARGET_64BIT);
5743       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5744     }
5745   else 
5746     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5748   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5749   [(const_int 0)]
5751   machine_mode mode = <MODE>mode;
5752   rtx pat;
5754   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5755      change operands[] array behind our back.  */
5756   pat = PATTERN (curr_insn);
5758   operands[0] = SET_DEST (pat);
5759   operands[1] = SET_SRC (pat);
5761   /* Emit all operations in SImode for zero-extended addresses.  */
5762   if (SImode_address_operand (operands[1], VOIDmode))
5763     mode = SImode;
5765   ix86_split_lea_for_addr (curr_insn, operands, mode);
5767   /* Zero-extend return register to DImode for zero-extended addresses.  */
5768   if (mode != <MODE>mode)
5769     emit_insn (gen_zero_extendsidi2
5770                (operands[0], gen_lowpart (mode, operands[0])));
5772   DONE;
5774   [(set_attr "type" "lea")
5775    (set (attr "mode")
5776      (if_then_else
5777        (match_operand 1 "SImode_address_operand")
5778        (const_string "SI")
5779        (const_string "<MODE>")))])
5781 ;; Add instructions
5783 (define_expand "add<mode>3"
5784   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5785         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5786                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5787   ""
5788   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5790 (define_insn_and_split "*add<dwi>3_doubleword"
5791   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5792         (plus:<DWI>
5793           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5794           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5795                                                         "ro<di>,r<di>")))
5796    (clobber (reg:CC FLAGS_REG))]
5797   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5798   "#"
5799   "reload_completed"
5800   [(parallel [(set (reg:CCC FLAGS_REG)
5801                    (compare:CCC
5802                      (plus:DWIH (match_dup 1) (match_dup 2))
5803                      (match_dup 1)))
5804               (set (match_dup 0)
5805                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5806    (parallel [(set (match_dup 3)
5807                    (plus:DWIH
5808                      (plus:DWIH
5809                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5810                        (match_dup 4))
5811                      (match_dup 5)))
5812               (clobber (reg:CC FLAGS_REG))])]
5814   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5815   if (operands[2] == const0_rtx)
5816     {
5817       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5818       DONE;
5819     }
5822 (define_insn "*add<mode>_1"
5823   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5824         (plus:SWI48
5825           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5826           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5827    (clobber (reg:CC FLAGS_REG))]
5828   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5830   switch (get_attr_type (insn))
5831     {
5832     case TYPE_LEA:
5833       return "#";
5835     case TYPE_INCDEC:
5836       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5837       if (operands[2] == const1_rtx)
5838         return "inc{<imodesuffix>}\t%0";
5839       else
5840         {
5841           gcc_assert (operands[2] == constm1_rtx);
5842           return "dec{<imodesuffix>}\t%0";
5843         }
5845     default:
5846       /* For most processors, ADD is faster than LEA.  This alternative
5847          was added to use ADD as much as possible.  */
5848       if (which_alternative == 2)
5849         std::swap (operands[1], operands[2]);
5850         
5851       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5852       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5853         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5855       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5856     }
5858   [(set (attr "type")
5859      (cond [(eq_attr "alternative" "3")
5860               (const_string "lea")
5861             (match_operand:SWI48 2 "incdec_operand")
5862               (const_string "incdec")
5863            ]
5864            (const_string "alu")))
5865    (set (attr "length_immediate")
5866       (if_then_else
5867         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5868         (const_string "1")
5869         (const_string "*")))
5870    (set_attr "mode" "<MODE>")])
5872 ;; It may seem that nonimmediate operand is proper one for operand 1.
5873 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5874 ;; we take care in ix86_binary_operator_ok to not allow two memory
5875 ;; operands so proper swapping will be done in reload.  This allow
5876 ;; patterns constructed from addsi_1 to match.
5878 (define_insn "addsi_1_zext"
5879   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5880         (zero_extend:DI
5881           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5882                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5883    (clobber (reg:CC FLAGS_REG))]
5884   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5886   switch (get_attr_type (insn))
5887     {
5888     case TYPE_LEA:
5889       return "#";
5891     case TYPE_INCDEC:
5892       if (operands[2] == const1_rtx)
5893         return "inc{l}\t%k0";
5894       else
5895         {
5896           gcc_assert (operands[2] == constm1_rtx);
5897           return "dec{l}\t%k0";
5898         }
5900     default:
5901       /* For most processors, ADD is faster than LEA.  This alternative
5902          was added to use ADD as much as possible.  */
5903       if (which_alternative == 1)
5904         std::swap (operands[1], operands[2]);
5906       if (x86_maybe_negate_const_int (&operands[2], SImode))
5907         return "sub{l}\t{%2, %k0|%k0, %2}";
5909       return "add{l}\t{%2, %k0|%k0, %2}";
5910     }
5912   [(set (attr "type")
5913      (cond [(eq_attr "alternative" "2")
5914               (const_string "lea")
5915             (match_operand:SI 2 "incdec_operand")
5916               (const_string "incdec")
5917            ]
5918            (const_string "alu")))
5919    (set (attr "length_immediate")
5920       (if_then_else
5921         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5922         (const_string "1")
5923         (const_string "*")))
5924    (set_attr "mode" "SI")])
5926 (define_insn "*addhi_1"
5927   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5928         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5929                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5930    (clobber (reg:CC FLAGS_REG))]
5931   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5933   switch (get_attr_type (insn))
5934     {
5935     case TYPE_LEA:
5936       return "#";
5938     case TYPE_INCDEC:
5939       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5940       if (operands[2] == const1_rtx)
5941         return "inc{w}\t%0";
5942       else
5943         {
5944           gcc_assert (operands[2] == constm1_rtx);
5945           return "dec{w}\t%0";
5946         }
5948     default:
5949       /* For most processors, ADD is faster than LEA.  This alternative
5950          was added to use ADD as much as possible.  */
5951       if (which_alternative == 2)
5952         std::swap (operands[1], operands[2]);
5954       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5955       if (x86_maybe_negate_const_int (&operands[2], HImode))
5956         return "sub{w}\t{%2, %0|%0, %2}";
5958       return "add{w}\t{%2, %0|%0, %2}";
5959     }
5961   [(set (attr "type")
5962      (cond [(eq_attr "alternative" "3")
5963               (const_string "lea")
5964             (match_operand:HI 2 "incdec_operand")
5965               (const_string "incdec")
5966            ]
5967            (const_string "alu")))
5968    (set (attr "length_immediate")
5969       (if_then_else
5970         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5971         (const_string "1")
5972         (const_string "*")))
5973    (set_attr "mode" "HI,HI,HI,SI")])
5975 (define_insn "*addqi_1"
5976   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5977         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5978                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5979    (clobber (reg:CC FLAGS_REG))]
5980   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5982   bool widen = (get_attr_mode (insn) != MODE_QI);
5984   switch (get_attr_type (insn))
5985     {
5986     case TYPE_LEA:
5987       return "#";
5989     case TYPE_INCDEC:
5990       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5991       if (operands[2] == const1_rtx)
5992         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5993       else
5994         {
5995           gcc_assert (operands[2] == constm1_rtx);
5996           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5997         }
5999     default:
6000       /* For most processors, ADD is faster than LEA.  These alternatives
6001          were added to use ADD as much as possible.  */
6002       if (which_alternative == 2 || which_alternative == 4)
6003         std::swap (operands[1], operands[2]);
6005       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6006       if (x86_maybe_negate_const_int (&operands[2], QImode))
6007         {
6008           if (widen)
6009             return "sub{l}\t{%2, %k0|%k0, %2}";
6010           else
6011             return "sub{b}\t{%2, %0|%0, %2}";
6012         }
6013       if (widen)
6014         return "add{l}\t{%k2, %k0|%k0, %k2}";
6015       else
6016         return "add{b}\t{%2, %0|%0, %2}";
6017     }
6019   [(set (attr "type")
6020      (cond [(eq_attr "alternative" "5")
6021               (const_string "lea")
6022             (match_operand:QI 2 "incdec_operand")
6023               (const_string "incdec")
6024            ]
6025            (const_string "alu")))
6026    (set (attr "length_immediate")
6027       (if_then_else
6028         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6029         (const_string "1")
6030         (const_string "*")))
6031    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6032    ;; Potential partial reg stall on alternatives 3 and 4.
6033    (set (attr "preferred_for_speed")
6034      (cond [(eq_attr "alternative" "3,4")
6035               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6036            (symbol_ref "true")))])
6038 (define_insn "*addqi_1_slp"
6039   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6040         (plus:QI (match_dup 0)
6041                  (match_operand:QI 1 "general_operand" "qn,qm")))
6042    (clobber (reg:CC FLAGS_REG))]
6043   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6044    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6046   switch (get_attr_type (insn))
6047     {
6048     case TYPE_INCDEC:
6049       if (operands[1] == const1_rtx)
6050         return "inc{b}\t%0";
6051       else
6052         {
6053           gcc_assert (operands[1] == constm1_rtx);
6054           return "dec{b}\t%0";
6055         }
6057     default:
6058       if (x86_maybe_negate_const_int (&operands[1], QImode))
6059         return "sub{b}\t{%1, %0|%0, %1}";
6061       return "add{b}\t{%1, %0|%0, %1}";
6062     }
6064   [(set (attr "type")
6065      (if_then_else (match_operand:QI 1 "incdec_operand")
6066         (const_string "incdec")
6067         (const_string "alu1")))
6068    (set (attr "memory")
6069      (if_then_else (match_operand 1 "memory_operand")
6070         (const_string "load")
6071         (const_string "none")))
6072    (set_attr "mode" "QI")])
6074 ;; Split non destructive adds if we cannot use lea.
6075 (define_split
6076   [(set (match_operand:SWI48 0 "register_operand")
6077         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6078                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6079    (clobber (reg:CC FLAGS_REG))]
6080   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6081   [(set (match_dup 0) (match_dup 1))
6082    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6083               (clobber (reg:CC FLAGS_REG))])])
6085 ;; Split non destructive adds if we cannot use lea.
6086 (define_split
6087   [(set (match_operand:DI 0 "register_operand")
6088         (zero_extend:DI
6089           (plus:SI (match_operand:SI 1 "register_operand")
6090                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6091    (clobber (reg:CC FLAGS_REG))]
6092   "TARGET_64BIT
6093    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6094   [(set (match_dup 3) (match_dup 1))
6095    (parallel [(set (match_dup 0)
6096                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6097               (clobber (reg:CC FLAGS_REG))])]
6098   "operands[3] = gen_lowpart (SImode, operands[0]);")
6100 ;; Convert add to the lea pattern to avoid flags dependency.
6101 (define_split
6102   [(set (match_operand:SWI 0 "register_operand")
6103         (plus:SWI (match_operand:SWI 1 "register_operand")
6104                   (match_operand:SWI 2 "<nonmemory_operand>")))
6105    (clobber (reg:CC FLAGS_REG))]
6106   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
6107   [(set (match_dup 0)
6108         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6110   if (<MODE>mode != <LEAMODE>mode)
6111     {
6112       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6113       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6114       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6115     }
6118 ;; Convert add to the lea pattern to avoid flags dependency.
6119 (define_split
6120   [(set (match_operand:DI 0 "register_operand")
6121         (zero_extend:DI
6122           (plus:SI (match_operand:SI 1 "register_operand")
6123                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6124    (clobber (reg:CC FLAGS_REG))]
6125   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6126   [(set (match_dup 0)
6127         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6129 (define_insn "*add<mode>_2"
6130   [(set (reg FLAGS_REG)
6131         (compare
6132           (plus:SWI
6133             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6134             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6135           (const_int 0)))
6136    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6137         (plus:SWI (match_dup 1) (match_dup 2)))]
6138   "ix86_match_ccmode (insn, CCGOCmode)
6139    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6141   switch (get_attr_type (insn))
6142     {
6143     case TYPE_INCDEC:
6144       if (operands[2] == const1_rtx)
6145         return "inc{<imodesuffix>}\t%0";
6146       else
6147         {
6148           gcc_assert (operands[2] == constm1_rtx);
6149           return "dec{<imodesuffix>}\t%0";
6150         }
6152     default:
6153       if (which_alternative == 2)
6154         std::swap (operands[1], operands[2]);
6155         
6156       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6157       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6158         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6160       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6161     }
6163   [(set (attr "type")
6164      (if_then_else (match_operand:SWI 2 "incdec_operand")
6165         (const_string "incdec")
6166         (const_string "alu")))
6167    (set (attr "length_immediate")
6168       (if_then_else
6169         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6170         (const_string "1")
6171         (const_string "*")))
6172    (set_attr "mode" "<MODE>")])
6174 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6175 (define_insn "*addsi_2_zext"
6176   [(set (reg FLAGS_REG)
6177         (compare
6178           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6179                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6180           (const_int 0)))
6181    (set (match_operand:DI 0 "register_operand" "=r,r")
6182         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6183   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6184    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6186   switch (get_attr_type (insn))
6187     {
6188     case TYPE_INCDEC:
6189       if (operands[2] == const1_rtx)
6190         return "inc{l}\t%k0";
6191       else
6192         {
6193           gcc_assert (operands[2] == constm1_rtx);
6194           return "dec{l}\t%k0";
6195         }
6197     default:
6198       if (which_alternative == 1)
6199         std::swap (operands[1], operands[2]);
6201       if (x86_maybe_negate_const_int (&operands[2], SImode))
6202         return "sub{l}\t{%2, %k0|%k0, %2}";
6204       return "add{l}\t{%2, %k0|%k0, %2}";
6205     }
6207   [(set (attr "type")
6208      (if_then_else (match_operand:SI 2 "incdec_operand")
6209         (const_string "incdec")
6210         (const_string "alu")))
6211    (set (attr "length_immediate")
6212       (if_then_else
6213         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6214         (const_string "1")
6215         (const_string "*")))
6216    (set_attr "mode" "SI")])
6218 (define_insn "*add<mode>_3"
6219   [(set (reg FLAGS_REG)
6220         (compare
6221           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6222           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6223    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6224   "ix86_match_ccmode (insn, CCZmode)
6225    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6227   switch (get_attr_type (insn))
6228     {
6229     case TYPE_INCDEC:
6230       if (operands[2] == const1_rtx)
6231         return "inc{<imodesuffix>}\t%0";
6232       else
6233         {
6234           gcc_assert (operands[2] == constm1_rtx);
6235           return "dec{<imodesuffix>}\t%0";
6236         }
6238     default:
6239       if (which_alternative == 1)
6240         std::swap (operands[1], operands[2]);
6242       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6243       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6244         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6246       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6247     }
6249   [(set (attr "type")
6250      (if_then_else (match_operand:SWI 2 "incdec_operand")
6251         (const_string "incdec")
6252         (const_string "alu")))
6253    (set (attr "length_immediate")
6254       (if_then_else
6255         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6256         (const_string "1")
6257         (const_string "*")))
6258    (set_attr "mode" "<MODE>")])
6260 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6261 (define_insn "*addsi_3_zext"
6262   [(set (reg FLAGS_REG)
6263         (compare
6264           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6265           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6266    (set (match_operand:DI 0 "register_operand" "=r,r")
6267         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6268   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6269    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6271   switch (get_attr_type (insn))
6272     {
6273     case TYPE_INCDEC:
6274       if (operands[2] == const1_rtx)
6275         return "inc{l}\t%k0";
6276       else
6277         {
6278           gcc_assert (operands[2] == constm1_rtx);
6279           return "dec{l}\t%k0";
6280         }
6282     default:
6283       if (which_alternative == 1)
6284         std::swap (operands[1], operands[2]);
6286       if (x86_maybe_negate_const_int (&operands[2], SImode))
6287         return "sub{l}\t{%2, %k0|%k0, %2}";
6289       return "add{l}\t{%2, %k0|%k0, %2}";
6290     }
6292   [(set (attr "type")
6293      (if_then_else (match_operand:SI 2 "incdec_operand")
6294         (const_string "incdec")
6295         (const_string "alu")))
6296    (set (attr "length_immediate")
6297       (if_then_else
6298         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6299         (const_string "1")
6300         (const_string "*")))
6301    (set_attr "mode" "SI")])
6303 ; For comparisons against 1, -1 and 128, we may generate better code
6304 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6305 ; is matched then.  We can't accept general immediate, because for
6306 ; case of overflows,  the result is messed up.
6307 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6308 ; only for comparisons not depending on it.
6310 (define_insn "*adddi_4"
6311   [(set (reg FLAGS_REG)
6312         (compare
6313           (match_operand:DI 1 "nonimmediate_operand" "0")
6314           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6315    (clobber (match_scratch:DI 0 "=rm"))]
6316   "TARGET_64BIT
6317    && ix86_match_ccmode (insn, CCGCmode)"
6319   switch (get_attr_type (insn))
6320     {
6321     case TYPE_INCDEC:
6322       if (operands[2] == constm1_rtx)
6323         return "inc{q}\t%0";
6324       else
6325         {
6326           gcc_assert (operands[2] == const1_rtx);
6327           return "dec{q}\t%0";
6328         }
6330     default:
6331       if (x86_maybe_negate_const_int (&operands[2], DImode))
6332         return "add{q}\t{%2, %0|%0, %2}";
6334       return "sub{q}\t{%2, %0|%0, %2}";
6335     }
6337   [(set (attr "type")
6338      (if_then_else (match_operand:DI 2 "incdec_operand")
6339         (const_string "incdec")
6340         (const_string "alu")))
6341    (set (attr "length_immediate")
6342       (if_then_else
6343         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6344         (const_string "1")
6345         (const_string "*")))
6346    (set_attr "mode" "DI")])
6348 ; For comparisons against 1, -1 and 128, we may generate better code
6349 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6350 ; is matched then.  We can't accept general immediate, because for
6351 ; case of overflows,  the result is messed up.
6352 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6353 ; only for comparisons not depending on it.
6355 (define_insn "*add<mode>_4"
6356   [(set (reg FLAGS_REG)
6357         (compare
6358           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6359           (match_operand:SWI124 2 "const_int_operand" "n")))
6360    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6361   "ix86_match_ccmode (insn, CCGCmode)"
6363   switch (get_attr_type (insn))
6364     {
6365     case TYPE_INCDEC:
6366       if (operands[2] == constm1_rtx)
6367         return "inc{<imodesuffix>}\t%0";
6368       else
6369         {
6370           gcc_assert (operands[2] == const1_rtx);
6371           return "dec{<imodesuffix>}\t%0";
6372         }
6374     default:
6375       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6376         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6378       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6379     }
6381   [(set (attr "type")
6382      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6383         (const_string "incdec")
6384         (const_string "alu")))
6385    (set (attr "length_immediate")
6386       (if_then_else
6387         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6388         (const_string "1")
6389         (const_string "*")))
6390    (set_attr "mode" "<MODE>")])
6392 (define_insn "*add<mode>_5"
6393   [(set (reg FLAGS_REG)
6394         (compare
6395           (plus:SWI
6396             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6397             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6398           (const_int 0)))
6399    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6400   "ix86_match_ccmode (insn, CCGOCmode)
6401    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6403   switch (get_attr_type (insn))
6404     {
6405     case TYPE_INCDEC:
6406       if (operands[2] == const1_rtx)
6407         return "inc{<imodesuffix>}\t%0";
6408       else
6409         {
6410           gcc_assert (operands[2] == constm1_rtx);
6411           return "dec{<imodesuffix>}\t%0";
6412         }
6414     default:
6415       if (which_alternative == 1)
6416         std::swap (operands[1], operands[2]);
6418       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6419       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6420         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6422       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6423     }
6425   [(set (attr "type")
6426      (if_then_else (match_operand:SWI 2 "incdec_operand")
6427         (const_string "incdec")
6428         (const_string "alu")))
6429    (set (attr "length_immediate")
6430       (if_then_else
6431         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6432         (const_string "1")
6433         (const_string "*")))
6434    (set_attr "mode" "<MODE>")])
6436 (define_insn "addqi_ext_1"
6437   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6438                          (const_int 8)
6439                          (const_int 8))
6440         (subreg:SI
6441           (plus:QI
6442             (subreg:QI
6443               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6444                                (const_int 8)
6445                                (const_int 8)) 0)
6446             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6447    (clobber (reg:CC FLAGS_REG))]
6448   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6449    rtx_equal_p (operands[0], operands[1])"
6451   switch (get_attr_type (insn))
6452     {
6453     case TYPE_INCDEC:
6454       if (operands[2] == const1_rtx)
6455         return "inc{b}\t%h0";
6456       else
6457         {
6458           gcc_assert (operands[2] == constm1_rtx);
6459           return "dec{b}\t%h0";
6460         }
6462     default:
6463       return "add{b}\t{%2, %h0|%h0, %2}";
6464     }
6466   [(set_attr "isa" "*,nox64")
6467    (set (attr "type")
6468      (if_then_else (match_operand:QI 2 "incdec_operand")
6469         (const_string "incdec")
6470         (const_string "alu")))
6471    (set_attr "mode" "QI")])
6473 (define_insn "*addqi_ext_2"
6474   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6475                          (const_int 8)
6476                          (const_int 8))
6477         (subreg:SI
6478           (plus:QI
6479             (subreg:QI
6480               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6481                                (const_int 8)
6482                                (const_int 8)) 0)
6483             (subreg:QI
6484               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6485                                (const_int 8)
6486                                (const_int 8)) 0)) 0))
6487   (clobber (reg:CC FLAGS_REG))]
6488   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6489    rtx_equal_p (operands[0], operands[1])
6490    || rtx_equal_p (operands[0], operands[2])"
6491   "add{b}\t{%h2, %h0|%h0, %h2}"
6492   [(set_attr "type" "alu")
6493    (set_attr "mode" "QI")])
6495 ;; Add with jump on overflow.
6496 (define_expand "addv<mode>4"
6497   [(parallel [(set (reg:CCO FLAGS_REG)
6498                    (eq:CCO (plus:<DWI>
6499                               (sign_extend:<DWI>
6500                                  (match_operand:SWI 1 "nonimmediate_operand"))
6501                               (match_dup 4))
6502                            (sign_extend:<DWI>
6503                               (plus:SWI (match_dup 1)
6504                                         (match_operand:SWI 2
6505                                            "<general_operand>")))))
6506               (set (match_operand:SWI 0 "register_operand")
6507                    (plus:SWI (match_dup 1) (match_dup 2)))])
6508    (set (pc) (if_then_else
6509                (eq (reg:CCO FLAGS_REG) (const_int 0))
6510                (label_ref (match_operand 3))
6511                (pc)))]
6512   ""
6514   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6515   if (CONST_INT_P (operands[2]))
6516     operands[4] = operands[2];
6517   else
6518     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6521 (define_insn "*addv<mode>4"
6522   [(set (reg:CCO FLAGS_REG)
6523         (eq:CCO (plus:<DWI>
6524                    (sign_extend:<DWI>
6525                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6526                    (sign_extend:<DWI>
6527                       (match_operand:SWI 2 "<general_sext_operand>"
6528                                            "<r>mWe,<r>We")))
6529                 (sign_extend:<DWI>
6530                    (plus:SWI (match_dup 1) (match_dup 2)))))
6531    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6532         (plus:SWI (match_dup 1) (match_dup 2)))]
6533   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6534   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6535   [(set_attr "type" "alu")
6536    (set_attr "mode" "<MODE>")])
6538 (define_insn "*addv<mode>4_1"
6539   [(set (reg:CCO FLAGS_REG)
6540         (eq:CCO (plus:<DWI>
6541                    (sign_extend:<DWI>
6542                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6543                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6544                 (sign_extend:<DWI>
6545                    (plus:SWI (match_dup 1)
6546                              (match_operand:SWI 2 "x86_64_immediate_operand"
6547                                                   "<i>")))))
6548    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6549         (plus:SWI (match_dup 1) (match_dup 2)))]
6550   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6551    && CONST_INT_P (operands[2])
6552    && INTVAL (operands[2]) == INTVAL (operands[3])"
6553   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6554   [(set_attr "type" "alu")
6555    (set_attr "mode" "<MODE>")
6556    (set (attr "length_immediate")
6557         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6558                   (const_string "1")
6559                (match_test "<MODE_SIZE> == 8")
6560                   (const_string "4")]
6561               (const_string "<MODE_SIZE>")))])
6563 (define_expand "uaddv<mode>4"
6564   [(parallel [(set (reg:CCC FLAGS_REG)
6565                    (compare:CCC
6566                      (plus:SWI
6567                        (match_operand:SWI 1 "nonimmediate_operand")
6568                        (match_operand:SWI 2 "<general_operand>"))
6569                      (match_dup 1)))
6570               (set (match_operand:SWI 0 "register_operand")
6571                    (plus:SWI (match_dup 1) (match_dup 2)))])
6572    (set (pc) (if_then_else
6573                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6574                (label_ref (match_operand 3))
6575                (pc)))]
6576   ""
6577   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6579 ;; The lea patterns for modes less than 32 bits need to be matched by
6580 ;; several insns converted to real lea by splitters.
6582 (define_insn_and_split "*lea<mode>_general_1"
6583   [(set (match_operand:SWI12 0 "register_operand" "=r")
6584         (plus:SWI12
6585           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6586                       (match_operand:SWI12 2 "register_operand" "r"))
6587           (match_operand:SWI12 3 "immediate_operand" "i")))]
6588   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6589   "#"
6590   "&& reload_completed"
6591   [(set (match_dup 0)
6592         (plus:SI
6593           (plus:SI (match_dup 1) (match_dup 2))
6594           (match_dup 3)))]
6596   operands[0] = gen_lowpart (SImode, operands[0]);
6597   operands[1] = gen_lowpart (SImode, operands[1]);
6598   operands[2] = gen_lowpart (SImode, operands[2]);
6599   operands[3] = gen_lowpart (SImode, operands[3]);
6601   [(set_attr "type" "lea")
6602    (set_attr "mode" "SI")])
6604 (define_insn_and_split "*lea<mode>_general_2"
6605   [(set (match_operand:SWI12 0 "register_operand" "=r")
6606         (plus:SWI12
6607           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6608                       (match_operand 2 "const248_operand" "n"))
6609           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6610   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6611   "#"
6612   "&& reload_completed"
6613   [(set (match_dup 0)
6614         (plus:SI
6615           (mult:SI (match_dup 1) (match_dup 2))
6616           (match_dup 3)))]
6618   operands[0] = gen_lowpart (SImode, operands[0]);
6619   operands[1] = gen_lowpart (SImode, operands[1]);
6620   operands[3] = gen_lowpart (SImode, operands[3]);
6622   [(set_attr "type" "lea")
6623    (set_attr "mode" "SI")])
6625 (define_insn_and_split "*lea<mode>_general_2b"
6626   [(set (match_operand:SWI12 0 "register_operand" "=r")
6627         (plus:SWI12
6628           (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6629                         (match_operand 2 "const123_operand" "n"))
6630           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6631   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6632   "#"
6633   "&& reload_completed"
6634   [(set (match_dup 0)
6635         (plus:SI
6636           (ashift:SI (match_dup 1) (match_dup 2))
6637           (match_dup 3)))]
6639   operands[0] = gen_lowpart (SImode, operands[0]);
6640   operands[1] = gen_lowpart (SImode, operands[1]);
6641   operands[3] = gen_lowpart (SImode, operands[3]);
6643   [(set_attr "type" "lea")
6644    (set_attr "mode" "SI")])
6646 (define_insn_and_split "*lea<mode>_general_3"
6647   [(set (match_operand:SWI12 0 "register_operand" "=r")
6648         (plus:SWI12
6649           (plus:SWI12
6650             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6651                         (match_operand 2 "const248_operand" "n"))
6652             (match_operand:SWI12 3 "register_operand" "r"))
6653           (match_operand:SWI12 4 "immediate_operand" "i")))]
6654   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6655   "#"
6656   "&& reload_completed"
6657   [(set (match_dup 0)
6658         (plus:SI
6659           (plus:SI
6660             (mult:SI (match_dup 1) (match_dup 2))
6661             (match_dup 3))
6662           (match_dup 4)))]
6664   operands[0] = gen_lowpart (SImode, operands[0]);
6665   operands[1] = gen_lowpart (SImode, operands[1]);
6666   operands[3] = gen_lowpart (SImode, operands[3]);
6667   operands[4] = gen_lowpart (SImode, operands[4]);
6669   [(set_attr "type" "lea")
6670    (set_attr "mode" "SI")])
6672 (define_insn_and_split "*lea<mode>_general_3b"
6673   [(set (match_operand:SWI12 0 "register_operand" "=r")
6674         (plus:SWI12
6675           (plus:SWI12
6676             (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6677                           (match_operand 2 "const123_operand" "n"))
6678             (match_operand:SWI12 3 "register_operand" "r"))
6679           (match_operand:SWI12 4 "immediate_operand" "i")))]
6680   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6681   "#"
6682   "&& reload_completed"
6683   [(set (match_dup 0)
6684         (plus:SI
6685           (plus:SI
6686             (ashift:SI (match_dup 1) (match_dup 2))
6687             (match_dup 3))
6688           (match_dup 4)))]
6690   operands[0] = gen_lowpart (SImode, operands[0]);
6691   operands[1] = gen_lowpart (SImode, operands[1]);
6692   operands[3] = gen_lowpart (SImode, operands[3]);
6693   operands[4] = gen_lowpart (SImode, operands[4]);
6695   [(set_attr "type" "lea")
6696    (set_attr "mode" "SI")])
6698 (define_insn_and_split "*lea<mode>_general_4"
6699   [(set (match_operand:SWI12 0 "register_operand" "=r")
6700         (any_or:SWI12
6701           (ashift:SWI12
6702             (match_operand:SWI12 1 "index_register_operand" "l")
6703             (match_operand 2 "const_0_to_3_operand" "n"))
6704           (match_operand 3 "const_int_operand" "n")))]
6705   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6706    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6707        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6708   "#"
6709   "&& reload_completed"
6710   [(set (match_dup 0)
6711         (plus:SI
6712           (mult:SI (match_dup 1) (match_dup 2))
6713           (match_dup 3)))]
6715   operands[0] = gen_lowpart (SImode, operands[0]);
6716   operands[1] = gen_lowpart (SImode, operands[1]);
6717   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6719   [(set_attr "type" "lea")
6720    (set_attr "mode" "SI")])
6722 (define_insn_and_split "*lea<mode>_general_4"
6723   [(set (match_operand:SWI48 0 "register_operand" "=r")
6724         (any_or:SWI48
6725           (ashift:SWI48
6726             (match_operand:SWI48 1 "index_register_operand" "l")
6727             (match_operand 2 "const_0_to_3_operand" "n"))
6728           (match_operand 3 "const_int_operand" "n")))]
6729   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6730    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6731   "#"
6732   "&& reload_completed"
6733   [(set (match_dup 0)
6734         (plus:SWI48
6735           (mult:SWI48 (match_dup 1) (match_dup 2))
6736           (match_dup 3)))]
6737   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6738   [(set_attr "type" "lea")
6739    (set_attr "mode" "<MODE>")])
6741 ;; Subtract instructions
6743 (define_expand "sub<mode>3"
6744   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6745         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6746                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6747   ""
6748   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6750 (define_insn_and_split "*sub<dwi>3_doubleword"
6751   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6752         (minus:<DWI>
6753           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6754           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6755                                                         "ro<di>,r<di>")))
6756    (clobber (reg:CC FLAGS_REG))]
6757   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6758   "#"
6759   "reload_completed"
6760   [(parallel [(set (reg:CC FLAGS_REG)
6761                    (compare:CC (match_dup 1) (match_dup 2)))
6762               (set (match_dup 0)
6763                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6764    (parallel [(set (match_dup 3)
6765                    (minus:DWIH
6766                      (minus:DWIH
6767                        (match_dup 4)
6768                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6769                      (match_dup 5)))
6770               (clobber (reg:CC FLAGS_REG))])]
6772   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6773   if (operands[2] == const0_rtx)
6774     {
6775       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6776       DONE;
6777     }
6780 (define_insn "*sub<mode>_1"
6781   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6782         (minus:SWI
6783           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6784           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6785    (clobber (reg:CC FLAGS_REG))]
6786   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6787   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6788   [(set_attr "type" "alu")
6789    (set_attr "mode" "<MODE>")])
6791 (define_insn "*subsi_1_zext"
6792   [(set (match_operand:DI 0 "register_operand" "=r")
6793         (zero_extend:DI
6794           (minus:SI (match_operand:SI 1 "register_operand" "0")
6795                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6796    (clobber (reg:CC FLAGS_REG))]
6797   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6798   "sub{l}\t{%2, %k0|%k0, %2}"
6799   [(set_attr "type" "alu")
6800    (set_attr "mode" "SI")])
6802 (define_insn "*subqi_1_slp"
6803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6804         (minus:QI (match_dup 0)
6805                   (match_operand:QI 1 "general_operand" "qn,qm")))
6806    (clobber (reg:CC FLAGS_REG))]
6807   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6808    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6809   "sub{b}\t{%1, %0|%0, %1}"
6810   [(set_attr "type" "alu1")
6811    (set_attr "mode" "QI")])
6813 (define_insn "*sub<mode>_2"
6814   [(set (reg FLAGS_REG)
6815         (compare
6816           (minus:SWI
6817             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6818             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6819           (const_int 0)))
6820    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6821         (minus:SWI (match_dup 1) (match_dup 2)))]
6822   "ix86_match_ccmode (insn, CCGOCmode)
6823    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6824   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6825   [(set_attr "type" "alu")
6826    (set_attr "mode" "<MODE>")])
6828 (define_insn "*subsi_2_zext"
6829   [(set (reg FLAGS_REG)
6830         (compare
6831           (minus:SI (match_operand:SI 1 "register_operand" "0")
6832                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6833           (const_int 0)))
6834    (set (match_operand:DI 0 "register_operand" "=r")
6835         (zero_extend:DI
6836           (minus:SI (match_dup 1)
6837                     (match_dup 2))))]
6838   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6839    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6840   "sub{l}\t{%2, %k0|%k0, %2}"
6841   [(set_attr "type" "alu")
6842    (set_attr "mode" "SI")])
6844 ;; Subtract with jump on overflow.
6845 (define_expand "subv<mode>4"
6846   [(parallel [(set (reg:CCO FLAGS_REG)
6847                    (eq:CCO (minus:<DWI>
6848                               (sign_extend:<DWI>
6849                                  (match_operand:SWI 1 "nonimmediate_operand"))
6850                               (match_dup 4))
6851                            (sign_extend:<DWI>
6852                               (minus:SWI (match_dup 1)
6853                                          (match_operand:SWI 2
6854                                             "<general_operand>")))))
6855               (set (match_operand:SWI 0 "register_operand")
6856                    (minus:SWI (match_dup 1) (match_dup 2)))])
6857    (set (pc) (if_then_else
6858                (eq (reg:CCO FLAGS_REG) (const_int 0))
6859                (label_ref (match_operand 3))
6860                (pc)))]
6861   ""
6863   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6864   if (CONST_INT_P (operands[2]))
6865     operands[4] = operands[2];
6866   else
6867     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6870 (define_insn "*subv<mode>4"
6871   [(set (reg:CCO FLAGS_REG)
6872         (eq:CCO (minus:<DWI>
6873                    (sign_extend:<DWI>
6874                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6875                    (sign_extend:<DWI>
6876                       (match_operand:SWI 2 "<general_sext_operand>"
6877                                            "<r>We,<r>m")))
6878                 (sign_extend:<DWI>
6879                    (minus:SWI (match_dup 1) (match_dup 2)))))
6880    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6881         (minus:SWI (match_dup 1) (match_dup 2)))]
6882   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6883   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6884   [(set_attr "type" "alu")
6885    (set_attr "mode" "<MODE>")])
6887 (define_insn "*subv<mode>4_1"
6888   [(set (reg:CCO FLAGS_REG)
6889         (eq:CCO (minus:<DWI>
6890                    (sign_extend:<DWI>
6891                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6892                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6893                 (sign_extend:<DWI>
6894                    (minus:SWI (match_dup 1)
6895                               (match_operand:SWI 2 "x86_64_immediate_operand"
6896                                                    "<i>")))))
6897    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6898         (minus:SWI (match_dup 1) (match_dup 2)))]
6899   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6900    && CONST_INT_P (operands[2])
6901    && INTVAL (operands[2]) == INTVAL (operands[3])"
6902   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6903   [(set_attr "type" "alu")
6904    (set_attr "mode" "<MODE>")
6905    (set (attr "length_immediate")
6906         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6907                   (const_string "1")
6908                (match_test "<MODE_SIZE> == 8")
6909                   (const_string "4")]
6910               (const_string "<MODE_SIZE>")))])
6912 (define_expand "usubv<mode>4"
6913   [(parallel [(set (reg:CC FLAGS_REG)
6914                    (compare:CC
6915                      (match_operand:SWI 1 "nonimmediate_operand")
6916                      (match_operand:SWI 2 "<general_operand>")))
6917               (set (match_operand:SWI 0 "register_operand")
6918                    (minus:SWI (match_dup 1) (match_dup 2)))])
6919    (set (pc) (if_then_else
6920                (ltu (reg:CC FLAGS_REG) (const_int 0))
6921                (label_ref (match_operand 3))
6922                (pc)))]
6923   ""
6924   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6926 (define_insn "*sub<mode>_3"
6927   [(set (reg FLAGS_REG)
6928         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6929                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6930    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6931         (minus:SWI (match_dup 1) (match_dup 2)))]
6932   "ix86_match_ccmode (insn, CCmode)
6933    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6934   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6935   [(set_attr "type" "alu")
6936    (set_attr "mode" "<MODE>")])
6938 (define_peephole2
6939   [(parallel
6940      [(set (reg:CC FLAGS_REG)
6941            (compare:CC (match_operand:SWI 0 "general_reg_operand")
6942                        (match_operand:SWI 1 "general_gr_operand")))
6943       (set (match_dup 0)
6944            (minus:SWI (match_dup 0) (match_dup 1)))])]
6945   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6946   [(set (reg:CC FLAGS_REG)
6947         (compare:CC (match_dup 0) (match_dup 1)))])
6949 (define_insn "*subsi_3_zext"
6950   [(set (reg FLAGS_REG)
6951         (compare (match_operand:SI 1 "register_operand" "0")
6952                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6953    (set (match_operand:DI 0 "register_operand" "=r")
6954         (zero_extend:DI
6955           (minus:SI (match_dup 1)
6956                     (match_dup 2))))]
6957   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6958    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6959   "sub{l}\t{%2, %1|%1, %2}"
6960   [(set_attr "type" "alu")
6961    (set_attr "mode" "SI")])
6963 ;; Add with carry and subtract with borrow
6965 (define_insn "add<mode>3_carry"
6966   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6967         (plus:SWI
6968           (plus:SWI
6969             (match_operator:SWI 4 "ix86_carry_flag_operator"
6970              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6971             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6972           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6973    (clobber (reg:CC FLAGS_REG))]
6974   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6975   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6976   [(set_attr "type" "alu")
6977    (set_attr "use_carry" "1")
6978    (set_attr "pent_pair" "pu")
6979    (set_attr "mode" "<MODE>")])
6981 (define_insn "*add<mode>3_carry_0"
6982   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6983         (plus:SWI
6984           (match_operator:SWI 3 "ix86_carry_flag_operator"
6985             [(match_operand 2 "flags_reg_operand") (const_int 0)])
6986           (match_operand:SWI 1 "nonimmediate_operand" "0")))
6987    (clobber (reg:CC FLAGS_REG))]
6988   "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6989   "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6990   [(set_attr "type" "alu")
6991    (set_attr "use_carry" "1")
6992    (set_attr "pent_pair" "pu")
6993    (set_attr "mode" "<MODE>")])
6995 (define_insn "*addsi3_carry_zext"
6996   [(set (match_operand:DI 0 "register_operand" "=r")
6997         (zero_extend:DI
6998           (plus:SI
6999             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
7000                       [(reg FLAGS_REG) (const_int 0)])
7001                      (match_operand:SI 1 "register_operand" "%0"))
7002             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7003    (clobber (reg:CC FLAGS_REG))]
7004   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7005   "adc{l}\t{%2, %k0|%k0, %2}"
7006   [(set_attr "type" "alu")
7007    (set_attr "use_carry" "1")
7008    (set_attr "pent_pair" "pu")
7009    (set_attr "mode" "SI")])
7011 (define_insn "*addsi3_carry_zext_0"
7012   [(set (match_operand:DI 0 "register_operand" "=r")
7013         (zero_extend:DI
7014           (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
7015                     [(reg FLAGS_REG) (const_int 0)])
7016                    (match_operand:SI 1 "register_operand" "0"))))
7017    (clobber (reg:CC FLAGS_REG))]
7018   "TARGET_64BIT"
7019   "adc{l}\t{$0, %k0|%k0, 0}"
7020   [(set_attr "type" "alu")
7021    (set_attr "use_carry" "1")
7022    (set_attr "pent_pair" "pu")
7023    (set_attr "mode" "SI")])
7025 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
7027 (define_insn "addcarry<mode>"
7028   [(set (reg:CCC FLAGS_REG)
7029         (compare:CCC
7030           (zero_extend:<DWI>
7031             (plus:SWI48
7032               (plus:SWI48
7033                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7034                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
7035                 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
7036               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
7037           (plus:<DWI>
7038             (zero_extend:<DWI> (match_dup 2))
7039             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7040               [(match_dup 3) (const_int 0)]))))
7041    (set (match_operand:SWI48 0 "register_operand" "=r")
7042         (plus:SWI48 (plus:SWI48 (match_op_dup 5
7043                                  [(match_dup 3) (const_int 0)])
7044                                 (match_dup 1))
7045                     (match_dup 2)))]
7046   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7047   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7048   [(set_attr "type" "alu")
7049    (set_attr "use_carry" "1")
7050    (set_attr "pent_pair" "pu")
7051    (set_attr "mode" "<MODE>")])
7053 (define_expand "addcarry<mode>_0"
7054   [(parallel
7055      [(set (reg:CCC FLAGS_REG)
7056            (compare:CCC
7057              (plus:SWI48
7058                (match_operand:SWI48 1 "nonimmediate_operand")
7059                (match_operand:SWI48 2 "x86_64_general_operand"))
7060              (match_dup 1)))
7061       (set (match_operand:SWI48 0 "register_operand")
7062            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
7063   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
7065 (define_insn "sub<mode>3_carry"
7066   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7067         (minus:SWI
7068           (minus:SWI
7069             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7070             (match_operator:SWI 4 "ix86_carry_flag_operator"
7071              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7072           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7073    (clobber (reg:CC FLAGS_REG))]
7074   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7075   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7076   [(set_attr "type" "alu")
7077    (set_attr "use_carry" "1")
7078    (set_attr "pent_pair" "pu")
7079    (set_attr "mode" "<MODE>")])
7081 (define_insn "*sub<mode>3_carry_0"
7082   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7083         (minus:SWI
7084           (match_operand:SWI 1 "nonimmediate_operand" "0")
7085           (match_operator:SWI 3 "ix86_carry_flag_operator"
7086             [(match_operand 2 "flags_reg_operand") (const_int 0)])))
7087    (clobber (reg:CC FLAGS_REG))]
7088   "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
7089   "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
7090   [(set_attr "type" "alu")
7091    (set_attr "use_carry" "1")
7092    (set_attr "pent_pair" "pu")
7093    (set_attr "mode" "<MODE>")])
7095 (define_insn "*subsi3_carry_zext"
7096   [(set (match_operand:DI 0 "register_operand" "=r")
7097         (zero_extend:DI
7098           (minus:SI
7099             (minus:SI
7100               (match_operand:SI 1 "register_operand" "0")
7101               (match_operator:SI 3 "ix86_carry_flag_operator"
7102                [(reg FLAGS_REG) (const_int 0)]))
7103             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7104    (clobber (reg:CC FLAGS_REG))]
7105   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7106   "sbb{l}\t{%2, %k0|%k0, %2}"
7107   [(set_attr "type" "alu")
7108    (set_attr "use_carry" "1")
7109    (set_attr "pent_pair" "pu")
7110    (set_attr "mode" "SI")])
7112 (define_insn "*subsi3_carry_zext_0"
7113   [(set (match_operand:DI 0 "register_operand" "=r")
7114         (zero_extend:DI
7115           (minus:SI
7116             (match_operand:SI 1 "register_operand" "0")
7117             (match_operator:SI 2 "ix86_carry_flag_operator"
7118               [(reg FLAGS_REG) (const_int 0)]))))
7119    (clobber (reg:CC FLAGS_REG))]
7120   "TARGET_64BIT"
7121   "sbb{l}\t{$0, %k0|%k0, 0}"
7122   [(set_attr "type" "alu")
7123    (set_attr "use_carry" "1")
7124    (set_attr "pent_pair" "pu")
7125    (set_attr "mode" "SI")])
7127 (define_insn "sub<mode>3_carry_ccc"
7128   [(set (reg:CCC FLAGS_REG)
7129         (compare:CCC
7130           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7131           (plus:<DWI>
7132             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7133             (zero_extend:<DWI>
7134               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
7135    (clobber (match_scratch:DWIH 0 "=r"))]
7136   ""
7137   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7138   [(set_attr "type" "alu")
7139    (set_attr "mode" "<MODE>")])
7141 (define_insn "*sub<mode>3_carry_ccc_1"
7142   [(set (reg:CCC FLAGS_REG)
7143         (compare:CCC
7144           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7145           (plus:<DWI>
7146             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7147             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7148    (clobber (match_scratch:DWIH 0 "=r"))]
7149   ""
7151   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7152   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7154   [(set_attr "type" "alu")
7155    (set_attr "mode" "<MODE>")])
7157 ;; The sign flag is set from the
7158 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7159 ;; result, the overflow flag likewise, but the overflow flag is also
7160 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7161 (define_insn "sub<mode>3_carry_ccgz"
7162   [(set (reg:CCGZ FLAGS_REG)
7163         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7164                       (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7165                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7166                      UNSPEC_SBB))
7167    (clobber (match_scratch:DWIH 0 "=r"))]
7168   ""
7169   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7170   [(set_attr "type" "alu")
7171    (set_attr "mode" "<MODE>")])
7173 (define_insn "subborrow<mode>"
7174   [(set (reg:CCC FLAGS_REG)
7175         (compare:CCC
7176           (zero_extend:<DWI>
7177             (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7178           (plus:<DWI>
7179             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7180               [(match_operand 3 "flags_reg_operand") (const_int 0)])
7181             (zero_extend:<DWI>
7182               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7183    (set (match_operand:SWI48 0 "register_operand" "=r")
7184         (minus:SWI48 (minus:SWI48
7185                        (match_dup 1)
7186                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
7187                          [(match_dup 3) (const_int 0)]))
7188                      (match_dup 2)))]
7189   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7190   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7191   [(set_attr "type" "alu")
7192    (set_attr "use_carry" "1")
7193    (set_attr "pent_pair" "pu")
7194    (set_attr "mode" "<MODE>")])
7196 (define_expand "subborrow<mode>_0"
7197   [(parallel
7198      [(set (reg:CC FLAGS_REG)
7199            (compare:CC
7200              (match_operand:SWI48 1 "nonimmediate_operand")
7201              (match_operand:SWI48 2 "<general_operand>")))
7202       (set (match_operand:SWI48 0 "register_operand")
7203            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7204   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7206 ;; Overflow setting add instructions
7208 (define_expand "addqi3_cconly_overflow"
7209   [(parallel
7210      [(set (reg:CCC FLAGS_REG)
7211            (compare:CCC
7212              (plus:QI
7213                (match_operand:QI 0 "nonimmediate_operand")
7214                (match_operand:QI 1 "general_operand"))
7215              (match_dup 0)))
7216       (clobber (match_scratch:QI 2))])]
7217   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7219 (define_insn "*add<mode>3_cconly_overflow_1"
7220   [(set (reg:CCC FLAGS_REG)
7221         (compare:CCC
7222           (plus:SWI
7223             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7224             (match_operand:SWI 2 "<general_operand>" "<g>"))
7225           (match_dup 1)))
7226    (clobber (match_scratch:SWI 0 "=<r>"))]
7227   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7228   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7229   [(set_attr "type" "alu")
7230    (set_attr "mode" "<MODE>")])
7232 (define_insn "*add<mode>3_cc_overflow_1"
7233   [(set (reg:CCC FLAGS_REG)
7234         (compare:CCC
7235             (plus:SWI
7236                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7237                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7238             (match_dup 1)))
7239    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7240         (plus:SWI (match_dup 1) (match_dup 2)))]
7241   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7242   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7243   [(set_attr "type" "alu")
7244    (set_attr "mode" "<MODE>")])
7246 (define_insn "*addsi3_zext_cc_overflow_1"
7247   [(set (reg:CCC FLAGS_REG)
7248         (compare:CCC
7249           (plus:SI
7250             (match_operand:SI 1 "nonimmediate_operand" "%0")
7251             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7252           (match_dup 1)))
7253    (set (match_operand:DI 0 "register_operand" "=r")
7254         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7255   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7256   "add{l}\t{%2, %k0|%k0, %2}"
7257   [(set_attr "type" "alu")
7258    (set_attr "mode" "SI")])
7260 (define_insn "*add<mode>3_cconly_overflow_2"
7261   [(set (reg:CCC FLAGS_REG)
7262         (compare:CCC
7263           (plus:SWI
7264             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7265             (match_operand:SWI 2 "<general_operand>" "<g>"))
7266           (match_dup 2)))
7267    (clobber (match_scratch:SWI 0 "=<r>"))]
7268   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7269   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7270   [(set_attr "type" "alu")
7271    (set_attr "mode" "<MODE>")])
7273 (define_insn "*add<mode>3_cc_overflow_2"
7274   [(set (reg:CCC FLAGS_REG)
7275         (compare:CCC
7276             (plus:SWI
7277                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7278                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7279             (match_dup 2)))
7280    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7281         (plus:SWI (match_dup 1) (match_dup 2)))]
7282   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7283   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7284   [(set_attr "type" "alu")
7285    (set_attr "mode" "<MODE>")])
7287 (define_insn "*addsi3_zext_cc_overflow_2"
7288   [(set (reg:CCC FLAGS_REG)
7289         (compare:CCC
7290           (plus:SI
7291             (match_operand:SI 1 "nonimmediate_operand" "%0")
7292             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7293           (match_dup 2)))
7294    (set (match_operand:DI 0 "register_operand" "=r")
7295         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7296   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7297   "add{l}\t{%2, %k0|%k0, %2}"
7298   [(set_attr "type" "alu")
7299    (set_attr "mode" "SI")])
7301 ;; The patterns that match these are at the end of this file.
7303 (define_expand "<plusminus_insn>xf3"
7304   [(set (match_operand:XF 0 "register_operand")
7305         (plusminus:XF
7306           (match_operand:XF 1 "register_operand")
7307           (match_operand:XF 2 "register_operand")))]
7308   "TARGET_80387")
7310 (define_expand "<plusminus_insn><mode>3"
7311   [(set (match_operand:MODEF 0 "register_operand")
7312         (plusminus:MODEF
7313           (match_operand:MODEF 1 "register_operand")
7314           (match_operand:MODEF 2 "nonimmediate_operand")))]
7315   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7316     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7318 ;; Multiply instructions
7320 (define_expand "mul<mode>3"
7321   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7322                    (mult:SWIM248
7323                      (match_operand:SWIM248 1 "register_operand")
7324                      (match_operand:SWIM248 2 "<general_operand>")))
7325               (clobber (reg:CC FLAGS_REG))])])
7327 (define_expand "mulqi3"
7328   [(parallel [(set (match_operand:QI 0 "register_operand")
7329                    (mult:QI
7330                      (match_operand:QI 1 "register_operand")
7331                      (match_operand:QI 2 "nonimmediate_operand")))
7332               (clobber (reg:CC FLAGS_REG))])]
7333   "TARGET_QIMODE_MATH")
7335 ;; On AMDFAM10
7336 ;; IMUL reg32/64, reg32/64, imm8        Direct
7337 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7338 ;; IMUL reg32/64, reg32/64, imm32       Direct
7339 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7340 ;; IMUL reg32/64, reg32/64              Direct
7341 ;; IMUL reg32/64, mem32/64              Direct
7343 ;; On BDVER1, all above IMULs use DirectPath
7345 ;; On AMDFAM10
7346 ;; IMUL reg16, reg16, imm8      VectorPath
7347 ;; IMUL reg16, mem16, imm8      VectorPath
7348 ;; IMUL reg16, reg16, imm16     VectorPath
7349 ;; IMUL reg16, mem16, imm16     VectorPath
7350 ;; IMUL reg16, reg16            Direct
7351 ;; IMUL reg16, mem16            Direct
7353 ;; On BDVER1, all HI MULs use DoublePath
7355 (define_insn "*mul<mode>3_1"
7356   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7357         (mult:SWIM248
7358           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7359           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7360    (clobber (reg:CC FLAGS_REG))]
7361   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7362   "@
7363    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7364    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7365    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7366   [(set_attr "type" "imul")
7367    (set_attr "prefix_0f" "0,0,1")
7368    (set (attr "athlon_decode")
7369         (cond [(eq_attr "cpu" "athlon")
7370                   (const_string "vector")
7371                (eq_attr "alternative" "1")
7372                   (const_string "vector")
7373                (and (eq_attr "alternative" "2")
7374                     (ior (match_test "<MODE>mode == HImode")
7375                          (match_operand 1 "memory_operand")))
7376                   (const_string "vector")]
7377               (const_string "direct")))
7378    (set (attr "amdfam10_decode")
7379         (cond [(and (eq_attr "alternative" "0,1")
7380                     (ior (match_test "<MODE>mode == HImode")
7381                          (match_operand 1 "memory_operand")))
7382                   (const_string "vector")]
7383               (const_string "direct")))
7384    (set (attr "bdver1_decode")
7385         (if_then_else
7386           (match_test "<MODE>mode == HImode")
7387             (const_string "double")
7388             (const_string "direct")))
7389    (set_attr "mode" "<MODE>")])
7391 (define_insn "*mulsi3_1_zext"
7392   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7393         (zero_extend:DI
7394           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7395                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7396    (clobber (reg:CC FLAGS_REG))]
7397   "TARGET_64BIT
7398    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7399   "@
7400    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7401    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7402    imul{l}\t{%2, %k0|%k0, %2}"
7403   [(set_attr "type" "imul")
7404    (set_attr "prefix_0f" "0,0,1")
7405    (set (attr "athlon_decode")
7406         (cond [(eq_attr "cpu" "athlon")
7407                   (const_string "vector")
7408                (eq_attr "alternative" "1")
7409                   (const_string "vector")
7410                (and (eq_attr "alternative" "2")
7411                     (match_operand 1 "memory_operand"))
7412                   (const_string "vector")]
7413               (const_string "direct")))
7414    (set (attr "amdfam10_decode")
7415         (cond [(and (eq_attr "alternative" "0,1")
7416                     (match_operand 1 "memory_operand"))
7417                   (const_string "vector")]
7418               (const_string "direct")))
7419    (set_attr "bdver1_decode" "direct")
7420    (set_attr "mode" "SI")])
7422 ;;On AMDFAM10 and BDVER1
7423 ;; MUL reg8     Direct
7424 ;; MUL mem8     Direct
7426 (define_insn "*mulqi3_1"
7427   [(set (match_operand:QI 0 "register_operand" "=a")
7428         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7429                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7430    (clobber (reg:CC FLAGS_REG))]
7431   "TARGET_QIMODE_MATH
7432    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7433   "mul{b}\t%2"
7434   [(set_attr "type" "imul")
7435    (set_attr "length_immediate" "0")
7436    (set (attr "athlon_decode")
7437      (if_then_else (eq_attr "cpu" "athlon")
7438         (const_string "vector")
7439         (const_string "direct")))
7440    (set_attr "amdfam10_decode" "direct")
7441    (set_attr "bdver1_decode" "direct")
7442    (set_attr "mode" "QI")])
7444 ;; Multiply with jump on overflow.
7445 (define_expand "mulv<mode>4"
7446   [(parallel [(set (reg:CCO FLAGS_REG)
7447                    (eq:CCO (mult:<DWI>
7448                               (sign_extend:<DWI>
7449                                  (match_operand:SWI248 1 "register_operand"))
7450                               (match_dup 4))
7451                            (sign_extend:<DWI>
7452                               (mult:SWI248 (match_dup 1)
7453                                            (match_operand:SWI248 2
7454                                               "<general_operand>")))))
7455               (set (match_operand:SWI248 0 "register_operand")
7456                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
7457    (set (pc) (if_then_else
7458                (eq (reg:CCO FLAGS_REG) (const_int 0))
7459                (label_ref (match_operand 3))
7460                (pc)))]
7461   ""
7463   if (CONST_INT_P (operands[2]))
7464     operands[4] = operands[2];
7465   else
7466     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7469 (define_insn "*mulv<mode>4"
7470   [(set (reg:CCO FLAGS_REG)
7471         (eq:CCO (mult:<DWI>
7472                    (sign_extend:<DWI>
7473                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7474                    (sign_extend:<DWI>
7475                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7476                 (sign_extend:<DWI>
7477                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
7478    (set (match_operand:SWI48 0 "register_operand" "=r,r")
7479         (mult:SWI48 (match_dup 1) (match_dup 2)))]
7480   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7481   "@
7482    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7483    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7484   [(set_attr "type" "imul")
7485    (set_attr "prefix_0f" "0,1")
7486    (set (attr "athlon_decode")
7487         (cond [(eq_attr "cpu" "athlon")
7488                   (const_string "vector")
7489                (eq_attr "alternative" "0")
7490                   (const_string "vector")
7491                (and (eq_attr "alternative" "1")
7492                     (match_operand 1 "memory_operand"))
7493                   (const_string "vector")]
7494               (const_string "direct")))
7495    (set (attr "amdfam10_decode")
7496         (cond [(and (eq_attr "alternative" "1")
7497                     (match_operand 1 "memory_operand"))
7498                   (const_string "vector")]
7499               (const_string "direct")))
7500    (set_attr "bdver1_decode" "direct")
7501    (set_attr "mode" "<MODE>")])
7503 (define_insn "*mulvhi4"
7504   [(set (reg:CCO FLAGS_REG)
7505         (eq:CCO (mult:SI
7506                    (sign_extend:SI
7507                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
7508                    (sign_extend:SI
7509                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
7510                 (sign_extend:SI
7511                    (mult:HI (match_dup 1) (match_dup 2)))))
7512    (set (match_operand:HI 0 "register_operand" "=r")
7513         (mult:HI (match_dup 1) (match_dup 2)))]
7514   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7515   "imul{w}\t{%2, %0|%0, %2}"
7516   [(set_attr "type" "imul")
7517    (set_attr "prefix_0f" "1")
7518    (set_attr "athlon_decode" "vector")
7519    (set_attr "amdfam10_decode" "direct")
7520    (set_attr "bdver1_decode" "double")
7521    (set_attr "mode" "HI")])
7523 (define_insn "*mulv<mode>4_1"
7524   [(set (reg:CCO FLAGS_REG)
7525         (eq:CCO (mult:<DWI>
7526                    (sign_extend:<DWI>
7527                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7528                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7529                 (sign_extend:<DWI>
7530                    (mult:SWI248 (match_dup 1)
7531                                 (match_operand:SWI248 2
7532                                    "<immediate_operand>" "K,<i>")))))
7533    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7534         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7535   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7536    && CONST_INT_P (operands[2])
7537    && INTVAL (operands[2]) == INTVAL (operands[3])"
7538   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7539   [(set_attr "type" "imul")
7540    (set (attr "prefix_0f")
7541         (if_then_else
7542           (match_test "<MODE>mode == HImode")
7543             (const_string "0")
7544             (const_string "*")))
7545    (set (attr "athlon_decode")
7546         (cond [(eq_attr "cpu" "athlon")
7547                   (const_string "vector")
7548                (eq_attr "alternative" "1")
7549                   (const_string "vector")]
7550               (const_string "direct")))
7551    (set (attr "amdfam10_decode")
7552         (cond [(ior (match_test "<MODE>mode == HImode")
7553                     (match_operand 1 "memory_operand"))
7554                   (const_string "vector")]
7555               (const_string "direct")))
7556    (set (attr "bdver1_decode")
7557         (if_then_else
7558           (match_test "<MODE>mode == HImode")
7559             (const_string "double")
7560             (const_string "direct")))
7561    (set_attr "mode" "<MODE>")
7562    (set (attr "length_immediate")
7563         (cond [(eq_attr "alternative" "0")
7564                   (const_string "1")
7565                (match_test "<MODE_SIZE> == 8")
7566                   (const_string "4")]
7567               (const_string "<MODE_SIZE>")))])
7569 (define_expand "umulv<mode>4"
7570   [(parallel [(set (reg:CCO FLAGS_REG)
7571                    (eq:CCO (mult:<DWI>
7572                               (zero_extend:<DWI>
7573                                  (match_operand:SWI248 1
7574                                                       "nonimmediate_operand"))
7575                               (zero_extend:<DWI>
7576                                  (match_operand:SWI248 2
7577                                                       "nonimmediate_operand")))
7578                            (zero_extend:<DWI>
7579                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7580               (set (match_operand:SWI248 0 "register_operand")
7581                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7582               (clobber (match_scratch:SWI248 4))])
7583    (set (pc) (if_then_else
7584                (eq (reg:CCO FLAGS_REG) (const_int 0))
7585                (label_ref (match_operand 3))
7586                (pc)))]
7587   ""
7589   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7590     operands[1] = force_reg (<MODE>mode, operands[1]);
7593 (define_insn "*umulv<mode>4"
7594   [(set (reg:CCO FLAGS_REG)
7595         (eq:CCO (mult:<DWI>
7596                    (zero_extend:<DWI>
7597                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7598                    (zero_extend:<DWI>
7599                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7600                 (zero_extend:<DWI>
7601                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7602    (set (match_operand:SWI248 0 "register_operand" "=a")
7603         (mult:SWI248 (match_dup 1) (match_dup 2)))
7604    (clobber (match_scratch:SWI248 3 "=d"))]
7605   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7606   "mul{<imodesuffix>}\t%2"
7607   [(set_attr "type" "imul")
7608    (set_attr "length_immediate" "0")
7609    (set (attr "athlon_decode")
7610      (if_then_else (eq_attr "cpu" "athlon")
7611        (const_string "vector")
7612        (const_string "double")))
7613    (set_attr "amdfam10_decode" "double")
7614    (set_attr "bdver1_decode" "direct")
7615    (set_attr "mode" "<MODE>")])
7617 (define_expand "<u>mulvqi4"
7618   [(parallel [(set (reg:CCO FLAGS_REG)
7619                    (eq:CCO (mult:HI
7620                               (any_extend:HI
7621                                  (match_operand:QI 1 "nonimmediate_operand"))
7622                               (any_extend:HI
7623                                  (match_operand:QI 2 "nonimmediate_operand")))
7624                            (any_extend:HI
7625                               (mult:QI (match_dup 1) (match_dup 2)))))
7626               (set (match_operand:QI 0 "register_operand")
7627                    (mult:QI (match_dup 1) (match_dup 2)))])
7628    (set (pc) (if_then_else
7629                (eq (reg:CCO FLAGS_REG) (const_int 0))
7630                (label_ref (match_operand 3))
7631                (pc)))]
7632   "TARGET_QIMODE_MATH"
7634   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7635     operands[1] = force_reg (QImode, operands[1]);
7638 (define_insn "*<u>mulvqi4"
7639   [(set (reg:CCO FLAGS_REG)
7640         (eq:CCO (mult:HI
7641                    (any_extend:HI
7642                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7643                    (any_extend:HI
7644                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7645                 (any_extend:HI
7646                    (mult:QI (match_dup 1) (match_dup 2)))))
7647    (set (match_operand:QI 0 "register_operand" "=a")
7648         (mult:QI (match_dup 1) (match_dup 2)))]
7649   "TARGET_QIMODE_MATH
7650    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7651   "<sgnprefix>mul{b}\t%2"
7652   [(set_attr "type" "imul")
7653    (set_attr "length_immediate" "0")
7654    (set (attr "athlon_decode")
7655      (if_then_else (eq_attr "cpu" "athlon")
7656         (const_string "vector")
7657         (const_string "direct")))
7658    (set_attr "amdfam10_decode" "direct")
7659    (set_attr "bdver1_decode" "direct")
7660    (set_attr "mode" "QI")])
7662 (define_expand "<u>mul<mode><dwi>3"
7663   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7664                    (mult:<DWI>
7665                      (any_extend:<DWI>
7666                        (match_operand:DWIH 1 "nonimmediate_operand"))
7667                      (any_extend:<DWI>
7668                        (match_operand:DWIH 2 "register_operand"))))
7669               (clobber (reg:CC FLAGS_REG))])])
7671 (define_expand "<u>mulqihi3"
7672   [(parallel [(set (match_operand:HI 0 "register_operand")
7673                    (mult:HI
7674                      (any_extend:HI
7675                        (match_operand:QI 1 "nonimmediate_operand"))
7676                      (any_extend:HI
7677                        (match_operand:QI 2 "register_operand"))))
7678               (clobber (reg:CC FLAGS_REG))])]
7679   "TARGET_QIMODE_MATH")
7681 (define_insn "*bmi2_umul<mode><dwi>3_1"
7682   [(set (match_operand:DWIH 0 "register_operand" "=r")
7683         (mult:DWIH
7684           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7685           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7686    (set (match_operand:DWIH 1 "register_operand" "=r")
7687         (truncate:DWIH
7688           (lshiftrt:<DWI>
7689             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7690                         (zero_extend:<DWI> (match_dup 3)))
7691             (match_operand:QI 4 "const_int_operand" "n"))))]
7692   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7693    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7694   "mulx\t{%3, %0, %1|%1, %0, %3}"
7695   [(set_attr "type" "imulx")
7696    (set_attr "prefix" "vex")
7697    (set_attr "mode" "<MODE>")])
7699 (define_insn "*umul<mode><dwi>3_1"
7700   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7701         (mult:<DWI>
7702           (zero_extend:<DWI>
7703             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7704           (zero_extend:<DWI>
7705             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7706    (clobber (reg:CC FLAGS_REG))]
7707   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7708   "@
7709    #
7710    mul{<imodesuffix>}\t%2"
7711   [(set_attr "isa" "bmi2,*")
7712    (set_attr "type" "imulx,imul")
7713    (set_attr "length_immediate" "*,0")
7714    (set (attr "athlon_decode")
7715         (cond [(eq_attr "alternative" "1")
7716                  (if_then_else (eq_attr "cpu" "athlon")
7717                    (const_string "vector")
7718                    (const_string "double"))]
7719               (const_string "*")))
7720    (set_attr "amdfam10_decode" "*,double")
7721    (set_attr "bdver1_decode" "*,direct")
7722    (set_attr "prefix" "vex,orig")
7723    (set_attr "mode" "<MODE>")])
7725 ;; Convert mul to the mulx pattern to avoid flags dependency.
7726 (define_split
7727  [(set (match_operand:<DWI> 0 "register_operand")
7728        (mult:<DWI>
7729          (zero_extend:<DWI>
7730            (match_operand:DWIH 1 "register_operand"))
7731          (zero_extend:<DWI>
7732            (match_operand:DWIH 2 "nonimmediate_operand"))))
7733   (clobber (reg:CC FLAGS_REG))]
7734  "TARGET_BMI2 && reload_completed
7735   && REGNO (operands[1]) == DX_REG"
7736   [(parallel [(set (match_dup 3)
7737                    (mult:DWIH (match_dup 1) (match_dup 2)))
7738               (set (match_dup 4)
7739                    (truncate:DWIH
7740                      (lshiftrt:<DWI>
7741                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7742                                    (zero_extend:<DWI> (match_dup 2)))
7743                        (match_dup 5))))])]
7745   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7747   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7750 (define_insn "*mul<mode><dwi>3_1"
7751   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7752         (mult:<DWI>
7753           (sign_extend:<DWI>
7754             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7755           (sign_extend:<DWI>
7756             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7757    (clobber (reg:CC FLAGS_REG))]
7758   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7759   "imul{<imodesuffix>}\t%2"
7760   [(set_attr "type" "imul")
7761    (set_attr "length_immediate" "0")
7762    (set (attr "athlon_decode")
7763      (if_then_else (eq_attr "cpu" "athlon")
7764         (const_string "vector")
7765         (const_string "double")))
7766    (set_attr "amdfam10_decode" "double")
7767    (set_attr "bdver1_decode" "direct")
7768    (set_attr "mode" "<MODE>")])
7770 (define_insn "*<u>mulqihi3_1"
7771   [(set (match_operand:HI 0 "register_operand" "=a")
7772         (mult:HI
7773           (any_extend:HI
7774             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7775           (any_extend:HI
7776             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7777    (clobber (reg:CC FLAGS_REG))]
7778   "TARGET_QIMODE_MATH
7779    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7780   "<sgnprefix>mul{b}\t%2"
7781   [(set_attr "type" "imul")
7782    (set_attr "length_immediate" "0")
7783    (set (attr "athlon_decode")
7784      (if_then_else (eq_attr "cpu" "athlon")
7785         (const_string "vector")
7786         (const_string "direct")))
7787    (set_attr "amdfam10_decode" "direct")
7788    (set_attr "bdver1_decode" "direct")
7789    (set_attr "mode" "QI")])
7791 (define_expand "<s>mul<mode>3_highpart"
7792   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7793                    (truncate:SWI48
7794                      (lshiftrt:<DWI>
7795                        (mult:<DWI>
7796                          (any_extend:<DWI>
7797                            (match_operand:SWI48 1 "nonimmediate_operand"))
7798                          (any_extend:<DWI>
7799                            (match_operand:SWI48 2 "register_operand")))
7800                        (match_dup 3))))
7801               (clobber (match_scratch:SWI48 4))
7802               (clobber (reg:CC FLAGS_REG))])]
7803   ""
7804   "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7806 (define_insn "*<s>muldi3_highpart_1"
7807   [(set (match_operand:DI 0 "register_operand" "=d")
7808         (truncate:DI
7809           (lshiftrt:TI
7810             (mult:TI
7811               (any_extend:TI
7812                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7813               (any_extend:TI
7814                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7815             (const_int 64))))
7816    (clobber (match_scratch:DI 3 "=1"))
7817    (clobber (reg:CC FLAGS_REG))]
7818   "TARGET_64BIT
7819    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7820   "<sgnprefix>mul{q}\t%2"
7821   [(set_attr "type" "imul")
7822    (set_attr "length_immediate" "0")
7823    (set (attr "athlon_decode")
7824      (if_then_else (eq_attr "cpu" "athlon")
7825         (const_string "vector")
7826         (const_string "double")))
7827    (set_attr "amdfam10_decode" "double")
7828    (set_attr "bdver1_decode" "direct")
7829    (set_attr "mode" "DI")])
7831 (define_insn "*<s>mulsi3_highpart_zext"
7832   [(set (match_operand:DI 0 "register_operand" "=d")
7833         (zero_extend:DI (truncate:SI
7834           (lshiftrt:DI
7835             (mult:DI (any_extend:DI
7836                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7837                      (any_extend:DI
7838                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7839             (const_int 32)))))
7840    (clobber (match_scratch:SI 3 "=1"))
7841    (clobber (reg:CC FLAGS_REG))]
7842   "TARGET_64BIT
7843    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7844   "<sgnprefix>mul{l}\t%2"
7845   [(set_attr "type" "imul")
7846    (set_attr "length_immediate" "0")
7847    (set (attr "athlon_decode")
7848      (if_then_else (eq_attr "cpu" "athlon")
7849         (const_string "vector")
7850         (const_string "double")))
7851    (set_attr "amdfam10_decode" "double")
7852    (set_attr "bdver1_decode" "direct")
7853    (set_attr "mode" "SI")])
7855 (define_insn "*<s>mulsi3_highpart_1"
7856   [(set (match_operand:SI 0 "register_operand" "=d")
7857         (truncate:SI
7858           (lshiftrt:DI
7859             (mult:DI
7860               (any_extend:DI
7861                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7862               (any_extend:DI
7863                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7864             (const_int 32))))
7865    (clobber (match_scratch:SI 3 "=1"))
7866    (clobber (reg:CC FLAGS_REG))]
7867   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7868   "<sgnprefix>mul{l}\t%2"
7869   [(set_attr "type" "imul")
7870    (set_attr "length_immediate" "0")
7871    (set (attr "athlon_decode")
7872      (if_then_else (eq_attr "cpu" "athlon")
7873         (const_string "vector")
7874         (const_string "double")))
7875    (set_attr "amdfam10_decode" "double")
7876    (set_attr "bdver1_decode" "direct")
7877    (set_attr "mode" "SI")])
7879 ;; The patterns that match these are at the end of this file.
7881 (define_expand "mulxf3"
7882   [(set (match_operand:XF 0 "register_operand")
7883         (mult:XF (match_operand:XF 1 "register_operand")
7884                  (match_operand:XF 2 "register_operand")))]
7885   "TARGET_80387")
7887 (define_expand "mul<mode>3"
7888   [(set (match_operand:MODEF 0 "register_operand")
7889         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7890                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7891   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7892     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7894 ;; Divide instructions
7896 ;; The patterns that match these are at the end of this file.
7898 (define_expand "divxf3"
7899   [(set (match_operand:XF 0 "register_operand")
7900         (div:XF (match_operand:XF 1 "register_operand")
7901                 (match_operand:XF 2 "register_operand")))]
7902   "TARGET_80387")
7904 (define_expand "div<mode>3"
7905   [(set (match_operand:MODEF 0 "register_operand")
7906         (div:MODEF (match_operand:MODEF 1 "register_operand")
7907                    (match_operand:MODEF 2 "nonimmediate_operand")))]
7908   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7909     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7911   if (<MODE>mode == SFmode
7912       && TARGET_SSE && TARGET_SSE_MATH
7913       && TARGET_RECIP_DIV
7914       && optimize_insn_for_speed_p ()
7915       && flag_finite_math_only && !flag_trapping_math
7916       && flag_unsafe_math_optimizations)
7917     {
7918       ix86_emit_swdivsf (operands[0], operands[1],
7919                          operands[2], SFmode);
7920       DONE;
7921     }
7924 ;; Divmod instructions.
7926 (define_expand "divmod<mode>4"
7927   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7928                    (div:SWIM248
7929                      (match_operand:SWIM248 1 "register_operand")
7930                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7931               (set (match_operand:SWIM248 3 "register_operand")
7932                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7933               (clobber (reg:CC FLAGS_REG))])])
7935 ;; Split with 8bit unsigned divide:
7936 ;;      if (dividend an divisor are in [0-255])
7937 ;;         use 8bit unsigned integer divide
7938 ;;       else
7939 ;;         use original integer divide
7940 (define_split
7941   [(set (match_operand:SWI48 0 "register_operand")
7942         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7943                     (match_operand:SWI48 3 "nonimmediate_operand")))
7944    (set (match_operand:SWI48 1 "register_operand")
7945         (mod:SWI48 (match_dup 2) (match_dup 3)))
7946    (clobber (reg:CC FLAGS_REG))]
7947   "TARGET_USE_8BIT_IDIV
7948    && TARGET_QIMODE_MATH
7949    && can_create_pseudo_p ()
7950    && !optimize_insn_for_size_p ()"
7951   [(const_int 0)]
7952   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7954 (define_split
7955   [(set (match_operand:DI 0 "register_operand")
7956         (zero_extend:DI
7957           (div:SI (match_operand:SI 2 "register_operand")
7958                   (match_operand:SI 3 "nonimmediate_operand"))))
7959    (set (match_operand:SI 1 "register_operand")
7960         (mod:SI (match_dup 2) (match_dup 3)))
7961    (clobber (reg:CC FLAGS_REG))]
7962   "TARGET_USE_8BIT_IDIV
7963    && TARGET_QIMODE_MATH
7964    && can_create_pseudo_p ()
7965    && !optimize_insn_for_size_p ()"
7966   [(const_int 0)]
7967   "ix86_split_idivmod (SImode, operands, true); DONE;")
7969 (define_split
7970   [(set (match_operand:DI 1 "register_operand")
7971         (zero_extend:DI
7972           (mod:SI (match_operand:SI 2 "register_operand")
7973                   (match_operand:SI 3 "nonimmediate_operand"))))
7974    (set (match_operand:SI 0 "register_operand")
7975         (div:SI  (match_dup 2) (match_dup 3)))
7976    (clobber (reg:CC FLAGS_REG))]
7977   "TARGET_USE_8BIT_IDIV
7978    && TARGET_QIMODE_MATH
7979    && can_create_pseudo_p ()
7980    && !optimize_insn_for_size_p ()"
7981   [(const_int 0)]
7982   "ix86_split_idivmod (SImode, operands, true); DONE;")
7984 (define_insn_and_split "divmod<mode>4_1"
7985   [(set (match_operand:SWI48 0 "register_operand" "=a")
7986         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7987                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7988    (set (match_operand:SWI48 1 "register_operand" "=&d")
7989         (mod:SWI48 (match_dup 2) (match_dup 3)))
7990    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7991    (clobber (reg:CC FLAGS_REG))]
7992   ""
7993   "#"
7994   "reload_completed"
7995   [(parallel [(set (match_dup 1)
7996                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7997               (clobber (reg:CC FLAGS_REG))])
7998    (parallel [(set (match_dup 0)
7999                    (div:SWI48 (match_dup 2) (match_dup 3)))
8000               (set (match_dup 1)
8001                    (mod:SWI48 (match_dup 2) (match_dup 3)))
8002               (use (match_dup 1))
8003               (clobber (reg:CC FLAGS_REG))])]
8005   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8007   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8008     operands[4] = operands[2];
8009   else
8010     {
8011       /* Avoid use of cltd in favor of a mov+shift.  */
8012       emit_move_insn (operands[1], operands[2]);
8013       operands[4] = operands[1];
8014     }
8016   [(set_attr "type" "multi")
8017    (set_attr "mode" "<MODE>")])
8019 (define_insn_and_split "divmodsi4_zext_1"
8020   [(set (match_operand:DI 0 "register_operand" "=a")
8021         (zero_extend:DI
8022           (div:SI (match_operand:SI 2 "register_operand" "0")
8023                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8024    (set (match_operand:SI 1 "register_operand" "=&d")
8025         (mod:SI (match_dup 2) (match_dup 3)))
8026    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8027    (clobber (reg:CC FLAGS_REG))]
8028   "TARGET_64BIT"
8029   "#"
8030   "reload_completed"
8031   [(parallel [(set (match_dup 1)
8032                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8033               (clobber (reg:CC FLAGS_REG))])
8034    (parallel [(set (match_dup 0)
8035                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8036               (set (match_dup 1)
8037                    (mod:SI (match_dup 2) (match_dup 3)))
8038               (use (match_dup 1))
8039               (clobber (reg:CC FLAGS_REG))])]
8041   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8043   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8044     operands[4] = operands[2];
8045   else
8046     {
8047       /* Avoid use of cltd in favor of a mov+shift.  */
8048       emit_move_insn (operands[1], operands[2]);
8049       operands[4] = operands[1];
8050     }
8052   [(set_attr "type" "multi")
8053    (set_attr "mode" "SI")])
8055 (define_insn_and_split "divmodsi4_zext_2"
8056   [(set (match_operand:DI 1 "register_operand" "=&d")
8057         (zero_extend:DI
8058           (mod:SI (match_operand:SI 2 "register_operand" "0")
8059                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8060    (set (match_operand:SI 0 "register_operand" "=a")
8061         (div:SI (match_dup 2) (match_dup 3)))
8062    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8063    (clobber (reg:CC FLAGS_REG))]
8064   "TARGET_64BIT"
8065   "#"
8066   "reload_completed"
8067   [(parallel [(set (match_dup 6)
8068                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8069               (clobber (reg:CC FLAGS_REG))])
8070    (parallel [(set (match_dup 1)
8071                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8072               (set (match_dup 0)
8073                    (div:SI (match_dup 2) (match_dup 3)))
8074               (use (match_dup 6))
8075               (clobber (reg:CC FLAGS_REG))])]
8077   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8078   operands[6] = gen_lowpart (SImode, operands[1]);
8080   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8081     operands[4] = operands[2];
8082   else
8083     {
8084       /* Avoid use of cltd in favor of a mov+shift.  */
8085       emit_move_insn (operands[6], operands[2]);
8086       operands[4] = operands[6];
8087     }
8089   [(set_attr "type" "multi")
8090    (set_attr "mode" "SI")])
8092 (define_insn_and_split "*divmod<mode>4"
8093   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8094         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8095                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8096    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8097         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8098    (clobber (reg:CC FLAGS_REG))]
8099   ""
8100   "#"
8101   "reload_completed"
8102   [(parallel [(set (match_dup 1)
8103                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8104               (clobber (reg:CC FLAGS_REG))])
8105    (parallel [(set (match_dup 0)
8106                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8107               (set (match_dup 1)
8108                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8109               (use (match_dup 1))
8110               (clobber (reg:CC FLAGS_REG))])]
8112   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8114   if (<MODE>mode != HImode
8115       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8116     operands[4] = operands[2];
8117   else
8118     {
8119       /* Avoid use of cltd in favor of a mov+shift.  */
8120       emit_move_insn (operands[1], operands[2]);
8121       operands[4] = operands[1];
8122     }
8124   [(set_attr "type" "multi")
8125    (set_attr "mode" "<MODE>")])
8127 (define_insn_and_split "*divmodsi4_zext_1"
8128   [(set (match_operand:DI 0 "register_operand" "=a")
8129         (zero_extend:DI
8130           (div:SI (match_operand:SI 2 "register_operand" "0")
8131                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8132    (set (match_operand:SI 1 "register_operand" "=&d")
8133         (mod:SI (match_dup 2) (match_dup 3)))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "TARGET_64BIT"
8136   "#"
8137   "reload_completed"
8138   [(parallel [(set (match_dup 1)
8139                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8140               (clobber (reg:CC FLAGS_REG))])
8141    (parallel [(set (match_dup 0)
8142                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8143               (set (match_dup 1)
8144                    (mod:SI (match_dup 2) (match_dup 3)))
8145               (use (match_dup 1))
8146               (clobber (reg:CC FLAGS_REG))])]
8148   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8150   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8151     operands[4] = operands[2];
8152   else
8153     {
8154       /* Avoid use of cltd in favor of a mov+shift.  */
8155       emit_move_insn (operands[1], operands[2]);
8156       operands[4] = operands[1];
8157     }
8159   [(set_attr "type" "multi")
8160    (set_attr "mode" "SI")])
8162 (define_insn_and_split "*divmodsi4_zext_2"
8163   [(set (match_operand:DI 1 "register_operand" "=&d")
8164         (zero_extend:DI
8165           (mod:SI (match_operand:SI 2 "register_operand" "0")
8166                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8167    (set (match_operand:SI 0 "register_operand" "=a")
8168         (div:SI (match_dup 2) (match_dup 3)))
8169    (clobber (reg:CC FLAGS_REG))]
8170   "TARGET_64BIT"
8171   "#"
8172   "reload_completed"
8173   [(parallel [(set (match_dup 6)
8174                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
8175               (clobber (reg:CC FLAGS_REG))])
8176    (parallel [(set (match_dup 1)
8177                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8178               (set (match_dup 0)
8179                    (div:SI (match_dup 2) (match_dup 3)))
8180               (use (match_dup 6))
8181               (clobber (reg:CC FLAGS_REG))])]
8183   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8184   operands[6] = gen_lowpart (SImode, operands[1]);
8186   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8187     operands[4] = operands[2];
8188   else
8189     {
8190       /* Avoid use of cltd in favor of a mov+shift.  */
8191       emit_move_insn (operands[6], operands[2]);
8192       operands[4] = operands[6];
8193     }
8195   [(set_attr "type" "multi")
8196    (set_attr "mode" "SI")])
8198 (define_insn "*divmod<mode>4_noext"
8199   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8200         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8201                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8202    (set (match_operand:SWIM248 1 "register_operand" "=d")
8203         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8204    (use (match_operand:SWIM248 4 "register_operand" "1"))
8205    (clobber (reg:CC FLAGS_REG))]
8206   ""
8207   "idiv{<imodesuffix>}\t%3"
8208   [(set_attr "type" "idiv")
8209    (set_attr "mode" "<MODE>")])
8211 (define_insn "*divmodsi4_noext_zext_1"
8212   [(set (match_operand:DI 0 "register_operand" "=a")
8213         (zero_extend:DI
8214           (div:SI (match_operand:SI 2 "register_operand" "0")
8215                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8216    (set (match_operand:SI 1 "register_operand" "=d")
8217         (mod:SI (match_dup 2) (match_dup 3)))
8218    (use (match_operand:SI 4 "register_operand" "1"))
8219    (clobber (reg:CC FLAGS_REG))]
8220   "TARGET_64BIT"
8221   "idiv{l}\t%3"
8222   [(set_attr "type" "idiv")
8223    (set_attr "mode" "SI")])
8225 (define_insn "*divmodsi4_noext_zext_2"
8226   [(set (match_operand:DI 1 "register_operand" "=d")
8227         (zero_extend:DI
8228           (mod:SI (match_operand:SI 2 "register_operand" "0")
8229                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8230    (set (match_operand:SI 0 "register_operand" "=a")
8231         (div:SI (match_dup 2) (match_dup 3)))
8232    (use (match_operand:SI 4 "register_operand" "1"))
8233    (clobber (reg:CC FLAGS_REG))]
8234   "TARGET_64BIT"
8235   "idiv{l}\t%3"
8236   [(set_attr "type" "idiv")
8237    (set_attr "mode" "SI")])
8239 (define_expand "divmodqi4"
8240   [(parallel [(set (match_operand:QI 0 "register_operand")
8241                    (div:QI
8242                      (match_operand:QI 1 "register_operand")
8243                      (match_operand:QI 2 "nonimmediate_operand")))
8244               (set (match_operand:QI 3 "register_operand")
8245                    (mod:QI (match_dup 1) (match_dup 2)))
8246               (clobber (reg:CC FLAGS_REG))])]
8247   "TARGET_QIMODE_MATH"
8249   rtx div, mod;
8250   rtx tmp0, tmp1;
8251   
8252   tmp0 = gen_reg_rtx (HImode);
8253   tmp1 = gen_reg_rtx (HImode);
8255   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8256   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8257   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8259   /* Extract remainder from AH.  */
8260   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8261   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8262   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8264   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8265   set_unique_reg_note (insn, REG_EQUAL, mod);
8267   /* Extract quotient from AL.  */
8268   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8270   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8271   set_unique_reg_note (insn, REG_EQUAL, div);
8273   DONE;
8276 ;; Divide AX by r/m8, with result stored in
8277 ;; AL <- Quotient
8278 ;; AH <- Remainder
8279 ;; Change div/mod to HImode and extend the second argument to HImode
8280 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
8281 ;; combine may fail.
8282 (define_insn "divmodhiqi3"
8283   [(set (match_operand:HI 0 "register_operand" "=a")
8284         (ior:HI
8285           (ashift:HI
8286             (zero_extend:HI
8287               (truncate:QI
8288                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8289                         (sign_extend:HI
8290                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8291             (const_int 8))
8292           (zero_extend:HI
8293             (truncate:QI
8294               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "TARGET_QIMODE_MATH"
8297   "idiv{b}\t%2"
8298   [(set_attr "type" "idiv")
8299    (set_attr "mode" "QI")])
8301 (define_expand "udivmod<mode>4"
8302   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8303                    (udiv:SWIM248
8304                      (match_operand:SWIM248 1 "register_operand")
8305                      (match_operand:SWIM248 2 "nonimmediate_operand")))
8306               (set (match_operand:SWIM248 3 "register_operand")
8307                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8308               (clobber (reg:CC FLAGS_REG))])])
8310 ;; Split with 8bit unsigned divide:
8311 ;;      if (dividend an divisor are in [0-255])
8312 ;;         use 8bit unsigned integer divide
8313 ;;       else
8314 ;;         use original integer divide
8315 (define_split
8316   [(set (match_operand:SWI48 0 "register_operand")
8317         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8318                     (match_operand:SWI48 3 "nonimmediate_operand")))
8319    (set (match_operand:SWI48 1 "register_operand")
8320         (umod:SWI48 (match_dup 2) (match_dup 3)))
8321    (clobber (reg:CC FLAGS_REG))]
8322   "TARGET_USE_8BIT_IDIV
8323    && TARGET_QIMODE_MATH
8324    && can_create_pseudo_p ()
8325    && !optimize_insn_for_size_p ()"
8326   [(const_int 0)]
8327   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8329 (define_split
8330   [(set (match_operand:DI 0 "register_operand")
8331         (zero_extend:DI
8332           (udiv:SI (match_operand:SI 2 "register_operand")
8333                    (match_operand:SI 3 "nonimmediate_operand"))))
8334    (set (match_operand:SI 1 "register_operand")
8335         (umod:SI (match_dup 2) (match_dup 3)))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "TARGET_64BIT
8338    && TARGET_USE_8BIT_IDIV
8339    && TARGET_QIMODE_MATH
8340    && can_create_pseudo_p ()
8341    && !optimize_insn_for_size_p ()"
8342   [(const_int 0)]
8343   "ix86_split_idivmod (SImode, operands, false); DONE;")
8345 (define_split
8346   [(set (match_operand:DI 1 "register_operand")
8347         (zero_extend:DI
8348           (umod:SI (match_operand:SI 2 "register_operand")
8349                    (match_operand:SI 3 "nonimmediate_operand"))))
8350    (set (match_operand:SI 0 "register_operand")
8351         (udiv:SI (match_dup 2) (match_dup 3)))
8352    (clobber (reg:CC FLAGS_REG))]
8353   "TARGET_64BIT
8354    && TARGET_USE_8BIT_IDIV
8355    && TARGET_QIMODE_MATH
8356    && can_create_pseudo_p ()
8357    && !optimize_insn_for_size_p ()"
8358   [(const_int 0)]
8359   "ix86_split_idivmod (SImode, operands, false); DONE;")
8361 (define_insn_and_split "udivmod<mode>4_1"
8362   [(set (match_operand:SWI48 0 "register_operand" "=a")
8363         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8364                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8365    (set (match_operand:SWI48 1 "register_operand" "=&d")
8366         (umod:SWI48 (match_dup 2) (match_dup 3)))
8367    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8368    (clobber (reg:CC FLAGS_REG))]
8369   ""
8370   "#"
8371   "reload_completed"
8372   [(set (match_dup 1) (const_int 0))
8373    (parallel [(set (match_dup 0)
8374                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
8375               (set (match_dup 1)
8376                    (umod:SWI48 (match_dup 2) (match_dup 3)))
8377               (use (match_dup 1))
8378               (clobber (reg:CC FLAGS_REG))])]
8379   ""
8380   [(set_attr "type" "multi")
8381    (set_attr "mode" "<MODE>")])
8383 (define_insn_and_split "udivmodsi4_zext_1"
8384   [(set (match_operand:DI 0 "register_operand" "=a")
8385         (zero_extend:DI
8386           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8387                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8388    (set (match_operand:SI 1 "register_operand" "=&d")
8389         (umod:SI (match_dup 2) (match_dup 3)))
8390    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8391    (clobber (reg:CC FLAGS_REG))]
8392   "TARGET_64BIT"
8393   "#"
8394   "reload_completed"
8395   [(set (match_dup 1) (const_int 0))
8396    (parallel [(set (match_dup 0)
8397                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8398               (set (match_dup 1)
8399                    (umod:SI (match_dup 2) (match_dup 3)))
8400               (use (match_dup 1))
8401               (clobber (reg:CC FLAGS_REG))])]
8402   ""
8403   [(set_attr "type" "multi")
8404    (set_attr "mode" "SI")])
8406 (define_insn_and_split "udivmodsi4_zext_2"
8407   [(set (match_operand:DI 1 "register_operand" "=&d")
8408         (zero_extend:DI
8409           (umod:SI (match_operand:SI 2 "register_operand" "0")
8410                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8411    (set (match_operand:SI 0 "register_operand" "=a")
8412         (udiv:SI (match_dup 2) (match_dup 3)))
8413    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8414    (clobber (reg:CC FLAGS_REG))]
8415   "TARGET_64BIT"
8416   "#"
8417   "reload_completed"
8418   [(set (match_dup 4) (const_int 0))
8419    (parallel [(set (match_dup 1)
8420                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8421               (set (match_dup 0)
8422                    (udiv:SI (match_dup 2) (match_dup 3)))
8423               (use (match_dup 4))
8424               (clobber (reg:CC FLAGS_REG))])]
8425   "operands[4] = gen_lowpart (SImode, operands[1]);"
8426   [(set_attr "type" "multi")
8427    (set_attr "mode" "SI")])
8429 (define_insn_and_split "*udivmod<mode>4"
8430   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8431         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8432                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8433    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8434         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8435    (clobber (reg:CC FLAGS_REG))]
8436   ""
8437   "#"
8438   "reload_completed"
8439   [(set (match_dup 1) (const_int 0))
8440    (parallel [(set (match_dup 0)
8441                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8442               (set (match_dup 1)
8443                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8444               (use (match_dup 1))
8445               (clobber (reg:CC FLAGS_REG))])]
8446   ""
8447   [(set_attr "type" "multi")
8448    (set_attr "mode" "<MODE>")])
8450 (define_insn_and_split "*udivmodsi4_zext_1"
8451   [(set (match_operand:DI 0 "register_operand" "=a")
8452         (zero_extend:DI
8453           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8454                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8455    (set (match_operand:SI 1 "register_operand" "=&d")
8456         (umod:SI (match_dup 2) (match_dup 3)))
8457    (clobber (reg:CC FLAGS_REG))]
8458   "TARGET_64BIT"
8459   "#"
8460   "reload_completed"
8461   [(set (match_dup 1) (const_int 0))
8462    (parallel [(set (match_dup 0)
8463                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8464               (set (match_dup 1)
8465                    (umod:SI (match_dup 2) (match_dup 3)))
8466               (use (match_dup 1))
8467               (clobber (reg:CC FLAGS_REG))])]
8468   ""
8469   [(set_attr "type" "multi")
8470    (set_attr "mode" "SI")])
8472 (define_insn_and_split "*udivmodsi4_zext_2"
8473   [(set (match_operand:DI 1 "register_operand" "=&d")
8474         (zero_extend:DI
8475           (umod:SI (match_operand:SI 2 "register_operand" "0")
8476                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8477    (set (match_operand:SI 0 "register_operand" "=a")
8478         (udiv:SI (match_dup 2) (match_dup 3)))
8479    (clobber (reg:CC FLAGS_REG))]
8480   "TARGET_64BIT"
8481   "#"
8482   "reload_completed"
8483   [(set (match_dup 4) (const_int 0))
8484    (parallel [(set (match_dup 1)
8485                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8486               (set (match_dup 0)
8487                    (udiv:SI (match_dup 2) (match_dup 3)))
8488               (use (match_dup 4))
8489               (clobber (reg:CC FLAGS_REG))])]
8490   "operands[4] = gen_lowpart (SImode, operands[1]);"
8491   [(set_attr "type" "multi")
8492    (set_attr "mode" "SI")])
8494 ;; Optimize division or modulo by constant power of 2, if the constant
8495 ;; materializes only after expansion.
8496 (define_insn_and_split "*udivmod<mode>4_pow2"
8497   [(set (match_operand:SWI48 0 "register_operand" "=r")
8498         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8499                     (match_operand:SWI48 3 "const_int_operand" "n")))
8500    (set (match_operand:SWI48 1 "register_operand" "=r")
8501         (umod:SWI48 (match_dup 2) (match_dup 3)))
8502    (clobber (reg:CC FLAGS_REG))]
8503   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8504    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8505   "#"
8506   "&& 1"
8507   [(set (match_dup 1) (match_dup 2))
8508    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8509               (clobber (reg:CC FLAGS_REG))])
8510    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8511               (clobber (reg:CC FLAGS_REG))])]
8513   int v = exact_log2 (UINTVAL (operands[3]));
8514   operands[4] = GEN_INT (v);
8515   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8517   [(set_attr "type" "multi")
8518    (set_attr "mode" "<MODE>")])
8520 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8521   [(set (match_operand:DI 0 "register_operand" "=r")
8522         (zero_extend:DI
8523           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8524                    (match_operand:SI 3 "const_int_operand" "n"))))
8525    (set (match_operand:SI 1 "register_operand" "=r")
8526         (umod:SI (match_dup 2) (match_dup 3)))
8527    (clobber (reg:CC FLAGS_REG))]
8528   "TARGET_64BIT
8529    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8530    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8531   "#"
8532   "&& 1"
8533   [(set (match_dup 1) (match_dup 2))
8534    (parallel [(set (match_dup 0)
8535                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8536               (clobber (reg:CC FLAGS_REG))])
8537    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8538               (clobber (reg:CC FLAGS_REG))])]
8540   int v = exact_log2 (UINTVAL (operands[3]));
8541   operands[4] = GEN_INT (v);
8542   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8544   [(set_attr "type" "multi")
8545    (set_attr "mode" "SI")])
8547 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8548   [(set (match_operand:DI 1 "register_operand" "=r")
8549         (zero_extend:DI
8550           (umod:SI (match_operand:SI 2 "register_operand" "0")
8551                    (match_operand:SI 3 "const_int_operand" "n"))))
8552    (set (match_operand:SI 0 "register_operand" "=r")
8553         (umod:SI (match_dup 2) (match_dup 3)))
8554    (clobber (reg:CC FLAGS_REG))]
8555   "TARGET_64BIT
8556    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8557    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8558   "#"
8559   "&& 1"
8560   [(set (match_dup 1) (match_dup 2))
8561    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8562               (clobber (reg:CC FLAGS_REG))])
8563    (parallel [(set (match_dup 1)
8564                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8565               (clobber (reg:CC FLAGS_REG))])]
8567   int v = exact_log2 (UINTVAL (operands[3]));
8568   operands[4] = GEN_INT (v);
8569   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8571   [(set_attr "type" "multi")
8572    (set_attr "mode" "SI")])
8574 (define_insn "*udivmod<mode>4_noext"
8575   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8576         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8577                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8578    (set (match_operand:SWIM248 1 "register_operand" "=d")
8579         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8580    (use (match_operand:SWIM248 4 "register_operand" "1"))
8581    (clobber (reg:CC FLAGS_REG))]
8582   ""
8583   "div{<imodesuffix>}\t%3"
8584   [(set_attr "type" "idiv")
8585    (set_attr "mode" "<MODE>")])
8587 (define_insn "*udivmodsi4_noext_zext_1"
8588   [(set (match_operand:DI 0 "register_operand" "=a")
8589         (zero_extend:DI
8590           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8591                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8592    (set (match_operand:SI 1 "register_operand" "=d")
8593         (umod:SI (match_dup 2) (match_dup 3)))
8594    (use (match_operand:SI 4 "register_operand" "1"))
8595    (clobber (reg:CC FLAGS_REG))]
8596   "TARGET_64BIT"
8597   "div{l}\t%3"
8598   [(set_attr "type" "idiv")
8599    (set_attr "mode" "SI")])
8601 (define_insn "*udivmodsi4_noext_zext_2"
8602   [(set (match_operand:DI 1 "register_operand" "=d")
8603         (zero_extend:DI
8604           (umod:SI (match_operand:SI 2 "register_operand" "0")
8605                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8606    (set (match_operand:SI 0 "register_operand" "=a")
8607         (udiv:SI (match_dup 2) (match_dup 3)))
8608    (use (match_operand:SI 4 "register_operand" "1"))
8609    (clobber (reg:CC FLAGS_REG))]
8610   "TARGET_64BIT"
8611   "div{l}\t%3"
8612   [(set_attr "type" "idiv")
8613    (set_attr "mode" "SI")])
8615 (define_expand "udivmodqi4"
8616   [(parallel [(set (match_operand:QI 0 "register_operand")
8617                    (udiv:QI
8618                      (match_operand:QI 1 "register_operand")
8619                      (match_operand:QI 2 "nonimmediate_operand")))
8620               (set (match_operand:QI 3 "register_operand")
8621                    (umod:QI (match_dup 1) (match_dup 2)))
8622               (clobber (reg:CC FLAGS_REG))])]
8623   "TARGET_QIMODE_MATH"
8625   rtx div, mod;
8626   rtx tmp0, tmp1;
8627   
8628   tmp0 = gen_reg_rtx (HImode);
8629   tmp1 = gen_reg_rtx (HImode);
8631   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8632   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8633   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8635   /* Extract remainder from AH.  */
8636   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8637   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8638   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8640   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8641   set_unique_reg_note (insn, REG_EQUAL, mod);
8643   /* Extract quotient from AL.  */
8644   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8646   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8647   set_unique_reg_note (insn, REG_EQUAL, div);
8649   DONE;
8652 (define_insn "udivmodhiqi3"
8653   [(set (match_operand:HI 0 "register_operand" "=a")
8654         (ior:HI
8655           (ashift:HI
8656             (zero_extend:HI
8657               (truncate:QI
8658                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8659                         (zero_extend:HI
8660                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8661             (const_int 8))
8662           (zero_extend:HI
8663             (truncate:QI
8664               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8665    (clobber (reg:CC FLAGS_REG))]
8666   "TARGET_QIMODE_MATH"
8667   "div{b}\t%2"
8668   [(set_attr "type" "idiv")
8669    (set_attr "mode" "QI")])
8671 ;; We cannot use div/idiv for double division, because it causes
8672 ;; "division by zero" on the overflow and that's not what we expect
8673 ;; from truncate.  Because true (non truncating) double division is
8674 ;; never generated, we can't create this insn anyway.
8676 ;(define_insn ""
8677 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8678 ;       (truncate:SI
8679 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8680 ;                  (zero_extend:DI
8681 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8682 ;   (set (match_operand:SI 3 "register_operand" "=d")
8683 ;       (truncate:SI
8684 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8685 ;   (clobber (reg:CC FLAGS_REG))]
8686 ;  ""
8687 ;  "div{l}\t{%2, %0|%0, %2}"
8688 ;  [(set_attr "type" "idiv")])
8690 ;;- Logical AND instructions
8692 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8693 ;; Note that this excludes ah.
8695 (define_expand "testsi_ccno_1"
8696   [(set (reg:CCNO FLAGS_REG)
8697         (compare:CCNO
8698           (and:SI (match_operand:SI 0 "nonimmediate_operand")
8699                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
8700           (const_int 0)))])
8702 (define_expand "testqi_ccz_1"
8703   [(set (reg:CCZ FLAGS_REG)
8704         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8705                              (match_operand:QI 1 "nonmemory_operand"))
8706                  (const_int 0)))])
8708 (define_expand "testdi_ccno_1"
8709   [(set (reg:CCNO FLAGS_REG)
8710         (compare:CCNO
8711           (and:DI (match_operand:DI 0 "nonimmediate_operand")
8712                   (match_operand:DI 1 "x86_64_szext_general_operand"))
8713           (const_int 0)))]
8714   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8716 (define_insn "*testdi_1"
8717   [(set (reg FLAGS_REG)
8718         (compare
8719          (and:DI
8720           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8721           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8722          (const_int 0)))]
8723   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8724    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8725   "@
8726    test{l}\t{%k1, %k0|%k0, %k1}
8727    test{l}\t{%k1, %k0|%k0, %k1}
8728    test{q}\t{%1, %0|%0, %1}
8729    test{q}\t{%1, %0|%0, %1}
8730    test{q}\t{%1, %0|%0, %1}"
8731   [(set_attr "type" "test")
8732    (set_attr "modrm" "0,1,0,1,1")
8733    (set_attr "mode" "SI,SI,DI,DI,DI")])
8735 (define_insn "*testqi_1_maybe_si"
8736   [(set (reg FLAGS_REG)
8737         (compare
8738           (and:QI
8739             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8740             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8741           (const_int 0)))]
8742    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8743     && ix86_match_ccmode (insn,
8744                          CONST_INT_P (operands[1])
8745                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8747   if (which_alternative == 3)
8748     {
8749       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8750         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8751       return "test{l}\t{%1, %k0|%k0, %1}";
8752     }
8753   return "test{b}\t{%1, %0|%0, %1}";
8755   [(set_attr "type" "test")
8756    (set_attr "modrm" "0,1,1,1")
8757    (set_attr "mode" "QI,QI,QI,SI")
8758    (set_attr "pent_pair" "uv,np,uv,np")])
8760 (define_insn "*test<mode>_1"
8761   [(set (reg FLAGS_REG)
8762         (compare
8763          (and:SWI124
8764           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8765           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8766          (const_int 0)))]
8767   "ix86_match_ccmode (insn, CCNOmode)
8768    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8769   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8770   [(set_attr "type" "test")
8771    (set_attr "modrm" "0,1,1")
8772    (set_attr "mode" "<MODE>")
8773    (set_attr "pent_pair" "uv,np,uv")])
8775 (define_expand "testqi_ext_1_ccno"
8776   [(set (reg:CCNO FLAGS_REG)
8777         (compare:CCNO
8778           (and:QI
8779             (subreg:QI
8780               (zero_extract:SI (match_operand 0 "ext_register_operand")
8781                                (const_int 8)
8782                                (const_int 8)) 0)
8783               (match_operand 1 "const_int_operand"))
8784           (const_int 0)))])
8786 (define_insn "*testqi_ext_1"
8787   [(set (reg FLAGS_REG)
8788         (compare
8789           (and:QI
8790             (subreg:QI
8791               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8792                                (const_int 8)
8793                                (const_int 8)) 0)
8794             (match_operand:QI 1 "general_operand" "QnBc,m"))
8795           (const_int 0)))]
8796   "ix86_match_ccmode (insn, CCNOmode)"
8797   "test{b}\t{%1, %h0|%h0, %1}"
8798   [(set_attr "isa" "*,nox64")
8799    (set_attr "type" "test")
8800    (set_attr "mode" "QI")])
8802 (define_insn "*testqi_ext_2"
8803   [(set (reg FLAGS_REG)
8804         (compare
8805           (and:QI
8806             (subreg:QI
8807               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8808                                (const_int 8)
8809                                (const_int 8)) 0)
8810             (subreg:QI
8811               (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8812                                (const_int 8)
8813                                (const_int 8)) 0))
8814           (const_int 0)))]
8815   "ix86_match_ccmode (insn, CCNOmode)"
8816   "test{b}\t{%h1, %h0|%h0, %h1}"
8817   [(set_attr "type" "test")
8818    (set_attr "mode" "QI")])
8820 ;; Combine likes to form bit extractions for some tests.  Humor it.
8821 (define_insn_and_split "*testqi_ext_3"
8822   [(set (match_operand 0 "flags_reg_operand")
8823         (match_operator 1 "compare_operator"
8824           [(zero_extract:SWI248
8825              (match_operand 2 "nonimmediate_operand" "rm")
8826              (match_operand 3 "const_int_operand" "n")
8827              (match_operand 4 "const_int_operand" "n"))
8828            (const_int 0)]))]
8829   "ix86_match_ccmode (insn, CCNOmode)
8830    && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8831        || GET_MODE (operands[2]) == SImode
8832        || GET_MODE (operands[2]) == HImode
8833        || GET_MODE (operands[2]) == QImode)
8834    /* Ensure that resulting mask is zero or sign extended operand.  */
8835    && INTVAL (operands[4]) >= 0
8836    && ((INTVAL (operands[3]) > 0
8837         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8838        || (<MODE>mode == DImode
8839            && INTVAL (operands[3]) > 32
8840            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8841   "#"
8842   "&& 1"
8843   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8845   rtx val = operands[2];
8846   HOST_WIDE_INT len = INTVAL (operands[3]);
8847   HOST_WIDE_INT pos = INTVAL (operands[4]);
8848   machine_mode mode = GET_MODE (val);
8850   if (SUBREG_P (val))
8851     {
8852       machine_mode submode = GET_MODE (SUBREG_REG (val));
8854       /* Narrow paradoxical subregs to prevent partial register stalls.  */
8855       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8856           && GET_MODE_CLASS (submode) == MODE_INT)
8857         {
8858           val = SUBREG_REG (val);
8859           mode = submode;
8860         }
8861     }
8863   /* Small HImode tests can be converted to QImode.  */
8864   if (register_operand (val, HImode) && pos + len <= 8)
8865     {
8866       val = gen_lowpart (QImode, val);
8867       mode = QImode;
8868     }
8870   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8872   wide_int mask
8873     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8875   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8878 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8879 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8880 ;; this is relatively important trick.
8881 ;; Do the conversion only post-reload to avoid limiting of the register class
8882 ;; to QI regs.
8883 (define_split
8884   [(set (match_operand 0 "flags_reg_operand")
8885         (match_operator 1 "compare_operator"
8886           [(and (match_operand 2 "QIreg_operand")
8887                 (match_operand 3 "const_int_operand"))
8888            (const_int 0)]))]
8889    "reload_completed
8890     && GET_MODE (operands[2]) != QImode
8891     && ((ix86_match_ccmode (insn, CCZmode)
8892          && !(INTVAL (operands[3]) & ~(255 << 8)))
8893         || (ix86_match_ccmode (insn, CCNOmode)
8894             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8895   [(set (match_dup 0)
8896         (match_op_dup 1
8897           [(and:QI
8898              (subreg:QI
8899                (zero_extract:SI (match_dup 2)
8900                                 (const_int 8)
8901                                 (const_int 8)) 0)
8902              (match_dup 3))
8903            (const_int 0)]))]
8905   operands[2] = gen_lowpart (SImode, operands[2]);
8906   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8909 (define_split
8910   [(set (match_operand 0 "flags_reg_operand")
8911         (match_operator 1 "compare_operator"
8912           [(and (match_operand 2 "nonimmediate_operand")
8913                 (match_operand 3 "const_int_operand"))
8914            (const_int 0)]))]
8915    "reload_completed
8916     && GET_MODE (operands[2]) != QImode
8917     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8918     && ((ix86_match_ccmode (insn, CCZmode)
8919          && !(INTVAL (operands[3]) & ~255))
8920         || (ix86_match_ccmode (insn, CCNOmode)
8921             && !(INTVAL (operands[3]) & ~127)))"
8922   [(set (match_dup 0)
8923         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8924                          (const_int 0)]))]
8926   operands[2] = gen_lowpart (QImode, operands[2]);
8927   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8930 ;; %%% This used to optimize known byte-wide and operations to memory,
8931 ;; and sometimes to QImode registers.  If this is considered useful,
8932 ;; it should be done with splitters.
8934 (define_expand "and<mode>3"
8935   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8936         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8937                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8938   ""
8940   machine_mode mode = <MODE>mode;
8941   rtx (*insn) (rtx, rtx);
8943   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8944     {
8945       HOST_WIDE_INT ival = INTVAL (operands[2]);
8947       if (ival == (HOST_WIDE_INT) 0xffffffff)
8948         mode = SImode;
8949       else if (ival == 0xffff)
8950         mode = HImode;
8951       else if (ival == 0xff)
8952         mode = QImode;
8953       }
8955   if (mode == <MODE>mode)
8956     {
8957       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8958       DONE;
8959     }
8961   if (<MODE>mode == DImode)
8962     insn = (mode == SImode)
8963            ? gen_zero_extendsidi2
8964            : (mode == HImode)
8965            ? gen_zero_extendhidi2
8966            : gen_zero_extendqidi2;
8967   else if (<MODE>mode == SImode)
8968     insn = (mode == HImode)
8969            ? gen_zero_extendhisi2
8970            : gen_zero_extendqisi2;
8971   else if (<MODE>mode == HImode)
8972     insn = gen_zero_extendqihi2;
8973   else
8974     gcc_unreachable ();
8976   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8977   DONE;
8980 (define_insn_and_split "*anddi3_doubleword"
8981   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8982         (and:DI
8983          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8984          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8985    (clobber (reg:CC FLAGS_REG))]
8986   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8987    && ix86_binary_operator_ok (AND, DImode, operands)"
8988   "#"
8989   "&& reload_completed"
8990   [(const_int 0)]
8992   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8993   if (operands[2] == const0_rtx)
8994     {
8995       operands[1] = const0_rtx;
8996       ix86_expand_move (SImode, &operands[0]);
8997     }
8998   else if (operands[2] != constm1_rtx)
8999     ix86_expand_binary_operator (AND, SImode, &operands[0]);
9000   else if (operands[5] == constm1_rtx)
9001     emit_note (NOTE_INSN_DELETED);
9002   if (operands[5] == const0_rtx)
9003     {
9004       operands[4] = const0_rtx;
9005       ix86_expand_move (SImode, &operands[3]);
9006     }
9007   else if (operands[5] != constm1_rtx)
9008     ix86_expand_binary_operator (AND, SImode, &operands[3]);
9009   DONE;
9012 (define_insn "*anddi_1"
9013   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9014         (and:DI
9015          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9016          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9017    (clobber (reg:CC FLAGS_REG))]
9018   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9019   "@
9020    and{l}\t{%k2, %k0|%k0, %k2}
9021    and{q}\t{%2, %0|%0, %2}
9022    and{q}\t{%2, %0|%0, %2}
9023    #"
9024   [(set_attr "type" "alu,alu,alu,imovx")
9025    (set_attr "length_immediate" "*,*,*,0")
9026    (set (attr "prefix_rex")
9027      (if_then_else
9028        (and (eq_attr "type" "imovx")
9029             (and (match_test "INTVAL (operands[2]) == 0xff")
9030                  (match_operand 1 "ext_QIreg_operand")))
9031        (const_string "1")
9032        (const_string "*")))
9033    (set_attr "mode" "SI,DI,DI,SI")])
9035 (define_insn_and_split "*anddi_1_btr"
9036   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9037         (and:DI
9038          (match_operand:DI 1 "nonimmediate_operand" "%0")
9039          (match_operand:DI 2 "const_int_operand" "n")))
9040    (clobber (reg:CC FLAGS_REG))]
9041   "TARGET_64BIT && TARGET_USE_BT
9042    && ix86_binary_operator_ok (AND, DImode, operands)
9043    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
9044   "#"
9045   "&& reload_completed"
9046   [(parallel [(set (zero_extract:DI (match_dup 0)
9047                                     (const_int 1)
9048                                     (match_dup 3))
9049                    (const_int 0))
9050               (clobber (reg:CC FLAGS_REG))])]
9051   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
9052   [(set_attr "type" "alu1")
9053    (set_attr "prefix_0f" "1")
9054    (set_attr "znver1_decode" "double")
9055    (set_attr "mode" "DI")])
9057 ;; Turn *anddi_1 into *andsi_1_zext if possible.
9058 (define_split
9059   [(set (match_operand:DI 0 "register_operand")
9060         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
9061                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
9062    (clobber (reg:CC FLAGS_REG))]
9063   "TARGET_64BIT"
9064   [(parallel [(set (match_dup 0)
9065                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9066               (clobber (reg:CC FLAGS_REG))])]
9067   "operands[2] = gen_lowpart (SImode, operands[2]);")
9069 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9070 (define_insn "*andsi_1_zext"
9071   [(set (match_operand:DI 0 "register_operand" "=r")
9072         (zero_extend:DI
9073           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9074                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9075    (clobber (reg:CC FLAGS_REG))]
9076   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9077   "and{l}\t{%2, %k0|%k0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "SI")])
9081 (define_insn "*and<mode>_1"
9082   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
9083         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
9084                    (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
9085    (clobber (reg:CC FLAGS_REG))]
9086   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9087   "@
9088    and{<imodesuffix>}\t{%2, %0|%0, %2}
9089    and{<imodesuffix>}\t{%2, %0|%0, %2}
9090    #"
9091   [(set_attr "type" "alu,alu,imovx")
9092    (set_attr "length_immediate" "*,*,0")
9093    (set (attr "prefix_rex")
9094      (if_then_else
9095        (and (eq_attr "type" "imovx")
9096             (and (match_test "INTVAL (operands[2]) == 0xff")
9097                  (match_operand 1 "ext_QIreg_operand")))
9098        (const_string "1")
9099        (const_string "*")))
9100    (set_attr "mode" "<MODE>,<MODE>,SI")])
9102 (define_insn "*andqi_1"
9103   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9104         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9105                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9106    (clobber (reg:CC FLAGS_REG))]
9107   "ix86_binary_operator_ok (AND, QImode, operands)"
9108   "@
9109    and{b}\t{%2, %0|%0, %2}
9110    and{b}\t{%2, %0|%0, %2}
9111    and{l}\t{%k2, %k0|%k0, %k2}"
9112   [(set_attr "type" "alu")
9113    (set_attr "mode" "QI,QI,SI")
9114    ;; Potential partial reg stall on alternative 2.
9115    (set (attr "preferred_for_speed")
9116      (cond [(eq_attr "alternative" "2")
9117               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9118            (symbol_ref "true")))])
9120 (define_insn "*andqi_1_slp"
9121   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9122         (and:QI (match_dup 0)
9123                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9124    (clobber (reg:CC FLAGS_REG))]
9125   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9126    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9127   "and{b}\t{%1, %0|%0, %1}"
9128   [(set_attr "type" "alu1")
9129    (set_attr "mode" "QI")])
9131 (define_split
9132   [(set (match_operand:SWI248 0 "register_operand")
9133         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9134                     (match_operand:SWI248 2 "const_int_operand")))
9135    (clobber (reg:CC FLAGS_REG))]
9136   "reload_completed
9137    && (!REG_P (operands[1])
9138        || REGNO (operands[0]) != REGNO (operands[1]))"
9139   [(const_int 0)]
9141   HOST_WIDE_INT ival = INTVAL (operands[2]);
9142   machine_mode mode;
9143   rtx (*insn) (rtx, rtx);
9145   if (ival == (HOST_WIDE_INT) 0xffffffff)
9146     mode = SImode;
9147   else if (ival == 0xffff)
9148     mode = HImode;
9149   else
9150     {
9151       gcc_assert (ival == 0xff);
9152       mode = QImode;
9153     }
9155   if (<MODE>mode == DImode)
9156     insn = (mode == SImode)
9157            ? gen_zero_extendsidi2
9158            : (mode == HImode)
9159            ? gen_zero_extendhidi2
9160            : gen_zero_extendqidi2;
9161   else
9162     {
9163       if (<MODE>mode != SImode)
9164         /* Zero extend to SImode to avoid partial register stalls.  */
9165         operands[0] = gen_lowpart (SImode, operands[0]);
9167       insn = (mode == HImode)
9168              ? gen_zero_extendhisi2
9169              : gen_zero_extendqisi2;
9170     }
9171   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
9172   DONE;
9175 (define_split
9176   [(set (match_operand:SWI48 0 "register_operand")
9177         (and:SWI48 (match_dup 0)
9178                    (const_int -65536)))
9179    (clobber (reg:CC FLAGS_REG))]
9180   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9181     || optimize_function_for_size_p (cfun)"
9182   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9183   "operands[1] = gen_lowpart (HImode, operands[0]);")
9185 (define_split
9186   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9187         (and:SWI248 (match_dup 0)
9188                     (const_int -256)))
9189    (clobber (reg:CC FLAGS_REG))]
9190   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9191    && reload_completed"
9192   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9193   "operands[1] = gen_lowpart (QImode, operands[0]);")
9195 (define_split
9196   [(set (match_operand:SWI248 0 "QIreg_operand")
9197         (and:SWI248 (match_dup 0)
9198                     (const_int -65281)))
9199    (clobber (reg:CC FLAGS_REG))]
9200   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9201    && reload_completed"
9202   [(parallel
9203      [(set (zero_extract:SI (match_dup 0)
9204                             (const_int 8)
9205                             (const_int 8))
9206            (subreg:SI
9207              (xor:QI
9208                (subreg:QI
9209                  (zero_extract:SI (match_dup 0)
9210                                   (const_int 8)
9211                                   (const_int 8)) 0)
9212                (subreg:QI
9213                  (zero_extract:SI (match_dup 0)
9214                                   (const_int 8)
9215                                   (const_int 8)) 0)) 0))
9216       (clobber (reg:CC FLAGS_REG))])]
9217   "operands[0] = gen_lowpart (SImode, operands[0]);")
9219 (define_insn "*anddi_2"
9220   [(set (reg FLAGS_REG)
9221         (compare
9222          (and:DI
9223           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9224           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9225          (const_int 0)))
9226    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9227         (and:DI (match_dup 1) (match_dup 2)))]
9228   "TARGET_64BIT
9229    && ix86_match_ccmode
9230         (insn,
9231          /* If we are going to emit andl instead of andq, and the operands[2]
9232             constant might have the SImode sign bit set, make sure the sign
9233             flag isn't tested, because the instruction will set the sign flag
9234             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
9235             conservatively assume it might have bit 31 set.  */
9236          (satisfies_constraint_Z (operands[2])
9237           && (!CONST_INT_P (operands[2])
9238               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9239          ? CCZmode : CCNOmode)
9240    && ix86_binary_operator_ok (AND, DImode, operands)"
9241   "@
9242    and{l}\t{%k2, %k0|%k0, %k2}
9243    and{q}\t{%2, %0|%0, %2}
9244    and{q}\t{%2, %0|%0, %2}"
9245   [(set_attr "type" "alu")
9246    (set_attr "mode" "SI,DI,DI")])
9248 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9249 (define_insn "*andsi_2_zext"
9250   [(set (reg FLAGS_REG)
9251         (compare (and:SI
9252                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9253                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
9254                  (const_int 0)))
9255    (set (match_operand:DI 0 "register_operand" "=r")
9256         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9257   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9258    && ix86_binary_operator_ok (AND, SImode, operands)"
9259   "and{l}\t{%2, %k0|%k0, %2}"
9260   [(set_attr "type" "alu")
9261    (set_attr "mode" "SI")])
9263 (define_insn "*andqi_2_maybe_si"
9264   [(set (reg FLAGS_REG)
9265         (compare (and:QI
9266                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9267                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9268                  (const_int 0)))
9269    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9270         (and:QI (match_dup 1) (match_dup 2)))]
9271   "ix86_binary_operator_ok (AND, QImode, operands)
9272    && ix86_match_ccmode (insn,
9273                          CONST_INT_P (operands[2])
9274                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9276   if (which_alternative == 2)
9277     {
9278       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9279         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9280       return "and{l}\t{%2, %k0|%k0, %2}";
9281     }
9282   return "and{b}\t{%2, %0|%0, %2}";
9284   [(set_attr "type" "alu")
9285    (set_attr "mode" "QI,QI,SI")])
9287 (define_insn "*and<mode>_2"
9288   [(set (reg FLAGS_REG)
9289         (compare (and:SWI124
9290                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9291                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9292                  (const_int 0)))
9293    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9294         (and:SWI124 (match_dup 1) (match_dup 2)))]
9295   "ix86_match_ccmode (insn, CCNOmode)
9296    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9297   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9298   [(set_attr "type" "alu")
9299    (set_attr "mode" "<MODE>")])
9301 (define_insn "*andqi_2_slp"
9302   [(set (reg FLAGS_REG)
9303         (compare (and:QI
9304                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9305                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9306                  (const_int 0)))
9307    (set (strict_low_part (match_dup 0))
9308         (and:QI (match_dup 0) (match_dup 1)))]
9309   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9310    && ix86_match_ccmode (insn, CCNOmode)
9311    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9312   "and{b}\t{%1, %0|%0, %1}"
9313   [(set_attr "type" "alu1")
9314    (set_attr "mode" "QI")])
9316 (define_insn "andqi_ext_1"
9317   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9318                          (const_int 8)
9319                          (const_int 8))
9320         (subreg:SI
9321           (and:QI
9322             (subreg:QI
9323               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9324                                (const_int 8)
9325                                (const_int 8)) 0)
9326             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9327    (clobber (reg:CC FLAGS_REG))]
9328   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9329    rtx_equal_p (operands[0], operands[1])"
9330   "and{b}\t{%2, %h0|%h0, %2}"
9331   [(set_attr "isa" "*,nox64")
9332    (set_attr "type" "alu")
9333    (set_attr "mode" "QI")])
9335 ;; Generated by peephole translating test to and.  This shows up
9336 ;; often in fp comparisons.
9337 (define_insn "*andqi_ext_1_cc"
9338   [(set (reg FLAGS_REG)
9339         (compare
9340           (and:QI
9341             (subreg:QI
9342               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9343                                (const_int 8)
9344                                (const_int 8)) 0)
9345             (match_operand:QI 2 "general_operand" "QnBc,m"))
9346           (const_int 0)))
9347    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9348                          (const_int 8)
9349                          (const_int 8))
9350         (subreg:SI
9351           (and:QI
9352             (subreg:QI
9353               (zero_extract:SI (match_dup 1)
9354                                (const_int 8)
9355                                (const_int 8)) 0)
9356             (match_dup 2)) 0))]
9357   "ix86_match_ccmode (insn, CCNOmode)
9358    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9359    && rtx_equal_p (operands[0], operands[1])"
9360   "and{b}\t{%2, %h0|%h0, %2}"
9361   [(set_attr "isa" "*,nox64")
9362    (set_attr "type" "alu")
9363    (set_attr "mode" "QI")])
9365 (define_insn "*andqi_ext_2"
9366   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9367                          (const_int 8)
9368                          (const_int 8))
9369         (subreg:SI
9370           (and:QI
9371             (subreg:QI
9372               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9373                                (const_int 8)
9374                                (const_int 8)) 0)
9375             (subreg:QI
9376               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9377                                (const_int 8)
9378                                (const_int 8)) 0)) 0))
9379    (clobber (reg:CC FLAGS_REG))]
9380   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9381    rtx_equal_p (operands[0], operands[1])
9382    || rtx_equal_p (operands[0], operands[2])"
9383   "and{b}\t{%h2, %h0|%h0, %h2}"
9384   [(set_attr "type" "alu")
9385    (set_attr "mode" "QI")])
9387 ;; Convert wide AND instructions with immediate operand to shorter QImode
9388 ;; equivalents when possible.
9389 ;; Don't do the splitting with memory operands, since it introduces risk
9390 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9391 ;; for size, but that can (should?) be handled by generic code instead.
9392 (define_split
9393   [(set (match_operand:SWI248 0 "QIreg_operand")
9394         (and:SWI248 (match_operand:SWI248 1 "register_operand")
9395                     (match_operand:SWI248 2 "const_int_operand")))
9396    (clobber (reg:CC FLAGS_REG))]
9397    "reload_completed
9398     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9399     && !(~INTVAL (operands[2]) & ~(255 << 8))"
9400   [(parallel
9401      [(set (zero_extract:SI (match_dup 0)
9402                             (const_int 8)
9403                             (const_int 8))
9404            (subreg:SI
9405              (and:QI
9406                (subreg:QI
9407                  (zero_extract:SI (match_dup 1)
9408                                   (const_int 8)
9409                                   (const_int 8)) 0)
9410                (match_dup 2)) 0))
9411       (clobber (reg:CC FLAGS_REG))])]
9413   operands[0] = gen_lowpart (SImode, operands[0]);
9414   operands[1] = gen_lowpart (SImode, operands[1]);
9415   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9418 ;; Since AND can be encoded with sign extended immediate, this is only
9419 ;; profitable when 7th bit is not set.
9420 (define_split
9421   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9422         (and:SWI248 (match_operand:SWI248 1 "general_operand")
9423                     (match_operand:SWI248 2 "const_int_operand")))
9424    (clobber (reg:CC FLAGS_REG))]
9425    "reload_completed
9426     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9427     && !(~INTVAL (operands[2]) & ~255)
9428     && !(INTVAL (operands[2]) & 128)"
9429   [(parallel [(set (strict_low_part (match_dup 0))
9430                    (and:QI (match_dup 1)
9431                            (match_dup 2)))
9432               (clobber (reg:CC FLAGS_REG))])]
9434   operands[0] = gen_lowpart (QImode, operands[0]);
9435   operands[1] = gen_lowpart (QImode, operands[1]);
9436   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9439 (define_insn "*andndi3_doubleword"
9440   [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9441         (and:DI
9442           (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9443           (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9444    (clobber (reg:CC FLAGS_REG))]
9445   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9446   "#"
9447   [(set_attr "isa" "bmi,bmi,bmi,*")])
9449 (define_split
9450   [(set (match_operand:DI 0 "register_operand")
9451         (and:DI
9452           (not:DI (match_operand:DI 1 "register_operand"))
9453           (match_operand:DI 2 "nonimmediate_operand")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9456    && reload_completed"
9457   [(parallel [(set (match_dup 0)
9458                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9459               (clobber (reg:CC FLAGS_REG))])
9460    (parallel [(set (match_dup 3)
9461                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9462               (clobber (reg:CC FLAGS_REG))])]
9463   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9465 (define_split
9466   [(set (match_operand:DI 0 "register_operand")
9467         (and:DI
9468           (not:DI (match_dup 0))
9469           (match_operand:DI 1 "nonimmediate_operand")))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9472    && reload_completed"
9473   [(set (match_dup 0) (not:SI (match_dup 0)))
9474    (parallel [(set (match_dup 0)
9475                    (and:SI (match_dup 0) (match_dup 1)))
9476               (clobber (reg:CC FLAGS_REG))])
9477    (set (match_dup 2) (not:SI (match_dup 2)))
9478    (parallel [(set (match_dup 2)
9479                    (and:SI (match_dup 2) (match_dup 3)))
9480               (clobber (reg:CC FLAGS_REG))])]
9481   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9483 (define_insn "*andn<mode>_1"
9484   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9485         (and:SWI48
9486           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9487           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9488    (clobber (reg:CC FLAGS_REG))]
9489   "TARGET_BMI"
9490   "andn\t{%2, %1, %0|%0, %1, %2}"
9491   [(set_attr "type" "bitmanip")
9492    (set_attr "btver2_decode" "direct, double")
9493    (set_attr "mode" "<MODE>")])
9495 (define_insn "*andn<mode>_1"
9496   [(set (match_operand:SWI12 0 "register_operand" "=r")
9497         (and:SWI12
9498           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9499           (match_operand:SWI12 2 "register_operand" "r")))
9500    (clobber (reg:CC FLAGS_REG))]
9501   "TARGET_BMI"
9502   "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9503   [(set_attr "type" "bitmanip")
9504    (set_attr "btver2_decode" "direct")
9505    (set_attr "mode" "SI")])
9507 (define_insn "*andn_<mode>_ccno"
9508   [(set (reg FLAGS_REG)
9509         (compare
9510           (and:SWI48
9511             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9512             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9513           (const_int 0)))
9514    (clobber (match_scratch:SWI48 0 "=r,r"))]
9515   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9516   "andn\t{%2, %1, %0|%0, %1, %2}"
9517   [(set_attr "type" "bitmanip")
9518    (set_attr "btver2_decode" "direct, double")
9519    (set_attr "mode" "<MODE>")])
9521 ;; Logical inclusive and exclusive OR instructions
9523 ;; %%% This used to optimize known byte-wide and operations to memory.
9524 ;; If this is considered useful, it should be done with splitters.
9526 (define_expand "<code><mode>3"
9527   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9528         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9529                              (match_operand:SWIM1248x 2 "<general_operand>")))]
9530   ""
9531   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9533 (define_insn_and_split "*<code>di3_doubleword"
9534   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9535         (any_or:DI
9536          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9537          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9538    (clobber (reg:CC FLAGS_REG))]
9539   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9540    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9541   "#"
9542   "&& reload_completed"
9543   [(const_int 0)]
9545   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9546   if (operands[2] == constm1_rtx)
9547     {
9548       if (<CODE> == IOR)
9549         {
9550           operands[1] = constm1_rtx;
9551           ix86_expand_move (SImode, &operands[0]);
9552         }
9553       else
9554         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9555     }
9556   else if (operands[2] != const0_rtx)
9557     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9558   else if (operands[5] == const0_rtx)
9559     emit_note (NOTE_INSN_DELETED);
9560   if (operands[5] == constm1_rtx)
9561     {
9562       if (<CODE> == IOR)
9563         {
9564           operands[4] = constm1_rtx;
9565           ix86_expand_move (SImode, &operands[3]);
9566         }
9567       else
9568         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9569     }
9570   else if (operands[5] != const0_rtx)
9571     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9572   DONE;
9575 (define_insn "*<code><mode>_1"
9576   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9577         (any_or:SWI248
9578          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9579          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9580    (clobber (reg:CC FLAGS_REG))]
9581   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9582   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9583   [(set_attr "type" "alu")
9584    (set_attr "mode" "<MODE>")])
9586 (define_insn_and_split "*iordi_1_bts"
9587   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9588         (ior:DI
9589          (match_operand:DI 1 "nonimmediate_operand" "%0")
9590          (match_operand:DI 2 "const_int_operand" "n")))
9591    (clobber (reg:CC FLAGS_REG))]
9592   "TARGET_64BIT && TARGET_USE_BT
9593    && ix86_binary_operator_ok (IOR, DImode, operands)
9594    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9595   "#"
9596   "&& reload_completed"
9597   [(parallel [(set (zero_extract:DI (match_dup 0)
9598                                     (const_int 1)
9599                                     (match_dup 3))
9600                    (const_int 1))
9601               (clobber (reg:CC FLAGS_REG))])]
9602   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9603   [(set_attr "type" "alu1")
9604    (set_attr "prefix_0f" "1")
9605    (set_attr "znver1_decode" "double")
9606    (set_attr "mode" "DI")])
9608 (define_insn_and_split "*xordi_1_btc"
9609   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9610         (xor:DI
9611          (match_operand:DI 1 "nonimmediate_operand" "%0")
9612          (match_operand:DI 2 "const_int_operand" "n")))
9613    (clobber (reg:CC FLAGS_REG))]
9614   "TARGET_64BIT && TARGET_USE_BT
9615    && ix86_binary_operator_ok (XOR, DImode, operands)
9616    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9617   "#"
9618   "&& reload_completed"
9619   [(parallel [(set (zero_extract:DI (match_dup 0)
9620                                     (const_int 1)
9621                                     (match_dup 3))
9622                    (not:DI (zero_extract:DI (match_dup 0)
9623                                             (const_int 1)
9624                                             (match_dup 3))))
9625               (clobber (reg:CC FLAGS_REG))])]
9626   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9627   [(set_attr "type" "alu1")
9628    (set_attr "prefix_0f" "1")
9629    (set_attr "znver1_decode" "double")
9630    (set_attr "mode" "DI")])
9632 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9633 (define_insn "*<code>si_1_zext"
9634   [(set (match_operand:DI 0 "register_operand" "=r")
9635         (zero_extend:DI
9636          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9637                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9638    (clobber (reg:CC FLAGS_REG))]
9639   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9640   "<logic>{l}\t{%2, %k0|%k0, %2}"
9641   [(set_attr "type" "alu")
9642    (set_attr "mode" "SI")])
9644 (define_insn "*<code>si_1_zext_imm"
9645   [(set (match_operand:DI 0 "register_operand" "=r")
9646         (any_or:DI
9647          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9648          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9649    (clobber (reg:CC FLAGS_REG))]
9650   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9651   "<logic>{l}\t{%2, %k0|%k0, %2}"
9652   [(set_attr "type" "alu")
9653    (set_attr "mode" "SI")])
9655 (define_insn "*<code>qi_1"
9656   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9657         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9658                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9659    (clobber (reg:CC FLAGS_REG))]
9660   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9661   "@
9662    <logic>{b}\t{%2, %0|%0, %2}
9663    <logic>{b}\t{%2, %0|%0, %2}
9664    <logic>{l}\t{%k2, %k0|%k0, %k2}"
9665   [(set_attr "type" "alu")
9666    (set_attr "mode" "QI,QI,SI")
9667    ;; Potential partial reg stall on alternative 2.
9668    (set (attr "preferred_for_speed")
9669      (cond [(eq_attr "alternative" "2")
9670               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9671            (symbol_ref "true")))])
9673 (define_insn "*<code>qi_1_slp"
9674   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9675         (any_or:QI (match_dup 0)
9676                    (match_operand:QI 1 "general_operand" "qmn,qn")))
9677    (clobber (reg:CC FLAGS_REG))]
9678   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9679    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9680   "<logic>{b}\t{%1, %0|%0, %1}"
9681   [(set_attr "type" "alu1")
9682    (set_attr "mode" "QI")])
9684 (define_insn "*<code><mode>_2"
9685   [(set (reg FLAGS_REG)
9686         (compare (any_or:SWI
9687                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9688                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9689                  (const_int 0)))
9690    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9691         (any_or:SWI (match_dup 1) (match_dup 2)))]
9692   "ix86_match_ccmode (insn, CCNOmode)
9693    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9694   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9695   [(set_attr "type" "alu")
9696    (set_attr "mode" "<MODE>")])
9698 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9699 ;; ??? Special case for immediate operand is missing - it is tricky.
9700 (define_insn "*<code>si_2_zext"
9701   [(set (reg FLAGS_REG)
9702         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9703                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
9704                  (const_int 0)))
9705    (set (match_operand:DI 0 "register_operand" "=r")
9706         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9707   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9708    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9709   "<logic>{l}\t{%2, %k0|%k0, %2}"
9710   [(set_attr "type" "alu")
9711    (set_attr "mode" "SI")])
9713 (define_insn "*<code>si_2_zext_imm"
9714   [(set (reg FLAGS_REG)
9715         (compare (any_or:SI
9716                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9717                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9718                  (const_int 0)))
9719    (set (match_operand:DI 0 "register_operand" "=r")
9720         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9721   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9722    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9723   "<logic>{l}\t{%2, %k0|%k0, %2}"
9724   [(set_attr "type" "alu")
9725    (set_attr "mode" "SI")])
9727 (define_insn "*<code>qi_2_slp"
9728   [(set (reg FLAGS_REG)
9729         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9730                             (match_operand:QI 1 "general_operand" "qmn,qn"))
9731                  (const_int 0)))
9732    (set (strict_low_part (match_dup 0))
9733         (any_or:QI (match_dup 0) (match_dup 1)))]
9734   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9735    && ix86_match_ccmode (insn, CCNOmode)
9736    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9737   "<logic>{b}\t{%1, %0|%0, %1}"
9738   [(set_attr "type" "alu1")
9739    (set_attr "mode" "QI")])
9741 (define_insn "*<code><mode>_3"
9742   [(set (reg FLAGS_REG)
9743         (compare (any_or:SWI
9744                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
9745                   (match_operand:SWI 2 "<general_operand>" "<g>"))
9746                  (const_int 0)))
9747    (clobber (match_scratch:SWI 0 "=<r>"))]
9748   "ix86_match_ccmode (insn, CCNOmode)
9749    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9750   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9751   [(set_attr "type" "alu")
9752    (set_attr "mode" "<MODE>")])
9754 (define_insn "*<code>qi_ext_1"
9755   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9756                          (const_int 8)
9757                          (const_int 8))
9758         (subreg:SI
9759           (any_or:QI
9760             (subreg:QI
9761               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9762                                (const_int 8)
9763                                (const_int 8)) 0)
9764             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9765    (clobber (reg:CC FLAGS_REG))]
9766   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9767    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9768    && rtx_equal_p (operands[0], operands[1])"
9769   "<logic>{b}\t{%2, %h0|%h0, %2}"
9770   [(set_attr "isa" "*,nox64")
9771    (set_attr "type" "alu")
9772    (set_attr "mode" "QI")])
9774 (define_insn "*<code>qi_ext_2"
9775   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9776                          (const_int 8)
9777                          (const_int 8))
9778         (subreg:SI
9779           (any_or:QI
9780             (subreg:QI
9781               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9782                                (const_int 8)
9783                                (const_int 8)) 0)
9784             (subreg:QI
9785               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9786                                (const_int 8)
9787                                (const_int 8)) 0)) 0))
9788    (clobber (reg:CC FLAGS_REG))]
9789   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9790    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9791    && (rtx_equal_p (operands[0], operands[1])
9792        || rtx_equal_p (operands[0], operands[2]))"
9793   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9794   [(set_attr "type" "alu")
9795    (set_attr "mode" "QI")])
9797 ;; Convert wide OR instructions with immediate operand to shorter QImode
9798 ;; equivalents when possible.
9799 ;; Don't do the splitting with memory operands, since it introduces risk
9800 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9801 ;; for size, but that can (should?) be handled by generic code instead.
9802 (define_split
9803   [(set (match_operand:SWI248 0 "QIreg_operand")
9804         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9805                        (match_operand:SWI248 2 "const_int_operand")))
9806    (clobber (reg:CC FLAGS_REG))]
9807    "reload_completed
9808     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9809     && !(INTVAL (operands[2]) & ~(255 << 8))"
9810   [(parallel
9811      [(set (zero_extract:SI (match_dup 0)
9812                             (const_int 8)
9813                             (const_int 8))
9814            (subreg:SI
9815              (any_or:QI
9816                (subreg:QI
9817                  (zero_extract:SI (match_dup 1)
9818                                   (const_int 8)
9819                                   (const_int 8)) 0)
9820                (match_dup 2)) 0))
9821       (clobber (reg:CC FLAGS_REG))])]
9823   operands[0] = gen_lowpart (SImode, operands[0]);
9824   operands[1] = gen_lowpart (SImode, operands[1]);
9825   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9828 ;; Since OR can be encoded with sign extended immediate, this is only
9829 ;; profitable when 7th bit is set.
9830 (define_split
9831   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9832         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9833                        (match_operand:SWI248 2 "const_int_operand")))
9834    (clobber (reg:CC FLAGS_REG))]
9835    "reload_completed
9836     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9837     && !(INTVAL (operands[2]) & ~255)
9838     && (INTVAL (operands[2]) & 128)"
9839   [(parallel [(set (strict_low_part (match_dup 0))
9840                    (any_or:QI (match_dup 1)
9841                               (match_dup 2)))
9842               (clobber (reg:CC FLAGS_REG))])]
9844   operands[0] = gen_lowpart (QImode, operands[0]);
9845   operands[1] = gen_lowpart (QImode, operands[1]);
9846   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9849 (define_expand "xorqi_ext_1_cc"
9850   [(parallel [
9851      (set (reg:CCNO FLAGS_REG)
9852           (compare:CCNO
9853             (xor:QI
9854               (subreg:QI
9855                 (zero_extract:SI (match_operand 1 "ext_register_operand")
9856                                  (const_int 8)
9857                                  (const_int 8)) 0)
9858               (match_operand 2 "const_int_operand"))
9859             (const_int 0)))
9860      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9861                            (const_int 8)
9862                            (const_int 8))
9863           (subreg:SI
9864             (xor:QI
9865               (subreg:QI
9866                 (zero_extract:SI (match_dup 1)
9867                                  (const_int 8)
9868                                  (const_int 8)) 0)
9869             (match_dup 2)) 0))])])
9871 (define_insn "*xorqi_ext_1_cc"
9872   [(set (reg FLAGS_REG)
9873         (compare
9874           (xor:QI
9875             (subreg:QI
9876               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9877                                (const_int 8)
9878                                (const_int 8)) 0)
9879             (match_operand:QI 2 "general_operand" "QnBc,m"))
9880           (const_int 0)))
9881    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9882                          (const_int 8)
9883                          (const_int 8))
9884         (subreg:SI
9885           (xor:QI
9886             (subreg:QI
9887               (zero_extract:SI (match_dup 1)
9888                                (const_int 8)
9889                                (const_int 8)) 0)
9890           (match_dup 2)) 0))]
9891   "ix86_match_ccmode (insn, CCNOmode)
9892    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9893    && rtx_equal_p (operands[0], operands[1])"
9894   "xor{b}\t{%2, %h0|%h0, %2}"
9895   [(set_attr "isa" "*,nox64")
9896    (set_attr "type" "alu")
9897    (set_attr "mode" "QI")])
9899 ;; Negation instructions
9901 (define_expand "neg<mode>2"
9902   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9903         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9904   ""
9905   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9907 (define_insn_and_split "*neg<dwi>2_doubleword"
9908   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9909         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9910    (clobber (reg:CC FLAGS_REG))]
9911   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9912   "#"
9913   "reload_completed"
9914   [(parallel
9915     [(set (reg:CCZ FLAGS_REG)
9916           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9917      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9918    (parallel
9919     [(set (match_dup 2)
9920           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9921                                 (match_dup 3))
9922                      (const_int 0)))
9923      (clobber (reg:CC FLAGS_REG))])
9924    (parallel
9925     [(set (match_dup 2)
9926           (neg:DWIH (match_dup 2)))
9927      (clobber (reg:CC FLAGS_REG))])]
9928   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9930 (define_insn "*neg<mode>2_1"
9931   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9932         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9933    (clobber (reg:CC FLAGS_REG))]
9934   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9935   "neg{<imodesuffix>}\t%0"
9936   [(set_attr "type" "negnot")
9937    (set_attr "mode" "<MODE>")])
9939 ;; Combine is quite creative about this pattern.
9940 (define_insn "*negsi2_1_zext"
9941   [(set (match_operand:DI 0 "register_operand" "=r")
9942         (lshiftrt:DI
9943           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9944                              (const_int 32)))
9945         (const_int 32)))
9946    (clobber (reg:CC FLAGS_REG))]
9947   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9948   "neg{l}\t%k0"
9949   [(set_attr "type" "negnot")
9950    (set_attr "mode" "SI")])
9952 ;; The problem with neg is that it does not perform (compare x 0),
9953 ;; it really performs (compare 0 x), which leaves us with the zero
9954 ;; flag being the only useful item.
9956 (define_insn "*neg<mode>2_cmpz"
9957   [(set (reg:CCZ FLAGS_REG)
9958         (compare:CCZ
9959           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9960                    (const_int 0)))
9961    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9962         (neg:SWI (match_dup 1)))]
9963   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9964   "neg{<imodesuffix>}\t%0"
9965   [(set_attr "type" "negnot")
9966    (set_attr "mode" "<MODE>")])
9968 (define_insn "*negsi2_cmpz_zext"
9969   [(set (reg:CCZ FLAGS_REG)
9970         (compare:CCZ
9971           (lshiftrt:DI
9972             (neg:DI (ashift:DI
9973                       (match_operand:DI 1 "register_operand" "0")
9974                       (const_int 32)))
9975             (const_int 32))
9976           (const_int 0)))
9977    (set (match_operand:DI 0 "register_operand" "=r")
9978         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9979                                         (const_int 32)))
9980                      (const_int 32)))]
9981   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9982   "neg{l}\t%k0"
9983   [(set_attr "type" "negnot")
9984    (set_attr "mode" "SI")])
9986 ;; Negate with jump on overflow.
9987 (define_expand "negv<mode>3"
9988   [(parallel [(set (reg:CCO FLAGS_REG)
9989                    (ne:CCO (match_operand:SWI 1 "register_operand")
9990                            (match_dup 3)))
9991               (set (match_operand:SWI 0 "register_operand")
9992                    (neg:SWI (match_dup 1)))])
9993    (set (pc) (if_then_else
9994                (eq (reg:CCO FLAGS_REG) (const_int 0))
9995                (label_ref (match_operand 2))
9996                (pc)))]
9997   ""
9999   operands[3]
10000     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
10001                     <MODE>mode);
10004 (define_insn "*negv<mode>3"
10005   [(set (reg:CCO FLAGS_REG)
10006         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
10007                 (match_operand:SWI 2 "const_int_operand")))
10008    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10009         (neg:SWI (match_dup 1)))]
10010   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
10011    && mode_signbit_p (<MODE>mode, operands[2])"
10012   "neg{<imodesuffix>}\t%0"
10013   [(set_attr "type" "negnot")
10014    (set_attr "mode" "<MODE>")])
10016 ;; Changing of sign for FP values is doable using integer unit too.
10018 (define_expand "<code><mode>2"
10019   [(set (match_operand:X87MODEF 0 "register_operand")
10020         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
10021   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10022   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10024 (define_insn "*absneg<mode>2"
10025   [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
10026         (match_operator:MODEF 3 "absneg_operator"
10027           [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
10028    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
10029    (clobber (reg:CC FLAGS_REG))]
10030   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10031   "#"
10032   [(set (attr "enabled")
10033      (if_then_else
10034        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
10035        (if_then_else
10036          (eq_attr "alternative" "2")
10037          (symbol_ref "TARGET_MIX_SSE_I387")
10038          (symbol_ref "true"))
10039        (if_then_else
10040          (eq_attr "alternative" "2,3")
10041          (symbol_ref "true")
10042          (symbol_ref "false"))))])
10044 (define_insn "*absnegxf2_i387"
10045   [(set (match_operand:XF 0 "register_operand" "=f,!r")
10046         (match_operator:XF 3 "absneg_operator"
10047           [(match_operand:XF 1 "register_operand" "0,0")]))
10048    (use (match_operand 2))
10049    (clobber (reg:CC FLAGS_REG))]
10050   "TARGET_80387"
10051   "#")
10053 (define_expand "<code>tf2"
10054   [(set (match_operand:TF 0 "register_operand")
10055         (absneg:TF (match_operand:TF 1 "register_operand")))]
10056   "TARGET_SSE"
10057   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10059 (define_insn "*absnegtf2_sse"
10060   [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
10061         (match_operator:TF 3 "absneg_operator"
10062           [(match_operand:TF 1 "register_operand" "0,Yv")]))
10063    (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
10064    (clobber (reg:CC FLAGS_REG))]
10065   "TARGET_SSE"
10066   "#")
10068 ;; Splitters for fp abs and neg.
10070 (define_split
10071   [(set (match_operand 0 "fp_register_operand")
10072         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10073    (use (match_operand 2))
10074    (clobber (reg:CC FLAGS_REG))]
10075   "reload_completed"
10076   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10078 (define_split
10079   [(set (match_operand 0 "sse_reg_operand")
10080         (match_operator 3 "absneg_operator"
10081           [(match_operand 1 "register_operand")]))
10082    (use (match_operand 2 "nonimmediate_operand"))
10083    (clobber (reg:CC FLAGS_REG))]
10084   "reload_completed"
10085   [(set (match_dup 0) (match_dup 3))]
10087   machine_mode mode = GET_MODE (operands[0]);
10088   machine_mode vmode = GET_MODE (operands[2]);
10089   rtx tmp;
10091   operands[0] = lowpart_subreg (vmode, operands[0], mode);
10092   operands[1] = lowpart_subreg (vmode, operands[1], mode);
10093   if (operands_match_p (operands[0], operands[2]))
10094     std::swap (operands[1], operands[2]);
10095   if (GET_CODE (operands[3]) == ABS)
10096     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10097   else
10098     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10099   operands[3] = tmp;
10102 (define_split
10103   [(set (match_operand:SF 0 "general_reg_operand")
10104         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10105    (use (match_operand:V4SF 2))
10106    (clobber (reg:CC FLAGS_REG))]
10107   "reload_completed"
10108   [(parallel [(set (match_dup 0) (match_dup 1))
10109               (clobber (reg:CC FLAGS_REG))])]
10111   rtx tmp;
10112   operands[0] = gen_lowpart (SImode, operands[0]);
10113   if (GET_CODE (operands[1]) == ABS)
10114     {
10115       tmp = gen_int_mode (0x7fffffff, SImode);
10116       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10117     }
10118   else
10119     {
10120       tmp = gen_int_mode (0x80000000, SImode);
10121       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10122     }
10123   operands[1] = tmp;
10126 (define_split
10127   [(set (match_operand:DF 0 "general_reg_operand")
10128         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10129    (use (match_operand 2))
10130    (clobber (reg:CC FLAGS_REG))]
10131   "reload_completed"
10132   [(parallel [(set (match_dup 0) (match_dup 1))
10133               (clobber (reg:CC FLAGS_REG))])]
10135   rtx tmp;
10136   if (TARGET_64BIT)
10137     {
10138       tmp = gen_lowpart (DImode, operands[0]);
10139       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10140       operands[0] = tmp;
10142       if (GET_CODE (operands[1]) == ABS)
10143         tmp = const0_rtx;
10144       else
10145         tmp = gen_rtx_NOT (DImode, tmp);
10146     }
10147   else
10148     {
10149       operands[0] = gen_highpart (SImode, operands[0]);
10150       if (GET_CODE (operands[1]) == ABS)
10151         {
10152           tmp = gen_int_mode (0x7fffffff, SImode);
10153           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10154         }
10155       else
10156         {
10157           tmp = gen_int_mode (0x80000000, SImode);
10158           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10159         }
10160     }
10161   operands[1] = tmp;
10164 (define_split
10165   [(set (match_operand:XF 0 "general_reg_operand")
10166         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10167    (use (match_operand 2))
10168    (clobber (reg:CC FLAGS_REG))]
10169   "reload_completed"
10170   [(parallel [(set (match_dup 0) (match_dup 1))
10171               (clobber (reg:CC FLAGS_REG))])]
10173   rtx tmp;
10174   operands[0] = gen_rtx_REG (SImode,
10175                              REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
10176   if (GET_CODE (operands[1]) == ABS)
10177     {
10178       tmp = GEN_INT (0x7fff);
10179       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10180     }
10181   else
10182     {
10183       tmp = GEN_INT (0x8000);
10184       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10185     }
10186   operands[1] = tmp;
10189 ;; Conditionalize these after reload. If they match before reload, we
10190 ;; lose the clobber and ability to use integer instructions.
10192 (define_insn "*<code><mode>2_1"
10193   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10194         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10195   "TARGET_80387
10196    && (reload_completed
10197        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10198   "f<absneg_mnemonic>"
10199   [(set_attr "type" "fsgn")
10200    (set_attr "mode" "<MODE>")])
10202 (define_insn "*<code>extendsfdf2"
10203   [(set (match_operand:DF 0 "register_operand" "=f")
10204         (absneg:DF (float_extend:DF
10205                      (match_operand:SF 1 "register_operand" "0"))))]
10206   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10207   "f<absneg_mnemonic>"
10208   [(set_attr "type" "fsgn")
10209    (set_attr "mode" "DF")])
10211 (define_insn "*<code>extendsfxf2"
10212   [(set (match_operand:XF 0 "register_operand" "=f")
10213         (absneg:XF (float_extend:XF
10214                      (match_operand:SF 1 "register_operand" "0"))))]
10215   "TARGET_80387"
10216   "f<absneg_mnemonic>"
10217   [(set_attr "type" "fsgn")
10218    (set_attr "mode" "XF")])
10220 (define_insn "*<code>extenddfxf2"
10221   [(set (match_operand:XF 0 "register_operand" "=f")
10222         (absneg:XF (float_extend:XF
10223                      (match_operand:DF 1 "register_operand" "0"))))]
10224   "TARGET_80387"
10225   "f<absneg_mnemonic>"
10226   [(set_attr "type" "fsgn")
10227    (set_attr "mode" "XF")])
10229 ;; Copysign instructions
10231 (define_mode_iterator CSGNMODE [SF DF TF])
10232 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10234 (define_expand "copysign<mode>3"
10235   [(match_operand:CSGNMODE 0 "register_operand")
10236    (match_operand:CSGNMODE 1 "nonmemory_operand")
10237    (match_operand:CSGNMODE 2 "register_operand")]
10238   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10239    || (TARGET_SSE && (<MODE>mode == TFmode))"
10240   "ix86_expand_copysign (operands); DONE;")
10242 (define_insn_and_split "copysign<mode>3_const"
10243   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10244         (unspec:CSGNMODE
10245           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10246            (match_operand:CSGNMODE 2 "register_operand" "0")
10247            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10248           UNSPEC_COPYSIGN))]
10249   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10250    || (TARGET_SSE && (<MODE>mode == TFmode))"
10251   "#"
10252   "&& reload_completed"
10253   [(const_int 0)]
10254   "ix86_split_copysign_const (operands); DONE;")
10256 (define_insn "copysign<mode>3_var"
10257   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10258         (unspec:CSGNMODE
10259           [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10260            (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10261            (match_operand:<CSGNVMODE> 4
10262              "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10263            (match_operand:<CSGNVMODE> 5
10264              "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10265           UNSPEC_COPYSIGN))
10266    (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10267   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10268    || (TARGET_SSE && (<MODE>mode == TFmode))"
10269   "#")
10271 (define_split
10272   [(set (match_operand:CSGNMODE 0 "register_operand")
10273         (unspec:CSGNMODE
10274           [(match_operand:CSGNMODE 2 "register_operand")
10275            (match_operand:CSGNMODE 3 "register_operand")
10276            (match_operand:<CSGNVMODE> 4)
10277            (match_operand:<CSGNVMODE> 5)]
10278           UNSPEC_COPYSIGN))
10279    (clobber (match_scratch:<CSGNVMODE> 1))]
10280   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10281     || (TARGET_SSE && (<MODE>mode == TFmode)))
10282    && reload_completed"
10283   [(const_int 0)]
10284   "ix86_split_copysign_var (operands); DONE;")
10286 ;; One complement instructions
10288 (define_expand "one_cmpl<mode>2"
10289   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10290         (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10291   ""
10292   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10294 (define_insn_and_split "*one_cmpldi2_doubleword"
10295   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10296         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10297   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10298    && ix86_unary_operator_ok (NOT, DImode, operands)"
10299   "#"
10300   "&& reload_completed"
10301   [(set (match_dup 0)
10302         (not:SI (match_dup 1)))
10303    (set (match_dup 2)
10304         (not:SI (match_dup 3)))]
10305   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10307 (define_insn "*one_cmpl<mode>2_1"
10308   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10309         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10310   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10311   "not{<imodesuffix>}\t%0"
10312   [(set_attr "type" "negnot")
10313    (set_attr "mode" "<MODE>")])
10315 ;; ??? Currently never generated - xor is used instead.
10316 (define_insn "*one_cmplsi2_1_zext"
10317   [(set (match_operand:DI 0 "register_operand" "=r")
10318         (zero_extend:DI
10319           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10320   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10321   "not{l}\t%k0"
10322   [(set_attr "type" "negnot")
10323    (set_attr "mode" "SI")])
10325 (define_insn "*one_cmplqi2_1"
10326   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10327         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10328   "ix86_unary_operator_ok (NOT, QImode, operands)"
10329   "@
10330    not{b}\t%0
10331    not{l}\t%k0"
10332   [(set_attr "type" "negnot")
10333    (set_attr "mode" "QI,SI")
10334    ;; Potential partial reg stall on alternative 1.
10335    (set (attr "preferred_for_speed")
10336      (cond [(eq_attr "alternative" "1")
10337               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10338            (symbol_ref "true")))])
10340 (define_insn "*one_cmpl<mode>2_2"
10341   [(set (reg FLAGS_REG)
10342         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10343                  (const_int 0)))
10344    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10345         (not:SWI (match_dup 1)))]
10346   "ix86_match_ccmode (insn, CCNOmode)
10347    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10348   "#"
10349   [(set_attr "type" "alu1")
10350    (set_attr "mode" "<MODE>")])
10352 (define_split
10353   [(set (match_operand 0 "flags_reg_operand")
10354         (match_operator 2 "compare_operator"
10355           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10356            (const_int 0)]))
10357    (set (match_operand:SWI 1 "nonimmediate_operand")
10358         (not:SWI (match_dup 3)))]
10359   "ix86_match_ccmode (insn, CCNOmode)"
10360   [(parallel [(set (match_dup 0)
10361                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10362                                     (const_int 0)]))
10363               (set (match_dup 1)
10364                    (xor:SWI (match_dup 3) (const_int -1)))])])
10366 ;; ??? Currently never generated - xor is used instead.
10367 (define_insn "*one_cmplsi2_2_zext"
10368   [(set (reg FLAGS_REG)
10369         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10370                  (const_int 0)))
10371    (set (match_operand:DI 0 "register_operand" "=r")
10372         (zero_extend:DI (not:SI (match_dup 1))))]
10373   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10374    && ix86_unary_operator_ok (NOT, SImode, operands)"
10375   "#"
10376   [(set_attr "type" "alu1")
10377    (set_attr "mode" "SI")])
10379 (define_split
10380   [(set (match_operand 0 "flags_reg_operand")
10381         (match_operator 2 "compare_operator"
10382           [(not:SI (match_operand:SI 3 "register_operand"))
10383            (const_int 0)]))
10384    (set (match_operand:DI 1 "register_operand")
10385         (zero_extend:DI (not:SI (match_dup 3))))]
10386   "ix86_match_ccmode (insn, CCNOmode)"
10387   [(parallel [(set (match_dup 0)
10388                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10389                                     (const_int 0)]))
10390               (set (match_dup 1)
10391                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10393 ;; Shift instructions
10395 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10396 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10397 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10398 ;; from the assembler input.
10400 ;; This instruction shifts the target reg/mem as usual, but instead of
10401 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10402 ;; is a left shift double, bits are taken from the high order bits of
10403 ;; reg, else if the insn is a shift right double, bits are taken from the
10404 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10405 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10407 ;; Since sh[lr]d does not change the `reg' operand, that is done
10408 ;; separately, making all shifts emit pairs of shift double and normal
10409 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10410 ;; support a 63 bit shift, each shift where the count is in a reg expands
10411 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10413 ;; If the shift count is a constant, we need never emit more than one
10414 ;; shift pair, instead using moves and sign extension for counts greater
10415 ;; than 31.
10417 (define_expand "ashl<mode>3"
10418   [(set (match_operand:SDWIM 0 "<shift_operand>")
10419         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10420                       (match_operand:QI 2 "nonmemory_operand")))]
10421   ""
10422   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10424 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10425   [(set (match_operand:<DWI> 0 "register_operand")
10426         (ashift:<DWI>
10427           (match_operand:<DWI> 1 "register_operand")
10428           (subreg:QI
10429             (and:SI
10430               (match_operand:SI 2 "register_operand" "c")
10431               (match_operand:SI 3 "const_int_operand")) 0)))
10432    (clobber (reg:CC FLAGS_REG))]
10433   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10434    && can_create_pseudo_p ()"
10435   "#"
10436   "&& 1"
10437   [(parallel
10438      [(set (match_dup 6)
10439            (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10440                      (lshiftrt:DWIH (match_dup 5)
10441                        (minus:QI (match_dup 8) (match_dup 2)))))
10442       (clobber (reg:CC FLAGS_REG))])
10443    (parallel
10444      [(set (match_dup 4)
10445            (ashift:DWIH (match_dup 5) (match_dup 2)))
10446       (clobber (reg:CC FLAGS_REG))])]
10448   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10450   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10452   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10453       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10454     {
10455       rtx tem = gen_reg_rtx (SImode);
10456       emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10457       operands[2] = tem;
10458     }
10460   operands[2] = gen_lowpart (QImode, operands[2]);
10462   if (!rtx_equal_p (operands[6], operands[7]))
10463     emit_move_insn (operands[6], operands[7]);
10466 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10467   [(set (match_operand:<DWI> 0 "register_operand")
10468         (ashift:<DWI>
10469           (match_operand:<DWI> 1 "register_operand")
10470           (and:QI
10471             (match_operand:QI 2 "register_operand" "c")
10472             (match_operand:QI 3 "const_int_operand"))))
10473    (clobber (reg:CC FLAGS_REG))]
10474   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10475    && can_create_pseudo_p ()"
10476   "#"
10477   "&& 1"
10478   [(parallel
10479      [(set (match_dup 6)
10480            (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10481                      (lshiftrt:DWIH (match_dup 5)
10482                        (minus:QI (match_dup 8) (match_dup 2)))))
10483       (clobber (reg:CC FLAGS_REG))])
10484    (parallel
10485      [(set (match_dup 4)
10486            (ashift:DWIH (match_dup 5) (match_dup 2)))
10487       (clobber (reg:CC FLAGS_REG))])]
10489   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10491   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10493   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10494       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10495     {
10496       rtx tem = gen_reg_rtx (QImode);
10497       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10498       operands[2] = tem;
10499     }
10501   if (!rtx_equal_p (operands[6], operands[7]))
10502     emit_move_insn (operands[6], operands[7]);
10505 (define_insn "*ashl<mode>3_doubleword"
10506   [(set (match_operand:DWI 0 "register_operand" "=&r")
10507         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10508                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10509    (clobber (reg:CC FLAGS_REG))]
10510   ""
10511   "#"
10512   [(set_attr "type" "multi")])
10514 (define_split
10515   [(set (match_operand:DWI 0 "register_operand")
10516         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10517                     (match_operand:QI 2 "nonmemory_operand")))
10518    (clobber (reg:CC FLAGS_REG))]
10519   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10520   [(const_int 0)]
10521   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10523 ;; By default we don't ask for a scratch register, because when DWImode
10524 ;; values are manipulated, registers are already at a premium.  But if
10525 ;; we have one handy, we won't turn it away.
10527 (define_peephole2
10528   [(match_scratch:DWIH 3 "r")
10529    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10530                    (ashift:<DWI>
10531                      (match_operand:<DWI> 1 "nonmemory_operand")
10532                      (match_operand:QI 2 "nonmemory_operand")))
10533               (clobber (reg:CC FLAGS_REG))])
10534    (match_dup 3)]
10535   "TARGET_CMOVE"
10536   [(const_int 0)]
10537   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10539 (define_insn "x86_64_shld"
10540   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10541         (ior:DI (ashift:DI (match_dup 0)
10542                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10543                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10544                   (minus:QI (const_int 64) (match_dup 2)))))
10545    (clobber (reg:CC FLAGS_REG))]
10546   "TARGET_64BIT"
10547   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10548   [(set_attr "type" "ishift")
10549    (set_attr "prefix_0f" "1")
10550    (set_attr "mode" "DI")
10551    (set_attr "athlon_decode" "vector")
10552    (set_attr "amdfam10_decode" "vector")
10553    (set_attr "bdver1_decode" "vector")])
10555 (define_insn "x86_shld"
10556   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10557         (ior:SI (ashift:SI (match_dup 0)
10558                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10559                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10560                   (minus:QI (const_int 32) (match_dup 2)))))
10561    (clobber (reg:CC FLAGS_REG))]
10562   ""
10563   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10564   [(set_attr "type" "ishift")
10565    (set_attr "prefix_0f" "1")
10566    (set_attr "mode" "SI")
10567    (set_attr "pent_pair" "np")
10568    (set_attr "athlon_decode" "vector")
10569    (set_attr "amdfam10_decode" "vector")
10570    (set_attr "bdver1_decode" "vector")])
10572 (define_expand "x86_shift<mode>_adj_1"
10573   [(set (reg:CCZ FLAGS_REG)
10574         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10575                              (match_dup 4))
10576                      (const_int 0)))
10577    (set (match_operand:SWI48 0 "register_operand")
10578         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10579                             (match_operand:SWI48 1 "register_operand")
10580                             (match_dup 0)))
10581    (set (match_dup 1)
10582         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10583                             (match_operand:SWI48 3 "register_operand")
10584                             (match_dup 1)))]
10585   "TARGET_CMOVE"
10586   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10588 (define_expand "x86_shift<mode>_adj_2"
10589   [(use (match_operand:SWI48 0 "register_operand"))
10590    (use (match_operand:SWI48 1 "register_operand"))
10591    (use (match_operand:QI 2 "register_operand"))]
10592   ""
10594   rtx_code_label *label = gen_label_rtx ();
10595   rtx tmp;
10597   emit_insn (gen_testqi_ccz_1 (operands[2],
10598                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10600   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10601   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10602   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10603                               gen_rtx_LABEL_REF (VOIDmode, label),
10604                               pc_rtx);
10605   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10606   JUMP_LABEL (tmp) = label;
10608   emit_move_insn (operands[0], operands[1]);
10609   ix86_expand_clear (operands[1]);
10611   emit_label (label);
10612   LABEL_NUSES (label) = 1;
10614   DONE;
10617 ;; Avoid useless masking of count operand.
10618 (define_insn_and_split "*ashl<mode>3_mask"
10619   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10620         (ashift:SWI48
10621           (match_operand:SWI48 1 "nonimmediate_operand")
10622           (subreg:QI
10623             (and:SI
10624               (match_operand:SI 2 "register_operand" "c,r")
10625               (match_operand:SI 3 "const_int_operand")) 0)))
10626    (clobber (reg:CC FLAGS_REG))]
10627   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10628    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10629       == GET_MODE_BITSIZE (<MODE>mode)-1
10630    && can_create_pseudo_p ()"
10631   "#"
10632   "&& 1"
10633   [(parallel
10634      [(set (match_dup 0)
10635            (ashift:SWI48 (match_dup 1)
10636                          (match_dup 2)))
10637       (clobber (reg:CC FLAGS_REG))])]
10638   "operands[2] = gen_lowpart (QImode, operands[2]);"
10639   [(set_attr "isa" "*,bmi2")])
10641 (define_insn_and_split "*ashl<mode>3_mask_1"
10642   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10643         (ashift:SWI48
10644           (match_operand:SWI48 1 "nonimmediate_operand")
10645           (and:QI
10646             (match_operand:QI 2 "register_operand" "c,r")
10647             (match_operand:QI 3 "const_int_operand"))))
10648    (clobber (reg:CC FLAGS_REG))]
10649   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10650    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10651       == GET_MODE_BITSIZE (<MODE>mode)-1
10652    && can_create_pseudo_p ()"
10653   "#"
10654   "&& 1"
10655   [(parallel
10656      [(set (match_dup 0)
10657            (ashift:SWI48 (match_dup 1)
10658                          (match_dup 2)))
10659       (clobber (reg:CC FLAGS_REG))])]
10660   ""
10661   [(set_attr "isa" "*,bmi2")])
10663 (define_insn "*bmi2_ashl<mode>3_1"
10664   [(set (match_operand:SWI48 0 "register_operand" "=r")
10665         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10666                       (match_operand:SWI48 2 "register_operand" "r")))]
10667   "TARGET_BMI2"
10668   "shlx\t{%2, %1, %0|%0, %1, %2}"
10669   [(set_attr "type" "ishiftx")
10670    (set_attr "mode" "<MODE>")])
10672 (define_insn "*ashl<mode>3_1"
10673   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10674         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10675                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10676    (clobber (reg:CC FLAGS_REG))]
10677   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10679   switch (get_attr_type (insn))
10680     {
10681     case TYPE_LEA:
10682     case TYPE_ISHIFTX:
10683       return "#";
10685     case TYPE_ALU:
10686       gcc_assert (operands[2] == const1_rtx);
10687       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10688       return "add{<imodesuffix>}\t%0, %0";
10690     default:
10691       if (operands[2] == const1_rtx
10692           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10693         return "sal{<imodesuffix>}\t%0";
10694       else
10695         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10696     }
10698   [(set_attr "isa" "*,*,bmi2")
10699    (set (attr "type")
10700      (cond [(eq_attr "alternative" "1")
10701               (const_string "lea")
10702             (eq_attr "alternative" "2")
10703               (const_string "ishiftx")
10704             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10705                       (match_operand 0 "register_operand"))
10706                  (match_operand 2 "const1_operand"))
10707               (const_string "alu")
10708            ]
10709            (const_string "ishift")))
10710    (set (attr "length_immediate")
10711      (if_then_else
10712        (ior (eq_attr "type" "alu")
10713             (and (eq_attr "type" "ishift")
10714                  (and (match_operand 2 "const1_operand")
10715                       (ior (match_test "TARGET_SHIFT1")
10716                            (match_test "optimize_function_for_size_p (cfun)")))))
10717        (const_string "0")
10718        (const_string "*")))
10719    (set_attr "mode" "<MODE>")])
10721 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10722 (define_split
10723   [(set (match_operand:SWI48 0 "register_operand")
10724         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10725                       (match_operand:QI 2 "register_operand")))
10726    (clobber (reg:CC FLAGS_REG))]
10727   "TARGET_BMI2 && reload_completed"
10728   [(set (match_dup 0)
10729         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10730   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10732 (define_insn "*bmi2_ashlsi3_1_zext"
10733   [(set (match_operand:DI 0 "register_operand" "=r")
10734         (zero_extend:DI
10735           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10736                      (match_operand:SI 2 "register_operand" "r"))))]
10737   "TARGET_64BIT && TARGET_BMI2"
10738   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10739   [(set_attr "type" "ishiftx")
10740    (set_attr "mode" "SI")])
10742 (define_insn "*ashlsi3_1_zext"
10743   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10744         (zero_extend:DI
10745           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10746                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10747    (clobber (reg:CC FLAGS_REG))]
10748   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10750   switch (get_attr_type (insn))
10751     {
10752     case TYPE_LEA:
10753     case TYPE_ISHIFTX:
10754       return "#";
10756     case TYPE_ALU:
10757       gcc_assert (operands[2] == const1_rtx);
10758       return "add{l}\t%k0, %k0";
10760     default:
10761       if (operands[2] == const1_rtx
10762           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10763         return "sal{l}\t%k0";
10764       else
10765         return "sal{l}\t{%2, %k0|%k0, %2}";
10766     }
10768   [(set_attr "isa" "*,*,bmi2")
10769    (set (attr "type")
10770      (cond [(eq_attr "alternative" "1")
10771               (const_string "lea")
10772             (eq_attr "alternative" "2")
10773               (const_string "ishiftx")
10774             (and (match_test "TARGET_DOUBLE_WITH_ADD")
10775                  (match_operand 2 "const1_operand"))
10776               (const_string "alu")
10777            ]
10778            (const_string "ishift")))
10779    (set (attr "length_immediate")
10780      (if_then_else
10781        (ior (eq_attr "type" "alu")
10782             (and (eq_attr "type" "ishift")
10783                  (and (match_operand 2 "const1_operand")
10784                       (ior (match_test "TARGET_SHIFT1")
10785                            (match_test "optimize_function_for_size_p (cfun)")))))
10786        (const_string "0")
10787        (const_string "*")))
10788    (set_attr "mode" "SI")])
10790 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10791 (define_split
10792   [(set (match_operand:DI 0 "register_operand")
10793         (zero_extend:DI
10794           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10795                      (match_operand:QI 2 "register_operand"))))
10796    (clobber (reg:CC FLAGS_REG))]
10797   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10798   [(set (match_dup 0)
10799         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10800   "operands[2] = gen_lowpart (SImode, operands[2]);")
10802 (define_insn "*ashlhi3_1"
10803   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10804         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10805                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10806    (clobber (reg:CC FLAGS_REG))]
10807   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10809   switch (get_attr_type (insn))
10810     {
10811     case TYPE_LEA:
10812       return "#";
10814     case TYPE_ALU:
10815       gcc_assert (operands[2] == const1_rtx);
10816       return "add{w}\t%0, %0";
10818     default:
10819       if (operands[2] == const1_rtx
10820           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10821         return "sal{w}\t%0";
10822       else
10823         return "sal{w}\t{%2, %0|%0, %2}";
10824     }
10826   [(set (attr "type")
10827      (cond [(eq_attr "alternative" "1")
10828               (const_string "lea")
10829             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10830                       (match_operand 0 "register_operand"))
10831                  (match_operand 2 "const1_operand"))
10832               (const_string "alu")
10833            ]
10834            (const_string "ishift")))
10835    (set (attr "length_immediate")
10836      (if_then_else
10837        (ior (eq_attr "type" "alu")
10838             (and (eq_attr "type" "ishift")
10839                  (and (match_operand 2 "const1_operand")
10840                       (ior (match_test "TARGET_SHIFT1")
10841                            (match_test "optimize_function_for_size_p (cfun)")))))
10842        (const_string "0")
10843        (const_string "*")))
10844    (set_attr "mode" "HI,SI")])
10846 (define_insn "*ashlqi3_1"
10847   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10848         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10849                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10850    (clobber (reg:CC FLAGS_REG))]
10851   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10853   switch (get_attr_type (insn))
10854     {
10855     case TYPE_LEA:
10856       return "#";
10858     case TYPE_ALU:
10859       gcc_assert (operands[2] == const1_rtx);
10860       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10861         return "add{l}\t%k0, %k0";
10862       else
10863         return "add{b}\t%0, %0";
10865     default:
10866       if (operands[2] == const1_rtx
10867           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10868         {
10869           if (get_attr_mode (insn) == MODE_SI)
10870             return "sal{l}\t%k0";
10871           else
10872             return "sal{b}\t%0";
10873         }
10874       else
10875         {
10876           if (get_attr_mode (insn) == MODE_SI)
10877             return "sal{l}\t{%2, %k0|%k0, %2}";
10878           else
10879             return "sal{b}\t{%2, %0|%0, %2}";
10880         }
10881     }
10883   [(set (attr "type")
10884      (cond [(eq_attr "alternative" "2")
10885               (const_string "lea")
10886             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10887                       (match_operand 0 "register_operand"))
10888                  (match_operand 2 "const1_operand"))
10889               (const_string "alu")
10890            ]
10891            (const_string "ishift")))
10892    (set (attr "length_immediate")
10893      (if_then_else
10894        (ior (eq_attr "type" "alu")
10895             (and (eq_attr "type" "ishift")
10896                  (and (match_operand 2 "const1_operand")
10897                       (ior (match_test "TARGET_SHIFT1")
10898                            (match_test "optimize_function_for_size_p (cfun)")))))
10899        (const_string "0")
10900        (const_string "*")))
10901    (set_attr "mode" "QI,SI,SI")
10902    ;; Potential partial reg stall on alternative 1.
10903    (set (attr "preferred_for_speed")
10904      (cond [(eq_attr "alternative" "1")
10905               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10906            (symbol_ref "true")))])
10908 (define_insn "*ashlqi3_1_slp"
10909   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10910         (ashift:QI (match_dup 0)
10911                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10912    (clobber (reg:CC FLAGS_REG))]
10913   "(optimize_function_for_size_p (cfun)
10914     || !TARGET_PARTIAL_FLAG_REG_STALL
10915     || (operands[1] == const1_rtx
10916         && (TARGET_SHIFT1
10917             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10919   switch (get_attr_type (insn))
10920     {
10921     case TYPE_ALU1:
10922       gcc_assert (operands[1] == const1_rtx);
10923       return "add{b}\t%0, %0";
10925     default:
10926       if (operands[1] == const1_rtx
10927           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10928         return "sal{b}\t%0";
10929       else
10930         return "sal{b}\t{%1, %0|%0, %1}";
10931     }
10933   [(set (attr "type")
10934      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10935                       (match_operand 0 "register_operand"))
10936                  (match_operand 1 "const1_operand"))
10937               (const_string "alu1")
10938            ]
10939            (const_string "ishift1")))
10940    (set (attr "length_immediate")
10941      (if_then_else
10942        (ior (eq_attr "type" "alu1")
10943             (and (eq_attr "type" "ishift1")
10944                  (and (match_operand 1 "const1_operand")
10945                       (ior (match_test "TARGET_SHIFT1")
10946                            (match_test "optimize_function_for_size_p (cfun)")))))
10947        (const_string "0")
10948        (const_string "*")))
10949    (set_attr "mode" "QI")])
10951 ;; Convert ashift to the lea pattern to avoid flags dependency.
10952 (define_split
10953   [(set (match_operand:SWI 0 "register_operand")
10954         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10955                     (match_operand 2 "const_0_to_3_operand")))
10956    (clobber (reg:CC FLAGS_REG))]
10957   "reload_completed
10958    && REGNO (operands[0]) != REGNO (operands[1])"
10959   [(set (match_dup 0)
10960         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10962   if (<MODE>mode != <LEAMODE>mode)
10963     {
10964       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10965       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10966     }
10967   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10970 ;; Convert ashift to the lea pattern to avoid flags dependency.
10971 (define_split
10972   [(set (match_operand:DI 0 "register_operand")
10973         (zero_extend:DI
10974           (ashift:SI (match_operand:SI 1 "index_register_operand")
10975                      (match_operand 2 "const_0_to_3_operand"))))
10976    (clobber (reg:CC FLAGS_REG))]
10977   "TARGET_64BIT && reload_completed
10978    && REGNO (operands[0]) != REGNO (operands[1])"
10979   [(set (match_dup 0)
10980         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10982   operands[1] = gen_lowpart (SImode, operands[1]);
10983   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10986 ;; This pattern can't accept a variable shift count, since shifts by
10987 ;; zero don't affect the flags.  We assume that shifts by constant
10988 ;; zero are optimized away.
10989 (define_insn "*ashl<mode>3_cmp"
10990   [(set (reg FLAGS_REG)
10991         (compare
10992           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10993                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10994           (const_int 0)))
10995    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10996         (ashift:SWI (match_dup 1) (match_dup 2)))]
10997   "(optimize_function_for_size_p (cfun)
10998     || !TARGET_PARTIAL_FLAG_REG_STALL
10999     || (operands[2] == const1_rtx
11000         && (TARGET_SHIFT1
11001             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11002    && ix86_match_ccmode (insn, CCGOCmode)
11003    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
11005   switch (get_attr_type (insn))
11006     {
11007     case TYPE_ALU:
11008       gcc_assert (operands[2] == const1_rtx);
11009       return "add{<imodesuffix>}\t%0, %0";
11011     default:
11012       if (operands[2] == const1_rtx
11013           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11014         return "sal{<imodesuffix>}\t%0";
11015       else
11016         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11017     }
11019   [(set (attr "type")
11020      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11021                       (match_operand 0 "register_operand"))
11022                  (match_operand 2 "const1_operand"))
11023               (const_string "alu")
11024            ]
11025            (const_string "ishift")))
11026    (set (attr "length_immediate")
11027      (if_then_else
11028        (ior (eq_attr "type" "alu")
11029             (and (eq_attr "type" "ishift")
11030                  (and (match_operand 2 "const1_operand")
11031                       (ior (match_test "TARGET_SHIFT1")
11032                            (match_test "optimize_function_for_size_p (cfun)")))))
11033        (const_string "0")
11034        (const_string "*")))
11035    (set_attr "mode" "<MODE>")])
11037 (define_insn "*ashlsi3_cmp_zext"
11038   [(set (reg FLAGS_REG)
11039         (compare
11040           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11041                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11042           (const_int 0)))
11043    (set (match_operand:DI 0 "register_operand" "=r")
11044         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11045   "TARGET_64BIT
11046    && (optimize_function_for_size_p (cfun)
11047        || !TARGET_PARTIAL_FLAG_REG_STALL
11048        || (operands[2] == const1_rtx
11049            && (TARGET_SHIFT1
11050                || TARGET_DOUBLE_WITH_ADD)))
11051    && ix86_match_ccmode (insn, CCGOCmode)
11052    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11054   switch (get_attr_type (insn))
11055     {
11056     case TYPE_ALU:
11057       gcc_assert (operands[2] == const1_rtx);
11058       return "add{l}\t%k0, %k0";
11060     default:
11061       if (operands[2] == const1_rtx
11062           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11063         return "sal{l}\t%k0";
11064       else
11065         return "sal{l}\t{%2, %k0|%k0, %2}";
11066     }
11068   [(set (attr "type")
11069      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11070                  (match_operand 2 "const1_operand"))
11071               (const_string "alu")
11072            ]
11073            (const_string "ishift")))
11074    (set (attr "length_immediate")
11075      (if_then_else
11076        (ior (eq_attr "type" "alu")
11077             (and (eq_attr "type" "ishift")
11078                  (and (match_operand 2 "const1_operand")
11079                       (ior (match_test "TARGET_SHIFT1")
11080                            (match_test "optimize_function_for_size_p (cfun)")))))
11081        (const_string "0")
11082        (const_string "*")))
11083    (set_attr "mode" "SI")])
11085 (define_insn "*ashl<mode>3_cconly"
11086   [(set (reg FLAGS_REG)
11087         (compare
11088           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11089                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11090           (const_int 0)))
11091    (clobber (match_scratch:SWI 0 "=<r>"))]
11092   "(optimize_function_for_size_p (cfun)
11093     || !TARGET_PARTIAL_FLAG_REG_STALL
11094     || (operands[2] == const1_rtx
11095         && (TARGET_SHIFT1
11096             || TARGET_DOUBLE_WITH_ADD)))
11097    && ix86_match_ccmode (insn, CCGOCmode)"
11099   switch (get_attr_type (insn))
11100     {
11101     case TYPE_ALU:
11102       gcc_assert (operands[2] == const1_rtx);
11103       return "add{<imodesuffix>}\t%0, %0";
11105     default:
11106       if (operands[2] == const1_rtx
11107           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11108         return "sal{<imodesuffix>}\t%0";
11109       else
11110         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11111     }
11113   [(set (attr "type")
11114      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11115                       (match_operand 0 "register_operand"))
11116                  (match_operand 2 "const1_operand"))
11117               (const_string "alu")
11118            ]
11119            (const_string "ishift")))
11120    (set (attr "length_immediate")
11121      (if_then_else
11122        (ior (eq_attr "type" "alu")
11123             (and (eq_attr "type" "ishift")
11124                  (and (match_operand 2 "const1_operand")
11125                       (ior (match_test "TARGET_SHIFT1")
11126                            (match_test "optimize_function_for_size_p (cfun)")))))
11127        (const_string "0")
11128        (const_string "*")))
11129    (set_attr "mode" "<MODE>")])
11131 ;; See comment above `ashl<mode>3' about how this works.
11133 (define_expand "<shift_insn><mode>3"
11134   [(set (match_operand:SDWIM 0 "<shift_operand>")
11135         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11136                            (match_operand:QI 2 "nonmemory_operand")))]
11137   ""
11138   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11140 ;; Avoid useless masking of count operand.
11141 (define_insn_and_split "*<shift_insn><mode>3_mask"
11142   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11143         (any_shiftrt:SWI48
11144           (match_operand:SWI48 1 "nonimmediate_operand")
11145           (subreg:QI
11146             (and:SI
11147               (match_operand:SI 2 "register_operand" "c,r")
11148               (match_operand:SI 3 "const_int_operand")) 0)))
11149    (clobber (reg:CC FLAGS_REG))]
11150   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11151    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11152       == GET_MODE_BITSIZE (<MODE>mode)-1
11153    && can_create_pseudo_p ()"
11154   "#"
11155   "&& 1"
11156   [(parallel
11157      [(set (match_dup 0)
11158            (any_shiftrt:SWI48 (match_dup 1)
11159                               (match_dup 2)))
11160       (clobber (reg:CC FLAGS_REG))])]
11161   "operands[2] = gen_lowpart (QImode, operands[2]);"
11162   [(set_attr "isa" "*,bmi2")])
11164 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
11165   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11166         (any_shiftrt:SWI48
11167           (match_operand:SWI48 1 "nonimmediate_operand")
11168           (and:QI
11169             (match_operand:QI 2 "register_operand" "c,r")
11170             (match_operand:QI 3 "const_int_operand"))))
11171    (clobber (reg:CC FLAGS_REG))]
11172   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11173    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11174       == GET_MODE_BITSIZE (<MODE>mode)-1
11175    && can_create_pseudo_p ()"
11176   "#"
11177   "&& 1"
11178   [(parallel
11179      [(set (match_dup 0)
11180            (any_shiftrt:SWI48 (match_dup 1)
11181                               (match_dup 2)))
11182       (clobber (reg:CC FLAGS_REG))])]
11183   ""
11184   [(set_attr "isa" "*,bmi2")])
11186 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
11187   [(set (match_operand:<DWI> 0 "register_operand")
11188         (any_shiftrt:<DWI>
11189           (match_operand:<DWI> 1 "register_operand")
11190           (subreg:QI
11191             (and:SI
11192               (match_operand:SI 2 "register_operand" "c")
11193               (match_operand:SI 3 "const_int_operand")) 0)))
11194    (clobber (reg:CC FLAGS_REG))]
11195   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11196    && can_create_pseudo_p ()"
11197   "#"
11198   "&& 1"
11199   [(parallel
11200      [(set (match_dup 4)
11201            (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11202                      (ashift:DWIH (match_dup 7)
11203                        (minus:QI (match_dup 8) (match_dup 2)))))
11204       (clobber (reg:CC FLAGS_REG))])
11205    (parallel
11206      [(set (match_dup 6)
11207            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11208       (clobber (reg:CC FLAGS_REG))])]
11210   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11212   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11214   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11215       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11216     {
11217       rtx tem = gen_reg_rtx (SImode);
11218       emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11219       operands[2] = tem;
11220     }
11222   operands[2] = gen_lowpart (QImode, operands[2]);
11224   if (!rtx_equal_p (operands[4], operands[5]))
11225     emit_move_insn (operands[4], operands[5]);
11228 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
11229   [(set (match_operand:<DWI> 0 "register_operand")
11230         (any_shiftrt:<DWI>
11231           (match_operand:<DWI> 1 "register_operand")
11232           (and:QI
11233             (match_operand:QI 2 "register_operand" "c")
11234             (match_operand:QI 3 "const_int_operand"))))
11235    (clobber (reg:CC FLAGS_REG))]
11236   "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11237    && can_create_pseudo_p ()"
11238   "#"
11239   "&& 1"
11240   [(parallel
11241      [(set (match_dup 4)
11242            (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11243                      (ashift:DWIH (match_dup 7)
11244                        (minus:QI (match_dup 8) (match_dup 2)))))
11245       (clobber (reg:CC FLAGS_REG))])
11246    (parallel
11247      [(set (match_dup 6)
11248            (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11249       (clobber (reg:CC FLAGS_REG))])]
11251   split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11253   operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11255   if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11256       != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11257     {
11258       rtx tem = gen_reg_rtx (QImode);
11259       emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11260       operands[2] = tem;
11261     }
11263   if (!rtx_equal_p (operands[4], operands[5]))
11264     emit_move_insn (operands[4], operands[5]);
11267 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
11268   [(set (match_operand:DWI 0 "register_operand" "=&r")
11269         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11270                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11271    (clobber (reg:CC FLAGS_REG))]
11272   ""
11273   "#"
11274   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
11275   [(const_int 0)]
11276   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11277   [(set_attr "type" "multi")])
11279 ;; By default we don't ask for a scratch register, because when DWImode
11280 ;; values are manipulated, registers are already at a premium.  But if
11281 ;; we have one handy, we won't turn it away.
11283 (define_peephole2
11284   [(match_scratch:DWIH 3 "r")
11285    (parallel [(set (match_operand:<DWI> 0 "register_operand")
11286                    (any_shiftrt:<DWI>
11287                      (match_operand:<DWI> 1 "register_operand")
11288                      (match_operand:QI 2 "nonmemory_operand")))
11289               (clobber (reg:CC FLAGS_REG))])
11290    (match_dup 3)]
11291   "TARGET_CMOVE"
11292   [(const_int 0)]
11293   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11295 (define_insn "x86_64_shrd"
11296   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11297         (ior:DI (lshiftrt:DI (match_dup 0)
11298                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11299                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11300                   (minus:QI (const_int 64) (match_dup 2)))))
11301    (clobber (reg:CC FLAGS_REG))]
11302   "TARGET_64BIT"
11303   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11304   [(set_attr "type" "ishift")
11305    (set_attr "prefix_0f" "1")
11306    (set_attr "mode" "DI")
11307    (set_attr "athlon_decode" "vector")
11308    (set_attr "amdfam10_decode" "vector")
11309    (set_attr "bdver1_decode" "vector")])
11311 (define_insn "x86_shrd"
11312   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11313         (ior:SI (lshiftrt:SI (match_dup 0)
11314                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11315                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11316                   (minus:QI (const_int 32) (match_dup 2)))))
11317    (clobber (reg:CC FLAGS_REG))]
11318   ""
11319   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11320   [(set_attr "type" "ishift")
11321    (set_attr "prefix_0f" "1")
11322    (set_attr "mode" "SI")
11323    (set_attr "pent_pair" "np")
11324    (set_attr "athlon_decode" "vector")
11325    (set_attr "amdfam10_decode" "vector")
11326    (set_attr "bdver1_decode" "vector")])
11328 (define_insn "ashrdi3_cvt"
11329   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11330         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11331                      (match_operand:QI 2 "const_int_operand")))
11332    (clobber (reg:CC FLAGS_REG))]
11333   "TARGET_64BIT && INTVAL (operands[2]) == 63
11334    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11335    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11336   "@
11337    {cqto|cqo}
11338    sar{q}\t{%2, %0|%0, %2}"
11339   [(set_attr "type" "imovx,ishift")
11340    (set_attr "prefix_0f" "0,*")
11341    (set_attr "length_immediate" "0,*")
11342    (set_attr "modrm" "0,1")
11343    (set_attr "mode" "DI")])
11345 (define_insn "*ashrsi3_cvt_zext"
11346   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11347         (zero_extend:DI
11348           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11349                        (match_operand:QI 2 "const_int_operand"))))
11350    (clobber (reg:CC FLAGS_REG))]
11351   "TARGET_64BIT && INTVAL (operands[2]) == 31
11352    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11353    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11354   "@
11355    {cltd|cdq}
11356    sar{l}\t{%2, %k0|%k0, %2}"
11357   [(set_attr "type" "imovx,ishift")
11358    (set_attr "prefix_0f" "0,*")
11359    (set_attr "length_immediate" "0,*")
11360    (set_attr "modrm" "0,1")
11361    (set_attr "mode" "SI")])
11363 (define_insn "ashrsi3_cvt"
11364   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11365         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11366                      (match_operand:QI 2 "const_int_operand")))
11367    (clobber (reg:CC FLAGS_REG))]
11368   "INTVAL (operands[2]) == 31
11369    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11370    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11371   "@
11372    {cltd|cdq}
11373    sar{l}\t{%2, %0|%0, %2}"
11374   [(set_attr "type" "imovx,ishift")
11375    (set_attr "prefix_0f" "0,*")
11376    (set_attr "length_immediate" "0,*")
11377    (set_attr "modrm" "0,1")
11378    (set_attr "mode" "SI")])
11380 (define_expand "x86_shift<mode>_adj_3"
11381   [(use (match_operand:SWI48 0 "register_operand"))
11382    (use (match_operand:SWI48 1 "register_operand"))
11383    (use (match_operand:QI 2 "register_operand"))]
11384   ""
11386   rtx_code_label *label = gen_label_rtx ();
11387   rtx tmp;
11389   emit_insn (gen_testqi_ccz_1 (operands[2],
11390                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11392   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11393   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11394   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11395                               gen_rtx_LABEL_REF (VOIDmode, label),
11396                               pc_rtx);
11397   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11398   JUMP_LABEL (tmp) = label;
11400   emit_move_insn (operands[0], operands[1]);
11401   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11402                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11403   emit_label (label);
11404   LABEL_NUSES (label) = 1;
11406   DONE;
11409 (define_insn "*bmi2_<shift_insn><mode>3_1"
11410   [(set (match_operand:SWI48 0 "register_operand" "=r")
11411         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11412                            (match_operand:SWI48 2 "register_operand" "r")))]
11413   "TARGET_BMI2"
11414   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11415   [(set_attr "type" "ishiftx")
11416    (set_attr "mode" "<MODE>")])
11418 (define_insn "*<shift_insn><mode>3_1"
11419   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11420         (any_shiftrt:SWI48
11421           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11422           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11423    (clobber (reg:CC FLAGS_REG))]
11424   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11426   switch (get_attr_type (insn))
11427     {
11428     case TYPE_ISHIFTX:
11429       return "#";
11431     default:
11432       if (operands[2] == const1_rtx
11433           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11434         return "<shift>{<imodesuffix>}\t%0";
11435       else
11436         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11437     }
11439   [(set_attr "isa" "*,bmi2")
11440    (set_attr "type" "ishift,ishiftx")
11441    (set (attr "length_immediate")
11442      (if_then_else
11443        (and (match_operand 2 "const1_operand")
11444             (ior (match_test "TARGET_SHIFT1")
11445                  (match_test "optimize_function_for_size_p (cfun)")))
11446        (const_string "0")
11447        (const_string "*")))
11448    (set_attr "mode" "<MODE>")])
11450 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11451 (define_split
11452   [(set (match_operand:SWI48 0 "register_operand")
11453         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11454                            (match_operand:QI 2 "register_operand")))
11455    (clobber (reg:CC FLAGS_REG))]
11456   "TARGET_BMI2 && reload_completed"
11457   [(set (match_dup 0)
11458         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11459   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11461 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11462   [(set (match_operand:DI 0 "register_operand" "=r")
11463         (zero_extend:DI
11464           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11465                           (match_operand:SI 2 "register_operand" "r"))))]
11466   "TARGET_64BIT && TARGET_BMI2"
11467   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11468   [(set_attr "type" "ishiftx")
11469    (set_attr "mode" "SI")])
11471 (define_insn "*<shift_insn>si3_1_zext"
11472   [(set (match_operand:DI 0 "register_operand" "=r,r")
11473         (zero_extend:DI
11474           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11475                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11476    (clobber (reg:CC FLAGS_REG))]
11477   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11479   switch (get_attr_type (insn))
11480     {
11481     case TYPE_ISHIFTX:
11482       return "#";
11484     default:
11485       if (operands[2] == const1_rtx
11486           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11487         return "<shift>{l}\t%k0";
11488       else
11489         return "<shift>{l}\t{%2, %k0|%k0, %2}";
11490     }
11492   [(set_attr "isa" "*,bmi2")
11493    (set_attr "type" "ishift,ishiftx")
11494    (set (attr "length_immediate")
11495      (if_then_else
11496        (and (match_operand 2 "const1_operand")
11497             (ior (match_test "TARGET_SHIFT1")
11498                  (match_test "optimize_function_for_size_p (cfun)")))
11499        (const_string "0")
11500        (const_string "*")))
11501    (set_attr "mode" "SI")])
11503 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11504 (define_split
11505   [(set (match_operand:DI 0 "register_operand")
11506         (zero_extend:DI
11507           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11508                           (match_operand:QI 2 "register_operand"))))
11509    (clobber (reg:CC FLAGS_REG))]
11510   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11511   [(set (match_dup 0)
11512         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11513   "operands[2] = gen_lowpart (SImode, operands[2]);")
11515 (define_insn "*<shift_insn><mode>3_1"
11516   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11517         (any_shiftrt:SWI12
11518           (match_operand:SWI12 1 "nonimmediate_operand" "0")
11519           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11520    (clobber (reg:CC FLAGS_REG))]
11521   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11523   if (operands[2] == const1_rtx
11524       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11525     return "<shift>{<imodesuffix>}\t%0";
11526   else
11527     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11529   [(set_attr "type" "ishift")
11530    (set (attr "length_immediate")
11531      (if_then_else
11532        (and (match_operand 2 "const1_operand")
11533             (ior (match_test "TARGET_SHIFT1")
11534                  (match_test "optimize_function_for_size_p (cfun)")))
11535        (const_string "0")
11536        (const_string "*")))
11537    (set_attr "mode" "<MODE>")])
11539 (define_insn "*<shift_insn>qi3_1_slp"
11540   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11541         (any_shiftrt:QI (match_dup 0)
11542                         (match_operand:QI 1 "nonmemory_operand" "cI")))
11543    (clobber (reg:CC FLAGS_REG))]
11544   "(optimize_function_for_size_p (cfun)
11545     || !TARGET_PARTIAL_REG_STALL
11546     || (operands[1] == const1_rtx
11547         && TARGET_SHIFT1))"
11549   if (operands[1] == const1_rtx
11550       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11551     return "<shift>{b}\t%0";
11552   else
11553     return "<shift>{b}\t{%1, %0|%0, %1}";
11555   [(set_attr "type" "ishift1")
11556    (set (attr "length_immediate")
11557      (if_then_else
11558        (and (match_operand 1 "const1_operand")
11559             (ior (match_test "TARGET_SHIFT1")
11560                  (match_test "optimize_function_for_size_p (cfun)")))
11561        (const_string "0")
11562        (const_string "*")))
11563    (set_attr "mode" "QI")])
11565 ;; This pattern can't accept a variable shift count, since shifts by
11566 ;; zero don't affect the flags.  We assume that shifts by constant
11567 ;; zero are optimized away.
11568 (define_insn "*<shift_insn><mode>3_cmp"
11569   [(set (reg FLAGS_REG)
11570         (compare
11571           (any_shiftrt:SWI
11572             (match_operand:SWI 1 "nonimmediate_operand" "0")
11573             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11574           (const_int 0)))
11575    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11576         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11577   "(optimize_function_for_size_p (cfun)
11578     || !TARGET_PARTIAL_FLAG_REG_STALL
11579     || (operands[2] == const1_rtx
11580         && TARGET_SHIFT1))
11581    && ix86_match_ccmode (insn, CCGOCmode)
11582    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11584   if (operands[2] == const1_rtx
11585       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11586     return "<shift>{<imodesuffix>}\t%0";
11587   else
11588     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11590   [(set_attr "type" "ishift")
11591    (set (attr "length_immediate")
11592      (if_then_else
11593        (and (match_operand 2 "const1_operand")
11594             (ior (match_test "TARGET_SHIFT1")
11595                  (match_test "optimize_function_for_size_p (cfun)")))
11596        (const_string "0")
11597        (const_string "*")))
11598    (set_attr "mode" "<MODE>")])
11600 (define_insn "*<shift_insn>si3_cmp_zext"
11601   [(set (reg FLAGS_REG)
11602         (compare
11603           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11604                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
11605           (const_int 0)))
11606    (set (match_operand:DI 0 "register_operand" "=r")
11607         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11608   "TARGET_64BIT
11609    && (optimize_function_for_size_p (cfun)
11610        || !TARGET_PARTIAL_FLAG_REG_STALL
11611        || (operands[2] == const1_rtx
11612            && TARGET_SHIFT1))
11613    && ix86_match_ccmode (insn, CCGOCmode)
11614    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11616   if (operands[2] == const1_rtx
11617       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11618     return "<shift>{l}\t%k0";
11619   else
11620     return "<shift>{l}\t{%2, %k0|%k0, %2}";
11622   [(set_attr "type" "ishift")
11623    (set (attr "length_immediate")
11624      (if_then_else
11625        (and (match_operand 2 "const1_operand")
11626             (ior (match_test "TARGET_SHIFT1")
11627                  (match_test "optimize_function_for_size_p (cfun)")))
11628        (const_string "0")
11629        (const_string "*")))
11630    (set_attr "mode" "SI")])
11632 (define_insn "*<shift_insn><mode>3_cconly"
11633   [(set (reg FLAGS_REG)
11634         (compare
11635           (any_shiftrt:SWI
11636             (match_operand:SWI 1 "register_operand" "0")
11637             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11638           (const_int 0)))
11639    (clobber (match_scratch:SWI 0 "=<r>"))]
11640   "(optimize_function_for_size_p (cfun)
11641     || !TARGET_PARTIAL_FLAG_REG_STALL
11642     || (operands[2] == const1_rtx
11643         && TARGET_SHIFT1))
11644    && ix86_match_ccmode (insn, CCGOCmode)"
11646   if (operands[2] == const1_rtx
11647       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11648     return "<shift>{<imodesuffix>}\t%0";
11649   else
11650     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11652   [(set_attr "type" "ishift")
11653    (set (attr "length_immediate")
11654      (if_then_else
11655        (and (match_operand 2 "const1_operand")
11656             (ior (match_test "TARGET_SHIFT1")
11657                  (match_test "optimize_function_for_size_p (cfun)")))
11658        (const_string "0")
11659        (const_string "*")))
11660    (set_attr "mode" "<MODE>")])
11662 ;; Rotate instructions
11664 (define_expand "<rotate_insn>ti3"
11665   [(set (match_operand:TI 0 "register_operand")
11666         (any_rotate:TI (match_operand:TI 1 "register_operand")
11667                        (match_operand:QI 2 "nonmemory_operand")))]
11668   "TARGET_64BIT"
11670   if (const_1_to_63_operand (operands[2], VOIDmode))
11671     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11672                 (operands[0], operands[1], operands[2]));
11673   else
11674     FAIL;
11676   DONE;
11679 (define_expand "<rotate_insn>di3"
11680   [(set (match_operand:DI 0 "shiftdi_operand")
11681         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11682                        (match_operand:QI 2 "nonmemory_operand")))]
11683  ""
11685   if (TARGET_64BIT)
11686     ix86_expand_binary_operator (<CODE>, DImode, operands);
11687   else if (const_1_to_31_operand (operands[2], VOIDmode))
11688     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11689                 (operands[0], operands[1], operands[2]));
11690   else
11691     FAIL;
11693   DONE;
11696 (define_expand "<rotate_insn><mode>3"
11697   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11698         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11699                             (match_operand:QI 2 "nonmemory_operand")))]
11700   ""
11701   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11703 ;; Avoid useless masking of count operand.
11704 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11705   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11706         (any_rotate:SWI48
11707           (match_operand:SWI48 1 "nonimmediate_operand")
11708           (subreg:QI
11709             (and:SI
11710               (match_operand:SI 2 "register_operand" "c")
11711               (match_operand:SI 3 "const_int_operand")) 0)))
11712    (clobber (reg:CC FLAGS_REG))]
11713   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11714    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11715       == GET_MODE_BITSIZE (<MODE>mode)-1
11716    && can_create_pseudo_p ()"
11717   "#"
11718   "&& 1"
11719   [(parallel
11720      [(set (match_dup 0)
11721            (any_rotate:SWI48 (match_dup 1)
11722                              (match_dup 2)))
11723       (clobber (reg:CC FLAGS_REG))])]
11724   "operands[2] = gen_lowpart (QImode, operands[2]);")
11726 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11727   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11728         (any_rotate:SWI48
11729           (match_operand:SWI48 1 "nonimmediate_operand")
11730           (and:QI
11731             (match_operand:QI 2 "register_operand" "c")
11732             (match_operand:QI 3 "const_int_operand"))))
11733    (clobber (reg:CC FLAGS_REG))]
11734   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11735    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11736       == GET_MODE_BITSIZE (<MODE>mode)-1
11737    && can_create_pseudo_p ()"
11738   "#"
11739   "&& 1"
11740   [(parallel
11741      [(set (match_dup 0)
11742            (any_rotate:SWI48 (match_dup 1)
11743                              (match_dup 2)))
11744       (clobber (reg:CC FLAGS_REG))])])
11746 ;; Implement rotation using two double-precision
11747 ;; shift instructions and a scratch register.
11749 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11750  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11751        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11752                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11753   (clobber (reg:CC FLAGS_REG))
11754   (clobber (match_scratch:DWIH 3 "=&r"))]
11755  ""
11756  "#"
11757  "reload_completed"
11758  [(set (match_dup 3) (match_dup 4))
11759   (parallel
11760    [(set (match_dup 4)
11761          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11762                    (lshiftrt:DWIH (match_dup 5)
11763                                   (minus:QI (match_dup 6) (match_dup 2)))))
11764     (clobber (reg:CC FLAGS_REG))])
11765   (parallel
11766    [(set (match_dup 5)
11767          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11768                    (lshiftrt:DWIH (match_dup 3)
11769                                   (minus:QI (match_dup 6) (match_dup 2)))))
11770     (clobber (reg:CC FLAGS_REG))])]
11772   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11774   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11777 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11778  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11779        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11780                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11781   (clobber (reg:CC FLAGS_REG))
11782   (clobber (match_scratch:DWIH 3 "=&r"))]
11783  ""
11784  "#"
11785  "reload_completed"
11786  [(set (match_dup 3) (match_dup 4))
11787   (parallel
11788    [(set (match_dup 4)
11789          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11790                    (ashift:DWIH (match_dup 5)
11791                                 (minus:QI (match_dup 6) (match_dup 2)))))
11792     (clobber (reg:CC FLAGS_REG))])
11793   (parallel
11794    [(set (match_dup 5)
11795          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11796                    (ashift:DWIH (match_dup 3)
11797                                 (minus:QI (match_dup 6) (match_dup 2)))))
11798     (clobber (reg:CC FLAGS_REG))])]
11800   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11802   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11805 (define_mode_attr rorx_immediate_operand
11806         [(SI "const_0_to_31_operand")
11807          (DI "const_0_to_63_operand")])
11809 (define_insn "*bmi2_rorx<mode>3_1"
11810   [(set (match_operand:SWI48 0 "register_operand" "=r")
11811         (rotatert:SWI48
11812           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11813           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11814   "TARGET_BMI2"
11815   "rorx\t{%2, %1, %0|%0, %1, %2}"
11816   [(set_attr "type" "rotatex")
11817    (set_attr "mode" "<MODE>")])
11819 (define_insn "*<rotate_insn><mode>3_1"
11820   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11821         (any_rotate:SWI48
11822           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11823           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11824    (clobber (reg:CC FLAGS_REG))]
11825   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11827   switch (get_attr_type (insn))
11828     {
11829     case TYPE_ROTATEX:
11830       return "#";
11832     default:
11833       if (operands[2] == const1_rtx
11834           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11835         return "<rotate>{<imodesuffix>}\t%0";
11836       else
11837         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11838     }
11840   [(set_attr "isa" "*,bmi2")
11841    (set_attr "type" "rotate,rotatex")
11842    (set (attr "length_immediate")
11843      (if_then_else
11844        (and (eq_attr "type" "rotate")
11845             (and (match_operand 2 "const1_operand")
11846                  (ior (match_test "TARGET_SHIFT1")
11847                       (match_test "optimize_function_for_size_p (cfun)"))))
11848        (const_string "0")
11849        (const_string "*")))
11850    (set_attr "mode" "<MODE>")])
11852 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11853 (define_split
11854   [(set (match_operand:SWI48 0 "register_operand")
11855         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11856                       (match_operand:QI 2 "const_int_operand")))
11857    (clobber (reg:CC FLAGS_REG))]
11858   "TARGET_BMI2 && reload_completed"
11859   [(set (match_dup 0)
11860         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11862   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11864   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11867 (define_split
11868   [(set (match_operand:SWI48 0 "register_operand")
11869         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11870                         (match_operand:QI 2 "const_int_operand")))
11871    (clobber (reg:CC FLAGS_REG))]
11872   "TARGET_BMI2 && reload_completed"
11873   [(set (match_dup 0)
11874         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11876 (define_insn "*bmi2_rorxsi3_1_zext"
11877   [(set (match_operand:DI 0 "register_operand" "=r")
11878         (zero_extend:DI
11879           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11880                        (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11881   "TARGET_64BIT && TARGET_BMI2"
11882   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11883   [(set_attr "type" "rotatex")
11884    (set_attr "mode" "SI")])
11886 (define_insn "*<rotate_insn>si3_1_zext"
11887   [(set (match_operand:DI 0 "register_operand" "=r,r")
11888         (zero_extend:DI
11889           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11890                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11891    (clobber (reg:CC FLAGS_REG))]
11892   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11894   switch (get_attr_type (insn))
11895     {
11896     case TYPE_ROTATEX:
11897       return "#";
11899     default:
11900       if (operands[2] == const1_rtx
11901           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11902         return "<rotate>{l}\t%k0";
11903       else
11904         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11905     }
11907   [(set_attr "isa" "*,bmi2")
11908    (set_attr "type" "rotate,rotatex")
11909    (set (attr "length_immediate")
11910      (if_then_else
11911        (and (eq_attr "type" "rotate")
11912             (and (match_operand 2 "const1_operand")
11913                  (ior (match_test "TARGET_SHIFT1")
11914                       (match_test "optimize_function_for_size_p (cfun)"))))
11915        (const_string "0")
11916        (const_string "*")))
11917    (set_attr "mode" "SI")])
11919 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11920 (define_split
11921   [(set (match_operand:DI 0 "register_operand")
11922         (zero_extend:DI
11923           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11924                      (match_operand:QI 2 "const_int_operand"))))
11925    (clobber (reg:CC FLAGS_REG))]
11926   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11927   [(set (match_dup 0)
11928         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11930   int bitsize = GET_MODE_BITSIZE (SImode);
11932   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11935 (define_split
11936   [(set (match_operand:DI 0 "register_operand")
11937         (zero_extend:DI
11938           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11939                        (match_operand:QI 2 "const_int_operand"))))
11940    (clobber (reg:CC FLAGS_REG))]
11941   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11942   [(set (match_dup 0)
11943         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11945 (define_insn "*<rotate_insn><mode>3_1"
11946   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11947         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11948                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11949    (clobber (reg:CC FLAGS_REG))]
11950   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11952   if (operands[2] == const1_rtx
11953       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11954     return "<rotate>{<imodesuffix>}\t%0";
11955   else
11956     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11958   [(set_attr "type" "rotate")
11959    (set (attr "length_immediate")
11960      (if_then_else
11961        (and (match_operand 2 "const1_operand")
11962             (ior (match_test "TARGET_SHIFT1")
11963                  (match_test "optimize_function_for_size_p (cfun)")))
11964        (const_string "0")
11965        (const_string "*")))
11966    (set_attr "mode" "<MODE>")])
11968 (define_insn "*<rotate_insn>qi3_1_slp"
11969   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11970         (any_rotate:QI (match_dup 0)
11971                        (match_operand:QI 1 "nonmemory_operand" "cI")))
11972    (clobber (reg:CC FLAGS_REG))]
11973   "(optimize_function_for_size_p (cfun)
11974     || !TARGET_PARTIAL_REG_STALL
11975     || (operands[1] == const1_rtx
11976         && TARGET_SHIFT1))"
11978   if (operands[1] == const1_rtx
11979       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11980     return "<rotate>{b}\t%0";
11981   else
11982     return "<rotate>{b}\t{%1, %0|%0, %1}";
11984   [(set_attr "type" "rotate1")
11985    (set (attr "length_immediate")
11986      (if_then_else
11987        (and (match_operand 1 "const1_operand")
11988             (ior (match_test "TARGET_SHIFT1")
11989                  (match_test "optimize_function_for_size_p (cfun)")))
11990        (const_string "0")
11991        (const_string "*")))
11992    (set_attr "mode" "QI")])
11994 (define_split
11995  [(set (match_operand:HI 0 "QIreg_operand")
11996        (any_rotate:HI (match_dup 0) (const_int 8)))
11997   (clobber (reg:CC FLAGS_REG))]
11998  "reload_completed
11999   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
12000  [(parallel [(set (strict_low_part (match_dup 0))
12001                   (bswap:HI (match_dup 0)))
12002              (clobber (reg:CC FLAGS_REG))])])
12004 ;; Bit set / bit test instructions
12006 ;; %%% bts, btr, btc
12008 ;; These instructions are *slow* when applied to memory.
12010 (define_code_attr btsc [(ior "bts") (xor "btc")])
12012 (define_insn "*<btsc><mode>"
12013   [(set (match_operand:SWI48 0 "register_operand" "=r")
12014         (any_or:SWI48
12015           (ashift:SWI48 (const_int 1)
12016                         (match_operand:QI 2 "register_operand" "r"))
12017           (match_operand:SWI48 1 "register_operand" "0")))
12018    (clobber (reg:CC FLAGS_REG))]
12019   "TARGET_USE_BT"
12020   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12021   [(set_attr "type" "alu1")
12022    (set_attr "prefix_0f" "1")
12023    (set_attr "znver1_decode" "double")
12024    (set_attr "mode" "<MODE>")])
12026 ;; Avoid useless masking of count operand.
12027 (define_insn_and_split "*<btsc><mode>_mask"
12028   [(set (match_operand:SWI48 0 "register_operand")
12029         (any_or:SWI48
12030           (ashift:SWI48
12031             (const_int 1)
12032             (subreg:QI
12033               (and:SI
12034                 (match_operand:SI 1 "register_operand")
12035                 (match_operand:SI 2 "const_int_operand")) 0))
12036           (match_operand:SWI48 3 "register_operand")))
12037    (clobber (reg:CC FLAGS_REG))]
12038   "TARGET_USE_BT
12039    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12040       == GET_MODE_BITSIZE (<MODE>mode)-1
12041    && can_create_pseudo_p ()"
12042   "#"
12043   "&& 1"
12044   [(parallel
12045      [(set (match_dup 0)
12046            (any_or:SWI48
12047              (ashift:SWI48 (const_int 1)
12048                            (match_dup 1))
12049              (match_dup 3)))
12050       (clobber (reg:CC FLAGS_REG))])]
12051   "operands[1] = gen_lowpart (QImode, operands[1]);")
12053 (define_insn_and_split "*<btsc><mode>_mask_1"
12054   [(set (match_operand:SWI48 0 "register_operand")
12055         (any_or:SWI48
12056           (ashift:SWI48
12057             (const_int 1)
12058             (and:QI
12059               (match_operand:QI 1 "register_operand")
12060               (match_operand:QI 2 "const_int_operand")))
12061           (match_operand:SWI48 3 "register_operand")))
12062    (clobber (reg:CC FLAGS_REG))]
12063   "TARGET_USE_BT
12064    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12065       == GET_MODE_BITSIZE (<MODE>mode)-1
12066    && can_create_pseudo_p ()"
12067   "#"
12068   "&& 1"
12069   [(parallel
12070      [(set (match_dup 0)
12071            (any_or:SWI48
12072              (ashift:SWI48 (const_int 1)
12073                            (match_dup 1))
12074              (match_dup 3)))
12075       (clobber (reg:CC FLAGS_REG))])])
12077 (define_insn "*btr<mode>"
12078   [(set (match_operand:SWI48 0 "register_operand" "=r")
12079         (and:SWI48
12080           (rotate:SWI48 (const_int -2)
12081                         (match_operand:QI 2 "register_operand" "r"))
12082         (match_operand:SWI48 1 "register_operand" "0")))
12083    (clobber (reg:CC FLAGS_REG))]
12084   "TARGET_USE_BT"
12085   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12086   [(set_attr "type" "alu1")
12087    (set_attr "prefix_0f" "1")
12088    (set_attr "znver1_decode" "double")
12089    (set_attr "mode" "<MODE>")])
12091 ;; Avoid useless masking of count operand.
12092 (define_insn_and_split "*btr<mode>_mask"
12093   [(set (match_operand:SWI48 0 "register_operand")
12094         (and:SWI48
12095           (rotate:SWI48
12096             (const_int -2)
12097             (subreg:QI
12098               (and:SI
12099                 (match_operand:SI 1 "register_operand")
12100                 (match_operand:SI 2 "const_int_operand")) 0))
12101           (match_operand:SWI48 3 "register_operand")))
12102    (clobber (reg:CC FLAGS_REG))]
12103   "TARGET_USE_BT
12104    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12105       == GET_MODE_BITSIZE (<MODE>mode)-1
12106    && can_create_pseudo_p ()"
12107   "#"
12108   "&& 1"
12109   [(parallel
12110      [(set (match_dup 0)
12111            (and:SWI48
12112              (rotate:SWI48 (const_int -2)
12113                            (match_dup 1))
12114              (match_dup 3)))
12115       (clobber (reg:CC FLAGS_REG))])]
12116   "operands[1] = gen_lowpart (QImode, operands[1]);")
12118 (define_insn_and_split "*btr<mode>_mask_1"
12119   [(set (match_operand:SWI48 0 "register_operand")
12120         (and:SWI48
12121           (rotate:SWI48
12122             (const_int -2)
12123             (and:QI
12124               (match_operand:QI 1 "register_operand")
12125               (match_operand:QI 2 "const_int_operand")))
12126           (match_operand:SWI48 3 "register_operand")))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "TARGET_USE_BT
12129    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12130       == GET_MODE_BITSIZE (<MODE>mode)-1
12131    && can_create_pseudo_p ()"
12132   "#"
12133   "&& 1"
12134   [(parallel
12135      [(set (match_dup 0)
12136            (and:SWI48
12137              (rotate:SWI48 (const_int -2)
12138                            (match_dup 1))
12139              (match_dup 3)))
12140       (clobber (reg:CC FLAGS_REG))])])
12142 ;; These instructions are never faster than the corresponding
12143 ;; and/ior/xor operations when using immediate operand, so with
12144 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
12145 ;; relevant immediates within the instruction itself, so operating
12146 ;; on bits in the high 32-bits of a register becomes easier.
12148 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12149 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12150 ;; negdf respectively, so they can never be disabled entirely.
12152 (define_insn "*btsq_imm"
12153   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12154                          (const_int 1)
12155                          (match_operand 1 "const_0_to_63_operand" "J"))
12156         (const_int 1))
12157    (clobber (reg:CC FLAGS_REG))]
12158   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12159   "bts{q}\t{%1, %0|%0, %1}"
12160   [(set_attr "type" "alu1")
12161    (set_attr "prefix_0f" "1")
12162    (set_attr "znver1_decode" "double")
12163    (set_attr "mode" "DI")])
12165 (define_insn "*btrq_imm"
12166   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12167                          (const_int 1)
12168                          (match_operand 1 "const_0_to_63_operand" "J"))
12169         (const_int 0))
12170    (clobber (reg:CC FLAGS_REG))]
12171   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12172   "btr{q}\t{%1, %0|%0, %1}"
12173   [(set_attr "type" "alu1")
12174    (set_attr "prefix_0f" "1")
12175    (set_attr "znver1_decode" "double")
12176    (set_attr "mode" "DI")])
12178 (define_insn "*btcq_imm"
12179   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12180                          (const_int 1)
12181                          (match_operand 1 "const_0_to_63_operand" "J"))
12182         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12183    (clobber (reg:CC FLAGS_REG))]
12184   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12185   "btc{q}\t{%1, %0|%0, %1}"
12186   [(set_attr "type" "alu1")
12187    (set_attr "prefix_0f" "1")
12188    (set_attr "znver1_decode" "double")
12189    (set_attr "mode" "DI")])
12191 ;; Allow Nocona to avoid these instructions if a register is available.
12193 (define_peephole2
12194   [(match_scratch:DI 2 "r")
12195    (parallel [(set (zero_extract:DI
12196                      (match_operand:DI 0 "nonimmediate_operand")
12197                      (const_int 1)
12198                      (match_operand 1 "const_0_to_63_operand"))
12199                    (const_int 1))
12200               (clobber (reg:CC FLAGS_REG))])]
12201   "TARGET_64BIT && !TARGET_USE_BT"
12202   [(parallel [(set (match_dup 0)
12203                    (ior:DI (match_dup 0) (match_dup 3)))
12204               (clobber (reg:CC FLAGS_REG))])]
12206   int i = INTVAL (operands[1]);
12208   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12210   if (!x86_64_immediate_operand (operands[3], DImode))
12211     {
12212       emit_move_insn (operands[2], operands[3]);
12213       operands[3] = operands[2];
12214     }
12217 (define_peephole2
12218   [(match_scratch:DI 2 "r")
12219    (parallel [(set (zero_extract:DI
12220                      (match_operand:DI 0 "nonimmediate_operand")
12221                      (const_int 1)
12222                      (match_operand 1 "const_0_to_63_operand"))
12223                    (const_int 0))
12224               (clobber (reg:CC FLAGS_REG))])]
12225   "TARGET_64BIT && !TARGET_USE_BT"
12226   [(parallel [(set (match_dup 0)
12227                    (and:DI (match_dup 0) (match_dup 3)))
12228               (clobber (reg:CC FLAGS_REG))])]
12230   int i = INTVAL (operands[1]);
12232   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12234   if (!x86_64_immediate_operand (operands[3], DImode))
12235     {
12236       emit_move_insn (operands[2], operands[3]);
12237       operands[3] = operands[2];
12238     }
12241 (define_peephole2
12242   [(match_scratch:DI 2 "r")
12243    (parallel [(set (zero_extract:DI
12244                      (match_operand:DI 0 "nonimmediate_operand")
12245                      (const_int 1)
12246                      (match_operand 1 "const_0_to_63_operand"))
12247               (not:DI (zero_extract:DI
12248                         (match_dup 0) (const_int 1) (match_dup 1))))
12249               (clobber (reg:CC FLAGS_REG))])]
12250   "TARGET_64BIT && !TARGET_USE_BT"
12251   [(parallel [(set (match_dup 0)
12252                    (xor:DI (match_dup 0) (match_dup 3)))
12253               (clobber (reg:CC FLAGS_REG))])]
12255   int i = INTVAL (operands[1]);
12257   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12259   if (!x86_64_immediate_operand (operands[3], DImode))
12260     {
12261       emit_move_insn (operands[2], operands[3]);
12262       operands[3] = operands[2];
12263     }
12266 ;; %%% bt
12268 (define_insn "*bt<mode>"
12269   [(set (reg:CCC FLAGS_REG)
12270         (compare:CCC
12271           (zero_extract:SWI48
12272             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12273             (const_int 1)
12274             (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12275           (const_int 0)))]
12276   ""
12278   switch (get_attr_mode (insn))
12279     {
12280     case MODE_SI:
12281       return "bt{l}\t{%1, %k0|%k0, %1}";
12283     case MODE_DI:
12284       return "bt{q}\t{%q1, %0|%0, %q1}";
12286     default:
12287       gcc_unreachable ();
12288     }
12290   [(set_attr "type" "alu1")
12291    (set_attr "prefix_0f" "1")
12292    (set (attr "mode")
12293         (if_then_else
12294           (and (match_test "CONST_INT_P (operands[1])")
12295                (match_test "INTVAL (operands[1]) < 32"))
12296           (const_string "SI")
12297           (const_string "<MODE>")))])
12299 (define_insn_and_split "*jcc_bt<mode>"
12300   [(set (pc)
12301         (if_then_else (match_operator 0 "bt_comparison_operator"
12302                         [(zero_extract:SWI48
12303                            (match_operand:SWI48 1 "nonimmediate_operand")
12304                            (const_int 1)
12305                            (match_operand:SI 2 "nonmemory_operand"))
12306                          (const_int 0)])
12307                       (label_ref (match_operand 3))
12308                       (pc)))
12309    (clobber (reg:CC FLAGS_REG))]
12310   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12311    && (CONST_INT_P (operands[2])
12312        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12313           && INTVAL (operands[2])
12314                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12315        : !memory_operand (operands[1], <MODE>mode))
12316    && can_create_pseudo_p ()"
12317   "#"
12318   "&& 1"
12319   [(set (reg:CCC FLAGS_REG)
12320         (compare:CCC
12321           (zero_extract:SWI48
12322             (match_dup 1)
12323             (const_int 1)
12324             (match_dup 2))
12325           (const_int 0)))
12326    (set (pc)
12327         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12328                       (label_ref (match_dup 3))
12329                       (pc)))]
12331   operands[0] = shallow_copy_rtx (operands[0]);
12332   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12335 (define_insn_and_split "*jcc_bt<mode>_1"
12336   [(set (pc)
12337         (if_then_else (match_operator 0 "bt_comparison_operator"
12338                         [(zero_extract:SWI48
12339                            (match_operand:SWI48 1 "register_operand")
12340                            (const_int 1)
12341                            (zero_extend:SI
12342                              (match_operand:QI 2 "register_operand")))
12343                          (const_int 0)])
12344                       (label_ref (match_operand 3))
12345                       (pc)))
12346    (clobber (reg:CC FLAGS_REG))]
12347   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12348    && can_create_pseudo_p ()"
12349   "#"
12350   "&& 1"
12351   [(set (reg:CCC FLAGS_REG)
12352         (compare:CCC
12353           (zero_extract:SWI48
12354             (match_dup 1)
12355             (const_int 1)
12356             (match_dup 2))
12357           (const_int 0)))
12358    (set (pc)
12359         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12360                       (label_ref (match_dup 3))
12361                       (pc)))]
12363   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12364   operands[0] = shallow_copy_rtx (operands[0]);
12365   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12368 ;; Avoid useless masking of bit offset operand.
12369 (define_insn_and_split "*jcc_bt<mode>_mask"
12370   [(set (pc)
12371         (if_then_else (match_operator 0 "bt_comparison_operator"
12372                         [(zero_extract:SWI48
12373                            (match_operand:SWI48 1 "register_operand")
12374                            (const_int 1)
12375                            (and:SI
12376                              (match_operand:SI 2 "register_operand")
12377                              (match_operand 3 "const_int_operand")))])
12378                       (label_ref (match_operand 4))
12379                       (pc)))
12380    (clobber (reg:CC FLAGS_REG))]
12381   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12382    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12383       == GET_MODE_BITSIZE (<MODE>mode)-1
12384    && can_create_pseudo_p ()"
12385   "#"
12386   "&& 1"
12387   [(set (reg:CCC FLAGS_REG)
12388         (compare:CCC
12389           (zero_extract:SWI48
12390             (match_dup 1)
12391             (const_int 1)
12392             (match_dup 2))
12393           (const_int 0)))
12394    (set (pc)
12395         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12396                       (label_ref (match_dup 4))
12397                       (pc)))]
12399   operands[0] = shallow_copy_rtx (operands[0]);
12400   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12403 ;; Store-flag instructions.
12405 ;; For all sCOND expanders, also expand the compare or test insn that
12406 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12408 (define_insn_and_split "*setcc_di_1"
12409   [(set (match_operand:DI 0 "register_operand" "=q")
12410         (match_operator:DI 1 "ix86_comparison_operator"
12411           [(reg FLAGS_REG) (const_int 0)]))]
12412   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12413   "#"
12414   "&& reload_completed"
12415   [(set (match_dup 2) (match_dup 1))
12416    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12418   operands[1] = shallow_copy_rtx (operands[1]);
12419   PUT_MODE (operands[1], QImode);
12420   operands[2] = gen_lowpart (QImode, operands[0]);
12423 (define_insn_and_split "*setcc_si_1_and"
12424   [(set (match_operand:SI 0 "register_operand" "=q")
12425         (match_operator:SI 1 "ix86_comparison_operator"
12426           [(reg FLAGS_REG) (const_int 0)]))
12427    (clobber (reg:CC FLAGS_REG))]
12428   "!TARGET_PARTIAL_REG_STALL
12429    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12430   "#"
12431   "&& reload_completed"
12432   [(set (match_dup 2) (match_dup 1))
12433    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12434               (clobber (reg:CC FLAGS_REG))])]
12436   operands[1] = shallow_copy_rtx (operands[1]);
12437   PUT_MODE (operands[1], QImode);
12438   operands[2] = gen_lowpart (QImode, operands[0]);
12441 (define_insn_and_split "*setcc_si_1_movzbl"
12442   [(set (match_operand:SI 0 "register_operand" "=q")
12443         (match_operator:SI 1 "ix86_comparison_operator"
12444           [(reg FLAGS_REG) (const_int 0)]))]
12445   "!TARGET_PARTIAL_REG_STALL
12446    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12447   "#"
12448   "&& reload_completed"
12449   [(set (match_dup 2) (match_dup 1))
12450    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12452   operands[1] = shallow_copy_rtx (operands[1]);
12453   PUT_MODE (operands[1], QImode);
12454   operands[2] = gen_lowpart (QImode, operands[0]);
12457 (define_insn "*setcc_qi"
12458   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12459         (match_operator:QI 1 "ix86_comparison_operator"
12460           [(reg FLAGS_REG) (const_int 0)]))]
12461   ""
12462   "set%C1\t%0"
12463   [(set_attr "type" "setcc")
12464    (set_attr "mode" "QI")])
12466 (define_insn "*setcc_qi_slp"
12467   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12468         (match_operator:QI 1 "ix86_comparison_operator"
12469           [(reg FLAGS_REG) (const_int 0)]))]
12470   ""
12471   "set%C1\t%0"
12472   [(set_attr "type" "setcc")
12473    (set_attr "mode" "QI")])
12475 ;; In general it is not safe to assume too much about CCmode registers,
12476 ;; so simplify-rtx stops when it sees a second one.  Under certain
12477 ;; conditions this is safe on x86, so help combine not create
12479 ;;      seta    %al
12480 ;;      testb   %al, %al
12481 ;;      sete    %al
12483 (define_split
12484   [(set (match_operand:QI 0 "nonimmediate_operand")
12485         (ne:QI (match_operator 1 "ix86_comparison_operator"
12486                  [(reg FLAGS_REG) (const_int 0)])
12487             (const_int 0)))]
12488   ""
12489   [(set (match_dup 0) (match_dup 1))]
12491   operands[1] = shallow_copy_rtx (operands[1]);
12492   PUT_MODE (operands[1], QImode);
12495 (define_split
12496   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12497         (ne:QI (match_operator 1 "ix86_comparison_operator"
12498                  [(reg FLAGS_REG) (const_int 0)])
12499             (const_int 0)))]
12500   ""
12501   [(set (match_dup 0) (match_dup 1))]
12503   operands[1] = shallow_copy_rtx (operands[1]);
12504   PUT_MODE (operands[1], QImode);
12507 (define_split
12508   [(set (match_operand:QI 0 "nonimmediate_operand")
12509         (eq:QI (match_operator 1 "ix86_comparison_operator"
12510                  [(reg FLAGS_REG) (const_int 0)])
12511             (const_int 0)))]
12512   ""
12513   [(set (match_dup 0) (match_dup 1))]
12515   operands[1] = shallow_copy_rtx (operands[1]);
12516   PUT_MODE (operands[1], QImode);
12517   PUT_CODE (operands[1],
12518             ix86_reverse_condition (GET_CODE (operands[1]),
12519                                     GET_MODE (XEXP (operands[1], 0))));
12521   /* Make sure that (a) the CCmode we have for the flags is strong
12522      enough for the reversed compare or (b) we have a valid FP compare.  */
12523   if (! ix86_comparison_operator (operands[1], VOIDmode))
12524     FAIL;
12527 (define_split
12528   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12529         (eq:QI (match_operator 1 "ix86_comparison_operator"
12530                  [(reg FLAGS_REG) (const_int 0)])
12531             (const_int 0)))]
12532   ""
12533   [(set (match_dup 0) (match_dup 1))]
12535   operands[1] = shallow_copy_rtx (operands[1]);
12536   PUT_MODE (operands[1], QImode);
12537   PUT_CODE (operands[1],
12538             ix86_reverse_condition (GET_CODE (operands[1]),
12539                                     GET_MODE (XEXP (operands[1], 0))));
12541   /* Make sure that (a) the CCmode we have for the flags is strong
12542      enough for the reversed compare or (b) we have a valid FP compare.  */
12543   if (! ix86_comparison_operator (operands[1], VOIDmode))
12544     FAIL;
12547 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12548 ;; subsequent logical operations are used to imitate conditional moves.
12549 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12550 ;; it directly.
12552 (define_insn "setcc_<mode>_sse"
12553   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12554         (match_operator:MODEF 3 "sse_comparison_operator"
12555           [(match_operand:MODEF 1 "register_operand" "0,x")
12556            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12557   "SSE_FLOAT_MODE_P (<MODE>mode)"
12558   "@
12559    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12560    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12561   [(set_attr "isa" "noavx,avx")
12562    (set_attr "type" "ssecmp")
12563    (set_attr "length_immediate" "1")
12564    (set_attr "prefix" "orig,vex")
12565    (set_attr "mode" "<MODE>")])
12567 ;; Basic conditional jump instructions.
12568 ;; We ignore the overflow flag for signed branch instructions.
12570 (define_insn "*jcc"
12571   [(set (pc)
12572         (if_then_else (match_operator 1 "ix86_comparison_operator"
12573                                       [(reg FLAGS_REG) (const_int 0)])
12574                       (label_ref (match_operand 0))
12575                       (pc)))]
12576   ""
12577   "%!%+j%C1\t%l0"
12578   [(set_attr "type" "ibr")
12579    (set_attr "modrm" "0")
12580    (set (attr "length")
12581         (if_then_else
12582           (and (ge (minus (match_dup 0) (pc))
12583                    (const_int -126))
12584                (lt (minus (match_dup 0) (pc))
12585                    (const_int 128)))
12586           (const_int 2)
12587           (const_int 6)))])
12589 ;; In general it is not safe to assume too much about CCmode registers,
12590 ;; so simplify-rtx stops when it sees a second one.  Under certain
12591 ;; conditions this is safe on x86, so help combine not create
12593 ;;      seta    %al
12594 ;;      testb   %al, %al
12595 ;;      je      Lfoo
12597 (define_split
12598   [(set (pc)
12599         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12600                                       [(reg FLAGS_REG) (const_int 0)])
12601                           (const_int 0))
12602                       (label_ref (match_operand 1))
12603                       (pc)))]
12604   ""
12605   [(set (pc)
12606         (if_then_else (match_dup 0)
12607                       (label_ref (match_dup 1))
12608                       (pc)))]
12610   operands[0] = shallow_copy_rtx (operands[0]);
12611   PUT_MODE (operands[0], VOIDmode);
12614 (define_split
12615   [(set (pc)
12616         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12617                                       [(reg FLAGS_REG) (const_int 0)])
12618                           (const_int 0))
12619                       (label_ref (match_operand 1))
12620                       (pc)))]
12621   ""
12622   [(set (pc)
12623         (if_then_else (match_dup 0)
12624                       (label_ref (match_dup 1))
12625                       (pc)))]
12627   operands[0] = shallow_copy_rtx (operands[0]);
12628   PUT_MODE (operands[0], VOIDmode);
12629   PUT_CODE (operands[0],
12630             ix86_reverse_condition (GET_CODE (operands[0]),
12631                                     GET_MODE (XEXP (operands[0], 0))));
12633   /* Make sure that (a) the CCmode we have for the flags is strong
12634      enough for the reversed compare or (b) we have a valid FP compare.  */
12635   if (! ix86_comparison_operator (operands[0], VOIDmode))
12636     FAIL;
12639 ;; Unconditional and other jump instructions
12641 (define_insn "jump"
12642   [(set (pc)
12643         (label_ref (match_operand 0)))]
12644   ""
12645   "%!jmp\t%l0"
12646   [(set_attr "type" "ibr")
12647    (set_attr "modrm" "0")
12648    (set (attr "length")
12649         (if_then_else
12650           (and (ge (minus (match_dup 0) (pc))
12651                    (const_int -126))
12652                (lt (minus (match_dup 0) (pc))
12653                    (const_int 128)))
12654           (const_int 2)
12655           (const_int 5)))])
12657 (define_expand "indirect_jump"
12658   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12659   ""
12661   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12662     operands[0] = convert_memory_address (word_mode, operands[0]);
12663   cfun->machine->has_local_indirect_jump = true;
12666 (define_insn "*indirect_jump"
12667   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12668   ""
12669   "* return ix86_output_indirect_jmp (operands[0]);"
12670   [(set (attr "type")
12671      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12672                                  != indirect_branch_keep)")
12673         (const_string "multi")
12674         (const_string "ibr")))
12675    (set_attr "length_immediate" "0")])
12677 (define_expand "tablejump"
12678   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12679               (use (label_ref (match_operand 1)))])]
12680   ""
12682   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12683      relative.  Convert the relative address to an absolute address.  */
12684   if (flag_pic)
12685     {
12686       rtx op0, op1;
12687       enum rtx_code code;
12689       /* We can't use @GOTOFF for text labels on VxWorks;
12690          see gotoff_operand.  */
12691       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12692         {
12693           code = PLUS;
12694           op0 = operands[0];
12695           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12696         }
12697       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12698         {
12699           code = PLUS;
12700           op0 = operands[0];
12701           op1 = pic_offset_table_rtx;
12702         }
12703       else
12704         {
12705           code = MINUS;
12706           op0 = pic_offset_table_rtx;
12707           op1 = operands[0];
12708         }
12710       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12711                                          OPTAB_DIRECT);
12712     }
12714   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12715     operands[0] = convert_memory_address (word_mode, operands[0]);
12716   cfun->machine->has_local_indirect_jump = true;
12719 (define_insn "*tablejump_1"
12720   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12721    (use (label_ref (match_operand 1)))]
12722   ""
12723   "* return ix86_output_indirect_jmp (operands[0]);"
12724   [(set (attr "type")
12725      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12726                                  != indirect_branch_keep)")
12727         (const_string "multi")
12728         (const_string "ibr")))
12729    (set_attr "length_immediate" "0")])
12731 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12733 (define_peephole2
12734   [(set (reg FLAGS_REG) (match_operand 0))
12735    (set (match_operand:QI 1 "register_operand")
12736         (match_operator:QI 2 "ix86_comparison_operator"
12737           [(reg FLAGS_REG) (const_int 0)]))
12738    (set (match_operand 3 "any_QIreg_operand")
12739         (zero_extend (match_dup 1)))]
12740   "(peep2_reg_dead_p (3, operands[1])
12741     || operands_match_p (operands[1], operands[3]))
12742    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12743    && peep2_regno_dead_p (0, FLAGS_REG)"
12744   [(set (match_dup 4) (match_dup 0))
12745    (set (strict_low_part (match_dup 5))
12746         (match_dup 2))]
12748   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12749   operands[5] = gen_lowpart (QImode, operands[3]);
12750   ix86_expand_clear (operands[3]);
12753 (define_peephole2
12754   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12755               (match_operand 4)])
12756    (set (match_operand:QI 1 "register_operand")
12757         (match_operator:QI 2 "ix86_comparison_operator"
12758           [(reg FLAGS_REG) (const_int 0)]))
12759    (set (match_operand 3 "any_QIreg_operand")
12760         (zero_extend (match_dup 1)))]
12761   "(peep2_reg_dead_p (3, operands[1])
12762     || operands_match_p (operands[1], operands[3]))
12763    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12764    && ! reg_overlap_mentioned_p (operands[3], operands[4])
12765    && ! reg_set_p (operands[3], operands[4])
12766    && peep2_regno_dead_p (0, FLAGS_REG)"
12767   [(parallel [(set (match_dup 5) (match_dup 0))
12768               (match_dup 4)])
12769    (set (strict_low_part (match_dup 6))
12770         (match_dup 2))]
12772   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12773   operands[6] = gen_lowpart (QImode, operands[3]);
12774   ix86_expand_clear (operands[3]);
12777 (define_peephole2
12778   [(set (reg FLAGS_REG) (match_operand 0))
12779    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12780               (match_operand 5)])
12781    (set (match_operand:QI 2 "register_operand")
12782         (match_operator:QI 3 "ix86_comparison_operator"
12783           [(reg FLAGS_REG) (const_int 0)]))
12784    (set (match_operand 4 "any_QIreg_operand")
12785         (zero_extend (match_dup 2)))]
12786   "(peep2_reg_dead_p (4, operands[2])
12787     || operands_match_p (operands[2], operands[4]))
12788    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12789    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12790    && ! reg_overlap_mentioned_p (operands[4], operands[5])
12791    && ! reg_set_p (operands[4], operands[5])
12792    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12793    && peep2_regno_dead_p (0, FLAGS_REG)"
12794   [(set (match_dup 6) (match_dup 0))
12795    (parallel [(set (match_dup 7) (match_dup 1))
12796               (match_dup 5)])
12797    (set (strict_low_part (match_dup 8))
12798         (match_dup 3))]
12800   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12801   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12802   operands[8] = gen_lowpart (QImode, operands[4]);
12803   ix86_expand_clear (operands[4]);
12806 ;; Similar, but match zero extend with andsi3.
12808 (define_peephole2
12809   [(set (reg FLAGS_REG) (match_operand 0))
12810    (set (match_operand:QI 1 "register_operand")
12811         (match_operator:QI 2 "ix86_comparison_operator"
12812           [(reg FLAGS_REG) (const_int 0)]))
12813    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12814                    (and:SI (match_dup 3) (const_int 255)))
12815               (clobber (reg:CC FLAGS_REG))])]
12816   "REGNO (operands[1]) == REGNO (operands[3])
12817    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12818    && peep2_regno_dead_p (0, FLAGS_REG)"
12819   [(set (match_dup 4) (match_dup 0))
12820    (set (strict_low_part (match_dup 5))
12821         (match_dup 2))]
12823   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12824   operands[5] = gen_lowpart (QImode, operands[3]);
12825   ix86_expand_clear (operands[3]);
12828 (define_peephole2
12829   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12830               (match_operand 4)])
12831    (set (match_operand:QI 1 "register_operand")
12832         (match_operator:QI 2 "ix86_comparison_operator"
12833           [(reg FLAGS_REG) (const_int 0)]))
12834    (parallel [(set (match_operand 3 "any_QIreg_operand")
12835                    (zero_extend (match_dup 1)))
12836               (clobber (reg:CC FLAGS_REG))])]
12837   "(peep2_reg_dead_p (3, operands[1])
12838     || operands_match_p (operands[1], operands[3]))
12839    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12840    && ! reg_overlap_mentioned_p (operands[3], operands[4])
12841    && ! reg_set_p (operands[3], operands[4])
12842    && peep2_regno_dead_p (0, FLAGS_REG)"
12843   [(parallel [(set (match_dup 5) (match_dup 0))
12844               (match_dup 4)])
12845    (set (strict_low_part (match_dup 6))
12846         (match_dup 2))]
12848   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12849   operands[6] = gen_lowpart (QImode, operands[3]);
12850   ix86_expand_clear (operands[3]);
12853 (define_peephole2
12854   [(set (reg FLAGS_REG) (match_operand 0))
12855    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12856               (match_operand 5)])
12857    (set (match_operand:QI 2 "register_operand")
12858         (match_operator:QI 3 "ix86_comparison_operator"
12859           [(reg FLAGS_REG) (const_int 0)]))
12860    (parallel [(set (match_operand 4 "any_QIreg_operand")
12861                    (zero_extend (match_dup 2)))
12862               (clobber (reg:CC FLAGS_REG))])]
12863   "(peep2_reg_dead_p (4, operands[2])
12864     || operands_match_p (operands[2], operands[4]))
12865    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12866    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12867    && ! reg_overlap_mentioned_p (operands[4], operands[5])
12868    && ! reg_set_p (operands[4], operands[5])
12869    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12870    && peep2_regno_dead_p (0, FLAGS_REG)"
12871   [(set (match_dup 6) (match_dup 0))
12872    (parallel [(set (match_dup 7) (match_dup 1))
12873               (match_dup 5)])
12874    (set (strict_low_part (match_dup 8))
12875         (match_dup 3))]
12877   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12878   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12879   operands[8] = gen_lowpart (QImode, operands[4]);
12880   ix86_expand_clear (operands[4]);
12883 ;; Call instructions.
12885 ;; The predicates normally associated with named expanders are not properly
12886 ;; checked for calls.  This is a bug in the generic code, but it isn't that
12887 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
12889 ;; P6 processors will jump to the address after the decrement when %esp
12890 ;; is used as a call operand, so they will execute return address as a code.
12891 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12893 ;; Register constraint for call instruction.
12894 (define_mode_attr c [(SI "l") (DI "r")])
12896 ;; Call subroutine returning no value.
12898 (define_expand "call"
12899   [(call (match_operand:QI 0)
12900          (match_operand 1))
12901    (use (match_operand 2))]
12902   ""
12904   ix86_expand_call (NULL, operands[0], operands[1],
12905                     operands[2], NULL, false);
12906   DONE;
12909 (define_expand "sibcall"
12910   [(call (match_operand:QI 0)
12911          (match_operand 1))
12912    (use (match_operand 2))]
12913   ""
12915   ix86_expand_call (NULL, operands[0], operands[1],
12916                     operands[2], NULL, true);
12917   DONE;
12920 (define_insn "*call"
12921   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12922          (match_operand 1))]
12923   "!SIBLING_CALL_P (insn)"
12924   "* return ix86_output_call_insn (insn, operands[0]);"
12925   [(set_attr "type" "call")])
12927 ;; This covers both call and sibcall since only GOT slot is allowed.
12928 (define_insn "*call_got_x32"
12929   [(call (mem:QI (zero_extend:DI
12930                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12931          (match_operand 1))]
12932   "TARGET_X32"
12934   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12935   return ix86_output_call_insn (insn, fnaddr);
12937   [(set_attr "type" "call")])
12939 ;; Since sibcall never returns, we can only use call-clobbered register
12940 ;; as GOT base.
12941 (define_insn "*sibcall_GOT_32"
12942   [(call (mem:QI
12943            (mem:SI (plus:SI
12944                      (match_operand:SI 0 "register_no_elim_operand" "U")
12945                      (match_operand:SI 1 "GOT32_symbol_operand"))))
12946          (match_operand 2))]
12947   "!TARGET_MACHO
12948   && !TARGET_64BIT
12949   && !TARGET_INDIRECT_BRANCH_REGISTER
12950   && SIBLING_CALL_P (insn)"
12952   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12953   fnaddr = gen_const_mem (SImode, fnaddr);
12954   return ix86_output_call_insn (insn, fnaddr);
12956   [(set_attr "type" "call")])
12958 (define_insn "*sibcall"
12959   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12960          (match_operand 1))]
12961   "SIBLING_CALL_P (insn)"
12962   "* return ix86_output_call_insn (insn, operands[0]);"
12963   [(set_attr "type" "call")])
12965 (define_insn "*sibcall_memory"
12966   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12967          (match_operand 1))
12968    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12969   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12970   "* return ix86_output_call_insn (insn, operands[0]);"
12971   [(set_attr "type" "call")])
12973 (define_peephole2
12974   [(set (match_operand:W 0 "register_operand")
12975         (match_operand:W 1 "memory_operand"))
12976    (call (mem:QI (match_dup 0))
12977          (match_operand 3))]
12978   "!TARGET_X32
12979    && !TARGET_INDIRECT_BRANCH_REGISTER
12980    && SIBLING_CALL_P (peep2_next_insn (1))
12981    && !reg_mentioned_p (operands[0],
12982                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12983   [(parallel [(call (mem:QI (match_dup 1))
12984                     (match_dup 3))
12985               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12987 (define_peephole2
12988   [(set (match_operand:W 0 "register_operand")
12989         (match_operand:W 1 "memory_operand"))
12990    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12991    (call (mem:QI (match_dup 0))
12992          (match_operand 3))]
12993   "!TARGET_X32
12994    && !TARGET_INDIRECT_BRANCH_REGISTER
12995    && SIBLING_CALL_P (peep2_next_insn (2))
12996    && !reg_mentioned_p (operands[0],
12997                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12998   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12999    (parallel [(call (mem:QI (match_dup 1))
13000                     (match_dup 3))
13001               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13003 (define_expand "call_pop"
13004   [(parallel [(call (match_operand:QI 0)
13005                     (match_operand:SI 1))
13006               (set (reg:SI SP_REG)
13007                    (plus:SI (reg:SI SP_REG)
13008                             (match_operand:SI 3)))])]
13009   "!TARGET_64BIT"
13011   ix86_expand_call (NULL, operands[0], operands[1],
13012                     operands[2], operands[3], false);
13013   DONE;
13016 (define_insn "*call_pop"
13017   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
13018          (match_operand 1))
13019    (set (reg:SI SP_REG)
13020         (plus:SI (reg:SI SP_REG)
13021                  (match_operand:SI 2 "immediate_operand" "i")))]
13022   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13023   "* return ix86_output_call_insn (insn, operands[0]);"
13024   [(set_attr "type" "call")])
13026 (define_insn "*sibcall_pop"
13027   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
13028          (match_operand 1))
13029    (set (reg:SI SP_REG)
13030         (plus:SI (reg:SI SP_REG)
13031                  (match_operand:SI 2 "immediate_operand" "i")))]
13032   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13033   "* return ix86_output_call_insn (insn, operands[0]);"
13034   [(set_attr "type" "call")])
13036 (define_insn "*sibcall_pop_memory"
13037   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
13038          (match_operand 1))
13039    (set (reg:SI SP_REG)
13040         (plus:SI (reg:SI SP_REG)
13041                  (match_operand:SI 2 "immediate_operand" "i")))
13042    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13043   "!TARGET_64BIT"
13044   "* return ix86_output_call_insn (insn, operands[0]);"
13045   [(set_attr "type" "call")])
13047 (define_peephole2
13048   [(set (match_operand:SI 0 "register_operand")
13049         (match_operand:SI 1 "memory_operand"))
13050    (parallel [(call (mem:QI (match_dup 0))
13051                     (match_operand 3))
13052               (set (reg:SI SP_REG)
13053                    (plus:SI (reg:SI SP_REG)
13054                             (match_operand:SI 4 "immediate_operand")))])]
13055   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13056    && !reg_mentioned_p (operands[0],
13057                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13058   [(parallel [(call (mem:QI (match_dup 1))
13059                     (match_dup 3))
13060               (set (reg:SI SP_REG)
13061                    (plus:SI (reg:SI SP_REG)
13062                             (match_dup 4)))
13063               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13065 (define_peephole2
13066   [(set (match_operand:SI 0 "register_operand")
13067         (match_operand:SI 1 "memory_operand"))
13068    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13069    (parallel [(call (mem:QI (match_dup 0))
13070                     (match_operand 3))
13071               (set (reg:SI SP_REG)
13072                    (plus:SI (reg:SI SP_REG)
13073                             (match_operand:SI 4 "immediate_operand")))])]
13074   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13075    && !reg_mentioned_p (operands[0],
13076                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13077   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13078    (parallel [(call (mem:QI (match_dup 1))
13079                     (match_dup 3))
13080               (set (reg:SI SP_REG)
13081                    (plus:SI (reg:SI SP_REG)
13082                             (match_dup 4)))
13083               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13085 ;; Combining simple memory jump instruction
13087 (define_peephole2
13088   [(set (match_operand:W 0 "register_operand")
13089         (match_operand:W 1 "memory_operand"))
13090    (set (pc) (match_dup 0))]
13091   "!TARGET_X32
13092    && !TARGET_INDIRECT_BRANCH_REGISTER
13093    && peep2_reg_dead_p (2, operands[0])"
13094   [(set (pc) (match_dup 1))])
13096 ;; Call subroutine, returning value in operand 0
13098 (define_expand "call_value"
13099   [(set (match_operand 0)
13100         (call (match_operand:QI 1)
13101               (match_operand 2)))
13102    (use (match_operand 3))]
13103   ""
13105   ix86_expand_call (operands[0], operands[1], operands[2],
13106                     operands[3], NULL, false);
13107   DONE;
13110 (define_expand "sibcall_value"
13111   [(set (match_operand 0)
13112         (call (match_operand:QI 1)
13113               (match_operand 2)))
13114    (use (match_operand 3))]
13115   ""
13117   ix86_expand_call (operands[0], operands[1], operands[2],
13118                     operands[3], NULL, true);
13119   DONE;
13122 (define_insn "*call_value"
13123   [(set (match_operand 0)
13124         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13125               (match_operand 2)))]
13126   "!SIBLING_CALL_P (insn)"
13127   "* return ix86_output_call_insn (insn, operands[1]);"
13128   [(set_attr "type" "callv")])
13130 ;; This covers both call and sibcall since only GOT slot is allowed.
13131 (define_insn "*call_value_got_x32"
13132   [(set (match_operand 0)
13133         (call (mem:QI
13134                 (zero_extend:DI
13135                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13136               (match_operand 2)))]
13137   "TARGET_X32"
13139   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13140   return ix86_output_call_insn (insn, fnaddr);
13142   [(set_attr "type" "callv")])
13144 ;; Since sibcall never returns, we can only use call-clobbered register
13145 ;; as GOT base.
13146 (define_insn "*sibcall_value_GOT_32"
13147   [(set (match_operand 0)
13148         (call (mem:QI
13149                 (mem:SI (plus:SI
13150                           (match_operand:SI 1 "register_no_elim_operand" "U")
13151                           (match_operand:SI 2 "GOT32_symbol_operand"))))
13152          (match_operand 3)))]
13153   "!TARGET_MACHO
13154    && !TARGET_64BIT
13155    && !TARGET_INDIRECT_BRANCH_REGISTER
13156    && SIBLING_CALL_P (insn)"
13158   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13159   fnaddr = gen_const_mem (SImode, fnaddr);
13160   return ix86_output_call_insn (insn, fnaddr);
13162   [(set_attr "type" "callv")])
13164 (define_insn "*sibcall_value"
13165   [(set (match_operand 0)
13166         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13167               (match_operand 2)))]
13168   "SIBLING_CALL_P (insn)"
13169   "* return ix86_output_call_insn (insn, operands[1]);"
13170   [(set_attr "type" "callv")])
13172 (define_insn "*sibcall_value_memory"
13173   [(set (match_operand 0)
13174         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13175               (match_operand 2)))
13176    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13177   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13178   "* return ix86_output_call_insn (insn, operands[1]);"
13179   [(set_attr "type" "callv")])
13181 (define_peephole2
13182   [(set (match_operand:W 0 "register_operand")
13183         (match_operand:W 1 "memory_operand"))
13184    (set (match_operand 2)
13185    (call (mem:QI (match_dup 0))
13186                  (match_operand 3)))]
13187   "!TARGET_X32
13188    && !TARGET_INDIRECT_BRANCH_REGISTER
13189    && SIBLING_CALL_P (peep2_next_insn (1))
13190    && !reg_mentioned_p (operands[0],
13191                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13192   [(parallel [(set (match_dup 2)
13193                    (call (mem:QI (match_dup 1))
13194                          (match_dup 3)))
13195               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13197 (define_peephole2
13198   [(set (match_operand:W 0 "register_operand")
13199         (match_operand:W 1 "memory_operand"))
13200    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13201    (set (match_operand 2)
13202         (call (mem:QI (match_dup 0))
13203               (match_operand 3)))]
13204   "!TARGET_X32
13205    && !TARGET_INDIRECT_BRANCH_REGISTER
13206    && SIBLING_CALL_P (peep2_next_insn (2))
13207    && !reg_mentioned_p (operands[0],
13208                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13209   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13210    (parallel [(set (match_dup 2)
13211                    (call (mem:QI (match_dup 1))
13212                          (match_dup 3)))
13213               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13215 (define_expand "call_value_pop"
13216   [(parallel [(set (match_operand 0)
13217                    (call (match_operand:QI 1)
13218                          (match_operand:SI 2)))
13219               (set (reg:SI SP_REG)
13220                    (plus:SI (reg:SI SP_REG)
13221                             (match_operand:SI 4)))])]
13222   "!TARGET_64BIT"
13224   ix86_expand_call (operands[0], operands[1], operands[2],
13225                     operands[3], operands[4], false);
13226   DONE;
13229 (define_insn "*call_value_pop"
13230   [(set (match_operand 0)
13231         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13232               (match_operand 2)))
13233    (set (reg:SI SP_REG)
13234         (plus:SI (reg:SI SP_REG)
13235                  (match_operand:SI 3 "immediate_operand" "i")))]
13236   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13237   "* return ix86_output_call_insn (insn, operands[1]);"
13238   [(set_attr "type" "callv")])
13240 (define_insn "*sibcall_value_pop"
13241   [(set (match_operand 0)
13242         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13243               (match_operand 2)))
13244    (set (reg:SI SP_REG)
13245         (plus:SI (reg:SI SP_REG)
13246                  (match_operand:SI 3 "immediate_operand" "i")))]
13247   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13248   "* return ix86_output_call_insn (insn, operands[1]);"
13249   [(set_attr "type" "callv")])
13251 (define_insn "*sibcall_value_pop_memory"
13252   [(set (match_operand 0)
13253         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13254               (match_operand 2)))
13255    (set (reg:SI SP_REG)
13256         (plus:SI (reg:SI SP_REG)
13257                  (match_operand:SI 3 "immediate_operand" "i")))
13258    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13259   "!TARGET_64BIT"
13260   "* return ix86_output_call_insn (insn, operands[1]);"
13261   [(set_attr "type" "callv")])
13263 (define_peephole2
13264   [(set (match_operand:SI 0 "register_operand")
13265         (match_operand:SI 1 "memory_operand"))
13266    (parallel [(set (match_operand 2)
13267                    (call (mem:QI (match_dup 0))
13268                          (match_operand 3)))
13269               (set (reg:SI SP_REG)
13270                    (plus:SI (reg:SI SP_REG)
13271                             (match_operand:SI 4 "immediate_operand")))])]
13272   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13273    && !reg_mentioned_p (operands[0],
13274                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13275   [(parallel [(set (match_dup 2)
13276                    (call (mem:QI (match_dup 1))
13277                          (match_dup 3)))
13278               (set (reg:SI SP_REG)
13279                    (plus:SI (reg:SI SP_REG)
13280                             (match_dup 4)))
13281               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13283 (define_peephole2
13284   [(set (match_operand:SI 0 "register_operand")
13285         (match_operand:SI 1 "memory_operand"))
13286    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13287    (parallel [(set (match_operand 2)
13288                    (call (mem:QI (match_dup 0))
13289                          (match_operand 3)))
13290               (set (reg:SI SP_REG)
13291                    (plus:SI (reg:SI SP_REG)
13292                             (match_operand:SI 4 "immediate_operand")))])]
13293   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13294    && !reg_mentioned_p (operands[0],
13295                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13296   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13297    (parallel [(set (match_dup 2)
13298                    (call (mem:QI (match_dup 1))
13299                          (match_dup 3)))
13300               (set (reg:SI SP_REG)
13301                    (plus:SI (reg:SI SP_REG)
13302                             (match_dup 4)))
13303               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13305 ;; Call subroutine returning any type.
13307 (define_expand "untyped_call"
13308   [(parallel [(call (match_operand 0)
13309                     (const_int 0))
13310               (match_operand 1)
13311               (match_operand 2)])]
13312   ""
13314   int i;
13316   /* In order to give reg-stack an easier job in validating two
13317      coprocessor registers as containing a possible return value,
13318      simply pretend the untyped call returns a complex long double
13319      value. 
13321      We can't use SSE_REGPARM_MAX here since callee is unprototyped
13322      and should have the default ABI.  */
13324   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13325                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13326                     operands[0], const0_rtx,
13327                     GEN_INT ((TARGET_64BIT
13328                               ? (ix86_abi == SYSV_ABI
13329                                  ? X86_64_SSE_REGPARM_MAX
13330                                  : X86_64_MS_SSE_REGPARM_MAX)
13331                               : X86_32_SSE_REGPARM_MAX)
13332                              - 1),
13333                     NULL, false);
13335   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13336     {
13337       rtx set = XVECEXP (operands[2], 0, i);
13338       emit_move_insn (SET_DEST (set), SET_SRC (set));
13339     }
13341   /* The optimizer does not know that the call sets the function value
13342      registers we stored in the result block.  We avoid problems by
13343      claiming that all hard registers are used and clobbered at this
13344      point.  */
13345   emit_insn (gen_blockage ());
13347   DONE;
13350 ;; Prologue and epilogue instructions
13352 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13353 ;; all of memory.  This blocks insns from being moved across this point.
13355 (define_insn "blockage"
13356   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13357   ""
13358   ""
13359   [(set_attr "length" "0")])
13361 ;; Do not schedule instructions accessing memory across this point.
13363 (define_expand "memory_blockage"
13364   [(set (match_dup 0)
13365         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13366   ""
13368   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13369   MEM_VOLATILE_P (operands[0]) = 1;
13372 (define_insn "*memory_blockage"
13373   [(set (match_operand:BLK 0)
13374         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13375   ""
13376   ""
13377   [(set_attr "length" "0")])
13379 ;; As USE insns aren't meaningful after reload, this is used instead
13380 ;; to prevent deleting instructions setting registers for PIC code
13381 (define_insn "prologue_use"
13382   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13383   ""
13384   ""
13385   [(set_attr "length" "0")])
13387 ;; Insn emitted into the body of a function to return from a function.
13388 ;; This is only done if the function's epilogue is known to be simple.
13389 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13391 (define_expand "return"
13392   [(simple_return)]
13393   "ix86_can_use_return_insn_p ()"
13395   if (crtl->args.pops_args)
13396     {
13397       rtx popc = GEN_INT (crtl->args.pops_args);
13398       emit_jump_insn (gen_simple_return_pop_internal (popc));
13399       DONE;
13400     }
13403 ;; We need to disable this for TARGET_SEH, as otherwise
13404 ;; shrink-wrapped prologue gets enabled too.  This might exceed
13405 ;; the maximum size of prologue in unwind information.
13406 ;; Also disallow shrink-wrapping if using stack slot to pass the
13407 ;; static chain pointer - the first instruction has to be pushl %esi
13408 ;; and it can't be moved around, as we use alternate entry points
13409 ;; in that case.
13411 (define_expand "simple_return"
13412   [(simple_return)]
13413   "!TARGET_SEH && !ix86_static_chain_on_stack"
13415   if (crtl->args.pops_args)
13416     {
13417       rtx popc = GEN_INT (crtl->args.pops_args);
13418       emit_jump_insn (gen_simple_return_pop_internal (popc));
13419       DONE;
13420     }
13423 (define_insn "simple_return_internal"
13424   [(simple_return)]
13425   "reload_completed"
13426   "* return ix86_output_function_return (false);"
13427   [(set_attr "length" "1")
13428    (set_attr "atom_unit" "jeu")
13429    (set_attr "length_immediate" "0")
13430    (set_attr "modrm" "0")])
13432 (define_insn "interrupt_return"
13433   [(simple_return)
13434    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13435   "reload_completed"
13437   return TARGET_64BIT ? "iretq" : "iret";
13440 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13441 ;; instruction Athlon and K8 have.
13443 (define_insn "simple_return_internal_long"
13444   [(simple_return)
13445    (unspec [(const_int 0)] UNSPEC_REP)]
13446   "reload_completed"
13447   "* return ix86_output_function_return (true);"
13448   [(set_attr "length" "2")
13449    (set_attr "atom_unit" "jeu")
13450    (set_attr "length_immediate" "0")
13451    (set_attr "prefix_rep" "1")
13452    (set_attr "modrm" "0")])
13454 (define_insn_and_split "simple_return_pop_internal"
13455   [(simple_return)
13456    (use (match_operand:SI 0 "const_int_operand"))]
13457   "reload_completed"
13458   "%!ret\t%0"
13459   "&& cfun->machine->function_return_type != indirect_branch_keep"
13460   [(const_int 0)]
13461   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13462   [(set_attr "length" "3")
13463    (set_attr "atom_unit" "jeu")
13464    (set_attr "length_immediate" "2")
13465    (set_attr "modrm" "0")])
13467 (define_expand "simple_return_indirect_internal"
13468   [(parallel
13469      [(simple_return)
13470       (use (match_operand 0 "register_operand"))])])
13472 (define_insn "*simple_return_indirect_internal<mode>"
13473   [(simple_return)
13474    (use (match_operand:W 0 "register_operand" "r"))]
13475   "reload_completed"
13476   "* return ix86_output_indirect_function_return (operands[0]);"
13477   [(set (attr "type")
13478      (if_then_else (match_test "(cfun->machine->indirect_branch_type
13479                                  != indirect_branch_keep)")
13480         (const_string "multi")
13481         (const_string "ibr")))
13482    (set_attr "length_immediate" "0")])
13484 (define_insn "nop"
13485   [(const_int 0)]
13486   ""
13487   "nop"
13488   [(set_attr "length" "1")
13489    (set_attr "length_immediate" "0")
13490    (set_attr "modrm" "0")])
13492 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
13493 (define_insn "nops"
13494   [(unspec_volatile [(match_operand 0 "const_int_operand")]
13495                     UNSPECV_NOPS)]
13496   "reload_completed"
13498   int num = INTVAL (operands[0]);
13500   gcc_assert (IN_RANGE (num, 1, 8));
13502   while (num--)
13503     fputs ("\tnop\n", asm_out_file);
13505   return "";
13507   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13508    (set_attr "length_immediate" "0")
13509    (set_attr "modrm" "0")])
13511 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13512 ;; branch prediction penalty for the third jump in a 16-byte
13513 ;; block on K8.
13515 (define_insn "pad"
13516   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13517   ""
13519 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13520   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13521 #else
13522   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13523      The align insn is used to avoid 3 jump instructions in the row to improve
13524      branch prediction and the benefits hardly outweigh the cost of extra 8
13525      nops on the average inserted by full alignment pseudo operation.  */
13526 #endif
13527   return "";
13529   [(set_attr "length" "16")])
13531 (define_expand "prologue"
13532   [(const_int 0)]
13533   ""
13534   "ix86_expand_prologue (); DONE;")
13536 (define_expand "set_got"
13537   [(parallel
13538      [(set (match_operand:SI 0 "register_operand")
13539            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13540       (clobber (reg:CC FLAGS_REG))])]
13541   "!TARGET_64BIT"
13543   if (flag_pic && !TARGET_VXWORKS_RTP)
13544     ix86_pc_thunk_call_expanded = true;
13547 (define_insn "*set_got"
13548   [(set (match_operand:SI 0 "register_operand" "=r")
13549         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13550    (clobber (reg:CC FLAGS_REG))]
13551   "!TARGET_64BIT"
13552   "* return output_set_got (operands[0], NULL_RTX);"
13553   [(set_attr "type" "multi")
13554    (set_attr "length" "12")])
13556 (define_expand "set_got_labelled"
13557   [(parallel
13558      [(set (match_operand:SI 0 "register_operand")
13559            (unspec:SI [(label_ref (match_operand 1))]
13560                       UNSPEC_SET_GOT))
13561       (clobber (reg:CC FLAGS_REG))])]
13562   "!TARGET_64BIT"
13564   if (flag_pic && !TARGET_VXWORKS_RTP)
13565     ix86_pc_thunk_call_expanded = true;
13568 (define_insn "*set_got_labelled"
13569   [(set (match_operand:SI 0 "register_operand" "=r")
13570         (unspec:SI [(label_ref (match_operand 1))]
13571          UNSPEC_SET_GOT))
13572    (clobber (reg:CC FLAGS_REG))]
13573   "!TARGET_64BIT"
13574   "* return output_set_got (operands[0], operands[1]);"
13575   [(set_attr "type" "multi")
13576    (set_attr "length" "12")])
13578 (define_insn "set_got_rex64"
13579   [(set (match_operand:DI 0 "register_operand" "=r")
13580         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13581   "TARGET_64BIT"
13582   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13583   [(set_attr "type" "lea")
13584    (set_attr "length_address" "4")
13585    (set_attr "modrm_class" "unknown")
13586    (set_attr "mode" "DI")])
13588 (define_insn "set_rip_rex64"
13589   [(set (match_operand:DI 0 "register_operand" "=r")
13590         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13591   "TARGET_64BIT"
13592   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13593   [(set_attr "type" "lea")
13594    (set_attr "length_address" "4")
13595    (set_attr "mode" "DI")])
13597 (define_insn "set_got_offset_rex64"
13598   [(set (match_operand:DI 0 "register_operand" "=r")
13599         (unspec:DI
13600           [(label_ref (match_operand 1))]
13601           UNSPEC_SET_GOT_OFFSET))]
13602   "TARGET_LP64"
13603   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13604   [(set_attr "type" "imov")
13605    (set_attr "length_immediate" "0")
13606    (set_attr "length_address" "8")
13607    (set_attr "mode" "DI")])
13609 (define_expand "epilogue"
13610   [(const_int 0)]
13611   ""
13612   "ix86_expand_epilogue (1); DONE;")
13614 (define_expand "sibcall_epilogue"
13615   [(const_int 0)]
13616   ""
13617   "ix86_expand_epilogue (0); DONE;")
13619 (define_expand "eh_return"
13620   [(use (match_operand 0 "register_operand"))]
13621   ""
13623   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13625   /* Tricky bit: we write the address of the handler to which we will
13626      be returning into someone else's stack frame, one word below the
13627      stack address we wish to restore.  */
13628   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13629   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13630   tmp = gen_rtx_MEM (Pmode, tmp);
13631   emit_move_insn (tmp, ra);
13633   emit_jump_insn (gen_eh_return_internal ());
13634   emit_barrier ();
13635   DONE;
13638 (define_insn_and_split "eh_return_internal"
13639   [(eh_return)]
13640   ""
13641   "#"
13642   "epilogue_completed"
13643   [(const_int 0)]
13644   "ix86_expand_epilogue (2); DONE;")
13646 (define_insn "leave"
13647   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13648    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13649    (clobber (mem:BLK (scratch)))]
13650   "!TARGET_64BIT"
13651   "leave"
13652   [(set_attr "type" "leave")])
13654 (define_insn "leave_rex64"
13655   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13656    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13657    (clobber (mem:BLK (scratch)))]
13658   "TARGET_64BIT"
13659   "leave"
13660   [(set_attr "type" "leave")])
13662 ;; Handle -fsplit-stack.
13664 (define_expand "split_stack_prologue"
13665   [(const_int 0)]
13666   ""
13668   ix86_expand_split_stack_prologue ();
13669   DONE;
13672 ;; In order to support the call/return predictor, we use a return
13673 ;; instruction which the middle-end doesn't see.
13674 (define_insn "split_stack_return"
13675   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13676                      UNSPECV_SPLIT_STACK_RETURN)]
13677   ""
13679   if (operands[0] == const0_rtx)
13680     return "ret";
13681   else
13682     return "ret\t%0";
13684   [(set_attr "atom_unit" "jeu")
13685    (set_attr "modrm" "0")
13686    (set (attr "length")
13687         (if_then_else (match_operand:SI 0 "const0_operand")
13688                       (const_int 1)
13689                       (const_int 3)))
13690    (set (attr "length_immediate")
13691         (if_then_else (match_operand:SI 0 "const0_operand")
13692                       (const_int 0)
13693                       (const_int 2)))])
13695 ;; If there are operand 0 bytes available on the stack, jump to
13696 ;; operand 1.
13698 (define_expand "split_stack_space_check"
13699   [(set (pc) (if_then_else
13700               (ltu (minus (reg SP_REG)
13701                           (match_operand 0 "register_operand"))
13702                    (match_dup 2))
13703               (label_ref (match_operand 1))
13704               (pc)))]
13705   ""
13707   rtx reg = gen_reg_rtx (Pmode);
13709   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13711   operands[2] = ix86_split_stack_guard ();
13712   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13714   DONE;
13717 ;; Bit manipulation instructions.
13719 (define_expand "ffs<mode>2"
13720   [(set (match_dup 2) (const_int -1))
13721    (parallel [(set (match_dup 3) (match_dup 4))
13722               (set (match_operand:SWI48 0 "register_operand")
13723                    (ctz:SWI48
13724                      (match_operand:SWI48 1 "nonimmediate_operand")))])
13725    (set (match_dup 0) (if_then_else:SWI48
13726                         (eq (match_dup 3) (const_int 0))
13727                         (match_dup 2)
13728                         (match_dup 0)))
13729    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13730               (clobber (reg:CC FLAGS_REG))])]
13731   ""
13733   machine_mode flags_mode;
13735   if (<MODE>mode == SImode && !TARGET_CMOVE)
13736     {
13737       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13738       DONE;
13739     }
13741   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13743   operands[2] = gen_reg_rtx (<MODE>mode);
13744   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13745   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13748 (define_insn_and_split "ffssi2_no_cmove"
13749   [(set (match_operand:SI 0 "register_operand" "=r")
13750         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13751    (clobber (match_scratch:SI 2 "=&q"))
13752    (clobber (reg:CC FLAGS_REG))]
13753   "!TARGET_CMOVE"
13754   "#"
13755   "&& reload_completed"
13756   [(parallel [(set (match_dup 4) (match_dup 5))
13757               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13758    (set (strict_low_part (match_dup 3))
13759         (eq:QI (match_dup 4) (const_int 0)))
13760    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13761               (clobber (reg:CC FLAGS_REG))])
13762    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13763               (clobber (reg:CC FLAGS_REG))])
13764    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13765               (clobber (reg:CC FLAGS_REG))])]
13767   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13769   operands[3] = gen_lowpart (QImode, operands[2]);
13770   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13771   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13773   ix86_expand_clear (operands[2]);
13776 (define_insn_and_split "*tzcnt<mode>_1"
13777   [(set (reg:CCC FLAGS_REG)
13778         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13779                      (const_int 0)))
13780    (set (match_operand:SWI48 0 "register_operand" "=r")
13781         (ctz:SWI48 (match_dup 1)))]
13782   "TARGET_BMI"
13783   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13784   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13785    && optimize_function_for_speed_p (cfun)
13786    && !reg_mentioned_p (operands[0], operands[1])"
13787   [(parallel
13788     [(set (reg:CCC FLAGS_REG)
13789           (compare:CCC (match_dup 1) (const_int 0)))
13790      (set (match_dup 0)
13791           (ctz:SWI48 (match_dup 1)))
13792      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13793   "ix86_expand_clear (operands[0]);"
13794   [(set_attr "type" "alu1")
13795    (set_attr "prefix_0f" "1")
13796    (set_attr "prefix_rep" "1")
13797    (set_attr "btver2_decode" "double")
13798    (set_attr "mode" "<MODE>")])
13800 ; False dependency happens when destination is only updated by tzcnt,
13801 ; lzcnt or popcnt.  There is no false dependency when destination is
13802 ; also used in source.
13803 (define_insn "*tzcnt<mode>_1_falsedep"
13804   [(set (reg:CCC FLAGS_REG)
13805         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13806                      (const_int 0)))
13807    (set (match_operand:SWI48 0 "register_operand" "=r")
13808         (ctz:SWI48 (match_dup 1)))
13809    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13810            UNSPEC_INSN_FALSE_DEP)]
13811   "TARGET_BMI"
13812   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13813   [(set_attr "type" "alu1")
13814    (set_attr "prefix_0f" "1")
13815    (set_attr "prefix_rep" "1")
13816    (set_attr "btver2_decode" "double")
13817    (set_attr "mode" "<MODE>")])
13819 (define_insn "*bsf<mode>_1"
13820   [(set (reg:CCZ FLAGS_REG)
13821         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13822                      (const_int 0)))
13823    (set (match_operand:SWI48 0 "register_operand" "=r")
13824         (ctz:SWI48 (match_dup 1)))]
13825   ""
13826   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13827   [(set_attr "type" "alu1")
13828    (set_attr "prefix_0f" "1")
13829    (set_attr "btver2_decode" "double")
13830    (set_attr "znver1_decode" "vector")
13831    (set_attr "mode" "<MODE>")])
13833 (define_insn_and_split "ctz<mode>2"
13834   [(set (match_operand:SWI48 0 "register_operand" "=r")
13835         (ctz:SWI48
13836           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13837    (clobber (reg:CC FLAGS_REG))]
13838   ""
13840   if (TARGET_BMI)
13841     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13842   else if (optimize_function_for_size_p (cfun))
13843     ;
13844   else if (TARGET_GENERIC)
13845     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13846     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13848   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13850   "(TARGET_BMI || TARGET_GENERIC)
13851    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13852    && optimize_function_for_speed_p (cfun)
13853    && !reg_mentioned_p (operands[0], operands[1])"
13854   [(parallel
13855     [(set (match_dup 0)
13856           (ctz:SWI48 (match_dup 1)))
13857      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13858      (clobber (reg:CC FLAGS_REG))])]
13859   "ix86_expand_clear (operands[0]);"
13860   [(set_attr "type" "alu1")
13861    (set_attr "prefix_0f" "1")
13862    (set (attr "prefix_rep")
13863      (if_then_else
13864        (ior (match_test "TARGET_BMI")
13865             (and (not (match_test "optimize_function_for_size_p (cfun)"))
13866                  (match_test "TARGET_GENERIC")))
13867        (const_string "1")
13868        (const_string "0")))
13869    (set_attr "mode" "<MODE>")])
13871 ; False dependency happens when destination is only updated by tzcnt,
13872 ; lzcnt or popcnt.  There is no false dependency when destination is
13873 ; also used in source.
13874 (define_insn "*ctz<mode>2_falsedep"
13875   [(set (match_operand:SWI48 0 "register_operand" "=r")
13876         (ctz:SWI48
13877           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13878    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13879            UNSPEC_INSN_FALSE_DEP)
13880    (clobber (reg:CC FLAGS_REG))]
13881   ""
13883   if (TARGET_BMI)
13884     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13885   else if (TARGET_GENERIC)
13886     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13887     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13888   else
13889     gcc_unreachable ();
13891   [(set_attr "type" "alu1")
13892    (set_attr "prefix_0f" "1")
13893    (set_attr "prefix_rep" "1")
13894    (set_attr "mode" "<MODE>")])
13896 (define_insn "bsr_rex64"
13897   [(set (match_operand:DI 0 "register_operand" "=r")
13898         (minus:DI (const_int 63)
13899                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13900    (clobber (reg:CC FLAGS_REG))]
13901   "TARGET_64BIT"
13902   "bsr{q}\t{%1, %0|%0, %1}"
13903   [(set_attr "type" "alu1")
13904    (set_attr "prefix_0f" "1")
13905    (set_attr "znver1_decode" "vector")
13906    (set_attr "mode" "DI")])
13908 (define_insn "bsr"
13909   [(set (match_operand:SI 0 "register_operand" "=r")
13910         (minus:SI (const_int 31)
13911                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13912    (clobber (reg:CC FLAGS_REG))]
13913   ""
13914   "bsr{l}\t{%1, %0|%0, %1}"
13915   [(set_attr "type" "alu1")
13916    (set_attr "prefix_0f" "1")
13917    (set_attr "znver1_decode" "vector")
13918    (set_attr "mode" "SI")])
13920 (define_insn "*bsrhi"
13921   [(set (match_operand:HI 0 "register_operand" "=r")
13922         (minus:HI (const_int 15)
13923                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13924    (clobber (reg:CC FLAGS_REG))]
13925   ""
13926   "bsr{w}\t{%1, %0|%0, %1}"
13927   [(set_attr "type" "alu1")
13928    (set_attr "prefix_0f" "1")
13929    (set_attr "znver1_decode" "vector")
13930    (set_attr "mode" "HI")])
13932 (define_expand "clz<mode>2"
13933   [(parallel
13934      [(set (match_operand:SWI48 0 "register_operand")
13935            (minus:SWI48
13936              (match_dup 2)
13937              (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13938       (clobber (reg:CC FLAGS_REG))])
13939    (parallel
13940      [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13941       (clobber (reg:CC FLAGS_REG))])]
13942   ""
13944   if (TARGET_LZCNT)
13945     {
13946       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13947       DONE;
13948     }
13949   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13952 (define_insn_and_split "clz<mode>2_lzcnt"
13953   [(set (match_operand:SWI48 0 "register_operand" "=r")
13954         (clz:SWI48
13955           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13956    (clobber (reg:CC FLAGS_REG))]
13957   "TARGET_LZCNT"
13958   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13959   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13960    && optimize_function_for_speed_p (cfun)
13961    && !reg_mentioned_p (operands[0], operands[1])"
13962   [(parallel
13963     [(set (match_dup 0)
13964           (clz:SWI48 (match_dup 1)))
13965      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13966      (clobber (reg:CC FLAGS_REG))])]
13967   "ix86_expand_clear (operands[0]);"
13968   [(set_attr "prefix_rep" "1")
13969    (set_attr "type" "bitmanip")
13970    (set_attr "mode" "<MODE>")])
13972 ; False dependency happens when destination is only updated by tzcnt,
13973 ; lzcnt or popcnt.  There is no false dependency when destination is
13974 ; also used in source.
13975 (define_insn "*clz<mode>2_lzcnt_falsedep"
13976   [(set (match_operand:SWI48 0 "register_operand" "=r")
13977         (clz:SWI48
13978           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13979    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13980            UNSPEC_INSN_FALSE_DEP)
13981    (clobber (reg:CC FLAGS_REG))]
13982   "TARGET_LZCNT"
13983   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13984   [(set_attr "prefix_rep" "1")
13985    (set_attr "type" "bitmanip")
13986    (set_attr "mode" "<MODE>")])
13988 (define_int_iterator LT_ZCNT
13989         [(UNSPEC_TZCNT "TARGET_BMI")
13990          (UNSPEC_LZCNT "TARGET_LZCNT")])
13992 (define_int_attr lt_zcnt
13993         [(UNSPEC_TZCNT "tzcnt")
13994          (UNSPEC_LZCNT "lzcnt")])
13996 (define_int_attr lt_zcnt_type
13997         [(UNSPEC_TZCNT "alu1")
13998          (UNSPEC_LZCNT "bitmanip")])
14000 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
14001 ;; provides operand size as output when source operand is zero. 
14003 (define_insn_and_split "<lt_zcnt>_<mode>"
14004   [(set (match_operand:SWI48 0 "register_operand" "=r")
14005         (unspec:SWI48
14006           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14007    (clobber (reg:CC FLAGS_REG))]
14008   ""
14009   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14010   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14011    && optimize_function_for_speed_p (cfun)
14012    && !reg_mentioned_p (operands[0], operands[1])"
14013   [(parallel
14014     [(set (match_dup 0)
14015           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
14016      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14017      (clobber (reg:CC FLAGS_REG))])]
14018   "ix86_expand_clear (operands[0]);"
14019   [(set_attr "type" "<lt_zcnt_type>")
14020    (set_attr "prefix_0f" "1")
14021    (set_attr "prefix_rep" "1")
14022    (set_attr "mode" "<MODE>")])
14024 ; False dependency happens when destination is only updated by tzcnt,
14025 ; lzcnt or popcnt.  There is no false dependency when destination is
14026 ; also used in source.
14027 (define_insn "*<lt_zcnt>_<mode>_falsedep"
14028   [(set (match_operand:SWI48 0 "register_operand" "=r")
14029         (unspec:SWI48
14030           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14031    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14032            UNSPEC_INSN_FALSE_DEP)
14033    (clobber (reg:CC FLAGS_REG))]
14034   ""
14035   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14036   [(set_attr "type" "<lt_zcnt_type>")
14037    (set_attr "prefix_0f" "1")
14038    (set_attr "prefix_rep" "1")
14039    (set_attr "mode" "<MODE>")])
14041 (define_insn "<lt_zcnt>_hi"
14042   [(set (match_operand:HI 0 "register_operand" "=r")
14043         (unspec:HI
14044           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14045    (clobber (reg:CC FLAGS_REG))]
14046   ""
14047   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
14048   [(set_attr "type" "<lt_zcnt_type>")
14049    (set_attr "prefix_0f" "1")
14050    (set_attr "prefix_rep" "1")
14051    (set_attr "mode" "HI")])
14053 ;; BMI instructions.
14055 (define_insn "bmi_bextr_<mode>"
14056   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
14057         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14058                        (match_operand:SWI48 2 "register_operand" "r,r")]
14059                       UNSPEC_BEXTR))
14060    (clobber (reg:CC FLAGS_REG))]
14061   "TARGET_BMI"
14062   "bextr\t{%2, %1, %0|%0, %1, %2}"
14063   [(set_attr "type" "bitmanip")
14064    (set_attr "btver2_decode" "direct, double")
14065    (set_attr "mode" "<MODE>")])
14067 (define_insn "*bmi_bextr_<mode>_ccz"
14068   [(set (reg:CCZ FLAGS_REG)
14069         (compare:CCZ
14070           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14071                          (match_operand:SWI48 2 "register_operand" "r,r")]
14072                         UNSPEC_BEXTR)
14073           (const_int 0)))
14074    (clobber (match_scratch:SWI48 0 "=r,r"))]
14075   "TARGET_BMI"
14076   "bextr\t{%2, %1, %0|%0, %1, %2}"
14077   [(set_attr "type" "bitmanip")
14078    (set_attr "btver2_decode" "direct, double")
14079    (set_attr "mode" "<MODE>")])
14081 (define_insn "*bmi_blsi_<mode>"
14082   [(set (match_operand:SWI48 0 "register_operand" "=r")
14083         (and:SWI48
14084           (neg:SWI48
14085             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14086           (match_dup 1)))
14087    (clobber (reg:CC FLAGS_REG))]
14088   "TARGET_BMI"
14089   "blsi\t{%1, %0|%0, %1}"
14090   [(set_attr "type" "bitmanip")
14091    (set_attr "btver2_decode" "double")
14092    (set_attr "mode" "<MODE>")])
14094 (define_insn "*bmi_blsmsk_<mode>"
14095   [(set (match_operand:SWI48 0 "register_operand" "=r")
14096         (xor:SWI48
14097           (plus:SWI48
14098             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14099             (const_int -1))
14100           (match_dup 1)))
14101    (clobber (reg:CC FLAGS_REG))]
14102   "TARGET_BMI"
14103   "blsmsk\t{%1, %0|%0, %1}"
14104   [(set_attr "type" "bitmanip")
14105    (set_attr "btver2_decode" "double")
14106    (set_attr "mode" "<MODE>")])
14108 (define_insn "*bmi_blsr_<mode>"
14109   [(set (match_operand:SWI48 0 "register_operand" "=r")
14110         (and:SWI48
14111           (plus:SWI48
14112             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14113             (const_int -1))
14114           (match_dup 1)))
14115    (clobber (reg:CC FLAGS_REG))]
14116    "TARGET_BMI"
14117    "blsr\t{%1, %0|%0, %1}"
14118   [(set_attr "type" "bitmanip")
14119    (set_attr "btver2_decode" "double")
14120    (set_attr "mode" "<MODE>")])
14122 (define_insn "*bmi_blsr_<mode>_cmp"
14123   [(set (reg:CCZ FLAGS_REG)
14124         (compare:CCZ
14125           (and:SWI48
14126             (plus:SWI48
14127               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14128               (const_int -1))
14129             (match_dup 1))
14130           (const_int 0)))
14131    (set (match_operand:SWI48 0 "register_operand" "=r")
14132         (and:SWI48
14133           (plus:SWI48
14134             (match_dup 1)
14135             (const_int -1))
14136           (match_dup 1)))]
14137    "TARGET_BMI"
14138    "blsr\t{%1, %0|%0, %1}"
14139   [(set_attr "type" "bitmanip")
14140    (set_attr "btver2_decode" "double")
14141    (set_attr "mode" "<MODE>")])
14143 (define_insn "*bmi_blsr_<mode>_ccz"
14144   [(set (reg:CCZ FLAGS_REG)
14145         (compare:CCZ
14146           (and:SWI48
14147             (plus:SWI48
14148               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14149               (const_int -1))
14150             (match_dup 1))
14151           (const_int 0)))
14152    (clobber (match_scratch:SWI48 0 "=r"))]
14153    "TARGET_BMI"
14154    "blsr\t{%1, %0|%0, %1}"
14155   [(set_attr "type" "bitmanip")
14156    (set_attr "btver2_decode" "double")
14157    (set_attr "mode" "<MODE>")])
14159 ;; BMI2 instructions.
14160 (define_expand "bmi2_bzhi_<mode>3"
14161   [(parallel
14162     [(set (match_operand:SWI48 0 "register_operand")
14163           (zero_extract:SWI48
14164             (match_operand:SWI48 1 "nonimmediate_operand")
14165             (umin:SWI48
14166               (and:SWI48 (match_operand:SWI48 2 "register_operand")
14167                          (const_int 255))
14168               (match_dup 3))
14169             (const_int 0)))
14170      (clobber (reg:CC FLAGS_REG))])]
14171   "TARGET_BMI2"
14172   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14174 (define_insn "*bmi2_bzhi_<mode>3"
14175   [(set (match_operand:SWI48 0 "register_operand" "=r")
14176         (zero_extract:SWI48
14177           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14178           (umin:SWI48
14179             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14180                        (const_int 255))
14181             (match_operand:SWI48 3 "const_int_operand" "n"))
14182           (const_int 0)))
14183    (clobber (reg:CC FLAGS_REG))]
14184   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14185   "bzhi\t{%2, %1, %0|%0, %1, %2}"
14186   [(set_attr "type" "bitmanip")
14187    (set_attr "prefix" "vex")
14188    (set_attr "mode" "<MODE>")])
14190 (define_insn "*bmi2_bzhi_<mode>3_1"
14191   [(set (match_operand:SWI48 0 "register_operand" "=r")
14192         (zero_extract:SWI48
14193           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14194           (umin:SWI48
14195             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14196             (match_operand:SWI48 3 "const_int_operand" "n"))
14197           (const_int 0)))
14198    (clobber (reg:CC FLAGS_REG))]
14199   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14200   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14201   [(set_attr "type" "bitmanip")
14202    (set_attr "prefix" "vex")
14203    (set_attr "mode" "<MODE>")])
14205 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14206   [(set (reg:CCZ FLAGS_REG)
14207         (compare:CCZ
14208           (zero_extract:SWI48
14209             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14210             (umin:SWI48
14211               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14212               (match_operand:SWI48 3 "const_int_operand" "n"))
14213             (const_int 0))
14214         (const_int 0)))
14215    (clobber (match_scratch:SWI48 0 "=r"))]
14216   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14217   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14218   [(set_attr "type" "bitmanip")
14219    (set_attr "prefix" "vex")
14220    (set_attr "mode" "<MODE>")])
14222 (define_insn "bmi2_pdep_<mode>3"
14223   [(set (match_operand:SWI48 0 "register_operand" "=r")
14224         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14225                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14226                        UNSPEC_PDEP))]
14227   "TARGET_BMI2"
14228   "pdep\t{%2, %1, %0|%0, %1, %2}"
14229   [(set_attr "type" "bitmanip")
14230    (set_attr "prefix" "vex")
14231    (set_attr "mode" "<MODE>")])
14233 (define_insn "bmi2_pext_<mode>3"
14234   [(set (match_operand:SWI48 0 "register_operand" "=r")
14235         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14236                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14237                        UNSPEC_PEXT))]
14238   "TARGET_BMI2"
14239   "pext\t{%2, %1, %0|%0, %1, %2}"
14240   [(set_attr "type" "bitmanip")
14241    (set_attr "prefix" "vex")
14242    (set_attr "mode" "<MODE>")])
14244 ;; TBM instructions.
14245 (define_insn "tbm_bextri_<mode>"
14246   [(set (match_operand:SWI48 0 "register_operand" "=r")
14247         (zero_extract:SWI48
14248           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14249           (match_operand 2 "const_0_to_255_operand" "N")
14250           (match_operand 3 "const_0_to_255_operand" "N")))
14251    (clobber (reg:CC FLAGS_REG))]
14252    "TARGET_TBM"
14254   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14255   return "bextr\t{%2, %1, %0|%0, %1, %2}";
14257   [(set_attr "type" "bitmanip")
14258    (set_attr "mode" "<MODE>")])
14260 (define_insn "*tbm_blcfill_<mode>"
14261   [(set (match_operand:SWI48 0 "register_operand" "=r")
14262         (and:SWI48
14263           (plus:SWI48
14264             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14265             (const_int 1))
14266           (match_dup 1)))
14267    (clobber (reg:CC FLAGS_REG))]
14268    "TARGET_TBM"
14269    "blcfill\t{%1, %0|%0, %1}"
14270   [(set_attr "type" "bitmanip")
14271    (set_attr "mode" "<MODE>")])
14273 (define_insn "*tbm_blci_<mode>"
14274   [(set (match_operand:SWI48 0 "register_operand" "=r")
14275         (ior:SWI48
14276           (not:SWI48
14277             (plus:SWI48
14278               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14279               (const_int 1)))
14280           (match_dup 1)))
14281    (clobber (reg:CC FLAGS_REG))]
14282    "TARGET_TBM"
14283    "blci\t{%1, %0|%0, %1}"
14284   [(set_attr "type" "bitmanip")
14285    (set_attr "mode" "<MODE>")])
14287 (define_insn "*tbm_blcic_<mode>"
14288   [(set (match_operand:SWI48 0 "register_operand" "=r")
14289         (and:SWI48
14290           (plus:SWI48
14291             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14292             (const_int 1))
14293           (not:SWI48
14294             (match_dup 1))))
14295    (clobber (reg:CC FLAGS_REG))]
14296    "TARGET_TBM"
14297    "blcic\t{%1, %0|%0, %1}"
14298   [(set_attr "type" "bitmanip")
14299    (set_attr "mode" "<MODE>")])
14301 (define_insn "*tbm_blcmsk_<mode>"
14302   [(set (match_operand:SWI48 0 "register_operand" "=r")
14303         (xor:SWI48
14304           (plus:SWI48
14305             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14306             (const_int 1))
14307           (match_dup 1)))
14308    (clobber (reg:CC FLAGS_REG))]
14309    "TARGET_TBM"
14310    "blcmsk\t{%1, %0|%0, %1}"
14311   [(set_attr "type" "bitmanip")
14312    (set_attr "mode" "<MODE>")])
14314 (define_insn "*tbm_blcs_<mode>"
14315   [(set (match_operand:SWI48 0 "register_operand" "=r")
14316         (ior:SWI48
14317           (plus:SWI48
14318             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14319             (const_int 1))
14320           (match_dup 1)))
14321    (clobber (reg:CC FLAGS_REG))]
14322    "TARGET_TBM"
14323    "blcs\t{%1, %0|%0, %1}"
14324   [(set_attr "type" "bitmanip")
14325    (set_attr "mode" "<MODE>")])
14327 (define_insn "*tbm_blsfill_<mode>"
14328   [(set (match_operand:SWI48 0 "register_operand" "=r")
14329         (ior:SWI48
14330           (plus:SWI48
14331             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14332             (const_int -1))
14333           (match_dup 1)))
14334    (clobber (reg:CC FLAGS_REG))]
14335    "TARGET_TBM"
14336    "blsfill\t{%1, %0|%0, %1}"
14337   [(set_attr "type" "bitmanip")
14338    (set_attr "mode" "<MODE>")])
14340 (define_insn "*tbm_blsic_<mode>"
14341   [(set (match_operand:SWI48 0 "register_operand" "=r")
14342         (ior:SWI48
14343           (plus:SWI48
14344             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14345             (const_int -1))
14346           (not:SWI48
14347             (match_dup 1))))
14348    (clobber (reg:CC FLAGS_REG))]
14349    "TARGET_TBM"
14350    "blsic\t{%1, %0|%0, %1}"
14351   [(set_attr "type" "bitmanip")
14352    (set_attr "mode" "<MODE>")])
14354 (define_insn "*tbm_t1mskc_<mode>"
14355   [(set (match_operand:SWI48 0 "register_operand" "=r")
14356         (ior:SWI48
14357           (plus:SWI48
14358             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14359             (const_int 1))
14360           (not:SWI48
14361             (match_dup 1))))
14362    (clobber (reg:CC FLAGS_REG))]
14363    "TARGET_TBM"
14364    "t1mskc\t{%1, %0|%0, %1}"
14365   [(set_attr "type" "bitmanip")
14366    (set_attr "mode" "<MODE>")])
14368 (define_insn "*tbm_tzmsk_<mode>"
14369   [(set (match_operand:SWI48 0 "register_operand" "=r")
14370         (and:SWI48
14371           (plus:SWI48
14372             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14373             (const_int -1))
14374           (not:SWI48
14375             (match_dup 1))))
14376    (clobber (reg:CC FLAGS_REG))]
14377    "TARGET_TBM"
14378    "tzmsk\t{%1, %0|%0, %1}"
14379   [(set_attr "type" "bitmanip")
14380    (set_attr "mode" "<MODE>")])
14382 (define_insn_and_split "popcount<mode>2"
14383   [(set (match_operand:SWI48 0 "register_operand" "=r")
14384         (popcount:SWI48
14385           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14386    (clobber (reg:CC FLAGS_REG))]
14387   "TARGET_POPCNT"
14389 #if TARGET_MACHO
14390   return "popcnt\t{%1, %0|%0, %1}";
14391 #else
14392   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14393 #endif
14395   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14396    && optimize_function_for_speed_p (cfun)
14397    && !reg_mentioned_p (operands[0], operands[1])"
14398   [(parallel
14399     [(set (match_dup 0)
14400           (popcount:SWI48 (match_dup 1)))
14401      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14402      (clobber (reg:CC FLAGS_REG))])]
14403   "ix86_expand_clear (operands[0]);"
14404   [(set_attr "prefix_rep" "1")
14405    (set_attr "type" "bitmanip")
14406    (set_attr "mode" "<MODE>")])
14408 ; False dependency happens when destination is only updated by tzcnt,
14409 ; lzcnt or popcnt.  There is no false dependency when destination is
14410 ; also used in source.
14411 (define_insn "*popcount<mode>2_falsedep"
14412   [(set (match_operand:SWI48 0 "register_operand" "=r")
14413         (popcount:SWI48
14414           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14415    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14416            UNSPEC_INSN_FALSE_DEP)
14417    (clobber (reg:CC FLAGS_REG))]
14418   "TARGET_POPCNT"
14420 #if TARGET_MACHO
14421   return "popcnt\t{%1, %0|%0, %1}";
14422 #else
14423   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14424 #endif
14426   [(set_attr "prefix_rep" "1")
14427    (set_attr "type" "bitmanip")
14428    (set_attr "mode" "<MODE>")])
14430 (define_insn_and_split "*popcounthi2_1"
14431   [(set (match_operand:SI 0 "register_operand")
14432         (popcount:SI
14433           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14434    (clobber (reg:CC FLAGS_REG))]
14435   "TARGET_POPCNT
14436    && can_create_pseudo_p ()"
14437   "#"
14438   "&& 1"
14439   [(const_int 0)]
14441   rtx tmp = gen_reg_rtx (HImode);
14443   emit_insn (gen_popcounthi2 (tmp, operands[1]));
14444   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14445   DONE;
14448 (define_insn "popcounthi2"
14449   [(set (match_operand:HI 0 "register_operand" "=r")
14450         (popcount:HI
14451           (match_operand:HI 1 "nonimmediate_operand" "rm")))
14452    (clobber (reg:CC FLAGS_REG))]
14453   "TARGET_POPCNT"
14455 #if TARGET_MACHO
14456   return "popcnt\t{%1, %0|%0, %1}";
14457 #else
14458   return "popcnt{w}\t{%1, %0|%0, %1}";
14459 #endif
14461   [(set_attr "prefix_rep" "1")
14462    (set_attr "type" "bitmanip")
14463    (set_attr "mode" "HI")])
14465 (define_expand "bswapdi2"
14466   [(set (match_operand:DI 0 "register_operand")
14467         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14468   "TARGET_64BIT"
14470   if (!TARGET_MOVBE)
14471     operands[1] = force_reg (DImode, operands[1]);
14474 (define_expand "bswapsi2"
14475   [(set (match_operand:SI 0 "register_operand")
14476         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14477   ""
14479   if (TARGET_MOVBE)
14480     ;
14481   else if (TARGET_BSWAP)
14482     operands[1] = force_reg (SImode, operands[1]);
14483   else
14484     {
14485       rtx x = operands[0];
14487       emit_move_insn (x, operands[1]);
14488       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14489       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14490       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14491       DONE;
14492     }
14495 (define_insn "*bswap<mode>2_movbe"
14496   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14497         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14498   "TARGET_MOVBE
14499    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14500   "@
14501     bswap\t%0
14502     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14503     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14504   [(set_attr "type" "bitmanip,imov,imov")
14505    (set_attr "modrm" "0,1,1")
14506    (set_attr "prefix_0f" "*,1,1")
14507    (set_attr "prefix_extra" "*,1,1")
14508    (set_attr "mode" "<MODE>")])
14510 (define_insn "*bswap<mode>2"
14511   [(set (match_operand:SWI48 0 "register_operand" "=r")
14512         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14513   "TARGET_BSWAP"
14514   "bswap\t%0"
14515   [(set_attr "type" "bitmanip")
14516    (set_attr "modrm" "0")
14517    (set_attr "mode" "<MODE>")])
14519 (define_expand "bswaphi2"
14520   [(set (match_operand:HI 0 "register_operand")
14521         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14522   "TARGET_MOVBE")
14524 (define_insn "*bswaphi2_movbe"
14525   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14526         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14527   "TARGET_MOVBE
14528    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14529   "@
14530     xchg{b}\t{%h0, %b0|%b0, %h0}
14531     movbe{w}\t{%1, %0|%0, %1}
14532     movbe{w}\t{%1, %0|%0, %1}"
14533   [(set_attr "type" "imov")
14534    (set_attr "modrm" "*,1,1")
14535    (set_attr "prefix_0f" "*,1,1")
14536    (set_attr "prefix_extra" "*,1,1")
14537    (set_attr "pent_pair" "np,*,*")
14538    (set_attr "athlon_decode" "vector,*,*")
14539    (set_attr "amdfam10_decode" "double,*,*")
14540    (set_attr "bdver1_decode" "double,*,*")
14541    (set_attr "mode" "QI,HI,HI")])
14543 (define_peephole2
14544   [(set (match_operand:HI 0 "general_reg_operand")
14545         (bswap:HI (match_dup 0)))]
14546   "TARGET_MOVBE
14547    && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14548    && peep2_regno_dead_p (0, FLAGS_REG)"
14549   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14550               (clobber (reg:CC FLAGS_REG))])])
14552 (define_insn "bswaphi_lowpart"
14553   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14554         (bswap:HI (match_dup 0)))
14555    (clobber (reg:CC FLAGS_REG))]
14556   ""
14557   "@
14558     xchg{b}\t{%h0, %b0|%b0, %h0}
14559     rol{w}\t{$8, %0|%0, 8}"
14560   [(set (attr "preferred_for_size")
14561      (cond [(eq_attr "alternative" "0")
14562               (symbol_ref "true")]
14563            (symbol_ref "false")))
14564    (set (attr "preferred_for_speed")
14565      (cond [(eq_attr "alternative" "0")
14566               (symbol_ref "TARGET_USE_XCHGB")]
14567            (symbol_ref "!TARGET_USE_XCHGB")))
14568    (set_attr "length" "2,4")
14569    (set_attr "mode" "QI,HI")])
14571 (define_expand "paritydi2"
14572   [(set (match_operand:DI 0 "register_operand")
14573         (parity:DI (match_operand:DI 1 "register_operand")))]
14574   "! TARGET_POPCNT"
14576   rtx scratch = gen_reg_rtx (QImode);
14578   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14579                                 NULL_RTX, operands[1]));
14581   ix86_expand_setcc (scratch, ORDERED,
14582                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14584   if (TARGET_64BIT)
14585     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14586   else
14587     {
14588       rtx tmp = gen_reg_rtx (SImode);
14590       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14591       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14592     }
14593   DONE;
14596 (define_expand "paritysi2"
14597   [(set (match_operand:SI 0 "register_operand")
14598         (parity:SI (match_operand:SI 1 "register_operand")))]
14599   "! TARGET_POPCNT"
14601   rtx scratch = gen_reg_rtx (QImode);
14603   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14605   ix86_expand_setcc (scratch, ORDERED,
14606                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14608   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14609   DONE;
14612 (define_insn_and_split "paritydi2_cmp"
14613   [(set (reg:CC FLAGS_REG)
14614         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14615                    UNSPEC_PARITY))
14616    (clobber (match_scratch:DI 0 "=r"))
14617    (clobber (match_scratch:SI 1 "=&r"))
14618    (clobber (match_scratch:HI 2 "=Q"))]
14619   "! TARGET_POPCNT"
14620   "#"
14621   "&& reload_completed"
14622   [(parallel
14623      [(set (match_dup 1)
14624            (xor:SI (match_dup 1) (match_dup 4)))
14625       (clobber (reg:CC FLAGS_REG))])
14626    (parallel
14627      [(set (reg:CC FLAGS_REG)
14628            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14629       (clobber (match_dup 1))
14630       (clobber (match_dup 2))])]
14632   operands[4] = gen_lowpart (SImode, operands[3]);
14634   if (TARGET_64BIT)
14635     {
14636       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14637       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14638     }
14639   else
14640     operands[1] = gen_highpart (SImode, operands[3]);
14643 (define_insn_and_split "paritysi2_cmp"
14644   [(set (reg:CC FLAGS_REG)
14645         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14646                    UNSPEC_PARITY))
14647    (clobber (match_scratch:SI 0 "=r"))
14648    (clobber (match_scratch:HI 1 "=&Q"))]
14649   "! TARGET_POPCNT"
14650   "#"
14651   "&& reload_completed"
14652   [(parallel
14653      [(set (match_dup 1)
14654            (xor:HI (match_dup 1) (match_dup 3)))
14655       (clobber (reg:CC FLAGS_REG))])
14656    (parallel
14657      [(set (reg:CC FLAGS_REG)
14658            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14659       (clobber (match_dup 1))])]
14661   operands[3] = gen_lowpart (HImode, operands[2]);
14663   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14664   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14667 (define_insn "*parityhi2_cmp"
14668   [(set (reg:CC FLAGS_REG)
14669         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14670                    UNSPEC_PARITY))
14671    (clobber (match_scratch:HI 0 "=Q"))]
14672   "! TARGET_POPCNT"
14673   "xor{b}\t{%h0, %b0|%b0, %h0}"
14674   [(set_attr "length" "2")
14675    (set_attr "mode" "HI")])
14678 ;; Thread-local storage patterns for ELF.
14680 ;; Note that these code sequences must appear exactly as shown
14681 ;; in order to allow linker relaxation.
14683 (define_insn "*tls_global_dynamic_32_gnu"
14684   [(set (match_operand:SI 0 "register_operand" "=a")
14685         (unspec:SI
14686          [(match_operand:SI 1 "register_operand" "Yb")
14687           (match_operand 2 "tls_symbolic_operand")
14688           (match_operand 3 "constant_call_address_operand" "Bz")
14689           (reg:SI SP_REG)]
14690          UNSPEC_TLS_GD))
14691    (clobber (match_scratch:SI 4 "=d"))
14692    (clobber (match_scratch:SI 5 "=c"))
14693    (clobber (reg:CC FLAGS_REG))]
14694   "!TARGET_64BIT && TARGET_GNU_TLS"
14696   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14697     output_asm_insn
14698       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14699   else
14700     output_asm_insn
14701       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14702   if (TARGET_SUN_TLS)
14703 #ifdef HAVE_AS_IX86_TLSGDPLT
14704     return "call\t%a2@tlsgdplt";
14705 #else
14706     return "call\t%p3@plt";
14707 #endif
14708   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14709     return "call\t%P3";
14710   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14712   [(set_attr "type" "multi")
14713    (set_attr "length" "12")])
14715 (define_expand "tls_global_dynamic_32"
14716   [(parallel
14717     [(set (match_operand:SI 0 "register_operand")
14718           (unspec:SI [(match_operand:SI 2 "register_operand")
14719                       (match_operand 1 "tls_symbolic_operand")
14720                       (match_operand 3 "constant_call_address_operand")
14721                       (reg:SI SP_REG)]
14722                      UNSPEC_TLS_GD))
14723      (clobber (match_scratch:SI 4))
14724      (clobber (match_scratch:SI 5))
14725      (clobber (reg:CC FLAGS_REG))])]
14726   ""
14727   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14729 (define_insn "*tls_global_dynamic_64_<mode>"
14730   [(set (match_operand:P 0 "register_operand" "=a")
14731         (call:P
14732          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14733          (match_operand 3)))
14734    (unspec:P [(match_operand 1 "tls_symbolic_operand")
14735               (reg:P SP_REG)]
14736              UNSPEC_TLS_GD)]
14737   "TARGET_64BIT"
14739   if (!TARGET_X32)
14740     /* The .loc directive has effect for 'the immediately following assembly
14741        instruction'.  So for a sequence:
14742          .loc f l
14743          .byte x
14744          insn1
14745        the 'immediately following assembly instruction' is insn1.
14746        We want to emit an insn prefix here, but if we use .byte (as shown in
14747        'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14748        inside the insn sequence, rather than to the start.  After relaxation
14749        of the sequence by the linker, the .loc might point inside an insn.
14750        Use data16 prefix instead, which doesn't have this problem.  */
14751     fputs ("\tdata16", asm_out_file);
14752   output_asm_insn
14753     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14754   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14755     fputs (ASM_SHORT "0x6666\n", asm_out_file);
14756   else
14757     fputs (ASM_BYTE "0x66\n", asm_out_file);
14758   fputs ("\trex64\n", asm_out_file);
14759   if (TARGET_SUN_TLS)
14760     return "call\t%p2@plt";
14761   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14762     return "call\t%P2";
14763   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14765   [(set_attr "type" "multi")
14766    (set (attr "length")
14767         (symbol_ref "TARGET_X32 ? 15 : 16"))])
14769 (define_insn "*tls_global_dynamic_64_largepic"
14770   [(set (match_operand:DI 0 "register_operand" "=a")
14771         (call:DI
14772          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14773                           (match_operand:DI 3 "immediate_operand" "i")))
14774          (match_operand 4)))
14775    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14776                (reg:DI SP_REG)]
14777               UNSPEC_TLS_GD)]
14778   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14779    && GET_CODE (operands[3]) == CONST
14780    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14781    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14783   output_asm_insn
14784     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14785   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14786   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14787   return "call\t{*%%rax|rax}";
14789   [(set_attr "type" "multi")
14790    (set_attr "length" "22")])
14792 (define_expand "tls_global_dynamic_64_<mode>"
14793   [(parallel
14794     [(set (match_operand:P 0 "register_operand")
14795           (call:P
14796            (mem:QI (match_operand 2))
14797            (const_int 0)))
14798      (unspec:P [(match_operand 1 "tls_symbolic_operand")
14799                 (reg:P SP_REG)]
14800                UNSPEC_TLS_GD)])]
14801   "TARGET_64BIT"
14802   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14804 (define_insn "*tls_local_dynamic_base_32_gnu"
14805   [(set (match_operand:SI 0 "register_operand" "=a")
14806         (unspec:SI
14807          [(match_operand:SI 1 "register_operand" "Yb")
14808           (match_operand 2 "constant_call_address_operand" "Bz")
14809           (reg:SI SP_REG)]
14810          UNSPEC_TLS_LD_BASE))
14811    (clobber (match_scratch:SI 3 "=d"))
14812    (clobber (match_scratch:SI 4 "=c"))
14813    (clobber (reg:CC FLAGS_REG))]
14814   "!TARGET_64BIT && TARGET_GNU_TLS"
14816   output_asm_insn
14817     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14818   if (TARGET_SUN_TLS)
14819     {
14820       if (HAVE_AS_IX86_TLSLDMPLT)
14821         return "call\t%&@tlsldmplt";
14822       else
14823         return "call\t%p2@plt";
14824     }
14825   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14826     return "call\t%P2";
14827   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14829   [(set_attr "type" "multi")
14830    (set_attr "length" "11")])
14832 (define_expand "tls_local_dynamic_base_32"
14833   [(parallel
14834      [(set (match_operand:SI 0 "register_operand")
14835            (unspec:SI
14836             [(match_operand:SI 1 "register_operand")
14837              (match_operand 2 "constant_call_address_operand")
14838              (reg:SI SP_REG)]
14839             UNSPEC_TLS_LD_BASE))
14840       (clobber (match_scratch:SI 3))
14841       (clobber (match_scratch:SI 4))
14842       (clobber (reg:CC FLAGS_REG))])]
14843   ""
14844   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14846 (define_insn "*tls_local_dynamic_base_64_<mode>"
14847   [(set (match_operand:P 0 "register_operand" "=a")
14848         (call:P
14849          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14850          (match_operand 2)))
14851    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14852   "TARGET_64BIT"
14854   output_asm_insn
14855     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14856   if (TARGET_SUN_TLS)
14857     return "call\t%p1@plt";
14858   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14859     return "call\t%P1";
14860   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14862   [(set_attr "type" "multi")
14863    (set_attr "length" "12")])
14865 (define_insn "*tls_local_dynamic_base_64_largepic"
14866   [(set (match_operand:DI 0 "register_operand" "=a")
14867         (call:DI
14868          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14869                           (match_operand:DI 2 "immediate_operand" "i")))
14870          (match_operand 3)))
14871    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14872   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14873    && GET_CODE (operands[2]) == CONST
14874    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14875    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14877   output_asm_insn
14878     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14879   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14880   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14881   return "call\t{*%%rax|rax}";
14883   [(set_attr "type" "multi")
14884    (set_attr "length" "22")])
14886 (define_expand "tls_local_dynamic_base_64_<mode>"
14887   [(parallel
14888      [(set (match_operand:P 0 "register_operand")
14889            (call:P
14890             (mem:QI (match_operand 1))
14891             (const_int 0)))
14892       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14893   "TARGET_64BIT"
14894   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14896 ;; Local dynamic of a single variable is a lose.  Show combine how
14897 ;; to convert that back to global dynamic.
14899 (define_insn_and_split "*tls_local_dynamic_32_once"
14900   [(set (match_operand:SI 0 "register_operand" "=a")
14901         (plus:SI
14902          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14903                      (match_operand 2 "constant_call_address_operand" "Bz")
14904                      (reg:SI SP_REG)]
14905                     UNSPEC_TLS_LD_BASE)
14906          (const:SI (unspec:SI
14907                     [(match_operand 3 "tls_symbolic_operand")]
14908                     UNSPEC_DTPOFF))))
14909    (clobber (match_scratch:SI 4 "=d"))
14910    (clobber (match_scratch:SI 5 "=c"))
14911    (clobber (reg:CC FLAGS_REG))]
14912   ""
14913   "#"
14914   ""
14915   [(parallel
14916      [(set (match_dup 0)
14917            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14918                        (reg:SI SP_REG)]
14919                       UNSPEC_TLS_GD))
14920       (clobber (match_dup 4))
14921       (clobber (match_dup 5))
14922       (clobber (reg:CC FLAGS_REG))])])
14924 ;; Load and add the thread base pointer from %<tp_seg>:0.
14925 (define_insn_and_split "*load_tp_<mode>"
14926   [(set (match_operand:PTR 0 "register_operand" "=r")
14927         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14928   ""
14929   "#"
14930   ""
14931   [(set (match_dup 0)
14932         (match_dup 1))]
14934   addr_space_t as = DEFAULT_TLS_SEG_REG;
14936   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14937   set_mem_addr_space (operands[1], as);
14940 (define_insn_and_split "*load_tp_x32_zext"
14941   [(set (match_operand:DI 0 "register_operand" "=r")
14942         (zero_extend:DI
14943           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14944   "TARGET_X32"
14945   "#"
14946   ""
14947   [(set (match_dup 0)
14948         (zero_extend:DI (match_dup 1)))]
14950   addr_space_t as = DEFAULT_TLS_SEG_REG;
14952   operands[1] = gen_const_mem (SImode, const0_rtx);
14953   set_mem_addr_space (operands[1], as);
14956 (define_insn_and_split "*add_tp_<mode>"
14957   [(set (match_operand:PTR 0 "register_operand" "=r")
14958         (plus:PTR
14959           (unspec:PTR [(const_int 0)] UNSPEC_TP)
14960           (match_operand:PTR 1 "register_operand" "0")))
14961    (clobber (reg:CC FLAGS_REG))]
14962   ""
14963   "#"
14964   ""
14965   [(parallel
14966      [(set (match_dup 0)
14967            (plus:PTR (match_dup 1) (match_dup 2)))
14968       (clobber (reg:CC FLAGS_REG))])]
14970   addr_space_t as = DEFAULT_TLS_SEG_REG;
14972   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14973   set_mem_addr_space (operands[2], as);
14976 (define_insn_and_split "*add_tp_x32_zext"
14977   [(set (match_operand:DI 0 "register_operand" "=r")
14978         (zero_extend:DI
14979           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14980                    (match_operand:SI 1 "register_operand" "0"))))
14981    (clobber (reg:CC FLAGS_REG))]
14982   "TARGET_X32"
14983   "#"
14984   ""
14985   [(parallel
14986      [(set (match_dup 0)
14987            (zero_extend:DI
14988              (plus:SI (match_dup 1) (match_dup 2))))
14989       (clobber (reg:CC FLAGS_REG))])]
14991   addr_space_t as = DEFAULT_TLS_SEG_REG;
14993   operands[2] = gen_const_mem (SImode, const0_rtx);
14994   set_mem_addr_space (operands[2], as);
14997 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14998 ;; %rax as destination of the initial executable code sequence.
14999 (define_insn "tls_initial_exec_64_sun"
15000   [(set (match_operand:DI 0 "register_operand" "=a")
15001         (unspec:DI
15002          [(match_operand 1 "tls_symbolic_operand")]
15003          UNSPEC_TLS_IE_SUN))
15004    (clobber (reg:CC FLAGS_REG))]
15005   "TARGET_64BIT && TARGET_SUN_TLS"
15007   output_asm_insn
15008     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
15009   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
15011   [(set_attr "type" "multi")])
15013 ;; GNU2 TLS patterns can be split.
15015 (define_expand "tls_dynamic_gnu2_32"
15016   [(set (match_dup 3)
15017         (plus:SI (match_operand:SI 2 "register_operand")
15018                  (const:SI
15019                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
15020                              UNSPEC_TLSDESC))))
15021    (parallel
15022     [(set (match_operand:SI 0 "register_operand")
15023           (unspec:SI [(match_dup 1) (match_dup 3)
15024                       (match_dup 2) (reg:SI SP_REG)]
15025                       UNSPEC_TLSDESC))
15026      (clobber (reg:CC FLAGS_REG))])]
15027   "!TARGET_64BIT && TARGET_GNU2_TLS"
15029   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15030   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15033 (define_insn "*tls_dynamic_gnu2_lea_32"
15034   [(set (match_operand:SI 0 "register_operand" "=r")
15035         (plus:SI (match_operand:SI 1 "register_operand" "b")
15036                  (const:SI
15037                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
15038                               UNSPEC_TLSDESC))))]
15039   "!TARGET_64BIT && TARGET_GNU2_TLS"
15040   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
15041   [(set_attr "type" "lea")
15042    (set_attr "mode" "SI")
15043    (set_attr "length" "6")
15044    (set_attr "length_address" "4")])
15046 (define_insn "*tls_dynamic_gnu2_call_32"
15047   [(set (match_operand:SI 0 "register_operand" "=a")
15048         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
15049                     (match_operand:SI 2 "register_operand" "0")
15050                     ;; we have to make sure %ebx still points to the GOT
15051                     (match_operand:SI 3 "register_operand" "b")
15052                     (reg:SI SP_REG)]
15053                    UNSPEC_TLSDESC))
15054    (clobber (reg:CC FLAGS_REG))]
15055   "!TARGET_64BIT && TARGET_GNU2_TLS"
15056   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15057   [(set_attr "type" "call")
15058    (set_attr "length" "2")
15059    (set_attr "length_address" "0")])
15061 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15062   [(set (match_operand:SI 0 "register_operand" "=&a")
15063         (plus:SI
15064          (unspec:SI [(match_operand 3 "tls_modbase_operand")
15065                      (match_operand:SI 4)
15066                      (match_operand:SI 2 "register_operand" "b")
15067                      (reg:SI SP_REG)]
15068                     UNSPEC_TLSDESC)
15069          (const:SI (unspec:SI
15070                     [(match_operand 1 "tls_symbolic_operand")]
15071                     UNSPEC_DTPOFF))))
15072    (clobber (reg:CC FLAGS_REG))]
15073   "!TARGET_64BIT && TARGET_GNU2_TLS"
15074   "#"
15075   ""
15076   [(set (match_dup 0) (match_dup 5))]
15078   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15079   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15082 (define_expand "tls_dynamic_gnu2_64"
15083   [(set (match_dup 2)
15084         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15085                    UNSPEC_TLSDESC))
15086    (parallel
15087     [(set (match_operand:DI 0 "register_operand")
15088           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15089                      UNSPEC_TLSDESC))
15090      (clobber (reg:CC FLAGS_REG))])]
15091   "TARGET_64BIT && TARGET_GNU2_TLS"
15093   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15094   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15097 (define_insn "*tls_dynamic_gnu2_lea_64"
15098   [(set (match_operand:DI 0 "register_operand" "=r")
15099         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15100                    UNSPEC_TLSDESC))]
15101   "TARGET_64BIT && TARGET_GNU2_TLS"
15102   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15103   [(set_attr "type" "lea")
15104    (set_attr "mode" "DI")
15105    (set_attr "length" "7")
15106    (set_attr "length_address" "4")])
15108 (define_insn "*tls_dynamic_gnu2_call_64"
15109   [(set (match_operand:DI 0 "register_operand" "=a")
15110         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
15111                     (match_operand:DI 2 "register_operand" "0")
15112                     (reg:DI SP_REG)]
15113                    UNSPEC_TLSDESC))
15114    (clobber (reg:CC FLAGS_REG))]
15115   "TARGET_64BIT && TARGET_GNU2_TLS"
15116   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15117   [(set_attr "type" "call")
15118    (set_attr "length" "2")
15119    (set_attr "length_address" "0")])
15121 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15122   [(set (match_operand:DI 0 "register_operand" "=&a")
15123         (plus:DI
15124          (unspec:DI [(match_operand 2 "tls_modbase_operand")
15125                      (match_operand:DI 3)
15126                      (reg:DI SP_REG)]
15127                     UNSPEC_TLSDESC)
15128          (const:DI (unspec:DI
15129                     [(match_operand 1 "tls_symbolic_operand")]
15130                     UNSPEC_DTPOFF))))
15131    (clobber (reg:CC FLAGS_REG))]
15132   "TARGET_64BIT && TARGET_GNU2_TLS"
15133   "#"
15134   ""
15135   [(set (match_dup 0) (match_dup 4))]
15137   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15138   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15141 (define_split
15142   [(match_operand 0 "tls_address_pattern")]
15143   "TARGET_TLS_DIRECT_SEG_REFS"
15144   [(match_dup 0)]
15145   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15148 ;; These patterns match the binary 387 instructions for addM3, subM3,
15149 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15150 ;; SFmode.  The first is the normal insn, the second the same insn but
15151 ;; with one operand a conversion, and the third the same insn but with
15152 ;; the other operand a conversion.  The conversion may be SFmode or
15153 ;; SImode if the target mode DFmode, but only SImode if the target mode
15154 ;; is SFmode.
15156 ;; Gcc is slightly more smart about handling normal two address instructions
15157 ;; so use special patterns for add and mull.
15159 (define_insn "*fop_<mode>_comm"
15160   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15161         (match_operator:MODEF 3 "binary_fp_operator"
15162           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15163            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15164   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15165     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15166    && COMMUTATIVE_ARITH_P (operands[3])
15167    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15168   "* return output_387_binary_op (insn, operands);"
15169   [(set (attr "type")
15170         (if_then_else (eq_attr "alternative" "1,2")
15171            (if_then_else (match_operand:MODEF 3 "mult_operator")
15172               (const_string "ssemul")
15173               (const_string "sseadd"))
15174            (if_then_else (match_operand:MODEF 3 "mult_operator")
15175               (const_string "fmul")
15176               (const_string "fop"))))
15177    (set_attr "isa" "*,noavx,avx")
15178    (set_attr "prefix" "orig,orig,vex")
15179    (set_attr "mode" "<MODE>")
15180    (set (attr "enabled")
15181      (if_then_else
15182        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15183        (if_then_else
15184          (eq_attr "alternative" "0")
15185          (symbol_ref "TARGET_MIX_SSE_I387
15186                       && X87_ENABLE_ARITH (<MODE>mode)")
15187          (const_string "*"))
15188        (if_then_else
15189          (eq_attr "alternative" "0")
15190          (symbol_ref "true")
15191          (symbol_ref "false"))))])
15193 (define_insn "*rcpsf2_sse"
15194   [(set (match_operand:SF 0 "register_operand" "=x,x")
15195         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
15196                    UNSPEC_RCP))]
15197   "TARGET_SSE && TARGET_SSE_MATH"
15198   "@
15199    %vrcpss\t{%d1, %0|%0, %d1}
15200    %vrcpss\t{%1, %d0|%d0, %1}"
15201   [(set_attr "type" "sse")
15202    (set_attr "atom_sse_attr" "rcp")
15203    (set_attr "btver2_sse_attr" "rcp")
15204    (set_attr "prefix" "maybe_vex")
15205    (set_attr "mode" "SF")])
15207 (define_insn "*fop_<mode>_1"
15208   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
15209         (match_operator:MODEF 3 "binary_fp_operator"
15210           [(match_operand:MODEF 1
15211              "x87nonimm_ssenomem_operand" "0,fm,0,v")
15212            (match_operand:MODEF 2
15213              "nonimmediate_operand"       "fm,0,xm,vm")]))]
15214   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15215     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15216    && !COMMUTATIVE_ARITH_P (operands[3])
15217    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15218   "* return output_387_binary_op (insn, operands);"
15219   [(set (attr "type")
15220         (if_then_else (eq_attr "alternative" "2,3")
15221            (if_then_else (match_operand:MODEF 3 "div_operator")
15222               (const_string "ssediv")
15223               (const_string "sseadd"))
15224            (if_then_else (match_operand:MODEF 3 "div_operator")
15225               (const_string "fdiv")
15226               (const_string "fop"))))
15227    (set_attr "isa" "*,*,noavx,avx")
15228    (set_attr "prefix" "orig,orig,orig,vex")
15229    (set_attr "mode" "<MODE>")
15230    (set (attr "enabled")
15231      (if_then_else
15232        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15233        (if_then_else
15234          (eq_attr "alternative" "0,1")
15235          (symbol_ref "TARGET_MIX_SSE_I387
15236                       && X87_ENABLE_ARITH (<MODE>mode)")
15237          (const_string "*"))
15238        (if_then_else
15239          (eq_attr "alternative" "0,1")
15240          (symbol_ref "true")
15241          (symbol_ref "false"))))])
15243 ;; ??? Add SSE splitters for these!
15244 (define_insn "*fop_<MODEF:mode>_2_i387"
15245   [(set (match_operand:MODEF 0 "register_operand" "=f")
15246         (match_operator:MODEF 3 "binary_fp_operator"
15247           [(float:MODEF
15248              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15249            (match_operand:MODEF 2 "register_operand" "0")]))]
15250   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15251    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15252    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15253        || optimize_function_for_size_p (cfun))"
15254   "* return output_387_binary_op (insn, operands);"
15255   [(set (attr "type")
15256         (cond [(match_operand:MODEF 3 "mult_operator")
15257                  (const_string "fmul")
15258                (match_operand:MODEF 3 "div_operator")
15259                  (const_string "fdiv")
15260               ]
15261               (const_string "fop")))
15262    (set_attr "fp_int_src" "true")
15263    (set_attr "mode" "<SWI24:MODE>")])
15265 (define_insn "*fop_<MODEF:mode>_3_i387"
15266   [(set (match_operand:MODEF 0 "register_operand" "=f")
15267         (match_operator:MODEF 3 "binary_fp_operator"
15268           [(match_operand:MODEF 1 "register_operand" "0")
15269            (float:MODEF
15270              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15271   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15272    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15273    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15274        || optimize_function_for_size_p (cfun))"
15275   "* return output_387_binary_op (insn, operands);"
15276   [(set (attr "type")
15277         (cond [(match_operand:MODEF 3 "mult_operator")
15278                  (const_string "fmul")
15279                (match_operand:MODEF 3 "div_operator")
15280                  (const_string "fdiv")
15281               ]
15282               (const_string "fop")))
15283    (set_attr "fp_int_src" "true")
15284    (set_attr "mode" "<MODE>")])
15286 (define_insn "*fop_df_4_i387"
15287   [(set (match_operand:DF 0 "register_operand" "=f,f")
15288         (match_operator:DF 3 "binary_fp_operator"
15289            [(float_extend:DF
15290              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15291             (match_operand:DF 2 "register_operand" "0,f")]))]
15292   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15293    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15294   "* return output_387_binary_op (insn, operands);"
15295   [(set (attr "type")
15296         (cond [(match_operand:DF 3 "mult_operator")
15297                  (const_string "fmul")
15298                (match_operand:DF 3 "div_operator")
15299                  (const_string "fdiv")
15300               ]
15301               (const_string "fop")))
15302    (set_attr "mode" "SF")])
15304 (define_insn "*fop_df_5_i387"
15305   [(set (match_operand:DF 0 "register_operand" "=f,f")
15306         (match_operator:DF 3 "binary_fp_operator"
15307           [(match_operand:DF 1 "register_operand" "0,f")
15308            (float_extend:DF
15309             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15310   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15311    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15312   "* return output_387_binary_op (insn, operands);"
15313   [(set (attr "type")
15314         (cond [(match_operand:DF 3 "mult_operator")
15315                  (const_string "fmul")
15316                (match_operand:DF 3 "div_operator")
15317                  (const_string "fdiv")
15318               ]
15319               (const_string "fop")))
15320    (set_attr "mode" "SF")])
15322 (define_insn "*fop_df_6_i387"
15323   [(set (match_operand:DF 0 "register_operand" "=f,f")
15324         (match_operator:DF 3 "binary_fp_operator"
15325           [(float_extend:DF
15326             (match_operand:SF 1 "register_operand" "0,f"))
15327            (float_extend:DF
15328             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15329   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15330    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15331   "* return output_387_binary_op (insn, operands);"
15332   [(set (attr "type")
15333         (cond [(match_operand:DF 3 "mult_operator")
15334                  (const_string "fmul")
15335                (match_operand:DF 3 "div_operator")
15336                  (const_string "fdiv")
15337               ]
15338               (const_string "fop")))
15339    (set_attr "mode" "SF")])
15341 (define_insn "*fop_xf_comm_i387"
15342   [(set (match_operand:XF 0 "register_operand" "=f")
15343         (match_operator:XF 3 "binary_fp_operator"
15344                         [(match_operand:XF 1 "register_operand" "%0")
15345                          (match_operand:XF 2 "register_operand" "f")]))]
15346   "TARGET_80387
15347    && COMMUTATIVE_ARITH_P (operands[3])"
15348   "* return output_387_binary_op (insn, operands);"
15349   [(set (attr "type")
15350         (if_then_else (match_operand:XF 3 "mult_operator")
15351            (const_string "fmul")
15352            (const_string "fop")))
15353    (set_attr "mode" "XF")])
15355 (define_insn "*fop_xf_1_i387"
15356   [(set (match_operand:XF 0 "register_operand" "=f,f")
15357         (match_operator:XF 3 "binary_fp_operator"
15358                         [(match_operand:XF 1 "register_operand" "0,f")
15359                          (match_operand:XF 2 "register_operand" "f,0")]))]
15360   "TARGET_80387
15361    && !COMMUTATIVE_ARITH_P (operands[3])"
15362   "* return output_387_binary_op (insn, operands);"
15363   [(set (attr "type")
15364         (if_then_else (match_operand:XF 3 "div_operator")
15365            (const_string "fdiv")
15366            (const_string "fop")))
15367    (set_attr "mode" "XF")])
15369 (define_insn "*fop_xf_2_i387"
15370   [(set (match_operand:XF 0 "register_operand" "=f")
15371         (match_operator:XF 3 "binary_fp_operator"
15372           [(float:XF
15373              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15374            (match_operand:XF 2 "register_operand" "0")]))]
15375   "TARGET_80387
15376    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15377   "* return output_387_binary_op (insn, operands);"
15378   [(set (attr "type")
15379         (cond [(match_operand:XF 3 "mult_operator")
15380                  (const_string "fmul")
15381                (match_operand:XF 3 "div_operator")
15382                  (const_string "fdiv")
15383               ]
15384               (const_string "fop")))
15385    (set_attr "fp_int_src" "true")
15386    (set_attr "mode" "<MODE>")])
15388 (define_insn "*fop_xf_3_i387"
15389   [(set (match_operand:XF 0 "register_operand" "=f")
15390         (match_operator:XF 3 "binary_fp_operator"
15391           [(match_operand:XF 1 "register_operand" "0")
15392            (float:XF
15393              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15394   "TARGET_80387
15395    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15396   "* return output_387_binary_op (insn, operands);"
15397   [(set (attr "type")
15398         (cond [(match_operand:XF 3 "mult_operator")
15399                  (const_string "fmul")
15400                (match_operand:XF 3 "div_operator")
15401                  (const_string "fdiv")
15402               ]
15403               (const_string "fop")))
15404    (set_attr "fp_int_src" "true")
15405    (set_attr "mode" "<MODE>")])
15407 (define_insn "*fop_xf_4_i387"
15408   [(set (match_operand:XF 0 "register_operand" "=f,f")
15409         (match_operator:XF 3 "binary_fp_operator"
15410            [(float_extend:XF
15411               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15412             (match_operand:XF 2 "register_operand" "0,f")]))]
15413   "TARGET_80387"
15414   "* return output_387_binary_op (insn, operands);"
15415   [(set (attr "type")
15416         (cond [(match_operand:XF 3 "mult_operator")
15417                  (const_string "fmul")
15418                (match_operand:XF 3 "div_operator")
15419                  (const_string "fdiv")
15420               ]
15421               (const_string "fop")))
15422    (set_attr "mode" "<MODE>")])
15424 (define_insn "*fop_xf_5_i387"
15425   [(set (match_operand:XF 0 "register_operand" "=f,f")
15426         (match_operator:XF 3 "binary_fp_operator"
15427           [(match_operand:XF 1 "register_operand" "0,f")
15428            (float_extend:XF
15429              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15430   "TARGET_80387"
15431   "* return output_387_binary_op (insn, operands);"
15432   [(set (attr "type")
15433         (cond [(match_operand:XF 3 "mult_operator")
15434                  (const_string "fmul")
15435                (match_operand:XF 3 "div_operator")
15436                  (const_string "fdiv")
15437               ]
15438               (const_string "fop")))
15439    (set_attr "mode" "<MODE>")])
15441 (define_insn "*fop_xf_6_i387"
15442   [(set (match_operand:XF 0 "register_operand" "=f,f")
15443         (match_operator:XF 3 "binary_fp_operator"
15444           [(float_extend:XF
15445              (match_operand:MODEF 1 "register_operand" "0,f"))
15446            (float_extend:XF
15447              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15448   "TARGET_80387"
15449   "* return output_387_binary_op (insn, operands);"
15450   [(set (attr "type")
15451         (cond [(match_operand:XF 3 "mult_operator")
15452                  (const_string "fmul")
15453                (match_operand:XF 3 "div_operator")
15454                  (const_string "fdiv")
15455               ]
15456               (const_string "fop")))
15457    (set_attr "mode" "<MODE>")])
15459 ;; FPU special functions.
15461 ;; This pattern implements a no-op XFmode truncation for
15462 ;; all fancy i386 XFmode math functions.
15464 (define_insn "truncxf<mode>2_i387_noop_unspec"
15465   [(set (match_operand:MODEF 0 "register_operand" "=f")
15466         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15467         UNSPEC_TRUNC_NOOP))]
15468   "TARGET_USE_FANCY_MATH_387"
15469   "* return output_387_reg_move (insn, operands);"
15470   [(set_attr "type" "fmov")
15471    (set_attr "mode" "<MODE>")])
15473 (define_insn "sqrtxf2"
15474   [(set (match_operand:XF 0 "register_operand" "=f")
15475         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15476   "TARGET_USE_FANCY_MATH_387"
15477   "fsqrt"
15478   [(set_attr "type" "fpspc")
15479    (set_attr "mode" "XF")
15480    (set_attr "athlon_decode" "direct")
15481    (set_attr "amdfam10_decode" "direct")
15482    (set_attr "bdver1_decode" "direct")])
15484 (define_insn "sqrt_extend<mode>xf2_i387"
15485   [(set (match_operand:XF 0 "register_operand" "=f")
15486         (sqrt:XF
15487           (float_extend:XF
15488             (match_operand:MODEF 1 "register_operand" "0"))))]
15489   "TARGET_USE_FANCY_MATH_387"
15490   "fsqrt"
15491   [(set_attr "type" "fpspc")
15492    (set_attr "mode" "XF")
15493    (set_attr "athlon_decode" "direct")
15494    (set_attr "amdfam10_decode" "direct")
15495    (set_attr "bdver1_decode" "direct")])
15497 (define_insn "*rsqrtsf2_sse"
15498   [(set (match_operand:SF 0 "register_operand" "=x,x")
15499         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
15500                    UNSPEC_RSQRT))]
15501   "TARGET_SSE && TARGET_SSE_MATH"
15502   "@
15503    %vrsqrtss\t{%d1, %0|%0, %d1}
15504    %vrsqrtss\t{%1, %d0|%d0, %1}"
15505   [(set_attr "type" "sse")
15506    (set_attr "atom_sse_attr" "rcp")
15507    (set_attr "btver2_sse_attr" "rcp")
15508    (set_attr "prefix" "maybe_vex")
15509    (set_attr "mode" "SF")])
15511 (define_expand "rsqrtsf2"
15512   [(set (match_operand:SF 0 "register_operand")
15513         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15514                    UNSPEC_RSQRT))]
15515   "TARGET_SSE && TARGET_SSE_MATH"
15517   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15518   DONE;
15521 (define_insn "*sqrt<mode>2_sse"
15522   [(set (match_operand:MODEF 0 "register_operand" "=v,v")
15523         (sqrt:MODEF
15524           (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
15525   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15526   "@
15527    %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15528    %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15529   [(set_attr "type" "sse")
15530    (set_attr "atom_sse_attr" "sqrt")
15531    (set_attr "btver2_sse_attr" "sqrt")
15532    (set_attr "prefix" "maybe_vex")
15533    (set_attr "mode" "<MODE>")
15534    (set_attr "athlon_decode" "*")
15535    (set_attr "amdfam10_decode" "*")
15536    (set_attr "bdver1_decode" "*")])
15538 (define_expand "sqrt<mode>2"
15539   [(set (match_operand:MODEF 0 "register_operand")
15540         (sqrt:MODEF
15541           (match_operand:MODEF 1 "nonimmediate_operand")))]
15542   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15543    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15545   if (<MODE>mode == SFmode
15546       && TARGET_SSE && TARGET_SSE_MATH
15547       && TARGET_RECIP_SQRT
15548       && !optimize_function_for_size_p (cfun)
15549       && flag_finite_math_only && !flag_trapping_math
15550       && flag_unsafe_math_optimizations)
15551     {
15552       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15553       DONE;
15554     }
15556   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15557     {
15558       rtx op0 = gen_reg_rtx (XFmode);
15559       rtx op1 = force_reg (<MODE>mode, operands[1]);
15561       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15562       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15563       DONE;
15564    }
15567 (define_insn "fpremxf4_i387"
15568   [(set (match_operand:XF 0 "register_operand" "=f")
15569         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15570                     (match_operand:XF 3 "register_operand" "1")]
15571                    UNSPEC_FPREM_F))
15572    (set (match_operand:XF 1 "register_operand" "=u")
15573         (unspec:XF [(match_dup 2) (match_dup 3)]
15574                    UNSPEC_FPREM_U))
15575    (set (reg:CCFP FPSR_REG)
15576         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15577                      UNSPEC_C2_FLAG))]
15578   "TARGET_USE_FANCY_MATH_387
15579    && flag_finite_math_only"
15580   "fprem"
15581   [(set_attr "type" "fpspc")
15582    (set_attr "znver1_decode" "vector")
15583    (set_attr "mode" "XF")])
15585 (define_expand "fmodxf3"
15586   [(use (match_operand:XF 0 "register_operand"))
15587    (use (match_operand:XF 1 "general_operand"))
15588    (use (match_operand:XF 2 "general_operand"))]
15589   "TARGET_USE_FANCY_MATH_387
15590    && flag_finite_math_only"
15592   rtx_code_label *label = gen_label_rtx ();
15594   rtx op1 = gen_reg_rtx (XFmode);
15595   rtx op2 = gen_reg_rtx (XFmode);
15597   emit_move_insn (op2, operands[2]);
15598   emit_move_insn (op1, operands[1]);
15600   emit_label (label);
15601   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15602   ix86_emit_fp_unordered_jump (label);
15603   LABEL_NUSES (label) = 1;
15605   emit_move_insn (operands[0], op1);
15606   DONE;
15609 (define_expand "fmod<mode>3"
15610   [(use (match_operand:MODEF 0 "register_operand"))
15611    (use (match_operand:MODEF 1 "general_operand"))
15612    (use (match_operand:MODEF 2 "general_operand"))]
15613   "TARGET_USE_FANCY_MATH_387
15614    && flag_finite_math_only"
15616   rtx (*gen_truncxf) (rtx, rtx);
15618   rtx_code_label *label = gen_label_rtx ();
15620   rtx op1 = gen_reg_rtx (XFmode);
15621   rtx op2 = gen_reg_rtx (XFmode);
15623   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15624   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15626   emit_label (label);
15627   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15628   ix86_emit_fp_unordered_jump (label);
15629   LABEL_NUSES (label) = 1;
15631   /* Truncate the result properly for strict SSE math.  */
15632   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15633       && !TARGET_MIX_SSE_I387)
15634     gen_truncxf = gen_truncxf<mode>2;
15635   else
15636     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15638   emit_insn (gen_truncxf (operands[0], op1));
15639   DONE;
15642 (define_insn "fprem1xf4_i387"
15643   [(set (match_operand:XF 0 "register_operand" "=f")
15644         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15645                     (match_operand:XF 3 "register_operand" "1")]
15646                    UNSPEC_FPREM1_F))
15647    (set (match_operand:XF 1 "register_operand" "=u")
15648         (unspec:XF [(match_dup 2) (match_dup 3)]
15649                    UNSPEC_FPREM1_U))
15650    (set (reg:CCFP FPSR_REG)
15651         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15652                      UNSPEC_C2_FLAG))]
15653   "TARGET_USE_FANCY_MATH_387
15654    && flag_finite_math_only"
15655   "fprem1"
15656   [(set_attr "type" "fpspc")
15657    (set_attr "znver1_decode" "vector")
15658    (set_attr "mode" "XF")])
15660 (define_expand "remainderxf3"
15661   [(use (match_operand:XF 0 "register_operand"))
15662    (use (match_operand:XF 1 "general_operand"))
15663    (use (match_operand:XF 2 "general_operand"))]
15664   "TARGET_USE_FANCY_MATH_387
15665    && flag_finite_math_only"
15667   rtx_code_label *label = gen_label_rtx ();
15669   rtx op1 = gen_reg_rtx (XFmode);
15670   rtx op2 = gen_reg_rtx (XFmode);
15672   emit_move_insn (op2, operands[2]);
15673   emit_move_insn (op1, operands[1]);
15675   emit_label (label);
15676   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15677   ix86_emit_fp_unordered_jump (label);
15678   LABEL_NUSES (label) = 1;
15680   emit_move_insn (operands[0], op1);
15681   DONE;
15684 (define_expand "remainder<mode>3"
15685   [(use (match_operand:MODEF 0 "register_operand"))
15686    (use (match_operand:MODEF 1 "general_operand"))
15687    (use (match_operand:MODEF 2 "general_operand"))]
15688   "TARGET_USE_FANCY_MATH_387
15689    && flag_finite_math_only"
15691   rtx (*gen_truncxf) (rtx, rtx);
15693   rtx_code_label *label = gen_label_rtx ();
15695   rtx op1 = gen_reg_rtx (XFmode);
15696   rtx op2 = gen_reg_rtx (XFmode);
15698   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15699   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15701   emit_label (label);
15703   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15704   ix86_emit_fp_unordered_jump (label);
15705   LABEL_NUSES (label) = 1;
15707   /* Truncate the result properly for strict SSE math.  */
15708   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15709       && !TARGET_MIX_SSE_I387)
15710     gen_truncxf = gen_truncxf<mode>2;
15711   else
15712     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15714   emit_insn (gen_truncxf (operands[0], op1));
15715   DONE;
15718 (define_int_iterator SINCOS
15719         [UNSPEC_SIN
15720          UNSPEC_COS])
15722 (define_int_attr sincos
15723         [(UNSPEC_SIN "sin")
15724          (UNSPEC_COS "cos")])
15726 (define_insn "*<sincos>xf2_i387"
15727   [(set (match_operand:XF 0 "register_operand" "=f")
15728         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15729                    SINCOS))]
15730   "TARGET_USE_FANCY_MATH_387
15731    && flag_unsafe_math_optimizations"
15732   "f<sincos>"
15733   [(set_attr "type" "fpspc")
15734    (set_attr "znver1_decode" "vector")
15735    (set_attr "mode" "XF")])
15737 (define_insn "*<sincos>_extend<mode>xf2_i387"
15738   [(set (match_operand:XF 0 "register_operand" "=f")
15739         (unspec:XF [(float_extend:XF
15740                       (match_operand:MODEF 1 "register_operand" "0"))]
15741                    SINCOS))]
15742   "TARGET_USE_FANCY_MATH_387
15743    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15744        || TARGET_MIX_SSE_I387)
15745    && flag_unsafe_math_optimizations"
15746   "f<sincos>"
15747   [(set_attr "type" "fpspc")
15748    (set_attr "znver1_decode" "vector")
15749    (set_attr "mode" "XF")])
15751 ;; When sincos pattern is defined, sin and cos builtin functions will be
15752 ;; expanded to sincos pattern with one of its outputs left unused.
15753 ;; CSE pass will figure out if two sincos patterns can be combined,
15754 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15755 ;; depending on the unused output.
15757 (define_insn "sincosxf3"
15758   [(set (match_operand:XF 0 "register_operand" "=f")
15759         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15760                    UNSPEC_SINCOS_COS))
15761    (set (match_operand:XF 1 "register_operand" "=u")
15762         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15763   "TARGET_USE_FANCY_MATH_387
15764    && flag_unsafe_math_optimizations"
15765   "fsincos"
15766   [(set_attr "type" "fpspc")
15767    (set_attr "znver1_decode" "vector")
15768    (set_attr "mode" "XF")])
15770 (define_split
15771   [(set (match_operand:XF 0 "register_operand")
15772         (unspec:XF [(match_operand:XF 2 "register_operand")]
15773                    UNSPEC_SINCOS_COS))
15774    (set (match_operand:XF 1 "register_operand")
15775         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15776   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15777    && can_create_pseudo_p ()"
15778   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15780 (define_split
15781   [(set (match_operand:XF 0 "register_operand")
15782         (unspec:XF [(match_operand:XF 2 "register_operand")]
15783                    UNSPEC_SINCOS_COS))
15784    (set (match_operand:XF 1 "register_operand")
15785         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15786   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15787    && can_create_pseudo_p ()"
15788   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15790 (define_insn "sincos_extend<mode>xf3_i387"
15791   [(set (match_operand:XF 0 "register_operand" "=f")
15792         (unspec:XF [(float_extend:XF
15793                       (match_operand:MODEF 2 "register_operand" "0"))]
15794                    UNSPEC_SINCOS_COS))
15795    (set (match_operand:XF 1 "register_operand" "=u")
15796         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15797   "TARGET_USE_FANCY_MATH_387
15798    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15799        || TARGET_MIX_SSE_I387)
15800    && flag_unsafe_math_optimizations"
15801   "fsincos"
15802   [(set_attr "type" "fpspc")
15803    (set_attr "znver1_decode" "vector")
15804    (set_attr "mode" "XF")])
15806 (define_split
15807   [(set (match_operand:XF 0 "register_operand")
15808         (unspec:XF [(float_extend:XF
15809                       (match_operand:MODEF 2 "register_operand"))]
15810                    UNSPEC_SINCOS_COS))
15811    (set (match_operand:XF 1 "register_operand")
15812         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15813   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15814    && can_create_pseudo_p ()"
15815   [(set (match_dup 1)
15816         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15818 (define_split
15819   [(set (match_operand:XF 0 "register_operand")
15820         (unspec:XF [(float_extend:XF
15821                       (match_operand:MODEF 2 "register_operand"))]
15822                    UNSPEC_SINCOS_COS))
15823    (set (match_operand:XF 1 "register_operand")
15824         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15825   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15826    && can_create_pseudo_p ()"
15827   [(set (match_dup 0)
15828         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15830 (define_expand "sincos<mode>3"
15831   [(use (match_operand:MODEF 0 "register_operand"))
15832    (use (match_operand:MODEF 1 "register_operand"))
15833    (use (match_operand:MODEF 2 "register_operand"))]
15834   "TARGET_USE_FANCY_MATH_387
15835    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15836        || TARGET_MIX_SSE_I387)
15837    && flag_unsafe_math_optimizations"
15839   rtx op0 = gen_reg_rtx (XFmode);
15840   rtx op1 = gen_reg_rtx (XFmode);
15842   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15843   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15844   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15845   DONE;
15848 (define_insn "fptanxf4_i387"
15849   [(set (match_operand:XF 0 "register_operand" "=f")
15850         (match_operand:XF 3 "const_double_operand" "F"))
15851    (set (match_operand:XF 1 "register_operand" "=u")
15852         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15853                    UNSPEC_TAN))]
15854   "TARGET_USE_FANCY_MATH_387
15855    && flag_unsafe_math_optimizations
15856    && standard_80387_constant_p (operands[3]) == 2"
15857   "fptan"
15858   [(set_attr "type" "fpspc")
15859    (set_attr "znver1_decode" "vector")
15860    (set_attr "mode" "XF")])
15862 (define_insn "fptan_extend<mode>xf4_i387"
15863   [(set (match_operand:MODEF 0 "register_operand" "=f")
15864         (match_operand:MODEF 3 "const_double_operand" "F"))
15865    (set (match_operand:XF 1 "register_operand" "=u")
15866         (unspec:XF [(float_extend:XF
15867                       (match_operand:MODEF 2 "register_operand" "0"))]
15868                    UNSPEC_TAN))]
15869   "TARGET_USE_FANCY_MATH_387
15870    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15871        || TARGET_MIX_SSE_I387)
15872    && flag_unsafe_math_optimizations
15873    && standard_80387_constant_p (operands[3]) == 2"
15874   "fptan"
15875   [(set_attr "type" "fpspc")
15876    (set_attr "znver1_decode" "vector")
15877    (set_attr "mode" "XF")])
15879 (define_expand "tanxf2"
15880   [(use (match_operand:XF 0 "register_operand"))
15881    (use (match_operand:XF 1 "register_operand"))]
15882   "TARGET_USE_FANCY_MATH_387
15883    && flag_unsafe_math_optimizations"
15885   rtx one = gen_reg_rtx (XFmode);
15886   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15888   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15889   DONE;
15892 (define_expand "tan<mode>2"
15893   [(use (match_operand:MODEF 0 "register_operand"))
15894    (use (match_operand:MODEF 1 "register_operand"))]
15895   "TARGET_USE_FANCY_MATH_387
15896    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15897        || TARGET_MIX_SSE_I387)
15898    && flag_unsafe_math_optimizations"
15900   rtx op0 = gen_reg_rtx (XFmode);
15902   rtx one = gen_reg_rtx (<MODE>mode);
15903   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15905   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15906                                              operands[1], op2));
15907   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15908   DONE;
15911 (define_insn "*fpatanxf3_i387"
15912   [(set (match_operand:XF 0 "register_operand" "=f")
15913         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15914                     (match_operand:XF 2 "register_operand" "u")]
15915                    UNSPEC_FPATAN))
15916    (clobber (match_scratch:XF 3 "=2"))]
15917   "TARGET_USE_FANCY_MATH_387
15918    && flag_unsafe_math_optimizations"
15919   "fpatan"
15920   [(set_attr "type" "fpspc")
15921    (set_attr "znver1_decode" "vector")
15922    (set_attr "mode" "XF")])
15924 (define_insn "fpatan_extend<mode>xf3_i387"
15925   [(set (match_operand:XF 0 "register_operand" "=f")
15926         (unspec:XF [(float_extend:XF
15927                       (match_operand:MODEF 1 "register_operand" "0"))
15928                     (float_extend:XF
15929                       (match_operand:MODEF 2 "register_operand" "u"))]
15930                    UNSPEC_FPATAN))
15931    (clobber (match_scratch:XF 3 "=2"))]
15932   "TARGET_USE_FANCY_MATH_387
15933    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15934        || TARGET_MIX_SSE_I387)
15935    && flag_unsafe_math_optimizations"
15936   "fpatan"
15937   [(set_attr "type" "fpspc")
15938    (set_attr "znver1_decode" "vector")
15939    (set_attr "mode" "XF")])
15941 (define_expand "atan2xf3"
15942   [(parallel [(set (match_operand:XF 0 "register_operand")
15943                    (unspec:XF [(match_operand:XF 2 "register_operand")
15944                                (match_operand:XF 1 "register_operand")]
15945                               UNSPEC_FPATAN))
15946               (clobber (match_scratch:XF 3))])]
15947   "TARGET_USE_FANCY_MATH_387
15948    && flag_unsafe_math_optimizations")
15950 (define_expand "atan2<mode>3"
15951   [(use (match_operand:MODEF 0 "register_operand"))
15952    (use (match_operand:MODEF 1 "register_operand"))
15953    (use (match_operand:MODEF 2 "register_operand"))]
15954   "TARGET_USE_FANCY_MATH_387
15955    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15956        || TARGET_MIX_SSE_I387)
15957    && flag_unsafe_math_optimizations"
15959   rtx op0 = gen_reg_rtx (XFmode);
15961   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15962   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15963   DONE;
15966 (define_expand "atanxf2"
15967   [(parallel [(set (match_operand:XF 0 "register_operand")
15968                    (unspec:XF [(match_dup 2)
15969                                (match_operand:XF 1 "register_operand")]
15970                               UNSPEC_FPATAN))
15971               (clobber (match_scratch:XF 3))])]
15972   "TARGET_USE_FANCY_MATH_387
15973    && flag_unsafe_math_optimizations"
15975   operands[2] = gen_reg_rtx (XFmode);
15976   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15979 (define_expand "atan<mode>2"
15980   [(use (match_operand:MODEF 0 "register_operand"))
15981    (use (match_operand:MODEF 1 "register_operand"))]
15982   "TARGET_USE_FANCY_MATH_387
15983    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15984        || TARGET_MIX_SSE_I387)
15985    && flag_unsafe_math_optimizations"
15987   rtx op0 = gen_reg_rtx (XFmode);
15989   rtx op2 = gen_reg_rtx (<MODE>mode);
15990   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15992   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15993   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15994   DONE;
15997 (define_expand "asinxf2"
15998   [(set (match_dup 2)
15999         (mult:XF (match_operand:XF 1 "register_operand")
16000                  (match_dup 1)))
16001    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16002    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16003    (parallel [(set (match_operand:XF 0 "register_operand")
16004                    (unspec:XF [(match_dup 5) (match_dup 1)]
16005                               UNSPEC_FPATAN))
16006               (clobber (match_scratch:XF 6))])]
16007   "TARGET_USE_FANCY_MATH_387
16008    && flag_unsafe_math_optimizations"
16010   int i;
16012   for (i = 2; i < 6; i++)
16013     operands[i] = gen_reg_rtx (XFmode);
16015   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16018 (define_expand "asin<mode>2"
16019   [(use (match_operand:MODEF 0 "register_operand"))
16020    (use (match_operand:MODEF 1 "general_operand"))]
16021   "TARGET_USE_FANCY_MATH_387
16022    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16023        || TARGET_MIX_SSE_I387)
16024    && flag_unsafe_math_optimizations"
16026   rtx op0 = gen_reg_rtx (XFmode);
16027   rtx op1 = gen_reg_rtx (XFmode);
16029   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16030   emit_insn (gen_asinxf2 (op0, op1));
16031   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16032   DONE;
16035 (define_expand "acosxf2"
16036   [(set (match_dup 2)
16037         (mult:XF (match_operand:XF 1 "register_operand")
16038                  (match_dup 1)))
16039    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16040    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16041    (parallel [(set (match_operand:XF 0 "register_operand")
16042                    (unspec:XF [(match_dup 1) (match_dup 5)]
16043                               UNSPEC_FPATAN))
16044               (clobber (match_scratch:XF 6))])]
16045   "TARGET_USE_FANCY_MATH_387
16046    && flag_unsafe_math_optimizations"
16048   int i;
16050   for (i = 2; i < 6; i++)
16051     operands[i] = gen_reg_rtx (XFmode);
16053   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16056 (define_expand "acos<mode>2"
16057   [(use (match_operand:MODEF 0 "register_operand"))
16058    (use (match_operand:MODEF 1 "general_operand"))]
16059   "TARGET_USE_FANCY_MATH_387
16060    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16061        || TARGET_MIX_SSE_I387)
16062    && flag_unsafe_math_optimizations"
16064   rtx op0 = gen_reg_rtx (XFmode);
16065   rtx op1 = gen_reg_rtx (XFmode);
16067   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16068   emit_insn (gen_acosxf2 (op0, op1));
16069   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16070   DONE;
16073 (define_insn "fyl2xxf3_i387"
16074   [(set (match_operand:XF 0 "register_operand" "=f")
16075         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16076                     (match_operand:XF 2 "register_operand" "u")]
16077                    UNSPEC_FYL2X))
16078    (clobber (match_scratch:XF 3 "=2"))]
16079   "TARGET_USE_FANCY_MATH_387
16080    && flag_unsafe_math_optimizations"
16081   "fyl2x"
16082   [(set_attr "type" "fpspc")
16083    (set_attr "znver1_decode" "vector")
16084    (set_attr "mode" "XF")])
16086 (define_insn "fyl2x_extend<mode>xf3_i387"
16087   [(set (match_operand:XF 0 "register_operand" "=f")
16088         (unspec:XF [(float_extend:XF
16089                       (match_operand:MODEF 1 "register_operand" "0"))
16090                     (match_operand:XF 2 "register_operand" "u")]
16091                    UNSPEC_FYL2X))
16092    (clobber (match_scratch:XF 3 "=2"))]
16093   "TARGET_USE_FANCY_MATH_387
16094    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16095        || TARGET_MIX_SSE_I387)
16096    && flag_unsafe_math_optimizations"
16097   "fyl2x"
16098   [(set_attr "type" "fpspc")
16099    (set_attr "znver1_decode" "vector")
16100    (set_attr "mode" "XF")])
16102 (define_expand "logxf2"
16103   [(parallel [(set (match_operand:XF 0 "register_operand")
16104                    (unspec:XF [(match_operand:XF 1 "register_operand")
16105                                (match_dup 2)] UNSPEC_FYL2X))
16106               (clobber (match_scratch:XF 3))])]
16107   "TARGET_USE_FANCY_MATH_387
16108    && flag_unsafe_math_optimizations"
16110   operands[2] = gen_reg_rtx (XFmode);
16111   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16114 (define_expand "log<mode>2"
16115   [(use (match_operand:MODEF 0 "register_operand"))
16116    (use (match_operand:MODEF 1 "register_operand"))]
16117   "TARGET_USE_FANCY_MATH_387
16118    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16119        || TARGET_MIX_SSE_I387)
16120    && flag_unsafe_math_optimizations"
16122   rtx op0 = gen_reg_rtx (XFmode);
16124   rtx op2 = gen_reg_rtx (XFmode);
16125   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16127   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16128   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16129   DONE;
16132 (define_expand "log10xf2"
16133   [(parallel [(set (match_operand:XF 0 "register_operand")
16134                    (unspec:XF [(match_operand:XF 1 "register_operand")
16135                                (match_dup 2)] UNSPEC_FYL2X))
16136               (clobber (match_scratch:XF 3))])]
16137   "TARGET_USE_FANCY_MATH_387
16138    && flag_unsafe_math_optimizations"
16140   operands[2] = gen_reg_rtx (XFmode);
16141   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16144 (define_expand "log10<mode>2"
16145   [(use (match_operand:MODEF 0 "register_operand"))
16146    (use (match_operand:MODEF 1 "register_operand"))]
16147   "TARGET_USE_FANCY_MATH_387
16148    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16149        || TARGET_MIX_SSE_I387)
16150    && flag_unsafe_math_optimizations"
16152   rtx op0 = gen_reg_rtx (XFmode);
16154   rtx op2 = gen_reg_rtx (XFmode);
16155   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16157   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16158   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16159   DONE;
16162 (define_expand "log2xf2"
16163   [(parallel [(set (match_operand:XF 0 "register_operand")
16164                    (unspec:XF [(match_operand:XF 1 "register_operand")
16165                                (match_dup 2)] UNSPEC_FYL2X))
16166               (clobber (match_scratch:XF 3))])]
16167   "TARGET_USE_FANCY_MATH_387
16168    && flag_unsafe_math_optimizations"
16170   operands[2] = gen_reg_rtx (XFmode);
16171   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16174 (define_expand "log2<mode>2"
16175   [(use (match_operand:MODEF 0 "register_operand"))
16176    (use (match_operand:MODEF 1 "register_operand"))]
16177   "TARGET_USE_FANCY_MATH_387
16178    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16179        || TARGET_MIX_SSE_I387)
16180    && flag_unsafe_math_optimizations"
16182   rtx op0 = gen_reg_rtx (XFmode);
16184   rtx op2 = gen_reg_rtx (XFmode);
16185   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16187   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16188   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16189   DONE;
16192 (define_insn "fyl2xp1xf3_i387"
16193   [(set (match_operand:XF 0 "register_operand" "=f")
16194         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16195                     (match_operand:XF 2 "register_operand" "u")]
16196                    UNSPEC_FYL2XP1))
16197    (clobber (match_scratch:XF 3 "=2"))]
16198   "TARGET_USE_FANCY_MATH_387
16199    && flag_unsafe_math_optimizations"
16200   "fyl2xp1"
16201   [(set_attr "type" "fpspc")
16202    (set_attr "znver1_decode" "vector")
16203    (set_attr "mode" "XF")])
16205 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16206   [(set (match_operand:XF 0 "register_operand" "=f")
16207         (unspec:XF [(float_extend:XF
16208                       (match_operand:MODEF 1 "register_operand" "0"))
16209                     (match_operand:XF 2 "register_operand" "u")]
16210                    UNSPEC_FYL2XP1))
16211    (clobber (match_scratch:XF 3 "=2"))]
16212   "TARGET_USE_FANCY_MATH_387
16213    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16214        || TARGET_MIX_SSE_I387)
16215    && flag_unsafe_math_optimizations"
16216   "fyl2xp1"
16217   [(set_attr "type" "fpspc")
16218    (set_attr "znver1_decode" "vector")
16219    (set_attr "mode" "XF")])
16221 (define_expand "log1pxf2"
16222   [(use (match_operand:XF 0 "register_operand"))
16223    (use (match_operand:XF 1 "register_operand"))]
16224   "TARGET_USE_FANCY_MATH_387
16225    && flag_unsafe_math_optimizations"
16227   ix86_emit_i387_log1p (operands[0], operands[1]);
16228   DONE;
16231 (define_expand "log1p<mode>2"
16232   [(use (match_operand:MODEF 0 "register_operand"))
16233    (use (match_operand:MODEF 1 "register_operand"))]
16234   "TARGET_USE_FANCY_MATH_387
16235    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16236        || TARGET_MIX_SSE_I387)
16237    && flag_unsafe_math_optimizations"
16239   rtx op0;
16241   op0 = gen_reg_rtx (XFmode);
16243   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16245   ix86_emit_i387_log1p (op0, operands[1]);
16246   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16247   DONE;
16250 (define_insn "fxtractxf3_i387"
16251   [(set (match_operand:XF 0 "register_operand" "=f")
16252         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16253                    UNSPEC_XTRACT_FRACT))
16254    (set (match_operand:XF 1 "register_operand" "=u")
16255         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16256   "TARGET_USE_FANCY_MATH_387
16257    && flag_unsafe_math_optimizations"
16258   "fxtract"
16259   [(set_attr "type" "fpspc")
16260    (set_attr "znver1_decode" "vector")
16261    (set_attr "mode" "XF")])
16263 (define_insn "fxtract_extend<mode>xf3_i387"
16264   [(set (match_operand:XF 0 "register_operand" "=f")
16265         (unspec:XF [(float_extend:XF
16266                       (match_operand:MODEF 2 "register_operand" "0"))]
16267                    UNSPEC_XTRACT_FRACT))
16268    (set (match_operand:XF 1 "register_operand" "=u")
16269         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16270   "TARGET_USE_FANCY_MATH_387
16271    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16272        || TARGET_MIX_SSE_I387)
16273    && flag_unsafe_math_optimizations"
16274   "fxtract"
16275   [(set_attr "type" "fpspc")
16276    (set_attr "znver1_decode" "vector")
16277    (set_attr "mode" "XF")])
16279 (define_expand "logbxf2"
16280   [(parallel [(set (match_dup 2)
16281                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16282                               UNSPEC_XTRACT_FRACT))
16283               (set (match_operand:XF 0 "register_operand")
16284                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16285   "TARGET_USE_FANCY_MATH_387
16286    && flag_unsafe_math_optimizations"
16287   "operands[2] = gen_reg_rtx (XFmode);")
16289 (define_expand "logb<mode>2"
16290   [(use (match_operand:MODEF 0 "register_operand"))
16291    (use (match_operand:MODEF 1 "register_operand"))]
16292   "TARGET_USE_FANCY_MATH_387
16293    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16294        || TARGET_MIX_SSE_I387)
16295    && flag_unsafe_math_optimizations"
16297   rtx op0 = gen_reg_rtx (XFmode);
16298   rtx op1 = gen_reg_rtx (XFmode);
16300   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16301   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16302   DONE;
16305 (define_expand "ilogbxf2"
16306   [(use (match_operand:SI 0 "register_operand"))
16307    (use (match_operand:XF 1 "register_operand"))]
16308   "TARGET_USE_FANCY_MATH_387
16309    && flag_unsafe_math_optimizations"
16311   rtx op0, op1;
16313   if (optimize_insn_for_size_p ())
16314     FAIL;
16316   op0 = gen_reg_rtx (XFmode);
16317   op1 = gen_reg_rtx (XFmode);
16319   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16320   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16321   DONE;
16324 (define_expand "ilogb<mode>2"
16325   [(use (match_operand:SI 0 "register_operand"))
16326    (use (match_operand:MODEF 1 "register_operand"))]
16327   "TARGET_USE_FANCY_MATH_387
16328    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16329        || TARGET_MIX_SSE_I387)
16330    && flag_unsafe_math_optimizations"
16332   rtx op0, op1;
16334   if (optimize_insn_for_size_p ())
16335     FAIL;
16337   op0 = gen_reg_rtx (XFmode);
16338   op1 = gen_reg_rtx (XFmode);
16340   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16341   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16342   DONE;
16345 (define_insn "*f2xm1xf2_i387"
16346   [(set (match_operand:XF 0 "register_operand" "=f")
16347         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16348                    UNSPEC_F2XM1))]
16349   "TARGET_USE_FANCY_MATH_387
16350    && flag_unsafe_math_optimizations"
16351   "f2xm1"
16352   [(set_attr "type" "fpspc")
16353    (set_attr "znver1_decode" "vector")
16354    (set_attr "mode" "XF")])
16356 (define_insn "fscalexf4_i387"
16357   [(set (match_operand:XF 0 "register_operand" "=f")
16358         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16359                     (match_operand:XF 3 "register_operand" "1")]
16360                    UNSPEC_FSCALE_FRACT))
16361    (set (match_operand:XF 1 "register_operand" "=u")
16362         (unspec:XF [(match_dup 2) (match_dup 3)]
16363                    UNSPEC_FSCALE_EXP))]
16364   "TARGET_USE_FANCY_MATH_387
16365    && flag_unsafe_math_optimizations"
16366   "fscale"
16367   [(set_attr "type" "fpspc")
16368    (set_attr "znver1_decode" "vector")
16369    (set_attr "mode" "XF")])
16371 (define_expand "expNcorexf3"
16372   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16373                                (match_operand:XF 2 "register_operand")))
16374    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16375    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16376    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16377    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16378    (parallel [(set (match_operand:XF 0 "register_operand")
16379                    (unspec:XF [(match_dup 8) (match_dup 4)]
16380                               UNSPEC_FSCALE_FRACT))
16381               (set (match_dup 9)
16382                    (unspec:XF [(match_dup 8) (match_dup 4)]
16383                               UNSPEC_FSCALE_EXP))])]
16384   "TARGET_USE_FANCY_MATH_387
16385    && flag_unsafe_math_optimizations"
16387   int i;
16389   for (i = 3; i < 10; i++)
16390     operands[i] = gen_reg_rtx (XFmode);
16392   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16395 (define_expand "expxf2"
16396   [(use (match_operand:XF 0 "register_operand"))
16397    (use (match_operand:XF 1 "register_operand"))]
16398   "TARGET_USE_FANCY_MATH_387
16399    && flag_unsafe_math_optimizations"
16401   rtx op2;
16403   op2 = gen_reg_rtx (XFmode);
16404   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16406   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16407   DONE;
16410 (define_expand "exp<mode>2"
16411   [(use (match_operand:MODEF 0 "register_operand"))
16412    (use (match_operand:MODEF 1 "general_operand"))]
16413   "TARGET_USE_FANCY_MATH_387
16414    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16415        || TARGET_MIX_SSE_I387)
16416    && flag_unsafe_math_optimizations"
16418   rtx op0, op1;
16420   op0 = gen_reg_rtx (XFmode);
16421   op1 = gen_reg_rtx (XFmode);
16423   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16424   emit_insn (gen_expxf2 (op0, op1));
16425   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16426   DONE;
16429 (define_expand "exp10xf2"
16430   [(use (match_operand:XF 0 "register_operand"))
16431    (use (match_operand:XF 1 "register_operand"))]
16432   "TARGET_USE_FANCY_MATH_387
16433    && flag_unsafe_math_optimizations"
16435   rtx op2;
16437   op2 = gen_reg_rtx (XFmode);
16438   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16440   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16441   DONE;
16444 (define_expand "exp10<mode>2"
16445   [(use (match_operand:MODEF 0 "register_operand"))
16446    (use (match_operand:MODEF 1 "general_operand"))]
16447   "TARGET_USE_FANCY_MATH_387
16448    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16449        || TARGET_MIX_SSE_I387)
16450    && flag_unsafe_math_optimizations"
16452   rtx op0, op1;
16454   op0 = gen_reg_rtx (XFmode);
16455   op1 = gen_reg_rtx (XFmode);
16457   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16458   emit_insn (gen_exp10xf2 (op0, op1));
16459   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16460   DONE;
16463 (define_expand "exp2xf2"
16464   [(use (match_operand:XF 0 "register_operand"))
16465    (use (match_operand:XF 1 "register_operand"))]
16466   "TARGET_USE_FANCY_MATH_387
16467    && flag_unsafe_math_optimizations"
16469   rtx op2;
16471   op2 = gen_reg_rtx (XFmode);
16472   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16474   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16475   DONE;
16478 (define_expand "exp2<mode>2"
16479   [(use (match_operand:MODEF 0 "register_operand"))
16480    (use (match_operand:MODEF 1 "general_operand"))]
16481   "TARGET_USE_FANCY_MATH_387
16482    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16483        || TARGET_MIX_SSE_I387)
16484    && flag_unsafe_math_optimizations"
16486   rtx op0, op1;
16488   op0 = gen_reg_rtx (XFmode);
16489   op1 = gen_reg_rtx (XFmode);
16491   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16492   emit_insn (gen_exp2xf2 (op0, op1));
16493   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16494   DONE;
16497 (define_expand "expm1xf2"
16498   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16499                                (match_dup 2)))
16500    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16501    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16502    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16503    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16504    (parallel [(set (match_dup 7)
16505                    (unspec:XF [(match_dup 6) (match_dup 4)]
16506                               UNSPEC_FSCALE_FRACT))
16507               (set (match_dup 8)
16508                    (unspec:XF [(match_dup 6) (match_dup 4)]
16509                               UNSPEC_FSCALE_EXP))])
16510    (parallel [(set (match_dup 10)
16511                    (unspec:XF [(match_dup 9) (match_dup 8)]
16512                               UNSPEC_FSCALE_FRACT))
16513               (set (match_dup 11)
16514                    (unspec:XF [(match_dup 9) (match_dup 8)]
16515                               UNSPEC_FSCALE_EXP))])
16516    (set (match_dup 12) (minus:XF (match_dup 10)
16517                                  (float_extend:XF (match_dup 13))))
16518    (set (match_operand:XF 0 "register_operand")
16519         (plus:XF (match_dup 12) (match_dup 7)))]
16520   "TARGET_USE_FANCY_MATH_387
16521    && flag_unsafe_math_optimizations"
16523   int i;
16525   for (i = 2; i < 13; i++)
16526     operands[i] = gen_reg_rtx (XFmode);
16528   operands[13]
16529     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16531   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16534 (define_expand "expm1<mode>2"
16535   [(use (match_operand:MODEF 0 "register_operand"))
16536    (use (match_operand:MODEF 1 "general_operand"))]
16537   "TARGET_USE_FANCY_MATH_387
16538    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16539        || TARGET_MIX_SSE_I387)
16540    && flag_unsafe_math_optimizations"
16542   rtx op0, op1;
16544   op0 = gen_reg_rtx (XFmode);
16545   op1 = gen_reg_rtx (XFmode);
16547   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16548   emit_insn (gen_expm1xf2 (op0, op1));
16549   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16550   DONE;
16553 (define_expand "ldexpxf3"
16554   [(match_operand:XF 0 "register_operand")
16555    (match_operand:XF 1 "register_operand")
16556    (match_operand:SI 2 "register_operand")]
16557   "TARGET_USE_FANCY_MATH_387
16558    && flag_unsafe_math_optimizations"
16560   rtx tmp1, tmp2;
16562   tmp1 = gen_reg_rtx (XFmode);
16563   tmp2 = gen_reg_rtx (XFmode);
16565   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16566   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16567                                  operands[1], tmp1));
16568   DONE;
16571 (define_expand "ldexp<mode>3"
16572   [(use (match_operand:MODEF 0 "register_operand"))
16573    (use (match_operand:MODEF 1 "general_operand"))
16574    (use (match_operand:SI 2 "register_operand"))]
16575   "TARGET_USE_FANCY_MATH_387
16576    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16577        || TARGET_MIX_SSE_I387)
16578    && flag_unsafe_math_optimizations"
16580   rtx op0, op1;
16582   op0 = gen_reg_rtx (XFmode);
16583   op1 = gen_reg_rtx (XFmode);
16585   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16586   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16587   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16588   DONE;
16591 (define_expand "scalbxf3"
16592   [(parallel [(set (match_operand:XF 0 " register_operand")
16593                    (unspec:XF [(match_operand:XF 1 "register_operand")
16594                                (match_operand:XF 2 "register_operand")]
16595                               UNSPEC_FSCALE_FRACT))
16596               (set (match_dup 3)
16597                    (unspec:XF [(match_dup 1) (match_dup 2)]
16598                               UNSPEC_FSCALE_EXP))])]
16599   "TARGET_USE_FANCY_MATH_387
16600    && flag_unsafe_math_optimizations"
16602   operands[3] = gen_reg_rtx (XFmode);
16605 (define_expand "scalb<mode>3"
16606   [(use (match_operand:MODEF 0 "register_operand"))
16607    (use (match_operand:MODEF 1 "general_operand"))
16608    (use (match_operand:MODEF 2 "general_operand"))]
16609   "TARGET_USE_FANCY_MATH_387
16610    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16611        || TARGET_MIX_SSE_I387)
16612    && flag_unsafe_math_optimizations"
16614   rtx op0, op1, op2;
16616   op0 = gen_reg_rtx (XFmode);
16617   op1 = gen_reg_rtx (XFmode);
16618   op2 = gen_reg_rtx (XFmode);
16620   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16621   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16622   emit_insn (gen_scalbxf3 (op0, op1, op2));
16623   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16624   DONE;
16627 (define_expand "significandxf2"
16628   [(parallel [(set (match_operand:XF 0 "register_operand")
16629                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16630                               UNSPEC_XTRACT_FRACT))
16631               (set (match_dup 2)
16632                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16633   "TARGET_USE_FANCY_MATH_387
16634    && flag_unsafe_math_optimizations"
16635   "operands[2] = gen_reg_rtx (XFmode);")
16637 (define_expand "significand<mode>2"
16638   [(use (match_operand:MODEF 0 "register_operand"))
16639    (use (match_operand:MODEF 1 "register_operand"))]
16640   "TARGET_USE_FANCY_MATH_387
16641    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16642        || TARGET_MIX_SSE_I387)
16643    && flag_unsafe_math_optimizations"
16645   rtx op0 = gen_reg_rtx (XFmode);
16646   rtx op1 = gen_reg_rtx (XFmode);
16648   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16649   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16650   DONE;
16654 (define_insn "sse4_1_round<mode>2"
16655   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16656         (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
16657                        (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16658                       UNSPEC_ROUND))]
16659   "TARGET_SSE4_1"
16660   "@
16661    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16662    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16663   [(set_attr "type" "ssecvt")
16664    (set_attr "prefix_extra" "1,*")
16665    (set_attr "length_immediate" "*,1")
16666    (set_attr "prefix" "maybe_vex,evex")
16667    (set_attr "isa" "noavx512f,avx512f")
16668    (set_attr "mode" "<MODE>")])
16670 (define_insn "rintxf2"
16671   [(set (match_operand:XF 0 "register_operand" "=f")
16672         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16673                    UNSPEC_FRNDINT))]
16674   "TARGET_USE_FANCY_MATH_387"
16675   "frndint"
16676   [(set_attr "type" "fpspc")
16677    (set_attr "znver1_decode" "vector")
16678    (set_attr "mode" "XF")])
16680 (define_insn "rint<mode>2_frndint"
16681   [(set (match_operand:MODEF 0 "register_operand" "=f")
16682         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16683                       UNSPEC_FRNDINT))]
16684   "TARGET_USE_FANCY_MATH_387"
16685   "frndint"
16686   [(set_attr "type" "fpspc")
16687    (set_attr "znver1_decode" "vector")
16688    (set_attr "mode" "<MODE>")])
16690 (define_expand "rint<mode>2"
16691   [(use (match_operand:MODEF 0 "register_operand"))
16692    (use (match_operand:MODEF 1 "register_operand"))]
16693   "(TARGET_USE_FANCY_MATH_387
16694     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16695         || TARGET_MIX_SSE_I387))
16696    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16698   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16699     {
16700       if (TARGET_SSE4_1)
16701         emit_insn (gen_sse4_1_round<mode>2
16702                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16703       else
16704         ix86_expand_rint (operands[0], operands[1]);
16705     }
16706   else
16707     emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16708   DONE;
16711 (define_expand "round<mode>2"
16712   [(match_operand:X87MODEF 0 "register_operand")
16713    (match_operand:X87MODEF 1 "nonimmediate_operand")]
16714   "(TARGET_USE_FANCY_MATH_387
16715     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16716         || TARGET_MIX_SSE_I387)
16717     && flag_unsafe_math_optimizations
16718     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16719    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16720        && !flag_trapping_math && !flag_rounding_math)"
16722   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16723       && !flag_trapping_math && !flag_rounding_math)
16724     {
16725       if (TARGET_SSE4_1)
16726         {
16727           operands[1] = force_reg (<MODE>mode, operands[1]);
16728           ix86_expand_round_sse4 (operands[0], operands[1]);
16729         }
16730       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16731         ix86_expand_round (operands[0], operands[1]);
16732       else
16733         ix86_expand_rounddf_32 (operands[0], operands[1]);
16734     }
16735   else
16736     {
16737       operands[1] = force_reg (<MODE>mode, operands[1]);
16738       ix86_emit_i387_round (operands[0], operands[1]);
16739     }
16740   DONE;
16743 (define_insn_and_split "*fistdi2_1"
16744   [(set (match_operand:DI 0 "nonimmediate_operand")
16745         (unspec:DI [(match_operand:XF 1 "register_operand")]
16746                    UNSPEC_FIST))]
16747   "TARGET_USE_FANCY_MATH_387
16748    && can_create_pseudo_p ()"
16749   "#"
16750   "&& 1"
16751   [(const_int 0)]
16753   if (memory_operand (operands[0], VOIDmode))
16754     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16755   else
16756     {
16757       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16758       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16759                                          operands[2]));
16760     }
16761   DONE;
16763   [(set_attr "type" "fpspc")
16764    (set_attr "mode" "DI")])
16766 (define_insn "fistdi2"
16767   [(set (match_operand:DI 0 "memory_operand" "=m")
16768         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16769                    UNSPEC_FIST))
16770    (clobber (match_scratch:XF 2 "=&1f"))]
16771   "TARGET_USE_FANCY_MATH_387"
16772   "* return output_fix_trunc (insn, operands, false);"
16773   [(set_attr "type" "fpspc")
16774    (set_attr "mode" "DI")])
16776 (define_insn "fistdi2_with_temp"
16777   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16778         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16779                    UNSPEC_FIST))
16780    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16781    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16782   "TARGET_USE_FANCY_MATH_387"
16783   "#"
16784   [(set_attr "type" "fpspc")
16785    (set_attr "mode" "DI")])
16787 (define_split
16788   [(set (match_operand:DI 0 "register_operand")
16789         (unspec:DI [(match_operand:XF 1 "register_operand")]
16790                    UNSPEC_FIST))
16791    (clobber (match_operand:DI 2 "memory_operand"))
16792    (clobber (match_scratch 3))]
16793   "reload_completed"
16794   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16795               (clobber (match_dup 3))])
16796    (set (match_dup 0) (match_dup 2))])
16798 (define_split
16799   [(set (match_operand:DI 0 "memory_operand")
16800         (unspec:DI [(match_operand:XF 1 "register_operand")]
16801                    UNSPEC_FIST))
16802    (clobber (match_operand:DI 2 "memory_operand"))
16803    (clobber (match_scratch 3))]
16804   "reload_completed"
16805   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16806               (clobber (match_dup 3))])])
16808 (define_insn_and_split "*fist<mode>2_1"
16809   [(set (match_operand:SWI24 0 "register_operand")
16810         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16811                       UNSPEC_FIST))]
16812   "TARGET_USE_FANCY_MATH_387
16813    && can_create_pseudo_p ()"
16814   "#"
16815   "&& 1"
16816   [(const_int 0)]
16818   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16819   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16820                                         operands[2]));
16821   DONE;
16823   [(set_attr "type" "fpspc")
16824    (set_attr "mode" "<MODE>")])
16826 (define_insn "fist<mode>2"
16827   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16828         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16829                       UNSPEC_FIST))]
16830   "TARGET_USE_FANCY_MATH_387"
16831   "* return output_fix_trunc (insn, operands, false);"
16832   [(set_attr "type" "fpspc")
16833    (set_attr "mode" "<MODE>")])
16835 (define_insn "fist<mode>2_with_temp"
16836   [(set (match_operand:SWI24 0 "register_operand" "=r")
16837         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16838                       UNSPEC_FIST))
16839    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16840   "TARGET_USE_FANCY_MATH_387"
16841   "#"
16842   [(set_attr "type" "fpspc")
16843    (set_attr "mode" "<MODE>")])
16845 (define_split
16846   [(set (match_operand:SWI24 0 "register_operand")
16847         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16848                       UNSPEC_FIST))
16849    (clobber (match_operand:SWI24 2 "memory_operand"))]
16850   "reload_completed"
16851   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16852    (set (match_dup 0) (match_dup 2))])
16854 (define_split
16855   [(set (match_operand:SWI24 0 "memory_operand")
16856         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16857                       UNSPEC_FIST))
16858    (clobber (match_operand:SWI24 2 "memory_operand"))]
16859   "reload_completed"
16860   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16862 (define_expand "lrintxf<mode>2"
16863   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16864      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16865                      UNSPEC_FIST))]
16866   "TARGET_USE_FANCY_MATH_387")
16868 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16869   [(set (match_operand:SWI48 0 "nonimmediate_operand")
16870      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16871                    UNSPEC_FIX_NOTRUNC))]
16872   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16874 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16875   [(match_operand:SWI248x 0 "nonimmediate_operand")
16876    (match_operand:X87MODEF 1 "register_operand")]
16877   "(TARGET_USE_FANCY_MATH_387
16878     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16879         || TARGET_MIX_SSE_I387)
16880     && flag_unsafe_math_optimizations)
16881    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16882        && <SWI248x:MODE>mode != HImode 
16883        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16884        && !flag_trapping_math && !flag_rounding_math)"
16886   if (optimize_insn_for_size_p ())
16887     FAIL;
16889   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16890       && <SWI248x:MODE>mode != HImode
16891       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16892       && !flag_trapping_math && !flag_rounding_math)
16893     ix86_expand_lround (operands[0], operands[1]);
16894   else
16895     ix86_emit_i387_round (operands[0], operands[1]);
16896   DONE;
16899 (define_int_iterator FRNDINT_ROUNDING
16900         [UNSPEC_FRNDINT_FLOOR
16901          UNSPEC_FRNDINT_CEIL
16902          UNSPEC_FRNDINT_TRUNC])
16904 (define_int_iterator FIST_ROUNDING
16905         [UNSPEC_FIST_FLOOR
16906          UNSPEC_FIST_CEIL])
16908 ;; Base name for define_insn
16909 (define_int_attr rounding_insn
16910         [(UNSPEC_FRNDINT_FLOOR "floor")
16911          (UNSPEC_FRNDINT_CEIL "ceil")
16912          (UNSPEC_FRNDINT_TRUNC "btrunc")
16913          (UNSPEC_FIST_FLOOR "floor")
16914          (UNSPEC_FIST_CEIL "ceil")])
16916 (define_int_attr rounding
16917         [(UNSPEC_FRNDINT_FLOOR "floor")
16918          (UNSPEC_FRNDINT_CEIL "ceil")
16919          (UNSPEC_FRNDINT_TRUNC "trunc")
16920          (UNSPEC_FIST_FLOOR "floor")
16921          (UNSPEC_FIST_CEIL "ceil")])
16923 (define_int_attr ROUNDING
16924         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16925          (UNSPEC_FRNDINT_CEIL "CEIL")
16926          (UNSPEC_FRNDINT_TRUNC "TRUNC")
16927          (UNSPEC_FIST_FLOOR "FLOOR")
16928          (UNSPEC_FIST_CEIL "CEIL")])
16930 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16931 (define_insn_and_split "frndint<mode>2_<rounding>"
16932   [(set (match_operand:X87MODEF 0 "register_operand")
16933         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16934                    FRNDINT_ROUNDING))
16935    (clobber (reg:CC FLAGS_REG))]
16936   "TARGET_USE_FANCY_MATH_387
16937    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16938    && can_create_pseudo_p ()"
16939   "#"
16940   "&& 1"
16941   [(const_int 0)]
16943   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16945   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16946   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16948   emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16949                                                  operands[2], operands[3]));
16950   DONE;
16952   [(set_attr "type" "frndint")
16953    (set_attr "i387_cw" "<rounding>")
16954    (set_attr "mode" "<MODE>")])
16956 (define_insn "frndint<mode>2_<rounding>_i387"
16957   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16958         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16959                          FRNDINT_ROUNDING))
16960    (use (match_operand:HI 2 "memory_operand" "m"))
16961    (use (match_operand:HI 3 "memory_operand" "m"))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16964   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16965   [(set_attr "type" "frndint")
16966    (set_attr "i387_cw" "<rounding>")
16967    (set_attr "mode" "<MODE>")])
16969 (define_expand "<rounding_insn>xf2"
16970   [(parallel [(set (match_operand:XF 0 "register_operand")
16971                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16972                               FRNDINT_ROUNDING))
16973               (clobber (reg:CC FLAGS_REG))])]
16974   "TARGET_USE_FANCY_MATH_387
16975    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16977 (define_expand "<rounding_insn><mode>2"
16978   [(parallel [(set (match_operand:MODEF 0 "register_operand")
16979                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16980                                  FRNDINT_ROUNDING))
16981               (clobber (reg:CC FLAGS_REG))])]
16982   "(TARGET_USE_FANCY_MATH_387
16983     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16984         || TARGET_MIX_SSE_I387)
16985     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16986    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16987        && (TARGET_SSE4_1 || !flag_trapping_math
16988            || flag_fp_int_builtin_inexact))"
16990   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16991       && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16992     {
16993       if (TARGET_SSE4_1)
16994         emit_insn (gen_sse4_1_round<mode>2
16995                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16996                                                        | ROUND_NO_EXC)));
16997       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16998         {
16999           if (ROUND_<ROUNDING> == ROUND_FLOOR)
17000             ix86_expand_floorceil (operands[0], operands[1], true);
17001           else if (ROUND_<ROUNDING> == ROUND_CEIL)
17002             ix86_expand_floorceil (operands[0], operands[1], false);
17003           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17004             ix86_expand_trunc (operands[0], operands[1]);
17005           else
17006             gcc_unreachable ();
17007         }
17008       else
17009         {
17010           if (ROUND_<ROUNDING> == ROUND_FLOOR)
17011             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
17012           else if (ROUND_<ROUNDING> == ROUND_CEIL)
17013             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
17014           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17015             ix86_expand_truncdf_32 (operands[0], operands[1]);
17016           else
17017             gcc_unreachable ();
17018         }
17019     }
17020   else
17021     emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
17022   DONE;
17025 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17026 (define_insn_and_split "frndintxf2_mask_pm"
17027   [(set (match_operand:XF 0 "register_operand")
17028         (unspec:XF [(match_operand:XF 1 "register_operand")]
17029                    UNSPEC_FRNDINT_MASK_PM))
17030    (clobber (reg:CC FLAGS_REG))]
17031   "TARGET_USE_FANCY_MATH_387
17032    && flag_unsafe_math_optimizations
17033    && can_create_pseudo_p ()"
17034   "#"
17035   "&& 1"
17036   [(const_int 0)]
17038   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17040   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17041   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17043   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17044                                           operands[2], operands[3]));
17045   DONE;
17047   [(set_attr "type" "frndint")
17048    (set_attr "i387_cw" "mask_pm")
17049    (set_attr "mode" "XF")])
17051 (define_insn "frndintxf2_mask_pm_i387"
17052   [(set (match_operand:XF 0 "register_operand" "=f")
17053         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17054                    UNSPEC_FRNDINT_MASK_PM))
17055    (use (match_operand:HI 2 "memory_operand" "m"))
17056    (use (match_operand:HI 3 "memory_operand" "m"))]
17057   "TARGET_USE_FANCY_MATH_387
17058    && flag_unsafe_math_optimizations"
17059   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17060   [(set_attr "type" "frndint")
17061    (set_attr "i387_cw" "mask_pm")
17062    (set_attr "mode" "XF")])
17064 (define_expand "nearbyintxf2"
17065   [(parallel [(set (match_operand:XF 0 "register_operand")
17066                    (unspec:XF [(match_operand:XF 1 "register_operand")]
17067                               UNSPEC_FRNDINT_MASK_PM))
17068               (clobber (reg:CC FLAGS_REG))])]
17069   "TARGET_USE_FANCY_MATH_387
17070    && flag_unsafe_math_optimizations")
17072 (define_expand "nearbyint<mode>2"
17073   [(use (match_operand:MODEF 0 "register_operand"))
17074    (use (match_operand:MODEF 1 "register_operand"))]
17075   "TARGET_USE_FANCY_MATH_387
17076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17077        || TARGET_MIX_SSE_I387)
17078    && flag_unsafe_math_optimizations"
17080   rtx op0 = gen_reg_rtx (XFmode);
17081   rtx op1 = gen_reg_rtx (XFmode);
17083   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17084   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17086   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17087   DONE;
17090 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17091 (define_insn_and_split "*fist<mode>2_<rounding>_1"
17092   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17093         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17094                         FIST_ROUNDING))
17095    (clobber (reg:CC FLAGS_REG))]
17096   "TARGET_USE_FANCY_MATH_387
17097    && flag_unsafe_math_optimizations
17098    && can_create_pseudo_p ()"
17099   "#"
17100   "&& 1"
17101   [(const_int 0)]
17103   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17105   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17106   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17107   if (memory_operand (operands[0], VOIDmode))
17108     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17109                                            operands[2], operands[3]));
17110   else
17111     {
17112       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17113       emit_insn (gen_fist<mode>2_<rounding>_with_temp
17114                   (operands[0], operands[1], operands[2],
17115                    operands[3], operands[4]));
17116     }
17117   DONE;
17119   [(set_attr "type" "fistp")
17120    (set_attr "i387_cw" "<rounding>")
17121    (set_attr "mode" "<MODE>")])
17123 (define_insn "fistdi2_<rounding>"
17124   [(set (match_operand:DI 0 "memory_operand" "=m")
17125         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17126                    FIST_ROUNDING))
17127    (use (match_operand:HI 2 "memory_operand" "m"))
17128    (use (match_operand:HI 3 "memory_operand" "m"))
17129    (clobber (match_scratch:XF 4 "=&1f"))]
17130   "TARGET_USE_FANCY_MATH_387
17131    && flag_unsafe_math_optimizations"
17132   "* return output_fix_trunc (insn, operands, false);"
17133   [(set_attr "type" "fistp")
17134    (set_attr "i387_cw" "<rounding>")
17135    (set_attr "mode" "DI")])
17137 (define_insn "fistdi2_<rounding>_with_temp"
17138   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17139         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17140                    FIST_ROUNDING))
17141    (use (match_operand:HI 2 "memory_operand" "m,m"))
17142    (use (match_operand:HI 3 "memory_operand" "m,m"))
17143    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17144    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17145   "TARGET_USE_FANCY_MATH_387
17146    && flag_unsafe_math_optimizations"
17147   "#"
17148   [(set_attr "type" "fistp")
17149    (set_attr "i387_cw" "<rounding>")
17150    (set_attr "mode" "DI")])
17152 (define_split
17153   [(set (match_operand:DI 0 "register_operand")
17154         (unspec:DI [(match_operand:XF 1 "register_operand")]
17155                    FIST_ROUNDING))
17156    (use (match_operand:HI 2 "memory_operand"))
17157    (use (match_operand:HI 3 "memory_operand"))
17158    (clobber (match_operand:DI 4 "memory_operand"))
17159    (clobber (match_scratch 5))]
17160   "reload_completed"
17161   [(parallel [(set (match_dup 4)
17162                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17163               (use (match_dup 2))
17164               (use (match_dup 3))
17165               (clobber (match_dup 5))])
17166    (set (match_dup 0) (match_dup 4))])
17168 (define_split
17169   [(set (match_operand:DI 0 "memory_operand")
17170         (unspec:DI [(match_operand:XF 1 "register_operand")]
17171                    FIST_ROUNDING))
17172    (use (match_operand:HI 2 "memory_operand"))
17173    (use (match_operand:HI 3 "memory_operand"))
17174    (clobber (match_operand:DI 4 "memory_operand"))
17175    (clobber (match_scratch 5))]
17176   "reload_completed"
17177   [(parallel [(set (match_dup 0)
17178                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17179               (use (match_dup 2))
17180               (use (match_dup 3))
17181               (clobber (match_dup 5))])])
17183 (define_insn "fist<mode>2_<rounding>"
17184   [(set (match_operand:SWI24 0 "memory_operand" "=m")
17185         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17186                       FIST_ROUNDING))
17187    (use (match_operand:HI 2 "memory_operand" "m"))
17188    (use (match_operand:HI 3 "memory_operand" "m"))]
17189   "TARGET_USE_FANCY_MATH_387
17190    && flag_unsafe_math_optimizations"
17191   "* return output_fix_trunc (insn, operands, false);"
17192   [(set_attr "type" "fistp")
17193    (set_attr "i387_cw" "<rounding>")
17194    (set_attr "mode" "<MODE>")])
17196 (define_insn "fist<mode>2_<rounding>_with_temp"
17197   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
17198         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
17199                       FIST_ROUNDING))
17200    (use (match_operand:HI 2 "memory_operand" "m,m"))
17201    (use (match_operand:HI 3 "memory_operand" "m,m"))
17202    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
17203   "TARGET_USE_FANCY_MATH_387
17204    && flag_unsafe_math_optimizations"
17205   "#"
17206   [(set_attr "type" "fistp")
17207    (set_attr "i387_cw" "<rounding>")
17208    (set_attr "mode" "<MODE>")])
17210 (define_split
17211   [(set (match_operand:SWI24 0 "register_operand")
17212         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17213                       FIST_ROUNDING))
17214    (use (match_operand:HI 2 "memory_operand"))
17215    (use (match_operand:HI 3 "memory_operand"))
17216    (clobber (match_operand:SWI24 4 "memory_operand"))]
17217   "reload_completed"
17218   [(parallel [(set (match_dup 4)
17219                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17220               (use (match_dup 2))
17221               (use (match_dup 3))])
17222    (set (match_dup 0) (match_dup 4))])
17224 (define_split
17225   [(set (match_operand:SWI24 0 "memory_operand")
17226         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17227                       FIST_ROUNDING))
17228    (use (match_operand:HI 2 "memory_operand"))
17229    (use (match_operand:HI 3 "memory_operand"))
17230    (clobber (match_operand:SWI24 4 "memory_operand"))]
17231   "reload_completed"
17232   [(parallel [(set (match_dup 0)
17233                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17234               (use (match_dup 2))
17235               (use (match_dup 3))])])
17237 (define_expand "l<rounding_insn>xf<mode>2"
17238   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17239                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17240                                    FIST_ROUNDING))
17241               (clobber (reg:CC FLAGS_REG))])]
17242   "TARGET_USE_FANCY_MATH_387
17243    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17244    && flag_unsafe_math_optimizations")
17246 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17247   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17248                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17249                                  FIST_ROUNDING))
17250               (clobber (reg:CC FLAGS_REG))])]
17251   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17252    && (TARGET_SSE4_1 || !flag_trapping_math)"
17254   if (TARGET_SSE4_1)
17255     {
17256       rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
17258       emit_insn (gen_sse4_1_round<mode>2
17259                  (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
17260                                              | ROUND_NO_EXC)));
17261       emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
17262                  (operands[0], tmp));
17263     }
17264   else if (ROUND_<ROUNDING> == ROUND_FLOOR)
17265     ix86_expand_lfloorceil (operands[0], operands[1], true);
17266   else if (ROUND_<ROUNDING> == ROUND_CEIL)
17267     ix86_expand_lfloorceil (operands[0], operands[1], false);
17268   else
17269     gcc_unreachable ();
17271   DONE;
17274 (define_insn "fxam<mode>2_i387"
17275   [(set (match_operand:HI 0 "register_operand" "=a")
17276         (unspec:HI
17277           [(match_operand:X87MODEF 1 "register_operand" "f")]
17278           UNSPEC_FXAM))]
17279   "TARGET_USE_FANCY_MATH_387"
17280   "fxam\n\tfnstsw\t%0"
17281   [(set_attr "type" "multi")
17282    (set_attr "length" "4")
17283    (set_attr "unit" "i387")
17284    (set_attr "mode" "<MODE>")])
17286 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17287   [(set (match_operand:HI 0 "register_operand")
17288         (unspec:HI
17289           [(match_operand:MODEF 1 "memory_operand")]
17290           UNSPEC_FXAM_MEM))]
17291   "TARGET_USE_FANCY_MATH_387
17292    && can_create_pseudo_p ()"
17293   "#"
17294   "&& 1"
17295   [(set (match_dup 2)(match_dup 1))
17296    (set (match_dup 0)
17297         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17299   operands[2] = gen_reg_rtx (<MODE>mode);
17301   MEM_VOLATILE_P (operands[1]) = 1;
17303   [(set_attr "type" "multi")
17304    (set_attr "unit" "i387")
17305    (set_attr "mode" "<MODE>")])
17307 (define_expand "isinfxf2"
17308   [(use (match_operand:SI 0 "register_operand"))
17309    (use (match_operand:XF 1 "register_operand"))]
17310   "TARGET_USE_FANCY_MATH_387
17311    && ix86_libc_has_function (function_c99_misc)"
17313   rtx mask = GEN_INT (0x45);
17314   rtx val = GEN_INT (0x05);
17316   rtx scratch = gen_reg_rtx (HImode);
17317   rtx res = gen_reg_rtx (QImode);
17319   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17321   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17322   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17323   ix86_expand_setcc (res, EQ,
17324                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17325   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17326   DONE;
17329 (define_expand "isinf<mode>2"
17330   [(use (match_operand:SI 0 "register_operand"))
17331    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17332   "TARGET_USE_FANCY_MATH_387
17333    && ix86_libc_has_function (function_c99_misc)
17334    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17336   rtx mask = GEN_INT (0x45);
17337   rtx val = GEN_INT (0x05);
17339   rtx scratch = gen_reg_rtx (HImode);
17340   rtx res = gen_reg_rtx (QImode);
17342   /* Remove excess precision by forcing value through memory. */
17343   if (memory_operand (operands[1], VOIDmode))
17344     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17345   else
17346     {
17347       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17349       emit_move_insn (temp, operands[1]);
17350       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17351     }
17353   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17354   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17355   ix86_expand_setcc (res, EQ,
17356                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17357   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17358   DONE;
17361 (define_expand "signbittf2"
17362   [(use (match_operand:SI 0 "register_operand"))
17363    (use (match_operand:TF 1 "register_operand"))]
17364   "TARGET_SSE"
17366   if (TARGET_SSE4_1)
17367     {
17368       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17369       rtx scratch = gen_reg_rtx (QImode);
17371       emit_insn (gen_ptesttf2 (operands[1], mask));
17372         ix86_expand_setcc (scratch, NE,
17373                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17375       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17376     }
17377   else
17378     {
17379       emit_insn (gen_sse_movmskps (operands[0],
17380                                    gen_lowpart (V4SFmode, operands[1])));
17381       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17382     }
17383   DONE;
17386 (define_expand "signbitxf2"
17387   [(use (match_operand:SI 0 "register_operand"))
17388    (use (match_operand:XF 1 "register_operand"))]
17389   "TARGET_USE_FANCY_MATH_387"
17391   rtx scratch = gen_reg_rtx (HImode);
17393   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17394   emit_insn (gen_andsi3 (operands[0],
17395              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17396   DONE;
17399 (define_insn "movmsk_df"
17400   [(set (match_operand:SI 0 "register_operand" "=r")
17401         (unspec:SI
17402           [(match_operand:DF 1 "register_operand" "x")]
17403           UNSPEC_MOVMSK))]
17404   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17405   "%vmovmskpd\t{%1, %0|%0, %1}"
17406   [(set_attr "type" "ssemov")
17407    (set_attr "prefix" "maybe_vex")
17408    (set_attr "mode" "DF")])
17410 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17411 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17412 (define_expand "signbitdf2"
17413   [(use (match_operand:SI 0 "register_operand"))
17414    (use (match_operand:DF 1 "register_operand"))]
17415   "TARGET_USE_FANCY_MATH_387
17416    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17418   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17419     {
17420       emit_insn (gen_movmsk_df (operands[0], operands[1]));
17421       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17422     }
17423   else
17424     {
17425       rtx scratch = gen_reg_rtx (HImode);
17427       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17428       emit_insn (gen_andsi3 (operands[0],
17429                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17430     }
17431   DONE;
17434 (define_expand "signbitsf2"
17435   [(use (match_operand:SI 0 "register_operand"))
17436    (use (match_operand:SF 1 "register_operand"))]
17437   "TARGET_USE_FANCY_MATH_387
17438    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17440   rtx scratch = gen_reg_rtx (HImode);
17442   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17443   emit_insn (gen_andsi3 (operands[0],
17444              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17445   DONE;
17448 ;; Block operation instructions
17450 (define_insn "cld"
17451   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17452   ""
17453   "cld"
17454   [(set_attr "length" "1")
17455    (set_attr "length_immediate" "0")
17456    (set_attr "modrm" "0")])
17458 (define_expand "movmem<mode>"
17459   [(use (match_operand:BLK 0 "memory_operand"))
17460    (use (match_operand:BLK 1 "memory_operand"))
17461    (use (match_operand:SWI48 2 "nonmemory_operand"))
17462    (use (match_operand:SWI48 3 "const_int_operand"))
17463    (use (match_operand:SI 4 "const_int_operand"))
17464    (use (match_operand:SI 5 "const_int_operand"))
17465    (use (match_operand:SI 6 ""))
17466    (use (match_operand:SI 7 ""))
17467    (use (match_operand:SI 8 ""))]
17468   ""
17470  if (ix86_expand_set_or_movmem (operands[0], operands[1],
17471                                 operands[2], NULL, operands[3],
17472                                 operands[4], operands[5],
17473                                 operands[6], operands[7],
17474                                 operands[8], false))
17475    DONE;
17476  else
17477    FAIL;
17480 ;; Most CPUs don't like single string operations
17481 ;; Handle this case here to simplify previous expander.
17483 (define_expand "strmov"
17484   [(set (match_dup 4) (match_operand 3 "memory_operand"))
17485    (set (match_operand 1 "memory_operand") (match_dup 4))
17486    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17487               (clobber (reg:CC FLAGS_REG))])
17488    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17489               (clobber (reg:CC FLAGS_REG))])]
17490   ""
17492   /* Can't use this for non-default address spaces.  */
17493   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17494     FAIL;
17496   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17498   /* If .md ever supports :P for Pmode, these can be directly
17499      in the pattern above.  */
17500   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17501   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17503   /* Can't use this if the user has appropriated esi or edi.  */
17504   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17505       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17506     {
17507       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17508                                       operands[2], operands[3],
17509                                       operands[5], operands[6]));
17510       DONE;
17511     }
17513   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17516 (define_expand "strmov_singleop"
17517   [(parallel [(set (match_operand 1 "memory_operand")
17518                    (match_operand 3 "memory_operand"))
17519               (set (match_operand 0 "register_operand")
17520                    (match_operand 4))
17521               (set (match_operand 2 "register_operand")
17522                    (match_operand 5))])]
17523   ""
17525   if (TARGET_CLD)
17526     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17529 (define_insn "*strmovdi_rex_1"
17530   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17531         (mem:DI (match_operand:P 3 "register_operand" "1")))
17532    (set (match_operand:P 0 "register_operand" "=D")
17533         (plus:P (match_dup 2)
17534                 (const_int 8)))
17535    (set (match_operand:P 1 "register_operand" "=S")
17536         (plus:P (match_dup 3)
17537                 (const_int 8)))]
17538   "TARGET_64BIT
17539    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17540    && ix86_check_no_addr_space (insn)"
17541   "%^movsq"
17542   [(set_attr "type" "str")
17543    (set_attr "memory" "both")
17544    (set_attr "mode" "DI")])
17546 (define_insn "*strmovsi_1"
17547   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17548         (mem:SI (match_operand:P 3 "register_operand" "1")))
17549    (set (match_operand:P 0 "register_operand" "=D")
17550         (plus:P (match_dup 2)
17551                 (const_int 4)))
17552    (set (match_operand:P 1 "register_operand" "=S")
17553         (plus:P (match_dup 3)
17554                 (const_int 4)))]
17555   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17556    && ix86_check_no_addr_space (insn)"
17557   "%^movs{l|d}"
17558   [(set_attr "type" "str")
17559    (set_attr "memory" "both")
17560    (set_attr "mode" "SI")])
17562 (define_insn "*strmovhi_1"
17563   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17564         (mem:HI (match_operand:P 3 "register_operand" "1")))
17565    (set (match_operand:P 0 "register_operand" "=D")
17566         (plus:P (match_dup 2)
17567                 (const_int 2)))
17568    (set (match_operand:P 1 "register_operand" "=S")
17569         (plus:P (match_dup 3)
17570                 (const_int 2)))]
17571   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17572    && ix86_check_no_addr_space (insn)"
17573   "%^movsw"
17574   [(set_attr "type" "str")
17575    (set_attr "memory" "both")
17576    (set_attr "mode" "HI")])
17578 (define_insn "*strmovqi_1"
17579   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17580         (mem:QI (match_operand:P 3 "register_operand" "1")))
17581    (set (match_operand:P 0 "register_operand" "=D")
17582         (plus:P (match_dup 2)
17583                 (const_int 1)))
17584    (set (match_operand:P 1 "register_operand" "=S")
17585         (plus:P (match_dup 3)
17586                 (const_int 1)))]
17587   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17588    && ix86_check_no_addr_space (insn)"
17589   "%^movsb"
17590   [(set_attr "type" "str")
17591    (set_attr "memory" "both")
17592    (set (attr "prefix_rex")
17593         (if_then_else
17594           (match_test "<P:MODE>mode == DImode")
17595           (const_string "0")
17596           (const_string "*")))
17597    (set_attr "mode" "QI")])
17599 (define_expand "rep_mov"
17600   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17601               (set (match_operand 0 "register_operand")
17602                    (match_operand 5))
17603               (set (match_operand 2 "register_operand")
17604                    (match_operand 6))
17605               (set (match_operand 1 "memory_operand")
17606                    (match_operand 3 "memory_operand"))
17607               (use (match_dup 4))])]
17608   ""
17610   if (TARGET_CLD)
17611     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17614 (define_insn "*rep_movdi_rex64"
17615   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17616    (set (match_operand:P 0 "register_operand" "=D")
17617         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17618                           (const_int 3))
17619                 (match_operand:P 3 "register_operand" "0")))
17620    (set (match_operand:P 1 "register_operand" "=S")
17621         (plus:P (ashift:P (match_dup 5) (const_int 3))
17622                 (match_operand:P 4 "register_operand" "1")))
17623    (set (mem:BLK (match_dup 3))
17624         (mem:BLK (match_dup 4)))
17625    (use (match_dup 5))]
17626   "TARGET_64BIT
17627    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17628    && ix86_check_no_addr_space (insn)"
17629   "%^rep{%;} movsq"
17630   [(set_attr "type" "str")
17631    (set_attr "prefix_rep" "1")
17632    (set_attr "memory" "both")
17633    (set_attr "mode" "DI")])
17635 (define_insn "*rep_movsi"
17636   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17637    (set (match_operand:P 0 "register_operand" "=D")
17638         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17639                           (const_int 2))
17640                  (match_operand:P 3 "register_operand" "0")))
17641    (set (match_operand:P 1 "register_operand" "=S")
17642         (plus:P (ashift:P (match_dup 5) (const_int 2))
17643                 (match_operand:P 4 "register_operand" "1")))
17644    (set (mem:BLK (match_dup 3))
17645         (mem:BLK (match_dup 4)))
17646    (use (match_dup 5))]
17647   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17648    && ix86_check_no_addr_space (insn)"
17649   "%^rep{%;} movs{l|d}"
17650   [(set_attr "type" "str")
17651    (set_attr "prefix_rep" "1")
17652    (set_attr "memory" "both")
17653    (set_attr "mode" "SI")])
17655 (define_insn "*rep_movqi"
17656   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17657    (set (match_operand:P 0 "register_operand" "=D")
17658         (plus:P (match_operand:P 3 "register_operand" "0")
17659                 (match_operand:P 5 "register_operand" "2")))
17660    (set (match_operand:P 1 "register_operand" "=S")
17661         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17662    (set (mem:BLK (match_dup 3))
17663         (mem:BLK (match_dup 4)))
17664    (use (match_dup 5))]
17665   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17666    && ix86_check_no_addr_space (insn)"
17667   "%^rep{%;} movsb"
17668   [(set_attr "type" "str")
17669    (set_attr "prefix_rep" "1")
17670    (set_attr "memory" "both")
17671    (set_attr "mode" "QI")])
17673 (define_expand "setmem<mode>"
17674    [(use (match_operand:BLK 0 "memory_operand"))
17675     (use (match_operand:SWI48 1 "nonmemory_operand"))
17676     (use (match_operand:QI 2 "nonmemory_operand"))
17677     (use (match_operand 3 "const_int_operand"))
17678     (use (match_operand:SI 4 "const_int_operand"))
17679     (use (match_operand:SI 5 "const_int_operand"))
17680     (use (match_operand:SI 6 ""))
17681     (use (match_operand:SI 7 ""))
17682     (use (match_operand:SI 8 ""))]
17683   ""
17685  if (ix86_expand_set_or_movmem (operands[0], NULL,
17686                                 operands[1], operands[2],
17687                                 operands[3], operands[4],
17688                                 operands[5], operands[6],
17689                                 operands[7], operands[8], true))
17690    DONE;
17691  else
17692    FAIL;
17695 ;; Most CPUs don't like single string operations
17696 ;; Handle this case here to simplify previous expander.
17698 (define_expand "strset"
17699   [(set (match_operand 1 "memory_operand")
17700         (match_operand 2 "register_operand"))
17701    (parallel [(set (match_operand 0 "register_operand")
17702                    (match_dup 3))
17703               (clobber (reg:CC FLAGS_REG))])]
17704   ""
17706   /* Can't use this for non-default address spaces.  */
17707   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17708     FAIL;
17710   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17711     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17713   /* If .md ever supports :P for Pmode, this can be directly
17714      in the pattern above.  */
17715   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17716                               GEN_INT (GET_MODE_SIZE (GET_MODE
17717                                                       (operands[2]))));
17718   /* Can't use this if the user has appropriated eax or edi.  */
17719   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17720       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17721     {
17722       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17723                                       operands[3]));
17724       DONE;
17725     }
17728 (define_expand "strset_singleop"
17729   [(parallel [(set (match_operand 1 "memory_operand")
17730                    (match_operand 2 "register_operand"))
17731               (set (match_operand 0 "register_operand")
17732                    (match_operand 3))
17733               (unspec [(const_int 0)] UNSPEC_STOS)])]
17734   ""
17736   if (TARGET_CLD)
17737     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17740 (define_insn "*strsetdi_rex_1"
17741   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17742         (match_operand:DI 2 "register_operand" "a"))
17743    (set (match_operand:P 0 "register_operand" "=D")
17744         (plus:P (match_dup 1)
17745                 (const_int 8)))
17746    (unspec [(const_int 0)] UNSPEC_STOS)]
17747   "TARGET_64BIT
17748    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17749    && ix86_check_no_addr_space (insn)"
17750   "%^stosq"
17751   [(set_attr "type" "str")
17752    (set_attr "memory" "store")
17753    (set_attr "mode" "DI")])
17755 (define_insn "*strsetsi_1"
17756   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17757         (match_operand:SI 2 "register_operand" "a"))
17758    (set (match_operand:P 0 "register_operand" "=D")
17759         (plus:P (match_dup 1)
17760                 (const_int 4)))
17761    (unspec [(const_int 0)] UNSPEC_STOS)]
17762   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17763    && ix86_check_no_addr_space (insn)"
17764   "%^stos{l|d}"
17765   [(set_attr "type" "str")
17766    (set_attr "memory" "store")
17767    (set_attr "mode" "SI")])
17769 (define_insn "*strsethi_1"
17770   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17771         (match_operand:HI 2 "register_operand" "a"))
17772    (set (match_operand:P 0 "register_operand" "=D")
17773         (plus:P (match_dup 1)
17774                 (const_int 2)))
17775    (unspec [(const_int 0)] UNSPEC_STOS)]
17776   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17777    && ix86_check_no_addr_space (insn)"
17778   "%^stosw"
17779   [(set_attr "type" "str")
17780    (set_attr "memory" "store")
17781    (set_attr "mode" "HI")])
17783 (define_insn "*strsetqi_1"
17784   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17785         (match_operand:QI 2 "register_operand" "a"))
17786    (set (match_operand:P 0 "register_operand" "=D")
17787         (plus:P (match_dup 1)
17788                 (const_int 1)))
17789    (unspec [(const_int 0)] UNSPEC_STOS)]
17790   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17791    && ix86_check_no_addr_space (insn)"
17792   "%^stosb"
17793   [(set_attr "type" "str")
17794    (set_attr "memory" "store")
17795    (set (attr "prefix_rex")
17796         (if_then_else
17797           (match_test "<P:MODE>mode == DImode")
17798           (const_string "0")
17799           (const_string "*")))
17800    (set_attr "mode" "QI")])
17802 (define_expand "rep_stos"
17803   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17804               (set (match_operand 0 "register_operand")
17805                    (match_operand 4))
17806               (set (match_operand 2 "memory_operand") (const_int 0))
17807               (use (match_operand 3 "register_operand"))
17808               (use (match_dup 1))])]
17809   ""
17811   if (TARGET_CLD)
17812     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17815 (define_insn "*rep_stosdi_rex64"
17816   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17817    (set (match_operand:P 0 "register_operand" "=D")
17818         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17819                           (const_int 3))
17820                  (match_operand:P 3 "register_operand" "0")))
17821    (set (mem:BLK (match_dup 3))
17822         (const_int 0))
17823    (use (match_operand:DI 2 "register_operand" "a"))
17824    (use (match_dup 4))]
17825   "TARGET_64BIT
17826    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17827    && ix86_check_no_addr_space (insn)"
17828   "%^rep{%;} stosq"
17829   [(set_attr "type" "str")
17830    (set_attr "prefix_rep" "1")
17831    (set_attr "memory" "store")
17832    (set_attr "mode" "DI")])
17834 (define_insn "*rep_stossi"
17835   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17836    (set (match_operand:P 0 "register_operand" "=D")
17837         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17838                           (const_int 2))
17839                  (match_operand:P 3 "register_operand" "0")))
17840    (set (mem:BLK (match_dup 3))
17841         (const_int 0))
17842    (use (match_operand:SI 2 "register_operand" "a"))
17843    (use (match_dup 4))]
17844   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17845    && ix86_check_no_addr_space (insn)"
17846   "%^rep{%;} stos{l|d}"
17847   [(set_attr "type" "str")
17848    (set_attr "prefix_rep" "1")
17849    (set_attr "memory" "store")
17850    (set_attr "mode" "SI")])
17852 (define_insn "*rep_stosqi"
17853   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17854    (set (match_operand:P 0 "register_operand" "=D")
17855         (plus:P (match_operand:P 3 "register_operand" "0")
17856                 (match_operand:P 4 "register_operand" "1")))
17857    (set (mem:BLK (match_dup 3))
17858         (const_int 0))
17859    (use (match_operand:QI 2 "register_operand" "a"))
17860    (use (match_dup 4))]
17861   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17862    && ix86_check_no_addr_space (insn)"
17863   "%^rep{%;} stosb"
17864   [(set_attr "type" "str")
17865    (set_attr "prefix_rep" "1")
17866    (set_attr "memory" "store")
17867    (set (attr "prefix_rex")
17868         (if_then_else
17869           (match_test "<P:MODE>mode == DImode")
17870           (const_string "0")
17871           (const_string "*")))
17872    (set_attr "mode" "QI")])
17874 (define_expand "cmpstrnsi"
17875   [(set (match_operand:SI 0 "register_operand")
17876         (compare:SI (match_operand:BLK 1 "general_operand")
17877                     (match_operand:BLK 2 "general_operand")))
17878    (use (match_operand 3 "general_operand"))
17879    (use (match_operand 4 "immediate_operand"))]
17880   ""
17882   rtx addr1, addr2, out, outlow, count, countreg, align;
17884   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17885     FAIL;
17887   /* Can't use this if the user has appropriated ecx, esi or edi.  */
17888   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17889     FAIL;
17891   /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
17892      will have rewritten the length arg to be the minimum of the const string
17893      length and the actual length arg.  If both strings are the same and
17894      shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17895      will incorrectly base the results on chars past the 0 byte.  */
17896   tree t1 = MEM_EXPR (operands[1]);
17897   tree t2 = MEM_EXPR (operands[2]);
17898   if (!((t1 && TREE_CODE (t1) == MEM_REF
17899          && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17900          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17901       || (t2 && TREE_CODE (t2) == MEM_REF
17902           && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17903           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17904     FAIL;
17906   out = operands[0];
17907   if (!REG_P (out))
17908     out = gen_reg_rtx (SImode);
17910   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17911   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17912   if (addr1 != XEXP (operands[1], 0))
17913     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17914   if (addr2 != XEXP (operands[2], 0))
17915     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17917   count = operands[3];
17918   countreg = ix86_zero_extend_to_Pmode (count);
17920   /* %%% Iff we are testing strict equality, we can use known alignment
17921      to good advantage.  This may be possible with combine, particularly
17922      once cc0 is dead.  */
17923   align = operands[4];
17925   if (CONST_INT_P (count))
17926     {
17927       if (INTVAL (count) == 0)
17928         {
17929           emit_move_insn (operands[0], const0_rtx);
17930           DONE;
17931         }
17932       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17933                                      operands[1], operands[2]));
17934     }
17935   else
17936     {
17937       rtx (*gen_cmp) (rtx, rtx);
17939       gen_cmp = (TARGET_64BIT
17940                  ? gen_cmpdi_1 : gen_cmpsi_1);
17942       emit_insn (gen_cmp (countreg, countreg));
17943       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17944                                   operands[1], operands[2]));
17945     }
17947   outlow = gen_lowpart (QImode, out);
17948   emit_insn (gen_cmpintqi (outlow));
17949   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17951   if (operands[0] != out)
17952     emit_move_insn (operands[0], out);
17954   DONE;
17957 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17959 (define_expand "cmpintqi"
17960   [(set (match_dup 1)
17961         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17962    (set (match_dup 2)
17963         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17964    (parallel [(set (match_operand:QI 0 "register_operand")
17965                    (minus:QI (match_dup 1)
17966                              (match_dup 2)))
17967               (clobber (reg:CC FLAGS_REG))])]
17968   ""
17970   operands[1] = gen_reg_rtx (QImode);
17971   operands[2] = gen_reg_rtx (QImode);
17974 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17975 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17977 (define_expand "cmpstrnqi_nz_1"
17978   [(parallel [(set (reg:CC FLAGS_REG)
17979                    (compare:CC (match_operand 4 "memory_operand")
17980                                (match_operand 5 "memory_operand")))
17981               (use (match_operand 2 "register_operand"))
17982               (use (match_operand:SI 3 "immediate_operand"))
17983               (clobber (match_operand 0 "register_operand"))
17984               (clobber (match_operand 1 "register_operand"))
17985               (clobber (match_dup 2))])]
17986   ""
17988   if (TARGET_CLD)
17989     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17992 (define_insn "*cmpstrnqi_nz_1"
17993   [(set (reg:CC FLAGS_REG)
17994         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17995                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17996    (use (match_operand:P 6 "register_operand" "2"))
17997    (use (match_operand:SI 3 "immediate_operand" "i"))
17998    (clobber (match_operand:P 0 "register_operand" "=S"))
17999    (clobber (match_operand:P 1 "register_operand" "=D"))
18000    (clobber (match_operand:P 2 "register_operand" "=c"))]
18001   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18002    && ix86_check_no_addr_space (insn)"
18003   "%^repz{%;} cmpsb"
18004   [(set_attr "type" "str")
18005    (set_attr "mode" "QI")
18006    (set (attr "prefix_rex")
18007         (if_then_else
18008           (match_test "<P:MODE>mode == DImode")
18009           (const_string "0")
18010           (const_string "*")))
18011    (set_attr "prefix_rep" "1")])
18013 ;; The same, but the count is not known to not be zero.
18015 (define_expand "cmpstrnqi_1"
18016   [(parallel [(set (reg:CC FLAGS_REG)
18017                 (if_then_else:CC (ne (match_operand 2 "register_operand")
18018                                      (const_int 0))
18019                   (compare:CC (match_operand 4 "memory_operand")
18020                               (match_operand 5 "memory_operand"))
18021                   (const_int 0)))
18022               (use (match_operand:SI 3 "immediate_operand"))
18023               (use (reg:CC FLAGS_REG))
18024               (clobber (match_operand 0 "register_operand"))
18025               (clobber (match_operand 1 "register_operand"))
18026               (clobber (match_dup 2))])]
18027   ""
18029   if (TARGET_CLD)
18030     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18033 (define_insn "*cmpstrnqi_1"
18034   [(set (reg:CC FLAGS_REG)
18035         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
18036                              (const_int 0))
18037           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18038                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
18039           (const_int 0)))
18040    (use (match_operand:SI 3 "immediate_operand" "i"))
18041    (use (reg:CC FLAGS_REG))
18042    (clobber (match_operand:P 0 "register_operand" "=S"))
18043    (clobber (match_operand:P 1 "register_operand" "=D"))
18044    (clobber (match_operand:P 2 "register_operand" "=c"))]
18045   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18046    && ix86_check_no_addr_space (insn)"
18047   "%^repz{%;} cmpsb"
18048   [(set_attr "type" "str")
18049    (set_attr "mode" "QI")
18050    (set (attr "prefix_rex")
18051         (if_then_else
18052           (match_test "<P:MODE>mode == DImode")
18053           (const_string "0")
18054           (const_string "*")))
18055    (set_attr "prefix_rep" "1")])
18057 (define_expand "strlen<mode>"
18058   [(set (match_operand:P 0 "register_operand")
18059         (unspec:P [(match_operand:BLK 1 "general_operand")
18060                    (match_operand:QI 2 "immediate_operand")
18061                    (match_operand 3 "immediate_operand")]
18062                   UNSPEC_SCAS))]
18063   ""
18065  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18066    DONE;
18067  else
18068    FAIL;
18071 (define_expand "strlenqi_1"
18072   [(parallel [(set (match_operand 0 "register_operand")
18073                    (match_operand 2))
18074               (clobber (match_operand 1 "register_operand"))
18075               (clobber (reg:CC FLAGS_REG))])]
18076   ""
18078   if (TARGET_CLD)
18079     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18082 (define_insn "*strlenqi_1"
18083   [(set (match_operand:P 0 "register_operand" "=&c")
18084         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
18085                    (match_operand:QI 2 "register_operand" "a")
18086                    (match_operand:P 3 "immediate_operand" "i")
18087                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
18088    (clobber (match_operand:P 1 "register_operand" "=D"))
18089    (clobber (reg:CC FLAGS_REG))]
18090   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18091    && ix86_check_no_addr_space (insn)"
18092   "%^repnz{%;} scasb"
18093   [(set_attr "type" "str")
18094    (set_attr "mode" "QI")
18095    (set (attr "prefix_rex")
18096         (if_then_else
18097           (match_test "<P:MODE>mode == DImode")
18098           (const_string "0")
18099           (const_string "*")))
18100    (set_attr "prefix_rep" "1")])
18102 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18103 ;; handled in combine, but it is not currently up to the task.
18104 ;; When used for their truth value, the cmpstrn* expanders generate
18105 ;; code like this:
18107 ;;   repz cmpsb
18108 ;;   seta       %al
18109 ;;   setb       %dl
18110 ;;   cmpb       %al, %dl
18111 ;;   jcc        label
18113 ;; The intermediate three instructions are unnecessary.
18115 ;; This one handles cmpstrn*_nz_1...
18116 (define_peephole2
18117   [(parallel[
18118      (set (reg:CC FLAGS_REG)
18119           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18120                       (mem:BLK (match_operand 5 "register_operand"))))
18121      (use (match_operand 6 "register_operand"))
18122      (use (match_operand:SI 3 "immediate_operand"))
18123      (clobber (match_operand 0 "register_operand"))
18124      (clobber (match_operand 1 "register_operand"))
18125      (clobber (match_operand 2 "register_operand"))])
18126    (set (match_operand:QI 7 "register_operand")
18127         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18128    (set (match_operand:QI 8 "register_operand")
18129         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18130    (set (reg FLAGS_REG)
18131         (compare (match_dup 7) (match_dup 8)))
18132   ]
18133   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18134   [(parallel[
18135      (set (reg:CC FLAGS_REG)
18136           (compare:CC (mem:BLK (match_dup 4))
18137                       (mem:BLK (match_dup 5))))
18138      (use (match_dup 6))
18139      (use (match_dup 3))
18140      (clobber (match_dup 0))
18141      (clobber (match_dup 1))
18142      (clobber (match_dup 2))])])
18144 ;; ...and this one handles cmpstrn*_1.
18145 (define_peephole2
18146   [(parallel[
18147      (set (reg:CC FLAGS_REG)
18148           (if_then_else:CC (ne (match_operand 6 "register_operand")
18149                                (const_int 0))
18150             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18151                         (mem:BLK (match_operand 5 "register_operand")))
18152             (const_int 0)))
18153      (use (match_operand:SI 3 "immediate_operand"))
18154      (use (reg:CC FLAGS_REG))
18155      (clobber (match_operand 0 "register_operand"))
18156      (clobber (match_operand 1 "register_operand"))
18157      (clobber (match_operand 2 "register_operand"))])
18158    (set (match_operand:QI 7 "register_operand")
18159         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18160    (set (match_operand:QI 8 "register_operand")
18161         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18162    (set (reg FLAGS_REG)
18163         (compare (match_dup 7) (match_dup 8)))
18164   ]
18165   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18166   [(parallel[
18167      (set (reg:CC FLAGS_REG)
18168           (if_then_else:CC (ne (match_dup 6)
18169                                (const_int 0))
18170             (compare:CC (mem:BLK (match_dup 4))
18171                         (mem:BLK (match_dup 5)))
18172             (const_int 0)))
18173      (use (match_dup 3))
18174      (use (reg:CC FLAGS_REG))
18175      (clobber (match_dup 0))
18176      (clobber (match_dup 1))
18177      (clobber (match_dup 2))])])
18179 ;; Conditional move instructions.
18181 (define_expand "mov<mode>cc"
18182   [(set (match_operand:SWIM 0 "register_operand")
18183         (if_then_else:SWIM (match_operand 1 "comparison_operator")
18184                            (match_operand:SWIM 2 "<general_operand>")
18185                            (match_operand:SWIM 3 "<general_operand>")))]
18186   ""
18187   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18189 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18190 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18191 ;; So just document what we're doing explicitly.
18193 (define_expand "x86_mov<mode>cc_0_m1"
18194   [(parallel
18195     [(set (match_operand:SWI48 0 "register_operand")
18196           (if_then_else:SWI48
18197             (match_operator:SWI48 2 "ix86_carry_flag_operator"
18198              [(match_operand 1 "flags_reg_operand")
18199               (const_int 0)])
18200             (const_int -1)
18201             (const_int 0)))
18202      (clobber (reg:CC FLAGS_REG))])])
18204 (define_insn "*x86_mov<mode>cc_0_m1"
18205   [(set (match_operand:SWI48 0 "register_operand" "=r")
18206         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18207                              [(reg FLAGS_REG) (const_int 0)])
18208           (const_int -1)
18209           (const_int 0)))
18210    (clobber (reg:CC FLAGS_REG))]
18211   ""
18212   "sbb{<imodesuffix>}\t%0, %0"
18213   [(set_attr "type" "alu1")
18214    (set_attr "modrm_class" "op0")
18215    (set_attr "use_carry" "1")
18216    (set_attr "pent_pair" "pu")
18217    (set_attr "mode" "<MODE>")
18218    (set_attr "length_immediate" "0")])
18220 (define_insn "*x86_mov<mode>cc_0_m1_se"
18221   [(set (match_operand:SWI48 0 "register_operand" "=r")
18222         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18223                              [(reg FLAGS_REG) (const_int 0)])
18224                             (const_int 1)
18225                             (const_int 0)))
18226    (clobber (reg:CC FLAGS_REG))]
18227   ""
18228   "sbb{<imodesuffix>}\t%0, %0"
18229   [(set_attr "type" "alu1")
18230    (set_attr "modrm_class" "op0")
18231    (set_attr "use_carry" "1")
18232    (set_attr "pent_pair" "pu")
18233    (set_attr "mode" "<MODE>")
18234    (set_attr "length_immediate" "0")])
18236 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18237   [(set (match_operand:SWI48 0 "register_operand" "=r")
18238         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18239                     [(reg FLAGS_REG) (const_int 0)])))
18240    (clobber (reg:CC FLAGS_REG))]
18241   ""
18242   "sbb{<imodesuffix>}\t%0, %0"
18243   [(set_attr "type" "alu1")
18244    (set_attr "modrm_class" "op0")
18245    (set_attr "use_carry" "1")
18246    (set_attr "pent_pair" "pu")
18247    (set_attr "mode" "<MODE>")
18248    (set_attr "length_immediate" "0")])
18250 (define_insn "*mov<mode>cc_noc"
18251   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18252         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18253                                [(reg FLAGS_REG) (const_int 0)])
18254           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18255           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18256   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18257   "@
18258    cmov%O2%C1\t{%2, %0|%0, %2}
18259    cmov%O2%c1\t{%3, %0|%0, %3}"
18260   [(set_attr "type" "icmov")
18261    (set_attr "mode" "<MODE>")])
18263 (define_insn "*movsicc_noc_zext"
18264   [(set (match_operand:DI 0 "register_operand" "=r,r")
18265         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18266                            [(reg FLAGS_REG) (const_int 0)])
18267           (zero_extend:DI
18268             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18269           (zero_extend:DI
18270             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18271   "TARGET_64BIT
18272    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18273   "@
18274    cmov%O2%C1\t{%2, %k0|%k0, %2}
18275    cmov%O2%c1\t{%3, %k0|%k0, %3}"
18276   [(set_attr "type" "icmov")
18277    (set_attr "mode" "SI")])
18279 ;; Don't do conditional moves with memory inputs.  This splitter helps
18280 ;; register starved x86_32 by forcing inputs into registers before reload.
18281 (define_split
18282   [(set (match_operand:SWI248 0 "register_operand")
18283         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18284                                [(reg FLAGS_REG) (const_int 0)])
18285           (match_operand:SWI248 2 "nonimmediate_operand")
18286           (match_operand:SWI248 3 "nonimmediate_operand")))]
18287   "!TARGET_64BIT && TARGET_CMOVE
18288    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18289    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18290    && can_create_pseudo_p ()
18291    && optimize_insn_for_speed_p ()"
18292   [(set (match_dup 0)
18293         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18295   if (MEM_P (operands[2]))
18296     operands[2] = force_reg (<MODE>mode, operands[2]);
18297   if (MEM_P (operands[3]))
18298     operands[3] = force_reg (<MODE>mode, operands[3]);
18301 (define_insn "*movqicc_noc"
18302   [(set (match_operand:QI 0 "register_operand" "=r,r")
18303         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18304                            [(reg FLAGS_REG) (const_int 0)])
18305                       (match_operand:QI 2 "register_operand" "r,0")
18306                       (match_operand:QI 3 "register_operand" "0,r")))]
18307   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18308   "#"
18309   [(set_attr "type" "icmov")
18310    (set_attr "mode" "QI")])
18312 (define_split
18313   [(set (match_operand:SWI12 0 "register_operand")
18314         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18315                               [(reg FLAGS_REG) (const_int 0)])
18316                       (match_operand:SWI12 2 "register_operand")
18317                       (match_operand:SWI12 3 "register_operand")))]
18318   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18319    && reload_completed"
18320   [(set (match_dup 0)
18321         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18323   operands[0] = gen_lowpart (SImode, operands[0]);
18324   operands[2] = gen_lowpart (SImode, operands[2]);
18325   operands[3] = gen_lowpart (SImode, operands[3]);
18328 ;; Don't do conditional moves with memory inputs
18329 (define_peephole2
18330   [(match_scratch:SWI248 4 "r")
18331    (set (match_operand:SWI248 0 "register_operand")
18332         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18333                                [(reg FLAGS_REG) (const_int 0)])
18334           (match_operand:SWI248 2 "nonimmediate_operand")
18335           (match_operand:SWI248 3 "nonimmediate_operand")))]
18336   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18337    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18338    && optimize_insn_for_speed_p ()"
18339   [(set (match_dup 4) (match_dup 5))
18340    (set (match_dup 0)
18341         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18343   if (MEM_P (operands[2]))
18344     {
18345       operands[5] = operands[2];
18346       operands[2] = operands[4];
18347     }
18348   else if (MEM_P (operands[3]))
18349     {
18350       operands[5] = operands[3];
18351       operands[3] = operands[4];
18352     }
18353   else
18354     gcc_unreachable ();
18357 (define_peephole2
18358   [(match_scratch:SI 4 "r")
18359    (set (match_operand:DI 0 "register_operand")
18360         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18361                            [(reg FLAGS_REG) (const_int 0)])
18362           (zero_extend:DI
18363             (match_operand:SI 2 "nonimmediate_operand"))
18364           (zero_extend:DI
18365             (match_operand:SI 3 "nonimmediate_operand"))))]
18366   "TARGET_64BIT
18367    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18368    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18369    && optimize_insn_for_speed_p ()"
18370   [(set (match_dup 4) (match_dup 5))
18371    (set (match_dup 0)
18372         (if_then_else:DI (match_dup 1)
18373           (zero_extend:DI (match_dup 2))
18374           (zero_extend:DI (match_dup 3))))]
18376   if (MEM_P (operands[2]))
18377     {
18378       operands[5] = operands[2];
18379       operands[2] = operands[4];
18380     }
18381   else if (MEM_P (operands[3]))
18382     {
18383       operands[5] = operands[3];
18384       operands[3] = operands[4];
18385     }
18386   else
18387     gcc_unreachable ();
18390 (define_expand "mov<mode>cc"
18391   [(set (match_operand:X87MODEF 0 "register_operand")
18392         (if_then_else:X87MODEF
18393           (match_operand 1 "comparison_operator")
18394           (match_operand:X87MODEF 2 "register_operand")
18395           (match_operand:X87MODEF 3 "register_operand")))]
18396   "(TARGET_80387 && TARGET_CMOVE)
18397    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18398   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18400 (define_insn "*movxfcc_1"
18401   [(set (match_operand:XF 0 "register_operand" "=f,f")
18402         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18403                                 [(reg FLAGS_REG) (const_int 0)])
18404                       (match_operand:XF 2 "register_operand" "f,0")
18405                       (match_operand:XF 3 "register_operand" "0,f")))]
18406   "TARGET_80387 && TARGET_CMOVE"
18407   "@
18408    fcmov%F1\t{%2, %0|%0, %2}
18409    fcmov%f1\t{%3, %0|%0, %3}"
18410   [(set_attr "type" "fcmov")
18411    (set_attr "mode" "XF")])
18413 (define_insn "*movdfcc_1"
18414   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18415         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18416                                 [(reg FLAGS_REG) (const_int 0)])
18417                       (match_operand:DF 2 "nonimmediate_operand"
18418                                                "f ,0,rm,0 ,rm,0")
18419                       (match_operand:DF 3 "nonimmediate_operand"
18420                                                "0 ,f,0 ,rm,0, rm")))]
18421   "TARGET_80387 && TARGET_CMOVE
18422    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18423   "@
18424    fcmov%F1\t{%2, %0|%0, %2}
18425    fcmov%f1\t{%3, %0|%0, %3}
18426    #
18427    #
18428    cmov%O2%C1\t{%2, %0|%0, %2}
18429    cmov%O2%c1\t{%3, %0|%0, %3}"
18430   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18431    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18432    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18434 (define_split
18435   [(set (match_operand:DF 0 "general_reg_operand")
18436         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18437                                 [(reg FLAGS_REG) (const_int 0)])
18438                       (match_operand:DF 2 "nonimmediate_operand")
18439                       (match_operand:DF 3 "nonimmediate_operand")))]
18440   "!TARGET_64BIT && reload_completed"
18441   [(set (match_dup 2)
18442         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18443    (set (match_dup 3)
18444         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18446   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18447   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18450 (define_insn "*movsfcc_1_387"
18451   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18452         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18453                                 [(reg FLAGS_REG) (const_int 0)])
18454                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18455                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18456   "TARGET_80387 && TARGET_CMOVE
18457    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18458   "@
18459    fcmov%F1\t{%2, %0|%0, %2}
18460    fcmov%f1\t{%3, %0|%0, %3}
18461    cmov%O2%C1\t{%2, %0|%0, %2}
18462    cmov%O2%c1\t{%3, %0|%0, %3}"
18463   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18464    (set_attr "mode" "SF,SF,SI,SI")])
18466 ;; Don't do conditional moves with memory inputs.  This splitter helps
18467 ;; register starved x86_32 by forcing inputs into registers before reload.
18468 (define_split
18469   [(set (match_operand:MODEF 0 "register_operand")
18470         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18471                               [(reg FLAGS_REG) (const_int 0)])
18472           (match_operand:MODEF 2 "nonimmediate_operand")
18473           (match_operand:MODEF 3 "nonimmediate_operand")))]
18474   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18475    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18476    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18477    && can_create_pseudo_p ()
18478    && optimize_insn_for_speed_p ()"
18479   [(set (match_dup 0)
18480         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18482   if (MEM_P (operands[2]))
18483     operands[2] = force_reg (<MODE>mode, operands[2]);
18484   if (MEM_P (operands[3]))
18485     operands[3] = force_reg (<MODE>mode, operands[3]);
18488 ;; Don't do conditional moves with memory inputs
18489 (define_peephole2
18490   [(match_scratch:MODEF 4 "r")
18491    (set (match_operand:MODEF 0 "general_reg_operand")
18492         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18493                               [(reg FLAGS_REG) (const_int 0)])
18494           (match_operand:MODEF 2 "nonimmediate_operand")
18495           (match_operand:MODEF 3 "nonimmediate_operand")))]
18496   "(<MODE>mode != DFmode || TARGET_64BIT)
18497    && TARGET_80387 && TARGET_CMOVE
18498    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18499    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18500    && optimize_insn_for_speed_p ()"
18501   [(set (match_dup 4) (match_dup 5))
18502    (set (match_dup 0)
18503         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18505   if (MEM_P (operands[2]))
18506     {
18507       operands[5] = operands[2];
18508       operands[2] = operands[4];
18509     }
18510   else if (MEM_P (operands[3]))
18511     {
18512       operands[5] = operands[3];
18513       operands[3] = operands[4];
18514     }
18515   else
18516     gcc_unreachable ();
18519 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18520 ;; the scalar versions to have only XMM registers as operands.
18522 ;; XOP conditional move
18523 (define_insn "*xop_pcmov_<mode>"
18524   [(set (match_operand:MODEF 0 "register_operand" "=x")
18525         (if_then_else:MODEF
18526           (match_operand:MODEF 1 "register_operand" "x")
18527           (match_operand:MODEF 2 "register_operand" "x")
18528           (match_operand:MODEF 3 "register_operand" "x")))]
18529   "TARGET_XOP"
18530   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18531   [(set_attr "type" "sse4arg")])
18533 ;; These versions of the min/max patterns are intentionally ignorant of
18534 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18535 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18536 ;; are undefined in this condition, we're certain this is correct.
18538 (define_insn "<code><mode>3"
18539   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18540         (smaxmin:MODEF
18541           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18542           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18543   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18544   "@
18545    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18546    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18547   [(set_attr "isa" "noavx,avx")
18548    (set_attr "prefix" "orig,vex")
18549    (set_attr "type" "sseadd")
18550    (set_attr "mode" "<MODE>")])
18552 ;; These versions of the min/max patterns implement exactly the operations
18553 ;;   min = (op1 < op2 ? op1 : op2)
18554 ;;   max = (!(op1 < op2) ? op1 : op2)
18555 ;; Their operands are not commutative, and thus they may be used in the
18556 ;; presence of -0.0 and NaN.
18558 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18559   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18560         (unspec:MODEF
18561           [(match_operand:MODEF 1 "register_operand" "0,v")
18562            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18563           IEEE_MAXMIN))]
18564   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18565   "@
18566    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18567    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18568   [(set_attr "isa" "noavx,avx")
18569    (set_attr "prefix" "orig,maybe_evex")
18570    (set_attr "type" "sseadd")
18571    (set_attr "mode" "<MODE>")])
18573 ;; Make two stack loads independent:
18574 ;;   fld aa              fld aa
18575 ;;   fld %st(0)     ->   fld bb
18576 ;;   fmul bb             fmul %st(1), %st
18578 ;; Actually we only match the last two instructions for simplicity.
18580 (define_peephole2
18581   [(set (match_operand 0 "fp_register_operand")
18582         (match_operand 1 "fp_register_operand"))
18583    (set (match_dup 0)
18584         (match_operator 2 "binary_fp_operator"
18585            [(match_dup 0)
18586             (match_operand 3 "memory_operand")]))]
18587   "REGNO (operands[0]) != REGNO (operands[1])"
18588   [(set (match_dup 0) (match_dup 3))
18589    (set (match_dup 0)
18590         (match_op_dup 2
18591           [(match_dup 5) (match_dup 4)]))]
18593   operands[4] = operands[0];
18594   operands[5] = operands[1];
18596   /* The % modifier is not operational anymore in peephole2's, so we have to
18597      swap the operands manually in the case of addition and multiplication. */
18598   if (COMMUTATIVE_ARITH_P (operands[2]))
18599     std::swap (operands[4], operands[5]);
18602 (define_peephole2
18603   [(set (match_operand 0 "fp_register_operand")
18604         (match_operand 1 "fp_register_operand"))
18605    (set (match_dup 0)
18606         (match_operator 2 "binary_fp_operator"
18607            [(match_operand 3 "memory_operand")
18608             (match_dup 0)]))]
18609   "REGNO (operands[0]) != REGNO (operands[1])"
18610   [(set (match_dup 0) (match_dup 3))
18611    (set (match_dup 0)
18612         (match_op_dup 2
18613           [(match_dup 4) (match_dup 5)]))]
18615   operands[4] = operands[0];
18616   operands[5] = operands[1];
18618   /* The % modifier is not operational anymore in peephole2's, so we have to
18619      swap the operands manually in the case of addition and multiplication. */
18620   if (COMMUTATIVE_ARITH_P (operands[2]))
18621     std::swap (operands[4], operands[5]);
18624 ;; Conditional addition patterns
18625 (define_expand "add<mode>cc"
18626   [(match_operand:SWI 0 "register_operand")
18627    (match_operand 1 "ordered_comparison_operator")
18628    (match_operand:SWI 2 "register_operand")
18629    (match_operand:SWI 3 "const_int_operand")]
18630   ""
18631   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18633 ;; Misc patterns (?)
18635 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18636 ;; Otherwise there will be nothing to keep
18638 ;; [(set (reg ebp) (reg esp))]
18639 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18640 ;;  (clobber (eflags)]
18641 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18643 ;; in proper program order.
18645 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18646   [(set (match_operand:P 0 "register_operand" "=r,r")
18647         (plus:P (match_operand:P 1 "register_operand" "0,r")
18648                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18649    (clobber (reg:CC FLAGS_REG))
18650    (clobber (mem:BLK (scratch)))]
18651   ""
18653   switch (get_attr_type (insn))
18654     {
18655     case TYPE_IMOV:
18656       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18658     case TYPE_ALU:
18659       gcc_assert (rtx_equal_p (operands[0], operands[1]));
18660       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18661         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18663       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18665     default:
18666       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18667       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18668     }
18670   [(set (attr "type")
18671         (cond [(and (eq_attr "alternative" "0")
18672                     (not (match_test "TARGET_OPT_AGU")))
18673                  (const_string "alu")
18674                (match_operand:<MODE> 2 "const0_operand")
18675                  (const_string "imov")
18676               ]
18677               (const_string "lea")))
18678    (set (attr "length_immediate")
18679         (cond [(eq_attr "type" "imov")
18680                  (const_string "0")
18681                (and (eq_attr "type" "alu")
18682                     (match_operand 2 "const128_operand"))
18683                  (const_string "1")
18684               ]
18685               (const_string "*")))
18686    (set_attr "mode" "<MODE>")])
18688 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18689   [(set (match_operand:P 0 "register_operand" "=r")
18690         (minus:P (match_operand:P 1 "register_operand" "0")
18691                  (match_operand:P 2 "register_operand" "r")))
18692    (clobber (reg:CC FLAGS_REG))
18693    (clobber (mem:BLK (scratch)))]
18694   ""
18695   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18696   [(set_attr "type" "alu")
18697    (set_attr "mode" "<MODE>")])
18699 (define_insn "allocate_stack_worker_probe_<mode>"
18700   [(set (match_operand:P 0 "register_operand" "=a")
18701         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18702                             UNSPECV_STACK_PROBE))
18703    (clobber (reg:CC FLAGS_REG))]
18704   "ix86_target_stack_probe ()"
18705   "call\t___chkstk_ms"
18706   [(set_attr "type" "multi")
18707    (set_attr "length" "5")])
18709 (define_expand "allocate_stack"
18710   [(match_operand 0 "register_operand")
18711    (match_operand 1 "general_operand")]
18712   "ix86_target_stack_probe ()"
18714   rtx x;
18716 #ifndef CHECK_STACK_LIMIT
18717 #define CHECK_STACK_LIMIT 0
18718 #endif
18720   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18721       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18722     x = operands[1];
18723   else
18724     {
18725       rtx (*insn) (rtx, rtx);
18727       x = copy_to_mode_reg (Pmode, operands[1]);
18729       insn = (TARGET_64BIT
18730               ? gen_allocate_stack_worker_probe_di
18731               : gen_allocate_stack_worker_probe_si);
18733       emit_insn (insn (x, x));
18734     }
18736   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18737                            stack_pointer_rtx, 0, OPTAB_DIRECT);
18739   if (x != stack_pointer_rtx)
18740     emit_move_insn (stack_pointer_rtx, x);
18742   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18743   DONE;
18746 (define_expand "probe_stack"
18747   [(match_operand 0 "memory_operand")]
18748   ""
18750   rtx (*insn) (rtx, rtx)
18751     = (GET_MODE (operands[0]) == DImode
18752        ? gen_probe_stack_di : gen_probe_stack_si);
18754   emit_insn (insn (operands[0], const0_rtx));
18755   DONE;
18758 ;; Use OR for stack probes, this is shorter.
18759 (define_insn "probe_stack_<mode>"
18760   [(set (match_operand:W 0 "memory_operand" "=m")
18761         (unspec:W [(match_operand:W 1 "const0_operand")]
18762                   UNSPEC_PROBE_STACK))
18763    (clobber (reg:CC FLAGS_REG))]
18764   ""
18765   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18766   [(set_attr "type" "alu1")
18767    (set_attr "mode" "<MODE>")
18768    (set_attr "length_immediate" "1")])
18769   
18770 (define_insn "adjust_stack_and_probe<mode>"
18771   [(set (match_operand:P 0 "register_operand" "=r")
18772         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18773                             UNSPECV_PROBE_STACK_RANGE))
18774    (set (reg:P SP_REG)
18775         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18776    (clobber (reg:CC FLAGS_REG))
18777    (clobber (mem:BLK (scratch)))]
18778   ""
18779   "* return output_adjust_stack_and_probe (operands[0]);"
18780   [(set_attr "type" "multi")])
18782 (define_insn "probe_stack_range<mode>"
18783   [(set (match_operand:P 0 "register_operand" "=r")
18784         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18785                             (match_operand:P 2 "const_int_operand" "n")]
18786                             UNSPECV_PROBE_STACK_RANGE))
18787    (clobber (reg:CC FLAGS_REG))]
18788   ""
18789   "* return output_probe_stack_range (operands[0], operands[2]);"
18790   [(set_attr "type" "multi")])
18792 (define_expand "builtin_setjmp_receiver"
18793   [(label_ref (match_operand 0))]
18794   "!TARGET_64BIT && flag_pic"
18796 #if TARGET_MACHO
18797   if (TARGET_MACHO)
18798     {
18799       rtx xops[3];
18800       rtx_code_label *label_rtx = gen_label_rtx ();
18801       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18802       xops[0] = xops[1] = pic_offset_table_rtx;
18803       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18804       ix86_expand_binary_operator (MINUS, SImode, xops);
18805     }
18806   else
18807 #endif
18808     emit_insn (gen_set_got (pic_offset_table_rtx));
18809   DONE;
18812 (define_expand "save_stack_nonlocal"
18813   [(set (match_operand 0 "memory_operand")
18814         (match_operand 1 "register_operand"))]
18815   ""
18817   rtx stack_slot;
18818   if ((flag_cf_protection & CF_RETURN))
18819     {
18820       /* Copy shadow stack pointer to the first slot and stack ppointer
18821          to the second slot.  */
18822       rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18823       stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18824       rtx ssp = gen_reg_rtx (word_mode);
18825       emit_insn ((word_mode == SImode)
18826                  ? gen_rdsspsi (ssp)
18827                  : gen_rdsspdi (ssp));
18828       emit_move_insn (ssp_slot, ssp);
18829     }
18830   else
18831     stack_slot = adjust_address (operands[0], Pmode, 0);
18832   emit_move_insn (stack_slot, operands[1]);
18833   DONE;
18836 (define_expand "restore_stack_nonlocal"
18837   [(set (match_operand 0 "register_operand" "")
18838         (match_operand 1 "memory_operand" ""))]
18839   ""
18841   rtx stack_slot;
18842   if ((flag_cf_protection & CF_RETURN))
18843     {
18844       /* Restore shadow stack pointer from the first slot and stack
18845          pointer from the second slot.  */
18846       rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18847       stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18849       rtx flags, jump, noadj_label, inc_label, loop_label;
18850       rtx reg_adj, reg_ssp, tmp, clob;
18852       /* Get the current shadow stack pointer.  The code below will check if
18853          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
18854          is a NOP.  */
18855       reg_ssp = gen_reg_rtx (word_mode);
18856       emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18857       emit_insn ((word_mode == SImode)
18858                  ? gen_rdsspsi (reg_ssp)
18859                  : gen_rdsspdi (reg_ssp));
18861       /* Compare through substraction the saved and the current ssp to decide
18862          if ssp has to be adjusted.  */
18863       tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18864                                                  ssp_slot));
18865       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18866       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18867       emit_insn (tmp);
18869       /* Compare and jump over adjustment code.  */
18870       noadj_label = gen_label_rtx ();
18871       flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18872       tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18873       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18874                                   gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18875                                   pc_rtx);
18876       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18877       JUMP_LABEL (jump) = noadj_label;
18879       /* Compute the numebr of frames to adjust.  */
18880       reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18881       tmp = gen_rtx_SET (reg_adj,
18882                          gen_rtx_LSHIFTRT (ptr_mode,
18883                                            negate_rtx (ptr_mode, reg_adj),
18884                                            GEN_INT ((word_mode == SImode)
18885                                                     ? 2
18886                                                     : 3)));
18887       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18888       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18889       emit_insn (tmp);
18891       /* Check if number of frames <= 255 so no loop is needed.  */
18892       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18893       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18894       emit_insn (gen_rtx_SET (flags, tmp));
18896       inc_label = gen_label_rtx ();
18897       tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18898       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18899                                   gen_rtx_LABEL_REF (VOIDmode, inc_label),
18900                                   pc_rtx);
18901       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18902       JUMP_LABEL (jump) = inc_label;
18904       rtx reg_255 = gen_reg_rtx (word_mode);
18905       emit_move_insn (reg_255, GEN_INT (255));
18907       /* Adjust the ssp in a loop.  */
18908       loop_label = gen_label_rtx ();
18909       emit_label (loop_label);
18910       LABEL_NUSES (loop_label) = 1;
18912       emit_insn ((word_mode == SImode)
18913                  ? gen_incsspsi (reg_255)
18914                  : gen_incsspdi (reg_255));
18915       tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18916                                                  reg_adj,
18917                                                  GEN_INT (255)));
18918       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18919       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18920       emit_insn (tmp);
18922       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18923       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18924       emit_insn (gen_rtx_SET (flags, tmp));
18926       /* Jump to the loop label.  */
18927       tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18928       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18929                                   gen_rtx_LABEL_REF (VOIDmode, loop_label),
18930                                   pc_rtx);
18931       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18932       JUMP_LABEL (jump) = loop_label;
18934       emit_label (inc_label);
18935       LABEL_NUSES (inc_label) = 1;
18936       emit_insn ((word_mode == SImode)
18937                  ? gen_incsspsi (reg_ssp)
18938                  : gen_incsspdi (reg_ssp));
18940       emit_label (noadj_label);
18941       LABEL_NUSES (noadj_label) = 1;
18942     }
18943   else
18944     stack_slot = adjust_address (operands[1], Pmode, 0);
18945   emit_move_insn (operands[0], stack_slot);
18946   DONE;
18950 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18951 ;; Do not split instructions with mask registers.
18952 (define_split
18953   [(set (match_operand 0 "general_reg_operand")
18954         (match_operator 3 "promotable_binary_operator"
18955            [(match_operand 1 "general_reg_operand")
18956             (match_operand 2 "aligned_operand")]))
18957    (clobber (reg:CC FLAGS_REG))]
18958   "! TARGET_PARTIAL_REG_STALL && reload_completed
18959    && ((GET_MODE (operands[0]) == HImode
18960         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18961             /* ??? next two lines just !satisfies_constraint_K (...) */
18962             || !CONST_INT_P (operands[2])
18963             || satisfies_constraint_K (operands[2])))
18964        || (GET_MODE (operands[0]) == QImode
18965            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18966   [(parallel [(set (match_dup 0)
18967                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18968               (clobber (reg:CC FLAGS_REG))])]
18970   operands[0] = gen_lowpart (SImode, operands[0]);
18971   operands[1] = gen_lowpart (SImode, operands[1]);
18972   if (GET_CODE (operands[3]) != ASHIFT)
18973     operands[2] = gen_lowpart (SImode, operands[2]);
18974   operands[3] = shallow_copy_rtx (operands[3]);
18975   PUT_MODE (operands[3], SImode);
18978 ; Promote the QImode tests, as i386 has encoding of the AND
18979 ; instruction with 32-bit sign-extended immediate and thus the
18980 ; instruction size is unchanged, except in the %eax case for
18981 ; which it is increased by one byte, hence the ! optimize_size.
18982 (define_split
18983   [(set (match_operand 0 "flags_reg_operand")
18984         (match_operator 2 "compare_operator"
18985           [(and (match_operand 3 "aligned_operand")
18986                 (match_operand 4 "const_int_operand"))
18987            (const_int 0)]))
18988    (set (match_operand 1 "register_operand")
18989         (and (match_dup 3) (match_dup 4)))]
18990   "! TARGET_PARTIAL_REG_STALL && reload_completed
18991    && optimize_insn_for_speed_p ()
18992    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18993        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18994    /* Ensure that the operand will remain sign-extended immediate.  */
18995    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18996   [(parallel [(set (match_dup 0)
18997                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18998                                     (const_int 0)]))
18999               (set (match_dup 1)
19000                    (and:SI (match_dup 3) (match_dup 4)))])]
19002   operands[4]
19003     = gen_int_mode (INTVAL (operands[4])
19004                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19005   operands[1] = gen_lowpart (SImode, operands[1]);
19006   operands[3] = gen_lowpart (SImode, operands[3]);
19009 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19010 ; the TEST instruction with 32-bit sign-extended immediate and thus
19011 ; the instruction size would at least double, which is not what we
19012 ; want even with ! optimize_size.
19013 (define_split
19014   [(set (match_operand 0 "flags_reg_operand")
19015         (match_operator 1 "compare_operator"
19016           [(and (match_operand:HI 2 "aligned_operand")
19017                 (match_operand:HI 3 "const_int_operand"))
19018            (const_int 0)]))]
19019   "! TARGET_PARTIAL_REG_STALL && reload_completed
19020    && ! TARGET_FAST_PREFIX
19021    && optimize_insn_for_speed_p ()
19022    /* Ensure that the operand will remain sign-extended immediate.  */
19023    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19024   [(set (match_dup 0)
19025         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19026                          (const_int 0)]))]
19028   operands[3]
19029     = gen_int_mode (INTVAL (operands[3])
19030                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19031   operands[2] = gen_lowpart (SImode, operands[2]);
19034 (define_split
19035   [(set (match_operand 0 "register_operand")
19036         (neg (match_operand 1 "register_operand")))
19037    (clobber (reg:CC FLAGS_REG))]
19038   "! TARGET_PARTIAL_REG_STALL && reload_completed
19039    && (GET_MODE (operands[0]) == HImode
19040        || (GET_MODE (operands[0]) == QImode
19041            && (TARGET_PROMOTE_QImode
19042                || optimize_insn_for_size_p ())))"
19043   [(parallel [(set (match_dup 0)
19044                    (neg:SI (match_dup 1)))
19045               (clobber (reg:CC FLAGS_REG))])]
19047   operands[0] = gen_lowpart (SImode, operands[0]);
19048   operands[1] = gen_lowpart (SImode, operands[1]);
19051 ;; Do not split instructions with mask regs.
19052 (define_split
19053   [(set (match_operand 0 "general_reg_operand")
19054         (not (match_operand 1 "general_reg_operand")))]
19055   "! TARGET_PARTIAL_REG_STALL && reload_completed
19056    && (GET_MODE (operands[0]) == HImode
19057        || (GET_MODE (operands[0]) == QImode
19058            && (TARGET_PROMOTE_QImode
19059                || optimize_insn_for_size_p ())))"
19060   [(set (match_dup 0)
19061         (not:SI (match_dup 1)))]
19063   operands[0] = gen_lowpart (SImode, operands[0]);
19064   operands[1] = gen_lowpart (SImode, operands[1]);
19067 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19068 ;; transform a complex memory operation into two memory to register operations.
19070 ;; Don't push memory operands
19071 (define_peephole2
19072   [(set (match_operand:SWI 0 "push_operand")
19073         (match_operand:SWI 1 "memory_operand"))
19074    (match_scratch:SWI 2 "<r>")]
19075   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19076    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19077   [(set (match_dup 2) (match_dup 1))
19078    (set (match_dup 0) (match_dup 2))])
19080 ;; We need to handle SFmode only, because DFmode and XFmode are split to
19081 ;; SImode pushes.
19082 (define_peephole2
19083   [(set (match_operand:SF 0 "push_operand")
19084         (match_operand:SF 1 "memory_operand"))
19085    (match_scratch:SF 2 "r")]
19086   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19087    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19088   [(set (match_dup 2) (match_dup 1))
19089    (set (match_dup 0) (match_dup 2))])
19091 ;; Don't move an immediate directly to memory when the instruction
19092 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
19093 (define_peephole2
19094   [(match_scratch:SWI124 1 "<r>")
19095    (set (match_operand:SWI124 0 "memory_operand")
19096         (const_int 0))]
19097   "optimize_insn_for_speed_p ()
19098    && ((<MODE>mode == HImode
19099        && TARGET_LCP_STALL)
19100        || (!TARGET_USE_MOV0
19101           && TARGET_SPLIT_LONG_MOVES
19102           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
19103    && peep2_regno_dead_p (0, FLAGS_REG)"
19104   [(parallel [(set (match_dup 2) (const_int 0))
19105               (clobber (reg:CC FLAGS_REG))])
19106    (set (match_dup 0) (match_dup 1))]
19107   "operands[2] = gen_lowpart (SImode, operands[1]);")
19109 (define_peephole2
19110   [(match_scratch:SWI124 2 "<r>")
19111    (set (match_operand:SWI124 0 "memory_operand")
19112         (match_operand:SWI124 1 "immediate_operand"))]
19113   "optimize_insn_for_speed_p ()
19114    && ((<MODE>mode == HImode
19115        && TARGET_LCP_STALL)
19116        || (TARGET_SPLIT_LONG_MOVES
19117           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
19118   [(set (match_dup 2) (match_dup 1))
19119    (set (match_dup 0) (match_dup 2))])
19121 ;; Don't compare memory with zero, load and use a test instead.
19122 (define_peephole2
19123   [(set (match_operand 0 "flags_reg_operand")
19124         (match_operator 1 "compare_operator"
19125           [(match_operand:SI 2 "memory_operand")
19126            (const_int 0)]))
19127    (match_scratch:SI 3 "r")]
19128   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19129   [(set (match_dup 3) (match_dup 2))
19130    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
19132 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19133 ;; Don't split NOTs with a displacement operand, because resulting XOR
19134 ;; will not be pairable anyway.
19136 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19137 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19138 ;; so this split helps here as well.
19140 ;; Note: Can't do this as a regular split because we can't get proper
19141 ;; lifetime information then.
19143 (define_peephole2
19144   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
19145         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
19146   "optimize_insn_for_speed_p ()
19147    && ((TARGET_NOT_UNPAIRABLE
19148         && (!MEM_P (operands[0])
19149             || !memory_displacement_operand (operands[0], <MODE>mode)))
19150        || (TARGET_NOT_VECTORMODE
19151            && long_memory_operand (operands[0], <MODE>mode)))
19152    && peep2_regno_dead_p (0, FLAGS_REG)"
19153   [(parallel [(set (match_dup 0)
19154                    (xor:SWI124 (match_dup 1) (const_int -1)))
19155               (clobber (reg:CC FLAGS_REG))])])
19157 ;; Non pairable "test imm, reg" instructions can be translated to
19158 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19159 ;; byte opcode instead of two, have a short form for byte operands),
19160 ;; so do it for other CPUs as well.  Given that the value was dead,
19161 ;; this should not create any new dependencies.  Pass on the sub-word
19162 ;; versions if we're concerned about partial register stalls.
19164 (define_peephole2
19165   [(set (match_operand 0 "flags_reg_operand")
19166         (match_operator 1 "compare_operator"
19167           [(and:SI (match_operand:SI 2 "register_operand")
19168                    (match_operand:SI 3 "immediate_operand"))
19169            (const_int 0)]))]
19170   "ix86_match_ccmode (insn, CCNOmode)
19171    && (REGNO (operands[2]) != AX_REG
19172        || satisfies_constraint_K (operands[3]))
19173    && peep2_reg_dead_p (1, operands[2])"
19174   [(parallel
19175      [(set (match_dup 0)
19176            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19177                             (const_int 0)]))
19178       (set (match_dup 2)
19179            (and:SI (match_dup 2) (match_dup 3)))])])
19181 ;; We don't need to handle HImode case, because it will be promoted to SImode
19182 ;; on ! TARGET_PARTIAL_REG_STALL
19184 (define_peephole2
19185   [(set (match_operand 0 "flags_reg_operand")
19186         (match_operator 1 "compare_operator"
19187           [(and:QI (match_operand:QI 2 "register_operand")
19188                    (match_operand:QI 3 "immediate_operand"))
19189            (const_int 0)]))]
19190   "! TARGET_PARTIAL_REG_STALL
19191    && ix86_match_ccmode (insn, CCNOmode)
19192    && REGNO (operands[2]) != AX_REG
19193    && peep2_reg_dead_p (1, operands[2])"
19194   [(parallel
19195      [(set (match_dup 0)
19196            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19197                             (const_int 0)]))
19198       (set (match_dup 2)
19199            (and:QI (match_dup 2) (match_dup 3)))])])
19201 (define_peephole2
19202   [(set (match_operand 0 "flags_reg_operand")
19203         (match_operator 1 "compare_operator"
19204           [(and:QI
19205              (subreg:QI
19206                (zero_extract:SI (match_operand 2 "QIreg_operand")
19207                                 (const_int 8)
19208                                 (const_int 8)) 0)
19209              (match_operand 3 "const_int_operand"))
19210            (const_int 0)]))]
19211   "! TARGET_PARTIAL_REG_STALL
19212    && ix86_match_ccmode (insn, CCNOmode)
19213    && REGNO (operands[2]) != AX_REG
19214    && peep2_reg_dead_p (1, operands[2])"
19215   [(parallel
19216      [(set (match_dup 0)
19217            (match_op_dup 1
19218              [(and:QI
19219                 (subreg:QI
19220                   (zero_extract:SI (match_dup 2)
19221                                    (const_int 8)
19222                                    (const_int 8)) 0)
19223                 (match_dup 3))
19224               (const_int 0)]))
19225       (set (zero_extract:SI (match_dup 2)
19226                             (const_int 8)
19227                             (const_int 8))
19228            (subreg:SI
19229              (and:QI
19230                (subreg:QI
19231                  (zero_extract:SI (match_dup 2)
19232                                   (const_int 8)
19233                                   (const_int 8)) 0)
19234                (match_dup 3)) 0))])])
19236 ;; Don't do logical operations with memory inputs.
19237 (define_peephole2
19238   [(match_scratch:SWI 2 "<r>")
19239    (parallel [(set (match_operand:SWI 0 "register_operand")
19240                    (match_operator:SWI 3 "arith_or_logical_operator"
19241                      [(match_dup 0)
19242                       (match_operand:SWI 1 "memory_operand")]))
19243               (clobber (reg:CC FLAGS_REG))])]
19244   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19245   [(set (match_dup 2) (match_dup 1))
19246    (parallel [(set (match_dup 0)
19247                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19248               (clobber (reg:CC FLAGS_REG))])])
19250 (define_peephole2
19251   [(match_scratch:SWI 2 "<r>")
19252    (parallel [(set (match_operand:SWI 0 "register_operand")
19253                    (match_operator:SWI 3 "arith_or_logical_operator"
19254                      [(match_operand:SWI 1 "memory_operand")
19255                       (match_dup 0)]))
19256               (clobber (reg:CC FLAGS_REG))])]
19257   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19258   [(set (match_dup 2) (match_dup 1))
19259    (parallel [(set (match_dup 0)
19260                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19261               (clobber (reg:CC FLAGS_REG))])])
19263 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
19264 ;; the memory address refers to the destination of the load!
19266 (define_peephole2
19267   [(set (match_operand:SWI 0 "general_reg_operand")
19268         (match_operand:SWI 1 "general_reg_operand"))
19269    (parallel [(set (match_dup 0)
19270                    (match_operator:SWI 3 "commutative_operator"
19271                      [(match_dup 0)
19272                       (match_operand:SWI 2 "memory_operand")]))
19273               (clobber (reg:CC FLAGS_REG))])]
19274   "REGNO (operands[0]) != REGNO (operands[1])
19275    && (<MODE>mode != QImode
19276        || any_QIreg_operand (operands[1], QImode))"
19277   [(set (match_dup 0) (match_dup 4))
19278    (parallel [(set (match_dup 0)
19279                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19280               (clobber (reg:CC FLAGS_REG))])]
19281   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19283 (define_peephole2
19284   [(set (match_operand 0 "mmx_reg_operand")
19285         (match_operand 1 "mmx_reg_operand"))
19286    (set (match_dup 0)
19287         (match_operator 3 "commutative_operator"
19288           [(match_dup 0)
19289            (match_operand 2 "memory_operand")]))]
19290   "REGNO (operands[0]) != REGNO (operands[1])"
19291   [(set (match_dup 0) (match_dup 2))
19292    (set (match_dup 0)
19293         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19295 (define_peephole2
19296   [(set (match_operand 0 "sse_reg_operand")
19297         (match_operand 1 "sse_reg_operand"))
19298    (set (match_dup 0)
19299         (match_operator 3 "commutative_operator"
19300           [(match_dup 0)
19301            (match_operand 2 "memory_operand")]))]
19302   "REGNO (operands[0]) != REGNO (operands[1])"
19303   [(set (match_dup 0) (match_dup 2))
19304    (set (match_dup 0)
19305         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19307 ; Don't do logical operations with memory outputs
19309 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19310 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19311 ; the same decoder scheduling characteristics as the original.
19313 (define_peephole2
19314   [(match_scratch:SWI 2 "<r>")
19315    (parallel [(set (match_operand:SWI 0 "memory_operand")
19316                    (match_operator:SWI 3 "arith_or_logical_operator"
19317                      [(match_dup 0)
19318                       (match_operand:SWI 1 "<nonmemory_operand>")]))
19319               (clobber (reg:CC FLAGS_REG))])]
19320   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19321   [(set (match_dup 2) (match_dup 0))
19322    (parallel [(set (match_dup 2)
19323                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19324               (clobber (reg:CC FLAGS_REG))])
19325    (set (match_dup 0) (match_dup 2))])
19327 (define_peephole2
19328   [(match_scratch:SWI 2 "<r>")
19329    (parallel [(set (match_operand:SWI 0 "memory_operand")
19330                    (match_operator:SWI 3 "arith_or_logical_operator"
19331                      [(match_operand:SWI 1 "<nonmemory_operand>")
19332                       (match_dup 0)]))
19333               (clobber (reg:CC FLAGS_REG))])]
19334   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19335   [(set (match_dup 2) (match_dup 0))
19336    (parallel [(set (match_dup 2)
19337                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19338               (clobber (reg:CC FLAGS_REG))])
19339    (set (match_dup 0) (match_dup 2))])
19341 ;; Attempt to use arith or logical operations with memory outputs with
19342 ;; setting of flags.
19343 (define_peephole2
19344   [(set (match_operand:SWI 0 "register_operand")
19345         (match_operand:SWI 1 "memory_operand"))
19346    (parallel [(set (match_dup 0)
19347                    (match_operator:SWI 3 "plusminuslogic_operator"
19348                      [(match_dup 0)
19349                       (match_operand:SWI 2 "<nonmemory_operand>")]))
19350               (clobber (reg:CC FLAGS_REG))])
19351    (set (match_dup 1) (match_dup 0))
19352    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19353   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19354    && peep2_reg_dead_p (4, operands[0])
19355    && !reg_overlap_mentioned_p (operands[0], operands[1])
19356    && !reg_overlap_mentioned_p (operands[0], operands[2])
19357    && (<MODE>mode != QImode
19358        || immediate_operand (operands[2], QImode)
19359        || any_QIreg_operand (operands[2], QImode))
19360    && ix86_match_ccmode (peep2_next_insn (3),
19361                          (GET_CODE (operands[3]) == PLUS
19362                           || GET_CODE (operands[3]) == MINUS)
19363                          ? CCGOCmode : CCNOmode)"
19364   [(parallel [(set (match_dup 4) (match_dup 6))
19365               (set (match_dup 1) (match_dup 5))])]
19367   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19368   operands[5]
19369     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19370                       copy_rtx (operands[1]),
19371                       operands[2]);
19372   operands[6]
19373     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19374                        copy_rtx (operands[5]),
19375                        const0_rtx);
19378 ;; Likewise for cmpelim optimized pattern.
19379 (define_peephole2
19380   [(set (match_operand:SWI 0 "register_operand")
19381         (match_operand:SWI 1 "memory_operand"))
19382    (parallel [(set (reg FLAGS_REG)
19383                    (compare (match_operator:SWI 3 "plusminuslogic_operator"
19384                               [(match_dup 0)
19385                                (match_operand:SWI 2 "<nonmemory_operand>")])
19386                             (const_int 0)))
19387               (set (match_dup 0) (match_dup 3))])
19388    (set (match_dup 1) (match_dup 0))]
19389   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19390    && peep2_reg_dead_p (3, operands[0])
19391    && !reg_overlap_mentioned_p (operands[0], operands[1])
19392    && !reg_overlap_mentioned_p (operands[0], operands[2])
19393    && ix86_match_ccmode (peep2_next_insn (1),
19394                          (GET_CODE (operands[3]) == PLUS
19395                           || GET_CODE (operands[3]) == MINUS)
19396                          ? CCGOCmode : CCNOmode)"
19397   [(parallel [(set (match_dup 4) (match_dup 6))
19398               (set (match_dup 1) (match_dup 5))])]
19400   operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19401   operands[5]
19402     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19403                       copy_rtx (operands[1]), operands[2]);
19404   operands[6]
19405     = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19406                        const0_rtx);
19409 ;; Likewise for instances where we have a lea pattern.
19410 (define_peephole2
19411   [(set (match_operand:SWI 0 "register_operand")
19412         (match_operand:SWI 1 "memory_operand"))
19413    (set (match_operand:SWI 3 "register_operand")
19414         (plus:SWI (match_dup 0)
19415                   (match_operand:SWI 2 "<nonmemory_operand>")))
19416    (set (match_dup 1) (match_dup 3))
19417    (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19418   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19419    && peep2_reg_dead_p (4, operands[3])
19420    && (rtx_equal_p (operands[0], operands[3])
19421        || peep2_reg_dead_p (2, operands[0]))
19422    && !reg_overlap_mentioned_p (operands[0], operands[1])
19423    && !reg_overlap_mentioned_p (operands[3], operands[1])
19424    && !reg_overlap_mentioned_p (operands[0], operands[2])
19425    && (<MODE>mode != QImode
19426        || immediate_operand (operands[2], QImode)
19427        || any_QIreg_operand (operands[2], QImode))
19428    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19429   [(parallel [(set (match_dup 4) (match_dup 6))
19430               (set (match_dup 1) (match_dup 5))])]
19432   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19433   operands[5]
19434     = gen_rtx_PLUS (<MODE>mode,
19435                     copy_rtx (operands[1]),
19436                     operands[2]);
19437   operands[6]
19438     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19439                        copy_rtx (operands[5]),
19440                        const0_rtx);
19443 (define_peephole2
19444   [(parallel [(set (match_operand:SWI 0 "register_operand")
19445                    (match_operator:SWI 2 "plusminuslogic_operator"
19446                      [(match_dup 0)
19447                       (match_operand:SWI 1 "memory_operand")]))
19448               (clobber (reg:CC FLAGS_REG))])
19449    (set (match_dup 1) (match_dup 0))
19450    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19451   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19452    && COMMUTATIVE_ARITH_P (operands[2])
19453    && peep2_reg_dead_p (3, operands[0])
19454    && !reg_overlap_mentioned_p (operands[0], operands[1])
19455    && ix86_match_ccmode (peep2_next_insn (2),
19456                          GET_CODE (operands[2]) == PLUS
19457                          ? CCGOCmode : CCNOmode)"
19458   [(parallel [(set (match_dup 3) (match_dup 5))
19459               (set (match_dup 1) (match_dup 4))])]
19461   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19462   operands[4]
19463     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19464                       copy_rtx (operands[1]),
19465                       operands[0]);
19466   operands[5]
19467     = gen_rtx_COMPARE (GET_MODE (operands[3]),
19468                        copy_rtx (operands[4]),
19469                        const0_rtx);
19472 ;; Likewise for cmpelim optimized pattern.
19473 (define_peephole2
19474   [(parallel [(set (reg FLAGS_REG)
19475                    (compare (match_operator:SWI 2 "plusminuslogic_operator"
19476                               [(match_operand:SWI 0 "register_operand")
19477                                (match_operand:SWI 1 "memory_operand")])
19478                             (const_int 0)))
19479               (set (match_dup 0) (match_dup 2))])
19480    (set (match_dup 1) (match_dup 0))]
19481   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19482    && COMMUTATIVE_ARITH_P (operands[2])
19483    && peep2_reg_dead_p (2, operands[0])
19484    && !reg_overlap_mentioned_p (operands[0], operands[1])
19485    && ix86_match_ccmode (peep2_next_insn (0),
19486                          GET_CODE (operands[2]) == PLUS
19487                          ? CCGOCmode : CCNOmode)"
19488   [(parallel [(set (match_dup 3) (match_dup 5))
19489               (set (match_dup 1) (match_dup 4))])]
19491   operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19492   operands[4]
19493     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19494                       copy_rtx (operands[1]), operands[0]);
19495   operands[5]
19496     = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19497                        const0_rtx);
19500 (define_peephole2
19501   [(set (match_operand:SWI12 0 "register_operand")
19502         (match_operand:SWI12 1 "memory_operand"))
19503    (parallel [(set (match_operand:SI 4 "register_operand")
19504                    (match_operator:SI 3 "plusminuslogic_operator"
19505                      [(match_dup 4)
19506                       (match_operand:SI 2 "nonmemory_operand")]))
19507               (clobber (reg:CC FLAGS_REG))])
19508    (set (match_dup 1) (match_dup 0))
19509    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19510   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19511    && REGNO (operands[0]) == REGNO (operands[4])
19512    && peep2_reg_dead_p (4, operands[0])
19513    && (<MODE>mode != QImode
19514        || immediate_operand (operands[2], SImode)
19515        || any_QIreg_operand (operands[2], SImode))
19516    && !reg_overlap_mentioned_p (operands[0], operands[1])
19517    && !reg_overlap_mentioned_p (operands[0], operands[2])
19518    && ix86_match_ccmode (peep2_next_insn (3),
19519                          (GET_CODE (operands[3]) == PLUS
19520                           || GET_CODE (operands[3]) == MINUS)
19521                          ? CCGOCmode : CCNOmode)"
19522   [(parallel [(set (match_dup 4) (match_dup 6))
19523               (set (match_dup 1) (match_dup 5))])]
19525   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19526   operands[5]
19527     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19528                       copy_rtx (operands[1]),
19529                       gen_lowpart (<MODE>mode, operands[2]));
19530   operands[6]
19531     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19532                        copy_rtx (operands[5]),
19533                        const0_rtx);
19536 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19537 (define_peephole2
19538   [(set (match_operand 0 "general_reg_operand")
19539         (match_operand 1 "const0_operand"))]
19540   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19541    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19542    && peep2_regno_dead_p (0, FLAGS_REG)"
19543   [(parallel [(set (match_dup 0) (const_int 0))
19544               (clobber (reg:CC FLAGS_REG))])]
19545   "operands[0] = gen_lowpart (word_mode, operands[0]);")
19547 (define_peephole2
19548   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19549         (const_int 0))]
19550   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19551    && peep2_regno_dead_p (0, FLAGS_REG)"
19552   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19553               (clobber (reg:CC FLAGS_REG))])])
19555 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19556 (define_peephole2
19557   [(set (match_operand:SWI248 0 "general_reg_operand")
19558         (const_int -1))]
19559   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19560    && peep2_regno_dead_p (0, FLAGS_REG)"
19561   [(parallel [(set (match_dup 0) (const_int -1))
19562               (clobber (reg:CC FLAGS_REG))])]
19564   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19565     operands[0] = gen_lowpart (SImode, operands[0]);
19568 ;; Attempt to convert simple lea to add/shift.
19569 ;; These can be created by move expanders.
19570 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19571 ;; relevant lea instructions were already split.
19573 (define_peephole2
19574   [(set (match_operand:SWI48 0 "register_operand")
19575         (plus:SWI48 (match_dup 0)
19576                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
19577   "!TARGET_OPT_AGU
19578    && peep2_regno_dead_p (0, FLAGS_REG)"
19579   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19580               (clobber (reg:CC FLAGS_REG))])])
19582 (define_peephole2
19583   [(set (match_operand:SWI48 0 "register_operand")
19584         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19585                     (match_dup 0)))]
19586   "!TARGET_OPT_AGU
19587    && peep2_regno_dead_p (0, FLAGS_REG)"
19588   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19589               (clobber (reg:CC FLAGS_REG))])])
19591 (define_peephole2
19592   [(set (match_operand:DI 0 "register_operand")
19593         (zero_extend:DI
19594           (plus:SI (match_operand:SI 1 "register_operand")
19595                    (match_operand:SI 2 "nonmemory_operand"))))]
19596   "TARGET_64BIT && !TARGET_OPT_AGU
19597    && REGNO (operands[0]) == REGNO (operands[1])
19598    && peep2_regno_dead_p (0, FLAGS_REG)"
19599   [(parallel [(set (match_dup 0)
19600                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19601               (clobber (reg:CC FLAGS_REG))])])
19603 (define_peephole2
19604   [(set (match_operand:DI 0 "register_operand")
19605         (zero_extend:DI
19606           (plus:SI (match_operand:SI 1 "nonmemory_operand")
19607                    (match_operand:SI 2 "register_operand"))))]
19608   "TARGET_64BIT && !TARGET_OPT_AGU
19609    && REGNO (operands[0]) == REGNO (operands[2])
19610    && peep2_regno_dead_p (0, FLAGS_REG)"
19611   [(parallel [(set (match_dup 0)
19612                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19613               (clobber (reg:CC FLAGS_REG))])])
19615 (define_peephole2
19616   [(set (match_operand:SWI48 0 "register_operand")
19617         (mult:SWI48 (match_dup 0)
19618                     (match_operand:SWI48 1 "const_int_operand")))]
19619   "pow2p_hwi (INTVAL (operands[1]))
19620    && peep2_regno_dead_p (0, FLAGS_REG)"
19621   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19622               (clobber (reg:CC FLAGS_REG))])]
19623   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19625 (define_peephole2
19626   [(set (match_operand:DI 0 "register_operand")
19627         (zero_extend:DI
19628           (mult:SI (match_operand:SI 1 "register_operand")
19629                    (match_operand:SI 2 "const_int_operand"))))]
19630   "TARGET_64BIT
19631    && pow2p_hwi (INTVAL (operands[2]))
19632    && REGNO (operands[0]) == REGNO (operands[1])
19633    && peep2_regno_dead_p (0, FLAGS_REG)"
19634   [(parallel [(set (match_dup 0)
19635                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19636               (clobber (reg:CC FLAGS_REG))])]
19637   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19639 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19640 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19641 ;; On many CPUs it is also faster, since special hardware to avoid esp
19642 ;; dependencies is present.
19644 ;; While some of these conversions may be done using splitters, we use
19645 ;; peepholes in order to allow combine_stack_adjustments pass to see
19646 ;; nonobfuscated RTL.
19648 ;; Convert prologue esp subtractions to push.
19649 ;; We need register to push.  In order to keep verify_flow_info happy we have
19650 ;; two choices
19651 ;; - use scratch and clobber it in order to avoid dependencies
19652 ;; - use already live register
19653 ;; We can't use the second way right now, since there is no reliable way how to
19654 ;; verify that given register is live.  First choice will also most likely in
19655 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19656 ;; call clobbered registers are dead.  We may want to use base pointer as an
19657 ;; alternative when no register is available later.
19659 (define_peephole2
19660   [(match_scratch:W 1 "r")
19661    (parallel [(set (reg:P SP_REG)
19662                    (plus:P (reg:P SP_REG)
19663                            (match_operand:P 0 "const_int_operand")))
19664               (clobber (reg:CC FLAGS_REG))
19665               (clobber (mem:BLK (scratch)))])]
19666   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19667    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19668    && ix86_red_zone_size == 0"
19669   [(clobber (match_dup 1))
19670    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19671               (clobber (mem:BLK (scratch)))])])
19673 (define_peephole2
19674   [(match_scratch:W 1 "r")
19675    (parallel [(set (reg:P SP_REG)
19676                    (plus:P (reg:P SP_REG)
19677                            (match_operand:P 0 "const_int_operand")))
19678               (clobber (reg:CC FLAGS_REG))
19679               (clobber (mem:BLK (scratch)))])]
19680   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19681    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19682    && ix86_red_zone_size == 0"
19683   [(clobber (match_dup 1))
19684    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19685    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19686               (clobber (mem:BLK (scratch)))])])
19688 ;; Convert esp subtractions to push.
19689 (define_peephole2
19690   [(match_scratch:W 1 "r")
19691    (parallel [(set (reg:P SP_REG)
19692                    (plus:P (reg:P SP_REG)
19693                            (match_operand:P 0 "const_int_operand")))
19694               (clobber (reg:CC FLAGS_REG))])]
19695   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19696    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19697    && ix86_red_zone_size == 0"
19698   [(clobber (match_dup 1))
19699    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19701 (define_peephole2
19702   [(match_scratch:W 1 "r")
19703    (parallel [(set (reg:P SP_REG)
19704                    (plus:P (reg:P SP_REG)
19705                            (match_operand:P 0 "const_int_operand")))
19706               (clobber (reg:CC FLAGS_REG))])]
19707   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19708    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19709    && ix86_red_zone_size == 0"
19710   [(clobber (match_dup 1))
19711    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19712    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19714 ;; Convert epilogue deallocator to pop.
19715 (define_peephole2
19716   [(match_scratch:W 1 "r")
19717    (parallel [(set (reg:P SP_REG)
19718                    (plus:P (reg:P SP_REG)
19719                            (match_operand:P 0 "const_int_operand")))
19720               (clobber (reg:CC FLAGS_REG))
19721               (clobber (mem:BLK (scratch)))])]
19722   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19723    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19724   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19725               (clobber (mem:BLK (scratch)))])])
19727 ;; Two pops case is tricky, since pop causes dependency
19728 ;; on destination register.  We use two registers if available.
19729 (define_peephole2
19730   [(match_scratch:W 1 "r")
19731    (match_scratch:W 2 "r")
19732    (parallel [(set (reg:P SP_REG)
19733                    (plus:P (reg:P SP_REG)
19734                            (match_operand:P 0 "const_int_operand")))
19735               (clobber (reg:CC FLAGS_REG))
19736               (clobber (mem:BLK (scratch)))])]
19737   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19738    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19739   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19740               (clobber (mem:BLK (scratch)))])
19741    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19743 (define_peephole2
19744   [(match_scratch:W 1 "r")
19745    (parallel [(set (reg:P SP_REG)
19746                    (plus:P (reg:P SP_REG)
19747                            (match_operand:P 0 "const_int_operand")))
19748               (clobber (reg:CC FLAGS_REG))
19749               (clobber (mem:BLK (scratch)))])]
19750   "optimize_insn_for_size_p ()
19751    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19752   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19753               (clobber (mem:BLK (scratch)))])
19754    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19756 ;; Convert esp additions to pop.
19757 (define_peephole2
19758   [(match_scratch:W 1 "r")
19759    (parallel [(set (reg:P SP_REG)
19760                    (plus:P (reg:P SP_REG)
19761                            (match_operand:P 0 "const_int_operand")))
19762               (clobber (reg:CC FLAGS_REG))])]
19763   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19764   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19766 ;; Two pops case is tricky, since pop causes dependency
19767 ;; on destination register.  We use two registers if available.
19768 (define_peephole2
19769   [(match_scratch:W 1 "r")
19770    (match_scratch:W 2 "r")
19771    (parallel [(set (reg:P SP_REG)
19772                    (plus:P (reg:P SP_REG)
19773                            (match_operand:P 0 "const_int_operand")))
19774               (clobber (reg:CC FLAGS_REG))])]
19775   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19776   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19777    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19779 (define_peephole2
19780   [(match_scratch:W 1 "r")
19781    (parallel [(set (reg:P SP_REG)
19782                    (plus:P (reg:P SP_REG)
19783                            (match_operand:P 0 "const_int_operand")))
19784               (clobber (reg:CC FLAGS_REG))])]
19785   "optimize_insn_for_size_p ()
19786    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19787   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19788    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19790 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19791 ;; required and register dies.  Similarly for 128 to -128.
19792 (define_peephole2
19793   [(set (match_operand 0 "flags_reg_operand")
19794         (match_operator 1 "compare_operator"
19795           [(match_operand 2 "register_operand")
19796            (match_operand 3 "const_int_operand")]))]
19797   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19798      && incdec_operand (operands[3], GET_MODE (operands[3])))
19799     || (!TARGET_FUSE_CMP_AND_BRANCH
19800         && INTVAL (operands[3]) == 128))
19801    && ix86_match_ccmode (insn, CCGCmode)
19802    && peep2_reg_dead_p (1, operands[2])"
19803   [(parallel [(set (match_dup 0)
19804                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19805               (clobber (match_dup 2))])])
19807 ;; Convert imul by three, five and nine into lea
19808 (define_peephole2
19809   [(parallel
19810     [(set (match_operand:SWI48 0 "register_operand")
19811           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19812                       (match_operand:SWI48 2 "const359_operand")))
19813      (clobber (reg:CC FLAGS_REG))])]
19814   "!TARGET_PARTIAL_REG_STALL
19815    || <MODE>mode == SImode
19816    || optimize_function_for_size_p (cfun)"
19817   [(set (match_dup 0)
19818         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19819                     (match_dup 1)))]
19820   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19822 (define_peephole2
19823   [(parallel
19824     [(set (match_operand:SWI48 0 "register_operand")
19825           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19826                       (match_operand:SWI48 2 "const359_operand")))
19827      (clobber (reg:CC FLAGS_REG))])]
19828   "optimize_insn_for_speed_p ()
19829    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19830   [(set (match_dup 0) (match_dup 1))
19831    (set (match_dup 0)
19832         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19833                     (match_dup 0)))]
19834   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19836 ;; imul $32bit_imm, mem, reg is vector decoded, while
19837 ;; imul $32bit_imm, reg, reg is direct decoded.
19838 (define_peephole2
19839   [(match_scratch:SWI48 3 "r")
19840    (parallel [(set (match_operand:SWI48 0 "register_operand")
19841                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19842                                (match_operand:SWI48 2 "immediate_operand")))
19843               (clobber (reg:CC FLAGS_REG))])]
19844   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19845    && !satisfies_constraint_K (operands[2])"
19846   [(set (match_dup 3) (match_dup 1))
19847    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19848               (clobber (reg:CC FLAGS_REG))])])
19850 (define_peephole2
19851   [(match_scratch:SI 3 "r")
19852    (parallel [(set (match_operand:DI 0 "register_operand")
19853                    (zero_extend:DI
19854                      (mult:SI (match_operand:SI 1 "memory_operand")
19855                               (match_operand:SI 2 "immediate_operand"))))
19856               (clobber (reg:CC FLAGS_REG))])]
19857   "TARGET_64BIT
19858    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19859    && !satisfies_constraint_K (operands[2])"
19860   [(set (match_dup 3) (match_dup 1))
19861    (parallel [(set (match_dup 0)
19862                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19863               (clobber (reg:CC FLAGS_REG))])])
19865 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19866 ;; Convert it into imul reg, reg
19867 ;; It would be better to force assembler to encode instruction using long
19868 ;; immediate, but there is apparently no way to do so.
19869 (define_peephole2
19870   [(parallel [(set (match_operand:SWI248 0 "register_operand")
19871                    (mult:SWI248
19872                     (match_operand:SWI248 1 "nonimmediate_operand")
19873                     (match_operand:SWI248 2 "const_int_operand")))
19874               (clobber (reg:CC FLAGS_REG))])
19875    (match_scratch:SWI248 3 "r")]
19876   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19877    && satisfies_constraint_K (operands[2])"
19878   [(set (match_dup 3) (match_dup 2))
19879    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19880               (clobber (reg:CC FLAGS_REG))])]
19882   if (!rtx_equal_p (operands[0], operands[1]))
19883     emit_move_insn (operands[0], operands[1]);
19886 ;; After splitting up read-modify operations, array accesses with memory
19887 ;; operands might end up in form:
19888 ;;  sall    $2, %eax
19889 ;;  movl    4(%esp), %edx
19890 ;;  addl    %edx, %eax
19891 ;; instead of pre-splitting:
19892 ;;  sall    $2, %eax
19893 ;;  addl    4(%esp), %eax
19894 ;; Turn it into:
19895 ;;  movl    4(%esp), %edx
19896 ;;  leal    (%edx,%eax,4), %eax
19898 (define_peephole2
19899   [(match_scratch:W 5 "r")
19900    (parallel [(set (match_operand 0 "register_operand")
19901                    (ashift (match_operand 1 "register_operand")
19902                            (match_operand 2 "const_int_operand")))
19903                (clobber (reg:CC FLAGS_REG))])
19904    (parallel [(set (match_operand 3 "register_operand")
19905                    (plus (match_dup 0)
19906                          (match_operand 4 "x86_64_general_operand")))
19907                    (clobber (reg:CC FLAGS_REG))])]
19908   "IN_RANGE (INTVAL (operands[2]), 1, 3)
19909    /* Validate MODE for lea.  */
19910    && ((!TARGET_PARTIAL_REG_STALL
19911         && (GET_MODE (operands[0]) == QImode
19912             || GET_MODE (operands[0]) == HImode))
19913        || GET_MODE (operands[0]) == SImode
19914        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19915    && (rtx_equal_p (operands[0], operands[3])
19916        || peep2_reg_dead_p (2, operands[0]))
19917    /* We reorder load and the shift.  */
19918    && !reg_overlap_mentioned_p (operands[0], operands[4])"
19919   [(set (match_dup 5) (match_dup 4))
19920    (set (match_dup 0) (match_dup 1))]
19922   machine_mode op1mode = GET_MODE (operands[1]);
19923   machine_mode mode = op1mode == DImode ? DImode : SImode;
19924   int scale = 1 << INTVAL (operands[2]);
19925   rtx index = gen_lowpart (word_mode, operands[1]);
19926   rtx base = gen_lowpart (word_mode, operands[5]);
19927   rtx dest = gen_lowpart (mode, operands[3]);
19929   operands[1] = gen_rtx_PLUS (word_mode, base,
19930                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19931   if (mode != word_mode)
19932     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19934   operands[5] = base;
19935   if (op1mode != word_mode)
19936     operands[5] = gen_lowpart (op1mode, operands[5]);
19938   operands[0] = dest;
19941 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19942 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19943 ;; caught for use by garbage collectors and the like.  Using an insn that
19944 ;; maps to SIGILL makes it more likely the program will rightfully die.
19945 ;; Keeping with tradition, "6" is in honor of #UD.
19946 (define_insn "trap"
19947   [(trap_if (const_int 1) (const_int 6))]
19948   ""
19950 #ifdef HAVE_AS_IX86_UD2
19951   return "ud2";
19952 #else
19953   return ASM_SHORT "0x0b0f";
19954 #endif
19956   [(set_attr "length" "2")])
19958 (define_insn "ud2"
19959   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19960   ""
19962 #ifdef HAVE_AS_IX86_UD2
19963   return "ud2";
19964 #else
19965   return ASM_SHORT "0x0b0f";
19966 #endif
19968   [(set_attr "length" "2")])
19970 (define_expand "prefetch"
19971   [(prefetch (match_operand 0 "address_operand")
19972              (match_operand:SI 1 "const_int_operand")
19973              (match_operand:SI 2 "const_int_operand"))]
19974   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19976   bool write = INTVAL (operands[1]) != 0;
19977   int locality = INTVAL (operands[2]);
19979   gcc_assert (IN_RANGE (locality, 0, 3));
19981   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19982      supported by SSE counterpart (non-SSE2 athlon machines) or the
19983      SSE prefetch is not available (K6 machines).  Otherwise use SSE
19984      prefetch as it allows specifying of locality.  */
19986   if (write)
19987     {
19988       if (TARGET_PREFETCHWT1)
19989         operands[2] = GEN_INT (MAX (locality, 2)); 
19990       else if (TARGET_PRFCHW)
19991         operands[2] = GEN_INT (3);
19992       else if (TARGET_3DNOW && !TARGET_SSE2)
19993         operands[2] = GEN_INT (3);
19994       else if (TARGET_PREFETCH_SSE)
19995         operands[1] = const0_rtx;
19996       else
19997         {
19998           gcc_assert (TARGET_3DNOW);
19999           operands[2] = GEN_INT (3);
20000         }
20001     }
20002   else
20003     {
20004       if (TARGET_PREFETCH_SSE)
20005         ;
20006       else
20007         {
20008           gcc_assert (TARGET_3DNOW);
20009           operands[2] = GEN_INT (3);
20010         }
20011     }
20014 (define_insn "*prefetch_sse"
20015   [(prefetch (match_operand 0 "address_operand" "p")
20016              (const_int 0)
20017              (match_operand:SI 1 "const_int_operand"))]
20018   "TARGET_PREFETCH_SSE"
20020   static const char * const patterns[4] = {
20021    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20022   };
20024   int locality = INTVAL (operands[1]);
20025   gcc_assert (IN_RANGE (locality, 0, 3));
20027   return patterns[locality];
20029   [(set_attr "type" "sse")
20030    (set_attr "atom_sse_attr" "prefetch")
20031    (set (attr "length_address")
20032         (symbol_ref "memory_address_length (operands[0], false)"))
20033    (set_attr "memory" "none")])
20035 (define_insn "*prefetch_3dnow"
20036   [(prefetch (match_operand 0 "address_operand" "p")
20037              (match_operand:SI 1 "const_int_operand" "n")
20038              (const_int 3))]
20039   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20041   if (INTVAL (operands[1]) == 0)
20042     return "prefetch\t%a0";
20043   else
20044     return "prefetchw\t%a0";
20046   [(set_attr "type" "mmx")
20047    (set (attr "length_address")
20048         (symbol_ref "memory_address_length (operands[0], false)"))
20049    (set_attr "memory" "none")])
20051 (define_insn "*prefetch_prefetchwt1"
20052   [(prefetch (match_operand 0 "address_operand" "p")
20053              (const_int 1)
20054              (const_int 2))]
20055   "TARGET_PREFETCHWT1"
20056   "prefetchwt1\t%a0";
20057   [(set_attr "type" "sse")
20058    (set (attr "length_address")
20059         (symbol_ref "memory_address_length (operands[0], false)"))
20060    (set_attr "memory" "none")])
20062 (define_expand "stack_protect_set"
20063   [(match_operand 0 "memory_operand")
20064    (match_operand 1 "memory_operand")]
20065   "TARGET_SSP_TLS_GUARD"
20067   rtx (*insn)(rtx, rtx);
20069   insn = (TARGET_LP64
20070           ? gen_stack_protect_set_di
20071           : gen_stack_protect_set_si);
20073   emit_insn (insn (operands[0], operands[1]));
20074   DONE;
20077 (define_insn "stack_protect_set_<mode>"
20078   [(set (match_operand:PTR 0 "memory_operand" "=m")
20079         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
20080                     UNSPEC_SP_SET))
20081    (set (match_scratch:PTR 2 "=&r") (const_int 0))
20082    (clobber (reg:CC FLAGS_REG))]
20083   "TARGET_SSP_TLS_GUARD"
20084   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20085   [(set_attr "type" "multi")])
20087 (define_expand "stack_protect_test"
20088   [(match_operand 0 "memory_operand")
20089    (match_operand 1 "memory_operand")
20090    (match_operand 2)]
20091   "TARGET_SSP_TLS_GUARD"
20093   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20095   rtx (*insn)(rtx, rtx, rtx);
20097   insn = (TARGET_LP64
20098           ? gen_stack_protect_test_di
20099           : gen_stack_protect_test_si);
20101   emit_insn (insn (flags, operands[0], operands[1]));
20103   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20104                                   flags, const0_rtx, operands[2]));
20105   DONE;
20108 (define_insn "stack_protect_test_<mode>"
20109   [(set (match_operand:CCZ 0 "flags_reg_operand")
20110         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20111                      (match_operand:PTR 2 "memory_operand" "m")]
20112                     UNSPEC_SP_TEST))
20113    (clobber (match_scratch:PTR 3 "=&r"))]
20114   "TARGET_SSP_TLS_GUARD"
20115   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
20116   [(set_attr "type" "multi")])
20118 (define_insn "sse4_2_crc32<mode>"
20119   [(set (match_operand:SI 0 "register_operand" "=r")
20120         (unspec:SI
20121           [(match_operand:SI 1 "register_operand" "0")
20122            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20123           UNSPEC_CRC32))]
20124   "TARGET_SSE4_2 || TARGET_CRC32"
20125   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20126   [(set_attr "type" "sselog1")
20127    (set_attr "prefix_rep" "1")
20128    (set_attr "prefix_extra" "1")
20129    (set (attr "prefix_data16")
20130      (if_then_else (match_operand:HI 2)
20131        (const_string "1")
20132        (const_string "*")))
20133    (set (attr "prefix_rex")
20134      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20135        (const_string "1")
20136        (const_string "*")))
20137    (set_attr "mode" "SI")])
20139 (define_insn "sse4_2_crc32di"
20140   [(set (match_operand:DI 0 "register_operand" "=r")
20141         (unspec:DI
20142           [(match_operand:DI 1 "register_operand" "0")
20143            (match_operand:DI 2 "nonimmediate_operand" "rm")]
20144           UNSPEC_CRC32))]
20145   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20146   "crc32{q}\t{%2, %0|%0, %2}"
20147   [(set_attr "type" "sselog1")
20148    (set_attr "prefix_rep" "1")
20149    (set_attr "prefix_extra" "1")
20150    (set_attr "mode" "DI")])
20152 (define_insn "rdpmc"
20153   [(set (match_operand:DI 0 "register_operand" "=A")
20154         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20155                             UNSPECV_RDPMC))]
20156   "!TARGET_64BIT"
20157   "rdpmc"
20158   [(set_attr "type" "other")
20159    (set_attr "length" "2")])
20161 (define_insn "rdpmc_rex64"
20162   [(set (match_operand:DI 0 "register_operand" "=a")
20163         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20164                             UNSPECV_RDPMC))
20165    (set (match_operand:DI 1 "register_operand" "=d")
20166         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
20167   "TARGET_64BIT"
20168   "rdpmc"
20169   [(set_attr "type" "other")
20170    (set_attr "length" "2")])
20172 (define_insn "rdtsc"
20173   [(set (match_operand:DI 0 "register_operand" "=A")
20174         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20175   "!TARGET_64BIT"
20176   "rdtsc"
20177   [(set_attr "type" "other")
20178    (set_attr "length" "2")])
20180 (define_insn "rdtsc_rex64"
20181   [(set (match_operand:DI 0 "register_operand" "=a")
20182         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20183    (set (match_operand:DI 1 "register_operand" "=d")
20184         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20185   "TARGET_64BIT"
20186   "rdtsc"
20187   [(set_attr "type" "other")
20188    (set_attr "length" "2")])
20190 (define_insn "rdtscp"
20191   [(set (match_operand:DI 0 "register_operand" "=A")
20192         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20193    (set (match_operand:SI 1 "register_operand" "=c")
20194         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20195   "!TARGET_64BIT"
20196   "rdtscp"
20197   [(set_attr "type" "other")
20198    (set_attr "length" "3")])
20200 (define_insn "rdtscp_rex64"
20201   [(set (match_operand:DI 0 "register_operand" "=a")
20202         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20203    (set (match_operand:DI 1 "register_operand" "=d")
20204         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20205    (set (match_operand:SI 2 "register_operand" "=c")
20206         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20207   "TARGET_64BIT"
20208   "rdtscp"
20209   [(set_attr "type" "other")
20210    (set_attr "length" "3")])
20212 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20214 ;; FXSR, XSAVE and XSAVEOPT instructions
20216 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20218 (define_insn "fxsave"
20219   [(set (match_operand:BLK 0 "memory_operand" "=m")
20220         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20221   "TARGET_FXSR"
20222   "fxsave\t%0"
20223   [(set_attr "type" "other")
20224    (set_attr "memory" "store")
20225    (set (attr "length")
20226         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20228 (define_insn "fxsave64"
20229   [(set (match_operand:BLK 0 "memory_operand" "=m")
20230         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20231   "TARGET_64BIT && TARGET_FXSR"
20232   "fxsave64\t%0"
20233   [(set_attr "type" "other")
20234    (set_attr "memory" "store")
20235    (set (attr "length")
20236         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20238 (define_insn "fxrstor"
20239   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20240                     UNSPECV_FXRSTOR)]
20241   "TARGET_FXSR"
20242   "fxrstor\t%0"
20243   [(set_attr "type" "other")
20244    (set_attr "memory" "load")
20245    (set (attr "length")
20246         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20248 (define_insn "fxrstor64"
20249   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20250                     UNSPECV_FXRSTOR64)]
20251   "TARGET_64BIT && TARGET_FXSR"
20252   "fxrstor64\t%0"
20253   [(set_attr "type" "other")
20254    (set_attr "memory" "load")
20255    (set (attr "length")
20256         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20258 (define_int_iterator ANY_XSAVE
20259         [UNSPECV_XSAVE
20260          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20261          (UNSPECV_XSAVEC "TARGET_XSAVEC")
20262          (UNSPECV_XSAVES "TARGET_XSAVES")])
20264 (define_int_iterator ANY_XSAVE64
20265         [UNSPECV_XSAVE64
20266          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20267          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20268          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20270 (define_int_attr xsave
20271         [(UNSPECV_XSAVE "xsave")
20272          (UNSPECV_XSAVE64 "xsave64")
20273          (UNSPECV_XSAVEOPT "xsaveopt")
20274          (UNSPECV_XSAVEOPT64 "xsaveopt64")
20275          (UNSPECV_XSAVEC "xsavec")
20276          (UNSPECV_XSAVEC64 "xsavec64")
20277          (UNSPECV_XSAVES "xsaves")
20278          (UNSPECV_XSAVES64 "xsaves64")])
20280 (define_int_iterator ANY_XRSTOR
20281         [UNSPECV_XRSTOR
20282          (UNSPECV_XRSTORS "TARGET_XSAVES")])
20284 (define_int_iterator ANY_XRSTOR64
20285         [UNSPECV_XRSTOR64
20286          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20288 (define_int_attr xrstor
20289         [(UNSPECV_XRSTOR "xrstor")
20290          (UNSPECV_XRSTOR64 "xrstor")
20291          (UNSPECV_XRSTORS "xrstors")
20292          (UNSPECV_XRSTORS64 "xrstors")])
20294 (define_insn "<xsave>"
20295   [(set (match_operand:BLK 0 "memory_operand" "=m")
20296         (unspec_volatile:BLK
20297          [(match_operand:DI 1 "register_operand" "A")]
20298          ANY_XSAVE))]
20299   "!TARGET_64BIT && TARGET_XSAVE"
20300   "<xsave>\t%0"
20301   [(set_attr "type" "other")
20302    (set_attr "memory" "store")
20303    (set (attr "length")
20304         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20306 (define_insn "<xsave>_rex64"
20307   [(set (match_operand:BLK 0 "memory_operand" "=m")
20308         (unspec_volatile:BLK
20309          [(match_operand:SI 1 "register_operand" "a")
20310           (match_operand:SI 2 "register_operand" "d")]
20311          ANY_XSAVE))]
20312   "TARGET_64BIT && TARGET_XSAVE"
20313   "<xsave>\t%0"
20314   [(set_attr "type" "other")
20315    (set_attr "memory" "store")
20316    (set (attr "length")
20317         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20319 (define_insn "<xsave>"
20320   [(set (match_operand:BLK 0 "memory_operand" "=m")
20321         (unspec_volatile:BLK
20322          [(match_operand:SI 1 "register_operand" "a")
20323           (match_operand:SI 2 "register_operand" "d")]
20324          ANY_XSAVE64))]
20325   "TARGET_64BIT && TARGET_XSAVE"
20326   "<xsave>\t%0"
20327   [(set_attr "type" "other")
20328    (set_attr "memory" "store")
20329    (set (attr "length")
20330         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20332 (define_insn "<xrstor>"
20333    [(unspec_volatile:BLK
20334      [(match_operand:BLK 0 "memory_operand" "m")
20335       (match_operand:DI 1 "register_operand" "A")]
20336      ANY_XRSTOR)]
20337   "!TARGET_64BIT && TARGET_XSAVE"
20338   "<xrstor>\t%0"
20339   [(set_attr "type" "other")
20340    (set_attr "memory" "load")
20341    (set (attr "length")
20342         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20344 (define_insn "<xrstor>_rex64"
20345    [(unspec_volatile:BLK
20346      [(match_operand:BLK 0 "memory_operand" "m")
20347       (match_operand:SI 1 "register_operand" "a")
20348       (match_operand:SI 2 "register_operand" "d")]
20349      ANY_XRSTOR)]
20350   "TARGET_64BIT && TARGET_XSAVE"
20351   "<xrstor>\t%0"
20352   [(set_attr "type" "other")
20353    (set_attr "memory" "load")
20354    (set (attr "length")
20355         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20357 (define_insn "<xrstor>64"
20358    [(unspec_volatile:BLK
20359      [(match_operand:BLK 0 "memory_operand" "m")
20360       (match_operand:SI 1 "register_operand" "a")
20361       (match_operand:SI 2 "register_operand" "d")]
20362      ANY_XRSTOR64)]
20363   "TARGET_64BIT && TARGET_XSAVE"
20364   "<xrstor>64\t%0"
20365   [(set_attr "type" "other")
20366    (set_attr "memory" "load")
20367    (set (attr "length")
20368         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20370 (define_insn "xsetbv"
20371   [(unspec_volatile:SI
20372          [(match_operand:SI 0 "register_operand" "c")
20373           (match_operand:DI 1 "register_operand" "A")]
20374          UNSPECV_XSETBV)]
20375   "!TARGET_64BIT && TARGET_XSAVE"
20376   "xsetbv"
20377   [(set_attr "type" "other")])
20379 (define_insn "xsetbv_rex64"
20380   [(unspec_volatile:SI
20381          [(match_operand:SI 0 "register_operand" "c")
20382           (match_operand:SI 1 "register_operand" "a")
20383           (match_operand:SI 2 "register_operand" "d")]
20384          UNSPECV_XSETBV)]
20385   "TARGET_64BIT && TARGET_XSAVE"
20386   "xsetbv"
20387   [(set_attr "type" "other")])
20389 (define_insn "xgetbv"
20390   [(set (match_operand:DI 0 "register_operand" "=A")
20391         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20392                             UNSPECV_XGETBV))]
20393   "!TARGET_64BIT && TARGET_XSAVE"
20394   "xgetbv"
20395   [(set_attr "type" "other")])
20397 (define_insn "xgetbv_rex64"
20398   [(set (match_operand:DI 0 "register_operand" "=a")
20399         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20400                             UNSPECV_XGETBV))
20401    (set (match_operand:DI 1 "register_operand" "=d")
20402         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20403   "TARGET_64BIT && TARGET_XSAVE"
20404   "xgetbv"
20405   [(set_attr "type" "other")])
20407 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20409 ;; Floating-point instructions for atomic compound assignments
20411 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20413 ; Clobber all floating-point registers on environment save and restore
20414 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20415 (define_insn "fnstenv"
20416   [(set (match_operand:BLK 0 "memory_operand" "=m")
20417         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20418    (clobber (reg:HI FPCR_REG))
20419    (clobber (reg:XF ST0_REG))
20420    (clobber (reg:XF ST1_REG))
20421    (clobber (reg:XF ST2_REG))
20422    (clobber (reg:XF ST3_REG))
20423    (clobber (reg:XF ST4_REG))
20424    (clobber (reg:XF ST5_REG))
20425    (clobber (reg:XF ST6_REG))
20426    (clobber (reg:XF ST7_REG))]
20427   "TARGET_80387"
20428   "fnstenv\t%0"
20429   [(set_attr "type" "other")
20430    (set_attr "memory" "store")
20431    (set (attr "length")
20432         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20434 (define_insn "fldenv"
20435   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20436                     UNSPECV_FLDENV)
20437    (clobber (reg:CCFP FPSR_REG))
20438    (clobber (reg:HI FPCR_REG))
20439    (clobber (reg:XF ST0_REG))
20440    (clobber (reg:XF ST1_REG))
20441    (clobber (reg:XF ST2_REG))
20442    (clobber (reg:XF ST3_REG))
20443    (clobber (reg:XF ST4_REG))
20444    (clobber (reg:XF ST5_REG))
20445    (clobber (reg:XF ST6_REG))
20446    (clobber (reg:XF ST7_REG))]
20447   "TARGET_80387"
20448   "fldenv\t%0"
20449   [(set_attr "type" "other")
20450    (set_attr "memory" "load")
20451    (set (attr "length")
20452         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20454 (define_insn "fnstsw"
20455   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20456         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20457   "TARGET_80387"
20458   "fnstsw\t%0"
20459   [(set_attr "type" "other,other")
20460    (set_attr "memory" "none,store")
20461    (set (attr "length")
20462         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20464 (define_insn "fnclex"
20465   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20466   "TARGET_80387"
20467   "fnclex"
20468   [(set_attr "type" "other")
20469    (set_attr "memory" "none")
20470    (set_attr "length" "2")])
20472 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20474 ;; LWP instructions
20476 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20478 (define_expand "lwp_llwpcb"
20479   [(unspec_volatile [(match_operand 0 "register_operand")]
20480                     UNSPECV_LLWP_INTRINSIC)]
20481   "TARGET_LWP")
20483 (define_insn "*lwp_llwpcb<mode>1"
20484   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20485                     UNSPECV_LLWP_INTRINSIC)]
20486   "TARGET_LWP"
20487   "llwpcb\t%0"
20488   [(set_attr "type" "lwp")
20489    (set_attr "mode" "<MODE>")
20490    (set_attr "length" "5")])
20492 (define_expand "lwp_slwpcb"
20493   [(set (match_operand 0 "register_operand")
20494         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20495   "TARGET_LWP"
20497   rtx (*insn)(rtx);
20499   insn = (Pmode == DImode
20500           ? gen_lwp_slwpcbdi
20501           : gen_lwp_slwpcbsi);
20503   emit_insn (insn (operands[0]));
20504   DONE;
20507 (define_insn "lwp_slwpcb<mode>"
20508   [(set (match_operand:P 0 "register_operand" "=r")
20509         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20510   "TARGET_LWP"
20511   "slwpcb\t%0"
20512   [(set_attr "type" "lwp")
20513    (set_attr "mode" "<MODE>")
20514    (set_attr "length" "5")])
20516 (define_expand "lwp_lwpval<mode>3"
20517   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20518                      (match_operand:SI 2 "nonimmediate_operand")
20519                      (match_operand:SI 3 "const_int_operand")]
20520                     UNSPECV_LWPVAL_INTRINSIC)]
20521   "TARGET_LWP"
20522   ;; Avoid unused variable warning.
20523   "(void) operands[0];")
20525 (define_insn "*lwp_lwpval<mode>3_1"
20526   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20527                      (match_operand:SI 1 "nonimmediate_operand" "rm")
20528                      (match_operand:SI 2 "const_int_operand" "i")]
20529                     UNSPECV_LWPVAL_INTRINSIC)]
20530   "TARGET_LWP"
20531   "lwpval\t{%2, %1, %0|%0, %1, %2}"
20532   [(set_attr "type" "lwp")
20533    (set_attr "mode" "<MODE>")
20534    (set (attr "length")
20535         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20537 (define_expand "lwp_lwpins<mode>3"
20538   [(set (reg:CCC FLAGS_REG)
20539         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20540                               (match_operand:SI 2 "nonimmediate_operand")
20541                               (match_operand:SI 3 "const_int_operand")]
20542                              UNSPECV_LWPINS_INTRINSIC))
20543    (set (match_operand:QI 0 "nonimmediate_operand")
20544         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20545   "TARGET_LWP")
20547 (define_insn "*lwp_lwpins<mode>3_1"
20548   [(set (reg:CCC FLAGS_REG)
20549         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20550                               (match_operand:SI 1 "nonimmediate_operand" "rm")
20551                               (match_operand:SI 2 "const_int_operand" "i")]
20552                              UNSPECV_LWPINS_INTRINSIC))]
20553   "TARGET_LWP"
20554   "lwpins\t{%2, %1, %0|%0, %1, %2}"
20555   [(set_attr "type" "lwp")
20556    (set_attr "mode" "<MODE>")
20557    (set (attr "length")
20558         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20560 (define_int_iterator RDFSGSBASE
20561         [UNSPECV_RDFSBASE
20562          UNSPECV_RDGSBASE])
20564 (define_int_iterator WRFSGSBASE
20565         [UNSPECV_WRFSBASE
20566          UNSPECV_WRGSBASE])
20568 (define_int_attr fsgs
20569         [(UNSPECV_RDFSBASE "fs")
20570          (UNSPECV_RDGSBASE "gs")
20571          (UNSPECV_WRFSBASE "fs")
20572          (UNSPECV_WRGSBASE "gs")])
20574 (define_insn "rd<fsgs>base<mode>"
20575   [(set (match_operand:SWI48 0 "register_operand" "=r")
20576         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20577   "TARGET_64BIT && TARGET_FSGSBASE"
20578   "rd<fsgs>base\t%0"
20579   [(set_attr "type" "other")
20580    (set_attr "prefix_extra" "2")])
20582 (define_insn "wr<fsgs>base<mode>"
20583   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20584                     WRFSGSBASE)]
20585   "TARGET_64BIT && TARGET_FSGSBASE"
20586   "wr<fsgs>base\t%0"
20587   [(set_attr "type" "other")
20588    (set_attr "prefix_extra" "2")])
20590 (define_insn "rdrand<mode>_1"
20591   [(set (match_operand:SWI248 0 "register_operand" "=r")
20592         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20593    (set (reg:CCC FLAGS_REG)
20594         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20595   "TARGET_RDRND"
20596   "rdrand\t%0"
20597   [(set_attr "type" "other")
20598    (set_attr "prefix_extra" "1")])
20600 (define_insn "rdseed<mode>_1"
20601   [(set (match_operand:SWI248 0 "register_operand" "=r")
20602         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20603    (set (reg:CCC FLAGS_REG)
20604         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20605   "TARGET_RDSEED"
20606   "rdseed\t%0"
20607   [(set_attr "type" "other")
20608    (set_attr "prefix_extra" "1")])
20610 (define_expand "pause"
20611   [(set (match_dup 0)
20612         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20613   ""
20615   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20616   MEM_VOLATILE_P (operands[0]) = 1;
20619 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20620 ;; They have the same encoding.
20621 (define_insn "*pause"
20622   [(set (match_operand:BLK 0)
20623         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20624   ""
20625   "rep%; nop"
20626   [(set_attr "length" "2")
20627    (set_attr "memory" "unknown")])
20629 ;; CET instructions
20630 (define_insn "rdssp<mode>"
20631   [(set (match_operand:SWI48x 0 "register_operand" "=r")
20632         (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20633   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20634   "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20635   [(set_attr "length" "6")
20636    (set_attr "type" "other")])
20638 (define_insn "incssp<mode>"
20639   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20640                     UNSPECV_INCSSP)]
20641   "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20642   "incssp<mskmodesuffix>\t%0"
20643   [(set_attr "length" "4")
20644    (set_attr "type" "other")])
20646 (define_insn "saveprevssp"
20647   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20648   "TARGET_SHSTK"
20649   "saveprevssp"
20650   [(set_attr "length" "5")
20651    (set_attr "type" "other")])
20653 (define_expand "rstorssp"
20654   [(unspec_volatile [(match_operand 0 "memory_operand")]
20655                     UNSPECV_RSTORSSP)]
20656   "TARGET_SHSTK")
20658 (define_insn "*rstorssp<mode>"
20659   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20660                     UNSPECV_RSTORSSP)]
20661   "TARGET_SHSTK"
20662   "rstorssp\t%0"
20663   [(set_attr "length" "5")
20664    (set_attr "type" "other")])
20666 (define_insn "wrss<mode>"
20667   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20668                      (match_operand:SWI48x 1 "memory_operand" "m")]
20669                     UNSPECV_WRSS)]
20670   "TARGET_SHSTK"
20671   "wrss<mskmodesuffix>\t%0, %1"
20672   [(set_attr "length" "3")
20673    (set_attr "type" "other")])
20675 (define_insn "wruss<mode>"
20676   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20677                      (match_operand:SWI48x 1 "memory_operand" "m")]
20678                     UNSPECV_WRUSS)]
20679   "TARGET_SHSTK"
20680   "wruss<mskmodesuffix>\t%0, %1"
20681   [(set_attr "length" "4")
20682    (set_attr "type" "other")])
20684 (define_insn "setssbsy"
20685   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20686   "TARGET_SHSTK"
20687   "setssbsy"
20688   [(set_attr "length" "4")
20689    (set_attr "type" "other")])
20691 (define_expand "clrssbsy"
20692   [(unspec_volatile [(match_operand 0 "memory_operand")]
20693                     UNSPECV_CLRSSBSY)]
20694   "TARGET_SHSTK")
20696 (define_insn "*clrssbsy<mode>"
20697   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20698                     UNSPECV_CLRSSBSY)]
20699   "TARGET_SHSTK"
20700   "clrssbsy\t%0"
20701   [(set_attr "length" "4")
20702    (set_attr "type" "other")])
20704 (define_insn "nop_endbr"
20705   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20706   "(flag_cf_protection & CF_BRANCH)"
20708   return TARGET_64BIT ? "endbr64" : "endbr32";
20710   [(set_attr "length" "4")
20711    (set_attr "length_immediate" "0")
20712    (set_attr "modrm" "0")])
20714 ;; For RTM support
20715 (define_expand "xbegin"
20716   [(set (match_operand:SI 0 "register_operand")
20717         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20718   "TARGET_RTM"
20720   rtx_code_label *label = gen_label_rtx ();
20722   /* xbegin is emitted as jump_insn, so reload won't be able
20723      to reload its operand.  Force the value into AX hard register.  */
20724   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20725   emit_move_insn (ax_reg, constm1_rtx);
20727   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20729   emit_label (label);
20730   LABEL_NUSES (label) = 1;
20732   emit_move_insn (operands[0], ax_reg);
20734   DONE;
20737 (define_insn "xbegin_1"
20738   [(set (pc)
20739         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20740                           (const_int 0))
20741                       (label_ref (match_operand 1))
20742                       (pc)))
20743    (set (match_operand:SI 0 "register_operand" "+a")
20744         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20745   "TARGET_RTM"
20746   "xbegin\t%l1"
20747   [(set_attr "type" "other")
20748    (set_attr "length" "6")])
20750 (define_insn "xend"
20751   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20752   "TARGET_RTM"
20753   "xend"
20754   [(set_attr "type" "other")
20755    (set_attr "length" "3")])
20757 (define_insn "xabort"
20758   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20759                     UNSPECV_XABORT)]
20760   "TARGET_RTM"
20761   "xabort\t%0"
20762   [(set_attr "type" "other")
20763    (set_attr "length" "3")])
20765 (define_expand "xtest"
20766   [(set (match_operand:QI 0 "register_operand")
20767         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20768   "TARGET_RTM"
20770   emit_insn (gen_xtest_1 ());
20772   ix86_expand_setcc (operands[0], NE,
20773                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20774   DONE;
20777 (define_insn "xtest_1"
20778   [(set (reg:CCZ FLAGS_REG)
20779         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20780   "TARGET_RTM"
20781   "xtest"
20782   [(set_attr "type" "other")
20783    (set_attr "length" "3")])
20785 (define_insn "clwb"
20786   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20787                    UNSPECV_CLWB)]
20788   "TARGET_CLWB"
20789   "clwb\t%a0"
20790   [(set_attr "type" "sse")
20791    (set_attr "atom_sse_attr" "fence")
20792    (set_attr "memory" "unknown")])
20794 (define_insn "clflushopt"
20795   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20796                    UNSPECV_CLFLUSHOPT)]
20797   "TARGET_CLFLUSHOPT"
20798   "clflushopt\t%a0"
20799   [(set_attr "type" "sse")
20800    (set_attr "atom_sse_attr" "fence")
20801    (set_attr "memory" "unknown")])
20803 ;; MONITORX and MWAITX
20804 (define_insn "mwaitx"
20805   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20806                      (match_operand:SI 1 "register_operand" "a")
20807                      (match_operand:SI 2 "register_operand" "b")]
20808                    UNSPECV_MWAITX)]
20809   "TARGET_MWAITX"
20810 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20811 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20812 ;; we only need to set up 32bit registers.
20813   "mwaitx"
20814   [(set_attr "length" "3")])
20816 (define_insn "monitorx_<mode>"
20817   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20818                      (match_operand:SI 1 "register_operand" "c")
20819                      (match_operand:SI 2 "register_operand" "d")]
20820                    UNSPECV_MONITORX)]
20821   "TARGET_MWAITX"
20822 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20823 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
20824 ;; zero extended to 64bit, we only need to set up 32bit registers.
20825   "%^monitorx"
20826   [(set (attr "length")
20827      (symbol_ref ("(Pmode != word_mode) + 3")))])
20829 ;; CLZERO
20830 (define_insn "clzero_<mode>"
20831   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20832                    UNSPECV_CLZERO)]
20833   "TARGET_CLZERO"
20834   "clzero"
20835   [(set_attr "length" "3")
20836   (set_attr "memory" "unknown")])
20838 ;; RDPKRU and WRPKRU
20840 (define_expand "rdpkru"
20841   [(parallel
20842      [(set (match_operand:SI 0 "register_operand")
20843            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20844       (set (match_dup 2) (const_int 0))])]
20845   "TARGET_PKU"
20847   operands[1] = force_reg (SImode, const0_rtx);
20848   operands[2] = gen_reg_rtx (SImode);
20851 (define_insn "*rdpkru"
20852   [(set (match_operand:SI 0 "register_operand" "=a")
20853         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20854                             UNSPECV_PKU))
20855    (set (match_operand:SI 1 "register_operand" "=d")
20856         (const_int 0))]
20857   "TARGET_PKU"
20858   "rdpkru"
20859   [(set_attr "type" "other")])
20861 (define_expand "wrpkru"
20862   [(unspec_volatile:SI
20863      [(match_operand:SI 0 "register_operand")
20864       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20865   "TARGET_PKU"
20867   operands[1] = force_reg (SImode, const0_rtx);
20868   operands[2] = force_reg (SImode, const0_rtx);
20871 (define_insn "*wrpkru"
20872   [(unspec_volatile:SI
20873      [(match_operand:SI 0 "register_operand" "a")
20874       (match_operand:SI 1 "register_operand" "d")
20875       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20876   "TARGET_PKU"
20877   "wrpkru"
20878   [(set_attr "type" "other")])
20880 (define_insn "rdpid"
20881   [(set (match_operand:SI 0 "register_operand" "=r")
20882         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20883   "!TARGET_64BIT && TARGET_RDPID"
20884   "rdpid\t%0"
20885   [(set_attr "type" "other")])
20887 (define_insn "rdpid_rex64"
20888   [(set (match_operand:DI 0 "register_operand" "=r")
20889         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20890   "TARGET_64BIT && TARGET_RDPID"
20891   "rdpid\t%0"
20892   [(set_attr "type" "other")])
20894 ;; Intirinsics for > i486
20896 (define_insn "wbinvd"
20897   [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20898   ""
20899   "wbinvd"
20900   [(set_attr "type" "other")])
20902 (define_insn "wbnoinvd"
20903   [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20904   "TARGET_WBNOINVD"
20905   "wbnoinvd"
20906   [(set_attr "type" "other")])
20908 ;; MOVDIRI and MOVDIR64B
20910 (define_insn "movdiri<mode>"
20911   [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20912                            (match_operand:SWI48 1 "register_operand" "r")]
20913                           UNSPECV_MOVDIRI)]
20914   "TARGET_MOVDIRI"
20915   "movdiri\t{%1, %0|%0, %1}"
20916   [(set_attr "type" "other")])
20918 (define_insn "movdir64b_<mode>"
20919   [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20920                         (match_operand:XI 1 "memory_operand")]
20921                        UNSPECV_MOVDIR64B)]
20922   "TARGET_MOVDIR64B"
20923   "movdir64b\t{%1, %0|%0, %1}"
20924   [(set_attr "type" "other")])
20926 ;; WAITPKG
20928 (define_insn "umwait"
20929   [(set (reg:CCC FLAGS_REG)
20930         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20931                               (match_operand:DI 1 "register_operand" "A")]
20932                              UNSPECV_UMWAIT))]
20933   "!TARGET_64BIT && TARGET_WAITPKG"
20934   "umwait\t%0"
20935   [(set_attr "length" "3")])
20937 (define_insn "umwait_rex64"
20938   [(set (reg:CCC FLAGS_REG)
20939         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20940                               (match_operand:SI 1 "register_operand" "a")
20941                               (match_operand:SI 2 "register_operand" "d")]
20942                              UNSPECV_UMWAIT))]
20943   "TARGET_64BIT && TARGET_WAITPKG"
20944   "umwait\t%0"
20945   [(set_attr "length" "3")])
20947 (define_insn "umonitor_<mode>"
20948   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20949                     UNSPECV_UMONITOR)]
20950   "TARGET_WAITPKG"
20951   "umonitor\t%0"
20952   [(set (attr "length")
20953      (symbol_ref ("(Pmode != word_mode) + 3")))])
20955 (define_insn "tpause"
20956   [(set (reg:CCC FLAGS_REG)
20957         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20958                               (match_operand:DI 1 "register_operand" "A")]
20959                              UNSPECV_TPAUSE))]
20960   "!TARGET_64BIT && TARGET_WAITPKG"
20961   "tpause\t%0"
20962   [(set_attr "length" "3")])
20964 (define_insn "tpause_rex64"
20965   [(set (reg:CCC FLAGS_REG)
20966         (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20967                               (match_operand:SI 1 "register_operand" "a")
20968                               (match_operand:SI 2 "register_operand" "d")]
20969                              UNSPECV_TPAUSE))]
20970   "TARGET_64BIT && TARGET_WAITPKG"
20971   "tpause\t%0"
20972   [(set_attr "length" "3")])
20974 (define_insn "cldemote"
20975   [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20976                  UNSPECV_CLDEMOTE)]
20977   "TARGET_CLDEMOTE"
20978   "cldemote\t%a0"
20979   [(set_attr "type" "other")
20980    (set_attr "memory" "unknown")])
20982 (include "mmx.md")
20983 (include "sse.md")
20984 (include "sync.md")