i386: Add TARGET_INDIRECT_BRANCH_REGISTER
[official-gcc.git] / gcc / config / i386 / i386.md
blob85e4b07cd0f73d7f4f0c1003ca8a5924630488cd
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 MPX or 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
241   ;; For atomic compound assignments.
242   UNSPECV_FNSTENV
243   UNSPECV_FLDENV
244   UNSPECV_FNSTSW
245   UNSPECV_FNCLEX
247   ;; For RDRAND support
248   UNSPECV_RDRAND
250   ;; For RDSEED support
251   UNSPECV_RDSEED
253   ;; For RTM support
254   UNSPECV_XBEGIN
255   UNSPECV_XEND
256   UNSPECV_XABORT
257   UNSPECV_XTEST
259   UNSPECV_NLGR
261   ;; For CLWB support
262   UNSPECV_CLWB
264   ;; For CLFLUSHOPT support
265   UNSPECV_CLFLUSHOPT
267   ;; For MONITORX and MWAITX support 
268   UNSPECV_MONITORX
269   UNSPECV_MWAITX
271   ;; For CLZERO support
272   UNSPECV_CLZERO
274   ;; For RDPKRU and WRPKRU support
275   UNSPECV_PKU
277   ;; For RDPID support
278   UNSPECV_RDPID
280   ;; For CET support
281   UNSPECV_NOP_ENDBR
282   UNSPECV_NOP_RDSSP
283   UNSPECV_INCSSP
284   UNSPECV_SAVEPREVSSP
285   UNSPECV_RSTORSSP
286   UNSPECV_WRSS
287   UNSPECV_WRUSS
288   UNSPECV_SETSSBSY
289   UNSPECV_CLRSSBSY
292 ;; Constants to represent rounding modes in the ROUND instruction
293 (define_constants
294   [(ROUND_FLOOR                 0x1)
295    (ROUND_CEIL                  0x2)
296    (ROUND_TRUNC                 0x3)
297    (ROUND_MXCSR                 0x4)
298    (ROUND_NO_EXC                0x8)
299   ])
301 ;; Constants to represent AVX512F embeded rounding
302 (define_constants
303   [(ROUND_NEAREST_INT                   0)
304    (ROUND_NEG_INF                       1)
305    (ROUND_POS_INF                       2)
306    (ROUND_ZERO                          3)
307    (NO_ROUND                            4)
308    (ROUND_SAE                           8)
309   ])
311 ;; Constants to represent pcomtrue/pcomfalse variants
312 (define_constants
313   [(PCOM_FALSE                  0)
314    (PCOM_TRUE                   1)
315    (COM_FALSE_S                 2)
316    (COM_FALSE_P                 3)
317    (COM_TRUE_S                  4)
318    (COM_TRUE_P                  5)
319   ])
321 ;; Constants used in the XOP pperm instruction
322 (define_constants
323   [(PPERM_SRC                   0x00)   /* copy source */
324    (PPERM_INVERT                0x20)   /* invert source */
325    (PPERM_REVERSE               0x40)   /* bit reverse source */
326    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
327    (PPERM_ZERO                  0x80)   /* all 0's */
328    (PPERM_ONES                  0xa0)   /* all 1's */
329    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
330    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
331    (PPERM_SRC1                  0x00)   /* use first source byte */
332    (PPERM_SRC2                  0x10)   /* use second source byte */
333    ])
335 ;; Registers by name.
336 (define_constants
337   [(AX_REG                       0)
338    (DX_REG                       1)
339    (CX_REG                       2)
340    (BX_REG                       3)
341    (SI_REG                       4)
342    (DI_REG                       5)
343    (BP_REG                       6)
344    (SP_REG                       7)
345    (ST0_REG                      8)
346    (ST1_REG                      9)
347    (ST2_REG                     10)
348    (ST3_REG                     11)
349    (ST4_REG                     12)
350    (ST5_REG                     13)
351    (ST6_REG                     14)
352    (ST7_REG                     15)
353    (ARGP_REG                    16)
354    (FLAGS_REG                   17)
355    (FPSR_REG                    18)
356    (FPCR_REG                    19)
357    (FRAME_REG                   20)
358    (XMM0_REG                    21)
359    (XMM1_REG                    22)
360    (XMM2_REG                    23)
361    (XMM3_REG                    24)
362    (XMM4_REG                    25)
363    (XMM5_REG                    26)
364    (XMM6_REG                    27)
365    (XMM7_REG                    28)
366    (MM0_REG                     29)
367    (MM1_REG                     30)
368    (MM2_REG                     31)
369    (MM3_REG                     32)
370    (MM4_REG                     33)
371    (MM5_REG                     34)
372    (MM6_REG                     35)
373    (MM7_REG                     36)
374    (R8_REG                      37)
375    (R9_REG                      38)
376    (R10_REG                     39)
377    (R11_REG                     40)
378    (R12_REG                     41)
379    (R13_REG                     42)
380    (R14_REG                     43)
381    (R15_REG                     44)
382    (XMM8_REG                    45)
383    (XMM9_REG                    46)
384    (XMM10_REG                   47)
385    (XMM11_REG                   48)
386    (XMM12_REG                   49)
387    (XMM13_REG                   50)
388    (XMM14_REG                   51)
389    (XMM15_REG                   52)
390    (XMM16_REG                   53)
391    (XMM17_REG                   54)
392    (XMM18_REG                   55)
393    (XMM19_REG                   56)
394    (XMM20_REG                   57)
395    (XMM21_REG                   58)
396    (XMM22_REG                   59)
397    (XMM23_REG                   60)
398    (XMM24_REG                   61)
399    (XMM25_REG                   62)
400    (XMM26_REG                   63)
401    (XMM27_REG                   64)
402    (XMM28_REG                   65)
403    (XMM29_REG                   66)
404    (XMM30_REG                   67)
405    (XMM31_REG                   68)
406    (MASK0_REG                   69)
407    (MASK1_REG                   70)
408    (MASK2_REG                   71)
409    (MASK3_REG                   72)
410    (MASK4_REG                   73)
411    (MASK5_REG                   74)
412    (MASK6_REG                   75)
413    (MASK7_REG                   76)
414    (BND0_REG                    77)
415    (BND1_REG                    78)
416    (BND2_REG                    79)
417    (BND3_REG                    80)
418    (FIRST_PSEUDO_REG            81)
419   ])
421 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
422 ;; from i386.c.
424 ;; In C guard expressions, put expressions which may be compile-time
425 ;; constants first.  This allows for better optimization.  For
426 ;; example, write "TARGET_64BIT && reload_completed", not
427 ;; "reload_completed && TARGET_64BIT".
430 ;; Processor type.
431 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
432                     atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
433                     bdver4,btver2,znver1"
434   (const (symbol_ref "ix86_schedule")))
436 ;; A basic instruction type.  Refinements due to arguments to be
437 ;; provided in other attributes.
438 (define_attr "type"
439   "other,multi,
440    alu,alu1,negnot,imov,imovx,lea,
441    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
442    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
443    push,pop,call,callv,leave,
444    str,bitmanip,
445    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
446    fxch,fistp,fisttp,frndint,
447    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
448    ssemul,sseimul,ssediv,sselog,sselog1,
449    sseishft,sseishft1,ssecmp,ssecomi,
450    ssecvt,ssecvt1,sseicvt,sseins,
451    sseshuf,sseshuf1,ssemuladd,sse4arg,
452    lwp,mskmov,msklog,
453    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
454    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
455   (const_string "other"))
457 ;; Main data type used by the insn
458 (define_attr "mode"
459   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
460   V2DF,V2SF,V1DF,V8DF"
461   (const_string "unknown"))
463 ;; The CPU unit operations uses.
464 (define_attr "unit" "integer,i387,sse,mmx,unknown"
465   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
466                           fxch,fistp,fisttp,frndint")
467            (const_string "i387")
468          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
469                           ssemul,sseimul,ssediv,sselog,sselog1,
470                           sseishft,sseishft1,ssecmp,ssecomi,
471                           ssecvt,ssecvt1,sseicvt,sseins,
472                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
473            (const_string "sse")
474          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
475            (const_string "mmx")
476          (eq_attr "type" "other")
477            (const_string "unknown")]
478          (const_string "integer")))
480 ;; The (bounding maximum) length of an instruction immediate.
481 (define_attr "length_immediate" ""
482   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
483                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
484                           mpxld,mpxst")
485            (const_int 0)
486          (eq_attr "unit" "i387,sse,mmx")
487            (const_int 0)
488          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
489                           rotate,rotatex,rotate1,imul,icmp,push,pop")
490            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
491          (eq_attr "type" "imov,test")
492            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
493          (eq_attr "type" "call")
494            (if_then_else (match_operand 0 "constant_call_address_operand")
495              (const_int 4)
496              (const_int 0))
497          (eq_attr "type" "callv")
498            (if_then_else (match_operand 1 "constant_call_address_operand")
499              (const_int 4)
500              (const_int 0))
501          ;; We don't know the size before shorten_branches.  Expect
502          ;; the instruction to fit for better scheduling.
503          (eq_attr "type" "ibr")
504            (const_int 1)
505          ]
506          (symbol_ref "/* Update immediate_length and other attributes! */
507                       gcc_unreachable (),1")))
509 ;; The (bounding maximum) length of an instruction address.
510 (define_attr "length_address" ""
511   (cond [(eq_attr "type" "str,other,multi,fxch")
512            (const_int 0)
513          (and (eq_attr "type" "call")
514               (match_operand 0 "constant_call_address_operand"))
515              (const_int 0)
516          (and (eq_attr "type" "callv")
517               (match_operand 1 "constant_call_address_operand"))
518              (const_int 0)
519          ]
520          (symbol_ref "ix86_attr_length_address_default (insn)")))
522 ;; Set when length prefix is used.
523 (define_attr "prefix_data16" ""
524   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
525            (const_int 0)
526          (eq_attr "mode" "HI")
527            (const_int 1)
528          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
529            (const_int 1)
530         ]
531         (const_int 0)))
533 ;; Set when string REP prefix is used.
534 (define_attr "prefix_rep" ""
535   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
536            (const_int 0)
537          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
538            (const_int 1)
539          (and (eq_attr "type" "ibr,call,callv")
540               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
541            (const_int 1)
542         ]
543         (const_int 0)))
545 ;; Set when 0f opcode prefix is used.
546 (define_attr "prefix_0f" ""
547   (if_then_else
548     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
549                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
550          (eq_attr "unit" "sse,mmx"))
551     (const_int 1)
552     (const_int 0)))
554 ;; Set when REX opcode prefix is used.
555 (define_attr "prefix_rex" ""
556   (cond [(not (match_test "TARGET_64BIT"))
557            (const_int 0)
558          (and (eq_attr "mode" "DI")
559               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
560                    (eq_attr "unit" "!mmx")))
561            (const_int 1)
562          (and (eq_attr "mode" "QI")
563               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
564            (const_int 1)
565          (match_test "x86_extended_reg_mentioned_p (insn)")
566            (const_int 1)
567          (and (eq_attr "type" "imovx")
568               (match_operand:QI 1 "ext_QIreg_operand"))
569            (const_int 1)
570         ]
571         (const_int 0)))
573 ;; There are also additional prefixes in 3DNOW, SSSE3.
574 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
575 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
576 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
577 (define_attr "prefix_extra" ""
578   (cond [(eq_attr "type" "ssemuladd,sse4arg")
579            (const_int 2)
580          (eq_attr "type" "sseiadd1,ssecvt1")
581            (const_int 1)
582         ]
583         (const_int 0)))
585 ;; Set when BND opcode prefix may be used.
586 (define_attr "maybe_prefix_bnd" "" (const_int 0))
588 ;; Prefix used: original, VEX or maybe VEX.
589 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
590   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
591            (const_string "vex")
592          (eq_attr "mode" "XI,V16SF,V8DF")
593            (const_string "evex")
594         ]
595         (const_string "orig")))
597 ;; VEX W bit is used.
598 (define_attr "prefix_vex_w" "" (const_int 0))
600 ;; The length of VEX prefix
601 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
602 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
603 ;; still prefix_0f 1, with prefix_extra 1.
604 (define_attr "length_vex" ""
605   (if_then_else (and (eq_attr "prefix_0f" "1")
606                      (eq_attr "prefix_extra" "0"))
607     (if_then_else (eq_attr "prefix_vex_w" "1")
608       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
609       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
610     (if_then_else (eq_attr "prefix_vex_w" "1")
611       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
612       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
614 ;; 4-bytes evex prefix and 1 byte opcode.
615 (define_attr "length_evex" "" (const_int 5))
617 ;; Set when modrm byte is used.
618 (define_attr "modrm" ""
619   (cond [(eq_attr "type" "str,leave")
620            (const_int 0)
621          (eq_attr "unit" "i387")
622            (const_int 0)
623          (and (eq_attr "type" "incdec")
624               (and (not (match_test "TARGET_64BIT"))
625                    (ior (match_operand:SI 1 "register_operand")
626                         (match_operand:HI 1 "register_operand"))))
627            (const_int 0)
628          (and (eq_attr "type" "push")
629               (not (match_operand 1 "memory_operand")))
630            (const_int 0)
631          (and (eq_attr "type" "pop")
632               (not (match_operand 0 "memory_operand")))
633            (const_int 0)
634          (and (eq_attr "type" "imov")
635               (and (not (eq_attr "mode" "DI"))
636                    (ior (and (match_operand 0 "register_operand")
637                              (match_operand 1 "immediate_operand"))
638                         (ior (and (match_operand 0 "ax_reg_operand")
639                                   (match_operand 1 "memory_displacement_only_operand"))
640                              (and (match_operand 0 "memory_displacement_only_operand")
641                                   (match_operand 1 "ax_reg_operand"))))))
642            (const_int 0)
643          (and (eq_attr "type" "call")
644               (match_operand 0 "constant_call_address_operand"))
645              (const_int 0)
646          (and (eq_attr "type" "callv")
647               (match_operand 1 "constant_call_address_operand"))
648              (const_int 0)
649          (and (eq_attr "type" "alu,alu1,icmp,test")
650               (match_operand 0 "ax_reg_operand"))
651              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
652          ]
653          (const_int 1)))
655 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
656   (cond [(eq_attr "modrm" "0")
657            (const_string "none")
658          (eq_attr "type" "alu,imul,ishift")
659            (const_string "op02")
660          (eq_attr "type" "imov,imovx,lea,alu1,icmp")
661            (const_string "op01")
662          (eq_attr "type" "incdec")
663            (const_string "incdec")
664          (eq_attr "type" "push,pop")
665            (const_string "pushpop")]
666          (const_string "unknown")))
668 ;; The (bounding maximum) length of an instruction in bytes.
669 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
670 ;; Later we may want to split them and compute proper length as for
671 ;; other insns.
672 (define_attr "length" ""
673   (cond [(eq_attr "type" "other,multi,fistp,frndint")
674            (const_int 16)
675          (eq_attr "type" "fcmp")
676            (const_int 4)
677          (eq_attr "unit" "i387")
678            (plus (const_int 2)
679                  (plus (attr "prefix_data16")
680                        (attr "length_address")))
681          (ior (eq_attr "prefix" "evex")
682               (and (ior (eq_attr "prefix" "maybe_evex")
683                         (eq_attr "prefix" "maybe_vex"))
684                    (match_test "TARGET_AVX512F")))
685            (plus (attr "length_evex")
686                  (plus (attr "length_immediate")
687                        (plus (attr "modrm")
688                              (attr "length_address"))))
689          (ior (eq_attr "prefix" "vex")
690               (and (ior (eq_attr "prefix" "maybe_vex")
691                         (eq_attr "prefix" "maybe_evex"))
692                    (match_test "TARGET_AVX")))
693            (plus (attr "length_vex")
694                  (plus (attr "length_immediate")
695                        (plus (attr "modrm")
696                              (attr "length_address"))))]
697          (plus (plus (attr "modrm")
698                      (plus (attr "prefix_0f")
699                            (plus (attr "prefix_rex")
700                                  (plus (attr "prefix_extra")
701                                        (const_int 1)))))
702                (plus (attr "prefix_rep")
703                      (plus (attr "prefix_data16")
704                            (plus (attr "length_immediate")
705                                  (attr "length_address")))))))
707 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
708 ;; `store' if there is a simple memory reference therein, or `unknown'
709 ;; if the instruction is complex.
711 (define_attr "memory" "none,load,store,both,unknown"
712   (cond [(eq_attr "type" "other,multi,str,lwp")
713            (const_string "unknown")
714          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
715            (const_string "none")
716          (eq_attr "type" "fistp,leave")
717            (const_string "both")
718          (eq_attr "type" "frndint")
719            (const_string "load")
720          (eq_attr "type" "mpxld")
721            (const_string "load")
722          (eq_attr "type" "mpxst")
723            (const_string "store")
724          (eq_attr "type" "push")
725            (if_then_else (match_operand 1 "memory_operand")
726              (const_string "both")
727              (const_string "store"))
728          (eq_attr "type" "pop")
729            (if_then_else (match_operand 0 "memory_operand")
730              (const_string "both")
731              (const_string "load"))
732          (eq_attr "type" "setcc")
733            (if_then_else (match_operand 0 "memory_operand")
734              (const_string "store")
735              (const_string "none"))
736          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
737            (if_then_else (ior (match_operand 0 "memory_operand")
738                               (match_operand 1 "memory_operand"))
739              (const_string "load")
740              (const_string "none"))
741          (eq_attr "type" "ibr")
742            (if_then_else (match_operand 0 "memory_operand")
743              (const_string "load")
744              (const_string "none"))
745          (eq_attr "type" "call")
746            (if_then_else (match_operand 0 "constant_call_address_operand")
747              (const_string "none")
748              (const_string "load"))
749          (eq_attr "type" "callv")
750            (if_then_else (match_operand 1 "constant_call_address_operand")
751              (const_string "none")
752              (const_string "load"))
753          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
754               (match_operand 1 "memory_operand"))
755            (const_string "both")
756          (and (match_operand 0 "memory_operand")
757               (match_operand 1 "memory_operand"))
758            (const_string "both")
759          (match_operand 0 "memory_operand")
760            (const_string "store")
761          (match_operand 1 "memory_operand")
762            (const_string "load")
763          (and (eq_attr "type"
764                  "!alu1,negnot,ishift1,
765                    imov,imovx,icmp,test,bitmanip,
766                    fmov,fcmp,fsgn,
767                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
768                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
769                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
770               (match_operand 2 "memory_operand"))
771            (const_string "load")
772          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
773               (match_operand 3 "memory_operand"))
774            (const_string "load")
775         ]
776         (const_string "none")))
778 ;; Indicates if an instruction has both an immediate and a displacement.
780 (define_attr "imm_disp" "false,true,unknown"
781   (cond [(eq_attr "type" "other,multi")
782            (const_string "unknown")
783          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
784               (and (match_operand 0 "memory_displacement_operand")
785                    (match_operand 1 "immediate_operand")))
786            (const_string "true")
787          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
788               (and (match_operand 0 "memory_displacement_operand")
789                    (match_operand 2 "immediate_operand")))
790            (const_string "true")
791         ]
792         (const_string "false")))
794 ;; Indicates if an FP operation has an integer source.
796 (define_attr "fp_int_src" "false,true"
797   (const_string "false"))
799 ;; Defines rounding mode of an FP operation.
801 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
802   (const_string "any"))
804 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
805 (define_attr "use_carry" "0,1" (const_string "0"))
807 ;; Define attribute to indicate unaligned ssemov insns
808 (define_attr "movu" "0,1" (const_string "0"))
810 ;; Used to control the "enabled" attribute on a per-instruction basis.
811 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
812                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
813                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
814                     avx512bw,noavx512bw,avx512dq,noavx512dq,
815                     avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
816   (const_string "base"))
818 (define_attr "enabled" ""
819   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
820          (eq_attr "isa" "x64_sse4")
821            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
822          (eq_attr "isa" "x64_sse4_noavx")
823            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
824          (eq_attr "isa" "x64_avx")
825            (symbol_ref "TARGET_64BIT && TARGET_AVX")
826          (eq_attr "isa" "x64_avx512dq")
827            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
828          (eq_attr "isa" "x64_avx512bw")
829            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
830          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
831          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
832          (eq_attr "isa" "sse2_noavx")
833            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
834          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
835          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
836          (eq_attr "isa" "sse4_noavx")
837            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
838          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
839          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
840          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
841          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
842          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
843          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
844          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
845          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
846          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
847          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
848          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
849          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
850          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
851          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
852          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
853          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
854         ]
855         (const_int 1)))
857 (define_attr "preferred_for_size" "" (const_int 1))
858 (define_attr "preferred_for_speed" "" (const_int 1))
860 ;; Describe a user's asm statement.
861 (define_asm_attributes
862   [(set_attr "length" "128")
863    (set_attr "type" "multi")])
865 (define_code_iterator plusminus [plus minus])
867 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
869 (define_code_iterator multdiv [mult div])
871 ;; Base name for define_insn
872 (define_code_attr plusminus_insn
873   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
874    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
876 ;; Base name for insn mnemonic.
877 (define_code_attr plusminus_mnemonic
878   [(plus "add") (ss_plus "adds") (us_plus "addus")
879    (minus "sub") (ss_minus "subs") (us_minus "subus")])
880 (define_code_attr multdiv_mnemonic
881   [(mult "mul") (div "div")])
883 ;; Mark commutative operators as such in constraints.
884 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
885                         (minus "") (ss_minus "") (us_minus "")])
887 ;; Mapping of max and min
888 (define_code_iterator maxmin [smax smin umax umin])
890 ;; Mapping of signed max and min
891 (define_code_iterator smaxmin [smax smin])
893 ;; Mapping of unsigned max and min
894 (define_code_iterator umaxmin [umax umin])
896 ;; Base name for integer and FP insn mnemonic
897 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
898                               (umax "maxu") (umin "minu")])
899 (define_code_attr maxmin_float [(smax "max") (smin "min")])
901 (define_int_iterator IEEE_MAXMIN
902         [UNSPEC_IEEE_MAX
903          UNSPEC_IEEE_MIN])
905 (define_int_attr ieee_maxmin
906         [(UNSPEC_IEEE_MAX "max")
907          (UNSPEC_IEEE_MIN "min")])
909 ;; Mapping of logic operators
910 (define_code_iterator any_logic [and ior xor])
911 (define_code_iterator any_or [ior xor])
912 (define_code_iterator fpint_logic [and xor])
914 ;; Base name for insn mnemonic.
915 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
917 ;; Mapping of logic-shift operators
918 (define_code_iterator any_lshift [ashift lshiftrt])
920 ;; Mapping of shift-right operators
921 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
923 ;; Mapping of all shift operators
924 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
926 ;; Base name for define_insn
927 (define_code_attr shift_insn
928   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
930 ;; Base name for insn mnemonic.
931 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
932 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
934 ;; Mapping of rotate operators
935 (define_code_iterator any_rotate [rotate rotatert])
937 ;; Base name for define_insn
938 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
940 ;; Base name for insn mnemonic.
941 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
943 ;; Mapping of abs neg operators
944 (define_code_iterator absneg [abs neg])
946 ;; Base name for x87 insn mnemonic.
947 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
949 ;; Used in signed and unsigned widening multiplications.
950 (define_code_iterator any_extend [sign_extend zero_extend])
952 ;; Prefix for insn menmonic.
953 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
955 ;; Prefix for define_insn
956 (define_code_attr u [(sign_extend "") (zero_extend "u")])
957 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
958 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
960 ;; Used in signed and unsigned truncations.
961 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
962 ;; Instruction suffix for truncations.
963 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
965 ;; Used in signed and unsigned fix.
966 (define_code_iterator any_fix [fix unsigned_fix])
967 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
969 ;; Used in signed and unsigned float.
970 (define_code_iterator any_float [float unsigned_float])
971 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
973 ;; All integer modes.
974 (define_mode_iterator SWI1248x [QI HI SI DI])
976 ;; All integer modes without QImode.
977 (define_mode_iterator SWI248x [HI SI DI])
979 ;; All integer modes without QImode and HImode.
980 (define_mode_iterator SWI48x [SI DI])
982 ;; All integer modes without SImode and DImode.
983 (define_mode_iterator SWI12 [QI HI])
985 ;; All integer modes without DImode.
986 (define_mode_iterator SWI124 [QI HI SI])
988 ;; All integer modes without QImode and DImode.
989 (define_mode_iterator SWI24 [HI SI])
991 ;; Single word integer modes.
992 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
994 ;; Single word integer modes without QImode.
995 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
997 ;; Single word integer modes without QImode and HImode.
998 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1000 ;; All math-dependant single and double word integer modes.
1001 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1002                              (HI "TARGET_HIMODE_MATH")
1003                              SI DI (TI "TARGET_64BIT")])
1005 ;; Math-dependant single word integer modes.
1006 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1007                             (HI "TARGET_HIMODE_MATH")
1008                             SI (DI "TARGET_64BIT")])
1010 ;; Math-dependant integer modes without DImode.
1011 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1012                                (HI "TARGET_HIMODE_MATH")
1013                                SI])
1015 ;; Math-dependant integer modes with DImode.
1016 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1017                                  (HI "TARGET_HIMODE_MATH")
1018                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1020 ;; Math-dependant single word integer modes without QImode.
1021 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1022                                SI (DI "TARGET_64BIT")])
1024 ;; Double word integer modes.
1025 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1026                            (TI "TARGET_64BIT")])
1028 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1029 ;; compile time constant, it is faster to use <MODE_SIZE> than
1030 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1031 ;; command line options just use GET_MODE_SIZE macro.
1032 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1033                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1034                              (V16QI "16") (V32QI "32") (V64QI "64")
1035                              (V8HI "16") (V16HI "32") (V32HI "64")
1036                              (V4SI "16") (V8SI "32") (V16SI "64")
1037                              (V2DI "16") (V4DI "32") (V8DI "64")
1038                              (V1TI "16") (V2TI "32") (V4TI "64")
1039                              (V2DF "16") (V4DF "32") (V8DF "64")
1040                              (V4SF "16") (V8SF "32") (V16SF "64")])
1042 ;; Double word integer modes as mode attribute.
1043 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1044 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1046 ;; LEA mode corresponding to an integer mode
1047 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1049 ;; Half mode for double word integer modes.
1050 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1051                             (DI "TARGET_64BIT")])
1053 ;; Bound modes.
1054 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1055                            (BND64 "TARGET_LP64")])
1057 ;; Pointer mode corresponding to bound mode.
1058 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1060 ;; MPX check types
1061 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1063 ;; Check name
1064 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1065                            (UNSPEC_BNDCU "cu")
1066                            (UNSPEC_BNDCN "cn")])
1068 ;; Instruction suffix for integer modes.
1069 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1071 ;; Instruction suffix for masks.
1072 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1074 ;; Pointer size prefix for integer modes (Intel asm dialect)
1075 (define_mode_attr iptrsize [(QI "BYTE")
1076                             (HI "WORD")
1077                             (SI "DWORD")
1078                             (DI "QWORD")])
1080 ;; Register class for integer modes.
1081 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1083 ;; Immediate operand constraint for integer modes.
1084 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1086 ;; General operand constraint for word modes.
1087 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1089 ;; Immediate operand constraint for double integer modes.
1090 (define_mode_attr di [(SI "nF") (DI "Wd")])
1092 ;; Immediate operand constraint for shifts.
1093 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1095 ;; Print register name in the specified mode.
1096 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1098 ;; General operand predicate for integer modes.
1099 (define_mode_attr general_operand
1100         [(QI "general_operand")
1101          (HI "general_operand")
1102          (SI "x86_64_general_operand")
1103          (DI "x86_64_general_operand")
1104          (TI "x86_64_general_operand")])
1106 ;; General operand predicate for integer modes, where for TImode
1107 ;; we need both words of the operand to be general operands.
1108 (define_mode_attr general_hilo_operand
1109         [(QI "general_operand")
1110          (HI "general_operand")
1111          (SI "x86_64_general_operand")
1112          (DI "x86_64_general_operand")
1113          (TI "x86_64_hilo_general_operand")])
1115 ;; General sign extend operand predicate for integer modes,
1116 ;; which disallows VOIDmode operands and thus it is suitable
1117 ;; for use inside sign_extend.
1118 (define_mode_attr general_sext_operand
1119         [(QI "sext_operand")
1120          (HI "sext_operand")
1121          (SI "x86_64_sext_operand")
1122          (DI "x86_64_sext_operand")])
1124 ;; General sign/zero extend operand predicate for integer modes.
1125 (define_mode_attr general_szext_operand
1126         [(QI "general_operand")
1127          (HI "general_operand")
1128          (SI "x86_64_szext_general_operand")
1129          (DI "x86_64_szext_general_operand")])
1131 ;; Immediate operand predicate for integer modes.
1132 (define_mode_attr immediate_operand
1133         [(QI "immediate_operand")
1134          (HI "immediate_operand")
1135          (SI "x86_64_immediate_operand")
1136          (DI "x86_64_immediate_operand")])
1138 ;; Nonmemory operand predicate for integer modes.
1139 (define_mode_attr nonmemory_operand
1140         [(QI "nonmemory_operand")
1141          (HI "nonmemory_operand")
1142          (SI "x86_64_nonmemory_operand")
1143          (DI "x86_64_nonmemory_operand")])
1145 ;; Operand predicate for shifts.
1146 (define_mode_attr shift_operand
1147         [(QI "nonimmediate_operand")
1148          (HI "nonimmediate_operand")
1149          (SI "nonimmediate_operand")
1150          (DI "shiftdi_operand")
1151          (TI "register_operand")])
1153 ;; Operand predicate for shift argument.
1154 (define_mode_attr shift_immediate_operand
1155         [(QI "const_1_to_31_operand")
1156          (HI "const_1_to_31_operand")
1157          (SI "const_1_to_31_operand")
1158          (DI "const_1_to_63_operand")])
1160 ;; Input operand predicate for arithmetic left shifts.
1161 (define_mode_attr ashl_input_operand
1162         [(QI "nonimmediate_operand")
1163          (HI "nonimmediate_operand")
1164          (SI "nonimmediate_operand")
1165          (DI "ashldi_input_operand")
1166          (TI "reg_or_pm1_operand")])
1168 ;; SSE and x87 SFmode and DFmode floating point modes
1169 (define_mode_iterator MODEF [SF DF])
1171 ;; All x87 floating point modes
1172 (define_mode_iterator X87MODEF [SF DF XF])
1174 ;; SSE instruction suffix for various modes
1175 (define_mode_attr ssemodesuffix
1176   [(SF "ss") (DF "sd")
1177    (V16SF "ps") (V8DF "pd")
1178    (V8SF "ps") (V4DF "pd")
1179    (V4SF "ps") (V2DF "pd")
1180    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1181    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1182    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1184 ;; SSE vector suffix for floating point modes
1185 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1187 ;; SSE vector mode corresponding to a scalar mode
1188 (define_mode_attr ssevecmode
1189   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1190 (define_mode_attr ssevecmodelower
1191   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1193 ;; AVX512F vector mode corresponding to a scalar mode
1194 (define_mode_attr avx512fvecmode
1195   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1197 ;; Instruction suffix for REX 64bit operators.
1198 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1200 ;; This mode iterator allows :P to be used for patterns that operate on
1201 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1202 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1204 ;; This mode iterator allows :W to be used for patterns that operate on
1205 ;; word_mode sized quantities.
1206 (define_mode_iterator W
1207   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1209 ;; This mode iterator allows :PTR to be used for patterns that operate on
1210 ;; ptr_mode sized quantities.
1211 (define_mode_iterator PTR
1212   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1214 ;; Scheduling descriptions
1216 (include "pentium.md")
1217 (include "ppro.md")
1218 (include "k6.md")
1219 (include "athlon.md")
1220 (include "bdver1.md")
1221 (include "bdver3.md")
1222 (include "btver2.md")
1223 (include "znver1.md")
1224 (include "geode.md")
1225 (include "atom.md")
1226 (include "slm.md")
1227 (include "core2.md")
1228 (include "haswell.md")
1231 ;; Operand and operator predicates and constraints
1233 (include "predicates.md")
1234 (include "constraints.md")
1237 ;; Compare and branch/compare and store instructions.
1239 (define_expand "cbranch<mode>4"
1240   [(set (reg:CC FLAGS_REG)
1241         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1242                     (match_operand:SDWIM 2 "<general_operand>")))
1243    (set (pc) (if_then_else
1244                (match_operator 0 "ordered_comparison_operator"
1245                 [(reg:CC FLAGS_REG) (const_int 0)])
1246                (label_ref (match_operand 3))
1247                (pc)))]
1248   ""
1250   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1251     operands[1] = force_reg (<MODE>mode, operands[1]);
1252   ix86_expand_branch (GET_CODE (operands[0]),
1253                       operands[1], operands[2], operands[3]);
1254   DONE;
1257 (define_expand "cstore<mode>4"
1258   [(set (reg:CC FLAGS_REG)
1259         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1260                     (match_operand:SWIM 3 "<general_operand>")))
1261    (set (match_operand:QI 0 "register_operand")
1262         (match_operator 1 "ordered_comparison_operator"
1263           [(reg:CC FLAGS_REG) (const_int 0)]))]
1264   ""
1266   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1267     operands[2] = force_reg (<MODE>mode, operands[2]);
1268   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1269                      operands[2], operands[3]);
1270   DONE;
1273 (define_expand "cmp<mode>_1"
1274   [(set (reg:CC FLAGS_REG)
1275         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1276                     (match_operand:SWI48 1 "<general_operand>")))])
1278 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1279   [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1280    (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1282 (define_insn "*cmp<mode>_ccz_1"
1283   [(set (reg FLAGS_REG)
1284         (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1285                         "nonimmediate_operand" "<r>,?m<r>,$k")
1286                  (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1287   "ix86_match_ccmode (insn, CCZmode)"
1288   "@
1289    test{<imodesuffix>}\t%0, %0
1290    cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1291    ktest<mskmodesuffix>\t%0, %0"
1292   [(set_attr "type" "test,icmp,msklog")
1293    (set_attr "length_immediate" "0,1,*")
1294    (set_attr "modrm_class" "op0,unknown,*")
1295    (set_attr "prefix" "*,*,vex")
1296    (set_attr "mode" "<MODE>")])
1298 (define_insn "*cmp<mode>_ccno_1"
1299   [(set (reg FLAGS_REG)
1300         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1301                  (match_operand:SWI 1 "const0_operand")))]
1302   "ix86_match_ccmode (insn, CCNOmode)"
1303   "@
1304    test{<imodesuffix>}\t%0, %0
1305    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1306   [(set_attr "type" "test,icmp")
1307    (set_attr "length_immediate" "0,1")
1308    (set_attr "modrm_class" "op0,unknown")
1309    (set_attr "mode" "<MODE>")])
1311 (define_insn "*cmp<mode>_1"
1312   [(set (reg FLAGS_REG)
1313         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1314                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1315   "ix86_match_ccmode (insn, CCmode)"
1316   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1317   [(set_attr "type" "icmp")
1318    (set_attr "mode" "<MODE>")])
1320 (define_insn "*cmp<mode>_minus_1"
1321   [(set (reg FLAGS_REG)
1322         (compare
1323           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1324                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1325           (const_int 0)))]
1326   "ix86_match_ccmode (insn, CCGOCmode)"
1327   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1328   [(set_attr "type" "icmp")
1329    (set_attr "mode" "<MODE>")])
1331 (define_insn "*cmpqi_ext_1"
1332   [(set (reg FLAGS_REG)
1333         (compare
1334           (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1335           (subreg:QI
1336             (zero_extract:SI
1337               (match_operand 1 "ext_register_operand" "Q,Q")
1338               (const_int 8)
1339               (const_int 8)) 0)))]
1340   "ix86_match_ccmode (insn, CCmode)"
1341   "cmp{b}\t{%h1, %0|%0, %h1}"
1342   [(set_attr "isa" "*,nox64")
1343    (set_attr "type" "icmp")
1344    (set_attr "mode" "QI")])
1346 (define_insn "*cmpqi_ext_2"
1347   [(set (reg FLAGS_REG)
1348         (compare
1349           (subreg:QI
1350             (zero_extract:SI
1351               (match_operand 0 "ext_register_operand" "Q")
1352               (const_int 8)
1353               (const_int 8)) 0)
1354           (match_operand:QI 1 "const0_operand")))]
1355   "ix86_match_ccmode (insn, CCNOmode)"
1356   "test{b}\t%h0, %h0"
1357   [(set_attr "type" "test")
1358    (set_attr "length_immediate" "0")
1359    (set_attr "mode" "QI")])
1361 (define_expand "cmpqi_ext_3"
1362   [(set (reg:CC FLAGS_REG)
1363         (compare:CC
1364           (subreg:QI
1365             (zero_extract:SI
1366               (match_operand 0 "ext_register_operand")
1367               (const_int 8)
1368               (const_int 8)) 0)
1369           (match_operand:QI 1 "const_int_operand")))])
1371 (define_insn "*cmpqi_ext_3"
1372   [(set (reg FLAGS_REG)
1373         (compare
1374           (subreg:QI
1375             (zero_extract:SI
1376               (match_operand 0 "ext_register_operand" "Q,Q")
1377               (const_int 8)
1378               (const_int 8)) 0)
1379           (match_operand:QI 1 "general_operand" "QnBc,m")))]
1380   "ix86_match_ccmode (insn, CCmode)"
1381   "cmp{b}\t{%1, %h0|%h0, %1}"
1382   [(set_attr "isa" "*,nox64")
1383    (set_attr "type" "icmp")
1384    (set_attr "mode" "QI")])
1386 (define_insn "*cmpqi_ext_4"
1387   [(set (reg FLAGS_REG)
1388         (compare
1389           (subreg:QI
1390             (zero_extract:SI
1391               (match_operand 0 "ext_register_operand" "Q")
1392               (const_int 8)
1393               (const_int 8)) 0)
1394           (subreg:QI
1395             (zero_extract:SI
1396               (match_operand 1 "ext_register_operand" "Q")
1397               (const_int 8)
1398               (const_int 8)) 0)))]
1399   "ix86_match_ccmode (insn, CCmode)"
1400   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1401   [(set_attr "type" "icmp")
1402    (set_attr "mode" "QI")])
1404 ;; These implement float point compares.
1405 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1406 ;; which would allow mix and match FP modes on the compares.  Which is what
1407 ;; the old patterns did, but with many more of them.
1409 (define_expand "cbranchxf4"
1410   [(set (reg:CC FLAGS_REG)
1411         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1412                     (match_operand:XF 2 "nonmemory_operand")))
1413    (set (pc) (if_then_else
1414               (match_operator 0 "ix86_fp_comparison_operator"
1415                [(reg:CC FLAGS_REG)
1416                 (const_int 0)])
1417               (label_ref (match_operand 3))
1418               (pc)))]
1419   "TARGET_80387"
1421   ix86_expand_branch (GET_CODE (operands[0]),
1422                       operands[1], operands[2], operands[3]);
1423   DONE;
1426 (define_expand "cstorexf4"
1427   [(set (reg:CC FLAGS_REG)
1428         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1429                     (match_operand:XF 3 "nonmemory_operand")))
1430    (set (match_operand:QI 0 "register_operand")
1431               (match_operator 1 "ix86_fp_comparison_operator"
1432                [(reg:CC FLAGS_REG)
1433                 (const_int 0)]))]
1434   "TARGET_80387"
1436   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1437                      operands[2], operands[3]);
1438   DONE;
1441 (define_expand "cbranch<mode>4"
1442   [(set (reg:CC FLAGS_REG)
1443         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1444                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1445    (set (pc) (if_then_else
1446               (match_operator 0 "ix86_fp_comparison_operator"
1447                [(reg:CC FLAGS_REG)
1448                 (const_int 0)])
1449               (label_ref (match_operand 3))
1450               (pc)))]
1451   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1453   ix86_expand_branch (GET_CODE (operands[0]),
1454                       operands[1], operands[2], operands[3]);
1455   DONE;
1458 (define_expand "cstore<mode>4"
1459   [(set (reg:CC FLAGS_REG)
1460         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1461                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1462    (set (match_operand:QI 0 "register_operand")
1463               (match_operator 1 "ix86_fp_comparison_operator"
1464                [(reg:CC FLAGS_REG)
1465                 (const_int 0)]))]
1466   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1468   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1469                      operands[2], operands[3]);
1470   DONE;
1473 (define_expand "cbranchcc4"
1474   [(set (pc) (if_then_else
1475               (match_operator 0 "comparison_operator"
1476                [(match_operand 1 "flags_reg_operand")
1477                 (match_operand 2 "const0_operand")])
1478               (label_ref (match_operand 3))
1479               (pc)))]
1480   ""
1482   ix86_expand_branch (GET_CODE (operands[0]),
1483                       operands[1], operands[2], operands[3]);
1484   DONE;
1487 (define_expand "cstorecc4"
1488   [(set (match_operand:QI 0 "register_operand")
1489               (match_operator 1 "comparison_operator"
1490                [(match_operand 2 "flags_reg_operand")
1491                 (match_operand 3 "const0_operand")]))]
1492   ""
1494   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1495                      operands[2], operands[3]);
1496   DONE;
1500 ;; FP compares, step 1:
1501 ;; Set the FP condition codes.
1503 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1504 ;; used to manage the reg stack popping would not be preserved.
1506 (define_insn "*cmp<mode>_0_i387"
1507   [(set (match_operand:HI 0 "register_operand" "=a")
1508         (unspec:HI
1509           [(compare:CCFP
1510              (match_operand:X87MODEF 1 "register_operand" "f")
1511              (match_operand:X87MODEF 2 "const0_operand"))]
1512         UNSPEC_FNSTSW))]
1513   "TARGET_80387"
1514   "* return output_fp_compare (insn, operands, false, false);"
1515   [(set_attr "type" "multi")
1516    (set_attr "unit" "i387")
1517    (set_attr "mode" "<MODE>")])
1519 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1520   [(set (reg:CCFP FLAGS_REG)
1521         (compare:CCFP
1522           (match_operand:X87MODEF 1 "register_operand" "f")
1523           (match_operand:X87MODEF 2 "const0_operand")))
1524    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1525   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1526   "#"
1527   "&& reload_completed"
1528   [(set (match_dup 0)
1529         (unspec:HI
1530           [(compare:CCFP (match_dup 1)(match_dup 2))]
1531         UNSPEC_FNSTSW))
1532    (set (reg:CC FLAGS_REG)
1533         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1534   ""
1535   [(set_attr "type" "multi")
1536    (set_attr "unit" "i387")
1537    (set_attr "mode" "<MODE>")])
1539 (define_insn "*cmpxf_i387"
1540   [(set (match_operand:HI 0 "register_operand" "=a")
1541         (unspec:HI
1542           [(compare:CCFP
1543              (match_operand:XF 1 "register_operand" "f")
1544              (match_operand:XF 2 "register_operand" "f"))]
1545           UNSPEC_FNSTSW))]
1546   "TARGET_80387"
1547   "* return output_fp_compare (insn, operands, false, false);"
1548   [(set_attr "type" "multi")
1549    (set_attr "unit" "i387")
1550    (set_attr "mode" "XF")])
1552 (define_insn_and_split "*cmpxf_cc_i387"
1553   [(set (reg:CCFP FLAGS_REG)
1554         (compare:CCFP
1555           (match_operand:XF 1 "register_operand" "f")
1556           (match_operand:XF 2 "register_operand" "f")))
1557    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1558   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1559   "#"
1560   "&& reload_completed"
1561   [(set (match_dup 0)
1562         (unspec:HI
1563           [(compare:CCFP (match_dup 1)(match_dup 2))]
1564         UNSPEC_FNSTSW))
1565    (set (reg:CC FLAGS_REG)
1566         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1567   ""
1568   [(set_attr "type" "multi")
1569    (set_attr "unit" "i387")
1570    (set_attr "mode" "XF")])
1572 (define_insn "*cmp<mode>_i387"
1573   [(set (match_operand:HI 0 "register_operand" "=a")
1574         (unspec:HI
1575           [(compare:CCFP
1576              (match_operand:MODEF 1 "register_operand" "f")
1577              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1578           UNSPEC_FNSTSW))]
1579   "TARGET_80387"
1580   "* return output_fp_compare (insn, operands, false, false);"
1581   [(set_attr "type" "multi")
1582    (set_attr "unit" "i387")
1583    (set_attr "mode" "<MODE>")])
1585 (define_insn_and_split "*cmp<mode>_cc_i387"
1586   [(set (reg:CCFP FLAGS_REG)
1587         (compare:CCFP
1588           (match_operand:MODEF 1 "register_operand" "f")
1589           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1590    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1591   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1592   "#"
1593   "&& reload_completed"
1594   [(set (match_dup 0)
1595         (unspec:HI
1596           [(compare:CCFP (match_dup 1)(match_dup 2))]
1597         UNSPEC_FNSTSW))
1598    (set (reg:CC FLAGS_REG)
1599         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1600   ""
1601   [(set_attr "type" "multi")
1602    (set_attr "unit" "i387")
1603    (set_attr "mode" "<MODE>")])
1605 (define_insn "*cmpu<mode>_i387"
1606   [(set (match_operand:HI 0 "register_operand" "=a")
1607         (unspec:HI
1608           [(unspec:CCFP
1609              [(compare:CCFP
1610                 (match_operand:X87MODEF 1 "register_operand" "f")
1611                 (match_operand:X87MODEF 2 "register_operand" "f"))]
1612              UNSPEC_NOTRAP)]
1613           UNSPEC_FNSTSW))]
1614   "TARGET_80387"
1615   "* return output_fp_compare (insn, operands, false, true);"
1616   [(set_attr "type" "multi")
1617    (set_attr "unit" "i387")
1618    (set_attr "mode" "<MODE>")])
1620 (define_insn_and_split "*cmpu<mode>_cc_i387"
1621   [(set (reg:CCFP FLAGS_REG)
1622         (unspec:CCFP
1623           [(compare:CCFP
1624              (match_operand:X87MODEF 1 "register_operand" "f")
1625              (match_operand:X87MODEF 2 "register_operand" "f"))]
1626           UNSPEC_NOTRAP))
1627    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1628   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1629   "#"
1630   "&& reload_completed"
1631   [(set (match_dup 0)
1632         (unspec:HI
1633           [(unspec:CCFP
1634              [(compare:CCFP (match_dup 1)(match_dup 2))]
1635              UNSPEC_NOTRAP)]
1636           UNSPEC_FNSTSW))
1637    (set (reg:CC FLAGS_REG)
1638         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1639   ""
1640   [(set_attr "type" "multi")
1641    (set_attr "unit" "i387")
1642    (set_attr "mode" "<MODE>")])
1644 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1645   [(set (match_operand:HI 0 "register_operand" "=a")
1646         (unspec:HI
1647           [(compare:CCFP
1648              (match_operand:X87MODEF 1 "register_operand" "f")
1649              (float:X87MODEF
1650                (match_operand:SWI24 2 "memory_operand" "m")))]
1651           UNSPEC_FNSTSW))]
1652   "TARGET_80387
1653    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1654        || optimize_function_for_size_p (cfun))"
1655   "* return output_fp_compare (insn, operands, false, false);"
1656   [(set_attr "type" "multi")
1657    (set_attr "unit" "i387")
1658    (set_attr "fp_int_src" "true")
1659    (set_attr "mode" "<SWI24:MODE>")])
1661 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1662   [(set (reg:CCFP FLAGS_REG)
1663         (compare:CCFP
1664           (match_operand:X87MODEF 1 "register_operand" "f")
1665           (float:X87MODEF
1666             (match_operand:SWI24 2 "memory_operand" "m"))))
1667    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1668   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1669    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1670        || optimize_function_for_size_p (cfun))"
1671   "#"
1672   "&& reload_completed"
1673   [(set (match_dup 0)
1674         (unspec:HI
1675           [(compare:CCFP
1676              (match_dup 1)
1677              (float:X87MODEF (match_dup 2)))]
1678         UNSPEC_FNSTSW))
1679    (set (reg:CC FLAGS_REG)
1680         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1681   ""
1682   [(set_attr "type" "multi")
1683    (set_attr "unit" "i387")
1684    (set_attr "fp_int_src" "true")
1685    (set_attr "mode" "<SWI24:MODE>")])
1687 ;; FP compares, step 2
1688 ;; Move the fpsw to ax.
1690 (define_insn "x86_fnstsw_1"
1691   [(set (match_operand:HI 0 "register_operand" "=a")
1692         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1693   "TARGET_80387"
1694   "fnstsw\t%0"
1695   [(set_attr "length" "2")
1696    (set_attr "mode" "SI")
1697    (set_attr "unit" "i387")])
1699 ;; FP compares, step 3
1700 ;; Get ax into flags, general case.
1702 (define_insn "x86_sahf_1"
1703   [(set (reg:CC FLAGS_REG)
1704         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1705                    UNSPEC_SAHF))]
1706   "TARGET_SAHF"
1708 #ifndef HAVE_AS_IX86_SAHF
1709   if (TARGET_64BIT)
1710     return ASM_BYTE "0x9e";
1711   else
1712 #endif
1713   return "sahf";
1715   [(set_attr "length" "1")
1716    (set_attr "athlon_decode" "vector")
1717    (set_attr "amdfam10_decode" "direct")
1718    (set_attr "bdver1_decode" "direct")
1719    (set_attr "mode" "SI")])
1721 ;; Pentium Pro can do steps 1 through 3 in one go.
1722 ;; (these instructions set flags directly)
1724 (define_subst_attr "unord" "unord_subst" "" "u")
1725 (define_subst_attr "unordered" "unord_subst" "false" "true")
1727 (define_subst "unord_subst"
1728   [(set (match_operand:CCFP 0)
1729         (match_operand:CCFP 1))]
1730   ""
1731   [(set (match_dup 0)
1732         (unspec:CCFP
1733           [(match_dup 1)]
1734           UNSPEC_NOTRAP))])
1736 (define_insn "*cmpi<unord><MODEF:mode>"
1737   [(set (reg:CCFP FLAGS_REG)
1738         (compare:CCFP
1739           (match_operand:MODEF 0 "register_operand" "f,v")
1740           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1741   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1742    || (TARGET_80387 && TARGET_CMOVE)"
1743   "@
1744    * return output_fp_compare (insn, operands, true, <unordered>);
1745    %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1746   [(set_attr "type" "fcmp,ssecomi")
1747    (set_attr "prefix" "orig,maybe_vex")
1748    (set_attr "mode" "<MODEF:MODE>")
1749    (set_attr "prefix_rep" "*,0")
1750    (set (attr "prefix_data16")
1751         (cond [(eq_attr "alternative" "0")
1752                  (const_string "*")
1753                (eq_attr "mode" "DF")
1754                  (const_string "1")
1755               ]
1756               (const_string "0")))
1757    (set_attr "athlon_decode" "vector")
1758    (set_attr "amdfam10_decode" "direct")
1759    (set_attr "bdver1_decode" "double")
1760    (set_attr "znver1_decode" "double")
1761    (set (attr "enabled")
1762      (if_then_else
1763        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1764        (if_then_else
1765          (eq_attr "alternative" "0")
1766          (symbol_ref "TARGET_MIX_SSE_I387")
1767          (symbol_ref "true"))
1768        (if_then_else
1769          (eq_attr "alternative" "0")
1770          (symbol_ref "true")
1771          (symbol_ref "false"))))])
1773 (define_insn "*cmpi<unord>xf_i387"
1774   [(set (reg:CCFP FLAGS_REG)
1775         (compare:CCFP
1776           (match_operand:XF 0 "register_operand" "f")
1777           (match_operand:XF 1 "register_operand" "f")))]
1778   "TARGET_80387 && TARGET_CMOVE"
1779   "* return output_fp_compare (insn, operands, true, <unordered>);"
1780   [(set_attr "type" "fcmp")
1781    (set_attr "mode" "XF")
1782    (set_attr "athlon_decode" "vector")
1783    (set_attr "amdfam10_decode" "direct")
1784    (set_attr "bdver1_decode" "double")
1785    (set_attr "znver1_decode" "double")])
1787 ;; Push/pop instructions.
1789 (define_insn "*push<mode>2"
1790   [(set (match_operand:DWI 0 "push_operand" "=<")
1791         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1792   ""
1793   "#"
1794   [(set_attr "type" "multi")
1795    (set_attr "mode" "<MODE>")])
1797 (define_split
1798   [(set (match_operand:DWI 0 "push_operand")
1799         (match_operand:DWI 1 "general_gr_operand"))]
1800   "reload_completed"
1801   [(const_int 0)]
1802   "ix86_split_long_move (operands); DONE;")
1804 (define_insn "*pushdi2_rex64"
1805   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1806         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1807   "TARGET_64BIT"
1808   "@
1809    push{q}\t%1
1810    #"
1811   [(set_attr "type" "push,multi")
1812    (set_attr "mode" "DI")])
1814 ;; Convert impossible pushes of immediate to existing instructions.
1815 ;; First try to get scratch register and go through it.  In case this
1816 ;; fails, push sign extended lower part first and then overwrite
1817 ;; upper part by 32bit move.
1818 (define_peephole2
1819   [(match_scratch:DI 2 "r")
1820    (set (match_operand:DI 0 "push_operand")
1821         (match_operand:DI 1 "immediate_operand"))]
1822   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1823    && !x86_64_immediate_operand (operands[1], DImode)"
1824   [(set (match_dup 2) (match_dup 1))
1825    (set (match_dup 0) (match_dup 2))])
1827 ;; We need to define this as both peepholer and splitter for case
1828 ;; peephole2 pass is not run.
1829 ;; "&& 1" is needed to keep it from matching the previous pattern.
1830 (define_peephole2
1831   [(set (match_operand:DI 0 "push_operand")
1832         (match_operand:DI 1 "immediate_operand"))]
1833   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1834    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1835   [(set (match_dup 0) (match_dup 1))
1836    (set (match_dup 2) (match_dup 3))]
1838   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1840   operands[1] = gen_lowpart (DImode, operands[2]);
1841   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1842                                                    GEN_INT (4)));
1845 (define_split
1846   [(set (match_operand:DI 0 "push_operand")
1847         (match_operand:DI 1 "immediate_operand"))]
1848   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1849                     ? epilogue_completed : reload_completed)
1850    && !symbolic_operand (operands[1], DImode)
1851    && !x86_64_immediate_operand (operands[1], DImode)"
1852   [(set (match_dup 0) (match_dup 1))
1853    (set (match_dup 2) (match_dup 3))]
1855   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1857   operands[1] = gen_lowpart (DImode, operands[2]);
1858   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1859                                                    GEN_INT (4)));
1862 (define_insn "*pushsi2"
1863   [(set (match_operand:SI 0 "push_operand" "=<")
1864         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1865   "!TARGET_64BIT"
1866   "push{l}\t%1"
1867   [(set_attr "type" "push")
1868    (set_attr "mode" "SI")])
1870 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1871 ;; "push a byte/word".  But actually we use pushl, which has the effect
1872 ;; of rounding the amount pushed up to a word.
1874 ;; For TARGET_64BIT we always round up to 8 bytes.
1875 (define_insn "*push<mode>2_rex64"
1876   [(set (match_operand:SWI124 0 "push_operand" "=X")
1877         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1878   "TARGET_64BIT"
1879   "push{q}\t%q1"
1880   [(set_attr "type" "push")
1881    (set_attr "mode" "DI")])
1883 (define_insn "*push<mode>2"
1884   [(set (match_operand:SWI12 0 "push_operand" "=X")
1885         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1886   "!TARGET_64BIT"
1887   "push{l}\t%k1"
1888   [(set_attr "type" "push")
1889    (set_attr "mode" "SI")])
1891 (define_insn "*push<mode>2_prologue"
1892   [(set (match_operand:W 0 "push_operand" "=<")
1893         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1894    (clobber (mem:BLK (scratch)))]
1895   ""
1896   "push{<imodesuffix>}\t%1"
1897   [(set_attr "type" "push")
1898    (set_attr "mode" "<MODE>")])
1900 (define_insn "*pop<mode>1"
1901   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1902         (match_operand:W 1 "pop_operand" ">"))]
1903   ""
1904   "pop{<imodesuffix>}\t%0"
1905   [(set_attr "type" "pop")
1906    (set_attr "mode" "<MODE>")])
1908 (define_insn "*pop<mode>1_epilogue"
1909   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1910         (match_operand:W 1 "pop_operand" ">"))
1911    (clobber (mem:BLK (scratch)))]
1912   ""
1913   "pop{<imodesuffix>}\t%0"
1914   [(set_attr "type" "pop")
1915    (set_attr "mode" "<MODE>")])
1917 (define_insn "*pushfl<mode>2"
1918   [(set (match_operand:W 0 "push_operand" "=<")
1919         (match_operand:W 1 "flags_reg_operand"))]
1920   ""
1921   "pushf{<imodesuffix>}"
1922   [(set_attr "type" "push")
1923    (set_attr "mode" "<MODE>")])
1925 (define_insn "*popfl<mode>1"
1926   [(set (match_operand:W 0 "flags_reg_operand")
1927         (match_operand:W 1 "pop_operand" ">"))]
1928   ""
1929   "popf{<imodesuffix>}"
1930   [(set_attr "type" "pop")
1931    (set_attr "mode" "<MODE>")])
1934 ;; Reload patterns to support multi-word load/store
1935 ;; with non-offsetable address.
1936 (define_expand "reload_noff_store"
1937   [(parallel [(match_operand 0 "memory_operand" "=m")
1938               (match_operand 1 "register_operand" "r")
1939               (match_operand:DI 2 "register_operand" "=&r")])]
1940   "TARGET_64BIT"
1942   rtx mem = operands[0];
1943   rtx addr = XEXP (mem, 0);
1945   emit_move_insn (operands[2], addr);
1946   mem = replace_equiv_address_nv (mem, operands[2]);
1948   emit_insn (gen_rtx_SET (mem, operands[1]));
1949   DONE;
1952 (define_expand "reload_noff_load"
1953   [(parallel [(match_operand 0 "register_operand" "=r")
1954               (match_operand 1 "memory_operand" "m")
1955               (match_operand:DI 2 "register_operand" "=r")])]
1956   "TARGET_64BIT"
1958   rtx mem = operands[1];
1959   rtx addr = XEXP (mem, 0);
1961   emit_move_insn (operands[2], addr);
1962   mem = replace_equiv_address_nv (mem, operands[2]);
1964   emit_insn (gen_rtx_SET (operands[0], mem));
1965   DONE;
1968 ;; Move instructions.
1970 (define_expand "movxi"
1971   [(set (match_operand:XI 0 "nonimmediate_operand")
1972         (match_operand:XI 1 "general_operand"))]
1973   "TARGET_AVX512F"
1974   "ix86_expand_vector_move (XImode, operands); DONE;")
1976 (define_expand "movoi"
1977   [(set (match_operand:OI 0 "nonimmediate_operand")
1978         (match_operand:OI 1 "general_operand"))]
1979   "TARGET_AVX"
1980   "ix86_expand_vector_move (OImode, operands); DONE;")
1982 (define_expand "movti"
1983   [(set (match_operand:TI 0 "nonimmediate_operand")
1984         (match_operand:TI 1 "general_operand"))]
1985   "TARGET_64BIT || TARGET_SSE"
1987   if (TARGET_64BIT)
1988     ix86_expand_move (TImode, operands);
1989   else
1990     ix86_expand_vector_move (TImode, operands);
1991   DONE;
1994 ;; This expands to what emit_move_complex would generate if we didn't
1995 ;; have a movti pattern.  Having this avoids problems with reload on
1996 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1997 ;; to have around all the time.
1998 (define_expand "movcdi"
1999   [(set (match_operand:CDI 0 "nonimmediate_operand")
2000         (match_operand:CDI 1 "general_operand"))]
2001   ""
2003   if (push_operand (operands[0], CDImode))
2004     emit_move_complex_push (CDImode, operands[0], operands[1]);
2005   else
2006     emit_move_complex_parts (operands[0], operands[1]);
2007   DONE;
2010 (define_expand "mov<mode>"
2011   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2012         (match_operand:SWI1248x 1 "general_operand"))]
2013   ""
2014   "ix86_expand_move (<MODE>mode, operands); DONE;")
2016 (define_insn "*mov<mode>_xor"
2017   [(set (match_operand:SWI48 0 "register_operand" "=r")
2018         (match_operand:SWI48 1 "const0_operand"))
2019    (clobber (reg:CC FLAGS_REG))]
2020   "reload_completed"
2021   "xor{l}\t%k0, %k0"
2022   [(set_attr "type" "alu1")
2023    (set_attr "modrm_class" "op0")
2024    (set_attr "mode" "SI")
2025    (set_attr "length_immediate" "0")])
2027 (define_insn "*mov<mode>_or"
2028   [(set (match_operand:SWI48 0 "register_operand" "=r")
2029         (match_operand:SWI48 1 "constm1_operand"))
2030    (clobber (reg:CC FLAGS_REG))]
2031   "reload_completed"
2032   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2033   [(set_attr "type" "alu1")
2034    (set_attr "mode" "<MODE>")
2035    (set_attr "length_immediate" "1")])
2037 (define_insn "*movxi_internal_avx512f"
2038   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2039         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2040   "TARGET_AVX512F
2041    && (register_operand (operands[0], XImode)
2042        || register_operand (operands[1], XImode))"
2044   switch (get_attr_type (insn))
2045     {
2046     case TYPE_SSELOG1:
2047       return standard_sse_constant_opcode (insn, operands);
2049     case TYPE_SSEMOV:
2050       if (misaligned_operand (operands[0], XImode)
2051           || misaligned_operand (operands[1], XImode))
2052         return "vmovdqu32\t{%1, %0|%0, %1}";
2053       else
2054         return "vmovdqa32\t{%1, %0|%0, %1}";
2056     default:
2057       gcc_unreachable ();
2058     }
2060   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2061    (set_attr "prefix" "evex")
2062    (set_attr "mode" "XI")])
2064 (define_insn "*movoi_internal_avx"
2065   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2066         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2067   "TARGET_AVX
2068    && (register_operand (operands[0], OImode)
2069        || register_operand (operands[1], OImode))"
2071   switch (get_attr_type (insn))
2072     {
2073     case TYPE_SSELOG1:
2074       return standard_sse_constant_opcode (insn, operands);
2076     case TYPE_SSEMOV:
2077       if (misaligned_operand (operands[0], OImode)
2078           || misaligned_operand (operands[1], OImode))
2079         {
2080           if (get_attr_mode (insn) == MODE_V8SF)
2081             return "vmovups\t{%1, %0|%0, %1}";
2082           else if (get_attr_mode (insn) == MODE_XI)
2083             return "vmovdqu32\t{%1, %0|%0, %1}";
2084           else
2085             return "vmovdqu\t{%1, %0|%0, %1}";
2086         }
2087       else
2088         {
2089           if (get_attr_mode (insn) == MODE_V8SF)
2090             return "vmovaps\t{%1, %0|%0, %1}";
2091           else if (get_attr_mode (insn) == MODE_XI)
2092             return "vmovdqa32\t{%1, %0|%0, %1}";
2093           else
2094             return "vmovdqa\t{%1, %0|%0, %1}";
2095         }
2097     default:
2098       gcc_unreachable ();
2099     }
2101   [(set_attr "isa" "*,avx2,*,*")
2102    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2103    (set_attr "prefix" "vex")
2104    (set (attr "mode")
2105         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2106                     (match_operand 1 "ext_sse_reg_operand"))
2107                  (const_string "XI")
2108                (and (eq_attr "alternative" "1")
2109                     (match_test "TARGET_AVX512VL"))
2110                  (const_string "XI")
2111                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2112                     (and (eq_attr "alternative" "3")
2113                          (match_test "TARGET_SSE_TYPELESS_STORES")))
2114                  (const_string "V8SF")
2115               ]
2116               (const_string "OI")))])
2118 (define_insn "*movti_internal"
2119   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2120         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Ye,r"))]
2121   "(TARGET_64BIT
2122     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2123    || (TARGET_SSE
2124        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2125        && (register_operand (operands[0], TImode)
2126            || register_operand (operands[1], TImode)))"
2128   switch (get_attr_type (insn))
2129     {
2130     case TYPE_MULTI:
2131       return "#";
2133     case TYPE_SSELOG1:
2134       return standard_sse_constant_opcode (insn, operands);
2136     case TYPE_SSEMOV:
2137       /* TDmode values are passed as TImode on the stack.  Moving them
2138          to stack may result in unaligned memory access.  */
2139       if (misaligned_operand (operands[0], TImode)
2140           || misaligned_operand (operands[1], TImode))
2141         {
2142           if (get_attr_mode (insn) == MODE_V4SF)
2143             return "%vmovups\t{%1, %0|%0, %1}";
2144           else if (get_attr_mode (insn) == MODE_XI)
2145             return "vmovdqu32\t{%1, %0|%0, %1}";
2146           else
2147             return "%vmovdqu\t{%1, %0|%0, %1}";
2148         }
2149       else
2150         {
2151           if (get_attr_mode (insn) == MODE_V4SF)
2152             return "%vmovaps\t{%1, %0|%0, %1}";
2153           else if (get_attr_mode (insn) == MODE_XI)
2154             return "vmovdqa32\t{%1, %0|%0, %1}";
2155           else
2156             return "%vmovdqa\t{%1, %0|%0, %1}";
2157         }
2159     default:
2160       gcc_unreachable ();
2161     }
2163   [(set (attr "isa")
2164      (cond [(eq_attr "alternative" "0,1,6,7")
2165               (const_string "x64")
2166             (eq_attr "alternative" "3")
2167               (const_string "sse2")
2168            ]
2169            (const_string "*")))
2170    (set (attr "type")
2171      (cond [(eq_attr "alternative" "0,1,6,7")
2172               (const_string "multi")
2173             (eq_attr "alternative" "2,3")
2174               (const_string "sselog1")
2175            ]
2176            (const_string "ssemov")))
2177    (set (attr "prefix")
2178      (if_then_else (eq_attr "type" "sselog1,ssemov")
2179        (const_string "maybe_vex")
2180        (const_string "orig")))
2181    (set (attr "mode")
2182         (cond [(eq_attr "alternative" "0,1")
2183                  (const_string "DI")
2184                (ior (match_operand 0 "ext_sse_reg_operand")
2185                     (match_operand 1 "ext_sse_reg_operand"))
2186                  (const_string "XI")
2187                (and (eq_attr "alternative" "3")
2188                     (match_test "TARGET_AVX512VL"))
2189                  (const_string "XI")
2190                (ior (not (match_test "TARGET_SSE2"))
2191                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2192                          (and (eq_attr "alternative" "5")
2193                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2194                  (const_string "V4SF")
2195                (match_test "TARGET_AVX")
2196                  (const_string "TI")
2197                (match_test "optimize_function_for_size_p (cfun)")
2198                  (const_string "V4SF")
2199                ]
2200                (const_string "TI")))])
2202 (define_split
2203   [(set (match_operand:TI 0 "sse_reg_operand")
2204         (match_operand:TI 1 "general_reg_operand"))]
2205   "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2206    && reload_completed"
2207   [(set (match_dup 2)
2208         (vec_merge:V2DI
2209           (vec_duplicate:V2DI (match_dup 3))
2210           (match_dup 2)
2211           (const_int 2)))]
2213   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2214   operands[3] = gen_highpart (DImode, operands[1]);
2216   emit_move_insn (gen_lowpart (DImode, operands[0]),
2217                   gen_lowpart (DImode, operands[1]));
2220 (define_insn "*movdi_internal"
2221   [(set (match_operand:DI 0 "nonimmediate_operand"
2222     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?*Yd,?r ,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m")
2223         (match_operand:DI 1 "general_operand"
2224     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,v,*Ye,r   ,*Yj,r   ,*Yj ,*Yn ,*r,*km,*k,*k"))]
2225   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2227   switch (get_attr_type (insn))
2228     {
2229     case TYPE_MSKMOV:
2230       return "kmovq\t{%1, %0|%0, %1}";
2232     case TYPE_MULTI:
2233       return "#";
2235     case TYPE_MMX:
2236       return "pxor\t%0, %0";
2238     case TYPE_MMXMOV:
2239       /* Handle broken assemblers that require movd instead of movq.  */
2240       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2241           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2242         return "movd\t{%1, %0|%0, %1}";
2243       return "movq\t{%1, %0|%0, %1}";
2245     case TYPE_SSELOG1:
2246       return standard_sse_constant_opcode (insn, operands);
2248     case TYPE_SSEMOV:
2249       switch (get_attr_mode (insn))
2250         {
2251         case MODE_DI:
2252           /* Handle broken assemblers that require movd instead of movq.  */
2253           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2254               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2255             return "%vmovd\t{%1, %0|%0, %1}";
2256           return "%vmovq\t{%1, %0|%0, %1}";
2258         case MODE_TI:
2259           /* Handle AVX512 registers set.  */
2260           if (EXT_REX_SSE_REG_P (operands[0])
2261               || EXT_REX_SSE_REG_P (operands[1]))
2262             return "vmovdqa64\t{%1, %0|%0, %1}";
2263           return "%vmovdqa\t{%1, %0|%0, %1}";
2265         case MODE_V2SF:
2266           gcc_assert (!TARGET_AVX);
2267           return "movlps\t{%1, %0|%0, %1}";
2268         case MODE_V4SF:
2269           return "%vmovaps\t{%1, %0|%0, %1}";
2271         default:
2272           gcc_unreachable ();
2273         }
2275     case TYPE_SSECVT:
2276       if (SSE_REG_P (operands[0]))
2277         return "movq2dq\t{%1, %0|%0, %1}";
2278       else
2279         return "movdq2q\t{%1, %0|%0, %1}";
2281     case TYPE_LEA:
2282       return "lea{q}\t{%E1, %0|%0, %E1}";
2284     case TYPE_IMOV:
2285       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2286       if (get_attr_mode (insn) == MODE_SI)
2287         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2288       else if (which_alternative == 4)
2289         return "movabs{q}\t{%1, %0|%0, %1}";
2290       else if (ix86_use_lea_for_mov (insn, operands))
2291         return "lea{q}\t{%E1, %0|%0, %E1}";
2292       else
2293         return "mov{q}\t{%1, %0|%0, %1}";
2295     default:
2296       gcc_unreachable ();
2297     }
2299   [(set (attr "isa")
2300      (cond [(eq_attr "alternative" "0,1,17,18")
2301               (const_string "nox64")
2302             (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25")
2303               (const_string "x64")
2304            ]
2305            (const_string "*")))
2306    (set (attr "type")
2307      (cond [(eq_attr "alternative" "0,1,17,18")
2308               (const_string "multi")
2309             (eq_attr "alternative" "6")
2310               (const_string "mmx")
2311             (eq_attr "alternative" "7,8,9,10,11")
2312               (const_string "mmxmov")
2313             (eq_attr "alternative" "12")
2314               (const_string "sselog1")
2315             (eq_attr "alternative" "13,14,15,16,19,20")
2316               (const_string "ssemov")
2317             (eq_attr "alternative" "21,22")
2318               (const_string "ssecvt")
2319             (eq_attr "alternative" "23,24,25,26")
2320               (const_string "mskmov")
2321             (and (match_operand 0 "register_operand")
2322                  (match_operand 1 "pic_32bit_operand"))
2323               (const_string "lea")
2324            ]
2325            (const_string "imov")))
2326    (set (attr "modrm")
2327      (if_then_else
2328        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2329        (const_string "0")
2330        (const_string "*")))
2331    (set (attr "length_immediate")
2332      (if_then_else
2333        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2334        (const_string "8")
2335        (const_string "*")))
2336    (set (attr "prefix_rex")
2337      (if_then_else
2338        (eq_attr "alternative" "10,11,19,20")
2339        (const_string "1")
2340        (const_string "*")))
2341    (set (attr "prefix")
2342      (if_then_else (eq_attr "type" "sselog1,ssemov")
2343        (const_string "maybe_vex")
2344        (const_string "orig")))
2345    (set (attr "prefix_data16")
2346      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2347        (const_string "1")
2348        (const_string "*")))
2349    (set (attr "mode")
2350      (cond [(eq_attr "alternative" "2")
2351               (const_string "SI")
2352             (eq_attr "alternative" "12,13")
2353               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2354                           (match_operand 1 "ext_sse_reg_operand"))
2355                        (const_string "TI")
2356                      (ior (not (match_test "TARGET_SSE2"))
2357                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2358                        (const_string "V4SF")
2359                      (match_test "TARGET_AVX")
2360                        (const_string "TI")
2361                      (match_test "optimize_function_for_size_p (cfun)")
2362                        (const_string "V4SF")
2363                     ]
2364                     (const_string "TI"))
2366             (and (eq_attr "alternative" "14,15,16")
2367                  (not (match_test "TARGET_SSE2")))
2368               (const_string "V2SF")
2369            ]
2370            (const_string "DI")))
2371    (set (attr "enabled")
2372      (cond [(eq_attr "alternative" "15")
2373               (if_then_else
2374                 (match_test "TARGET_STV && TARGET_SSE2")
2375                 (symbol_ref "false")
2376                 (const_string "*"))
2377             (eq_attr "alternative" "16")
2378               (if_then_else
2379                 (match_test "TARGET_STV && TARGET_SSE2")
2380                 (symbol_ref "true")
2381                 (symbol_ref "false"))
2382            ]
2383            (const_string "*")))])
2385 (define_split
2386   [(set (match_operand:<DWI> 0 "general_reg_operand")
2387         (match_operand:<DWI> 1 "sse_reg_operand"))]
2388   "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC
2389    && reload_completed"
2390   [(set (match_dup 2)
2391         (vec_select:DWIH
2392           (match_dup 3)
2393           (parallel [(const_int 1)])))]
2395   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2396   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2398   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2399                   gen_lowpart (<MODE>mode, operands[1]));
2402 (define_split
2403   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2404         (match_operand:DWI 1 "general_gr_operand"))]
2405   "reload_completed"
2406   [(const_int 0)]
2407   "ix86_split_long_move (operands); DONE;")
2409 (define_split
2410   [(set (match_operand:DI 0 "sse_reg_operand")
2411         (match_operand:DI 1 "general_reg_operand"))]
2412   "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2413    && reload_completed"
2414   [(set (match_dup 2)
2415         (vec_merge:V4SI
2416           (vec_duplicate:V4SI (match_dup 3))
2417           (match_dup 2)
2418           (const_int 2)))]
2420   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2421   operands[3] = gen_highpart (SImode, operands[1]);
2423   emit_move_insn (gen_lowpart (SImode, operands[0]),
2424                   gen_lowpart (SImode, operands[1]));
2427 ;; movabsq $0x0012345678000000, %rax is longer
2428 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2429 (define_peephole2
2430   [(set (match_operand:DI 0 "register_operand")
2431         (match_operand:DI 1 "const_int_operand"))]
2432   "TARGET_64BIT
2433    && optimize_insn_for_size_p ()
2434    && LEGACY_INT_REG_P (operands[0])
2435    && !x86_64_immediate_operand (operands[1], DImode)
2436    && !x86_64_zext_immediate_operand (operands[1], DImode)
2437    && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2438         & ~(HOST_WIDE_INT) 0xffffffff)
2439    && peep2_regno_dead_p (0, FLAGS_REG)"
2440   [(set (match_dup 0) (match_dup 1))
2441    (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2442               (clobber (reg:CC FLAGS_REG))])]
2444   int shift = ctz_hwi (UINTVAL (operands[1]));
2445   operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2446   operands[2] = gen_int_mode (shift, QImode);
2449 (define_insn "*movsi_internal"
2450   [(set (match_operand:SI 0 "nonimmediate_operand"
2451     "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm")
2452         (match_operand:SI 1 "general_operand"
2453     "g ,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,r   ,*r,*km,*k"))]
2454   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2456   switch (get_attr_type (insn))
2457     {
2458     case TYPE_SSELOG1:
2459       return standard_sse_constant_opcode (insn, operands);
2461     case TYPE_MSKMOV:
2462       return "kmovd\t{%1, %0|%0, %1}";
2464     case TYPE_SSEMOV:
2465       switch (get_attr_mode (insn))
2466         {
2467         case MODE_SI:
2468           return "%vmovd\t{%1, %0|%0, %1}";
2469         case MODE_TI:
2470           return "%vmovdqa\t{%1, %0|%0, %1}";
2471         case MODE_XI:
2472           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2474         case MODE_V4SF:
2475           return "%vmovaps\t{%1, %0|%0, %1}";
2477         case MODE_SF:
2478           gcc_assert (!TARGET_AVX);
2479           return "movss\t{%1, %0|%0, %1}";
2481         default:
2482           gcc_unreachable ();
2483         }
2485     case TYPE_MMX:
2486       return "pxor\t%0, %0";
2488     case TYPE_MMXMOV:
2489       switch (get_attr_mode (insn))
2490         {
2491         case MODE_DI:
2492           return "movq\t{%1, %0|%0, %1}";
2493         case MODE_SI:
2494           return "movd\t{%1, %0|%0, %1}";
2496         default:
2497           gcc_unreachable ();
2498         }
2500     case TYPE_LEA:
2501       return "lea{l}\t{%E1, %0|%0, %E1}";
2503     case TYPE_IMOV:
2504       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2505       if (ix86_use_lea_for_mov (insn, operands))
2506         return "lea{l}\t{%E1, %0|%0, %E1}";
2507       else
2508         return "mov{l}\t{%1, %0|%0, %1}";
2510     default:
2511       gcc_unreachable ();
2512     }
2514   [(set (attr "type")
2515      (cond [(eq_attr "alternative" "2")
2516               (const_string "mmx")
2517             (eq_attr "alternative" "3,4,5,6,7")
2518               (const_string "mmxmov")
2519             (eq_attr "alternative" "8")
2520               (const_string "sselog1")
2521             (eq_attr "alternative" "9,10,11,12,13")
2522               (const_string "ssemov")
2523             (eq_attr "alternative" "14,15,16")
2524               (const_string "mskmov")
2525             (and (match_operand 0 "register_operand")
2526                  (match_operand 1 "pic_32bit_operand"))
2527               (const_string "lea")
2528            ]
2529            (const_string "imov")))
2530    (set (attr "prefix")
2531      (if_then_else (eq_attr "type" "sselog1,ssemov")
2532        (const_string "maybe_vex")
2533        (const_string "orig")))
2534    (set (attr "prefix_data16")
2535      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2536        (const_string "1")
2537        (const_string "*")))
2538    (set (attr "mode")
2539      (cond [(eq_attr "alternative" "2,3")
2540               (const_string "DI")
2541             (eq_attr "alternative" "8,9")
2542               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2543                           (match_operand 1 "ext_sse_reg_operand"))
2544                        (const_string "XI")
2545                      (ior (not (match_test "TARGET_SSE2"))
2546                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2547                        (const_string "V4SF")
2548                      (match_test "TARGET_AVX")
2549                        (const_string "TI")
2550                      (match_test "optimize_function_for_size_p (cfun)")
2551                        (const_string "V4SF")
2552                     ]
2553                     (const_string "TI"))
2555             (and (eq_attr "alternative" "10,11")
2556                  (not (match_test "TARGET_SSE2")))
2557               (const_string "SF")
2558            ]
2559            (const_string "SI")))])
2561 (define_insn "*movhi_internal"
2562   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2563         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2564   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2566   switch (get_attr_type (insn))
2567     {
2568     case TYPE_IMOVX:
2569       /* movzwl is faster than movw on p2 due to partial word stalls,
2570          though not as fast as an aligned movl.  */
2571       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2573     case TYPE_MSKMOV:
2574       switch (which_alternative)
2575         {
2576         case 4:
2577           return "kmovw\t{%k1, %0|%0, %k1}";
2578         case 6:
2579           return "kmovw\t{%1, %k0|%k0, %1}";
2580         case 5:
2581         case 7:
2582           return "kmovw\t{%1, %0|%0, %1}";
2583         default:
2584           gcc_unreachable ();
2585         }
2587     default:
2588       if (get_attr_mode (insn) == MODE_SI)
2589         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2590       else
2591         return "mov{w}\t{%1, %0|%0, %1}";
2592     }
2594   [(set (attr "type")
2595      (cond [(eq_attr "alternative" "4,5,6,7")
2596               (const_string "mskmov")
2597             (match_test "optimize_function_for_size_p (cfun)")
2598               (const_string "imov")
2599             (and (eq_attr "alternative" "0")
2600                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2601                       (not (match_test "TARGET_HIMODE_MATH"))))
2602               (const_string "imov")
2603             (and (eq_attr "alternative" "1,2")
2604                  (match_operand:HI 1 "aligned_operand"))
2605               (const_string "imov")
2606             (and (match_test "TARGET_MOVX")
2607                  (eq_attr "alternative" "0,2"))
2608               (const_string "imovx")
2609            ]
2610            (const_string "imov")))
2611     (set (attr "prefix")
2612       (if_then_else (eq_attr "alternative" "4,5,6,7")
2613         (const_string "vex")
2614         (const_string "orig")))
2615     (set (attr "mode")
2616       (cond [(eq_attr "type" "imovx")
2617                (const_string "SI")
2618              (and (eq_attr "alternative" "1,2")
2619                   (match_operand:HI 1 "aligned_operand"))
2620                (const_string "SI")
2621              (and (eq_attr "alternative" "0")
2622                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2623                        (not (match_test "TARGET_HIMODE_MATH"))))
2624                (const_string "SI")
2625             ]
2626             (const_string "HI")))])
2628 ;; Situation is quite tricky about when to choose full sized (SImode) move
2629 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2630 ;; partial register dependency machines (such as AMD Athlon), where QImode
2631 ;; moves issue extra dependency and for partial register stalls machines
2632 ;; that don't use QImode patterns (and QImode move cause stall on the next
2633 ;; instruction).
2635 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2636 ;; register stall machines with, where we use QImode instructions, since
2637 ;; partial register stall can be caused there.  Then we use movzx.
2639 (define_insn "*movqi_internal"
2640   [(set (match_operand:QI 0 "nonimmediate_operand"
2641                         "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2642         (match_operand:QI 1 "general_operand"
2643                         "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2644   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2646   static char buf[128];
2647   const char *ops;
2648   const char *suffix;
2650   switch (get_attr_type (insn))
2651     {
2652     case TYPE_IMOVX:
2653       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2654       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2656     case TYPE_MSKMOV:
2657       switch (which_alternative)
2658         {
2659         case 9:
2660           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2661           break;
2662         case 11:
2663           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2664           break;
2665         case 12:
2666         case 13:
2667           gcc_assert (TARGET_AVX512DQ);
2668           /* FALLTHRU */
2669         case 10:
2670           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2671           break;
2672         default:
2673           gcc_unreachable ();
2674         }
2676       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2678       snprintf (buf, sizeof (buf), ops, suffix);
2679       return buf;
2681     default:
2682       if (get_attr_mode (insn) == MODE_SI)
2683         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2684       else
2685         return "mov{b}\t{%1, %0|%0, %1}";
2686     }
2688   [(set (attr "isa")
2689      (cond [(eq_attr "alternative" "1,2")
2690               (const_string "x64")
2691             (eq_attr "alternative" "12,13")
2692               (const_string "avx512dq")
2693            ]
2694            (const_string "*")))
2695    (set (attr "type")
2696      (cond [(eq_attr "alternative" "9,10,11,12,13")
2697               (const_string "mskmov")
2698             (and (eq_attr "alternative" "7")
2699                  (not (match_operand:QI 1 "aligned_operand")))
2700               (const_string "imovx")
2701             (match_test "optimize_function_for_size_p (cfun)")
2702               (const_string "imov")
2703             (and (eq_attr "alternative" "5")
2704                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2705                       (not (match_test "TARGET_QIMODE_MATH"))))
2706               (const_string "imov")
2707             (eq_attr "alternative" "5,7")
2708               (const_string "imovx")
2709             (and (match_test "TARGET_MOVX")
2710                  (eq_attr "alternative" "4"))
2711               (const_string "imovx")
2712            ]
2713            (const_string "imov")))
2714    (set (attr "prefix")
2715      (if_then_else (eq_attr "alternative" "9,10,11")
2716        (const_string "vex")
2717        (const_string "orig")))
2718    (set (attr "mode")
2719       (cond [(eq_attr "alternative" "5,6,7")
2720                (const_string "SI")
2721              (eq_attr "alternative" "8")
2722                (const_string "QI")
2723              (and (eq_attr "alternative" "9,10,11")
2724                   (not (match_test "TARGET_AVX512DQ")))
2725                (const_string "HI")
2726              (eq_attr "type" "imovx")
2727                (const_string "SI")
2728              ;; For -Os, 8-bit immediates are always shorter than 32-bit
2729              ;; ones.
2730              (and (eq_attr "type" "imov")
2731                   (and (eq_attr "alternative" "3")
2732                        (match_test "optimize_function_for_size_p (cfun)")))
2733                (const_string "QI")
2734              ;; For -Os, movl where one or both operands are NON_Q_REGS
2735              ;; and both are LEGACY_REGS is shorter than movb.
2736              ;; Otherwise movb and movl sizes are the same, so decide purely
2737              ;; based on speed factors.
2738              (and (eq_attr "type" "imov")
2739                   (and (eq_attr "alternative" "1")
2740                        (match_test "optimize_function_for_size_p (cfun)")))
2741                (const_string "SI")
2742              (and (eq_attr "type" "imov")
2743                   (and (eq_attr "alternative" "0,1,2,3")
2744                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2745                             (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2746                (const_string "SI")
2747              ;; Avoid partial register stalls when not using QImode arithmetic
2748              (and (eq_attr "type" "imov")
2749                   (and (eq_attr "alternative" "0,1,2,3")
2750                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2751                             (not (match_test "TARGET_QIMODE_MATH")))))
2752                (const_string "SI")
2753            ]
2754            (const_string "QI")))])
2756 ;; Stores and loads of ax to arbitrary constant address.
2757 ;; We fake an second form of instruction to force reload to load address
2758 ;; into register when rax is not available
2759 (define_insn "*movabs<mode>_1"
2760   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2761         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2762   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2764   /* Recover the full memory rtx.  */
2765   operands[0] = SET_DEST (PATTERN (insn));
2766   switch (which_alternative)
2767     {
2768     case 0:
2769       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2770     case 1:
2771       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2772     default:
2773       gcc_unreachable ();
2774     }
2776   [(set_attr "type" "imov")
2777    (set_attr "modrm" "0,*")
2778    (set_attr "length_address" "8,0")
2779    (set_attr "length_immediate" "0,*")
2780    (set_attr "memory" "store")
2781    (set_attr "mode" "<MODE>")])
2783 (define_insn "*movabs<mode>_2"
2784   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2785         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2786   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2788   /* Recover the full memory rtx.  */
2789   operands[1] = SET_SRC (PATTERN (insn));
2790   switch (which_alternative)
2791     {
2792     case 0:
2793       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2794     case 1:
2795       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2796     default:
2797       gcc_unreachable ();
2798     }
2800   [(set_attr "type" "imov")
2801    (set_attr "modrm" "0,*")
2802    (set_attr "length_address" "8,0")
2803    (set_attr "length_immediate" "0")
2804    (set_attr "memory" "load")
2805    (set_attr "mode" "<MODE>")])
2807 (define_insn "*swap<mode>"
2808   [(set (match_operand:SWI48 0 "register_operand" "+r")
2809         (match_operand:SWI48 1 "register_operand" "+r"))
2810    (set (match_dup 1)
2811         (match_dup 0))]
2812   ""
2813   "xchg{<imodesuffix>}\t%1, %0"
2814   [(set_attr "type" "imov")
2815    (set_attr "mode" "<MODE>")
2816    (set_attr "pent_pair" "np")
2817    (set_attr "athlon_decode" "vector")
2818    (set_attr "amdfam10_decode" "double")
2819    (set_attr "bdver1_decode" "double")])
2821 (define_insn "*swap<mode>"
2822   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2823         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2824    (set (match_dup 1)
2825         (match_dup 0))]
2826   ""
2827   "@
2828    xchg{<imodesuffix>}\t%1, %0
2829    xchg{l}\t%k1, %k0"
2830   [(set_attr "type" "imov")
2831    (set_attr "mode" "<MODE>,SI")
2832    (set (attr "preferred_for_size")
2833      (cond [(eq_attr "alternative" "0")
2834               (symbol_ref "false")]
2835            (symbol_ref "true")))
2836    ;; Potential partial reg stall on alternative 1.
2837    (set (attr "preferred_for_speed")
2838      (cond [(eq_attr "alternative" "1")
2839               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2840            (symbol_ref "true")))
2841    (set_attr "pent_pair" "np")
2842    (set_attr "athlon_decode" "vector")
2843    (set_attr "amdfam10_decode" "double")
2844    (set_attr "bdver1_decode" "double")])
2846 (define_expand "movstrict<mode>"
2847   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2848         (match_operand:SWI12 1 "general_operand"))]
2849   ""
2851   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2852     FAIL;
2853   if (SUBREG_P (operands[0])
2854       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2855     FAIL;
2856   /* Don't generate memory->memory moves, go through a register */
2857   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2858     operands[1] = force_reg (<MODE>mode, operands[1]);
2861 (define_insn "*movstrict<mode>_1"
2862   [(set (strict_low_part
2863           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2864         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2865   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2866    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2867   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2868   [(set_attr "type" "imov")
2869    (set_attr "mode" "<MODE>")])
2871 (define_insn "*movstrict<mode>_xor"
2872   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2873         (match_operand:SWI12 1 "const0_operand"))
2874    (clobber (reg:CC FLAGS_REG))]
2875   "reload_completed"
2876   "xor{<imodesuffix>}\t%0, %0"
2877   [(set_attr "type" "alu1")
2878    (set_attr "modrm_class" "op0")
2879    (set_attr "mode" "<MODE>")
2880    (set_attr "length_immediate" "0")])
2882 (define_expand "extv<mode>"
2883   [(set (match_operand:SWI24 0 "register_operand")
2884         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2885                             (match_operand:SI 2 "const_int_operand")
2886                             (match_operand:SI 3 "const_int_operand")))]
2887   ""
2889   /* Handle extractions from %ah et al.  */
2890   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2891     FAIL;
2893   unsigned int regno = reg_or_subregno (operands[1]);
2895   /* Be careful to expand only with registers having upper parts.  */
2896   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2897     operands[1] = copy_to_reg (operands[1]);
2900 (define_insn "*extv<mode>"
2901   [(set (match_operand:SWI24 0 "register_operand" "=R")
2902         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2903                             (const_int 8)
2904                             (const_int 8)))]
2905   ""
2906   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2907   [(set_attr "type" "imovx")
2908    (set_attr "mode" "SI")])
2910 (define_expand "extzv<mode>"
2911   [(set (match_operand:SWI248 0 "register_operand")
2912         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2913                              (match_operand:SI 2 "const_int_operand")
2914                              (match_operand:SI 3 "const_int_operand")))]
2915   ""
2917   if (ix86_expand_pextr (operands))
2918     DONE;
2920   /* Handle extractions from %ah et al.  */
2921   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2922     FAIL;
2924   unsigned int regno = reg_or_subregno (operands[1]);
2926   /* Be careful to expand only with registers having upper parts.  */
2927   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2928     operands[1] = copy_to_reg (operands[1]);
2931 (define_insn "*extzvqi_mem_rex64"
2932   [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2933         (subreg:QI
2934           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2935                            (const_int 8)
2936                            (const_int 8)) 0))]
2937   "TARGET_64BIT && reload_completed"
2938   "mov{b}\t{%h1, %0|%0, %h1}"
2939   [(set_attr "type" "imov")
2940    (set_attr "mode" "QI")])
2942 (define_insn "*extzv<mode>"
2943   [(set (match_operand:SWI248 0 "register_operand" "=R")
2944         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2945                              (const_int 8)
2946                              (const_int 8)))]
2947   ""
2948   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2949   [(set_attr "type" "imovx")
2950    (set_attr "mode" "SI")])
2952 (define_insn "*extzvqi"
2953   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2954         (subreg:QI
2955           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2956                            (const_int 8)
2957                            (const_int 8)) 0))]
2958   ""
2960   switch (get_attr_type (insn))
2961     {
2962     case TYPE_IMOVX:
2963       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2964     default:
2965       return "mov{b}\t{%h1, %0|%0, %h1}";
2966     }
2968   [(set_attr "isa" "*,*,nox64")
2969    (set (attr "type")
2970      (if_then_else (and (match_operand:QI 0 "register_operand")
2971                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2972                              (match_test "TARGET_MOVX")))
2973         (const_string "imovx")
2974         (const_string "imov")))
2975    (set (attr "mode")
2976      (if_then_else (eq_attr "type" "imovx")
2977         (const_string "SI")
2978         (const_string "QI")))])
2980 (define_peephole2
2981   [(set (match_operand:QI 0 "register_operand")
2982         (subreg:QI
2983           (zero_extract:SI (match_operand 1 "ext_register_operand")
2984                            (const_int 8)
2985                            (const_int 8)) 0))
2986    (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2987   "TARGET_64BIT
2988    && peep2_reg_dead_p (2, operands[0])"
2989   [(set (match_dup 2)
2990         (subreg:QI
2991           (zero_extract:SI (match_dup 1)
2992                            (const_int 8)
2993                            (const_int 8)) 0))])
2995 (define_expand "insv<mode>"
2996   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2997                              (match_operand:SI 1 "const_int_operand")
2998                              (match_operand:SI 2 "const_int_operand"))
2999         (match_operand:SWI248 3 "register_operand"))]
3000   ""
3002   rtx dst;
3004   if (ix86_expand_pinsr (operands))
3005     DONE;
3007   /* Handle insertions to %ah et al.  */
3008   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3009     FAIL;
3011   unsigned int regno = reg_or_subregno (operands[0]);
3013   /* Be careful to expand only with registers having upper parts.  */
3014   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3015     dst = copy_to_reg (operands[0]);
3016   else
3017     dst = operands[0];
3019   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3021   /* Fix up the destination if needed.  */
3022   if (dst != operands[0])
3023     emit_move_insn (operands[0], dst);
3025   DONE;
3028 (define_insn "*insvqi_1_mem_rex64"
3029   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3030                          (const_int 8)
3031                          (const_int 8))
3032         (subreg:SI
3033           (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3034   "TARGET_64BIT && reload_completed"
3035   "mov{b}\t{%1, %h0|%h0, %1}"
3036   [(set_attr "type" "imov")
3037    (set_attr "mode" "QI")])
3039 (define_insn "insv<mode>_1"
3040   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3041                              (const_int 8)
3042                              (const_int 8))
3043         (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3044   ""
3046   if (CONST_INT_P (operands[1]))
3047     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3048   return "mov{b}\t{%b1, %h0|%h0, %b1}";
3050   [(set_attr "isa" "*,nox64")
3051    (set_attr "type" "imov")
3052    (set_attr "mode" "QI")])
3054 (define_insn "*insvqi_1"
3055   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3056                          (const_int 8)
3057                          (const_int 8))
3058         (subreg:SI
3059           (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3060   ""
3061   "mov{b}\t{%1, %h0|%h0, %1}"
3062   [(set_attr "isa" "*,nox64")
3063    (set_attr "type" "imov")
3064    (set_attr "mode" "QI")])
3066 (define_peephole2
3067   [(set (match_operand:QI 0 "register_operand")
3068         (match_operand:QI 1 "norex_memory_operand"))
3069    (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3070                          (const_int 8)
3071                          (const_int 8))
3072         (subreg:SI (match_dup 0) 0))]
3073   "TARGET_64BIT
3074    && peep2_reg_dead_p (2, operands[0])"
3075   [(set (zero_extract:SI (match_dup 2)
3076                          (const_int 8)
3077                          (const_int 8))
3078            (subreg:SI (match_dup 1) 0))])
3080 (define_code_iterator any_extract [sign_extract zero_extract])
3082 (define_insn "*insvqi_2"
3083   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3084                          (const_int 8)
3085                          (const_int 8))
3086         (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3087                         (const_int 8)
3088                         (const_int 8)))]
3089   ""
3090   "mov{b}\t{%h1, %h0|%h0, %h1}"
3091   [(set_attr "type" "imov")
3092    (set_attr "mode" "QI")])
3094 (define_insn "*insvqi_3"
3095   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3096                          (const_int 8)
3097                          (const_int 8))
3098         (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3099                         (const_int 8)))]
3100   ""
3101   "mov{b}\t{%h1, %h0|%h0, %h1}"
3102   [(set_attr "type" "imov")
3103    (set_attr "mode" "QI")])
3105 ;; Floating point push instructions.
3107 (define_insn "*pushtf"
3108   [(set (match_operand:TF 0 "push_operand" "=<,<")
3109         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3110   "TARGET_64BIT || TARGET_SSE"
3112   /* This insn should be already split before reg-stack.  */
3113   gcc_unreachable ();
3115   [(set_attr "isa" "*,x64")
3116    (set_attr "type" "multi")
3117    (set_attr "unit" "sse,*")
3118    (set_attr "mode" "TF,DI")])
3120 ;; %%% Kill this when call knows how to work this out.
3121 (define_split
3122   [(set (match_operand:TF 0 "push_operand")
3123         (match_operand:TF 1 "sse_reg_operand"))]
3124   "TARGET_SSE && reload_completed"
3125   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3126    (set (match_dup 0) (match_dup 1))]
3128   /* Preserve memory attributes. */
3129   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3132 (define_insn_and_split "*pushxf_rounded"
3133   [(set (mem:XF
3134           (pre_modify:P
3135             (reg:P SP_REG)
3136             (plus:P (reg:P SP_REG) (const_int -16))))
3137         (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3138   "TARGET_64BIT"
3139   "#"
3140   "&& 1"
3141   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3142    (set (match_dup 1) (match_dup 0))]
3144   rtx pat = PATTERN (curr_insn);
3145   operands[1] = SET_DEST (pat);
3147   /* Preserve memory attributes. */
3148   operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3150   [(set_attr "type" "multi")
3151    (set_attr "unit" "i387,*,*,*")
3152    (set (attr "mode")
3153         (cond [(eq_attr "alternative" "1,2,3")
3154                  (const_string "DI")
3155               ]
3156               (const_string "XF")))
3157    (set (attr "preferred_for_size")
3158      (cond [(eq_attr "alternative" "1")
3159               (symbol_ref "false")]
3160            (symbol_ref "true")))])
3162 (define_insn "*pushxf"
3163   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3164         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3165   ""
3167   /* This insn should be already split before reg-stack.  */
3168   gcc_unreachable ();
3170   [(set_attr "isa" "*,*,*,nox64,x64")
3171    (set_attr "type" "multi")
3172    (set_attr "unit" "i387,*,*,*,*")
3173    (set (attr "mode")
3174         (cond [(eq_attr "alternative" "1,2,3,4")
3175                  (if_then_else (match_test "TARGET_64BIT")
3176                    (const_string "DI")
3177                    (const_string "SI"))
3178               ]
3179               (const_string "XF")))
3180    (set (attr "preferred_for_size")
3181      (cond [(eq_attr "alternative" "1")
3182               (symbol_ref "false")]
3183            (symbol_ref "true")))])
3185 ;; %%% Kill this when call knows how to work this out.
3186 (define_split
3187   [(set (match_operand:XF 0 "push_operand")
3188         (match_operand:XF 1 "fp_register_operand"))]
3189   "reload_completed"
3190   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3191    (set (match_dup 0) (match_dup 1))]
3193   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3194   /* Preserve memory attributes. */
3195   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3198 (define_insn "*pushdf"
3199   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3200         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3201   ""
3203   /* This insn should be already split before reg-stack.  */
3204   gcc_unreachable ();
3206   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3207    (set_attr "type" "multi")
3208    (set_attr "unit" "i387,*,*,*,*,sse")
3209    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3210    (set (attr "preferred_for_size")
3211      (cond [(eq_attr "alternative" "1")
3212               (symbol_ref "false")]
3213            (symbol_ref "true")))
3214    (set (attr "preferred_for_speed")
3215      (cond [(eq_attr "alternative" "1")
3216               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3217            (symbol_ref "true")))])
3218    
3219 ;; %%% Kill this when call knows how to work this out.
3220 (define_split
3221   [(set (match_operand:DF 0 "push_operand")
3222         (match_operand:DF 1 "any_fp_register_operand"))]
3223   "reload_completed"
3224   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3225    (set (match_dup 0) (match_dup 1))]
3227   /* Preserve memory attributes. */
3228   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3231 (define_insn "*pushsf_rex64"
3232   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3233         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3234   "TARGET_64BIT"
3236   /* Anything else should be already split before reg-stack.  */
3237   gcc_assert (which_alternative == 1);
3238   return "push{q}\t%q1";
3240   [(set_attr "type" "multi,push,multi")
3241    (set_attr "unit" "i387,*,*")
3242    (set_attr "mode" "SF,DI,SF")])
3244 (define_insn "*pushsf"
3245   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3246         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3247   "!TARGET_64BIT"
3249   /* Anything else should be already split before reg-stack.  */
3250   gcc_assert (which_alternative == 1);
3251   return "push{l}\t%1";
3253   [(set_attr "type" "multi,push,multi")
3254    (set_attr "unit" "i387,*,*")
3255    (set_attr "mode" "SF,SI,SF")])
3257 ;; %%% Kill this when call knows how to work this out.
3258 (define_split
3259   [(set (match_operand:SF 0 "push_operand")
3260         (match_operand:SF 1 "any_fp_register_operand"))]
3261   "reload_completed"
3262   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3263    (set (match_dup 0) (match_dup 1))]
3265   rtx op = XEXP (operands[0], 0);
3266   if (GET_CODE (op) == PRE_DEC)
3267     {
3268       gcc_assert (!TARGET_64BIT);
3269       op = GEN_INT (-4);
3270     }
3271   else
3272     {
3273       op = XEXP (XEXP (op, 1), 1);
3274       gcc_assert (CONST_INT_P (op));
3275     }
3276   operands[2] = op;
3277   /* Preserve memory attributes. */
3278   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3281 (define_split
3282   [(set (match_operand:SF 0 "push_operand")
3283         (match_operand:SF 1 "memory_operand"))]
3284   "reload_completed
3285    && find_constant_src (insn)"
3286   [(set (match_dup 0) (match_dup 2))]
3287   "operands[2] = find_constant_src (curr_insn);")
3289 (define_split
3290   [(set (match_operand 0 "push_operand")
3291         (match_operand 1 "general_gr_operand"))]
3292   "reload_completed
3293    && (GET_MODE (operands[0]) == TFmode
3294        || GET_MODE (operands[0]) == XFmode
3295        || GET_MODE (operands[0]) == DFmode)"
3296   [(const_int 0)]
3297   "ix86_split_long_move (operands); DONE;")
3299 ;; Floating point move instructions.
3301 (define_expand "movtf"
3302   [(set (match_operand:TF 0 "nonimmediate_operand")
3303         (match_operand:TF 1 "nonimmediate_operand"))]
3304   "TARGET_64BIT || TARGET_SSE"
3305   "ix86_expand_move (TFmode, operands); DONE;")
3307 (define_expand "mov<mode>"
3308   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3309         (match_operand:X87MODEF 1 "general_operand"))]
3310   ""
3311   "ix86_expand_move (<MODE>mode, operands); DONE;")
3313 (define_insn "*movtf_internal"
3314   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3315         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3316   "(TARGET_64BIT || TARGET_SSE)
3317    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3318    && (lra_in_progress || reload_completed
3319        || !CONST_DOUBLE_P (operands[1])
3320        || ((optimize_function_for_size_p (cfun)
3321             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3322            && standard_sse_constant_p (operands[1], TFmode) == 1
3323            && !memory_operand (operands[0], TFmode))
3324        || (!TARGET_MEMORY_MISMATCH_STALL
3325            && memory_operand (operands[0], TFmode)))"
3327   switch (get_attr_type (insn))
3328     {
3329     case TYPE_SSELOG1:
3330       return standard_sse_constant_opcode (insn, operands);
3332     case TYPE_SSEMOV:
3333       /* Handle misaligned load/store since we
3334          don't have movmisaligntf pattern. */
3335       if (misaligned_operand (operands[0], TFmode)
3336           || misaligned_operand (operands[1], TFmode))
3337         {
3338           if (get_attr_mode (insn) == MODE_V4SF)
3339             return "%vmovups\t{%1, %0|%0, %1}";
3340           else if (TARGET_AVX512VL
3341                    && (EXT_REX_SSE_REG_P (operands[0])
3342                        || EXT_REX_SSE_REG_P (operands[1])))
3343             return "vmovdqu64\t{%1, %0|%0, %1}";
3344           else
3345             return "%vmovdqu\t{%1, %0|%0, %1}";
3346         }
3347       else
3348         {
3349           if (get_attr_mode (insn) == MODE_V4SF)
3350             return "%vmovaps\t{%1, %0|%0, %1}";
3351           else if (TARGET_AVX512VL
3352                    && (EXT_REX_SSE_REG_P (operands[0])
3353                        || EXT_REX_SSE_REG_P (operands[1])))
3354             return "vmovdqa64\t{%1, %0|%0, %1}";
3355           else
3356             return "%vmovdqa\t{%1, %0|%0, %1}";
3357         }
3359     case TYPE_MULTI:
3360         return "#";
3362     default:
3363       gcc_unreachable ();
3364     }
3366   [(set_attr "isa" "*,*,*,x64,x64")
3367    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3368    (set (attr "prefix")
3369      (if_then_else (eq_attr "type" "sselog1,ssemov")
3370        (const_string "maybe_vex")
3371        (const_string "orig")))
3372    (set (attr "mode")
3373         (cond [(eq_attr "alternative" "3,4")
3374                  (const_string "DI")
3375                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3376                  (const_string "V4SF")
3377                (and (eq_attr "alternative" "2")
3378                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3379                  (const_string "V4SF")
3380                (match_test "TARGET_AVX")
3381                  (const_string "TI")
3382                (ior (not (match_test "TARGET_SSE2"))
3383                     (match_test "optimize_function_for_size_p (cfun)"))
3384                  (const_string "V4SF")
3385                ]
3386                (const_string "TI")))])
3388 (define_split
3389   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3390         (match_operand:TF 1 "general_gr_operand"))]
3391   "reload_completed"
3392   [(const_int 0)]
3393   "ix86_split_long_move (operands); DONE;")
3395 ;; Possible store forwarding (partial memory) stall
3396 ;; in alternatives 4, 6, 7 and 8.
3397 (define_insn "*movxf_internal"
3398   [(set (match_operand:XF 0 "nonimmediate_operand"
3399          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3400         (match_operand:XF 1 "general_operand"
3401          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3402   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3403    && (lra_in_progress || reload_completed
3404        || !CONST_DOUBLE_P (operands[1])
3405        || ((optimize_function_for_size_p (cfun)
3406             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3407            && standard_80387_constant_p (operands[1]) > 0
3408            && !memory_operand (operands[0], XFmode))
3409        || (!TARGET_MEMORY_MISMATCH_STALL
3410            && memory_operand (operands[0], XFmode))
3411        || !TARGET_HARD_XF_REGS)"
3413   switch (get_attr_type (insn))
3414     {
3415     case TYPE_FMOV:
3416       if (which_alternative == 2)
3417         return standard_80387_constant_opcode (operands[1]);
3418       return output_387_reg_move (insn, operands);
3420     case TYPE_MULTI:
3421       return "#";
3423     default:
3424       gcc_unreachable ();
3425     }
3427   [(set (attr "isa")
3428         (cond [(eq_attr "alternative" "7,10")
3429                  (const_string "nox64")
3430                (eq_attr "alternative" "8,11")
3431                  (const_string "x64")
3432               ]
3433               (const_string "*")))
3434    (set (attr "type")
3435         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3436                  (const_string "multi")
3437               ]
3438               (const_string "fmov")))
3439    (set (attr "mode")
3440         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3441                  (if_then_else (match_test "TARGET_64BIT")
3442                    (const_string "DI")
3443                    (const_string "SI"))
3444               ]
3445               (const_string "XF")))
3446    (set (attr "preferred_for_size")
3447      (cond [(eq_attr "alternative" "3,4")
3448               (symbol_ref "false")]
3449            (symbol_ref "true")))
3450    (set (attr "enabled")
3451      (cond [(eq_attr "alternative" "9,10,11")
3452               (if_then_else
3453                 (match_test "TARGET_HARD_XF_REGS")
3454                 (symbol_ref "false")
3455                 (const_string "*"))
3456             (not (match_test "TARGET_HARD_XF_REGS"))
3457               (symbol_ref "false")
3458            ]
3459            (const_string "*")))])
3460    
3461 (define_split
3462   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3463         (match_operand:XF 1 "general_gr_operand"))]
3464   "reload_completed"
3465   [(const_int 0)]
3466   "ix86_split_long_move (operands); DONE;")
3468 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3469 (define_insn "*movdf_internal"
3470   [(set (match_operand:DF 0 "nonimmediate_operand"
3471     "=Yf*f,m   ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r  ,o ,r  ,m")
3472         (match_operand:DF 1 "general_operand"
3473     "Yf*fm,Yf*f,G   ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
3474   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3475    && (lra_in_progress || reload_completed
3476        || !CONST_DOUBLE_P (operands[1])
3477        || ((optimize_function_for_size_p (cfun)
3478             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3479            && ((IS_STACK_MODE (DFmode)
3480                 && standard_80387_constant_p (operands[1]) > 0)
3481                || (TARGET_SSE2 && TARGET_SSE_MATH
3482                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3483            && !memory_operand (operands[0], DFmode))
3484        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3485            && memory_operand (operands[0], DFmode))
3486        || !TARGET_HARD_DF_REGS)"
3488   switch (get_attr_type (insn))
3489     {
3490     case TYPE_FMOV:
3491       if (which_alternative == 2)
3492         return standard_80387_constant_opcode (operands[1]);
3493       return output_387_reg_move (insn, operands);
3495     case TYPE_MULTI:
3496       return "#";
3498     case TYPE_IMOV:
3499       if (get_attr_mode (insn) == MODE_SI)
3500         return "mov{l}\t{%1, %k0|%k0, %1}";
3501       else if (which_alternative == 11)
3502         return "movabs{q}\t{%1, %0|%0, %1}";
3503       else
3504         return "mov{q}\t{%1, %0|%0, %1}";
3506     case TYPE_SSELOG1:
3507       return standard_sse_constant_opcode (insn, operands);
3509     case TYPE_SSEMOV:
3510       switch (get_attr_mode (insn))
3511         {
3512         case MODE_DF:
3513           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3514             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3515           return "%vmovsd\t{%1, %0|%0, %1}";
3517         case MODE_V4SF:
3518           return "%vmovaps\t{%1, %0|%0, %1}";
3519         case MODE_V8DF:
3520           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3521         case MODE_V2DF:
3522           return "%vmovapd\t{%1, %0|%0, %1}";
3524         case MODE_V2SF:
3525           gcc_assert (!TARGET_AVX);
3526           return "movlps\t{%1, %0|%0, %1}";
3527         case MODE_V1DF:
3528           gcc_assert (!TARGET_AVX);
3529           return "movlpd\t{%1, %0|%0, %1}";
3531         case MODE_DI:
3532           /* Handle broken assemblers that require movd instead of movq.  */
3533           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3534               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3535             return "%vmovd\t{%1, %0|%0, %1}";
3536           return "%vmovq\t{%1, %0|%0, %1}";
3538         default:
3539           gcc_unreachable ();
3540         }
3542     default:
3543       gcc_unreachable ();
3544     }
3546   [(set (attr "isa")
3547         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3548                  (const_string "nox64")
3549                (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3550                  (const_string "x64")
3551                (eq_attr "alternative" "12,13,14,15")
3552                  (const_string "sse2")
3553               ]
3554               (const_string "*")))
3555    (set (attr "type")
3556         (cond [(eq_attr "alternative" "0,1,2")
3557                  (const_string "fmov")
3558                (eq_attr "alternative" "3,4,5,6,7,22,23")
3559                  (const_string "multi")
3560                (eq_attr "alternative" "8,9,10,11,24,25")
3561                  (const_string "imov")
3562                (eq_attr "alternative" "12,16")
3563                  (const_string "sselog1")
3564               ]
3565               (const_string "ssemov")))
3566    (set (attr "modrm")
3567      (if_then_else (eq_attr "alternative" "11")
3568        (const_string "0")
3569        (const_string "*")))
3570    (set (attr "length_immediate")
3571      (if_then_else (eq_attr "alternative" "11")
3572        (const_string "8")
3573        (const_string "*")))
3574    (set (attr "prefix")
3575      (if_then_else (eq_attr "type" "sselog1,ssemov")
3576        (const_string "maybe_vex")
3577        (const_string "orig")))
3578    (set (attr "prefix_data16")
3579      (if_then_else
3580        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3581             (eq_attr "mode" "V1DF"))
3582        (const_string "1")
3583        (const_string "*")))
3584    (set (attr "mode")
3585         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3586                  (const_string "SI")
3587                (eq_attr "alternative" "8,9,11,20,21,24,25")
3588                  (const_string "DI")
3590                /* xorps is one byte shorter for non-AVX targets.  */
3591                (eq_attr "alternative" "12,16")
3592                  (cond [(not (match_test "TARGET_SSE2"))
3593                           (const_string "V4SF")
3594                         (and (match_test "TARGET_AVX512F")
3595                           (not (match_test "TARGET_PREFER_AVX256")))
3596                           (const_string "XI")
3597                         (match_test "TARGET_AVX")
3598                           (const_string "V2DF")
3599                         (match_test "optimize_function_for_size_p (cfun)")
3600                           (const_string "V4SF")
3601                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3602                           (const_string "TI")
3603                        ]
3604                        (const_string "V2DF"))
3606                /* For architectures resolving dependencies on
3607                   whole SSE registers use movapd to break dependency
3608                   chains, otherwise use short move to avoid extra work.  */
3610                /* movaps is one byte shorter for non-AVX targets.  */
3611                (eq_attr "alternative" "13,17")
3612                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3613                                   (not (match_test "TARGET_AVX512VL")))
3614                              (ior (match_operand 0 "ext_sse_reg_operand")
3615                                   (match_operand 1 "ext_sse_reg_operand")))
3616                           (const_string "V8DF")
3617                         (ior (not (match_test "TARGET_SSE2"))
3618                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3619                           (const_string "V4SF")
3620                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3621                           (const_string "V2DF")
3622                         (match_test "TARGET_AVX")
3623                           (const_string "DF")
3624                         (match_test "optimize_function_for_size_p (cfun)")
3625                           (const_string "V4SF")
3626                        ]
3627                        (const_string "DF"))
3629                /* For architectures resolving dependencies on register
3630                   parts we may avoid extra work to zero out upper part
3631                   of register.  */
3632                (eq_attr "alternative" "14,18")
3633                  (cond [(not (match_test "TARGET_SSE2"))
3634                           (const_string "V2SF")
3635                         (match_test "TARGET_AVX")
3636                           (const_string "DF")
3637                         (match_test "TARGET_SSE_SPLIT_REGS")
3638                           (const_string "V1DF")
3639                        ]
3640                        (const_string "DF"))
3642                (and (eq_attr "alternative" "15,19")
3643                     (not (match_test "TARGET_SSE2")))
3644                  (const_string "V2SF")
3645               ]
3646               (const_string "DF")))
3647    (set (attr "preferred_for_size")
3648      (cond [(eq_attr "alternative" "3,4")
3649               (symbol_ref "false")]
3650            (symbol_ref "true")))
3651    (set (attr "preferred_for_speed")
3652      (cond [(eq_attr "alternative" "3,4")
3653               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3654            (symbol_ref "true")))
3655    (set (attr "enabled")
3656      (cond [(eq_attr "alternative" "22,23,24,25")
3657               (if_then_else
3658                 (match_test "TARGET_HARD_DF_REGS")
3659                 (symbol_ref "false")
3660                 (const_string "*"))
3661             (not (match_test "TARGET_HARD_DF_REGS"))
3662               (symbol_ref "false")
3663            ]
3664            (const_string "*")))])
3666 (define_split
3667   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3668         (match_operand:DF 1 "general_gr_operand"))]
3669   "!TARGET_64BIT && reload_completed"
3670   [(const_int 0)]
3671   "ix86_split_long_move (operands); DONE;")
3673 (define_insn "*movsf_internal"
3674   [(set (match_operand:SF 0 "nonimmediate_operand"
3675           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
3676         (match_operand:SF 1 "general_operand"
3677           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
3678   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3679    && (lra_in_progress || reload_completed
3680        || !CONST_DOUBLE_P (operands[1])
3681        || ((optimize_function_for_size_p (cfun)
3682             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3683            && ((IS_STACK_MODE (SFmode)
3684                 && standard_80387_constant_p (operands[1]) > 0)
3685                || (TARGET_SSE && TARGET_SSE_MATH
3686                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3687        || memory_operand (operands[0], SFmode)
3688        || !TARGET_HARD_SF_REGS)"
3690   switch (get_attr_type (insn))
3691     {
3692     case TYPE_FMOV:
3693       if (which_alternative == 2)
3694         return standard_80387_constant_opcode (operands[1]);
3695       return output_387_reg_move (insn, operands);
3697     case TYPE_IMOV:
3698       return "mov{l}\t{%1, %0|%0, %1}";
3700     case TYPE_SSELOG1:
3701       return standard_sse_constant_opcode (insn, operands);
3703     case TYPE_SSEMOV:
3704       switch (get_attr_mode (insn))
3705         {
3706         case MODE_SF:
3707           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3708             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3709           return "%vmovss\t{%1, %0|%0, %1}";
3711         case MODE_V16SF:
3712           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3713         case MODE_V4SF:
3714           return "%vmovaps\t{%1, %0|%0, %1}";
3716         case MODE_SI:
3717           return "%vmovd\t{%1, %0|%0, %1}";
3719         default:
3720           gcc_unreachable ();
3721         }
3723     case TYPE_MMXMOV:
3724       switch (get_attr_mode (insn))
3725         {
3726         case MODE_DI:
3727           return "movq\t{%1, %0|%0, %1}";
3728         case MODE_SI:
3729           return "movd\t{%1, %0|%0, %1}";
3731         default:
3732           gcc_unreachable ();
3733         }
3735     default:
3736       gcc_unreachable ();
3737     }
3739   [(set (attr "type")
3740         (cond [(eq_attr "alternative" "0,1,2")
3741                  (const_string "fmov")
3742                (eq_attr "alternative" "3,4,16,17")
3743                  (const_string "imov")
3744                (eq_attr "alternative" "5")
3745                  (const_string "sselog1")
3746                (eq_attr "alternative" "11,12,13,14,15")
3747                  (const_string "mmxmov")
3748               ]
3749               (const_string "ssemov")))
3750    (set (attr "prefix")
3751      (if_then_else (eq_attr "type" "sselog1,ssemov")
3752        (const_string "maybe_vex")
3753        (const_string "orig")))
3754    (set (attr "prefix_data16")
3755      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3756        (const_string "1")
3757        (const_string "*")))
3758    (set (attr "mode")
3759         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3760                  (const_string "SI")
3761                (eq_attr "alternative" "11")
3762                  (const_string "DI")
3763                (eq_attr "alternative" "5")
3764                  (cond [(not (match_test "TARGET_SSE2"))
3765                           (const_string "V4SF")
3766                         (and (match_test "TARGET_AVX512F")
3767                           (not (match_test "TARGET_PREFER_AVX256")))
3768                           (const_string "V16SF")
3769                         (match_test "TARGET_AVX")
3770                           (const_string "V4SF")
3771                         (match_test "optimize_function_for_size_p (cfun)")
3772                           (const_string "V4SF")
3773                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3774                           (const_string "TI")
3775                        ]
3776                        (const_string "V4SF"))
3778                /* For architectures resolving dependencies on
3779                   whole SSE registers use APS move to break dependency
3780                   chains, otherwise use short move to avoid extra work.
3782                   Do the same for architectures resolving dependencies on
3783                   the parts.  While in DF mode it is better to always handle
3784                   just register parts, the SF mode is different due to lack
3785                   of instructions to load just part of the register.  It is
3786                   better to maintain the whole registers in single format
3787                   to avoid problems on using packed logical operations.  */
3788                (eq_attr "alternative" "6")
3789                  (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3790                                   (not (match_test "TARGET_AVX512VL")))
3791                              (ior (match_operand 0 "ext_sse_reg_operand")
3792                                   (match_operand 1 "ext_sse_reg_operand")))
3793                           (const_string "V16SF")
3794                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3795                              (match_test "TARGET_SSE_SPLIT_REGS"))
3796                           (const_string "V4SF")
3797                        ]
3798                        (const_string "SF"))
3799               ]
3800               (const_string "SF")))
3801    (set (attr "enabled")
3802      (cond [(eq_attr "alternative" "16,17")
3803               (if_then_else
3804                 (match_test "TARGET_HARD_SF_REGS")
3805                 (symbol_ref "false")
3806                 (const_string "*"))
3807             (not (match_test "TARGET_HARD_SF_REGS"))
3808               (symbol_ref "false")
3809            ]
3810            (const_string "*")))])
3812 (define_split
3813   [(set (match_operand 0 "any_fp_register_operand")
3814         (match_operand 1 "nonimmediate_operand"))]
3815   "reload_completed
3816    && (GET_MODE (operands[0]) == TFmode
3817        || GET_MODE (operands[0]) == XFmode
3818        || GET_MODE (operands[0]) == DFmode
3819        || GET_MODE (operands[0]) == SFmode)
3820    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3821   [(set (match_dup 0) (match_dup 2))]
3822   "operands[2] = find_constant_src (curr_insn);")
3824 (define_split
3825   [(set (match_operand 0 "any_fp_register_operand")
3826         (float_extend (match_operand 1 "nonimmediate_operand")))]
3827   "reload_completed
3828    && (GET_MODE (operands[0]) == TFmode
3829        || GET_MODE (operands[0]) == XFmode
3830        || GET_MODE (operands[0]) == DFmode)
3831    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3832   [(set (match_dup 0) (match_dup 2))]
3833   "operands[2] = find_constant_src (curr_insn);")
3835 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3836 (define_split
3837   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3838         (match_operand:X87MODEF 1 "immediate_operand"))]
3839   "reload_completed
3840    && (standard_80387_constant_p (operands[1]) == 8
3841        || standard_80387_constant_p (operands[1]) == 9)"
3842   [(set (match_dup 0)(match_dup 1))
3843    (set (match_dup 0)
3844         (neg:X87MODEF (match_dup 0)))]
3846   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3847     operands[1] = CONST0_RTX (<MODE>mode);
3848   else
3849     operands[1] = CONST1_RTX (<MODE>mode);
3852 (define_insn "swapxf"
3853   [(set (match_operand:XF 0 "register_operand" "+f")
3854         (match_operand:XF 1 "register_operand" "+f"))
3855    (set (match_dup 1)
3856         (match_dup 0))]
3857   "TARGET_80387"
3859   if (STACK_TOP_P (operands[0]))
3860     return "fxch\t%1";
3861   else
3862     return "fxch\t%0";
3864   [(set_attr "type" "fxch")
3865    (set_attr "mode" "XF")])
3867 (define_insn "*swap<mode>"
3868   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3869         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3870    (set (match_dup 1)
3871         (match_dup 0))]
3872   "TARGET_80387 || reload_completed"
3874   if (STACK_TOP_P (operands[0]))
3875     return "fxch\t%1";
3876   else
3877     return "fxch\t%0";
3879   [(set_attr "type" "fxch")
3880    (set_attr "mode" "<MODE>")])
3882 ;; Zero extension instructions
3884 (define_expand "zero_extendsidi2"
3885   [(set (match_operand:DI 0 "nonimmediate_operand")
3886         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3888 (define_insn "*zero_extendsidi2"
3889   [(set (match_operand:DI 0 "nonimmediate_operand"
3890                 "=r,?r,?o,r   ,o,?*Ym,?!*y,$r,$Yi,$x,*x,*v,*r")
3891         (zero_extend:DI
3892          (match_operand:SI 1 "x86_64_zext_operand"
3893                 "0 ,rm,r ,rmWz,0,r   ,m   ,Yj,r  ,m ,*x,*v,*k")))]
3894   ""
3896   switch (get_attr_type (insn))
3897     {
3898     case TYPE_IMOVX:
3899       if (ix86_use_lea_for_mov (insn, operands))
3900         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3901       else
3902         return "mov{l}\t{%1, %k0|%k0, %1}";
3904     case TYPE_MULTI:
3905       return "#";
3907     case TYPE_MMXMOV:
3908       return "movd\t{%1, %0|%0, %1}";
3910     case TYPE_SSEMOV:
3911       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3912         {
3913           if (EXT_REX_SSE_REG_P (operands[0])
3914               || EXT_REX_SSE_REG_P (operands[1]))
3915             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3916           else
3917             return "%vpmovzxdq\t{%1, %0|%0, %1}";
3918         }
3920       if (GENERAL_REG_P (operands[0]))
3921         return "%vmovd\t{%1, %k0|%k0, %1}";
3923       return "%vmovd\t{%1, %0|%0, %1}";
3925     case TYPE_MSKMOV:
3926       return "kmovd\t{%1, %k0|%k0, %1}";
3928     default:
3929       gcc_unreachable ();
3930     }
3932   [(set (attr "isa")
3933      (cond [(eq_attr "alternative" "0,1,2")
3934               (const_string "nox64")
3935             (eq_attr "alternative" "3")
3936               (const_string "x64")
3937             (eq_attr "alternative" "9")
3938               (const_string "sse2")
3939             (eq_attr "alternative" "10")
3940               (const_string "sse4")
3941             (eq_attr "alternative" "11")
3942               (const_string "avx512f")
3943             (eq_attr "alternative" "12")
3944               (const_string "x64_avx512bw")
3945            ]
3946            (const_string "*")))
3947    (set (attr "type")
3948      (cond [(eq_attr "alternative" "0,1,2,4")
3949               (const_string "multi")
3950             (eq_attr "alternative" "5,6")
3951               (const_string "mmxmov")
3952             (eq_attr "alternative" "7")
3953               (if_then_else (match_test "TARGET_64BIT")
3954                 (const_string "ssemov")
3955                 (const_string "multi"))
3956             (eq_attr "alternative" "8,9,10,11")
3957               (const_string "ssemov")
3958             (eq_attr "alternative" "12")
3959               (const_string "mskmov")
3960            ]
3961            (const_string "imovx")))
3962    (set (attr "prefix_extra")
3963      (if_then_else (eq_attr "alternative" "10,11")
3964        (const_string "1")
3965        (const_string "*")))
3966    (set (attr "prefix")
3967      (if_then_else (eq_attr "type" "ssemov")
3968        (const_string "maybe_vex")
3969        (const_string "orig")))
3970    (set (attr "prefix_0f")
3971      (if_then_else (eq_attr "type" "imovx")
3972        (const_string "0")
3973        (const_string "*")))
3974    (set (attr "mode")
3975      (cond [(eq_attr "alternative" "5,6")
3976               (const_string "DI")
3977             (and (eq_attr "alternative" "7")
3978                  (match_test "TARGET_64BIT"))
3979               (const_string "TI")
3980             (eq_attr "alternative" "8,10,11")
3981               (const_string "TI")
3982            ]
3983            (const_string "SI")))])
3985 (define_split
3986   [(set (match_operand:DI 0 "memory_operand")
3987         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3988   "reload_completed"
3989   [(set (match_dup 4) (const_int 0))]
3990   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3992 (define_split
3993   [(set (match_operand:DI 0 "general_reg_operand")
3994         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3995   "!TARGET_64BIT && reload_completed
3996    && REGNO (operands[0]) == REGNO (operands[1])"
3997   [(set (match_dup 4) (const_int 0))]
3998   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4000 (define_split
4001   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4002         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4003   "!TARGET_64BIT && reload_completed
4004    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4005   [(set (match_dup 3) (match_dup 1))
4006    (set (match_dup 4) (const_int 0))]
4007   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4009 (define_mode_attr kmov_isa
4010   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4012 (define_insn "zero_extend<mode>di2"
4013   [(set (match_operand:DI 0 "register_operand" "=r,*r")
4014         (zero_extend:DI
4015          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4016   "TARGET_64BIT"
4017   "@
4018    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4019    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4020   [(set_attr "isa" "*,<kmov_isa>")
4021    (set_attr "type" "imovx,mskmov")
4022    (set_attr "mode" "SI,<MODE>")])
4024 (define_expand "zero_extend<mode>si2"
4025   [(set (match_operand:SI 0 "register_operand")
4026         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4027   ""
4029   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4030     {
4031       operands[1] = force_reg (<MODE>mode, operands[1]);
4032       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4033       DONE;
4034     }
4037 (define_insn_and_split "zero_extend<mode>si2_and"
4038   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4039         (zero_extend:SI
4040           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4041    (clobber (reg:CC FLAGS_REG))]
4042   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4043   "#"
4044   "&& reload_completed"
4045   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4046               (clobber (reg:CC FLAGS_REG))])]
4048   if (!REG_P (operands[1])
4049       || REGNO (operands[0]) != REGNO (operands[1]))
4050     {
4051       ix86_expand_clear (operands[0]);
4053       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4054       emit_insn (gen_movstrict<mode>
4055                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4056       DONE;
4057     }
4059   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4061   [(set_attr "type" "alu1")
4062    (set_attr "mode" "SI")])
4064 (define_insn "*zero_extend<mode>si2"
4065   [(set (match_operand:SI 0 "register_operand" "=r,*r")
4066         (zero_extend:SI
4067           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4068   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4069   "@
4070    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4071    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4072   [(set_attr "isa" "*,<kmov_isa>")
4073    (set_attr "type" "imovx,mskmov")
4074    (set_attr "mode" "SI,<MODE>")])
4076 (define_expand "zero_extendqihi2"
4077   [(set (match_operand:HI 0 "register_operand")
4078         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4079   ""
4081   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4082     {
4083       operands[1] = force_reg (QImode, operands[1]);
4084       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4085       DONE;
4086     }
4089 (define_insn_and_split "zero_extendqihi2_and"
4090   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4091         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4092    (clobber (reg:CC FLAGS_REG))]
4093   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4094   "#"
4095   "&& reload_completed"
4096   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4097               (clobber (reg:CC FLAGS_REG))])]
4099   if (!REG_P (operands[1])
4100       || REGNO (operands[0]) != REGNO (operands[1]))
4101     {
4102       ix86_expand_clear (operands[0]);
4104       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4105       emit_insn (gen_movstrictqi
4106                   (gen_lowpart (QImode, operands[0]), operands[1]));
4107       DONE;
4108     }
4110   operands[0] = gen_lowpart (SImode, operands[0]);
4112   [(set_attr "type" "alu1")
4113    (set_attr "mode" "SI")])
4115 ; zero extend to SImode to avoid partial register stalls
4116 (define_insn "*zero_extendqihi2"
4117   [(set (match_operand:HI 0 "register_operand" "=r,*r")
4118         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4119   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4120   "@
4121    movz{bl|x}\t{%1, %k0|%k0, %1}
4122    kmovb\t{%1, %k0|%k0, %1}"
4123   [(set_attr "isa" "*,avx512dq")
4124    (set_attr "type" "imovx,mskmov")
4125    (set_attr "mode" "SI,QI")])
4127 (define_insn_and_split "*zext<mode>_doubleword_and"
4128   [(set (match_operand:DI 0 "register_operand" "=&<r>")
4129         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4130   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4131    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4132   "#"
4133   "&& reload_completed && GENERAL_REG_P (operands[0])"
4134   [(set (match_dup 2) (const_int 0))]
4136   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4138   emit_move_insn (operands[0], const0_rtx);
4140   gcc_assert (!TARGET_PARTIAL_REG_STALL);
4141   emit_insn (gen_movstrict<mode>
4142              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4145 (define_insn_and_split "*zext<mode>_doubleword"
4146   [(set (match_operand:DI 0 "register_operand" "=r")
4147         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4148   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4149    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4150   "#"
4151   "&& reload_completed && GENERAL_REG_P (operands[0])"
4152   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4153    (set (match_dup 2) (const_int 0))]
4154   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4156 (define_insn_and_split "*zextsi_doubleword"
4157   [(set (match_operand:DI 0 "register_operand" "=r")
4158         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4159   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4160   "#"
4161   "&& reload_completed && GENERAL_REG_P (operands[0])"
4162   [(set (match_dup 0) (match_dup 1))
4163    (set (match_dup 2) (const_int 0))]
4164   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4166 ;; Sign extension instructions
4168 (define_expand "extendsidi2"
4169   [(set (match_operand:DI 0 "register_operand")
4170         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4171   ""
4173   if (!TARGET_64BIT)
4174     {
4175       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4176       DONE;
4177     }
4180 (define_insn "*extendsidi2_rex64"
4181   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4182         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4183   "TARGET_64BIT"
4184   "@
4185    {cltq|cdqe}
4186    movs{lq|x}\t{%1, %0|%0, %1}"
4187   [(set_attr "type" "imovx")
4188    (set_attr "mode" "DI")
4189    (set_attr "prefix_0f" "0")
4190    (set_attr "modrm" "0,1")])
4192 (define_insn "extendsidi2_1"
4193   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4194         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4195    (clobber (reg:CC FLAGS_REG))
4196    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4197   "!TARGET_64BIT"
4198   "#")
4200 ;; Split the memory case.  If the source register doesn't die, it will stay
4201 ;; this way, if it does die, following peephole2s take care of it.
4202 (define_split
4203   [(set (match_operand:DI 0 "memory_operand")
4204         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4205    (clobber (reg:CC FLAGS_REG))
4206    (clobber (match_operand:SI 2 "register_operand"))]
4207   "reload_completed"
4208   [(const_int 0)]
4210   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4212   emit_move_insn (operands[3], operands[1]);
4214   /* Generate a cltd if possible and doing so it profitable.  */
4215   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4216       && REGNO (operands[1]) == AX_REG
4217       && REGNO (operands[2]) == DX_REG)
4218     {
4219       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4220     }
4221   else
4222     {
4223       emit_move_insn (operands[2], operands[1]);
4224       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4225     }
4226   emit_move_insn (operands[4], operands[2]);
4227   DONE;
4230 ;; Peepholes for the case where the source register does die, after
4231 ;; being split with the above splitter.
4232 (define_peephole2
4233   [(set (match_operand:SI 0 "memory_operand")
4234         (match_operand:SI 1 "general_reg_operand"))
4235    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4236    (parallel [(set (match_dup 2)
4237                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4238                (clobber (reg:CC FLAGS_REG))])
4239    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4240   "REGNO (operands[1]) != REGNO (operands[2])
4241    && peep2_reg_dead_p (2, operands[1])
4242    && peep2_reg_dead_p (4, operands[2])
4243    && !reg_mentioned_p (operands[2], operands[3])"
4244   [(set (match_dup 0) (match_dup 1))
4245    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4246               (clobber (reg:CC FLAGS_REG))])
4247    (set (match_dup 3) (match_dup 1))])
4249 (define_peephole2
4250   [(set (match_operand:SI 0 "memory_operand")
4251         (match_operand:SI 1 "general_reg_operand"))
4252    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4253                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4254                (clobber (reg:CC FLAGS_REG))])
4255    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4256   "/* cltd is shorter than sarl $31, %eax */
4257    !optimize_function_for_size_p (cfun)
4258    && REGNO (operands[1]) == AX_REG
4259    && REGNO (operands[2]) == DX_REG
4260    && peep2_reg_dead_p (2, operands[1])
4261    && peep2_reg_dead_p (3, operands[2])
4262    && !reg_mentioned_p (operands[2], operands[3])"
4263   [(set (match_dup 0) (match_dup 1))
4264    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4265               (clobber (reg:CC FLAGS_REG))])
4266    (set (match_dup 3) (match_dup 1))])
4268 ;; Extend to register case.  Optimize case where source and destination
4269 ;; registers match and cases where we can use cltd.
4270 (define_split
4271   [(set (match_operand:DI 0 "register_operand")
4272         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4273    (clobber (reg:CC FLAGS_REG))
4274    (clobber (match_scratch:SI 2))]
4275   "reload_completed"
4276   [(const_int 0)]
4278   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4280   if (REGNO (operands[3]) != REGNO (operands[1]))
4281     emit_move_insn (operands[3], operands[1]);
4283   /* Generate a cltd if possible and doing so it profitable.  */
4284   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4285       && REGNO (operands[3]) == AX_REG
4286       && REGNO (operands[4]) == DX_REG)
4287     {
4288       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4289       DONE;
4290     }
4292   if (REGNO (operands[4]) != REGNO (operands[1]))
4293     emit_move_insn (operands[4], operands[1]);
4295   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4296   DONE;
4299 (define_insn "extend<mode>di2"
4300   [(set (match_operand:DI 0 "register_operand" "=r")
4301         (sign_extend:DI
4302          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4303   "TARGET_64BIT"
4304   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4305   [(set_attr "type" "imovx")
4306    (set_attr "mode" "DI")])
4308 (define_insn "extendhisi2"
4309   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4310         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4311   ""
4313   switch (get_attr_prefix_0f (insn))
4314     {
4315     case 0:
4316       return "{cwtl|cwde}";
4317     default:
4318       return "movs{wl|x}\t{%1, %0|%0, %1}";
4319     }
4321   [(set_attr "type" "imovx")
4322    (set_attr "mode" "SI")
4323    (set (attr "prefix_0f")
4324      ;; movsx is short decodable while cwtl is vector decoded.
4325      (if_then_else (and (eq_attr "cpu" "!k6")
4326                         (eq_attr "alternative" "0"))
4327         (const_string "0")
4328         (const_string "1")))
4329    (set (attr "znver1_decode")
4330      (if_then_else (eq_attr "prefix_0f" "0")
4331         (const_string "double")
4332         (const_string "direct")))
4333    (set (attr "modrm")
4334      (if_then_else (eq_attr "prefix_0f" "0")
4335         (const_string "0")
4336         (const_string "1")))])
4338 (define_insn "*extendhisi2_zext"
4339   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4340         (zero_extend:DI
4341          (sign_extend:SI
4342           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4343   "TARGET_64BIT"
4345   switch (get_attr_prefix_0f (insn))
4346     {
4347     case 0:
4348       return "{cwtl|cwde}";
4349     default:
4350       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4351     }
4353   [(set_attr "type" "imovx")
4354    (set_attr "mode" "SI")
4355    (set (attr "prefix_0f")
4356      ;; movsx is short decodable while cwtl is vector decoded.
4357      (if_then_else (and (eq_attr "cpu" "!k6")
4358                         (eq_attr "alternative" "0"))
4359         (const_string "0")
4360         (const_string "1")))
4361    (set (attr "modrm")
4362      (if_then_else (eq_attr "prefix_0f" "0")
4363         (const_string "0")
4364         (const_string "1")))])
4366 (define_insn "extendqisi2"
4367   [(set (match_operand:SI 0 "register_operand" "=r")
4368         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4369   ""
4370   "movs{bl|x}\t{%1, %0|%0, %1}"
4371    [(set_attr "type" "imovx")
4372     (set_attr "mode" "SI")])
4374 (define_insn "*extendqisi2_zext"
4375   [(set (match_operand:DI 0 "register_operand" "=r")
4376         (zero_extend:DI
4377           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4378   "TARGET_64BIT"
4379   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4380    [(set_attr "type" "imovx")
4381     (set_attr "mode" "SI")])
4383 (define_insn "extendqihi2"
4384   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4385         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4386   ""
4388   switch (get_attr_prefix_0f (insn))
4389     {
4390     case 0:
4391       return "{cbtw|cbw}";
4392     default:
4393       return "movs{bw|x}\t{%1, %0|%0, %1}";
4394     }
4396   [(set_attr "type" "imovx")
4397    (set_attr "mode" "HI")
4398    (set (attr "prefix_0f")
4399      ;; movsx is short decodable while cwtl is vector decoded.
4400      (if_then_else (and (eq_attr "cpu" "!k6")
4401                         (eq_attr "alternative" "0"))
4402         (const_string "0")
4403         (const_string "1")))
4404    (set (attr "modrm")
4405      (if_then_else (eq_attr "prefix_0f" "0")
4406         (const_string "0")
4407         (const_string "1")))])
4409 ;; Conversions between float and double.
4411 ;; These are all no-ops in the model used for the 80387.
4412 ;; So just emit moves.
4414 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4415 (define_split
4416   [(set (match_operand:DF 0 "push_operand")
4417         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4418   "reload_completed"
4419   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4420    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4422 (define_split
4423   [(set (match_operand:XF 0 "push_operand")
4424         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4425   "reload_completed"
4426   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4427    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4428   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4430 (define_expand "extendsfdf2"
4431   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4432         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4433   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4435   /* ??? Needed for compress_float_constant since all fp constants
4436      are TARGET_LEGITIMATE_CONSTANT_P.  */
4437   if (CONST_DOUBLE_P (operands[1]))
4438     {
4439       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4440           && standard_80387_constant_p (operands[1]) > 0)
4441         {
4442           operands[1] = simplify_const_unary_operation
4443             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4444           emit_move_insn_1 (operands[0], operands[1]);
4445           DONE;
4446         }
4447       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4448     }
4451 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4452    cvtss2sd:
4453       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4454       cvtps2pd xmm2,xmm1
4455    We do the conversion post reload to avoid producing of 128bit spills
4456    that might lead to ICE on 32bit target.  The sequence unlikely combine
4457    anyway.  */
4458 (define_split
4459   [(set (match_operand:DF 0 "sse_reg_operand")
4460         (float_extend:DF
4461           (match_operand:SF 1 "nonimmediate_operand")))]
4462   "TARGET_USE_VECTOR_FP_CONVERTS
4463    && optimize_insn_for_speed_p ()
4464    && reload_completed
4465    && (!EXT_REX_SSE_REG_P (operands[0])
4466        || TARGET_AVX512VL)"
4467    [(set (match_dup 2)
4468          (float_extend:V2DF
4469            (vec_select:V2SF
4470              (match_dup 3)
4471              (parallel [(const_int 0) (const_int 1)]))))]
4473   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4474   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4475   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4476      Try to avoid move when unpacking can be done in source.  */
4477   if (REG_P (operands[1]))
4478     {
4479       /* If it is unsafe to overwrite upper half of source, we need
4480          to move to destination and unpack there.  */
4481       if (REGNO (operands[0]) != REGNO (operands[1])
4482           || (EXT_REX_SSE_REG_P (operands[1])
4483               && !TARGET_AVX512VL))
4484         {
4485           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4486           emit_move_insn (tmp, operands[1]);
4487         }
4488       else
4489         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4490       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4491          =v, v, then vbroadcastss will be only needed for AVX512F without
4492          AVX512VL.  */
4493       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4494         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4495                                                operands[3]));
4496       else
4497         {
4498           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4499           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4500         }
4501     }
4502   else
4503     emit_insn (gen_vec_setv4sf_0 (operands[3],
4504                                   CONST0_RTX (V4SFmode), operands[1]));
4507 ;; It's more profitable to split and then extend in the same register.
4508 (define_peephole2
4509   [(set (match_operand:DF 0 "sse_reg_operand")
4510         (float_extend:DF
4511           (match_operand:SF 1 "memory_operand")))]
4512   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4513    && optimize_insn_for_speed_p ()"
4514   [(set (match_dup 2) (match_dup 1))
4515    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4516   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4518 (define_insn "*extendsfdf2"
4519   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4520         (float_extend:DF
4521           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4522   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4524   switch (which_alternative)
4525     {
4526     case 0:
4527     case 1:
4528       return output_387_reg_move (insn, operands);
4530     case 2:
4531       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4533     default:
4534       gcc_unreachable ();
4535     }
4537   [(set_attr "type" "fmov,fmov,ssecvt")
4538    (set_attr "prefix" "orig,orig,maybe_vex")
4539    (set_attr "mode" "SF,XF,DF")
4540    (set (attr "enabled")
4541      (if_then_else
4542        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4543        (if_then_else
4544          (eq_attr "alternative" "0,1")
4545          (symbol_ref "TARGET_MIX_SSE_I387")
4546          (symbol_ref "true"))
4547        (if_then_else
4548          (eq_attr "alternative" "0,1")
4549          (symbol_ref "true")
4550          (symbol_ref "false"))))])
4552 (define_expand "extend<mode>xf2"
4553   [(set (match_operand:XF 0 "nonimmediate_operand")
4554         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4555   "TARGET_80387"
4557   /* ??? Needed for compress_float_constant since all fp constants
4558      are TARGET_LEGITIMATE_CONSTANT_P.  */
4559   if (CONST_DOUBLE_P (operands[1]))
4560     {
4561       if (standard_80387_constant_p (operands[1]) > 0)
4562         {
4563           operands[1] = simplify_const_unary_operation
4564             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4565           emit_move_insn_1 (operands[0], operands[1]);
4566           DONE;
4567         }
4568       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4569     }
4572 (define_insn "*extend<mode>xf2_i387"
4573   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4574         (float_extend:XF
4575           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4576   "TARGET_80387"
4577   "* return output_387_reg_move (insn, operands);"
4578   [(set_attr "type" "fmov")
4579    (set_attr "mode" "<MODE>,XF")])
4581 ;; %%% This seems like bad news.
4582 ;; This cannot output into an f-reg because there is no way to be sure
4583 ;; of truncating in that case.  Otherwise this is just like a simple move
4584 ;; insn.  So we pretend we can output to a reg in order to get better
4585 ;; register preferencing, but we really use a stack slot.
4587 ;; Conversion from DFmode to SFmode.
4589 (define_expand "truncdfsf2"
4590   [(set (match_operand:SF 0 "nonimmediate_operand")
4591         (float_truncate:SF
4592           (match_operand:DF 1 "nonimmediate_operand")))]
4593   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4595   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4596     ;
4597   else if (flag_unsafe_math_optimizations)
4598     ;
4599   else
4600     {
4601       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4602       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4603       DONE;
4604     }
4607 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4608    cvtsd2ss:
4609       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4610       cvtpd2ps xmm2,xmm1
4611    We do the conversion post reload to avoid producing of 128bit spills
4612    that might lead to ICE on 32bit target.  The sequence unlikely combine
4613    anyway.  */
4614 (define_split
4615   [(set (match_operand:SF 0 "sse_reg_operand")
4616         (float_truncate:SF
4617           (match_operand:DF 1 "nonimmediate_operand")))]
4618   "TARGET_USE_VECTOR_FP_CONVERTS
4619    && optimize_insn_for_speed_p ()
4620    && reload_completed
4621    && (!EXT_REX_SSE_REG_P (operands[0])
4622        || TARGET_AVX512VL)"
4623    [(set (match_dup 2)
4624          (vec_concat:V4SF
4625            (float_truncate:V2SF
4626              (match_dup 4))
4627            (match_dup 3)))]
4629   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4630   operands[3] = CONST0_RTX (V2SFmode);
4631   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4632   /* Use movsd for loading from memory, unpcklpd for registers.
4633      Try to avoid move when unpacking can be done in source, or SSE3
4634      movddup is available.  */
4635   if (REG_P (operands[1]))
4636     {
4637       if (!TARGET_SSE3
4638           && REGNO (operands[0]) != REGNO (operands[1]))
4639         {
4640           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4641           emit_move_insn (tmp, operands[1]);
4642           operands[1] = tmp;
4643         }
4644       else if (!TARGET_SSE3)
4645         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4646       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4647     }
4648   else
4649     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4650                                    CONST0_RTX (DFmode)));
4653 ;; It's more profitable to split and then extend in the same register.
4654 (define_peephole2
4655   [(set (match_operand:SF 0 "sse_reg_operand")
4656         (float_truncate:SF
4657           (match_operand:DF 1 "memory_operand")))]
4658   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4659    && optimize_insn_for_speed_p ()"
4660   [(set (match_dup 2) (match_dup 1))
4661    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4662   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4664 (define_expand "truncdfsf2_with_temp"
4665   [(parallel [(set (match_operand:SF 0)
4666                    (float_truncate:SF (match_operand:DF 1)))
4667               (clobber (match_operand:SF 2))])])
4669 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4670 ;; because nothing we do there is unsafe.
4671 (define_insn "*truncdfsf_fast_mixed"
4672   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4673         (float_truncate:SF
4674           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4675   "TARGET_SSE2 && TARGET_SSE_MATH"
4677   switch (which_alternative)
4678     {
4679     case 0:
4680       return output_387_reg_move (insn, operands);
4681     case 1:
4682       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4683     default:
4684       gcc_unreachable ();
4685     }
4687   [(set_attr "type" "fmov,ssecvt")
4688    (set_attr "prefix" "orig,maybe_vex")
4689    (set_attr "mode" "SF")
4690    (set (attr "enabled")
4691      (cond [(eq_attr "alternative" "0")
4692               (symbol_ref "TARGET_MIX_SSE_I387
4693                            && flag_unsafe_math_optimizations")
4694            ]
4695            (symbol_ref "true")))])
4697 (define_insn "*truncdfsf_fast_i387"
4698   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4699         (float_truncate:SF
4700           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4701   "TARGET_80387 && flag_unsafe_math_optimizations"
4702   "* return output_387_reg_move (insn, operands);"
4703   [(set_attr "type" "fmov")
4704    (set_attr "mode" "SF")])
4706 (define_insn "*truncdfsf_mixed"
4707   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
4708         (float_truncate:SF
4709           (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4710    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4711   "TARGET_MIX_SSE_I387"
4713   switch (which_alternative)
4714     {
4715     case 0:
4716       return output_387_reg_move (insn, operands);
4717     case 1:
4718       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4720     default:
4721       return "#";
4722     }
4724   [(set_attr "isa" "*,sse2,*,*,*")
4725    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4726    (set_attr "unit" "*,*,i387,i387,i387")
4727    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4728    (set_attr "mode" "SF")])
4730 (define_insn "*truncdfsf_i387"
4731   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
4732         (float_truncate:SF
4733           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4734    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4735   "TARGET_80387"
4737   switch (which_alternative)
4738     {
4739     case 0:
4740       return output_387_reg_move (insn, operands);
4742     default:
4743       return "#";
4744     }
4746   [(set_attr "type" "fmov,multi,multi,multi")
4747    (set_attr "unit" "*,i387,i387,i387")
4748    (set_attr "mode" "SF")])
4750 (define_insn "*truncdfsf2_i387_1"
4751   [(set (match_operand:SF 0 "memory_operand" "=m")
4752         (float_truncate:SF
4753           (match_operand:DF 1 "register_operand" "f")))]
4754   "TARGET_80387
4755    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4756    && !TARGET_MIX_SSE_I387"
4757   "* return output_387_reg_move (insn, operands);"
4758   [(set_attr "type" "fmov")
4759    (set_attr "mode" "SF")])
4761 (define_split
4762   [(set (match_operand:SF 0 "register_operand")
4763         (float_truncate:SF
4764          (match_operand:DF 1 "fp_register_operand")))
4765    (clobber (match_operand 2))]
4766   "reload_completed"
4767   [(set (match_dup 2) (match_dup 1))
4768    (set (match_dup 0) (match_dup 2))]
4769   "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4771 ;; Conversion from XFmode to {SF,DF}mode
4773 (define_expand "truncxf<mode>2"
4774   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4775                    (float_truncate:MODEF
4776                      (match_operand:XF 1 "register_operand")))
4777               (clobber (match_dup 2))])]
4778   "TARGET_80387"
4780   if (flag_unsafe_math_optimizations)
4781     {
4782       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4783       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4784       if (reg != operands[0])
4785         emit_move_insn (operands[0], reg);
4786       DONE;
4787     }
4788   else
4789     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4792 (define_insn "*truncxfsf2_mixed"
4793   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4794         (float_truncate:SF
4795           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4796    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4797   "TARGET_80387"
4799   gcc_assert (!which_alternative);
4800   return output_387_reg_move (insn, operands);
4802   [(set_attr "type" "fmov,multi,multi,multi")
4803    (set_attr "unit" "*,i387,i387,i387")
4804    (set_attr "mode" "SF")])
4806 (define_insn "*truncxfdf2_mixed"
4807   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4808         (float_truncate:DF
4809           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4810    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4811   "TARGET_80387"
4813   gcc_assert (!which_alternative);
4814   return output_387_reg_move (insn, operands);
4816   [(set_attr "isa" "*,*,sse2,*")
4817    (set_attr "type" "fmov,multi,multi,multi")
4818    (set_attr "unit" "*,i387,i387,i387")
4819    (set_attr "mode" "DF")])
4821 (define_insn "truncxf<mode>2_i387_noop"
4822   [(set (match_operand:MODEF 0 "register_operand" "=f")
4823         (float_truncate:MODEF
4824           (match_operand:XF 1 "register_operand" "f")))]
4825   "TARGET_80387 && flag_unsafe_math_optimizations"
4826   "* return output_387_reg_move (insn, operands);"
4827   [(set_attr "type" "fmov")
4828    (set_attr "mode" "<MODE>")])
4830 (define_insn "*truncxf<mode>2_i387"
4831   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4832         (float_truncate:MODEF
4833           (match_operand:XF 1 "register_operand" "f")))]
4834   "TARGET_80387"
4835   "* return output_387_reg_move (insn, operands);"
4836   [(set_attr "type" "fmov")
4837    (set_attr "mode" "<MODE>")])
4839 (define_split
4840   [(set (match_operand:MODEF 0 "register_operand")
4841         (float_truncate:MODEF
4842           (match_operand:XF 1 "register_operand")))
4843    (clobber (match_operand:MODEF 2 "memory_operand"))]
4844   "TARGET_80387 && reload_completed"
4845   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4846    (set (match_dup 0) (match_dup 2))])
4848 (define_split
4849   [(set (match_operand:MODEF 0 "memory_operand")
4850         (float_truncate:MODEF
4851           (match_operand:XF 1 "register_operand")))
4852    (clobber (match_operand:MODEF 2 "memory_operand"))]
4853   "TARGET_80387"
4854   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4856 ;; Signed conversion to DImode.
4858 (define_expand "fix_truncxfdi2"
4859   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4860                    (fix:DI (match_operand:XF 1 "register_operand")))
4861               (clobber (reg:CC FLAGS_REG))])]
4862   "TARGET_80387"
4864   if (TARGET_FISTTP)
4865    {
4866      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4867      DONE;
4868    }
4871 (define_expand "fix_trunc<mode>di2"
4872   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4873                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4874               (clobber (reg:CC FLAGS_REG))])]
4875   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4877   if (TARGET_FISTTP
4878       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4879    {
4880      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4881      DONE;
4882    }
4883   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4884    {
4885      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4886      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4887      if (out != operands[0])
4888         emit_move_insn (operands[0], out);
4889      DONE;
4890    }
4893 ;; Signed conversion to SImode.
4895 (define_expand "fix_truncxfsi2"
4896   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4897                    (fix:SI (match_operand:XF 1 "register_operand")))
4898               (clobber (reg:CC FLAGS_REG))])]
4899   "TARGET_80387"
4901   if (TARGET_FISTTP)
4902    {
4903      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4904      DONE;
4905    }
4908 (define_expand "fix_trunc<mode>si2"
4909   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4910                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4911               (clobber (reg:CC FLAGS_REG))])]
4912   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4914   if (TARGET_FISTTP
4915       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4916    {
4917      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4918      DONE;
4919    }
4920   if (SSE_FLOAT_MODE_P (<MODE>mode))
4921    {
4922      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4923      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4924      if (out != operands[0])
4925         emit_move_insn (operands[0], out);
4926      DONE;
4927    }
4930 ;; Signed conversion to HImode.
4932 (define_expand "fix_trunc<mode>hi2"
4933   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4934                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4935               (clobber (reg:CC FLAGS_REG))])]
4936   "TARGET_80387
4937    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4939   if (TARGET_FISTTP)
4940    {
4941      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4942      DONE;
4943    }
4946 ;; Unsigned conversion to SImode.
4948 (define_expand "fixuns_trunc<mode>si2"
4949   [(parallel
4950     [(set (match_operand:SI 0 "register_operand")
4951           (unsigned_fix:SI
4952             (match_operand:MODEF 1 "nonimmediate_operand")))
4953      (use (match_dup 2))
4954      (clobber (match_scratch:<ssevecmode> 3))
4955      (clobber (match_scratch:<ssevecmode> 4))])]
4956   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4958   machine_mode mode = <MODE>mode;
4959   machine_mode vecmode = <ssevecmode>mode;
4960   REAL_VALUE_TYPE TWO31r;
4961   rtx two31;
4963   if (optimize_insn_for_size_p ())
4964     FAIL;
4966   real_ldexp (&TWO31r, &dconst1, 31);
4967   two31 = const_double_from_real_value (TWO31r, mode);
4968   two31 = ix86_build_const_vector (vecmode, true, two31);
4969   operands[2] = force_reg (vecmode, two31);
4972 (define_insn_and_split "*fixuns_trunc<mode>_1"
4973   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4974         (unsigned_fix:SI
4975           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4976    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4977    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4978    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4979   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4980    && optimize_function_for_speed_p (cfun)"
4981   "#"
4982   "&& reload_completed"
4983   [(const_int 0)]
4985   ix86_split_convert_uns_si_sse (operands);
4986   DONE;
4989 ;; Unsigned conversion to HImode.
4990 ;; Without these patterns, we'll try the unsigned SI conversion which
4991 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4993 (define_expand "fixuns_trunc<mode>hi2"
4994   [(set (match_dup 2)
4995         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4996    (set (match_operand:HI 0 "nonimmediate_operand")
4997         (subreg:HI (match_dup 2) 0))]
4998   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4999   "operands[2] = gen_reg_rtx (SImode);")
5001 ;; When SSE is available, it is always faster to use it!
5002 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5003   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5004         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5005   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5006    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5007   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5008   [(set_attr "type" "sseicvt")
5009    (set_attr "prefix" "maybe_vex")
5010    (set (attr "prefix_rex")
5011         (if_then_else
5012           (match_test "<SWI48:MODE>mode == DImode")
5013           (const_string "1")
5014           (const_string "*")))
5015    (set_attr "mode" "<MODEF:MODE>")
5016    (set_attr "athlon_decode" "double,vector")
5017    (set_attr "amdfam10_decode" "double,double")
5018    (set_attr "bdver1_decode" "double,double")])
5020 ;; Avoid vector decoded forms of the instruction.
5021 (define_peephole2
5022   [(match_scratch:MODEF 2 "x")
5023    (set (match_operand:SWI48 0 "register_operand")
5024         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5025   "TARGET_AVOID_VECTOR_DECODE
5026    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5027    && optimize_insn_for_speed_p ()"
5028   [(set (match_dup 2) (match_dup 1))
5029    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5031 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5032   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5033         (fix:SWI248x (match_operand 1 "register_operand")))]
5034   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5035    && TARGET_FISTTP
5036    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5037          && (TARGET_64BIT || <MODE>mode != DImode))
5038         && TARGET_SSE_MATH)
5039    && can_create_pseudo_p ()"
5040   "#"
5041   "&& 1"
5042   [(const_int 0)]
5044   if (memory_operand (operands[0], VOIDmode))
5045     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5046   else
5047     {
5048       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5049       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5050                                                             operands[1],
5051                                                             operands[2]));
5052     }
5053   DONE;
5055   [(set_attr "type" "fisttp")
5056    (set_attr "mode" "<MODE>")])
5058 (define_insn "fix_trunc<mode>_i387_fisttp"
5059   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5060         (fix:SWI248x (match_operand 1 "register_operand" "f")))
5061    (clobber (match_scratch:XF 2 "=&1f"))]
5062   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5063    && TARGET_FISTTP
5064    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5065          && (TARGET_64BIT || <MODE>mode != DImode))
5066         && TARGET_SSE_MATH)"
5067   "* return output_fix_trunc (insn, operands, true);"
5068   [(set_attr "type" "fisttp")
5069    (set_attr "mode" "<MODE>")])
5071 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5072   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5073         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5074    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5075    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5076   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5077    && TARGET_FISTTP
5078    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5079         && (TARGET_64BIT || <MODE>mode != DImode))
5080         && TARGET_SSE_MATH)"
5081   "#"
5082   [(set_attr "type" "fisttp")
5083    (set_attr "mode" "<MODE>")])
5085 (define_split
5086   [(set (match_operand:SWI248x 0 "register_operand")
5087         (fix:SWI248x (match_operand 1 "register_operand")))
5088    (clobber (match_operand:SWI248x 2 "memory_operand"))
5089    (clobber (match_scratch 3))]
5090   "reload_completed"
5091   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5092               (clobber (match_dup 3))])
5093    (set (match_dup 0) (match_dup 2))])
5095 (define_split
5096   [(set (match_operand:SWI248x 0 "memory_operand")
5097         (fix:SWI248x (match_operand 1 "register_operand")))
5098    (clobber (match_operand:SWI248x 2 "memory_operand"))
5099    (clobber (match_scratch 3))]
5100   "reload_completed"
5101   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5102               (clobber (match_dup 3))])])
5104 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5105 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5106 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5107 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5108 ;; function in i386.c.
5109 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5110   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5111         (fix:SWI248x (match_operand 1 "register_operand")))
5112    (clobber (reg:CC FLAGS_REG))]
5113   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5114    && !TARGET_FISTTP
5115    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5116          && (TARGET_64BIT || <MODE>mode != DImode))
5117    && can_create_pseudo_p ()"
5118   "#"
5119   "&& 1"
5120   [(const_int 0)]
5122   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5124   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5125   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5126   if (memory_operand (operands[0], VOIDmode))
5127     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5128                                          operands[2], operands[3]));
5129   else
5130     {
5131       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5132       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5133                                                      operands[2], operands[3],
5134                                                      operands[4]));
5135     }
5136   DONE;
5138   [(set_attr "type" "fistp")
5139    (set_attr "i387_cw" "trunc")
5140    (set_attr "mode" "<MODE>")])
5142 (define_insn "fix_truncdi_i387"
5143   [(set (match_operand:DI 0 "memory_operand" "=m")
5144         (fix:DI (match_operand 1 "register_operand" "f")))
5145    (use (match_operand:HI 2 "memory_operand" "m"))
5146    (use (match_operand:HI 3 "memory_operand" "m"))
5147    (clobber (match_scratch:XF 4 "=&1f"))]
5148   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5149    && !TARGET_FISTTP
5150    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5151   "* return output_fix_trunc (insn, operands, false);"
5152   [(set_attr "type" "fistp")
5153    (set_attr "i387_cw" "trunc")
5154    (set_attr "mode" "DI")])
5156 (define_insn "fix_truncdi_i387_with_temp"
5157   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5158         (fix:DI (match_operand 1 "register_operand" "f,f")))
5159    (use (match_operand:HI 2 "memory_operand" "m,m"))
5160    (use (match_operand:HI 3 "memory_operand" "m,m"))
5161    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5162    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5163   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5164    && !TARGET_FISTTP
5165    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5166   "#"
5167   [(set_attr "type" "fistp")
5168    (set_attr "i387_cw" "trunc")
5169    (set_attr "mode" "DI")])
5171 (define_split
5172   [(set (match_operand:DI 0 "register_operand")
5173         (fix:DI (match_operand 1 "register_operand")))
5174    (use (match_operand:HI 2 "memory_operand"))
5175    (use (match_operand:HI 3 "memory_operand"))
5176    (clobber (match_operand:DI 4 "memory_operand"))
5177    (clobber (match_scratch 5))]
5178   "reload_completed"
5179   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5180               (use (match_dup 2))
5181               (use (match_dup 3))
5182               (clobber (match_dup 5))])
5183    (set (match_dup 0) (match_dup 4))])
5185 (define_split
5186   [(set (match_operand:DI 0 "memory_operand")
5187         (fix:DI (match_operand 1 "register_operand")))
5188    (use (match_operand:HI 2 "memory_operand"))
5189    (use (match_operand:HI 3 "memory_operand"))
5190    (clobber (match_operand:DI 4 "memory_operand"))
5191    (clobber (match_scratch 5))]
5192   "reload_completed"
5193   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5194               (use (match_dup 2))
5195               (use (match_dup 3))
5196               (clobber (match_dup 5))])])
5198 (define_insn "fix_trunc<mode>_i387"
5199   [(set (match_operand:SWI24 0 "memory_operand" "=m")
5200         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5201    (use (match_operand:HI 2 "memory_operand" "m"))
5202    (use (match_operand:HI 3 "memory_operand" "m"))]
5203   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5204    && !TARGET_FISTTP
5205    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5206   "* return output_fix_trunc (insn, operands, false);"
5207   [(set_attr "type" "fistp")
5208    (set_attr "i387_cw" "trunc")
5209    (set_attr "mode" "<MODE>")])
5211 (define_insn "fix_trunc<mode>_i387_with_temp"
5212   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5213         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5214    (use (match_operand:HI 2 "memory_operand" "m,m"))
5215    (use (match_operand:HI 3 "memory_operand" "m,m"))
5216    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5217   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5218    && !TARGET_FISTTP
5219    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5220   "#"
5221   [(set_attr "type" "fistp")
5222    (set_attr "i387_cw" "trunc")
5223    (set_attr "mode" "<MODE>")])
5225 (define_split
5226   [(set (match_operand:SWI24 0 "register_operand")
5227         (fix:SWI24 (match_operand 1 "register_operand")))
5228    (use (match_operand:HI 2 "memory_operand"))
5229    (use (match_operand:HI 3 "memory_operand"))
5230    (clobber (match_operand:SWI24 4 "memory_operand"))]
5231   "reload_completed"
5232   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5233               (use (match_dup 2))
5234               (use (match_dup 3))])
5235    (set (match_dup 0) (match_dup 4))])
5237 (define_split
5238   [(set (match_operand:SWI24 0 "memory_operand")
5239         (fix:SWI24 (match_operand 1 "register_operand")))
5240    (use (match_operand:HI 2 "memory_operand"))
5241    (use (match_operand:HI 3 "memory_operand"))
5242    (clobber (match_operand:SWI24 4 "memory_operand"))]
5243   "reload_completed"
5244   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5245               (use (match_dup 2))
5246               (use (match_dup 3))])])
5248 (define_insn "x86_fnstcw_1"
5249   [(set (match_operand:HI 0 "memory_operand" "=m")
5250         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5251   "TARGET_80387"
5252   "fnstcw\t%0"
5253   [(set (attr "length")
5254         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5255    (set_attr "mode" "HI")
5256    (set_attr "unit" "i387")
5257    (set_attr "bdver1_decode" "vector")])
5259 (define_insn "x86_fldcw_1"
5260   [(set (reg:HI FPCR_REG)
5261         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5262   "TARGET_80387"
5263   "fldcw\t%0"
5264   [(set (attr "length")
5265         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5266    (set_attr "mode" "HI")
5267    (set_attr "unit" "i387")
5268    (set_attr "athlon_decode" "vector")
5269    (set_attr "amdfam10_decode" "vector")
5270    (set_attr "bdver1_decode" "vector")])
5272 ;; Conversion between fixed point and floating point.
5274 ;; Even though we only accept memory inputs, the backend _really_
5275 ;; wants to be able to do this between registers.  Thankfully, LRA
5276 ;; will fix this up for us during register allocation.
5278 (define_insn "floathi<mode>2"
5279   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5280         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5281   "TARGET_80387
5282    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5283        || TARGET_MIX_SSE_I387)"
5284   "fild%Z1\t%1"
5285   [(set_attr "type" "fmov")
5286    (set_attr "mode" "<MODE>")
5287    (set_attr "znver1_decode" "double")
5288    (set_attr "fp_int_src" "true")])
5290 (define_insn "float<SWI48x:mode>xf2"
5291   [(set (match_operand:XF 0 "register_operand" "=f")
5292         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5293   "TARGET_80387"
5294   "fild%Z1\t%1"
5295   [(set_attr "type" "fmov")
5296    (set_attr "mode" "XF")
5297    (set_attr "znver1_decode" "double")
5298    (set_attr "fp_int_src" "true")])
5300 (define_expand "float<SWI48:mode><MODEF:mode>2"
5301   [(set (match_operand:MODEF 0 "register_operand")
5302         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5303   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5305   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5306       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5307     {
5308       rtx reg = gen_reg_rtx (XFmode);
5309       rtx (*insn)(rtx, rtx);
5311       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5313       if (<MODEF:MODE>mode == SFmode)
5314         insn = gen_truncxfsf2;
5315       else if (<MODEF:MODE>mode == DFmode)
5316         insn = gen_truncxfdf2;
5317       else
5318         gcc_unreachable ();
5320       emit_insn (insn (operands[0], reg));
5321       DONE;
5322     }
5325 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5326   [(set (match_operand:MODEF 0 "register_operand" "=f,Yc,v")
5327         (float:MODEF
5328           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5329   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5330   "@
5331    fild%Z1\t%1
5332    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5333    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5334   [(set_attr "type" "fmov,sseicvt,sseicvt")
5335    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5336    (set_attr "mode" "<MODEF:MODE>")
5337    (set (attr "prefix_rex")
5338      (if_then_else
5339        (and (eq_attr "prefix" "maybe_vex")
5340             (match_test "<SWI48:MODE>mode == DImode"))
5341        (const_string "1")
5342        (const_string "*")))
5343    (set_attr "unit" "i387,*,*")
5344    (set_attr "athlon_decode" "*,double,direct")
5345    (set_attr "amdfam10_decode" "*,vector,double")
5346    (set_attr "bdver1_decode" "*,double,direct")
5347    (set_attr "znver1_decode" "double,*,*")
5348    (set_attr "fp_int_src" "true")
5349    (set (attr "enabled")
5350      (cond [(eq_attr "alternative" "0")
5351               (symbol_ref "TARGET_MIX_SSE_I387
5352                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5353                                                 <SWI48:MODE>mode)")
5354            ]
5355            (symbol_ref "true")))])
5357 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5358   [(set (match_operand:MODEF 0 "register_operand" "=f")
5359         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5360   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5361   "fild%Z1\t%1"
5362   [(set_attr "type" "fmov")
5363    (set_attr "mode" "<MODEF:MODE>")
5364    (set_attr "znver1_decode" "double")
5365    (set_attr "fp_int_src" "true")])
5367 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5368 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5369 ;; alternative in sse2_loadld.
5370 (define_split
5371   [(set (match_operand:MODEF 0 "sse_reg_operand")
5372         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5373   "TARGET_SSE2
5374    && TARGET_USE_VECTOR_CONVERTS
5375    && optimize_function_for_speed_p (cfun)
5376    && reload_completed
5377    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5378    && (!EXT_REX_SSE_REG_P (operands[0])
5379        || TARGET_AVX512VL)"
5380   [(const_int 0)]
5382   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5383   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5385   emit_insn (gen_sse2_loadld (operands[4],
5386                               CONST0_RTX (V4SImode), operands[1]));
5388   if (<ssevecmode>mode == V4SFmode)
5389     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5390   else
5391     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5392   DONE;
5395 ;; Avoid partial SSE register dependency stalls.  This splitter should split
5396 ;; late in the pass sequence (after register rename pass), so allocated
5397 ;; registers won't change anymore
5399 (define_split
5400   [(set (match_operand:MODEF 0 "sse_reg_operand")
5401         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5402   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5403    && optimize_function_for_speed_p (cfun)
5404    && (!EXT_REX_SSE_REG_P (operands[0])
5405        || TARGET_AVX512VL)"
5406   [(set (match_dup 0)
5407         (vec_merge:<MODEF:ssevecmode>
5408           (vec_duplicate:<MODEF:ssevecmode>
5409             (float:MODEF
5410               (match_dup 1)))
5411           (match_dup 0)
5412           (const_int 1)))]
5414   const machine_mode vmode = <MODEF:ssevecmode>mode;
5416   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5417   emit_move_insn (operands[0], CONST0_RTX (vmode));
5420 ;; Break partial reg stall for cvtsd2ss.  This splitter should split
5421 ;; late in the pass sequence (after register rename pass),
5422 ;; so allocated registers won't change anymore.
5424 (define_split
5425   [(set (match_operand:SF 0 "sse_reg_operand")
5426         (float_truncate:SF
5427           (match_operand:DF 1 "nonimmediate_operand")))]
5428   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5429    && optimize_function_for_speed_p (cfun)
5430    && (!REG_P (operands[1])
5431        || REGNO (operands[0]) != REGNO (operands[1]))
5432    && (!EXT_REX_SSE_REG_P (operands[0])
5433        || TARGET_AVX512VL)"
5434   [(set (match_dup 0)
5435         (vec_merge:V4SF
5436           (vec_duplicate:V4SF
5437             (float_truncate:SF
5438               (match_dup 1)))
5439           (match_dup 0)
5440           (const_int 1)))]
5442   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5443   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5446 ;; Break partial reg stall for cvtss2sd.  This splitter should split
5447 ;; late in the pass sequence (after register rename pass),
5448 ;; so allocated registers won't change anymore.
5450 (define_split
5451   [(set (match_operand:DF 0 "sse_reg_operand")
5452         (float_extend:DF
5453           (match_operand:SF 1 "nonimmediate_operand")))]
5454   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5455    && optimize_function_for_speed_p (cfun)
5456    && (!REG_P (operands[1])
5457        || REGNO (operands[0]) != REGNO (operands[1]))
5458    && (!EXT_REX_SSE_REG_P (operands[0])
5459        || TARGET_AVX512VL)"
5460   [(set (match_dup 0)
5461         (vec_merge:V2DF
5462           (vec_duplicate:V2DF
5463             (float_extend:DF
5464               (match_dup 1)))
5465           (match_dup 0)
5466           (const_int 1)))]
5468   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5469   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5472 ;; Avoid store forwarding (partial memory) stall penalty
5473 ;; by passing DImode value through XMM registers.  */
5475 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5476   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5477         (float:X87MODEF
5478           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5479    (clobber (match_scratch:V4SI 3 "=X,x"))
5480    (clobber (match_scratch:V4SI 4 "=X,x"))
5481    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5482   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5483    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5484    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5485   "#"
5486   [(set_attr "type" "multi")
5487    (set_attr "mode" "<X87MODEF:MODE>")
5488    (set_attr "unit" "i387")
5489    (set_attr "fp_int_src" "true")])
5491 (define_split
5492   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5493         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5494    (clobber (match_scratch:V4SI 3))
5495    (clobber (match_scratch:V4SI 4))
5496    (clobber (match_operand:DI 2 "memory_operand"))]
5497   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5498    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5499    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5500    && reload_completed"
5501   [(set (match_dup 2) (match_dup 3))
5502    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5504   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5505      Assemble the 64-bit DImode value in an xmm register.  */
5506   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5507                               gen_lowpart (SImode, operands[1])));
5508   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5509                               gen_highpart (SImode, operands[1])));
5510   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5511                                          operands[4]));
5513   operands[3] = gen_lowpart (DImode, operands[3]);
5516 (define_split
5517   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5518         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5519    (clobber (match_scratch:V4SI 3))
5520    (clobber (match_scratch:V4SI 4))
5521    (clobber (match_operand:DI 2 "memory_operand"))]
5522   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5523    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5524    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5525    && reload_completed"
5526   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5528 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5529   [(set (match_operand:MODEF 0 "register_operand")
5530         (unsigned_float:MODEF
5531           (match_operand:SWI12 1 "nonimmediate_operand")))]
5532   "!TARGET_64BIT
5533    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5535   operands[1] = convert_to_mode (SImode, operands[1], 1);
5536   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5537   DONE;
5540 ;; Avoid store forwarding (partial memory) stall penalty by extending
5541 ;; SImode value to DImode through XMM register instead of pushing two
5542 ;; SImode values to stack. Also note that fild loads from memory only.
5544 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5545   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5546         (unsigned_float:X87MODEF
5547           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5548    (clobber (match_scratch:DI 3 "=x"))
5549    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5550   "!TARGET_64BIT
5551    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5552    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5553   "#"
5554   "&& reload_completed"
5555   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5556    (set (match_dup 2) (match_dup 3))
5557    (set (match_dup 0)
5558         (float:X87MODEF (match_dup 2)))]
5559   ""
5560   [(set_attr "type" "multi")
5561    (set_attr "mode" "<MODE>")])
5563 (define_expand "floatunssi<mode>2"
5564   [(parallel
5565      [(set (match_operand:X87MODEF 0 "register_operand")
5566            (unsigned_float:X87MODEF
5567              (match_operand:SI 1 "nonimmediate_operand")))
5568       (clobber (match_scratch:DI 3))
5569       (clobber (match_dup 2))])]
5570   "!TARGET_64BIT
5571    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5572         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5573        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5575   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5576     {
5577       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5578       DONE;
5579     }
5580   else
5581     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5584 (define_expand "floatunsdisf2"
5585   [(use (match_operand:SF 0 "register_operand"))
5586    (use (match_operand:DI 1 "nonimmediate_operand"))]
5587   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5588   "x86_emit_floatuns (operands); DONE;")
5590 (define_expand "floatunsdidf2"
5591   [(use (match_operand:DF 0 "register_operand"))
5592    (use (match_operand:DI 1 "nonimmediate_operand"))]
5593   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5594    && TARGET_SSE2 && TARGET_SSE_MATH"
5596   if (TARGET_64BIT)
5597     x86_emit_floatuns (operands);
5598   else
5599     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5600   DONE;
5603 ;; Load effective address instructions
5605 (define_insn_and_split "*lea<mode>"
5606   [(set (match_operand:SWI48 0 "register_operand" "=r")
5607         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5608   ""
5610   if (SImode_address_operand (operands[1], VOIDmode))
5611     {
5612       gcc_assert (TARGET_64BIT);
5613       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5614     }
5615   else 
5616     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5618   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5619   [(const_int 0)]
5621   machine_mode mode = <MODE>mode;
5622   rtx pat;
5624   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5625      change operands[] array behind our back.  */
5626   pat = PATTERN (curr_insn);
5628   operands[0] = SET_DEST (pat);
5629   operands[1] = SET_SRC (pat);
5631   /* Emit all operations in SImode for zero-extended addresses.  */
5632   if (SImode_address_operand (operands[1], VOIDmode))
5633     mode = SImode;
5635   ix86_split_lea_for_addr (curr_insn, operands, mode);
5637   /* Zero-extend return register to DImode for zero-extended addresses.  */
5638   if (mode != <MODE>mode)
5639     emit_insn (gen_zero_extendsidi2
5640                (operands[0], gen_lowpart (mode, operands[0])));
5642   DONE;
5644   [(set_attr "type" "lea")
5645    (set (attr "mode")
5646      (if_then_else
5647        (match_operand 1 "SImode_address_operand")
5648        (const_string "SI")
5649        (const_string "<MODE>")))])
5651 ;; Add instructions
5653 (define_expand "add<mode>3"
5654   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5655         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5656                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5657   ""
5658   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5660 (define_insn_and_split "*add<dwi>3_doubleword"
5661   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5662         (plus:<DWI>
5663           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5664           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5665                                                         "ro<di>,r<di>")))
5666    (clobber (reg:CC FLAGS_REG))]
5667   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5668   "#"
5669   "reload_completed"
5670   [(parallel [(set (reg:CCC FLAGS_REG)
5671                    (compare:CCC
5672                      (plus:DWIH (match_dup 1) (match_dup 2))
5673                      (match_dup 1)))
5674               (set (match_dup 0)
5675                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5676    (parallel [(set (match_dup 3)
5677                    (plus:DWIH
5678                      (plus:DWIH
5679                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5680                        (match_dup 4))
5681                      (match_dup 5)))
5682               (clobber (reg:CC FLAGS_REG))])]
5684   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5685   if (operands[2] == const0_rtx)
5686     {
5687       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5688       DONE;
5689     }
5692 (define_insn "*add<mode>_1"
5693   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5694         (plus:SWI48
5695           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5696           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5697    (clobber (reg:CC FLAGS_REG))]
5698   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5700   switch (get_attr_type (insn))
5701     {
5702     case TYPE_LEA:
5703       return "#";
5705     case TYPE_INCDEC:
5706       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5707       if (operands[2] == const1_rtx)
5708         return "inc{<imodesuffix>}\t%0";
5709       else
5710         {
5711           gcc_assert (operands[2] == constm1_rtx);
5712           return "dec{<imodesuffix>}\t%0";
5713         }
5715     default:
5716       /* For most processors, ADD is faster than LEA.  This alternative
5717          was added to use ADD as much as possible.  */
5718       if (which_alternative == 2)
5719         std::swap (operands[1], operands[2]);
5720         
5721       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5722       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5723         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5725       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5726     }
5728   [(set (attr "type")
5729      (cond [(eq_attr "alternative" "3")
5730               (const_string "lea")
5731             (match_operand:SWI48 2 "incdec_operand")
5732               (const_string "incdec")
5733            ]
5734            (const_string "alu")))
5735    (set (attr "length_immediate")
5736       (if_then_else
5737         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5738         (const_string "1")
5739         (const_string "*")))
5740    (set_attr "mode" "<MODE>")])
5742 ;; It may seem that nonimmediate operand is proper one for operand 1.
5743 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5744 ;; we take care in ix86_binary_operator_ok to not allow two memory
5745 ;; operands so proper swapping will be done in reload.  This allow
5746 ;; patterns constructed from addsi_1 to match.
5748 (define_insn "addsi_1_zext"
5749   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5750         (zero_extend:DI
5751           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5752                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5753    (clobber (reg:CC FLAGS_REG))]
5754   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5756   switch (get_attr_type (insn))
5757     {
5758     case TYPE_LEA:
5759       return "#";
5761     case TYPE_INCDEC:
5762       if (operands[2] == const1_rtx)
5763         return "inc{l}\t%k0";
5764       else
5765         {
5766           gcc_assert (operands[2] == constm1_rtx);
5767           return "dec{l}\t%k0";
5768         }
5770     default:
5771       /* For most processors, ADD is faster than LEA.  This alternative
5772          was added to use ADD as much as possible.  */
5773       if (which_alternative == 1)
5774         std::swap (operands[1], operands[2]);
5776       if (x86_maybe_negate_const_int (&operands[2], SImode))
5777         return "sub{l}\t{%2, %k0|%k0, %2}";
5779       return "add{l}\t{%2, %k0|%k0, %2}";
5780     }
5782   [(set (attr "type")
5783      (cond [(eq_attr "alternative" "2")
5784               (const_string "lea")
5785             (match_operand:SI 2 "incdec_operand")
5786               (const_string "incdec")
5787            ]
5788            (const_string "alu")))
5789    (set (attr "length_immediate")
5790       (if_then_else
5791         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5792         (const_string "1")
5793         (const_string "*")))
5794    (set_attr "mode" "SI")])
5796 (define_insn "*addhi_1"
5797   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5798         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5799                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5800    (clobber (reg:CC FLAGS_REG))]
5801   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5803   switch (get_attr_type (insn))
5804     {
5805     case TYPE_LEA:
5806       return "#";
5808     case TYPE_INCDEC:
5809       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5810       if (operands[2] == const1_rtx)
5811         return "inc{w}\t%0";
5812       else
5813         {
5814           gcc_assert (operands[2] == constm1_rtx);
5815           return "dec{w}\t%0";
5816         }
5818     default:
5819       /* For most processors, ADD is faster than LEA.  This alternative
5820          was added to use ADD as much as possible.  */
5821       if (which_alternative == 2)
5822         std::swap (operands[1], operands[2]);
5824       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5825       if (x86_maybe_negate_const_int (&operands[2], HImode))
5826         return "sub{w}\t{%2, %0|%0, %2}";
5828       return "add{w}\t{%2, %0|%0, %2}";
5829     }
5831   [(set (attr "type")
5832      (cond [(eq_attr "alternative" "3")
5833               (const_string "lea")
5834             (match_operand:HI 2 "incdec_operand")
5835               (const_string "incdec")
5836            ]
5837            (const_string "alu")))
5838    (set (attr "length_immediate")
5839       (if_then_else
5840         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5841         (const_string "1")
5842         (const_string "*")))
5843    (set_attr "mode" "HI,HI,HI,SI")])
5845 (define_insn "*addqi_1"
5846   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5847         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5848                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5849    (clobber (reg:CC FLAGS_REG))]
5850   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5852   bool widen = (get_attr_mode (insn) != MODE_QI);
5854   switch (get_attr_type (insn))
5855     {
5856     case TYPE_LEA:
5857       return "#";
5859     case TYPE_INCDEC:
5860       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5861       if (operands[2] == const1_rtx)
5862         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5863       else
5864         {
5865           gcc_assert (operands[2] == constm1_rtx);
5866           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5867         }
5869     default:
5870       /* For most processors, ADD is faster than LEA.  These alternatives
5871          were added to use ADD as much as possible.  */
5872       if (which_alternative == 2 || which_alternative == 4)
5873         std::swap (operands[1], operands[2]);
5875       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5876       if (x86_maybe_negate_const_int (&operands[2], QImode))
5877         {
5878           if (widen)
5879             return "sub{l}\t{%2, %k0|%k0, %2}";
5880           else
5881             return "sub{b}\t{%2, %0|%0, %2}";
5882         }
5883       if (widen)
5884         return "add{l}\t{%k2, %k0|%k0, %k2}";
5885       else
5886         return "add{b}\t{%2, %0|%0, %2}";
5887     }
5889   [(set (attr "type")
5890      (cond [(eq_attr "alternative" "5")
5891               (const_string "lea")
5892             (match_operand:QI 2 "incdec_operand")
5893               (const_string "incdec")
5894            ]
5895            (const_string "alu")))
5896    (set (attr "length_immediate")
5897       (if_then_else
5898         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5899         (const_string "1")
5900         (const_string "*")))
5901    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5902    ;; Potential partial reg stall on alternatives 3 and 4.
5903    (set (attr "preferred_for_speed")
5904      (cond [(eq_attr "alternative" "3,4")
5905               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5906            (symbol_ref "true")))])
5908 (define_insn "*addqi_1_slp"
5909   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5910         (plus:QI (match_dup 0)
5911                  (match_operand:QI 1 "general_operand" "qn,qm")))
5912    (clobber (reg:CC FLAGS_REG))]
5913   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5914    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5916   switch (get_attr_type (insn))
5917     {
5918     case TYPE_INCDEC:
5919       if (operands[1] == const1_rtx)
5920         return "inc{b}\t%0";
5921       else
5922         {
5923           gcc_assert (operands[1] == constm1_rtx);
5924           return "dec{b}\t%0";
5925         }
5927     default:
5928       if (x86_maybe_negate_const_int (&operands[1], QImode))
5929         return "sub{b}\t{%1, %0|%0, %1}";
5931       return "add{b}\t{%1, %0|%0, %1}";
5932     }
5934   [(set (attr "type")
5935      (if_then_else (match_operand:QI 1 "incdec_operand")
5936         (const_string "incdec")
5937         (const_string "alu1")))
5938    (set (attr "memory")
5939      (if_then_else (match_operand 1 "memory_operand")
5940         (const_string "load")
5941         (const_string "none")))
5942    (set_attr "mode" "QI")])
5944 ;; Split non destructive adds if we cannot use lea.
5945 (define_split
5946   [(set (match_operand:SWI48 0 "register_operand")
5947         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5948                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5949    (clobber (reg:CC FLAGS_REG))]
5950   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5951   [(set (match_dup 0) (match_dup 1))
5952    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5953               (clobber (reg:CC FLAGS_REG))])])
5955 ;; Split non destructive adds if we cannot use lea.
5956 (define_split
5957   [(set (match_operand:DI 0 "register_operand")
5958         (zero_extend:DI
5959           (plus:SI (match_operand:SI 1 "register_operand")
5960                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5961    (clobber (reg:CC FLAGS_REG))]
5962   "TARGET_64BIT
5963    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5964   [(set (match_dup 3) (match_dup 1))
5965    (parallel [(set (match_dup 0)
5966                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5967               (clobber (reg:CC FLAGS_REG))])]
5968   "operands[3] = gen_lowpart (SImode, operands[0]);")
5970 ;; Convert add to the lea pattern to avoid flags dependency.
5971 (define_split
5972   [(set (match_operand:SWI 0 "register_operand")
5973         (plus:SWI (match_operand:SWI 1 "register_operand")
5974                   (match_operand:SWI 2 "<nonmemory_operand>")))
5975    (clobber (reg:CC FLAGS_REG))]
5976   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5977   [(set (match_dup 0)
5978         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5980   if (<MODE>mode != <LEAMODE>mode)
5981     {
5982       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5983       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5984       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5985     }
5988 ;; Convert add to the lea pattern to avoid flags dependency.
5989 (define_split
5990   [(set (match_operand:DI 0 "register_operand")
5991         (zero_extend:DI
5992           (plus:SI (match_operand:SI 1 "register_operand")
5993                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5994    (clobber (reg:CC FLAGS_REG))]
5995   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5996   [(set (match_dup 0)
5997         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5999 (define_insn "*add<mode>_2"
6000   [(set (reg FLAGS_REG)
6001         (compare
6002           (plus:SWI
6003             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6004             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6005           (const_int 0)))
6006    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6007         (plus:SWI (match_dup 1) (match_dup 2)))]
6008   "ix86_match_ccmode (insn, CCGOCmode)
6009    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6011   switch (get_attr_type (insn))
6012     {
6013     case TYPE_INCDEC:
6014       if (operands[2] == const1_rtx)
6015         return "inc{<imodesuffix>}\t%0";
6016       else
6017         {
6018           gcc_assert (operands[2] == constm1_rtx);
6019           return "dec{<imodesuffix>}\t%0";
6020         }
6022     default:
6023       if (which_alternative == 2)
6024         std::swap (operands[1], operands[2]);
6025         
6026       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6027       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6028         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6030       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6031     }
6033   [(set (attr "type")
6034      (if_then_else (match_operand:SWI 2 "incdec_operand")
6035         (const_string "incdec")
6036         (const_string "alu")))
6037    (set (attr "length_immediate")
6038       (if_then_else
6039         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6040         (const_string "1")
6041         (const_string "*")))
6042    (set_attr "mode" "<MODE>")])
6044 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6045 (define_insn "*addsi_2_zext"
6046   [(set (reg FLAGS_REG)
6047         (compare
6048           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6049                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6050           (const_int 0)))
6051    (set (match_operand:DI 0 "register_operand" "=r,r")
6052         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6053   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6054    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6056   switch (get_attr_type (insn))
6057     {
6058     case TYPE_INCDEC:
6059       if (operands[2] == const1_rtx)
6060         return "inc{l}\t%k0";
6061       else
6062         {
6063           gcc_assert (operands[2] == constm1_rtx);
6064           return "dec{l}\t%k0";
6065         }
6067     default:
6068       if (which_alternative == 1)
6069         std::swap (operands[1], operands[2]);
6071       if (x86_maybe_negate_const_int (&operands[2], SImode))
6072         return "sub{l}\t{%2, %k0|%k0, %2}";
6074       return "add{l}\t{%2, %k0|%k0, %2}";
6075     }
6077   [(set (attr "type")
6078      (if_then_else (match_operand:SI 2 "incdec_operand")
6079         (const_string "incdec")
6080         (const_string "alu")))
6081    (set (attr "length_immediate")
6082       (if_then_else
6083         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6084         (const_string "1")
6085         (const_string "*")))
6086    (set_attr "mode" "SI")])
6088 (define_insn "*add<mode>_3"
6089   [(set (reg FLAGS_REG)
6090         (compare
6091           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6092           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6093    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6094   "ix86_match_ccmode (insn, CCZmode)
6095    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6097   switch (get_attr_type (insn))
6098     {
6099     case TYPE_INCDEC:
6100       if (operands[2] == const1_rtx)
6101         return "inc{<imodesuffix>}\t%0";
6102       else
6103         {
6104           gcc_assert (operands[2] == constm1_rtx);
6105           return "dec{<imodesuffix>}\t%0";
6106         }
6108     default:
6109       if (which_alternative == 1)
6110         std::swap (operands[1], operands[2]);
6112       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6113       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6114         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6116       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6117     }
6119   [(set (attr "type")
6120      (if_then_else (match_operand:SWI 2 "incdec_operand")
6121         (const_string "incdec")
6122         (const_string "alu")))
6123    (set (attr "length_immediate")
6124       (if_then_else
6125         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6126         (const_string "1")
6127         (const_string "*")))
6128    (set_attr "mode" "<MODE>")])
6130 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6131 (define_insn "*addsi_3_zext"
6132   [(set (reg FLAGS_REG)
6133         (compare
6134           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6135           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6136    (set (match_operand:DI 0 "register_operand" "=r,r")
6137         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6138   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6139    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6141   switch (get_attr_type (insn))
6142     {
6143     case TYPE_INCDEC:
6144       if (operands[2] == const1_rtx)
6145         return "inc{l}\t%k0";
6146       else
6147         {
6148           gcc_assert (operands[2] == constm1_rtx);
6149           return "dec{l}\t%k0";
6150         }
6152     default:
6153       if (which_alternative == 1)
6154         std::swap (operands[1], operands[2]);
6156       if (x86_maybe_negate_const_int (&operands[2], SImode))
6157         return "sub{l}\t{%2, %k0|%k0, %2}";
6159       return "add{l}\t{%2, %k0|%k0, %2}";
6160     }
6162   [(set (attr "type")
6163      (if_then_else (match_operand:SI 2 "incdec_operand")
6164         (const_string "incdec")
6165         (const_string "alu")))
6166    (set (attr "length_immediate")
6167       (if_then_else
6168         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6169         (const_string "1")
6170         (const_string "*")))
6171    (set_attr "mode" "SI")])
6173 ; For comparisons against 1, -1 and 128, we may generate better code
6174 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6175 ; is matched then.  We can't accept general immediate, because for
6176 ; case of overflows,  the result is messed up.
6177 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6178 ; only for comparisons not depending on it.
6180 (define_insn "*adddi_4"
6181   [(set (reg FLAGS_REG)
6182         (compare
6183           (match_operand:DI 1 "nonimmediate_operand" "0")
6184           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6185    (clobber (match_scratch:DI 0 "=rm"))]
6186   "TARGET_64BIT
6187    && ix86_match_ccmode (insn, CCGCmode)"
6189   switch (get_attr_type (insn))
6190     {
6191     case TYPE_INCDEC:
6192       if (operands[2] == constm1_rtx)
6193         return "inc{q}\t%0";
6194       else
6195         {
6196           gcc_assert (operands[2] == const1_rtx);
6197           return "dec{q}\t%0";
6198         }
6200     default:
6201       if (x86_maybe_negate_const_int (&operands[2], DImode))
6202         return "add{q}\t{%2, %0|%0, %2}";
6204       return "sub{q}\t{%2, %0|%0, %2}";
6205     }
6207   [(set (attr "type")
6208      (if_then_else (match_operand:DI 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" "DI")])
6218 ; For comparisons against 1, -1 and 128, we may generate better code
6219 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6220 ; is matched then.  We can't accept general immediate, because for
6221 ; case of overflows,  the result is messed up.
6222 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6223 ; only for comparisons not depending on it.
6225 (define_insn "*add<mode>_4"
6226   [(set (reg FLAGS_REG)
6227         (compare
6228           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6229           (match_operand:SWI124 2 "const_int_operand" "n")))
6230    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6231   "ix86_match_ccmode (insn, CCGCmode)"
6233   switch (get_attr_type (insn))
6234     {
6235     case TYPE_INCDEC:
6236       if (operands[2] == constm1_rtx)
6237         return "inc{<imodesuffix>}\t%0";
6238       else
6239         {
6240           gcc_assert (operands[2] == const1_rtx);
6241           return "dec{<imodesuffix>}\t%0";
6242         }
6244     default:
6245       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6246         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6248       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6249     }
6251   [(set (attr "type")
6252      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6253         (const_string "incdec")
6254         (const_string "alu")))
6255    (set (attr "length_immediate")
6256       (if_then_else
6257         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6258         (const_string "1")
6259         (const_string "*")))
6260    (set_attr "mode" "<MODE>")])
6262 (define_insn "*add<mode>_5"
6263   [(set (reg FLAGS_REG)
6264         (compare
6265           (plus:SWI
6266             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6267             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6268           (const_int 0)))
6269    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6270   "ix86_match_ccmode (insn, CCGOCmode)
6271    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6273   switch (get_attr_type (insn))
6274     {
6275     case TYPE_INCDEC:
6276       if (operands[2] == const1_rtx)
6277         return "inc{<imodesuffix>}\t%0";
6278       else
6279         {
6280           gcc_assert (operands[2] == constm1_rtx);
6281           return "dec{<imodesuffix>}\t%0";
6282         }
6284     default:
6285       if (which_alternative == 1)
6286         std::swap (operands[1], operands[2]);
6288       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6289       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6290         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6292       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6293     }
6295   [(set (attr "type")
6296      (if_then_else (match_operand:SWI 2 "incdec_operand")
6297         (const_string "incdec")
6298         (const_string "alu")))
6299    (set (attr "length_immediate")
6300       (if_then_else
6301         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6302         (const_string "1")
6303         (const_string "*")))
6304    (set_attr "mode" "<MODE>")])
6306 (define_insn "addqi_ext_1"
6307   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6308                          (const_int 8)
6309                          (const_int 8))
6310         (subreg:SI
6311           (plus:QI
6312             (subreg:QI
6313               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6314                                (const_int 8)
6315                                (const_int 8)) 0)
6316             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6317    (clobber (reg:CC FLAGS_REG))]
6318   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6319    rtx_equal_p (operands[0], operands[1])"
6321   switch (get_attr_type (insn))
6322     {
6323     case TYPE_INCDEC:
6324       if (operands[2] == const1_rtx)
6325         return "inc{b}\t%h0";
6326       else
6327         {
6328           gcc_assert (operands[2] == constm1_rtx);
6329           return "dec{b}\t%h0";
6330         }
6332     default:
6333       return "add{b}\t{%2, %h0|%h0, %2}";
6334     }
6336   [(set_attr "isa" "*,nox64")
6337    (set (attr "type")
6338      (if_then_else (match_operand:QI 2 "incdec_operand")
6339         (const_string "incdec")
6340         (const_string "alu")))
6341    (set_attr "mode" "QI")])
6343 (define_insn "*addqi_ext_2"
6344   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6345                          (const_int 8)
6346                          (const_int 8))
6347         (subreg:SI
6348           (plus:QI
6349             (subreg:QI
6350               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6351                                (const_int 8)
6352                                (const_int 8)) 0)
6353             (subreg:QI
6354               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6355                                (const_int 8)
6356                                (const_int 8)) 0)) 0))
6357   (clobber (reg:CC FLAGS_REG))]
6358   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
6359    rtx_equal_p (operands[0], operands[1])
6360    || rtx_equal_p (operands[0], operands[2])"
6361   "add{b}\t{%h2, %h0|%h0, %h2}"
6362   [(set_attr "type" "alu")
6363    (set_attr "mode" "QI")])
6365 ;; Add with jump on overflow.
6366 (define_expand "addv<mode>4"
6367   [(parallel [(set (reg:CCO FLAGS_REG)
6368                    (eq:CCO (plus:<DWI>
6369                               (sign_extend:<DWI>
6370                                  (match_operand:SWI 1 "nonimmediate_operand"))
6371                               (match_dup 4))
6372                            (sign_extend:<DWI>
6373                               (plus:SWI (match_dup 1)
6374                                         (match_operand:SWI 2
6375                                            "<general_operand>")))))
6376               (set (match_operand:SWI 0 "register_operand")
6377                    (plus:SWI (match_dup 1) (match_dup 2)))])
6378    (set (pc) (if_then_else
6379                (eq (reg:CCO FLAGS_REG) (const_int 0))
6380                (label_ref (match_operand 3))
6381                (pc)))]
6382   ""
6384   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6385   if (CONST_INT_P (operands[2]))
6386     operands[4] = operands[2];
6387   else
6388     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6391 (define_insn "*addv<mode>4"
6392   [(set (reg:CCO FLAGS_REG)
6393         (eq:CCO (plus:<DWI>
6394                    (sign_extend:<DWI>
6395                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6396                    (sign_extend:<DWI>
6397                       (match_operand:SWI 2 "<general_sext_operand>"
6398                                            "<r>mWe,<r>We")))
6399                 (sign_extend:<DWI>
6400                    (plus:SWI (match_dup 1) (match_dup 2)))))
6401    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6402         (plus:SWI (match_dup 1) (match_dup 2)))]
6403   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6404   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6405   [(set_attr "type" "alu")
6406    (set_attr "mode" "<MODE>")])
6408 (define_insn "*addv<mode>4_1"
6409   [(set (reg:CCO FLAGS_REG)
6410         (eq:CCO (plus:<DWI>
6411                    (sign_extend:<DWI>
6412                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6413                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6414                 (sign_extend:<DWI>
6415                    (plus:SWI (match_dup 1)
6416                              (match_operand:SWI 2 "x86_64_immediate_operand"
6417                                                   "<i>")))))
6418    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6419         (plus:SWI (match_dup 1) (match_dup 2)))]
6420   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6421    && CONST_INT_P (operands[2])
6422    && INTVAL (operands[2]) == INTVAL (operands[3])"
6423   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6424   [(set_attr "type" "alu")
6425    (set_attr "mode" "<MODE>")
6426    (set (attr "length_immediate")
6427         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6428                   (const_string "1")
6429                (match_test "<MODE_SIZE> == 8")
6430                   (const_string "4")]
6431               (const_string "<MODE_SIZE>")))])
6433 (define_expand "uaddv<mode>4"
6434   [(parallel [(set (reg:CCC FLAGS_REG)
6435                    (compare:CCC
6436                      (plus:SWI
6437                        (match_operand:SWI 1 "nonimmediate_operand")
6438                        (match_operand:SWI 2 "<general_operand>"))
6439                      (match_dup 1)))
6440               (set (match_operand:SWI 0 "register_operand")
6441                    (plus:SWI (match_dup 1) (match_dup 2)))])
6442    (set (pc) (if_then_else
6443                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6444                (label_ref (match_operand 3))
6445                (pc)))]
6446   ""
6447   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6449 ;; The lea patterns for modes less than 32 bits need to be matched by
6450 ;; several insns converted to real lea by splitters.
6452 (define_insn_and_split "*lea<mode>_general_1"
6453   [(set (match_operand:SWI12 0 "register_operand" "=r")
6454         (plus:SWI12
6455           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6456                       (match_operand:SWI12 2 "register_operand" "r"))
6457           (match_operand:SWI12 3 "immediate_operand" "i")))]
6458   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6459   "#"
6460   "&& reload_completed"
6461   [(set (match_dup 0)
6462         (plus:SI
6463           (plus:SI (match_dup 1) (match_dup 2))
6464           (match_dup 3)))]
6466   operands[0] = gen_lowpart (SImode, operands[0]);
6467   operands[1] = gen_lowpart (SImode, operands[1]);
6468   operands[2] = gen_lowpart (SImode, operands[2]);
6469   operands[3] = gen_lowpart (SImode, operands[3]);
6471   [(set_attr "type" "lea")
6472    (set_attr "mode" "SI")])
6474 (define_insn_and_split "*lea<mode>_general_2"
6475   [(set (match_operand:SWI12 0 "register_operand" "=r")
6476         (plus:SWI12
6477           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6478                       (match_operand 2 "const248_operand" "n"))
6479           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6480   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6481   "#"
6482   "&& reload_completed"
6483   [(set (match_dup 0)
6484         (plus:SI
6485           (mult:SI (match_dup 1) (match_dup 2))
6486           (match_dup 3)))]
6488   operands[0] = gen_lowpart (SImode, operands[0]);
6489   operands[1] = gen_lowpart (SImode, operands[1]);
6490   operands[3] = gen_lowpart (SImode, operands[3]);
6492   [(set_attr "type" "lea")
6493    (set_attr "mode" "SI")])
6495 (define_insn_and_split "*lea<mode>_general_2b"
6496   [(set (match_operand:SWI12 0 "register_operand" "=r")
6497         (plus:SWI12
6498           (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6499                         (match_operand 2 "const123_operand" "n"))
6500           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6501   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6502   "#"
6503   "&& reload_completed"
6504   [(set (match_dup 0)
6505         (plus:SI
6506           (ashift:SI (match_dup 1) (match_dup 2))
6507           (match_dup 3)))]
6509   operands[0] = gen_lowpart (SImode, operands[0]);
6510   operands[1] = gen_lowpart (SImode, operands[1]);
6511   operands[3] = gen_lowpart (SImode, operands[3]);
6513   [(set_attr "type" "lea")
6514    (set_attr "mode" "SI")])
6516 (define_insn_and_split "*lea<mode>_general_3"
6517   [(set (match_operand:SWI12 0 "register_operand" "=r")
6518         (plus:SWI12
6519           (plus:SWI12
6520             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6521                         (match_operand 2 "const248_operand" "n"))
6522             (match_operand:SWI12 3 "register_operand" "r"))
6523           (match_operand:SWI12 4 "immediate_operand" "i")))]
6524   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6525   "#"
6526   "&& reload_completed"
6527   [(set (match_dup 0)
6528         (plus:SI
6529           (plus:SI
6530             (mult:SI (match_dup 1) (match_dup 2))
6531             (match_dup 3))
6532           (match_dup 4)))]
6534   operands[0] = gen_lowpart (SImode, operands[0]);
6535   operands[1] = gen_lowpart (SImode, operands[1]);
6536   operands[3] = gen_lowpart (SImode, operands[3]);
6537   operands[4] = gen_lowpart (SImode, operands[4]);
6539   [(set_attr "type" "lea")
6540    (set_attr "mode" "SI")])
6542 (define_insn_and_split "*lea<mode>_general_3b"
6543   [(set (match_operand:SWI12 0 "register_operand" "=r")
6544         (plus:SWI12
6545           (plus:SWI12
6546             (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6547                           (match_operand 2 "const123_operand" "n"))
6548             (match_operand:SWI12 3 "register_operand" "r"))
6549           (match_operand:SWI12 4 "immediate_operand" "i")))]
6550   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6551   "#"
6552   "&& reload_completed"
6553   [(set (match_dup 0)
6554         (plus:SI
6555           (plus:SI
6556             (ashift:SI (match_dup 1) (match_dup 2))
6557             (match_dup 3))
6558           (match_dup 4)))]
6560   operands[0] = gen_lowpart (SImode, operands[0]);
6561   operands[1] = gen_lowpart (SImode, operands[1]);
6562   operands[3] = gen_lowpart (SImode, operands[3]);
6563   operands[4] = gen_lowpart (SImode, operands[4]);
6565   [(set_attr "type" "lea")
6566    (set_attr "mode" "SI")])
6568 (define_insn_and_split "*lea<mode>_general_4"
6569   [(set (match_operand:SWI12 0 "register_operand" "=r")
6570         (any_or:SWI12
6571           (ashift:SWI12
6572             (match_operand:SWI12 1 "index_register_operand" "l")
6573             (match_operand 2 "const_0_to_3_operand" "n"))
6574           (match_operand 3 "const_int_operand" "n")))]
6575   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6576    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6577        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6578   "#"
6579   "&& reload_completed"
6580   [(set (match_dup 0)
6581         (plus:SI
6582           (mult:SI (match_dup 1) (match_dup 2))
6583           (match_dup 3)))]
6585   operands[0] = gen_lowpart (SImode, operands[0]);
6586   operands[1] = gen_lowpart (SImode, operands[1]);
6587   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6589   [(set_attr "type" "lea")
6590    (set_attr "mode" "SI")])
6592 (define_insn_and_split "*lea<mode>_general_4"
6593   [(set (match_operand:SWI48 0 "register_operand" "=r")
6594         (any_or:SWI48
6595           (ashift:SWI48
6596             (match_operand:SWI48 1 "index_register_operand" "l")
6597             (match_operand 2 "const_0_to_3_operand" "n"))
6598           (match_operand 3 "const_int_operand" "n")))]
6599   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6600    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6601   "#"
6602   "&& reload_completed"
6603   [(set (match_dup 0)
6604         (plus:SWI48
6605           (mult:SWI48 (match_dup 1) (match_dup 2))
6606           (match_dup 3)))]
6607   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6608   [(set_attr "type" "lea")
6609    (set_attr "mode" "<MODE>")])
6611 ;; Subtract instructions
6613 (define_expand "sub<mode>3"
6614   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6615         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6616                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6617   ""
6618   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6620 (define_insn_and_split "*sub<dwi>3_doubleword"
6621   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6622         (minus:<DWI>
6623           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6624           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6625                                                         "ro<di>,r<di>")))
6626    (clobber (reg:CC FLAGS_REG))]
6627   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6628   "#"
6629   "reload_completed"
6630   [(parallel [(set (reg:CC FLAGS_REG)
6631                    (compare:CC (match_dup 1) (match_dup 2)))
6632               (set (match_dup 0)
6633                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6634    (parallel [(set (match_dup 3)
6635                    (minus:DWIH
6636                      (minus:DWIH
6637                        (match_dup 4)
6638                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6639                      (match_dup 5)))
6640               (clobber (reg:CC FLAGS_REG))])]
6642   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6643   if (operands[2] == const0_rtx)
6644     {
6645       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6646       DONE;
6647     }
6650 (define_insn "*sub<mode>_1"
6651   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6652         (minus:SWI
6653           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6654           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6655    (clobber (reg:CC FLAGS_REG))]
6656   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6657   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6658   [(set_attr "type" "alu")
6659    (set_attr "mode" "<MODE>")])
6661 (define_insn "*subsi_1_zext"
6662   [(set (match_operand:DI 0 "register_operand" "=r")
6663         (zero_extend:DI
6664           (minus:SI (match_operand:SI 1 "register_operand" "0")
6665                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6666    (clobber (reg:CC FLAGS_REG))]
6667   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6668   "sub{l}\t{%2, %k0|%k0, %2}"
6669   [(set_attr "type" "alu")
6670    (set_attr "mode" "SI")])
6672 (define_insn "*subqi_1_slp"
6673   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6674         (minus:QI (match_dup 0)
6675                   (match_operand:QI 1 "general_operand" "qn,qm")))
6676    (clobber (reg:CC FLAGS_REG))]
6677   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6678    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6679   "sub{b}\t{%1, %0|%0, %1}"
6680   [(set_attr "type" "alu1")
6681    (set_attr "mode" "QI")])
6683 (define_insn "*sub<mode>_2"
6684   [(set (reg FLAGS_REG)
6685         (compare
6686           (minus:SWI
6687             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6688             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6689           (const_int 0)))
6690    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6691         (minus:SWI (match_dup 1) (match_dup 2)))]
6692   "ix86_match_ccmode (insn, CCGOCmode)
6693    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6694   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6695   [(set_attr "type" "alu")
6696    (set_attr "mode" "<MODE>")])
6698 (define_insn "*subsi_2_zext"
6699   [(set (reg FLAGS_REG)
6700         (compare
6701           (minus:SI (match_operand:SI 1 "register_operand" "0")
6702                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6703           (const_int 0)))
6704    (set (match_operand:DI 0 "register_operand" "=r")
6705         (zero_extend:DI
6706           (minus:SI (match_dup 1)
6707                     (match_dup 2))))]
6708   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6709    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6710   "sub{l}\t{%2, %k0|%k0, %2}"
6711   [(set_attr "type" "alu")
6712    (set_attr "mode" "SI")])
6714 ;; Subtract with jump on overflow.
6715 (define_expand "subv<mode>4"
6716   [(parallel [(set (reg:CCO FLAGS_REG)
6717                    (eq:CCO (minus:<DWI>
6718                               (sign_extend:<DWI>
6719                                  (match_operand:SWI 1 "nonimmediate_operand"))
6720                               (match_dup 4))
6721                            (sign_extend:<DWI>
6722                               (minus:SWI (match_dup 1)
6723                                          (match_operand:SWI 2
6724                                             "<general_operand>")))))
6725               (set (match_operand:SWI 0 "register_operand")
6726                    (minus:SWI (match_dup 1) (match_dup 2)))])
6727    (set (pc) (if_then_else
6728                (eq (reg:CCO FLAGS_REG) (const_int 0))
6729                (label_ref (match_operand 3))
6730                (pc)))]
6731   ""
6733   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6734   if (CONST_INT_P (operands[2]))
6735     operands[4] = operands[2];
6736   else
6737     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6740 (define_insn "*subv<mode>4"
6741   [(set (reg:CCO FLAGS_REG)
6742         (eq:CCO (minus:<DWI>
6743                    (sign_extend:<DWI>
6744                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6745                    (sign_extend:<DWI>
6746                       (match_operand:SWI 2 "<general_sext_operand>"
6747                                            "<r>We,<r>m")))
6748                 (sign_extend:<DWI>
6749                    (minus:SWI (match_dup 1) (match_dup 2)))))
6750    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6751         (minus:SWI (match_dup 1) (match_dup 2)))]
6752   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6753   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6754   [(set_attr "type" "alu")
6755    (set_attr "mode" "<MODE>")])
6757 (define_insn "*subv<mode>4_1"
6758   [(set (reg:CCO FLAGS_REG)
6759         (eq:CCO (minus:<DWI>
6760                    (sign_extend:<DWI>
6761                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6762                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6763                 (sign_extend:<DWI>
6764                    (minus:SWI (match_dup 1)
6765                               (match_operand:SWI 2 "x86_64_immediate_operand"
6766                                                    "<i>")))))
6767    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6768         (minus:SWI (match_dup 1) (match_dup 2)))]
6769   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6770    && CONST_INT_P (operands[2])
6771    && INTVAL (operands[2]) == INTVAL (operands[3])"
6772   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6773   [(set_attr "type" "alu")
6774    (set_attr "mode" "<MODE>")
6775    (set (attr "length_immediate")
6776         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6777                   (const_string "1")
6778                (match_test "<MODE_SIZE> == 8")
6779                   (const_string "4")]
6780               (const_string "<MODE_SIZE>")))])
6782 (define_expand "usubv<mode>4"
6783   [(parallel [(set (reg:CC FLAGS_REG)
6784                    (compare:CC
6785                      (match_operand:SWI 1 "nonimmediate_operand")
6786                      (match_operand:SWI 2 "<general_operand>")))
6787               (set (match_operand:SWI 0 "register_operand")
6788                    (minus:SWI (match_dup 1) (match_dup 2)))])
6789    (set (pc) (if_then_else
6790                (ltu (reg:CC FLAGS_REG) (const_int 0))
6791                (label_ref (match_operand 3))
6792                (pc)))]
6793   ""
6794   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6796 (define_insn "*sub<mode>_3"
6797   [(set (reg FLAGS_REG)
6798         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6799                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6800    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6801         (minus:SWI (match_dup 1) (match_dup 2)))]
6802   "ix86_match_ccmode (insn, CCmode)
6803    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6804   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6805   [(set_attr "type" "alu")
6806    (set_attr "mode" "<MODE>")])
6808 (define_peephole2
6809   [(parallel
6810      [(set (reg:CC FLAGS_REG)
6811            (compare:CC (match_operand:SWI 0 "general_reg_operand")
6812                        (match_operand:SWI 1 "general_gr_operand")))
6813       (set (match_dup 0)
6814            (minus:SWI (match_dup 0) (match_dup 1)))])]
6815   "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6816   [(set (reg:CC FLAGS_REG)
6817         (compare:CC (match_dup 0) (match_dup 1)))])
6819 (define_insn "*subsi_3_zext"
6820   [(set (reg FLAGS_REG)
6821         (compare (match_operand:SI 1 "register_operand" "0")
6822                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6823    (set (match_operand:DI 0 "register_operand" "=r")
6824         (zero_extend:DI
6825           (minus:SI (match_dup 1)
6826                     (match_dup 2))))]
6827   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6828    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6829   "sub{l}\t{%2, %1|%1, %2}"
6830   [(set_attr "type" "alu")
6831    (set_attr "mode" "SI")])
6833 ;; Add with carry and subtract with borrow
6835 (define_insn "add<mode>3_carry"
6836   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6837         (plus:SWI
6838           (plus:SWI
6839             (match_operator:SWI 4 "ix86_carry_flag_operator"
6840              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6841             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6842           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6845   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6846   [(set_attr "type" "alu")
6847    (set_attr "use_carry" "1")
6848    (set_attr "pent_pair" "pu")
6849    (set_attr "mode" "<MODE>")])
6851 (define_insn "*addsi3_carry_zext"
6852   [(set (match_operand:DI 0 "register_operand" "=r")
6853         (zero_extend:DI
6854           (plus:SI
6855             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6856                       [(reg FLAGS_REG) (const_int 0)])
6857                      (match_operand:SI 1 "register_operand" "%0"))
6858             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6859    (clobber (reg:CC FLAGS_REG))]
6860   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6861   "adc{l}\t{%2, %k0|%k0, %2}"
6862   [(set_attr "type" "alu")
6863    (set_attr "use_carry" "1")
6864    (set_attr "pent_pair" "pu")
6865    (set_attr "mode" "SI")])
6867 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6869 (define_insn "addcarry<mode>"
6870   [(set (reg:CCC FLAGS_REG)
6871         (compare:CCC
6872           (zero_extend:<DWI>
6873             (plus:SWI48
6874               (plus:SWI48
6875                 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6876                   [(match_operand 3 "flags_reg_operand") (const_int 0)])
6877                 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6878               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6879           (plus:<DWI>
6880             (zero_extend:<DWI> (match_dup 2))
6881             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6882               [(match_dup 3) (const_int 0)]))))
6883    (set (match_operand:SWI48 0 "register_operand" "=r")
6884         (plus:SWI48 (plus:SWI48 (match_op_dup 5
6885                                  [(match_dup 3) (const_int 0)])
6886                                 (match_dup 1))
6887                     (match_dup 2)))]
6888   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6889   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6890   [(set_attr "type" "alu")
6891    (set_attr "use_carry" "1")
6892    (set_attr "pent_pair" "pu")
6893    (set_attr "mode" "<MODE>")])
6895 (define_expand "addcarry<mode>_0"
6896   [(parallel
6897      [(set (reg:CCC FLAGS_REG)
6898            (compare:CCC
6899              (plus:SWI48
6900                (match_operand:SWI48 1 "nonimmediate_operand")
6901                (match_operand:SWI48 2 "x86_64_general_operand"))
6902              (match_dup 1)))
6903       (set (match_operand:SWI48 0 "register_operand")
6904            (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6905   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6907 (define_insn "sub<mode>3_carry"
6908   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6909         (minus:SWI
6910           (minus:SWI
6911             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6912             (match_operator:SWI 4 "ix86_carry_flag_operator"
6913              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6914           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6915    (clobber (reg:CC FLAGS_REG))]
6916   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6917   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6918   [(set_attr "type" "alu")
6919    (set_attr "use_carry" "1")
6920    (set_attr "pent_pair" "pu")
6921    (set_attr "mode" "<MODE>")])
6923 (define_insn "*subsi3_carry_zext"
6924   [(set (match_operand:DI 0 "register_operand" "=r")
6925         (zero_extend:DI
6926           (minus:SI
6927             (minus:SI
6928               (match_operand:SI 1 "register_operand" "0")
6929               (match_operator:SI 3 "ix86_carry_flag_operator"
6930                [(reg FLAGS_REG) (const_int 0)]))
6931             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6932    (clobber (reg:CC FLAGS_REG))]
6933   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6934   "sbb{l}\t{%2, %k0|%k0, %2}"
6935   [(set_attr "type" "alu")
6936    (set_attr "use_carry" "1")
6937    (set_attr "pent_pair" "pu")
6938    (set_attr "mode" "SI")])
6940 (define_insn "sub<mode>3_carry_ccc"
6941   [(set (reg:CCC FLAGS_REG)
6942         (compare:CCC
6943           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6944           (plus:<DWI>
6945             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6946             (zero_extend:<DWI>
6947               (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6948    (clobber (match_scratch:DWIH 0 "=r"))]
6949   ""
6950   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6951   [(set_attr "type" "alu")
6952    (set_attr "mode" "<MODE>")])
6954 (define_insn "*sub<mode>3_carry_ccc_1"
6955   [(set (reg:CCC FLAGS_REG)
6956         (compare:CCC
6957           (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6958           (plus:<DWI>
6959             (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6960             (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6961    (clobber (match_scratch:DWIH 0 "=r"))]
6962   ""
6964   operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6965   return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6967   [(set_attr "type" "alu")
6968    (set_attr "mode" "<MODE>")])
6970 ;; The sign flag is set from the
6971 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6972 ;; result, the overflow flag likewise, but the overflow flag is also
6973 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6974 (define_insn "sub<mode>3_carry_ccgz"
6975   [(set (reg:CCGZ FLAGS_REG)
6976         (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6977                       (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6978                       (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6979                      UNSPEC_SBB))
6980    (clobber (match_scratch:DWIH 0 "=r"))]
6981   ""
6982   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6983   [(set_attr "type" "alu")
6984    (set_attr "mode" "<MODE>")])
6986 (define_insn "subborrow<mode>"
6987   [(set (reg:CCC FLAGS_REG)
6988         (compare:CCC
6989           (zero_extend:<DWI>
6990             (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6991           (plus:<DWI>
6992             (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6993               [(match_operand 3 "flags_reg_operand") (const_int 0)])
6994             (zero_extend:<DWI>
6995               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6996    (set (match_operand:SWI48 0 "register_operand" "=r")
6997         (minus:SWI48 (minus:SWI48
6998                        (match_dup 1)
6999                        (match_operator:SWI48 5 "ix86_carry_flag_operator"
7000                          [(match_dup 3) (const_int 0)]))
7001                      (match_dup 2)))]
7002   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7003   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7004   [(set_attr "type" "alu")
7005    (set_attr "use_carry" "1")
7006    (set_attr "pent_pair" "pu")
7007    (set_attr "mode" "<MODE>")])
7009 (define_expand "subborrow<mode>_0"
7010   [(parallel
7011      [(set (reg:CC FLAGS_REG)
7012            (compare:CC
7013              (match_operand:SWI48 1 "nonimmediate_operand")
7014              (match_operand:SWI48 2 "<general_operand>")))
7015       (set (match_operand:SWI48 0 "register_operand")
7016            (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7017   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7019 ;; Overflow setting add instructions
7021 (define_expand "addqi3_cconly_overflow"
7022   [(parallel
7023      [(set (reg:CCC FLAGS_REG)
7024            (compare:CCC
7025              (plus:QI
7026                (match_operand:QI 0 "nonimmediate_operand")
7027                (match_operand:QI 1 "general_operand"))
7028              (match_dup 0)))
7029       (clobber (match_scratch:QI 2))])]
7030   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7032 (define_insn "*add<mode>3_cconly_overflow_1"
7033   [(set (reg:CCC FLAGS_REG)
7034         (compare:CCC
7035           (plus:SWI
7036             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7037             (match_operand:SWI 2 "<general_operand>" "<g>"))
7038           (match_dup 1)))
7039    (clobber (match_scratch:SWI 0 "=<r>"))]
7040   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7041   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7042   [(set_attr "type" "alu")
7043    (set_attr "mode" "<MODE>")])
7045 (define_insn "*add<mode>3_cc_overflow_1"
7046   [(set (reg:CCC FLAGS_REG)
7047         (compare:CCC
7048             (plus:SWI
7049                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7050                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7051             (match_dup 1)))
7052    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7053         (plus:SWI (match_dup 1) (match_dup 2)))]
7054   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7055   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7056   [(set_attr "type" "alu")
7057    (set_attr "mode" "<MODE>")])
7059 (define_insn "*addsi3_zext_cc_overflow_1"
7060   [(set (reg:CCC FLAGS_REG)
7061         (compare:CCC
7062           (plus:SI
7063             (match_operand:SI 1 "nonimmediate_operand" "%0")
7064             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7065           (match_dup 1)))
7066    (set (match_operand:DI 0 "register_operand" "=r")
7067         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7068   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7069   "add{l}\t{%2, %k0|%k0, %2}"
7070   [(set_attr "type" "alu")
7071    (set_attr "mode" "SI")])
7073 (define_insn "*add<mode>3_cconly_overflow_2"
7074   [(set (reg:CCC FLAGS_REG)
7075         (compare:CCC
7076           (plus:SWI
7077             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7078             (match_operand:SWI 2 "<general_operand>" "<g>"))
7079           (match_dup 2)))
7080    (clobber (match_scratch:SWI 0 "=<r>"))]
7081   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7082   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7083   [(set_attr "type" "alu")
7084    (set_attr "mode" "<MODE>")])
7086 (define_insn "*add<mode>3_cc_overflow_2"
7087   [(set (reg:CCC FLAGS_REG)
7088         (compare:CCC
7089             (plus:SWI
7090                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7091                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7092             (match_dup 2)))
7093    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7094         (plus:SWI (match_dup 1) (match_dup 2)))]
7095   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7096   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7097   [(set_attr "type" "alu")
7098    (set_attr "mode" "<MODE>")])
7100 (define_insn "*addsi3_zext_cc_overflow_2"
7101   [(set (reg:CCC FLAGS_REG)
7102         (compare:CCC
7103           (plus:SI
7104             (match_operand:SI 1 "nonimmediate_operand" "%0")
7105             (match_operand:SI 2 "x86_64_general_operand" "rme"))
7106           (match_dup 2)))
7107    (set (match_operand:DI 0 "register_operand" "=r")
7108         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7109   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7110   "add{l}\t{%2, %k0|%k0, %2}"
7111   [(set_attr "type" "alu")
7112    (set_attr "mode" "SI")])
7114 ;; The patterns that match these are at the end of this file.
7116 (define_expand "<plusminus_insn>xf3"
7117   [(set (match_operand:XF 0 "register_operand")
7118         (plusminus:XF
7119           (match_operand:XF 1 "register_operand")
7120           (match_operand:XF 2 "register_operand")))]
7121   "TARGET_80387")
7123 (define_expand "<plusminus_insn><mode>3"
7124   [(set (match_operand:MODEF 0 "register_operand")
7125         (plusminus:MODEF
7126           (match_operand:MODEF 1 "register_operand")
7127           (match_operand:MODEF 2 "nonimmediate_operand")))]
7128   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7129     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7131 ;; Multiply instructions
7133 (define_expand "mul<mode>3"
7134   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7135                    (mult:SWIM248
7136                      (match_operand:SWIM248 1 "register_operand")
7137                      (match_operand:SWIM248 2 "<general_operand>")))
7138               (clobber (reg:CC FLAGS_REG))])])
7140 (define_expand "mulqi3"
7141   [(parallel [(set (match_operand:QI 0 "register_operand")
7142                    (mult:QI
7143                      (match_operand:QI 1 "register_operand")
7144                      (match_operand:QI 2 "nonimmediate_operand")))
7145               (clobber (reg:CC FLAGS_REG))])]
7146   "TARGET_QIMODE_MATH")
7148 ;; On AMDFAM10
7149 ;; IMUL reg32/64, reg32/64, imm8        Direct
7150 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7151 ;; IMUL reg32/64, reg32/64, imm32       Direct
7152 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7153 ;; IMUL reg32/64, reg32/64              Direct
7154 ;; IMUL reg32/64, mem32/64              Direct
7156 ;; On BDVER1, all above IMULs use DirectPath
7158 ;; On AMDFAM10
7159 ;; IMUL reg16, reg16, imm8      VectorPath
7160 ;; IMUL reg16, mem16, imm8      VectorPath
7161 ;; IMUL reg16, reg16, imm16     VectorPath
7162 ;; IMUL reg16, mem16, imm16     VectorPath
7163 ;; IMUL reg16, reg16            Direct
7164 ;; IMUL reg16, mem16            Direct
7166 ;; On BDVER1, all HI MULs use DoublePath
7168 (define_insn "*mul<mode>3_1"
7169   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7170         (mult:SWIM248
7171           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7172           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7173    (clobber (reg:CC FLAGS_REG))]
7174   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7175   "@
7176    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7177    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7178    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7179   [(set_attr "type" "imul")
7180    (set_attr "prefix_0f" "0,0,1")
7181    (set (attr "athlon_decode")
7182         (cond [(eq_attr "cpu" "athlon")
7183                   (const_string "vector")
7184                (eq_attr "alternative" "1")
7185                   (const_string "vector")
7186                (and (eq_attr "alternative" "2")
7187                     (ior (match_test "<MODE>mode == HImode")
7188                          (match_operand 1 "memory_operand")))
7189                   (const_string "vector")]
7190               (const_string "direct")))
7191    (set (attr "amdfam10_decode")
7192         (cond [(and (eq_attr "alternative" "0,1")
7193                     (ior (match_test "<MODE>mode == HImode")
7194                          (match_operand 1 "memory_operand")))
7195                   (const_string "vector")]
7196               (const_string "direct")))
7197    (set (attr "bdver1_decode")
7198         (if_then_else
7199           (match_test "<MODE>mode == HImode")
7200             (const_string "double")
7201             (const_string "direct")))
7202    (set_attr "mode" "<MODE>")])
7204 (define_insn "*mulsi3_1_zext"
7205   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7206         (zero_extend:DI
7207           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7208                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7209    (clobber (reg:CC FLAGS_REG))]
7210   "TARGET_64BIT
7211    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7212   "@
7213    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7214    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7215    imul{l}\t{%2, %k0|%k0, %2}"
7216   [(set_attr "type" "imul")
7217    (set_attr "prefix_0f" "0,0,1")
7218    (set (attr "athlon_decode")
7219         (cond [(eq_attr "cpu" "athlon")
7220                   (const_string "vector")
7221                (eq_attr "alternative" "1")
7222                   (const_string "vector")
7223                (and (eq_attr "alternative" "2")
7224                     (match_operand 1 "memory_operand"))
7225                   (const_string "vector")]
7226               (const_string "direct")))
7227    (set (attr "amdfam10_decode")
7228         (cond [(and (eq_attr "alternative" "0,1")
7229                     (match_operand 1 "memory_operand"))
7230                   (const_string "vector")]
7231               (const_string "direct")))
7232    (set_attr "bdver1_decode" "direct")
7233    (set_attr "mode" "SI")])
7235 ;;On AMDFAM10 and BDVER1
7236 ;; MUL reg8     Direct
7237 ;; MUL mem8     Direct
7239 (define_insn "*mulqi3_1"
7240   [(set (match_operand:QI 0 "register_operand" "=a")
7241         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7242                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7243    (clobber (reg:CC FLAGS_REG))]
7244   "TARGET_QIMODE_MATH
7245    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7246   "mul{b}\t%2"
7247   [(set_attr "type" "imul")
7248    (set_attr "length_immediate" "0")
7249    (set (attr "athlon_decode")
7250      (if_then_else (eq_attr "cpu" "athlon")
7251         (const_string "vector")
7252         (const_string "direct")))
7253    (set_attr "amdfam10_decode" "direct")
7254    (set_attr "bdver1_decode" "direct")
7255    (set_attr "mode" "QI")])
7257 ;; Multiply with jump on overflow.
7258 (define_expand "mulv<mode>4"
7259   [(parallel [(set (reg:CCO FLAGS_REG)
7260                    (eq:CCO (mult:<DWI>
7261                               (sign_extend:<DWI>
7262                                  (match_operand:SWI248 1 "register_operand"))
7263                               (match_dup 4))
7264                            (sign_extend:<DWI>
7265                               (mult:SWI248 (match_dup 1)
7266                                            (match_operand:SWI248 2
7267                                               "<general_operand>")))))
7268               (set (match_operand:SWI248 0 "register_operand")
7269                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
7270    (set (pc) (if_then_else
7271                (eq (reg:CCO FLAGS_REG) (const_int 0))
7272                (label_ref (match_operand 3))
7273                (pc)))]
7274   ""
7276   if (CONST_INT_P (operands[2]))
7277     operands[4] = operands[2];
7278   else
7279     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7282 (define_insn "*mulv<mode>4"
7283   [(set (reg:CCO FLAGS_REG)
7284         (eq:CCO (mult:<DWI>
7285                    (sign_extend:<DWI>
7286                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7287                    (sign_extend:<DWI>
7288                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7289                 (sign_extend:<DWI>
7290                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
7291    (set (match_operand:SWI48 0 "register_operand" "=r,r")
7292         (mult:SWI48 (match_dup 1) (match_dup 2)))]
7293   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7294   "@
7295    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7296    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7297   [(set_attr "type" "imul")
7298    (set_attr "prefix_0f" "0,1")
7299    (set (attr "athlon_decode")
7300         (cond [(eq_attr "cpu" "athlon")
7301                   (const_string "vector")
7302                (eq_attr "alternative" "0")
7303                   (const_string "vector")
7304                (and (eq_attr "alternative" "1")
7305                     (match_operand 1 "memory_operand"))
7306                   (const_string "vector")]
7307               (const_string "direct")))
7308    (set (attr "amdfam10_decode")
7309         (cond [(and (eq_attr "alternative" "1")
7310                     (match_operand 1 "memory_operand"))
7311                   (const_string "vector")]
7312               (const_string "direct")))
7313    (set_attr "bdver1_decode" "direct")
7314    (set_attr "mode" "<MODE>")])
7316 (define_insn "*mulvhi4"
7317   [(set (reg:CCO FLAGS_REG)
7318         (eq:CCO (mult:SI
7319                    (sign_extend:SI
7320                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
7321                    (sign_extend:SI
7322                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
7323                 (sign_extend:SI
7324                    (mult:HI (match_dup 1) (match_dup 2)))))
7325    (set (match_operand:HI 0 "register_operand" "=r")
7326         (mult:HI (match_dup 1) (match_dup 2)))]
7327   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7328   "imul{w}\t{%2, %0|%0, %2}"
7329   [(set_attr "type" "imul")
7330    (set_attr "prefix_0f" "1")
7331    (set_attr "athlon_decode" "vector")
7332    (set_attr "amdfam10_decode" "direct")
7333    (set_attr "bdver1_decode" "double")
7334    (set_attr "mode" "HI")])
7336 (define_insn "*mulv<mode>4_1"
7337   [(set (reg:CCO FLAGS_REG)
7338         (eq:CCO (mult:<DWI>
7339                    (sign_extend:<DWI>
7340                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7341                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7342                 (sign_extend:<DWI>
7343                    (mult:SWI248 (match_dup 1)
7344                                 (match_operand:SWI248 2
7345                                    "<immediate_operand>" "K,<i>")))))
7346    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7347         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7348   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7349    && CONST_INT_P (operands[2])
7350    && INTVAL (operands[2]) == INTVAL (operands[3])"
7351   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7352   [(set_attr "type" "imul")
7353    (set (attr "prefix_0f")
7354         (if_then_else
7355           (match_test "<MODE>mode == HImode")
7356             (const_string "0")
7357             (const_string "*")))
7358    (set (attr "athlon_decode")
7359         (cond [(eq_attr "cpu" "athlon")
7360                   (const_string "vector")
7361                (eq_attr "alternative" "1")
7362                   (const_string "vector")]
7363               (const_string "direct")))
7364    (set (attr "amdfam10_decode")
7365         (cond [(ior (match_test "<MODE>mode == HImode")
7366                     (match_operand 1 "memory_operand"))
7367                   (const_string "vector")]
7368               (const_string "direct")))
7369    (set (attr "bdver1_decode")
7370         (if_then_else
7371           (match_test "<MODE>mode == HImode")
7372             (const_string "double")
7373             (const_string "direct")))
7374    (set_attr "mode" "<MODE>")
7375    (set (attr "length_immediate")
7376         (cond [(eq_attr "alternative" "0")
7377                   (const_string "1")
7378                (match_test "<MODE_SIZE> == 8")
7379                   (const_string "4")]
7380               (const_string "<MODE_SIZE>")))])
7382 (define_expand "umulv<mode>4"
7383   [(parallel [(set (reg:CCO FLAGS_REG)
7384                    (eq:CCO (mult:<DWI>
7385                               (zero_extend:<DWI>
7386                                  (match_operand:SWI248 1
7387                                                       "nonimmediate_operand"))
7388                               (zero_extend:<DWI>
7389                                  (match_operand:SWI248 2
7390                                                       "nonimmediate_operand")))
7391                            (zero_extend:<DWI>
7392                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7393               (set (match_operand:SWI248 0 "register_operand")
7394                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7395               (clobber (match_scratch:SWI248 4))])
7396    (set (pc) (if_then_else
7397                (eq (reg:CCO FLAGS_REG) (const_int 0))
7398                (label_ref (match_operand 3))
7399                (pc)))]
7400   ""
7402   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7403     operands[1] = force_reg (<MODE>mode, operands[1]);
7406 (define_insn "*umulv<mode>4"
7407   [(set (reg:CCO FLAGS_REG)
7408         (eq:CCO (mult:<DWI>
7409                    (zero_extend:<DWI>
7410                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7411                    (zero_extend:<DWI>
7412                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7413                 (zero_extend:<DWI>
7414                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7415    (set (match_operand:SWI248 0 "register_operand" "=a")
7416         (mult:SWI248 (match_dup 1) (match_dup 2)))
7417    (clobber (match_scratch:SWI248 3 "=d"))]
7418   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7419   "mul{<imodesuffix>}\t%2"
7420   [(set_attr "type" "imul")
7421    (set_attr "length_immediate" "0")
7422    (set (attr "athlon_decode")
7423      (if_then_else (eq_attr "cpu" "athlon")
7424        (const_string "vector")
7425        (const_string "double")))
7426    (set_attr "amdfam10_decode" "double")
7427    (set_attr "bdver1_decode" "direct")
7428    (set_attr "mode" "<MODE>")])
7430 (define_expand "<u>mulvqi4"
7431   [(parallel [(set (reg:CCO FLAGS_REG)
7432                    (eq:CCO (mult:HI
7433                               (any_extend:HI
7434                                  (match_operand:QI 1 "nonimmediate_operand"))
7435                               (any_extend:HI
7436                                  (match_operand:QI 2 "nonimmediate_operand")))
7437                            (any_extend:HI
7438                               (mult:QI (match_dup 1) (match_dup 2)))))
7439               (set (match_operand:QI 0 "register_operand")
7440                    (mult:QI (match_dup 1) (match_dup 2)))])
7441    (set (pc) (if_then_else
7442                (eq (reg:CCO FLAGS_REG) (const_int 0))
7443                (label_ref (match_operand 3))
7444                (pc)))]
7445   "TARGET_QIMODE_MATH"
7447   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7448     operands[1] = force_reg (QImode, operands[1]);
7451 (define_insn "*<u>mulvqi4"
7452   [(set (reg:CCO FLAGS_REG)
7453         (eq:CCO (mult:HI
7454                    (any_extend:HI
7455                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7456                    (any_extend:HI
7457                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7458                 (any_extend:HI
7459                    (mult:QI (match_dup 1) (match_dup 2)))))
7460    (set (match_operand:QI 0 "register_operand" "=a")
7461         (mult:QI (match_dup 1) (match_dup 2)))]
7462   "TARGET_QIMODE_MATH
7463    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7464   "<sgnprefix>mul{b}\t%2"
7465   [(set_attr "type" "imul")
7466    (set_attr "length_immediate" "0")
7467    (set (attr "athlon_decode")
7468      (if_then_else (eq_attr "cpu" "athlon")
7469         (const_string "vector")
7470         (const_string "direct")))
7471    (set_attr "amdfam10_decode" "direct")
7472    (set_attr "bdver1_decode" "direct")
7473    (set_attr "mode" "QI")])
7475 (define_expand "<u>mul<mode><dwi>3"
7476   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7477                    (mult:<DWI>
7478                      (any_extend:<DWI>
7479                        (match_operand:DWIH 1 "nonimmediate_operand"))
7480                      (any_extend:<DWI>
7481                        (match_operand:DWIH 2 "register_operand"))))
7482               (clobber (reg:CC FLAGS_REG))])])
7484 (define_expand "<u>mulqihi3"
7485   [(parallel [(set (match_operand:HI 0 "register_operand")
7486                    (mult:HI
7487                      (any_extend:HI
7488                        (match_operand:QI 1 "nonimmediate_operand"))
7489                      (any_extend:HI
7490                        (match_operand:QI 2 "register_operand"))))
7491               (clobber (reg:CC FLAGS_REG))])]
7492   "TARGET_QIMODE_MATH")
7494 (define_insn "*bmi2_umul<mode><dwi>3_1"
7495   [(set (match_operand:DWIH 0 "register_operand" "=r")
7496         (mult:DWIH
7497           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7498           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7499    (set (match_operand:DWIH 1 "register_operand" "=r")
7500         (truncate:DWIH
7501           (lshiftrt:<DWI>
7502             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7503                         (zero_extend:<DWI> (match_dup 3)))
7504             (match_operand:QI 4 "const_int_operand" "n"))))]
7505   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7506    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7507   "mulx\t{%3, %0, %1|%1, %0, %3}"
7508   [(set_attr "type" "imulx")
7509    (set_attr "prefix" "vex")
7510    (set_attr "mode" "<MODE>")])
7512 (define_insn "*umul<mode><dwi>3_1"
7513   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7514         (mult:<DWI>
7515           (zero_extend:<DWI>
7516             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7517           (zero_extend:<DWI>
7518             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7519    (clobber (reg:CC FLAGS_REG))]
7520   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7521   "@
7522    #
7523    mul{<imodesuffix>}\t%2"
7524   [(set_attr "isa" "bmi2,*")
7525    (set_attr "type" "imulx,imul")
7526    (set_attr "length_immediate" "*,0")
7527    (set (attr "athlon_decode")
7528         (cond [(eq_attr "alternative" "1")
7529                  (if_then_else (eq_attr "cpu" "athlon")
7530                    (const_string "vector")
7531                    (const_string "double"))]
7532               (const_string "*")))
7533    (set_attr "amdfam10_decode" "*,double")
7534    (set_attr "bdver1_decode" "*,direct")
7535    (set_attr "prefix" "vex,orig")
7536    (set_attr "mode" "<MODE>")])
7538 ;; Convert mul to the mulx pattern to avoid flags dependency.
7539 (define_split
7540  [(set (match_operand:<DWI> 0 "register_operand")
7541        (mult:<DWI>
7542          (zero_extend:<DWI>
7543            (match_operand:DWIH 1 "register_operand"))
7544          (zero_extend:<DWI>
7545            (match_operand:DWIH 2 "nonimmediate_operand"))))
7546   (clobber (reg:CC FLAGS_REG))]
7547  "TARGET_BMI2 && reload_completed
7548   && REGNO (operands[1]) == DX_REG"
7549   [(parallel [(set (match_dup 3)
7550                    (mult:DWIH (match_dup 1) (match_dup 2)))
7551               (set (match_dup 4)
7552                    (truncate:DWIH
7553                      (lshiftrt:<DWI>
7554                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7555                                    (zero_extend:<DWI> (match_dup 2)))
7556                        (match_dup 5))))])]
7558   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7560   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7563 (define_insn "*mul<mode><dwi>3_1"
7564   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7565         (mult:<DWI>
7566           (sign_extend:<DWI>
7567             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7568           (sign_extend:<DWI>
7569             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7570    (clobber (reg:CC FLAGS_REG))]
7571   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7572   "imul{<imodesuffix>}\t%2"
7573   [(set_attr "type" "imul")
7574    (set_attr "length_immediate" "0")
7575    (set (attr "athlon_decode")
7576      (if_then_else (eq_attr "cpu" "athlon")
7577         (const_string "vector")
7578         (const_string "double")))
7579    (set_attr "amdfam10_decode" "double")
7580    (set_attr "bdver1_decode" "direct")
7581    (set_attr "mode" "<MODE>")])
7583 (define_insn "*<u>mulqihi3_1"
7584   [(set (match_operand:HI 0 "register_operand" "=a")
7585         (mult:HI
7586           (any_extend:HI
7587             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7588           (any_extend:HI
7589             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7590    (clobber (reg:CC FLAGS_REG))]
7591   "TARGET_QIMODE_MATH
7592    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7593   "<sgnprefix>mul{b}\t%2"
7594   [(set_attr "type" "imul")
7595    (set_attr "length_immediate" "0")
7596    (set (attr "athlon_decode")
7597      (if_then_else (eq_attr "cpu" "athlon")
7598         (const_string "vector")
7599         (const_string "direct")))
7600    (set_attr "amdfam10_decode" "direct")
7601    (set_attr "bdver1_decode" "direct")
7602    (set_attr "mode" "QI")])
7604 (define_expand "<s>mul<mode>3_highpart"
7605   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7606                    (truncate:SWI48
7607                      (lshiftrt:<DWI>
7608                        (mult:<DWI>
7609                          (any_extend:<DWI>
7610                            (match_operand:SWI48 1 "nonimmediate_operand"))
7611                          (any_extend:<DWI>
7612                            (match_operand:SWI48 2 "register_operand")))
7613                        (match_dup 3))))
7614               (clobber (match_scratch:SWI48 4))
7615               (clobber (reg:CC FLAGS_REG))])]
7616   ""
7617   "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7619 (define_insn "*<s>muldi3_highpart_1"
7620   [(set (match_operand:DI 0 "register_operand" "=d")
7621         (truncate:DI
7622           (lshiftrt:TI
7623             (mult:TI
7624               (any_extend:TI
7625                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7626               (any_extend:TI
7627                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7628             (const_int 64))))
7629    (clobber (match_scratch:DI 3 "=1"))
7630    (clobber (reg:CC FLAGS_REG))]
7631   "TARGET_64BIT
7632    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7633   "<sgnprefix>mul{q}\t%2"
7634   [(set_attr "type" "imul")
7635    (set_attr "length_immediate" "0")
7636    (set (attr "athlon_decode")
7637      (if_then_else (eq_attr "cpu" "athlon")
7638         (const_string "vector")
7639         (const_string "double")))
7640    (set_attr "amdfam10_decode" "double")
7641    (set_attr "bdver1_decode" "direct")
7642    (set_attr "mode" "DI")])
7644 (define_insn "*<s>mulsi3_highpart_zext"
7645   [(set (match_operand:DI 0 "register_operand" "=d")
7646         (zero_extend:DI (truncate:SI
7647           (lshiftrt:DI
7648             (mult:DI (any_extend:DI
7649                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7650                      (any_extend:DI
7651                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7652             (const_int 32)))))
7653    (clobber (match_scratch:SI 3 "=1"))
7654    (clobber (reg:CC FLAGS_REG))]
7655   "TARGET_64BIT
7656    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7657   "<sgnprefix>mul{l}\t%2"
7658   [(set_attr "type" "imul")
7659    (set_attr "length_immediate" "0")
7660    (set (attr "athlon_decode")
7661      (if_then_else (eq_attr "cpu" "athlon")
7662         (const_string "vector")
7663         (const_string "double")))
7664    (set_attr "amdfam10_decode" "double")
7665    (set_attr "bdver1_decode" "direct")
7666    (set_attr "mode" "SI")])
7668 (define_insn "*<s>mulsi3_highpart_1"
7669   [(set (match_operand:SI 0 "register_operand" "=d")
7670         (truncate:SI
7671           (lshiftrt:DI
7672             (mult:DI
7673               (any_extend:DI
7674                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7675               (any_extend:DI
7676                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7677             (const_int 32))))
7678    (clobber (match_scratch:SI 3 "=1"))
7679    (clobber (reg:CC FLAGS_REG))]
7680   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7681   "<sgnprefix>mul{l}\t%2"
7682   [(set_attr "type" "imul")
7683    (set_attr "length_immediate" "0")
7684    (set (attr "athlon_decode")
7685      (if_then_else (eq_attr "cpu" "athlon")
7686         (const_string "vector")
7687         (const_string "double")))
7688    (set_attr "amdfam10_decode" "double")
7689    (set_attr "bdver1_decode" "direct")
7690    (set_attr "mode" "SI")])
7692 ;; The patterns that match these are at the end of this file.
7694 (define_expand "mulxf3"
7695   [(set (match_operand:XF 0 "register_operand")
7696         (mult:XF (match_operand:XF 1 "register_operand")
7697                  (match_operand:XF 2 "register_operand")))]
7698   "TARGET_80387")
7700 (define_expand "mul<mode>3"
7701   [(set (match_operand:MODEF 0 "register_operand")
7702         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7703                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7704   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7705     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7707 ;; Divide instructions
7709 ;; The patterns that match these are at the end of this file.
7711 (define_expand "divxf3"
7712   [(set (match_operand:XF 0 "register_operand")
7713         (div:XF (match_operand:XF 1 "register_operand")
7714                 (match_operand:XF 2 "register_operand")))]
7715   "TARGET_80387")
7717 (define_expand "div<mode>3"
7718   [(set (match_operand:MODEF 0 "register_operand")
7719         (div:MODEF (match_operand:MODEF 1 "register_operand")
7720                    (match_operand:MODEF 2 "nonimmediate_operand")))]
7721   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7722     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7724   if (<MODE>mode == SFmode
7725       && TARGET_SSE && TARGET_SSE_MATH
7726       && TARGET_RECIP_DIV
7727       && optimize_insn_for_speed_p ()
7728       && flag_finite_math_only && !flag_trapping_math
7729       && flag_unsafe_math_optimizations)
7730     {
7731       ix86_emit_swdivsf (operands[0], operands[1],
7732                          operands[2], SFmode);
7733       DONE;
7734     }
7737 ;; Divmod instructions.
7739 (define_expand "divmod<mode>4"
7740   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7741                    (div:SWIM248
7742                      (match_operand:SWIM248 1 "register_operand")
7743                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7744               (set (match_operand:SWIM248 3 "register_operand")
7745                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7746               (clobber (reg:CC FLAGS_REG))])])
7748 ;; Split with 8bit unsigned divide:
7749 ;;      if (dividend an divisor are in [0-255])
7750 ;;         use 8bit unsigned integer divide
7751 ;;       else
7752 ;;         use original integer divide
7753 (define_split
7754   [(set (match_operand:SWI48 0 "register_operand")
7755         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7756                     (match_operand:SWI48 3 "nonimmediate_operand")))
7757    (set (match_operand:SWI48 1 "register_operand")
7758         (mod:SWI48 (match_dup 2) (match_dup 3)))
7759    (clobber (reg:CC FLAGS_REG))]
7760   "TARGET_USE_8BIT_IDIV
7761    && TARGET_QIMODE_MATH
7762    && can_create_pseudo_p ()
7763    && !optimize_insn_for_size_p ()"
7764   [(const_int 0)]
7765   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7767 (define_split
7768   [(set (match_operand:DI 0 "register_operand")
7769         (zero_extend:DI
7770           (div:SI (match_operand:SI 2 "register_operand")
7771                   (match_operand:SI 3 "nonimmediate_operand"))))
7772    (set (match_operand:SI 1 "register_operand")
7773         (mod:SI (match_dup 2) (match_dup 3)))
7774    (clobber (reg:CC FLAGS_REG))]
7775   "TARGET_USE_8BIT_IDIV
7776    && TARGET_QIMODE_MATH
7777    && can_create_pseudo_p ()
7778    && !optimize_insn_for_size_p ()"
7779   [(const_int 0)]
7780   "ix86_split_idivmod (SImode, operands, true); DONE;")
7782 (define_split
7783   [(set (match_operand:DI 1 "register_operand")
7784         (zero_extend:DI
7785           (mod:SI (match_operand:SI 2 "register_operand")
7786                   (match_operand:SI 3 "nonimmediate_operand"))))
7787    (set (match_operand:SI 0 "register_operand")
7788         (div:SI  (match_dup 2) (match_dup 3)))
7789    (clobber (reg:CC FLAGS_REG))]
7790   "TARGET_USE_8BIT_IDIV
7791    && TARGET_QIMODE_MATH
7792    && can_create_pseudo_p ()
7793    && !optimize_insn_for_size_p ()"
7794   [(const_int 0)]
7795   "ix86_split_idivmod (SImode, operands, true); DONE;")
7797 (define_insn_and_split "divmod<mode>4_1"
7798   [(set (match_operand:SWI48 0 "register_operand" "=a")
7799         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7800                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7801    (set (match_operand:SWI48 1 "register_operand" "=&d")
7802         (mod:SWI48 (match_dup 2) (match_dup 3)))
7803    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7804    (clobber (reg:CC FLAGS_REG))]
7805   ""
7806   "#"
7807   "reload_completed"
7808   [(parallel [(set (match_dup 1)
7809                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7810               (clobber (reg:CC FLAGS_REG))])
7811    (parallel [(set (match_dup 0)
7812                    (div:SWI48 (match_dup 2) (match_dup 3)))
7813               (set (match_dup 1)
7814                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7815               (use (match_dup 1))
7816               (clobber (reg:CC FLAGS_REG))])]
7818   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7820   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7821     operands[4] = operands[2];
7822   else
7823     {
7824       /* Avoid use of cltd in favor of a mov+shift.  */
7825       emit_move_insn (operands[1], operands[2]);
7826       operands[4] = operands[1];
7827     }
7829   [(set_attr "type" "multi")
7830    (set_attr "mode" "<MODE>")])
7832 (define_insn_and_split "divmodsi4_zext_1"
7833   [(set (match_operand:DI 0 "register_operand" "=a")
7834         (zero_extend:DI
7835           (div:SI (match_operand:SI 2 "register_operand" "0")
7836                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7837    (set (match_operand:SI 1 "register_operand" "=&d")
7838         (mod:SI (match_dup 2) (match_dup 3)))
7839    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7840    (clobber (reg:CC FLAGS_REG))]
7841   "TARGET_64BIT"
7842   "#"
7843   "reload_completed"
7844   [(parallel [(set (match_dup 1)
7845                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7846               (clobber (reg:CC FLAGS_REG))])
7847    (parallel [(set (match_dup 0)
7848                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7849               (set (match_dup 1)
7850                    (mod:SI (match_dup 2) (match_dup 3)))
7851               (use (match_dup 1))
7852               (clobber (reg:CC FLAGS_REG))])]
7854   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7856   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7857     operands[4] = operands[2];
7858   else
7859     {
7860       /* Avoid use of cltd in favor of a mov+shift.  */
7861       emit_move_insn (operands[1], operands[2]);
7862       operands[4] = operands[1];
7863     }
7865   [(set_attr "type" "multi")
7866    (set_attr "mode" "SI")])
7868 (define_insn_and_split "divmodsi4_zext_2"
7869   [(set (match_operand:DI 1 "register_operand" "=&d")
7870         (zero_extend:DI
7871           (mod:SI (match_operand:SI 2 "register_operand" "0")
7872                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7873    (set (match_operand:SI 0 "register_operand" "=a")
7874         (div:SI (match_dup 2) (match_dup 3)))
7875    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7876    (clobber (reg:CC FLAGS_REG))]
7877   "TARGET_64BIT"
7878   "#"
7879   "reload_completed"
7880   [(parallel [(set (match_dup 6)
7881                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7882               (clobber (reg:CC FLAGS_REG))])
7883    (parallel [(set (match_dup 1)
7884                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7885               (set (match_dup 0)
7886                    (div:SI (match_dup 2) (match_dup 3)))
7887               (use (match_dup 6))
7888               (clobber (reg:CC FLAGS_REG))])]
7890   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7891   operands[6] = gen_lowpart (SImode, operands[1]);
7893   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7894     operands[4] = operands[2];
7895   else
7896     {
7897       /* Avoid use of cltd in favor of a mov+shift.  */
7898       emit_move_insn (operands[6], operands[2]);
7899       operands[4] = operands[6];
7900     }
7902   [(set_attr "type" "multi")
7903    (set_attr "mode" "SI")])
7905 (define_insn_and_split "*divmod<mode>4"
7906   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7907         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7908                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7909    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7910         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7911    (clobber (reg:CC FLAGS_REG))]
7912   ""
7913   "#"
7914   "reload_completed"
7915   [(parallel [(set (match_dup 1)
7916                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7917               (clobber (reg:CC FLAGS_REG))])
7918    (parallel [(set (match_dup 0)
7919                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7920               (set (match_dup 1)
7921                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7922               (use (match_dup 1))
7923               (clobber (reg:CC FLAGS_REG))])]
7925   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7927   if (<MODE>mode != HImode
7928       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7929     operands[4] = operands[2];
7930   else
7931     {
7932       /* Avoid use of cltd in favor of a mov+shift.  */
7933       emit_move_insn (operands[1], operands[2]);
7934       operands[4] = operands[1];
7935     }
7937   [(set_attr "type" "multi")
7938    (set_attr "mode" "<MODE>")])
7940 (define_insn_and_split "*divmodsi4_zext_1"
7941   [(set (match_operand:DI 0 "register_operand" "=a")
7942         (zero_extend:DI
7943           (div:SI (match_operand:SI 2 "register_operand" "0")
7944                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7945    (set (match_operand:SI 1 "register_operand" "=&d")
7946         (mod:SI (match_dup 2) (match_dup 3)))
7947    (clobber (reg:CC FLAGS_REG))]
7948   "TARGET_64BIT"
7949   "#"
7950   "reload_completed"
7951   [(parallel [(set (match_dup 1)
7952                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7953               (clobber (reg:CC FLAGS_REG))])
7954    (parallel [(set (match_dup 0)
7955                    (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7956               (set (match_dup 1)
7957                    (mod:SI (match_dup 2) (match_dup 3)))
7958               (use (match_dup 1))
7959               (clobber (reg:CC FLAGS_REG))])]
7961   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7963   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7964     operands[4] = operands[2];
7965   else
7966     {
7967       /* Avoid use of cltd in favor of a mov+shift.  */
7968       emit_move_insn (operands[1], operands[2]);
7969       operands[4] = operands[1];
7970     }
7972   [(set_attr "type" "multi")
7973    (set_attr "mode" "SI")])
7975 (define_insn_and_split "*divmodsi4_zext_2"
7976   [(set (match_operand:DI 1 "register_operand" "=&d")
7977         (zero_extend:DI
7978           (mod:SI (match_operand:SI 2 "register_operand" "0")
7979                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7980    (set (match_operand:SI 0 "register_operand" "=a")
7981         (div:SI (match_dup 2) (match_dup 3)))
7982    (clobber (reg:CC FLAGS_REG))]
7983   "TARGET_64BIT"
7984   "#"
7985   "reload_completed"
7986   [(parallel [(set (match_dup 6)
7987                    (ashiftrt:SI (match_dup 4) (match_dup 5)))
7988               (clobber (reg:CC FLAGS_REG))])
7989    (parallel [(set (match_dup 1)
7990                    (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7991               (set (match_dup 0)
7992                    (div:SI (match_dup 2) (match_dup 3)))
7993               (use (match_dup 6))
7994               (clobber (reg:CC FLAGS_REG))])]
7996   operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7997   operands[6] = gen_lowpart (SImode, operands[1]);
7999   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8000     operands[4] = operands[2];
8001   else
8002     {
8003       /* Avoid use of cltd in favor of a mov+shift.  */
8004       emit_move_insn (operands[6], operands[2]);
8005       operands[4] = operands[6];
8006     }
8008   [(set_attr "type" "multi")
8009    (set_attr "mode" "SI")])
8011 (define_insn "*divmod<mode>4_noext"
8012   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8013         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8014                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8015    (set (match_operand:SWIM248 1 "register_operand" "=d")
8016         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8017    (use (match_operand:SWIM248 4 "register_operand" "1"))
8018    (clobber (reg:CC FLAGS_REG))]
8019   ""
8020   "idiv{<imodesuffix>}\t%3"
8021   [(set_attr "type" "idiv")
8022    (set_attr "mode" "<MODE>")])
8024 (define_insn "*divmodsi4_noext_zext_1"
8025   [(set (match_operand:DI 0 "register_operand" "=a")
8026         (zero_extend:DI
8027           (div:SI (match_operand:SI 2 "register_operand" "0")
8028                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8029    (set (match_operand:SI 1 "register_operand" "=d")
8030         (mod:SI (match_dup 2) (match_dup 3)))
8031    (use (match_operand:SI 4 "register_operand" "1"))
8032    (clobber (reg:CC FLAGS_REG))]
8033   "TARGET_64BIT"
8034   "idiv{l}\t%3"
8035   [(set_attr "type" "idiv")
8036    (set_attr "mode" "SI")])
8038 (define_insn "*divmodsi4_noext_zext_2"
8039   [(set (match_operand:DI 1 "register_operand" "=d")
8040         (zero_extend:DI
8041           (mod:SI (match_operand:SI 2 "register_operand" "0")
8042                   (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8043    (set (match_operand:SI 0 "register_operand" "=a")
8044         (div:SI (match_dup 2) (match_dup 3)))
8045    (use (match_operand:SI 4 "register_operand" "1"))
8046    (clobber (reg:CC FLAGS_REG))]
8047   "TARGET_64BIT"
8048   "idiv{l}\t%3"
8049   [(set_attr "type" "idiv")
8050    (set_attr "mode" "SI")])
8052 (define_expand "divmodqi4"
8053   [(parallel [(set (match_operand:QI 0 "register_operand")
8054                    (div:QI
8055                      (match_operand:QI 1 "register_operand")
8056                      (match_operand:QI 2 "nonimmediate_operand")))
8057               (set (match_operand:QI 3 "register_operand")
8058                    (mod:QI (match_dup 1) (match_dup 2)))
8059               (clobber (reg:CC FLAGS_REG))])]
8060   "TARGET_QIMODE_MATH"
8062   rtx div, mod;
8063   rtx tmp0, tmp1;
8064   
8065   tmp0 = gen_reg_rtx (HImode);
8066   tmp1 = gen_reg_rtx (HImode);
8068   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8069   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8070   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8072   /* Extract remainder from AH.  */
8073   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8074   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8075   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8077   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8078   set_unique_reg_note (insn, REG_EQUAL, mod);
8080   /* Extract quotient from AL.  */
8081   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8083   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8084   set_unique_reg_note (insn, REG_EQUAL, div);
8086   DONE;
8089 ;; Divide AX by r/m8, with result stored in
8090 ;; AL <- Quotient
8091 ;; AH <- Remainder
8092 ;; Change div/mod to HImode and extend the second argument to HImode
8093 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
8094 ;; combine may fail.
8095 (define_insn "divmodhiqi3"
8096   [(set (match_operand:HI 0 "register_operand" "=a")
8097         (ior:HI
8098           (ashift:HI
8099             (zero_extend:HI
8100               (truncate:QI
8101                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8102                         (sign_extend:HI
8103                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8104             (const_int 8))
8105           (zero_extend:HI
8106             (truncate:QI
8107               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8108    (clobber (reg:CC FLAGS_REG))]
8109   "TARGET_QIMODE_MATH"
8110   "idiv{b}\t%2"
8111   [(set_attr "type" "idiv")
8112    (set_attr "mode" "QI")])
8114 (define_expand "udivmod<mode>4"
8115   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8116                    (udiv:SWIM248
8117                      (match_operand:SWIM248 1 "register_operand")
8118                      (match_operand:SWIM248 2 "nonimmediate_operand")))
8119               (set (match_operand:SWIM248 3 "register_operand")
8120                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8121               (clobber (reg:CC FLAGS_REG))])])
8123 ;; Split with 8bit unsigned divide:
8124 ;;      if (dividend an divisor are in [0-255])
8125 ;;         use 8bit unsigned integer divide
8126 ;;       else
8127 ;;         use original integer divide
8128 (define_split
8129   [(set (match_operand:SWI48 0 "register_operand")
8130         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8131                     (match_operand:SWI48 3 "nonimmediate_operand")))
8132    (set (match_operand:SWI48 1 "register_operand")
8133         (umod:SWI48 (match_dup 2) (match_dup 3)))
8134    (clobber (reg:CC FLAGS_REG))]
8135   "TARGET_USE_8BIT_IDIV
8136    && TARGET_QIMODE_MATH
8137    && can_create_pseudo_p ()
8138    && !optimize_insn_for_size_p ()"
8139   [(const_int 0)]
8140   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8142 (define_split
8143   [(set (match_operand:DI 0 "register_operand")
8144         (zero_extend:DI
8145           (udiv:SI (match_operand:SI 2 "register_operand")
8146                    (match_operand:SI 3 "nonimmediate_operand"))))
8147    (set (match_operand:SI 1 "register_operand")
8148         (umod:SI (match_dup 2) (match_dup 3)))
8149    (clobber (reg:CC FLAGS_REG))]
8150   "TARGET_64BIT
8151    && TARGET_USE_8BIT_IDIV
8152    && TARGET_QIMODE_MATH
8153    && can_create_pseudo_p ()
8154    && !optimize_insn_for_size_p ()"
8155   [(const_int 0)]
8156   "ix86_split_idivmod (SImode, operands, false); DONE;")
8158 (define_split
8159   [(set (match_operand:DI 1 "register_operand")
8160         (zero_extend:DI
8161           (umod:SI (match_operand:SI 2 "register_operand")
8162                    (match_operand:SI 3 "nonimmediate_operand"))))
8163    (set (match_operand:SI 0 "register_operand")
8164         (udiv:SI (match_dup 2) (match_dup 3)))
8165    (clobber (reg:CC FLAGS_REG))]
8166   "TARGET_64BIT
8167    && TARGET_USE_8BIT_IDIV
8168    && TARGET_QIMODE_MATH
8169    && can_create_pseudo_p ()
8170    && !optimize_insn_for_size_p ()"
8171   [(const_int 0)]
8172   "ix86_split_idivmod (SImode, operands, false); DONE;")
8174 (define_insn_and_split "udivmod<mode>4_1"
8175   [(set (match_operand:SWI48 0 "register_operand" "=a")
8176         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8177                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8178    (set (match_operand:SWI48 1 "register_operand" "=&d")
8179         (umod:SWI48 (match_dup 2) (match_dup 3)))
8180    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8181    (clobber (reg:CC FLAGS_REG))]
8182   ""
8183   "#"
8184   "reload_completed"
8185   [(set (match_dup 1) (const_int 0))
8186    (parallel [(set (match_dup 0)
8187                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
8188               (set (match_dup 1)
8189                    (umod:SWI48 (match_dup 2) (match_dup 3)))
8190               (use (match_dup 1))
8191               (clobber (reg:CC FLAGS_REG))])]
8192   ""
8193   [(set_attr "type" "multi")
8194    (set_attr "mode" "<MODE>")])
8196 (define_insn_and_split "udivmodsi4_zext_1"
8197   [(set (match_operand:DI 0 "register_operand" "=a")
8198         (zero_extend:DI
8199           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8200                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8201    (set (match_operand:SI 1 "register_operand" "=&d")
8202         (umod:SI (match_dup 2) (match_dup 3)))
8203    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8204    (clobber (reg:CC FLAGS_REG))]
8205   "TARGET_64BIT"
8206   "#"
8207   "reload_completed"
8208   [(set (match_dup 1) (const_int 0))
8209    (parallel [(set (match_dup 0)
8210                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8211               (set (match_dup 1)
8212                    (umod:SI (match_dup 2) (match_dup 3)))
8213               (use (match_dup 1))
8214               (clobber (reg:CC FLAGS_REG))])]
8215   ""
8216   [(set_attr "type" "multi")
8217    (set_attr "mode" "SI")])
8219 (define_insn_and_split "udivmodsi4_zext_2"
8220   [(set (match_operand:DI 1 "register_operand" "=&d")
8221         (zero_extend:DI
8222           (umod:SI (match_operand:SI 2 "register_operand" "0")
8223                  (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8224    (set (match_operand:SI 0 "register_operand" "=a")
8225         (udiv:SI (match_dup 2) (match_dup 3)))
8226    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8227    (clobber (reg:CC FLAGS_REG))]
8228   "TARGET_64BIT"
8229   "#"
8230   "reload_completed"
8231   [(set (match_dup 4) (const_int 0))
8232    (parallel [(set (match_dup 1)
8233                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8234               (set (match_dup 0)
8235                    (udiv:SI (match_dup 2) (match_dup 3)))
8236               (use (match_dup 4))
8237               (clobber (reg:CC FLAGS_REG))])]
8238   "operands[4] = gen_lowpart (SImode, operands[1]);"
8239   [(set_attr "type" "multi")
8240    (set_attr "mode" "SI")])
8242 (define_insn_and_split "*udivmod<mode>4"
8243   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8244         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8245                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8246    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8247         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8248    (clobber (reg:CC FLAGS_REG))]
8249   ""
8250   "#"
8251   "reload_completed"
8252   [(set (match_dup 1) (const_int 0))
8253    (parallel [(set (match_dup 0)
8254                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8255               (set (match_dup 1)
8256                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8257               (use (match_dup 1))
8258               (clobber (reg:CC FLAGS_REG))])]
8259   ""
8260   [(set_attr "type" "multi")
8261    (set_attr "mode" "<MODE>")])
8263 (define_insn_and_split "*udivmodsi4_zext_1"
8264   [(set (match_operand:DI 0 "register_operand" "=a")
8265         (zero_extend:DI
8266           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8267                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8268    (set (match_operand:SI 1 "register_operand" "=&d")
8269         (umod:SI (match_dup 2) (match_dup 3)))
8270    (clobber (reg:CC FLAGS_REG))]
8271   "TARGET_64BIT"
8272   "#"
8273   "reload_completed"
8274   [(set (match_dup 1) (const_int 0))
8275    (parallel [(set (match_dup 0)
8276                    (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8277               (set (match_dup 1)
8278                    (umod:SI (match_dup 2) (match_dup 3)))
8279               (use (match_dup 1))
8280               (clobber (reg:CC FLAGS_REG))])]
8281   ""
8282   [(set_attr "type" "multi")
8283    (set_attr "mode" "SI")])
8285 (define_insn_and_split "*udivmodsi4_zext_2"
8286   [(set (match_operand:DI 1 "register_operand" "=&d")
8287         (zero_extend:DI
8288           (umod:SI (match_operand:SI 2 "register_operand" "0")
8289                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8290    (set (match_operand:SI 0 "register_operand" "=a")
8291         (udiv:SI (match_dup 2) (match_dup 3)))
8292    (clobber (reg:CC FLAGS_REG))]
8293   "TARGET_64BIT"
8294   "#"
8295   "reload_completed"
8296   [(set (match_dup 4) (const_int 0))
8297    (parallel [(set (match_dup 1)
8298                    (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8299               (set (match_dup 0)
8300                    (udiv:SI (match_dup 2) (match_dup 3)))
8301               (use (match_dup 4))
8302               (clobber (reg:CC FLAGS_REG))])]
8303   "operands[4] = gen_lowpart (SImode, operands[1]);"
8304   [(set_attr "type" "multi")
8305    (set_attr "mode" "SI")])
8307 ;; Optimize division or modulo by constant power of 2, if the constant
8308 ;; materializes only after expansion.
8309 (define_insn_and_split "*udivmod<mode>4_pow2"
8310   [(set (match_operand:SWI48 0 "register_operand" "=r")
8311         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8312                     (match_operand:SWI48 3 "const_int_operand" "n")))
8313    (set (match_operand:SWI48 1 "register_operand" "=r")
8314         (umod:SWI48 (match_dup 2) (match_dup 3)))
8315    (clobber (reg:CC FLAGS_REG))]
8316   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8317    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8318   "#"
8319   "&& 1"
8320   [(set (match_dup 1) (match_dup 2))
8321    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8322               (clobber (reg:CC FLAGS_REG))])
8323    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8324               (clobber (reg:CC FLAGS_REG))])]
8326   int v = exact_log2 (UINTVAL (operands[3]));
8327   operands[4] = GEN_INT (v);
8328   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8330   [(set_attr "type" "multi")
8331    (set_attr "mode" "<MODE>")])
8333 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8334   [(set (match_operand:DI 0 "register_operand" "=r")
8335         (zero_extend:DI
8336           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8337                    (match_operand:SI 3 "const_int_operand" "n"))))
8338    (set (match_operand:SI 1 "register_operand" "=r")
8339         (umod:SI (match_dup 2) (match_dup 3)))
8340    (clobber (reg:CC FLAGS_REG))]
8341   "TARGET_64BIT
8342    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8343    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8344   "#"
8345   "&& 1"
8346   [(set (match_dup 1) (match_dup 2))
8347    (parallel [(set (match_dup 0)
8348                    (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8349               (clobber (reg:CC FLAGS_REG))])
8350    (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8351               (clobber (reg:CC FLAGS_REG))])]
8353   int v = exact_log2 (UINTVAL (operands[3]));
8354   operands[4] = GEN_INT (v);
8355   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8357   [(set_attr "type" "multi")
8358    (set_attr "mode" "SI")])
8360 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8361   [(set (match_operand:DI 1 "register_operand" "=r")
8362         (zero_extend:DI
8363           (umod:SI (match_operand:SI 2 "register_operand" "0")
8364                    (match_operand:SI 3 "const_int_operand" "n"))))
8365    (set (match_operand:SI 0 "register_operand" "=r")
8366         (umod:SI (match_dup 2) (match_dup 3)))
8367    (clobber (reg:CC FLAGS_REG))]
8368   "TARGET_64BIT
8369    && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8370    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8371   "#"
8372   "&& 1"
8373   [(set (match_dup 1) (match_dup 2))
8374    (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8375               (clobber (reg:CC FLAGS_REG))])
8376    (parallel [(set (match_dup 1)
8377                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8378               (clobber (reg:CC FLAGS_REG))])]
8380   int v = exact_log2 (UINTVAL (operands[3]));
8381   operands[4] = GEN_INT (v);
8382   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8384   [(set_attr "type" "multi")
8385    (set_attr "mode" "SI")])
8387 (define_insn "*udivmod<mode>4_noext"
8388   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8389         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8390                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8391    (set (match_operand:SWIM248 1 "register_operand" "=d")
8392         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8393    (use (match_operand:SWIM248 4 "register_operand" "1"))
8394    (clobber (reg:CC FLAGS_REG))]
8395   ""
8396   "div{<imodesuffix>}\t%3"
8397   [(set_attr "type" "idiv")
8398    (set_attr "mode" "<MODE>")])
8400 (define_insn "*udivmodsi4_noext_zext_1"
8401   [(set (match_operand:DI 0 "register_operand" "=a")
8402         (zero_extend:DI
8403           (udiv:SI (match_operand:SI 2 "register_operand" "0")
8404                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8405    (set (match_operand:SI 1 "register_operand" "=d")
8406         (umod:SI (match_dup 2) (match_dup 3)))
8407    (use (match_operand:SI 4 "register_operand" "1"))
8408    (clobber (reg:CC FLAGS_REG))]
8409   "TARGET_64BIT"
8410   "div{l}\t%3"
8411   [(set_attr "type" "idiv")
8412    (set_attr "mode" "SI")])
8414 (define_insn "*udivmodsi4_noext_zext_2"
8415   [(set (match_operand:DI 1 "register_operand" "=d")
8416         (zero_extend:DI
8417           (umod:SI (match_operand:SI 2 "register_operand" "0")
8418                    (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8419    (set (match_operand:SI 0 "register_operand" "=a")
8420         (udiv:SI (match_dup 2) (match_dup 3)))
8421    (use (match_operand:SI 4 "register_operand" "1"))
8422    (clobber (reg:CC FLAGS_REG))]
8423   "TARGET_64BIT"
8424   "div{l}\t%3"
8425   [(set_attr "type" "idiv")
8426    (set_attr "mode" "SI")])
8428 (define_expand "udivmodqi4"
8429   [(parallel [(set (match_operand:QI 0 "register_operand")
8430                    (udiv:QI
8431                      (match_operand:QI 1 "register_operand")
8432                      (match_operand:QI 2 "nonimmediate_operand")))
8433               (set (match_operand:QI 3 "register_operand")
8434                    (umod:QI (match_dup 1) (match_dup 2)))
8435               (clobber (reg:CC FLAGS_REG))])]
8436   "TARGET_QIMODE_MATH"
8438   rtx div, mod;
8439   rtx tmp0, tmp1;
8440   
8441   tmp0 = gen_reg_rtx (HImode);
8442   tmp1 = gen_reg_rtx (HImode);
8444   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
8445   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8446   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8448   /* Extract remainder from AH.  */
8449   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8450   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8451   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8453   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8454   set_unique_reg_note (insn, REG_EQUAL, mod);
8456   /* Extract quotient from AL.  */
8457   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8459   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8460   set_unique_reg_note (insn, REG_EQUAL, div);
8462   DONE;
8465 (define_insn "udivmodhiqi3"
8466   [(set (match_operand:HI 0 "register_operand" "=a")
8467         (ior:HI
8468           (ashift:HI
8469             (zero_extend:HI
8470               (truncate:QI
8471                 (mod:HI (match_operand:HI 1 "register_operand" "0")
8472                         (zero_extend:HI
8473                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8474             (const_int 8))
8475           (zero_extend:HI
8476             (truncate:QI
8477               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "TARGET_QIMODE_MATH"
8480   "div{b}\t%2"
8481   [(set_attr "type" "idiv")
8482    (set_attr "mode" "QI")])
8484 ;; We cannot use div/idiv for double division, because it causes
8485 ;; "division by zero" on the overflow and that's not what we expect
8486 ;; from truncate.  Because true (non truncating) double division is
8487 ;; never generated, we can't create this insn anyway.
8489 ;(define_insn ""
8490 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8491 ;       (truncate:SI
8492 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8493 ;                  (zero_extend:DI
8494 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8495 ;   (set (match_operand:SI 3 "register_operand" "=d")
8496 ;       (truncate:SI
8497 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8498 ;   (clobber (reg:CC FLAGS_REG))]
8499 ;  ""
8500 ;  "div{l}\t{%2, %0|%0, %2}"
8501 ;  [(set_attr "type" "idiv")])
8503 ;;- Logical AND instructions
8505 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8506 ;; Note that this excludes ah.
8508 (define_expand "testsi_ccno_1"
8509   [(set (reg:CCNO FLAGS_REG)
8510         (compare:CCNO
8511           (and:SI (match_operand:SI 0 "nonimmediate_operand")
8512                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
8513           (const_int 0)))])
8515 (define_expand "testqi_ccz_1"
8516   [(set (reg:CCZ FLAGS_REG)
8517         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8518                              (match_operand:QI 1 "nonmemory_operand"))
8519                  (const_int 0)))])
8521 (define_expand "testdi_ccno_1"
8522   [(set (reg:CCNO FLAGS_REG)
8523         (compare:CCNO
8524           (and:DI (match_operand:DI 0 "nonimmediate_operand")
8525                   (match_operand:DI 1 "x86_64_szext_general_operand"))
8526           (const_int 0)))]
8527   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8529 (define_insn "*testdi_1"
8530   [(set (reg FLAGS_REG)
8531         (compare
8532          (and:DI
8533           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8534           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8535          (const_int 0)))]
8536   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8537    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8538   "@
8539    test{l}\t{%k1, %k0|%k0, %k1}
8540    test{l}\t{%k1, %k0|%k0, %k1}
8541    test{q}\t{%1, %0|%0, %1}
8542    test{q}\t{%1, %0|%0, %1}
8543    test{q}\t{%1, %0|%0, %1}"
8544   [(set_attr "type" "test")
8545    (set_attr "modrm" "0,1,0,1,1")
8546    (set_attr "mode" "SI,SI,DI,DI,DI")])
8548 (define_insn "*testqi_1_maybe_si"
8549   [(set (reg FLAGS_REG)
8550         (compare
8551           (and:QI
8552             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8553             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8554           (const_int 0)))]
8555    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8556     && ix86_match_ccmode (insn,
8557                          CONST_INT_P (operands[1])
8558                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8560   if (which_alternative == 3)
8561     {
8562       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8563         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8564       return "test{l}\t{%1, %k0|%k0, %1}";
8565     }
8566   return "test{b}\t{%1, %0|%0, %1}";
8568   [(set_attr "type" "test")
8569    (set_attr "modrm" "0,1,1,1")
8570    (set_attr "mode" "QI,QI,QI,SI")
8571    (set_attr "pent_pair" "uv,np,uv,np")])
8573 (define_insn "*test<mode>_1"
8574   [(set (reg FLAGS_REG)
8575         (compare
8576          (and:SWI124
8577           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8578           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8579          (const_int 0)))]
8580   "ix86_match_ccmode (insn, CCNOmode)
8581    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8582   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8583   [(set_attr "type" "test")
8584    (set_attr "modrm" "0,1,1")
8585    (set_attr "mode" "<MODE>")
8586    (set_attr "pent_pair" "uv,np,uv")])
8588 (define_expand "testqi_ext_1_ccno"
8589   [(set (reg:CCNO FLAGS_REG)
8590         (compare:CCNO
8591           (and:QI
8592             (subreg:QI
8593               (zero_extract:SI (match_operand 0 "ext_register_operand")
8594                                (const_int 8)
8595                                (const_int 8)) 0)
8596               (match_operand 1 "const_int_operand"))
8597           (const_int 0)))])
8599 (define_insn "*testqi_ext_1"
8600   [(set (reg FLAGS_REG)
8601         (compare
8602           (and:QI
8603             (subreg:QI
8604               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8605                                (const_int 8)
8606                                (const_int 8)) 0)
8607             (match_operand:QI 1 "general_operand" "QnBc,m"))
8608           (const_int 0)))]
8609   "ix86_match_ccmode (insn, CCNOmode)"
8610   "test{b}\t{%1, %h0|%h0, %1}"
8611   [(set_attr "isa" "*,nox64")
8612    (set_attr "type" "test")
8613    (set_attr "mode" "QI")])
8615 (define_insn "*testqi_ext_2"
8616   [(set (reg FLAGS_REG)
8617         (compare
8618           (and:QI
8619             (subreg:QI
8620               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8621                                (const_int 8)
8622                                (const_int 8)) 0)
8623             (subreg:QI
8624               (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8625                                (const_int 8)
8626                                (const_int 8)) 0))
8627           (const_int 0)))]
8628   "ix86_match_ccmode (insn, CCNOmode)"
8629   "test{b}\t{%h1, %h0|%h0, %h1}"
8630   [(set_attr "type" "test")
8631    (set_attr "mode" "QI")])
8633 ;; Combine likes to form bit extractions for some tests.  Humor it.
8634 (define_insn_and_split "*testqi_ext_3"
8635   [(set (match_operand 0 "flags_reg_operand")
8636         (match_operator 1 "compare_operator"
8637           [(zero_extract:SWI248
8638              (match_operand 2 "nonimmediate_operand" "rm")
8639              (match_operand 3 "const_int_operand" "n")
8640              (match_operand 4 "const_int_operand" "n"))
8641            (const_int 0)]))]
8642   "ix86_match_ccmode (insn, CCNOmode)
8643    && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8644        || GET_MODE (operands[2]) == SImode
8645        || GET_MODE (operands[2]) == HImode
8646        || GET_MODE (operands[2]) == QImode)
8647    /* Ensure that resulting mask is zero or sign extended operand.  */
8648    && INTVAL (operands[4]) >= 0
8649    && ((INTVAL (operands[3]) > 0
8650         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8651        || (<MODE>mode == DImode
8652            && INTVAL (operands[3]) > 32
8653            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8654   "#"
8655   "&& 1"
8656   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8658   rtx val = operands[2];
8659   HOST_WIDE_INT len = INTVAL (operands[3]);
8660   HOST_WIDE_INT pos = INTVAL (operands[4]);
8661   machine_mode mode = GET_MODE (val);
8663   if (SUBREG_P (val))
8664     {
8665       machine_mode submode = GET_MODE (SUBREG_REG (val));
8667       /* Narrow paradoxical subregs to prevent partial register stalls.  */
8668       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8669           && GET_MODE_CLASS (submode) == MODE_INT)
8670         {
8671           val = SUBREG_REG (val);
8672           mode = submode;
8673         }
8674     }
8676   /* Small HImode tests can be converted to QImode.  */
8677   if (register_operand (val, HImode) && pos + len <= 8)
8678     {
8679       val = gen_lowpart (QImode, val);
8680       mode = QImode;
8681     }
8683   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8685   wide_int mask
8686     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8688   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8691 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8692 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8693 ;; this is relatively important trick.
8694 ;; Do the conversion only post-reload to avoid limiting of the register class
8695 ;; to QI regs.
8696 (define_split
8697   [(set (match_operand 0 "flags_reg_operand")
8698         (match_operator 1 "compare_operator"
8699           [(and (match_operand 2 "QIreg_operand")
8700                 (match_operand 3 "const_int_operand"))
8701            (const_int 0)]))]
8702    "reload_completed
8703     && GET_MODE (operands[2]) != QImode
8704     && ((ix86_match_ccmode (insn, CCZmode)
8705          && !(INTVAL (operands[3]) & ~(255 << 8)))
8706         || (ix86_match_ccmode (insn, CCNOmode)
8707             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8708   [(set (match_dup 0)
8709         (match_op_dup 1
8710           [(and:QI
8711              (subreg:QI
8712                (zero_extract:SI (match_dup 2)
8713                                 (const_int 8)
8714                                 (const_int 8)) 0)
8715              (match_dup 3))
8716            (const_int 0)]))]
8718   operands[2] = gen_lowpart (SImode, operands[2]);
8719   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8722 (define_split
8723   [(set (match_operand 0 "flags_reg_operand")
8724         (match_operator 1 "compare_operator"
8725           [(and (match_operand 2 "nonimmediate_operand")
8726                 (match_operand 3 "const_int_operand"))
8727            (const_int 0)]))]
8728    "reload_completed
8729     && GET_MODE (operands[2]) != QImode
8730     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8731     && ((ix86_match_ccmode (insn, CCZmode)
8732          && !(INTVAL (operands[3]) & ~255))
8733         || (ix86_match_ccmode (insn, CCNOmode)
8734             && !(INTVAL (operands[3]) & ~127)))"
8735   [(set (match_dup 0)
8736         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8737                          (const_int 0)]))]
8739   operands[2] = gen_lowpart (QImode, operands[2]);
8740   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8743 ;; %%% This used to optimize known byte-wide and operations to memory,
8744 ;; and sometimes to QImode registers.  If this is considered useful,
8745 ;; it should be done with splitters.
8747 (define_expand "and<mode>3"
8748   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8749         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8750                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8751   ""
8753   machine_mode mode = <MODE>mode;
8754   rtx (*insn) (rtx, rtx);
8756   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8757     {
8758       HOST_WIDE_INT ival = INTVAL (operands[2]);
8760       if (ival == (HOST_WIDE_INT) 0xffffffff)
8761         mode = SImode;
8762       else if (ival == 0xffff)
8763         mode = HImode;
8764       else if (ival == 0xff)
8765         mode = QImode;
8766       }
8768   if (mode == <MODE>mode)
8769     {
8770       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8771       DONE;
8772     }
8774   if (<MODE>mode == DImode)
8775     insn = (mode == SImode)
8776            ? gen_zero_extendsidi2
8777            : (mode == HImode)
8778            ? gen_zero_extendhidi2
8779            : gen_zero_extendqidi2;
8780   else if (<MODE>mode == SImode)
8781     insn = (mode == HImode)
8782            ? gen_zero_extendhisi2
8783            : gen_zero_extendqisi2;
8784   else if (<MODE>mode == HImode)
8785     insn = gen_zero_extendqihi2;
8786   else
8787     gcc_unreachable ();
8789   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8790   DONE;
8793 (define_insn_and_split "*anddi3_doubleword"
8794   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8795         (and:DI
8796          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8797          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8798    (clobber (reg:CC FLAGS_REG))]
8799   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8800    && ix86_binary_operator_ok (AND, DImode, operands)"
8801   "#"
8802   "&& reload_completed"
8803   [(const_int 0)]
8805   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8806   if (operands[2] == const0_rtx)
8807     {
8808       operands[1] = const0_rtx;
8809       ix86_expand_move (SImode, &operands[0]);
8810     }
8811   else if (operands[2] != constm1_rtx)
8812     ix86_expand_binary_operator (AND, SImode, &operands[0]);
8813   else if (operands[5] == constm1_rtx)
8814     emit_note (NOTE_INSN_DELETED);
8815   if (operands[5] == const0_rtx)
8816     {
8817       operands[4] = const0_rtx;
8818       ix86_expand_move (SImode, &operands[3]);
8819     }
8820   else if (operands[5] != constm1_rtx)
8821     ix86_expand_binary_operator (AND, SImode, &operands[3]);
8822   DONE;
8825 (define_insn "*anddi_1"
8826   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8827         (and:DI
8828          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8829          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8830    (clobber (reg:CC FLAGS_REG))]
8831   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8832   "@
8833    and{l}\t{%k2, %k0|%k0, %k2}
8834    and{q}\t{%2, %0|%0, %2}
8835    and{q}\t{%2, %0|%0, %2}
8836    #"
8837   [(set_attr "type" "alu,alu,alu,imovx")
8838    (set_attr "length_immediate" "*,*,*,0")
8839    (set (attr "prefix_rex")
8840      (if_then_else
8841        (and (eq_attr "type" "imovx")
8842             (and (match_test "INTVAL (operands[2]) == 0xff")
8843                  (match_operand 1 "ext_QIreg_operand")))
8844        (const_string "1")
8845        (const_string "*")))
8846    (set_attr "mode" "SI,DI,DI,SI")])
8848 (define_insn_and_split "*anddi_1_btr"
8849   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8850         (and:DI
8851          (match_operand:DI 1 "nonimmediate_operand" "%0")
8852          (match_operand:DI 2 "const_int_operand" "n")))
8853    (clobber (reg:CC FLAGS_REG))]
8854   "TARGET_64BIT && TARGET_USE_BT
8855    && ix86_binary_operator_ok (AND, DImode, operands)
8856    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8857   "#"
8858   "&& reload_completed"
8859   [(parallel [(set (zero_extract:DI (match_dup 0)
8860                                     (const_int 1)
8861                                     (match_dup 3))
8862                    (const_int 0))
8863               (clobber (reg:CC FLAGS_REG))])]
8864   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8865   [(set_attr "type" "alu1")
8866    (set_attr "prefix_0f" "1")
8867    (set_attr "znver1_decode" "double")
8868    (set_attr "mode" "DI")])
8870 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8871 (define_split
8872   [(set (match_operand:DI 0 "register_operand")
8873         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8874                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8875    (clobber (reg:CC FLAGS_REG))]
8876   "TARGET_64BIT"
8877   [(parallel [(set (match_dup 0)
8878                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8879               (clobber (reg:CC FLAGS_REG))])]
8880   "operands[2] = gen_lowpart (SImode, operands[2]);")
8882 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8883 (define_insn "*andsi_1_zext"
8884   [(set (match_operand:DI 0 "register_operand" "=r")
8885         (zero_extend:DI
8886           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8887                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8888    (clobber (reg:CC FLAGS_REG))]
8889   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8890   "and{l}\t{%2, %k0|%k0, %2}"
8891   [(set_attr "type" "alu")
8892    (set_attr "mode" "SI")])
8894 (define_insn "*and<mode>_1"
8895   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8896         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8897                    (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8898    (clobber (reg:CC FLAGS_REG))]
8899   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8900   "@
8901    and{<imodesuffix>}\t{%2, %0|%0, %2}
8902    and{<imodesuffix>}\t{%2, %0|%0, %2}
8903    #"
8904   [(set_attr "type" "alu,alu,imovx")
8905    (set_attr "length_immediate" "*,*,0")
8906    (set (attr "prefix_rex")
8907      (if_then_else
8908        (and (eq_attr "type" "imovx")
8909             (and (match_test "INTVAL (operands[2]) == 0xff")
8910                  (match_operand 1 "ext_QIreg_operand")))
8911        (const_string "1")
8912        (const_string "*")))
8913    (set_attr "mode" "<MODE>,<MODE>,SI")])
8915 (define_insn "*andqi_1"
8916   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8917         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8918                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8919    (clobber (reg:CC FLAGS_REG))]
8920   "ix86_binary_operator_ok (AND, QImode, operands)"
8921   "@
8922    and{b}\t{%2, %0|%0, %2}
8923    and{b}\t{%2, %0|%0, %2}
8924    and{l}\t{%k2, %k0|%k0, %k2}"
8925   [(set_attr "type" "alu")
8926    (set_attr "mode" "QI,QI,SI")
8927    ;; Potential partial reg stall on alternative 2.
8928    (set (attr "preferred_for_speed")
8929      (cond [(eq_attr "alternative" "2")
8930               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8931            (symbol_ref "true")))])
8933 (define_insn "*andqi_1_slp"
8934   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8935         (and:QI (match_dup 0)
8936                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8937    (clobber (reg:CC FLAGS_REG))]
8938   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8939    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8940   "and{b}\t{%1, %0|%0, %1}"
8941   [(set_attr "type" "alu1")
8942    (set_attr "mode" "QI")])
8944 (define_split
8945   [(set (match_operand:SWI248 0 "register_operand")
8946         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8947                     (match_operand:SWI248 2 "const_int_operand")))
8948    (clobber (reg:CC FLAGS_REG))]
8949   "reload_completed
8950    && (!REG_P (operands[1])
8951        || REGNO (operands[0]) != REGNO (operands[1]))"
8952   [(const_int 0)]
8954   HOST_WIDE_INT ival = INTVAL (operands[2]);
8955   machine_mode mode;
8956   rtx (*insn) (rtx, rtx);
8958   if (ival == (HOST_WIDE_INT) 0xffffffff)
8959     mode = SImode;
8960   else if (ival == 0xffff)
8961     mode = HImode;
8962   else
8963     {
8964       gcc_assert (ival == 0xff);
8965       mode = QImode;
8966     }
8968   if (<MODE>mode == DImode)
8969     insn = (mode == SImode)
8970            ? gen_zero_extendsidi2
8971            : (mode == HImode)
8972            ? gen_zero_extendhidi2
8973            : gen_zero_extendqidi2;
8974   else
8975     {
8976       if (<MODE>mode != SImode)
8977         /* Zero extend to SImode to avoid partial register stalls.  */
8978         operands[0] = gen_lowpart (SImode, operands[0]);
8980       insn = (mode == HImode)
8981              ? gen_zero_extendhisi2
8982              : gen_zero_extendqisi2;
8983     }
8984   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8985   DONE;
8988 (define_split
8989   [(set (match_operand:SWI48 0 "register_operand")
8990         (and:SWI48 (match_dup 0)
8991                    (const_int -65536)))
8992    (clobber (reg:CC FLAGS_REG))]
8993   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8994     || optimize_function_for_size_p (cfun)"
8995   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8996   "operands[1] = gen_lowpart (HImode, operands[0]);")
8998 (define_split
8999   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9000         (and:SWI248 (match_dup 0)
9001                     (const_int -256)))
9002    (clobber (reg:CC FLAGS_REG))]
9003   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9004    && reload_completed"
9005   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9006   "operands[1] = gen_lowpart (QImode, operands[0]);")
9008 (define_split
9009   [(set (match_operand:SWI248 0 "QIreg_operand")
9010         (and:SWI248 (match_dup 0)
9011                     (const_int -65281)))
9012    (clobber (reg:CC FLAGS_REG))]
9013   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9014    && reload_completed"
9015   [(parallel
9016      [(set (zero_extract:SI (match_dup 0)
9017                             (const_int 8)
9018                             (const_int 8))
9019            (subreg:SI
9020              (xor:QI
9021                (subreg:QI
9022                  (zero_extract:SI (match_dup 0)
9023                                   (const_int 8)
9024                                   (const_int 8)) 0)
9025                (subreg:QI
9026                  (zero_extract:SI (match_dup 0)
9027                                   (const_int 8)
9028                                   (const_int 8)) 0)) 0))
9029       (clobber (reg:CC FLAGS_REG))])]
9030   "operands[0] = gen_lowpart (SImode, operands[0]);")
9032 (define_insn "*anddi_2"
9033   [(set (reg FLAGS_REG)
9034         (compare
9035          (and:DI
9036           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9037           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9038          (const_int 0)))
9039    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9040         (and:DI (match_dup 1) (match_dup 2)))]
9041   "TARGET_64BIT
9042    && ix86_match_ccmode
9043         (insn,
9044          /* If we are going to emit andl instead of andq, and the operands[2]
9045             constant might have the SImode sign bit set, make sure the sign
9046             flag isn't tested, because the instruction will set the sign flag
9047             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
9048             conservatively assume it might have bit 31 set.  */
9049          (satisfies_constraint_Z (operands[2])
9050           && (!CONST_INT_P (operands[2])
9051               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9052          ? CCZmode : CCNOmode)
9053    && ix86_binary_operator_ok (AND, DImode, operands)"
9054   "@
9055    and{l}\t{%k2, %k0|%k0, %k2}
9056    and{q}\t{%2, %0|%0, %2}
9057    and{q}\t{%2, %0|%0, %2}"
9058   [(set_attr "type" "alu")
9059    (set_attr "mode" "SI,DI,DI")])
9061 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9062 (define_insn "*andsi_2_zext"
9063   [(set (reg FLAGS_REG)
9064         (compare (and:SI
9065                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9066                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
9067                  (const_int 0)))
9068    (set (match_operand:DI 0 "register_operand" "=r")
9069         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9070   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9071    && ix86_binary_operator_ok (AND, SImode, operands)"
9072   "and{l}\t{%2, %k0|%k0, %2}"
9073   [(set_attr "type" "alu")
9074    (set_attr "mode" "SI")])
9076 (define_insn "*andqi_2_maybe_si"
9077   [(set (reg FLAGS_REG)
9078         (compare (and:QI
9079                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9080                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9081                  (const_int 0)))
9082    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9083         (and:QI (match_dup 1) (match_dup 2)))]
9084   "ix86_binary_operator_ok (AND, QImode, operands)
9085    && ix86_match_ccmode (insn,
9086                          CONST_INT_P (operands[2])
9087                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9089   if (which_alternative == 2)
9090     {
9091       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9092         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9093       return "and{l}\t{%2, %k0|%k0, %2}";
9094     }
9095   return "and{b}\t{%2, %0|%0, %2}";
9097   [(set_attr "type" "alu")
9098    (set_attr "mode" "QI,QI,SI")])
9100 (define_insn "*and<mode>_2"
9101   [(set (reg FLAGS_REG)
9102         (compare (and:SWI124
9103                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9104                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9105                  (const_int 0)))
9106    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9107         (and:SWI124 (match_dup 1) (match_dup 2)))]
9108   "ix86_match_ccmode (insn, CCNOmode)
9109    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9110   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9111   [(set_attr "type" "alu")
9112    (set_attr "mode" "<MODE>")])
9114 (define_insn "*andqi_2_slp"
9115   [(set (reg FLAGS_REG)
9116         (compare (and:QI
9117                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9118                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9119                  (const_int 0)))
9120    (set (strict_low_part (match_dup 0))
9121         (and:QI (match_dup 0) (match_dup 1)))]
9122   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9123    && ix86_match_ccmode (insn, CCNOmode)
9124    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9125   "and{b}\t{%1, %0|%0, %1}"
9126   [(set_attr "type" "alu1")
9127    (set_attr "mode" "QI")])
9129 (define_insn "andqi_ext_1"
9130   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9131                          (const_int 8)
9132                          (const_int 8))
9133         (subreg:SI
9134           (and:QI
9135             (subreg:QI
9136               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9137                                (const_int 8)
9138                                (const_int 8)) 0)
9139             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9140    (clobber (reg:CC FLAGS_REG))]
9141   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9142    rtx_equal_p (operands[0], operands[1])"
9143   "and{b}\t{%2, %h0|%h0, %2}"
9144   [(set_attr "isa" "*,nox64")
9145    (set_attr "type" "alu")
9146    (set_attr "mode" "QI")])
9148 ;; Generated by peephole translating test to and.  This shows up
9149 ;; often in fp comparisons.
9150 (define_insn "*andqi_ext_1_cc"
9151   [(set (reg FLAGS_REG)
9152         (compare
9153           (and:QI
9154             (subreg:QI
9155               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9156                                (const_int 8)
9157                                (const_int 8)) 0)
9158             (match_operand:QI 2 "general_operand" "QnBc,m"))
9159           (const_int 0)))
9160    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9161                          (const_int 8)
9162                          (const_int 8))
9163         (subreg:SI
9164           (and:QI
9165             (subreg:QI
9166               (zero_extract:SI (match_dup 1)
9167                                (const_int 8)
9168                                (const_int 8)) 0)
9169             (match_dup 2)) 0))]
9170   "ix86_match_ccmode (insn, CCNOmode)
9171    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9172    && rtx_equal_p (operands[0], operands[1])"
9173   "and{b}\t{%2, %h0|%h0, %2}"
9174   [(set_attr "isa" "*,nox64")
9175    (set_attr "type" "alu")
9176    (set_attr "mode" "QI")])
9178 (define_insn "*andqi_ext_2"
9179   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9180                          (const_int 8)
9181                          (const_int 8))
9182         (subreg:SI
9183           (and:QI
9184             (subreg:QI
9185               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9186                                (const_int 8)
9187                                (const_int 8)) 0)
9188             (subreg:QI
9189               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9190                                (const_int 8)
9191                                (const_int 8)) 0)) 0))
9192    (clobber (reg:CC FLAGS_REG))]
9193   "/* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9194    rtx_equal_p (operands[0], operands[1])
9195    || rtx_equal_p (operands[0], operands[2])"
9196   "and{b}\t{%h2, %h0|%h0, %h2}"
9197   [(set_attr "type" "alu")
9198    (set_attr "mode" "QI")])
9200 ;; Convert wide AND instructions with immediate operand to shorter QImode
9201 ;; equivalents when possible.
9202 ;; Don't do the splitting with memory operands, since it introduces risk
9203 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9204 ;; for size, but that can (should?) be handled by generic code instead.
9205 (define_split
9206   [(set (match_operand:SWI248 0 "QIreg_operand")
9207         (and:SWI248 (match_operand:SWI248 1 "register_operand")
9208                     (match_operand:SWI248 2 "const_int_operand")))
9209    (clobber (reg:CC FLAGS_REG))]
9210    "reload_completed
9211     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9212     && !(~INTVAL (operands[2]) & ~(255 << 8))"
9213   [(parallel
9214      [(set (zero_extract:SI (match_dup 0)
9215                             (const_int 8)
9216                             (const_int 8))
9217            (subreg:SI
9218              (and:QI
9219                (subreg:QI
9220                  (zero_extract:SI (match_dup 1)
9221                                   (const_int 8)
9222                                   (const_int 8)) 0)
9223                (match_dup 2)) 0))
9224       (clobber (reg:CC FLAGS_REG))])]
9226   operands[0] = gen_lowpart (SImode, operands[0]);
9227   operands[1] = gen_lowpart (SImode, operands[1]);
9228   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9231 ;; Since AND can be encoded with sign extended immediate, this is only
9232 ;; profitable when 7th bit is not set.
9233 (define_split
9234   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9235         (and:SWI248 (match_operand:SWI248 1 "general_operand")
9236                     (match_operand:SWI248 2 "const_int_operand")))
9237    (clobber (reg:CC FLAGS_REG))]
9238    "reload_completed
9239     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9240     && !(~INTVAL (operands[2]) & ~255)
9241     && !(INTVAL (operands[2]) & 128)"
9242   [(parallel [(set (strict_low_part (match_dup 0))
9243                    (and:QI (match_dup 1)
9244                            (match_dup 2)))
9245               (clobber (reg:CC FLAGS_REG))])]
9247   operands[0] = gen_lowpart (QImode, operands[0]);
9248   operands[1] = gen_lowpart (QImode, operands[1]);
9249   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9252 (define_insn "*andndi3_doubleword"
9253   [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9254         (and:DI
9255           (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9256           (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9257    (clobber (reg:CC FLAGS_REG))]
9258   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9259   "#"
9260   [(set_attr "isa" "bmi,bmi,bmi,*")])
9262 (define_split
9263   [(set (match_operand:DI 0 "register_operand")
9264         (and:DI
9265           (not:DI (match_operand:DI 1 "register_operand"))
9266           (match_operand:DI 2 "nonimmediate_operand")))
9267    (clobber (reg:CC FLAGS_REG))]
9268   "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9269    && reload_completed"
9270   [(parallel [(set (match_dup 0)
9271                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9272               (clobber (reg:CC FLAGS_REG))])
9273    (parallel [(set (match_dup 3)
9274                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9275               (clobber (reg:CC FLAGS_REG))])]
9276   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9278 (define_split
9279   [(set (match_operand:DI 0 "register_operand")
9280         (and:DI
9281           (not:DI (match_dup 0))
9282           (match_operand:DI 1 "nonimmediate_operand")))
9283    (clobber (reg:CC FLAGS_REG))]
9284   "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9285    && reload_completed"
9286   [(set (match_dup 0) (not:SI (match_dup 0)))
9287    (parallel [(set (match_dup 0)
9288                    (and:SI (match_dup 0) (match_dup 1)))
9289               (clobber (reg:CC FLAGS_REG))])
9290    (set (match_dup 2) (not:SI (match_dup 2)))
9291    (parallel [(set (match_dup 2)
9292                    (and:SI (match_dup 2) (match_dup 3)))
9293               (clobber (reg:CC FLAGS_REG))])]
9294   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9296 (define_insn "*andn<mode>_1"
9297   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9298         (and:SWI48
9299           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9300           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9301    (clobber (reg:CC FLAGS_REG))]
9302   "TARGET_BMI"
9303   "andn\t{%2, %1, %0|%0, %1, %2}"
9304   [(set_attr "type" "bitmanip")
9305    (set_attr "btver2_decode" "direct, double")
9306    (set_attr "mode" "<MODE>")])
9308 (define_insn "*andn<mode>_1"
9309   [(set (match_operand:SWI12 0 "register_operand" "=r")
9310         (and:SWI12
9311           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9312           (match_operand:SWI12 2 "register_operand" "r")))
9313    (clobber (reg:CC FLAGS_REG))]
9314   "TARGET_BMI"
9315   "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9316   [(set_attr "type" "bitmanip")
9317    (set_attr "btver2_decode" "direct")
9318    (set_attr "mode" "SI")])
9320 (define_insn "*andn_<mode>_ccno"
9321   [(set (reg FLAGS_REG)
9322         (compare
9323           (and:SWI48
9324             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9325             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9326           (const_int 0)))
9327    (clobber (match_scratch:SWI48 0 "=r,r"))]
9328   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9329   "andn\t{%2, %1, %0|%0, %1, %2}"
9330   [(set_attr "type" "bitmanip")
9331    (set_attr "btver2_decode" "direct, double")
9332    (set_attr "mode" "<MODE>")])
9334 ;; Logical inclusive and exclusive OR instructions
9336 ;; %%% This used to optimize known byte-wide and operations to memory.
9337 ;; If this is considered useful, it should be done with splitters.
9339 (define_expand "<code><mode>3"
9340   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9341         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9342                              (match_operand:SWIM1248x 2 "<general_operand>")))]
9343   ""
9344   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9346 (define_insn_and_split "*<code>di3_doubleword"
9347   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9348         (any_or:DI
9349          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9350          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9351    (clobber (reg:CC FLAGS_REG))]
9352   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9353    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9354   "#"
9355   "&& reload_completed"
9356   [(const_int 0)]
9358   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9359   if (operands[2] == constm1_rtx)
9360     {
9361       if (<CODE> == IOR)
9362         {
9363           operands[1] = constm1_rtx;
9364           ix86_expand_move (SImode, &operands[0]);
9365         }
9366       else
9367         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9368     }
9369   else if (operands[2] != const0_rtx)
9370     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9371   else if (operands[5] == const0_rtx)
9372     emit_note (NOTE_INSN_DELETED);
9373   if (operands[5] == constm1_rtx)
9374     {
9375       if (<CODE> == IOR)
9376         {
9377           operands[4] = constm1_rtx;
9378           ix86_expand_move (SImode, &operands[3]);
9379         }
9380       else
9381         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9382     }
9383   else if (operands[5] != const0_rtx)
9384     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9385   DONE;
9388 (define_insn "*<code><mode>_1"
9389   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9390         (any_or:SWI248
9391          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9392          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9395   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9396   [(set_attr "type" "alu")
9397    (set_attr "mode" "<MODE>")])
9399 (define_insn_and_split "*iordi_1_bts"
9400   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9401         (ior:DI
9402          (match_operand:DI 1 "nonimmediate_operand" "%0")
9403          (match_operand:DI 2 "const_int_operand" "n")))
9404    (clobber (reg:CC FLAGS_REG))]
9405   "TARGET_64BIT && TARGET_USE_BT
9406    && ix86_binary_operator_ok (IOR, DImode, operands)
9407    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9408   "#"
9409   "&& reload_completed"
9410   [(parallel [(set (zero_extract:DI (match_dup 0)
9411                                     (const_int 1)
9412                                     (match_dup 3))
9413                    (const_int 1))
9414               (clobber (reg:CC FLAGS_REG))])]
9415   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9416   [(set_attr "type" "alu1")
9417    (set_attr "prefix_0f" "1")
9418    (set_attr "znver1_decode" "double")
9419    (set_attr "mode" "DI")])
9421 (define_insn_and_split "*xordi_1_btc"
9422   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9423         (xor:DI
9424          (match_operand:DI 1 "nonimmediate_operand" "%0")
9425          (match_operand:DI 2 "const_int_operand" "n")))
9426    (clobber (reg:CC FLAGS_REG))]
9427   "TARGET_64BIT && TARGET_USE_BT
9428    && ix86_binary_operator_ok (XOR, DImode, operands)
9429    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9430   "#"
9431   "&& reload_completed"
9432   [(parallel [(set (zero_extract:DI (match_dup 0)
9433                                     (const_int 1)
9434                                     (match_dup 3))
9435                    (not:DI (zero_extract:DI (match_dup 0)
9436                                             (const_int 1)
9437                                             (match_dup 3))))
9438               (clobber (reg:CC FLAGS_REG))])]
9439   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9440   [(set_attr "type" "alu1")
9441    (set_attr "prefix_0f" "1")
9442    (set_attr "znver1_decode" "double")
9443    (set_attr "mode" "DI")])
9445 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9446 (define_insn "*<code>si_1_zext"
9447   [(set (match_operand:DI 0 "register_operand" "=r")
9448         (zero_extend:DI
9449          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9450                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9451    (clobber (reg:CC FLAGS_REG))]
9452   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9453   "<logic>{l}\t{%2, %k0|%k0, %2}"
9454   [(set_attr "type" "alu")
9455    (set_attr "mode" "SI")])
9457 (define_insn "*<code>si_1_zext_imm"
9458   [(set (match_operand:DI 0 "register_operand" "=r")
9459         (any_or:DI
9460          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9461          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9462    (clobber (reg:CC FLAGS_REG))]
9463   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9464   "<logic>{l}\t{%2, %k0|%k0, %2}"
9465   [(set_attr "type" "alu")
9466    (set_attr "mode" "SI")])
9468 (define_insn "*<code>qi_1"
9469   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9470         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9471                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9472    (clobber (reg:CC FLAGS_REG))]
9473   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9474   "@
9475    <logic>{b}\t{%2, %0|%0, %2}
9476    <logic>{b}\t{%2, %0|%0, %2}
9477    <logic>{l}\t{%k2, %k0|%k0, %k2}"
9478   [(set_attr "type" "alu")
9479    (set_attr "mode" "QI,QI,SI")
9480    ;; Potential partial reg stall on alternative 2.
9481    (set (attr "preferred_for_speed")
9482      (cond [(eq_attr "alternative" "2")
9483               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9484            (symbol_ref "true")))])
9486 (define_insn "*<code>qi_1_slp"
9487   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9488         (any_or:QI (match_dup 0)
9489                    (match_operand:QI 1 "general_operand" "qmn,qn")))
9490    (clobber (reg:CC FLAGS_REG))]
9491   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9492    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9493   "<logic>{b}\t{%1, %0|%0, %1}"
9494   [(set_attr "type" "alu1")
9495    (set_attr "mode" "QI")])
9497 (define_insn "*<code><mode>_2"
9498   [(set (reg FLAGS_REG)
9499         (compare (any_or:SWI
9500                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9501                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9502                  (const_int 0)))
9503    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9504         (any_or:SWI (match_dup 1) (match_dup 2)))]
9505   "ix86_match_ccmode (insn, CCNOmode)
9506    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9507   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9508   [(set_attr "type" "alu")
9509    (set_attr "mode" "<MODE>")])
9511 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9512 ;; ??? Special case for immediate operand is missing - it is tricky.
9513 (define_insn "*<code>si_2_zext"
9514   [(set (reg FLAGS_REG)
9515         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9516                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
9517                  (const_int 0)))
9518    (set (match_operand:DI 0 "register_operand" "=r")
9519         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9520   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9521    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9522   "<logic>{l}\t{%2, %k0|%k0, %2}"
9523   [(set_attr "type" "alu")
9524    (set_attr "mode" "SI")])
9526 (define_insn "*<code>si_2_zext_imm"
9527   [(set (reg FLAGS_REG)
9528         (compare (any_or:SI
9529                   (match_operand:SI 1 "nonimmediate_operand" "%0")
9530                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9531                  (const_int 0)))
9532    (set (match_operand:DI 0 "register_operand" "=r")
9533         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9534   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9535    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9536   "<logic>{l}\t{%2, %k0|%k0, %2}"
9537   [(set_attr "type" "alu")
9538    (set_attr "mode" "SI")])
9540 (define_insn "*<code>qi_2_slp"
9541   [(set (reg FLAGS_REG)
9542         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9543                             (match_operand:QI 1 "general_operand" "qmn,qn"))
9544                  (const_int 0)))
9545    (set (strict_low_part (match_dup 0))
9546         (any_or:QI (match_dup 0) (match_dup 1)))]
9547   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9548    && ix86_match_ccmode (insn, CCNOmode)
9549    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9550   "<logic>{b}\t{%1, %0|%0, %1}"
9551   [(set_attr "type" "alu1")
9552    (set_attr "mode" "QI")])
9554 (define_insn "*<code><mode>_3"
9555   [(set (reg FLAGS_REG)
9556         (compare (any_or:SWI
9557                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
9558                   (match_operand:SWI 2 "<general_operand>" "<g>"))
9559                  (const_int 0)))
9560    (clobber (match_scratch:SWI 0 "=<r>"))]
9561   "ix86_match_ccmode (insn, CCNOmode)
9562    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9563   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9564   [(set_attr "type" "alu")
9565    (set_attr "mode" "<MODE>")])
9567 (define_insn "*<code>qi_ext_1"
9568   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9569                          (const_int 8)
9570                          (const_int 8))
9571         (subreg:SI
9572           (any_or:QI
9573             (subreg:QI
9574               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9575                                (const_int 8)
9576                                (const_int 8)) 0)
9577             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9580    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9581    && rtx_equal_p (operands[0], operands[1])"
9582   "<logic>{b}\t{%2, %h0|%h0, %2}"
9583   [(set_attr "isa" "*,nox64")
9584    (set_attr "type" "alu")
9585    (set_attr "mode" "QI")])
9587 (define_insn "*<code>qi_ext_2"
9588   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9589                          (const_int 8)
9590                          (const_int 8))
9591         (subreg:SI
9592           (any_or:QI
9593             (subreg:QI
9594               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9595                                (const_int 8)
9596                                (const_int 8)) 0)
9597             (subreg:QI
9598               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9599                                (const_int 8)
9600                                (const_int 8)) 0)) 0))
9601    (clobber (reg:CC FLAGS_REG))]
9602   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9603    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9604    && (rtx_equal_p (operands[0], operands[1])
9605        || rtx_equal_p (operands[0], operands[2]))"
9606   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9607   [(set_attr "type" "alu")
9608    (set_attr "mode" "QI")])
9610 ;; Convert wide OR instructions with immediate operand to shorter QImode
9611 ;; equivalents when possible.
9612 ;; Don't do the splitting with memory operands, since it introduces risk
9613 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9614 ;; for size, but that can (should?) be handled by generic code instead.
9615 (define_split
9616   [(set (match_operand:SWI248 0 "QIreg_operand")
9617         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9618                        (match_operand:SWI248 2 "const_int_operand")))
9619    (clobber (reg:CC FLAGS_REG))]
9620    "reload_completed
9621     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9622     && !(INTVAL (operands[2]) & ~(255 << 8))"
9623   [(parallel
9624      [(set (zero_extract:SI (match_dup 0)
9625                             (const_int 8)
9626                             (const_int 8))
9627            (subreg:SI
9628              (any_or:QI
9629                (subreg:QI
9630                  (zero_extract:SI (match_dup 1)
9631                                   (const_int 8)
9632                                   (const_int 8)) 0)
9633                (match_dup 2)) 0))
9634       (clobber (reg:CC FLAGS_REG))])]
9636   operands[0] = gen_lowpart (SImode, operands[0]);
9637   operands[1] = gen_lowpart (SImode, operands[1]);
9638   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9641 ;; Since OR can be encoded with sign extended immediate, this is only
9642 ;; profitable when 7th bit is set.
9643 (define_split
9644   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9645         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9646                        (match_operand:SWI248 2 "const_int_operand")))
9647    (clobber (reg:CC FLAGS_REG))]
9648    "reload_completed
9649     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9650     && !(INTVAL (operands[2]) & ~255)
9651     && (INTVAL (operands[2]) & 128)"
9652   [(parallel [(set (strict_low_part (match_dup 0))
9653                    (any_or:QI (match_dup 1)
9654                               (match_dup 2)))
9655               (clobber (reg:CC FLAGS_REG))])]
9657   operands[0] = gen_lowpart (QImode, operands[0]);
9658   operands[1] = gen_lowpart (QImode, operands[1]);
9659   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9662 (define_expand "xorqi_ext_1_cc"
9663   [(parallel [
9664      (set (reg:CCNO FLAGS_REG)
9665           (compare:CCNO
9666             (xor:QI
9667               (subreg:QI
9668                 (zero_extract:SI (match_operand 1 "ext_register_operand")
9669                                  (const_int 8)
9670                                  (const_int 8)) 0)
9671               (match_operand 2 "const_int_operand"))
9672             (const_int 0)))
9673      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9674                            (const_int 8)
9675                            (const_int 8))
9676           (subreg:SI
9677             (xor:QI
9678               (subreg:QI
9679                 (zero_extract:SI (match_dup 1)
9680                                  (const_int 8)
9681                                  (const_int 8)) 0)
9682             (match_dup 2)) 0))])])
9684 (define_insn "*xorqi_ext_1_cc"
9685   [(set (reg FLAGS_REG)
9686         (compare
9687           (xor:QI
9688             (subreg:QI
9689               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9690                                (const_int 8)
9691                                (const_int 8)) 0)
9692             (match_operand:QI 2 "general_operand" "QnBc,m"))
9693           (const_int 0)))
9694    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9695                          (const_int 8)
9696                          (const_int 8))
9697         (subreg:SI
9698           (xor:QI
9699             (subreg:QI
9700               (zero_extract:SI (match_dup 1)
9701                                (const_int 8)
9702                                (const_int 8)) 0)
9703           (match_dup 2)) 0))]
9704   "ix86_match_ccmode (insn, CCNOmode)
9705    /* FIXME: without this LRA can't reload this pattern, see PR82524.  */
9706    && rtx_equal_p (operands[0], operands[1])"
9707   "xor{b}\t{%2, %h0|%h0, %2}"
9708   [(set_attr "isa" "*,nox64")
9709    (set_attr "type" "alu")
9710    (set_attr "mode" "QI")])
9712 ;; Negation instructions
9714 (define_expand "neg<mode>2"
9715   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9716         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9717   ""
9718   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9720 (define_insn_and_split "*neg<dwi>2_doubleword"
9721   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9722         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9725   "#"
9726   "reload_completed"
9727   [(parallel
9728     [(set (reg:CCZ FLAGS_REG)
9729           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9730      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9731    (parallel
9732     [(set (match_dup 2)
9733           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9734                                 (match_dup 3))
9735                      (const_int 0)))
9736      (clobber (reg:CC FLAGS_REG))])
9737    (parallel
9738     [(set (match_dup 2)
9739           (neg:DWIH (match_dup 2)))
9740      (clobber (reg:CC FLAGS_REG))])]
9741   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9743 (define_insn "*neg<mode>2_1"
9744   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9745         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9746    (clobber (reg:CC FLAGS_REG))]
9747   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9748   "neg{<imodesuffix>}\t%0"
9749   [(set_attr "type" "negnot")
9750    (set_attr "mode" "<MODE>")])
9752 ;; Combine is quite creative about this pattern.
9753 (define_insn "*negsi2_1_zext"
9754   [(set (match_operand:DI 0 "register_operand" "=r")
9755         (lshiftrt:DI
9756           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9757                              (const_int 32)))
9758         (const_int 32)))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9761   "neg{l}\t%k0"
9762   [(set_attr "type" "negnot")
9763    (set_attr "mode" "SI")])
9765 ;; The problem with neg is that it does not perform (compare x 0),
9766 ;; it really performs (compare 0 x), which leaves us with the zero
9767 ;; flag being the only useful item.
9769 (define_insn "*neg<mode>2_cmpz"
9770   [(set (reg:CCZ FLAGS_REG)
9771         (compare:CCZ
9772           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9773                    (const_int 0)))
9774    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9775         (neg:SWI (match_dup 1)))]
9776   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9777   "neg{<imodesuffix>}\t%0"
9778   [(set_attr "type" "negnot")
9779    (set_attr "mode" "<MODE>")])
9781 (define_insn "*negsi2_cmpz_zext"
9782   [(set (reg:CCZ FLAGS_REG)
9783         (compare:CCZ
9784           (lshiftrt:DI
9785             (neg:DI (ashift:DI
9786                       (match_operand:DI 1 "register_operand" "0")
9787                       (const_int 32)))
9788             (const_int 32))
9789           (const_int 0)))
9790    (set (match_operand:DI 0 "register_operand" "=r")
9791         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9792                                         (const_int 32)))
9793                      (const_int 32)))]
9794   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9795   "neg{l}\t%k0"
9796   [(set_attr "type" "negnot")
9797    (set_attr "mode" "SI")])
9799 ;; Negate with jump on overflow.
9800 (define_expand "negv<mode>3"
9801   [(parallel [(set (reg:CCO FLAGS_REG)
9802                    (ne:CCO (match_operand:SWI 1 "register_operand")
9803                            (match_dup 3)))
9804               (set (match_operand:SWI 0 "register_operand")
9805                    (neg:SWI (match_dup 1)))])
9806    (set (pc) (if_then_else
9807                (eq (reg:CCO FLAGS_REG) (const_int 0))
9808                (label_ref (match_operand 2))
9809                (pc)))]
9810   ""
9812   operands[3]
9813     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9814                     <MODE>mode);
9817 (define_insn "*negv<mode>3"
9818   [(set (reg:CCO FLAGS_REG)
9819         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9820                 (match_operand:SWI 2 "const_int_operand")))
9821    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9822         (neg:SWI (match_dup 1)))]
9823   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9824    && mode_signbit_p (<MODE>mode, operands[2])"
9825   "neg{<imodesuffix>}\t%0"
9826   [(set_attr "type" "negnot")
9827    (set_attr "mode" "<MODE>")])
9829 ;; Changing of sign for FP values is doable using integer unit too.
9831 (define_expand "<code><mode>2"
9832   [(set (match_operand:X87MODEF 0 "register_operand")
9833         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9834   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9835   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9837 (define_insn "*absneg<mode>2"
9838   [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9839         (match_operator:MODEF 3 "absneg_operator"
9840           [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9841    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9842    (clobber (reg:CC FLAGS_REG))]
9843   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9844   "#"
9845   [(set (attr "enabled")
9846      (if_then_else
9847        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9848        (if_then_else
9849          (eq_attr "alternative" "2")
9850          (symbol_ref "TARGET_MIX_SSE_I387")
9851          (symbol_ref "true"))
9852        (if_then_else
9853          (eq_attr "alternative" "2,3")
9854          (symbol_ref "true")
9855          (symbol_ref "false"))))])
9857 (define_insn "*absnegxf2_i387"
9858   [(set (match_operand:XF 0 "register_operand" "=f,!r")
9859         (match_operator:XF 3 "absneg_operator"
9860           [(match_operand:XF 1 "register_operand" "0,0")]))
9861    (use (match_operand 2))
9862    (clobber (reg:CC FLAGS_REG))]
9863   "TARGET_80387"
9864   "#")
9866 (define_expand "<code>tf2"
9867   [(set (match_operand:TF 0 "register_operand")
9868         (absneg:TF (match_operand:TF 1 "register_operand")))]
9869   "TARGET_SSE"
9870   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9872 (define_insn "*absnegtf2_sse"
9873   [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9874         (match_operator:TF 3 "absneg_operator"
9875           [(match_operand:TF 1 "register_operand" "0,Yv")]))
9876    (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9877    (clobber (reg:CC FLAGS_REG))]
9878   "TARGET_SSE"
9879   "#")
9881 ;; Splitters for fp abs and neg.
9883 (define_split
9884   [(set (match_operand 0 "fp_register_operand")
9885         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9886    (use (match_operand 2))
9887    (clobber (reg:CC FLAGS_REG))]
9888   "reload_completed"
9889   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9891 (define_split
9892   [(set (match_operand 0 "sse_reg_operand")
9893         (match_operator 3 "absneg_operator"
9894           [(match_operand 1 "register_operand")]))
9895    (use (match_operand 2 "nonimmediate_operand"))
9896    (clobber (reg:CC FLAGS_REG))]
9897   "reload_completed"
9898   [(set (match_dup 0) (match_dup 3))]
9900   machine_mode mode = GET_MODE (operands[0]);
9901   machine_mode vmode = GET_MODE (operands[2]);
9902   rtx tmp;
9904   operands[0] = lowpart_subreg (vmode, operands[0], mode);
9905   operands[1] = lowpart_subreg (vmode, operands[1], mode);
9906   if (operands_match_p (operands[0], operands[2]))
9907     std::swap (operands[1], operands[2]);
9908   if (GET_CODE (operands[3]) == ABS)
9909     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9910   else
9911     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9912   operands[3] = tmp;
9915 (define_split
9916   [(set (match_operand:SF 0 "general_reg_operand")
9917         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9918    (use (match_operand:V4SF 2))
9919    (clobber (reg:CC FLAGS_REG))]
9920   "reload_completed"
9921   [(parallel [(set (match_dup 0) (match_dup 1))
9922               (clobber (reg:CC FLAGS_REG))])]
9924   rtx tmp;
9925   operands[0] = gen_lowpart (SImode, operands[0]);
9926   if (GET_CODE (operands[1]) == ABS)
9927     {
9928       tmp = gen_int_mode (0x7fffffff, SImode);
9929       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9930     }
9931   else
9932     {
9933       tmp = gen_int_mode (0x80000000, SImode);
9934       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9935     }
9936   operands[1] = tmp;
9939 (define_split
9940   [(set (match_operand:DF 0 "general_reg_operand")
9941         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9942    (use (match_operand 2))
9943    (clobber (reg:CC FLAGS_REG))]
9944   "reload_completed"
9945   [(parallel [(set (match_dup 0) (match_dup 1))
9946               (clobber (reg:CC FLAGS_REG))])]
9948   rtx tmp;
9949   if (TARGET_64BIT)
9950     {
9951       tmp = gen_lowpart (DImode, operands[0]);
9952       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9953       operands[0] = tmp;
9955       if (GET_CODE (operands[1]) == ABS)
9956         tmp = const0_rtx;
9957       else
9958         tmp = gen_rtx_NOT (DImode, tmp);
9959     }
9960   else
9961     {
9962       operands[0] = gen_highpart (SImode, operands[0]);
9963       if (GET_CODE (operands[1]) == ABS)
9964         {
9965           tmp = gen_int_mode (0x7fffffff, SImode);
9966           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9967         }
9968       else
9969         {
9970           tmp = gen_int_mode (0x80000000, SImode);
9971           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9972         }
9973     }
9974   operands[1] = tmp;
9977 (define_split
9978   [(set (match_operand:XF 0 "general_reg_operand")
9979         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9980    (use (match_operand 2))
9981    (clobber (reg:CC FLAGS_REG))]
9982   "reload_completed"
9983   [(parallel [(set (match_dup 0) (match_dup 1))
9984               (clobber (reg:CC FLAGS_REG))])]
9986   rtx tmp;
9987   operands[0] = gen_rtx_REG (SImode,
9988                              REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9989   if (GET_CODE (operands[1]) == ABS)
9990     {
9991       tmp = GEN_INT (0x7fff);
9992       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9993     }
9994   else
9995     {
9996       tmp = GEN_INT (0x8000);
9997       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9998     }
9999   operands[1] = tmp;
10002 ;; Conditionalize these after reload. If they match before reload, we
10003 ;; lose the clobber and ability to use integer instructions.
10005 (define_insn "*<code><mode>2_1"
10006   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10007         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10008   "TARGET_80387
10009    && (reload_completed
10010        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10011   "f<absneg_mnemonic>"
10012   [(set_attr "type" "fsgn")
10013    (set_attr "mode" "<MODE>")])
10015 (define_insn "*<code>extendsfdf2"
10016   [(set (match_operand:DF 0 "register_operand" "=f")
10017         (absneg:DF (float_extend:DF
10018                      (match_operand:SF 1 "register_operand" "0"))))]
10019   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10020   "f<absneg_mnemonic>"
10021   [(set_attr "type" "fsgn")
10022    (set_attr "mode" "DF")])
10024 (define_insn "*<code>extendsfxf2"
10025   [(set (match_operand:XF 0 "register_operand" "=f")
10026         (absneg:XF (float_extend:XF
10027                      (match_operand:SF 1 "register_operand" "0"))))]
10028   "TARGET_80387"
10029   "f<absneg_mnemonic>"
10030   [(set_attr "type" "fsgn")
10031    (set_attr "mode" "XF")])
10033 (define_insn "*<code>extenddfxf2"
10034   [(set (match_operand:XF 0 "register_operand" "=f")
10035         (absneg:XF (float_extend:XF
10036                      (match_operand:DF 1 "register_operand" "0"))))]
10037   "TARGET_80387"
10038   "f<absneg_mnemonic>"
10039   [(set_attr "type" "fsgn")
10040    (set_attr "mode" "XF")])
10042 ;; Copysign instructions
10044 (define_mode_iterator CSGNMODE [SF DF TF])
10045 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10047 (define_expand "copysign<mode>3"
10048   [(match_operand:CSGNMODE 0 "register_operand")
10049    (match_operand:CSGNMODE 1 "nonmemory_operand")
10050    (match_operand:CSGNMODE 2 "register_operand")]
10051   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10052    || (TARGET_SSE && (<MODE>mode == TFmode))"
10053   "ix86_expand_copysign (operands); DONE;")
10055 (define_insn_and_split "copysign<mode>3_const"
10056   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10057         (unspec:CSGNMODE
10058           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10059            (match_operand:CSGNMODE 2 "register_operand" "0")
10060            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10061           UNSPEC_COPYSIGN))]
10062   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10063    || (TARGET_SSE && (<MODE>mode == TFmode))"
10064   "#"
10065   "&& reload_completed"
10066   [(const_int 0)]
10067   "ix86_split_copysign_const (operands); DONE;")
10069 (define_insn "copysign<mode>3_var"
10070   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10071         (unspec:CSGNMODE
10072           [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10073            (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10074            (match_operand:<CSGNVMODE> 4
10075              "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10076            (match_operand:<CSGNVMODE> 5
10077              "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10078           UNSPEC_COPYSIGN))
10079    (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10080   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10081    || (TARGET_SSE && (<MODE>mode == TFmode))"
10082   "#")
10084 (define_split
10085   [(set (match_operand:CSGNMODE 0 "register_operand")
10086         (unspec:CSGNMODE
10087           [(match_operand:CSGNMODE 2 "register_operand")
10088            (match_operand:CSGNMODE 3 "register_operand")
10089            (match_operand:<CSGNVMODE> 4)
10090            (match_operand:<CSGNVMODE> 5)]
10091           UNSPEC_COPYSIGN))
10092    (clobber (match_scratch:<CSGNVMODE> 1))]
10093   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10094     || (TARGET_SSE && (<MODE>mode == TFmode)))
10095    && reload_completed"
10096   [(const_int 0)]
10097   "ix86_split_copysign_var (operands); DONE;")
10099 ;; One complement instructions
10101 (define_expand "one_cmpl<mode>2"
10102   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10103         (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10104   ""
10105   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10107 (define_insn_and_split "*one_cmpldi2_doubleword"
10108   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10109         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10110   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10111    && ix86_unary_operator_ok (NOT, DImode, operands)"
10112   "#"
10113   "&& reload_completed"
10114   [(set (match_dup 0)
10115         (not:SI (match_dup 1)))
10116    (set (match_dup 2)
10117         (not:SI (match_dup 3)))]
10118   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10120 (define_insn "*one_cmpl<mode>2_1"
10121   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10122         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10123   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10124   "not{<imodesuffix>}\t%0"
10125   [(set_attr "type" "negnot")
10126    (set_attr "mode" "<MODE>")])
10128 ;; ??? Currently never generated - xor is used instead.
10129 (define_insn "*one_cmplsi2_1_zext"
10130   [(set (match_operand:DI 0 "register_operand" "=r")
10131         (zero_extend:DI
10132           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10133   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10134   "not{l}\t%k0"
10135   [(set_attr "type" "negnot")
10136    (set_attr "mode" "SI")])
10138 (define_insn "*one_cmplqi2_1"
10139   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10140         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10141   "ix86_unary_operator_ok (NOT, QImode, operands)"
10142   "@
10143    not{b}\t%0
10144    not{l}\t%k0"
10145   [(set_attr "type" "negnot")
10146    (set_attr "mode" "QI,SI")
10147    ;; Potential partial reg stall on alternative 1.
10148    (set (attr "preferred_for_speed")
10149      (cond [(eq_attr "alternative" "1")
10150               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10151            (symbol_ref "true")))])
10153 (define_insn "*one_cmpl<mode>2_2"
10154   [(set (reg FLAGS_REG)
10155         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10156                  (const_int 0)))
10157    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10158         (not:SWI (match_dup 1)))]
10159   "ix86_match_ccmode (insn, CCNOmode)
10160    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10161   "#"
10162   [(set_attr "type" "alu1")
10163    (set_attr "mode" "<MODE>")])
10165 (define_split
10166   [(set (match_operand 0 "flags_reg_operand")
10167         (match_operator 2 "compare_operator"
10168           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10169            (const_int 0)]))
10170    (set (match_operand:SWI 1 "nonimmediate_operand")
10171         (not:SWI (match_dup 3)))]
10172   "ix86_match_ccmode (insn, CCNOmode)"
10173   [(parallel [(set (match_dup 0)
10174                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10175                                     (const_int 0)]))
10176               (set (match_dup 1)
10177                    (xor:SWI (match_dup 3) (const_int -1)))])])
10179 ;; ??? Currently never generated - xor is used instead.
10180 (define_insn "*one_cmplsi2_2_zext"
10181   [(set (reg FLAGS_REG)
10182         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10183                  (const_int 0)))
10184    (set (match_operand:DI 0 "register_operand" "=r")
10185         (zero_extend:DI (not:SI (match_dup 1))))]
10186   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10187    && ix86_unary_operator_ok (NOT, SImode, operands)"
10188   "#"
10189   [(set_attr "type" "alu1")
10190    (set_attr "mode" "SI")])
10192 (define_split
10193   [(set (match_operand 0 "flags_reg_operand")
10194         (match_operator 2 "compare_operator"
10195           [(not:SI (match_operand:SI 3 "register_operand"))
10196            (const_int 0)]))
10197    (set (match_operand:DI 1 "register_operand")
10198         (zero_extend:DI (not:SI (match_dup 3))))]
10199   "ix86_match_ccmode (insn, CCNOmode)"
10200   [(parallel [(set (match_dup 0)
10201                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10202                                     (const_int 0)]))
10203               (set (match_dup 1)
10204                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10206 ;; Shift instructions
10208 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10209 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10210 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10211 ;; from the assembler input.
10213 ;; This instruction shifts the target reg/mem as usual, but instead of
10214 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10215 ;; is a left shift double, bits are taken from the high order bits of
10216 ;; reg, else if the insn is a shift right double, bits are taken from the
10217 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10218 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10220 ;; Since sh[lr]d does not change the `reg' operand, that is done
10221 ;; separately, making all shifts emit pairs of shift double and normal
10222 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10223 ;; support a 63 bit shift, each shift where the count is in a reg expands
10224 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10226 ;; If the shift count is a constant, we need never emit more than one
10227 ;; shift pair, instead using moves and sign extension for counts greater
10228 ;; than 31.
10230 (define_expand "ashl<mode>3"
10231   [(set (match_operand:SDWIM 0 "<shift_operand>")
10232         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10233                       (match_operand:QI 2 "nonmemory_operand")))]
10234   ""
10235   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10237 (define_insn "*ashl<mode>3_doubleword"
10238   [(set (match_operand:DWI 0 "register_operand" "=&r")
10239         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10240                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10241    (clobber (reg:CC FLAGS_REG))]
10242   ""
10243   "#"
10244   [(set_attr "type" "multi")])
10246 (define_split
10247   [(set (match_operand:DWI 0 "register_operand")
10248         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10249                     (match_operand:QI 2 "nonmemory_operand")))
10250    (clobber (reg:CC FLAGS_REG))]
10251   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10252   [(const_int 0)]
10253   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10255 ;; By default we don't ask for a scratch register, because when DWImode
10256 ;; values are manipulated, registers are already at a premium.  But if
10257 ;; we have one handy, we won't turn it away.
10259 (define_peephole2
10260   [(match_scratch:DWIH 3 "r")
10261    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10262                    (ashift:<DWI>
10263                      (match_operand:<DWI> 1 "nonmemory_operand")
10264                      (match_operand:QI 2 "nonmemory_operand")))
10265               (clobber (reg:CC FLAGS_REG))])
10266    (match_dup 3)]
10267   "TARGET_CMOVE"
10268   [(const_int 0)]
10269   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10271 (define_insn "x86_64_shld"
10272   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10273         (ior:DI (ashift:DI (match_dup 0)
10274                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10275                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10276                   (minus:QI (const_int 64) (match_dup 2)))))
10277    (clobber (reg:CC FLAGS_REG))]
10278   "TARGET_64BIT"
10279   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10280   [(set_attr "type" "ishift")
10281    (set_attr "prefix_0f" "1")
10282    (set_attr "mode" "DI")
10283    (set_attr "athlon_decode" "vector")
10284    (set_attr "amdfam10_decode" "vector")
10285    (set_attr "bdver1_decode" "vector")])
10287 (define_insn "x86_shld"
10288   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10289         (ior:SI (ashift:SI (match_dup 0)
10290                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10291                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10292                   (minus:QI (const_int 32) (match_dup 2)))))
10293    (clobber (reg:CC FLAGS_REG))]
10294   ""
10295   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10296   [(set_attr "type" "ishift")
10297    (set_attr "prefix_0f" "1")
10298    (set_attr "mode" "SI")
10299    (set_attr "pent_pair" "np")
10300    (set_attr "athlon_decode" "vector")
10301    (set_attr "amdfam10_decode" "vector")
10302    (set_attr "bdver1_decode" "vector")])
10304 (define_expand "x86_shift<mode>_adj_1"
10305   [(set (reg:CCZ FLAGS_REG)
10306         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10307                              (match_dup 4))
10308                      (const_int 0)))
10309    (set (match_operand:SWI48 0 "register_operand")
10310         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10311                             (match_operand:SWI48 1 "register_operand")
10312                             (match_dup 0)))
10313    (set (match_dup 1)
10314         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10315                             (match_operand:SWI48 3 "register_operand")
10316                             (match_dup 1)))]
10317   "TARGET_CMOVE"
10318   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10320 (define_expand "x86_shift<mode>_adj_2"
10321   [(use (match_operand:SWI48 0 "register_operand"))
10322    (use (match_operand:SWI48 1 "register_operand"))
10323    (use (match_operand:QI 2 "register_operand"))]
10324   ""
10326   rtx_code_label *label = gen_label_rtx ();
10327   rtx tmp;
10329   emit_insn (gen_testqi_ccz_1 (operands[2],
10330                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10332   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10333   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10334   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10335                               gen_rtx_LABEL_REF (VOIDmode, label),
10336                               pc_rtx);
10337   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10338   JUMP_LABEL (tmp) = label;
10340   emit_move_insn (operands[0], operands[1]);
10341   ix86_expand_clear (operands[1]);
10343   emit_label (label);
10344   LABEL_NUSES (label) = 1;
10346   DONE;
10349 ;; Avoid useless masking of count operand.
10350 (define_insn_and_split "*ashl<mode>3_mask"
10351   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10352         (ashift:SWI48
10353           (match_operand:SWI48 1 "nonimmediate_operand")
10354           (subreg:QI
10355             (and:SI
10356               (match_operand:SI 2 "register_operand" "c,r")
10357               (match_operand:SI 3 "const_int_operand")) 0)))
10358    (clobber (reg:CC FLAGS_REG))]
10359   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10360    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10361       == GET_MODE_BITSIZE (<MODE>mode)-1
10362    && can_create_pseudo_p ()"
10363   "#"
10364   "&& 1"
10365   [(parallel
10366      [(set (match_dup 0)
10367            (ashift:SWI48 (match_dup 1)
10368                          (match_dup 2)))
10369       (clobber (reg:CC FLAGS_REG))])]
10370   "operands[2] = gen_lowpart (QImode, operands[2]);"
10371   [(set_attr "isa" "*,bmi2")])
10373 (define_insn_and_split "*ashl<mode>3_mask_1"
10374   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10375         (ashift:SWI48
10376           (match_operand:SWI48 1 "nonimmediate_operand")
10377           (and:QI
10378             (match_operand:QI 2 "register_operand" "c,r")
10379             (match_operand:QI 3 "const_int_operand"))))
10380    (clobber (reg:CC FLAGS_REG))]
10381   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10382    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10383       == GET_MODE_BITSIZE (<MODE>mode)-1
10384    && can_create_pseudo_p ()"
10385   "#"
10386   "&& 1"
10387   [(parallel
10388      [(set (match_dup 0)
10389            (ashift:SWI48 (match_dup 1)
10390                          (match_dup 2)))
10391       (clobber (reg:CC FLAGS_REG))])]
10392   ""
10393   [(set_attr "isa" "*,bmi2")])
10395 (define_insn "*bmi2_ashl<mode>3_1"
10396   [(set (match_operand:SWI48 0 "register_operand" "=r")
10397         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10398                       (match_operand:SWI48 2 "register_operand" "r")))]
10399   "TARGET_BMI2"
10400   "shlx\t{%2, %1, %0|%0, %1, %2}"
10401   [(set_attr "type" "ishiftx")
10402    (set_attr "mode" "<MODE>")])
10404 (define_insn "*ashl<mode>3_1"
10405   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10406         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10407                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10408    (clobber (reg:CC FLAGS_REG))]
10409   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10411   switch (get_attr_type (insn))
10412     {
10413     case TYPE_LEA:
10414     case TYPE_ISHIFTX:
10415       return "#";
10417     case TYPE_ALU:
10418       gcc_assert (operands[2] == const1_rtx);
10419       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10420       return "add{<imodesuffix>}\t%0, %0";
10422     default:
10423       if (operands[2] == const1_rtx
10424           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10425         return "sal{<imodesuffix>}\t%0";
10426       else
10427         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10428     }
10430   [(set_attr "isa" "*,*,bmi2")
10431    (set (attr "type")
10432      (cond [(eq_attr "alternative" "1")
10433               (const_string "lea")
10434             (eq_attr "alternative" "2")
10435               (const_string "ishiftx")
10436             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10437                       (match_operand 0 "register_operand"))
10438                  (match_operand 2 "const1_operand"))
10439               (const_string "alu")
10440            ]
10441            (const_string "ishift")))
10442    (set (attr "length_immediate")
10443      (if_then_else
10444        (ior (eq_attr "type" "alu")
10445             (and (eq_attr "type" "ishift")
10446                  (and (match_operand 2 "const1_operand")
10447                       (ior (match_test "TARGET_SHIFT1")
10448                            (match_test "optimize_function_for_size_p (cfun)")))))
10449        (const_string "0")
10450        (const_string "*")))
10451    (set_attr "mode" "<MODE>")])
10453 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10454 (define_split
10455   [(set (match_operand:SWI48 0 "register_operand")
10456         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10457                       (match_operand:QI 2 "register_operand")))
10458    (clobber (reg:CC FLAGS_REG))]
10459   "TARGET_BMI2 && reload_completed"
10460   [(set (match_dup 0)
10461         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10462   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10464 (define_insn "*bmi2_ashlsi3_1_zext"
10465   [(set (match_operand:DI 0 "register_operand" "=r")
10466         (zero_extend:DI
10467           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10468                      (match_operand:SI 2 "register_operand" "r"))))]
10469   "TARGET_64BIT && TARGET_BMI2"
10470   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10471   [(set_attr "type" "ishiftx")
10472    (set_attr "mode" "SI")])
10474 (define_insn "*ashlsi3_1_zext"
10475   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10476         (zero_extend:DI
10477           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10478                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10479    (clobber (reg:CC FLAGS_REG))]
10480   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10482   switch (get_attr_type (insn))
10483     {
10484     case TYPE_LEA:
10485     case TYPE_ISHIFTX:
10486       return "#";
10488     case TYPE_ALU:
10489       gcc_assert (operands[2] == const1_rtx);
10490       return "add{l}\t%k0, %k0";
10492     default:
10493       if (operands[2] == const1_rtx
10494           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10495         return "sal{l}\t%k0";
10496       else
10497         return "sal{l}\t{%2, %k0|%k0, %2}";
10498     }
10500   [(set_attr "isa" "*,*,bmi2")
10501    (set (attr "type")
10502      (cond [(eq_attr "alternative" "1")
10503               (const_string "lea")
10504             (eq_attr "alternative" "2")
10505               (const_string "ishiftx")
10506             (and (match_test "TARGET_DOUBLE_WITH_ADD")
10507                  (match_operand 2 "const1_operand"))
10508               (const_string "alu")
10509            ]
10510            (const_string "ishift")))
10511    (set (attr "length_immediate")
10512      (if_then_else
10513        (ior (eq_attr "type" "alu")
10514             (and (eq_attr "type" "ishift")
10515                  (and (match_operand 2 "const1_operand")
10516                       (ior (match_test "TARGET_SHIFT1")
10517                            (match_test "optimize_function_for_size_p (cfun)")))))
10518        (const_string "0")
10519        (const_string "*")))
10520    (set_attr "mode" "SI")])
10522 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10523 (define_split
10524   [(set (match_operand:DI 0 "register_operand")
10525         (zero_extend:DI
10526           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10527                      (match_operand:QI 2 "register_operand"))))
10528    (clobber (reg:CC FLAGS_REG))]
10529   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10530   [(set (match_dup 0)
10531         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10532   "operands[2] = gen_lowpart (SImode, operands[2]);")
10534 (define_insn "*ashlhi3_1"
10535   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10536         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10537                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10538    (clobber (reg:CC FLAGS_REG))]
10539   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10541   switch (get_attr_type (insn))
10542     {
10543     case TYPE_LEA:
10544       return "#";
10546     case TYPE_ALU:
10547       gcc_assert (operands[2] == const1_rtx);
10548       return "add{w}\t%0, %0";
10550     default:
10551       if (operands[2] == const1_rtx
10552           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10553         return "sal{w}\t%0";
10554       else
10555         return "sal{w}\t{%2, %0|%0, %2}";
10556     }
10558   [(set (attr "type")
10559      (cond [(eq_attr "alternative" "1")
10560               (const_string "lea")
10561             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10562                       (match_operand 0 "register_operand"))
10563                  (match_operand 2 "const1_operand"))
10564               (const_string "alu")
10565            ]
10566            (const_string "ishift")))
10567    (set (attr "length_immediate")
10568      (if_then_else
10569        (ior (eq_attr "type" "alu")
10570             (and (eq_attr "type" "ishift")
10571                  (and (match_operand 2 "const1_operand")
10572                       (ior (match_test "TARGET_SHIFT1")
10573                            (match_test "optimize_function_for_size_p (cfun)")))))
10574        (const_string "0")
10575        (const_string "*")))
10576    (set_attr "mode" "HI,SI")])
10578 (define_insn "*ashlqi3_1"
10579   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10580         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10581                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10582    (clobber (reg:CC FLAGS_REG))]
10583   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10585   switch (get_attr_type (insn))
10586     {
10587     case TYPE_LEA:
10588       return "#";
10590     case TYPE_ALU:
10591       gcc_assert (operands[2] == const1_rtx);
10592       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10593         return "add{l}\t%k0, %k0";
10594       else
10595         return "add{b}\t%0, %0";
10597     default:
10598       if (operands[2] == const1_rtx
10599           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10600         {
10601           if (get_attr_mode (insn) == MODE_SI)
10602             return "sal{l}\t%k0";
10603           else
10604             return "sal{b}\t%0";
10605         }
10606       else
10607         {
10608           if (get_attr_mode (insn) == MODE_SI)
10609             return "sal{l}\t{%2, %k0|%k0, %2}";
10610           else
10611             return "sal{b}\t{%2, %0|%0, %2}";
10612         }
10613     }
10615   [(set (attr "type")
10616      (cond [(eq_attr "alternative" "2")
10617               (const_string "lea")
10618             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10619                       (match_operand 0 "register_operand"))
10620                  (match_operand 2 "const1_operand"))
10621               (const_string "alu")
10622            ]
10623            (const_string "ishift")))
10624    (set (attr "length_immediate")
10625      (if_then_else
10626        (ior (eq_attr "type" "alu")
10627             (and (eq_attr "type" "ishift")
10628                  (and (match_operand 2 "const1_operand")
10629                       (ior (match_test "TARGET_SHIFT1")
10630                            (match_test "optimize_function_for_size_p (cfun)")))))
10631        (const_string "0")
10632        (const_string "*")))
10633    (set_attr "mode" "QI,SI,SI")
10634    ;; Potential partial reg stall on alternative 1.
10635    (set (attr "preferred_for_speed")
10636      (cond [(eq_attr "alternative" "1")
10637               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10638            (symbol_ref "true")))])
10640 (define_insn "*ashlqi3_1_slp"
10641   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10642         (ashift:QI (match_dup 0)
10643                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10644    (clobber (reg:CC FLAGS_REG))]
10645   "(optimize_function_for_size_p (cfun)
10646     || !TARGET_PARTIAL_FLAG_REG_STALL
10647     || (operands[1] == const1_rtx
10648         && (TARGET_SHIFT1
10649             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10651   switch (get_attr_type (insn))
10652     {
10653     case TYPE_ALU:
10654       gcc_assert (operands[1] == const1_rtx);
10655       return "add{b}\t%0, %0";
10657     default:
10658       if (operands[1] == const1_rtx
10659           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10660         return "sal{b}\t%0";
10661       else
10662         return "sal{b}\t{%1, %0|%0, %1}";
10663     }
10665   [(set (attr "type")
10666      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10667                       (match_operand 0 "register_operand"))
10668                  (match_operand 1 "const1_operand"))
10669               (const_string "alu")
10670            ]
10671            (const_string "ishift1")))
10672    (set (attr "length_immediate")
10673      (if_then_else
10674        (ior (eq_attr "type" "alu")
10675             (and (eq_attr "type" "ishift1")
10676                  (and (match_operand 1 "const1_operand")
10677                       (ior (match_test "TARGET_SHIFT1")
10678                            (match_test "optimize_function_for_size_p (cfun)")))))
10679        (const_string "0")
10680        (const_string "*")))
10681    (set_attr "mode" "QI")])
10683 ;; Convert ashift to the lea pattern to avoid flags dependency.
10684 (define_split
10685   [(set (match_operand:SWI 0 "register_operand")
10686         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10687                     (match_operand 2 "const_0_to_3_operand")))
10688    (clobber (reg:CC FLAGS_REG))]
10689   "reload_completed
10690    && REGNO (operands[0]) != REGNO (operands[1])"
10691   [(set (match_dup 0)
10692         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10694   if (<MODE>mode != <LEAMODE>mode)
10695     {
10696       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10697       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10698     }
10699   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10702 ;; Convert ashift to the lea pattern to avoid flags dependency.
10703 (define_split
10704   [(set (match_operand:DI 0 "register_operand")
10705         (zero_extend:DI
10706           (ashift:SI (match_operand:SI 1 "index_register_operand")
10707                      (match_operand 2 "const_0_to_3_operand"))))
10708    (clobber (reg:CC FLAGS_REG))]
10709   "TARGET_64BIT && reload_completed
10710    && REGNO (operands[0]) != REGNO (operands[1])"
10711   [(set (match_dup 0)
10712         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10714   operands[1] = gen_lowpart (SImode, operands[1]);
10715   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10718 ;; This pattern can't accept a variable shift count, since shifts by
10719 ;; zero don't affect the flags.  We assume that shifts by constant
10720 ;; zero are optimized away.
10721 (define_insn "*ashl<mode>3_cmp"
10722   [(set (reg FLAGS_REG)
10723         (compare
10724           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10725                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10726           (const_int 0)))
10727    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10728         (ashift:SWI (match_dup 1) (match_dup 2)))]
10729   "(optimize_function_for_size_p (cfun)
10730     || !TARGET_PARTIAL_FLAG_REG_STALL
10731     || (operands[2] == const1_rtx
10732         && (TARGET_SHIFT1
10733             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10734    && ix86_match_ccmode (insn, CCGOCmode)
10735    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10737   switch (get_attr_type (insn))
10738     {
10739     case TYPE_ALU:
10740       gcc_assert (operands[2] == const1_rtx);
10741       return "add{<imodesuffix>}\t%0, %0";
10743     default:
10744       if (operands[2] == const1_rtx
10745           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10746         return "sal{<imodesuffix>}\t%0";
10747       else
10748         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10749     }
10751   [(set (attr "type")
10752      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10753                       (match_operand 0 "register_operand"))
10754                  (match_operand 2 "const1_operand"))
10755               (const_string "alu")
10756            ]
10757            (const_string "ishift")))
10758    (set (attr "length_immediate")
10759      (if_then_else
10760        (ior (eq_attr "type" "alu")
10761             (and (eq_attr "type" "ishift")
10762                  (and (match_operand 2 "const1_operand")
10763                       (ior (match_test "TARGET_SHIFT1")
10764                            (match_test "optimize_function_for_size_p (cfun)")))))
10765        (const_string "0")
10766        (const_string "*")))
10767    (set_attr "mode" "<MODE>")])
10769 (define_insn "*ashlsi3_cmp_zext"
10770   [(set (reg FLAGS_REG)
10771         (compare
10772           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10773                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10774           (const_int 0)))
10775    (set (match_operand:DI 0 "register_operand" "=r")
10776         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10777   "TARGET_64BIT
10778    && (optimize_function_for_size_p (cfun)
10779        || !TARGET_PARTIAL_FLAG_REG_STALL
10780        || (operands[2] == const1_rtx
10781            && (TARGET_SHIFT1
10782                || TARGET_DOUBLE_WITH_ADD)))
10783    && ix86_match_ccmode (insn, CCGOCmode)
10784    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10786   switch (get_attr_type (insn))
10787     {
10788     case TYPE_ALU:
10789       gcc_assert (operands[2] == const1_rtx);
10790       return "add{l}\t%k0, %k0";
10792     default:
10793       if (operands[2] == const1_rtx
10794           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10795         return "sal{l}\t%k0";
10796       else
10797         return "sal{l}\t{%2, %k0|%k0, %2}";
10798     }
10800   [(set (attr "type")
10801      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10802                  (match_operand 2 "const1_operand"))
10803               (const_string "alu")
10804            ]
10805            (const_string "ishift")))
10806    (set (attr "length_immediate")
10807      (if_then_else
10808        (ior (eq_attr "type" "alu")
10809             (and (eq_attr "type" "ishift")
10810                  (and (match_operand 2 "const1_operand")
10811                       (ior (match_test "TARGET_SHIFT1")
10812                            (match_test "optimize_function_for_size_p (cfun)")))))
10813        (const_string "0")
10814        (const_string "*")))
10815    (set_attr "mode" "SI")])
10817 (define_insn "*ashl<mode>3_cconly"
10818   [(set (reg FLAGS_REG)
10819         (compare
10820           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10821                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10822           (const_int 0)))
10823    (clobber (match_scratch:SWI 0 "=<r>"))]
10824   "(optimize_function_for_size_p (cfun)
10825     || !TARGET_PARTIAL_FLAG_REG_STALL
10826     || (operands[2] == const1_rtx
10827         && (TARGET_SHIFT1
10828             || TARGET_DOUBLE_WITH_ADD)))
10829    && ix86_match_ccmode (insn, CCGOCmode)"
10831   switch (get_attr_type (insn))
10832     {
10833     case TYPE_ALU:
10834       gcc_assert (operands[2] == const1_rtx);
10835       return "add{<imodesuffix>}\t%0, %0";
10837     default:
10838       if (operands[2] == const1_rtx
10839           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10840         return "sal{<imodesuffix>}\t%0";
10841       else
10842         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10843     }
10845   [(set (attr "type")
10846      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10847                       (match_operand 0 "register_operand"))
10848                  (match_operand 2 "const1_operand"))
10849               (const_string "alu")
10850            ]
10851            (const_string "ishift")))
10852    (set (attr "length_immediate")
10853      (if_then_else
10854        (ior (eq_attr "type" "alu")
10855             (and (eq_attr "type" "ishift")
10856                  (and (match_operand 2 "const1_operand")
10857                       (ior (match_test "TARGET_SHIFT1")
10858                            (match_test "optimize_function_for_size_p (cfun)")))))
10859        (const_string "0")
10860        (const_string "*")))
10861    (set_attr "mode" "<MODE>")])
10863 ;; See comment above `ashl<mode>3' about how this works.
10865 (define_expand "<shift_insn><mode>3"
10866   [(set (match_operand:SDWIM 0 "<shift_operand>")
10867         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10868                            (match_operand:QI 2 "nonmemory_operand")))]
10869   ""
10870   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10872 ;; Avoid useless masking of count operand.
10873 (define_insn_and_split "*<shift_insn><mode>3_mask"
10874   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10875         (any_shiftrt:SWI48
10876           (match_operand:SWI48 1 "nonimmediate_operand")
10877           (subreg:QI
10878             (and:SI
10879               (match_operand:SI 2 "register_operand" "c,r")
10880               (match_operand:SI 3 "const_int_operand")) 0)))
10881    (clobber (reg:CC FLAGS_REG))]
10882   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10883    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10884       == GET_MODE_BITSIZE (<MODE>mode)-1
10885    && can_create_pseudo_p ()"
10886   "#"
10887   "&& 1"
10888   [(parallel
10889      [(set (match_dup 0)
10890            (any_shiftrt:SWI48 (match_dup 1)
10891                               (match_dup 2)))
10892       (clobber (reg:CC FLAGS_REG))])]
10893   "operands[2] = gen_lowpart (QImode, operands[2]);"
10894   [(set_attr "isa" "*,bmi2")])
10896 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10897   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10898         (any_shiftrt:SWI48
10899           (match_operand:SWI48 1 "nonimmediate_operand")
10900           (and:QI
10901             (match_operand:QI 2 "register_operand" "c,r")
10902             (match_operand:QI 3 "const_int_operand"))))
10903    (clobber (reg:CC FLAGS_REG))]
10904   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10905    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10906       == GET_MODE_BITSIZE (<MODE>mode)-1
10907    && can_create_pseudo_p ()"
10908   "#"
10909   "&& 1"
10910   [(parallel
10911      [(set (match_dup 0)
10912            (any_shiftrt:SWI48 (match_dup 1)
10913                               (match_dup 2)))
10914       (clobber (reg:CC FLAGS_REG))])]
10915   ""
10916   [(set_attr "isa" "*,bmi2")])
10918 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10919   [(set (match_operand:DWI 0 "register_operand" "=&r")
10920         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10921                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10922    (clobber (reg:CC FLAGS_REG))]
10923   ""
10924   "#"
10925   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10926   [(const_int 0)]
10927   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10928   [(set_attr "type" "multi")])
10930 ;; By default we don't ask for a scratch register, because when DWImode
10931 ;; values are manipulated, registers are already at a premium.  But if
10932 ;; we have one handy, we won't turn it away.
10934 (define_peephole2
10935   [(match_scratch:DWIH 3 "r")
10936    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10937                    (any_shiftrt:<DWI>
10938                      (match_operand:<DWI> 1 "register_operand")
10939                      (match_operand:QI 2 "nonmemory_operand")))
10940               (clobber (reg:CC FLAGS_REG))])
10941    (match_dup 3)]
10942   "TARGET_CMOVE"
10943   [(const_int 0)]
10944   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10946 (define_insn "x86_64_shrd"
10947   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10948         (ior:DI (lshiftrt:DI (match_dup 0)
10949                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10950                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10951                   (minus:QI (const_int 64) (match_dup 2)))))
10952    (clobber (reg:CC FLAGS_REG))]
10953   "TARGET_64BIT"
10954   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10955   [(set_attr "type" "ishift")
10956    (set_attr "prefix_0f" "1")
10957    (set_attr "mode" "DI")
10958    (set_attr "athlon_decode" "vector")
10959    (set_attr "amdfam10_decode" "vector")
10960    (set_attr "bdver1_decode" "vector")])
10962 (define_insn "x86_shrd"
10963   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10964         (ior:SI (lshiftrt:SI (match_dup 0)
10965                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10966                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10967                   (minus:QI (const_int 32) (match_dup 2)))))
10968    (clobber (reg:CC FLAGS_REG))]
10969   ""
10970   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10971   [(set_attr "type" "ishift")
10972    (set_attr "prefix_0f" "1")
10973    (set_attr "mode" "SI")
10974    (set_attr "pent_pair" "np")
10975    (set_attr "athlon_decode" "vector")
10976    (set_attr "amdfam10_decode" "vector")
10977    (set_attr "bdver1_decode" "vector")])
10979 (define_insn "ashrdi3_cvt"
10980   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10981         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10982                      (match_operand:QI 2 "const_int_operand")))
10983    (clobber (reg:CC FLAGS_REG))]
10984   "TARGET_64BIT && INTVAL (operands[2]) == 63
10985    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10986    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10987   "@
10988    {cqto|cqo}
10989    sar{q}\t{%2, %0|%0, %2}"
10990   [(set_attr "type" "imovx,ishift")
10991    (set_attr "prefix_0f" "0,*")
10992    (set_attr "length_immediate" "0,*")
10993    (set_attr "modrm" "0,1")
10994    (set_attr "mode" "DI")])
10996 (define_insn "*ashrsi3_cvt_zext"
10997   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10998         (zero_extend:DI
10999           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11000                        (match_operand:QI 2 "const_int_operand"))))
11001    (clobber (reg:CC FLAGS_REG))]
11002   "TARGET_64BIT && INTVAL (operands[2]) == 31
11003    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11004    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11005   "@
11006    {cltd|cdq}
11007    sar{l}\t{%2, %k0|%k0, %2}"
11008   [(set_attr "type" "imovx,ishift")
11009    (set_attr "prefix_0f" "0,*")
11010    (set_attr "length_immediate" "0,*")
11011    (set_attr "modrm" "0,1")
11012    (set_attr "mode" "SI")])
11014 (define_insn "ashrsi3_cvt"
11015   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11016         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11017                      (match_operand:QI 2 "const_int_operand")))
11018    (clobber (reg:CC FLAGS_REG))]
11019   "INTVAL (operands[2]) == 31
11020    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11021    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11022   "@
11023    {cltd|cdq}
11024    sar{l}\t{%2, %0|%0, %2}"
11025   [(set_attr "type" "imovx,ishift")
11026    (set_attr "prefix_0f" "0,*")
11027    (set_attr "length_immediate" "0,*")
11028    (set_attr "modrm" "0,1")
11029    (set_attr "mode" "SI")])
11031 (define_expand "x86_shift<mode>_adj_3"
11032   [(use (match_operand:SWI48 0 "register_operand"))
11033    (use (match_operand:SWI48 1 "register_operand"))
11034    (use (match_operand:QI 2 "register_operand"))]
11035   ""
11037   rtx_code_label *label = gen_label_rtx ();
11038   rtx tmp;
11040   emit_insn (gen_testqi_ccz_1 (operands[2],
11041                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11043   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11044   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11045   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11046                               gen_rtx_LABEL_REF (VOIDmode, label),
11047                               pc_rtx);
11048   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11049   JUMP_LABEL (tmp) = label;
11051   emit_move_insn (operands[0], operands[1]);
11052   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11053                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11054   emit_label (label);
11055   LABEL_NUSES (label) = 1;
11057   DONE;
11060 (define_insn "*bmi2_<shift_insn><mode>3_1"
11061   [(set (match_operand:SWI48 0 "register_operand" "=r")
11062         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11063                            (match_operand:SWI48 2 "register_operand" "r")))]
11064   "TARGET_BMI2"
11065   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11066   [(set_attr "type" "ishiftx")
11067    (set_attr "mode" "<MODE>")])
11069 (define_insn "*<shift_insn><mode>3_1"
11070   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11071         (any_shiftrt:SWI48
11072           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11073           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11074    (clobber (reg:CC FLAGS_REG))]
11075   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11077   switch (get_attr_type (insn))
11078     {
11079     case TYPE_ISHIFTX:
11080       return "#";
11082     default:
11083       if (operands[2] == const1_rtx
11084           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11085         return "<shift>{<imodesuffix>}\t%0";
11086       else
11087         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11088     }
11090   [(set_attr "isa" "*,bmi2")
11091    (set_attr "type" "ishift,ishiftx")
11092    (set (attr "length_immediate")
11093      (if_then_else
11094        (and (match_operand 2 "const1_operand")
11095             (ior (match_test "TARGET_SHIFT1")
11096                  (match_test "optimize_function_for_size_p (cfun)")))
11097        (const_string "0")
11098        (const_string "*")))
11099    (set_attr "mode" "<MODE>")])
11101 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11102 (define_split
11103   [(set (match_operand:SWI48 0 "register_operand")
11104         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11105                            (match_operand:QI 2 "register_operand")))
11106    (clobber (reg:CC FLAGS_REG))]
11107   "TARGET_BMI2 && reload_completed"
11108   [(set (match_dup 0)
11109         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11110   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11112 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11113   [(set (match_operand:DI 0 "register_operand" "=r")
11114         (zero_extend:DI
11115           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11116                           (match_operand:SI 2 "register_operand" "r"))))]
11117   "TARGET_64BIT && TARGET_BMI2"
11118   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11119   [(set_attr "type" "ishiftx")
11120    (set_attr "mode" "SI")])
11122 (define_insn "*<shift_insn>si3_1_zext"
11123   [(set (match_operand:DI 0 "register_operand" "=r,r")
11124         (zero_extend:DI
11125           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11126                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11127    (clobber (reg:CC FLAGS_REG))]
11128   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11130   switch (get_attr_type (insn))
11131     {
11132     case TYPE_ISHIFTX:
11133       return "#";
11135     default:
11136       if (operands[2] == const1_rtx
11137           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11138         return "<shift>{l}\t%k0";
11139       else
11140         return "<shift>{l}\t{%2, %k0|%k0, %2}";
11141     }
11143   [(set_attr "isa" "*,bmi2")
11144    (set_attr "type" "ishift,ishiftx")
11145    (set (attr "length_immediate")
11146      (if_then_else
11147        (and (match_operand 2 "const1_operand")
11148             (ior (match_test "TARGET_SHIFT1")
11149                  (match_test "optimize_function_for_size_p (cfun)")))
11150        (const_string "0")
11151        (const_string "*")))
11152    (set_attr "mode" "SI")])
11154 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11155 (define_split
11156   [(set (match_operand:DI 0 "register_operand")
11157         (zero_extend:DI
11158           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11159                           (match_operand:QI 2 "register_operand"))))
11160    (clobber (reg:CC FLAGS_REG))]
11161   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11162   [(set (match_dup 0)
11163         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11164   "operands[2] = gen_lowpart (SImode, operands[2]);")
11166 (define_insn "*<shift_insn><mode>3_1"
11167   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11168         (any_shiftrt:SWI12
11169           (match_operand:SWI12 1 "nonimmediate_operand" "0")
11170           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11171    (clobber (reg:CC FLAGS_REG))]
11172   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11174   if (operands[2] == const1_rtx
11175       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11176     return "<shift>{<imodesuffix>}\t%0";
11177   else
11178     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11180   [(set_attr "type" "ishift")
11181    (set (attr "length_immediate")
11182      (if_then_else
11183        (and (match_operand 2 "const1_operand")
11184             (ior (match_test "TARGET_SHIFT1")
11185                  (match_test "optimize_function_for_size_p (cfun)")))
11186        (const_string "0")
11187        (const_string "*")))
11188    (set_attr "mode" "<MODE>")])
11190 (define_insn "*<shift_insn>qi3_1_slp"
11191   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11192         (any_shiftrt:QI (match_dup 0)
11193                         (match_operand:QI 1 "nonmemory_operand" "cI")))
11194    (clobber (reg:CC FLAGS_REG))]
11195   "(optimize_function_for_size_p (cfun)
11196     || !TARGET_PARTIAL_REG_STALL
11197     || (operands[1] == const1_rtx
11198         && TARGET_SHIFT1))"
11200   if (operands[1] == const1_rtx
11201       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11202     return "<shift>{b}\t%0";
11203   else
11204     return "<shift>{b}\t{%1, %0|%0, %1}";
11206   [(set_attr "type" "ishift1")
11207    (set (attr "length_immediate")
11208      (if_then_else
11209        (and (match_operand 1 "const1_operand")
11210             (ior (match_test "TARGET_SHIFT1")
11211                  (match_test "optimize_function_for_size_p (cfun)")))
11212        (const_string "0")
11213        (const_string "*")))
11214    (set_attr "mode" "QI")])
11216 ;; This pattern can't accept a variable shift count, since shifts by
11217 ;; zero don't affect the flags.  We assume that shifts by constant
11218 ;; zero are optimized away.
11219 (define_insn "*<shift_insn><mode>3_cmp"
11220   [(set (reg FLAGS_REG)
11221         (compare
11222           (any_shiftrt:SWI
11223             (match_operand:SWI 1 "nonimmediate_operand" "0")
11224             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11225           (const_int 0)))
11226    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11227         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11228   "(optimize_function_for_size_p (cfun)
11229     || !TARGET_PARTIAL_FLAG_REG_STALL
11230     || (operands[2] == const1_rtx
11231         && TARGET_SHIFT1))
11232    && ix86_match_ccmode (insn, CCGOCmode)
11233    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11235   if (operands[2] == const1_rtx
11236       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11237     return "<shift>{<imodesuffix>}\t%0";
11238   else
11239     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11241   [(set_attr "type" "ishift")
11242    (set (attr "length_immediate")
11243      (if_then_else
11244        (and (match_operand 2 "const1_operand")
11245             (ior (match_test "TARGET_SHIFT1")
11246                  (match_test "optimize_function_for_size_p (cfun)")))
11247        (const_string "0")
11248        (const_string "*")))
11249    (set_attr "mode" "<MODE>")])
11251 (define_insn "*<shift_insn>si3_cmp_zext"
11252   [(set (reg FLAGS_REG)
11253         (compare
11254           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11255                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
11256           (const_int 0)))
11257    (set (match_operand:DI 0 "register_operand" "=r")
11258         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11259   "TARGET_64BIT
11260    && (optimize_function_for_size_p (cfun)
11261        || !TARGET_PARTIAL_FLAG_REG_STALL
11262        || (operands[2] == const1_rtx
11263            && TARGET_SHIFT1))
11264    && ix86_match_ccmode (insn, CCGOCmode)
11265    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11267   if (operands[2] == const1_rtx
11268       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11269     return "<shift>{l}\t%k0";
11270   else
11271     return "<shift>{l}\t{%2, %k0|%k0, %2}";
11273   [(set_attr "type" "ishift")
11274    (set (attr "length_immediate")
11275      (if_then_else
11276        (and (match_operand 2 "const1_operand")
11277             (ior (match_test "TARGET_SHIFT1")
11278                  (match_test "optimize_function_for_size_p (cfun)")))
11279        (const_string "0")
11280        (const_string "*")))
11281    (set_attr "mode" "SI")])
11283 (define_insn "*<shift_insn><mode>3_cconly"
11284   [(set (reg FLAGS_REG)
11285         (compare
11286           (any_shiftrt:SWI
11287             (match_operand:SWI 1 "register_operand" "0")
11288             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11289           (const_int 0)))
11290    (clobber (match_scratch:SWI 0 "=<r>"))]
11291   "(optimize_function_for_size_p (cfun)
11292     || !TARGET_PARTIAL_FLAG_REG_STALL
11293     || (operands[2] == const1_rtx
11294         && TARGET_SHIFT1))
11295    && ix86_match_ccmode (insn, CCGOCmode)"
11297   if (operands[2] == const1_rtx
11298       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11299     return "<shift>{<imodesuffix>}\t%0";
11300   else
11301     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11303   [(set_attr "type" "ishift")
11304    (set (attr "length_immediate")
11305      (if_then_else
11306        (and (match_operand 2 "const1_operand")
11307             (ior (match_test "TARGET_SHIFT1")
11308                  (match_test "optimize_function_for_size_p (cfun)")))
11309        (const_string "0")
11310        (const_string "*")))
11311    (set_attr "mode" "<MODE>")])
11313 ;; Rotate instructions
11315 (define_expand "<rotate_insn>ti3"
11316   [(set (match_operand:TI 0 "register_operand")
11317         (any_rotate:TI (match_operand:TI 1 "register_operand")
11318                        (match_operand:QI 2 "nonmemory_operand")))]
11319   "TARGET_64BIT"
11321   if (const_1_to_63_operand (operands[2], VOIDmode))
11322     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11323                 (operands[0], operands[1], operands[2]));
11324   else
11325     FAIL;
11327   DONE;
11330 (define_expand "<rotate_insn>di3"
11331   [(set (match_operand:DI 0 "shiftdi_operand")
11332         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11333                        (match_operand:QI 2 "nonmemory_operand")))]
11334  ""
11336   if (TARGET_64BIT)
11337     ix86_expand_binary_operator (<CODE>, DImode, operands);
11338   else if (const_1_to_31_operand (operands[2], VOIDmode))
11339     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11340                 (operands[0], operands[1], operands[2]));
11341   else
11342     FAIL;
11344   DONE;
11347 (define_expand "<rotate_insn><mode>3"
11348   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11349         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11350                             (match_operand:QI 2 "nonmemory_operand")))]
11351   ""
11352   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11354 ;; Avoid useless masking of count operand.
11355 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11356   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11357         (any_rotate:SWI48
11358           (match_operand:SWI48 1 "nonimmediate_operand")
11359           (subreg:QI
11360             (and:SI
11361               (match_operand:SI 2 "register_operand" "c")
11362               (match_operand:SI 3 "const_int_operand")) 0)))
11363    (clobber (reg:CC FLAGS_REG))]
11364   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11365    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11366       == GET_MODE_BITSIZE (<MODE>mode)-1
11367    && can_create_pseudo_p ()"
11368   "#"
11369   "&& 1"
11370   [(parallel
11371      [(set (match_dup 0)
11372            (any_rotate:SWI48 (match_dup 1)
11373                              (match_dup 2)))
11374       (clobber (reg:CC FLAGS_REG))])]
11375   "operands[2] = gen_lowpart (QImode, operands[2]);")
11377 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11378   [(set (match_operand:SWI48 0 "nonimmediate_operand")
11379         (any_rotate:SWI48
11380           (match_operand:SWI48 1 "nonimmediate_operand")
11381           (and:QI
11382             (match_operand:QI 2 "register_operand" "c")
11383             (match_operand:QI 3 "const_int_operand"))))
11384    (clobber (reg:CC FLAGS_REG))]
11385   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11386    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11387       == GET_MODE_BITSIZE (<MODE>mode)-1
11388    && can_create_pseudo_p ()"
11389   "#"
11390   "&& 1"
11391   [(parallel
11392      [(set (match_dup 0)
11393            (any_rotate:SWI48 (match_dup 1)
11394                              (match_dup 2)))
11395       (clobber (reg:CC FLAGS_REG))])])
11397 ;; Implement rotation using two double-precision
11398 ;; shift instructions and a scratch register.
11400 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11401  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11402        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11403                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11404   (clobber (reg:CC FLAGS_REG))
11405   (clobber (match_scratch:DWIH 3 "=&r"))]
11406  ""
11407  "#"
11408  "reload_completed"
11409  [(set (match_dup 3) (match_dup 4))
11410   (parallel
11411    [(set (match_dup 4)
11412          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11413                    (lshiftrt:DWIH (match_dup 5)
11414                                   (minus:QI (match_dup 6) (match_dup 2)))))
11415     (clobber (reg:CC FLAGS_REG))])
11416   (parallel
11417    [(set (match_dup 5)
11418          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11419                    (lshiftrt:DWIH (match_dup 3)
11420                                   (minus:QI (match_dup 6) (match_dup 2)))))
11421     (clobber (reg:CC FLAGS_REG))])]
11423   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11425   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11428 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11429  [(set (match_operand:<DWI> 0 "register_operand" "=r")
11430        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11431                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11432   (clobber (reg:CC FLAGS_REG))
11433   (clobber (match_scratch:DWIH 3 "=&r"))]
11434  ""
11435  "#"
11436  "reload_completed"
11437  [(set (match_dup 3) (match_dup 4))
11438   (parallel
11439    [(set (match_dup 4)
11440          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11441                    (ashift:DWIH (match_dup 5)
11442                                 (minus:QI (match_dup 6) (match_dup 2)))))
11443     (clobber (reg:CC FLAGS_REG))])
11444   (parallel
11445    [(set (match_dup 5)
11446          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11447                    (ashift:DWIH (match_dup 3)
11448                                 (minus:QI (match_dup 6) (match_dup 2)))))
11449     (clobber (reg:CC FLAGS_REG))])]
11451   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11453   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11456 (define_mode_attr rorx_immediate_operand
11457         [(SI "const_0_to_31_operand")
11458          (DI "const_0_to_63_operand")])
11460 (define_insn "*bmi2_rorx<mode>3_1"
11461   [(set (match_operand:SWI48 0 "register_operand" "=r")
11462         (rotatert:SWI48
11463           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11464           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11465   "TARGET_BMI2"
11466   "rorx\t{%2, %1, %0|%0, %1, %2}"
11467   [(set_attr "type" "rotatex")
11468    (set_attr "mode" "<MODE>")])
11470 (define_insn "*<rotate_insn><mode>3_1"
11471   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11472         (any_rotate:SWI48
11473           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11474           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11475    (clobber (reg:CC FLAGS_REG))]
11476   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11478   switch (get_attr_type (insn))
11479     {
11480     case TYPE_ROTATEX:
11481       return "#";
11483     default:
11484       if (operands[2] == const1_rtx
11485           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11486         return "<rotate>{<imodesuffix>}\t%0";
11487       else
11488         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11489     }
11491   [(set_attr "isa" "*,bmi2")
11492    (set_attr "type" "rotate,rotatex")
11493    (set (attr "length_immediate")
11494      (if_then_else
11495        (and (eq_attr "type" "rotate")
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" "<MODE>")])
11503 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11504 (define_split
11505   [(set (match_operand:SWI48 0 "register_operand")
11506         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11507                       (match_operand:QI 2 "const_int_operand")))
11508    (clobber (reg:CC FLAGS_REG))]
11509   "TARGET_BMI2 && reload_completed"
11510   [(set (match_dup 0)
11511         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11513   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11515   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11518 (define_split
11519   [(set (match_operand:SWI48 0 "register_operand")
11520         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11521                         (match_operand:QI 2 "const_int_operand")))
11522    (clobber (reg:CC FLAGS_REG))]
11523   "TARGET_BMI2 && reload_completed"
11524   [(set (match_dup 0)
11525         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11527 (define_insn "*bmi2_rorxsi3_1_zext"
11528   [(set (match_operand:DI 0 "register_operand" "=r")
11529         (zero_extend:DI
11530           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11531                        (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11532   "TARGET_64BIT && TARGET_BMI2"
11533   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11534   [(set_attr "type" "rotatex")
11535    (set_attr "mode" "SI")])
11537 (define_insn "*<rotate_insn>si3_1_zext"
11538   [(set (match_operand:DI 0 "register_operand" "=r,r")
11539         (zero_extend:DI
11540           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11541                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11542    (clobber (reg:CC FLAGS_REG))]
11543   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11545   switch (get_attr_type (insn))
11546     {
11547     case TYPE_ROTATEX:
11548       return "#";
11550     default:
11551       if (operands[2] == const1_rtx
11552           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11553         return "<rotate>{l}\t%k0";
11554       else
11555         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11556     }
11558   [(set_attr "isa" "*,bmi2")
11559    (set_attr "type" "rotate,rotatex")
11560    (set (attr "length_immediate")
11561      (if_then_else
11562        (and (eq_attr "type" "rotate")
11563             (and (match_operand 2 "const1_operand")
11564                  (ior (match_test "TARGET_SHIFT1")
11565                       (match_test "optimize_function_for_size_p (cfun)"))))
11566        (const_string "0")
11567        (const_string "*")))
11568    (set_attr "mode" "SI")])
11570 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11571 (define_split
11572   [(set (match_operand:DI 0 "register_operand")
11573         (zero_extend:DI
11574           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11575                      (match_operand:QI 2 "const_int_operand"))))
11576    (clobber (reg:CC FLAGS_REG))]
11577   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11578   [(set (match_dup 0)
11579         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11581   int bitsize = GET_MODE_BITSIZE (SImode);
11583   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11586 (define_split
11587   [(set (match_operand:DI 0 "register_operand")
11588         (zero_extend:DI
11589           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11590                        (match_operand:QI 2 "const_int_operand"))))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11593   [(set (match_dup 0)
11594         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11596 (define_insn "*<rotate_insn><mode>3_1"
11597   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11598         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11599                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11600    (clobber (reg:CC FLAGS_REG))]
11601   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11603   if (operands[2] == const1_rtx
11604       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11605     return "<rotate>{<imodesuffix>}\t%0";
11606   else
11607     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11609   [(set_attr "type" "rotate")
11610    (set (attr "length_immediate")
11611      (if_then_else
11612        (and (match_operand 2 "const1_operand")
11613             (ior (match_test "TARGET_SHIFT1")
11614                  (match_test "optimize_function_for_size_p (cfun)")))
11615        (const_string "0")
11616        (const_string "*")))
11617    (set_attr "mode" "<MODE>")])
11619 (define_insn "*<rotate_insn>qi3_1_slp"
11620   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11621         (any_rotate:QI (match_dup 0)
11622                        (match_operand:QI 1 "nonmemory_operand" "cI")))
11623    (clobber (reg:CC FLAGS_REG))]
11624   "(optimize_function_for_size_p (cfun)
11625     || !TARGET_PARTIAL_REG_STALL
11626     || (operands[1] == const1_rtx
11627         && TARGET_SHIFT1))"
11629   if (operands[1] == const1_rtx
11630       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11631     return "<rotate>{b}\t%0";
11632   else
11633     return "<rotate>{b}\t{%1, %0|%0, %1}";
11635   [(set_attr "type" "rotate1")
11636    (set (attr "length_immediate")
11637      (if_then_else
11638        (and (match_operand 1 "const1_operand")
11639             (ior (match_test "TARGET_SHIFT1")
11640                  (match_test "optimize_function_for_size_p (cfun)")))
11641        (const_string "0")
11642        (const_string "*")))
11643    (set_attr "mode" "QI")])
11645 (define_split
11646  [(set (match_operand:HI 0 "QIreg_operand")
11647        (any_rotate:HI (match_dup 0) (const_int 8)))
11648   (clobber (reg:CC FLAGS_REG))]
11649  "reload_completed
11650   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11651  [(parallel [(set (strict_low_part (match_dup 0))
11652                   (bswap:HI (match_dup 0)))
11653              (clobber (reg:CC FLAGS_REG))])])
11655 ;; Bit set / bit test instructions
11657 ;; %%% bts, btr, btc
11659 ;; These instructions are *slow* when applied to memory.
11661 (define_code_attr btsc [(ior "bts") (xor "btc")])
11663 (define_insn "*<btsc><mode>"
11664   [(set (match_operand:SWI48 0 "register_operand" "=r")
11665         (any_or:SWI48
11666           (ashift:SWI48 (const_int 1)
11667                         (match_operand:QI 2 "register_operand" "r"))
11668           (match_operand:SWI48 1 "register_operand" "0")))
11669    (clobber (reg:CC FLAGS_REG))]
11670   "TARGET_USE_BT"
11671   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11672   [(set_attr "type" "alu1")
11673    (set_attr "prefix_0f" "1")
11674    (set_attr "znver1_decode" "double")
11675    (set_attr "mode" "<MODE>")])
11677 ;; Avoid useless masking of count operand.
11678 (define_insn_and_split "*<btsc><mode>_mask"
11679   [(set (match_operand:SWI48 0 "register_operand")
11680         (any_or:SWI48
11681           (ashift:SWI48
11682             (const_int 1)
11683             (subreg:QI
11684               (and:SI
11685                 (match_operand:SI 1 "register_operand")
11686                 (match_operand:SI 2 "const_int_operand")) 0))
11687           (match_operand:SWI48 3 "register_operand")))
11688    (clobber (reg:CC FLAGS_REG))]
11689   "TARGET_USE_BT
11690    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11691       == GET_MODE_BITSIZE (<MODE>mode)-1
11692    && can_create_pseudo_p ()"
11693   "#"
11694   "&& 1"
11695   [(parallel
11696      [(set (match_dup 0)
11697            (any_or:SWI48
11698              (ashift:SWI48 (const_int 1)
11699                            (match_dup 1))
11700              (match_dup 3)))
11701       (clobber (reg:CC FLAGS_REG))])]
11702   "operands[1] = gen_lowpart (QImode, operands[1]);")
11704 (define_insn_and_split "*<btsc><mode>_mask_1"
11705   [(set (match_operand:SWI48 0 "register_operand")
11706         (any_or:SWI48
11707           (ashift:SWI48
11708             (const_int 1)
11709             (and:QI
11710               (match_operand:QI 1 "register_operand")
11711               (match_operand:QI 2 "const_int_operand")))
11712           (match_operand:SWI48 3 "register_operand")))
11713    (clobber (reg:CC FLAGS_REG))]
11714   "TARGET_USE_BT
11715    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11716       == GET_MODE_BITSIZE (<MODE>mode)-1
11717    && can_create_pseudo_p ()"
11718   "#"
11719   "&& 1"
11720   [(parallel
11721      [(set (match_dup 0)
11722            (any_or:SWI48
11723              (ashift:SWI48 (const_int 1)
11724                            (match_dup 1))
11725              (match_dup 3)))
11726       (clobber (reg:CC FLAGS_REG))])])
11728 (define_insn "*btr<mode>"
11729   [(set (match_operand:SWI48 0 "register_operand" "=r")
11730         (and:SWI48
11731           (rotate:SWI48 (const_int -2)
11732                         (match_operand:QI 2 "register_operand" "r"))
11733         (match_operand:SWI48 1 "register_operand" "0")))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "TARGET_USE_BT"
11736   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11737   [(set_attr "type" "alu1")
11738    (set_attr "prefix_0f" "1")
11739    (set_attr "znver1_decode" "double")
11740    (set_attr "mode" "<MODE>")])
11742 ;; Avoid useless masking of count operand.
11743 (define_insn_and_split "*btr<mode>_mask"
11744   [(set (match_operand:SWI48 0 "register_operand")
11745         (and:SWI48
11746           (rotate:SWI48
11747             (const_int -2)
11748             (subreg:QI
11749               (and:SI
11750                 (match_operand:SI 1 "register_operand")
11751                 (match_operand:SI 2 "const_int_operand")) 0))
11752           (match_operand:SWI48 3 "register_operand")))
11753    (clobber (reg:CC FLAGS_REG))]
11754   "TARGET_USE_BT
11755    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11756       == GET_MODE_BITSIZE (<MODE>mode)-1
11757    && can_create_pseudo_p ()"
11758   "#"
11759   "&& 1"
11760   [(parallel
11761      [(set (match_dup 0)
11762            (and:SWI48
11763              (rotate:SWI48 (const_int -2)
11764                            (match_dup 1))
11765              (match_dup 3)))
11766       (clobber (reg:CC FLAGS_REG))])]
11767   "operands[1] = gen_lowpart (QImode, operands[1]);")
11769 (define_insn_and_split "*btr<mode>_mask_1"
11770   [(set (match_operand:SWI48 0 "register_operand")
11771         (and:SWI48
11772           (rotate:SWI48
11773             (const_int -2)
11774             (and:QI
11775               (match_operand:QI 1 "register_operand")
11776               (match_operand:QI 2 "const_int_operand")))
11777           (match_operand:SWI48 3 "register_operand")))
11778    (clobber (reg:CC FLAGS_REG))]
11779   "TARGET_USE_BT
11780    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11781       == GET_MODE_BITSIZE (<MODE>mode)-1
11782    && can_create_pseudo_p ()"
11783   "#"
11784   "&& 1"
11785   [(parallel
11786      [(set (match_dup 0)
11787            (and:SWI48
11788              (rotate:SWI48 (const_int -2)
11789                            (match_dup 1))
11790              (match_dup 3)))
11791       (clobber (reg:CC FLAGS_REG))])])
11793 ;; These instructions are never faster than the corresponding
11794 ;; and/ior/xor operations when using immediate operand, so with
11795 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
11796 ;; relevant immediates within the instruction itself, so operating
11797 ;; on bits in the high 32-bits of a register becomes easier.
11799 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11800 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11801 ;; negdf respectively, so they can never be disabled entirely.
11803 (define_insn "*btsq_imm"
11804   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11805                          (const_int 1)
11806                          (match_operand 1 "const_0_to_63_operand" "J"))
11807         (const_int 1))
11808    (clobber (reg:CC FLAGS_REG))]
11809   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11810   "bts{q}\t{%1, %0|%0, %1}"
11811   [(set_attr "type" "alu1")
11812    (set_attr "prefix_0f" "1")
11813    (set_attr "znver1_decode" "double")
11814    (set_attr "mode" "DI")])
11816 (define_insn "*btrq_imm"
11817   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11818                          (const_int 1)
11819                          (match_operand 1 "const_0_to_63_operand" "J"))
11820         (const_int 0))
11821    (clobber (reg:CC FLAGS_REG))]
11822   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11823   "btr{q}\t{%1, %0|%0, %1}"
11824   [(set_attr "type" "alu1")
11825    (set_attr "prefix_0f" "1")
11826    (set_attr "znver1_decode" "double")
11827    (set_attr "mode" "DI")])
11829 (define_insn "*btcq_imm"
11830   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11831                          (const_int 1)
11832                          (match_operand 1 "const_0_to_63_operand" "J"))
11833         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11834    (clobber (reg:CC FLAGS_REG))]
11835   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11836   "btc{q}\t{%1, %0|%0, %1}"
11837   [(set_attr "type" "alu1")
11838    (set_attr "prefix_0f" "1")
11839    (set_attr "znver1_decode" "double")
11840    (set_attr "mode" "DI")])
11842 ;; Allow Nocona to avoid these instructions if a register is available.
11844 (define_peephole2
11845   [(match_scratch:DI 2 "r")
11846    (parallel [(set (zero_extract:DI
11847                      (match_operand:DI 0 "nonimmediate_operand")
11848                      (const_int 1)
11849                      (match_operand 1 "const_0_to_63_operand"))
11850                    (const_int 1))
11851               (clobber (reg:CC FLAGS_REG))])]
11852   "TARGET_64BIT && !TARGET_USE_BT"
11853   [(parallel [(set (match_dup 0)
11854                    (ior:DI (match_dup 0) (match_dup 3)))
11855               (clobber (reg:CC FLAGS_REG))])]
11857   int i = INTVAL (operands[1]);
11859   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11861   if (!x86_64_immediate_operand (operands[3], DImode))
11862     {
11863       emit_move_insn (operands[2], operands[3]);
11864       operands[3] = operands[2];
11865     }
11868 (define_peephole2
11869   [(match_scratch:DI 2 "r")
11870    (parallel [(set (zero_extract:DI
11871                      (match_operand:DI 0 "nonimmediate_operand")
11872                      (const_int 1)
11873                      (match_operand 1 "const_0_to_63_operand"))
11874                    (const_int 0))
11875               (clobber (reg:CC FLAGS_REG))])]
11876   "TARGET_64BIT && !TARGET_USE_BT"
11877   [(parallel [(set (match_dup 0)
11878                    (and:DI (match_dup 0) (match_dup 3)))
11879               (clobber (reg:CC FLAGS_REG))])]
11881   int i = INTVAL (operands[1]);
11883   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11885   if (!x86_64_immediate_operand (operands[3], DImode))
11886     {
11887       emit_move_insn (operands[2], operands[3]);
11888       operands[3] = operands[2];
11889     }
11892 (define_peephole2
11893   [(match_scratch:DI 2 "r")
11894    (parallel [(set (zero_extract:DI
11895                      (match_operand:DI 0 "nonimmediate_operand")
11896                      (const_int 1)
11897                      (match_operand 1 "const_0_to_63_operand"))
11898               (not:DI (zero_extract:DI
11899                         (match_dup 0) (const_int 1) (match_dup 1))))
11900               (clobber (reg:CC FLAGS_REG))])]
11901   "TARGET_64BIT && !TARGET_USE_BT"
11902   [(parallel [(set (match_dup 0)
11903                    (xor:DI (match_dup 0) (match_dup 3)))
11904               (clobber (reg:CC FLAGS_REG))])]
11906   int i = INTVAL (operands[1]);
11908   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11910   if (!x86_64_immediate_operand (operands[3], DImode))
11911     {
11912       emit_move_insn (operands[2], operands[3]);
11913       operands[3] = operands[2];
11914     }
11917 ;; %%% bt
11919 (define_insn "*bt<mode>"
11920   [(set (reg:CCC FLAGS_REG)
11921         (compare:CCC
11922           (zero_extract:SWI48
11923             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11924             (const_int 1)
11925             (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11926           (const_int 0)))]
11927   ""
11929   switch (get_attr_mode (insn))
11930     {
11931     case MODE_SI:
11932       return "bt{l}\t{%1, %k0|%k0, %1}";
11934     case MODE_DI:
11935       return "bt{q}\t{%q1, %0|%0, %q1}";
11937     default:
11938       gcc_unreachable ();
11939     }
11941   [(set_attr "type" "alu1")
11942    (set_attr "prefix_0f" "1")
11943    (set (attr "mode")
11944         (if_then_else
11945           (and (match_test "CONST_INT_P (operands[1])")
11946                (match_test "INTVAL (operands[1]) < 32"))
11947           (const_string "SI")
11948           (const_string "<MODE>")))])
11950 (define_insn_and_split "*jcc_bt<mode>"
11951   [(set (pc)
11952         (if_then_else (match_operator 0 "bt_comparison_operator"
11953                         [(zero_extract:SWI48
11954                            (match_operand:SWI48 1 "nonimmediate_operand")
11955                            (const_int 1)
11956                            (match_operand:SI 2 "nonmemory_operand"))
11957                          (const_int 0)])
11958                       (label_ref (match_operand 3))
11959                       (pc)))
11960    (clobber (reg:CC FLAGS_REG))]
11961   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11962    && (CONST_INT_P (operands[2])
11963        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11964           && INTVAL (operands[2])
11965                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11966        : !memory_operand (operands[1], <MODE>mode))
11967    && can_create_pseudo_p ()"
11968   "#"
11969   "&& 1"
11970   [(set (reg:CCC FLAGS_REG)
11971         (compare:CCC
11972           (zero_extract:SWI48
11973             (match_dup 1)
11974             (const_int 1)
11975             (match_dup 2))
11976           (const_int 0)))
11977    (set (pc)
11978         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11979                       (label_ref (match_dup 3))
11980                       (pc)))]
11982   operands[0] = shallow_copy_rtx (operands[0]);
11983   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11986 (define_insn_and_split "*jcc_bt<mode>_1"
11987   [(set (pc)
11988         (if_then_else (match_operator 0 "bt_comparison_operator"
11989                         [(zero_extract:SWI48
11990                            (match_operand:SWI48 1 "register_operand")
11991                            (const_int 1)
11992                            (zero_extend:SI
11993                              (match_operand:QI 2 "register_operand")))
11994                          (const_int 0)])
11995                       (label_ref (match_operand 3))
11996                       (pc)))
11997    (clobber (reg:CC FLAGS_REG))]
11998   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11999    && can_create_pseudo_p ()"
12000   "#"
12001   "&& 1"
12002   [(set (reg:CCC FLAGS_REG)
12003         (compare:CCC
12004           (zero_extract:SWI48
12005             (match_dup 1)
12006             (const_int 1)
12007             (match_dup 2))
12008           (const_int 0)))
12009    (set (pc)
12010         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12011                       (label_ref (match_dup 3))
12012                       (pc)))]
12014   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12015   operands[0] = shallow_copy_rtx (operands[0]);
12016   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12019 ;; Avoid useless masking of bit offset operand.
12020 (define_insn_and_split "*jcc_bt<mode>_mask"
12021   [(set (pc)
12022         (if_then_else (match_operator 0 "bt_comparison_operator"
12023                         [(zero_extract:SWI48
12024                            (match_operand:SWI48 1 "register_operand")
12025                            (const_int 1)
12026                            (and:SI
12027                              (match_operand:SI 2 "register_operand")
12028                              (match_operand 3 "const_int_operand")))])
12029                       (label_ref (match_operand 4))
12030                       (pc)))
12031    (clobber (reg:CC FLAGS_REG))]
12032   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12033    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12034       == GET_MODE_BITSIZE (<MODE>mode)-1
12035    && can_create_pseudo_p ()"
12036   "#"
12037   "&& 1"
12038   [(set (reg:CCC FLAGS_REG)
12039         (compare:CCC
12040           (zero_extract:SWI48
12041             (match_dup 1)
12042             (const_int 1)
12043             (match_dup 2))
12044           (const_int 0)))
12045    (set (pc)
12046         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12047                       (label_ref (match_dup 4))
12048                       (pc)))]
12050   operands[0] = shallow_copy_rtx (operands[0]);
12051   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12054 ;; Store-flag instructions.
12056 ;; For all sCOND expanders, also expand the compare or test insn that
12057 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12059 (define_insn_and_split "*setcc_di_1"
12060   [(set (match_operand:DI 0 "register_operand" "=q")
12061         (match_operator:DI 1 "ix86_comparison_operator"
12062           [(reg FLAGS_REG) (const_int 0)]))]
12063   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12064   "#"
12065   "&& reload_completed"
12066   [(set (match_dup 2) (match_dup 1))
12067    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12069   operands[1] = shallow_copy_rtx (operands[1]);
12070   PUT_MODE (operands[1], QImode);
12071   operands[2] = gen_lowpart (QImode, operands[0]);
12074 (define_insn_and_split "*setcc_si_1_and"
12075   [(set (match_operand:SI 0 "register_operand" "=q")
12076         (match_operator:SI 1 "ix86_comparison_operator"
12077           [(reg FLAGS_REG) (const_int 0)]))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "!TARGET_PARTIAL_REG_STALL
12080    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12081   "#"
12082   "&& reload_completed"
12083   [(set (match_dup 2) (match_dup 1))
12084    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12085               (clobber (reg:CC FLAGS_REG))])]
12087   operands[1] = shallow_copy_rtx (operands[1]);
12088   PUT_MODE (operands[1], QImode);
12089   operands[2] = gen_lowpart (QImode, operands[0]);
12092 (define_insn_and_split "*setcc_si_1_movzbl"
12093   [(set (match_operand:SI 0 "register_operand" "=q")
12094         (match_operator:SI 1 "ix86_comparison_operator"
12095           [(reg FLAGS_REG) (const_int 0)]))]
12096   "!TARGET_PARTIAL_REG_STALL
12097    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12098   "#"
12099   "&& reload_completed"
12100   [(set (match_dup 2) (match_dup 1))
12101    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12103   operands[1] = shallow_copy_rtx (operands[1]);
12104   PUT_MODE (operands[1], QImode);
12105   operands[2] = gen_lowpart (QImode, operands[0]);
12108 (define_insn "*setcc_qi"
12109   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12110         (match_operator:QI 1 "ix86_comparison_operator"
12111           [(reg FLAGS_REG) (const_int 0)]))]
12112   ""
12113   "set%C1\t%0"
12114   [(set_attr "type" "setcc")
12115    (set_attr "mode" "QI")])
12117 (define_insn "*setcc_qi_slp"
12118   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12119         (match_operator:QI 1 "ix86_comparison_operator"
12120           [(reg FLAGS_REG) (const_int 0)]))]
12121   ""
12122   "set%C1\t%0"
12123   [(set_attr "type" "setcc")
12124    (set_attr "mode" "QI")])
12126 ;; In general it is not safe to assume too much about CCmode registers,
12127 ;; so simplify-rtx stops when it sees a second one.  Under certain
12128 ;; conditions this is safe on x86, so help combine not create
12130 ;;      seta    %al
12131 ;;      testb   %al, %al
12132 ;;      sete    %al
12134 (define_split
12135   [(set (match_operand:QI 0 "nonimmediate_operand")
12136         (ne:QI (match_operator 1 "ix86_comparison_operator"
12137                  [(reg FLAGS_REG) (const_int 0)])
12138             (const_int 0)))]
12139   ""
12140   [(set (match_dup 0) (match_dup 1))]
12142   operands[1] = shallow_copy_rtx (operands[1]);
12143   PUT_MODE (operands[1], QImode);
12146 (define_split
12147   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12148         (ne:QI (match_operator 1 "ix86_comparison_operator"
12149                  [(reg FLAGS_REG) (const_int 0)])
12150             (const_int 0)))]
12151   ""
12152   [(set (match_dup 0) (match_dup 1))]
12154   operands[1] = shallow_copy_rtx (operands[1]);
12155   PUT_MODE (operands[1], QImode);
12158 (define_split
12159   [(set (match_operand:QI 0 "nonimmediate_operand")
12160         (eq:QI (match_operator 1 "ix86_comparison_operator"
12161                  [(reg FLAGS_REG) (const_int 0)])
12162             (const_int 0)))]
12163   ""
12164   [(set (match_dup 0) (match_dup 1))]
12166   operands[1] = shallow_copy_rtx (operands[1]);
12167   PUT_MODE (operands[1], QImode);
12168   PUT_CODE (operands[1],
12169             ix86_reverse_condition (GET_CODE (operands[1]),
12170                                     GET_MODE (XEXP (operands[1], 0))));
12172   /* Make sure that (a) the CCmode we have for the flags is strong
12173      enough for the reversed compare or (b) we have a valid FP compare.  */
12174   if (! ix86_comparison_operator (operands[1], VOIDmode))
12175     FAIL;
12178 (define_split
12179   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12180         (eq:QI (match_operator 1 "ix86_comparison_operator"
12181                  [(reg FLAGS_REG) (const_int 0)])
12182             (const_int 0)))]
12183   ""
12184   [(set (match_dup 0) (match_dup 1))]
12186   operands[1] = shallow_copy_rtx (operands[1]);
12187   PUT_MODE (operands[1], QImode);
12188   PUT_CODE (operands[1],
12189             ix86_reverse_condition (GET_CODE (operands[1]),
12190                                     GET_MODE (XEXP (operands[1], 0))));
12192   /* Make sure that (a) the CCmode we have for the flags is strong
12193      enough for the reversed compare or (b) we have a valid FP compare.  */
12194   if (! ix86_comparison_operator (operands[1], VOIDmode))
12195     FAIL;
12198 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12199 ;; subsequent logical operations are used to imitate conditional moves.
12200 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12201 ;; it directly.
12203 (define_insn "setcc_<mode>_sse"
12204   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12205         (match_operator:MODEF 3 "sse_comparison_operator"
12206           [(match_operand:MODEF 1 "register_operand" "0,x")
12207            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12208   "SSE_FLOAT_MODE_P (<MODE>mode)"
12209   "@
12210    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12211    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12212   [(set_attr "isa" "noavx,avx")
12213    (set_attr "type" "ssecmp")
12214    (set_attr "length_immediate" "1")
12215    (set_attr "prefix" "orig,vex")
12216    (set_attr "mode" "<MODE>")])
12218 ;; Basic conditional jump instructions.
12219 ;; We ignore the overflow flag for signed branch instructions.
12221 (define_insn "*jcc"
12222   [(set (pc)
12223         (if_then_else (match_operator 1 "ix86_comparison_operator"
12224                                       [(reg FLAGS_REG) (const_int 0)])
12225                       (label_ref (match_operand 0))
12226                       (pc)))]
12227   ""
12228   "%!%+j%C1\t%l0"
12229   [(set_attr "type" "ibr")
12230    (set_attr "modrm" "0")
12231    (set (attr "length")
12232         (if_then_else
12233           (and (ge (minus (match_dup 0) (pc))
12234                    (const_int -126))
12235                (lt (minus (match_dup 0) (pc))
12236                    (const_int 128)))
12237           (const_int 2)
12238           (const_int 6)))
12239    (set_attr "maybe_prefix_bnd" "1")])
12241 ;; In general it is not safe to assume too much about CCmode registers,
12242 ;; so simplify-rtx stops when it sees a second one.  Under certain
12243 ;; conditions this is safe on x86, so help combine not create
12245 ;;      seta    %al
12246 ;;      testb   %al, %al
12247 ;;      je      Lfoo
12249 (define_split
12250   [(set (pc)
12251         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12252                                       [(reg FLAGS_REG) (const_int 0)])
12253                           (const_int 0))
12254                       (label_ref (match_operand 1))
12255                       (pc)))]
12256   ""
12257   [(set (pc)
12258         (if_then_else (match_dup 0)
12259                       (label_ref (match_dup 1))
12260                       (pc)))]
12262   operands[0] = shallow_copy_rtx (operands[0]);
12263   PUT_MODE (operands[0], VOIDmode);
12266 (define_split
12267   [(set (pc)
12268         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12269                                       [(reg FLAGS_REG) (const_int 0)])
12270                           (const_int 0))
12271                       (label_ref (match_operand 1))
12272                       (pc)))]
12273   ""
12274   [(set (pc)
12275         (if_then_else (match_dup 0)
12276                       (label_ref (match_dup 1))
12277                       (pc)))]
12279   operands[0] = shallow_copy_rtx (operands[0]);
12280   PUT_MODE (operands[0], VOIDmode);
12281   PUT_CODE (operands[0],
12282             ix86_reverse_condition (GET_CODE (operands[0]),
12283                                     GET_MODE (XEXP (operands[0], 0))));
12285   /* Make sure that (a) the CCmode we have for the flags is strong
12286      enough for the reversed compare or (b) we have a valid FP compare.  */
12287   if (! ix86_comparison_operator (operands[0], VOIDmode))
12288     FAIL;
12291 ;; Unconditional and other jump instructions
12293 (define_insn "jump"
12294   [(set (pc)
12295         (label_ref (match_operand 0)))]
12296   ""
12297   "%!jmp\t%l0"
12298   [(set_attr "type" "ibr")
12299    (set_attr "modrm" "0")
12300    (set (attr "length")
12301         (if_then_else
12302           (and (ge (minus (match_dup 0) (pc))
12303                    (const_int -126))
12304                (lt (minus (match_dup 0) (pc))
12305                    (const_int 128)))
12306           (const_int 2)
12307           (const_int 5)))
12308    (set_attr "maybe_prefix_bnd" "1")])
12310 (define_expand "indirect_jump"
12311   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12312   ""
12314   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12315     operands[0] = convert_memory_address (word_mode, operands[0]);
12316   cfun->machine->has_local_indirect_jump = true;
12319 (define_insn "*indirect_jump"
12320   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12321   ""
12322   "* return ix86_output_indirect_jmp (operands[0]);"
12323   [(set (attr "type")
12324      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12325                                  != indirect_branch_keep)")
12326         (const_string "multi")
12327         (const_string "ibr")))
12328    (set_attr "length_immediate" "0")
12329    (set_attr "maybe_prefix_bnd" "1")])
12331 (define_expand "tablejump"
12332   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12333               (use (label_ref (match_operand 1)))])]
12334   ""
12336   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12337      relative.  Convert the relative address to an absolute address.  */
12338   if (flag_pic)
12339     {
12340       rtx op0, op1;
12341       enum rtx_code code;
12343       /* We can't use @GOTOFF for text labels on VxWorks;
12344          see gotoff_operand.  */
12345       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12346         {
12347           code = PLUS;
12348           op0 = operands[0];
12349           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12350         }
12351       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12352         {
12353           code = PLUS;
12354           op0 = operands[0];
12355           op1 = pic_offset_table_rtx;
12356         }
12357       else
12358         {
12359           code = MINUS;
12360           op0 = pic_offset_table_rtx;
12361           op1 = operands[0];
12362         }
12364       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12365                                          OPTAB_DIRECT);
12366     }
12368   if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12369     operands[0] = convert_memory_address (word_mode, operands[0]);
12370   cfun->machine->has_local_indirect_jump = true;
12373 (define_insn "*tablejump_1"
12374   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12375    (use (label_ref (match_operand 1)))]
12376   ""
12377   "* return ix86_output_indirect_jmp (operands[0]);"
12378   [(set (attr "type")
12379      (if_then_else (match_test "(cfun->machine->indirect_branch_type
12380                                  != indirect_branch_keep)")
12381         (const_string "multi")
12382         (const_string "ibr")))
12383    (set_attr "length_immediate" "0")
12384    (set_attr "maybe_prefix_bnd" "1")])
12386 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12388 (define_peephole2
12389   [(set (reg FLAGS_REG) (match_operand 0))
12390    (set (match_operand:QI 1 "register_operand")
12391         (match_operator:QI 2 "ix86_comparison_operator"
12392           [(reg FLAGS_REG) (const_int 0)]))
12393    (set (match_operand 3 "any_QIreg_operand")
12394         (zero_extend (match_dup 1)))]
12395   "(peep2_reg_dead_p (3, operands[1])
12396     || operands_match_p (operands[1], operands[3]))
12397    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12398    && peep2_regno_dead_p (0, FLAGS_REG)"
12399   [(set (match_dup 4) (match_dup 0))
12400    (set (strict_low_part (match_dup 5))
12401         (match_dup 2))]
12403   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12404   operands[5] = gen_lowpart (QImode, operands[3]);
12405   ix86_expand_clear (operands[3]);
12408 (define_peephole2
12409   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12410               (match_operand 4)])
12411    (set (match_operand:QI 1 "register_operand")
12412         (match_operator:QI 2 "ix86_comparison_operator"
12413           [(reg FLAGS_REG) (const_int 0)]))
12414    (set (match_operand 3 "any_QIreg_operand")
12415         (zero_extend (match_dup 1)))]
12416   "(peep2_reg_dead_p (3, operands[1])
12417     || operands_match_p (operands[1], operands[3]))
12418    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12419    && ! reg_set_p (operands[3], operands[4])
12420    && peep2_regno_dead_p (0, FLAGS_REG)"
12421   [(parallel [(set (match_dup 5) (match_dup 0))
12422               (match_dup 4)])
12423    (set (strict_low_part (match_dup 6))
12424         (match_dup 2))]
12426   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12427   operands[6] = gen_lowpart (QImode, operands[3]);
12428   ix86_expand_clear (operands[3]);
12431 (define_peephole2
12432   [(set (reg FLAGS_REG) (match_operand 0))
12433    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12434               (match_operand 5)])
12435    (set (match_operand:QI 2 "register_operand")
12436         (match_operator:QI 3 "ix86_comparison_operator"
12437           [(reg FLAGS_REG) (const_int 0)]))
12438    (set (match_operand 4 "any_QIreg_operand")
12439         (zero_extend (match_dup 2)))]
12440   "(peep2_reg_dead_p (4, operands[2])
12441     || operands_match_p (operands[2], operands[4]))
12442    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12443    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12444    && ! reg_set_p (operands[4], operands[5])
12445    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12446    && peep2_regno_dead_p (0, FLAGS_REG)"
12447   [(set (match_dup 6) (match_dup 0))
12448    (parallel [(set (match_dup 7) (match_dup 1))
12449               (match_dup 5)])
12450    (set (strict_low_part (match_dup 8))
12451         (match_dup 3))]
12453   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12454   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12455   operands[8] = gen_lowpart (QImode, operands[4]);
12456   ix86_expand_clear (operands[4]);
12459 ;; Similar, but match zero extend with andsi3.
12461 (define_peephole2
12462   [(set (reg FLAGS_REG) (match_operand 0))
12463    (set (match_operand:QI 1 "register_operand")
12464         (match_operator:QI 2 "ix86_comparison_operator"
12465           [(reg FLAGS_REG) (const_int 0)]))
12466    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12467                    (and:SI (match_dup 3) (const_int 255)))
12468               (clobber (reg:CC FLAGS_REG))])]
12469   "REGNO (operands[1]) == REGNO (operands[3])
12470    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12471    && peep2_regno_dead_p (0, FLAGS_REG)"
12472   [(set (match_dup 4) (match_dup 0))
12473    (set (strict_low_part (match_dup 5))
12474         (match_dup 2))]
12476   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12477   operands[5] = gen_lowpart (QImode, operands[3]);
12478   ix86_expand_clear (operands[3]);
12481 (define_peephole2
12482   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12483               (match_operand 4)])
12484    (set (match_operand:QI 1 "register_operand")
12485         (match_operator:QI 2 "ix86_comparison_operator"
12486           [(reg FLAGS_REG) (const_int 0)]))
12487    (parallel [(set (match_operand 3 "any_QIreg_operand")
12488                    (zero_extend (match_dup 1)))
12489               (clobber (reg:CC FLAGS_REG))])]
12490   "(peep2_reg_dead_p (3, operands[1])
12491     || operands_match_p (operands[1], operands[3]))
12492    && ! reg_overlap_mentioned_p (operands[3], operands[0])
12493    && ! reg_set_p (operands[3], operands[4])
12494    && peep2_regno_dead_p (0, FLAGS_REG)"
12495   [(parallel [(set (match_dup 5) (match_dup 0))
12496               (match_dup 4)])
12497    (set (strict_low_part (match_dup 6))
12498         (match_dup 2))]
12500   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12501   operands[6] = gen_lowpart (QImode, operands[3]);
12502   ix86_expand_clear (operands[3]);
12505 (define_peephole2
12506   [(set (reg FLAGS_REG) (match_operand 0))
12507    (parallel [(set (reg FLAGS_REG) (match_operand 1))
12508               (match_operand 5)])
12509    (set (match_operand:QI 2 "register_operand")
12510         (match_operator:QI 3 "ix86_comparison_operator"
12511           [(reg FLAGS_REG) (const_int 0)]))
12512    (parallel [(set (match_operand 4 "any_QIreg_operand")
12513                    (zero_extend (match_dup 2)))
12514               (clobber (reg:CC FLAGS_REG))])]
12515   "(peep2_reg_dead_p (4, operands[2])
12516     || operands_match_p (operands[2], operands[4]))
12517    && ! reg_overlap_mentioned_p (operands[4], operands[0])
12518    && ! reg_overlap_mentioned_p (operands[4], operands[1])
12519    && ! reg_set_p (operands[4], operands[5])
12520    && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12521    && peep2_regno_dead_p (0, FLAGS_REG)"
12522   [(set (match_dup 6) (match_dup 0))
12523    (parallel [(set (match_dup 7) (match_dup 1))
12524               (match_dup 5)])
12525    (set (strict_low_part (match_dup 8))
12526         (match_dup 3))]
12528   operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12529   operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12530   operands[8] = gen_lowpart (QImode, operands[4]);
12531   ix86_expand_clear (operands[4]);
12534 ;; Call instructions.
12536 ;; The predicates normally associated with named expanders are not properly
12537 ;; checked for calls.  This is a bug in the generic code, but it isn't that
12538 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
12540 ;; P6 processors will jump to the address after the decrement when %esp
12541 ;; is used as a call operand, so they will execute return address as a code.
12542 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12544 ;; Register constraint for call instruction.
12545 (define_mode_attr c [(SI "l") (DI "r")])
12547 ;; Call subroutine returning no value.
12549 (define_expand "call"
12550   [(call (match_operand:QI 0)
12551          (match_operand 1))
12552    (use (match_operand 2))]
12553   ""
12555   ix86_expand_call (NULL, operands[0], operands[1],
12556                     operands[2], NULL, false);
12557   DONE;
12560 (define_expand "sibcall"
12561   [(call (match_operand:QI 0)
12562          (match_operand 1))
12563    (use (match_operand 2))]
12564   ""
12566   ix86_expand_call (NULL, operands[0], operands[1],
12567                     operands[2], NULL, true);
12568   DONE;
12571 (define_insn "*call"
12572   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12573          (match_operand 1))]
12574   "!SIBLING_CALL_P (insn)"
12575   "* return ix86_output_call_insn (insn, operands[0]);"
12576   [(set_attr "type" "call")])
12578 ;; This covers both call and sibcall since only GOT slot is allowed.
12579 (define_insn "*call_got_x32"
12580   [(call (mem:QI (zero_extend:DI
12581                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12582          (match_operand 1))]
12583   "TARGET_X32"
12585   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12586   return ix86_output_call_insn (insn, fnaddr);
12588   [(set_attr "type" "call")])
12590 ;; Since sibcall never returns, we can only use call-clobbered register
12591 ;; as GOT base.
12592 (define_insn "*sibcall_GOT_32"
12593   [(call (mem:QI
12594            (mem:SI (plus:SI
12595                      (match_operand:SI 0 "register_no_elim_operand" "U")
12596                      (match_operand:SI 1 "GOT32_symbol_operand"))))
12597          (match_operand 2))]
12598   "!TARGET_MACHO
12599   && !TARGET_64BIT
12600   && !TARGET_INDIRECT_BRANCH_REGISTER
12601   && SIBLING_CALL_P (insn)"
12603   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12604   fnaddr = gen_const_mem (SImode, fnaddr);
12605   return ix86_output_call_insn (insn, fnaddr);
12607   [(set_attr "type" "call")])
12609 (define_insn "*sibcall"
12610   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12611          (match_operand 1))]
12612   "SIBLING_CALL_P (insn)"
12613   "* return ix86_output_call_insn (insn, operands[0]);"
12614   [(set_attr "type" "call")])
12616 (define_insn "*sibcall_memory"
12617   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12618          (match_operand 1))
12619    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12620   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12621   "* return ix86_output_call_insn (insn, operands[0]);"
12622   [(set_attr "type" "call")])
12624 (define_peephole2
12625   [(set (match_operand:W 0 "register_operand")
12626         (match_operand:W 1 "memory_operand"))
12627    (call (mem:QI (match_dup 0))
12628          (match_operand 3))]
12629   "!TARGET_X32
12630    && !TARGET_INDIRECT_BRANCH_REGISTER
12631    && SIBLING_CALL_P (peep2_next_insn (1))
12632    && !reg_mentioned_p (operands[0],
12633                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12634   [(parallel [(call (mem:QI (match_dup 1))
12635                     (match_dup 3))
12636               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12638 (define_peephole2
12639   [(set (match_operand:W 0 "register_operand")
12640         (match_operand:W 1 "memory_operand"))
12641    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12642    (call (mem:QI (match_dup 0))
12643          (match_operand 3))]
12644   "!TARGET_X32
12645    && !TARGET_INDIRECT_BRANCH_REGISTER
12646    && SIBLING_CALL_P (peep2_next_insn (2))
12647    && !reg_mentioned_p (operands[0],
12648                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12649   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12650    (parallel [(call (mem:QI (match_dup 1))
12651                     (match_dup 3))
12652               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12654 (define_expand "call_pop"
12655   [(parallel [(call (match_operand:QI 0)
12656                     (match_operand:SI 1))
12657               (set (reg:SI SP_REG)
12658                    (plus:SI (reg:SI SP_REG)
12659                             (match_operand:SI 3)))])]
12660   "!TARGET_64BIT"
12662   ix86_expand_call (NULL, operands[0], operands[1],
12663                     operands[2], operands[3], false);
12664   DONE;
12667 (define_insn "*call_pop"
12668   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12669          (match_operand 1))
12670    (set (reg:SI SP_REG)
12671         (plus:SI (reg:SI SP_REG)
12672                  (match_operand:SI 2 "immediate_operand" "i")))]
12673   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12674   "* return ix86_output_call_insn (insn, operands[0]);"
12675   [(set_attr "type" "call")])
12677 (define_insn "*sibcall_pop"
12678   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12679          (match_operand 1))
12680    (set (reg:SI SP_REG)
12681         (plus:SI (reg:SI SP_REG)
12682                  (match_operand:SI 2 "immediate_operand" "i")))]
12683   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12684   "* return ix86_output_call_insn (insn, operands[0]);"
12685   [(set_attr "type" "call")])
12687 (define_insn "*sibcall_pop_memory"
12688   [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12689          (match_operand 1))
12690    (set (reg:SI SP_REG)
12691         (plus:SI (reg:SI SP_REG)
12692                  (match_operand:SI 2 "immediate_operand" "i")))
12693    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12694   "!TARGET_64BIT"
12695   "* return ix86_output_call_insn (insn, operands[0]);"
12696   [(set_attr "type" "call")])
12698 (define_peephole2
12699   [(set (match_operand:SI 0 "register_operand")
12700         (match_operand:SI 1 "memory_operand"))
12701    (parallel [(call (mem:QI (match_dup 0))
12702                     (match_operand 3))
12703               (set (reg:SI SP_REG)
12704                    (plus:SI (reg:SI SP_REG)
12705                             (match_operand:SI 4 "immediate_operand")))])]
12706   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12707    && !reg_mentioned_p (operands[0],
12708                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12709   [(parallel [(call (mem:QI (match_dup 1))
12710                     (match_dup 3))
12711               (set (reg:SI SP_REG)
12712                    (plus:SI (reg:SI SP_REG)
12713                             (match_dup 4)))
12714               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12716 (define_peephole2
12717   [(set (match_operand:SI 0 "register_operand")
12718         (match_operand:SI 1 "memory_operand"))
12719    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12720    (parallel [(call (mem:QI (match_dup 0))
12721                     (match_operand 3))
12722               (set (reg:SI SP_REG)
12723                    (plus:SI (reg:SI SP_REG)
12724                             (match_operand:SI 4 "immediate_operand")))])]
12725   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12726    && !reg_mentioned_p (operands[0],
12727                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12728   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12729    (parallel [(call (mem:QI (match_dup 1))
12730                     (match_dup 3))
12731               (set (reg:SI SP_REG)
12732                    (plus:SI (reg:SI SP_REG)
12733                             (match_dup 4)))
12734               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12736 ;; Combining simple memory jump instruction
12738 (define_peephole2
12739   [(set (match_operand:W 0 "register_operand")
12740         (match_operand:W 1 "memory_operand"))
12741    (set (pc) (match_dup 0))]
12742   "!TARGET_X32
12743    && !TARGET_INDIRECT_BRANCH_REGISTER
12744    && peep2_reg_dead_p (2, operands[0])"
12745   [(set (pc) (match_dup 1))])
12747 ;; Call subroutine, returning value in operand 0
12749 (define_expand "call_value"
12750   [(set (match_operand 0)
12751         (call (match_operand:QI 1)
12752               (match_operand 2)))
12753    (use (match_operand 3))]
12754   ""
12756   ix86_expand_call (operands[0], operands[1], operands[2],
12757                     operands[3], NULL, false);
12758   DONE;
12761 (define_expand "sibcall_value"
12762   [(set (match_operand 0)
12763         (call (match_operand:QI 1)
12764               (match_operand 2)))
12765    (use (match_operand 3))]
12766   ""
12768   ix86_expand_call (operands[0], operands[1], operands[2],
12769                     operands[3], NULL, true);
12770   DONE;
12773 (define_insn "*call_value"
12774   [(set (match_operand 0)
12775         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12776               (match_operand 2)))]
12777   "!SIBLING_CALL_P (insn)"
12778   "* return ix86_output_call_insn (insn, operands[1]);"
12779   [(set_attr "type" "callv")])
12781 ;; This covers both call and sibcall since only GOT slot is allowed.
12782 (define_insn "*call_value_got_x32"
12783   [(set (match_operand 0)
12784         (call (mem:QI
12785                 (zero_extend:DI
12786                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12787               (match_operand 2)))]
12788   "TARGET_X32"
12790   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12791   return ix86_output_call_insn (insn, fnaddr);
12793   [(set_attr "type" "callv")])
12795 ;; Since sibcall never returns, we can only use call-clobbered register
12796 ;; as GOT base.
12797 (define_insn "*sibcall_value_GOT_32"
12798   [(set (match_operand 0)
12799         (call (mem:QI
12800                 (mem:SI (plus:SI
12801                           (match_operand:SI 1 "register_no_elim_operand" "U")
12802                           (match_operand:SI 2 "GOT32_symbol_operand"))))
12803          (match_operand 3)))]
12804   "!TARGET_MACHO
12805    && !TARGET_64BIT
12806    && !TARGET_INDIRECT_BRANCH_REGISTER
12807    && SIBLING_CALL_P (insn)"
12809   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12810   fnaddr = gen_const_mem (SImode, fnaddr);
12811   return ix86_output_call_insn (insn, fnaddr);
12813   [(set_attr "type" "callv")])
12815 (define_insn "*sibcall_value"
12816   [(set (match_operand 0)
12817         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12818               (match_operand 2)))]
12819   "SIBLING_CALL_P (insn)"
12820   "* return ix86_output_call_insn (insn, operands[1]);"
12821   [(set_attr "type" "callv")])
12823 (define_insn "*sibcall_value_memory"
12824   [(set (match_operand 0)
12825         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12826               (match_operand 2)))
12827    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12828   "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12829   "* return ix86_output_call_insn (insn, operands[1]);"
12830   [(set_attr "type" "callv")])
12832 (define_peephole2
12833   [(set (match_operand:W 0 "register_operand")
12834         (match_operand:W 1 "memory_operand"))
12835    (set (match_operand 2)
12836    (call (mem:QI (match_dup 0))
12837                  (match_operand 3)))]
12838   "!TARGET_X32
12839    && !TARGET_INDIRECT_BRANCH_REGISTER
12840    && SIBLING_CALL_P (peep2_next_insn (1))
12841    && !reg_mentioned_p (operands[0],
12842                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12843   [(parallel [(set (match_dup 2)
12844                    (call (mem:QI (match_dup 1))
12845                          (match_dup 3)))
12846               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12848 (define_peephole2
12849   [(set (match_operand:W 0 "register_operand")
12850         (match_operand:W 1 "memory_operand"))
12851    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12852    (set (match_operand 2)
12853         (call (mem:QI (match_dup 0))
12854               (match_operand 3)))]
12855   "!TARGET_X32
12856    && !TARGET_INDIRECT_BRANCH_REGISTER
12857    && SIBLING_CALL_P (peep2_next_insn (2))
12858    && !reg_mentioned_p (operands[0],
12859                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12860   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12861    (parallel [(set (match_dup 2)
12862                    (call (mem:QI (match_dup 1))
12863                          (match_dup 3)))
12864               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12866 (define_expand "call_value_pop"
12867   [(parallel [(set (match_operand 0)
12868                    (call (match_operand:QI 1)
12869                          (match_operand:SI 2)))
12870               (set (reg:SI SP_REG)
12871                    (plus:SI (reg:SI SP_REG)
12872                             (match_operand:SI 4)))])]
12873   "!TARGET_64BIT"
12875   ix86_expand_call (operands[0], operands[1], operands[2],
12876                     operands[3], operands[4], false);
12877   DONE;
12880 (define_insn "*call_value_pop"
12881   [(set (match_operand 0)
12882         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12883               (match_operand 2)))
12884    (set (reg:SI SP_REG)
12885         (plus:SI (reg:SI SP_REG)
12886                  (match_operand:SI 3 "immediate_operand" "i")))]
12887   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12888   "* return ix86_output_call_insn (insn, operands[1]);"
12889   [(set_attr "type" "callv")])
12891 (define_insn "*sibcall_value_pop"
12892   [(set (match_operand 0)
12893         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12894               (match_operand 2)))
12895    (set (reg:SI SP_REG)
12896         (plus:SI (reg:SI SP_REG)
12897                  (match_operand:SI 3 "immediate_operand" "i")))]
12898   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12899   "* return ix86_output_call_insn (insn, operands[1]);"
12900   [(set_attr "type" "callv")])
12902 (define_insn "*sibcall_value_pop_memory"
12903   [(set (match_operand 0)
12904         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12905               (match_operand 2)))
12906    (set (reg:SI SP_REG)
12907         (plus:SI (reg:SI SP_REG)
12908                  (match_operand:SI 3 "immediate_operand" "i")))
12909    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12910   "!TARGET_64BIT"
12911   "* return ix86_output_call_insn (insn, operands[1]);"
12912   [(set_attr "type" "callv")])
12914 (define_peephole2
12915   [(set (match_operand:SI 0 "register_operand")
12916         (match_operand:SI 1 "memory_operand"))
12917    (parallel [(set (match_operand 2)
12918                    (call (mem:QI (match_dup 0))
12919                          (match_operand 3)))
12920               (set (reg:SI SP_REG)
12921                    (plus:SI (reg:SI SP_REG)
12922                             (match_operand:SI 4 "immediate_operand")))])]
12923   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12924    && !reg_mentioned_p (operands[0],
12925                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12926   [(parallel [(set (match_dup 2)
12927                    (call (mem:QI (match_dup 1))
12928                          (match_dup 3)))
12929               (set (reg:SI SP_REG)
12930                    (plus:SI (reg:SI SP_REG)
12931                             (match_dup 4)))
12932               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12934 (define_peephole2
12935   [(set (match_operand:SI 0 "register_operand")
12936         (match_operand:SI 1 "memory_operand"))
12937    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12938    (parallel [(set (match_operand 2)
12939                    (call (mem:QI (match_dup 0))
12940                          (match_operand 3)))
12941               (set (reg:SI SP_REG)
12942                    (plus:SI (reg:SI SP_REG)
12943                             (match_operand:SI 4 "immediate_operand")))])]
12944   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12945    && !reg_mentioned_p (operands[0],
12946                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12947   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12948    (parallel [(set (match_dup 2)
12949                    (call (mem:QI (match_dup 1))
12950                          (match_dup 3)))
12951               (set (reg:SI SP_REG)
12952                    (plus:SI (reg:SI SP_REG)
12953                             (match_dup 4)))
12954               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12956 ;; Call subroutine returning any type.
12958 (define_expand "untyped_call"
12959   [(parallel [(call (match_operand 0)
12960                     (const_int 0))
12961               (match_operand 1)
12962               (match_operand 2)])]
12963   ""
12965   int i;
12967   /* In order to give reg-stack an easier job in validating two
12968      coprocessor registers as containing a possible return value,
12969      simply pretend the untyped call returns a complex long double
12970      value. 
12972      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12973      and should have the default ABI.  */
12975   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12976                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12977                     operands[0], const0_rtx,
12978                     GEN_INT ((TARGET_64BIT
12979                               ? (ix86_abi == SYSV_ABI
12980                                  ? X86_64_SSE_REGPARM_MAX
12981                                  : X86_64_MS_SSE_REGPARM_MAX)
12982                               : X86_32_SSE_REGPARM_MAX)
12983                              - 1),
12984                     NULL, false);
12986   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12987     {
12988       rtx set = XVECEXP (operands[2], 0, i);
12989       emit_move_insn (SET_DEST (set), SET_SRC (set));
12990     }
12992   /* The optimizer does not know that the call sets the function value
12993      registers we stored in the result block.  We avoid problems by
12994      claiming that all hard registers are used and clobbered at this
12995      point.  */
12996   emit_insn (gen_blockage ());
12998   DONE;
13001 ;; Prologue and epilogue instructions
13003 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13004 ;; all of memory.  This blocks insns from being moved across this point.
13006 (define_insn "blockage"
13007   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13008   ""
13009   ""
13010   [(set_attr "length" "0")])
13012 ;; Do not schedule instructions accessing memory across this point.
13014 (define_expand "memory_blockage"
13015   [(set (match_dup 0)
13016         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13017   ""
13019   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13020   MEM_VOLATILE_P (operands[0]) = 1;
13023 (define_insn "*memory_blockage"
13024   [(set (match_operand:BLK 0)
13025         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13026   ""
13027   ""
13028   [(set_attr "length" "0")])
13030 ;; As USE insns aren't meaningful after reload, this is used instead
13031 ;; to prevent deleting instructions setting registers for PIC code
13032 (define_insn "prologue_use"
13033   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13034   ""
13035   ""
13036   [(set_attr "length" "0")])
13038 ;; Insn emitted into the body of a function to return from a function.
13039 ;; This is only done if the function's epilogue is known to be simple.
13040 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13042 (define_expand "return"
13043   [(simple_return)]
13044   "ix86_can_use_return_insn_p ()"
13046   if (crtl->args.pops_args)
13047     {
13048       rtx popc = GEN_INT (crtl->args.pops_args);
13049       emit_jump_insn (gen_simple_return_pop_internal (popc));
13050       DONE;
13051     }
13054 ;; We need to disable this for TARGET_SEH, as otherwise
13055 ;; shrink-wrapped prologue gets enabled too.  This might exceed
13056 ;; the maximum size of prologue in unwind information.
13057 ;; Also disallow shrink-wrapping if using stack slot to pass the
13058 ;; static chain pointer - the first instruction has to be pushl %esi
13059 ;; and it can't be moved around, as we use alternate entry points
13060 ;; in that case.
13062 (define_expand "simple_return"
13063   [(simple_return)]
13064   "!TARGET_SEH && !ix86_static_chain_on_stack"
13066   if (crtl->args.pops_args)
13067     {
13068       rtx popc = GEN_INT (crtl->args.pops_args);
13069       emit_jump_insn (gen_simple_return_pop_internal (popc));
13070       DONE;
13071     }
13074 (define_insn "simple_return_internal"
13075   [(simple_return)]
13076   "reload_completed"
13077   "* return ix86_output_function_return (false);"
13078   [(set_attr "length" "1")
13079    (set_attr "atom_unit" "jeu")
13080    (set_attr "length_immediate" "0")
13081    (set_attr "modrm" "0")
13082    (set_attr "maybe_prefix_bnd" "1")])
13084 (define_insn "interrupt_return"
13085   [(simple_return)
13086    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13087   "reload_completed"
13089   return TARGET_64BIT ? "iretq" : "iret";
13092 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13093 ;; instruction Athlon and K8 have.
13095 (define_insn "simple_return_internal_long"
13096   [(simple_return)
13097    (unspec [(const_int 0)] UNSPEC_REP)]
13098   "reload_completed"
13099   "* return ix86_output_function_return (true);"
13100   [(set_attr "length" "2")
13101    (set_attr "atom_unit" "jeu")
13102    (set_attr "length_immediate" "0")
13103    (set_attr "prefix_rep" "1")
13104    (set_attr "modrm" "0")])
13106 (define_insn_and_split "simple_return_pop_internal"
13107   [(simple_return)
13108    (use (match_operand:SI 0 "const_int_operand"))]
13109   "reload_completed"
13110   "%!ret\t%0"
13111   "&& cfun->machine->function_return_type != indirect_branch_keep"
13112   [(const_int 0)]
13113   "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13114   [(set_attr "length" "3")
13115    (set_attr "atom_unit" "jeu")
13116    (set_attr "length_immediate" "2")
13117    (set_attr "modrm" "0")
13118    (set_attr "maybe_prefix_bnd" "1")])
13120 (define_insn "simple_return_indirect_internal"
13121   [(simple_return)
13122    (use (match_operand 0 "register_operand" "r"))]
13123   "reload_completed"
13124   "* return ix86_output_indirect_function_return (operands[0]);"
13125   [(set (attr "type")
13126      (if_then_else (match_test "(cfun->machine->indirect_branch_type
13127                                  != indirect_branch_keep)")
13128         (const_string "multi")
13129         (const_string "ibr")))
13130    (set_attr "length_immediate" "0")
13131    (set_attr "maybe_prefix_bnd" "1")])
13133 (define_insn "nop"
13134   [(const_int 0)]
13135   ""
13136   "nop"
13137   [(set_attr "length" "1")
13138    (set_attr "length_immediate" "0")
13139    (set_attr "modrm" "0")])
13141 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
13142 (define_insn "nops"
13143   [(unspec_volatile [(match_operand 0 "const_int_operand")]
13144                     UNSPECV_NOPS)]
13145   "reload_completed"
13147   int num = INTVAL (operands[0]);
13149   gcc_assert (IN_RANGE (num, 1, 8));
13151   while (num--)
13152     fputs ("\tnop\n", asm_out_file);
13154   return "";
13156   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13157    (set_attr "length_immediate" "0")
13158    (set_attr "modrm" "0")])
13160 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13161 ;; branch prediction penalty for the third jump in a 16-byte
13162 ;; block on K8.
13164 (define_insn "pad"
13165   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13166   ""
13168 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13169   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13170 #else
13171   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13172      The align insn is used to avoid 3 jump instructions in the row to improve
13173      branch prediction and the benefits hardly outweigh the cost of extra 8
13174      nops on the average inserted by full alignment pseudo operation.  */
13175 #endif
13176   return "";
13178   [(set_attr "length" "16")])
13180 (define_expand "prologue"
13181   [(const_int 0)]
13182   ""
13183   "ix86_expand_prologue (); DONE;")
13185 (define_expand "set_got"
13186   [(parallel
13187      [(set (match_operand:SI 0 "register_operand")
13188            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13189       (clobber (reg:CC FLAGS_REG))])]
13190   "!TARGET_64BIT"
13192   if (flag_pic && !TARGET_VXWORKS_RTP)
13193     ix86_pc_thunk_call_expanded = true;
13196 (define_insn "*set_got"
13197   [(set (match_operand:SI 0 "register_operand" "=r")
13198         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13199    (clobber (reg:CC FLAGS_REG))]
13200   "!TARGET_64BIT"
13201   "* return output_set_got (operands[0], NULL_RTX);"
13202   [(set_attr "type" "multi")
13203    (set_attr "length" "12")])
13205 (define_expand "set_got_labelled"
13206   [(parallel
13207      [(set (match_operand:SI 0 "register_operand")
13208            (unspec:SI [(label_ref (match_operand 1))]
13209                       UNSPEC_SET_GOT))
13210       (clobber (reg:CC FLAGS_REG))])]
13211   "!TARGET_64BIT"
13213   if (flag_pic && !TARGET_VXWORKS_RTP)
13214     ix86_pc_thunk_call_expanded = true;
13217 (define_insn "*set_got_labelled"
13218   [(set (match_operand:SI 0 "register_operand" "=r")
13219         (unspec:SI [(label_ref (match_operand 1))]
13220          UNSPEC_SET_GOT))
13221    (clobber (reg:CC FLAGS_REG))]
13222   "!TARGET_64BIT"
13223   "* return output_set_got (operands[0], operands[1]);"
13224   [(set_attr "type" "multi")
13225    (set_attr "length" "12")])
13227 (define_insn "set_got_rex64"
13228   [(set (match_operand:DI 0 "register_operand" "=r")
13229         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13230   "TARGET_64BIT"
13231   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13232   [(set_attr "type" "lea")
13233    (set_attr "length_address" "4")
13234    (set_attr "modrm_class" "unknown")
13235    (set_attr "mode" "DI")])
13237 (define_insn "set_rip_rex64"
13238   [(set (match_operand:DI 0 "register_operand" "=r")
13239         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13240   "TARGET_64BIT"
13241   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13242   [(set_attr "type" "lea")
13243    (set_attr "length_address" "4")
13244    (set_attr "mode" "DI")])
13246 (define_insn "set_got_offset_rex64"
13247   [(set (match_operand:DI 0 "register_operand" "=r")
13248         (unspec:DI
13249           [(label_ref (match_operand 1))]
13250           UNSPEC_SET_GOT_OFFSET))]
13251   "TARGET_LP64"
13252   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13253   [(set_attr "type" "imov")
13254    (set_attr "length_immediate" "0")
13255    (set_attr "length_address" "8")
13256    (set_attr "mode" "DI")])
13258 (define_expand "epilogue"
13259   [(const_int 0)]
13260   ""
13261   "ix86_expand_epilogue (1); DONE;")
13263 (define_expand "sibcall_epilogue"
13264   [(const_int 0)]
13265   ""
13266   "ix86_expand_epilogue (0); DONE;")
13268 (define_expand "eh_return"
13269   [(use (match_operand 0 "register_operand"))]
13270   ""
13272   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13274   /* Tricky bit: we write the address of the handler to which we will
13275      be returning into someone else's stack frame, one word below the
13276      stack address we wish to restore.  */
13277   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13278   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13279   tmp = gen_rtx_MEM (Pmode, tmp);
13280   emit_move_insn (tmp, ra);
13282   emit_jump_insn (gen_eh_return_internal ());
13283   emit_barrier ();
13284   DONE;
13287 (define_insn_and_split "eh_return_internal"
13288   [(eh_return)]
13289   ""
13290   "#"
13291   "epilogue_completed"
13292   [(const_int 0)]
13293   "ix86_expand_epilogue (2); DONE;")
13295 (define_insn "leave"
13296   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13297    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13298    (clobber (mem:BLK (scratch)))]
13299   "!TARGET_64BIT"
13300   "leave"
13301   [(set_attr "type" "leave")])
13303 (define_insn "leave_rex64"
13304   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13305    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13306    (clobber (mem:BLK (scratch)))]
13307   "TARGET_64BIT"
13308   "leave"
13309   [(set_attr "type" "leave")])
13311 ;; Handle -fsplit-stack.
13313 (define_expand "split_stack_prologue"
13314   [(const_int 0)]
13315   ""
13317   ix86_expand_split_stack_prologue ();
13318   DONE;
13321 ;; In order to support the call/return predictor, we use a return
13322 ;; instruction which the middle-end doesn't see.
13323 (define_insn "split_stack_return"
13324   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13325                      UNSPECV_SPLIT_STACK_RETURN)]
13326   ""
13328   if (operands[0] == const0_rtx)
13329     return "ret";
13330   else
13331     return "ret\t%0";
13333   [(set_attr "atom_unit" "jeu")
13334    (set_attr "modrm" "0")
13335    (set (attr "length")
13336         (if_then_else (match_operand:SI 0 "const0_operand")
13337                       (const_int 1)
13338                       (const_int 3)))
13339    (set (attr "length_immediate")
13340         (if_then_else (match_operand:SI 0 "const0_operand")
13341                       (const_int 0)
13342                       (const_int 2)))])
13344 ;; If there are operand 0 bytes available on the stack, jump to
13345 ;; operand 1.
13347 (define_expand "split_stack_space_check"
13348   [(set (pc) (if_then_else
13349               (ltu (minus (reg SP_REG)
13350                           (match_operand 0 "register_operand"))
13351                    (match_dup 2))
13352               (label_ref (match_operand 1))
13353               (pc)))]
13354   ""
13356   rtx reg = gen_reg_rtx (Pmode);
13358   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13360   operands[2] = ix86_split_stack_guard ();
13361   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13363   DONE;
13366 ;; Bit manipulation instructions.
13368 (define_expand "ffs<mode>2"
13369   [(set (match_dup 2) (const_int -1))
13370    (parallel [(set (match_dup 3) (match_dup 4))
13371               (set (match_operand:SWI48 0 "register_operand")
13372                    (ctz:SWI48
13373                      (match_operand:SWI48 1 "nonimmediate_operand")))])
13374    (set (match_dup 0) (if_then_else:SWI48
13375                         (eq (match_dup 3) (const_int 0))
13376                         (match_dup 2)
13377                         (match_dup 0)))
13378    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13379               (clobber (reg:CC FLAGS_REG))])]
13380   ""
13382   machine_mode flags_mode;
13384   if (<MODE>mode == SImode && !TARGET_CMOVE)
13385     {
13386       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13387       DONE;
13388     }
13390   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13392   operands[2] = gen_reg_rtx (<MODE>mode);
13393   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13394   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13397 (define_insn_and_split "ffssi2_no_cmove"
13398   [(set (match_operand:SI 0 "register_operand" "=r")
13399         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13400    (clobber (match_scratch:SI 2 "=&q"))
13401    (clobber (reg:CC FLAGS_REG))]
13402   "!TARGET_CMOVE"
13403   "#"
13404   "&& reload_completed"
13405   [(parallel [(set (match_dup 4) (match_dup 5))
13406               (set (match_dup 0) (ctz:SI (match_dup 1)))])
13407    (set (strict_low_part (match_dup 3))
13408         (eq:QI (match_dup 4) (const_int 0)))
13409    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13410               (clobber (reg:CC FLAGS_REG))])
13411    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13412               (clobber (reg:CC FLAGS_REG))])
13413    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13414               (clobber (reg:CC FLAGS_REG))])]
13416   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13418   operands[3] = gen_lowpart (QImode, operands[2]);
13419   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13420   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13422   ix86_expand_clear (operands[2]);
13425 (define_insn_and_split "*tzcnt<mode>_1"
13426   [(set (reg:CCC FLAGS_REG)
13427         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13428                      (const_int 0)))
13429    (set (match_operand:SWI48 0 "register_operand" "=r")
13430         (ctz:SWI48 (match_dup 1)))]
13431   "TARGET_BMI"
13432   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13433   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13434    && optimize_function_for_speed_p (cfun)
13435    && !reg_mentioned_p (operands[0], operands[1])"
13436   [(parallel
13437     [(set (reg:CCC FLAGS_REG)
13438           (compare:CCC (match_dup 1) (const_int 0)))
13439      (set (match_dup 0)
13440           (ctz:SWI48 (match_dup 1)))
13441      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13442   "ix86_expand_clear (operands[0]);"
13443   [(set_attr "type" "alu1")
13444    (set_attr "prefix_0f" "1")
13445    (set_attr "prefix_rep" "1")
13446    (set_attr "btver2_decode" "double")
13447    (set_attr "mode" "<MODE>")])
13449 ; False dependency happens when destination is only updated by tzcnt,
13450 ; lzcnt or popcnt.  There is no false dependency when destination is
13451 ; also used in source.
13452 (define_insn "*tzcnt<mode>_1_falsedep"
13453   [(set (reg:CCC FLAGS_REG)
13454         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13455                      (const_int 0)))
13456    (set (match_operand:SWI48 0 "register_operand" "=r")
13457         (ctz:SWI48 (match_dup 1)))
13458    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13459            UNSPEC_INSN_FALSE_DEP)]
13460   "TARGET_BMI"
13461   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13462   [(set_attr "type" "alu1")
13463    (set_attr "prefix_0f" "1")
13464    (set_attr "prefix_rep" "1")
13465    (set_attr "btver2_decode" "double")
13466    (set_attr "mode" "<MODE>")])
13468 (define_insn "*bsf<mode>_1"
13469   [(set (reg:CCZ FLAGS_REG)
13470         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13471                      (const_int 0)))
13472    (set (match_operand:SWI48 0 "register_operand" "=r")
13473         (ctz:SWI48 (match_dup 1)))]
13474   ""
13475   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13476   [(set_attr "type" "alu1")
13477    (set_attr "prefix_0f" "1")
13478    (set_attr "btver2_decode" "double")
13479    (set_attr "znver1_decode" "vector")
13480    (set_attr "mode" "<MODE>")])
13482 (define_insn_and_split "ctz<mode>2"
13483   [(set (match_operand:SWI48 0 "register_operand" "=r")
13484         (ctz:SWI48
13485           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13486    (clobber (reg:CC FLAGS_REG))]
13487   ""
13489   if (TARGET_BMI)
13490     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13491   else if (optimize_function_for_size_p (cfun))
13492     ;
13493   else if (TARGET_GENERIC)
13494     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13495     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13497   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13499   "(TARGET_BMI || TARGET_GENERIC)
13500    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13501    && optimize_function_for_speed_p (cfun)
13502    && !reg_mentioned_p (operands[0], operands[1])"
13503   [(parallel
13504     [(set (match_dup 0)
13505           (ctz:SWI48 (match_dup 1)))
13506      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13507      (clobber (reg:CC FLAGS_REG))])]
13508   "ix86_expand_clear (operands[0]);"
13509   [(set_attr "type" "alu1")
13510    (set_attr "prefix_0f" "1")
13511    (set (attr "prefix_rep")
13512      (if_then_else
13513        (ior (match_test "TARGET_BMI")
13514             (and (not (match_test "optimize_function_for_size_p (cfun)"))
13515                  (match_test "TARGET_GENERIC")))
13516        (const_string "1")
13517        (const_string "0")))
13518    (set_attr "mode" "<MODE>")])
13520 ; False dependency happens when destination is only updated by tzcnt,
13521 ; lzcnt or popcnt.  There is no false dependency when destination is
13522 ; also used in source.
13523 (define_insn "*ctz<mode>2_falsedep"
13524   [(set (match_operand:SWI48 0 "register_operand" "=r")
13525         (ctz:SWI48
13526           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13527    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13528            UNSPEC_INSN_FALSE_DEP)
13529    (clobber (reg:CC FLAGS_REG))]
13530   ""
13532   if (TARGET_BMI)
13533     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13534   else if (TARGET_GENERIC)
13535     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
13536     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13537   else
13538     gcc_unreachable ();
13540   [(set_attr "type" "alu1")
13541    (set_attr "prefix_0f" "1")
13542    (set_attr "prefix_rep" "1")
13543    (set_attr "mode" "<MODE>")])
13545 (define_insn "bsr_rex64"
13546   [(set (match_operand:DI 0 "register_operand" "=r")
13547         (minus:DI (const_int 63)
13548                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13549    (clobber (reg:CC FLAGS_REG))]
13550   "TARGET_64BIT"
13551   "bsr{q}\t{%1, %0|%0, %1}"
13552   [(set_attr "type" "alu1")
13553    (set_attr "prefix_0f" "1")
13554    (set_attr "znver1_decode" "vector")
13555    (set_attr "mode" "DI")])
13557 (define_insn "bsr"
13558   [(set (match_operand:SI 0 "register_operand" "=r")
13559         (minus:SI (const_int 31)
13560                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13561    (clobber (reg:CC FLAGS_REG))]
13562   ""
13563   "bsr{l}\t{%1, %0|%0, %1}"
13564   [(set_attr "type" "alu1")
13565    (set_attr "prefix_0f" "1")
13566    (set_attr "znver1_decode" "vector")
13567    (set_attr "mode" "SI")])
13569 (define_insn "*bsrhi"
13570   [(set (match_operand:HI 0 "register_operand" "=r")
13571         (minus:HI (const_int 15)
13572                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13573    (clobber (reg:CC FLAGS_REG))]
13574   ""
13575   "bsr{w}\t{%1, %0|%0, %1}"
13576   [(set_attr "type" "alu1")
13577    (set_attr "prefix_0f" "1")
13578    (set_attr "znver1_decode" "vector")
13579    (set_attr "mode" "HI")])
13581 (define_expand "clz<mode>2"
13582   [(parallel
13583      [(set (match_operand:SWI48 0 "register_operand")
13584            (minus:SWI48
13585              (match_dup 2)
13586              (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13587       (clobber (reg:CC FLAGS_REG))])
13588    (parallel
13589      [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13590       (clobber (reg:CC FLAGS_REG))])]
13591   ""
13593   if (TARGET_LZCNT)
13594     {
13595       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13596       DONE;
13597     }
13598   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13601 (define_insn_and_split "clz<mode>2_lzcnt"
13602   [(set (match_operand:SWI48 0 "register_operand" "=r")
13603         (clz:SWI48
13604           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13605    (clobber (reg:CC FLAGS_REG))]
13606   "TARGET_LZCNT"
13607   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13608   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13609    && optimize_function_for_speed_p (cfun)
13610    && !reg_mentioned_p (operands[0], operands[1])"
13611   [(parallel
13612     [(set (match_dup 0)
13613           (clz:SWI48 (match_dup 1)))
13614      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13615      (clobber (reg:CC FLAGS_REG))])]
13616   "ix86_expand_clear (operands[0]);"
13617   [(set_attr "prefix_rep" "1")
13618    (set_attr "type" "bitmanip")
13619    (set_attr "mode" "<MODE>")])
13621 ; False dependency happens when destination is only updated by tzcnt,
13622 ; lzcnt or popcnt.  There is no false dependency when destination is
13623 ; also used in source.
13624 (define_insn "*clz<mode>2_lzcnt_falsedep"
13625   [(set (match_operand:SWI48 0 "register_operand" "=r")
13626         (clz:SWI48
13627           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13628    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13629            UNSPEC_INSN_FALSE_DEP)
13630    (clobber (reg:CC FLAGS_REG))]
13631   "TARGET_LZCNT"
13632   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13633   [(set_attr "prefix_rep" "1")
13634    (set_attr "type" "bitmanip")
13635    (set_attr "mode" "<MODE>")])
13637 (define_int_iterator LT_ZCNT
13638         [(UNSPEC_TZCNT "TARGET_BMI")
13639          (UNSPEC_LZCNT "TARGET_LZCNT")])
13641 (define_int_attr lt_zcnt
13642         [(UNSPEC_TZCNT "tzcnt")
13643          (UNSPEC_LZCNT "lzcnt")])
13645 (define_int_attr lt_zcnt_type
13646         [(UNSPEC_TZCNT "alu1")
13647          (UNSPEC_LZCNT "bitmanip")])
13649 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
13650 ;; provides operand size as output when source operand is zero. 
13652 (define_insn_and_split "<lt_zcnt>_<mode>"
13653   [(set (match_operand:SWI48 0 "register_operand" "=r")
13654         (unspec:SWI48
13655           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13656    (clobber (reg:CC FLAGS_REG))]
13657   ""
13658   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13659   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13660    && optimize_function_for_speed_p (cfun)
13661    && !reg_mentioned_p (operands[0], operands[1])"
13662   [(parallel
13663     [(set (match_dup 0)
13664           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13665      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13666      (clobber (reg:CC FLAGS_REG))])]
13667   "ix86_expand_clear (operands[0]);"
13668   [(set_attr "type" "<lt_zcnt_type>")
13669    (set_attr "prefix_0f" "1")
13670    (set_attr "prefix_rep" "1")
13671    (set_attr "mode" "<MODE>")])
13673 ; False dependency happens when destination is only updated by tzcnt,
13674 ; lzcnt or popcnt.  There is no false dependency when destination is
13675 ; also used in source.
13676 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13677   [(set (match_operand:SWI48 0 "register_operand" "=r")
13678         (unspec:SWI48
13679           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13680    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13681            UNSPEC_INSN_FALSE_DEP)
13682    (clobber (reg:CC FLAGS_REG))]
13683   ""
13684   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13685   [(set_attr "type" "<lt_zcnt_type>")
13686    (set_attr "prefix_0f" "1")
13687    (set_attr "prefix_rep" "1")
13688    (set_attr "mode" "<MODE>")])
13690 (define_insn "<lt_zcnt>_hi"
13691   [(set (match_operand:HI 0 "register_operand" "=r")
13692         (unspec:HI
13693           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13694    (clobber (reg:CC FLAGS_REG))]
13695   ""
13696   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13697   [(set_attr "type" "<lt_zcnt_type>")
13698    (set_attr "prefix_0f" "1")
13699    (set_attr "prefix_rep" "1")
13700    (set_attr "mode" "HI")])
13702 ;; BMI instructions.
13704 (define_insn "bmi_bextr_<mode>"
13705   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13706         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13707                        (match_operand:SWI48 2 "register_operand" "r,r")]
13708                       UNSPEC_BEXTR))
13709    (clobber (reg:CC FLAGS_REG))]
13710   "TARGET_BMI"
13711   "bextr\t{%2, %1, %0|%0, %1, %2}"
13712   [(set_attr "type" "bitmanip")
13713    (set_attr "btver2_decode" "direct, double")
13714    (set_attr "mode" "<MODE>")])
13716 (define_insn "*bmi_bextr_<mode>_ccz"
13717   [(set (reg:CCZ FLAGS_REG)
13718         (compare:CCZ
13719           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13720                          (match_operand:SWI48 2 "register_operand" "r,r")]
13721                         UNSPEC_BEXTR)
13722           (const_int 0)))
13723    (clobber (match_scratch:SWI48 0 "=r,r"))]
13724   "TARGET_BMI"
13725   "bextr\t{%2, %1, %0|%0, %1, %2}"
13726   [(set_attr "type" "bitmanip")
13727    (set_attr "btver2_decode" "direct, double")
13728    (set_attr "mode" "<MODE>")])
13730 (define_insn "*bmi_blsi_<mode>"
13731   [(set (match_operand:SWI48 0 "register_operand" "=r")
13732         (and:SWI48
13733           (neg:SWI48
13734             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13735           (match_dup 1)))
13736    (clobber (reg:CC FLAGS_REG))]
13737   "TARGET_BMI"
13738   "blsi\t{%1, %0|%0, %1}"
13739   [(set_attr "type" "bitmanip")
13740    (set_attr "btver2_decode" "double")
13741    (set_attr "mode" "<MODE>")])
13743 (define_insn "*bmi_blsmsk_<mode>"
13744   [(set (match_operand:SWI48 0 "register_operand" "=r")
13745         (xor:SWI48
13746           (plus:SWI48
13747             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13748             (const_int -1))
13749           (match_dup 1)))
13750    (clobber (reg:CC FLAGS_REG))]
13751   "TARGET_BMI"
13752   "blsmsk\t{%1, %0|%0, %1}"
13753   [(set_attr "type" "bitmanip")
13754    (set_attr "btver2_decode" "double")
13755    (set_attr "mode" "<MODE>")])
13757 (define_insn "*bmi_blsr_<mode>"
13758   [(set (match_operand:SWI48 0 "register_operand" "=r")
13759         (and:SWI48
13760           (plus:SWI48
13761             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13762             (const_int -1))
13763           (match_dup 1)))
13764    (clobber (reg:CC FLAGS_REG))]
13765    "TARGET_BMI"
13766    "blsr\t{%1, %0|%0, %1}"
13767   [(set_attr "type" "bitmanip")
13768    (set_attr "btver2_decode" "double")
13769    (set_attr "mode" "<MODE>")])
13771 ;; BMI2 instructions.
13772 (define_expand "bmi2_bzhi_<mode>3"
13773   [(parallel
13774     [(set (match_operand:SWI48 0 "register_operand")
13775           (zero_extract:SWI48
13776             (match_operand:SWI48 1 "nonimmediate_operand")
13777             (umin:SWI48
13778               (and:SWI48 (match_operand:SWI48 2 "register_operand")
13779                          (const_int 255))
13780               (match_dup 3))
13781             (const_int 0)))
13782      (clobber (reg:CC FLAGS_REG))])]
13783   "TARGET_BMI2"
13784   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13786 (define_insn "*bmi2_bzhi_<mode>3"
13787   [(set (match_operand:SWI48 0 "register_operand" "=r")
13788         (zero_extract:SWI48
13789           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13790           (umin:SWI48
13791             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13792                        (const_int 255))
13793             (match_operand:SWI48 3 "const_int_operand" "n"))
13794           (const_int 0)))
13795    (clobber (reg:CC FLAGS_REG))]
13796   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13797   "bzhi\t{%2, %1, %0|%0, %1, %2}"
13798   [(set_attr "type" "bitmanip")
13799    (set_attr "prefix" "vex")
13800    (set_attr "mode" "<MODE>")])
13802 (define_insn "*bmi2_bzhi_<mode>3_1"
13803   [(set (match_operand:SWI48 0 "register_operand" "=r")
13804         (zero_extract:SWI48
13805           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13806           (umin:SWI48
13807             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13808             (match_operand:SWI48 3 "const_int_operand" "n"))
13809           (const_int 0)))
13810    (clobber (reg:CC FLAGS_REG))]
13811   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13812   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13813   [(set_attr "type" "bitmanip")
13814    (set_attr "prefix" "vex")
13815    (set_attr "mode" "<MODE>")])
13817 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13818   [(set (reg:CCZ FLAGS_REG)
13819         (compare:CCZ
13820           (zero_extract:SWI48
13821             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13822             (umin:SWI48
13823               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13824               (match_operand:SWI48 3 "const_int_operand" "n"))
13825             (const_int 0))
13826         (const_int 0)))
13827    (clobber (match_scratch:SWI48 0 "=r"))]
13828   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13829   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13830   [(set_attr "type" "bitmanip")
13831    (set_attr "prefix" "vex")
13832    (set_attr "mode" "<MODE>")])
13834 (define_insn "bmi2_pdep_<mode>3"
13835   [(set (match_operand:SWI48 0 "register_operand" "=r")
13836         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13837                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13838                        UNSPEC_PDEP))]
13839   "TARGET_BMI2"
13840   "pdep\t{%2, %1, %0|%0, %1, %2}"
13841   [(set_attr "type" "bitmanip")
13842    (set_attr "prefix" "vex")
13843    (set_attr "mode" "<MODE>")])
13845 (define_insn "bmi2_pext_<mode>3"
13846   [(set (match_operand:SWI48 0 "register_operand" "=r")
13847         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13848                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13849                        UNSPEC_PEXT))]
13850   "TARGET_BMI2"
13851   "pext\t{%2, %1, %0|%0, %1, %2}"
13852   [(set_attr "type" "bitmanip")
13853    (set_attr "prefix" "vex")
13854    (set_attr "mode" "<MODE>")])
13856 ;; TBM instructions.
13857 (define_insn "tbm_bextri_<mode>"
13858   [(set (match_operand:SWI48 0 "register_operand" "=r")
13859         (zero_extract:SWI48
13860           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13861           (match_operand 2 "const_0_to_255_operand" "N")
13862           (match_operand 3 "const_0_to_255_operand" "N")))
13863    (clobber (reg:CC FLAGS_REG))]
13864    "TARGET_TBM"
13866   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13867   return "bextr\t{%2, %1, %0|%0, %1, %2}";
13869   [(set_attr "type" "bitmanip")
13870    (set_attr "mode" "<MODE>")])
13872 (define_insn "*tbm_blcfill_<mode>"
13873   [(set (match_operand:SWI48 0 "register_operand" "=r")
13874         (and:SWI48
13875           (plus:SWI48
13876             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13877             (const_int 1))
13878           (match_dup 1)))
13879    (clobber (reg:CC FLAGS_REG))]
13880    "TARGET_TBM"
13881    "blcfill\t{%1, %0|%0, %1}"
13882   [(set_attr "type" "bitmanip")
13883    (set_attr "mode" "<MODE>")])
13885 (define_insn "*tbm_blci_<mode>"
13886   [(set (match_operand:SWI48 0 "register_operand" "=r")
13887         (ior:SWI48
13888           (not:SWI48
13889             (plus:SWI48
13890               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13891               (const_int 1)))
13892           (match_dup 1)))
13893    (clobber (reg:CC FLAGS_REG))]
13894    "TARGET_TBM"
13895    "blci\t{%1, %0|%0, %1}"
13896   [(set_attr "type" "bitmanip")
13897    (set_attr "mode" "<MODE>")])
13899 (define_insn "*tbm_blcic_<mode>"
13900   [(set (match_operand:SWI48 0 "register_operand" "=r")
13901         (and:SWI48
13902           (plus:SWI48
13903             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13904             (const_int 1))
13905           (not:SWI48
13906             (match_dup 1))))
13907    (clobber (reg:CC FLAGS_REG))]
13908    "TARGET_TBM"
13909    "blcic\t{%1, %0|%0, %1}"
13910   [(set_attr "type" "bitmanip")
13911    (set_attr "mode" "<MODE>")])
13913 (define_insn "*tbm_blcmsk_<mode>"
13914   [(set (match_operand:SWI48 0 "register_operand" "=r")
13915         (xor:SWI48
13916           (plus:SWI48
13917             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13918             (const_int 1))
13919           (match_dup 1)))
13920    (clobber (reg:CC FLAGS_REG))]
13921    "TARGET_TBM"
13922    "blcmsk\t{%1, %0|%0, %1}"
13923   [(set_attr "type" "bitmanip")
13924    (set_attr "mode" "<MODE>")])
13926 (define_insn "*tbm_blcs_<mode>"
13927   [(set (match_operand:SWI48 0 "register_operand" "=r")
13928         (ior:SWI48
13929           (plus:SWI48
13930             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13931             (const_int 1))
13932           (match_dup 1)))
13933    (clobber (reg:CC FLAGS_REG))]
13934    "TARGET_TBM"
13935    "blcs\t{%1, %0|%0, %1}"
13936   [(set_attr "type" "bitmanip")
13937    (set_attr "mode" "<MODE>")])
13939 (define_insn "*tbm_blsfill_<mode>"
13940   [(set (match_operand:SWI48 0 "register_operand" "=r")
13941         (ior:SWI48
13942           (plus:SWI48
13943             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13944             (const_int -1))
13945           (match_dup 1)))
13946    (clobber (reg:CC FLAGS_REG))]
13947    "TARGET_TBM"
13948    "blsfill\t{%1, %0|%0, %1}"
13949   [(set_attr "type" "bitmanip")
13950    (set_attr "mode" "<MODE>")])
13952 (define_insn "*tbm_blsic_<mode>"
13953   [(set (match_operand:SWI48 0 "register_operand" "=r")
13954         (ior:SWI48
13955           (plus:SWI48
13956             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13957             (const_int -1))
13958           (not:SWI48
13959             (match_dup 1))))
13960    (clobber (reg:CC FLAGS_REG))]
13961    "TARGET_TBM"
13962    "blsic\t{%1, %0|%0, %1}"
13963   [(set_attr "type" "bitmanip")
13964    (set_attr "mode" "<MODE>")])
13966 (define_insn "*tbm_t1mskc_<mode>"
13967   [(set (match_operand:SWI48 0 "register_operand" "=r")
13968         (ior:SWI48
13969           (plus:SWI48
13970             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13971             (const_int 1))
13972           (not:SWI48
13973             (match_dup 1))))
13974    (clobber (reg:CC FLAGS_REG))]
13975    "TARGET_TBM"
13976    "t1mskc\t{%1, %0|%0, %1}"
13977   [(set_attr "type" "bitmanip")
13978    (set_attr "mode" "<MODE>")])
13980 (define_insn "*tbm_tzmsk_<mode>"
13981   [(set (match_operand:SWI48 0 "register_operand" "=r")
13982         (and:SWI48
13983           (plus:SWI48
13984             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13985             (const_int -1))
13986           (not:SWI48
13987             (match_dup 1))))
13988    (clobber (reg:CC FLAGS_REG))]
13989    "TARGET_TBM"
13990    "tzmsk\t{%1, %0|%0, %1}"
13991   [(set_attr "type" "bitmanip")
13992    (set_attr "mode" "<MODE>")])
13994 (define_insn_and_split "popcount<mode>2"
13995   [(set (match_operand:SWI48 0 "register_operand" "=r")
13996         (popcount:SWI48
13997           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13998    (clobber (reg:CC FLAGS_REG))]
13999   "TARGET_POPCNT"
14001 #if TARGET_MACHO
14002   return "popcnt\t{%1, %0|%0, %1}";
14003 #else
14004   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14005 #endif
14007   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14008    && optimize_function_for_speed_p (cfun)
14009    && !reg_mentioned_p (operands[0], operands[1])"
14010   [(parallel
14011     [(set (match_dup 0)
14012           (popcount:SWI48 (match_dup 1)))
14013      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14014      (clobber (reg:CC FLAGS_REG))])]
14015   "ix86_expand_clear (operands[0]);"
14016   [(set_attr "prefix_rep" "1")
14017    (set_attr "type" "bitmanip")
14018    (set_attr "mode" "<MODE>")])
14020 ; False dependency happens when destination is only updated by tzcnt,
14021 ; lzcnt or popcnt.  There is no false dependency when destination is
14022 ; also used in source.
14023 (define_insn "*popcount<mode>2_falsedep"
14024   [(set (match_operand:SWI48 0 "register_operand" "=r")
14025         (popcount:SWI48
14026           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14027    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14028            UNSPEC_INSN_FALSE_DEP)
14029    (clobber (reg:CC FLAGS_REG))]
14030   "TARGET_POPCNT"
14032 #if TARGET_MACHO
14033   return "popcnt\t{%1, %0|%0, %1}";
14034 #else
14035   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14036 #endif
14038   [(set_attr "prefix_rep" "1")
14039    (set_attr "type" "bitmanip")
14040    (set_attr "mode" "<MODE>")])
14042 (define_insn_and_split "*popcounthi2_1"
14043   [(set (match_operand:SI 0 "register_operand")
14044         (popcount:SI
14045           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14046    (clobber (reg:CC FLAGS_REG))]
14047   "TARGET_POPCNT
14048    && can_create_pseudo_p ()"
14049   "#"
14050   "&& 1"
14051   [(const_int 0)]
14053   rtx tmp = gen_reg_rtx (HImode);
14055   emit_insn (gen_popcounthi2 (tmp, operands[1]));
14056   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14057   DONE;
14060 (define_insn "popcounthi2"
14061   [(set (match_operand:HI 0 "register_operand" "=r")
14062         (popcount:HI
14063           (match_operand:HI 1 "nonimmediate_operand" "rm")))
14064    (clobber (reg:CC FLAGS_REG))]
14065   "TARGET_POPCNT"
14067 #if TARGET_MACHO
14068   return "popcnt\t{%1, %0|%0, %1}";
14069 #else
14070   return "popcnt{w}\t{%1, %0|%0, %1}";
14071 #endif
14073   [(set_attr "prefix_rep" "1")
14074    (set_attr "type" "bitmanip")
14075    (set_attr "mode" "HI")])
14077 (define_expand "bswapdi2"
14078   [(set (match_operand:DI 0 "register_operand")
14079         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14080   "TARGET_64BIT"
14082   if (!TARGET_MOVBE)
14083     operands[1] = force_reg (DImode, operands[1]);
14086 (define_expand "bswapsi2"
14087   [(set (match_operand:SI 0 "register_operand")
14088         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14089   ""
14091   if (TARGET_MOVBE)
14092     ;
14093   else if (TARGET_BSWAP)
14094     operands[1] = force_reg (SImode, operands[1]);
14095   else
14096     {
14097       rtx x = operands[0];
14099       emit_move_insn (x, operands[1]);
14100       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14101       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14102       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14103       DONE;
14104     }
14107 (define_insn "*bswap<mode>2_movbe"
14108   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14109         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14110   "TARGET_MOVBE
14111    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14112   "@
14113     bswap\t%0
14114     movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14115     movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14116   [(set_attr "type" "bitmanip,imov,imov")
14117    (set_attr "modrm" "0,1,1")
14118    (set_attr "prefix_0f" "*,1,1")
14119    (set_attr "prefix_extra" "*,1,1")
14120    (set_attr "mode" "<MODE>")])
14122 (define_insn "*bswap<mode>2"
14123   [(set (match_operand:SWI48 0 "register_operand" "=r")
14124         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14125   "TARGET_BSWAP"
14126   "bswap\t%0"
14127   [(set_attr "type" "bitmanip")
14128    (set_attr "modrm" "0")
14129    (set_attr "mode" "<MODE>")])
14131 (define_expand "bswaphi2"
14132   [(set (match_operand:HI 0 "register_operand")
14133         (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14134   "TARGET_MOVBE")
14136 (define_insn "*bswaphi2_movbe"
14137   [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14138         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14139   "TARGET_MOVBE
14140    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14141   "@
14142     xchg{b}\t{%h0, %b0|%b0, %h0}
14143     movbe{w}\t{%1, %0|%0, %1}
14144     movbe{w}\t{%1, %0|%0, %1}"
14145   [(set_attr "type" "imov")
14146    (set_attr "modrm" "*,1,1")
14147    (set_attr "prefix_0f" "*,1,1")
14148    (set_attr "prefix_extra" "*,1,1")
14149    (set_attr "pent_pair" "np,*,*")
14150    (set_attr "athlon_decode" "vector,*,*")
14151    (set_attr "amdfam10_decode" "double,*,*")
14152    (set_attr "bdver1_decode" "double,*,*")
14153    (set_attr "mode" "QI,HI,HI")])
14155 (define_peephole2
14156   [(set (match_operand:HI 0 "general_reg_operand")
14157         (bswap:HI (match_dup 0)))]
14158   "TARGET_MOVBE
14159    && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14160    && peep2_regno_dead_p (0, FLAGS_REG)"
14161   [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14162               (clobber (reg:CC FLAGS_REG))])])
14164 (define_insn "bswaphi_lowpart"
14165   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14166         (bswap:HI (match_dup 0)))
14167    (clobber (reg:CC FLAGS_REG))]
14168   ""
14169   "@
14170     xchg{b}\t{%h0, %b0|%b0, %h0}
14171     rol{w}\t{$8, %0|%0, 8}"
14172   [(set (attr "preferred_for_size")
14173      (cond [(eq_attr "alternative" "0")
14174               (symbol_ref "true")]
14175            (symbol_ref "false")))
14176    (set (attr "preferred_for_speed")
14177      (cond [(eq_attr "alternative" "0")
14178               (symbol_ref "TARGET_USE_XCHGB")]
14179            (symbol_ref "!TARGET_USE_XCHGB")))
14180    (set_attr "length" "2,4")
14181    (set_attr "mode" "QI,HI")])
14183 (define_expand "paritydi2"
14184   [(set (match_operand:DI 0 "register_operand")
14185         (parity:DI (match_operand:DI 1 "register_operand")))]
14186   "! TARGET_POPCNT"
14188   rtx scratch = gen_reg_rtx (QImode);
14190   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14191                                 NULL_RTX, operands[1]));
14193   ix86_expand_setcc (scratch, ORDERED,
14194                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14196   if (TARGET_64BIT)
14197     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14198   else
14199     {
14200       rtx tmp = gen_reg_rtx (SImode);
14202       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14203       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14204     }
14205   DONE;
14208 (define_expand "paritysi2"
14209   [(set (match_operand:SI 0 "register_operand")
14210         (parity:SI (match_operand:SI 1 "register_operand")))]
14211   "! TARGET_POPCNT"
14213   rtx scratch = gen_reg_rtx (QImode);
14215   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14217   ix86_expand_setcc (scratch, ORDERED,
14218                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14220   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14221   DONE;
14224 (define_insn_and_split "paritydi2_cmp"
14225   [(set (reg:CC FLAGS_REG)
14226         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14227                    UNSPEC_PARITY))
14228    (clobber (match_scratch:DI 0 "=r"))
14229    (clobber (match_scratch:SI 1 "=&r"))
14230    (clobber (match_scratch:HI 2 "=Q"))]
14231   "! TARGET_POPCNT"
14232   "#"
14233   "&& reload_completed"
14234   [(parallel
14235      [(set (match_dup 1)
14236            (xor:SI (match_dup 1) (match_dup 4)))
14237       (clobber (reg:CC FLAGS_REG))])
14238    (parallel
14239      [(set (reg:CC FLAGS_REG)
14240            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14241       (clobber (match_dup 1))
14242       (clobber (match_dup 2))])]
14244   operands[4] = gen_lowpart (SImode, operands[3]);
14246   if (TARGET_64BIT)
14247     {
14248       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14249       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14250     }
14251   else
14252     operands[1] = gen_highpart (SImode, operands[3]);
14255 (define_insn_and_split "paritysi2_cmp"
14256   [(set (reg:CC FLAGS_REG)
14257         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14258                    UNSPEC_PARITY))
14259    (clobber (match_scratch:SI 0 "=r"))
14260    (clobber (match_scratch:HI 1 "=&Q"))]
14261   "! TARGET_POPCNT"
14262   "#"
14263   "&& reload_completed"
14264   [(parallel
14265      [(set (match_dup 1)
14266            (xor:HI (match_dup 1) (match_dup 3)))
14267       (clobber (reg:CC FLAGS_REG))])
14268    (parallel
14269      [(set (reg:CC FLAGS_REG)
14270            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14271       (clobber (match_dup 1))])]
14273   operands[3] = gen_lowpart (HImode, operands[2]);
14275   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14276   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14279 (define_insn "*parityhi2_cmp"
14280   [(set (reg:CC FLAGS_REG)
14281         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14282                    UNSPEC_PARITY))
14283    (clobber (match_scratch:HI 0 "=Q"))]
14284   "! TARGET_POPCNT"
14285   "xor{b}\t{%h0, %b0|%b0, %h0}"
14286   [(set_attr "length" "2")
14287    (set_attr "mode" "HI")])
14290 ;; Thread-local storage patterns for ELF.
14292 ;; Note that these code sequences must appear exactly as shown
14293 ;; in order to allow linker relaxation.
14295 (define_insn "*tls_global_dynamic_32_gnu"
14296   [(set (match_operand:SI 0 "register_operand" "=a")
14297         (unspec:SI
14298          [(match_operand:SI 1 "register_operand" "Yb")
14299           (match_operand 2 "tls_symbolic_operand")
14300           (match_operand 3 "constant_call_address_operand" "Bz")
14301           (reg:SI SP_REG)]
14302          UNSPEC_TLS_GD))
14303    (clobber (match_scratch:SI 4 "=d"))
14304    (clobber (match_scratch:SI 5 "=c"))
14305    (clobber (reg:CC FLAGS_REG))]
14306   "!TARGET_64BIT && TARGET_GNU_TLS"
14308   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14309     output_asm_insn
14310       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14311   else
14312     output_asm_insn
14313       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14314   if (TARGET_SUN_TLS)
14315 #ifdef HAVE_AS_IX86_TLSGDPLT
14316     return "call\t%a2@tlsgdplt";
14317 #else
14318     return "call\t%p3@plt";
14319 #endif
14320   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14321     return "call\t%P3";
14322   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14324   [(set_attr "type" "multi")
14325    (set_attr "length" "12")])
14327 (define_expand "tls_global_dynamic_32"
14328   [(parallel
14329     [(set (match_operand:SI 0 "register_operand")
14330           (unspec:SI [(match_operand:SI 2 "register_operand")
14331                       (match_operand 1 "tls_symbolic_operand")
14332                       (match_operand 3 "constant_call_address_operand")
14333                       (reg:SI SP_REG)]
14334                      UNSPEC_TLS_GD))
14335      (clobber (match_scratch:SI 4))
14336      (clobber (match_scratch:SI 5))
14337      (clobber (reg:CC FLAGS_REG))])]
14338   ""
14339   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14341 (define_insn "*tls_global_dynamic_64_<mode>"
14342   [(set (match_operand:P 0 "register_operand" "=a")
14343         (call:P
14344          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14345          (match_operand 3)))
14346    (unspec:P [(match_operand 1 "tls_symbolic_operand")
14347               (reg:P SP_REG)]
14348              UNSPEC_TLS_GD)]
14349   "TARGET_64BIT"
14351   if (!TARGET_X32)
14352     fputs (ASM_BYTE "0x66\n", asm_out_file);
14353   output_asm_insn
14354     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14355   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14356     fputs (ASM_SHORT "0x6666\n", asm_out_file);
14357   else
14358     fputs (ASM_BYTE "0x66\n", asm_out_file);
14359   fputs ("\trex64\n", asm_out_file);
14360   if (TARGET_SUN_TLS)
14361     return "call\t%p2@plt";
14362   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14363     return "call\t%P2";
14364   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14366   [(set_attr "type" "multi")
14367    (set (attr "length")
14368         (symbol_ref "TARGET_X32 ? 15 : 16"))])
14370 (define_insn "*tls_global_dynamic_64_largepic"
14371   [(set (match_operand:DI 0 "register_operand" "=a")
14372         (call:DI
14373          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14374                           (match_operand:DI 3 "immediate_operand" "i")))
14375          (match_operand 4)))
14376    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14377                (reg:DI SP_REG)]
14378               UNSPEC_TLS_GD)]
14379   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14380    && GET_CODE (operands[3]) == CONST
14381    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14382    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14384   output_asm_insn
14385     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14386   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14387   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14388   return "call\t{*%%rax|rax}";
14390   [(set_attr "type" "multi")
14391    (set_attr "length" "22")])
14393 (define_expand "tls_global_dynamic_64_<mode>"
14394   [(parallel
14395     [(set (match_operand:P 0 "register_operand")
14396           (call:P
14397            (mem:QI (match_operand 2))
14398            (const_int 0)))
14399      (unspec:P [(match_operand 1 "tls_symbolic_operand")
14400                 (reg:P SP_REG)]
14401                UNSPEC_TLS_GD)])]
14402   "TARGET_64BIT"
14403   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14405 (define_insn "*tls_local_dynamic_base_32_gnu"
14406   [(set (match_operand:SI 0 "register_operand" "=a")
14407         (unspec:SI
14408          [(match_operand:SI 1 "register_operand" "Yb")
14409           (match_operand 2 "constant_call_address_operand" "Bz")
14410           (reg:SI SP_REG)]
14411          UNSPEC_TLS_LD_BASE))
14412    (clobber (match_scratch:SI 3 "=d"))
14413    (clobber (match_scratch:SI 4 "=c"))
14414    (clobber (reg:CC FLAGS_REG))]
14415   "!TARGET_64BIT && TARGET_GNU_TLS"
14417   output_asm_insn
14418     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14419   if (TARGET_SUN_TLS)
14420     {
14421       if (HAVE_AS_IX86_TLSLDMPLT)
14422         return "call\t%&@tlsldmplt";
14423       else
14424         return "call\t%p2@plt";
14425     }
14426   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14427     return "call\t%P2";
14428   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14430   [(set_attr "type" "multi")
14431    (set_attr "length" "11")])
14433 (define_expand "tls_local_dynamic_base_32"
14434   [(parallel
14435      [(set (match_operand:SI 0 "register_operand")
14436            (unspec:SI
14437             [(match_operand:SI 1 "register_operand")
14438              (match_operand 2 "constant_call_address_operand")
14439              (reg:SI SP_REG)]
14440             UNSPEC_TLS_LD_BASE))
14441       (clobber (match_scratch:SI 3))
14442       (clobber (match_scratch:SI 4))
14443       (clobber (reg:CC FLAGS_REG))])]
14444   ""
14445   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14447 (define_insn "*tls_local_dynamic_base_64_<mode>"
14448   [(set (match_operand:P 0 "register_operand" "=a")
14449         (call:P
14450          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14451          (match_operand 2)))
14452    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14453   "TARGET_64BIT"
14455   output_asm_insn
14456     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14457   if (TARGET_SUN_TLS)
14458     return "call\t%p1@plt";
14459   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14460     return "call\t%P1";
14461   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14463   [(set_attr "type" "multi")
14464    (set_attr "length" "12")])
14466 (define_insn "*tls_local_dynamic_base_64_largepic"
14467   [(set (match_operand:DI 0 "register_operand" "=a")
14468         (call:DI
14469          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14470                           (match_operand:DI 2 "immediate_operand" "i")))
14471          (match_operand 3)))
14472    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14473   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14474    && GET_CODE (operands[2]) == CONST
14475    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14476    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14478   output_asm_insn
14479     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14480   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14481   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14482   return "call\t{*%%rax|rax}";
14484   [(set_attr "type" "multi")
14485    (set_attr "length" "22")])
14487 (define_expand "tls_local_dynamic_base_64_<mode>"
14488   [(parallel
14489      [(set (match_operand:P 0 "register_operand")
14490            (call:P
14491             (mem:QI (match_operand 1))
14492             (const_int 0)))
14493       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14494   "TARGET_64BIT"
14495   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14497 ;; Local dynamic of a single variable is a lose.  Show combine how
14498 ;; to convert that back to global dynamic.
14500 (define_insn_and_split "*tls_local_dynamic_32_once"
14501   [(set (match_operand:SI 0 "register_operand" "=a")
14502         (plus:SI
14503          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14504                      (match_operand 2 "constant_call_address_operand" "Bz")
14505                      (reg:SI SP_REG)]
14506                     UNSPEC_TLS_LD_BASE)
14507          (const:SI (unspec:SI
14508                     [(match_operand 3 "tls_symbolic_operand")]
14509                     UNSPEC_DTPOFF))))
14510    (clobber (match_scratch:SI 4 "=d"))
14511    (clobber (match_scratch:SI 5 "=c"))
14512    (clobber (reg:CC FLAGS_REG))]
14513   ""
14514   "#"
14515   ""
14516   [(parallel
14517      [(set (match_dup 0)
14518            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14519                        (reg:SI SP_REG)]
14520                       UNSPEC_TLS_GD))
14521       (clobber (match_dup 4))
14522       (clobber (match_dup 5))
14523       (clobber (reg:CC FLAGS_REG))])])
14525 ;; Load and add the thread base pointer from %<tp_seg>:0.
14526 (define_insn_and_split "*load_tp_<mode>"
14527   [(set (match_operand:PTR 0 "register_operand" "=r")
14528         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14529   ""
14530   "#"
14531   ""
14532   [(set (match_dup 0)
14533         (match_dup 1))]
14535   addr_space_t as = DEFAULT_TLS_SEG_REG;
14537   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14538   set_mem_addr_space (operands[1], as);
14541 (define_insn_and_split "*load_tp_x32_zext"
14542   [(set (match_operand:DI 0 "register_operand" "=r")
14543         (zero_extend:DI
14544           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14545   "TARGET_X32"
14546   "#"
14547   ""
14548   [(set (match_dup 0)
14549         (zero_extend:DI (match_dup 1)))]
14551   addr_space_t as = DEFAULT_TLS_SEG_REG;
14553   operands[1] = gen_const_mem (SImode, const0_rtx);
14554   set_mem_addr_space (operands[1], as);
14557 (define_insn_and_split "*add_tp_<mode>"
14558   [(set (match_operand:PTR 0 "register_operand" "=r")
14559         (plus:PTR
14560           (unspec:PTR [(const_int 0)] UNSPEC_TP)
14561           (match_operand:PTR 1 "register_operand" "0")))
14562    (clobber (reg:CC FLAGS_REG))]
14563   ""
14564   "#"
14565   ""
14566   [(parallel
14567      [(set (match_dup 0)
14568            (plus:PTR (match_dup 1) (match_dup 2)))
14569       (clobber (reg:CC FLAGS_REG))])]
14571   addr_space_t as = DEFAULT_TLS_SEG_REG;
14573   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14574   set_mem_addr_space (operands[2], as);
14577 (define_insn_and_split "*add_tp_x32_zext"
14578   [(set (match_operand:DI 0 "register_operand" "=r")
14579         (zero_extend:DI
14580           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14581                    (match_operand:SI 1 "register_operand" "0"))))
14582    (clobber (reg:CC FLAGS_REG))]
14583   "TARGET_X32"
14584   "#"
14585   ""
14586   [(parallel
14587      [(set (match_dup 0)
14588            (zero_extend:DI
14589              (plus:SI (match_dup 1) (match_dup 2))))
14590       (clobber (reg:CC FLAGS_REG))])]
14592   addr_space_t as = DEFAULT_TLS_SEG_REG;
14594   operands[2] = gen_const_mem (SImode, const0_rtx);
14595   set_mem_addr_space (operands[2], as);
14598 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14599 ;; %rax as destination of the initial executable code sequence.
14600 (define_insn "tls_initial_exec_64_sun"
14601   [(set (match_operand:DI 0 "register_operand" "=a")
14602         (unspec:DI
14603          [(match_operand 1 "tls_symbolic_operand")]
14604          UNSPEC_TLS_IE_SUN))
14605    (clobber (reg:CC FLAGS_REG))]
14606   "TARGET_64BIT && TARGET_SUN_TLS"
14608   output_asm_insn
14609     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14610   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14612   [(set_attr "type" "multi")])
14614 ;; GNU2 TLS patterns can be split.
14616 (define_expand "tls_dynamic_gnu2_32"
14617   [(set (match_dup 3)
14618         (plus:SI (match_operand:SI 2 "register_operand")
14619                  (const:SI
14620                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14621                              UNSPEC_TLSDESC))))
14622    (parallel
14623     [(set (match_operand:SI 0 "register_operand")
14624           (unspec:SI [(match_dup 1) (match_dup 3)
14625                       (match_dup 2) (reg:SI SP_REG)]
14626                       UNSPEC_TLSDESC))
14627      (clobber (reg:CC FLAGS_REG))])]
14628   "!TARGET_64BIT && TARGET_GNU2_TLS"
14630   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14631   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14634 (define_insn "*tls_dynamic_gnu2_lea_32"
14635   [(set (match_operand:SI 0 "register_operand" "=r")
14636         (plus:SI (match_operand:SI 1 "register_operand" "b")
14637                  (const:SI
14638                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14639                               UNSPEC_TLSDESC))))]
14640   "!TARGET_64BIT && TARGET_GNU2_TLS"
14641   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14642   [(set_attr "type" "lea")
14643    (set_attr "mode" "SI")
14644    (set_attr "length" "6")
14645    (set_attr "length_address" "4")])
14647 (define_insn "*tls_dynamic_gnu2_call_32"
14648   [(set (match_operand:SI 0 "register_operand" "=a")
14649         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14650                     (match_operand:SI 2 "register_operand" "0")
14651                     ;; we have to make sure %ebx still points to the GOT
14652                     (match_operand:SI 3 "register_operand" "b")
14653                     (reg:SI SP_REG)]
14654                    UNSPEC_TLSDESC))
14655    (clobber (reg:CC FLAGS_REG))]
14656   "!TARGET_64BIT && TARGET_GNU2_TLS"
14657   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14658   [(set_attr "type" "call")
14659    (set_attr "length" "2")
14660    (set_attr "length_address" "0")])
14662 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14663   [(set (match_operand:SI 0 "register_operand" "=&a")
14664         (plus:SI
14665          (unspec:SI [(match_operand 3 "tls_modbase_operand")
14666                      (match_operand:SI 4)
14667                      (match_operand:SI 2 "register_operand" "b")
14668                      (reg:SI SP_REG)]
14669                     UNSPEC_TLSDESC)
14670          (const:SI (unspec:SI
14671                     [(match_operand 1 "tls_symbolic_operand")]
14672                     UNSPEC_DTPOFF))))
14673    (clobber (reg:CC FLAGS_REG))]
14674   "!TARGET_64BIT && TARGET_GNU2_TLS"
14675   "#"
14676   ""
14677   [(set (match_dup 0) (match_dup 5))]
14679   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14680   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14683 (define_expand "tls_dynamic_gnu2_64"
14684   [(set (match_dup 2)
14685         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14686                    UNSPEC_TLSDESC))
14687    (parallel
14688     [(set (match_operand:DI 0 "register_operand")
14689           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14690                      UNSPEC_TLSDESC))
14691      (clobber (reg:CC FLAGS_REG))])]
14692   "TARGET_64BIT && TARGET_GNU2_TLS"
14694   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14695   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14698 (define_insn "*tls_dynamic_gnu2_lea_64"
14699   [(set (match_operand:DI 0 "register_operand" "=r")
14700         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14701                    UNSPEC_TLSDESC))]
14702   "TARGET_64BIT && TARGET_GNU2_TLS"
14703   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14704   [(set_attr "type" "lea")
14705    (set_attr "mode" "DI")
14706    (set_attr "length" "7")
14707    (set_attr "length_address" "4")])
14709 (define_insn "*tls_dynamic_gnu2_call_64"
14710   [(set (match_operand:DI 0 "register_operand" "=a")
14711         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14712                     (match_operand:DI 2 "register_operand" "0")
14713                     (reg:DI SP_REG)]
14714                    UNSPEC_TLSDESC))
14715    (clobber (reg:CC FLAGS_REG))]
14716   "TARGET_64BIT && TARGET_GNU2_TLS"
14717   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14718   [(set_attr "type" "call")
14719    (set_attr "length" "2")
14720    (set_attr "length_address" "0")])
14722 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14723   [(set (match_operand:DI 0 "register_operand" "=&a")
14724         (plus:DI
14725          (unspec:DI [(match_operand 2 "tls_modbase_operand")
14726                      (match_operand:DI 3)
14727                      (reg:DI SP_REG)]
14728                     UNSPEC_TLSDESC)
14729          (const:DI (unspec:DI
14730                     [(match_operand 1 "tls_symbolic_operand")]
14731                     UNSPEC_DTPOFF))))
14732    (clobber (reg:CC FLAGS_REG))]
14733   "TARGET_64BIT && TARGET_GNU2_TLS"
14734   "#"
14735   ""
14736   [(set (match_dup 0) (match_dup 4))]
14738   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14739   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14742 (define_split
14743   [(match_operand 0 "tls_address_pattern")]
14744   "TARGET_TLS_DIRECT_SEG_REFS"
14745   [(match_dup 0)]
14746   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14749 ;; These patterns match the binary 387 instructions for addM3, subM3,
14750 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14751 ;; SFmode.  The first is the normal insn, the second the same insn but
14752 ;; with one operand a conversion, and the third the same insn but with
14753 ;; the other operand a conversion.  The conversion may be SFmode or
14754 ;; SImode if the target mode DFmode, but only SImode if the target mode
14755 ;; is SFmode.
14757 ;; Gcc is slightly more smart about handling normal two address instructions
14758 ;; so use special patterns for add and mull.
14760 (define_insn "*fop_<mode>_comm"
14761   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14762         (match_operator:MODEF 3 "binary_fp_operator"
14763           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14764            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14765   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14766     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14767    && COMMUTATIVE_ARITH_P (operands[3])
14768    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14769   "* return output_387_binary_op (insn, operands);"
14770   [(set (attr "type")
14771         (if_then_else (eq_attr "alternative" "1,2")
14772            (if_then_else (match_operand:MODEF 3 "mult_operator")
14773               (const_string "ssemul")
14774               (const_string "sseadd"))
14775            (if_then_else (match_operand:MODEF 3 "mult_operator")
14776               (const_string "fmul")
14777               (const_string "fop"))))
14778    (set_attr "isa" "*,noavx,avx")
14779    (set_attr "prefix" "orig,orig,vex")
14780    (set_attr "mode" "<MODE>")
14781    (set (attr "enabled")
14782      (if_then_else
14783        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14784        (if_then_else
14785          (eq_attr "alternative" "0")
14786          (symbol_ref "TARGET_MIX_SSE_I387
14787                       && X87_ENABLE_ARITH (<MODE>mode)")
14788          (const_string "*"))
14789        (if_then_else
14790          (eq_attr "alternative" "0")
14791          (symbol_ref "true")
14792          (symbol_ref "false"))))])
14794 (define_insn "*rcpsf2_sse"
14795   [(set (match_operand:SF 0 "register_operand" "=x")
14796         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14797                    UNSPEC_RCP))]
14798   "TARGET_SSE && TARGET_SSE_MATH"
14799   "%vrcpss\t{%1, %d0|%d0, %1}"
14800   [(set_attr "type" "sse")
14801    (set_attr "atom_sse_attr" "rcp")
14802    (set_attr "btver2_sse_attr" "rcp")
14803    (set_attr "prefix" "maybe_vex")
14804    (set_attr "mode" "SF")])
14806 (define_insn "*fop_<mode>_1"
14807   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14808         (match_operator:MODEF 3 "binary_fp_operator"
14809           [(match_operand:MODEF 1
14810              "x87nonimm_ssenomem_operand" "0,fm,0,v")
14811            (match_operand:MODEF 2
14812              "nonimmediate_operand"       "fm,0,xm,vm")]))]
14813   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14814     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14815    && !COMMUTATIVE_ARITH_P (operands[3])
14816    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14817   "* return output_387_binary_op (insn, operands);"
14818   [(set (attr "type")
14819         (if_then_else (eq_attr "alternative" "2,3")
14820            (if_then_else (match_operand:MODEF 3 "div_operator")
14821               (const_string "ssediv")
14822               (const_string "sseadd"))
14823            (if_then_else (match_operand:MODEF 3 "div_operator")
14824               (const_string "fdiv")
14825               (const_string "fop"))))
14826    (set_attr "isa" "*,*,noavx,avx")
14827    (set_attr "prefix" "orig,orig,orig,vex")
14828    (set_attr "mode" "<MODE>")
14829    (set (attr "enabled")
14830      (if_then_else
14831        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14832        (if_then_else
14833          (eq_attr "alternative" "0,1")
14834          (symbol_ref "TARGET_MIX_SSE_I387
14835                       && X87_ENABLE_ARITH (<MODE>mode)")
14836          (const_string "*"))
14837        (if_then_else
14838          (eq_attr "alternative" "0,1")
14839          (symbol_ref "true")
14840          (symbol_ref "false"))))])
14842 ;; ??? Add SSE splitters for these!
14843 (define_insn "*fop_<MODEF:mode>_2_i387"
14844   [(set (match_operand:MODEF 0 "register_operand" "=f")
14845         (match_operator:MODEF 3 "binary_fp_operator"
14846           [(float:MODEF
14847              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14848            (match_operand:MODEF 2 "register_operand" "0")]))]
14849   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14850    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14851    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14852        || optimize_function_for_size_p (cfun))"
14853   "* return output_387_binary_op (insn, operands);"
14854   [(set (attr "type")
14855         (cond [(match_operand:MODEF 3 "mult_operator")
14856                  (const_string "fmul")
14857                (match_operand:MODEF 3 "div_operator")
14858                  (const_string "fdiv")
14859               ]
14860               (const_string "fop")))
14861    (set_attr "fp_int_src" "true")
14862    (set_attr "mode" "<SWI24:MODE>")])
14864 (define_insn "*fop_<MODEF:mode>_3_i387"
14865   [(set (match_operand:MODEF 0 "register_operand" "=f")
14866         (match_operator:MODEF 3 "binary_fp_operator"
14867           [(match_operand:MODEF 1 "register_operand" "0")
14868            (float:MODEF
14869              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14870   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14871    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14872    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14873        || optimize_function_for_size_p (cfun))"
14874   "* return output_387_binary_op (insn, operands);"
14875   [(set (attr "type")
14876         (cond [(match_operand:MODEF 3 "mult_operator")
14877                  (const_string "fmul")
14878                (match_operand:MODEF 3 "div_operator")
14879                  (const_string "fdiv")
14880               ]
14881               (const_string "fop")))
14882    (set_attr "fp_int_src" "true")
14883    (set_attr "mode" "<MODE>")])
14885 (define_insn "*fop_df_4_i387"
14886   [(set (match_operand:DF 0 "register_operand" "=f,f")
14887         (match_operator:DF 3 "binary_fp_operator"
14888            [(float_extend:DF
14889              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14890             (match_operand:DF 2 "register_operand" "0,f")]))]
14891   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14892    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14893   "* return output_387_binary_op (insn, operands);"
14894   [(set (attr "type")
14895         (cond [(match_operand:DF 3 "mult_operator")
14896                  (const_string "fmul")
14897                (match_operand:DF 3 "div_operator")
14898                  (const_string "fdiv")
14899               ]
14900               (const_string "fop")))
14901    (set_attr "mode" "SF")])
14903 (define_insn "*fop_df_5_i387"
14904   [(set (match_operand:DF 0 "register_operand" "=f,f")
14905         (match_operator:DF 3 "binary_fp_operator"
14906           [(match_operand:DF 1 "register_operand" "0,f")
14907            (float_extend:DF
14908             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14909   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14910    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14911   "* return output_387_binary_op (insn, operands);"
14912   [(set (attr "type")
14913         (cond [(match_operand:DF 3 "mult_operator")
14914                  (const_string "fmul")
14915                (match_operand:DF 3 "div_operator")
14916                  (const_string "fdiv")
14917               ]
14918               (const_string "fop")))
14919    (set_attr "mode" "SF")])
14921 (define_insn "*fop_df_6_i387"
14922   [(set (match_operand:DF 0 "register_operand" "=f,f")
14923         (match_operator:DF 3 "binary_fp_operator"
14924           [(float_extend:DF
14925             (match_operand:SF 1 "register_operand" "0,f"))
14926            (float_extend:DF
14927             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14928   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14929    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14930   "* return output_387_binary_op (insn, operands);"
14931   [(set (attr "type")
14932         (cond [(match_operand:DF 3 "mult_operator")
14933                  (const_string "fmul")
14934                (match_operand:DF 3 "div_operator")
14935                  (const_string "fdiv")
14936               ]
14937               (const_string "fop")))
14938    (set_attr "mode" "SF")])
14940 (define_insn "*fop_xf_comm_i387"
14941   [(set (match_operand:XF 0 "register_operand" "=f")
14942         (match_operator:XF 3 "binary_fp_operator"
14943                         [(match_operand:XF 1 "register_operand" "%0")
14944                          (match_operand:XF 2 "register_operand" "f")]))]
14945   "TARGET_80387
14946    && COMMUTATIVE_ARITH_P (operands[3])"
14947   "* return output_387_binary_op (insn, operands);"
14948   [(set (attr "type")
14949         (if_then_else (match_operand:XF 3 "mult_operator")
14950            (const_string "fmul")
14951            (const_string "fop")))
14952    (set_attr "mode" "XF")])
14954 (define_insn "*fop_xf_1_i387"
14955   [(set (match_operand:XF 0 "register_operand" "=f,f")
14956         (match_operator:XF 3 "binary_fp_operator"
14957                         [(match_operand:XF 1 "register_operand" "0,f")
14958                          (match_operand:XF 2 "register_operand" "f,0")]))]
14959   "TARGET_80387
14960    && !COMMUTATIVE_ARITH_P (operands[3])"
14961   "* return output_387_binary_op (insn, operands);"
14962   [(set (attr "type")
14963         (if_then_else (match_operand:XF 3 "div_operator")
14964            (const_string "fdiv")
14965            (const_string "fop")))
14966    (set_attr "mode" "XF")])
14968 (define_insn "*fop_xf_2_i387"
14969   [(set (match_operand:XF 0 "register_operand" "=f")
14970         (match_operator:XF 3 "binary_fp_operator"
14971           [(float:XF
14972              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14973            (match_operand:XF 2 "register_operand" "0")]))]
14974   "TARGET_80387
14975    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14976   "* return output_387_binary_op (insn, operands);"
14977   [(set (attr "type")
14978         (cond [(match_operand:XF 3 "mult_operator")
14979                  (const_string "fmul")
14980                (match_operand:XF 3 "div_operator")
14981                  (const_string "fdiv")
14982               ]
14983               (const_string "fop")))
14984    (set_attr "fp_int_src" "true")
14985    (set_attr "mode" "<MODE>")])
14987 (define_insn "*fop_xf_3_i387"
14988   [(set (match_operand:XF 0 "register_operand" "=f")
14989         (match_operator:XF 3 "binary_fp_operator"
14990           [(match_operand:XF 1 "register_operand" "0")
14991            (float:XF
14992              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14993   "TARGET_80387
14994    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14995   "* return output_387_binary_op (insn, operands);"
14996   [(set (attr "type")
14997         (cond [(match_operand:XF 3 "mult_operator")
14998                  (const_string "fmul")
14999                (match_operand:XF 3 "div_operator")
15000                  (const_string "fdiv")
15001               ]
15002               (const_string "fop")))
15003    (set_attr "fp_int_src" "true")
15004    (set_attr "mode" "<MODE>")])
15006 (define_insn "*fop_xf_4_i387"
15007   [(set (match_operand:XF 0 "register_operand" "=f,f")
15008         (match_operator:XF 3 "binary_fp_operator"
15009            [(float_extend:XF
15010               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15011             (match_operand:XF 2 "register_operand" "0,f")]))]
15012   "TARGET_80387"
15013   "* return output_387_binary_op (insn, operands);"
15014   [(set (attr "type")
15015         (cond [(match_operand:XF 3 "mult_operator")
15016                  (const_string "fmul")
15017                (match_operand:XF 3 "div_operator")
15018                  (const_string "fdiv")
15019               ]
15020               (const_string "fop")))
15021    (set_attr "mode" "<MODE>")])
15023 (define_insn "*fop_xf_5_i387"
15024   [(set (match_operand:XF 0 "register_operand" "=f,f")
15025         (match_operator:XF 3 "binary_fp_operator"
15026           [(match_operand:XF 1 "register_operand" "0,f")
15027            (float_extend:XF
15028              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15029   "TARGET_80387"
15030   "* return output_387_binary_op (insn, operands);"
15031   [(set (attr "type")
15032         (cond [(match_operand:XF 3 "mult_operator")
15033                  (const_string "fmul")
15034                (match_operand:XF 3 "div_operator")
15035                  (const_string "fdiv")
15036               ]
15037               (const_string "fop")))
15038    (set_attr "mode" "<MODE>")])
15040 (define_insn "*fop_xf_6_i387"
15041   [(set (match_operand:XF 0 "register_operand" "=f,f")
15042         (match_operator:XF 3 "binary_fp_operator"
15043           [(float_extend:XF
15044              (match_operand:MODEF 1 "register_operand" "0,f"))
15045            (float_extend:XF
15046              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15047   "TARGET_80387"
15048   "* return output_387_binary_op (insn, operands);"
15049   [(set (attr "type")
15050         (cond [(match_operand:XF 3 "mult_operator")
15051                  (const_string "fmul")
15052                (match_operand:XF 3 "div_operator")
15053                  (const_string "fdiv")
15054               ]
15055               (const_string "fop")))
15056    (set_attr "mode" "<MODE>")])
15058 ;; FPU special functions.
15060 ;; This pattern implements a no-op XFmode truncation for
15061 ;; all fancy i386 XFmode math functions.
15063 (define_insn "truncxf<mode>2_i387_noop_unspec"
15064   [(set (match_operand:MODEF 0 "register_operand" "=f")
15065         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15066         UNSPEC_TRUNC_NOOP))]
15067   "TARGET_USE_FANCY_MATH_387"
15068   "* return output_387_reg_move (insn, operands);"
15069   [(set_attr "type" "fmov")
15070    (set_attr "mode" "<MODE>")])
15072 (define_insn "sqrtxf2"
15073   [(set (match_operand:XF 0 "register_operand" "=f")
15074         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15075   "TARGET_USE_FANCY_MATH_387"
15076   "fsqrt"
15077   [(set_attr "type" "fpspc")
15078    (set_attr "mode" "XF")
15079    (set_attr "athlon_decode" "direct")
15080    (set_attr "amdfam10_decode" "direct")
15081    (set_attr "bdver1_decode" "direct")])
15083 (define_insn "sqrt_extend<mode>xf2_i387"
15084   [(set (match_operand:XF 0 "register_operand" "=f")
15085         (sqrt:XF
15086           (float_extend:XF
15087             (match_operand:MODEF 1 "register_operand" "0"))))]
15088   "TARGET_USE_FANCY_MATH_387"
15089   "fsqrt"
15090   [(set_attr "type" "fpspc")
15091    (set_attr "mode" "XF")
15092    (set_attr "athlon_decode" "direct")
15093    (set_attr "amdfam10_decode" "direct")
15094    (set_attr "bdver1_decode" "direct")])
15096 (define_insn "*rsqrtsf2_sse"
15097   [(set (match_operand:SF 0 "register_operand" "=x")
15098         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15099                    UNSPEC_RSQRT))]
15100   "TARGET_SSE && TARGET_SSE_MATH"
15101   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15102   [(set_attr "type" "sse")
15103    (set_attr "atom_sse_attr" "rcp")
15104    (set_attr "btver2_sse_attr" "rcp")
15105    (set_attr "prefix" "maybe_vex")
15106    (set_attr "mode" "SF")])
15108 (define_expand "rsqrtsf2"
15109   [(set (match_operand:SF 0 "register_operand")
15110         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15111                    UNSPEC_RSQRT))]
15112   "TARGET_SSE && TARGET_SSE_MATH"
15114   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15115   DONE;
15118 (define_insn "*sqrt<mode>2_sse"
15119   [(set (match_operand:MODEF 0 "register_operand" "=v")
15120         (sqrt:MODEF
15121           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15122   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15123   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15124   [(set_attr "type" "sse")
15125    (set_attr "atom_sse_attr" "sqrt")
15126    (set_attr "btver2_sse_attr" "sqrt")
15127    (set_attr "prefix" "maybe_vex")
15128    (set_attr "mode" "<MODE>")
15129    (set_attr "athlon_decode" "*")
15130    (set_attr "amdfam10_decode" "*")
15131    (set_attr "bdver1_decode" "*")])
15133 (define_expand "sqrt<mode>2"
15134   [(set (match_operand:MODEF 0 "register_operand")
15135         (sqrt:MODEF
15136           (match_operand:MODEF 1 "nonimmediate_operand")))]
15137   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15138    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15140   if (<MODE>mode == SFmode
15141       && TARGET_SSE && TARGET_SSE_MATH
15142       && TARGET_RECIP_SQRT
15143       && !optimize_function_for_size_p (cfun)
15144       && flag_finite_math_only && !flag_trapping_math
15145       && flag_unsafe_math_optimizations)
15146     {
15147       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15148       DONE;
15149     }
15151   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15152     {
15153       rtx op0 = gen_reg_rtx (XFmode);
15154       rtx op1 = force_reg (<MODE>mode, operands[1]);
15156       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15157       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15158       DONE;
15159    }
15162 (define_insn "fpremxf4_i387"
15163   [(set (match_operand:XF 0 "register_operand" "=f")
15164         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15165                     (match_operand:XF 3 "register_operand" "1")]
15166                    UNSPEC_FPREM_F))
15167    (set (match_operand:XF 1 "register_operand" "=u")
15168         (unspec:XF [(match_dup 2) (match_dup 3)]
15169                    UNSPEC_FPREM_U))
15170    (set (reg:CCFP FPSR_REG)
15171         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15172                      UNSPEC_C2_FLAG))]
15173   "TARGET_USE_FANCY_MATH_387
15174    && flag_finite_math_only"
15175   "fprem"
15176   [(set_attr "type" "fpspc")
15177    (set_attr "znver1_decode" "vector")
15178    (set_attr "mode" "XF")])
15180 (define_expand "fmodxf3"
15181   [(use (match_operand:XF 0 "register_operand"))
15182    (use (match_operand:XF 1 "general_operand"))
15183    (use (match_operand:XF 2 "general_operand"))]
15184   "TARGET_USE_FANCY_MATH_387
15185    && flag_finite_math_only"
15187   rtx_code_label *label = gen_label_rtx ();
15189   rtx op1 = gen_reg_rtx (XFmode);
15190   rtx op2 = gen_reg_rtx (XFmode);
15192   emit_move_insn (op2, operands[2]);
15193   emit_move_insn (op1, operands[1]);
15195   emit_label (label);
15196   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15197   ix86_emit_fp_unordered_jump (label);
15198   LABEL_NUSES (label) = 1;
15200   emit_move_insn (operands[0], op1);
15201   DONE;
15204 (define_expand "fmod<mode>3"
15205   [(use (match_operand:MODEF 0 "register_operand"))
15206    (use (match_operand:MODEF 1 "general_operand"))
15207    (use (match_operand:MODEF 2 "general_operand"))]
15208   "TARGET_USE_FANCY_MATH_387
15209    && flag_finite_math_only"
15211   rtx (*gen_truncxf) (rtx, rtx);
15213   rtx_code_label *label = gen_label_rtx ();
15215   rtx op1 = gen_reg_rtx (XFmode);
15216   rtx op2 = gen_reg_rtx (XFmode);
15218   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15219   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15221   emit_label (label);
15222   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15223   ix86_emit_fp_unordered_jump (label);
15224   LABEL_NUSES (label) = 1;
15226   /* Truncate the result properly for strict SSE math.  */
15227   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15228       && !TARGET_MIX_SSE_I387)
15229     gen_truncxf = gen_truncxf<mode>2;
15230   else
15231     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15233   emit_insn (gen_truncxf (operands[0], op1));
15234   DONE;
15237 (define_insn "fprem1xf4_i387"
15238   [(set (match_operand:XF 0 "register_operand" "=f")
15239         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15240                     (match_operand:XF 3 "register_operand" "1")]
15241                    UNSPEC_FPREM1_F))
15242    (set (match_operand:XF 1 "register_operand" "=u")
15243         (unspec:XF [(match_dup 2) (match_dup 3)]
15244                    UNSPEC_FPREM1_U))
15245    (set (reg:CCFP FPSR_REG)
15246         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15247                      UNSPEC_C2_FLAG))]
15248   "TARGET_USE_FANCY_MATH_387
15249    && flag_finite_math_only"
15250   "fprem1"
15251   [(set_attr "type" "fpspc")
15252    (set_attr "znver1_decode" "vector")
15253    (set_attr "mode" "XF")])
15255 (define_expand "remainderxf3"
15256   [(use (match_operand:XF 0 "register_operand"))
15257    (use (match_operand:XF 1 "general_operand"))
15258    (use (match_operand:XF 2 "general_operand"))]
15259   "TARGET_USE_FANCY_MATH_387
15260    && flag_finite_math_only"
15262   rtx_code_label *label = gen_label_rtx ();
15264   rtx op1 = gen_reg_rtx (XFmode);
15265   rtx op2 = gen_reg_rtx (XFmode);
15267   emit_move_insn (op2, operands[2]);
15268   emit_move_insn (op1, operands[1]);
15270   emit_label (label);
15271   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15272   ix86_emit_fp_unordered_jump (label);
15273   LABEL_NUSES (label) = 1;
15275   emit_move_insn (operands[0], op1);
15276   DONE;
15279 (define_expand "remainder<mode>3"
15280   [(use (match_operand:MODEF 0 "register_operand"))
15281    (use (match_operand:MODEF 1 "general_operand"))
15282    (use (match_operand:MODEF 2 "general_operand"))]
15283   "TARGET_USE_FANCY_MATH_387
15284    && flag_finite_math_only"
15286   rtx (*gen_truncxf) (rtx, rtx);
15288   rtx_code_label *label = gen_label_rtx ();
15290   rtx op1 = gen_reg_rtx (XFmode);
15291   rtx op2 = gen_reg_rtx (XFmode);
15293   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15294   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15296   emit_label (label);
15298   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15299   ix86_emit_fp_unordered_jump (label);
15300   LABEL_NUSES (label) = 1;
15302   /* Truncate the result properly for strict SSE math.  */
15303   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15304       && !TARGET_MIX_SSE_I387)
15305     gen_truncxf = gen_truncxf<mode>2;
15306   else
15307     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15309   emit_insn (gen_truncxf (operands[0], op1));
15310   DONE;
15313 (define_int_iterator SINCOS
15314         [UNSPEC_SIN
15315          UNSPEC_COS])
15317 (define_int_attr sincos
15318         [(UNSPEC_SIN "sin")
15319          (UNSPEC_COS "cos")])
15321 (define_insn "*<sincos>xf2_i387"
15322   [(set (match_operand:XF 0 "register_operand" "=f")
15323         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15324                    SINCOS))]
15325   "TARGET_USE_FANCY_MATH_387
15326    && flag_unsafe_math_optimizations"
15327   "f<sincos>"
15328   [(set_attr "type" "fpspc")
15329    (set_attr "znver1_decode" "vector")
15330    (set_attr "mode" "XF")])
15332 (define_insn "*<sincos>_extend<mode>xf2_i387"
15333   [(set (match_operand:XF 0 "register_operand" "=f")
15334         (unspec:XF [(float_extend:XF
15335                       (match_operand:MODEF 1 "register_operand" "0"))]
15336                    SINCOS))]
15337   "TARGET_USE_FANCY_MATH_387
15338    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15339        || TARGET_MIX_SSE_I387)
15340    && flag_unsafe_math_optimizations"
15341   "f<sincos>"
15342   [(set_attr "type" "fpspc")
15343    (set_attr "znver1_decode" "vector")
15344    (set_attr "mode" "XF")])
15346 ;; When sincos pattern is defined, sin and cos builtin functions will be
15347 ;; expanded to sincos pattern with one of its outputs left unused.
15348 ;; CSE pass will figure out if two sincos patterns can be combined,
15349 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15350 ;; depending on the unused output.
15352 (define_insn "sincosxf3"
15353   [(set (match_operand:XF 0 "register_operand" "=f")
15354         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15355                    UNSPEC_SINCOS_COS))
15356    (set (match_operand:XF 1 "register_operand" "=u")
15357         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15358   "TARGET_USE_FANCY_MATH_387
15359    && flag_unsafe_math_optimizations"
15360   "fsincos"
15361   [(set_attr "type" "fpspc")
15362    (set_attr "znver1_decode" "vector")
15363    (set_attr "mode" "XF")])
15365 (define_split
15366   [(set (match_operand:XF 0 "register_operand")
15367         (unspec:XF [(match_operand:XF 2 "register_operand")]
15368                    UNSPEC_SINCOS_COS))
15369    (set (match_operand:XF 1 "register_operand")
15370         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15371   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15372    && can_create_pseudo_p ()"
15373   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15375 (define_split
15376   [(set (match_operand:XF 0 "register_operand")
15377         (unspec:XF [(match_operand:XF 2 "register_operand")]
15378                    UNSPEC_SINCOS_COS))
15379    (set (match_operand:XF 1 "register_operand")
15380         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15381   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15382    && can_create_pseudo_p ()"
15383   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15385 (define_insn "sincos_extend<mode>xf3_i387"
15386   [(set (match_operand:XF 0 "register_operand" "=f")
15387         (unspec:XF [(float_extend:XF
15388                       (match_operand:MODEF 2 "register_operand" "0"))]
15389                    UNSPEC_SINCOS_COS))
15390    (set (match_operand:XF 1 "register_operand" "=u")
15391         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15392   "TARGET_USE_FANCY_MATH_387
15393    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15394        || TARGET_MIX_SSE_I387)
15395    && flag_unsafe_math_optimizations"
15396   "fsincos"
15397   [(set_attr "type" "fpspc")
15398    (set_attr "znver1_decode" "vector")
15399    (set_attr "mode" "XF")])
15401 (define_split
15402   [(set (match_operand:XF 0 "register_operand")
15403         (unspec:XF [(float_extend:XF
15404                       (match_operand:MODEF 2 "register_operand"))]
15405                    UNSPEC_SINCOS_COS))
15406    (set (match_operand:XF 1 "register_operand")
15407         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15408   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15409    && can_create_pseudo_p ()"
15410   [(set (match_dup 1)
15411         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15413 (define_split
15414   [(set (match_operand:XF 0 "register_operand")
15415         (unspec:XF [(float_extend:XF
15416                       (match_operand:MODEF 2 "register_operand"))]
15417                    UNSPEC_SINCOS_COS))
15418    (set (match_operand:XF 1 "register_operand")
15419         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15420   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15421    && can_create_pseudo_p ()"
15422   [(set (match_dup 0)
15423         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15425 (define_expand "sincos<mode>3"
15426   [(use (match_operand:MODEF 0 "register_operand"))
15427    (use (match_operand:MODEF 1 "register_operand"))
15428    (use (match_operand:MODEF 2 "register_operand"))]
15429   "TARGET_USE_FANCY_MATH_387
15430    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15431        || TARGET_MIX_SSE_I387)
15432    && flag_unsafe_math_optimizations"
15434   rtx op0 = gen_reg_rtx (XFmode);
15435   rtx op1 = gen_reg_rtx (XFmode);
15437   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15438   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15439   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15440   DONE;
15443 (define_insn "fptanxf4_i387"
15444   [(set (match_operand:XF 0 "register_operand" "=f")
15445         (match_operand:XF 3 "const_double_operand" "F"))
15446    (set (match_operand:XF 1 "register_operand" "=u")
15447         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15448                    UNSPEC_TAN))]
15449   "TARGET_USE_FANCY_MATH_387
15450    && flag_unsafe_math_optimizations
15451    && standard_80387_constant_p (operands[3]) == 2"
15452   "fptan"
15453   [(set_attr "type" "fpspc")
15454    (set_attr "znver1_decode" "vector")
15455    (set_attr "mode" "XF")])
15457 (define_insn "fptan_extend<mode>xf4_i387"
15458   [(set (match_operand:MODEF 0 "register_operand" "=f")
15459         (match_operand:MODEF 3 "const_double_operand" "F"))
15460    (set (match_operand:XF 1 "register_operand" "=u")
15461         (unspec:XF [(float_extend:XF
15462                       (match_operand:MODEF 2 "register_operand" "0"))]
15463                    UNSPEC_TAN))]
15464   "TARGET_USE_FANCY_MATH_387
15465    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15466        || TARGET_MIX_SSE_I387)
15467    && flag_unsafe_math_optimizations
15468    && standard_80387_constant_p (operands[3]) == 2"
15469   "fptan"
15470   [(set_attr "type" "fpspc")
15471    (set_attr "znver1_decode" "vector")
15472    (set_attr "mode" "XF")])
15474 (define_expand "tanxf2"
15475   [(use (match_operand:XF 0 "register_operand"))
15476    (use (match_operand:XF 1 "register_operand"))]
15477   "TARGET_USE_FANCY_MATH_387
15478    && flag_unsafe_math_optimizations"
15480   rtx one = gen_reg_rtx (XFmode);
15481   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15483   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15484   DONE;
15487 (define_expand "tan<mode>2"
15488   [(use (match_operand:MODEF 0 "register_operand"))
15489    (use (match_operand:MODEF 1 "register_operand"))]
15490   "TARGET_USE_FANCY_MATH_387
15491    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15492        || TARGET_MIX_SSE_I387)
15493    && flag_unsafe_math_optimizations"
15495   rtx op0 = gen_reg_rtx (XFmode);
15497   rtx one = gen_reg_rtx (<MODE>mode);
15498   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15500   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15501                                              operands[1], op2));
15502   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15503   DONE;
15506 (define_insn "*fpatanxf3_i387"
15507   [(set (match_operand:XF 0 "register_operand" "=f")
15508         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15509                     (match_operand:XF 2 "register_operand" "u")]
15510                    UNSPEC_FPATAN))
15511    (clobber (match_scratch:XF 3 "=2"))]
15512   "TARGET_USE_FANCY_MATH_387
15513    && flag_unsafe_math_optimizations"
15514   "fpatan"
15515   [(set_attr "type" "fpspc")
15516    (set_attr "znver1_decode" "vector")
15517    (set_attr "mode" "XF")])
15519 (define_insn "fpatan_extend<mode>xf3_i387"
15520   [(set (match_operand:XF 0 "register_operand" "=f")
15521         (unspec:XF [(float_extend:XF
15522                       (match_operand:MODEF 1 "register_operand" "0"))
15523                     (float_extend:XF
15524                       (match_operand:MODEF 2 "register_operand" "u"))]
15525                    UNSPEC_FPATAN))
15526    (clobber (match_scratch:XF 3 "=2"))]
15527   "TARGET_USE_FANCY_MATH_387
15528    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15529        || TARGET_MIX_SSE_I387)
15530    && flag_unsafe_math_optimizations"
15531   "fpatan"
15532   [(set_attr "type" "fpspc")
15533    (set_attr "znver1_decode" "vector")
15534    (set_attr "mode" "XF")])
15536 (define_expand "atan2xf3"
15537   [(parallel [(set (match_operand:XF 0 "register_operand")
15538                    (unspec:XF [(match_operand:XF 2 "register_operand")
15539                                (match_operand:XF 1 "register_operand")]
15540                               UNSPEC_FPATAN))
15541               (clobber (match_scratch:XF 3))])]
15542   "TARGET_USE_FANCY_MATH_387
15543    && flag_unsafe_math_optimizations")
15545 (define_expand "atan2<mode>3"
15546   [(use (match_operand:MODEF 0 "register_operand"))
15547    (use (match_operand:MODEF 1 "register_operand"))
15548    (use (match_operand:MODEF 2 "register_operand"))]
15549   "TARGET_USE_FANCY_MATH_387
15550    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15551        || TARGET_MIX_SSE_I387)
15552    && flag_unsafe_math_optimizations"
15554   rtx op0 = gen_reg_rtx (XFmode);
15556   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15557   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15558   DONE;
15561 (define_expand "atanxf2"
15562   [(parallel [(set (match_operand:XF 0 "register_operand")
15563                    (unspec:XF [(match_dup 2)
15564                                (match_operand:XF 1 "register_operand")]
15565                               UNSPEC_FPATAN))
15566               (clobber (match_scratch:XF 3))])]
15567   "TARGET_USE_FANCY_MATH_387
15568    && flag_unsafe_math_optimizations"
15570   operands[2] = gen_reg_rtx (XFmode);
15571   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15574 (define_expand "atan<mode>2"
15575   [(use (match_operand:MODEF 0 "register_operand"))
15576    (use (match_operand:MODEF 1 "register_operand"))]
15577   "TARGET_USE_FANCY_MATH_387
15578    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15579        || TARGET_MIX_SSE_I387)
15580    && flag_unsafe_math_optimizations"
15582   rtx op0 = gen_reg_rtx (XFmode);
15584   rtx op2 = gen_reg_rtx (<MODE>mode);
15585   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15587   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15588   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15589   DONE;
15592 (define_expand "asinxf2"
15593   [(set (match_dup 2)
15594         (mult:XF (match_operand:XF 1 "register_operand")
15595                  (match_dup 1)))
15596    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15597    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15598    (parallel [(set (match_operand:XF 0 "register_operand")
15599                    (unspec:XF [(match_dup 5) (match_dup 1)]
15600                               UNSPEC_FPATAN))
15601               (clobber (match_scratch:XF 6))])]
15602   "TARGET_USE_FANCY_MATH_387
15603    && flag_unsafe_math_optimizations"
15605   int i;
15607   for (i = 2; i < 6; i++)
15608     operands[i] = gen_reg_rtx (XFmode);
15610   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15613 (define_expand "asin<mode>2"
15614   [(use (match_operand:MODEF 0 "register_operand"))
15615    (use (match_operand:MODEF 1 "general_operand"))]
15616   "TARGET_USE_FANCY_MATH_387
15617    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15618        || TARGET_MIX_SSE_I387)
15619    && flag_unsafe_math_optimizations"
15621   rtx op0 = gen_reg_rtx (XFmode);
15622   rtx op1 = gen_reg_rtx (XFmode);
15624   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15625   emit_insn (gen_asinxf2 (op0, op1));
15626   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15627   DONE;
15630 (define_expand "acosxf2"
15631   [(set (match_dup 2)
15632         (mult:XF (match_operand:XF 1 "register_operand")
15633                  (match_dup 1)))
15634    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15635    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15636    (parallel [(set (match_operand:XF 0 "register_operand")
15637                    (unspec:XF [(match_dup 1) (match_dup 5)]
15638                               UNSPEC_FPATAN))
15639               (clobber (match_scratch:XF 6))])]
15640   "TARGET_USE_FANCY_MATH_387
15641    && flag_unsafe_math_optimizations"
15643   int i;
15645   for (i = 2; i < 6; i++)
15646     operands[i] = gen_reg_rtx (XFmode);
15648   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15651 (define_expand "acos<mode>2"
15652   [(use (match_operand:MODEF 0 "register_operand"))
15653    (use (match_operand:MODEF 1 "general_operand"))]
15654   "TARGET_USE_FANCY_MATH_387
15655    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15656        || TARGET_MIX_SSE_I387)
15657    && flag_unsafe_math_optimizations"
15659   rtx op0 = gen_reg_rtx (XFmode);
15660   rtx op1 = gen_reg_rtx (XFmode);
15662   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15663   emit_insn (gen_acosxf2 (op0, op1));
15664   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15665   DONE;
15668 (define_insn "fyl2xxf3_i387"
15669   [(set (match_operand:XF 0 "register_operand" "=f")
15670         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15671                     (match_operand:XF 2 "register_operand" "u")]
15672                    UNSPEC_FYL2X))
15673    (clobber (match_scratch:XF 3 "=2"))]
15674   "TARGET_USE_FANCY_MATH_387
15675    && flag_unsafe_math_optimizations"
15676   "fyl2x"
15677   [(set_attr "type" "fpspc")
15678    (set_attr "znver1_decode" "vector")
15679    (set_attr "mode" "XF")])
15681 (define_insn "fyl2x_extend<mode>xf3_i387"
15682   [(set (match_operand:XF 0 "register_operand" "=f")
15683         (unspec:XF [(float_extend:XF
15684                       (match_operand:MODEF 1 "register_operand" "0"))
15685                     (match_operand:XF 2 "register_operand" "u")]
15686                    UNSPEC_FYL2X))
15687    (clobber (match_scratch:XF 3 "=2"))]
15688   "TARGET_USE_FANCY_MATH_387
15689    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15690        || TARGET_MIX_SSE_I387)
15691    && flag_unsafe_math_optimizations"
15692   "fyl2x"
15693   [(set_attr "type" "fpspc")
15694    (set_attr "znver1_decode" "vector")
15695    (set_attr "mode" "XF")])
15697 (define_expand "logxf2"
15698   [(parallel [(set (match_operand:XF 0 "register_operand")
15699                    (unspec:XF [(match_operand:XF 1 "register_operand")
15700                                (match_dup 2)] UNSPEC_FYL2X))
15701               (clobber (match_scratch:XF 3))])]
15702   "TARGET_USE_FANCY_MATH_387
15703    && flag_unsafe_math_optimizations"
15705   operands[2] = gen_reg_rtx (XFmode);
15706   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15709 (define_expand "log<mode>2"
15710   [(use (match_operand:MODEF 0 "register_operand"))
15711    (use (match_operand:MODEF 1 "register_operand"))]
15712   "TARGET_USE_FANCY_MATH_387
15713    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15714        || TARGET_MIX_SSE_I387)
15715    && flag_unsafe_math_optimizations"
15717   rtx op0 = gen_reg_rtx (XFmode);
15719   rtx op2 = gen_reg_rtx (XFmode);
15720   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15722   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15723   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15724   DONE;
15727 (define_expand "log10xf2"
15728   [(parallel [(set (match_operand:XF 0 "register_operand")
15729                    (unspec:XF [(match_operand:XF 1 "register_operand")
15730                                (match_dup 2)] UNSPEC_FYL2X))
15731               (clobber (match_scratch:XF 3))])]
15732   "TARGET_USE_FANCY_MATH_387
15733    && flag_unsafe_math_optimizations"
15735   operands[2] = gen_reg_rtx (XFmode);
15736   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15739 (define_expand "log10<mode>2"
15740   [(use (match_operand:MODEF 0 "register_operand"))
15741    (use (match_operand:MODEF 1 "register_operand"))]
15742   "TARGET_USE_FANCY_MATH_387
15743    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15744        || TARGET_MIX_SSE_I387)
15745    && flag_unsafe_math_optimizations"
15747   rtx op0 = gen_reg_rtx (XFmode);
15749   rtx op2 = gen_reg_rtx (XFmode);
15750   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15752   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15753   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15754   DONE;
15757 (define_expand "log2xf2"
15758   [(parallel [(set (match_operand:XF 0 "register_operand")
15759                    (unspec:XF [(match_operand:XF 1 "register_operand")
15760                                (match_dup 2)] UNSPEC_FYL2X))
15761               (clobber (match_scratch:XF 3))])]
15762   "TARGET_USE_FANCY_MATH_387
15763    && flag_unsafe_math_optimizations"
15765   operands[2] = gen_reg_rtx (XFmode);
15766   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15769 (define_expand "log2<mode>2"
15770   [(use (match_operand:MODEF 0 "register_operand"))
15771    (use (match_operand:MODEF 1 "register_operand"))]
15772   "TARGET_USE_FANCY_MATH_387
15773    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15774        || TARGET_MIX_SSE_I387)
15775    && flag_unsafe_math_optimizations"
15777   rtx op0 = gen_reg_rtx (XFmode);
15779   rtx op2 = gen_reg_rtx (XFmode);
15780   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15782   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15783   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15784   DONE;
15787 (define_insn "fyl2xp1xf3_i387"
15788   [(set (match_operand:XF 0 "register_operand" "=f")
15789         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15790                     (match_operand:XF 2 "register_operand" "u")]
15791                    UNSPEC_FYL2XP1))
15792    (clobber (match_scratch:XF 3 "=2"))]
15793   "TARGET_USE_FANCY_MATH_387
15794    && flag_unsafe_math_optimizations"
15795   "fyl2xp1"
15796   [(set_attr "type" "fpspc")
15797    (set_attr "znver1_decode" "vector")
15798    (set_attr "mode" "XF")])
15800 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15801   [(set (match_operand:XF 0 "register_operand" "=f")
15802         (unspec:XF [(float_extend:XF
15803                       (match_operand:MODEF 1 "register_operand" "0"))
15804                     (match_operand:XF 2 "register_operand" "u")]
15805                    UNSPEC_FYL2XP1))
15806    (clobber (match_scratch:XF 3 "=2"))]
15807   "TARGET_USE_FANCY_MATH_387
15808    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15809        || TARGET_MIX_SSE_I387)
15810    && flag_unsafe_math_optimizations"
15811   "fyl2xp1"
15812   [(set_attr "type" "fpspc")
15813    (set_attr "znver1_decode" "vector")
15814    (set_attr "mode" "XF")])
15816 (define_expand "log1pxf2"
15817   [(use (match_operand:XF 0 "register_operand"))
15818    (use (match_operand:XF 1 "register_operand"))]
15819   "TARGET_USE_FANCY_MATH_387
15820    && flag_unsafe_math_optimizations"
15822   ix86_emit_i387_log1p (operands[0], operands[1]);
15823   DONE;
15826 (define_expand "log1p<mode>2"
15827   [(use (match_operand:MODEF 0 "register_operand"))
15828    (use (match_operand:MODEF 1 "register_operand"))]
15829   "TARGET_USE_FANCY_MATH_387
15830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15831        || TARGET_MIX_SSE_I387)
15832    && flag_unsafe_math_optimizations"
15834   rtx op0;
15836   op0 = gen_reg_rtx (XFmode);
15838   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15840   ix86_emit_i387_log1p (op0, operands[1]);
15841   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15842   DONE;
15845 (define_insn "fxtractxf3_i387"
15846   [(set (match_operand:XF 0 "register_operand" "=f")
15847         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15848                    UNSPEC_XTRACT_FRACT))
15849    (set (match_operand:XF 1 "register_operand" "=u")
15850         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15851   "TARGET_USE_FANCY_MATH_387
15852    && flag_unsafe_math_optimizations"
15853   "fxtract"
15854   [(set_attr "type" "fpspc")
15855    (set_attr "znver1_decode" "vector")
15856    (set_attr "mode" "XF")])
15858 (define_insn "fxtract_extend<mode>xf3_i387"
15859   [(set (match_operand:XF 0 "register_operand" "=f")
15860         (unspec:XF [(float_extend:XF
15861                       (match_operand:MODEF 2 "register_operand" "0"))]
15862                    UNSPEC_XTRACT_FRACT))
15863    (set (match_operand:XF 1 "register_operand" "=u")
15864         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15865   "TARGET_USE_FANCY_MATH_387
15866    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15867        || TARGET_MIX_SSE_I387)
15868    && flag_unsafe_math_optimizations"
15869   "fxtract"
15870   [(set_attr "type" "fpspc")
15871    (set_attr "znver1_decode" "vector")
15872    (set_attr "mode" "XF")])
15874 (define_expand "logbxf2"
15875   [(parallel [(set (match_dup 2)
15876                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15877                               UNSPEC_XTRACT_FRACT))
15878               (set (match_operand:XF 0 "register_operand")
15879                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15880   "TARGET_USE_FANCY_MATH_387
15881    && flag_unsafe_math_optimizations"
15882   "operands[2] = gen_reg_rtx (XFmode);")
15884 (define_expand "logb<mode>2"
15885   [(use (match_operand:MODEF 0 "register_operand"))
15886    (use (match_operand:MODEF 1 "register_operand"))]
15887   "TARGET_USE_FANCY_MATH_387
15888    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15889        || TARGET_MIX_SSE_I387)
15890    && flag_unsafe_math_optimizations"
15892   rtx op0 = gen_reg_rtx (XFmode);
15893   rtx op1 = gen_reg_rtx (XFmode);
15895   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15896   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15897   DONE;
15900 (define_expand "ilogbxf2"
15901   [(use (match_operand:SI 0 "register_operand"))
15902    (use (match_operand:XF 1 "register_operand"))]
15903   "TARGET_USE_FANCY_MATH_387
15904    && flag_unsafe_math_optimizations"
15906   rtx op0, op1;
15908   if (optimize_insn_for_size_p ())
15909     FAIL;
15911   op0 = gen_reg_rtx (XFmode);
15912   op1 = gen_reg_rtx (XFmode);
15914   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15915   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15916   DONE;
15919 (define_expand "ilogb<mode>2"
15920   [(use (match_operand:SI 0 "register_operand"))
15921    (use (match_operand:MODEF 1 "register_operand"))]
15922   "TARGET_USE_FANCY_MATH_387
15923    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15924        || TARGET_MIX_SSE_I387)
15925    && flag_unsafe_math_optimizations"
15927   rtx op0, op1;
15929   if (optimize_insn_for_size_p ())
15930     FAIL;
15932   op0 = gen_reg_rtx (XFmode);
15933   op1 = gen_reg_rtx (XFmode);
15935   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15936   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15937   DONE;
15940 (define_insn "*f2xm1xf2_i387"
15941   [(set (match_operand:XF 0 "register_operand" "=f")
15942         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15943                    UNSPEC_F2XM1))]
15944   "TARGET_USE_FANCY_MATH_387
15945    && flag_unsafe_math_optimizations"
15946   "f2xm1"
15947   [(set_attr "type" "fpspc")
15948    (set_attr "znver1_decode" "vector")
15949    (set_attr "mode" "XF")])
15951 (define_insn "fscalexf4_i387"
15952   [(set (match_operand:XF 0 "register_operand" "=f")
15953         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15954                     (match_operand:XF 3 "register_operand" "1")]
15955                    UNSPEC_FSCALE_FRACT))
15956    (set (match_operand:XF 1 "register_operand" "=u")
15957         (unspec:XF [(match_dup 2) (match_dup 3)]
15958                    UNSPEC_FSCALE_EXP))]
15959   "TARGET_USE_FANCY_MATH_387
15960    && flag_unsafe_math_optimizations"
15961   "fscale"
15962   [(set_attr "type" "fpspc")
15963    (set_attr "znver1_decode" "vector")
15964    (set_attr "mode" "XF")])
15966 (define_expand "expNcorexf3"
15967   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15968                                (match_operand:XF 2 "register_operand")))
15969    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15970    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15971    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15972    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15973    (parallel [(set (match_operand:XF 0 "register_operand")
15974                    (unspec:XF [(match_dup 8) (match_dup 4)]
15975                               UNSPEC_FSCALE_FRACT))
15976               (set (match_dup 9)
15977                    (unspec:XF [(match_dup 8) (match_dup 4)]
15978                               UNSPEC_FSCALE_EXP))])]
15979   "TARGET_USE_FANCY_MATH_387
15980    && flag_unsafe_math_optimizations"
15982   int i;
15984   for (i = 3; i < 10; i++)
15985     operands[i] = gen_reg_rtx (XFmode);
15987   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15990 (define_expand "expxf2"
15991   [(use (match_operand:XF 0 "register_operand"))
15992    (use (match_operand:XF 1 "register_operand"))]
15993   "TARGET_USE_FANCY_MATH_387
15994    && flag_unsafe_math_optimizations"
15996   rtx op2;
15998   op2 = gen_reg_rtx (XFmode);
15999   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16001   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16002   DONE;
16005 (define_expand "exp<mode>2"
16006   [(use (match_operand:MODEF 0 "register_operand"))
16007    (use (match_operand:MODEF 1 "general_operand"))]
16008   "TARGET_USE_FANCY_MATH_387
16009    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16010        || TARGET_MIX_SSE_I387)
16011    && flag_unsafe_math_optimizations"
16013   rtx op0, op1;
16015   op0 = gen_reg_rtx (XFmode);
16016   op1 = gen_reg_rtx (XFmode);
16018   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16019   emit_insn (gen_expxf2 (op0, op1));
16020   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16021   DONE;
16024 (define_expand "exp10xf2"
16025   [(use (match_operand:XF 0 "register_operand"))
16026    (use (match_operand:XF 1 "register_operand"))]
16027   "TARGET_USE_FANCY_MATH_387
16028    && flag_unsafe_math_optimizations"
16030   rtx op2;
16032   op2 = gen_reg_rtx (XFmode);
16033   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16035   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16036   DONE;
16039 (define_expand "exp10<mode>2"
16040   [(use (match_operand:MODEF 0 "register_operand"))
16041    (use (match_operand:MODEF 1 "general_operand"))]
16042   "TARGET_USE_FANCY_MATH_387
16043    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16044        || TARGET_MIX_SSE_I387)
16045    && flag_unsafe_math_optimizations"
16047   rtx op0, op1;
16049   op0 = gen_reg_rtx (XFmode);
16050   op1 = gen_reg_rtx (XFmode);
16052   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16053   emit_insn (gen_exp10xf2 (op0, op1));
16054   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16055   DONE;
16058 (define_expand "exp2xf2"
16059   [(use (match_operand:XF 0 "register_operand"))
16060    (use (match_operand:XF 1 "register_operand"))]
16061   "TARGET_USE_FANCY_MATH_387
16062    && flag_unsafe_math_optimizations"
16064   rtx op2;
16066   op2 = gen_reg_rtx (XFmode);
16067   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16069   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16070   DONE;
16073 (define_expand "exp2<mode>2"
16074   [(use (match_operand:MODEF 0 "register_operand"))
16075    (use (match_operand:MODEF 1 "general_operand"))]
16076   "TARGET_USE_FANCY_MATH_387
16077    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16078        || TARGET_MIX_SSE_I387)
16079    && flag_unsafe_math_optimizations"
16081   rtx op0, op1;
16083   op0 = gen_reg_rtx (XFmode);
16084   op1 = gen_reg_rtx (XFmode);
16086   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16087   emit_insn (gen_exp2xf2 (op0, op1));
16088   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16089   DONE;
16092 (define_expand "expm1xf2"
16093   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16094                                (match_dup 2)))
16095    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16096    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16097    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16098    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16099    (parallel [(set (match_dup 7)
16100                    (unspec:XF [(match_dup 6) (match_dup 4)]
16101                               UNSPEC_FSCALE_FRACT))
16102               (set (match_dup 8)
16103                    (unspec:XF [(match_dup 6) (match_dup 4)]
16104                               UNSPEC_FSCALE_EXP))])
16105    (parallel [(set (match_dup 10)
16106                    (unspec:XF [(match_dup 9) (match_dup 8)]
16107                               UNSPEC_FSCALE_FRACT))
16108               (set (match_dup 11)
16109                    (unspec:XF [(match_dup 9) (match_dup 8)]
16110                               UNSPEC_FSCALE_EXP))])
16111    (set (match_dup 12) (minus:XF (match_dup 10)
16112                                  (float_extend:XF (match_dup 13))))
16113    (set (match_operand:XF 0 "register_operand")
16114         (plus:XF (match_dup 12) (match_dup 7)))]
16115   "TARGET_USE_FANCY_MATH_387
16116    && flag_unsafe_math_optimizations"
16118   int i;
16120   for (i = 2; i < 13; i++)
16121     operands[i] = gen_reg_rtx (XFmode);
16123   operands[13]
16124     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16126   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16129 (define_expand "expm1<mode>2"
16130   [(use (match_operand:MODEF 0 "register_operand"))
16131    (use (match_operand:MODEF 1 "general_operand"))]
16132   "TARGET_USE_FANCY_MATH_387
16133    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16134        || TARGET_MIX_SSE_I387)
16135    && flag_unsafe_math_optimizations"
16137   rtx op0, op1;
16139   op0 = gen_reg_rtx (XFmode);
16140   op1 = gen_reg_rtx (XFmode);
16142   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16143   emit_insn (gen_expm1xf2 (op0, op1));
16144   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16145   DONE;
16148 (define_expand "ldexpxf3"
16149   [(match_operand:XF 0 "register_operand")
16150    (match_operand:XF 1 "register_operand")
16151    (match_operand:SI 2 "register_operand")]
16152   "TARGET_USE_FANCY_MATH_387
16153    && flag_unsafe_math_optimizations"
16155   rtx tmp1, tmp2;
16157   tmp1 = gen_reg_rtx (XFmode);
16158   tmp2 = gen_reg_rtx (XFmode);
16160   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16161   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16162                                  operands[1], tmp1));
16163   DONE;
16166 (define_expand "ldexp<mode>3"
16167   [(use (match_operand:MODEF 0 "register_operand"))
16168    (use (match_operand:MODEF 1 "general_operand"))
16169    (use (match_operand:SI 2 "register_operand"))]
16170   "TARGET_USE_FANCY_MATH_387
16171    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16172        || TARGET_MIX_SSE_I387)
16173    && flag_unsafe_math_optimizations"
16175   rtx op0, op1;
16177   op0 = gen_reg_rtx (XFmode);
16178   op1 = gen_reg_rtx (XFmode);
16180   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16181   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16182   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16183   DONE;
16186 (define_expand "scalbxf3"
16187   [(parallel [(set (match_operand:XF 0 " register_operand")
16188                    (unspec:XF [(match_operand:XF 1 "register_operand")
16189                                (match_operand:XF 2 "register_operand")]
16190                               UNSPEC_FSCALE_FRACT))
16191               (set (match_dup 3)
16192                    (unspec:XF [(match_dup 1) (match_dup 2)]
16193                               UNSPEC_FSCALE_EXP))])]
16194   "TARGET_USE_FANCY_MATH_387
16195    && flag_unsafe_math_optimizations"
16197   operands[3] = gen_reg_rtx (XFmode);
16200 (define_expand "scalb<mode>3"
16201   [(use (match_operand:MODEF 0 "register_operand"))
16202    (use (match_operand:MODEF 1 "general_operand"))
16203    (use (match_operand:MODEF 2 "general_operand"))]
16204   "TARGET_USE_FANCY_MATH_387
16205    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16206        || TARGET_MIX_SSE_I387)
16207    && flag_unsafe_math_optimizations"
16209   rtx op0, op1, op2;
16211   op0 = gen_reg_rtx (XFmode);
16212   op1 = gen_reg_rtx (XFmode);
16213   op2 = gen_reg_rtx (XFmode);
16215   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16216   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16217   emit_insn (gen_scalbxf3 (op0, op1, op2));
16218   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16219   DONE;
16222 (define_expand "significandxf2"
16223   [(parallel [(set (match_operand:XF 0 "register_operand")
16224                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16225                               UNSPEC_XTRACT_FRACT))
16226               (set (match_dup 2)
16227                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16228   "TARGET_USE_FANCY_MATH_387
16229    && flag_unsafe_math_optimizations"
16230   "operands[2] = gen_reg_rtx (XFmode);")
16232 (define_expand "significand<mode>2"
16233   [(use (match_operand:MODEF 0 "register_operand"))
16234    (use (match_operand:MODEF 1 "register_operand"))]
16235   "TARGET_USE_FANCY_MATH_387
16236    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16237        || TARGET_MIX_SSE_I387)
16238    && flag_unsafe_math_optimizations"
16240   rtx op0 = gen_reg_rtx (XFmode);
16241   rtx op1 = gen_reg_rtx (XFmode);
16243   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16244   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16245   DONE;
16249 (define_insn "sse4_1_round<mode>2"
16250   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16251         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
16252                        (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16253                       UNSPEC_ROUND))]
16254   "TARGET_SSE4_1"
16255   "@
16256    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16257    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16258   [(set_attr "type" "ssecvt")
16259    (set_attr "prefix_extra" "1,*")
16260    (set_attr "length_immediate" "*,1")
16261    (set_attr "prefix" "maybe_vex,evex")
16262    (set_attr "isa" "noavx512f,avx512f")
16263    (set_attr "mode" "<MODE>")])
16265 (define_insn "rintxf2"
16266   [(set (match_operand:XF 0 "register_operand" "=f")
16267         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16268                    UNSPEC_FRNDINT))]
16269   "TARGET_USE_FANCY_MATH_387"
16270   "frndint"
16271   [(set_attr "type" "fpspc")
16272    (set_attr "znver1_decode" "vector")
16273    (set_attr "mode" "XF")])
16275 (define_insn "rint<mode>2_frndint"
16276   [(set (match_operand:MODEF 0 "register_operand" "=f")
16277         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16278                       UNSPEC_FRNDINT))]
16279   "TARGET_USE_FANCY_MATH_387"
16280   "frndint"
16281   [(set_attr "type" "fpspc")
16282    (set_attr "znver1_decode" "vector")
16283    (set_attr "mode" "<MODE>")])
16285 (define_expand "rint<mode>2"
16286   [(use (match_operand:MODEF 0 "register_operand"))
16287    (use (match_operand:MODEF 1 "register_operand"))]
16288   "(TARGET_USE_FANCY_MATH_387
16289     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16290         || TARGET_MIX_SSE_I387))
16291    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16293   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16294     {
16295       if (TARGET_SSE4_1)
16296         emit_insn (gen_sse4_1_round<mode>2
16297                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16298       else
16299         ix86_expand_rint (operands[0], operands[1]);
16300     }
16301   else
16302     emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16303   DONE;
16306 (define_expand "round<mode>2"
16307   [(match_operand:X87MODEF 0 "register_operand")
16308    (match_operand:X87MODEF 1 "nonimmediate_operand")]
16309   "(TARGET_USE_FANCY_MATH_387
16310     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16311         || TARGET_MIX_SSE_I387)
16312     && flag_unsafe_math_optimizations)
16313    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16314        && !flag_trapping_math && !flag_rounding_math)"
16316   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16317       && !flag_trapping_math && !flag_rounding_math)
16318     {
16319       if (TARGET_SSE4_1)
16320         {
16321           operands[1] = force_reg (<MODE>mode, operands[1]);
16322           ix86_expand_round_sse4 (operands[0], operands[1]);
16323         }
16324       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16325         ix86_expand_round (operands[0], operands[1]);
16326       else
16327         ix86_expand_rounddf_32 (operands[0], operands[1]);
16328     }
16329   else
16330     {
16331       operands[1] = force_reg (<MODE>mode, operands[1]);
16332       ix86_emit_i387_round (operands[0], operands[1]);
16333     }
16334   DONE;
16337 (define_insn_and_split "*fistdi2_1"
16338   [(set (match_operand:DI 0 "nonimmediate_operand")
16339         (unspec:DI [(match_operand:XF 1 "register_operand")]
16340                    UNSPEC_FIST))]
16341   "TARGET_USE_FANCY_MATH_387
16342    && can_create_pseudo_p ()"
16343   "#"
16344   "&& 1"
16345   [(const_int 0)]
16347   if (memory_operand (operands[0], VOIDmode))
16348     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16349   else
16350     {
16351       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16352       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16353                                          operands[2]));
16354     }
16355   DONE;
16357   [(set_attr "type" "fpspc")
16358    (set_attr "mode" "DI")])
16360 (define_insn "fistdi2"
16361   [(set (match_operand:DI 0 "memory_operand" "=m")
16362         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16363                    UNSPEC_FIST))
16364    (clobber (match_scratch:XF 2 "=&1f"))]
16365   "TARGET_USE_FANCY_MATH_387"
16366   "* return output_fix_trunc (insn, operands, false);"
16367   [(set_attr "type" "fpspc")
16368    (set_attr "mode" "DI")])
16370 (define_insn "fistdi2_with_temp"
16371   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16372         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16373                    UNSPEC_FIST))
16374    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16375    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16376   "TARGET_USE_FANCY_MATH_387"
16377   "#"
16378   [(set_attr "type" "fpspc")
16379    (set_attr "mode" "DI")])
16381 (define_split
16382   [(set (match_operand:DI 0 "register_operand")
16383         (unspec:DI [(match_operand:XF 1 "register_operand")]
16384                    UNSPEC_FIST))
16385    (clobber (match_operand:DI 2 "memory_operand"))
16386    (clobber (match_scratch 3))]
16387   "reload_completed"
16388   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16389               (clobber (match_dup 3))])
16390    (set (match_dup 0) (match_dup 2))])
16392 (define_split
16393   [(set (match_operand:DI 0 "memory_operand")
16394         (unspec:DI [(match_operand:XF 1 "register_operand")]
16395                    UNSPEC_FIST))
16396    (clobber (match_operand:DI 2 "memory_operand"))
16397    (clobber (match_scratch 3))]
16398   "reload_completed"
16399   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16400               (clobber (match_dup 3))])])
16402 (define_insn_and_split "*fist<mode>2_1"
16403   [(set (match_operand:SWI24 0 "register_operand")
16404         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16405                       UNSPEC_FIST))]
16406   "TARGET_USE_FANCY_MATH_387
16407    && can_create_pseudo_p ()"
16408   "#"
16409   "&& 1"
16410   [(const_int 0)]
16412   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16413   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16414                                         operands[2]));
16415   DONE;
16417   [(set_attr "type" "fpspc")
16418    (set_attr "mode" "<MODE>")])
16420 (define_insn "fist<mode>2"
16421   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16422         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16423                       UNSPEC_FIST))]
16424   "TARGET_USE_FANCY_MATH_387"
16425   "* return output_fix_trunc (insn, operands, false);"
16426   [(set_attr "type" "fpspc")
16427    (set_attr "mode" "<MODE>")])
16429 (define_insn "fist<mode>2_with_temp"
16430   [(set (match_operand:SWI24 0 "register_operand" "=r")
16431         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16432                       UNSPEC_FIST))
16433    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16434   "TARGET_USE_FANCY_MATH_387"
16435   "#"
16436   [(set_attr "type" "fpspc")
16437    (set_attr "mode" "<MODE>")])
16439 (define_split
16440   [(set (match_operand:SWI24 0 "register_operand")
16441         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16442                       UNSPEC_FIST))
16443    (clobber (match_operand:SWI24 2 "memory_operand"))]
16444   "reload_completed"
16445   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16446    (set (match_dup 0) (match_dup 2))])
16448 (define_split
16449   [(set (match_operand:SWI24 0 "memory_operand")
16450         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16451                       UNSPEC_FIST))
16452    (clobber (match_operand:SWI24 2 "memory_operand"))]
16453   "reload_completed"
16454   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16456 (define_expand "lrintxf<mode>2"
16457   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16458      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16459                      UNSPEC_FIST))]
16460   "TARGET_USE_FANCY_MATH_387")
16462 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16463   [(set (match_operand:SWI48 0 "nonimmediate_operand")
16464      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16465                    UNSPEC_FIX_NOTRUNC))]
16466   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16468 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16469   [(match_operand:SWI248x 0 "nonimmediate_operand")
16470    (match_operand:X87MODEF 1 "register_operand")]
16471   "(TARGET_USE_FANCY_MATH_387
16472     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16473         || TARGET_MIX_SSE_I387)
16474     && flag_unsafe_math_optimizations)
16475    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16476        && <SWI248x:MODE>mode != HImode 
16477        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16478        && !flag_trapping_math && !flag_rounding_math)"
16480   if (optimize_insn_for_size_p ())
16481     FAIL;
16483   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16484       && <SWI248x:MODE>mode != HImode
16485       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16486       && !flag_trapping_math && !flag_rounding_math)
16487     ix86_expand_lround (operands[0], operands[1]);
16488   else
16489     ix86_emit_i387_round (operands[0], operands[1]);
16490   DONE;
16493 (define_int_iterator FRNDINT_ROUNDING
16494         [UNSPEC_FRNDINT_FLOOR
16495          UNSPEC_FRNDINT_CEIL
16496          UNSPEC_FRNDINT_TRUNC])
16498 (define_int_iterator FIST_ROUNDING
16499         [UNSPEC_FIST_FLOOR
16500          UNSPEC_FIST_CEIL])
16502 ;; Base name for define_insn
16503 (define_int_attr rounding_insn
16504         [(UNSPEC_FRNDINT_FLOOR "floor")
16505          (UNSPEC_FRNDINT_CEIL "ceil")
16506          (UNSPEC_FRNDINT_TRUNC "btrunc")
16507          (UNSPEC_FIST_FLOOR "floor")
16508          (UNSPEC_FIST_CEIL "ceil")])
16510 (define_int_attr rounding
16511         [(UNSPEC_FRNDINT_FLOOR "floor")
16512          (UNSPEC_FRNDINT_CEIL "ceil")
16513          (UNSPEC_FRNDINT_TRUNC "trunc")
16514          (UNSPEC_FIST_FLOOR "floor")
16515          (UNSPEC_FIST_CEIL "ceil")])
16517 (define_int_attr ROUNDING
16518         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16519          (UNSPEC_FRNDINT_CEIL "CEIL")
16520          (UNSPEC_FRNDINT_TRUNC "TRUNC")
16521          (UNSPEC_FIST_FLOOR "FLOOR")
16522          (UNSPEC_FIST_CEIL "CEIL")])
16524 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16525 (define_insn_and_split "frndint<mode>2_<rounding>"
16526   [(set (match_operand:X87MODEF 0 "register_operand")
16527         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16528                    FRNDINT_ROUNDING))
16529    (clobber (reg:CC FLAGS_REG))]
16530   "TARGET_USE_FANCY_MATH_387
16531    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16532    && can_create_pseudo_p ()"
16533   "#"
16534   "&& 1"
16535   [(const_int 0)]
16537   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16539   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16540   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16542   emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16543                                                  operands[2], operands[3]));
16544   DONE;
16546   [(set_attr "type" "frndint")
16547    (set_attr "i387_cw" "<rounding>")
16548    (set_attr "mode" "<MODE>")])
16550 (define_insn "frndint<mode>2_<rounding>_i387"
16551   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16552         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16553                          FRNDINT_ROUNDING))
16554    (use (match_operand:HI 2 "memory_operand" "m"))
16555    (use (match_operand:HI 3 "memory_operand" "m"))]
16556   "TARGET_USE_FANCY_MATH_387
16557    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16558   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16559   [(set_attr "type" "frndint")
16560    (set_attr "i387_cw" "<rounding>")
16561    (set_attr "mode" "<MODE>")])
16563 (define_expand "<rounding_insn>xf2"
16564   [(parallel [(set (match_operand:XF 0 "register_operand")
16565                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16566                               FRNDINT_ROUNDING))
16567               (clobber (reg:CC FLAGS_REG))])]
16568   "TARGET_USE_FANCY_MATH_387
16569    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16571 (define_expand "<rounding_insn><mode>2"
16572   [(parallel [(set (match_operand:MODEF 0 "register_operand")
16573                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16574                                  FRNDINT_ROUNDING))
16575               (clobber (reg:CC FLAGS_REG))])]
16576   "(TARGET_USE_FANCY_MATH_387
16577     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16578         || TARGET_MIX_SSE_I387)
16579     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16580    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16581        && (TARGET_SSE4_1 || !flag_trapping_math
16582            || flag_fp_int_builtin_inexact))"
16584   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16585       && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16586     {
16587       if (TARGET_SSE4_1)
16588         emit_insn (gen_sse4_1_round<mode>2
16589                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16590                                                        | ROUND_NO_EXC)));
16591       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16592         {
16593           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16594             ix86_expand_floorceil (operands[0], operands[1], true);
16595           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16596             ix86_expand_floorceil (operands[0], operands[1], false);
16597           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16598             ix86_expand_trunc (operands[0], operands[1]);
16599           else
16600             gcc_unreachable ();
16601         }
16602       else
16603         {
16604           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16605             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16606           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16607             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16608           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16609             ix86_expand_truncdf_32 (operands[0], operands[1]);
16610           else
16611             gcc_unreachable ();
16612         }
16613     }
16614   else
16615     emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16616   DONE;
16619 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16620 (define_insn_and_split "frndintxf2_mask_pm"
16621   [(set (match_operand:XF 0 "register_operand")
16622         (unspec:XF [(match_operand:XF 1 "register_operand")]
16623                    UNSPEC_FRNDINT_MASK_PM))
16624    (clobber (reg:CC FLAGS_REG))]
16625   "TARGET_USE_FANCY_MATH_387
16626    && flag_unsafe_math_optimizations
16627    && can_create_pseudo_p ()"
16628   "#"
16629   "&& 1"
16630   [(const_int 0)]
16632   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16634   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16635   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16637   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16638                                           operands[2], operands[3]));
16639   DONE;
16641   [(set_attr "type" "frndint")
16642    (set_attr "i387_cw" "mask_pm")
16643    (set_attr "mode" "XF")])
16645 (define_insn "frndintxf2_mask_pm_i387"
16646   [(set (match_operand:XF 0 "register_operand" "=f")
16647         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16648                    UNSPEC_FRNDINT_MASK_PM))
16649    (use (match_operand:HI 2 "memory_operand" "m"))
16650    (use (match_operand:HI 3 "memory_operand" "m"))]
16651   "TARGET_USE_FANCY_MATH_387
16652    && flag_unsafe_math_optimizations"
16653   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16654   [(set_attr "type" "frndint")
16655    (set_attr "i387_cw" "mask_pm")
16656    (set_attr "mode" "XF")])
16658 (define_expand "nearbyintxf2"
16659   [(parallel [(set (match_operand:XF 0 "register_operand")
16660                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16661                               UNSPEC_FRNDINT_MASK_PM))
16662               (clobber (reg:CC FLAGS_REG))])]
16663   "TARGET_USE_FANCY_MATH_387
16664    && flag_unsafe_math_optimizations")
16666 (define_expand "nearbyint<mode>2"
16667   [(use (match_operand:MODEF 0 "register_operand"))
16668    (use (match_operand:MODEF 1 "register_operand"))]
16669   "TARGET_USE_FANCY_MATH_387
16670    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16671        || TARGET_MIX_SSE_I387)
16672    && flag_unsafe_math_optimizations"
16674   rtx op0 = gen_reg_rtx (XFmode);
16675   rtx op1 = gen_reg_rtx (XFmode);
16677   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16678   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16680   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16681   DONE;
16684 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16685 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16686   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16687         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16688                         FIST_ROUNDING))
16689    (clobber (reg:CC FLAGS_REG))]
16690   "TARGET_USE_FANCY_MATH_387
16691    && flag_unsafe_math_optimizations
16692    && can_create_pseudo_p ()"
16693   "#"
16694   "&& 1"
16695   [(const_int 0)]
16697   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16699   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16700   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16701   if (memory_operand (operands[0], VOIDmode))
16702     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16703                                            operands[2], operands[3]));
16704   else
16705     {
16706       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16707       emit_insn (gen_fist<mode>2_<rounding>_with_temp
16708                   (operands[0], operands[1], operands[2],
16709                    operands[3], operands[4]));
16710     }
16711   DONE;
16713   [(set_attr "type" "fistp")
16714    (set_attr "i387_cw" "<rounding>")
16715    (set_attr "mode" "<MODE>")])
16717 (define_insn "fistdi2_<rounding>"
16718   [(set (match_operand:DI 0 "memory_operand" "=m")
16719         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16720                    FIST_ROUNDING))
16721    (use (match_operand:HI 2 "memory_operand" "m"))
16722    (use (match_operand:HI 3 "memory_operand" "m"))
16723    (clobber (match_scratch:XF 4 "=&1f"))]
16724   "TARGET_USE_FANCY_MATH_387
16725    && flag_unsafe_math_optimizations"
16726   "* return output_fix_trunc (insn, operands, false);"
16727   [(set_attr "type" "fistp")
16728    (set_attr "i387_cw" "<rounding>")
16729    (set_attr "mode" "DI")])
16731 (define_insn "fistdi2_<rounding>_with_temp"
16732   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16733         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16734                    FIST_ROUNDING))
16735    (use (match_operand:HI 2 "memory_operand" "m,m"))
16736    (use (match_operand:HI 3 "memory_operand" "m,m"))
16737    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16738    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16739   "TARGET_USE_FANCY_MATH_387
16740    && flag_unsafe_math_optimizations"
16741   "#"
16742   [(set_attr "type" "fistp")
16743    (set_attr "i387_cw" "<rounding>")
16744    (set_attr "mode" "DI")])
16746 (define_split
16747   [(set (match_operand:DI 0 "register_operand")
16748         (unspec:DI [(match_operand:XF 1 "register_operand")]
16749                    FIST_ROUNDING))
16750    (use (match_operand:HI 2 "memory_operand"))
16751    (use (match_operand:HI 3 "memory_operand"))
16752    (clobber (match_operand:DI 4 "memory_operand"))
16753    (clobber (match_scratch 5))]
16754   "reload_completed"
16755   [(parallel [(set (match_dup 4)
16756                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16757               (use (match_dup 2))
16758               (use (match_dup 3))
16759               (clobber (match_dup 5))])
16760    (set (match_dup 0) (match_dup 4))])
16762 (define_split
16763   [(set (match_operand:DI 0 "memory_operand")
16764         (unspec:DI [(match_operand:XF 1 "register_operand")]
16765                    FIST_ROUNDING))
16766    (use (match_operand:HI 2 "memory_operand"))
16767    (use (match_operand:HI 3 "memory_operand"))
16768    (clobber (match_operand:DI 4 "memory_operand"))
16769    (clobber (match_scratch 5))]
16770   "reload_completed"
16771   [(parallel [(set (match_dup 0)
16772                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16773               (use (match_dup 2))
16774               (use (match_dup 3))
16775               (clobber (match_dup 5))])])
16777 (define_insn "fist<mode>2_<rounding>"
16778   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16779         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16780                       FIST_ROUNDING))
16781    (use (match_operand:HI 2 "memory_operand" "m"))
16782    (use (match_operand:HI 3 "memory_operand" "m"))]
16783   "TARGET_USE_FANCY_MATH_387
16784    && flag_unsafe_math_optimizations"
16785   "* return output_fix_trunc (insn, operands, false);"
16786   [(set_attr "type" "fistp")
16787    (set_attr "i387_cw" "<rounding>")
16788    (set_attr "mode" "<MODE>")])
16790 (define_insn "fist<mode>2_<rounding>_with_temp"
16791   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16792         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16793                       FIST_ROUNDING))
16794    (use (match_operand:HI 2 "memory_operand" "m,m"))
16795    (use (match_operand:HI 3 "memory_operand" "m,m"))
16796    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16797   "TARGET_USE_FANCY_MATH_387
16798    && flag_unsafe_math_optimizations"
16799   "#"
16800   [(set_attr "type" "fistp")
16801    (set_attr "i387_cw" "<rounding>")
16802    (set_attr "mode" "<MODE>")])
16804 (define_split
16805   [(set (match_operand:SWI24 0 "register_operand")
16806         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16807                       FIST_ROUNDING))
16808    (use (match_operand:HI 2 "memory_operand"))
16809    (use (match_operand:HI 3 "memory_operand"))
16810    (clobber (match_operand:SWI24 4 "memory_operand"))]
16811   "reload_completed"
16812   [(parallel [(set (match_dup 4)
16813                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16814               (use (match_dup 2))
16815               (use (match_dup 3))])
16816    (set (match_dup 0) (match_dup 4))])
16818 (define_split
16819   [(set (match_operand:SWI24 0 "memory_operand")
16820         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16821                       FIST_ROUNDING))
16822    (use (match_operand:HI 2 "memory_operand"))
16823    (use (match_operand:HI 3 "memory_operand"))
16824    (clobber (match_operand:SWI24 4 "memory_operand"))]
16825   "reload_completed"
16826   [(parallel [(set (match_dup 0)
16827                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16828               (use (match_dup 2))
16829               (use (match_dup 3))])])
16831 (define_expand "l<rounding_insn>xf<mode>2"
16832   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16833                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16834                                    FIST_ROUNDING))
16835               (clobber (reg:CC FLAGS_REG))])]
16836   "TARGET_USE_FANCY_MATH_387
16837    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16838    && flag_unsafe_math_optimizations")
16840 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16841   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16842                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16843                                  FIST_ROUNDING))
16844               (clobber (reg:CC FLAGS_REG))])]
16845   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16846    && !flag_trapping_math"
16848   if (TARGET_64BIT && optimize_insn_for_size_p ())
16849     FAIL;
16851   if (ROUND_<ROUNDING> == ROUND_FLOOR)
16852     ix86_expand_lfloorceil (operands[0], operands[1], true);
16853   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16854     ix86_expand_lfloorceil (operands[0], operands[1], false);
16855   else
16856     gcc_unreachable ();
16858   DONE;
16861 (define_insn "fxam<mode>2_i387"
16862   [(set (match_operand:HI 0 "register_operand" "=a")
16863         (unspec:HI
16864           [(match_operand:X87MODEF 1 "register_operand" "f")]
16865           UNSPEC_FXAM))]
16866   "TARGET_USE_FANCY_MATH_387"
16867   "fxam\n\tfnstsw\t%0"
16868   [(set_attr "type" "multi")
16869    (set_attr "length" "4")
16870    (set_attr "unit" "i387")
16871    (set_attr "mode" "<MODE>")])
16873 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16874   [(set (match_operand:HI 0 "register_operand")
16875         (unspec:HI
16876           [(match_operand:MODEF 1 "memory_operand")]
16877           UNSPEC_FXAM_MEM))]
16878   "TARGET_USE_FANCY_MATH_387
16879    && can_create_pseudo_p ()"
16880   "#"
16881   "&& 1"
16882   [(set (match_dup 2)(match_dup 1))
16883    (set (match_dup 0)
16884         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16886   operands[2] = gen_reg_rtx (<MODE>mode);
16888   MEM_VOLATILE_P (operands[1]) = 1;
16890   [(set_attr "type" "multi")
16891    (set_attr "unit" "i387")
16892    (set_attr "mode" "<MODE>")])
16894 (define_expand "isinfxf2"
16895   [(use (match_operand:SI 0 "register_operand"))
16896    (use (match_operand:XF 1 "register_operand"))]
16897   "TARGET_USE_FANCY_MATH_387
16898    && ix86_libc_has_function (function_c99_misc)"
16900   rtx mask = GEN_INT (0x45);
16901   rtx val = GEN_INT (0x05);
16903   rtx scratch = gen_reg_rtx (HImode);
16904   rtx res = gen_reg_rtx (QImode);
16906   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16908   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16909   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16910   ix86_expand_setcc (res, EQ,
16911                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16912   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16913   DONE;
16916 (define_expand "isinf<mode>2"
16917   [(use (match_operand:SI 0 "register_operand"))
16918    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16919   "TARGET_USE_FANCY_MATH_387
16920    && ix86_libc_has_function (function_c99_misc)
16921    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16923   rtx mask = GEN_INT (0x45);
16924   rtx val = GEN_INT (0x05);
16926   rtx scratch = gen_reg_rtx (HImode);
16927   rtx res = gen_reg_rtx (QImode);
16929   /* Remove excess precision by forcing value through memory. */
16930   if (memory_operand (operands[1], VOIDmode))
16931     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16932   else
16933     {
16934       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16936       emit_move_insn (temp, operands[1]);
16937       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16938     }
16940   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16941   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16942   ix86_expand_setcc (res, EQ,
16943                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16944   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16945   DONE;
16948 (define_expand "signbittf2"
16949   [(use (match_operand:SI 0 "register_operand"))
16950    (use (match_operand:TF 1 "register_operand"))]
16951   "TARGET_SSE"
16953   if (TARGET_SSE4_1)
16954     {
16955       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16956       rtx scratch = gen_reg_rtx (QImode);
16958       emit_insn (gen_ptesttf2 (operands[1], mask));
16959         ix86_expand_setcc (scratch, NE,
16960                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16962       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16963     }
16964   else
16965     {
16966       emit_insn (gen_sse_movmskps (operands[0],
16967                                    gen_lowpart (V4SFmode, operands[1])));
16968       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16969     }
16970   DONE;
16973 (define_expand "signbitxf2"
16974   [(use (match_operand:SI 0 "register_operand"))
16975    (use (match_operand:XF 1 "register_operand"))]
16976   "TARGET_USE_FANCY_MATH_387"
16978   rtx scratch = gen_reg_rtx (HImode);
16980   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16981   emit_insn (gen_andsi3 (operands[0],
16982              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16983   DONE;
16986 (define_insn "movmsk_df"
16987   [(set (match_operand:SI 0 "register_operand" "=r")
16988         (unspec:SI
16989           [(match_operand:DF 1 "register_operand" "x")]
16990           UNSPEC_MOVMSK))]
16991   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16992   "%vmovmskpd\t{%1, %0|%0, %1}"
16993   [(set_attr "type" "ssemov")
16994    (set_attr "prefix" "maybe_vex")
16995    (set_attr "mode" "DF")])
16997 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16998 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16999 (define_expand "signbitdf2"
17000   [(use (match_operand:SI 0 "register_operand"))
17001    (use (match_operand:DF 1 "register_operand"))]
17002   "TARGET_USE_FANCY_MATH_387
17003    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17005   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17006     {
17007       emit_insn (gen_movmsk_df (operands[0], operands[1]));
17008       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17009     }
17010   else
17011     {
17012       rtx scratch = gen_reg_rtx (HImode);
17014       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17015       emit_insn (gen_andsi3 (operands[0],
17016                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17017     }
17018   DONE;
17021 (define_expand "signbitsf2"
17022   [(use (match_operand:SI 0 "register_operand"))
17023    (use (match_operand:SF 1 "register_operand"))]
17024   "TARGET_USE_FANCY_MATH_387
17025    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17027   rtx scratch = gen_reg_rtx (HImode);
17029   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17030   emit_insn (gen_andsi3 (operands[0],
17031              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17032   DONE;
17035 ;; Block operation instructions
17037 (define_insn "cld"
17038   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17039   ""
17040   "cld"
17041   [(set_attr "length" "1")
17042    (set_attr "length_immediate" "0")
17043    (set_attr "modrm" "0")])
17045 (define_expand "movmem<mode>"
17046   [(use (match_operand:BLK 0 "memory_operand"))
17047    (use (match_operand:BLK 1 "memory_operand"))
17048    (use (match_operand:SWI48 2 "nonmemory_operand"))
17049    (use (match_operand:SWI48 3 "const_int_operand"))
17050    (use (match_operand:SI 4 "const_int_operand"))
17051    (use (match_operand:SI 5 "const_int_operand"))
17052    (use (match_operand:SI 6 ""))
17053    (use (match_operand:SI 7 ""))
17054    (use (match_operand:SI 8 ""))]
17055   ""
17057  if (ix86_expand_set_or_movmem (operands[0], operands[1],
17058                                 operands[2], NULL, operands[3],
17059                                 operands[4], operands[5],
17060                                 operands[6], operands[7],
17061                                 operands[8], false))
17062    DONE;
17063  else
17064    FAIL;
17067 ;; Most CPUs don't like single string operations
17068 ;; Handle this case here to simplify previous expander.
17070 (define_expand "strmov"
17071   [(set (match_dup 4) (match_operand 3 "memory_operand"))
17072    (set (match_operand 1 "memory_operand") (match_dup 4))
17073    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17074               (clobber (reg:CC FLAGS_REG))])
17075    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17076               (clobber (reg:CC FLAGS_REG))])]
17077   ""
17079   /* Can't use this for non-default address spaces.  */
17080   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17081     FAIL;
17083   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17085   /* If .md ever supports :P for Pmode, these can be directly
17086      in the pattern above.  */
17087   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17088   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17090   /* Can't use this if the user has appropriated esi or edi.  */
17091   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17092       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17093     {
17094       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17095                                       operands[2], operands[3],
17096                                       operands[5], operands[6]));
17097       DONE;
17098     }
17100   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17103 (define_expand "strmov_singleop"
17104   [(parallel [(set (match_operand 1 "memory_operand")
17105                    (match_operand 3 "memory_operand"))
17106               (set (match_operand 0 "register_operand")
17107                    (match_operand 4))
17108               (set (match_operand 2 "register_operand")
17109                    (match_operand 5))])]
17110   ""
17112   if (TARGET_CLD)
17113     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17116 (define_insn "*strmovdi_rex_1"
17117   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17118         (mem:DI (match_operand:P 3 "register_operand" "1")))
17119    (set (match_operand:P 0 "register_operand" "=D")
17120         (plus:P (match_dup 2)
17121                 (const_int 8)))
17122    (set (match_operand:P 1 "register_operand" "=S")
17123         (plus:P (match_dup 3)
17124                 (const_int 8)))]
17125   "TARGET_64BIT
17126    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17127    && ix86_check_no_addr_space (insn)"
17128   "%^movsq"
17129   [(set_attr "type" "str")
17130    (set_attr "memory" "both")
17131    (set_attr "mode" "DI")])
17133 (define_insn "*strmovsi_1"
17134   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17135         (mem:SI (match_operand:P 3 "register_operand" "1")))
17136    (set (match_operand:P 0 "register_operand" "=D")
17137         (plus:P (match_dup 2)
17138                 (const_int 4)))
17139    (set (match_operand:P 1 "register_operand" "=S")
17140         (plus:P (match_dup 3)
17141                 (const_int 4)))]
17142   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17143    && ix86_check_no_addr_space (insn)"
17144   "%^movs{l|d}"
17145   [(set_attr "type" "str")
17146    (set_attr "memory" "both")
17147    (set_attr "mode" "SI")])
17149 (define_insn "*strmovhi_1"
17150   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17151         (mem:HI (match_operand:P 3 "register_operand" "1")))
17152    (set (match_operand:P 0 "register_operand" "=D")
17153         (plus:P (match_dup 2)
17154                 (const_int 2)))
17155    (set (match_operand:P 1 "register_operand" "=S")
17156         (plus:P (match_dup 3)
17157                 (const_int 2)))]
17158   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17159    && ix86_check_no_addr_space (insn)"
17160   "%^movsw"
17161   [(set_attr "type" "str")
17162    (set_attr "memory" "both")
17163    (set_attr "mode" "HI")])
17165 (define_insn "*strmovqi_1"
17166   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17167         (mem:QI (match_operand:P 3 "register_operand" "1")))
17168    (set (match_operand:P 0 "register_operand" "=D")
17169         (plus:P (match_dup 2)
17170                 (const_int 1)))
17171    (set (match_operand:P 1 "register_operand" "=S")
17172         (plus:P (match_dup 3)
17173                 (const_int 1)))]
17174   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17175    && ix86_check_no_addr_space (insn)"
17176   "%^movsb"
17177   [(set_attr "type" "str")
17178    (set_attr "memory" "both")
17179    (set (attr "prefix_rex")
17180         (if_then_else
17181           (match_test "<P:MODE>mode == DImode")
17182           (const_string "0")
17183           (const_string "*")))
17184    (set_attr "mode" "QI")])
17186 (define_expand "rep_mov"
17187   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17188               (set (match_operand 0 "register_operand")
17189                    (match_operand 5))
17190               (set (match_operand 2 "register_operand")
17191                    (match_operand 6))
17192               (set (match_operand 1 "memory_operand")
17193                    (match_operand 3 "memory_operand"))
17194               (use (match_dup 4))])]
17195   ""
17197   if (TARGET_CLD)
17198     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17201 (define_insn "*rep_movdi_rex64"
17202   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17203    (set (match_operand:P 0 "register_operand" "=D")
17204         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17205                           (const_int 3))
17206                 (match_operand:P 3 "register_operand" "0")))
17207    (set (match_operand:P 1 "register_operand" "=S")
17208         (plus:P (ashift:P (match_dup 5) (const_int 3))
17209                 (match_operand:P 4 "register_operand" "1")))
17210    (set (mem:BLK (match_dup 3))
17211         (mem:BLK (match_dup 4)))
17212    (use (match_dup 5))]
17213   "TARGET_64BIT
17214    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17215    && ix86_check_no_addr_space (insn)"
17216   "%^rep{%;} movsq"
17217   [(set_attr "type" "str")
17218    (set_attr "prefix_rep" "1")
17219    (set_attr "memory" "both")
17220    (set_attr "mode" "DI")])
17222 (define_insn "*rep_movsi"
17223   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17224    (set (match_operand:P 0 "register_operand" "=D")
17225         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17226                           (const_int 2))
17227                  (match_operand:P 3 "register_operand" "0")))
17228    (set (match_operand:P 1 "register_operand" "=S")
17229         (plus:P (ashift:P (match_dup 5) (const_int 2))
17230                 (match_operand:P 4 "register_operand" "1")))
17231    (set (mem:BLK (match_dup 3))
17232         (mem:BLK (match_dup 4)))
17233    (use (match_dup 5))]
17234   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17235    && ix86_check_no_addr_space (insn)"
17236   "%^rep{%;} movs{l|d}"
17237   [(set_attr "type" "str")
17238    (set_attr "prefix_rep" "1")
17239    (set_attr "memory" "both")
17240    (set_attr "mode" "SI")])
17242 (define_insn "*rep_movqi"
17243   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17244    (set (match_operand:P 0 "register_operand" "=D")
17245         (plus:P (match_operand:P 3 "register_operand" "0")
17246                 (match_operand:P 5 "register_operand" "2")))
17247    (set (match_operand:P 1 "register_operand" "=S")
17248         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17249    (set (mem:BLK (match_dup 3))
17250         (mem:BLK (match_dup 4)))
17251    (use (match_dup 5))]
17252   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17253    && ix86_check_no_addr_space (insn)"
17254   "%^rep{%;} movsb"
17255   [(set_attr "type" "str")
17256    (set_attr "prefix_rep" "1")
17257    (set_attr "memory" "both")
17258    (set_attr "mode" "QI")])
17260 (define_expand "setmem<mode>"
17261    [(use (match_operand:BLK 0 "memory_operand"))
17262     (use (match_operand:SWI48 1 "nonmemory_operand"))
17263     (use (match_operand:QI 2 "nonmemory_operand"))
17264     (use (match_operand 3 "const_int_operand"))
17265     (use (match_operand:SI 4 "const_int_operand"))
17266     (use (match_operand:SI 5 "const_int_operand"))
17267     (use (match_operand:SI 6 ""))
17268     (use (match_operand:SI 7 ""))
17269     (use (match_operand:SI 8 ""))]
17270   ""
17272  if (ix86_expand_set_or_movmem (operands[0], NULL,
17273                                 operands[1], operands[2],
17274                                 operands[3], operands[4],
17275                                 operands[5], operands[6],
17276                                 operands[7], operands[8], true))
17277    DONE;
17278  else
17279    FAIL;
17282 ;; Most CPUs don't like single string operations
17283 ;; Handle this case here to simplify previous expander.
17285 (define_expand "strset"
17286   [(set (match_operand 1 "memory_operand")
17287         (match_operand 2 "register_operand"))
17288    (parallel [(set (match_operand 0 "register_operand")
17289                    (match_dup 3))
17290               (clobber (reg:CC FLAGS_REG))])]
17291   ""
17293   /* Can't use this for non-default address spaces.  */
17294   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17295     FAIL;
17297   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17298     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17300   /* If .md ever supports :P for Pmode, this can be directly
17301      in the pattern above.  */
17302   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17303                               GEN_INT (GET_MODE_SIZE (GET_MODE
17304                                                       (operands[2]))));
17305   /* Can't use this if the user has appropriated eax or edi.  */
17306   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17307       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17308     {
17309       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17310                                       operands[3]));
17311       DONE;
17312     }
17315 (define_expand "strset_singleop"
17316   [(parallel [(set (match_operand 1 "memory_operand")
17317                    (match_operand 2 "register_operand"))
17318               (set (match_operand 0 "register_operand")
17319                    (match_operand 3))
17320               (unspec [(const_int 0)] UNSPEC_STOS)])]
17321   ""
17323   if (TARGET_CLD)
17324     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17327 (define_insn "*strsetdi_rex_1"
17328   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17329         (match_operand:DI 2 "register_operand" "a"))
17330    (set (match_operand:P 0 "register_operand" "=D")
17331         (plus:P (match_dup 1)
17332                 (const_int 8)))
17333    (unspec [(const_int 0)] UNSPEC_STOS)]
17334   "TARGET_64BIT
17335    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17336    && ix86_check_no_addr_space (insn)"
17337   "%^stosq"
17338   [(set_attr "type" "str")
17339    (set_attr "memory" "store")
17340    (set_attr "mode" "DI")])
17342 (define_insn "*strsetsi_1"
17343   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17344         (match_operand:SI 2 "register_operand" "a"))
17345    (set (match_operand:P 0 "register_operand" "=D")
17346         (plus:P (match_dup 1)
17347                 (const_int 4)))
17348    (unspec [(const_int 0)] UNSPEC_STOS)]
17349   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17350    && ix86_check_no_addr_space (insn)"
17351   "%^stos{l|d}"
17352   [(set_attr "type" "str")
17353    (set_attr "memory" "store")
17354    (set_attr "mode" "SI")])
17356 (define_insn "*strsethi_1"
17357   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17358         (match_operand:HI 2 "register_operand" "a"))
17359    (set (match_operand:P 0 "register_operand" "=D")
17360         (plus:P (match_dup 1)
17361                 (const_int 2)))
17362    (unspec [(const_int 0)] UNSPEC_STOS)]
17363   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17364    && ix86_check_no_addr_space (insn)"
17365   "%^stosw"
17366   [(set_attr "type" "str")
17367    (set_attr "memory" "store")
17368    (set_attr "mode" "HI")])
17370 (define_insn "*strsetqi_1"
17371   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17372         (match_operand:QI 2 "register_operand" "a"))
17373    (set (match_operand:P 0 "register_operand" "=D")
17374         (plus:P (match_dup 1)
17375                 (const_int 1)))
17376    (unspec [(const_int 0)] UNSPEC_STOS)]
17377   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17378    && ix86_check_no_addr_space (insn)"
17379   "%^stosb"
17380   [(set_attr "type" "str")
17381    (set_attr "memory" "store")
17382    (set (attr "prefix_rex")
17383         (if_then_else
17384           (match_test "<P:MODE>mode == DImode")
17385           (const_string "0")
17386           (const_string "*")))
17387    (set_attr "mode" "QI")])
17389 (define_expand "rep_stos"
17390   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17391               (set (match_operand 0 "register_operand")
17392                    (match_operand 4))
17393               (set (match_operand 2 "memory_operand") (const_int 0))
17394               (use (match_operand 3 "register_operand"))
17395               (use (match_dup 1))])]
17396   ""
17398   if (TARGET_CLD)
17399     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17402 (define_insn "*rep_stosdi_rex64"
17403   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17404    (set (match_operand:P 0 "register_operand" "=D")
17405         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17406                           (const_int 3))
17407                  (match_operand:P 3 "register_operand" "0")))
17408    (set (mem:BLK (match_dup 3))
17409         (const_int 0))
17410    (use (match_operand:DI 2 "register_operand" "a"))
17411    (use (match_dup 4))]
17412   "TARGET_64BIT
17413    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17414    && ix86_check_no_addr_space (insn)"
17415   "%^rep{%;} stosq"
17416   [(set_attr "type" "str")
17417    (set_attr "prefix_rep" "1")
17418    (set_attr "memory" "store")
17419    (set_attr "mode" "DI")])
17421 (define_insn "*rep_stossi"
17422   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17423    (set (match_operand:P 0 "register_operand" "=D")
17424         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17425                           (const_int 2))
17426                  (match_operand:P 3 "register_operand" "0")))
17427    (set (mem:BLK (match_dup 3))
17428         (const_int 0))
17429    (use (match_operand:SI 2 "register_operand" "a"))
17430    (use (match_dup 4))]
17431   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17432    && ix86_check_no_addr_space (insn)"
17433   "%^rep{%;} stos{l|d}"
17434   [(set_attr "type" "str")
17435    (set_attr "prefix_rep" "1")
17436    (set_attr "memory" "store")
17437    (set_attr "mode" "SI")])
17439 (define_insn "*rep_stosqi"
17440   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17441    (set (match_operand:P 0 "register_operand" "=D")
17442         (plus:P (match_operand:P 3 "register_operand" "0")
17443                 (match_operand:P 4 "register_operand" "1")))
17444    (set (mem:BLK (match_dup 3))
17445         (const_int 0))
17446    (use (match_operand:QI 2 "register_operand" "a"))
17447    (use (match_dup 4))]
17448   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17449    && ix86_check_no_addr_space (insn)"
17450   "%^rep{%;} stosb"
17451   [(set_attr "type" "str")
17452    (set_attr "prefix_rep" "1")
17453    (set_attr "memory" "store")
17454    (set (attr "prefix_rex")
17455         (if_then_else
17456           (match_test "<P:MODE>mode == DImode")
17457           (const_string "0")
17458           (const_string "*")))
17459    (set_attr "mode" "QI")])
17461 (define_expand "cmpstrnsi"
17462   [(set (match_operand:SI 0 "register_operand")
17463         (compare:SI (match_operand:BLK 1 "general_operand")
17464                     (match_operand:BLK 2 "general_operand")))
17465    (use (match_operand 3 "general_operand"))
17466    (use (match_operand 4 "immediate_operand"))]
17467   ""
17469   rtx addr1, addr2, out, outlow, count, countreg, align;
17471   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17472     FAIL;
17474   /* Can't use this if the user has appropriated ecx, esi or edi.  */
17475   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17476     FAIL;
17478   /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
17479      will have rewritten the length arg to be the minimum of the const string
17480      length and the actual length arg.  If both strings are the same and
17481      shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17482      will incorrectly base the results on chars past the 0 byte.  */
17483   tree t1 = MEM_EXPR (operands[1]);
17484   tree t2 = MEM_EXPR (operands[2]);
17485   if (!((t1 && TREE_CODE (t1) == MEM_REF
17486          && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17487          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17488       || (t2 && TREE_CODE (t2) == MEM_REF
17489           && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17490           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17491     FAIL;
17493   out = operands[0];
17494   if (!REG_P (out))
17495     out = gen_reg_rtx (SImode);
17497   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17498   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17499   if (addr1 != XEXP (operands[1], 0))
17500     operands[1] = replace_equiv_address_nv (operands[1], addr1);
17501   if (addr2 != XEXP (operands[2], 0))
17502     operands[2] = replace_equiv_address_nv (operands[2], addr2);
17504   count = operands[3];
17505   countreg = ix86_zero_extend_to_Pmode (count);
17507   /* %%% Iff we are testing strict equality, we can use known alignment
17508      to good advantage.  This may be possible with combine, particularly
17509      once cc0 is dead.  */
17510   align = operands[4];
17512   if (CONST_INT_P (count))
17513     {
17514       if (INTVAL (count) == 0)
17515         {
17516           emit_move_insn (operands[0], const0_rtx);
17517           DONE;
17518         }
17519       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17520                                      operands[1], operands[2]));
17521     }
17522   else
17523     {
17524       rtx (*gen_cmp) (rtx, rtx);
17526       gen_cmp = (TARGET_64BIT
17527                  ? gen_cmpdi_1 : gen_cmpsi_1);
17529       emit_insn (gen_cmp (countreg, countreg));
17530       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17531                                   operands[1], operands[2]));
17532     }
17534   outlow = gen_lowpart (QImode, out);
17535   emit_insn (gen_cmpintqi (outlow));
17536   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17538   if (operands[0] != out)
17539     emit_move_insn (operands[0], out);
17541   DONE;
17544 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17546 (define_expand "cmpintqi"
17547   [(set (match_dup 1)
17548         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17549    (set (match_dup 2)
17550         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17551    (parallel [(set (match_operand:QI 0 "register_operand")
17552                    (minus:QI (match_dup 1)
17553                              (match_dup 2)))
17554               (clobber (reg:CC FLAGS_REG))])]
17555   ""
17557   operands[1] = gen_reg_rtx (QImode);
17558   operands[2] = gen_reg_rtx (QImode);
17561 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
17562 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
17564 (define_expand "cmpstrnqi_nz_1"
17565   [(parallel [(set (reg:CC FLAGS_REG)
17566                    (compare:CC (match_operand 4 "memory_operand")
17567                                (match_operand 5 "memory_operand")))
17568               (use (match_operand 2 "register_operand"))
17569               (use (match_operand:SI 3 "immediate_operand"))
17570               (clobber (match_operand 0 "register_operand"))
17571               (clobber (match_operand 1 "register_operand"))
17572               (clobber (match_dup 2))])]
17573   ""
17575   if (TARGET_CLD)
17576     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17579 (define_insn "*cmpstrnqi_nz_1"
17580   [(set (reg:CC FLAGS_REG)
17581         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17582                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17583    (use (match_operand:P 6 "register_operand" "2"))
17584    (use (match_operand:SI 3 "immediate_operand" "i"))
17585    (clobber (match_operand:P 0 "register_operand" "=S"))
17586    (clobber (match_operand:P 1 "register_operand" "=D"))
17587    (clobber (match_operand:P 2 "register_operand" "=c"))]
17588   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17589    && ix86_check_no_addr_space (insn)"
17590   "%^repz{%;} cmpsb"
17591   [(set_attr "type" "str")
17592    (set_attr "mode" "QI")
17593    (set (attr "prefix_rex")
17594         (if_then_else
17595           (match_test "<P:MODE>mode == DImode")
17596           (const_string "0")
17597           (const_string "*")))
17598    (set_attr "prefix_rep" "1")])
17600 ;; The same, but the count is not known to not be zero.
17602 (define_expand "cmpstrnqi_1"
17603   [(parallel [(set (reg:CC FLAGS_REG)
17604                 (if_then_else:CC (ne (match_operand 2 "register_operand")
17605                                      (const_int 0))
17606                   (compare:CC (match_operand 4 "memory_operand")
17607                               (match_operand 5 "memory_operand"))
17608                   (const_int 0)))
17609               (use (match_operand:SI 3 "immediate_operand"))
17610               (use (reg:CC FLAGS_REG))
17611               (clobber (match_operand 0 "register_operand"))
17612               (clobber (match_operand 1 "register_operand"))
17613               (clobber (match_dup 2))])]
17614   ""
17616   if (TARGET_CLD)
17617     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17620 (define_insn "*cmpstrnqi_1"
17621   [(set (reg:CC FLAGS_REG)
17622         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17623                              (const_int 0))
17624           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17625                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
17626           (const_int 0)))
17627    (use (match_operand:SI 3 "immediate_operand" "i"))
17628    (use (reg:CC FLAGS_REG))
17629    (clobber (match_operand:P 0 "register_operand" "=S"))
17630    (clobber (match_operand:P 1 "register_operand" "=D"))
17631    (clobber (match_operand:P 2 "register_operand" "=c"))]
17632   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17633    && ix86_check_no_addr_space (insn)"
17634   "%^repz{%;} cmpsb"
17635   [(set_attr "type" "str")
17636    (set_attr "mode" "QI")
17637    (set (attr "prefix_rex")
17638         (if_then_else
17639           (match_test "<P:MODE>mode == DImode")
17640           (const_string "0")
17641           (const_string "*")))
17642    (set_attr "prefix_rep" "1")])
17644 (define_expand "strlen<mode>"
17645   [(set (match_operand:P 0 "register_operand")
17646         (unspec:P [(match_operand:BLK 1 "general_operand")
17647                    (match_operand:QI 2 "immediate_operand")
17648                    (match_operand 3 "immediate_operand")]
17649                   UNSPEC_SCAS))]
17650   ""
17652  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17653    DONE;
17654  else
17655    FAIL;
17658 (define_expand "strlenqi_1"
17659   [(parallel [(set (match_operand 0 "register_operand")
17660                    (match_operand 2))
17661               (clobber (match_operand 1 "register_operand"))
17662               (clobber (reg:CC FLAGS_REG))])]
17663   ""
17665   if (TARGET_CLD)
17666     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17669 (define_insn "*strlenqi_1"
17670   [(set (match_operand:P 0 "register_operand" "=&c")
17671         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17672                    (match_operand:QI 2 "register_operand" "a")
17673                    (match_operand:P 3 "immediate_operand" "i")
17674                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17675    (clobber (match_operand:P 1 "register_operand" "=D"))
17676    (clobber (reg:CC FLAGS_REG))]
17677   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17678    && ix86_check_no_addr_space (insn)"
17679   "%^repnz{%;} scasb"
17680   [(set_attr "type" "str")
17681    (set_attr "mode" "QI")
17682    (set (attr "prefix_rex")
17683         (if_then_else
17684           (match_test "<P:MODE>mode == DImode")
17685           (const_string "0")
17686           (const_string "*")))
17687    (set_attr "prefix_rep" "1")])
17689 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17690 ;; handled in combine, but it is not currently up to the task.
17691 ;; When used for their truth value, the cmpstrn* expanders generate
17692 ;; code like this:
17694 ;;   repz cmpsb
17695 ;;   seta       %al
17696 ;;   setb       %dl
17697 ;;   cmpb       %al, %dl
17698 ;;   jcc        label
17700 ;; The intermediate three instructions are unnecessary.
17702 ;; This one handles cmpstrn*_nz_1...
17703 (define_peephole2
17704   [(parallel[
17705      (set (reg:CC FLAGS_REG)
17706           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17707                       (mem:BLK (match_operand 5 "register_operand"))))
17708      (use (match_operand 6 "register_operand"))
17709      (use (match_operand:SI 3 "immediate_operand"))
17710      (clobber (match_operand 0 "register_operand"))
17711      (clobber (match_operand 1 "register_operand"))
17712      (clobber (match_operand 2 "register_operand"))])
17713    (set (match_operand:QI 7 "register_operand")
17714         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17715    (set (match_operand:QI 8 "register_operand")
17716         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17717    (set (reg FLAGS_REG)
17718         (compare (match_dup 7) (match_dup 8)))
17719   ]
17720   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17721   [(parallel[
17722      (set (reg:CC FLAGS_REG)
17723           (compare:CC (mem:BLK (match_dup 4))
17724                       (mem:BLK (match_dup 5))))
17725      (use (match_dup 6))
17726      (use (match_dup 3))
17727      (clobber (match_dup 0))
17728      (clobber (match_dup 1))
17729      (clobber (match_dup 2))])])
17731 ;; ...and this one handles cmpstrn*_1.
17732 (define_peephole2
17733   [(parallel[
17734      (set (reg:CC FLAGS_REG)
17735           (if_then_else:CC (ne (match_operand 6 "register_operand")
17736                                (const_int 0))
17737             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17738                         (mem:BLK (match_operand 5 "register_operand")))
17739             (const_int 0)))
17740      (use (match_operand:SI 3 "immediate_operand"))
17741      (use (reg:CC FLAGS_REG))
17742      (clobber (match_operand 0 "register_operand"))
17743      (clobber (match_operand 1 "register_operand"))
17744      (clobber (match_operand 2 "register_operand"))])
17745    (set (match_operand:QI 7 "register_operand")
17746         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17747    (set (match_operand:QI 8 "register_operand")
17748         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17749    (set (reg FLAGS_REG)
17750         (compare (match_dup 7) (match_dup 8)))
17751   ]
17752   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17753   [(parallel[
17754      (set (reg:CC FLAGS_REG)
17755           (if_then_else:CC (ne (match_dup 6)
17756                                (const_int 0))
17757             (compare:CC (mem:BLK (match_dup 4))
17758                         (mem:BLK (match_dup 5)))
17759             (const_int 0)))
17760      (use (match_dup 3))
17761      (use (reg:CC FLAGS_REG))
17762      (clobber (match_dup 0))
17763      (clobber (match_dup 1))
17764      (clobber (match_dup 2))])])
17766 ;; Conditional move instructions.
17768 (define_expand "mov<mode>cc"
17769   [(set (match_operand:SWIM 0 "register_operand")
17770         (if_then_else:SWIM (match_operand 1 "comparison_operator")
17771                            (match_operand:SWIM 2 "<general_operand>")
17772                            (match_operand:SWIM 3 "<general_operand>")))]
17773   ""
17774   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17776 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17777 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17778 ;; So just document what we're doing explicitly.
17780 (define_expand "x86_mov<mode>cc_0_m1"
17781   [(parallel
17782     [(set (match_operand:SWI48 0 "register_operand")
17783           (if_then_else:SWI48
17784             (match_operator:SWI48 2 "ix86_carry_flag_operator"
17785              [(match_operand 1 "flags_reg_operand")
17786               (const_int 0)])
17787             (const_int -1)
17788             (const_int 0)))
17789      (clobber (reg:CC FLAGS_REG))])])
17791 (define_insn "*x86_mov<mode>cc_0_m1"
17792   [(set (match_operand:SWI48 0 "register_operand" "=r")
17793         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17794                              [(reg FLAGS_REG) (const_int 0)])
17795           (const_int -1)
17796           (const_int 0)))
17797    (clobber (reg:CC FLAGS_REG))]
17798   ""
17799   "sbb{<imodesuffix>}\t%0, %0"
17800   ; Since we don't have the proper number of operands for an alu insn,
17801   ; fill in all the blanks.
17802   [(set_attr "type" "alu")
17803    (set_attr "modrm_class" "op0")
17804    (set_attr "use_carry" "1")
17805    (set_attr "pent_pair" "pu")
17806    (set_attr "memory" "none")
17807    (set_attr "imm_disp" "false")
17808    (set_attr "mode" "<MODE>")
17809    (set_attr "length_immediate" "0")])
17811 (define_insn "*x86_mov<mode>cc_0_m1_se"
17812   [(set (match_operand:SWI48 0 "register_operand" "=r")
17813         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17814                              [(reg FLAGS_REG) (const_int 0)])
17815                             (const_int 1)
17816                             (const_int 0)))
17817    (clobber (reg:CC FLAGS_REG))]
17818   ""
17819   "sbb{<imodesuffix>}\t%0, %0"
17820   [(set_attr "type" "alu")
17821    (set_attr "modrm_class" "op0")
17822    (set_attr "use_carry" "1")
17823    (set_attr "pent_pair" "pu")
17824    (set_attr "memory" "none")
17825    (set_attr "imm_disp" "false")
17826    (set_attr "mode" "<MODE>")
17827    (set_attr "length_immediate" "0")])
17829 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17830   [(set (match_operand:SWI48 0 "register_operand" "=r")
17831         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17832                     [(reg FLAGS_REG) (const_int 0)])))
17833    (clobber (reg:CC FLAGS_REG))]
17834   ""
17835   "sbb{<imodesuffix>}\t%0, %0"
17836   [(set_attr "type" "alu")
17837    (set_attr "modrm_class" "op0")
17838    (set_attr "use_carry" "1")
17839    (set_attr "pent_pair" "pu")
17840    (set_attr "memory" "none")
17841    (set_attr "imm_disp" "false")
17842    (set_attr "mode" "<MODE>")
17843    (set_attr "length_immediate" "0")])
17845 (define_insn "*mov<mode>cc_noc"
17846   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17847         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17848                                [(reg FLAGS_REG) (const_int 0)])
17849           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17850           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17851   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17852   "@
17853    cmov%O2%C1\t{%2, %0|%0, %2}
17854    cmov%O2%c1\t{%3, %0|%0, %3}"
17855   [(set_attr "type" "icmov")
17856    (set_attr "mode" "<MODE>")])
17858 (define_insn "*movsicc_noc_zext"
17859   [(set (match_operand:DI 0 "register_operand" "=r,r")
17860         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17861                            [(reg FLAGS_REG) (const_int 0)])
17862           (zero_extend:DI
17863             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17864           (zero_extend:DI
17865             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17866   "TARGET_64BIT
17867    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17868   "@
17869    cmov%O2%C1\t{%2, %k0|%k0, %2}
17870    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17871   [(set_attr "type" "icmov")
17872    (set_attr "mode" "SI")])
17874 ;; Don't do conditional moves with memory inputs.  This splitter helps
17875 ;; register starved x86_32 by forcing inputs into registers before reload.
17876 (define_split
17877   [(set (match_operand:SWI248 0 "register_operand")
17878         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17879                                [(reg FLAGS_REG) (const_int 0)])
17880           (match_operand:SWI248 2 "nonimmediate_operand")
17881           (match_operand:SWI248 3 "nonimmediate_operand")))]
17882   "!TARGET_64BIT && TARGET_CMOVE
17883    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17884    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17885    && can_create_pseudo_p ()
17886    && optimize_insn_for_speed_p ()"
17887   [(set (match_dup 0)
17888         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17890   if (MEM_P (operands[2]))
17891     operands[2] = force_reg (<MODE>mode, operands[2]);
17892   if (MEM_P (operands[3]))
17893     operands[3] = force_reg (<MODE>mode, operands[3]);
17896 (define_insn "*movqicc_noc"
17897   [(set (match_operand:QI 0 "register_operand" "=r,r")
17898         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17899                            [(reg FLAGS_REG) (const_int 0)])
17900                       (match_operand:QI 2 "register_operand" "r,0")
17901                       (match_operand:QI 3 "register_operand" "0,r")))]
17902   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17903   "#"
17904   [(set_attr "type" "icmov")
17905    (set_attr "mode" "QI")])
17907 (define_split
17908   [(set (match_operand:SWI12 0 "register_operand")
17909         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17910                               [(reg FLAGS_REG) (const_int 0)])
17911                       (match_operand:SWI12 2 "register_operand")
17912                       (match_operand:SWI12 3 "register_operand")))]
17913   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17914    && reload_completed"
17915   [(set (match_dup 0)
17916         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17918   operands[0] = gen_lowpart (SImode, operands[0]);
17919   operands[2] = gen_lowpart (SImode, operands[2]);
17920   operands[3] = gen_lowpart (SImode, operands[3]);
17923 ;; Don't do conditional moves with memory inputs
17924 (define_peephole2
17925   [(match_scratch:SWI248 4 "r")
17926    (set (match_operand:SWI248 0 "register_operand")
17927         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17928                                [(reg FLAGS_REG) (const_int 0)])
17929           (match_operand:SWI248 2 "nonimmediate_operand")
17930           (match_operand:SWI248 3 "nonimmediate_operand")))]
17931   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17932    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17933    && optimize_insn_for_speed_p ()"
17934   [(set (match_dup 4) (match_dup 5))
17935    (set (match_dup 0)
17936         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17938   if (MEM_P (operands[2]))
17939     {
17940       operands[5] = operands[2];
17941       operands[2] = operands[4];
17942     }
17943   else if (MEM_P (operands[3]))
17944     {
17945       operands[5] = operands[3];
17946       operands[3] = operands[4];
17947     }
17948   else
17949     gcc_unreachable ();
17952 (define_peephole2
17953   [(match_scratch:SI 4 "r")
17954    (set (match_operand:DI 0 "register_operand")
17955         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17956                            [(reg FLAGS_REG) (const_int 0)])
17957           (zero_extend:DI
17958             (match_operand:SI 2 "nonimmediate_operand"))
17959           (zero_extend:DI
17960             (match_operand:SI 3 "nonimmediate_operand"))))]
17961   "TARGET_64BIT
17962    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17963    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17964    && optimize_insn_for_speed_p ()"
17965   [(set (match_dup 4) (match_dup 5))
17966    (set (match_dup 0)
17967         (if_then_else:DI (match_dup 1)
17968           (zero_extend:DI (match_dup 2))
17969           (zero_extend:DI (match_dup 3))))]
17971   if (MEM_P (operands[2]))
17972     {
17973       operands[5] = operands[2];
17974       operands[2] = operands[4];
17975     }
17976   else if (MEM_P (operands[3]))
17977     {
17978       operands[5] = operands[3];
17979       operands[3] = operands[4];
17980     }
17981   else
17982     gcc_unreachable ();
17985 (define_expand "mov<mode>cc"
17986   [(set (match_operand:X87MODEF 0 "register_operand")
17987         (if_then_else:X87MODEF
17988           (match_operand 1 "comparison_operator")
17989           (match_operand:X87MODEF 2 "register_operand")
17990           (match_operand:X87MODEF 3 "register_operand")))]
17991   "(TARGET_80387 && TARGET_CMOVE)
17992    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17993   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17995 (define_insn "*movxfcc_1"
17996   [(set (match_operand:XF 0 "register_operand" "=f,f")
17997         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17998                                 [(reg FLAGS_REG) (const_int 0)])
17999                       (match_operand:XF 2 "register_operand" "f,0")
18000                       (match_operand:XF 3 "register_operand" "0,f")))]
18001   "TARGET_80387 && TARGET_CMOVE"
18002   "@
18003    fcmov%F1\t{%2, %0|%0, %2}
18004    fcmov%f1\t{%3, %0|%0, %3}"
18005   [(set_attr "type" "fcmov")
18006    (set_attr "mode" "XF")])
18008 (define_insn "*movdfcc_1"
18009   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18010         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18011                                 [(reg FLAGS_REG) (const_int 0)])
18012                       (match_operand:DF 2 "nonimmediate_operand"
18013                                                "f ,0,rm,0 ,rm,0")
18014                       (match_operand:DF 3 "nonimmediate_operand"
18015                                                "0 ,f,0 ,rm,0, rm")))]
18016   "TARGET_80387 && TARGET_CMOVE
18017    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18018   "@
18019    fcmov%F1\t{%2, %0|%0, %2}
18020    fcmov%f1\t{%3, %0|%0, %3}
18021    #
18022    #
18023    cmov%O2%C1\t{%2, %0|%0, %2}
18024    cmov%O2%c1\t{%3, %0|%0, %3}"
18025   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18026    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18027    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18029 (define_split
18030   [(set (match_operand:DF 0 "general_reg_operand")
18031         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18032                                 [(reg FLAGS_REG) (const_int 0)])
18033                       (match_operand:DF 2 "nonimmediate_operand")
18034                       (match_operand:DF 3 "nonimmediate_operand")))]
18035   "!TARGET_64BIT && reload_completed"
18036   [(set (match_dup 2)
18037         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18038    (set (match_dup 3)
18039         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18041   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18042   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18045 (define_insn "*movsfcc_1_387"
18046   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18047         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18048                                 [(reg FLAGS_REG) (const_int 0)])
18049                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18050                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18051   "TARGET_80387 && TARGET_CMOVE
18052    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18053   "@
18054    fcmov%F1\t{%2, %0|%0, %2}
18055    fcmov%f1\t{%3, %0|%0, %3}
18056    cmov%O2%C1\t{%2, %0|%0, %2}
18057    cmov%O2%c1\t{%3, %0|%0, %3}"
18058   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18059    (set_attr "mode" "SF,SF,SI,SI")])
18061 ;; Don't do conditional moves with memory inputs.  This splitter helps
18062 ;; register starved x86_32 by forcing inputs into registers before reload.
18063 (define_split
18064   [(set (match_operand:MODEF 0 "register_operand")
18065         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18066                               [(reg FLAGS_REG) (const_int 0)])
18067           (match_operand:MODEF 2 "nonimmediate_operand")
18068           (match_operand:MODEF 3 "nonimmediate_operand")))]
18069   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18070    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18071    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18072    && can_create_pseudo_p ()
18073    && optimize_insn_for_speed_p ()"
18074   [(set (match_dup 0)
18075         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18077   if (MEM_P (operands[2]))
18078     operands[2] = force_reg (<MODE>mode, operands[2]);
18079   if (MEM_P (operands[3]))
18080     operands[3] = force_reg (<MODE>mode, operands[3]);
18083 ;; Don't do conditional moves with memory inputs
18084 (define_peephole2
18085   [(match_scratch:MODEF 4 "r")
18086    (set (match_operand:MODEF 0 "general_reg_operand")
18087         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18088                               [(reg FLAGS_REG) (const_int 0)])
18089           (match_operand:MODEF 2 "nonimmediate_operand")
18090           (match_operand:MODEF 3 "nonimmediate_operand")))]
18091   "(<MODE>mode != DFmode || TARGET_64BIT)
18092    && TARGET_80387 && TARGET_CMOVE
18093    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18094    && (MEM_P (operands[2]) || MEM_P (operands[3]))
18095    && optimize_insn_for_speed_p ()"
18096   [(set (match_dup 4) (match_dup 5))
18097    (set (match_dup 0)
18098         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18100   if (MEM_P (operands[2]))
18101     {
18102       operands[5] = operands[2];
18103       operands[2] = operands[4];
18104     }
18105   else if (MEM_P (operands[3]))
18106     {
18107       operands[5] = operands[3];
18108       operands[3] = operands[4];
18109     }
18110   else
18111     gcc_unreachable ();
18114 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18115 ;; the scalar versions to have only XMM registers as operands.
18117 ;; XOP conditional move
18118 (define_insn "*xop_pcmov_<mode>"
18119   [(set (match_operand:MODEF 0 "register_operand" "=x")
18120         (if_then_else:MODEF
18121           (match_operand:MODEF 1 "register_operand" "x")
18122           (match_operand:MODEF 2 "register_operand" "x")
18123           (match_operand:MODEF 3 "register_operand" "x")))]
18124   "TARGET_XOP"
18125   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18126   [(set_attr "type" "sse4arg")])
18128 ;; These versions of the min/max patterns are intentionally ignorant of
18129 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18130 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18131 ;; are undefined in this condition, we're certain this is correct.
18133 (define_insn "<code><mode>3"
18134   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18135         (smaxmin:MODEF
18136           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18137           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18138   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18139   "@
18140    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18141    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18142   [(set_attr "isa" "noavx,avx")
18143    (set_attr "prefix" "orig,vex")
18144    (set_attr "type" "sseadd")
18145    (set_attr "mode" "<MODE>")])
18147 ;; These versions of the min/max patterns implement exactly the operations
18148 ;;   min = (op1 < op2 ? op1 : op2)
18149 ;;   max = (!(op1 < op2) ? op1 : op2)
18150 ;; Their operands are not commutative, and thus they may be used in the
18151 ;; presence of -0.0 and NaN.
18153 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18154   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18155         (unspec:MODEF
18156           [(match_operand:MODEF 1 "register_operand" "0,v")
18157            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18158           IEEE_MAXMIN))]
18159   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18160   "@
18161    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18162    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18163   [(set_attr "isa" "noavx,avx")
18164    (set_attr "prefix" "orig,maybe_evex")
18165    (set_attr "type" "sseadd")
18166    (set_attr "mode" "<MODE>")])
18168 ;; Make two stack loads independent:
18169 ;;   fld aa              fld aa
18170 ;;   fld %st(0)     ->   fld bb
18171 ;;   fmul bb             fmul %st(1), %st
18173 ;; Actually we only match the last two instructions for simplicity.
18175 (define_peephole2
18176   [(set (match_operand 0 "fp_register_operand")
18177         (match_operand 1 "fp_register_operand"))
18178    (set (match_dup 0)
18179         (match_operator 2 "binary_fp_operator"
18180            [(match_dup 0)
18181             (match_operand 3 "memory_operand")]))]
18182   "REGNO (operands[0]) != REGNO (operands[1])"
18183   [(set (match_dup 0) (match_dup 3))
18184    (set (match_dup 0)
18185         (match_op_dup 2
18186           [(match_dup 5) (match_dup 4)]))]
18188   operands[4] = operands[0];
18189   operands[5] = operands[1];
18191   /* The % modifier is not operational anymore in peephole2's, so we have to
18192      swap the operands manually in the case of addition and multiplication. */
18193   if (COMMUTATIVE_ARITH_P (operands[2]))
18194     std::swap (operands[4], operands[5]);
18197 (define_peephole2
18198   [(set (match_operand 0 "fp_register_operand")
18199         (match_operand 1 "fp_register_operand"))
18200    (set (match_dup 0)
18201         (match_operator 2 "binary_fp_operator"
18202            [(match_operand 3 "memory_operand")
18203             (match_dup 0)]))]
18204   "REGNO (operands[0]) != REGNO (operands[1])"
18205   [(set (match_dup 0) (match_dup 3))
18206    (set (match_dup 0)
18207         (match_op_dup 2
18208           [(match_dup 4) (match_dup 5)]))]
18210   operands[4] = operands[0];
18211   operands[5] = operands[1];
18213   /* The % modifier is not operational anymore in peephole2's, so we have to
18214      swap the operands manually in the case of addition and multiplication. */
18215   if (COMMUTATIVE_ARITH_P (operands[2]))
18216     std::swap (operands[4], operands[5]);
18219 ;; Conditional addition patterns
18220 (define_expand "add<mode>cc"
18221   [(match_operand:SWI 0 "register_operand")
18222    (match_operand 1 "ordered_comparison_operator")
18223    (match_operand:SWI 2 "register_operand")
18224    (match_operand:SWI 3 "const_int_operand")]
18225   ""
18226   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18228 ;; Misc patterns (?)
18230 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18231 ;; Otherwise there will be nothing to keep
18233 ;; [(set (reg ebp) (reg esp))]
18234 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18235 ;;  (clobber (eflags)]
18236 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18238 ;; in proper program order.
18240 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18241   [(set (match_operand:P 0 "register_operand" "=r,r")
18242         (plus:P (match_operand:P 1 "register_operand" "0,r")
18243                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18244    (clobber (reg:CC FLAGS_REG))
18245    (clobber (mem:BLK (scratch)))]
18246   ""
18248   switch (get_attr_type (insn))
18249     {
18250     case TYPE_IMOV:
18251       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18253     case TYPE_ALU:
18254       gcc_assert (rtx_equal_p (operands[0], operands[1]));
18255       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18256         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18258       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18260     default:
18261       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18262       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18263     }
18265   [(set (attr "type")
18266         (cond [(and (eq_attr "alternative" "0")
18267                     (not (match_test "TARGET_OPT_AGU")))
18268                  (const_string "alu")
18269                (match_operand:<MODE> 2 "const0_operand")
18270                  (const_string "imov")
18271               ]
18272               (const_string "lea")))
18273    (set (attr "length_immediate")
18274         (cond [(eq_attr "type" "imov")
18275                  (const_string "0")
18276                (and (eq_attr "type" "alu")
18277                     (match_operand 2 "const128_operand"))
18278                  (const_string "1")
18279               ]
18280               (const_string "*")))
18281    (set_attr "mode" "<MODE>")])
18283 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18284   [(set (match_operand:P 0 "register_operand" "=r")
18285         (minus:P (match_operand:P 1 "register_operand" "0")
18286                  (match_operand:P 2 "register_operand" "r")))
18287    (clobber (reg:CC FLAGS_REG))
18288    (clobber (mem:BLK (scratch)))]
18289   ""
18290   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18291   [(set_attr "type" "alu")
18292    (set_attr "mode" "<MODE>")])
18294 (define_insn "allocate_stack_worker_probe_<mode>"
18295   [(set (match_operand:P 0 "register_operand" "=a")
18296         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18297                             UNSPECV_STACK_PROBE))
18298    (clobber (reg:CC FLAGS_REG))]
18299   "ix86_target_stack_probe ()"
18300   "call\t___chkstk_ms"
18301   [(set_attr "type" "multi")
18302    (set_attr "length" "5")])
18304 (define_expand "allocate_stack"
18305   [(match_operand 0 "register_operand")
18306    (match_operand 1 "general_operand")]
18307   "ix86_target_stack_probe ()"
18309   rtx x;
18311 #ifndef CHECK_STACK_LIMIT
18312 #define CHECK_STACK_LIMIT 0
18313 #endif
18315   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18316       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18317     x = operands[1];
18318   else
18319     {
18320       rtx (*insn) (rtx, rtx);
18322       x = copy_to_mode_reg (Pmode, operands[1]);
18324       insn = (TARGET_64BIT
18325               ? gen_allocate_stack_worker_probe_di
18326               : gen_allocate_stack_worker_probe_si);
18328       emit_insn (insn (x, x));
18329     }
18331   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18332                            stack_pointer_rtx, 0, OPTAB_DIRECT);
18334   if (x != stack_pointer_rtx)
18335     emit_move_insn (stack_pointer_rtx, x);
18337   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18338   DONE;
18341 (define_expand "probe_stack"
18342   [(match_operand 0 "memory_operand")]
18343   ""
18345   rtx (*insn) (rtx, rtx)
18346     = (GET_MODE (operands[0]) == DImode
18347        ? gen_probe_stack_di : gen_probe_stack_si);
18349   emit_insn (insn (operands[0], const0_rtx));
18350   DONE;
18353 ;; Use OR for stack probes, this is shorter.
18354 (define_insn "probe_stack_<mode>"
18355   [(set (match_operand:W 0 "memory_operand" "=m")
18356         (unspec:W [(match_operand:W 1 "const0_operand")]
18357                   UNSPEC_PROBE_STACK))
18358    (clobber (reg:CC FLAGS_REG))]
18359   ""
18360   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18361   [(set_attr "type" "alu1")
18362    (set_attr "mode" "<MODE>")
18363    (set_attr "length_immediate" "1")])
18364   
18365 (define_insn "adjust_stack_and_probe<mode>"
18366   [(set (match_operand:P 0 "register_operand" "=r")
18367         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18368                             UNSPECV_PROBE_STACK_RANGE))
18369    (set (reg:P SP_REG)
18370         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18371    (clobber (reg:CC FLAGS_REG))
18372    (clobber (mem:BLK (scratch)))]
18373   ""
18374   "* return output_adjust_stack_and_probe (operands[0]);"
18375   [(set_attr "type" "multi")])
18377 (define_insn "probe_stack_range<mode>"
18378   [(set (match_operand:P 0 "register_operand" "=r")
18379         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18380                             (match_operand:P 2 "const_int_operand" "n")]
18381                             UNSPECV_PROBE_STACK_RANGE))
18382    (clobber (reg:CC FLAGS_REG))]
18383   ""
18384   "* return output_probe_stack_range (operands[0], operands[2]);"
18385   [(set_attr "type" "multi")])
18387 /* Additional processing for builtin_setjmp.  Store the shadow stack pointer
18388    as a forth element in jmpbuf.  */
18389 (define_expand "builtin_setjmp_setup"
18390   [(match_operand 0 "address_operand")]
18391   "TARGET_SHSTK"
18393   if (flag_cf_protection & CF_RETURN)
18394     {
18395       rtx mem, reg_ssp;
18397       mem = gen_rtx_MEM (word_mode,
18398                          plus_constant (Pmode, operands[0],
18399                                         3 * GET_MODE_SIZE (ptr_mode)));
18400       reg_ssp = gen_reg_rtx (word_mode);
18401       emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18402       emit_insn ((word_mode == SImode)
18403                  ? gen_rdsspsi (reg_ssp)
18404                  : gen_rdsspdi (reg_ssp));
18405       emit_move_insn (mem, reg_ssp);
18406     }
18407   DONE;
18410 (define_expand "builtin_setjmp_receiver"
18411   [(label_ref (match_operand 0))]
18412   "!TARGET_64BIT && flag_pic"
18414 #if TARGET_MACHO
18415   if (TARGET_MACHO)
18416     {
18417       rtx xops[3];
18418       rtx_code_label *label_rtx = gen_label_rtx ();
18419       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18420       xops[0] = xops[1] = pic_offset_table_rtx;
18421       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18422       ix86_expand_binary_operator (MINUS, SImode, xops);
18423     }
18424   else
18425 #endif
18426     emit_insn (gen_set_got (pic_offset_table_rtx));
18427   DONE;
18430 (define_expand "builtin_longjmp"
18431   [(match_operand 0 "address_operand")]
18432   "TARGET_SHSTK"
18434   rtx fp, lab, stack;
18435   rtx flags, jump, noadj_label, inc_label, loop_label;
18436   rtx reg_adj, reg_ssp, mem_buf, tmp, clob;
18437   machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
18439   /* Adjust the shadow stack pointer (ssp) to the value saved in the
18440      jmp_buf.  The saving was done in the builtin_setjmp_setup.  */
18441   if (flag_cf_protection & CF_RETURN)
18442     {
18443       /* Get the current shadow stack pointer.  The code below will check if
18444          SHSTK feature is enabled.  If it is not enabled the RDSSP instruction
18445          is a NOP.  */
18446       reg_ssp = gen_reg_rtx (word_mode);
18447       emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18448       emit_insn ((word_mode == SImode)
18449                  ? gen_rdsspsi (reg_ssp)
18450                  : gen_rdsspdi (reg_ssp));
18451       mem_buf = gen_rtx_MEM (word_mode,
18452                              plus_constant (Pmode, operands[0],
18453                                             3 * GET_MODE_SIZE (ptr_mode)));
18455       /* Compare through substraction the saved and the current ssp to decide
18456          if ssp has to be adjusted.  */
18457       tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp, mem_buf));
18458       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18459       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18460       emit_insn (tmp);
18462       /* Compare and jump over adjustment code.  */
18463       noadj_label = gen_label_rtx ();
18464       flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18465       tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18466       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18467                                   gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18468                                   pc_rtx);
18469       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18470       JUMP_LABEL (jump) = noadj_label;
18472       /* Compute the numebr of frames to adjust.  */
18473       reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18474       tmp = gen_rtx_SET (reg_adj,
18475                          gen_rtx_LSHIFTRT (ptr_mode,
18476                                            negate_rtx (ptr_mode, reg_adj),
18477                                            GEN_INT ((word_mode == SImode)
18478                                                     ? 2
18479                                                     : 3)));
18480       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18481       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18482       emit_insn (tmp);
18484       /* Check if number of frames <= 255 so no loop is needed.  */
18485       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18486       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18487       emit_insn (gen_rtx_SET (flags, tmp));
18489       inc_label = gen_label_rtx ();
18490       tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18491       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18492                                   gen_rtx_LABEL_REF (VOIDmode, inc_label),
18493                                   pc_rtx);
18494       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18495       JUMP_LABEL (jump) = inc_label;
18497       /* Adjust the ssp in a loop.  */
18498       loop_label = gen_label_rtx ();
18499       emit_label (loop_label);
18500       LABEL_NUSES (loop_label) = 1;
18502       emit_insn ((word_mode == SImode)
18503                  ? gen_incsspsi (reg_ssp)
18504                  : gen_incsspdi (reg_ssp));
18505       tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18506                                                  reg_adj,
18507                                                  GEN_INT (255)));
18508       clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18509       tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18510       emit_insn (tmp);
18512       tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18513       flags = gen_rtx_REG (CCmode, FLAGS_REG);
18514       emit_insn (gen_rtx_SET (flags, tmp));
18516       /* Jump to the loop label.  */
18517       tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18518       tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18519                                   gen_rtx_LABEL_REF (VOIDmode, loop_label),
18520                                   pc_rtx);
18521       jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18522       JUMP_LABEL (jump) = loop_label;
18524       emit_label (inc_label);
18525       LABEL_NUSES (inc_label) = 1;
18526       emit_insn ((word_mode == SImode)
18527                  ? gen_incsspsi (reg_ssp)
18528                  : gen_incsspdi (reg_ssp));
18530       emit_label (noadj_label);
18531       LABEL_NUSES (noadj_label) = 1;
18532     }
18534   /* This code is the same as in expand_buildin_longjmp.  */
18535   fp = gen_rtx_MEM (ptr_mode, operands[0]);
18536   lab = gen_rtx_MEM (ptr_mode, plus_constant (Pmode, operands[0],
18537                                               GET_MODE_SIZE (ptr_mode)));
18538   stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, operands[0],
18539                                                2 * GET_MODE_SIZE (ptr_mode)));
18540   lab = copy_to_reg (lab);
18542   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
18543   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
18545   if (GET_MODE (fp) != Pmode)
18546     fp = convert_to_mode (Pmode, fp, 1);
18547   emit_move_insn (hard_frame_pointer_rtx, fp);
18548   emit_stack_restore (SAVE_NONLOCAL, stack);
18550   emit_use (hard_frame_pointer_rtx);
18551   emit_use (stack_pointer_rtx);
18552   emit_indirect_jump (lab);
18556 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18557 ;; Do not split instructions with mask registers.
18558 (define_split
18559   [(set (match_operand 0 "general_reg_operand")
18560         (match_operator 3 "promotable_binary_operator"
18561            [(match_operand 1 "general_reg_operand")
18562             (match_operand 2 "aligned_operand")]))
18563    (clobber (reg:CC FLAGS_REG))]
18564   "! TARGET_PARTIAL_REG_STALL && reload_completed
18565    && ((GET_MODE (operands[0]) == HImode
18566         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18567             /* ??? next two lines just !satisfies_constraint_K (...) */
18568             || !CONST_INT_P (operands[2])
18569             || satisfies_constraint_K (operands[2])))
18570        || (GET_MODE (operands[0]) == QImode
18571            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18572   [(parallel [(set (match_dup 0)
18573                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18574               (clobber (reg:CC FLAGS_REG))])]
18576   operands[0] = gen_lowpart (SImode, operands[0]);
18577   operands[1] = gen_lowpart (SImode, operands[1]);
18578   if (GET_CODE (operands[3]) != ASHIFT)
18579     operands[2] = gen_lowpart (SImode, operands[2]);
18580   operands[3] = shallow_copy_rtx (operands[3]);
18581   PUT_MODE (operands[3], SImode);
18584 ; Promote the QImode tests, as i386 has encoding of the AND
18585 ; instruction with 32-bit sign-extended immediate and thus the
18586 ; instruction size is unchanged, except in the %eax case for
18587 ; which it is increased by one byte, hence the ! optimize_size.
18588 (define_split
18589   [(set (match_operand 0 "flags_reg_operand")
18590         (match_operator 2 "compare_operator"
18591           [(and (match_operand 3 "aligned_operand")
18592                 (match_operand 4 "const_int_operand"))
18593            (const_int 0)]))
18594    (set (match_operand 1 "register_operand")
18595         (and (match_dup 3) (match_dup 4)))]
18596   "! TARGET_PARTIAL_REG_STALL && reload_completed
18597    && optimize_insn_for_speed_p ()
18598    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18599        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18600    /* Ensure that the operand will remain sign-extended immediate.  */
18601    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18602   [(parallel [(set (match_dup 0)
18603                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18604                                     (const_int 0)]))
18605               (set (match_dup 1)
18606                    (and:SI (match_dup 3) (match_dup 4)))])]
18608   operands[4]
18609     = gen_int_mode (INTVAL (operands[4])
18610                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18611   operands[1] = gen_lowpart (SImode, operands[1]);
18612   operands[3] = gen_lowpart (SImode, operands[3]);
18615 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18616 ; the TEST instruction with 32-bit sign-extended immediate and thus
18617 ; the instruction size would at least double, which is not what we
18618 ; want even with ! optimize_size.
18619 (define_split
18620   [(set (match_operand 0 "flags_reg_operand")
18621         (match_operator 1 "compare_operator"
18622           [(and (match_operand:HI 2 "aligned_operand")
18623                 (match_operand:HI 3 "const_int_operand"))
18624            (const_int 0)]))]
18625   "! TARGET_PARTIAL_REG_STALL && reload_completed
18626    && ! TARGET_FAST_PREFIX
18627    && optimize_insn_for_speed_p ()
18628    /* Ensure that the operand will remain sign-extended immediate.  */
18629    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18630   [(set (match_dup 0)
18631         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18632                          (const_int 0)]))]
18634   operands[3]
18635     = gen_int_mode (INTVAL (operands[3])
18636                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18637   operands[2] = gen_lowpart (SImode, operands[2]);
18640 (define_split
18641   [(set (match_operand 0 "register_operand")
18642         (neg (match_operand 1 "register_operand")))
18643    (clobber (reg:CC FLAGS_REG))]
18644   "! TARGET_PARTIAL_REG_STALL && reload_completed
18645    && (GET_MODE (operands[0]) == HImode
18646        || (GET_MODE (operands[0]) == QImode
18647            && (TARGET_PROMOTE_QImode
18648                || optimize_insn_for_size_p ())))"
18649   [(parallel [(set (match_dup 0)
18650                    (neg:SI (match_dup 1)))
18651               (clobber (reg:CC FLAGS_REG))])]
18653   operands[0] = gen_lowpart (SImode, operands[0]);
18654   operands[1] = gen_lowpart (SImode, operands[1]);
18657 ;; Do not split instructions with mask regs.
18658 (define_split
18659   [(set (match_operand 0 "general_reg_operand")
18660         (not (match_operand 1 "general_reg_operand")))]
18661   "! TARGET_PARTIAL_REG_STALL && reload_completed
18662    && (GET_MODE (operands[0]) == HImode
18663        || (GET_MODE (operands[0]) == QImode
18664            && (TARGET_PROMOTE_QImode
18665                || optimize_insn_for_size_p ())))"
18666   [(set (match_dup 0)
18667         (not:SI (match_dup 1)))]
18669   operands[0] = gen_lowpart (SImode, operands[0]);
18670   operands[1] = gen_lowpart (SImode, operands[1]);
18673 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
18674 ;; transform a complex memory operation into two memory to register operations.
18676 ;; Don't push memory operands
18677 (define_peephole2
18678   [(set (match_operand:SWI 0 "push_operand")
18679         (match_operand:SWI 1 "memory_operand"))
18680    (match_scratch:SWI 2 "<r>")]
18681   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18682    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18683   [(set (match_dup 2) (match_dup 1))
18684    (set (match_dup 0) (match_dup 2))])
18686 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18687 ;; SImode pushes.
18688 (define_peephole2
18689   [(set (match_operand:SF 0 "push_operand")
18690         (match_operand:SF 1 "memory_operand"))
18691    (match_scratch:SF 2 "r")]
18692   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18693    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18694   [(set (match_dup 2) (match_dup 1))
18695    (set (match_dup 0) (match_dup 2))])
18697 ;; Don't move an immediate directly to memory when the instruction
18698 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18699 (define_peephole2
18700   [(match_scratch:SWI124 1 "<r>")
18701    (set (match_operand:SWI124 0 "memory_operand")
18702         (const_int 0))]
18703   "optimize_insn_for_speed_p ()
18704    && ((<MODE>mode == HImode
18705        && TARGET_LCP_STALL)
18706        || (!TARGET_USE_MOV0
18707           && TARGET_SPLIT_LONG_MOVES
18708           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18709    && peep2_regno_dead_p (0, FLAGS_REG)"
18710   [(parallel [(set (match_dup 2) (const_int 0))
18711               (clobber (reg:CC FLAGS_REG))])
18712    (set (match_dup 0) (match_dup 1))]
18713   "operands[2] = gen_lowpart (SImode, operands[1]);")
18715 (define_peephole2
18716   [(match_scratch:SWI124 2 "<r>")
18717    (set (match_operand:SWI124 0 "memory_operand")
18718         (match_operand:SWI124 1 "immediate_operand"))]
18719   "optimize_insn_for_speed_p ()
18720    && ((<MODE>mode == HImode
18721        && TARGET_LCP_STALL)
18722        || (TARGET_SPLIT_LONG_MOVES
18723           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18724   [(set (match_dup 2) (match_dup 1))
18725    (set (match_dup 0) (match_dup 2))])
18727 ;; Don't compare memory with zero, load and use a test instead.
18728 (define_peephole2
18729   [(set (match_operand 0 "flags_reg_operand")
18730         (match_operator 1 "compare_operator"
18731           [(match_operand:SI 2 "memory_operand")
18732            (const_int 0)]))
18733    (match_scratch:SI 3 "r")]
18734   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18735   [(set (match_dup 3) (match_dup 2))
18736    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18738 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18739 ;; Don't split NOTs with a displacement operand, because resulting XOR
18740 ;; will not be pairable anyway.
18742 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18743 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18744 ;; so this split helps here as well.
18746 ;; Note: Can't do this as a regular split because we can't get proper
18747 ;; lifetime information then.
18749 (define_peephole2
18750   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18751         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18752   "optimize_insn_for_speed_p ()
18753    && ((TARGET_NOT_UNPAIRABLE
18754         && (!MEM_P (operands[0])
18755             || !memory_displacement_operand (operands[0], <MODE>mode)))
18756        || (TARGET_NOT_VECTORMODE
18757            && long_memory_operand (operands[0], <MODE>mode)))
18758    && peep2_regno_dead_p (0, FLAGS_REG)"
18759   [(parallel [(set (match_dup 0)
18760                    (xor:SWI124 (match_dup 1) (const_int -1)))
18761               (clobber (reg:CC FLAGS_REG))])])
18763 ;; Non pairable "test imm, reg" instructions can be translated to
18764 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18765 ;; byte opcode instead of two, have a short form for byte operands),
18766 ;; so do it for other CPUs as well.  Given that the value was dead,
18767 ;; this should not create any new dependencies.  Pass on the sub-word
18768 ;; versions if we're concerned about partial register stalls.
18770 (define_peephole2
18771   [(set (match_operand 0 "flags_reg_operand")
18772         (match_operator 1 "compare_operator"
18773           [(and:SI (match_operand:SI 2 "register_operand")
18774                    (match_operand:SI 3 "immediate_operand"))
18775            (const_int 0)]))]
18776   "ix86_match_ccmode (insn, CCNOmode)
18777    && (REGNO (operands[2]) != AX_REG
18778        || satisfies_constraint_K (operands[3]))
18779    && peep2_reg_dead_p (1, operands[2])"
18780   [(parallel
18781      [(set (match_dup 0)
18782            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18783                             (const_int 0)]))
18784       (set (match_dup 2)
18785            (and:SI (match_dup 2) (match_dup 3)))])])
18787 ;; We don't need to handle HImode case, because it will be promoted to SImode
18788 ;; on ! TARGET_PARTIAL_REG_STALL
18790 (define_peephole2
18791   [(set (match_operand 0 "flags_reg_operand")
18792         (match_operator 1 "compare_operator"
18793           [(and:QI (match_operand:QI 2 "register_operand")
18794                    (match_operand:QI 3 "immediate_operand"))
18795            (const_int 0)]))]
18796   "! TARGET_PARTIAL_REG_STALL
18797    && ix86_match_ccmode (insn, CCNOmode)
18798    && REGNO (operands[2]) != AX_REG
18799    && peep2_reg_dead_p (1, operands[2])"
18800   [(parallel
18801      [(set (match_dup 0)
18802            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18803                             (const_int 0)]))
18804       (set (match_dup 2)
18805            (and:QI (match_dup 2) (match_dup 3)))])])
18807 (define_peephole2
18808   [(set (match_operand 0 "flags_reg_operand")
18809         (match_operator 1 "compare_operator"
18810           [(and:QI
18811              (subreg:QI
18812                (zero_extract:SI (match_operand 2 "QIreg_operand")
18813                                 (const_int 8)
18814                                 (const_int 8)) 0)
18815              (match_operand 3 "const_int_operand"))
18816            (const_int 0)]))]
18817   "! TARGET_PARTIAL_REG_STALL
18818    && ix86_match_ccmode (insn, CCNOmode)
18819    && REGNO (operands[2]) != AX_REG
18820    && peep2_reg_dead_p (1, operands[2])"
18821   [(parallel
18822      [(set (match_dup 0)
18823            (match_op_dup 1
18824              [(and:QI
18825                 (subreg:QI
18826                   (zero_extract:SI (match_dup 2)
18827                                    (const_int 8)
18828                                    (const_int 8)) 0)
18829                 (match_dup 3))
18830               (const_int 0)]))
18831       (set (zero_extract:SI (match_dup 2)
18832                             (const_int 8)
18833                             (const_int 8))
18834            (subreg:SI
18835              (and:QI
18836                (subreg:QI
18837                  (zero_extract:SI (match_dup 2)
18838                                   (const_int 8)
18839                                   (const_int 8)) 0)
18840                (match_dup 3)) 0))])])
18842 ;; Don't do logical operations with memory inputs.
18843 (define_peephole2
18844   [(match_scratch:SWI 2 "<r>")
18845    (parallel [(set (match_operand:SWI 0 "register_operand")
18846                    (match_operator:SWI 3 "arith_or_logical_operator"
18847                      [(match_dup 0)
18848                       (match_operand:SWI 1 "memory_operand")]))
18849               (clobber (reg:CC FLAGS_REG))])]
18850   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18851   [(set (match_dup 2) (match_dup 1))
18852    (parallel [(set (match_dup 0)
18853                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18854               (clobber (reg:CC FLAGS_REG))])])
18856 (define_peephole2
18857   [(match_scratch:SWI 2 "<r>")
18858    (parallel [(set (match_operand:SWI 0 "register_operand")
18859                    (match_operator:SWI 3 "arith_or_logical_operator"
18860                      [(match_operand:SWI 1 "memory_operand")
18861                       (match_dup 0)]))
18862               (clobber (reg:CC FLAGS_REG))])]
18863   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18864   [(set (match_dup 2) (match_dup 1))
18865    (parallel [(set (match_dup 0)
18866                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18867               (clobber (reg:CC FLAGS_REG))])])
18869 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
18870 ;; the memory address refers to the destination of the load!
18872 (define_peephole2
18873   [(set (match_operand:SWI 0 "general_reg_operand")
18874         (match_operand:SWI 1 "general_reg_operand"))
18875    (parallel [(set (match_dup 0)
18876                    (match_operator:SWI 3 "commutative_operator"
18877                      [(match_dup 0)
18878                       (match_operand:SWI 2 "memory_operand")]))
18879               (clobber (reg:CC FLAGS_REG))])]
18880   "REGNO (operands[0]) != REGNO (operands[1])
18881    && (<MODE>mode != QImode
18882        || any_QIreg_operand (operands[1], QImode))"
18883   [(set (match_dup 0) (match_dup 4))
18884    (parallel [(set (match_dup 0)
18885                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18886               (clobber (reg:CC FLAGS_REG))])]
18887   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18889 (define_peephole2
18890   [(set (match_operand 0 "mmx_reg_operand")
18891         (match_operand 1 "mmx_reg_operand"))
18892    (set (match_dup 0)
18893         (match_operator 3 "commutative_operator"
18894           [(match_dup 0)
18895            (match_operand 2 "memory_operand")]))]
18896   "REGNO (operands[0]) != REGNO (operands[1])"
18897   [(set (match_dup 0) (match_dup 2))
18898    (set (match_dup 0)
18899         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18901 (define_peephole2
18902   [(set (match_operand 0 "sse_reg_operand")
18903         (match_operand 1 "sse_reg_operand"))
18904    (set (match_dup 0)
18905         (match_operator 3 "commutative_operator"
18906           [(match_dup 0)
18907            (match_operand 2 "memory_operand")]))]
18908   "REGNO (operands[0]) != REGNO (operands[1])"
18909   [(set (match_dup 0) (match_dup 2))
18910    (set (match_dup 0)
18911         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18913 ; Don't do logical operations with memory outputs
18915 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18916 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18917 ; the same decoder scheduling characteristics as the original.
18919 (define_peephole2
18920   [(match_scratch:SWI 2 "<r>")
18921    (parallel [(set (match_operand:SWI 0 "memory_operand")
18922                    (match_operator:SWI 3 "arith_or_logical_operator"
18923                      [(match_dup 0)
18924                       (match_operand:SWI 1 "<nonmemory_operand>")]))
18925               (clobber (reg:CC FLAGS_REG))])]
18926   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18927   [(set (match_dup 2) (match_dup 0))
18928    (parallel [(set (match_dup 2)
18929                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18930               (clobber (reg:CC FLAGS_REG))])
18931    (set (match_dup 0) (match_dup 2))])
18933 (define_peephole2
18934   [(match_scratch:SWI 2 "<r>")
18935    (parallel [(set (match_operand:SWI 0 "memory_operand")
18936                    (match_operator:SWI 3 "arith_or_logical_operator"
18937                      [(match_operand:SWI 1 "<nonmemory_operand>")
18938                       (match_dup 0)]))
18939               (clobber (reg:CC FLAGS_REG))])]
18940   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18941   [(set (match_dup 2) (match_dup 0))
18942    (parallel [(set (match_dup 2)
18943                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18944               (clobber (reg:CC FLAGS_REG))])
18945    (set (match_dup 0) (match_dup 2))])
18947 ;; Attempt to use arith or logical operations with memory outputs with
18948 ;; setting of flags.
18949 (define_peephole2
18950   [(set (match_operand:SWI 0 "register_operand")
18951         (match_operand:SWI 1 "memory_operand"))
18952    (parallel [(set (match_dup 0)
18953                    (match_operator:SWI 3 "plusminuslogic_operator"
18954                      [(match_dup 0)
18955                       (match_operand:SWI 2 "<nonmemory_operand>")]))
18956               (clobber (reg:CC FLAGS_REG))])
18957    (set (match_dup 1) (match_dup 0))
18958    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18959   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18960    && peep2_reg_dead_p (4, operands[0])
18961    && !reg_overlap_mentioned_p (operands[0], operands[1])
18962    && !reg_overlap_mentioned_p (operands[0], operands[2])
18963    && (<MODE>mode != QImode
18964        || immediate_operand (operands[2], QImode)
18965        || any_QIreg_operand (operands[2], QImode))
18966    && ix86_match_ccmode (peep2_next_insn (3),
18967                          (GET_CODE (operands[3]) == PLUS
18968                           || GET_CODE (operands[3]) == MINUS)
18969                          ? CCGOCmode : CCNOmode)"
18970   [(parallel [(set (match_dup 4) (match_dup 6))
18971               (set (match_dup 1) (match_dup 5))])]
18973   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18974   operands[5]
18975     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18976                       copy_rtx (operands[1]),
18977                       operands[2]);
18978   operands[6]
18979     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18980                        copy_rtx (operands[5]),
18981                        const0_rtx);
18984 ;; Likewise for instances where we have a lea pattern.
18985 (define_peephole2
18986   [(set (match_operand:SWI 0 "register_operand")
18987         (match_operand:SWI 1 "memory_operand"))
18988    (set (match_operand:SWI 3 "register_operand")
18989         (plus:SWI (match_dup 0)
18990                   (match_operand:SWI 2 "<nonmemory_operand>")))
18991    (set (match_dup 1) (match_dup 3))
18992    (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18993   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18994    && peep2_reg_dead_p (4, operands[3])
18995    && (rtx_equal_p (operands[0], operands[3])
18996        || peep2_reg_dead_p (2, operands[0]))
18997    && !reg_overlap_mentioned_p (operands[0], operands[1])
18998    && !reg_overlap_mentioned_p (operands[3], operands[1])
18999    && !reg_overlap_mentioned_p (operands[0], operands[2])
19000    && (<MODE>mode != QImode
19001        || immediate_operand (operands[2], QImode)
19002        || any_QIreg_operand (operands[2], QImode))
19003    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19004   [(parallel [(set (match_dup 4) (match_dup 6))
19005               (set (match_dup 1) (match_dup 5))])]
19007   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19008   operands[5]
19009     = gen_rtx_PLUS (<MODE>mode,
19010                     copy_rtx (operands[1]),
19011                     operands[2]);
19012   operands[6]
19013     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19014                        copy_rtx (operands[5]),
19015                        const0_rtx);
19018 (define_peephole2
19019   [(parallel [(set (match_operand:SWI 0 "register_operand")
19020                    (match_operator:SWI 2 "plusminuslogic_operator"
19021                      [(match_dup 0)
19022                       (match_operand:SWI 1 "memory_operand")]))
19023               (clobber (reg:CC FLAGS_REG))])
19024    (set (match_dup 1) (match_dup 0))
19025    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19026   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19027    && GET_CODE (operands[2]) != MINUS
19028    && peep2_reg_dead_p (3, operands[0])
19029    && !reg_overlap_mentioned_p (operands[0], operands[1])
19030    && ix86_match_ccmode (peep2_next_insn (2),
19031                          GET_CODE (operands[2]) == PLUS
19032                          ? CCGOCmode : CCNOmode)"
19033   [(parallel [(set (match_dup 3) (match_dup 5))
19034               (set (match_dup 1) (match_dup 4))])]
19036   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19037   operands[4]
19038     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19039                       copy_rtx (operands[1]),
19040                       operands[0]);
19041   operands[5]
19042     = gen_rtx_COMPARE (GET_MODE (operands[3]),
19043                        copy_rtx (operands[4]),
19044                        const0_rtx);
19047 (define_peephole2
19048   [(set (match_operand:SWI12 0 "register_operand")
19049         (match_operand:SWI12 1 "memory_operand"))
19050    (parallel [(set (match_operand:SI 4 "register_operand")
19051                    (match_operator:SI 3 "plusminuslogic_operator"
19052                      [(match_dup 4)
19053                       (match_operand:SI 2 "nonmemory_operand")]))
19054               (clobber (reg:CC FLAGS_REG))])
19055    (set (match_dup 1) (match_dup 0))
19056    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19057   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19058    && REGNO (operands[0]) == REGNO (operands[4])
19059    && peep2_reg_dead_p (4, operands[0])
19060    && (<MODE>mode != QImode
19061        || immediate_operand (operands[2], SImode)
19062        || any_QIreg_operand (operands[2], SImode))
19063    && !reg_overlap_mentioned_p (operands[0], operands[1])
19064    && !reg_overlap_mentioned_p (operands[0], operands[2])
19065    && ix86_match_ccmode (peep2_next_insn (3),
19066                          (GET_CODE (operands[3]) == PLUS
19067                           || GET_CODE (operands[3]) == MINUS)
19068                          ? CCGOCmode : CCNOmode)"
19069   [(parallel [(set (match_dup 4) (match_dup 6))
19070               (set (match_dup 1) (match_dup 5))])]
19072   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19073   operands[5]
19074     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19075                       copy_rtx (operands[1]),
19076                       gen_lowpart (<MODE>mode, operands[2]));
19077   operands[6]
19078     = gen_rtx_COMPARE (GET_MODE (operands[4]),
19079                        copy_rtx (operands[5]),
19080                        const0_rtx);
19083 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19084 (define_peephole2
19085   [(set (match_operand 0 "general_reg_operand")
19086         (match_operand 1 "const0_operand"))]
19087   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19088    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19089    && peep2_regno_dead_p (0, FLAGS_REG)"
19090   [(parallel [(set (match_dup 0) (const_int 0))
19091               (clobber (reg:CC FLAGS_REG))])]
19092   "operands[0] = gen_lowpart (word_mode, operands[0]);")
19094 (define_peephole2
19095   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19096         (const_int 0))]
19097   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19098    && peep2_regno_dead_p (0, FLAGS_REG)"
19099   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19100               (clobber (reg:CC FLAGS_REG))])])
19102 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19103 (define_peephole2
19104   [(set (match_operand:SWI248 0 "general_reg_operand")
19105         (const_int -1))]
19106   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19107    && peep2_regno_dead_p (0, FLAGS_REG)"
19108   [(parallel [(set (match_dup 0) (const_int -1))
19109               (clobber (reg:CC FLAGS_REG))])]
19111   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19112     operands[0] = gen_lowpart (SImode, operands[0]);
19115 ;; Attempt to convert simple lea to add/shift.
19116 ;; These can be created by move expanders.
19117 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19118 ;; relevant lea instructions were already split.
19120 (define_peephole2
19121   [(set (match_operand:SWI48 0 "register_operand")
19122         (plus:SWI48 (match_dup 0)
19123                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
19124   "!TARGET_OPT_AGU
19125    && peep2_regno_dead_p (0, FLAGS_REG)"
19126   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19127               (clobber (reg:CC FLAGS_REG))])])
19129 (define_peephole2
19130   [(set (match_operand:SWI48 0 "register_operand")
19131         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19132                     (match_dup 0)))]
19133   "!TARGET_OPT_AGU
19134    && peep2_regno_dead_p (0, FLAGS_REG)"
19135   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19136               (clobber (reg:CC FLAGS_REG))])])
19138 (define_peephole2
19139   [(set (match_operand:DI 0 "register_operand")
19140         (zero_extend:DI
19141           (plus:SI (match_operand:SI 1 "register_operand")
19142                    (match_operand:SI 2 "nonmemory_operand"))))]
19143   "TARGET_64BIT && !TARGET_OPT_AGU
19144    && REGNO (operands[0]) == REGNO (operands[1])
19145    && peep2_regno_dead_p (0, FLAGS_REG)"
19146   [(parallel [(set (match_dup 0)
19147                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19148               (clobber (reg:CC FLAGS_REG))])])
19150 (define_peephole2
19151   [(set (match_operand:DI 0 "register_operand")
19152         (zero_extend:DI
19153           (plus:SI (match_operand:SI 1 "nonmemory_operand")
19154                    (match_operand:SI 2 "register_operand"))))]
19155   "TARGET_64BIT && !TARGET_OPT_AGU
19156    && REGNO (operands[0]) == REGNO (operands[2])
19157    && peep2_regno_dead_p (0, FLAGS_REG)"
19158   [(parallel [(set (match_dup 0)
19159                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19160               (clobber (reg:CC FLAGS_REG))])])
19162 (define_peephole2
19163   [(set (match_operand:SWI48 0 "register_operand")
19164         (mult:SWI48 (match_dup 0)
19165                     (match_operand:SWI48 1 "const_int_operand")))]
19166   "pow2p_hwi (INTVAL (operands[1]))
19167    && peep2_regno_dead_p (0, FLAGS_REG)"
19168   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19169               (clobber (reg:CC FLAGS_REG))])]
19170   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19172 (define_peephole2
19173   [(set (match_operand:DI 0 "register_operand")
19174         (zero_extend:DI
19175           (mult:SI (match_operand:SI 1 "register_operand")
19176                    (match_operand:SI 2 "const_int_operand"))))]
19177   "TARGET_64BIT
19178    && pow2p_hwi (INTVAL (operands[2]))
19179    && REGNO (operands[0]) == REGNO (operands[1])
19180    && peep2_regno_dead_p (0, FLAGS_REG)"
19181   [(parallel [(set (match_dup 0)
19182                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19183               (clobber (reg:CC FLAGS_REG))])]
19184   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19186 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19187 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19188 ;; On many CPUs it is also faster, since special hardware to avoid esp
19189 ;; dependencies is present.
19191 ;; While some of these conversions may be done using splitters, we use
19192 ;; peepholes in order to allow combine_stack_adjustments pass to see
19193 ;; nonobfuscated RTL.
19195 ;; Convert prologue esp subtractions to push.
19196 ;; We need register to push.  In order to keep verify_flow_info happy we have
19197 ;; two choices
19198 ;; - use scratch and clobber it in order to avoid dependencies
19199 ;; - use already live register
19200 ;; We can't use the second way right now, since there is no reliable way how to
19201 ;; verify that given register is live.  First choice will also most likely in
19202 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19203 ;; call clobbered registers are dead.  We may want to use base pointer as an
19204 ;; alternative when no register is available later.
19206 (define_peephole2
19207   [(match_scratch:W 1 "r")
19208    (parallel [(set (reg:P SP_REG)
19209                    (plus:P (reg:P SP_REG)
19210                            (match_operand:P 0 "const_int_operand")))
19211               (clobber (reg:CC FLAGS_REG))
19212               (clobber (mem:BLK (scratch)))])]
19213   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19214    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19215    && ix86_red_zone_size == 0"
19216   [(clobber (match_dup 1))
19217    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19218               (clobber (mem:BLK (scratch)))])])
19220 (define_peephole2
19221   [(match_scratch:W 1 "r")
19222    (parallel [(set (reg:P SP_REG)
19223                    (plus:P (reg:P SP_REG)
19224                            (match_operand:P 0 "const_int_operand")))
19225               (clobber (reg:CC FLAGS_REG))
19226               (clobber (mem:BLK (scratch)))])]
19227   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19228    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19229    && ix86_red_zone_size == 0"
19230   [(clobber (match_dup 1))
19231    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19232    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19233               (clobber (mem:BLK (scratch)))])])
19235 ;; Convert esp subtractions to push.
19236 (define_peephole2
19237   [(match_scratch:W 1 "r")
19238    (parallel [(set (reg:P SP_REG)
19239                    (plus:P (reg:P SP_REG)
19240                            (match_operand:P 0 "const_int_operand")))
19241               (clobber (reg:CC FLAGS_REG))])]
19242   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19243    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19244    && ix86_red_zone_size == 0"
19245   [(clobber (match_dup 1))
19246    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19248 (define_peephole2
19249   [(match_scratch:W 1 "r")
19250    (parallel [(set (reg:P SP_REG)
19251                    (plus:P (reg:P SP_REG)
19252                            (match_operand:P 0 "const_int_operand")))
19253               (clobber (reg:CC FLAGS_REG))])]
19254   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19255    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19256    && ix86_red_zone_size == 0"
19257   [(clobber (match_dup 1))
19258    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19259    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19261 ;; Convert epilogue deallocator to pop.
19262 (define_peephole2
19263   [(match_scratch:W 1 "r")
19264    (parallel [(set (reg:P SP_REG)
19265                    (plus:P (reg:P SP_REG)
19266                            (match_operand:P 0 "const_int_operand")))
19267               (clobber (reg:CC FLAGS_REG))
19268               (clobber (mem:BLK (scratch)))])]
19269   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19270    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19271   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19272               (clobber (mem:BLK (scratch)))])])
19274 ;; Two pops case is tricky, since pop causes dependency
19275 ;; on destination register.  We use two registers if available.
19276 (define_peephole2
19277   [(match_scratch:W 1 "r")
19278    (match_scratch:W 2 "r")
19279    (parallel [(set (reg:P SP_REG)
19280                    (plus:P (reg:P SP_REG)
19281                            (match_operand:P 0 "const_int_operand")))
19282               (clobber (reg:CC FLAGS_REG))
19283               (clobber (mem:BLK (scratch)))])]
19284   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19285    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19286   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19287               (clobber (mem:BLK (scratch)))])
19288    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19290 (define_peephole2
19291   [(match_scratch:W 1 "r")
19292    (parallel [(set (reg:P SP_REG)
19293                    (plus:P (reg:P SP_REG)
19294                            (match_operand:P 0 "const_int_operand")))
19295               (clobber (reg:CC FLAGS_REG))
19296               (clobber (mem:BLK (scratch)))])]
19297   "optimize_insn_for_size_p ()
19298    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19299   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19300               (clobber (mem:BLK (scratch)))])
19301    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19303 ;; Convert esp additions to pop.
19304 (define_peephole2
19305   [(match_scratch:W 1 "r")
19306    (parallel [(set (reg:P SP_REG)
19307                    (plus:P (reg:P SP_REG)
19308                            (match_operand:P 0 "const_int_operand")))
19309               (clobber (reg:CC FLAGS_REG))])]
19310   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19311   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19313 ;; Two pops case is tricky, since pop causes dependency
19314 ;; on destination register.  We use two registers if available.
19315 (define_peephole2
19316   [(match_scratch:W 1 "r")
19317    (match_scratch:W 2 "r")
19318    (parallel [(set (reg:P SP_REG)
19319                    (plus:P (reg:P SP_REG)
19320                            (match_operand:P 0 "const_int_operand")))
19321               (clobber (reg:CC FLAGS_REG))])]
19322   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19323   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19324    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19326 (define_peephole2
19327   [(match_scratch:W 1 "r")
19328    (parallel [(set (reg:P SP_REG)
19329                    (plus:P (reg:P SP_REG)
19330                            (match_operand:P 0 "const_int_operand")))
19331               (clobber (reg:CC FLAGS_REG))])]
19332   "optimize_insn_for_size_p ()
19333    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19334   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19335    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19337 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19338 ;; required and register dies.  Similarly for 128 to -128.
19339 (define_peephole2
19340   [(set (match_operand 0 "flags_reg_operand")
19341         (match_operator 1 "compare_operator"
19342           [(match_operand 2 "register_operand")
19343            (match_operand 3 "const_int_operand")]))]
19344   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19345      && incdec_operand (operands[3], GET_MODE (operands[3])))
19346     || (!TARGET_FUSE_CMP_AND_BRANCH
19347         && INTVAL (operands[3]) == 128))
19348    && ix86_match_ccmode (insn, CCGCmode)
19349    && peep2_reg_dead_p (1, operands[2])"
19350   [(parallel [(set (match_dup 0)
19351                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19352               (clobber (match_dup 2))])])
19354 ;; Convert imul by three, five and nine into lea
19355 (define_peephole2
19356   [(parallel
19357     [(set (match_operand:SWI48 0 "register_operand")
19358           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19359                       (match_operand:SWI48 2 "const359_operand")))
19360      (clobber (reg:CC FLAGS_REG))])]
19361   "!TARGET_PARTIAL_REG_STALL
19362    || <MODE>mode == SImode
19363    || optimize_function_for_size_p (cfun)"
19364   [(set (match_dup 0)
19365         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19366                     (match_dup 1)))]
19367   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19369 (define_peephole2
19370   [(parallel
19371     [(set (match_operand:SWI48 0 "register_operand")
19372           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19373                       (match_operand:SWI48 2 "const359_operand")))
19374      (clobber (reg:CC FLAGS_REG))])]
19375   "optimize_insn_for_speed_p ()
19376    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19377   [(set (match_dup 0) (match_dup 1))
19378    (set (match_dup 0)
19379         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19380                     (match_dup 0)))]
19381   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19383 ;; imul $32bit_imm, mem, reg is vector decoded, while
19384 ;; imul $32bit_imm, reg, reg is direct decoded.
19385 (define_peephole2
19386   [(match_scratch:SWI48 3 "r")
19387    (parallel [(set (match_operand:SWI48 0 "register_operand")
19388                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19389                                (match_operand:SWI48 2 "immediate_operand")))
19390               (clobber (reg:CC FLAGS_REG))])]
19391   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19392    && !satisfies_constraint_K (operands[2])"
19393   [(set (match_dup 3) (match_dup 1))
19394    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19395               (clobber (reg:CC FLAGS_REG))])])
19397 (define_peephole2
19398   [(match_scratch:SI 3 "r")
19399    (parallel [(set (match_operand:DI 0 "register_operand")
19400                    (zero_extend:DI
19401                      (mult:SI (match_operand:SI 1 "memory_operand")
19402                               (match_operand:SI 2 "immediate_operand"))))
19403               (clobber (reg:CC FLAGS_REG))])]
19404   "TARGET_64BIT
19405    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19406    && !satisfies_constraint_K (operands[2])"
19407   [(set (match_dup 3) (match_dup 1))
19408    (parallel [(set (match_dup 0)
19409                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19410               (clobber (reg:CC FLAGS_REG))])])
19412 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19413 ;; Convert it into imul reg, reg
19414 ;; It would be better to force assembler to encode instruction using long
19415 ;; immediate, but there is apparently no way to do so.
19416 (define_peephole2
19417   [(parallel [(set (match_operand:SWI248 0 "register_operand")
19418                    (mult:SWI248
19419                     (match_operand:SWI248 1 "nonimmediate_operand")
19420                     (match_operand:SWI248 2 "const_int_operand")))
19421               (clobber (reg:CC FLAGS_REG))])
19422    (match_scratch:SWI248 3 "r")]
19423   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19424    && satisfies_constraint_K (operands[2])"
19425   [(set (match_dup 3) (match_dup 2))
19426    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19427               (clobber (reg:CC FLAGS_REG))])]
19429   if (!rtx_equal_p (operands[0], operands[1]))
19430     emit_move_insn (operands[0], operands[1]);
19433 ;; After splitting up read-modify operations, array accesses with memory
19434 ;; operands might end up in form:
19435 ;;  sall    $2, %eax
19436 ;;  movl    4(%esp), %edx
19437 ;;  addl    %edx, %eax
19438 ;; instead of pre-splitting:
19439 ;;  sall    $2, %eax
19440 ;;  addl    4(%esp), %eax
19441 ;; Turn it into:
19442 ;;  movl    4(%esp), %edx
19443 ;;  leal    (%edx,%eax,4), %eax
19445 (define_peephole2
19446   [(match_scratch:W 5 "r")
19447    (parallel [(set (match_operand 0 "register_operand")
19448                    (ashift (match_operand 1 "register_operand")
19449                            (match_operand 2 "const_int_operand")))
19450                (clobber (reg:CC FLAGS_REG))])
19451    (parallel [(set (match_operand 3 "register_operand")
19452                    (plus (match_dup 0)
19453                          (match_operand 4 "x86_64_general_operand")))
19454                    (clobber (reg:CC FLAGS_REG))])]
19455   "IN_RANGE (INTVAL (operands[2]), 1, 3)
19456    /* Validate MODE for lea.  */
19457    && ((!TARGET_PARTIAL_REG_STALL
19458         && (GET_MODE (operands[0]) == QImode
19459             || GET_MODE (operands[0]) == HImode))
19460        || GET_MODE (operands[0]) == SImode
19461        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19462    && (rtx_equal_p (operands[0], operands[3])
19463        || peep2_reg_dead_p (2, operands[0]))
19464    /* We reorder load and the shift.  */
19465    && !reg_overlap_mentioned_p (operands[0], operands[4])"
19466   [(set (match_dup 5) (match_dup 4))
19467    (set (match_dup 0) (match_dup 1))]
19469   machine_mode op1mode = GET_MODE (operands[1]);
19470   machine_mode mode = op1mode == DImode ? DImode : SImode;
19471   int scale = 1 << INTVAL (operands[2]);
19472   rtx index = gen_lowpart (word_mode, operands[1]);
19473   rtx base = gen_lowpart (word_mode, operands[5]);
19474   rtx dest = gen_lowpart (mode, operands[3]);
19476   operands[1] = gen_rtx_PLUS (word_mode, base,
19477                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19478   if (mode != word_mode)
19479     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19481   operands[5] = base;
19482   if (op1mode != word_mode)
19483     operands[5] = gen_lowpart (op1mode, operands[5]);
19485   operands[0] = dest;
19488 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19489 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19490 ;; caught for use by garbage collectors and the like.  Using an insn that
19491 ;; maps to SIGILL makes it more likely the program will rightfully die.
19492 ;; Keeping with tradition, "6" is in honor of #UD.
19493 (define_insn "trap"
19494   [(trap_if (const_int 1) (const_int 6))]
19495   ""
19497 #ifdef HAVE_AS_IX86_UD2
19498   return "ud2";
19499 #else
19500   return ASM_SHORT "0x0b0f";
19501 #endif
19503   [(set_attr "length" "2")])
19505 (define_insn "ud2"
19506   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19507   ""
19509 #ifdef HAVE_AS_IX86_UD2
19510   return "ud2";
19511 #else
19512   return ASM_SHORT "0x0b0f";
19513 #endif
19515   [(set_attr "length" "2")])
19517 (define_expand "prefetch"
19518   [(prefetch (match_operand 0 "address_operand")
19519              (match_operand:SI 1 "const_int_operand")
19520              (match_operand:SI 2 "const_int_operand"))]
19521   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19523   bool write = INTVAL (operands[1]) != 0;
19524   int locality = INTVAL (operands[2]);
19526   gcc_assert (IN_RANGE (locality, 0, 3));
19528   /* Use 3dNOW prefetch in case we are asking for write prefetch not
19529      supported by SSE counterpart (non-SSE2 athlon machines) or the
19530      SSE prefetch is not available (K6 machines).  Otherwise use SSE
19531      prefetch as it allows specifying of locality.  */
19533   if (write)
19534     {
19535       if (TARGET_PREFETCHWT1)
19536         operands[2] = GEN_INT (MAX (locality, 2)); 
19537       else if (TARGET_PRFCHW)
19538         operands[2] = GEN_INT (3);
19539       else if (TARGET_3DNOW && !TARGET_SSE2)
19540         operands[2] = GEN_INT (3);
19541       else if (TARGET_PREFETCH_SSE)
19542         operands[1] = const0_rtx;
19543       else
19544         {
19545           gcc_assert (TARGET_3DNOW);
19546           operands[2] = GEN_INT (3);
19547         }
19548     }
19549   else
19550     {
19551       if (TARGET_PREFETCH_SSE)
19552         ;
19553       else
19554         {
19555           gcc_assert (TARGET_3DNOW);
19556           operands[2] = GEN_INT (3);
19557         }
19558     }
19561 (define_insn "*prefetch_sse"
19562   [(prefetch (match_operand 0 "address_operand" "p")
19563              (const_int 0)
19564              (match_operand:SI 1 "const_int_operand"))]
19565   "TARGET_PREFETCH_SSE"
19567   static const char * const patterns[4] = {
19568    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19569   };
19571   int locality = INTVAL (operands[1]);
19572   gcc_assert (IN_RANGE (locality, 0, 3));
19574   return patterns[locality];
19576   [(set_attr "type" "sse")
19577    (set_attr "atom_sse_attr" "prefetch")
19578    (set (attr "length_address")
19579         (symbol_ref "memory_address_length (operands[0], false)"))
19580    (set_attr "memory" "none")])
19582 (define_insn "*prefetch_3dnow"
19583   [(prefetch (match_operand 0 "address_operand" "p")
19584              (match_operand:SI 1 "const_int_operand" "n")
19585              (const_int 3))]
19586   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19588   if (INTVAL (operands[1]) == 0)
19589     return "prefetch\t%a0";
19590   else
19591     return "prefetchw\t%a0";
19593   [(set_attr "type" "mmx")
19594    (set (attr "length_address")
19595         (symbol_ref "memory_address_length (operands[0], false)"))
19596    (set_attr "memory" "none")])
19598 (define_insn "*prefetch_prefetchwt1"
19599   [(prefetch (match_operand 0 "address_operand" "p")
19600              (const_int 1)
19601              (const_int 2))]
19602   "TARGET_PREFETCHWT1"
19603   "prefetchwt1\t%a0";
19604   [(set_attr "type" "sse")
19605    (set (attr "length_address")
19606         (symbol_ref "memory_address_length (operands[0], false)"))
19607    (set_attr "memory" "none")])
19609 (define_expand "stack_protect_set"
19610   [(match_operand 0 "memory_operand")
19611    (match_operand 1 "memory_operand")]
19612   "TARGET_SSP_TLS_GUARD"
19614   rtx (*insn)(rtx, rtx);
19616   insn = (TARGET_LP64
19617           ? gen_stack_protect_set_di
19618           : gen_stack_protect_set_si);
19620   emit_insn (insn (operands[0], operands[1]));
19621   DONE;
19624 (define_insn "stack_protect_set_<mode>"
19625   [(set (match_operand:PTR 0 "memory_operand" "=m")
19626         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19627                     UNSPEC_SP_SET))
19628    (set (match_scratch:PTR 2 "=&r") (const_int 0))
19629    (clobber (reg:CC FLAGS_REG))]
19630   "TARGET_SSP_TLS_GUARD"
19631   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19632   [(set_attr "type" "multi")])
19634 (define_expand "stack_protect_test"
19635   [(match_operand 0 "memory_operand")
19636    (match_operand 1 "memory_operand")
19637    (match_operand 2)]
19638   "TARGET_SSP_TLS_GUARD"
19640   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19642   rtx (*insn)(rtx, rtx, rtx);
19644   insn = (TARGET_LP64
19645           ? gen_stack_protect_test_di
19646           : gen_stack_protect_test_si);
19648   emit_insn (insn (flags, operands[0], operands[1]));
19650   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19651                                   flags, const0_rtx, operands[2]));
19652   DONE;
19655 (define_insn "stack_protect_test_<mode>"
19656   [(set (match_operand:CCZ 0 "flags_reg_operand")
19657         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19658                      (match_operand:PTR 2 "memory_operand" "m")]
19659                     UNSPEC_SP_TEST))
19660    (clobber (match_scratch:PTR 3 "=&r"))]
19661   "TARGET_SSP_TLS_GUARD"
19662   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19663   [(set_attr "type" "multi")])
19665 (define_insn "sse4_2_crc32<mode>"
19666   [(set (match_operand:SI 0 "register_operand" "=r")
19667         (unspec:SI
19668           [(match_operand:SI 1 "register_operand" "0")
19669            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19670           UNSPEC_CRC32))]
19671   "TARGET_SSE4_2 || TARGET_CRC32"
19672   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19673   [(set_attr "type" "sselog1")
19674    (set_attr "prefix_rep" "1")
19675    (set_attr "prefix_extra" "1")
19676    (set (attr "prefix_data16")
19677      (if_then_else (match_operand:HI 2)
19678        (const_string "1")
19679        (const_string "*")))
19680    (set (attr "prefix_rex")
19681      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19682        (const_string "1")
19683        (const_string "*")))
19684    (set_attr "mode" "SI")])
19686 (define_insn "sse4_2_crc32di"
19687   [(set (match_operand:DI 0 "register_operand" "=r")
19688         (unspec:DI
19689           [(match_operand:DI 1 "register_operand" "0")
19690            (match_operand:DI 2 "nonimmediate_operand" "rm")]
19691           UNSPEC_CRC32))]
19692   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19693   "crc32{q}\t{%2, %0|%0, %2}"
19694   [(set_attr "type" "sselog1")
19695    (set_attr "prefix_rep" "1")
19696    (set_attr "prefix_extra" "1")
19697    (set_attr "mode" "DI")])
19699 (define_insn "rdpmc"
19700   [(set (match_operand:DI 0 "register_operand" "=A")
19701         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19702                             UNSPECV_RDPMC))]
19703   "!TARGET_64BIT"
19704   "rdpmc"
19705   [(set_attr "type" "other")
19706    (set_attr "length" "2")])
19708 (define_insn "rdpmc_rex64"
19709   [(set (match_operand:DI 0 "register_operand" "=a")
19710         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19711                             UNSPECV_RDPMC))
19712    (set (match_operand:DI 1 "register_operand" "=d")
19713         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19714   "TARGET_64BIT"
19715   "rdpmc"
19716   [(set_attr "type" "other")
19717    (set_attr "length" "2")])
19719 (define_insn "rdtsc"
19720   [(set (match_operand:DI 0 "register_operand" "=A")
19721         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19722   "!TARGET_64BIT"
19723   "rdtsc"
19724   [(set_attr "type" "other")
19725    (set_attr "length" "2")])
19727 (define_insn "rdtsc_rex64"
19728   [(set (match_operand:DI 0 "register_operand" "=a")
19729         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19730    (set (match_operand:DI 1 "register_operand" "=d")
19731         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19732   "TARGET_64BIT"
19733   "rdtsc"
19734   [(set_attr "type" "other")
19735    (set_attr "length" "2")])
19737 (define_insn "rdtscp"
19738   [(set (match_operand:DI 0 "register_operand" "=A")
19739         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19740    (set (match_operand:SI 1 "register_operand" "=c")
19741         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19742   "!TARGET_64BIT"
19743   "rdtscp"
19744   [(set_attr "type" "other")
19745    (set_attr "length" "3")])
19747 (define_insn "rdtscp_rex64"
19748   [(set (match_operand:DI 0 "register_operand" "=a")
19749         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19750    (set (match_operand:DI 1 "register_operand" "=d")
19751         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19752    (set (match_operand:SI 2 "register_operand" "=c")
19753         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19754   "TARGET_64BIT"
19755   "rdtscp"
19756   [(set_attr "type" "other")
19757    (set_attr "length" "3")])
19759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19761 ;; FXSR, XSAVE and XSAVEOPT instructions
19763 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19765 (define_insn "fxsave"
19766   [(set (match_operand:BLK 0 "memory_operand" "=m")
19767         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19768   "TARGET_FXSR"
19769   "fxsave\t%0"
19770   [(set_attr "type" "other")
19771    (set_attr "memory" "store")
19772    (set (attr "length")
19773         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19775 (define_insn "fxsave64"
19776   [(set (match_operand:BLK 0 "memory_operand" "=m")
19777         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19778   "TARGET_64BIT && TARGET_FXSR"
19779   "fxsave64\t%0"
19780   [(set_attr "type" "other")
19781    (set_attr "memory" "store")
19782    (set (attr "length")
19783         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19785 (define_insn "fxrstor"
19786   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19787                     UNSPECV_FXRSTOR)]
19788   "TARGET_FXSR"
19789   "fxrstor\t%0"
19790   [(set_attr "type" "other")
19791    (set_attr "memory" "load")
19792    (set (attr "length")
19793         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19795 (define_insn "fxrstor64"
19796   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19797                     UNSPECV_FXRSTOR64)]
19798   "TARGET_64BIT && TARGET_FXSR"
19799   "fxrstor64\t%0"
19800   [(set_attr "type" "other")
19801    (set_attr "memory" "load")
19802    (set (attr "length")
19803         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19805 (define_int_iterator ANY_XSAVE
19806         [UNSPECV_XSAVE
19807          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19808          (UNSPECV_XSAVEC "TARGET_XSAVEC")
19809          (UNSPECV_XSAVES "TARGET_XSAVES")])
19811 (define_int_iterator ANY_XSAVE64
19812         [UNSPECV_XSAVE64
19813          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19814          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19815          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19817 (define_int_attr xsave
19818         [(UNSPECV_XSAVE "xsave")
19819          (UNSPECV_XSAVE64 "xsave64")
19820          (UNSPECV_XSAVEOPT "xsaveopt")
19821          (UNSPECV_XSAVEOPT64 "xsaveopt64")
19822          (UNSPECV_XSAVEC "xsavec")
19823          (UNSPECV_XSAVEC64 "xsavec64")
19824          (UNSPECV_XSAVES "xsaves")
19825          (UNSPECV_XSAVES64 "xsaves64")])
19827 (define_int_iterator ANY_XRSTOR
19828         [UNSPECV_XRSTOR
19829          (UNSPECV_XRSTORS "TARGET_XSAVES")])
19831 (define_int_iterator ANY_XRSTOR64
19832         [UNSPECV_XRSTOR64
19833          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19835 (define_int_attr xrstor
19836         [(UNSPECV_XRSTOR "xrstor")
19837          (UNSPECV_XRSTOR64 "xrstor")
19838          (UNSPECV_XRSTORS "xrstors")
19839          (UNSPECV_XRSTORS64 "xrstors")])
19841 (define_insn "<xsave>"
19842   [(set (match_operand:BLK 0 "memory_operand" "=m")
19843         (unspec_volatile:BLK
19844          [(match_operand:DI 1 "register_operand" "A")]
19845          ANY_XSAVE))]
19846   "!TARGET_64BIT && TARGET_XSAVE"
19847   "<xsave>\t%0"
19848   [(set_attr "type" "other")
19849    (set_attr "memory" "store")
19850    (set (attr "length")
19851         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19853 (define_insn "<xsave>_rex64"
19854   [(set (match_operand:BLK 0 "memory_operand" "=m")
19855         (unspec_volatile:BLK
19856          [(match_operand:SI 1 "register_operand" "a")
19857           (match_operand:SI 2 "register_operand" "d")]
19858          ANY_XSAVE))]
19859   "TARGET_64BIT && TARGET_XSAVE"
19860   "<xsave>\t%0"
19861   [(set_attr "type" "other")
19862    (set_attr "memory" "store")
19863    (set (attr "length")
19864         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19866 (define_insn "<xsave>"
19867   [(set (match_operand:BLK 0 "memory_operand" "=m")
19868         (unspec_volatile:BLK
19869          [(match_operand:SI 1 "register_operand" "a")
19870           (match_operand:SI 2 "register_operand" "d")]
19871          ANY_XSAVE64))]
19872   "TARGET_64BIT && TARGET_XSAVE"
19873   "<xsave>\t%0"
19874   [(set_attr "type" "other")
19875    (set_attr "memory" "store")
19876    (set (attr "length")
19877         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19879 (define_insn "<xrstor>"
19880    [(unspec_volatile:BLK
19881      [(match_operand:BLK 0 "memory_operand" "m")
19882       (match_operand:DI 1 "register_operand" "A")]
19883      ANY_XRSTOR)]
19884   "!TARGET_64BIT && TARGET_XSAVE"
19885   "<xrstor>\t%0"
19886   [(set_attr "type" "other")
19887    (set_attr "memory" "load")
19888    (set (attr "length")
19889         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19891 (define_insn "<xrstor>_rex64"
19892    [(unspec_volatile:BLK
19893      [(match_operand:BLK 0 "memory_operand" "m")
19894       (match_operand:SI 1 "register_operand" "a")
19895       (match_operand:SI 2 "register_operand" "d")]
19896      ANY_XRSTOR)]
19897   "TARGET_64BIT && TARGET_XSAVE"
19898   "<xrstor>\t%0"
19899   [(set_attr "type" "other")
19900    (set_attr "memory" "load")
19901    (set (attr "length")
19902         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19904 (define_insn "<xrstor>64"
19905    [(unspec_volatile:BLK
19906      [(match_operand:BLK 0 "memory_operand" "m")
19907       (match_operand:SI 1 "register_operand" "a")
19908       (match_operand:SI 2 "register_operand" "d")]
19909      ANY_XRSTOR64)]
19910   "TARGET_64BIT && TARGET_XSAVE"
19911   "<xrstor>64\t%0"
19912   [(set_attr "type" "other")
19913    (set_attr "memory" "load")
19914    (set (attr "length")
19915         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19917 (define_insn "xsetbv"
19918   [(unspec_volatile:SI
19919          [(match_operand:SI 0 "register_operand" "c")
19920           (match_operand:DI 1 "register_operand" "A")]
19921          UNSPECV_XSETBV)]
19922   "!TARGET_64BIT && TARGET_XSAVE"
19923   "xsetbv"
19924   [(set_attr "type" "other")])
19926 (define_insn "xsetbv_rex64"
19927   [(unspec_volatile:SI
19928          [(match_operand:SI 0 "register_operand" "c")
19929           (match_operand:SI 1 "register_operand" "a")
19930           (match_operand:SI 2 "register_operand" "d")]
19931          UNSPECV_XSETBV)]
19932   "TARGET_64BIT && TARGET_XSAVE"
19933   "xsetbv"
19934   [(set_attr "type" "other")])
19936 (define_insn "xgetbv"
19937   [(set (match_operand:DI 0 "register_operand" "=A")
19938         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19939                             UNSPECV_XGETBV))]
19940   "!TARGET_64BIT && TARGET_XSAVE"
19941   "xgetbv"
19942   [(set_attr "type" "other")])
19944 (define_insn "xgetbv_rex64"
19945   [(set (match_operand:DI 0 "register_operand" "=a")
19946         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19947                             UNSPECV_XGETBV))
19948    (set (match_operand:DI 1 "register_operand" "=d")
19949         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19950   "TARGET_64BIT && TARGET_XSAVE"
19951   "xgetbv"
19952   [(set_attr "type" "other")])
19954 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19956 ;; Floating-point instructions for atomic compound assignments
19958 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19960 ; Clobber all floating-point registers on environment save and restore
19961 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19962 (define_insn "fnstenv"
19963   [(set (match_operand:BLK 0 "memory_operand" "=m")
19964         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19965    (clobber (reg:HI FPCR_REG))
19966    (clobber (reg:XF ST0_REG))
19967    (clobber (reg:XF ST1_REG))
19968    (clobber (reg:XF ST2_REG))
19969    (clobber (reg:XF ST3_REG))
19970    (clobber (reg:XF ST4_REG))
19971    (clobber (reg:XF ST5_REG))
19972    (clobber (reg:XF ST6_REG))
19973    (clobber (reg:XF ST7_REG))]
19974   "TARGET_80387"
19975   "fnstenv\t%0"
19976   [(set_attr "type" "other")
19977    (set_attr "memory" "store")
19978    (set (attr "length")
19979         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19981 (define_insn "fldenv"
19982   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19983                     UNSPECV_FLDENV)
19984    (clobber (reg:CCFP FPSR_REG))
19985    (clobber (reg:HI FPCR_REG))
19986    (clobber (reg:XF ST0_REG))
19987    (clobber (reg:XF ST1_REG))
19988    (clobber (reg:XF ST2_REG))
19989    (clobber (reg:XF ST3_REG))
19990    (clobber (reg:XF ST4_REG))
19991    (clobber (reg:XF ST5_REG))
19992    (clobber (reg:XF ST6_REG))
19993    (clobber (reg:XF ST7_REG))]
19994   "TARGET_80387"
19995   "fldenv\t%0"
19996   [(set_attr "type" "other")
19997    (set_attr "memory" "load")
19998    (set (attr "length")
19999         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20001 (define_insn "fnstsw"
20002   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20003         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20004   "TARGET_80387"
20005   "fnstsw\t%0"
20006   [(set_attr "type" "other,other")
20007    (set_attr "memory" "none,store")
20008    (set (attr "length")
20009         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20011 (define_insn "fnclex"
20012   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20013   "TARGET_80387"
20014   "fnclex"
20015   [(set_attr "type" "other")
20016    (set_attr "memory" "none")
20017    (set_attr "length" "2")])
20019 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20021 ;; LWP instructions
20023 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20025 (define_expand "lwp_llwpcb"
20026   [(unspec_volatile [(match_operand 0 "register_operand")]
20027                     UNSPECV_LLWP_INTRINSIC)]
20028   "TARGET_LWP")
20030 (define_insn "*lwp_llwpcb<mode>1"
20031   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20032                     UNSPECV_LLWP_INTRINSIC)]
20033   "TARGET_LWP"
20034   "llwpcb\t%0"
20035   [(set_attr "type" "lwp")
20036    (set_attr "mode" "<MODE>")
20037    (set_attr "length" "5")])
20039 (define_expand "lwp_slwpcb"
20040   [(set (match_operand 0 "register_operand")
20041         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20042   "TARGET_LWP"
20044   rtx (*insn)(rtx);
20046   insn = (Pmode == DImode
20047           ? gen_lwp_slwpcbdi
20048           : gen_lwp_slwpcbsi);
20050   emit_insn (insn (operands[0]));
20051   DONE;
20054 (define_insn "lwp_slwpcb<mode>"
20055   [(set (match_operand:P 0 "register_operand" "=r")
20056         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20057   "TARGET_LWP"
20058   "slwpcb\t%0"
20059   [(set_attr "type" "lwp")
20060    (set_attr "mode" "<MODE>")
20061    (set_attr "length" "5")])
20063 (define_expand "lwp_lwpval<mode>3"
20064   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20065                      (match_operand:SI 2 "nonimmediate_operand")
20066                      (match_operand:SI 3 "const_int_operand")]
20067                     UNSPECV_LWPVAL_INTRINSIC)]
20068   "TARGET_LWP"
20069   ;; Avoid unused variable warning.
20070   "(void) operands[0];")
20072 (define_insn "*lwp_lwpval<mode>3_1"
20073   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20074                      (match_operand:SI 1 "nonimmediate_operand" "rm")
20075                      (match_operand:SI 2 "const_int_operand" "i")]
20076                     UNSPECV_LWPVAL_INTRINSIC)]
20077   "TARGET_LWP"
20078   "lwpval\t{%2, %1, %0|%0, %1, %2}"
20079   [(set_attr "type" "lwp")
20080    (set_attr "mode" "<MODE>")
20081    (set (attr "length")
20082         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20084 (define_expand "lwp_lwpins<mode>3"
20085   [(set (reg:CCC FLAGS_REG)
20086         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20087                               (match_operand:SI 2 "nonimmediate_operand")
20088                               (match_operand:SI 3 "const_int_operand")]
20089                              UNSPECV_LWPINS_INTRINSIC))
20090    (set (match_operand:QI 0 "nonimmediate_operand")
20091         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20092   "TARGET_LWP")
20094 (define_insn "*lwp_lwpins<mode>3_1"
20095   [(set (reg:CCC FLAGS_REG)
20096         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20097                               (match_operand:SI 1 "nonimmediate_operand" "rm")
20098                               (match_operand:SI 2 "const_int_operand" "i")]
20099                              UNSPECV_LWPINS_INTRINSIC))]
20100   "TARGET_LWP"
20101   "lwpins\t{%2, %1, %0|%0, %1, %2}"
20102   [(set_attr "type" "lwp")
20103    (set_attr "mode" "<MODE>")
20104    (set (attr "length")
20105         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20107 (define_int_iterator RDFSGSBASE
20108         [UNSPECV_RDFSBASE
20109          UNSPECV_RDGSBASE])
20111 (define_int_iterator WRFSGSBASE
20112         [UNSPECV_WRFSBASE
20113          UNSPECV_WRGSBASE])
20115 (define_int_attr fsgs
20116         [(UNSPECV_RDFSBASE "fs")
20117          (UNSPECV_RDGSBASE "gs")
20118          (UNSPECV_WRFSBASE "fs")
20119          (UNSPECV_WRGSBASE "gs")])
20121 (define_insn "rd<fsgs>base<mode>"
20122   [(set (match_operand:SWI48 0 "register_operand" "=r")
20123         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20124   "TARGET_64BIT && TARGET_FSGSBASE"
20125   "rd<fsgs>base\t%0"
20126   [(set_attr "type" "other")
20127    (set_attr "prefix_extra" "2")])
20129 (define_insn "wr<fsgs>base<mode>"
20130   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20131                     WRFSGSBASE)]
20132   "TARGET_64BIT && TARGET_FSGSBASE"
20133   "wr<fsgs>base\t%0"
20134   [(set_attr "type" "other")
20135    (set_attr "prefix_extra" "2")])
20137 (define_insn "rdrand<mode>_1"
20138   [(set (match_operand:SWI248 0 "register_operand" "=r")
20139         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20140    (set (reg:CCC FLAGS_REG)
20141         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20142   "TARGET_RDRND"
20143   "rdrand\t%0"
20144   [(set_attr "type" "other")
20145    (set_attr "prefix_extra" "1")])
20147 (define_insn "rdseed<mode>_1"
20148   [(set (match_operand:SWI248 0 "register_operand" "=r")
20149         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20150    (set (reg:CCC FLAGS_REG)
20151         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20152   "TARGET_RDSEED"
20153   "rdseed\t%0"
20154   [(set_attr "type" "other")
20155    (set_attr "prefix_extra" "1")])
20157 (define_expand "pause"
20158   [(set (match_dup 0)
20159         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20160   ""
20162   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20163   MEM_VOLATILE_P (operands[0]) = 1;
20166 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20167 ;; They have the same encoding.
20168 (define_insn "*pause"
20169   [(set (match_operand:BLK 0)
20170         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20171   ""
20172   "rep%; nop"
20173   [(set_attr "length" "2")
20174    (set_attr "memory" "unknown")])
20176 ;; CET instructions
20177 (define_insn "rdssp<mode>"
20178   [(set (match_operand:SWI48x 0 "register_operand" "=r")
20179         (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20180   "TARGET_SHSTK"
20181   "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20182   [(set_attr "length" "6")
20183    (set_attr "type" "other")])
20185 (define_insn "incssp<mode>"
20186   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20187                    UNSPECV_INCSSP)]
20188   "TARGET_SHSTK"
20189   "incssp<mskmodesuffix>\t%0"
20190   [(set_attr "length" "4")
20191    (set_attr "type" "other")])
20193 (define_insn "saveprevssp"
20194   [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20195   "TARGET_SHSTK"
20196   "saveprevssp"
20197   [(set_attr "length" "5")
20198    (set_attr "type" "other")])
20200 (define_insn "rstorssp"
20201   [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20202                    UNSPECV_RSTORSSP)]
20203   "TARGET_SHSTK"
20204   "rstorssp\t%0"
20205   [(set_attr "length" "5")
20206    (set_attr "type" "other")])
20208 (define_insn "wrss<mode>"
20209   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20210                      (match_operand:SWI48x 1 "memory_operand" "m")]
20211                    UNSPECV_WRSS)]
20212   "TARGET_SHSTK"
20213   "wrss<mskmodesuffix>\t%0, %1"
20214   [(set_attr "length" "3")
20215    (set_attr "type" "other")])
20217 (define_insn "wruss<mode>"
20218   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20219                      (match_operand:SWI48x 1 "memory_operand" "m")]
20220                    UNSPECV_WRUSS)]
20221   "TARGET_SHSTK"
20222   "wruss<mskmodesuffix>\t%0, %1"
20223   [(set_attr "length" "4")
20224    (set_attr "type" "other")])
20226 (define_insn "setssbsy"
20227   [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20228   "TARGET_SHSTK"
20229   "setssbsy"
20230   [(set_attr "length" "4")
20231    (set_attr "type" "other")])
20233 (define_insn "clrssbsy"
20234   [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20235                    UNSPECV_CLRSSBSY)]
20236   "TARGET_SHSTK"
20237   "clrssbsy\t%0"
20238   [(set_attr "length" "4")
20239    (set_attr "type" "other")])
20241 (define_insn "nop_endbr"
20242   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20243   "TARGET_IBT"
20244   "*
20245 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20246   [(set_attr "length" "4")
20247    (set_attr "length_immediate" "0")
20248    (set_attr "modrm" "0")])
20250 ;; For RTM support
20251 (define_expand "xbegin"
20252   [(set (match_operand:SI 0 "register_operand")
20253         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20254   "TARGET_RTM"
20256   rtx_code_label *label = gen_label_rtx ();
20258   /* xbegin is emitted as jump_insn, so reload won't be able
20259      to reload its operand.  Force the value into AX hard register.  */
20260   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20261   emit_move_insn (ax_reg, constm1_rtx);
20263   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20265   emit_label (label);
20266   LABEL_NUSES (label) = 1;
20268   emit_move_insn (operands[0], ax_reg);
20270   DONE;
20273 (define_insn "xbegin_1"
20274   [(set (pc)
20275         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20276                           (const_int 0))
20277                       (label_ref (match_operand 1))
20278                       (pc)))
20279    (set (match_operand:SI 0 "register_operand" "+a")
20280         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20281   "TARGET_RTM"
20282   "xbegin\t%l1"
20283   [(set_attr "type" "other")
20284    (set_attr "length" "6")])
20286 (define_insn "xend"
20287   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20288   "TARGET_RTM"
20289   "xend"
20290   [(set_attr "type" "other")
20291    (set_attr "length" "3")])
20293 (define_insn "xabort"
20294   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20295                     UNSPECV_XABORT)]
20296   "TARGET_RTM"
20297   "xabort\t%0"
20298   [(set_attr "type" "other")
20299    (set_attr "length" "3")])
20301 (define_expand "xtest"
20302   [(set (match_operand:QI 0 "register_operand")
20303         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20304   "TARGET_RTM"
20306   emit_insn (gen_xtest_1 ());
20308   ix86_expand_setcc (operands[0], NE,
20309                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20310   DONE;
20313 (define_insn "xtest_1"
20314   [(set (reg:CCZ FLAGS_REG)
20315         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20316   "TARGET_RTM"
20317   "xtest"
20318   [(set_attr "type" "other")
20319    (set_attr "length" "3")])
20321 (define_insn "clwb"
20322   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20323                    UNSPECV_CLWB)]
20324   "TARGET_CLWB"
20325   "clwb\t%a0"
20326   [(set_attr "type" "sse")
20327    (set_attr "atom_sse_attr" "fence")
20328    (set_attr "memory" "unknown")])
20330 (define_insn "clflushopt"
20331   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20332                    UNSPECV_CLFLUSHOPT)]
20333   "TARGET_CLFLUSHOPT"
20334   "clflushopt\t%a0"
20335   [(set_attr "type" "sse")
20336    (set_attr "atom_sse_attr" "fence")
20337    (set_attr "memory" "unknown")])
20339 ;; MONITORX and MWAITX
20340 (define_insn "mwaitx"
20341   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20342                      (match_operand:SI 1 "register_operand" "a")
20343                      (match_operand:SI 2 "register_operand" "b")]
20344                    UNSPECV_MWAITX)]
20345   "TARGET_MWAITX"
20346 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20347 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20348 ;; we only need to set up 32bit registers.
20349   "mwaitx"
20350   [(set_attr "length" "3")])
20352 (define_insn "monitorx_<mode>"
20353   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20354                      (match_operand:SI 1 "register_operand" "c")
20355                      (match_operand:SI 2 "register_operand" "d")]
20356                    UNSPECV_MONITORX)]
20357   "TARGET_MWAITX"
20358 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20359 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
20360 ;; zero extended to 64bit, we only need to set up 32bit registers.
20361   "%^monitorx"
20362   [(set (attr "length")
20363      (symbol_ref ("(Pmode != word_mode) + 3")))])
20365 ;; CLZERO
20366 (define_insn "clzero_<mode>"
20367   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20368                    UNSPECV_CLZERO)]
20369   "TARGET_CLZERO"
20370   "clzero"
20371   [(set_attr "length" "3")
20372   (set_attr "memory" "unknown")])
20374 ;; MPX instructions
20376 (define_expand "<mode>_mk"
20377   [(set (match_operand:BND 0 "register_operand")
20378         (unspec:BND
20379           [(mem:<bnd_ptr>
20380            (match_par_dup 3
20381              [(match_operand:<bnd_ptr> 1 "register_operand")
20382               (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20383           UNSPEC_BNDMK))]
20384   "TARGET_MPX"
20386   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20387                                                   operands[2]),
20388                                 UNSPEC_BNDMK_ADDR);
20391 (define_insn "*<mode>_mk"
20392   [(set (match_operand:BND 0 "register_operand" "=w")
20393         (unspec:BND
20394           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20395              [(unspec:<bnd_ptr>
20396                 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
20397                  (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20398                 UNSPEC_BNDMK_ADDR)])]
20399           UNSPEC_BNDMK))]
20400   "TARGET_MPX"
20401   "bndmk\t{%3, %0|%0, %3}"
20402   [(set_attr "type" "mpxmk")])
20404 (define_expand "mov<mode>"
20405   [(set (match_operand:BND 0 "general_operand")
20406         (match_operand:BND 1 "general_operand"))]
20407   "TARGET_MPX"
20408   "ix86_expand_move (<MODE>mode, operands); DONE;")
20410 (define_insn "*mov<mode>_internal_mpx"
20411   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20412         (match_operand:BND 1 "general_operand" "wm,w"))]
20413   "TARGET_MPX"
20414   "bndmov\t{%1, %0|%0, %1}"
20415   [(set_attr "type" "mpxmov")])
20417 (define_expand "<mode>_<bndcheck>"
20418   [(parallel
20419      [(unspec
20420         [(match_operand:BND 0 "register_operand")
20421          (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20422       (set (match_dup 2)
20423            (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20424   "TARGET_MPX"
20426   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20427   MEM_VOLATILE_P (operands[2]) = 1;
20430 (define_insn "*<mode>_<bndcheck>"
20431   [(unspec
20432      [(match_operand:BND 0 "register_operand" "w")
20433       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20434    (set (match_operand:BLK 2 "bnd_mem_operator")
20435         (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20436   "TARGET_MPX"
20437   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20438   [(set_attr "type" "mpxchk")])
20440 (define_expand "<mode>_ldx"
20441   [(parallel
20442      [(set (match_operand:BND 0 "register_operand")
20443            (unspec:BND
20444              [(mem:<bnd_ptr>
20445                 (match_par_dup 3
20446                   [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20447                    (match_operand:<bnd_ptr> 2 "register_operand")]))]
20448              UNSPEC_BNDLDX))
20449       (use (mem:BLK (match_dup 1)))])]
20450   "TARGET_MPX"
20452   /* Avoid registers which cannot be used as index.  */
20453   if (!index_register_operand (operands[2], Pmode))
20454     operands[2] = copy_addr_to_reg (operands[2]);
20456   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20457                                                   operands[2]),
20458                                 UNSPEC_BNDLDX_ADDR);
20461 (define_insn "*<mode>_ldx"
20462   [(set (match_operand:BND 0 "register_operand" "=w")
20463         (unspec:BND
20464           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20465              [(unspec:<bnd_ptr>
20466                 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20467                  (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20468                 UNSPEC_BNDLDX_ADDR)])]
20469           UNSPEC_BNDLDX))
20470    (use (mem:BLK (match_dup 1)))]
20471   "TARGET_MPX"
20472   "bndldx\t{%3, %0|%0, %3}"
20473   [(set_attr "type" "mpxld")])
20475 (define_expand "<mode>_stx"
20476   [(parallel
20477      [(unspec
20478         [(mem:<bnd_ptr>
20479            (match_par_dup 3
20480              [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20481               (match_operand:<bnd_ptr> 1 "register_operand")]))
20482          (match_operand:BND 2 "register_operand")]
20483         UNSPEC_BNDSTX)
20484       (set (match_dup 4)
20485            (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20486   "TARGET_MPX"
20488   /* Avoid registers which cannot be used as index.  */
20489   if (!index_register_operand (operands[1], Pmode))
20490     operands[1] = copy_addr_to_reg (operands[1]);
20492   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20493                                                   operands[1]),
20494                                 UNSPEC_BNDLDX_ADDR);
20495   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20496   MEM_VOLATILE_P (operands[4]) = 1;
20499 (define_insn "*<mode>_stx"
20500   [(unspec
20501      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20502         [(unspec:<bnd_ptr>
20503            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20504             (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20505            UNSPEC_BNDLDX_ADDR)])
20506          (match_operand:BND 2 "register_operand" "w")]
20507         UNSPEC_BNDSTX)
20508    (set (match_operand:BLK 4 "bnd_mem_operator")
20509         (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20510   "TARGET_MPX"
20511   "bndstx\t{%2, %3|%3, %2}"
20512   [(set_attr "type" "mpxst")])
20514 (define_insn "move_size_reloc_<mode>"
20515   [(set (match_operand:SWI48 0 "register_operand" "=r")
20516         (unspec:SWI48
20517           [(match_operand:SWI48 1 "symbol_operand")]
20518         UNSPEC_SIZEOF))]
20519   "TARGET_MPX"
20521   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20522     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20523   else
20524     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20526   [(set_attr "type" "imov")
20527    (set_attr "mode" "<MODE>")])
20529 ;; RDPKRU and WRPKRU
20531 (define_expand "rdpkru"
20532   [(parallel
20533      [(set (match_operand:SI 0 "register_operand")
20534            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20535       (set (match_dup 2) (const_int 0))])]
20536   "TARGET_PKU"
20538   operands[1] = force_reg (SImode, const0_rtx);
20539   operands[2] = gen_reg_rtx (SImode);
20542 (define_insn "*rdpkru"
20543   [(set (match_operand:SI 0 "register_operand" "=a")
20544         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20545                             UNSPECV_PKU))
20546    (set (match_operand:SI 1 "register_operand" "=d")
20547         (const_int 0))]
20548   "TARGET_PKU"
20549   "rdpkru"
20550   [(set_attr "type" "other")])
20552 (define_expand "wrpkru"
20553   [(unspec_volatile:SI
20554      [(match_operand:SI 0 "register_operand")
20555       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20556   "TARGET_PKU"
20558   operands[1] = force_reg (SImode, const0_rtx);
20559   operands[2] = force_reg (SImode, const0_rtx);
20562 (define_insn "*wrpkru"
20563   [(unspec_volatile:SI
20564      [(match_operand:SI 0 "register_operand" "a")
20565       (match_operand:SI 1 "register_operand" "d")
20566       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20567   "TARGET_PKU"
20568   "wrpkru"
20569   [(set_attr "type" "other")])
20571 (define_insn "rdpid"
20572   [(set (match_operand:SI 0 "register_operand" "=r")
20573         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20574   "!TARGET_64BIT && TARGET_RDPID"
20575   "rdpid\t%0"
20576   [(set_attr "type" "other")])
20578 (define_insn "rdpid_rex64"
20579   [(set (match_operand:DI 0 "register_operand" "=r")
20580         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20581   "TARGET_64BIT && TARGET_RDPID"
20582   "rdpid\t%0"
20583   [(set_attr "type" "other")])
20585 (include "mmx.md")
20586 (include "sse.md")
20587 (include "sync.md")