Daily bump.
[official-gcc.git] / gcc / config / i386 / i386.md
blob43227dc77ee94bc93f14baae737c3cad9174ed54
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2017 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 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_PARITY
103   UNSPEC_FSTCW
104   UNSPEC_FLDCW
105   UNSPEC_REP
106   UNSPEC_LD_MPIC        ; load_macho_picbase
107   UNSPEC_TRUNC_NOOP
108   UNSPEC_DIV_ALREADY_SPLIT
109   UNSPEC_PAUSE
110   UNSPEC_LEA_ADDR
111   UNSPEC_XBEGIN_ABORT
112   UNSPEC_STOS
113   UNSPEC_PEEPSIB
114   UNSPEC_INSN_FALSE_DEP
116   ;; For SSE/MMX support:
117   UNSPEC_FIX_NOTRUNC
118   UNSPEC_MASKMOV
119   UNSPEC_MOVMSK
120   UNSPEC_RCP
121   UNSPEC_RSQRT
122   UNSPEC_PSADBW
124   ;; Generic math support
125   UNSPEC_COPYSIGN
126   UNSPEC_IEEE_MIN       ; not commutative
127   UNSPEC_IEEE_MAX       ; not commutative
129   ;; x87 Floating point
130   UNSPEC_SIN
131   UNSPEC_COS
132   UNSPEC_FPATAN
133   UNSPEC_FYL2X
134   UNSPEC_FYL2XP1
135   UNSPEC_FRNDINT
136   UNSPEC_FIST
137   UNSPEC_F2XM1
138   UNSPEC_TAN
139   UNSPEC_FXAM
141   ;; x87 Rounding
142   UNSPEC_FRNDINT_FLOOR
143   UNSPEC_FRNDINT_CEIL
144   UNSPEC_FRNDINT_TRUNC
145   UNSPEC_FRNDINT_MASK_PM
146   UNSPEC_FIST_FLOOR
147   UNSPEC_FIST_CEIL
149   ;; x87 Double output FP
150   UNSPEC_SINCOS_COS
151   UNSPEC_SINCOS_SIN
152   UNSPEC_XTRACT_FRACT
153   UNSPEC_XTRACT_EXP
154   UNSPEC_FSCALE_FRACT
155   UNSPEC_FSCALE_EXP
156   UNSPEC_FPREM_F
157   UNSPEC_FPREM_U
158   UNSPEC_FPREM1_F
159   UNSPEC_FPREM1_U
161   UNSPEC_C2_FLAG
162   UNSPEC_FXAM_MEM
164   ;; SSP patterns
165   UNSPEC_SP_SET
166   UNSPEC_SP_TEST
168   ;; For ROUND support
169   UNSPEC_ROUND
171   ;; For CRC32 support
172   UNSPEC_CRC32
174   ;; For LZCNT suppoprt
175   UNSPEC_LZCNT
177   ;; For BMI support
178   UNSPEC_TZCNT
179   UNSPEC_BEXTR
181   ;; For BMI2 support
182   UNSPEC_PDEP
183   UNSPEC_PEXT
185   UNSPEC_BNDMK
186   UNSPEC_BNDMK_ADDR
187   UNSPEC_BNDSTX
188   UNSPEC_BNDLDX
189   UNSPEC_BNDLDX_ADDR
190   UNSPEC_BNDCL
191   UNSPEC_BNDCU
192   UNSPEC_BNDCN
193   UNSPEC_MPX_FENCE
195   ;; IRET support
196   UNSPEC_INTERRUPT_RETURN
199 (define_c_enum "unspecv" [
200   UNSPECV_UD2
201   UNSPECV_BLOCKAGE
202   UNSPECV_STACK_PROBE
203   UNSPECV_PROBE_STACK_RANGE
204   UNSPECV_ALIGN
205   UNSPECV_PROLOGUE_USE
206   UNSPECV_SPLIT_STACK_RETURN
207   UNSPECV_CLD
208   UNSPECV_NOPS
209   UNSPECV_RDTSC
210   UNSPECV_RDTSCP
211   UNSPECV_RDPMC
212   UNSPECV_LLWP_INTRINSIC
213   UNSPECV_SLWP_INTRINSIC
214   UNSPECV_LWPVAL_INTRINSIC
215   UNSPECV_LWPINS_INTRINSIC
216   UNSPECV_RDFSBASE
217   UNSPECV_RDGSBASE
218   UNSPECV_WRFSBASE
219   UNSPECV_WRGSBASE
220   UNSPECV_FXSAVE
221   UNSPECV_FXRSTOR
222   UNSPECV_FXSAVE64
223   UNSPECV_FXRSTOR64
224   UNSPECV_XSAVE
225   UNSPECV_XRSTOR
226   UNSPECV_XSAVE64
227   UNSPECV_XRSTOR64
228   UNSPECV_XSAVEOPT
229   UNSPECV_XSAVEOPT64
230   UNSPECV_XSAVES
231   UNSPECV_XRSTORS
232   UNSPECV_XSAVES64
233   UNSPECV_XRSTORS64
234   UNSPECV_XSAVEC
235   UNSPECV_XSAVEC64
236   UNSPECV_XGETBV
237   UNSPECV_XSETBV
239   ;; For atomic compound assignments.
240   UNSPECV_FNSTENV
241   UNSPECV_FLDENV
242   UNSPECV_FNSTSW
243   UNSPECV_FNCLEX
245   ;; For RDRAND support
246   UNSPECV_RDRAND
248   ;; For RDSEED support
249   UNSPECV_RDSEED
251   ;; For RTM support
252   UNSPECV_XBEGIN
253   UNSPECV_XEND
254   UNSPECV_XABORT
255   UNSPECV_XTEST
257   UNSPECV_NLGR
259   ;; For CLWB support
260   UNSPECV_CLWB
262   ;; For CLFLUSHOPT support
263   UNSPECV_CLFLUSHOPT
265   ;; For MONITORX and MWAITX support 
266   UNSPECV_MONITORX
267   UNSPECV_MWAITX
269   ;; For CLZERO support
270   UNSPECV_CLZERO
272   ;; For RDPKRU and WRPKRU support
273   UNSPECV_PKU
275   ;; For RDPID support
276   UNSPECV_RDPID
279 ;; Constants to represent rounding modes in the ROUND instruction
280 (define_constants
281   [(ROUND_FLOOR                 0x1)
282    (ROUND_CEIL                  0x2)
283    (ROUND_TRUNC                 0x3)
284    (ROUND_MXCSR                 0x4)
285    (ROUND_NO_EXC                0x8)
286   ])
288 ;; Constants to represent AVX512F embeded rounding
289 (define_constants
290   [(ROUND_NEAREST_INT                   0)
291    (ROUND_NEG_INF                       1)
292    (ROUND_POS_INF                       2)
293    (ROUND_ZERO                          3)
294    (NO_ROUND                            4)
295    (ROUND_SAE                           8)
296   ])
298 ;; Constants to represent pcomtrue/pcomfalse variants
299 (define_constants
300   [(PCOM_FALSE                  0)
301    (PCOM_TRUE                   1)
302    (COM_FALSE_S                 2)
303    (COM_FALSE_P                 3)
304    (COM_TRUE_S                  4)
305    (COM_TRUE_P                  5)
306   ])
308 ;; Constants used in the XOP pperm instruction
309 (define_constants
310   [(PPERM_SRC                   0x00)   /* copy source */
311    (PPERM_INVERT                0x20)   /* invert source */
312    (PPERM_REVERSE               0x40)   /* bit reverse source */
313    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
314    (PPERM_ZERO                  0x80)   /* all 0's */
315    (PPERM_ONES                  0xa0)   /* all 1's */
316    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
317    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
318    (PPERM_SRC1                  0x00)   /* use first source byte */
319    (PPERM_SRC2                  0x10)   /* use second source byte */
320    ])
322 ;; Registers by name.
323 (define_constants
324   [(AX_REG                       0)
325    (DX_REG                       1)
326    (CX_REG                       2)
327    (BX_REG                       3)
328    (SI_REG                       4)
329    (DI_REG                       5)
330    (BP_REG                       6)
331    (SP_REG                       7)
332    (ST0_REG                      8)
333    (ST1_REG                      9)
334    (ST2_REG                     10)
335    (ST3_REG                     11)
336    (ST4_REG                     12)
337    (ST5_REG                     13)
338    (ST6_REG                     14)
339    (ST7_REG                     15)
340    (ARGP_REG                    16)
341    (FLAGS_REG                   17)
342    (FPSR_REG                    18)
343    (FPCR_REG                    19)
344    (FRAME_REG                   20)
345    (XMM0_REG                    21)
346    (XMM1_REG                    22)
347    (XMM2_REG                    23)
348    (XMM3_REG                    24)
349    (XMM4_REG                    25)
350    (XMM5_REG                    26)
351    (XMM6_REG                    27)
352    (XMM7_REG                    28)
353    (MM0_REG                     29)
354    (MM1_REG                     30)
355    (MM2_REG                     31)
356    (MM3_REG                     32)
357    (MM4_REG                     33)
358    (MM5_REG                     34)
359    (MM6_REG                     35)
360    (MM7_REG                     36)
361    (R8_REG                      37)
362    (R9_REG                      38)
363    (R10_REG                     39)
364    (R11_REG                     40)
365    (R12_REG                     41)
366    (R13_REG                     42)
367    (R14_REG                     43)
368    (R15_REG                     44)
369    (XMM8_REG                    45)
370    (XMM9_REG                    46)
371    (XMM10_REG                   47)
372    (XMM11_REG                   48)
373    (XMM12_REG                   49)
374    (XMM13_REG                   50)
375    (XMM14_REG                   51)
376    (XMM15_REG                   52)
377    (XMM16_REG                   53)
378    (XMM17_REG                   54)
379    (XMM18_REG                   55)
380    (XMM19_REG                   56)
381    (XMM20_REG                   57)
382    (XMM21_REG                   58)
383    (XMM22_REG                   59)
384    (XMM23_REG                   60)
385    (XMM24_REG                   61)
386    (XMM25_REG                   62)
387    (XMM26_REG                   63)
388    (XMM27_REG                   64)
389    (XMM28_REG                   65)
390    (XMM29_REG                   66)
391    (XMM30_REG                   67)
392    (XMM31_REG                   68)
393    (MASK0_REG                   69)
394    (MASK1_REG                   70)
395    (MASK2_REG                   71)
396    (MASK3_REG                   72)
397    (MASK4_REG                   73)
398    (MASK5_REG                   74)
399    (MASK6_REG                   75)
400    (MASK7_REG                   76)
401    (BND0_REG                    77)
402    (BND1_REG                    78)
403    (BND2_REG                    79)
404    (BND3_REG                    80)
405    (FIRST_PSEUDO_REG            81)
406   ])
408 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
409 ;; from i386.c.
411 ;; In C guard expressions, put expressions which may be compile-time
412 ;; constants first.  This allows for better optimization.  For
413 ;; example, write "TARGET_64BIT && reload_completed", not
414 ;; "reload_completed && TARGET_64BIT".
417 ;; Processor type.
418 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
419                     atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
420                     bdver4,btver2,znver1"
421   (const (symbol_ref "ix86_schedule")))
423 ;; A basic instruction type.  Refinements due to arguments to be
424 ;; provided in other attributes.
425 (define_attr "type"
426   "other,multi,
427    alu,alu1,negnot,imov,imovx,lea,
428    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
429    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
430    push,pop,call,callv,leave,
431    str,bitmanip,
432    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
433    fxch,fistp,fisttp,frndint,
434    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
435    ssemul,sseimul,ssediv,sselog,sselog1,
436    sseishft,sseishft1,ssecmp,ssecomi,
437    ssecvt,ssecvt1,sseicvt,sseins,
438    sseshuf,sseshuf1,ssemuladd,sse4arg,
439    lwp,mskmov,msklog,
440    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
441    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
442   (const_string "other"))
444 ;; Main data type used by the insn
445 (define_attr "mode"
446   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
447   V2DF,V2SF,V1DF,V8DF"
448   (const_string "unknown"))
450 ;; The CPU unit operations uses.
451 (define_attr "unit" "integer,i387,sse,mmx,unknown"
452   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
453                           fxch,fistp,fisttp,frndint")
454            (const_string "i387")
455          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
456                           ssemul,sseimul,ssediv,sselog,sselog1,
457                           sseishft,sseishft1,ssecmp,ssecomi,
458                           ssecvt,ssecvt1,sseicvt,sseins,
459                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
460            (const_string "sse")
461          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
462            (const_string "mmx")
463          (eq_attr "type" "other")
464            (const_string "unknown")]
465          (const_string "integer")))
467 ;; The (bounding maximum) length of an instruction immediate.
468 (define_attr "length_immediate" ""
469   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
470                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
471                           mpxld,mpxst")
472            (const_int 0)
473          (eq_attr "unit" "i387,sse,mmx")
474            (const_int 0)
475          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
476                           rotate,rotatex,rotate1,imul,icmp,push,pop")
477            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
478          (eq_attr "type" "imov,test")
479            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
480          (eq_attr "type" "call")
481            (if_then_else (match_operand 0 "constant_call_address_operand")
482              (const_int 4)
483              (const_int 0))
484          (eq_attr "type" "callv")
485            (if_then_else (match_operand 1 "constant_call_address_operand")
486              (const_int 4)
487              (const_int 0))
488          ;; We don't know the size before shorten_branches.  Expect
489          ;; the instruction to fit for better scheduling.
490          (eq_attr "type" "ibr")
491            (const_int 1)
492          ]
493          (symbol_ref "/* Update immediate_length and other attributes! */
494                       gcc_unreachable (),1")))
496 ;; The (bounding maximum) length of an instruction address.
497 (define_attr "length_address" ""
498   (cond [(eq_attr "type" "str,other,multi,fxch")
499            (const_int 0)
500          (and (eq_attr "type" "call")
501               (match_operand 0 "constant_call_address_operand"))
502              (const_int 0)
503          (and (eq_attr "type" "callv")
504               (match_operand 1 "constant_call_address_operand"))
505              (const_int 0)
506          ]
507          (symbol_ref "ix86_attr_length_address_default (insn)")))
509 ;; Set when length prefix is used.
510 (define_attr "prefix_data16" ""
511   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
512            (const_int 0)
513          (eq_attr "mode" "HI")
514            (const_int 1)
515          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
516            (const_int 1)
517         ]
518         (const_int 0)))
520 ;; Set when string REP prefix is used.
521 (define_attr "prefix_rep" ""
522   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
523            (const_int 0)
524          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
525            (const_int 1)
526          (and (eq_attr "type" "ibr,call,callv")
527               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
528            (const_int 1)
529         ]
530         (const_int 0)))
532 ;; Set when 0f opcode prefix is used.
533 (define_attr "prefix_0f" ""
534   (if_then_else
535     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
536                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
537          (eq_attr "unit" "sse,mmx"))
538     (const_int 1)
539     (const_int 0)))
541 ;; Set when REX opcode prefix is used.
542 (define_attr "prefix_rex" ""
543   (cond [(not (match_test "TARGET_64BIT"))
544            (const_int 0)
545          (and (eq_attr "mode" "DI")
546               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
547                    (eq_attr "unit" "!mmx")))
548            (const_int 1)
549          (and (eq_attr "mode" "QI")
550               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
551            (const_int 1)
552          (match_test "x86_extended_reg_mentioned_p (insn)")
553            (const_int 1)
554          (and (eq_attr "type" "imovx")
555               (match_operand:QI 1 "ext_QIreg_operand"))
556            (const_int 1)
557         ]
558         (const_int 0)))
560 ;; There are also additional prefixes in 3DNOW, SSSE3.
561 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
562 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
563 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
564 (define_attr "prefix_extra" ""
565   (cond [(eq_attr "type" "ssemuladd,sse4arg")
566            (const_int 2)
567          (eq_attr "type" "sseiadd1,ssecvt1")
568            (const_int 1)
569         ]
570         (const_int 0)))
572 ;; Set when BND opcode prefix may be used.
573 (define_attr "maybe_prefix_bnd" "" (const_int 0))
575 ;; Prefix used: original, VEX or maybe VEX.
576 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
577   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
578            (const_string "vex")
579          (eq_attr "mode" "XI,V16SF,V8DF")
580            (const_string "evex")
581         ]
582         (const_string "orig")))
584 ;; VEX W bit is used.
585 (define_attr "prefix_vex_w" "" (const_int 0))
587 ;; The length of VEX prefix
588 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
589 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
590 ;; still prefix_0f 1, with prefix_extra 1.
591 (define_attr "length_vex" ""
592   (if_then_else (and (eq_attr "prefix_0f" "1")
593                      (eq_attr "prefix_extra" "0"))
594     (if_then_else (eq_attr "prefix_vex_w" "1")
595       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
596       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
597     (if_then_else (eq_attr "prefix_vex_w" "1")
598       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
599       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
601 ;; 4-bytes evex prefix and 1 byte opcode.
602 (define_attr "length_evex" "" (const_int 5))
604 ;; Set when modrm byte is used.
605 (define_attr "modrm" ""
606   (cond [(eq_attr "type" "str,leave")
607            (const_int 0)
608          (eq_attr "unit" "i387")
609            (const_int 0)
610          (and (eq_attr "type" "incdec")
611               (and (not (match_test "TARGET_64BIT"))
612                    (ior (match_operand:SI 1 "register_operand")
613                         (match_operand:HI 1 "register_operand"))))
614            (const_int 0)
615          (and (eq_attr "type" "push")
616               (not (match_operand 1 "memory_operand")))
617            (const_int 0)
618          (and (eq_attr "type" "pop")
619               (not (match_operand 0 "memory_operand")))
620            (const_int 0)
621          (and (eq_attr "type" "imov")
622               (and (not (eq_attr "mode" "DI"))
623                    (ior (and (match_operand 0 "register_operand")
624                              (match_operand 1 "immediate_operand"))
625                         (ior (and (match_operand 0 "ax_reg_operand")
626                                   (match_operand 1 "memory_displacement_only_operand"))
627                              (and (match_operand 0 "memory_displacement_only_operand")
628                                   (match_operand 1 "ax_reg_operand"))))))
629            (const_int 0)
630          (and (eq_attr "type" "call")
631               (match_operand 0 "constant_call_address_operand"))
632              (const_int 0)
633          (and (eq_attr "type" "callv")
634               (match_operand 1 "constant_call_address_operand"))
635              (const_int 0)
636          (and (eq_attr "type" "alu,alu1,icmp,test")
637               (match_operand 0 "ax_reg_operand"))
638              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
639          ]
640          (const_int 1)))
642 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
643   (cond [(eq_attr "modrm" "0")
644            (const_string "none")
645          (eq_attr "type" "alu,imul,ishift")
646            (const_string "op02")
647          (eq_attr "type" "imov,imovx,lea,alu1,icmp")
648            (const_string "op01")
649          (eq_attr "type" "incdec")
650            (const_string "incdec")
651          (eq_attr "type" "push,pop")
652            (const_string "pushpop")]
653          (const_string "unknown")))
655 ;; The (bounding maximum) length of an instruction in bytes.
656 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
657 ;; Later we may want to split them and compute proper length as for
658 ;; other insns.
659 (define_attr "length" ""
660   (cond [(eq_attr "type" "other,multi,fistp,frndint")
661            (const_int 16)
662          (eq_attr "type" "fcmp")
663            (const_int 4)
664          (eq_attr "unit" "i387")
665            (plus (const_int 2)
666                  (plus (attr "prefix_data16")
667                        (attr "length_address")))
668          (ior (eq_attr "prefix" "evex")
669               (and (ior (eq_attr "prefix" "maybe_evex")
670                         (eq_attr "prefix" "maybe_vex"))
671                    (match_test "TARGET_AVX512F")))
672            (plus (attr "length_evex")
673                  (plus (attr "length_immediate")
674                        (plus (attr "modrm")
675                              (attr "length_address"))))
676          (ior (eq_attr "prefix" "vex")
677               (and (ior (eq_attr "prefix" "maybe_vex")
678                         (eq_attr "prefix" "maybe_evex"))
679                    (match_test "TARGET_AVX")))
680            (plus (attr "length_vex")
681                  (plus (attr "length_immediate")
682                        (plus (attr "modrm")
683                              (attr "length_address"))))]
684          (plus (plus (attr "modrm")
685                      (plus (attr "prefix_0f")
686                            (plus (attr "prefix_rex")
687                                  (plus (attr "prefix_extra")
688                                        (const_int 1)))))
689                (plus (attr "prefix_rep")
690                      (plus (attr "prefix_data16")
691                            (plus (attr "length_immediate")
692                                  (attr "length_address")))))))
694 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
695 ;; `store' if there is a simple memory reference therein, or `unknown'
696 ;; if the instruction is complex.
698 (define_attr "memory" "none,load,store,both,unknown"
699   (cond [(eq_attr "type" "other,multi,str,lwp")
700            (const_string "unknown")
701          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
702            (const_string "none")
703          (eq_attr "type" "fistp,leave")
704            (const_string "both")
705          (eq_attr "type" "frndint")
706            (const_string "load")
707          (eq_attr "type" "mpxld")
708            (const_string "load")
709          (eq_attr "type" "mpxst")
710            (const_string "store")
711          (eq_attr "type" "push")
712            (if_then_else (match_operand 1 "memory_operand")
713              (const_string "both")
714              (const_string "store"))
715          (eq_attr "type" "pop")
716            (if_then_else (match_operand 0 "memory_operand")
717              (const_string "both")
718              (const_string "load"))
719          (eq_attr "type" "setcc")
720            (if_then_else (match_operand 0 "memory_operand")
721              (const_string "store")
722              (const_string "none"))
723          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
724            (if_then_else (ior (match_operand 0 "memory_operand")
725                               (match_operand 1 "memory_operand"))
726              (const_string "load")
727              (const_string "none"))
728          (eq_attr "type" "ibr")
729            (if_then_else (match_operand 0 "memory_operand")
730              (const_string "load")
731              (const_string "none"))
732          (eq_attr "type" "call")
733            (if_then_else (match_operand 0 "constant_call_address_operand")
734              (const_string "none")
735              (const_string "load"))
736          (eq_attr "type" "callv")
737            (if_then_else (match_operand 1 "constant_call_address_operand")
738              (const_string "none")
739              (const_string "load"))
740          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
741               (match_operand 1 "memory_operand"))
742            (const_string "both")
743          (and (match_operand 0 "memory_operand")
744               (match_operand 1 "memory_operand"))
745            (const_string "both")
746          (match_operand 0 "memory_operand")
747            (const_string "store")
748          (match_operand 1 "memory_operand")
749            (const_string "load")
750          (and (eq_attr "type"
751                  "!alu1,negnot,ishift1,
752                    imov,imovx,icmp,test,bitmanip,
753                    fmov,fcmp,fsgn,
754                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
755                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
756                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
757               (match_operand 2 "memory_operand"))
758            (const_string "load")
759          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
760               (match_operand 3 "memory_operand"))
761            (const_string "load")
762         ]
763         (const_string "none")))
765 ;; Indicates if an instruction has both an immediate and a displacement.
767 (define_attr "imm_disp" "false,true,unknown"
768   (cond [(eq_attr "type" "other,multi")
769            (const_string "unknown")
770          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
771               (and (match_operand 0 "memory_displacement_operand")
772                    (match_operand 1 "immediate_operand")))
773            (const_string "true")
774          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
775               (and (match_operand 0 "memory_displacement_operand")
776                    (match_operand 2 "immediate_operand")))
777            (const_string "true")
778         ]
779         (const_string "false")))
781 ;; Indicates if an FP operation has an integer source.
783 (define_attr "fp_int_src" "false,true"
784   (const_string "false"))
786 ;; Defines rounding mode of an FP operation.
788 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
789   (const_string "any"))
791 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
792 (define_attr "use_carry" "0,1" (const_string "0"))
794 ;; Define attribute to indicate unaligned ssemov insns
795 (define_attr "movu" "0,1" (const_string "0"))
797 ;; Used to control the "enabled" attribute on a per-instruction basis.
798 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
799                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
800                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
801                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
802                     avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
803   (const_string "base"))
805 (define_attr "enabled" ""
806   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
807          (eq_attr "isa" "x64_sse4")
808            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
809          (eq_attr "isa" "x64_sse4_noavx")
810            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
811          (eq_attr "isa" "x64_avx")
812            (symbol_ref "TARGET_64BIT && TARGET_AVX")
813          (eq_attr "isa" "x64_avx512dq")
814            (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
815          (eq_attr "isa" "x64_avx512bw")
816            (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
817          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
818          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
819          (eq_attr "isa" "sse2_noavx")
820            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
821          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
822          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
823          (eq_attr "isa" "sse4_noavx")
824            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
825          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
826          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
827          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
828          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
829          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
830          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
831          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
832          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
833          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
834          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
835          (eq_attr "isa" "fma_avx512f")
836            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
837          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
838          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
839          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
840          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
841          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
842          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
843         ]
844         (const_int 1)))
846 (define_attr "preferred_for_size" "" (const_int 1))
847 (define_attr "preferred_for_speed" "" (const_int 1))
849 ;; Describe a user's asm statement.
850 (define_asm_attributes
851   [(set_attr "length" "128")
852    (set_attr "type" "multi")])
854 (define_code_iterator plusminus [plus minus])
856 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
858 (define_code_iterator multdiv [mult div])
860 ;; Base name for define_insn
861 (define_code_attr plusminus_insn
862   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
863    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
865 ;; Base name for insn mnemonic.
866 (define_code_attr plusminus_mnemonic
867   [(plus "add") (ss_plus "adds") (us_plus "addus")
868    (minus "sub") (ss_minus "subs") (us_minus "subus")])
869 (define_code_attr multdiv_mnemonic
870   [(mult "mul") (div "div")])
872 ;; Mark commutative operators as such in constraints.
873 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
874                         (minus "") (ss_minus "") (us_minus "")])
876 ;; Mapping of max and min
877 (define_code_iterator maxmin [smax smin umax umin])
879 ;; Mapping of signed max and min
880 (define_code_iterator smaxmin [smax smin])
882 ;; Mapping of unsigned max and min
883 (define_code_iterator umaxmin [umax umin])
885 ;; Base name for integer and FP insn mnemonic
886 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
887                               (umax "maxu") (umin "minu")])
888 (define_code_attr maxmin_float [(smax "max") (smin "min")])
890 (define_int_iterator IEEE_MAXMIN
891         [UNSPEC_IEEE_MAX
892          UNSPEC_IEEE_MIN])
894 (define_int_attr ieee_maxmin
895         [(UNSPEC_IEEE_MAX "max")
896          (UNSPEC_IEEE_MIN "min")])
898 ;; Mapping of logic operators
899 (define_code_iterator any_logic [and ior xor])
900 (define_code_iterator any_or [ior xor])
901 (define_code_iterator fpint_logic [and xor])
903 ;; Base name for insn mnemonic.
904 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
906 ;; Mapping of logic-shift operators
907 (define_code_iterator any_lshift [ashift lshiftrt])
909 ;; Mapping of shift-right operators
910 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
912 ;; Mapping of all shift operators
913 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
915 ;; Base name for define_insn
916 (define_code_attr shift_insn
917   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
919 ;; Base name for insn mnemonic.
920 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
921 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
923 ;; Mapping of rotate operators
924 (define_code_iterator any_rotate [rotate rotatert])
926 ;; Base name for define_insn
927 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
929 ;; Base name for insn mnemonic.
930 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
932 ;; Mapping of abs neg operators
933 (define_code_iterator absneg [abs neg])
935 ;; Base name for x87 insn mnemonic.
936 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
938 ;; Used in signed and unsigned widening multiplications.
939 (define_code_iterator any_extend [sign_extend zero_extend])
941 ;; Prefix for insn menmonic.
942 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
944 ;; Prefix for define_insn
945 (define_code_attr u [(sign_extend "") (zero_extend "u")])
946 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
947 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
949 ;; Used in signed and unsigned truncations.
950 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
951 ;; Instruction suffix for truncations.
952 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
954 ;; Used in signed and unsigned fix.
955 (define_code_iterator any_fix [fix unsigned_fix])
956 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
958 ;; Used in signed and unsigned float.
959 (define_code_iterator any_float [float unsigned_float])
960 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
962 ;; All integer modes.
963 (define_mode_iterator SWI1248x [QI HI SI DI])
965 ;; All integer modes without QImode.
966 (define_mode_iterator SWI248x [HI SI DI])
968 ;; All integer modes without QImode and HImode.
969 (define_mode_iterator SWI48x [SI DI])
971 ;; All integer modes without SImode and DImode.
972 (define_mode_iterator SWI12 [QI HI])
974 ;; All integer modes without DImode.
975 (define_mode_iterator SWI124 [QI HI SI])
977 ;; All integer modes without QImode and DImode.
978 (define_mode_iterator SWI24 [HI SI])
980 ;; Single word integer modes.
981 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
983 ;; Single word integer modes without QImode.
984 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
986 ;; Single word integer modes without QImode and HImode.
987 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
989 ;; All math-dependant single and double word integer modes.
990 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
991                              (HI "TARGET_HIMODE_MATH")
992                              SI DI (TI "TARGET_64BIT")])
994 ;; Math-dependant single word integer modes.
995 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
996                             (HI "TARGET_HIMODE_MATH")
997                             SI (DI "TARGET_64BIT")])
999 ;; Math-dependant integer modes without DImode.
1000 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1001                                (HI "TARGET_HIMODE_MATH")
1002                                SI])
1004 ;; Math-dependant integer modes with DImode.
1005 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1006                                  (HI "TARGET_HIMODE_MATH")
1007                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1009 ;; Math-dependant single word integer modes without QImode.
1010 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1011                                SI (DI "TARGET_64BIT")])
1013 ;; Double word integer modes.
1014 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1015                            (TI "TARGET_64BIT")])
1017 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1018 ;; compile time constant, it is faster to use <MODE_SIZE> than
1019 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1020 ;; command line options just use GET_MODE_SIZE macro.
1021 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1022                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1023                              (V16QI "16") (V32QI "32") (V64QI "64")
1024                              (V8HI "16") (V16HI "32") (V32HI "64")
1025                              (V4SI "16") (V8SI "32") (V16SI "64")
1026                              (V2DI "16") (V4DI "32") (V8DI "64")
1027                              (V1TI "16") (V2TI "32") (V4TI "64")
1028                              (V2DF "16") (V4DF "32") (V8DF "64")
1029                              (V4SF "16") (V8SF "32") (V16SF "64")])
1031 ;; Double word integer modes as mode attribute.
1032 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1033 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1035 ;; LEA mode corresponding to an integer mode
1036 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1038 ;; Half mode for double word integer modes.
1039 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1040                             (DI "TARGET_64BIT")])
1042 ;; Bound modes.
1043 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1044                            (BND64 "TARGET_LP64")])
1046 ;; Pointer mode corresponding to bound mode.
1047 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1049 ;; MPX check types
1050 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1052 ;; Check name
1053 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1054                            (UNSPEC_BNDCU "cu")
1055                            (UNSPEC_BNDCN "cn")])
1057 ;; Instruction suffix for integer modes.
1058 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1060 ;; Instruction suffix for masks.
1061 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1063 ;; Pointer size prefix for integer modes (Intel asm dialect)
1064 (define_mode_attr iptrsize [(QI "BYTE")
1065                             (HI "WORD")
1066                             (SI "DWORD")
1067                             (DI "QWORD")])
1069 ;; Register class for integer modes.
1070 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1072 ;; Immediate operand constraint for integer modes.
1073 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1075 ;; General operand constraint for word modes.
1076 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1078 ;; Immediate operand constraint for double integer modes.
1079 (define_mode_attr di [(SI "nF") (DI "Wd")])
1081 ;; Immediate operand constraint for shifts.
1082 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1084 ;; Print register name in the specified mode.
1085 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1087 ;; General operand predicate for integer modes.
1088 (define_mode_attr general_operand
1089         [(QI "general_operand")
1090          (HI "general_operand")
1091          (SI "x86_64_general_operand")
1092          (DI "x86_64_general_operand")
1093          (TI "x86_64_general_operand")])
1095 ;; General operand predicate for integer modes, where for TImode
1096 ;; we need both words of the operand to be general operands.
1097 (define_mode_attr general_hilo_operand
1098         [(QI "general_operand")
1099          (HI "general_operand")
1100          (SI "x86_64_general_operand")
1101          (DI "x86_64_general_operand")
1102          (TI "x86_64_hilo_general_operand")])
1104 ;; General sign extend operand predicate for integer modes,
1105 ;; which disallows VOIDmode operands and thus it is suitable
1106 ;; for use inside sign_extend.
1107 (define_mode_attr general_sext_operand
1108         [(QI "sext_operand")
1109          (HI "sext_operand")
1110          (SI "x86_64_sext_operand")
1111          (DI "x86_64_sext_operand")])
1113 ;; General sign/zero extend operand predicate for integer modes.
1114 (define_mode_attr general_szext_operand
1115         [(QI "general_operand")
1116          (HI "general_operand")
1117          (SI "x86_64_szext_general_operand")
1118          (DI "x86_64_szext_general_operand")])
1120 ;; Immediate operand predicate for integer modes.
1121 (define_mode_attr immediate_operand
1122         [(QI "immediate_operand")
1123          (HI "immediate_operand")
1124          (SI "x86_64_immediate_operand")
1125          (DI "x86_64_immediate_operand")])
1127 ;; Nonmemory operand predicate for integer modes.
1128 (define_mode_attr nonmemory_operand
1129         [(QI "nonmemory_operand")
1130          (HI "nonmemory_operand")
1131          (SI "x86_64_nonmemory_operand")
1132          (DI "x86_64_nonmemory_operand")])
1134 ;; Operand predicate for shifts.
1135 (define_mode_attr shift_operand
1136         [(QI "nonimmediate_operand")
1137          (HI "nonimmediate_operand")
1138          (SI "nonimmediate_operand")
1139          (DI "shiftdi_operand")
1140          (TI "register_operand")])
1142 ;; Operand predicate for shift argument.
1143 (define_mode_attr shift_immediate_operand
1144         [(QI "const_1_to_31_operand")
1145          (HI "const_1_to_31_operand")
1146          (SI "const_1_to_31_operand")
1147          (DI "const_1_to_63_operand")])
1149 ;; Input operand predicate for arithmetic left shifts.
1150 (define_mode_attr ashl_input_operand
1151         [(QI "nonimmediate_operand")
1152          (HI "nonimmediate_operand")
1153          (SI "nonimmediate_operand")
1154          (DI "ashldi_input_operand")
1155          (TI "reg_or_pm1_operand")])
1157 ;; SSE and x87 SFmode and DFmode floating point modes
1158 (define_mode_iterator MODEF [SF DF])
1160 ;; All x87 floating point modes
1161 (define_mode_iterator X87MODEF [SF DF XF])
1163 ;; SSE instruction suffix for various modes
1164 (define_mode_attr ssemodesuffix
1165   [(SF "ss") (DF "sd")
1166    (V16SF "ps") (V8DF "pd")
1167    (V8SF "ps") (V4DF "pd")
1168    (V4SF "ps") (V2DF "pd")
1169    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1170    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1171    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1173 ;; SSE vector suffix for floating point modes
1174 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1176 ;; SSE vector mode corresponding to a scalar mode
1177 (define_mode_attr ssevecmode
1178   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1179 (define_mode_attr ssevecmodelower
1180   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1182 ;; AVX512F vector mode corresponding to a scalar mode
1183 (define_mode_attr avx512fvecmode
1184   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1186 ;; Instruction suffix for REX 64bit operators.
1187 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1189 ;; This mode iterator allows :P to be used for patterns that operate on
1190 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1191 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1193 ;; This mode iterator allows :W to be used for patterns that operate on
1194 ;; word_mode sized quantities.
1195 (define_mode_iterator W
1196   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1198 ;; This mode iterator allows :PTR to be used for patterns that operate on
1199 ;; ptr_mode sized quantities.
1200 (define_mode_iterator PTR
1201   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1203 ;; Scheduling descriptions
1205 (include "pentium.md")
1206 (include "ppro.md")
1207 (include "k6.md")
1208 (include "athlon.md")
1209 (include "bdver1.md")
1210 (include "bdver3.md")
1211 (include "btver2.md")
1212 (include "znver1.md")
1213 (include "geode.md")
1214 (include "atom.md")
1215 (include "slm.md")
1216 (include "core2.md")
1217 (include "haswell.md")
1220 ;; Operand and operator predicates and constraints
1222 (include "predicates.md")
1223 (include "constraints.md")
1226 ;; Compare and branch/compare and store instructions.
1228 (define_expand "cbranch<mode>4"
1229   [(set (reg:CC FLAGS_REG)
1230         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1231                     (match_operand:SDWIM 2 "<general_operand>")))
1232    (set (pc) (if_then_else
1233                (match_operator 0 "ordered_comparison_operator"
1234                 [(reg:CC FLAGS_REG) (const_int 0)])
1235                (label_ref (match_operand 3))
1236                (pc)))]
1237   ""
1239   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1240     operands[1] = force_reg (<MODE>mode, operands[1]);
1241   ix86_expand_branch (GET_CODE (operands[0]),
1242                       operands[1], operands[2], operands[3]);
1243   DONE;
1246 (define_expand "cstore<mode>4"
1247   [(set (reg:CC FLAGS_REG)
1248         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1249                     (match_operand:SWIM 3 "<general_operand>")))
1250    (set (match_operand:QI 0 "register_operand")
1251         (match_operator 1 "ordered_comparison_operator"
1252           [(reg:CC FLAGS_REG) (const_int 0)]))]
1253   ""
1255   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1256     operands[2] = force_reg (<MODE>mode, operands[2]);
1257   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1258                      operands[2], operands[3]);
1259   DONE;
1262 (define_expand "cmp<mode>_1"
1263   [(set (reg:CC FLAGS_REG)
1264         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1265                     (match_operand:SWI48 1 "<general_operand>")))])
1267 (define_insn "*cmp<mode>_ccno_1"
1268   [(set (reg FLAGS_REG)
1269         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1270                  (match_operand:SWI 1 "const0_operand")))]
1271   "ix86_match_ccmode (insn, CCNOmode)"
1272   "@
1273    test{<imodesuffix>}\t%0, %0
1274    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1275   [(set_attr "type" "test,icmp")
1276    (set_attr "length_immediate" "0,1")
1277    (set_attr "modrm_class" "op0,unknown")
1278    (set_attr "mode" "<MODE>")])
1280 (define_insn "*cmp<mode>_1"
1281   [(set (reg FLAGS_REG)
1282         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1283                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1284   "ix86_match_ccmode (insn, CCmode)"
1285   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1286   [(set_attr "type" "icmp")
1287    (set_attr "mode" "<MODE>")])
1289 (define_insn "*cmp<mode>_minus_1"
1290   [(set (reg FLAGS_REG)
1291         (compare
1292           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1293                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1294           (const_int 0)))]
1295   "ix86_match_ccmode (insn, CCGOCmode)"
1296   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1297   [(set_attr "type" "icmp")
1298    (set_attr "mode" "<MODE>")])
1300 (define_insn "*cmpqi_ext_1"
1301   [(set (reg FLAGS_REG)
1302         (compare
1303           (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1304           (subreg:QI
1305             (zero_extract:SI
1306               (match_operand 1 "ext_register_operand" "Q,Q")
1307               (const_int 8)
1308               (const_int 8)) 0)))]
1309   "ix86_match_ccmode (insn, CCmode)"
1310   "cmp{b}\t{%h1, %0|%0, %h1}"
1311   [(set_attr "isa" "*,nox64")
1312    (set_attr "type" "icmp")
1313    (set_attr "mode" "QI")])
1315 (define_insn "*cmpqi_ext_2"
1316   [(set (reg FLAGS_REG)
1317         (compare
1318           (subreg:QI
1319             (zero_extract:SI
1320               (match_operand 0 "ext_register_operand" "Q")
1321               (const_int 8)
1322               (const_int 8)) 0)
1323           (match_operand:QI 1 "const0_operand")))]
1324   "ix86_match_ccmode (insn, CCNOmode)"
1325   "test{b}\t%h0, %h0"
1326   [(set_attr "type" "test")
1327    (set_attr "length_immediate" "0")
1328    (set_attr "mode" "QI")])
1330 (define_expand "cmpqi_ext_3"
1331   [(set (reg:CC FLAGS_REG)
1332         (compare:CC
1333           (subreg:QI
1334             (zero_extract:SI
1335               (match_operand 0 "ext_register_operand")
1336               (const_int 8)
1337               (const_int 8)) 0)
1338           (match_operand:QI 1 "const_int_operand")))])
1340 (define_insn "*cmpqi_ext_3"
1341   [(set (reg FLAGS_REG)
1342         (compare
1343           (subreg:QI
1344             (zero_extract:SI
1345               (match_operand 0 "ext_register_operand" "Q,Q")
1346               (const_int 8)
1347               (const_int 8)) 0)
1348           (match_operand:QI 1 "general_operand" "QnBc,m")))]
1349   "ix86_match_ccmode (insn, CCmode)"
1350   "cmp{b}\t{%1, %h0|%h0, %1}"
1351   [(set_attr "isa" "*,nox64")
1352    (set_attr "type" "icmp")
1353    (set_attr "mode" "QI")])
1355 (define_insn "*cmpqi_ext_4"
1356   [(set (reg FLAGS_REG)
1357         (compare
1358           (subreg:QI
1359             (zero_extract:SI
1360               (match_operand 0 "ext_register_operand" "Q")
1361               (const_int 8)
1362               (const_int 8)) 0)
1363           (subreg:QI
1364             (zero_extract:SI
1365               (match_operand 1 "ext_register_operand" "Q")
1366               (const_int 8)
1367               (const_int 8)) 0)))]
1368   "ix86_match_ccmode (insn, CCmode)"
1369   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1370   [(set_attr "type" "icmp")
1371    (set_attr "mode" "QI")])
1373 ;; These implement float point compares.
1374 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1375 ;; which would allow mix and match FP modes on the compares.  Which is what
1376 ;; the old patterns did, but with many more of them.
1378 (define_expand "cbranchxf4"
1379   [(set (reg:CC FLAGS_REG)
1380         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1381                     (match_operand:XF 2 "nonmemory_operand")))
1382    (set (pc) (if_then_else
1383               (match_operator 0 "ix86_fp_comparison_operator"
1384                [(reg:CC FLAGS_REG)
1385                 (const_int 0)])
1386               (label_ref (match_operand 3))
1387               (pc)))]
1388   "TARGET_80387"
1390   ix86_expand_branch (GET_CODE (operands[0]),
1391                       operands[1], operands[2], operands[3]);
1392   DONE;
1395 (define_expand "cstorexf4"
1396   [(set (reg:CC FLAGS_REG)
1397         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1398                     (match_operand:XF 3 "nonmemory_operand")))
1399    (set (match_operand:QI 0 "register_operand")
1400               (match_operator 1 "ix86_fp_comparison_operator"
1401                [(reg:CC FLAGS_REG)
1402                 (const_int 0)]))]
1403   "TARGET_80387"
1405   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1406                      operands[2], operands[3]);
1407   DONE;
1410 (define_expand "cbranch<mode>4"
1411   [(set (reg:CC FLAGS_REG)
1412         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1413                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1414    (set (pc) (if_then_else
1415               (match_operator 0 "ix86_fp_comparison_operator"
1416                [(reg:CC FLAGS_REG)
1417                 (const_int 0)])
1418               (label_ref (match_operand 3))
1419               (pc)))]
1420   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1422   ix86_expand_branch (GET_CODE (operands[0]),
1423                       operands[1], operands[2], operands[3]);
1424   DONE;
1427 (define_expand "cstore<mode>4"
1428   [(set (reg:CC FLAGS_REG)
1429         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1430                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1431    (set (match_operand:QI 0 "register_operand")
1432               (match_operator 1 "ix86_fp_comparison_operator"
1433                [(reg:CC FLAGS_REG)
1434                 (const_int 0)]))]
1435   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1437   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1438                      operands[2], operands[3]);
1439   DONE;
1442 (define_expand "cbranchcc4"
1443   [(set (pc) (if_then_else
1444               (match_operator 0 "comparison_operator"
1445                [(match_operand 1 "flags_reg_operand")
1446                 (match_operand 2 "const0_operand")])
1447               (label_ref (match_operand 3))
1448               (pc)))]
1449   ""
1451   ix86_expand_branch (GET_CODE (operands[0]),
1452                       operands[1], operands[2], operands[3]);
1453   DONE;
1456 (define_expand "cstorecc4"
1457   [(set (match_operand:QI 0 "register_operand")
1458               (match_operator 1 "comparison_operator"
1459                [(match_operand 2 "flags_reg_operand")
1460                 (match_operand 3 "const0_operand")]))]
1461   ""
1463   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1464                      operands[2], operands[3]);
1465   DONE;
1469 ;; FP compares, step 1:
1470 ;; Set the FP condition codes.
1472 ;; CCFPmode     compare with exceptions
1473 ;; CCFPUmode    compare with no exceptions
1475 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1476 ;; used to manage the reg stack popping would not be preserved.
1478 (define_insn "*cmp<mode>_0_i387"
1479   [(set (match_operand:HI 0 "register_operand" "=a")
1480         (unspec:HI
1481           [(compare:CCFP
1482              (match_operand:X87MODEF 1 "register_operand" "f")
1483              (match_operand:X87MODEF 2 "const0_operand"))]
1484         UNSPEC_FNSTSW))]
1485   "TARGET_80387"
1486   "* return output_fp_compare (insn, operands, false, false);"
1487   [(set_attr "type" "multi")
1488    (set_attr "unit" "i387")
1489    (set_attr "mode" "<MODE>")])
1491 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1492   [(set (reg:CCFP FLAGS_REG)
1493         (compare:CCFP
1494           (match_operand:X87MODEF 1 "register_operand" "f")
1495           (match_operand:X87MODEF 2 "const0_operand")))
1496    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1497   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1498   "#"
1499   "&& reload_completed"
1500   [(set (match_dup 0)
1501         (unspec:HI
1502           [(compare:CCFP (match_dup 1)(match_dup 2))]
1503         UNSPEC_FNSTSW))
1504    (set (reg:CC FLAGS_REG)
1505         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1506   ""
1507   [(set_attr "type" "multi")
1508    (set_attr "unit" "i387")
1509    (set_attr "mode" "<MODE>")])
1511 (define_insn "*cmpxf_i387"
1512   [(set (match_operand:HI 0 "register_operand" "=a")
1513         (unspec:HI
1514           [(compare:CCFP
1515              (match_operand:XF 1 "register_operand" "f")
1516              (match_operand:XF 2 "register_operand" "f"))]
1517           UNSPEC_FNSTSW))]
1518   "TARGET_80387"
1519   "* return output_fp_compare (insn, operands, false, false);"
1520   [(set_attr "type" "multi")
1521    (set_attr "unit" "i387")
1522    (set_attr "mode" "XF")])
1524 (define_insn_and_split "*cmpxf_cc_i387"
1525   [(set (reg:CCFP FLAGS_REG)
1526         (compare:CCFP
1527           (match_operand:XF 1 "register_operand" "f")
1528           (match_operand:XF 2 "register_operand" "f")))
1529    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1530   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1531   "#"
1532   "&& reload_completed"
1533   [(set (match_dup 0)
1534         (unspec:HI
1535           [(compare:CCFP (match_dup 1)(match_dup 2))]
1536         UNSPEC_FNSTSW))
1537    (set (reg:CC FLAGS_REG)
1538         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1539   ""
1540   [(set_attr "type" "multi")
1541    (set_attr "unit" "i387")
1542    (set_attr "mode" "XF")])
1544 (define_insn "*cmp<mode>_i387"
1545   [(set (match_operand:HI 0 "register_operand" "=a")
1546         (unspec:HI
1547           [(compare:CCFP
1548              (match_operand:MODEF 1 "register_operand" "f")
1549              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1550           UNSPEC_FNSTSW))]
1551   "TARGET_80387"
1552   "* return output_fp_compare (insn, operands, false, false);"
1553   [(set_attr "type" "multi")
1554    (set_attr "unit" "i387")
1555    (set_attr "mode" "<MODE>")])
1557 (define_insn_and_split "*cmp<mode>_cc_i387"
1558   [(set (reg:CCFP FLAGS_REG)
1559         (compare:CCFP
1560           (match_operand:MODEF 1 "register_operand" "f")
1561           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1562    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1563   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1564   "#"
1565   "&& reload_completed"
1566   [(set (match_dup 0)
1567         (unspec:HI
1568           [(compare:CCFP (match_dup 1)(match_dup 2))]
1569         UNSPEC_FNSTSW))
1570    (set (reg:CC FLAGS_REG)
1571         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1572   ""
1573   [(set_attr "type" "multi")
1574    (set_attr "unit" "i387")
1575    (set_attr "mode" "<MODE>")])
1577 (define_insn "*cmpu<mode>_i387"
1578   [(set (match_operand:HI 0 "register_operand" "=a")
1579         (unspec:HI
1580           [(compare:CCFPU
1581              (match_operand:X87MODEF 1 "register_operand" "f")
1582              (match_operand:X87MODEF 2 "register_operand" "f"))]
1583           UNSPEC_FNSTSW))]
1584   "TARGET_80387"
1585   "* return output_fp_compare (insn, operands, false, true);"
1586   [(set_attr "type" "multi")
1587    (set_attr "unit" "i387")
1588    (set_attr "mode" "<MODE>")])
1590 (define_insn_and_split "*cmpu<mode>_cc_i387"
1591   [(set (reg:CCFPU FLAGS_REG)
1592         (compare:CCFPU
1593           (match_operand:X87MODEF 1 "register_operand" "f")
1594           (match_operand:X87MODEF 2 "register_operand" "f")))
1595    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1596   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1597   "#"
1598   "&& reload_completed"
1599   [(set (match_dup 0)
1600         (unspec:HI
1601           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1602         UNSPEC_FNSTSW))
1603    (set (reg:CC FLAGS_REG)
1604         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1605   ""
1606   [(set_attr "type" "multi")
1607    (set_attr "unit" "i387")
1608    (set_attr "mode" "<MODE>")])
1610 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1611   [(set (match_operand:HI 0 "register_operand" "=a")
1612         (unspec:HI
1613           [(compare:CCFP
1614              (match_operand:X87MODEF 1 "register_operand" "f")
1615              (match_operator:X87MODEF 3 "float_operator"
1616                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1617           UNSPEC_FNSTSW))]
1618   "TARGET_80387
1619    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1620        || optimize_function_for_size_p (cfun))"
1621   "* return output_fp_compare (insn, operands, false, false);"
1622   [(set_attr "type" "multi")
1623    (set_attr "unit" "i387")
1624    (set_attr "fp_int_src" "true")
1625    (set_attr "mode" "<SWI24:MODE>")])
1627 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1628   [(set (reg:CCFP FLAGS_REG)
1629         (compare:CCFP
1630           (match_operand:X87MODEF 1 "register_operand" "f")
1631           (match_operator:X87MODEF 3 "float_operator"
1632             [(match_operand:SWI24 2 "memory_operand" "m")])))
1633    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1634   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1635    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1636        || optimize_function_for_size_p (cfun))"
1637   "#"
1638   "&& reload_completed"
1639   [(set (match_dup 0)
1640         (unspec:HI
1641           [(compare:CCFP
1642              (match_dup 1)
1643              (match_op_dup 3 [(match_dup 2)]))]
1644         UNSPEC_FNSTSW))
1645    (set (reg:CC FLAGS_REG)
1646         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1647   ""
1648   [(set_attr "type" "multi")
1649    (set_attr "unit" "i387")
1650    (set_attr "fp_int_src" "true")
1651    (set_attr "mode" "<SWI24:MODE>")])
1653 ;; FP compares, step 2
1654 ;; Move the fpsw to ax.
1656 (define_insn "x86_fnstsw_1"
1657   [(set (match_operand:HI 0 "register_operand" "=a")
1658         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1659   "TARGET_80387"
1660   "fnstsw\t%0"
1661   [(set_attr "length" "2")
1662    (set_attr "mode" "SI")
1663    (set_attr "unit" "i387")])
1665 ;; FP compares, step 3
1666 ;; Get ax into flags, general case.
1668 (define_insn "x86_sahf_1"
1669   [(set (reg:CC FLAGS_REG)
1670         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1671                    UNSPEC_SAHF))]
1672   "TARGET_SAHF"
1674 #ifndef HAVE_AS_IX86_SAHF
1675   if (TARGET_64BIT)
1676     return ASM_BYTE "0x9e";
1677   else
1678 #endif
1679   return "sahf";
1681   [(set_attr "length" "1")
1682    (set_attr "athlon_decode" "vector")
1683    (set_attr "amdfam10_decode" "direct")
1684    (set_attr "bdver1_decode" "direct")
1685    (set_attr "mode" "SI")])
1687 ;; Pentium Pro can do steps 1 through 3 in one go.
1688 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1689 ;; (these i387 instructions set flags directly)
1691 (define_mode_iterator FPCMP [CCFP CCFPU])
1692 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1694 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
1695   [(set (reg:FPCMP FLAGS_REG)
1696         (compare:FPCMP
1697           (match_operand:MODEF 0 "register_operand" "f,v")
1698           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1699   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1700    || (TARGET_80387 && TARGET_CMOVE)"
1701   "* return output_fp_compare (insn, operands, true,
1702                                <FPCMP:MODE>mode == CCFPUmode);"
1703   [(set_attr "type" "fcmp,ssecomi")
1704    (set_attr "prefix" "orig,maybe_vex")
1705    (set_attr "mode" "<MODEF:MODE>")
1706    (set_attr "prefix_rep" "*,0")
1707    (set (attr "prefix_data16")
1708         (cond [(eq_attr "alternative" "0")
1709                  (const_string "*")
1710                (eq_attr "mode" "DF")
1711                  (const_string "1")
1712               ]
1713               (const_string "0")))
1714    (set_attr "athlon_decode" "vector")
1715    (set_attr "amdfam10_decode" "direct")
1716    (set_attr "bdver1_decode" "double")
1717    (set_attr "znver1_decode" "double")
1718    (set (attr "enabled")
1719      (if_then_else
1720        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1721        (if_then_else
1722          (eq_attr "alternative" "0")
1723          (symbol_ref "TARGET_MIX_SSE_I387")
1724          (symbol_ref "true"))
1725        (if_then_else
1726          (eq_attr "alternative" "0")
1727          (symbol_ref "true")
1728          (symbol_ref "false"))))])
1730 (define_insn "*cmpi<unord>xf_i387"
1731   [(set (reg:FPCMP FLAGS_REG)
1732         (compare:FPCMP
1733           (match_operand:XF 0 "register_operand" "f")
1734           (match_operand:XF 1 "register_operand" "f")))]
1735   "TARGET_80387 && TARGET_CMOVE"
1736   "* return output_fp_compare (insn, operands, true,
1737                                <MODE>mode == CCFPUmode);"
1738   [(set_attr "type" "fcmp")
1739    (set_attr "mode" "XF")
1740    (set_attr "athlon_decode" "vector")
1741    (set_attr "amdfam10_decode" "direct")
1742    (set_attr "bdver1_decode" "double")
1743    (set_attr "znver1_decode" "double")])
1745 ;; Push/pop instructions.
1747 (define_insn "*push<mode>2"
1748   [(set (match_operand:DWI 0 "push_operand" "=<")
1749         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1750   ""
1751   "#"
1752   [(set_attr "type" "multi")
1753    (set_attr "mode" "<MODE>")])
1755 (define_split
1756   [(set (match_operand:DWI 0 "push_operand")
1757         (match_operand:DWI 1 "general_gr_operand"))]
1758   "reload_completed"
1759   [(const_int 0)]
1760   "ix86_split_long_move (operands); DONE;")
1762 (define_insn "*pushdi2_rex64"
1763   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1764         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1765   "TARGET_64BIT"
1766   "@
1767    push{q}\t%1
1768    #"
1769   [(set_attr "type" "push,multi")
1770    (set_attr "mode" "DI")])
1772 ;; Convert impossible pushes of immediate to existing instructions.
1773 ;; First try to get scratch register and go through it.  In case this
1774 ;; fails, push sign extended lower part first and then overwrite
1775 ;; upper part by 32bit move.
1776 (define_peephole2
1777   [(match_scratch:DI 2 "r")
1778    (set (match_operand:DI 0 "push_operand")
1779         (match_operand:DI 1 "immediate_operand"))]
1780   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1781    && !x86_64_immediate_operand (operands[1], DImode)"
1782   [(set (match_dup 2) (match_dup 1))
1783    (set (match_dup 0) (match_dup 2))])
1785 ;; We need to define this as both peepholer and splitter for case
1786 ;; peephole2 pass is not run.
1787 ;; "&& 1" is needed to keep it from matching the previous pattern.
1788 (define_peephole2
1789   [(set (match_operand:DI 0 "push_operand")
1790         (match_operand:DI 1 "immediate_operand"))]
1791   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1792    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1793   [(set (match_dup 0) (match_dup 1))
1794    (set (match_dup 2) (match_dup 3))]
1796   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1798   operands[1] = gen_lowpart (DImode, operands[2]);
1799   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1800                                                    GEN_INT (4)));
1803 (define_split
1804   [(set (match_operand:DI 0 "push_operand")
1805         (match_operand:DI 1 "immediate_operand"))]
1806   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1807                     ? epilogue_completed : reload_completed)
1808    && !symbolic_operand (operands[1], DImode)
1809    && !x86_64_immediate_operand (operands[1], DImode)"
1810   [(set (match_dup 0) (match_dup 1))
1811    (set (match_dup 2) (match_dup 3))]
1813   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1815   operands[1] = gen_lowpart (DImode, operands[2]);
1816   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1817                                                    GEN_INT (4)));
1820 (define_insn "*pushsi2"
1821   [(set (match_operand:SI 0 "push_operand" "=<")
1822         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1823   "!TARGET_64BIT"
1824   "push{l}\t%1"
1825   [(set_attr "type" "push")
1826    (set_attr "mode" "SI")])
1828 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1829 ;; "push a byte/word".  But actually we use pushl, which has the effect
1830 ;; of rounding the amount pushed up to a word.
1832 ;; For TARGET_64BIT we always round up to 8 bytes.
1833 (define_insn "*push<mode>2_rex64"
1834   [(set (match_operand:SWI124 0 "push_operand" "=X")
1835         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1836   "TARGET_64BIT"
1837   "push{q}\t%q1"
1838   [(set_attr "type" "push")
1839    (set_attr "mode" "DI")])
1841 (define_insn "*push<mode>2"
1842   [(set (match_operand:SWI12 0 "push_operand" "=X")
1843         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1844   "!TARGET_64BIT"
1845   "push{l}\t%k1"
1846   [(set_attr "type" "push")
1847    (set_attr "mode" "SI")])
1849 (define_insn "*push<mode>2_prologue"
1850   [(set (match_operand:W 0 "push_operand" "=<")
1851         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1852    (clobber (mem:BLK (scratch)))]
1853   ""
1854   "push{<imodesuffix>}\t%1"
1855   [(set_attr "type" "push")
1856    (set_attr "mode" "<MODE>")])
1858 (define_insn "*pop<mode>1"
1859   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1860         (match_operand:W 1 "pop_operand" ">"))]
1861   ""
1862   "pop{<imodesuffix>}\t%0"
1863   [(set_attr "type" "pop")
1864    (set_attr "mode" "<MODE>")])
1866 (define_insn "*pop<mode>1_epilogue"
1867   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1868         (match_operand:W 1 "pop_operand" ">"))
1869    (clobber (mem:BLK (scratch)))]
1870   ""
1871   "pop{<imodesuffix>}\t%0"
1872   [(set_attr "type" "pop")
1873    (set_attr "mode" "<MODE>")])
1875 (define_insn "*pushfl<mode>2"
1876   [(set (match_operand:W 0 "push_operand" "=<")
1877         (match_operand:W 1 "flags_reg_operand"))]
1878   ""
1879   "pushf{<imodesuffix>}"
1880   [(set_attr "type" "push")
1881    (set_attr "mode" "<MODE>")])
1883 (define_insn "*popfl<mode>1"
1884   [(set (match_operand:W 0 "flags_reg_operand")
1885         (match_operand:W 1 "pop_operand" ">"))]
1886   ""
1887   "popf{<imodesuffix>}"
1888   [(set_attr "type" "pop")
1889    (set_attr "mode" "<MODE>")])
1892 ;; Reload patterns to support multi-word load/store
1893 ;; with non-offsetable address.
1894 (define_expand "reload_noff_store"
1895   [(parallel [(match_operand 0 "memory_operand" "=m")
1896               (match_operand 1 "register_operand" "r")
1897               (match_operand:DI 2 "register_operand" "=&r")])]
1898   "TARGET_64BIT"
1900   rtx mem = operands[0];
1901   rtx addr = XEXP (mem, 0);
1903   emit_move_insn (operands[2], addr);
1904   mem = replace_equiv_address_nv (mem, operands[2]);
1906   emit_insn (gen_rtx_SET (mem, operands[1]));
1907   DONE;
1910 (define_expand "reload_noff_load"
1911   [(parallel [(match_operand 0 "register_operand" "=r")
1912               (match_operand 1 "memory_operand" "m")
1913               (match_operand:DI 2 "register_operand" "=r")])]
1914   "TARGET_64BIT"
1916   rtx mem = operands[1];
1917   rtx addr = XEXP (mem, 0);
1919   emit_move_insn (operands[2], addr);
1920   mem = replace_equiv_address_nv (mem, operands[2]);
1922   emit_insn (gen_rtx_SET (operands[0], mem));
1923   DONE;
1926 ;; Move instructions.
1928 (define_expand "movxi"
1929   [(set (match_operand:XI 0 "nonimmediate_operand")
1930         (match_operand:XI 1 "general_operand"))]
1931   "TARGET_AVX512F"
1932   "ix86_expand_vector_move (XImode, operands); DONE;")
1934 (define_expand "movoi"
1935   [(set (match_operand:OI 0 "nonimmediate_operand")
1936         (match_operand:OI 1 "general_operand"))]
1937   "TARGET_AVX"
1938   "ix86_expand_vector_move (OImode, operands); DONE;")
1940 (define_expand "movti"
1941   [(set (match_operand:TI 0 "nonimmediate_operand")
1942         (match_operand:TI 1 "general_operand"))]
1943   "TARGET_64BIT || TARGET_SSE"
1945   if (TARGET_64BIT)
1946     ix86_expand_move (TImode, operands);
1947   else
1948     ix86_expand_vector_move (TImode, operands);
1949   DONE;
1952 ;; This expands to what emit_move_complex would generate if we didn't
1953 ;; have a movti pattern.  Having this avoids problems with reload on
1954 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1955 ;; to have around all the time.
1956 (define_expand "movcdi"
1957   [(set (match_operand:CDI 0 "nonimmediate_operand")
1958         (match_operand:CDI 1 "general_operand"))]
1959   ""
1961   if (push_operand (operands[0], CDImode))
1962     emit_move_complex_push (CDImode, operands[0], operands[1]);
1963   else
1964     emit_move_complex_parts (operands[0], operands[1]);
1965   DONE;
1968 (define_expand "mov<mode>"
1969   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1970         (match_operand:SWI1248x 1 "general_operand"))]
1971   ""
1972   "ix86_expand_move (<MODE>mode, operands); DONE;")
1974 (define_insn "*mov<mode>_xor"
1975   [(set (match_operand:SWI48 0 "register_operand" "=r")
1976         (match_operand:SWI48 1 "const0_operand"))
1977    (clobber (reg:CC FLAGS_REG))]
1978   "reload_completed"
1979   "xor{l}\t%k0, %k0"
1980   [(set_attr "type" "alu1")
1981    (set_attr "modrm_class" "op0")
1982    (set_attr "mode" "SI")
1983    (set_attr "length_immediate" "0")])
1985 (define_insn "*mov<mode>_or"
1986   [(set (match_operand:SWI48 0 "register_operand" "=r")
1987         (match_operand:SWI48 1 "constm1_operand"))
1988    (clobber (reg:CC FLAGS_REG))]
1989   "reload_completed"
1990   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1991   [(set_attr "type" "alu1")
1992    (set_attr "mode" "<MODE>")
1993    (set_attr "length_immediate" "1")])
1995 (define_insn "*movxi_internal_avx512f"
1996   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
1997         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1998   "TARGET_AVX512F
1999    && (register_operand (operands[0], XImode)
2000        || register_operand (operands[1], XImode))"
2002   switch (get_attr_type (insn))
2003     {
2004     case TYPE_SSELOG1:
2005       return standard_sse_constant_opcode (insn, operands[1]);
2007     case TYPE_SSEMOV:
2008       if (misaligned_operand (operands[0], XImode)
2009           || misaligned_operand (operands[1], XImode))
2010         return "vmovdqu32\t{%1, %0|%0, %1}";
2011       else
2012         return "vmovdqa32\t{%1, %0|%0, %1}";
2014     default:
2015       gcc_unreachable ();
2016     }
2018   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2019    (set_attr "prefix" "evex")
2020    (set_attr "mode" "XI")])
2022 (define_insn "*movoi_internal_avx"
2023   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2024         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2025   "TARGET_AVX
2026    && (register_operand (operands[0], OImode)
2027        || register_operand (operands[1], OImode))"
2029   switch (get_attr_type (insn))
2030     {
2031     case TYPE_SSELOG1:
2032       return standard_sse_constant_opcode (insn, operands[1]);
2034     case TYPE_SSEMOV:
2035       if (misaligned_operand (operands[0], OImode)
2036           || misaligned_operand (operands[1], OImode))
2037         {
2038           if (get_attr_mode (insn) == MODE_V8SF)
2039             return "vmovups\t{%1, %0|%0, %1}";
2040           else if (get_attr_mode (insn) == MODE_XI)
2041             return "vmovdqu32\t{%1, %0|%0, %1}";
2042           else
2043             return "vmovdqu\t{%1, %0|%0, %1}";
2044         }
2045       else
2046         {
2047           if (get_attr_mode (insn) == MODE_V8SF)
2048             return "vmovaps\t{%1, %0|%0, %1}";
2049           else if (get_attr_mode (insn) == MODE_XI)
2050             return "vmovdqa32\t{%1, %0|%0, %1}";
2051           else
2052             return "vmovdqa\t{%1, %0|%0, %1}";
2053         }
2055     default:
2056       gcc_unreachable ();
2057     }
2059   [(set_attr "isa" "*,avx2,*,*")
2060    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2061    (set_attr "prefix" "vex")
2062    (set (attr "mode")
2063         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2064                     (match_operand 1 "ext_sse_reg_operand"))
2065                  (const_string "XI")
2066                (and (eq_attr "alternative" "1")
2067                     (match_test "TARGET_AVX512VL"))
2068                  (const_string "XI")
2069                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2070                     (and (eq_attr "alternative" "3")
2071                          (match_test "TARGET_SSE_TYPELESS_STORES")))
2072                  (const_string "V8SF")
2073               ]
2074               (const_string "OI")))])
2076 (define_insn "*movti_internal"
2077   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2078         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v,Ye,r"))]
2079   "(TARGET_64BIT
2080     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2081    || (TARGET_SSE
2082        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2083        && (register_operand (operands[0], TImode)
2084            || register_operand (operands[1], TImode)))"
2086   switch (get_attr_type (insn))
2087     {
2088     case TYPE_MULTI:
2089       return "#";
2091     case TYPE_SSELOG1:
2092       return standard_sse_constant_opcode (insn, operands[1]);
2094     case TYPE_SSEMOV:
2095       /* TDmode values are passed as TImode on the stack.  Moving them
2096          to stack may result in unaligned memory access.  */
2097       if (misaligned_operand (operands[0], TImode)
2098           || misaligned_operand (operands[1], TImode))
2099         {
2100           if (get_attr_mode (insn) == MODE_V4SF)
2101             return "%vmovups\t{%1, %0|%0, %1}";
2102           else if (get_attr_mode (insn) == MODE_XI)
2103             return "vmovdqu32\t{%1, %0|%0, %1}";
2104           else
2105             return "%vmovdqu\t{%1, %0|%0, %1}";
2106         }
2107       else
2108         {
2109           if (get_attr_mode (insn) == MODE_V4SF)
2110             return "%vmovaps\t{%1, %0|%0, %1}";
2111           else if (get_attr_mode (insn) == MODE_XI)
2112             return "vmovdqa32\t{%1, %0|%0, %1}";
2113           else
2114             return "%vmovdqa\t{%1, %0|%0, %1}";
2115         }
2117     default:
2118       gcc_unreachable ();
2119     }
2121   [(set (attr "isa")
2122      (cond [(eq_attr "alternative" "0,1,6,7")
2123               (const_string "x64")
2124             (eq_attr "alternative" "3")
2125               (const_string "sse2")
2126            ]
2127            (const_string "*")))
2128    (set (attr "type")
2129      (cond [(eq_attr "alternative" "0,1,6,7")
2130               (const_string "multi")
2131             (eq_attr "alternative" "2,3")
2132               (const_string "sselog1")
2133            ]
2134            (const_string "ssemov")))
2135    (set (attr "prefix")
2136      (if_then_else (eq_attr "type" "sselog1,ssemov")
2137        (const_string "maybe_vex")
2138        (const_string "orig")))
2139    (set (attr "mode")
2140         (cond [(eq_attr "alternative" "0,1")
2141                  (const_string "DI")
2142                (ior (match_operand 0 "ext_sse_reg_operand")
2143                     (match_operand 1 "ext_sse_reg_operand"))
2144                  (const_string "XI")
2145                (and (eq_attr "alternative" "3")
2146                     (match_test "TARGET_AVX512VL"))
2147                  (const_string "XI")
2148                (ior (not (match_test "TARGET_SSE2"))
2149                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2150                          (and (eq_attr "alternative" "5")
2151                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2152                  (const_string "V4SF")
2153                (match_test "TARGET_AVX")
2154                  (const_string "TI")
2155                (match_test "optimize_function_for_size_p (cfun)")
2156                  (const_string "V4SF")
2157                ]
2158                (const_string "TI")))])
2160 (define_split
2161   [(set (match_operand:TI 0 "sse_reg_operand")
2162         (match_operand:TI 1 "general_reg_operand"))]
2163   "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2164    && reload_completed"
2165   [(set (match_dup 2)
2166         (vec_merge:V2DI
2167           (vec_duplicate:V2DI (match_dup 3))
2168           (match_dup 2)
2169           (const_int 2)))]
2171   operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2172   operands[3] = gen_highpart (DImode, operands[1]);
2174   emit_move_insn (gen_lowpart (DImode, operands[0]),
2175                   gen_lowpart (DImode, operands[1]));
2178 (define_insn "*movdi_internal"
2179   [(set (match_operand:DI 0 "nonimmediate_operand"
2180     "=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")
2181         (match_operand:DI 1 "general_operand"
2182     "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"))]
2183   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2185   switch (get_attr_type (insn))
2186     {
2187     case TYPE_MSKMOV:
2188       return "kmovq\t{%1, %0|%0, %1}";
2190     case TYPE_MULTI:
2191       return "#";
2193     case TYPE_MMX:
2194       return "pxor\t%0, %0";
2196     case TYPE_MMXMOV:
2197       /* Handle broken assemblers that require movd instead of movq.  */
2198       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2199           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2200         return "movd\t{%1, %0|%0, %1}";
2201       return "movq\t{%1, %0|%0, %1}";
2203     case TYPE_SSELOG1:
2204       return standard_sse_constant_opcode (insn, operands[1]);
2206     case TYPE_SSEMOV:
2207       switch (get_attr_mode (insn))
2208         {
2209         case MODE_DI:
2210           /* Handle broken assemblers that require movd instead of movq.  */
2211           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2212               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2213             return "%vmovd\t{%1, %0|%0, %1}";
2214           return "%vmovq\t{%1, %0|%0, %1}";
2215         case MODE_TI:
2216           return "%vmovdqa\t{%1, %0|%0, %1}";
2217         case MODE_XI:
2218           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2220         case MODE_V2SF:
2221           gcc_assert (!TARGET_AVX);
2222           return "movlps\t{%1, %0|%0, %1}";
2223         case MODE_V4SF:
2224           return "%vmovaps\t{%1, %0|%0, %1}";
2226         default:
2227           gcc_unreachable ();
2228         }
2230     case TYPE_SSECVT:
2231       if (SSE_REG_P (operands[0]))
2232         return "movq2dq\t{%1, %0|%0, %1}";
2233       else
2234         return "movdq2q\t{%1, %0|%0, %1}";
2236     case TYPE_LEA:
2237       return "lea{q}\t{%E1, %0|%0, %E1}";
2239     case TYPE_IMOV:
2240       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2241       if (get_attr_mode (insn) == MODE_SI)
2242         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2243       else if (which_alternative == 4)
2244         return "movabs{q}\t{%1, %0|%0, %1}";
2245       else if (ix86_use_lea_for_mov (insn, operands))
2246         return "lea{q}\t{%E1, %0|%0, %E1}";
2247       else
2248         return "mov{q}\t{%1, %0|%0, %1}";
2250     default:
2251       gcc_unreachable ();
2252     }
2254   [(set (attr "isa")
2255      (cond [(eq_attr "alternative" "0,1,17,18")
2256               (const_string "nox64")
2257             (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25")
2258               (const_string "x64")
2259            ]
2260            (const_string "*")))
2261    (set (attr "type")
2262      (cond [(eq_attr "alternative" "0,1,17,18")
2263               (const_string "multi")
2264             (eq_attr "alternative" "6")
2265               (const_string "mmx")
2266             (eq_attr "alternative" "7,8,9,10,11")
2267               (const_string "mmxmov")
2268             (eq_attr "alternative" "12")
2269               (const_string "sselog1")
2270             (eq_attr "alternative" "13,14,15,16,19,20")
2271               (const_string "ssemov")
2272             (eq_attr "alternative" "21,22")
2273               (const_string "ssecvt")
2274             (eq_attr "alternative" "23,24,25,26")
2275               (const_string "mskmov")
2276             (and (match_operand 0 "register_operand")
2277                  (match_operand 1 "pic_32bit_operand"))
2278               (const_string "lea")
2279            ]
2280            (const_string "imov")))
2281    (set (attr "modrm")
2282      (if_then_else
2283        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2284        (const_string "0")
2285        (const_string "*")))
2286    (set (attr "length_immediate")
2287      (if_then_else
2288        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2289        (const_string "8")
2290        (const_string "*")))
2291    (set (attr "prefix_rex")
2292      (if_then_else
2293        (eq_attr "alternative" "10,11,19,20")
2294        (const_string "1")
2295        (const_string "*")))
2296    (set (attr "prefix")
2297      (if_then_else (eq_attr "type" "sselog1,ssemov")
2298        (const_string "maybe_vex")
2299        (const_string "orig")))
2300    (set (attr "prefix_data16")
2301      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2302        (const_string "1")
2303        (const_string "*")))
2304    (set (attr "mode")
2305      (cond [(eq_attr "alternative" "2")
2306               (const_string "SI")
2307             (eq_attr "alternative" "12,13")
2308               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2309                           (match_operand 1 "ext_sse_reg_operand"))
2310                        (const_string "XI")
2311                      (ior (not (match_test "TARGET_SSE2"))
2312                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2313                        (const_string "V4SF")
2314                      (match_test "TARGET_AVX")
2315                        (const_string "TI")
2316                      (match_test "optimize_function_for_size_p (cfun)")
2317                        (const_string "V4SF")
2318                     ]
2319                     (const_string "TI"))
2321             (and (eq_attr "alternative" "14,15,16")
2322                  (not (match_test "TARGET_SSE2")))
2323               (const_string "V2SF")
2324            ]
2325            (const_string "DI")))
2326    (set (attr "enabled")
2327      (cond [(eq_attr "alternative" "15")
2328               (if_then_else
2329                 (match_test "TARGET_STV && TARGET_SSE2")
2330                 (symbol_ref "false")
2331                 (const_string "*"))
2332             (eq_attr "alternative" "16")
2333               (if_then_else
2334                 (match_test "TARGET_STV && TARGET_SSE2")
2335                 (symbol_ref "true")
2336                 (symbol_ref "false"))
2337            ]
2338            (const_string "*")))])
2340 (define_split
2341   [(set (match_operand:<DWI> 0 "general_reg_operand")
2342         (match_operand:<DWI> 1 "sse_reg_operand"))]
2343   "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC
2344    && reload_completed"
2345   [(set (match_dup 2)
2346         (vec_select:DWIH
2347           (match_dup 3)
2348           (parallel [(const_int 1)])))]
2350   operands[2] = gen_highpart (<MODE>mode, operands[0]);
2351   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2353   emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2354                   gen_lowpart (<MODE>mode, operands[1]));
2357 (define_split
2358   [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2359         (match_operand:DWI 1 "general_gr_operand"))]
2360   "reload_completed"
2361   [(const_int 0)]
2362   "ix86_split_long_move (operands); DONE;")
2364 (define_split
2365   [(set (match_operand:DI 0 "sse_reg_operand")
2366         (match_operand:DI 1 "general_reg_operand"))]
2367   "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2368    && reload_completed"
2369   [(set (match_dup 2)
2370         (vec_merge:V4SI
2371           (vec_duplicate:V4SI (match_dup 3))
2372           (match_dup 2)
2373           (const_int 2)))]
2375   operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2376   operands[3] = gen_highpart (SImode, operands[1]);
2378   emit_move_insn (gen_lowpart (SImode, operands[0]),
2379                   gen_lowpart (SImode, operands[1]));
2382 (define_insn "*movsi_internal"
2383   [(set (match_operand:SI 0 "nonimmediate_operand"
2384     "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm")
2385         (match_operand:SI 1 "general_operand"
2386     "g ,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,r   ,*r,*km,*k"))]
2387   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2389   switch (get_attr_type (insn))
2390     {
2391     case TYPE_SSELOG1:
2392       return standard_sse_constant_opcode (insn, operands[1]);
2394     case TYPE_MSKMOV:
2395       return "kmovd\t{%1, %0|%0, %1}";
2397     case TYPE_SSEMOV:
2398       switch (get_attr_mode (insn))
2399         {
2400         case MODE_SI:
2401           return "%vmovd\t{%1, %0|%0, %1}";
2402         case MODE_TI:
2403           return "%vmovdqa\t{%1, %0|%0, %1}";
2404         case MODE_XI:
2405           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2407         case MODE_V4SF:
2408           return "%vmovaps\t{%1, %0|%0, %1}";
2410         case MODE_SF:
2411           gcc_assert (!TARGET_AVX);
2412           return "movss\t{%1, %0|%0, %1}";
2414         default:
2415           gcc_unreachable ();
2416         }
2418     case TYPE_MMX:
2419       return "pxor\t%0, %0";
2421     case TYPE_MMXMOV:
2422       switch (get_attr_mode (insn))
2423         {
2424         case MODE_DI:
2425           return "movq\t{%1, %0|%0, %1}";
2426         case MODE_SI:
2427           return "movd\t{%1, %0|%0, %1}";
2429         default:
2430           gcc_unreachable ();
2431         }
2433     case TYPE_LEA:
2434       return "lea{l}\t{%E1, %0|%0, %E1}";
2436     case TYPE_IMOV:
2437       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2438       if (ix86_use_lea_for_mov (insn, operands))
2439         return "lea{l}\t{%E1, %0|%0, %E1}";
2440       else
2441         return "mov{l}\t{%1, %0|%0, %1}";
2443     default:
2444       gcc_unreachable ();
2445     }
2447   [(set (attr "type")
2448      (cond [(eq_attr "alternative" "2")
2449               (const_string "mmx")
2450             (eq_attr "alternative" "3,4,5,6,7")
2451               (const_string "mmxmov")
2452             (eq_attr "alternative" "8")
2453               (const_string "sselog1")
2454             (eq_attr "alternative" "9,10,11,12,13")
2455               (const_string "ssemov")
2456             (eq_attr "alternative" "14,15,16")
2457               (const_string "mskmov")
2458             (and (match_operand 0 "register_operand")
2459                  (match_operand 1 "pic_32bit_operand"))
2460               (const_string "lea")
2461            ]
2462            (const_string "imov")))
2463    (set (attr "prefix")
2464      (if_then_else (eq_attr "type" "sselog1,ssemov")
2465        (const_string "maybe_vex")
2466        (const_string "orig")))
2467    (set (attr "prefix_data16")
2468      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2469        (const_string "1")
2470        (const_string "*")))
2471    (set (attr "mode")
2472      (cond [(eq_attr "alternative" "2,3")
2473               (const_string "DI")
2474             (eq_attr "alternative" "8,9")
2475               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2476                           (match_operand 1 "ext_sse_reg_operand"))
2477                        (const_string "XI")
2478                      (ior (not (match_test "TARGET_SSE2"))
2479                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2480                        (const_string "V4SF")
2481                      (match_test "TARGET_AVX")
2482                        (const_string "TI")
2483                      (match_test "optimize_function_for_size_p (cfun)")
2484                        (const_string "V4SF")
2485                     ]
2486                     (const_string "TI"))
2488             (and (eq_attr "alternative" "10,11")
2489                  (not (match_test "TARGET_SSE2")))
2490               (const_string "SF")
2491            ]
2492            (const_string "SI")))])
2494 (define_insn "*movhi_internal"
2495   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2496         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2497   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2499   switch (get_attr_type (insn))
2500     {
2501     case TYPE_IMOVX:
2502       /* movzwl is faster than movw on p2 due to partial word stalls,
2503          though not as fast as an aligned movl.  */
2504       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2506     case TYPE_MSKMOV:
2507       switch (which_alternative)
2508         {
2509         case 4:
2510           return "kmovw\t{%k1, %0|%0, %k1}";
2511         case 6:
2512           return "kmovw\t{%1, %k0|%k0, %1}";
2513         case 5:
2514         case 7:
2515           return "kmovw\t{%1, %0|%0, %1}";
2516         default:
2517           gcc_unreachable ();
2518         }
2520     default:
2521       if (get_attr_mode (insn) == MODE_SI)
2522         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2523       else
2524         return "mov{w}\t{%1, %0|%0, %1}";
2525     }
2527   [(set (attr "type")
2528      (cond [(eq_attr "alternative" "4,5,6,7")
2529               (const_string "mskmov")
2530             (match_test "optimize_function_for_size_p (cfun)")
2531               (const_string "imov")
2532             (and (eq_attr "alternative" "0")
2533                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2534                       (not (match_test "TARGET_HIMODE_MATH"))))
2535               (const_string "imov")
2536             (and (eq_attr "alternative" "1,2")
2537                  (match_operand:HI 1 "aligned_operand"))
2538               (const_string "imov")
2539             (and (match_test "TARGET_MOVX")
2540                  (eq_attr "alternative" "0,2"))
2541               (const_string "imovx")
2542            ]
2543            (const_string "imov")))
2544     (set (attr "prefix")
2545       (if_then_else (eq_attr "alternative" "4,5,6,7")
2546         (const_string "vex")
2547         (const_string "orig")))
2548     (set (attr "mode")
2549       (cond [(eq_attr "type" "imovx")
2550                (const_string "SI")
2551              (and (eq_attr "alternative" "1,2")
2552                   (match_operand:HI 1 "aligned_operand"))
2553                (const_string "SI")
2554              (and (eq_attr "alternative" "0")
2555                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2556                        (not (match_test "TARGET_HIMODE_MATH"))))
2557                (const_string "SI")
2558             ]
2559             (const_string "HI")))])
2561 ;; Situation is quite tricky about when to choose full sized (SImode) move
2562 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2563 ;; partial register dependency machines (such as AMD Athlon), where QImode
2564 ;; moves issue extra dependency and for partial register stalls machines
2565 ;; that don't use QImode patterns (and QImode move cause stall on the next
2566 ;; instruction).
2568 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2569 ;; register stall machines with, where we use QImode instructions, since
2570 ;; partial register stall can be caused there.  Then we use movzx.
2572 (define_insn "*movqi_internal"
2573   [(set (match_operand:QI 0 "nonimmediate_operand"
2574                         "=q,q ,q ,r,r ,?r,m ,k,k,r,m,k")
2575         (match_operand:QI 1 "general_operand"
2576                         "q ,qn,qm,q,rn,qm,qn,r,k,k,k,m"))]
2577   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2579   static char buf[128];
2580   const char *ops;
2581   const char *suffix;
2583   switch (get_attr_type (insn))
2584     {
2585     case TYPE_IMOVX:
2586       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2587       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2589     case TYPE_MSKMOV:
2590       switch (which_alternative)
2591         {
2592         case 7:
2593           ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2594           break;
2595         case 9:
2596           ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2597           break;
2598         case 10:
2599         case 11:
2600           gcc_assert (TARGET_AVX512DQ);
2601           /* FALLTHRU */
2602         case 8:
2603           ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2604           break;
2605         default:
2606           gcc_unreachable ();
2607         }
2609       suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2611       snprintf (buf, sizeof (buf), ops, suffix);
2612       return buf;
2614     default:
2615       if (get_attr_mode (insn) == MODE_SI)
2616         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2617       else
2618         return "mov{b}\t{%1, %0|%0, %1}";
2619     }
2621   [(set (attr "isa")
2622      (if_then_else (eq_attr "alternative" "10,11")
2623        (const_string "avx512dq")
2624        (const_string "*")))
2625    (set (attr "type")
2626      (cond [(eq_attr "alternative" "7,8,9,10,11")
2627               (const_string "mskmov")
2628             (and (eq_attr "alternative" "5")
2629                  (not (match_operand:QI 1 "aligned_operand")))
2630               (const_string "imovx")
2631             (match_test "optimize_function_for_size_p (cfun)")
2632               (const_string "imov")
2633             (and (eq_attr "alternative" "3")
2634                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2635                       (not (match_test "TARGET_QIMODE_MATH"))))
2636               (const_string "imov")
2637             (eq_attr "alternative" "3,5")
2638               (const_string "imovx")
2639             (and (match_test "TARGET_MOVX")
2640                  (eq_attr "alternative" "2"))
2641               (const_string "imovx")
2642            ]
2643            (const_string "imov")))
2644    (set (attr "prefix")
2645      (if_then_else (eq_attr "alternative" "7,8,9")
2646        (const_string "vex")
2647        (const_string "orig")))
2648    (set (attr "mode")
2649       (cond [(eq_attr "alternative" "3,4,5")
2650                (const_string "SI")
2651              (eq_attr "alternative" "6")
2652                (const_string "QI")
2653              (and (eq_attr "alternative" "7,8,9")
2654                   (not (match_test "TARGET_AVX512DQ")))
2655                (const_string "HI")
2656              (eq_attr "type" "imovx")
2657                (const_string "SI")
2658              (and (eq_attr "type" "imov")
2659                   (and (eq_attr "alternative" "0,1")
2660                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2661                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2662                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2663                (const_string "SI")
2664              ;; Avoid partial register stalls when not using QImode arithmetic
2665              (and (eq_attr "type" "imov")
2666                   (and (eq_attr "alternative" "0,1")
2667                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2668                             (not (match_test "TARGET_QIMODE_MATH")))))
2669                (const_string "SI")
2670            ]
2671            (const_string "QI")))])
2673 ;; Stores and loads of ax to arbitrary constant address.
2674 ;; We fake an second form of instruction to force reload to load address
2675 ;; into register when rax is not available
2676 (define_insn "*movabs<mode>_1"
2677   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2678         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2679   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2681   /* Recover the full memory rtx.  */
2682   operands[0] = SET_DEST (PATTERN (insn));
2683   switch (which_alternative)
2684     {
2685     case 0:
2686       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2687     case 1:
2688       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2689     default:
2690       gcc_unreachable ();
2691     }
2693   [(set_attr "type" "imov")
2694    (set_attr "modrm" "0,*")
2695    (set_attr "length_address" "8,0")
2696    (set_attr "length_immediate" "0,*")
2697    (set_attr "memory" "store")
2698    (set_attr "mode" "<MODE>")])
2700 (define_insn "*movabs<mode>_2"
2701   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2702         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2703   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2705   /* Recover the full memory rtx.  */
2706   operands[1] = SET_SRC (PATTERN (insn));
2707   switch (which_alternative)
2708     {
2709     case 0:
2710       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2711     case 1:
2712       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2713     default:
2714       gcc_unreachable ();
2715     }
2717   [(set_attr "type" "imov")
2718    (set_attr "modrm" "0,*")
2719    (set_attr "length_address" "8,0")
2720    (set_attr "length_immediate" "0")
2721    (set_attr "memory" "load")
2722    (set_attr "mode" "<MODE>")])
2724 (define_insn "*swap<mode>"
2725   [(set (match_operand:SWI48 0 "register_operand" "+r")
2726         (match_operand:SWI48 1 "register_operand" "+r"))
2727    (set (match_dup 1)
2728         (match_dup 0))]
2729   ""
2730   "xchg{<imodesuffix>}\t%1, %0"
2731   [(set_attr "type" "imov")
2732    (set_attr "mode" "<MODE>")
2733    (set_attr "pent_pair" "np")
2734    (set_attr "athlon_decode" "vector")
2735    (set_attr "amdfam10_decode" "double")
2736    (set_attr "bdver1_decode" "double")])
2738 (define_insn "*swap<mode>"
2739   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2740         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2741    (set (match_dup 1)
2742         (match_dup 0))]
2743   ""
2744   "@
2745    xchg{<imodesuffix>}\t%1, %0
2746    xchg{l}\t%k1, %k0"
2747   [(set_attr "type" "imov")
2748    (set_attr "mode" "<MODE>,SI")
2749    (set (attr "preferred_for_size")
2750      (cond [(eq_attr "alternative" "0")
2751               (symbol_ref "false")]
2752            (symbol_ref "true")))
2753    ;; Potential partial reg stall on alternative 1.
2754    (set (attr "preferred_for_speed")
2755      (cond [(eq_attr "alternative" "1")
2756               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2757            (symbol_ref "true")))
2758    (set_attr "pent_pair" "np")
2759    (set_attr "athlon_decode" "vector")
2760    (set_attr "amdfam10_decode" "double")
2761    (set_attr "bdver1_decode" "double")])
2763 (define_expand "movstrict<mode>"
2764   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2765         (match_operand:SWI12 1 "general_operand"))]
2766   ""
2768   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2769     FAIL;
2770   if (SUBREG_P (operands[0])
2771       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2772     FAIL;
2773   /* Don't generate memory->memory moves, go through a register */
2774   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2775     operands[1] = force_reg (<MODE>mode, operands[1]);
2778 (define_insn "*movstrict<mode>_1"
2779   [(set (strict_low_part
2780           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2781         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2782   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2783    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2784   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2785   [(set_attr "type" "imov")
2786    (set_attr "mode" "<MODE>")])
2788 (define_insn "*movstrict<mode>_xor"
2789   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2790         (match_operand:SWI12 1 "const0_operand"))
2791    (clobber (reg:CC FLAGS_REG))]
2792   "reload_completed"
2793   "xor{<imodesuffix>}\t%0, %0"
2794   [(set_attr "type" "alu1")
2795    (set_attr "modrm_class" "op0")
2796    (set_attr "mode" "<MODE>")
2797    (set_attr "length_immediate" "0")])
2799 (define_expand "extv<mode>"
2800   [(set (match_operand:SWI24 0 "register_operand")
2801         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2802                             (match_operand:SI 2 "const_int_operand")
2803                             (match_operand:SI 3 "const_int_operand")))]
2804   ""
2806   /* Handle extractions from %ah et al.  */
2807   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2808     FAIL;
2810   unsigned int regno = reg_or_subregno (operands[1]);
2812   /* Be careful to expand only with registers having upper parts.  */
2813   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2814     operands[1] = copy_to_reg (operands[1]);
2817 (define_insn "*extv<mode>"
2818   [(set (match_operand:SWI24 0 "register_operand" "=R")
2819         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2820                             (const_int 8)
2821                             (const_int 8)))]
2822   ""
2823   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2824   [(set_attr "type" "imovx")
2825    (set_attr "mode" "SI")])
2827 (define_expand "extzv<mode>"
2828   [(set (match_operand:SWI248 0 "register_operand")
2829         (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2830                              (match_operand:SI 2 "const_int_operand")
2831                              (match_operand:SI 3 "const_int_operand")))]
2832   ""
2834   if (ix86_expand_pextr (operands))
2835     DONE;
2837   /* Handle extractions from %ah et al.  */
2838   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2839     FAIL;
2841   unsigned int regno = reg_or_subregno (operands[1]);
2843   /* Be careful to expand only with registers having upper parts.  */
2844   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2845     operands[1] = copy_to_reg (operands[1]);
2848 (define_insn "*extzvqi_mem_rex64"
2849   [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2850         (subreg:QI
2851           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2852                            (const_int 8)
2853                            (const_int 8)) 0))]
2854   "TARGET_64BIT && reload_completed"
2855   "mov{b}\t{%h1, %0|%0, %h1}"
2856   [(set_attr "type" "imov")
2857    (set_attr "mode" "QI")])
2859 (define_insn "*extzv<mode>"
2860   [(set (match_operand:SWI248 0 "register_operand" "=R")
2861         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2862                              (const_int 8)
2863                              (const_int 8)))]
2864   ""
2865   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2866   [(set_attr "type" "imovx")
2867    (set_attr "mode" "SI")])
2869 (define_insn "*extzvqi"
2870   [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2871         (subreg:QI
2872           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2873                            (const_int 8)
2874                            (const_int 8)) 0))]
2875   ""
2877   switch (get_attr_type (insn))
2878     {
2879     case TYPE_IMOVX:
2880       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2881     default:
2882       return "mov{b}\t{%h1, %0|%0, %h1}";
2883     }
2885   [(set_attr "isa" "*,*,nox64")
2886    (set (attr "type")
2887      (if_then_else (and (match_operand:QI 0 "register_operand")
2888                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2889                              (match_test "TARGET_MOVX")))
2890         (const_string "imovx")
2891         (const_string "imov")))
2892    (set (attr "mode")
2893      (if_then_else (eq_attr "type" "imovx")
2894         (const_string "SI")
2895         (const_string "QI")))])
2897 (define_peephole2
2898   [(set (match_operand:QI 0 "register_operand")
2899         (subreg:QI
2900           (zero_extract:SI (match_operand 1 "ext_register_operand")
2901                            (const_int 8)
2902                            (const_int 8)) 0))
2903    (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2904   "TARGET_64BIT
2905    && peep2_reg_dead_p (2, operands[0])"
2906   [(set (match_dup 2)
2907         (subreg:QI
2908           (zero_extract:SI (match_dup 1)
2909                            (const_int 8)
2910                            (const_int 8)) 0))])
2912 (define_expand "insv<mode>"
2913   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2914                              (match_operand:SI 1 "const_int_operand")
2915                              (match_operand:SI 2 "const_int_operand"))
2916         (match_operand:SWI248 3 "register_operand"))]
2917   ""
2919   rtx dst;
2921   if (ix86_expand_pinsr (operands))
2922     DONE;
2924   /* Handle insertions to %ah et al.  */
2925   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2926     FAIL;
2928   unsigned int regno = reg_or_subregno (operands[0]);
2930   /* Be careful to expand only with registers having upper parts.  */
2931   if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2932     dst = copy_to_reg (operands[0]);
2933   else
2934     dst = operands[0];
2936   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2938   /* Fix up the destination if needed.  */
2939   if (dst != operands[0])
2940     emit_move_insn (operands[0], dst);
2942   DONE;
2945 (define_insn "*insvqi_1_mem_rex64"
2946   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2947                          (const_int 8)
2948                          (const_int 8))
2949         (subreg:SI
2950           (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2951   "TARGET_64BIT && reload_completed"
2952   "mov{b}\t{%1, %h0|%h0, %1}"
2953   [(set_attr "type" "imov")
2954    (set_attr "mode" "QI")])
2956 (define_insn "insv<mode>_1"
2957   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2958                              (const_int 8)
2959                              (const_int 8))
2960         (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2961   ""
2963   if (CONST_INT_P (operands[1]))
2964     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2965   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2967   [(set_attr "isa" "*,nox64")
2968    (set_attr "type" "imov")
2969    (set_attr "mode" "QI")])
2971 (define_insn "*insvqi_1"
2972   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
2973                          (const_int 8)
2974                          (const_int 8))
2975         (subreg:SI
2976           (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2977   ""
2978   "mov{b}\t{%1, %h0|%h0, %1}"
2979   [(set_attr "isa" "*,nox64")
2980    (set_attr "type" "imov")
2981    (set_attr "mode" "QI")])
2983 (define_peephole2
2984   [(set (match_operand:QI 0 "register_operand")
2985         (match_operand:QI 1 "norex_memory_operand"))
2986    (set (zero_extract:SI (match_operand 2 "ext_register_operand")
2987                          (const_int 8)
2988                          (const_int 8))
2989         (subreg:SI (match_dup 0) 0))]
2990   "TARGET_64BIT
2991    && peep2_reg_dead_p (2, operands[0])"
2992   [(set (zero_extract:SI (match_dup 2)
2993                          (const_int 8)
2994                          (const_int 8))
2995            (subreg:SI (match_dup 1) 0))])
2997 (define_code_iterator any_extract [sign_extract zero_extract])
2999 (define_insn "*insvqi_2"
3000   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3001                          (const_int 8)
3002                          (const_int 8))
3003         (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3004                         (const_int 8)
3005                         (const_int 8)))]
3006   ""
3007   "mov{b}\t{%h1, %h0|%h0, %h1}"
3008   [(set_attr "type" "imov")
3009    (set_attr "mode" "QI")])
3011 (define_insn "*insvqi_3"
3012   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3013                          (const_int 8)
3014                          (const_int 8))
3015         (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3016                         (const_int 8)))]
3017   ""
3018   "mov{b}\t{%h1, %h0|%h0, %h1}"
3019   [(set_attr "type" "imov")
3020    (set_attr "mode" "QI")])
3022 ;; Floating point push instructions.
3024 (define_insn "*pushtf"
3025   [(set (match_operand:TF 0 "push_operand" "=<,<")
3026         (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3027   "TARGET_64BIT || TARGET_SSE"
3029   /* This insn should be already split before reg-stack.  */
3030   gcc_unreachable ();
3032   [(set_attr "isa" "*,x64")
3033    (set_attr "type" "multi")
3034    (set_attr "unit" "sse,*")
3035    (set_attr "mode" "TF,DI")])
3037 ;; %%% Kill this when call knows how to work this out.
3038 (define_split
3039   [(set (match_operand:TF 0 "push_operand")
3040         (match_operand:TF 1 "sse_reg_operand"))]
3041   "TARGET_SSE && reload_completed"
3042   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3043    (set (match_dup 0) (match_dup 1))]
3045   /* Preserve memory attributes. */
3046   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3049 (define_insn_and_split "*pushxf_rounded"
3050   [(set (mem:XF
3051           (pre_modify:P
3052             (reg:P SP_REG)
3053             (plus:P (reg:P SP_REG) (const_int -16))))
3054         (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3055   "TARGET_64BIT"
3056   "#"
3057   "&& 1"
3058   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3059    (set (match_dup 1) (match_dup 0))]
3061   rtx pat = PATTERN (curr_insn);
3062   operands[1] = SET_DEST (pat);
3064   /* Preserve memory attributes. */
3065   operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3067   [(set_attr "type" "multi")
3068    (set_attr "unit" "i387,*,*,*")
3069    (set (attr "mode")
3070         (cond [(eq_attr "alternative" "1,2,3")
3071                  (const_string "DI")
3072               ]
3073               (const_string "XF")))
3074    (set (attr "preferred_for_size")
3075      (cond [(eq_attr "alternative" "1")
3076               (symbol_ref "false")]
3077            (symbol_ref "true")))])
3079 (define_insn "*pushxf"
3080   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3081         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3082   ""
3084   /* This insn should be already split before reg-stack.  */
3085   gcc_unreachable ();
3087   [(set_attr "isa" "*,*,*,nox64,x64")
3088    (set_attr "type" "multi")
3089    (set_attr "unit" "i387,*,*,*,*")
3090    (set (attr "mode")
3091         (cond [(eq_attr "alternative" "1,2,3,4")
3092                  (if_then_else (match_test "TARGET_64BIT")
3093                    (const_string "DI")
3094                    (const_string "SI"))
3095               ]
3096               (const_string "XF")))
3097    (set (attr "preferred_for_size")
3098      (cond [(eq_attr "alternative" "1")
3099               (symbol_ref "false")]
3100            (symbol_ref "true")))])
3102 ;; %%% Kill this when call knows how to work this out.
3103 (define_split
3104   [(set (match_operand:XF 0 "push_operand")
3105         (match_operand:XF 1 "fp_register_operand"))]
3106   "reload_completed"
3107   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3108    (set (match_dup 0) (match_dup 1))]
3110   operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3111   /* Preserve memory attributes. */
3112   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3115 (define_insn "*pushdf"
3116   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3117         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3118   ""
3120   /* This insn should be already split before reg-stack.  */
3121   gcc_unreachable ();
3123   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3124    (set_attr "type" "multi")
3125    (set_attr "unit" "i387,*,*,*,*,sse")
3126    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3127    (set (attr "preferred_for_size")
3128      (cond [(eq_attr "alternative" "1")
3129               (symbol_ref "false")]
3130            (symbol_ref "true")))
3131    (set (attr "preferred_for_speed")
3132      (cond [(eq_attr "alternative" "1")
3133               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3134            (symbol_ref "true")))])
3135    
3136 ;; %%% Kill this when call knows how to work this out.
3137 (define_split
3138   [(set (match_operand:DF 0 "push_operand")
3139         (match_operand:DF 1 "any_fp_register_operand"))]
3140   "reload_completed"
3141   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3142    (set (match_dup 0) (match_dup 1))]
3144   /* Preserve memory attributes. */
3145   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3148 (define_insn "*pushsf_rex64"
3149   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3150         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3151   "TARGET_64BIT"
3153   /* Anything else should be already split before reg-stack.  */
3154   gcc_assert (which_alternative == 1);
3155   return "push{q}\t%q1";
3157   [(set_attr "type" "multi,push,multi")
3158    (set_attr "unit" "i387,*,*")
3159    (set_attr "mode" "SF,DI,SF")])
3161 (define_insn "*pushsf"
3162   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3163         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3164   "!TARGET_64BIT"
3166   /* Anything else should be already split before reg-stack.  */
3167   gcc_assert (which_alternative == 1);
3168   return "push{l}\t%1";
3170   [(set_attr "type" "multi,push,multi")
3171    (set_attr "unit" "i387,*,*")
3172    (set_attr "mode" "SF,SI,SF")])
3174 ;; %%% Kill this when call knows how to work this out.
3175 (define_split
3176   [(set (match_operand:SF 0 "push_operand")
3177         (match_operand:SF 1 "any_fp_register_operand"))]
3178   "reload_completed"
3179   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3180    (set (match_dup 0) (match_dup 1))]
3182   rtx op = XEXP (operands[0], 0);
3183   if (GET_CODE (op) == PRE_DEC)
3184     {
3185       gcc_assert (!TARGET_64BIT);
3186       op = GEN_INT (-4);
3187     }
3188   else
3189     {
3190       op = XEXP (XEXP (op, 1), 1);
3191       gcc_assert (CONST_INT_P (op));
3192     }
3193   operands[2] = op;
3194   /* Preserve memory attributes. */
3195   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3198 (define_split
3199   [(set (match_operand:SF 0 "push_operand")
3200         (match_operand:SF 1 "memory_operand"))]
3201   "reload_completed
3202    && find_constant_src (insn)"
3203   [(set (match_dup 0) (match_dup 2))]
3204   "operands[2] = find_constant_src (curr_insn);")
3206 (define_split
3207   [(set (match_operand 0 "push_operand")
3208         (match_operand 1 "general_gr_operand"))]
3209   "reload_completed
3210    && (GET_MODE (operands[0]) == TFmode
3211        || GET_MODE (operands[0]) == XFmode
3212        || GET_MODE (operands[0]) == DFmode)"
3213   [(const_int 0)]
3214   "ix86_split_long_move (operands); DONE;")
3216 ;; Floating point move instructions.
3218 (define_expand "movtf"
3219   [(set (match_operand:TF 0 "nonimmediate_operand")
3220         (match_operand:TF 1 "nonimmediate_operand"))]
3221   "TARGET_64BIT || TARGET_SSE"
3222   "ix86_expand_move (TFmode, operands); DONE;")
3224 (define_expand "mov<mode>"
3225   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3226         (match_operand:X87MODEF 1 "general_operand"))]
3227   ""
3228   "ix86_expand_move (<MODE>mode, operands); DONE;")
3230 (define_insn "*movtf_internal"
3231   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3232         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3233   "(TARGET_64BIT || TARGET_SSE)
3234    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3235    && (lra_in_progress || reload_completed
3236        || !CONST_DOUBLE_P (operands[1])
3237        || ((optimize_function_for_size_p (cfun)
3238             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3239            && standard_sse_constant_p (operands[1], TFmode) == 1
3240            && !memory_operand (operands[0], TFmode))
3241        || (!TARGET_MEMORY_MISMATCH_STALL
3242            && memory_operand (operands[0], TFmode)))"
3244   switch (get_attr_type (insn))
3245     {
3246     case TYPE_SSELOG1:
3247       return standard_sse_constant_opcode (insn, operands[1]);
3249     case TYPE_SSEMOV:
3250       /* Handle misaligned load/store since we
3251          don't have movmisaligntf pattern. */
3252       if (misaligned_operand (operands[0], TFmode)
3253           || misaligned_operand (operands[1], TFmode))
3254         {
3255           if (get_attr_mode (insn) == MODE_V4SF)
3256             return "%vmovups\t{%1, %0|%0, %1}";
3257           else if (TARGET_AVX512VL
3258                    && (EXT_REX_SSE_REG_P (operands[0])
3259                        || EXT_REX_SSE_REG_P (operands[1])))
3260             return "vmovdqu64\t{%1, %0|%0, %1}";
3261           else
3262             return "%vmovdqu\t{%1, %0|%0, %1}";
3263         }
3264       else
3265         {
3266           if (get_attr_mode (insn) == MODE_V4SF)
3267             return "%vmovaps\t{%1, %0|%0, %1}";
3268           else if (TARGET_AVX512VL
3269                    && (EXT_REX_SSE_REG_P (operands[0])
3270                        || EXT_REX_SSE_REG_P (operands[1])))
3271             return "vmovdqa64\t{%1, %0|%0, %1}";
3272           else
3273             return "%vmovdqa\t{%1, %0|%0, %1}";
3274         }
3276     case TYPE_MULTI:
3277         return "#";
3279     default:
3280       gcc_unreachable ();
3281     }
3283   [(set_attr "isa" "*,*,*,x64,x64")
3284    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3285    (set (attr "prefix")
3286      (if_then_else (eq_attr "type" "sselog1,ssemov")
3287        (const_string "maybe_vex")
3288        (const_string "orig")))
3289    (set (attr "mode")
3290         (cond [(eq_attr "alternative" "3,4")
3291                  (const_string "DI")
3292                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3293                  (const_string "V4SF")
3294                (and (eq_attr "alternative" "2")
3295                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3296                  (const_string "V4SF")
3297                (match_test "TARGET_AVX")
3298                  (const_string "TI")
3299                (ior (not (match_test "TARGET_SSE2"))
3300                     (match_test "optimize_function_for_size_p (cfun)"))
3301                  (const_string "V4SF")
3302                ]
3303                (const_string "TI")))])
3305 (define_split
3306   [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3307         (match_operand:TF 1 "general_gr_operand"))]
3308   "reload_completed"
3309   [(const_int 0)]
3310   "ix86_split_long_move (operands); DONE;")
3312 ;; Possible store forwarding (partial memory) stall
3313 ;; in alternatives 4, 6, 7 and 8.
3314 (define_insn "*movxf_internal"
3315   [(set (match_operand:XF 0 "nonimmediate_operand"
3316          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o ,o")
3317         (match_operand:XF 1 "general_operand"
3318          "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3319   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3320    && (lra_in_progress || reload_completed
3321        || !CONST_DOUBLE_P (operands[1])
3322        || ((optimize_function_for_size_p (cfun)
3323             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3324            && standard_80387_constant_p (operands[1]) > 0
3325            && !memory_operand (operands[0], XFmode))
3326        || (!TARGET_MEMORY_MISMATCH_STALL
3327            && memory_operand (operands[0], XFmode))
3328        || !TARGET_HARD_XF_REGS)"
3330   switch (get_attr_type (insn))
3331     {
3332     case TYPE_FMOV:
3333       if (which_alternative == 2)
3334         return standard_80387_constant_opcode (operands[1]);
3335       return output_387_reg_move (insn, operands);
3337     case TYPE_MULTI:
3338       return "#";
3340     default:
3341       gcc_unreachable ();
3342     }
3344   [(set (attr "isa")
3345         (cond [(eq_attr "alternative" "7,10")
3346                  (const_string "nox64")
3347                (eq_attr "alternative" "8,11")
3348                  (const_string "x64")
3349               ]
3350               (const_string "*")))
3351    (set (attr "type")
3352         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3353                  (const_string "multi")
3354               ]
3355               (const_string "fmov")))
3356    (set (attr "mode")
3357         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3358                  (if_then_else (match_test "TARGET_64BIT")
3359                    (const_string "DI")
3360                    (const_string "SI"))
3361               ]
3362               (const_string "XF")))
3363    (set (attr "preferred_for_size")
3364      (cond [(eq_attr "alternative" "3,4")
3365               (symbol_ref "false")]
3366            (symbol_ref "true")))
3367    (set (attr "enabled")
3368      (cond [(eq_attr "alternative" "9,10,11")
3369               (if_then_else
3370                 (match_test "TARGET_HARD_XF_REGS")
3371                 (symbol_ref "false")
3372                 (const_string "*"))
3373             (not (match_test "TARGET_HARD_XF_REGS"))
3374               (symbol_ref "false")
3375            ]
3376            (const_string "*")))])
3377    
3378 (define_split
3379   [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3380         (match_operand:XF 1 "general_gr_operand"))]
3381   "reload_completed"
3382   [(const_int 0)]
3383   "ix86_split_long_move (operands); DONE;")
3385 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3386 (define_insn "*movdf_internal"
3387   [(set (match_operand:DF 0 "nonimmediate_operand"
3388     "=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")
3389         (match_operand:DF 1 "general_operand"
3390     "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"))]
3391   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3392    && (lra_in_progress || reload_completed
3393        || !CONST_DOUBLE_P (operands[1])
3394        || ((optimize_function_for_size_p (cfun)
3395             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3396            && ((IS_STACK_MODE (DFmode)
3397                 && standard_80387_constant_p (operands[1]) > 0)
3398                || (TARGET_SSE2 && TARGET_SSE_MATH
3399                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3400            && !memory_operand (operands[0], DFmode))
3401        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3402            && memory_operand (operands[0], DFmode))
3403        || !TARGET_HARD_DF_REGS)"
3405   switch (get_attr_type (insn))
3406     {
3407     case TYPE_FMOV:
3408       if (which_alternative == 2)
3409         return standard_80387_constant_opcode (operands[1]);
3410       return output_387_reg_move (insn, operands);
3412     case TYPE_MULTI:
3413       return "#";
3415     case TYPE_IMOV:
3416       if (get_attr_mode (insn) == MODE_SI)
3417         return "mov{l}\t{%1, %k0|%k0, %1}";
3418       else if (which_alternative == 11)
3419         return "movabs{q}\t{%1, %0|%0, %1}";
3420       else
3421         return "mov{q}\t{%1, %0|%0, %1}";
3423     case TYPE_SSELOG1:
3424       return standard_sse_constant_opcode (insn, operands[1]);
3426     case TYPE_SSEMOV:
3427       switch (get_attr_mode (insn))
3428         {
3429         case MODE_DF:
3430           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3431             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3432           return "%vmovsd\t{%1, %0|%0, %1}";
3434         case MODE_V4SF:
3435           return "%vmovaps\t{%1, %0|%0, %1}";
3436         case MODE_V8DF:
3437           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3438         case MODE_V2DF:
3439           return "%vmovapd\t{%1, %0|%0, %1}";
3441         case MODE_V2SF:
3442           gcc_assert (!TARGET_AVX);
3443           return "movlps\t{%1, %0|%0, %1}";
3444         case MODE_V1DF:
3445           gcc_assert (!TARGET_AVX);
3446           return "movlpd\t{%1, %0|%0, %1}";
3448         case MODE_DI:
3449           /* Handle broken assemblers that require movd instead of movq.  */
3450           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3451               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3452             return "%vmovd\t{%1, %0|%0, %1}";
3453           return "%vmovq\t{%1, %0|%0, %1}";
3455         default:
3456           gcc_unreachable ();
3457         }
3459     default:
3460       gcc_unreachable ();
3461     }
3463   [(set (attr "isa")
3464         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3465                  (const_string "nox64")
3466                (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3467                  (const_string "x64")
3468                (eq_attr "alternative" "12,13,14,15")
3469                  (const_string "sse2")
3470               ]
3471               (const_string "*")))
3472    (set (attr "type")
3473         (cond [(eq_attr "alternative" "0,1,2")
3474                  (const_string "fmov")
3475                (eq_attr "alternative" "3,4,5,6,7,22,23")
3476                  (const_string "multi")
3477                (eq_attr "alternative" "8,9,10,11,24,25")
3478                  (const_string "imov")
3479                (eq_attr "alternative" "12,16")
3480                  (const_string "sselog1")
3481               ]
3482               (const_string "ssemov")))
3483    (set (attr "modrm")
3484      (if_then_else (eq_attr "alternative" "11")
3485        (const_string "0")
3486        (const_string "*")))
3487    (set (attr "length_immediate")
3488      (if_then_else (eq_attr "alternative" "11")
3489        (const_string "8")
3490        (const_string "*")))
3491    (set (attr "prefix")
3492      (if_then_else (eq_attr "type" "sselog1,ssemov")
3493        (const_string "maybe_vex")
3494        (const_string "orig")))
3495    (set (attr "prefix_data16")
3496      (if_then_else
3497        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3498             (eq_attr "mode" "V1DF"))
3499        (const_string "1")
3500        (const_string "*")))
3501    (set (attr "mode")
3502         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3503                  (const_string "SI")
3504                (eq_attr "alternative" "8,9,11,20,21,24,25")
3505                  (const_string "DI")
3507                /* xorps is one byte shorter for non-AVX targets.  */
3508                (eq_attr "alternative" "12,16")
3509                  (cond [(not (match_test "TARGET_SSE2"))
3510                           (const_string "V4SF")
3511                         (match_test "TARGET_AVX512F")
3512                           (const_string "XI")
3513                         (match_test "TARGET_AVX")
3514                           (const_string "V2DF")
3515                         (match_test "optimize_function_for_size_p (cfun)")
3516                           (const_string "V4SF")
3517                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3518                           (const_string "TI")
3519                        ]
3520                        (const_string "V2DF"))
3522                /* For architectures resolving dependencies on
3523                   whole SSE registers use movapd to break dependency
3524                   chains, otherwise use short move to avoid extra work.  */
3526                /* movaps is one byte shorter for non-AVX targets.  */
3527                (eq_attr "alternative" "13,17")
3528                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3529                              (match_operand 1 "ext_sse_reg_operand"))
3530                           (const_string "V8DF")
3531                         (ior (not (match_test "TARGET_SSE2"))
3532                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3533                           (const_string "V4SF")
3534                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3535                           (const_string "V2DF")
3536                         (match_test "TARGET_AVX")
3537                           (const_string "DF")
3538                         (match_test "optimize_function_for_size_p (cfun)")
3539                           (const_string "V4SF")
3540                        ]
3541                        (const_string "DF"))
3543                /* For architectures resolving dependencies on register
3544                   parts we may avoid extra work to zero out upper part
3545                   of register.  */
3546                (eq_attr "alternative" "14,18")
3547                  (cond [(not (match_test "TARGET_SSE2"))
3548                           (const_string "V2SF")
3549                         (match_test "TARGET_AVX")
3550                           (const_string "DF")
3551                         (match_test "TARGET_SSE_SPLIT_REGS")
3552                           (const_string "V1DF")
3553                        ]
3554                        (const_string "DF"))
3556                (and (eq_attr "alternative" "15,19")
3557                     (not (match_test "TARGET_SSE2")))
3558                  (const_string "V2SF")
3559               ]
3560               (const_string "DF")))
3561    (set (attr "preferred_for_size")
3562      (cond [(eq_attr "alternative" "3,4")
3563               (symbol_ref "false")]
3564            (symbol_ref "true")))
3565    (set (attr "preferred_for_speed")
3566      (cond [(eq_attr "alternative" "3,4")
3567               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3568            (symbol_ref "true")))
3569    (set (attr "enabled")
3570      (cond [(eq_attr "alternative" "22,23,24,25")
3571               (if_then_else
3572                 (match_test "TARGET_HARD_DF_REGS")
3573                 (symbol_ref "false")
3574                 (const_string "*"))
3575             (not (match_test "TARGET_HARD_DF_REGS"))
3576               (symbol_ref "false")
3577            ]
3578            (const_string "*")))])
3580 (define_split
3581   [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3582         (match_operand:DF 1 "general_gr_operand"))]
3583   "!TARGET_64BIT && reload_completed"
3584   [(const_int 0)]
3585   "ix86_split_long_move (operands); DONE;")
3587 (define_insn "*movsf_internal"
3588   [(set (match_operand:SF 0 "nonimmediate_operand"
3589           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
3590         (match_operand:SF 1 "general_operand"
3591           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
3592   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3593    && (lra_in_progress || reload_completed
3594        || !CONST_DOUBLE_P (operands[1])
3595        || ((optimize_function_for_size_p (cfun)
3596             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3597            && ((IS_STACK_MODE (SFmode)
3598                 && standard_80387_constant_p (operands[1]) > 0)
3599                || (TARGET_SSE && TARGET_SSE_MATH
3600                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3601        || memory_operand (operands[0], SFmode)
3602        || !TARGET_HARD_SF_REGS)"
3604   switch (get_attr_type (insn))
3605     {
3606     case TYPE_FMOV:
3607       if (which_alternative == 2)
3608         return standard_80387_constant_opcode (operands[1]);
3609       return output_387_reg_move (insn, operands);
3611     case TYPE_IMOV:
3612       return "mov{l}\t{%1, %0|%0, %1}";
3614     case TYPE_SSELOG1:
3615       return standard_sse_constant_opcode (insn, operands[1]);
3617     case TYPE_SSEMOV:
3618       switch (get_attr_mode (insn))
3619         {
3620         case MODE_SF:
3621           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3622             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3623           return "%vmovss\t{%1, %0|%0, %1}";
3625         case MODE_V16SF:
3626           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3627         case MODE_V4SF:
3628           return "%vmovaps\t{%1, %0|%0, %1}";
3630         case MODE_SI:
3631           return "%vmovd\t{%1, %0|%0, %1}";
3633         default:
3634           gcc_unreachable ();
3635         }
3637     case TYPE_MMXMOV:
3638       switch (get_attr_mode (insn))
3639         {
3640         case MODE_DI:
3641           return "movq\t{%1, %0|%0, %1}";
3642         case MODE_SI:
3643           return "movd\t{%1, %0|%0, %1}";
3645         default:
3646           gcc_unreachable ();
3647         }
3649     default:
3650       gcc_unreachable ();
3651     }
3653   [(set (attr "type")
3654         (cond [(eq_attr "alternative" "0,1,2")
3655                  (const_string "fmov")
3656                (eq_attr "alternative" "3,4,16,17")
3657                  (const_string "imov")
3658                (eq_attr "alternative" "5")
3659                  (const_string "sselog1")
3660                (eq_attr "alternative" "11,12,13,14,15")
3661                  (const_string "mmxmov")
3662               ]
3663               (const_string "ssemov")))
3664    (set (attr "prefix")
3665      (if_then_else (eq_attr "type" "sselog1,ssemov")
3666        (const_string "maybe_vex")
3667        (const_string "orig")))
3668    (set (attr "prefix_data16")
3669      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3670        (const_string "1")
3671        (const_string "*")))
3672    (set (attr "mode")
3673         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3674                  (const_string "SI")
3675                (eq_attr "alternative" "11")
3676                  (const_string "DI")
3677                (eq_attr "alternative" "5")
3678                  (cond [(not (match_test "TARGET_SSE2"))
3679                           (const_string "V4SF")
3680                         (match_test "TARGET_AVX512F")
3681                           (const_string "V16SF")
3682                         (match_test "TARGET_AVX")
3683                           (const_string "V4SF")
3684                         (match_test "optimize_function_for_size_p (cfun)")
3685                           (const_string "V4SF")
3686                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3687                           (const_string "TI")
3688                        ]
3689                        (const_string "V4SF"))
3691                /* For architectures resolving dependencies on
3692                   whole SSE registers use APS move to break dependency
3693                   chains, otherwise use short move to avoid extra work.
3695                   Do the same for architectures resolving dependencies on
3696                   the parts.  While in DF mode it is better to always handle
3697                   just register parts, the SF mode is different due to lack
3698                   of instructions to load just part of the register.  It is
3699                   better to maintain the whole registers in single format
3700                   to avoid problems on using packed logical operations.  */
3701                (eq_attr "alternative" "6")
3702                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3703                               (match_operand 1 "ext_sse_reg_operand"))
3704                           (const_string "V16SF")
3705                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3706                              (match_test "TARGET_SSE_SPLIT_REGS"))
3707                           (const_string "V4SF")
3708                        ]
3709                        (const_string "SF"))
3710               ]
3711               (const_string "SF")))
3712    (set (attr "enabled")
3713      (cond [(eq_attr "alternative" "16,17")
3714               (if_then_else
3715                 (match_test "TARGET_HARD_SF_REGS")
3716                 (symbol_ref "false")
3717                 (const_string "*"))
3718             (not (match_test "TARGET_HARD_SF_REGS"))
3719               (symbol_ref "false")
3720            ]
3721            (const_string "*")))])
3723 (define_split
3724   [(set (match_operand 0 "any_fp_register_operand")
3725         (match_operand 1 "nonimmediate_operand"))]
3726   "reload_completed
3727    && (GET_MODE (operands[0]) == TFmode
3728        || GET_MODE (operands[0]) == XFmode
3729        || GET_MODE (operands[0]) == DFmode
3730        || GET_MODE (operands[0]) == SFmode)
3731    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3732   [(set (match_dup 0) (match_dup 2))]
3733   "operands[2] = find_constant_src (curr_insn);")
3735 (define_split
3736   [(set (match_operand 0 "any_fp_register_operand")
3737         (float_extend (match_operand 1 "nonimmediate_operand")))]
3738   "reload_completed
3739    && (GET_MODE (operands[0]) == TFmode
3740        || GET_MODE (operands[0]) == XFmode
3741        || GET_MODE (operands[0]) == DFmode)
3742    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3743   [(set (match_dup 0) (match_dup 2))]
3744   "operands[2] = find_constant_src (curr_insn);")
3746 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3747 (define_split
3748   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3749         (match_operand:X87MODEF 1 "immediate_operand"))]
3750   "reload_completed
3751    && (standard_80387_constant_p (operands[1]) == 8
3752        || standard_80387_constant_p (operands[1]) == 9)"
3753   [(set (match_dup 0)(match_dup 1))
3754    (set (match_dup 0)
3755         (neg:X87MODEF (match_dup 0)))]
3757   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3758     operands[1] = CONST0_RTX (<MODE>mode);
3759   else
3760     operands[1] = CONST1_RTX (<MODE>mode);
3763 (define_insn "swapxf"
3764   [(set (match_operand:XF 0 "register_operand" "+f")
3765         (match_operand:XF 1 "register_operand" "+f"))
3766    (set (match_dup 1)
3767         (match_dup 0))]
3768   "TARGET_80387"
3770   if (STACK_TOP_P (operands[0]))
3771     return "fxch\t%1";
3772   else
3773     return "fxch\t%0";
3775   [(set_attr "type" "fxch")
3776    (set_attr "mode" "XF")])
3778 (define_insn "*swap<mode>"
3779   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3780         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3781    (set (match_dup 1)
3782         (match_dup 0))]
3783   "TARGET_80387 || reload_completed"
3785   if (STACK_TOP_P (operands[0]))
3786     return "fxch\t%1";
3787   else
3788     return "fxch\t%0";
3790   [(set_attr "type" "fxch")
3791    (set_attr "mode" "<MODE>")])
3793 ;; Zero extension instructions
3795 (define_expand "zero_extendsidi2"
3796   [(set (match_operand:DI 0 "nonimmediate_operand")
3797         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3799 (define_insn "*zero_extendsidi2"
3800   [(set (match_operand:DI 0 "nonimmediate_operand"
3801                 "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?*Yi,*x,*x,*v,*r")
3802         (zero_extend:DI
3803          (match_operand:SI 1 "x86_64_zext_operand"
3804                 "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,r   ,m ,*x,*v,*k")))]
3805   ""
3807   switch (get_attr_type (insn))
3808     {
3809     case TYPE_IMOVX:
3810       if (ix86_use_lea_for_mov (insn, operands))
3811         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3812       else
3813         return "mov{l}\t{%1, %k0|%k0, %1}";
3815     case TYPE_MULTI:
3816       return "#";
3818     case TYPE_MMXMOV:
3819       return "movd\t{%1, %0|%0, %1}";
3821     case TYPE_SSEMOV:
3822       if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3823         {
3824           if (EXT_REX_SSE_REG_P (operands[0])
3825               || EXT_REX_SSE_REG_P (operands[1]))
3826             return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3827           else
3828             return "%vpmovzxdq\t{%1, %0|%0, %1}";
3829         }
3831       if (GENERAL_REG_P (operands[0]))
3832         return "%vmovd\t{%1, %k0|%k0, %1}";
3834       return "%vmovd\t{%1, %0|%0, %1}";
3836     case TYPE_MSKMOV:
3837       return "kmovd\t{%1, %k0|%k0, %1}";
3839     default:
3840       gcc_unreachable ();
3841     }
3843   [(set (attr "isa")
3844      (cond [(eq_attr "alternative" "0,1,2")
3845               (const_string "nox64")
3846             (eq_attr "alternative" "3")
3847               (const_string "x64")
3848             (eq_attr "alternative" "9")
3849               (const_string "sse2")
3850             (eq_attr "alternative" "10")
3851               (const_string "sse4")
3852             (eq_attr "alternative" "11")
3853               (const_string "avx512f")
3854             (eq_attr "alternative" "12")
3855               (const_string "x64_avx512bw")
3856            ]
3857            (const_string "*")))
3858    (set (attr "type")
3859      (cond [(eq_attr "alternative" "0,1,2,4")
3860               (const_string "multi")
3861             (eq_attr "alternative" "5,6")
3862               (const_string "mmxmov")
3863             (eq_attr "alternative" "7")
3864               (if_then_else (match_test "TARGET_64BIT")
3865                 (const_string "ssemov")
3866                 (const_string "multi"))
3867             (eq_attr "alternative" "8,9,10,11")
3868               (const_string "ssemov")
3869             (eq_attr "alternative" "12")
3870               (const_string "mskmov")
3871            ]
3872            (const_string "imovx")))
3873    (set (attr "prefix_extra")
3874      (if_then_else (eq_attr "alternative" "10,11")
3875        (const_string "1")
3876        (const_string "*")))
3877    (set (attr "prefix")
3878      (if_then_else (eq_attr "type" "ssemov")
3879        (const_string "maybe_vex")
3880        (const_string "orig")))
3881    (set (attr "prefix_0f")
3882      (if_then_else (eq_attr "type" "imovx")
3883        (const_string "0")
3884        (const_string "*")))
3885    (set (attr "mode")
3886      (cond [(eq_attr "alternative" "5,6")
3887               (const_string "DI")
3888             (and (eq_attr "alternative" "7")
3889                  (match_test "TARGET_64BIT"))
3890               (const_string "TI")
3891             (eq_attr "alternative" "8,10,11")
3892               (const_string "TI")
3893            ]
3894            (const_string "SI")))])
3896 (define_split
3897   [(set (match_operand:DI 0 "memory_operand")
3898         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3899   "reload_completed"
3900   [(set (match_dup 4) (const_int 0))]
3901   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3903 (define_split
3904   [(set (match_operand:DI 0 "general_reg_operand")
3905         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3906   "!TARGET_64BIT && reload_completed
3907    && REGNO (operands[0]) == REGNO (operands[1])"
3908   [(set (match_dup 4) (const_int 0))]
3909   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3911 (define_split
3912   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3913         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3914   "!TARGET_64BIT && reload_completed
3915    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3916   [(set (match_dup 3) (match_dup 1))
3917    (set (match_dup 4) (const_int 0))]
3918   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3920 (define_peephole2
3921   [(set (match_operand:DI 0 "general_reg_operand")
3922         (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))
3923    (set (match_operand:DI 2 "sse_reg_operand") (match_dup 0))]
3924   "TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
3925    && peep2_reg_dead_p (2, operands[0])"
3926   [(set (match_dup 2)
3927         (zero_extend:DI (match_dup 1)))])
3929 (define_mode_attr kmov_isa
3930   [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3932 (define_insn "zero_extend<mode>di2"
3933   [(set (match_operand:DI 0 "register_operand" "=r,*r")
3934         (zero_extend:DI
3935          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3936   "TARGET_64BIT"
3937   "@
3938    movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3939    kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3940   [(set_attr "isa" "*,<kmov_isa>")
3941    (set_attr "type" "imovx,mskmov")
3942    (set_attr "mode" "SI,<MODE>")])
3944 (define_expand "zero_extend<mode>si2"
3945   [(set (match_operand:SI 0 "register_operand")
3946         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3947   ""
3949   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3950     {
3951       operands[1] = force_reg (<MODE>mode, operands[1]);
3952       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3953       DONE;
3954     }
3957 (define_insn_and_split "zero_extend<mode>si2_and"
3958   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3959         (zero_extend:SI
3960           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3961    (clobber (reg:CC FLAGS_REG))]
3962   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3963   "#"
3964   "&& reload_completed"
3965   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3966               (clobber (reg:CC FLAGS_REG))])]
3968   if (!REG_P (operands[1])
3969       || REGNO (operands[0]) != REGNO (operands[1]))
3970     {
3971       ix86_expand_clear (operands[0]);
3973       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3974       emit_insn (gen_movstrict<mode>
3975                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3976       DONE;
3977     }
3979   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3981   [(set_attr "type" "alu1")
3982    (set_attr "mode" "SI")])
3984 (define_insn "*zero_extend<mode>si2"
3985   [(set (match_operand:SI 0 "register_operand" "=r,*r")
3986         (zero_extend:SI
3987           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3988   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3989   "@
3990    movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3991    kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3992   [(set_attr "isa" "*,<kmov_isa>")
3993    (set_attr "type" "imovx,mskmov")
3994    (set_attr "mode" "SI,<MODE>")])
3996 (define_expand "zero_extendqihi2"
3997   [(set (match_operand:HI 0 "register_operand")
3998         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3999   ""
4001   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4002     {
4003       operands[1] = force_reg (QImode, operands[1]);
4004       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4005       DONE;
4006     }
4009 (define_insn_and_split "zero_extendqihi2_and"
4010   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4011         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4012    (clobber (reg:CC FLAGS_REG))]
4013   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4014   "#"
4015   "&& reload_completed"
4016   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4017               (clobber (reg:CC FLAGS_REG))])]
4019   if (!REG_P (operands[1])
4020       || REGNO (operands[0]) != REGNO (operands[1]))
4021     {
4022       ix86_expand_clear (operands[0]);
4024       gcc_assert (!TARGET_PARTIAL_REG_STALL);
4025       emit_insn (gen_movstrictqi
4026                   (gen_lowpart (QImode, operands[0]), operands[1]));
4027       DONE;
4028     }
4030   operands[0] = gen_lowpart (SImode, operands[0]);
4032   [(set_attr "type" "alu1")
4033    (set_attr "mode" "SI")])
4035 ; zero extend to SImode to avoid partial register stalls
4036 (define_insn "*zero_extendqihi2"
4037   [(set (match_operand:HI 0 "register_operand" "=r,*r")
4038         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4039   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4040   "@
4041    movz{bl|x}\t{%1, %k0|%k0, %1}
4042    kmovb\t{%1, %k0|%k0, %1}"
4043   [(set_attr "isa" "*,avx512dq")
4044    (set_attr "type" "imovx,mskmov")
4045    (set_attr "mode" "SI,QI")])
4047 (define_insn_and_split "*zext<mode>_doubleword_and"
4048   [(set (match_operand:DI 0 "register_operand" "=&<r>")
4049         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4050   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4051    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4052   "#"
4053   "&& reload_completed && GENERAL_REG_P (operands[0])"
4054   [(set (match_dup 2) (const_int 0))]
4056   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4058   emit_move_insn (operands[0], const0_rtx);
4060   gcc_assert (!TARGET_PARTIAL_REG_STALL);
4061   emit_insn (gen_movstrict<mode>
4062              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4065 (define_insn_and_split "*zext<mode>_doubleword"
4066   [(set (match_operand:DI 0 "register_operand" "=r")
4067         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4068   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4069    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4070   "#"
4071   "&& reload_completed && GENERAL_REG_P (operands[0])"
4072   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4073    (set (match_dup 2) (const_int 0))]
4074   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4076 (define_insn_and_split "*zextsi_doubleword"
4077   [(set (match_operand:DI 0 "register_operand" "=r")
4078         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4079   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4080   "#"
4081   "&& reload_completed && GENERAL_REG_P (operands[0])"
4082   [(set (match_dup 0) (match_dup 1))
4083    (set (match_dup 2) (const_int 0))]
4084   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4086 ;; Sign extension instructions
4088 (define_expand "extendsidi2"
4089   [(set (match_operand:DI 0 "register_operand")
4090         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4091   ""
4093   if (!TARGET_64BIT)
4094     {
4095       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4096       DONE;
4097     }
4100 (define_insn "*extendsidi2_rex64"
4101   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4102         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4103   "TARGET_64BIT"
4104   "@
4105    {cltq|cdqe}
4106    movs{lq|x}\t{%1, %0|%0, %1}"
4107   [(set_attr "type" "imovx")
4108    (set_attr "mode" "DI")
4109    (set_attr "prefix_0f" "0")
4110    (set_attr "modrm" "0,1")])
4112 (define_insn "extendsidi2_1"
4113   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4114         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4115    (clobber (reg:CC FLAGS_REG))
4116    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4117   "!TARGET_64BIT"
4118   "#")
4120 ;; Split the memory case.  If the source register doesn't die, it will stay
4121 ;; this way, if it does die, following peephole2s take care of it.
4122 (define_split
4123   [(set (match_operand:DI 0 "memory_operand")
4124         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4125    (clobber (reg:CC FLAGS_REG))
4126    (clobber (match_operand:SI 2 "register_operand"))]
4127   "reload_completed"
4128   [(const_int 0)]
4130   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4132   emit_move_insn (operands[3], operands[1]);
4134   /* Generate a cltd if possible and doing so it profitable.  */
4135   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4136       && REGNO (operands[1]) == AX_REG
4137       && REGNO (operands[2]) == DX_REG)
4138     {
4139       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4140     }
4141   else
4142     {
4143       emit_move_insn (operands[2], operands[1]);
4144       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4145     }
4146   emit_move_insn (operands[4], operands[2]);
4147   DONE;
4150 ;; Peepholes for the case where the source register does die, after
4151 ;; being split with the above splitter.
4152 (define_peephole2
4153   [(set (match_operand:SI 0 "memory_operand")
4154         (match_operand:SI 1 "general_reg_operand"))
4155    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4156    (parallel [(set (match_dup 2)
4157                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4158                (clobber (reg:CC FLAGS_REG))])
4159    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4160   "REGNO (operands[1]) != REGNO (operands[2])
4161    && peep2_reg_dead_p (2, operands[1])
4162    && peep2_reg_dead_p (4, operands[2])
4163    && !reg_mentioned_p (operands[2], operands[3])"
4164   [(set (match_dup 0) (match_dup 1))
4165    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4166               (clobber (reg:CC FLAGS_REG))])
4167    (set (match_dup 3) (match_dup 1))])
4169 (define_peephole2
4170   [(set (match_operand:SI 0 "memory_operand")
4171         (match_operand:SI 1 "general_reg_operand"))
4172    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4173                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4174                (clobber (reg:CC FLAGS_REG))])
4175    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4176   "/* cltd is shorter than sarl $31, %eax */
4177    !optimize_function_for_size_p (cfun)
4178    && REGNO (operands[1]) == AX_REG
4179    && REGNO (operands[2]) == DX_REG
4180    && peep2_reg_dead_p (2, operands[1])
4181    && peep2_reg_dead_p (3, operands[2])
4182    && !reg_mentioned_p (operands[2], operands[3])"
4183   [(set (match_dup 0) (match_dup 1))
4184    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4185               (clobber (reg:CC FLAGS_REG))])
4186    (set (match_dup 3) (match_dup 1))])
4188 ;; Extend to register case.  Optimize case where source and destination
4189 ;; registers match and cases where we can use cltd.
4190 (define_split
4191   [(set (match_operand:DI 0 "register_operand")
4192         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4193    (clobber (reg:CC FLAGS_REG))
4194    (clobber (match_scratch:SI 2))]
4195   "reload_completed"
4196   [(const_int 0)]
4198   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4200   if (REGNO (operands[3]) != REGNO (operands[1]))
4201     emit_move_insn (operands[3], operands[1]);
4203   /* Generate a cltd if possible and doing so it profitable.  */
4204   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4205       && REGNO (operands[3]) == AX_REG
4206       && REGNO (operands[4]) == DX_REG)
4207     {
4208       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4209       DONE;
4210     }
4212   if (REGNO (operands[4]) != REGNO (operands[1]))
4213     emit_move_insn (operands[4], operands[1]);
4215   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4216   DONE;
4219 (define_insn "extend<mode>di2"
4220   [(set (match_operand:DI 0 "register_operand" "=r")
4221         (sign_extend:DI
4222          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4223   "TARGET_64BIT"
4224   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4225   [(set_attr "type" "imovx")
4226    (set_attr "mode" "DI")])
4228 (define_insn "extendhisi2"
4229   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4230         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4231   ""
4233   switch (get_attr_prefix_0f (insn))
4234     {
4235     case 0:
4236       return "{cwtl|cwde}";
4237     default:
4238       return "movs{wl|x}\t{%1, %0|%0, %1}";
4239     }
4241   [(set_attr "type" "imovx")
4242    (set_attr "mode" "SI")
4243    (set (attr "prefix_0f")
4244      ;; movsx is short decodable while cwtl is vector decoded.
4245      (if_then_else (and (eq_attr "cpu" "!k6")
4246                         (eq_attr "alternative" "0"))
4247         (const_string "0")
4248         (const_string "1")))
4249    (set (attr "znver1_decode")
4250      (if_then_else (eq_attr "prefix_0f" "0")
4251         (const_string "double")
4252         (const_string "direct")))
4253    (set (attr "modrm")
4254      (if_then_else (eq_attr "prefix_0f" "0")
4255         (const_string "0")
4256         (const_string "1")))])
4258 (define_insn "*extendhisi2_zext"
4259   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4260         (zero_extend:DI
4261          (sign_extend:SI
4262           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4263   "TARGET_64BIT"
4265   switch (get_attr_prefix_0f (insn))
4266     {
4267     case 0:
4268       return "{cwtl|cwde}";
4269     default:
4270       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4271     }
4273   [(set_attr "type" "imovx")
4274    (set_attr "mode" "SI")
4275    (set (attr "prefix_0f")
4276      ;; movsx is short decodable while cwtl is vector decoded.
4277      (if_then_else (and (eq_attr "cpu" "!k6")
4278                         (eq_attr "alternative" "0"))
4279         (const_string "0")
4280         (const_string "1")))
4281    (set (attr "modrm")
4282      (if_then_else (eq_attr "prefix_0f" "0")
4283         (const_string "0")
4284         (const_string "1")))])
4286 (define_insn "extendqisi2"
4287   [(set (match_operand:SI 0 "register_operand" "=r")
4288         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4289   ""
4290   "movs{bl|x}\t{%1, %0|%0, %1}"
4291    [(set_attr "type" "imovx")
4292     (set_attr "mode" "SI")])
4294 (define_insn "*extendqisi2_zext"
4295   [(set (match_operand:DI 0 "register_operand" "=r")
4296         (zero_extend:DI
4297           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4298   "TARGET_64BIT"
4299   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4300    [(set_attr "type" "imovx")
4301     (set_attr "mode" "SI")])
4303 (define_insn "extendqihi2"
4304   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4305         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4306   ""
4308   switch (get_attr_prefix_0f (insn))
4309     {
4310     case 0:
4311       return "{cbtw|cbw}";
4312     default:
4313       return "movs{bw|x}\t{%1, %0|%0, %1}";
4314     }
4316   [(set_attr "type" "imovx")
4317    (set_attr "mode" "HI")
4318    (set (attr "prefix_0f")
4319      ;; movsx is short decodable while cwtl is vector decoded.
4320      (if_then_else (and (eq_attr "cpu" "!k6")
4321                         (eq_attr "alternative" "0"))
4322         (const_string "0")
4323         (const_string "1")))
4324    (set (attr "modrm")
4325      (if_then_else (eq_attr "prefix_0f" "0")
4326         (const_string "0")
4327         (const_string "1")))])
4329 ;; Conversions between float and double.
4331 ;; These are all no-ops in the model used for the 80387.
4332 ;; So just emit moves.
4334 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4335 (define_split
4336   [(set (match_operand:DF 0 "push_operand")
4337         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4338   "reload_completed"
4339   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4340    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4342 (define_split
4343   [(set (match_operand:XF 0 "push_operand")
4344         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4345   "reload_completed"
4346   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4347    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4348   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4350 (define_expand "extendsfdf2"
4351   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4352         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4353   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4355   /* ??? Needed for compress_float_constant since all fp constants
4356      are TARGET_LEGITIMATE_CONSTANT_P.  */
4357   if (CONST_DOUBLE_P (operands[1]))
4358     {
4359       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4360           && standard_80387_constant_p (operands[1]) > 0)
4361         {
4362           operands[1] = simplify_const_unary_operation
4363             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4364           emit_move_insn_1 (operands[0], operands[1]);
4365           DONE;
4366         }
4367       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4368     }
4371 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4372    cvtss2sd:
4373       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4374       cvtps2pd xmm2,xmm1
4375    We do the conversion post reload to avoid producing of 128bit spills
4376    that might lead to ICE on 32bit target.  The sequence unlikely combine
4377    anyway.  */
4378 (define_split
4379   [(set (match_operand:DF 0 "sse_reg_operand")
4380         (float_extend:DF
4381           (match_operand:SF 1 "nonimmediate_operand")))]
4382   "TARGET_USE_VECTOR_FP_CONVERTS
4383    && optimize_insn_for_speed_p ()
4384    && reload_completed
4385    && (!EXT_REX_SSE_REG_P (operands[0])
4386        || TARGET_AVX512VL)"
4387    [(set (match_dup 2)
4388          (float_extend:V2DF
4389            (vec_select:V2SF
4390              (match_dup 3)
4391              (parallel [(const_int 0) (const_int 1)]))))]
4393   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4394   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4395   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4396      Try to avoid move when unpacking can be done in source.  */
4397   if (REG_P (operands[1]))
4398     {
4399       /* If it is unsafe to overwrite upper half of source, we need
4400          to move to destination and unpack there.  */
4401       if (REGNO (operands[0]) != REGNO (operands[1])
4402           || (EXT_REX_SSE_REG_P (operands[1])
4403               && !TARGET_AVX512VL))
4404         {
4405           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4406           emit_move_insn (tmp, operands[1]);
4407         }
4408       else
4409         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4410       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4411          =v, v, then vbroadcastss will be only needed for AVX512F without
4412          AVX512VL.  */
4413       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4414         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4415                                                operands[3]));
4416       else
4417         {
4418           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4419           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4420         }
4421     }
4422   else
4423     emit_insn (gen_vec_setv4sf_0 (operands[3],
4424                                   CONST0_RTX (V4SFmode), operands[1]));
4427 ;; It's more profitable to split and then extend in the same register.
4428 (define_peephole2
4429   [(set (match_operand:DF 0 "sse_reg_operand")
4430         (float_extend:DF
4431           (match_operand:SF 1 "memory_operand")))]
4432   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4433    && optimize_insn_for_speed_p ()"
4434   [(set (match_dup 2) (match_dup 1))
4435    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4436   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4438 (define_insn "*extendsfdf2"
4439   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4440         (float_extend:DF
4441           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4442   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4444   switch (which_alternative)
4445     {
4446     case 0:
4447     case 1:
4448       return output_387_reg_move (insn, operands);
4450     case 2:
4451       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4453     default:
4454       gcc_unreachable ();
4455     }
4457   [(set_attr "type" "fmov,fmov,ssecvt")
4458    (set_attr "prefix" "orig,orig,maybe_vex")
4459    (set_attr "mode" "SF,XF,DF")
4460    (set (attr "enabled")
4461      (if_then_else
4462        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4463        (if_then_else
4464          (eq_attr "alternative" "0,1")
4465          (symbol_ref "TARGET_MIX_SSE_I387")
4466          (symbol_ref "true"))
4467        (if_then_else
4468          (eq_attr "alternative" "0,1")
4469          (symbol_ref "true")
4470          (symbol_ref "false"))))])
4472 (define_expand "extend<mode>xf2"
4473   [(set (match_operand:XF 0 "nonimmediate_operand")
4474         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4475   "TARGET_80387"
4477   /* ??? Needed for compress_float_constant since all fp constants
4478      are TARGET_LEGITIMATE_CONSTANT_P.  */
4479   if (CONST_DOUBLE_P (operands[1]))
4480     {
4481       if (standard_80387_constant_p (operands[1]) > 0)
4482         {
4483           operands[1] = simplify_const_unary_operation
4484             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4485           emit_move_insn_1 (operands[0], operands[1]);
4486           DONE;
4487         }
4488       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4489     }
4492 (define_insn "*extend<mode>xf2_i387"
4493   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4494         (float_extend:XF
4495           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4496   "TARGET_80387"
4497   "* return output_387_reg_move (insn, operands);"
4498   [(set_attr "type" "fmov")
4499    (set_attr "mode" "<MODE>,XF")])
4501 ;; %%% This seems like bad news.
4502 ;; This cannot output into an f-reg because there is no way to be sure
4503 ;; of truncating in that case.  Otherwise this is just like a simple move
4504 ;; insn.  So we pretend we can output to a reg in order to get better
4505 ;; register preferencing, but we really use a stack slot.
4507 ;; Conversion from DFmode to SFmode.
4509 (define_expand "truncdfsf2"
4510   [(set (match_operand:SF 0 "nonimmediate_operand")
4511         (float_truncate:SF
4512           (match_operand:DF 1 "nonimmediate_operand")))]
4513   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4515   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4516     ;
4517   else if (flag_unsafe_math_optimizations)
4518     ;
4519   else
4520     {
4521       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4522       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4523       DONE;
4524     }
4527 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4528    cvtsd2ss:
4529       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4530       cvtpd2ps xmm2,xmm1
4531    We do the conversion post reload to avoid producing of 128bit spills
4532    that might lead to ICE on 32bit target.  The sequence unlikely combine
4533    anyway.  */
4534 (define_split
4535   [(set (match_operand:SF 0 "sse_reg_operand")
4536         (float_truncate:SF
4537           (match_operand:DF 1 "nonimmediate_operand")))]
4538   "TARGET_USE_VECTOR_FP_CONVERTS
4539    && optimize_insn_for_speed_p ()
4540    && reload_completed
4541    && (!EXT_REX_SSE_REG_P (operands[0])
4542        || TARGET_AVX512VL)"
4543    [(set (match_dup 2)
4544          (vec_concat:V4SF
4545            (float_truncate:V2SF
4546              (match_dup 4))
4547            (match_dup 3)))]
4549   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4550   operands[3] = CONST0_RTX (V2SFmode);
4551   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4552   /* Use movsd for loading from memory, unpcklpd for registers.
4553      Try to avoid move when unpacking can be done in source, or SSE3
4554      movddup is available.  */
4555   if (REG_P (operands[1]))
4556     {
4557       if (!TARGET_SSE3
4558           && REGNO (operands[0]) != REGNO (operands[1]))
4559         {
4560           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4561           emit_move_insn (tmp, operands[1]);
4562           operands[1] = tmp;
4563         }
4564       else if (!TARGET_SSE3)
4565         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4566       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4567     }
4568   else
4569     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4570                                    CONST0_RTX (DFmode)));
4573 ;; It's more profitable to split and then extend in the same register.
4574 (define_peephole2
4575   [(set (match_operand:SF 0 "sse_reg_operand")
4576         (float_truncate:SF
4577           (match_operand:DF 1 "memory_operand")))]
4578   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4579    && optimize_insn_for_speed_p ()"
4580   [(set (match_dup 2) (match_dup 1))
4581    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4582   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4584 (define_expand "truncdfsf2_with_temp"
4585   [(parallel [(set (match_operand:SF 0)
4586                    (float_truncate:SF (match_operand:DF 1)))
4587               (clobber (match_operand:SF 2))])])
4589 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4590 ;; because nothing we do there is unsafe.
4591 (define_insn "*truncdfsf_fast_mixed"
4592   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4593         (float_truncate:SF
4594           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4595   "TARGET_SSE2 && TARGET_SSE_MATH"
4597   switch (which_alternative)
4598     {
4599     case 0:
4600       return output_387_reg_move (insn, operands);
4601     case 1:
4602       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4603     default:
4604       gcc_unreachable ();
4605     }
4607   [(set_attr "type" "fmov,ssecvt")
4608    (set_attr "prefix" "orig,maybe_vex")
4609    (set_attr "mode" "SF")
4610    (set (attr "enabled")
4611      (cond [(eq_attr "alternative" "0")
4612               (symbol_ref "TARGET_MIX_SSE_I387
4613                            && flag_unsafe_math_optimizations")
4614            ]
4615            (symbol_ref "true")))])
4617 (define_insn "*truncdfsf_fast_i387"
4618   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4619         (float_truncate:SF
4620           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4621   "TARGET_80387 && flag_unsafe_math_optimizations"
4622   "* return output_387_reg_move (insn, operands);"
4623   [(set_attr "type" "fmov")
4624    (set_attr "mode" "SF")])
4626 (define_insn "*truncdfsf_mixed"
4627   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
4628         (float_truncate:SF
4629           (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4630    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4631   "TARGET_MIX_SSE_I387"
4633   switch (which_alternative)
4634     {
4635     case 0:
4636       return output_387_reg_move (insn, operands);
4637     case 1:
4638       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4640     default:
4641       return "#";
4642     }
4644   [(set_attr "isa" "*,sse2,*,*,*")
4645    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4646    (set_attr "unit" "*,*,i387,i387,i387")
4647    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4648    (set_attr "mode" "SF")])
4650 (define_insn "*truncdfsf_i387"
4651   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
4652         (float_truncate:SF
4653           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4654    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4655   "TARGET_80387"
4657   switch (which_alternative)
4658     {
4659     case 0:
4660       return output_387_reg_move (insn, operands);
4662     default:
4663       return "#";
4664     }
4666   [(set_attr "type" "fmov,multi,multi,multi")
4667    (set_attr "unit" "*,i387,i387,i387")
4668    (set_attr "mode" "SF")])
4670 (define_insn "*truncdfsf2_i387_1"
4671   [(set (match_operand:SF 0 "memory_operand" "=m")
4672         (float_truncate:SF
4673           (match_operand:DF 1 "register_operand" "f")))]
4674   "TARGET_80387
4675    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4676    && !TARGET_MIX_SSE_I387"
4677   "* return output_387_reg_move (insn, operands);"
4678   [(set_attr "type" "fmov")
4679    (set_attr "mode" "SF")])
4681 (define_split
4682   [(set (match_operand:SF 0 "register_operand")
4683         (float_truncate:SF
4684          (match_operand:DF 1 "fp_register_operand")))
4685    (clobber (match_operand 2))]
4686   "reload_completed"
4687   [(set (match_dup 2) (match_dup 1))
4688    (set (match_dup 0) (match_dup 2))]
4689   "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4691 ;; Conversion from XFmode to {SF,DF}mode
4693 (define_expand "truncxf<mode>2"
4694   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4695                    (float_truncate:MODEF
4696                      (match_operand:XF 1 "register_operand")))
4697               (clobber (match_dup 2))])]
4698   "TARGET_80387"
4700   if (flag_unsafe_math_optimizations)
4701     {
4702       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4703       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4704       if (reg != operands[0])
4705         emit_move_insn (operands[0], reg);
4706       DONE;
4707     }
4708   else
4709     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4712 (define_insn "*truncxfsf2_mixed"
4713   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4714         (float_truncate:SF
4715           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4716    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4717   "TARGET_80387"
4719   gcc_assert (!which_alternative);
4720   return output_387_reg_move (insn, operands);
4722   [(set_attr "type" "fmov,multi,multi,multi")
4723    (set_attr "unit" "*,i387,i387,i387")
4724    (set_attr "mode" "SF")])
4726 (define_insn "*truncxfdf2_mixed"
4727   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4728         (float_truncate:DF
4729           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4730    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4731   "TARGET_80387"
4733   gcc_assert (!which_alternative);
4734   return output_387_reg_move (insn, operands);
4736   [(set_attr "isa" "*,*,sse2,*")
4737    (set_attr "type" "fmov,multi,multi,multi")
4738    (set_attr "unit" "*,i387,i387,i387")
4739    (set_attr "mode" "DF")])
4741 (define_insn "truncxf<mode>2_i387_noop"
4742   [(set (match_operand:MODEF 0 "register_operand" "=f")
4743         (float_truncate:MODEF
4744           (match_operand:XF 1 "register_operand" "f")))]
4745   "TARGET_80387 && flag_unsafe_math_optimizations"
4746   "* return output_387_reg_move (insn, operands);"
4747   [(set_attr "type" "fmov")
4748    (set_attr "mode" "<MODE>")])
4750 (define_insn "*truncxf<mode>2_i387"
4751   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4752         (float_truncate:MODEF
4753           (match_operand:XF 1 "register_operand" "f")))]
4754   "TARGET_80387"
4755   "* return output_387_reg_move (insn, operands);"
4756   [(set_attr "type" "fmov")
4757    (set_attr "mode" "<MODE>")])
4759 (define_split
4760   [(set (match_operand:MODEF 0 "register_operand")
4761         (float_truncate:MODEF
4762           (match_operand:XF 1 "register_operand")))
4763    (clobber (match_operand:MODEF 2 "memory_operand"))]
4764   "TARGET_80387 && reload_completed"
4765   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4766    (set (match_dup 0) (match_dup 2))])
4768 (define_split
4769   [(set (match_operand:MODEF 0 "memory_operand")
4770         (float_truncate:MODEF
4771           (match_operand:XF 1 "register_operand")))
4772    (clobber (match_operand:MODEF 2 "memory_operand"))]
4773   "TARGET_80387"
4774   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4776 ;; Signed conversion to DImode.
4778 (define_expand "fix_truncxfdi2"
4779   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4780                    (fix:DI (match_operand:XF 1 "register_operand")))
4781               (clobber (reg:CC FLAGS_REG))])]
4782   "TARGET_80387"
4784   if (TARGET_FISTTP)
4785    {
4786      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4787      DONE;
4788    }
4791 (define_expand "fix_trunc<mode>di2"
4792   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4793                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4794               (clobber (reg:CC FLAGS_REG))])]
4795   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4797   if (TARGET_FISTTP
4798       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4799    {
4800      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4801      DONE;
4802    }
4803   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4804    {
4805      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4806      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4807      if (out != operands[0])
4808         emit_move_insn (operands[0], out);
4809      DONE;
4810    }
4813 ;; Signed conversion to SImode.
4815 (define_expand "fix_truncxfsi2"
4816   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4817                    (fix:SI (match_operand:XF 1 "register_operand")))
4818               (clobber (reg:CC FLAGS_REG))])]
4819   "TARGET_80387"
4821   if (TARGET_FISTTP)
4822    {
4823      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4824      DONE;
4825    }
4828 (define_expand "fix_trunc<mode>si2"
4829   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4830                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4831               (clobber (reg:CC FLAGS_REG))])]
4832   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4834   if (TARGET_FISTTP
4835       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4836    {
4837      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4838      DONE;
4839    }
4840   if (SSE_FLOAT_MODE_P (<MODE>mode))
4841    {
4842      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4843      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4844      if (out != operands[0])
4845         emit_move_insn (operands[0], out);
4846      DONE;
4847    }
4850 ;; Signed conversion to HImode.
4852 (define_expand "fix_trunc<mode>hi2"
4853   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4854                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4855               (clobber (reg:CC FLAGS_REG))])]
4856   "TARGET_80387
4857    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4859   if (TARGET_FISTTP)
4860    {
4861      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4862      DONE;
4863    }
4866 ;; Unsigned conversion to SImode.
4868 (define_expand "fixuns_trunc<mode>si2"
4869   [(parallel
4870     [(set (match_operand:SI 0 "register_operand")
4871           (unsigned_fix:SI
4872             (match_operand:MODEF 1 "nonimmediate_operand")))
4873      (use (match_dup 2))
4874      (clobber (match_scratch:<ssevecmode> 3))
4875      (clobber (match_scratch:<ssevecmode> 4))])]
4876   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4878   machine_mode mode = <MODE>mode;
4879   machine_mode vecmode = <ssevecmode>mode;
4880   REAL_VALUE_TYPE TWO31r;
4881   rtx two31;
4883   if (optimize_insn_for_size_p ())
4884     FAIL;
4886   real_ldexp (&TWO31r, &dconst1, 31);
4887   two31 = const_double_from_real_value (TWO31r, mode);
4888   two31 = ix86_build_const_vector (vecmode, true, two31);
4889   operands[2] = force_reg (vecmode, two31);
4892 (define_insn_and_split "*fixuns_trunc<mode>_1"
4893   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4894         (unsigned_fix:SI
4895           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4896    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4897    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4898    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4899   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4900    && optimize_function_for_speed_p (cfun)"
4901   "#"
4902   "&& reload_completed"
4903   [(const_int 0)]
4905   ix86_split_convert_uns_si_sse (operands);
4906   DONE;
4909 ;; Unsigned conversion to HImode.
4910 ;; Without these patterns, we'll try the unsigned SI conversion which
4911 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4913 (define_expand "fixuns_trunc<mode>hi2"
4914   [(set (match_dup 2)
4915         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4916    (set (match_operand:HI 0 "nonimmediate_operand")
4917         (subreg:HI (match_dup 2) 0))]
4918   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4919   "operands[2] = gen_reg_rtx (SImode);")
4921 ;; When SSE is available, it is always faster to use it!
4922 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4923   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4924         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4925   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4926    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4927   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4928   [(set_attr "type" "sseicvt")
4929    (set_attr "prefix" "maybe_vex")
4930    (set (attr "prefix_rex")
4931         (if_then_else
4932           (match_test "<SWI48:MODE>mode == DImode")
4933           (const_string "1")
4934           (const_string "*")))
4935    (set_attr "mode" "<MODEF:MODE>")
4936    (set_attr "athlon_decode" "double,vector")
4937    (set_attr "amdfam10_decode" "double,double")
4938    (set_attr "bdver1_decode" "double,double")])
4940 ;; Avoid vector decoded forms of the instruction.
4941 (define_peephole2
4942   [(match_scratch:MODEF 2 "x")
4943    (set (match_operand:SWI48 0 "register_operand")
4944         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4945   "TARGET_AVOID_VECTOR_DECODE
4946    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4947    && optimize_insn_for_speed_p ()"
4948   [(set (match_dup 2) (match_dup 1))
4949    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4951 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4952   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4953         (fix:SWI248x (match_operand 1 "register_operand")))]
4954   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4955    && TARGET_FISTTP
4956    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4957          && (TARGET_64BIT || <MODE>mode != DImode))
4958         && TARGET_SSE_MATH)
4959    && can_create_pseudo_p ()"
4960   "#"
4961   "&& 1"
4962   [(const_int 0)]
4964   if (memory_operand (operands[0], VOIDmode))
4965     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4966   else
4967     {
4968       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4969       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4970                                                             operands[1],
4971                                                             operands[2]));
4972     }
4973   DONE;
4975   [(set_attr "type" "fisttp")
4976    (set_attr "mode" "<MODE>")])
4978 (define_insn "fix_trunc<mode>_i387_fisttp"
4979   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4980         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4981    (clobber (match_scratch:XF 2 "=&1f"))]
4982   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4983    && TARGET_FISTTP
4984    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4985          && (TARGET_64BIT || <MODE>mode != DImode))
4986         && TARGET_SSE_MATH)"
4987   "* return output_fix_trunc (insn, operands, true);"
4988   [(set_attr "type" "fisttp")
4989    (set_attr "mode" "<MODE>")])
4991 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4992   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4993         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4994    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4995    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4996   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4997    && TARGET_FISTTP
4998    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4999         && (TARGET_64BIT || <MODE>mode != DImode))
5000         && TARGET_SSE_MATH)"
5001   "#"
5002   [(set_attr "type" "fisttp")
5003    (set_attr "mode" "<MODE>")])
5005 (define_split
5006   [(set (match_operand:SWI248x 0 "register_operand")
5007         (fix:SWI248x (match_operand 1 "register_operand")))
5008    (clobber (match_operand:SWI248x 2 "memory_operand"))
5009    (clobber (match_scratch 3))]
5010   "reload_completed"
5011   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5012               (clobber (match_dup 3))])
5013    (set (match_dup 0) (match_dup 2))])
5015 (define_split
5016   [(set (match_operand:SWI248x 0 "memory_operand")
5017         (fix:SWI248x (match_operand 1 "register_operand")))
5018    (clobber (match_operand:SWI248x 2 "memory_operand"))
5019    (clobber (match_scratch 3))]
5020   "reload_completed"
5021   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5022               (clobber (match_dup 3))])])
5024 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5025 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5026 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5027 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5028 ;; function in i386.c.
5029 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5030   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5031         (fix:SWI248x (match_operand 1 "register_operand")))
5032    (clobber (reg:CC FLAGS_REG))]
5033   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5034    && !TARGET_FISTTP
5035    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5036          && (TARGET_64BIT || <MODE>mode != DImode))
5037    && can_create_pseudo_p ()"
5038   "#"
5039   "&& 1"
5040   [(const_int 0)]
5042   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5044   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5045   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5046   if (memory_operand (operands[0], VOIDmode))
5047     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5048                                          operands[2], operands[3]));
5049   else
5050     {
5051       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5052       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5053                                                      operands[2], operands[3],
5054                                                      operands[4]));
5055     }
5056   DONE;
5058   [(set_attr "type" "fistp")
5059    (set_attr "i387_cw" "trunc")
5060    (set_attr "mode" "<MODE>")])
5062 (define_insn "fix_truncdi_i387"
5063   [(set (match_operand:DI 0 "memory_operand" "=m")
5064         (fix:DI (match_operand 1 "register_operand" "f")))
5065    (use (match_operand:HI 2 "memory_operand" "m"))
5066    (use (match_operand:HI 3 "memory_operand" "m"))
5067    (clobber (match_scratch:XF 4 "=&1f"))]
5068   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5069    && !TARGET_FISTTP
5070    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5071   "* return output_fix_trunc (insn, operands, false);"
5072   [(set_attr "type" "fistp")
5073    (set_attr "i387_cw" "trunc")
5074    (set_attr "mode" "DI")])
5076 (define_insn "fix_truncdi_i387_with_temp"
5077   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5078         (fix:DI (match_operand 1 "register_operand" "f,f")))
5079    (use (match_operand:HI 2 "memory_operand" "m,m"))
5080    (use (match_operand:HI 3 "memory_operand" "m,m"))
5081    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5082    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5083   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5084    && !TARGET_FISTTP
5085    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5086   "#"
5087   [(set_attr "type" "fistp")
5088    (set_attr "i387_cw" "trunc")
5089    (set_attr "mode" "DI")])
5091 (define_split
5092   [(set (match_operand:DI 0 "register_operand")
5093         (fix:DI (match_operand 1 "register_operand")))
5094    (use (match_operand:HI 2 "memory_operand"))
5095    (use (match_operand:HI 3 "memory_operand"))
5096    (clobber (match_operand:DI 4 "memory_operand"))
5097    (clobber (match_scratch 5))]
5098   "reload_completed"
5099   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5100               (use (match_dup 2))
5101               (use (match_dup 3))
5102               (clobber (match_dup 5))])
5103    (set (match_dup 0) (match_dup 4))])
5105 (define_split
5106   [(set (match_operand:DI 0 "memory_operand")
5107         (fix:DI (match_operand 1 "register_operand")))
5108    (use (match_operand:HI 2 "memory_operand"))
5109    (use (match_operand:HI 3 "memory_operand"))
5110    (clobber (match_operand:DI 4 "memory_operand"))
5111    (clobber (match_scratch 5))]
5112   "reload_completed"
5113   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5114               (use (match_dup 2))
5115               (use (match_dup 3))
5116               (clobber (match_dup 5))])])
5118 (define_insn "fix_trunc<mode>_i387"
5119   [(set (match_operand:SWI24 0 "memory_operand" "=m")
5120         (fix:SWI24 (match_operand 1 "register_operand" "f")))
5121    (use (match_operand:HI 2 "memory_operand" "m"))
5122    (use (match_operand:HI 3 "memory_operand" "m"))]
5123   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5124    && !TARGET_FISTTP
5125    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5126   "* return output_fix_trunc (insn, operands, false);"
5127   [(set_attr "type" "fistp")
5128    (set_attr "i387_cw" "trunc")
5129    (set_attr "mode" "<MODE>")])
5131 (define_insn "fix_trunc<mode>_i387_with_temp"
5132   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5133         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5134    (use (match_operand:HI 2 "memory_operand" "m,m"))
5135    (use (match_operand:HI 3 "memory_operand" "m,m"))
5136    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5137   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5138    && !TARGET_FISTTP
5139    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5140   "#"
5141   [(set_attr "type" "fistp")
5142    (set_attr "i387_cw" "trunc")
5143    (set_attr "mode" "<MODE>")])
5145 (define_split
5146   [(set (match_operand:SWI24 0 "register_operand")
5147         (fix:SWI24 (match_operand 1 "register_operand")))
5148    (use (match_operand:HI 2 "memory_operand"))
5149    (use (match_operand:HI 3 "memory_operand"))
5150    (clobber (match_operand:SWI24 4 "memory_operand"))]
5151   "reload_completed"
5152   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5153               (use (match_dup 2))
5154               (use (match_dup 3))])
5155    (set (match_dup 0) (match_dup 4))])
5157 (define_split
5158   [(set (match_operand:SWI24 0 "memory_operand")
5159         (fix:SWI24 (match_operand 1 "register_operand")))
5160    (use (match_operand:HI 2 "memory_operand"))
5161    (use (match_operand:HI 3 "memory_operand"))
5162    (clobber (match_operand:SWI24 4 "memory_operand"))]
5163   "reload_completed"
5164   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5165               (use (match_dup 2))
5166               (use (match_dup 3))])])
5168 (define_insn "x86_fnstcw_1"
5169   [(set (match_operand:HI 0 "memory_operand" "=m")
5170         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5171   "TARGET_80387"
5172   "fnstcw\t%0"
5173   [(set (attr "length")
5174         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5175    (set_attr "mode" "HI")
5176    (set_attr "unit" "i387")
5177    (set_attr "bdver1_decode" "vector")])
5179 (define_insn "x86_fldcw_1"
5180   [(set (reg:HI FPCR_REG)
5181         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5182   "TARGET_80387"
5183   "fldcw\t%0"
5184   [(set (attr "length")
5185         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5186    (set_attr "mode" "HI")
5187    (set_attr "unit" "i387")
5188    (set_attr "athlon_decode" "vector")
5189    (set_attr "amdfam10_decode" "vector")
5190    (set_attr "bdver1_decode" "vector")])
5192 ;; Conversion between fixed point and floating point.
5194 ;; Even though we only accept memory inputs, the backend _really_
5195 ;; wants to be able to do this between registers.  Thankfully, LRA
5196 ;; will fix this up for us during register allocation.
5198 (define_insn "floathi<mode>2"
5199   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5200         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5201   "TARGET_80387
5202    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5203        || TARGET_MIX_SSE_I387)"
5204   "fild%Z1\t%1"
5205   [(set_attr "type" "fmov")
5206    (set_attr "mode" "<MODE>")
5207    (set_attr "znver1_decode" "double")
5208    (set_attr "fp_int_src" "true")])
5210 (define_insn "float<SWI48x:mode>xf2"
5211   [(set (match_operand:XF 0 "register_operand" "=f")
5212         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5213   "TARGET_80387"
5214   "fild%Z1\t%1"
5215   [(set_attr "type" "fmov")
5216    (set_attr "mode" "XF")
5217    (set_attr "znver1_decode" "double")
5218    (set_attr "fp_int_src" "true")])
5220 (define_expand "float<SWI48:mode><MODEF:mode>2"
5221   [(set (match_operand:MODEF 0 "register_operand")
5222         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5223   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5225   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5226       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5227     {
5228       rtx reg = gen_reg_rtx (XFmode);
5229       rtx (*insn)(rtx, rtx);
5231       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5233       if (<MODEF:MODE>mode == SFmode)
5234         insn = gen_truncxfsf2;
5235       else if (<MODEF:MODE>mode == DFmode)
5236         insn = gen_truncxfdf2;
5237       else
5238         gcc_unreachable ();
5240       emit_insn (insn (operands[0], reg));
5241       DONE;
5242     }
5245 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5246   [(set (match_operand:MODEF 0 "register_operand" "=f,Yc,v")
5247         (float:MODEF
5248           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5249   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5250   "@
5251    fild%Z1\t%1
5252    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5253    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5254   [(set_attr "type" "fmov,sseicvt,sseicvt")
5255    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5256    (set_attr "mode" "<MODEF:MODE>")
5257    (set (attr "prefix_rex")
5258      (if_then_else
5259        (and (eq_attr "prefix" "maybe_vex")
5260             (match_test "<SWI48:MODE>mode == DImode"))
5261        (const_string "1")
5262        (const_string "*")))
5263    (set_attr "unit" "i387,*,*")
5264    (set_attr "athlon_decode" "*,double,direct")
5265    (set_attr "amdfam10_decode" "*,vector,double")
5266    (set_attr "bdver1_decode" "*,double,direct")
5267    (set_attr "znver1_decode" "double,*,*")
5268    (set_attr "fp_int_src" "true")
5269    (set (attr "enabled")
5270      (cond [(eq_attr "alternative" "0")
5271               (symbol_ref "TARGET_MIX_SSE_I387
5272                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5273                                                 <SWI48:MODE>mode)")
5274            ]
5275            (symbol_ref "true")))])
5277 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5278   [(set (match_operand:MODEF 0 "register_operand" "=f")
5279         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5280   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5281   "fild%Z1\t%1"
5282   [(set_attr "type" "fmov")
5283    (set_attr "mode" "<MODEF:MODE>")
5284    (set_attr "znver1_decode" "double")
5285    (set_attr "fp_int_src" "true")])
5287 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5288 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5289 ;; alternative in sse2_loadld.
5290 (define_split
5291   [(set (match_operand:MODEF 0 "sse_reg_operand")
5292         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5293   "TARGET_SSE2
5294    && TARGET_USE_VECTOR_CONVERTS
5295    && optimize_function_for_speed_p (cfun)
5296    && reload_completed
5297    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5298    && (!EXT_REX_SSE_REG_P (operands[0])
5299        || TARGET_AVX512VL)"
5300   [(const_int 0)]
5302   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5303   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5305   emit_insn (gen_sse2_loadld (operands[4],
5306                               CONST0_RTX (V4SImode), operands[1]));
5308   if (<ssevecmode>mode == V4SFmode)
5309     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5310   else
5311     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5312   DONE;
5315 ;; Avoid partial SSE register dependency stalls.  This splitter should split
5316 ;; late in the pass sequence (after register rename pass), so allocated
5317 ;; registers won't change anymore
5319 (define_split
5320   [(set (match_operand:MODEF 0 "sse_reg_operand")
5321         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5322   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5323    && optimize_function_for_speed_p (cfun)
5324    && (!EXT_REX_SSE_REG_P (operands[0])
5325        || TARGET_AVX512VL)"
5326   [(set (match_dup 0)
5327         (vec_merge:<MODEF:ssevecmode>
5328           (vec_duplicate:<MODEF:ssevecmode>
5329             (float:MODEF
5330               (match_dup 1)))
5331           (match_dup 0)
5332           (const_int 1)))]
5334   const machine_mode vmode = <MODEF:ssevecmode>mode;
5336   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5337   emit_move_insn (operands[0], CONST0_RTX (vmode));
5340 ;; Break partial reg stall for cvtsd2ss.  This splitter should split
5341 ;; late in the pass sequence (after register rename pass),
5342 ;; so allocated registers won't change anymore.
5344 (define_split
5345   [(set (match_operand:SF 0 "sse_reg_operand")
5346         (float_truncate:SF
5347           (match_operand:DF 1 "nonimmediate_operand")))]
5348   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5349    && optimize_function_for_speed_p (cfun)
5350    && (!REG_P (operands[1])
5351        || REGNO (operands[0]) != REGNO (operands[1]))
5352    && (!EXT_REX_SSE_REG_P (operands[0])
5353        || TARGET_AVX512VL)"
5354   [(set (match_dup 0)
5355         (vec_merge:V4SF
5356           (vec_duplicate:V4SF
5357             (float_truncate:SF
5358               (match_dup 1)))
5359           (match_dup 0)
5360           (const_int 1)))]
5362   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5363   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5366 ;; Break partial reg stall for cvtss2sd.  This splitter should split
5367 ;; late in the pass sequence (after register rename pass),
5368 ;; so allocated registers won't change anymore.
5370 (define_split
5371   [(set (match_operand:DF 0 "sse_reg_operand")
5372         (float_extend:DF
5373           (match_operand:SF 1 "nonimmediate_operand")))]
5374   "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5375    && optimize_function_for_speed_p (cfun)
5376    && (!REG_P (operands[1])
5377        || REGNO (operands[0]) != REGNO (operands[1]))
5378    && (!EXT_REX_SSE_REG_P (operands[0])
5379        || TARGET_AVX512VL)"
5380   [(set (match_dup 0)
5381         (vec_merge:V2DF
5382           (vec_duplicate:V2DF
5383             (float_extend:DF
5384               (match_dup 1)))
5385           (match_dup 0)
5386           (const_int 1)))]
5388   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5389   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5392 ;; Avoid store forwarding (partial memory) stall penalty
5393 ;; by passing DImode value through XMM registers.  */
5395 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5396   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5397         (float:X87MODEF
5398           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5399    (clobber (match_scratch:V4SI 3 "=X,x"))
5400    (clobber (match_scratch:V4SI 4 "=X,x"))
5401    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5402   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5403    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5404    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5405   "#"
5406   [(set_attr "type" "multi")
5407    (set_attr "mode" "<X87MODEF:MODE>")
5408    (set_attr "unit" "i387")
5409    (set_attr "fp_int_src" "true")])
5411 (define_split
5412   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5413         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5414    (clobber (match_scratch:V4SI 3))
5415    (clobber (match_scratch:V4SI 4))
5416    (clobber (match_operand:DI 2 "memory_operand"))]
5417   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5418    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5419    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5420    && reload_completed"
5421   [(set (match_dup 2) (match_dup 3))
5422    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5424   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5425      Assemble the 64-bit DImode value in an xmm register.  */
5426   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5427                               gen_lowpart (SImode, operands[1])));
5428   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5429                               gen_highpart (SImode, operands[1])));
5430   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5431                                          operands[4]));
5433   operands[3] = gen_lowpart (DImode, operands[3]);
5436 (define_split
5437   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5438         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5439    (clobber (match_scratch:V4SI 3))
5440    (clobber (match_scratch:V4SI 4))
5441    (clobber (match_operand:DI 2 "memory_operand"))]
5442   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5443    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5444    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5445    && reload_completed"
5446   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5448 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5449   [(set (match_operand:MODEF 0 "register_operand")
5450         (unsigned_float:MODEF
5451           (match_operand:SWI12 1 "nonimmediate_operand")))]
5452   "!TARGET_64BIT
5453    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5455   operands[1] = convert_to_mode (SImode, operands[1], 1);
5456   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5457   DONE;
5460 ;; Avoid store forwarding (partial memory) stall penalty by extending
5461 ;; SImode value to DImode through XMM register instead of pushing two
5462 ;; SImode values to stack. Also note that fild loads from memory only.
5464 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5465   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5466         (unsigned_float:X87MODEF
5467           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5468    (clobber (match_scratch:DI 3 "=x"))
5469    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5470   "!TARGET_64BIT
5471    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5472    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5473   "#"
5474   "&& reload_completed"
5475   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5476    (set (match_dup 2) (match_dup 3))
5477    (set (match_dup 0)
5478         (float:X87MODEF (match_dup 2)))]
5479   ""
5480   [(set_attr "type" "multi")
5481    (set_attr "mode" "<MODE>")])
5483 (define_expand "floatunssi<mode>2"
5484   [(parallel
5485      [(set (match_operand:X87MODEF 0 "register_operand")
5486            (unsigned_float:X87MODEF
5487              (match_operand:SI 1 "nonimmediate_operand")))
5488       (clobber (match_scratch:DI 3))
5489       (clobber (match_dup 2))])]
5490   "!TARGET_64BIT
5491    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5492         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5493        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5495   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5496     {
5497       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5498       DONE;
5499     }
5500   else
5501     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5504 (define_expand "floatunsdisf2"
5505   [(use (match_operand:SF 0 "register_operand"))
5506    (use (match_operand:DI 1 "nonimmediate_operand"))]
5507   "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5508   "x86_emit_floatuns (operands); DONE;")
5510 (define_expand "floatunsdidf2"
5511   [(use (match_operand:DF 0 "register_operand"))
5512    (use (match_operand:DI 1 "nonimmediate_operand"))]
5513   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5514    && TARGET_SSE2 && TARGET_SSE_MATH"
5516   if (TARGET_64BIT)
5517     x86_emit_floatuns (operands);
5518   else
5519     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5520   DONE;
5523 ;; Load effective address instructions
5525 (define_insn_and_split "*lea<mode>"
5526   [(set (match_operand:SWI48 0 "register_operand" "=r")
5527         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5528   ""
5530   if (SImode_address_operand (operands[1], VOIDmode))
5531     {
5532       gcc_assert (TARGET_64BIT);
5533       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5534     }
5535   else 
5536     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5538   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5539   [(const_int 0)]
5541   machine_mode mode = <MODE>mode;
5542   rtx pat;
5544   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5545      change operands[] array behind our back.  */
5546   pat = PATTERN (curr_insn);
5548   operands[0] = SET_DEST (pat);
5549   operands[1] = SET_SRC (pat);
5551   /* Emit all operations in SImode for zero-extended addresses.  */
5552   if (SImode_address_operand (operands[1], VOIDmode))
5553     mode = SImode;
5555   ix86_split_lea_for_addr (curr_insn, operands, mode);
5557   /* Zero-extend return register to DImode for zero-extended addresses.  */
5558   if (mode != <MODE>mode)
5559     emit_insn (gen_zero_extendsidi2
5560                (operands[0], gen_lowpart (mode, operands[0])));
5562   DONE;
5564   [(set_attr "type" "lea")
5565    (set (attr "mode")
5566      (if_then_else
5567        (match_operand 1 "SImode_address_operand")
5568        (const_string "SI")
5569        (const_string "<MODE>")))])
5571 ;; Add instructions
5573 (define_expand "add<mode>3"
5574   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5575         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5576                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5577   ""
5578   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5580 (define_insn_and_split "*add<dwi>3_doubleword"
5581   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5582         (plus:<DWI>
5583           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5584           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5585                                                         "ro<di>,r<di>")))
5586    (clobber (reg:CC FLAGS_REG))]
5587   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5588   "#"
5589   "reload_completed"
5590   [(parallel [(set (reg:CCC FLAGS_REG)
5591                    (compare:CCC
5592                      (plus:DWIH (match_dup 1) (match_dup 2))
5593                      (match_dup 1)))
5594               (set (match_dup 0)
5595                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5596    (parallel [(set (match_dup 3)
5597                    (plus:DWIH
5598                      (plus:DWIH
5599                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5600                        (match_dup 4))
5601                      (match_dup 5)))
5602               (clobber (reg:CC FLAGS_REG))])]
5604   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5605   if (operands[2] == const0_rtx)
5606     {
5607       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5608       DONE;
5609     }
5612 (define_insn "*add<mode>_1"
5613   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5614         (plus:SWI48
5615           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5616           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5617    (clobber (reg:CC FLAGS_REG))]
5618   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5620   switch (get_attr_type (insn))
5621     {
5622     case TYPE_LEA:
5623       return "#";
5625     case TYPE_INCDEC:
5626       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5627       if (operands[2] == const1_rtx)
5628         return "inc{<imodesuffix>}\t%0";
5629       else
5630         {
5631           gcc_assert (operands[2] == constm1_rtx);
5632           return "dec{<imodesuffix>}\t%0";
5633         }
5635     default:
5636       /* For most processors, ADD is faster than LEA.  This alternative
5637          was added to use ADD as much as possible.  */
5638       if (which_alternative == 2)
5639         std::swap (operands[1], operands[2]);
5640         
5641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5643         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5645       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5646     }
5648   [(set (attr "type")
5649      (cond [(eq_attr "alternative" "3")
5650               (const_string "lea")
5651             (match_operand:SWI48 2 "incdec_operand")
5652               (const_string "incdec")
5653            ]
5654            (const_string "alu")))
5655    (set (attr "length_immediate")
5656       (if_then_else
5657         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5658         (const_string "1")
5659         (const_string "*")))
5660    (set_attr "mode" "<MODE>")])
5662 ;; It may seem that nonimmediate operand is proper one for operand 1.
5663 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5664 ;; we take care in ix86_binary_operator_ok to not allow two memory
5665 ;; operands so proper swapping will be done in reload.  This allow
5666 ;; patterns constructed from addsi_1 to match.
5668 (define_insn "addsi_1_zext"
5669   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5670         (zero_extend:DI
5671           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5672                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5673    (clobber (reg:CC FLAGS_REG))]
5674   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5676   switch (get_attr_type (insn))
5677     {
5678     case TYPE_LEA:
5679       return "#";
5681     case TYPE_INCDEC:
5682       if (operands[2] == const1_rtx)
5683         return "inc{l}\t%k0";
5684       else
5685         {
5686           gcc_assert (operands[2] == constm1_rtx);
5687           return "dec{l}\t%k0";
5688         }
5690     default:
5691       /* For most processors, ADD is faster than LEA.  This alternative
5692          was added to use ADD as much as possible.  */
5693       if (which_alternative == 1)
5694         std::swap (operands[1], operands[2]);
5696       if (x86_maybe_negate_const_int (&operands[2], SImode))
5697         return "sub{l}\t{%2, %k0|%k0, %2}";
5699       return "add{l}\t{%2, %k0|%k0, %2}";
5700     }
5702   [(set (attr "type")
5703      (cond [(eq_attr "alternative" "2")
5704               (const_string "lea")
5705             (match_operand:SI 2 "incdec_operand")
5706               (const_string "incdec")
5707            ]
5708            (const_string "alu")))
5709    (set (attr "length_immediate")
5710       (if_then_else
5711         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5712         (const_string "1")
5713         (const_string "*")))
5714    (set_attr "mode" "SI")])
5716 (define_insn "*addhi_1"
5717   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5718         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5719                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5720    (clobber (reg:CC FLAGS_REG))]
5721   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5723   switch (get_attr_type (insn))
5724     {
5725     case TYPE_LEA:
5726       return "#";
5728     case TYPE_INCDEC:
5729       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5730       if (operands[2] == const1_rtx)
5731         return "inc{w}\t%0";
5732       else
5733         {
5734           gcc_assert (operands[2] == constm1_rtx);
5735           return "dec{w}\t%0";
5736         }
5738     default:
5739       /* For most processors, ADD is faster than LEA.  This alternative
5740          was added to use ADD as much as possible.  */
5741       if (which_alternative == 2)
5742         std::swap (operands[1], operands[2]);
5744       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5745       if (x86_maybe_negate_const_int (&operands[2], HImode))
5746         return "sub{w}\t{%2, %0|%0, %2}";
5748       return "add{w}\t{%2, %0|%0, %2}";
5749     }
5751   [(set (attr "type")
5752      (cond [(eq_attr "alternative" "3")
5753               (const_string "lea")
5754             (match_operand:HI 2 "incdec_operand")
5755               (const_string "incdec")
5756            ]
5757            (const_string "alu")))
5758    (set (attr "length_immediate")
5759       (if_then_else
5760         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5761         (const_string "1")
5762         (const_string "*")))
5763    (set_attr "mode" "HI,HI,HI,SI")])
5765 (define_insn "*addqi_1"
5766   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5767         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5768                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5769    (clobber (reg:CC FLAGS_REG))]
5770   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5772   bool widen = (get_attr_mode (insn) != MODE_QI);
5774   switch (get_attr_type (insn))
5775     {
5776     case TYPE_LEA:
5777       return "#";
5779     case TYPE_INCDEC:
5780       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5781       if (operands[2] == const1_rtx)
5782         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5783       else
5784         {
5785           gcc_assert (operands[2] == constm1_rtx);
5786           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5787         }
5789     default:
5790       /* For most processors, ADD is faster than LEA.  These alternatives
5791          were added to use ADD as much as possible.  */
5792       if (which_alternative == 2 || which_alternative == 4)
5793         std::swap (operands[1], operands[2]);
5795       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5796       if (x86_maybe_negate_const_int (&operands[2], QImode))
5797         {
5798           if (widen)
5799             return "sub{l}\t{%2, %k0|%k0, %2}";
5800           else
5801             return "sub{b}\t{%2, %0|%0, %2}";
5802         }
5803       if (widen)
5804         return "add{l}\t{%k2, %k0|%k0, %k2}";
5805       else
5806         return "add{b}\t{%2, %0|%0, %2}";
5807     }
5809   [(set (attr "type")
5810      (cond [(eq_attr "alternative" "5")
5811               (const_string "lea")
5812             (match_operand:QI 2 "incdec_operand")
5813               (const_string "incdec")
5814            ]
5815            (const_string "alu")))
5816    (set (attr "length_immediate")
5817       (if_then_else
5818         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5819         (const_string "1")
5820         (const_string "*")))
5821    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5822    ;; Potential partial reg stall on alternatives 3 and 4.
5823    (set (attr "preferred_for_speed")
5824      (cond [(eq_attr "alternative" "3,4")
5825               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5826            (symbol_ref "true")))])
5828 (define_insn "*addqi_1_slp"
5829   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5830         (plus:QI (match_dup 0)
5831                  (match_operand:QI 1 "general_operand" "qn,qm")))
5832    (clobber (reg:CC FLAGS_REG))]
5833   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5834    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5836   switch (get_attr_type (insn))
5837     {
5838     case TYPE_INCDEC:
5839       if (operands[1] == const1_rtx)
5840         return "inc{b}\t%0";
5841       else
5842         {
5843           gcc_assert (operands[1] == constm1_rtx);
5844           return "dec{b}\t%0";
5845         }
5847     default:
5848       if (x86_maybe_negate_const_int (&operands[1], QImode))
5849         return "sub{b}\t{%1, %0|%0, %1}";
5851       return "add{b}\t{%1, %0|%0, %1}";
5852     }
5854   [(set (attr "type")
5855      (if_then_else (match_operand:QI 1 "incdec_operand")
5856         (const_string "incdec")
5857         (const_string "alu1")))
5858    (set (attr "memory")
5859      (if_then_else (match_operand 1 "memory_operand")
5860         (const_string "load")
5861         (const_string "none")))
5862    (set_attr "mode" "QI")])
5864 ;; Split non destructive adds if we cannot use lea.
5865 (define_split
5866   [(set (match_operand:SWI48 0 "register_operand")
5867         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5868                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5869    (clobber (reg:CC FLAGS_REG))]
5870   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5871   [(set (match_dup 0) (match_dup 1))
5872    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5873               (clobber (reg:CC FLAGS_REG))])])
5875 ;; Split non destructive adds if we cannot use lea.
5876 (define_split
5877   [(set (match_operand:DI 0 "register_operand")
5878         (zero_extend:DI
5879           (plus:SI (match_operand:SI 1 "register_operand")
5880                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5881    (clobber (reg:CC FLAGS_REG))]
5882   "TARGET_64BIT
5883    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5884   [(set (match_dup 3) (match_dup 1))
5885    (parallel [(set (match_dup 0)
5886                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5887               (clobber (reg:CC FLAGS_REG))])]
5888   "operands[3] = gen_lowpart (SImode, operands[0]);")
5890 ;; Convert add to the lea pattern to avoid flags dependency.
5891 (define_split
5892   [(set (match_operand:SWI 0 "register_operand")
5893         (plus:SWI (match_operand:SWI 1 "register_operand")
5894                   (match_operand:SWI 2 "<nonmemory_operand>")))
5895    (clobber (reg:CC FLAGS_REG))]
5896   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5897   [(set (match_dup 0)
5898         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5900   if (<MODE>mode != <LEAMODE>mode)
5901     {
5902       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5903       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5904       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5905     }
5908 ;; Convert add to the lea pattern to avoid flags dependency.
5909 (define_split
5910   [(set (match_operand:DI 0 "register_operand")
5911         (zero_extend:DI
5912           (plus:SI (match_operand:SI 1 "register_operand")
5913                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5914    (clobber (reg:CC FLAGS_REG))]
5915   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5916   [(set (match_dup 0)
5917         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5919 (define_insn "*add<mode>_2"
5920   [(set (reg FLAGS_REG)
5921         (compare
5922           (plus:SWI
5923             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5924             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5925           (const_int 0)))
5926    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5927         (plus:SWI (match_dup 1) (match_dup 2)))]
5928   "ix86_match_ccmode (insn, CCGOCmode)
5929    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5931   switch (get_attr_type (insn))
5932     {
5933     case TYPE_INCDEC:
5934       if (operands[2] == const1_rtx)
5935         return "inc{<imodesuffix>}\t%0";
5936       else
5937         {
5938           gcc_assert (operands[2] == constm1_rtx);
5939           return "dec{<imodesuffix>}\t%0";
5940         }
5942     default:
5943       if (which_alternative == 2)
5944         std::swap (operands[1], operands[2]);
5945         
5946       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5947       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5948         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5950       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5951     }
5953   [(set (attr "type")
5954      (if_then_else (match_operand:SWI 2 "incdec_operand")
5955         (const_string "incdec")
5956         (const_string "alu")))
5957    (set (attr "length_immediate")
5958       (if_then_else
5959         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5960         (const_string "1")
5961         (const_string "*")))
5962    (set_attr "mode" "<MODE>")])
5964 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5965 (define_insn "*addsi_2_zext"
5966   [(set (reg FLAGS_REG)
5967         (compare
5968           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5969                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5970           (const_int 0)))
5971    (set (match_operand:DI 0 "register_operand" "=r,r")
5972         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5973   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5974    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5976   switch (get_attr_type (insn))
5977     {
5978     case TYPE_INCDEC:
5979       if (operands[2] == const1_rtx)
5980         return "inc{l}\t%k0";
5981       else
5982         {
5983           gcc_assert (operands[2] == constm1_rtx);
5984           return "dec{l}\t%k0";
5985         }
5987     default:
5988       if (which_alternative == 1)
5989         std::swap (operands[1], operands[2]);
5991       if (x86_maybe_negate_const_int (&operands[2], SImode))
5992         return "sub{l}\t{%2, %k0|%k0, %2}";
5994       return "add{l}\t{%2, %k0|%k0, %2}";
5995     }
5997   [(set (attr "type")
5998      (if_then_else (match_operand:SI 2 "incdec_operand")
5999         (const_string "incdec")
6000         (const_string "alu")))
6001    (set (attr "length_immediate")
6002       (if_then_else
6003         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6004         (const_string "1")
6005         (const_string "*")))
6006    (set_attr "mode" "SI")])
6008 (define_insn "*add<mode>_3"
6009   [(set (reg FLAGS_REG)
6010         (compare
6011           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6012           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6013    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6014   "ix86_match_ccmode (insn, CCZmode)
6015    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6017   switch (get_attr_type (insn))
6018     {
6019     case TYPE_INCDEC:
6020       if (operands[2] == const1_rtx)
6021         return "inc{<imodesuffix>}\t%0";
6022       else
6023         {
6024           gcc_assert (operands[2] == constm1_rtx);
6025           return "dec{<imodesuffix>}\t%0";
6026         }
6028     default:
6029       if (which_alternative == 1)
6030         std::swap (operands[1], operands[2]);
6032       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6033       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6034         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6036       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6037     }
6039   [(set (attr "type")
6040      (if_then_else (match_operand:SWI 2 "incdec_operand")
6041         (const_string "incdec")
6042         (const_string "alu")))
6043    (set (attr "length_immediate")
6044       (if_then_else
6045         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6046         (const_string "1")
6047         (const_string "*")))
6048    (set_attr "mode" "<MODE>")])
6050 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6051 (define_insn "*addsi_3_zext"
6052   [(set (reg FLAGS_REG)
6053         (compare
6054           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6055           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6056    (set (match_operand:DI 0 "register_operand" "=r,r")
6057         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6058   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6059    && ix86_binary_operator_ok (PLUS, SImode, operands)"
6061   switch (get_attr_type (insn))
6062     {
6063     case TYPE_INCDEC:
6064       if (operands[2] == const1_rtx)
6065         return "inc{l}\t%k0";
6066       else
6067         {
6068           gcc_assert (operands[2] == constm1_rtx);
6069           return "dec{l}\t%k0";
6070         }
6072     default:
6073       if (which_alternative == 1)
6074         std::swap (operands[1], operands[2]);
6076       if (x86_maybe_negate_const_int (&operands[2], SImode))
6077         return "sub{l}\t{%2, %k0|%k0, %2}";
6079       return "add{l}\t{%2, %k0|%k0, %2}";
6080     }
6082   [(set (attr "type")
6083      (if_then_else (match_operand:SI 2 "incdec_operand")
6084         (const_string "incdec")
6085         (const_string "alu")))
6086    (set (attr "length_immediate")
6087       (if_then_else
6088         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6089         (const_string "1")
6090         (const_string "*")))
6091    (set_attr "mode" "SI")])
6093 ; For comparisons against 1, -1 and 128, we may generate better code
6094 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6095 ; is matched then.  We can't accept general immediate, because for
6096 ; case of overflows,  the result is messed up.
6097 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6098 ; only for comparisons not depending on it.
6100 (define_insn "*adddi_4"
6101   [(set (reg FLAGS_REG)
6102         (compare
6103           (match_operand:DI 1 "nonimmediate_operand" "0")
6104           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6105    (clobber (match_scratch:DI 0 "=rm"))]
6106   "TARGET_64BIT
6107    && ix86_match_ccmode (insn, CCGCmode)"
6109   switch (get_attr_type (insn))
6110     {
6111     case TYPE_INCDEC:
6112       if (operands[2] == constm1_rtx)
6113         return "inc{q}\t%0";
6114       else
6115         {
6116           gcc_assert (operands[2] == const1_rtx);
6117           return "dec{q}\t%0";
6118         }
6120     default:
6121       if (x86_maybe_negate_const_int (&operands[2], DImode))
6122         return "add{q}\t{%2, %0|%0, %2}";
6124       return "sub{q}\t{%2, %0|%0, %2}";
6125     }
6127   [(set (attr "type")
6128      (if_then_else (match_operand:DI 2 "incdec_operand")
6129         (const_string "incdec")
6130         (const_string "alu")))
6131    (set (attr "length_immediate")
6132       (if_then_else
6133         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6134         (const_string "1")
6135         (const_string "*")))
6136    (set_attr "mode" "DI")])
6138 ; For comparisons against 1, -1 and 128, we may generate better code
6139 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6140 ; is matched then.  We can't accept general immediate, because for
6141 ; case of overflows,  the result is messed up.
6142 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6143 ; only for comparisons not depending on it.
6145 (define_insn "*add<mode>_4"
6146   [(set (reg FLAGS_REG)
6147         (compare
6148           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6149           (match_operand:SWI124 2 "const_int_operand" "n")))
6150    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6151   "ix86_match_ccmode (insn, CCGCmode)"
6153   switch (get_attr_type (insn))
6154     {
6155     case TYPE_INCDEC:
6156       if (operands[2] == constm1_rtx)
6157         return "inc{<imodesuffix>}\t%0";
6158       else
6159         {
6160           gcc_assert (operands[2] == const1_rtx);
6161           return "dec{<imodesuffix>}\t%0";
6162         }
6164     default:
6165       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6166         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6168       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6169     }
6171   [(set (attr "type")
6172      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6173         (const_string "incdec")
6174         (const_string "alu")))
6175    (set (attr "length_immediate")
6176       (if_then_else
6177         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6178         (const_string "1")
6179         (const_string "*")))
6180    (set_attr "mode" "<MODE>")])
6182 (define_insn "*add<mode>_5"
6183   [(set (reg FLAGS_REG)
6184         (compare
6185           (plus:SWI
6186             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6187             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6188           (const_int 0)))
6189    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6190   "ix86_match_ccmode (insn, CCGOCmode)
6191    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6193   switch (get_attr_type (insn))
6194     {
6195     case TYPE_INCDEC:
6196       if (operands[2] == const1_rtx)
6197         return "inc{<imodesuffix>}\t%0";
6198       else
6199         {
6200           gcc_assert (operands[2] == constm1_rtx);
6201           return "dec{<imodesuffix>}\t%0";
6202         }
6204     default:
6205       if (which_alternative == 1)
6206         std::swap (operands[1], operands[2]);
6208       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6209       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6210         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6212       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6213     }
6215   [(set (attr "type")
6216      (if_then_else (match_operand:SWI 2 "incdec_operand")
6217         (const_string "incdec")
6218         (const_string "alu")))
6219    (set (attr "length_immediate")
6220       (if_then_else
6221         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6222         (const_string "1")
6223         (const_string "*")))
6224    (set_attr "mode" "<MODE>")])
6226 (define_insn "addqi_ext_1"
6227   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6228                          (const_int 8)
6229                          (const_int 8))
6230         (subreg:SI
6231           (plus:QI
6232             (subreg:QI
6233               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6234                                (const_int 8)
6235                                (const_int 8)) 0)
6236             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6237    (clobber (reg:CC FLAGS_REG))]
6238   ""
6240   switch (get_attr_type (insn))
6241     {
6242     case TYPE_INCDEC:
6243       if (operands[2] == const1_rtx)
6244         return "inc{b}\t%h0";
6245       else
6246         {
6247           gcc_assert (operands[2] == constm1_rtx);
6248           return "dec{b}\t%h0";
6249         }
6251     default:
6252       return "add{b}\t{%2, %h0|%h0, %2}";
6253     }
6255   [(set_attr "isa" "*,nox64")
6256    (set (attr "type")
6257      (if_then_else (match_operand:QI 2 "incdec_operand")
6258         (const_string "incdec")
6259         (const_string "alu")))
6260    (set_attr "mode" "QI")])
6262 (define_insn "*addqi_ext_2"
6263   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6264                          (const_int 8)
6265                          (const_int 8))
6266         (subreg:SI
6267           (plus:QI
6268             (subreg:QI
6269               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6270                                (const_int 8)
6271                                (const_int 8)) 0)
6272             (subreg:QI
6273               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6274                                (const_int 8)
6275                                (const_int 8)) 0)) 0))
6276   (clobber (reg:CC FLAGS_REG))]
6277   ""
6278   "add{b}\t{%h2, %h0|%h0, %h2}"
6279   [(set_attr "type" "alu")
6280    (set_attr "mode" "QI")])
6282 ;; Add with jump on overflow.
6283 (define_expand "addv<mode>4"
6284   [(parallel [(set (reg:CCO FLAGS_REG)
6285                    (eq:CCO (plus:<DWI>
6286                               (sign_extend:<DWI>
6287                                  (match_operand:SWI 1 "nonimmediate_operand"))
6288                               (match_dup 4))
6289                            (sign_extend:<DWI>
6290                               (plus:SWI (match_dup 1)
6291                                         (match_operand:SWI 2
6292                                            "<general_operand>")))))
6293               (set (match_operand:SWI 0 "register_operand")
6294                    (plus:SWI (match_dup 1) (match_dup 2)))])
6295    (set (pc) (if_then_else
6296                (eq (reg:CCO FLAGS_REG) (const_int 0))
6297                (label_ref (match_operand 3))
6298                (pc)))]
6299   ""
6301   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6302   if (CONST_INT_P (operands[2]))
6303     operands[4] = operands[2];
6304   else
6305     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6308 (define_insn "*addv<mode>4"
6309   [(set (reg:CCO FLAGS_REG)
6310         (eq:CCO (plus:<DWI>
6311                    (sign_extend:<DWI>
6312                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6313                    (sign_extend:<DWI>
6314                       (match_operand:SWI 2 "<general_sext_operand>"
6315                                            "<r>mWe,<r>We")))
6316                 (sign_extend:<DWI>
6317                    (plus:SWI (match_dup 1) (match_dup 2)))))
6318    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6319         (plus:SWI (match_dup 1) (match_dup 2)))]
6320   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6321   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6322   [(set_attr "type" "alu")
6323    (set_attr "mode" "<MODE>")])
6325 (define_insn "*addv<mode>4_1"
6326   [(set (reg:CCO FLAGS_REG)
6327         (eq:CCO (plus:<DWI>
6328                    (sign_extend:<DWI>
6329                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6330                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6331                 (sign_extend:<DWI>
6332                    (plus:SWI (match_dup 1)
6333                              (match_operand:SWI 2 "x86_64_immediate_operand"
6334                                                   "<i>")))))
6335    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6336         (plus:SWI (match_dup 1) (match_dup 2)))]
6337   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6338    && CONST_INT_P (operands[2])
6339    && INTVAL (operands[2]) == INTVAL (operands[3])"
6340   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6341   [(set_attr "type" "alu")
6342    (set_attr "mode" "<MODE>")
6343    (set (attr "length_immediate")
6344         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6345                   (const_string "1")
6346                (match_test "<MODE_SIZE> == 8")
6347                   (const_string "4")]
6348               (const_string "<MODE_SIZE>")))])
6350 (define_expand "uaddv<mode>4"
6351   [(parallel [(set (reg:CCC FLAGS_REG)
6352                    (compare:CCC
6353                      (plus:SWI
6354                        (match_operand:SWI 1 "nonimmediate_operand")
6355                        (match_operand:SWI 2 "<general_operand>"))
6356                      (match_dup 1)))
6357               (set (match_operand:SWI 0 "register_operand")
6358                    (plus:SWI (match_dup 1) (match_dup 2)))])
6359    (set (pc) (if_then_else
6360                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6361                (label_ref (match_operand 3))
6362                (pc)))]
6363   ""
6364   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6366 ;; The lea patterns for modes less than 32 bits need to be matched by
6367 ;; several insns converted to real lea by splitters.
6369 (define_insn_and_split "*lea<mode>_general_1"
6370   [(set (match_operand:SWI12 0 "register_operand" "=r")
6371         (plus:SWI12
6372           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6373                       (match_operand:SWI12 2 "register_operand" "r"))
6374           (match_operand:SWI12 3 "immediate_operand" "i")))]
6375   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6376   "#"
6377   "&& reload_completed"
6378   [(set (match_dup 0)
6379         (plus:SI
6380           (plus:SI (match_dup 1) (match_dup 2))
6381           (match_dup 3)))]
6383   operands[0] = gen_lowpart (SImode, operands[0]);
6384   operands[1] = gen_lowpart (SImode, operands[1]);
6385   operands[2] = gen_lowpart (SImode, operands[2]);
6386   operands[3] = gen_lowpart (SImode, operands[3]);
6388   [(set_attr "type" "lea")
6389    (set_attr "mode" "SI")])
6391 (define_insn_and_split "*lea<mode>_general_2"
6392   [(set (match_operand:SWI12 0 "register_operand" "=r")
6393         (plus:SWI12
6394           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6395                       (match_operand 2 "const248_operand" "n"))
6396           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6397   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6398   "#"
6399   "&& reload_completed"
6400   [(set (match_dup 0)
6401         (plus:SI
6402           (mult:SI (match_dup 1) (match_dup 2))
6403           (match_dup 3)))]
6405   operands[0] = gen_lowpart (SImode, operands[0]);
6406   operands[1] = gen_lowpart (SImode, operands[1]);
6407   operands[3] = gen_lowpart (SImode, operands[3]);
6409   [(set_attr "type" "lea")
6410    (set_attr "mode" "SI")])
6412 (define_insn_and_split "*lea<mode>_general_2b"
6413   [(set (match_operand:SWI12 0 "register_operand" "=r")
6414         (plus:SWI12
6415           (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6416                         (match_operand 2 "const123_operand" "n"))
6417           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6418   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6419   "#"
6420   "&& reload_completed"
6421   [(set (match_dup 0)
6422         (plus:SI
6423           (ashift:SI (match_dup 1) (match_dup 2))
6424           (match_dup 3)))]
6426   operands[0] = gen_lowpart (SImode, operands[0]);
6427   operands[1] = gen_lowpart (SImode, operands[1]);
6428   operands[3] = gen_lowpart (SImode, operands[3]);
6430   [(set_attr "type" "lea")
6431    (set_attr "mode" "SI")])
6433 (define_insn_and_split "*lea<mode>_general_3"
6434   [(set (match_operand:SWI12 0 "register_operand" "=r")
6435         (plus:SWI12
6436           (plus:SWI12
6437             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6438                         (match_operand 2 "const248_operand" "n"))
6439             (match_operand:SWI12 3 "register_operand" "r"))
6440           (match_operand:SWI12 4 "immediate_operand" "i")))]
6441   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6442   "#"
6443   "&& reload_completed"
6444   [(set (match_dup 0)
6445         (plus:SI
6446           (plus:SI
6447             (mult:SI (match_dup 1) (match_dup 2))
6448             (match_dup 3))
6449           (match_dup 4)))]
6451   operands[0] = gen_lowpart (SImode, operands[0]);
6452   operands[1] = gen_lowpart (SImode, operands[1]);
6453   operands[3] = gen_lowpart (SImode, operands[3]);
6454   operands[4] = gen_lowpart (SImode, operands[4]);
6456   [(set_attr "type" "lea")
6457    (set_attr "mode" "SI")])
6459 (define_insn_and_split "*lea<mode>_general_3b"
6460   [(set (match_operand:SWI12 0 "register_operand" "=r")
6461         (plus:SWI12
6462           (plus:SWI12
6463             (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6464                           (match_operand 2 "const123_operand" "n"))
6465             (match_operand:SWI12 3 "register_operand" "r"))
6466           (match_operand:SWI12 4 "immediate_operand" "i")))]
6467   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6468   "#"
6469   "&& reload_completed"
6470   [(set (match_dup 0)
6471         (plus:SI
6472           (plus:SI
6473             (ashift:SI (match_dup 1) (match_dup 2))
6474             (match_dup 3))
6475           (match_dup 4)))]
6477   operands[0] = gen_lowpart (SImode, operands[0]);
6478   operands[1] = gen_lowpart (SImode, operands[1]);
6479   operands[3] = gen_lowpart (SImode, operands[3]);
6480   operands[4] = gen_lowpart (SImode, operands[4]);
6482   [(set_attr "type" "lea")
6483    (set_attr "mode" "SI")])
6485 (define_insn_and_split "*lea<mode>_general_4"
6486   [(set (match_operand:SWI12 0 "register_operand" "=r")
6487         (any_or:SWI12
6488           (ashift:SWI12
6489             (match_operand:SWI12 1 "index_register_operand" "l")
6490             (match_operand 2 "const_0_to_3_operand" "n"))
6491           (match_operand 3 "const_int_operand" "n")))]
6492   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6493    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6494        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6495   "#"
6496   "&& reload_completed"
6497   [(set (match_dup 0)
6498         (plus:SI
6499           (mult:SI (match_dup 1) (match_dup 2))
6500           (match_dup 3)))]
6502   operands[0] = gen_lowpart (SImode, operands[0]);
6503   operands[1] = gen_lowpart (SImode, operands[1]);
6504   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6506   [(set_attr "type" "lea")
6507    (set_attr "mode" "SI")])
6509 (define_insn_and_split "*lea<mode>_general_4"
6510   [(set (match_operand:SWI48 0 "register_operand" "=r")
6511         (any_or:SWI48
6512           (ashift:SWI48
6513             (match_operand:SWI48 1 "index_register_operand" "l")
6514             (match_operand 2 "const_0_to_3_operand" "n"))
6515           (match_operand 3 "const_int_operand" "n")))]
6516   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6517    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6518   "#"
6519   "&& reload_completed"
6520   [(set (match_dup 0)
6521         (plus:SWI48
6522           (mult:SWI48 (match_dup 1) (match_dup 2))
6523           (match_dup 3)))]
6524   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6525   [(set_attr "type" "lea")
6526    (set_attr "mode" "<MODE>")])
6528 ;; Subtract instructions
6530 (define_expand "sub<mode>3"
6531   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6532         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6533                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6534   ""
6535   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6537 (define_insn_and_split "*sub<dwi>3_doubleword"
6538   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6539         (minus:<DWI>
6540           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6541           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6542                                                         "ro<di>,r<di>")))
6543    (clobber (reg:CC FLAGS_REG))]
6544   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6545   "#"
6546   "reload_completed"
6547   [(parallel [(set (reg:CC FLAGS_REG)
6548                    (compare:CC (match_dup 1) (match_dup 2)))
6549               (set (match_dup 0)
6550                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6551    (parallel [(set (match_dup 3)
6552                    (minus:DWIH
6553                      (minus:DWIH
6554                        (match_dup 4)
6555                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6556                      (match_dup 5)))
6557               (clobber (reg:CC FLAGS_REG))])]
6559   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6560   if (operands[2] == const0_rtx)
6561     {
6562       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6563       DONE;
6564     }
6567 (define_insn "*sub<mode>_1"
6568   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6569         (minus:SWI
6570           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6571           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6572    (clobber (reg:CC FLAGS_REG))]
6573   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6574   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6575   [(set_attr "type" "alu")
6576    (set_attr "mode" "<MODE>")])
6578 (define_insn "*subsi_1_zext"
6579   [(set (match_operand:DI 0 "register_operand" "=r")
6580         (zero_extend:DI
6581           (minus:SI (match_operand:SI 1 "register_operand" "0")
6582                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6583    (clobber (reg:CC FLAGS_REG))]
6584   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6585   "sub{l}\t{%2, %k0|%k0, %2}"
6586   [(set_attr "type" "alu")
6587    (set_attr "mode" "SI")])
6589 (define_insn "*subqi_1_slp"
6590   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6591         (minus:QI (match_dup 0)
6592                   (match_operand:QI 1 "general_operand" "qn,qm")))
6593    (clobber (reg:CC FLAGS_REG))]
6594   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6595    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6596   "sub{b}\t{%1, %0|%0, %1}"
6597   [(set_attr "type" "alu1")
6598    (set_attr "mode" "QI")])
6600 (define_insn "*sub<mode>_2"
6601   [(set (reg FLAGS_REG)
6602         (compare
6603           (minus:SWI
6604             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6605             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6606           (const_int 0)))
6607    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6608         (minus:SWI (match_dup 1) (match_dup 2)))]
6609   "ix86_match_ccmode (insn, CCGOCmode)
6610    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6611   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6612   [(set_attr "type" "alu")
6613    (set_attr "mode" "<MODE>")])
6615 (define_insn "*subsi_2_zext"
6616   [(set (reg FLAGS_REG)
6617         (compare
6618           (minus:SI (match_operand:SI 1 "register_operand" "0")
6619                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6620           (const_int 0)))
6621    (set (match_operand:DI 0 "register_operand" "=r")
6622         (zero_extend:DI
6623           (minus:SI (match_dup 1)
6624                     (match_dup 2))))]
6625   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6626    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6627   "sub{l}\t{%2, %k0|%k0, %2}"
6628   [(set_attr "type" "alu")
6629    (set_attr "mode" "SI")])
6631 ;; Subtract with jump on overflow.
6632 (define_expand "subv<mode>4"
6633   [(parallel [(set (reg:CCO FLAGS_REG)
6634                    (eq:CCO (minus:<DWI>
6635                               (sign_extend:<DWI>
6636                                  (match_operand:SWI 1 "nonimmediate_operand"))
6637                               (match_dup 4))
6638                            (sign_extend:<DWI>
6639                               (minus:SWI (match_dup 1)
6640                                          (match_operand:SWI 2
6641                                             "<general_operand>")))))
6642               (set (match_operand:SWI 0 "register_operand")
6643                    (minus:SWI (match_dup 1) (match_dup 2)))])
6644    (set (pc) (if_then_else
6645                (eq (reg:CCO FLAGS_REG) (const_int 0))
6646                (label_ref (match_operand 3))
6647                (pc)))]
6648   ""
6650   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6651   if (CONST_INT_P (operands[2]))
6652     operands[4] = operands[2];
6653   else
6654     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6657 (define_insn "*subv<mode>4"
6658   [(set (reg:CCO FLAGS_REG)
6659         (eq:CCO (minus:<DWI>
6660                    (sign_extend:<DWI>
6661                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6662                    (sign_extend:<DWI>
6663                       (match_operand:SWI 2 "<general_sext_operand>"
6664                                            "<r>We,<r>m")))
6665                 (sign_extend:<DWI>
6666                    (minus:SWI (match_dup 1) (match_dup 2)))))
6667    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6668         (minus:SWI (match_dup 1) (match_dup 2)))]
6669   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6670   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6671   [(set_attr "type" "alu")
6672    (set_attr "mode" "<MODE>")])
6674 (define_insn "*subv<mode>4_1"
6675   [(set (reg:CCO FLAGS_REG)
6676         (eq:CCO (minus:<DWI>
6677                    (sign_extend:<DWI>
6678                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6679                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6680                 (sign_extend:<DWI>
6681                    (minus:SWI (match_dup 1)
6682                               (match_operand:SWI 2 "x86_64_immediate_operand"
6683                                                    "<i>")))))
6684    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6685         (minus:SWI (match_dup 1) (match_dup 2)))]
6686   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6687    && CONST_INT_P (operands[2])
6688    && INTVAL (operands[2]) == INTVAL (operands[3])"
6689   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6690   [(set_attr "type" "alu")
6691    (set_attr "mode" "<MODE>")
6692    (set (attr "length_immediate")
6693         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6694                   (const_string "1")
6695                (match_test "<MODE_SIZE> == 8")
6696                   (const_string "4")]
6697               (const_string "<MODE_SIZE>")))])
6699 (define_expand "usubv<mode>4"
6700   [(parallel [(set (reg:CC FLAGS_REG)
6701                    (compare:CC
6702                      (match_operand:SWI 1 "nonimmediate_operand")
6703                      (match_operand:SWI 2 "<general_operand>")))
6704               (set (match_operand:SWI 0 "register_operand")
6705                    (minus:SWI (match_dup 1) (match_dup 2)))])
6706    (set (pc) (if_then_else
6707                (ltu (reg:CC FLAGS_REG) (const_int 0))
6708                (label_ref (match_operand 3))
6709                (pc)))]
6710   ""
6711   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6713 (define_insn "*sub<mode>_3"
6714   [(set (reg FLAGS_REG)
6715         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6716                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6717    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6718         (minus:SWI (match_dup 1) (match_dup 2)))]
6719   "ix86_match_ccmode (insn, CCmode)
6720    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6721   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6722   [(set_attr "type" "alu")
6723    (set_attr "mode" "<MODE>")])
6725 (define_insn "*subsi_3_zext"
6726   [(set (reg FLAGS_REG)
6727         (compare (match_operand:SI 1 "register_operand" "0")
6728                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6729    (set (match_operand:DI 0 "register_operand" "=r")
6730         (zero_extend:DI
6731           (minus:SI (match_dup 1)
6732                     (match_dup 2))))]
6733   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6734    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735   "sub{l}\t{%2, %1|%1, %2}"
6736   [(set_attr "type" "alu")
6737    (set_attr "mode" "SI")])
6739 ;; Add with carry and subtract with borrow
6741 (define_insn "add<mode>3_carry"
6742   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6743         (plus:SWI
6744           (plus:SWI
6745             (match_operator:SWI 4 "ix86_carry_flag_operator"
6746              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6747             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6748           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6749    (clobber (reg:CC FLAGS_REG))]
6750   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6751   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6752   [(set_attr "type" "alu")
6753    (set_attr "use_carry" "1")
6754    (set_attr "pent_pair" "pu")
6755    (set_attr "mode" "<MODE>")])
6757 (define_insn "*addsi3_carry_zext"
6758   [(set (match_operand:DI 0 "register_operand" "=r")
6759         (zero_extend:DI
6760           (plus:SI
6761             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6762                       [(reg FLAGS_REG) (const_int 0)])
6763                      (match_operand:SI 1 "register_operand" "%0"))
6764             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6765    (clobber (reg:CC FLAGS_REG))]
6766   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6767   "adc{l}\t{%2, %k0|%k0, %2}"
6768   [(set_attr "type" "alu")
6769    (set_attr "use_carry" "1")
6770    (set_attr "pent_pair" "pu")
6771    (set_attr "mode" "SI")])
6773 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6775 (define_insn "addcarry<mode>"
6776   [(set (reg:CCC FLAGS_REG)
6777         (compare:CCC
6778           (plus:SWI48
6779             (plus:SWI48
6780               (match_operator:SWI48 4 "ix86_carry_flag_operator"
6781                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6782               (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6783             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6784           (match_dup 1)))
6785    (set (match_operand:SWI48 0 "register_operand" "=r")
6786         (plus:SWI48 (plus:SWI48 (match_op_dup 4
6787                                  [(match_dup 3) (const_int 0)])
6788                                 (match_dup 1))
6789                     (match_dup 2)))]
6790   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6791   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6792   [(set_attr "type" "alu")
6793    (set_attr "use_carry" "1")
6794    (set_attr "pent_pair" "pu")
6795    (set_attr "mode" "<MODE>")])
6797 (define_insn "sub<mode>3_carry"
6798   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6799         (minus:SWI
6800           (minus:SWI
6801             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6802             (match_operator:SWI 4 "ix86_carry_flag_operator"
6803              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6804           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6805    (clobber (reg:CC FLAGS_REG))]
6806   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6807   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6808   [(set_attr "type" "alu")
6809    (set_attr "use_carry" "1")
6810    (set_attr "pent_pair" "pu")
6811    (set_attr "mode" "<MODE>")])
6813 (define_insn "*subsi3_carry_zext"
6814   [(set (match_operand:DI 0 "register_operand" "=r")
6815         (zero_extend:DI
6816           (minus:SI
6817             (minus:SI
6818               (match_operand:SI 1 "register_operand" "0")
6819               (match_operator:SI 3 "ix86_carry_flag_operator"
6820                [(reg FLAGS_REG) (const_int 0)]))
6821             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6822    (clobber (reg:CC FLAGS_REG))]
6823   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6824   "sbb{l}\t{%2, %k0|%k0, %2}"
6825   [(set_attr "type" "alu")
6826    (set_attr "use_carry" "1")
6827    (set_attr "pent_pair" "pu")
6828    (set_attr "mode" "SI")])
6830 (define_insn "subborrow<mode>"
6831   [(set (reg:CCC FLAGS_REG)
6832         (compare:CCC
6833           (match_operand:SWI48 1 "nonimmediate_operand" "0")
6834           (plus:SWI48
6835             (match_operator:SWI48 4 "ix86_carry_flag_operator"
6836              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6837             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6838    (set (match_operand:SWI48 0 "register_operand" "=r")
6839         (minus:SWI48 (minus:SWI48 (match_dup 1)
6840                                   (match_op_dup 4
6841                                    [(match_dup 3) (const_int 0)]))
6842                      (match_dup 2)))]
6843   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6844   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6845   [(set_attr "type" "alu")
6846    (set_attr "use_carry" "1")
6847    (set_attr "pent_pair" "pu")
6848    (set_attr "mode" "<MODE>")])
6850 ;; Overflow setting add instructions
6852 (define_expand "addqi3_cconly_overflow"
6853   [(parallel
6854      [(set (reg:CCC FLAGS_REG)
6855            (compare:CCC
6856              (plus:QI
6857                (match_operand:QI 0 "nonimmediate_operand")
6858                (match_operand:QI 1 "general_operand"))
6859              (match_dup 0)))
6860       (clobber (match_scratch:QI 2))])]
6861   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6863 (define_insn "*add<mode>3_cconly_overflow_1"
6864   [(set (reg:CCC FLAGS_REG)
6865         (compare:CCC
6866           (plus:SWI
6867             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6868             (match_operand:SWI 2 "<general_operand>" "<g>"))
6869           (match_dup 1)))
6870    (clobber (match_scratch:SWI 0 "=<r>"))]
6871   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6872   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6873   [(set_attr "type" "alu")
6874    (set_attr "mode" "<MODE>")])
6876 (define_insn "*add<mode>3_cc_overflow_1"
6877   [(set (reg:CCC FLAGS_REG)
6878         (compare:CCC
6879             (plus:SWI
6880                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6881                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6882             (match_dup 1)))
6883    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6884         (plus:SWI (match_dup 1) (match_dup 2)))]
6885   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6886   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6887   [(set_attr "type" "alu")
6888    (set_attr "mode" "<MODE>")])
6890 (define_insn "*addsi3_zext_cc_overflow_1"
6891   [(set (reg:CCC FLAGS_REG)
6892         (compare:CCC
6893           (plus:SI
6894             (match_operand:SI 1 "nonimmediate_operand" "%0")
6895             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6896           (match_dup 1)))
6897    (set (match_operand:DI 0 "register_operand" "=r")
6898         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6899   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6900   "add{l}\t{%2, %k0|%k0, %2}"
6901   [(set_attr "type" "alu")
6902    (set_attr "mode" "SI")])
6904 (define_insn "*add<mode>3_cconly_overflow_2"
6905   [(set (reg:CCC FLAGS_REG)
6906         (compare:CCC
6907           (plus:SWI
6908             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6909             (match_operand:SWI 2 "<general_operand>" "<g>"))
6910           (match_dup 2)))
6911    (clobber (match_scratch:SWI 0 "=<r>"))]
6912   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6913   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6914   [(set_attr "type" "alu")
6915    (set_attr "mode" "<MODE>")])
6917 (define_insn "*add<mode>3_cc_overflow_2"
6918   [(set (reg:CCC FLAGS_REG)
6919         (compare:CCC
6920             (plus:SWI
6921                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6922                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6923             (match_dup 2)))
6924    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6925         (plus:SWI (match_dup 1) (match_dup 2)))]
6926   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6927   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6928   [(set_attr "type" "alu")
6929    (set_attr "mode" "<MODE>")])
6931 (define_insn "*addsi3_zext_cc_overflow_2"
6932   [(set (reg:CCC FLAGS_REG)
6933         (compare:CCC
6934           (plus:SI
6935             (match_operand:SI 1 "nonimmediate_operand" "%0")
6936             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6937           (match_dup 2)))
6938    (set (match_operand:DI 0 "register_operand" "=r")
6939         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6940   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6941   "add{l}\t{%2, %k0|%k0, %2}"
6942   [(set_attr "type" "alu")
6943    (set_attr "mode" "SI")])
6945 ;; The patterns that match these are at the end of this file.
6947 (define_expand "<plusminus_insn>xf3"
6948   [(set (match_operand:XF 0 "register_operand")
6949         (plusminus:XF
6950           (match_operand:XF 1 "register_operand")
6951           (match_operand:XF 2 "register_operand")))]
6952   "TARGET_80387")
6954 (define_expand "<plusminus_insn><mode>3"
6955   [(set (match_operand:MODEF 0 "register_operand")
6956         (plusminus:MODEF
6957           (match_operand:MODEF 1 "register_operand")
6958           (match_operand:MODEF 2 "nonimmediate_operand")))]
6959   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6960     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6962 ;; Multiply instructions
6964 (define_expand "mul<mode>3"
6965   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6966                    (mult:SWIM248
6967                      (match_operand:SWIM248 1 "register_operand")
6968                      (match_operand:SWIM248 2 "<general_operand>")))
6969               (clobber (reg:CC FLAGS_REG))])])
6971 (define_expand "mulqi3"
6972   [(parallel [(set (match_operand:QI 0 "register_operand")
6973                    (mult:QI
6974                      (match_operand:QI 1 "register_operand")
6975                      (match_operand:QI 2 "nonimmediate_operand")))
6976               (clobber (reg:CC FLAGS_REG))])]
6977   "TARGET_QIMODE_MATH")
6979 ;; On AMDFAM10
6980 ;; IMUL reg32/64, reg32/64, imm8        Direct
6981 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6982 ;; IMUL reg32/64, reg32/64, imm32       Direct
6983 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6984 ;; IMUL reg32/64, reg32/64              Direct
6985 ;; IMUL reg32/64, mem32/64              Direct
6987 ;; On BDVER1, all above IMULs use DirectPath
6989 ;; On AMDFAM10
6990 ;; IMUL reg16, reg16, imm8      VectorPath
6991 ;; IMUL reg16, mem16, imm8      VectorPath
6992 ;; IMUL reg16, reg16, imm16     VectorPath
6993 ;; IMUL reg16, mem16, imm16     VectorPath
6994 ;; IMUL reg16, reg16            Direct
6995 ;; IMUL reg16, mem16            Direct
6997 ;; On BDVER1, all HI MULs use DoublePath
6999 (define_insn "*mul<mode>3_1"
7000   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7001         (mult:SWIM248
7002           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7003           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7004    (clobber (reg:CC FLAGS_REG))]
7005   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7006   "@
7007    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7008    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7009    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7010   [(set_attr "type" "imul")
7011    (set_attr "prefix_0f" "0,0,1")
7012    (set (attr "athlon_decode")
7013         (cond [(eq_attr "cpu" "athlon")
7014                   (const_string "vector")
7015                (eq_attr "alternative" "1")
7016                   (const_string "vector")
7017                (and (eq_attr "alternative" "2")
7018                     (ior (match_test "<MODE>mode == HImode")
7019                          (match_operand 1 "memory_operand")))
7020                   (const_string "vector")]
7021               (const_string "direct")))
7022    (set (attr "amdfam10_decode")
7023         (cond [(and (eq_attr "alternative" "0,1")
7024                     (ior (match_test "<MODE>mode == HImode")
7025                          (match_operand 1 "memory_operand")))
7026                   (const_string "vector")]
7027               (const_string "direct")))
7028    (set (attr "bdver1_decode")
7029         (if_then_else
7030           (match_test "<MODE>mode == HImode")
7031             (const_string "double")
7032             (const_string "direct")))
7033    (set_attr "mode" "<MODE>")])
7035 (define_insn "*mulsi3_1_zext"
7036   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7037         (zero_extend:DI
7038           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7039                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7040    (clobber (reg:CC FLAGS_REG))]
7041   "TARGET_64BIT
7042    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7043   "@
7044    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7045    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7046    imul{l}\t{%2, %k0|%k0, %2}"
7047   [(set_attr "type" "imul")
7048    (set_attr "prefix_0f" "0,0,1")
7049    (set (attr "athlon_decode")
7050         (cond [(eq_attr "cpu" "athlon")
7051                   (const_string "vector")
7052                (eq_attr "alternative" "1")
7053                   (const_string "vector")
7054                (and (eq_attr "alternative" "2")
7055                     (match_operand 1 "memory_operand"))
7056                   (const_string "vector")]
7057               (const_string "direct")))
7058    (set (attr "amdfam10_decode")
7059         (cond [(and (eq_attr "alternative" "0,1")
7060                     (match_operand 1 "memory_operand"))
7061                   (const_string "vector")]
7062               (const_string "direct")))
7063    (set_attr "bdver1_decode" "direct")
7064    (set_attr "mode" "SI")])
7066 ;;On AMDFAM10 and BDVER1
7067 ;; MUL reg8     Direct
7068 ;; MUL mem8     Direct
7070 (define_insn "*mulqi3_1"
7071   [(set (match_operand:QI 0 "register_operand" "=a")
7072         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7073                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7074    (clobber (reg:CC FLAGS_REG))]
7075   "TARGET_QIMODE_MATH
7076    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7077   "mul{b}\t%2"
7078   [(set_attr "type" "imul")
7079    (set_attr "length_immediate" "0")
7080    (set (attr "athlon_decode")
7081      (if_then_else (eq_attr "cpu" "athlon")
7082         (const_string "vector")
7083         (const_string "direct")))
7084    (set_attr "amdfam10_decode" "direct")
7085    (set_attr "bdver1_decode" "direct")
7086    (set_attr "mode" "QI")])
7088 ;; Multiply with jump on overflow.
7089 (define_expand "mulv<mode>4"
7090   [(parallel [(set (reg:CCO FLAGS_REG)
7091                    (eq:CCO (mult:<DWI>
7092                               (sign_extend:<DWI>
7093                                  (match_operand:SWI248 1 "register_operand"))
7094                               (match_dup 4))
7095                            (sign_extend:<DWI>
7096                               (mult:SWI248 (match_dup 1)
7097                                            (match_operand:SWI248 2
7098                                               "<general_operand>")))))
7099               (set (match_operand:SWI248 0 "register_operand")
7100                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
7101    (set (pc) (if_then_else
7102                (eq (reg:CCO FLAGS_REG) (const_int 0))
7103                (label_ref (match_operand 3))
7104                (pc)))]
7105   ""
7107   if (CONST_INT_P (operands[2]))
7108     operands[4] = operands[2];
7109   else
7110     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7113 (define_insn "*mulv<mode>4"
7114   [(set (reg:CCO FLAGS_REG)
7115         (eq:CCO (mult:<DWI>
7116                    (sign_extend:<DWI>
7117                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7118                    (sign_extend:<DWI>
7119                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7120                 (sign_extend:<DWI>
7121                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
7122    (set (match_operand:SWI48 0 "register_operand" "=r,r")
7123         (mult:SWI48 (match_dup 1) (match_dup 2)))]
7124   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7125   "@
7126    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7127    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7128   [(set_attr "type" "imul")
7129    (set_attr "prefix_0f" "0,1")
7130    (set (attr "athlon_decode")
7131         (cond [(eq_attr "cpu" "athlon")
7132                   (const_string "vector")
7133                (eq_attr "alternative" "0")
7134                   (const_string "vector")
7135                (and (eq_attr "alternative" "1")
7136                     (match_operand 1 "memory_operand"))
7137                   (const_string "vector")]
7138               (const_string "direct")))
7139    (set (attr "amdfam10_decode")
7140         (cond [(and (eq_attr "alternative" "1")
7141                     (match_operand 1 "memory_operand"))
7142                   (const_string "vector")]
7143               (const_string "direct")))
7144    (set_attr "bdver1_decode" "direct")
7145    (set_attr "mode" "<MODE>")])
7147 (define_insn "*mulvhi4"
7148   [(set (reg:CCO FLAGS_REG)
7149         (eq:CCO (mult:SI
7150                    (sign_extend:SI
7151                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
7152                    (sign_extend:SI
7153                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
7154                 (sign_extend:SI
7155                    (mult:HI (match_dup 1) (match_dup 2)))))
7156    (set (match_operand:HI 0 "register_operand" "=r")
7157         (mult:HI (match_dup 1) (match_dup 2)))]
7158   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7159   "imul{w}\t{%2, %0|%0, %2}"
7160   [(set_attr "type" "imul")
7161    (set_attr "prefix_0f" "1")
7162    (set_attr "athlon_decode" "vector")
7163    (set_attr "amdfam10_decode" "direct")
7164    (set_attr "bdver1_decode" "double")
7165    (set_attr "mode" "HI")])
7167 (define_insn "*mulv<mode>4_1"
7168   [(set (reg:CCO FLAGS_REG)
7169         (eq:CCO (mult:<DWI>
7170                    (sign_extend:<DWI>
7171                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7172                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7173                 (sign_extend:<DWI>
7174                    (mult:SWI248 (match_dup 1)
7175                                 (match_operand:SWI248 2
7176                                    "<immediate_operand>" "K,<i>")))))
7177    (set (match_operand:SWI248 0 "register_operand" "=r,r")
7178         (mult:SWI248 (match_dup 1) (match_dup 2)))]
7179   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7180    && CONST_INT_P (operands[2])
7181    && INTVAL (operands[2]) == INTVAL (operands[3])"
7182   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7183   [(set_attr "type" "imul")
7184    (set (attr "prefix_0f")
7185         (if_then_else
7186           (match_test "<MODE>mode == HImode")
7187             (const_string "0")
7188             (const_string "*")))
7189    (set (attr "athlon_decode")
7190         (cond [(eq_attr "cpu" "athlon")
7191                   (const_string "vector")
7192                (eq_attr "alternative" "1")
7193                   (const_string "vector")]
7194               (const_string "direct")))
7195    (set (attr "amdfam10_decode")
7196         (cond [(ior (match_test "<MODE>mode == HImode")
7197                     (match_operand 1 "memory_operand"))
7198                   (const_string "vector")]
7199               (const_string "direct")))
7200    (set (attr "bdver1_decode")
7201         (if_then_else
7202           (match_test "<MODE>mode == HImode")
7203             (const_string "double")
7204             (const_string "direct")))
7205    (set_attr "mode" "<MODE>")
7206    (set (attr "length_immediate")
7207         (cond [(eq_attr "alternative" "0")
7208                   (const_string "1")
7209                (match_test "<MODE_SIZE> == 8")
7210                   (const_string "4")]
7211               (const_string "<MODE_SIZE>")))])
7213 (define_expand "umulv<mode>4"
7214   [(parallel [(set (reg:CCO FLAGS_REG)
7215                    (eq:CCO (mult:<DWI>
7216                               (zero_extend:<DWI>
7217                                  (match_operand:SWI248 1
7218                                                       "nonimmediate_operand"))
7219                               (zero_extend:<DWI>
7220                                  (match_operand:SWI248 2
7221                                                       "nonimmediate_operand")))
7222                            (zero_extend:<DWI>
7223                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7224               (set (match_operand:SWI248 0 "register_operand")
7225                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7226               (clobber (match_scratch:SWI248 4))])
7227    (set (pc) (if_then_else
7228                (eq (reg:CCO FLAGS_REG) (const_int 0))
7229                (label_ref (match_operand 3))
7230                (pc)))]
7231   ""
7233   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7234     operands[1] = force_reg (<MODE>mode, operands[1]);
7237 (define_insn "*umulv<mode>4"
7238   [(set (reg:CCO FLAGS_REG)
7239         (eq:CCO (mult:<DWI>
7240                    (zero_extend:<DWI>
7241                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7242                    (zero_extend:<DWI>
7243                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7244                 (zero_extend:<DWI>
7245                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7246    (set (match_operand:SWI248 0 "register_operand" "=a")
7247         (mult:SWI248 (match_dup 1) (match_dup 2)))
7248    (clobber (match_scratch:SWI248 3 "=d"))]
7249   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7250   "mul{<imodesuffix>}\t%2"
7251   [(set_attr "type" "imul")
7252    (set_attr "length_immediate" "0")
7253    (set (attr "athlon_decode")
7254      (if_then_else (eq_attr "cpu" "athlon")
7255        (const_string "vector")
7256        (const_string "double")))
7257    (set_attr "amdfam10_decode" "double")
7258    (set_attr "bdver1_decode" "direct")
7259    (set_attr "mode" "<MODE>")])
7261 (define_expand "<u>mulvqi4"
7262   [(parallel [(set (reg:CCO FLAGS_REG)
7263                    (eq:CCO (mult:HI
7264                               (any_extend:HI
7265                                  (match_operand:QI 1 "nonimmediate_operand"))
7266                               (any_extend:HI
7267                                  (match_operand:QI 2 "nonimmediate_operand")))
7268                            (any_extend:HI
7269                               (mult:QI (match_dup 1) (match_dup 2)))))
7270               (set (match_operand:QI 0 "register_operand")
7271                    (mult:QI (match_dup 1) (match_dup 2)))])
7272    (set (pc) (if_then_else
7273                (eq (reg:CCO FLAGS_REG) (const_int 0))
7274                (label_ref (match_operand 3))
7275                (pc)))]
7276   "TARGET_QIMODE_MATH"
7278   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7279     operands[1] = force_reg (QImode, operands[1]);
7282 (define_insn "*<u>mulvqi4"
7283   [(set (reg:CCO FLAGS_REG)
7284         (eq:CCO (mult:HI
7285                    (any_extend:HI
7286                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7287                    (any_extend:HI
7288                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7289                 (any_extend:HI
7290                    (mult:QI (match_dup 1) (match_dup 2)))))
7291    (set (match_operand:QI 0 "register_operand" "=a")
7292         (mult:QI (match_dup 1) (match_dup 2)))]
7293   "TARGET_QIMODE_MATH
7294    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7295   "<sgnprefix>mul{b}\t%2"
7296   [(set_attr "type" "imul")
7297    (set_attr "length_immediate" "0")
7298    (set (attr "athlon_decode")
7299      (if_then_else (eq_attr "cpu" "athlon")
7300         (const_string "vector")
7301         (const_string "direct")))
7302    (set_attr "amdfam10_decode" "direct")
7303    (set_attr "bdver1_decode" "direct")
7304    (set_attr "mode" "QI")])
7306 (define_expand "<u>mul<mode><dwi>3"
7307   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7308                    (mult:<DWI>
7309                      (any_extend:<DWI>
7310                        (match_operand:DWIH 1 "nonimmediate_operand"))
7311                      (any_extend:<DWI>
7312                        (match_operand:DWIH 2 "register_operand"))))
7313               (clobber (reg:CC FLAGS_REG))])])
7315 (define_expand "<u>mulqihi3"
7316   [(parallel [(set (match_operand:HI 0 "register_operand")
7317                    (mult:HI
7318                      (any_extend:HI
7319                        (match_operand:QI 1 "nonimmediate_operand"))
7320                      (any_extend:HI
7321                        (match_operand:QI 2 "register_operand"))))
7322               (clobber (reg:CC FLAGS_REG))])]
7323   "TARGET_QIMODE_MATH")
7325 (define_insn "*bmi2_umul<mode><dwi>3_1"
7326   [(set (match_operand:DWIH 0 "register_operand" "=r")
7327         (mult:DWIH
7328           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7329           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7330    (set (match_operand:DWIH 1 "register_operand" "=r")
7331         (truncate:DWIH
7332           (lshiftrt:<DWI>
7333             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7334                         (zero_extend:<DWI> (match_dup 3)))
7335             (match_operand:QI 4 "const_int_operand" "n"))))]
7336   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7337    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7338   "mulx\t{%3, %0, %1|%1, %0, %3}"
7339   [(set_attr "type" "imulx")
7340    (set_attr "prefix" "vex")
7341    (set_attr "mode" "<MODE>")])
7343 (define_insn "*umul<mode><dwi>3_1"
7344   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7345         (mult:<DWI>
7346           (zero_extend:<DWI>
7347             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7348           (zero_extend:<DWI>
7349             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7350    (clobber (reg:CC FLAGS_REG))]
7351   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7352   "@
7353    #
7354    mul{<imodesuffix>}\t%2"
7355   [(set_attr "isa" "bmi2,*")
7356    (set_attr "type" "imulx,imul")
7357    (set_attr "length_immediate" "*,0")
7358    (set (attr "athlon_decode")
7359         (cond [(eq_attr "alternative" "1")
7360                  (if_then_else (eq_attr "cpu" "athlon")
7361                    (const_string "vector")
7362                    (const_string "double"))]
7363               (const_string "*")))
7364    (set_attr "amdfam10_decode" "*,double")
7365    (set_attr "bdver1_decode" "*,direct")
7366    (set_attr "prefix" "vex,orig")
7367    (set_attr "mode" "<MODE>")])
7369 ;; Convert mul to the mulx pattern to avoid flags dependency.
7370 (define_split
7371  [(set (match_operand:<DWI> 0 "register_operand")
7372        (mult:<DWI>
7373          (zero_extend:<DWI>
7374            (match_operand:DWIH 1 "register_operand"))
7375          (zero_extend:<DWI>
7376            (match_operand:DWIH 2 "nonimmediate_operand"))))
7377   (clobber (reg:CC FLAGS_REG))]
7378  "TARGET_BMI2 && reload_completed
7379   && REGNO (operands[1]) == DX_REG"
7380   [(parallel [(set (match_dup 3)
7381                    (mult:DWIH (match_dup 1) (match_dup 2)))
7382               (set (match_dup 4)
7383                    (truncate:DWIH
7384                      (lshiftrt:<DWI>
7385                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7386                                    (zero_extend:<DWI> (match_dup 2)))
7387                        (match_dup 5))))])]
7389   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7391   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7394 (define_insn "*mul<mode><dwi>3_1"
7395   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7396         (mult:<DWI>
7397           (sign_extend:<DWI>
7398             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7399           (sign_extend:<DWI>
7400             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7401    (clobber (reg:CC FLAGS_REG))]
7402   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7403   "imul{<imodesuffix>}\t%2"
7404   [(set_attr "type" "imul")
7405    (set_attr "length_immediate" "0")
7406    (set (attr "athlon_decode")
7407      (if_then_else (eq_attr "cpu" "athlon")
7408         (const_string "vector")
7409         (const_string "double")))
7410    (set_attr "amdfam10_decode" "double")
7411    (set_attr "bdver1_decode" "direct")
7412    (set_attr "mode" "<MODE>")])
7414 (define_insn "*<u>mulqihi3_1"
7415   [(set (match_operand:HI 0 "register_operand" "=a")
7416         (mult:HI
7417           (any_extend:HI
7418             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7419           (any_extend:HI
7420             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7421    (clobber (reg:CC FLAGS_REG))]
7422   "TARGET_QIMODE_MATH
7423    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7424   "<sgnprefix>mul{b}\t%2"
7425   [(set_attr "type" "imul")
7426    (set_attr "length_immediate" "0")
7427    (set (attr "athlon_decode")
7428      (if_then_else (eq_attr "cpu" "athlon")
7429         (const_string "vector")
7430         (const_string "direct")))
7431    (set_attr "amdfam10_decode" "direct")
7432    (set_attr "bdver1_decode" "direct")
7433    (set_attr "mode" "QI")])
7435 (define_expand "<s>mul<mode>3_highpart"
7436   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7437                    (truncate:SWI48
7438                      (lshiftrt:<DWI>
7439                        (mult:<DWI>
7440                          (any_extend:<DWI>
7441                            (match_operand:SWI48 1 "nonimmediate_operand"))
7442                          (any_extend:<DWI>
7443                            (match_operand:SWI48 2 "register_operand")))
7444                        (match_dup 3))))
7445               (clobber (match_scratch:SWI48 4))
7446               (clobber (reg:CC FLAGS_REG))])]
7447   ""
7448   "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7450 (define_insn "*<s>muldi3_highpart_1"
7451   [(set (match_operand:DI 0 "register_operand" "=d")
7452         (truncate:DI
7453           (lshiftrt:TI
7454             (mult:TI
7455               (any_extend:TI
7456                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7457               (any_extend:TI
7458                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7459             (const_int 64))))
7460    (clobber (match_scratch:DI 3 "=1"))
7461    (clobber (reg:CC FLAGS_REG))]
7462   "TARGET_64BIT
7463    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7464   "<sgnprefix>mul{q}\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 "double")))
7471    (set_attr "amdfam10_decode" "double")
7472    (set_attr "bdver1_decode" "direct")
7473    (set_attr "mode" "DI")])
7475 (define_insn "*<s>mulsi3_highpart_zext"
7476   [(set (match_operand:DI 0 "register_operand" "=d")
7477         (zero_extend:DI (truncate:SI
7478           (lshiftrt:DI
7479             (mult:DI (any_extend:DI
7480                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7481                      (any_extend:DI
7482                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7483             (const_int 32)))))
7484    (clobber (match_scratch:SI 3 "=1"))
7485    (clobber (reg:CC FLAGS_REG))]
7486   "TARGET_64BIT
7487    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7488   "<sgnprefix>mul{l}\t%2"
7489   [(set_attr "type" "imul")
7490    (set_attr "length_immediate" "0")
7491    (set (attr "athlon_decode")
7492      (if_then_else (eq_attr "cpu" "athlon")
7493         (const_string "vector")
7494         (const_string "double")))
7495    (set_attr "amdfam10_decode" "double")
7496    (set_attr "bdver1_decode" "direct")
7497    (set_attr "mode" "SI")])
7499 (define_insn "*<s>mulsi3_highpart_1"
7500   [(set (match_operand:SI 0 "register_operand" "=d")
7501         (truncate:SI
7502           (lshiftrt:DI
7503             (mult:DI
7504               (any_extend:DI
7505                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7506               (any_extend:DI
7507                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7508             (const_int 32))))
7509    (clobber (match_scratch:SI 3 "=1"))
7510    (clobber (reg:CC FLAGS_REG))]
7511   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7512   "<sgnprefix>mul{l}\t%2"
7513   [(set_attr "type" "imul")
7514    (set_attr "length_immediate" "0")
7515    (set (attr "athlon_decode")
7516      (if_then_else (eq_attr "cpu" "athlon")
7517         (const_string "vector")
7518         (const_string "double")))
7519    (set_attr "amdfam10_decode" "double")
7520    (set_attr "bdver1_decode" "direct")
7521    (set_attr "mode" "SI")])
7523 ;; The patterns that match these are at the end of this file.
7525 (define_expand "mulxf3"
7526   [(set (match_operand:XF 0 "register_operand")
7527         (mult:XF (match_operand:XF 1 "register_operand")
7528                  (match_operand:XF 2 "register_operand")))]
7529   "TARGET_80387")
7531 (define_expand "mul<mode>3"
7532   [(set (match_operand:MODEF 0 "register_operand")
7533         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7534                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7535   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7536     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7538 ;; Divide instructions
7540 ;; The patterns that match these are at the end of this file.
7542 (define_expand "divxf3"
7543   [(set (match_operand:XF 0 "register_operand")
7544         (div:XF (match_operand:XF 1 "register_operand")
7545                 (match_operand:XF 2 "register_operand")))]
7546   "TARGET_80387")
7548 (define_expand "div<mode>3"
7549   [(set (match_operand:MODEF 0 "register_operand")
7550         (div:MODEF (match_operand:MODEF 1 "register_operand")
7551                    (match_operand:MODEF 2 "nonimmediate_operand")))]
7552   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7553     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7555   if (<MODE>mode == SFmode
7556       && TARGET_SSE && TARGET_SSE_MATH
7557       && TARGET_RECIP_DIV
7558       && optimize_insn_for_speed_p ()
7559       && flag_finite_math_only && !flag_trapping_math
7560       && flag_unsafe_math_optimizations)
7561     {
7562       ix86_emit_swdivsf (operands[0], operands[1],
7563                          operands[2], SFmode);
7564       DONE;
7565     }
7568 ;; Divmod instructions.
7570 (define_expand "divmod<mode>4"
7571   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7572                    (div:SWIM248
7573                      (match_operand:SWIM248 1 "register_operand")
7574                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7575               (set (match_operand:SWIM248 3 "register_operand")
7576                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7577               (clobber (reg:CC FLAGS_REG))])])
7579 ;; Split with 8bit unsigned divide:
7580 ;;      if (dividend an divisor are in [0-255])
7581 ;;         use 8bit unsigned integer divide
7582 ;;       else
7583 ;;         use original integer divide
7584 (define_split
7585   [(set (match_operand:SWI48 0 "register_operand")
7586         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7587                     (match_operand:SWI48 3 "nonimmediate_operand")))
7588    (set (match_operand:SWI48 1 "register_operand")
7589         (mod:SWI48 (match_dup 2) (match_dup 3)))
7590    (clobber (reg:CC FLAGS_REG))]
7591   "TARGET_USE_8BIT_IDIV
7592    && TARGET_QIMODE_MATH
7593    && can_create_pseudo_p ()
7594    && !optimize_insn_for_size_p ()"
7595   [(const_int 0)]
7596   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7598 (define_insn_and_split "divmod<mode>4_1"
7599   [(set (match_operand:SWI48 0 "register_operand" "=a")
7600         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7601                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7602    (set (match_operand:SWI48 1 "register_operand" "=&d")
7603         (mod:SWI48 (match_dup 2) (match_dup 3)))
7604    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7605    (clobber (reg:CC FLAGS_REG))]
7606   ""
7607   "#"
7608   "reload_completed"
7609   [(parallel [(set (match_dup 1)
7610                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7611               (clobber (reg:CC FLAGS_REG))])
7612    (parallel [(set (match_dup 0)
7613                    (div:SWI48 (match_dup 2) (match_dup 3)))
7614               (set (match_dup 1)
7615                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7616               (use (match_dup 1))
7617               (clobber (reg:CC FLAGS_REG))])]
7619   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7621   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7622     operands[4] = operands[2];
7623   else
7624     {
7625       /* Avoid use of cltd in favor of a mov+shift.  */
7626       emit_move_insn (operands[1], operands[2]);
7627       operands[4] = operands[1];
7628     }
7630   [(set_attr "type" "multi")
7631    (set_attr "mode" "<MODE>")])
7633 (define_insn_and_split "*divmod<mode>4"
7634   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7635         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7636                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7637    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7638         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7639    (clobber (reg:CC FLAGS_REG))]
7640   ""
7641   "#"
7642   "reload_completed"
7643   [(parallel [(set (match_dup 1)
7644                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7645               (clobber (reg:CC FLAGS_REG))])
7646    (parallel [(set (match_dup 0)
7647                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7648               (set (match_dup 1)
7649                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7650               (use (match_dup 1))
7651               (clobber (reg:CC FLAGS_REG))])]
7653   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7655   if (<MODE>mode != HImode
7656       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7657     operands[4] = operands[2];
7658   else
7659     {
7660       /* Avoid use of cltd in favor of a mov+shift.  */
7661       emit_move_insn (operands[1], operands[2]);
7662       operands[4] = operands[1];
7663     }
7665   [(set_attr "type" "multi")
7666    (set_attr "mode" "<MODE>")])
7668 (define_insn "*divmod<mode>4_noext"
7669   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7670         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7671                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7672    (set (match_operand:SWIM248 1 "register_operand" "=d")
7673         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7674    (use (match_operand:SWIM248 4 "register_operand" "1"))
7675    (clobber (reg:CC FLAGS_REG))]
7676   ""
7677   "idiv{<imodesuffix>}\t%3"
7678   [(set_attr "type" "idiv")
7679    (set_attr "mode" "<MODE>")])
7681 (define_expand "divmodqi4"
7682   [(parallel [(set (match_operand:QI 0 "register_operand")
7683                    (div:QI
7684                      (match_operand:QI 1 "register_operand")
7685                      (match_operand:QI 2 "nonimmediate_operand")))
7686               (set (match_operand:QI 3 "register_operand")
7687                    (mod:QI (match_dup 1) (match_dup 2)))
7688               (clobber (reg:CC FLAGS_REG))])]
7689   "TARGET_QIMODE_MATH"
7691   rtx div, mod;
7692   rtx tmp0, tmp1;
7693   
7694   tmp0 = gen_reg_rtx (HImode);
7695   tmp1 = gen_reg_rtx (HImode);
7697   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
7698   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7699   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7701   /* Extract remainder from AH.  */
7702   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7703   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7704   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7706   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7707   set_unique_reg_note (insn, REG_EQUAL, mod);
7709   /* Extract quotient from AL.  */
7710   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7712   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7713   set_unique_reg_note (insn, REG_EQUAL, div);
7715   DONE;
7718 ;; Divide AX by r/m8, with result stored in
7719 ;; AL <- Quotient
7720 ;; AH <- Remainder
7721 ;; Change div/mod to HImode and extend the second argument to HImode
7722 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7723 ;; combine may fail.
7724 (define_insn "divmodhiqi3"
7725   [(set (match_operand:HI 0 "register_operand" "=a")
7726         (ior:HI
7727           (ashift:HI
7728             (zero_extend:HI
7729               (truncate:QI
7730                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7731                         (sign_extend:HI
7732                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7733             (const_int 8))
7734           (zero_extend:HI
7735             (truncate:QI
7736               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7737    (clobber (reg:CC FLAGS_REG))]
7738   "TARGET_QIMODE_MATH"
7739   "idiv{b}\t%2"
7740   [(set_attr "type" "idiv")
7741    (set_attr "mode" "QI")])
7743 (define_expand "udivmod<mode>4"
7744   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7745                    (udiv:SWIM248
7746                      (match_operand:SWIM248 1 "register_operand")
7747                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7748               (set (match_operand:SWIM248 3 "register_operand")
7749                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7750               (clobber (reg:CC FLAGS_REG))])])
7752 ;; Split with 8bit unsigned divide:
7753 ;;      if (dividend an divisor are in [0-255])
7754 ;;         use 8bit unsigned integer divide
7755 ;;       else
7756 ;;         use original integer divide
7757 (define_split
7758   [(set (match_operand:SWI48 0 "register_operand")
7759         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7760                     (match_operand:SWI48 3 "nonimmediate_operand")))
7761    (set (match_operand:SWI48 1 "register_operand")
7762         (umod:SWI48 (match_dup 2) (match_dup 3)))
7763    (clobber (reg:CC FLAGS_REG))]
7764   "TARGET_USE_8BIT_IDIV
7765    && TARGET_QIMODE_MATH
7766    && can_create_pseudo_p ()
7767    && !optimize_insn_for_size_p ()"
7768   [(const_int 0)]
7769   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7771 (define_insn_and_split "udivmod<mode>4_1"
7772   [(set (match_operand:SWI48 0 "register_operand" "=a")
7773         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7774                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7775    (set (match_operand:SWI48 1 "register_operand" "=&d")
7776         (umod:SWI48 (match_dup 2) (match_dup 3)))
7777    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7778    (clobber (reg:CC FLAGS_REG))]
7779   ""
7780   "#"
7781   "reload_completed"
7782   [(set (match_dup 1) (const_int 0))
7783    (parallel [(set (match_dup 0)
7784                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7785               (set (match_dup 1)
7786                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7787               (use (match_dup 1))
7788               (clobber (reg:CC FLAGS_REG))])]
7789   ""
7790   [(set_attr "type" "multi")
7791    (set_attr "mode" "<MODE>")])
7793 (define_insn_and_split "*udivmod<mode>4"
7794   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7795         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7796                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7797    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7798         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7799    (clobber (reg:CC FLAGS_REG))]
7800   ""
7801   "#"
7802   "reload_completed"
7803   [(set (match_dup 1) (const_int 0))
7804    (parallel [(set (match_dup 0)
7805                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7806               (set (match_dup 1)
7807                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7808               (use (match_dup 1))
7809               (clobber (reg:CC FLAGS_REG))])]
7810   ""
7811   [(set_attr "type" "multi")
7812    (set_attr "mode" "<MODE>")])
7814 ;; Optimize division or modulo by constant power of 2, if the constant
7815 ;; materializes only after expansion.
7816 (define_insn_and_split "*udivmod<mode>4_pow2"
7817   [(set (match_operand:SWI48 0 "register_operand" "=r")
7818         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7819                     (match_operand:SWI48 3 "const_int_operand" "n")))
7820    (set (match_operand:SWI48 1 "register_operand" "=r")
7821         (umod:SWI48 (match_dup 2) (match_dup 3)))
7822    (clobber (reg:CC FLAGS_REG))]
7823   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7824    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7825   "#"
7826   "&& 1"
7827   [(set (match_dup 1) (match_dup 2))
7828    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7829               (clobber (reg:CC FLAGS_REG))])
7830    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7831               (clobber (reg:CC FLAGS_REG))])]
7833   int v = exact_log2 (UINTVAL (operands[3]));
7834   operands[4] = GEN_INT (v);
7835   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7837   [(set_attr "type" "multi")
7838    (set_attr "mode" "<MODE>")])
7840 (define_insn "*udivmod<mode>4_noext"
7841   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7842         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7843                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7844    (set (match_operand:SWIM248 1 "register_operand" "=d")
7845         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7846    (use (match_operand:SWIM248 4 "register_operand" "1"))
7847    (clobber (reg:CC FLAGS_REG))]
7848   ""
7849   "div{<imodesuffix>}\t%3"
7850   [(set_attr "type" "idiv")
7851    (set_attr "mode" "<MODE>")])
7853 (define_expand "udivmodqi4"
7854   [(parallel [(set (match_operand:QI 0 "register_operand")
7855                    (udiv:QI
7856                      (match_operand:QI 1 "register_operand")
7857                      (match_operand:QI 2 "nonimmediate_operand")))
7858               (set (match_operand:QI 3 "register_operand")
7859                    (umod:QI (match_dup 1) (match_dup 2)))
7860               (clobber (reg:CC FLAGS_REG))])]
7861   "TARGET_QIMODE_MATH"
7863   rtx div, mod;
7864   rtx tmp0, tmp1;
7865   
7866   tmp0 = gen_reg_rtx (HImode);
7867   tmp1 = gen_reg_rtx (HImode);
7869   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
7870   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7871   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7873   /* Extract remainder from AH.  */
7874   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7875   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7876   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7878   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7879   set_unique_reg_note (insn, REG_EQUAL, mod);
7881   /* Extract quotient from AL.  */
7882   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7884   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7885   set_unique_reg_note (insn, REG_EQUAL, div);
7887   DONE;
7890 (define_insn "udivmodhiqi3"
7891   [(set (match_operand:HI 0 "register_operand" "=a")
7892         (ior:HI
7893           (ashift:HI
7894             (zero_extend:HI
7895               (truncate:QI
7896                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7897                         (zero_extend:HI
7898                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7899             (const_int 8))
7900           (zero_extend:HI
7901             (truncate:QI
7902               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7903    (clobber (reg:CC FLAGS_REG))]
7904   "TARGET_QIMODE_MATH"
7905   "div{b}\t%2"
7906   [(set_attr "type" "idiv")
7907    (set_attr "mode" "QI")])
7909 ;; We cannot use div/idiv for double division, because it causes
7910 ;; "division by zero" on the overflow and that's not what we expect
7911 ;; from truncate.  Because true (non truncating) double division is
7912 ;; never generated, we can't create this insn anyway.
7914 ;(define_insn ""
7915 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7916 ;       (truncate:SI
7917 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7918 ;                  (zero_extend:DI
7919 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7920 ;   (set (match_operand:SI 3 "register_operand" "=d")
7921 ;       (truncate:SI
7922 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7923 ;   (clobber (reg:CC FLAGS_REG))]
7924 ;  ""
7925 ;  "div{l}\t{%2, %0|%0, %2}"
7926 ;  [(set_attr "type" "idiv")])
7928 ;;- Logical AND instructions
7930 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7931 ;; Note that this excludes ah.
7933 (define_expand "testsi_ccno_1"
7934   [(set (reg:CCNO FLAGS_REG)
7935         (compare:CCNO
7936           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7937                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7938           (const_int 0)))])
7940 (define_expand "testqi_ccz_1"
7941   [(set (reg:CCZ FLAGS_REG)
7942         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7943                              (match_operand:QI 1 "nonmemory_operand"))
7944                  (const_int 0)))])
7946 (define_expand "testdi_ccno_1"
7947   [(set (reg:CCNO FLAGS_REG)
7948         (compare:CCNO
7949           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7950                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7951           (const_int 0)))]
7952   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7954 (define_insn "*testdi_1"
7955   [(set (reg FLAGS_REG)
7956         (compare
7957          (and:DI
7958           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7959           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7960          (const_int 0)))]
7961   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7962    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7963   "@
7964    test{l}\t{%k1, %k0|%k0, %k1}
7965    test{l}\t{%k1, %k0|%k0, %k1}
7966    test{q}\t{%1, %0|%0, %1}
7967    test{q}\t{%1, %0|%0, %1}
7968    test{q}\t{%1, %0|%0, %1}"
7969   [(set_attr "type" "test")
7970    (set_attr "modrm" "0,1,0,1,1")
7971    (set_attr "mode" "SI,SI,DI,DI,DI")])
7973 (define_insn "*testqi_1_maybe_si"
7974   [(set (reg FLAGS_REG)
7975         (compare
7976           (and:QI
7977             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7978             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7979           (const_int 0)))]
7980    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7981     && ix86_match_ccmode (insn,
7982                          CONST_INT_P (operands[1])
7983                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7985   if (which_alternative == 3)
7986     {
7987       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7988         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7989       return "test{l}\t{%1, %k0|%k0, %1}";
7990     }
7991   return "test{b}\t{%1, %0|%0, %1}";
7993   [(set_attr "type" "test")
7994    (set_attr "modrm" "0,1,1,1")
7995    (set_attr "mode" "QI,QI,QI,SI")
7996    (set_attr "pent_pair" "uv,np,uv,np")])
7998 (define_insn "*test<mode>_1"
7999   [(set (reg FLAGS_REG)
8000         (compare
8001          (and:SWI124
8002           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8003           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8004          (const_int 0)))]
8005   "ix86_match_ccmode (insn, CCNOmode)
8006    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8008   [(set_attr "type" "test")
8009    (set_attr "modrm" "0,1,1")
8010    (set_attr "mode" "<MODE>")
8011    (set_attr "pent_pair" "uv,np,uv")])
8013 (define_expand "testqi_ext_1_ccno"
8014   [(set (reg:CCNO FLAGS_REG)
8015         (compare:CCNO
8016           (and:QI
8017             (subreg:QI
8018               (zero_extract:SI (match_operand 0 "ext_register_operand")
8019                                (const_int 8)
8020                                (const_int 8)) 0)
8021               (match_operand 1 "const_int_operand"))
8022           (const_int 0)))])
8024 (define_insn "*testqi_ext_1"
8025   [(set (reg FLAGS_REG)
8026         (compare
8027           (and:QI
8028             (subreg:QI
8029               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8030                                (const_int 8)
8031                                (const_int 8)) 0)
8032             (match_operand:QI 1 "general_operand" "QnBc,m"))
8033           (const_int 0)))]
8034   "ix86_match_ccmode (insn, CCNOmode)"
8035   "test{b}\t{%1, %h0|%h0, %1}"
8036   [(set_attr "isa" "*,nox64")
8037    (set_attr "type" "test")
8038    (set_attr "mode" "QI")])
8040 (define_insn "*testqi_ext_2"
8041   [(set (reg FLAGS_REG)
8042         (compare
8043           (and:QI
8044             (subreg:QI
8045               (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8046                                (const_int 8)
8047                                (const_int 8)) 0)
8048             (subreg:QI
8049               (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8050                                (const_int 8)
8051                                (const_int 8)) 0))
8052           (const_int 0)))]
8053   "ix86_match_ccmode (insn, CCNOmode)"
8054   "test{b}\t{%h1, %h0|%h0, %h1}"
8055   [(set_attr "type" "test")
8056    (set_attr "mode" "QI")])
8058 ;; Combine likes to form bit extractions for some tests.  Humor it.
8059 (define_insn_and_split "*testqi_ext_3"
8060   [(set (match_operand 0 "flags_reg_operand")
8061         (match_operator 1 "compare_operator"
8062           [(zero_extract:SWI248
8063              (match_operand 2 "nonimmediate_operand" "rm")
8064              (match_operand 3 "const_int_operand" "n")
8065              (match_operand 4 "const_int_operand" "n"))
8066            (const_int 0)]))]
8067   "ix86_match_ccmode (insn, CCNOmode)
8068    && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8069        || GET_MODE (operands[2]) == SImode
8070        || GET_MODE (operands[2]) == HImode
8071        || GET_MODE (operands[2]) == QImode)
8072    /* Ensure that resulting mask is zero or sign extended operand.  */
8073    && INTVAL (operands[4]) >= 0
8074    && ((INTVAL (operands[3]) > 0
8075         && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8076        || (<MODE>mode == DImode
8077            && INTVAL (operands[3]) > 32
8078            && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8079   "#"
8080   "&& 1"
8081   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8083   rtx val = operands[2];
8084   HOST_WIDE_INT len = INTVAL (operands[3]);
8085   HOST_WIDE_INT pos = INTVAL (operands[4]);
8086   machine_mode mode = GET_MODE (val);
8088   if (SUBREG_P (val))
8089     {
8090       machine_mode submode = GET_MODE (SUBREG_REG (val));
8092       /* Narrow paradoxical subregs to prevent partial register stalls.  */
8093       if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8094           && GET_MODE_CLASS (submode) == MODE_INT)
8095         {
8096           val = SUBREG_REG (val);
8097           mode = submode;
8098         }
8099     }
8101   /* Small HImode tests can be converted to QImode.  */
8102   if (register_operand (val, HImode) && pos + len <= 8)
8103     {
8104       val = gen_lowpart (QImode, val);
8105       mode = QImode;
8106     }
8108   gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8110   wide_int mask
8111     = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8113   operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8116 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8117 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8118 ;; this is relatively important trick.
8119 ;; Do the conversion only post-reload to avoid limiting of the register class
8120 ;; to QI regs.
8121 (define_split
8122   [(set (match_operand 0 "flags_reg_operand")
8123         (match_operator 1 "compare_operator"
8124           [(and (match_operand 2 "QIreg_operand")
8125                 (match_operand 3 "const_int_operand"))
8126            (const_int 0)]))]
8127    "reload_completed
8128     && GET_MODE (operands[2]) != QImode
8129     && ((ix86_match_ccmode (insn, CCZmode)
8130          && !(INTVAL (operands[3]) & ~(255 << 8)))
8131         || (ix86_match_ccmode (insn, CCNOmode)
8132             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8133   [(set (match_dup 0)
8134         (match_op_dup 1
8135           [(and:QI
8136              (subreg:QI
8137                (zero_extract:SI (match_dup 2)
8138                                 (const_int 8)
8139                                 (const_int 8)) 0)
8140              (match_dup 3))
8141            (const_int 0)]))]
8143   operands[2] = gen_lowpart (SImode, operands[2]);
8144   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8147 (define_split
8148   [(set (match_operand 0 "flags_reg_operand")
8149         (match_operator 1 "compare_operator"
8150           [(and (match_operand 2 "nonimmediate_operand")
8151                 (match_operand 3 "const_int_operand"))
8152            (const_int 0)]))]
8153    "reload_completed
8154     && GET_MODE (operands[2]) != QImode
8155     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8156     && ((ix86_match_ccmode (insn, CCZmode)
8157          && !(INTVAL (operands[3]) & ~255))
8158         || (ix86_match_ccmode (insn, CCNOmode)
8159             && !(INTVAL (operands[3]) & ~127)))"
8160   [(set (match_dup 0)
8161         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8162                          (const_int 0)]))]
8164   operands[2] = gen_lowpart (QImode, operands[2]);
8165   operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8168 ;; %%% This used to optimize known byte-wide and operations to memory,
8169 ;; and sometimes to QImode registers.  If this is considered useful,
8170 ;; it should be done with splitters.
8172 (define_expand "and<mode>3"
8173   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8174         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8175                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8176   ""
8178   machine_mode mode = <MODE>mode;
8179   rtx (*insn) (rtx, rtx);
8181   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8182     {
8183       HOST_WIDE_INT ival = INTVAL (operands[2]);
8185       if (ival == (HOST_WIDE_INT) 0xffffffff)
8186         mode = SImode;
8187       else if (ival == 0xffff)
8188         mode = HImode;
8189       else if (ival == 0xff)
8190         mode = QImode;
8191       }
8193   if (mode == <MODE>mode)
8194     {
8195       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8196       DONE;
8197     }
8199   if (<MODE>mode == DImode)
8200     insn = (mode == SImode)
8201            ? gen_zero_extendsidi2
8202            : (mode == HImode)
8203            ? gen_zero_extendhidi2
8204            : gen_zero_extendqidi2;
8205   else if (<MODE>mode == SImode)
8206     insn = (mode == HImode)
8207            ? gen_zero_extendhisi2
8208            : gen_zero_extendqisi2;
8209   else if (<MODE>mode == HImode)
8210     insn = gen_zero_extendqihi2;
8211   else
8212     gcc_unreachable ();
8214   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8215   DONE;
8218 (define_insn_and_split "*anddi3_doubleword"
8219   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8220         (and:DI
8221          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8222          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8223    (clobber (reg:CC FLAGS_REG))]
8224   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8225    && ix86_binary_operator_ok (AND, DImode, operands)"
8226   "#"
8227   "&& reload_completed"
8228   [(const_int 0)]
8230   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8231   if (operands[2] == const0_rtx)
8232     {
8233       operands[1] = const0_rtx;
8234       ix86_expand_move (SImode, &operands[0]);
8235     }
8236   else if (operands[2] != constm1_rtx)
8237     ix86_expand_binary_operator (AND, SImode, &operands[0]);
8238   else if (operands[5] == constm1_rtx)
8239     emit_note (NOTE_INSN_DELETED);
8240   if (operands[5] == const0_rtx)
8241     {
8242       operands[4] = const0_rtx;
8243       ix86_expand_move (SImode, &operands[3]);
8244     }
8245   else if (operands[5] != constm1_rtx)
8246     ix86_expand_binary_operator (AND, SImode, &operands[3]);
8247   DONE;
8250 (define_insn "*anddi_1"
8251   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8252         (and:DI
8253          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8254          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8255    (clobber (reg:CC FLAGS_REG))]
8256   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8257   "@
8258    and{l}\t{%k2, %k0|%k0, %k2}
8259    and{q}\t{%2, %0|%0, %2}
8260    and{q}\t{%2, %0|%0, %2}
8261    #"
8262   [(set_attr "type" "alu,alu,alu,imovx")
8263    (set_attr "length_immediate" "*,*,*,0")
8264    (set (attr "prefix_rex")
8265      (if_then_else
8266        (and (eq_attr "type" "imovx")
8267             (and (match_test "INTVAL (operands[2]) == 0xff")
8268                  (match_operand 1 "ext_QIreg_operand")))
8269        (const_string "1")
8270        (const_string "*")))
8271    (set_attr "mode" "SI,DI,DI,SI")])
8273 (define_insn_and_split "*anddi_1_btr"
8274   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8275         (and:DI
8276          (match_operand:DI 1 "nonimmediate_operand" "%0")
8277          (match_operand:DI 2 "const_int_operand" "n")))
8278    (clobber (reg:CC FLAGS_REG))]
8279   "TARGET_64BIT && TARGET_USE_BT
8280    && ix86_binary_operator_ok (AND, DImode, operands)
8281    && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8282   "#"
8283   "&& reload_completed"
8284   [(parallel [(set (zero_extract:DI (match_dup 0)
8285                                     (const_int 1)
8286                                     (match_dup 3))
8287                    (const_int 0))
8288               (clobber (reg:CC FLAGS_REG))])]
8289   "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8290   [(set_attr "type" "alu1")
8291    (set_attr "prefix_0f" "1")
8292    (set_attr "znver1_decode" "double")
8293    (set_attr "mode" "DI")])
8295 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8296 (define_split
8297   [(set (match_operand:DI 0 "register_operand")
8298         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8299                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8300    (clobber (reg:CC FLAGS_REG))]
8301   "TARGET_64BIT"
8302   [(parallel [(set (match_dup 0)
8303                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8304               (clobber (reg:CC FLAGS_REG))])]
8305   "operands[2] = gen_lowpart (SImode, operands[2]);")
8307 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8308 (define_insn "*andsi_1_zext"
8309   [(set (match_operand:DI 0 "register_operand" "=r")
8310         (zero_extend:DI
8311           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8312                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8315   "and{l}\t{%2, %k0|%k0, %2}"
8316   [(set_attr "type" "alu")
8317    (set_attr "mode" "SI")])
8319 (define_insn "*and<mode>_1"
8320   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8321         (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8322                    (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8323    (clobber (reg:CC FLAGS_REG))]
8324   "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8325   "@
8326    and{<imodesuffix>}\t{%2, %0|%0, %2}
8327    and{<imodesuffix>}\t{%2, %0|%0, %2}
8328    #"
8329   [(set_attr "type" "alu,alu,imovx")
8330    (set_attr "length_immediate" "*,*,0")
8331    (set (attr "prefix_rex")
8332      (if_then_else
8333        (and (eq_attr "type" "imovx")
8334             (and (match_test "INTVAL (operands[2]) == 0xff")
8335                  (match_operand 1 "ext_QIreg_operand")))
8336        (const_string "1")
8337        (const_string "*")))
8338    (set_attr "mode" "<MODE>,<MODE>,SI")])
8340 (define_insn "*andqi_1"
8341   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8342         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8343                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8344    (clobber (reg:CC FLAGS_REG))]
8345   "ix86_binary_operator_ok (AND, QImode, operands)"
8346   "@
8347    and{b}\t{%2, %0|%0, %2}
8348    and{b}\t{%2, %0|%0, %2}
8349    and{l}\t{%k2, %k0|%k0, %k2}"
8350   [(set_attr "type" "alu")
8351    (set_attr "mode" "QI,QI,SI")
8352    ;; Potential partial reg stall on alternative 2.
8353    (set (attr "preferred_for_speed")
8354      (cond [(eq_attr "alternative" "2")
8355               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8356            (symbol_ref "true")))])
8358 (define_insn "*andqi_1_slp"
8359   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8360         (and:QI (match_dup 0)
8361                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8362    (clobber (reg:CC FLAGS_REG))]
8363   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8364    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8365   "and{b}\t{%1, %0|%0, %1}"
8366   [(set_attr "type" "alu1")
8367    (set_attr "mode" "QI")])
8369 (define_split
8370   [(set (match_operand:SWI248 0 "register_operand")
8371         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8372                     (match_operand:SWI248 2 "const_int_operand")))
8373    (clobber (reg:CC FLAGS_REG))]
8374   "reload_completed
8375    && (!REG_P (operands[1])
8376        || REGNO (operands[0]) != REGNO (operands[1]))"
8377   [(const_int 0)]
8379   HOST_WIDE_INT ival = INTVAL (operands[2]);
8380   machine_mode mode;
8381   rtx (*insn) (rtx, rtx);
8383   if (ival == (HOST_WIDE_INT) 0xffffffff)
8384     mode = SImode;
8385   else if (ival == 0xffff)
8386     mode = HImode;
8387   else
8388     {
8389       gcc_assert (ival == 0xff);
8390       mode = QImode;
8391     }
8393   if (<MODE>mode == DImode)
8394     insn = (mode == SImode)
8395            ? gen_zero_extendsidi2
8396            : (mode == HImode)
8397            ? gen_zero_extendhidi2
8398            : gen_zero_extendqidi2;
8399   else
8400     {
8401       if (<MODE>mode != SImode)
8402         /* Zero extend to SImode to avoid partial register stalls.  */
8403         operands[0] = gen_lowpart (SImode, operands[0]);
8405       insn = (mode == HImode)
8406              ? gen_zero_extendhisi2
8407              : gen_zero_extendqisi2;
8408     }
8409   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8410   DONE;
8413 (define_split
8414   [(set (match_operand:SWI48 0 "register_operand")
8415         (and:SWI48 (match_dup 0)
8416                    (const_int -65536)))
8417    (clobber (reg:CC FLAGS_REG))]
8418   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8419     || optimize_function_for_size_p (cfun)"
8420   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8421   "operands[1] = gen_lowpart (HImode, operands[0]);")
8423 (define_split
8424   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8425         (and:SWI248 (match_dup 0)
8426                     (const_int -256)))
8427    (clobber (reg:CC FLAGS_REG))]
8428   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8429    && reload_completed"
8430   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8431   "operands[1] = gen_lowpart (QImode, operands[0]);")
8433 (define_split
8434   [(set (match_operand:SWI248 0 "QIreg_operand")
8435         (and:SWI248 (match_dup 0)
8436                     (const_int -65281)))
8437    (clobber (reg:CC FLAGS_REG))]
8438   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8439    && reload_completed"
8440   [(parallel
8441      [(set (zero_extract:SI (match_dup 0)
8442                             (const_int 8)
8443                             (const_int 8))
8444            (subreg:SI
8445              (xor:QI
8446                (subreg:QI
8447                  (zero_extract:SI (match_dup 0)
8448                                   (const_int 8)
8449                                   (const_int 8)) 0)
8450                (subreg:QI
8451                  (zero_extract:SI (match_dup 0)
8452                                   (const_int 8)
8453                                   (const_int 8)) 0)) 0))
8454       (clobber (reg:CC FLAGS_REG))])]
8455   "operands[0] = gen_lowpart (SImode, operands[0]);")
8457 (define_insn "*anddi_2"
8458   [(set (reg FLAGS_REG)
8459         (compare
8460          (and:DI
8461           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8462           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8463          (const_int 0)))
8464    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8465         (and:DI (match_dup 1) (match_dup 2)))]
8466   "TARGET_64BIT
8467    && ix86_match_ccmode
8468         (insn,
8469          /* If we are going to emit andl instead of andq, and the operands[2]
8470             constant might have the SImode sign bit set, make sure the sign
8471             flag isn't tested, because the instruction will set the sign flag
8472             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8473             conservatively assume it might have bit 31 set.  */
8474          (satisfies_constraint_Z (operands[2])
8475           && (!CONST_INT_P (operands[2])
8476               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8477          ? CCZmode : CCNOmode)
8478    && ix86_binary_operator_ok (AND, DImode, operands)"
8479   "@
8480    and{l}\t{%k2, %k0|%k0, %k2}
8481    and{q}\t{%2, %0|%0, %2}
8482    and{q}\t{%2, %0|%0, %2}"
8483   [(set_attr "type" "alu")
8484    (set_attr "mode" "SI,DI,DI")])
8486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8487 (define_insn "*andsi_2_zext"
8488   [(set (reg FLAGS_REG)
8489         (compare (and:SI
8490                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8491                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8492                  (const_int 0)))
8493    (set (match_operand:DI 0 "register_operand" "=r")
8494         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8495   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8496    && ix86_binary_operator_ok (AND, SImode, operands)"
8497   "and{l}\t{%2, %k0|%k0, %2}"
8498   [(set_attr "type" "alu")
8499    (set_attr "mode" "SI")])
8501 (define_insn "*andqi_2_maybe_si"
8502   [(set (reg FLAGS_REG)
8503         (compare (and:QI
8504                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8505                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8506                  (const_int 0)))
8507    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8508         (and:QI (match_dup 1) (match_dup 2)))]
8509   "ix86_binary_operator_ok (AND, QImode, operands)
8510    && ix86_match_ccmode (insn,
8511                          CONST_INT_P (operands[2])
8512                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8514   if (which_alternative == 2)
8515     {
8516       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8517         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8518       return "and{l}\t{%2, %k0|%k0, %2}";
8519     }
8520   return "and{b}\t{%2, %0|%0, %2}";
8522   [(set_attr "type" "alu")
8523    (set_attr "mode" "QI,QI,SI")])
8525 (define_insn "*and<mode>_2"
8526   [(set (reg FLAGS_REG)
8527         (compare (and:SWI124
8528                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8529                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8530                  (const_int 0)))
8531    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8532         (and:SWI124 (match_dup 1) (match_dup 2)))]
8533   "ix86_match_ccmode (insn, CCNOmode)
8534    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8535   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8536   [(set_attr "type" "alu")
8537    (set_attr "mode" "<MODE>")])
8539 (define_insn "*andqi_2_slp"
8540   [(set (reg FLAGS_REG)
8541         (compare (and:QI
8542                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8543                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8544                  (const_int 0)))
8545    (set (strict_low_part (match_dup 0))
8546         (and:QI (match_dup 0) (match_dup 1)))]
8547   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8548    && ix86_match_ccmode (insn, CCNOmode)
8549    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8550   "and{b}\t{%1, %0|%0, %1}"
8551   [(set_attr "type" "alu1")
8552    (set_attr "mode" "QI")])
8554 (define_insn "andqi_ext_1"
8555   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8556                          (const_int 8)
8557                          (const_int 8))
8558         (subreg:SI
8559           (and:QI
8560             (subreg:QI
8561               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8562                                (const_int 8)
8563                                (const_int 8)) 0)
8564             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8565    (clobber (reg:CC FLAGS_REG))]
8566   ""
8567   "and{b}\t{%2, %h0|%h0, %2}"
8568   [(set_attr "isa" "*,nox64")
8569    (set_attr "type" "alu")
8570    (set_attr "mode" "QI")])
8572 ;; Generated by peephole translating test to and.  This shows up
8573 ;; often in fp comparisons.
8574 (define_insn "*andqi_ext_1_cc"
8575   [(set (reg FLAGS_REG)
8576         (compare
8577           (and:QI
8578             (subreg:QI
8579               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8580                                (const_int 8)
8581                                (const_int 8)) 0)
8582             (match_operand:QI 2 "general_operand" "QnBc,m"))
8583           (const_int 0)))
8584    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8585                          (const_int 8)
8586                          (const_int 8))
8587         (subreg:SI
8588           (and:QI
8589             (subreg:QI
8590               (zero_extract:SI (match_dup 1)
8591                                (const_int 8)
8592                                (const_int 8)) 0)
8593             (match_dup 2)) 0))]
8594   "ix86_match_ccmode (insn, CCNOmode)"
8595   "and{b}\t{%2, %h0|%h0, %2}"
8596   [(set_attr "isa" "*,nox64")
8597    (set_attr "type" "alu")
8598    (set_attr "mode" "QI")])
8600 (define_insn "*andqi_ext_2"
8601   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8602                          (const_int 8)
8603                          (const_int 8))
8604         (subreg:SI
8605           (and:QI
8606             (subreg:QI
8607               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8608                                (const_int 8)
8609                                (const_int 8)) 0)
8610             (subreg:QI
8611               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8612                                (const_int 8)
8613                                (const_int 8)) 0)) 0))
8614    (clobber (reg:CC FLAGS_REG))]
8615   ""
8616   "and{b}\t{%h2, %h0|%h0, %h2}"
8617   [(set_attr "type" "alu")
8618    (set_attr "mode" "QI")])
8620 ;; Convert wide AND instructions with immediate operand to shorter QImode
8621 ;; equivalents when possible.
8622 ;; Don't do the splitting with memory operands, since it introduces risk
8623 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8624 ;; for size, but that can (should?) be handled by generic code instead.
8625 (define_split
8626   [(set (match_operand:SWI248 0 "QIreg_operand")
8627         (and:SWI248 (match_operand:SWI248 1 "register_operand")
8628                     (match_operand:SWI248 2 "const_int_operand")))
8629    (clobber (reg:CC FLAGS_REG))]
8630    "reload_completed
8631     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8632     && !(~INTVAL (operands[2]) & ~(255 << 8))"
8633   [(parallel
8634      [(set (zero_extract:SI (match_dup 0)
8635                             (const_int 8)
8636                             (const_int 8))
8637            (subreg:SI
8638              (and:QI
8639                (subreg:QI
8640                  (zero_extract:SI (match_dup 1)
8641                                   (const_int 8)
8642                                   (const_int 8)) 0)
8643                (match_dup 2)) 0))
8644       (clobber (reg:CC FLAGS_REG))])]
8646   operands[0] = gen_lowpart (SImode, operands[0]);
8647   operands[1] = gen_lowpart (SImode, operands[1]);
8648   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8651 ;; Since AND can be encoded with sign extended immediate, this is only
8652 ;; profitable when 7th bit is not set.
8653 (define_split
8654   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8655         (and:SWI248 (match_operand:SWI248 1 "general_operand")
8656                     (match_operand:SWI248 2 "const_int_operand")))
8657    (clobber (reg:CC FLAGS_REG))]
8658    "reload_completed
8659     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8660     && !(~INTVAL (operands[2]) & ~255)
8661     && !(INTVAL (operands[2]) & 128)"
8662   [(parallel [(set (strict_low_part (match_dup 0))
8663                    (and:QI (match_dup 1)
8664                            (match_dup 2)))
8665               (clobber (reg:CC FLAGS_REG))])]
8667   operands[0] = gen_lowpart (QImode, operands[0]);
8668   operands[1] = gen_lowpart (QImode, operands[1]);
8669   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
8672 (define_insn "*andndi3_doubleword"
8673   [(set (match_operand:DI 0 "register_operand" "=r,&r")
8674         (and:DI
8675           (not:DI (match_operand:DI 1 "register_operand" "r,0"))
8676           (match_operand:DI 2 "nonimmediate_operand" "rm,rm")))
8677    (clobber (reg:CC FLAGS_REG))]
8678   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
8679   "#"
8680   [(set_attr "isa" "bmi,*")])
8682 (define_split
8683   [(set (match_operand:DI 0 "register_operand")
8684         (and:DI
8685           (not:DI (match_operand:DI 1 "register_operand"))
8686           (match_operand:DI 2 "nonimmediate_operand")))
8687    (clobber (reg:CC FLAGS_REG))]
8688   "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8689    && reload_completed"
8690   [(parallel [(set (match_dup 0)
8691                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8692               (clobber (reg:CC FLAGS_REG))])
8693    (parallel [(set (match_dup 3)
8694                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8695               (clobber (reg:CC FLAGS_REG))])]
8696   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8698 (define_split
8699   [(set (match_operand:DI 0 "register_operand")
8700         (and:DI
8701           (not:DI (match_dup 0))
8702           (match_operand:DI 1 "nonimmediate_operand")))
8703    (clobber (reg:CC FLAGS_REG))]
8704   "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8705    && reload_completed"
8706   [(set (match_dup 0) (not:SI (match_dup 0)))
8707    (parallel [(set (match_dup 0)
8708                    (and:SI (match_dup 0) (match_dup 1)))
8709               (clobber (reg:CC FLAGS_REG))])
8710    (set (match_dup 2) (not:SI (match_dup 2)))
8711    (parallel [(set (match_dup 2)
8712                    (and:SI (match_dup 2) (match_dup 3)))
8713               (clobber (reg:CC FLAGS_REG))])]
8714   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
8716 (define_insn "*andn<mode>_1"
8717   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8718         (and:SWI48
8719           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8720           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8721    (clobber (reg:CC FLAGS_REG))]
8722   "TARGET_BMI"
8723   "andn\t{%2, %1, %0|%0, %1, %2}"
8724   [(set_attr "type" "bitmanip")
8725    (set_attr "btver2_decode" "direct, double")
8726    (set_attr "mode" "<MODE>")])
8728 (define_insn "*andn<mode>_1"
8729   [(set (match_operand:SWI12 0 "register_operand" "=r")
8730         (and:SWI12
8731           (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8732           (match_operand:SWI12 2 "register_operand" "r")))
8733    (clobber (reg:CC FLAGS_REG))]
8734   "TARGET_BMI"
8735   "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8736   [(set_attr "type" "bitmanip")
8737    (set_attr "btver2_decode" "direct")
8738    (set_attr "mode" "SI")])
8740 (define_insn "*andn_<mode>_ccno"
8741   [(set (reg FLAGS_REG)
8742         (compare
8743           (and:SWI48
8744             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8745             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8746           (const_int 0)))
8747    (clobber (match_scratch:SWI48 0 "=r,r"))]
8748   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8749   "andn\t{%2, %1, %0|%0, %1, %2}"
8750   [(set_attr "type" "bitmanip")
8751    (set_attr "btver2_decode" "direct, double")
8752    (set_attr "mode" "<MODE>")])
8754 ;; Logical inclusive and exclusive OR instructions
8756 ;; %%% This used to optimize known byte-wide and operations to memory.
8757 ;; If this is considered useful, it should be done with splitters.
8759 (define_expand "<code><mode>3"
8760   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8761         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8762                              (match_operand:SWIM1248x 2 "<general_operand>")))]
8763   ""
8764   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8766 (define_insn_and_split "*<code>di3_doubleword"
8767   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8768         (any_or:DI
8769          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8770          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8771    (clobber (reg:CC FLAGS_REG))]
8772   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8773    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8774   "#"
8775   "&& reload_completed"
8776   [(const_int 0)]
8778   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8779   if (operands[2] == constm1_rtx)
8780     {
8781       if (<CODE> == IOR)
8782         {
8783           operands[1] = constm1_rtx;
8784           ix86_expand_move (SImode, &operands[0]);
8785         }
8786       else
8787         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8788     }
8789   else if (operands[2] != const0_rtx)
8790     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8791   else if (operands[5] == const0_rtx)
8792     emit_note (NOTE_INSN_DELETED);
8793   if (operands[5] == constm1_rtx)
8794     {
8795       if (<CODE> == IOR)
8796         {
8797           operands[4] = constm1_rtx;
8798           ix86_expand_move (SImode, &operands[3]);
8799         }
8800       else
8801         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8802     }
8803   else if (operands[5] != const0_rtx)
8804     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8805   DONE;
8808 (define_insn "*<code><mode>_1"
8809   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8810         (any_or:SWI248
8811          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8812          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8813    (clobber (reg:CC FLAGS_REG))]
8814   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8815   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8816   [(set_attr "type" "alu")
8817    (set_attr "mode" "<MODE>")])
8819 (define_insn_and_split "*iordi_1_bts"
8820   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8821         (ior:DI
8822          (match_operand:DI 1 "nonimmediate_operand" "%0")
8823          (match_operand:DI 2 "const_int_operand" "n")))
8824    (clobber (reg:CC FLAGS_REG))]
8825   "TARGET_64BIT && TARGET_USE_BT
8826    && ix86_binary_operator_ok (IOR, DImode, operands)
8827    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
8828   "#"
8829   "&& reload_completed"
8830   [(parallel [(set (zero_extract:DI (match_dup 0)
8831                                     (const_int 1)
8832                                     (match_dup 3))
8833                    (const_int 1))
8834               (clobber (reg:CC FLAGS_REG))])]
8835   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
8836   [(set_attr "type" "alu1")
8837    (set_attr "prefix_0f" "1")
8838    (set_attr "znver1_decode" "double")
8839    (set_attr "mode" "DI")])
8841 (define_insn_and_split "*xordi_1_btc"
8842   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8843         (xor:DI
8844          (match_operand:DI 1 "nonimmediate_operand" "%0")
8845          (match_operand:DI 2 "const_int_operand" "n")))
8846    (clobber (reg:CC FLAGS_REG))]
8847   "TARGET_64BIT && TARGET_USE_BT
8848    && ix86_binary_operator_ok (XOR, DImode, operands)
8849    && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
8850   "#"
8851   "&& reload_completed"
8852   [(parallel [(set (zero_extract:DI (match_dup 0)
8853                                     (const_int 1)
8854                                     (match_dup 3))
8855                    (not:DI (zero_extract:DI (match_dup 0)
8856                                             (const_int 1)
8857                                             (match_dup 3))))
8858               (clobber (reg:CC FLAGS_REG))])]
8859   "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
8860   [(set_attr "type" "alu1")
8861    (set_attr "prefix_0f" "1")
8862    (set_attr "znver1_decode" "double")
8863    (set_attr "mode" "DI")])
8865 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8866 (define_insn "*<code>si_1_zext"
8867   [(set (match_operand:DI 0 "register_operand" "=r")
8868         (zero_extend:DI
8869          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8870                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8871    (clobber (reg:CC FLAGS_REG))]
8872   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8873   "<logic>{l}\t{%2, %k0|%k0, %2}"
8874   [(set_attr "type" "alu")
8875    (set_attr "mode" "SI")])
8877 (define_insn "*<code>si_1_zext_imm"
8878   [(set (match_operand:DI 0 "register_operand" "=r")
8879         (any_or:DI
8880          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8881          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8882    (clobber (reg:CC FLAGS_REG))]
8883   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8884   "<logic>{l}\t{%2, %k0|%k0, %2}"
8885   [(set_attr "type" "alu")
8886    (set_attr "mode" "SI")])
8888 (define_insn "*<code>qi_1"
8889   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8890         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8891                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8892    (clobber (reg:CC FLAGS_REG))]
8893   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8894   "@
8895    <logic>{b}\t{%2, %0|%0, %2}
8896    <logic>{b}\t{%2, %0|%0, %2}
8897    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8898   [(set_attr "type" "alu")
8899    (set_attr "mode" "QI,QI,SI")
8900    ;; Potential partial reg stall on alternative 2.
8901    (set (attr "preferred_for_speed")
8902      (cond [(eq_attr "alternative" "2")
8903               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8904            (symbol_ref "true")))])
8906 (define_insn "*<code>qi_1_slp"
8907   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8908         (any_or:QI (match_dup 0)
8909                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8910    (clobber (reg:CC FLAGS_REG))]
8911   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8912    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8913   "<logic>{b}\t{%1, %0|%0, %1}"
8914   [(set_attr "type" "alu1")
8915    (set_attr "mode" "QI")])
8917 (define_insn "*<code><mode>_2"
8918   [(set (reg FLAGS_REG)
8919         (compare (any_or:SWI
8920                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8921                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8922                  (const_int 0)))
8923    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8924         (any_or:SWI (match_dup 1) (match_dup 2)))]
8925   "ix86_match_ccmode (insn, CCNOmode)
8926    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8927   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8928   [(set_attr "type" "alu")
8929    (set_attr "mode" "<MODE>")])
8931 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8932 ;; ??? Special case for immediate operand is missing - it is tricky.
8933 (define_insn "*<code>si_2_zext"
8934   [(set (reg FLAGS_REG)
8935         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8936                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8937                  (const_int 0)))
8938    (set (match_operand:DI 0 "register_operand" "=r")
8939         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8940   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8941    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8942   "<logic>{l}\t{%2, %k0|%k0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "mode" "SI")])
8946 (define_insn "*<code>si_2_zext_imm"
8947   [(set (reg FLAGS_REG)
8948         (compare (any_or:SI
8949                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8950                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8951                  (const_int 0)))
8952    (set (match_operand:DI 0 "register_operand" "=r")
8953         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8954   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8955    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8956   "<logic>{l}\t{%2, %k0|%k0, %2}"
8957   [(set_attr "type" "alu")
8958    (set_attr "mode" "SI")])
8960 (define_insn "*<code>qi_2_slp"
8961   [(set (reg FLAGS_REG)
8962         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8963                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8964                  (const_int 0)))
8965    (set (strict_low_part (match_dup 0))
8966         (any_or:QI (match_dup 0) (match_dup 1)))]
8967   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8968    && ix86_match_ccmode (insn, CCNOmode)
8969    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8970   "<logic>{b}\t{%1, %0|%0, %1}"
8971   [(set_attr "type" "alu1")
8972    (set_attr "mode" "QI")])
8974 (define_insn "*<code><mode>_3"
8975   [(set (reg FLAGS_REG)
8976         (compare (any_or:SWI
8977                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8978                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8979                  (const_int 0)))
8980    (clobber (match_scratch:SWI 0 "=<r>"))]
8981   "ix86_match_ccmode (insn, CCNOmode)
8982    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8983   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "<MODE>")])
8987 (define_insn "*<code>qi_ext_1"
8988   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8989                          (const_int 8)
8990                          (const_int 8))
8991         (subreg:SI
8992           (any_or:QI
8993             (subreg:QI
8994               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8995                                (const_int 8)
8996                                (const_int 8)) 0)
8997             (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8998    (clobber (reg:CC FLAGS_REG))]
8999   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9000   "<logic>{b}\t{%2, %h0|%h0, %2}"
9001   [(set_attr "isa" "*,nox64")
9002    (set_attr "type" "alu")
9003    (set_attr "mode" "QI")])
9005 (define_insn "*<code>qi_ext_2"
9006   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9007                          (const_int 8)
9008                          (const_int 8))
9009         (subreg:SI
9010           (any_or:QI
9011             (subreg:QI
9012               (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9013                                (const_int 8)
9014                                (const_int 8)) 0)
9015             (subreg:QI
9016               (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9017                                (const_int 8)
9018                                (const_int 8)) 0)) 0))
9019    (clobber (reg:CC FLAGS_REG))]
9020   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9021   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9022   [(set_attr "type" "alu")
9023    (set_attr "mode" "QI")])
9025 ;; Convert wide OR instructions with immediate operand to shorter QImode
9026 ;; equivalents when possible.
9027 ;; Don't do the splitting with memory operands, since it introduces risk
9028 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9029 ;; for size, but that can (should?) be handled by generic code instead.
9030 (define_split
9031   [(set (match_operand:SWI248 0 "QIreg_operand")
9032         (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9033                        (match_operand:SWI248 2 "const_int_operand")))
9034    (clobber (reg:CC FLAGS_REG))]
9035    "reload_completed
9036     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9037     && !(INTVAL (operands[2]) & ~(255 << 8))"
9038   [(parallel
9039      [(set (zero_extract:SI (match_dup 0)
9040                             (const_int 8)
9041                             (const_int 8))
9042            (subreg:SI
9043              (any_or:QI
9044                (subreg:QI
9045                  (zero_extract:SI (match_dup 1)
9046                                   (const_int 8)
9047                                   (const_int 8)) 0)
9048                (match_dup 2)) 0))
9049       (clobber (reg:CC FLAGS_REG))])]
9051   operands[0] = gen_lowpart (SImode, operands[0]);
9052   operands[1] = gen_lowpart (SImode, operands[1]);
9053   operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9056 ;; Since OR can be encoded with sign extended immediate, this is only
9057 ;; profitable when 7th bit is set.
9058 (define_split
9059   [(set (match_operand:SWI248 0 "any_QIreg_operand")
9060         (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9061                        (match_operand:SWI248 2 "const_int_operand")))
9062    (clobber (reg:CC FLAGS_REG))]
9063    "reload_completed
9064     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9065     && !(INTVAL (operands[2]) & ~255)
9066     && (INTVAL (operands[2]) & 128)"
9067   [(parallel [(set (strict_low_part (match_dup 0))
9068                    (any_or:QI (match_dup 1)
9069                               (match_dup 2)))
9070               (clobber (reg:CC FLAGS_REG))])]
9072   operands[0] = gen_lowpart (QImode, operands[0]);
9073   operands[1] = gen_lowpart (QImode, operands[1]);
9074   operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9077 (define_expand "xorqi_ext_1_cc"
9078   [(parallel [
9079      (set (reg:CCNO FLAGS_REG)
9080           (compare:CCNO
9081             (xor:QI
9082               (subreg:QI
9083                 (zero_extract:SI (match_operand 1 "ext_register_operand")
9084                                  (const_int 8)
9085                                  (const_int 8)) 0)
9086               (match_operand 2 "const_int_operand"))
9087             (const_int 0)))
9088      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9089                            (const_int 8)
9090                            (const_int 8))
9091           (subreg:SI
9092             (xor:QI
9093               (subreg:QI
9094                 (zero_extract:SI (match_dup 1)
9095                                  (const_int 8)
9096                                  (const_int 8)) 0)
9097             (match_dup 2)) 0))])])
9099 (define_insn "*xorqi_ext_1_cc"
9100   [(set (reg FLAGS_REG)
9101         (compare
9102           (xor:QI
9103             (subreg:QI
9104               (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9105                                (const_int 8)
9106                                (const_int 8)) 0)
9107             (match_operand:QI 2 "general_operand" "QnBc,m"))
9108           (const_int 0)))
9109    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9110                          (const_int 8)
9111                          (const_int 8))
9112         (subreg:SI
9113           (xor:QI
9114             (subreg:QI
9115               (zero_extract:SI (match_dup 1)
9116                                (const_int 8)
9117                                (const_int 8)) 0)
9118           (match_dup 2)) 0))]
9119   "ix86_match_ccmode (insn, CCNOmode)"
9120   "xor{b}\t{%2, %h0|%h0, %2}"
9121   [(set_attr "isa" "*,nox64")
9122    (set_attr "type" "alu")
9123    (set_attr "mode" "QI")])
9125 ;; Negation instructions
9127 (define_expand "neg<mode>2"
9128   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9129         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9130   ""
9131   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9133 (define_insn_and_split "*neg<dwi>2_doubleword"
9134   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9135         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9136    (clobber (reg:CC FLAGS_REG))]
9137   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9138   "#"
9139   "reload_completed"
9140   [(parallel
9141     [(set (reg:CCZ FLAGS_REG)
9142           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9143      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9144    (parallel
9145     [(set (match_dup 2)
9146           (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9147                                 (match_dup 3))
9148                      (const_int 0)))
9149      (clobber (reg:CC FLAGS_REG))])
9150    (parallel
9151     [(set (match_dup 2)
9152           (neg:DWIH (match_dup 2)))
9153      (clobber (reg:CC FLAGS_REG))])]
9154   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9156 (define_insn "*neg<mode>2_1"
9157   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9158         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9159    (clobber (reg:CC FLAGS_REG))]
9160   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9161   "neg{<imodesuffix>}\t%0"
9162   [(set_attr "type" "negnot")
9163    (set_attr "mode" "<MODE>")])
9165 ;; Combine is quite creative about this pattern.
9166 (define_insn "*negsi2_1_zext"
9167   [(set (match_operand:DI 0 "register_operand" "=r")
9168         (lshiftrt:DI
9169           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9170                              (const_int 32)))
9171         (const_int 32)))
9172    (clobber (reg:CC FLAGS_REG))]
9173   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9174   "neg{l}\t%k0"
9175   [(set_attr "type" "negnot")
9176    (set_attr "mode" "SI")])
9178 ;; The problem with neg is that it does not perform (compare x 0),
9179 ;; it really performs (compare 0 x), which leaves us with the zero
9180 ;; flag being the only useful item.
9182 (define_insn "*neg<mode>2_cmpz"
9183   [(set (reg:CCZ FLAGS_REG)
9184         (compare:CCZ
9185           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9186                    (const_int 0)))
9187    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9188         (neg:SWI (match_dup 1)))]
9189   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9190   "neg{<imodesuffix>}\t%0"
9191   [(set_attr "type" "negnot")
9192    (set_attr "mode" "<MODE>")])
9194 (define_insn "*negsi2_cmpz_zext"
9195   [(set (reg:CCZ FLAGS_REG)
9196         (compare:CCZ
9197           (lshiftrt:DI
9198             (neg:DI (ashift:DI
9199                       (match_operand:DI 1 "register_operand" "0")
9200                       (const_int 32)))
9201             (const_int 32))
9202           (const_int 0)))
9203    (set (match_operand:DI 0 "register_operand" "=r")
9204         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9205                                         (const_int 32)))
9206                      (const_int 32)))]
9207   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9208   "neg{l}\t%k0"
9209   [(set_attr "type" "negnot")
9210    (set_attr "mode" "SI")])
9212 ;; Negate with jump on overflow.
9213 (define_expand "negv<mode>3"
9214   [(parallel [(set (reg:CCO FLAGS_REG)
9215                    (ne:CCO (match_operand:SWI 1 "register_operand")
9216                            (match_dup 3)))
9217               (set (match_operand:SWI 0 "register_operand")
9218                    (neg:SWI (match_dup 1)))])
9219    (set (pc) (if_then_else
9220                (eq (reg:CCO FLAGS_REG) (const_int 0))
9221                (label_ref (match_operand 2))
9222                (pc)))]
9223   ""
9225   operands[3]
9226     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9227                     <MODE>mode);
9230 (define_insn "*negv<mode>3"
9231   [(set (reg:CCO FLAGS_REG)
9232         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9233                 (match_operand:SWI 2 "const_int_operand")))
9234    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9235         (neg:SWI (match_dup 1)))]
9236   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9237    && mode_signbit_p (<MODE>mode, operands[2])"
9238   "neg{<imodesuffix>}\t%0"
9239   [(set_attr "type" "negnot")
9240    (set_attr "mode" "<MODE>")])
9242 ;; Changing of sign for FP values is doable using integer unit too.
9244 (define_expand "<code><mode>2"
9245   [(set (match_operand:X87MODEF 0 "register_operand")
9246         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9247   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9248   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9250 (define_insn "*absneg<mode>2"
9251   [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9252         (match_operator:MODEF 3 "absneg_operator"
9253           [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9254    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9255    (clobber (reg:CC FLAGS_REG))]
9256   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9257   "#"
9258   [(set (attr "enabled")
9259      (if_then_else
9260        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9261        (if_then_else
9262          (eq_attr "alternative" "2")
9263          (symbol_ref "TARGET_MIX_SSE_I387")
9264          (symbol_ref "true"))
9265        (if_then_else
9266          (eq_attr "alternative" "2,3")
9267          (symbol_ref "true")
9268          (symbol_ref "false"))))])
9270 (define_insn "*absnegxf2_i387"
9271   [(set (match_operand:XF 0 "register_operand" "=f,!r")
9272         (match_operator:XF 3 "absneg_operator"
9273           [(match_operand:XF 1 "register_operand" "0,0")]))
9274    (use (match_operand 2))
9275    (clobber (reg:CC FLAGS_REG))]
9276   "TARGET_80387"
9277   "#")
9279 (define_expand "<code>tf2"
9280   [(set (match_operand:TF 0 "register_operand")
9281         (absneg:TF (match_operand:TF 1 "register_operand")))]
9282   "TARGET_SSE"
9283   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9285 (define_insn "*absnegtf2_sse"
9286   [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9287         (match_operator:TF 3 "absneg_operator"
9288           [(match_operand:TF 1 "register_operand" "0,Yv")]))
9289    (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9290    (clobber (reg:CC FLAGS_REG))]
9291   "TARGET_SSE"
9292   "#")
9294 ;; Splitters for fp abs and neg.
9296 (define_split
9297   [(set (match_operand 0 "fp_register_operand")
9298         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9299    (use (match_operand 2))
9300    (clobber (reg:CC FLAGS_REG))]
9301   "reload_completed"
9302   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9304 (define_split
9305   [(set (match_operand 0 "sse_reg_operand")
9306         (match_operator 3 "absneg_operator"
9307           [(match_operand 1 "register_operand")]))
9308    (use (match_operand 2 "nonimmediate_operand"))
9309    (clobber (reg:CC FLAGS_REG))]
9310   "reload_completed"
9311   [(set (match_dup 0) (match_dup 3))]
9313   machine_mode mode = GET_MODE (operands[0]);
9314   machine_mode vmode = GET_MODE (operands[2]);
9315   rtx tmp;
9317   operands[0] = lowpart_subreg (vmode, operands[0], mode);
9318   operands[1] = lowpart_subreg (vmode, operands[1], mode);
9319   if (operands_match_p (operands[0], operands[2]))
9320     std::swap (operands[1], operands[2]);
9321   if (GET_CODE (operands[3]) == ABS)
9322     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9323   else
9324     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9325   operands[3] = tmp;
9328 (define_split
9329   [(set (match_operand:SF 0 "general_reg_operand")
9330         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9331    (use (match_operand:V4SF 2))
9332    (clobber (reg:CC FLAGS_REG))]
9333   "reload_completed"
9334   [(parallel [(set (match_dup 0) (match_dup 1))
9335               (clobber (reg:CC FLAGS_REG))])]
9337   rtx tmp;
9338   operands[0] = gen_lowpart (SImode, operands[0]);
9339   if (GET_CODE (operands[1]) == ABS)
9340     {
9341       tmp = gen_int_mode (0x7fffffff, SImode);
9342       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9343     }
9344   else
9345     {
9346       tmp = gen_int_mode (0x80000000, SImode);
9347       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9348     }
9349   operands[1] = tmp;
9352 (define_split
9353   [(set (match_operand:DF 0 "general_reg_operand")
9354         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9355    (use (match_operand 2))
9356    (clobber (reg:CC FLAGS_REG))]
9357   "reload_completed"
9358   [(parallel [(set (match_dup 0) (match_dup 1))
9359               (clobber (reg:CC FLAGS_REG))])]
9361   rtx tmp;
9362   if (TARGET_64BIT)
9363     {
9364       tmp = gen_lowpart (DImode, operands[0]);
9365       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9366       operands[0] = tmp;
9368       if (GET_CODE (operands[1]) == ABS)
9369         tmp = const0_rtx;
9370       else
9371         tmp = gen_rtx_NOT (DImode, tmp);
9372     }
9373   else
9374     {
9375       operands[0] = gen_highpart (SImode, operands[0]);
9376       if (GET_CODE (operands[1]) == ABS)
9377         {
9378           tmp = gen_int_mode (0x7fffffff, SImode);
9379           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9380         }
9381       else
9382         {
9383           tmp = gen_int_mode (0x80000000, SImode);
9384           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9385         }
9386     }
9387   operands[1] = tmp;
9390 (define_split
9391   [(set (match_operand:XF 0 "general_reg_operand")
9392         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9393    (use (match_operand 2))
9394    (clobber (reg:CC FLAGS_REG))]
9395   "reload_completed"
9396   [(parallel [(set (match_dup 0) (match_dup 1))
9397               (clobber (reg:CC FLAGS_REG))])]
9399   rtx tmp;
9400   operands[0] = gen_rtx_REG (SImode,
9401                              REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9402   if (GET_CODE (operands[1]) == ABS)
9403     {
9404       tmp = GEN_INT (0x7fff);
9405       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9406     }
9407   else
9408     {
9409       tmp = GEN_INT (0x8000);
9410       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9411     }
9412   operands[1] = tmp;
9415 ;; Conditionalize these after reload. If they match before reload, we
9416 ;; lose the clobber and ability to use integer instructions.
9418 (define_insn "*<code><mode>2_1"
9419   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9420         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9421   "TARGET_80387
9422    && (reload_completed
9423        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9424   "f<absneg_mnemonic>"
9425   [(set_attr "type" "fsgn")
9426    (set_attr "mode" "<MODE>")])
9428 (define_insn "*<code>extendsfdf2"
9429   [(set (match_operand:DF 0 "register_operand" "=f")
9430         (absneg:DF (float_extend:DF
9431                      (match_operand:SF 1 "register_operand" "0"))))]
9432   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9433   "f<absneg_mnemonic>"
9434   [(set_attr "type" "fsgn")
9435    (set_attr "mode" "DF")])
9437 (define_insn "*<code>extendsfxf2"
9438   [(set (match_operand:XF 0 "register_operand" "=f")
9439         (absneg:XF (float_extend:XF
9440                      (match_operand:SF 1 "register_operand" "0"))))]
9441   "TARGET_80387"
9442   "f<absneg_mnemonic>"
9443   [(set_attr "type" "fsgn")
9444    (set_attr "mode" "XF")])
9446 (define_insn "*<code>extenddfxf2"
9447   [(set (match_operand:XF 0 "register_operand" "=f")
9448         (absneg:XF (float_extend:XF
9449                      (match_operand:DF 1 "register_operand" "0"))))]
9450   "TARGET_80387"
9451   "f<absneg_mnemonic>"
9452   [(set_attr "type" "fsgn")
9453    (set_attr "mode" "XF")])
9455 ;; Copysign instructions
9457 (define_mode_iterator CSGNMODE [SF DF TF])
9458 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9460 (define_expand "copysign<mode>3"
9461   [(match_operand:CSGNMODE 0 "register_operand")
9462    (match_operand:CSGNMODE 1 "nonmemory_operand")
9463    (match_operand:CSGNMODE 2 "register_operand")]
9464   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9465    || (TARGET_SSE && (<MODE>mode == TFmode))"
9466   "ix86_expand_copysign (operands); DONE;")
9468 (define_insn_and_split "copysign<mode>3_const"
9469   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9470         (unspec:CSGNMODE
9471           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
9472            (match_operand:CSGNMODE 2 "register_operand" "0")
9473            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9474           UNSPEC_COPYSIGN))]
9475   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9476    || (TARGET_SSE && (<MODE>mode == TFmode))"
9477   "#"
9478   "&& reload_completed"
9479   [(const_int 0)]
9480   "ix86_split_copysign_const (operands); DONE;")
9482 (define_insn "copysign<mode>3_var"
9483   [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9484         (unspec:CSGNMODE
9485           [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9486            (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9487            (match_operand:<CSGNVMODE> 4
9488              "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9489            (match_operand:<CSGNVMODE> 5
9490              "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9491           UNSPEC_COPYSIGN))
9492    (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9493   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9494    || (TARGET_SSE && (<MODE>mode == TFmode))"
9495   "#")
9497 (define_split
9498   [(set (match_operand:CSGNMODE 0 "register_operand")
9499         (unspec:CSGNMODE
9500           [(match_operand:CSGNMODE 2 "register_operand")
9501            (match_operand:CSGNMODE 3 "register_operand")
9502            (match_operand:<CSGNVMODE> 4)
9503            (match_operand:<CSGNVMODE> 5)]
9504           UNSPEC_COPYSIGN))
9505    (clobber (match_scratch:<CSGNVMODE> 1))]
9506   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9507     || (TARGET_SSE && (<MODE>mode == TFmode)))
9508    && reload_completed"
9509   [(const_int 0)]
9510   "ix86_split_copysign_var (operands); DONE;")
9512 ;; One complement instructions
9514 (define_expand "one_cmpl<mode>2"
9515   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9516         (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
9517   ""
9518   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9520 (define_insn_and_split "*one_cmpldi2_doubleword"
9521   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9522         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9523   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9524    && ix86_unary_operator_ok (NOT, DImode, operands)"
9525   "#"
9526   "&& reload_completed"
9527   [(set (match_dup 0)
9528         (not:SI (match_dup 1)))
9529    (set (match_dup 2)
9530         (not:SI (match_dup 3)))]
9531   "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9533 (define_insn "*one_cmpl<mode>2_1"
9534   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9535         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9536   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9537   "not{<imodesuffix>}\t%0"
9538   [(set_attr "type" "negnot")
9539    (set_attr "mode" "<MODE>")])
9541 ;; ??? Currently never generated - xor is used instead.
9542 (define_insn "*one_cmplsi2_1_zext"
9543   [(set (match_operand:DI 0 "register_operand" "=r")
9544         (zero_extend:DI
9545           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9546   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9547   "not{l}\t%k0"
9548   [(set_attr "type" "negnot")
9549    (set_attr "mode" "SI")])
9551 (define_insn "*one_cmplqi2_1"
9552   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9553         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9554   "ix86_unary_operator_ok (NOT, QImode, operands)"
9555   "@
9556    not{b}\t%0
9557    not{l}\t%k0"
9558   [(set_attr "type" "negnot")
9559    (set_attr "mode" "QI,SI")
9560    ;; Potential partial reg stall on alternative 1.
9561    (set (attr "preferred_for_speed")
9562      (cond [(eq_attr "alternative" "1")
9563               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9564            (symbol_ref "true")))])
9566 (define_insn "*one_cmpl<mode>2_2"
9567   [(set (reg FLAGS_REG)
9568         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9569                  (const_int 0)))
9570    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9571         (not:SWI (match_dup 1)))]
9572   "ix86_match_ccmode (insn, CCNOmode)
9573    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9574   "#"
9575   [(set_attr "type" "alu1")
9576    (set_attr "mode" "<MODE>")])
9578 (define_split
9579   [(set (match_operand 0 "flags_reg_operand")
9580         (match_operator 2 "compare_operator"
9581           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9582            (const_int 0)]))
9583    (set (match_operand:SWI 1 "nonimmediate_operand")
9584         (not:SWI (match_dup 3)))]
9585   "ix86_match_ccmode (insn, CCNOmode)"
9586   [(parallel [(set (match_dup 0)
9587                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9588                                     (const_int 0)]))
9589               (set (match_dup 1)
9590                    (xor:SWI (match_dup 3) (const_int -1)))])])
9592 ;; ??? Currently never generated - xor is used instead.
9593 (define_insn "*one_cmplsi2_2_zext"
9594   [(set (reg FLAGS_REG)
9595         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9596                  (const_int 0)))
9597    (set (match_operand:DI 0 "register_operand" "=r")
9598         (zero_extend:DI (not:SI (match_dup 1))))]
9599   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9600    && ix86_unary_operator_ok (NOT, SImode, operands)"
9601   "#"
9602   [(set_attr "type" "alu1")
9603    (set_attr "mode" "SI")])
9605 (define_split
9606   [(set (match_operand 0 "flags_reg_operand")
9607         (match_operator 2 "compare_operator"
9608           [(not:SI (match_operand:SI 3 "register_operand"))
9609            (const_int 0)]))
9610    (set (match_operand:DI 1 "register_operand")
9611         (zero_extend:DI (not:SI (match_dup 3))))]
9612   "ix86_match_ccmode (insn, CCNOmode)"
9613   [(parallel [(set (match_dup 0)
9614                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9615                                     (const_int 0)]))
9616               (set (match_dup 1)
9617                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9619 ;; Shift instructions
9621 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9622 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9623 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9624 ;; from the assembler input.
9626 ;; This instruction shifts the target reg/mem as usual, but instead of
9627 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9628 ;; is a left shift double, bits are taken from the high order bits of
9629 ;; reg, else if the insn is a shift right double, bits are taken from the
9630 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9631 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9633 ;; Since sh[lr]d does not change the `reg' operand, that is done
9634 ;; separately, making all shifts emit pairs of shift double and normal
9635 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9636 ;; support a 63 bit shift, each shift where the count is in a reg expands
9637 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9639 ;; If the shift count is a constant, we need never emit more than one
9640 ;; shift pair, instead using moves and sign extension for counts greater
9641 ;; than 31.
9643 (define_expand "ashl<mode>3"
9644   [(set (match_operand:SDWIM 0 "<shift_operand>")
9645         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9646                       (match_operand:QI 2 "nonmemory_operand")))]
9647   ""
9648   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9650 (define_insn "*ashl<mode>3_doubleword"
9651   [(set (match_operand:DWI 0 "register_operand" "=&r")
9652         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9653                     (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9654    (clobber (reg:CC FLAGS_REG))]
9655   ""
9656   "#"
9657   [(set_attr "type" "multi")])
9659 (define_split
9660   [(set (match_operand:DWI 0 "register_operand")
9661         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9662                     (match_operand:QI 2 "nonmemory_operand")))
9663    (clobber (reg:CC FLAGS_REG))]
9664   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9665   [(const_int 0)]
9666   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9668 ;; By default we don't ask for a scratch register, because when DWImode
9669 ;; values are manipulated, registers are already at a premium.  But if
9670 ;; we have one handy, we won't turn it away.
9672 (define_peephole2
9673   [(match_scratch:DWIH 3 "r")
9674    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9675                    (ashift:<DWI>
9676                      (match_operand:<DWI> 1 "nonmemory_operand")
9677                      (match_operand:QI 2 "nonmemory_operand")))
9678               (clobber (reg:CC FLAGS_REG))])
9679    (match_dup 3)]
9680   "TARGET_CMOVE"
9681   [(const_int 0)]
9682   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9684 (define_insn "x86_64_shld"
9685   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9686         (ior:DI (ashift:DI (match_dup 0)
9687                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9688                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9689                   (minus:QI (const_int 64) (match_dup 2)))))
9690    (clobber (reg:CC FLAGS_REG))]
9691   "TARGET_64BIT"
9692   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9693   [(set_attr "type" "ishift")
9694    (set_attr "prefix_0f" "1")
9695    (set_attr "mode" "DI")
9696    (set_attr "athlon_decode" "vector")
9697    (set_attr "amdfam10_decode" "vector")
9698    (set_attr "bdver1_decode" "vector")])
9700 (define_insn "x86_shld"
9701   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9702         (ior:SI (ashift:SI (match_dup 0)
9703                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9704                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9705                   (minus:QI (const_int 32) (match_dup 2)))))
9706    (clobber (reg:CC FLAGS_REG))]
9707   ""
9708   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9709   [(set_attr "type" "ishift")
9710    (set_attr "prefix_0f" "1")
9711    (set_attr "mode" "SI")
9712    (set_attr "pent_pair" "np")
9713    (set_attr "athlon_decode" "vector")
9714    (set_attr "amdfam10_decode" "vector")
9715    (set_attr "bdver1_decode" "vector")])
9717 (define_expand "x86_shift<mode>_adj_1"
9718   [(set (reg:CCZ FLAGS_REG)
9719         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9720                              (match_dup 4))
9721                      (const_int 0)))
9722    (set (match_operand:SWI48 0 "register_operand")
9723         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9724                             (match_operand:SWI48 1 "register_operand")
9725                             (match_dup 0)))
9726    (set (match_dup 1)
9727         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9728                             (match_operand:SWI48 3 "register_operand")
9729                             (match_dup 1)))]
9730   "TARGET_CMOVE"
9731   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9733 (define_expand "x86_shift<mode>_adj_2"
9734   [(use (match_operand:SWI48 0 "register_operand"))
9735    (use (match_operand:SWI48 1 "register_operand"))
9736    (use (match_operand:QI 2 "register_operand"))]
9737   ""
9739   rtx_code_label *label = gen_label_rtx ();
9740   rtx tmp;
9742   emit_insn (gen_testqi_ccz_1 (operands[2],
9743                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9745   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9746   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9747   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9748                               gen_rtx_LABEL_REF (VOIDmode, label),
9749                               pc_rtx);
9750   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9751   JUMP_LABEL (tmp) = label;
9753   emit_move_insn (operands[0], operands[1]);
9754   ix86_expand_clear (operands[1]);
9756   emit_label (label);
9757   LABEL_NUSES (label) = 1;
9759   DONE;
9762 ;; Avoid useless masking of count operand.
9763 (define_insn_and_split "*ashl<mode>3_mask"
9764   [(set (match_operand:SWI48 0 "nonimmediate_operand")
9765         (ashift:SWI48
9766           (match_operand:SWI48 1 "nonimmediate_operand")
9767           (subreg:QI
9768             (and:SI
9769               (match_operand:SI 2 "register_operand")
9770               (match_operand:SI 3 "const_int_operand")) 0)))
9771    (clobber (reg:CC FLAGS_REG))]
9772   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9773    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9774       == GET_MODE_BITSIZE (<MODE>mode)-1
9775    && can_create_pseudo_p ()"
9776   "#"
9777   "&& 1"
9778   [(parallel
9779      [(set (match_dup 0)
9780            (ashift:SWI48 (match_dup 1)
9781                          (match_dup 2)))
9782       (clobber (reg:CC FLAGS_REG))])]
9783   "operands[2] = gen_lowpart (QImode, operands[2]);")
9785 (define_insn "*bmi2_ashl<mode>3_1"
9786   [(set (match_operand:SWI48 0 "register_operand" "=r")
9787         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9788                       (match_operand:SWI48 2 "register_operand" "r")))]
9789   "TARGET_BMI2"
9790   "shlx\t{%2, %1, %0|%0, %1, %2}"
9791   [(set_attr "type" "ishiftx")
9792    (set_attr "mode" "<MODE>")])
9794 (define_insn "*ashl<mode>3_1"
9795   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9796         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9797                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9798    (clobber (reg:CC FLAGS_REG))]
9799   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9801   switch (get_attr_type (insn))
9802     {
9803     case TYPE_LEA:
9804     case TYPE_ISHIFTX:
9805       return "#";
9807     case TYPE_ALU:
9808       gcc_assert (operands[2] == const1_rtx);
9809       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9810       return "add{<imodesuffix>}\t%0, %0";
9812     default:
9813       if (operands[2] == const1_rtx
9814           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9815         return "sal{<imodesuffix>}\t%0";
9816       else
9817         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9818     }
9820   [(set_attr "isa" "*,*,bmi2")
9821    (set (attr "type")
9822      (cond [(eq_attr "alternative" "1")
9823               (const_string "lea")
9824             (eq_attr "alternative" "2")
9825               (const_string "ishiftx")
9826             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9827                       (match_operand 0 "register_operand"))
9828                  (match_operand 2 "const1_operand"))
9829               (const_string "alu")
9830            ]
9831            (const_string "ishift")))
9832    (set (attr "length_immediate")
9833      (if_then_else
9834        (ior (eq_attr "type" "alu")
9835             (and (eq_attr "type" "ishift")
9836                  (and (match_operand 2 "const1_operand")
9837                       (ior (match_test "TARGET_SHIFT1")
9838                            (match_test "optimize_function_for_size_p (cfun)")))))
9839        (const_string "0")
9840        (const_string "*")))
9841    (set_attr "mode" "<MODE>")])
9843 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9844 (define_split
9845   [(set (match_operand:SWI48 0 "register_operand")
9846         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9847                       (match_operand:QI 2 "register_operand")))
9848    (clobber (reg:CC FLAGS_REG))]
9849   "TARGET_BMI2 && reload_completed"
9850   [(set (match_dup 0)
9851         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9852   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9854 (define_insn "*bmi2_ashlsi3_1_zext"
9855   [(set (match_operand:DI 0 "register_operand" "=r")
9856         (zero_extend:DI
9857           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9858                      (match_operand:SI 2 "register_operand" "r"))))]
9859   "TARGET_64BIT && TARGET_BMI2"
9860   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9861   [(set_attr "type" "ishiftx")
9862    (set_attr "mode" "SI")])
9864 (define_insn "*ashlsi3_1_zext"
9865   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9866         (zero_extend:DI
9867           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9868                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9869    (clobber (reg:CC FLAGS_REG))]
9870   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9872   switch (get_attr_type (insn))
9873     {
9874     case TYPE_LEA:
9875     case TYPE_ISHIFTX:
9876       return "#";
9878     case TYPE_ALU:
9879       gcc_assert (operands[2] == const1_rtx);
9880       return "add{l}\t%k0, %k0";
9882     default:
9883       if (operands[2] == const1_rtx
9884           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9885         return "sal{l}\t%k0";
9886       else
9887         return "sal{l}\t{%2, %k0|%k0, %2}";
9888     }
9890   [(set_attr "isa" "*,*,bmi2")
9891    (set (attr "type")
9892      (cond [(eq_attr "alternative" "1")
9893               (const_string "lea")
9894             (eq_attr "alternative" "2")
9895               (const_string "ishiftx")
9896             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9897                  (match_operand 2 "const1_operand"))
9898               (const_string "alu")
9899            ]
9900            (const_string "ishift")))
9901    (set (attr "length_immediate")
9902      (if_then_else
9903        (ior (eq_attr "type" "alu")
9904             (and (eq_attr "type" "ishift")
9905                  (and (match_operand 2 "const1_operand")
9906                       (ior (match_test "TARGET_SHIFT1")
9907                            (match_test "optimize_function_for_size_p (cfun)")))))
9908        (const_string "0")
9909        (const_string "*")))
9910    (set_attr "mode" "SI")])
9912 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9913 (define_split
9914   [(set (match_operand:DI 0 "register_operand")
9915         (zero_extend:DI
9916           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9917                      (match_operand:QI 2 "register_operand"))))
9918    (clobber (reg:CC FLAGS_REG))]
9919   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9920   [(set (match_dup 0)
9921         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9922   "operands[2] = gen_lowpart (SImode, operands[2]);")
9924 (define_insn "*ashlhi3_1"
9925   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9926         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9927                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9928    (clobber (reg:CC FLAGS_REG))]
9929   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9931   switch (get_attr_type (insn))
9932     {
9933     case TYPE_LEA:
9934       return "#";
9936     case TYPE_ALU:
9937       gcc_assert (operands[2] == const1_rtx);
9938       return "add{w}\t%0, %0";
9940     default:
9941       if (operands[2] == const1_rtx
9942           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9943         return "sal{w}\t%0";
9944       else
9945         return "sal{w}\t{%2, %0|%0, %2}";
9946     }
9948   [(set (attr "type")
9949      (cond [(eq_attr "alternative" "1")
9950               (const_string "lea")
9951             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9952                       (match_operand 0 "register_operand"))
9953                  (match_operand 2 "const1_operand"))
9954               (const_string "alu")
9955            ]
9956            (const_string "ishift")))
9957    (set (attr "length_immediate")
9958      (if_then_else
9959        (ior (eq_attr "type" "alu")
9960             (and (eq_attr "type" "ishift")
9961                  (and (match_operand 2 "const1_operand")
9962                       (ior (match_test "TARGET_SHIFT1")
9963                            (match_test "optimize_function_for_size_p (cfun)")))))
9964        (const_string "0")
9965        (const_string "*")))
9966    (set_attr "mode" "HI,SI")])
9968 (define_insn "*ashlqi3_1"
9969   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9970         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9971                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9972    (clobber (reg:CC FLAGS_REG))]
9973   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9975   switch (get_attr_type (insn))
9976     {
9977     case TYPE_LEA:
9978       return "#";
9980     case TYPE_ALU:
9981       gcc_assert (operands[2] == const1_rtx);
9982       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
9983         return "add{l}\t%k0, %k0";
9984       else
9985         return "add{b}\t%0, %0";
9987     default:
9988       if (operands[2] == const1_rtx
9989           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9990         {
9991           if (get_attr_mode (insn) == MODE_SI)
9992             return "sal{l}\t%k0";
9993           else
9994             return "sal{b}\t%0";
9995         }
9996       else
9997         {
9998           if (get_attr_mode (insn) == MODE_SI)
9999             return "sal{l}\t{%2, %k0|%k0, %2}";
10000           else
10001             return "sal{b}\t{%2, %0|%0, %2}";
10002         }
10003     }
10005   [(set (attr "type")
10006      (cond [(eq_attr "alternative" "2")
10007               (const_string "lea")
10008             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10009                       (match_operand 0 "register_operand"))
10010                  (match_operand 2 "const1_operand"))
10011               (const_string "alu")
10012            ]
10013            (const_string "ishift")))
10014    (set (attr "length_immediate")
10015      (if_then_else
10016        (ior (eq_attr "type" "alu")
10017             (and (eq_attr "type" "ishift")
10018                  (and (match_operand 2 "const1_operand")
10019                       (ior (match_test "TARGET_SHIFT1")
10020                            (match_test "optimize_function_for_size_p (cfun)")))))
10021        (const_string "0")
10022        (const_string "*")))
10023    (set_attr "mode" "QI,SI,SI")
10024    ;; Potential partial reg stall on alternative 1.
10025    (set (attr "preferred_for_speed")
10026      (cond [(eq_attr "alternative" "1")
10027               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10028            (symbol_ref "true")))])
10030 (define_insn "*ashlqi3_1_slp"
10031   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10032         (ashift:QI (match_dup 0)
10033                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10034    (clobber (reg:CC FLAGS_REG))]
10035   "(optimize_function_for_size_p (cfun)
10036     || !TARGET_PARTIAL_FLAG_REG_STALL
10037     || (operands[1] == const1_rtx
10038         && (TARGET_SHIFT1
10039             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10041   switch (get_attr_type (insn))
10042     {
10043     case TYPE_ALU:
10044       gcc_assert (operands[1] == const1_rtx);
10045       return "add{b}\t%0, %0";
10047     default:
10048       if (operands[1] == const1_rtx
10049           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050         return "sal{b}\t%0";
10051       else
10052         return "sal{b}\t{%1, %0|%0, %1}";
10053     }
10055   [(set (attr "type")
10056      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10057                       (match_operand 0 "register_operand"))
10058                  (match_operand 1 "const1_operand"))
10059               (const_string "alu")
10060            ]
10061            (const_string "ishift1")))
10062    (set (attr "length_immediate")
10063      (if_then_else
10064        (ior (eq_attr "type" "alu")
10065             (and (eq_attr "type" "ishift1")
10066                  (and (match_operand 1 "const1_operand")
10067                       (ior (match_test "TARGET_SHIFT1")
10068                            (match_test "optimize_function_for_size_p (cfun)")))))
10069        (const_string "0")
10070        (const_string "*")))
10071    (set_attr "mode" "QI")])
10073 ;; Convert ashift to the lea pattern to avoid flags dependency.
10074 (define_split
10075   [(set (match_operand:SWI 0 "register_operand")
10076         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10077                     (match_operand 2 "const_0_to_3_operand")))
10078    (clobber (reg:CC FLAGS_REG))]
10079   "reload_completed
10080    && REGNO (operands[0]) != REGNO (operands[1])"
10081   [(set (match_dup 0)
10082         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10084   if (<MODE>mode != <LEAMODE>mode)
10085     {
10086       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10087       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10088     }
10089   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10092 ;; Convert ashift to the lea pattern to avoid flags dependency.
10093 (define_split
10094   [(set (match_operand:DI 0 "register_operand")
10095         (zero_extend:DI
10096           (ashift:SI (match_operand:SI 1 "index_register_operand")
10097                      (match_operand 2 "const_0_to_3_operand"))))
10098    (clobber (reg:CC FLAGS_REG))]
10099   "TARGET_64BIT && reload_completed
10100    && REGNO (operands[0]) != REGNO (operands[1])"
10101   [(set (match_dup 0)
10102         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10104   operands[1] = gen_lowpart (SImode, operands[1]);
10105   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10108 ;; This pattern can't accept a variable shift count, since shifts by
10109 ;; zero don't affect the flags.  We assume that shifts by constant
10110 ;; zero are optimized away.
10111 (define_insn "*ashl<mode>3_cmp"
10112   [(set (reg FLAGS_REG)
10113         (compare
10114           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10115                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10116           (const_int 0)))
10117    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10118         (ashift:SWI (match_dup 1) (match_dup 2)))]
10119   "(optimize_function_for_size_p (cfun)
10120     || !TARGET_PARTIAL_FLAG_REG_STALL
10121     || (operands[2] == const1_rtx
10122         && (TARGET_SHIFT1
10123             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10124    && ix86_match_ccmode (insn, CCGOCmode)
10125    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10127   switch (get_attr_type (insn))
10128     {
10129     case TYPE_ALU:
10130       gcc_assert (operands[2] == const1_rtx);
10131       return "add{<imodesuffix>}\t%0, %0";
10133     default:
10134       if (operands[2] == const1_rtx
10135           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10136         return "sal{<imodesuffix>}\t%0";
10137       else
10138         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10139     }
10141   [(set (attr "type")
10142      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10143                       (match_operand 0 "register_operand"))
10144                  (match_operand 2 "const1_operand"))
10145               (const_string "alu")
10146            ]
10147            (const_string "ishift")))
10148    (set (attr "length_immediate")
10149      (if_then_else
10150        (ior (eq_attr "type" "alu")
10151             (and (eq_attr "type" "ishift")
10152                  (and (match_operand 2 "const1_operand")
10153                       (ior (match_test "TARGET_SHIFT1")
10154                            (match_test "optimize_function_for_size_p (cfun)")))))
10155        (const_string "0")
10156        (const_string "*")))
10157    (set_attr "mode" "<MODE>")])
10159 (define_insn "*ashlsi3_cmp_zext"
10160   [(set (reg FLAGS_REG)
10161         (compare
10162           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10163                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10164           (const_int 0)))
10165    (set (match_operand:DI 0 "register_operand" "=r")
10166         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10167   "TARGET_64BIT
10168    && (optimize_function_for_size_p (cfun)
10169        || !TARGET_PARTIAL_FLAG_REG_STALL
10170        || (operands[2] == const1_rtx
10171            && (TARGET_SHIFT1
10172                || TARGET_DOUBLE_WITH_ADD)))
10173    && ix86_match_ccmode (insn, CCGOCmode)
10174    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10176   switch (get_attr_type (insn))
10177     {
10178     case TYPE_ALU:
10179       gcc_assert (operands[2] == const1_rtx);
10180       return "add{l}\t%k0, %k0";
10182     default:
10183       if (operands[2] == const1_rtx
10184           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10185         return "sal{l}\t%k0";
10186       else
10187         return "sal{l}\t{%2, %k0|%k0, %2}";
10188     }
10190   [(set (attr "type")
10191      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10192                  (match_operand 2 "const1_operand"))
10193               (const_string "alu")
10194            ]
10195            (const_string "ishift")))
10196    (set (attr "length_immediate")
10197      (if_then_else
10198        (ior (eq_attr "type" "alu")
10199             (and (eq_attr "type" "ishift")
10200                  (and (match_operand 2 "const1_operand")
10201                       (ior (match_test "TARGET_SHIFT1")
10202                            (match_test "optimize_function_for_size_p (cfun)")))))
10203        (const_string "0")
10204        (const_string "*")))
10205    (set_attr "mode" "SI")])
10207 (define_insn "*ashl<mode>3_cconly"
10208   [(set (reg FLAGS_REG)
10209         (compare
10210           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10211                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10212           (const_int 0)))
10213    (clobber (match_scratch:SWI 0 "=<r>"))]
10214   "(optimize_function_for_size_p (cfun)
10215     || !TARGET_PARTIAL_FLAG_REG_STALL
10216     || (operands[2] == const1_rtx
10217         && (TARGET_SHIFT1
10218             || TARGET_DOUBLE_WITH_ADD)))
10219    && ix86_match_ccmode (insn, CCGOCmode)"
10221   switch (get_attr_type (insn))
10222     {
10223     case TYPE_ALU:
10224       gcc_assert (operands[2] == const1_rtx);
10225       return "add{<imodesuffix>}\t%0, %0";
10227     default:
10228       if (operands[2] == const1_rtx
10229           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10230         return "sal{<imodesuffix>}\t%0";
10231       else
10232         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10233     }
10235   [(set (attr "type")
10236      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10237                       (match_operand 0 "register_operand"))
10238                  (match_operand 2 "const1_operand"))
10239               (const_string "alu")
10240            ]
10241            (const_string "ishift")))
10242    (set (attr "length_immediate")
10243      (if_then_else
10244        (ior (eq_attr "type" "alu")
10245             (and (eq_attr "type" "ishift")
10246                  (and (match_operand 2 "const1_operand")
10247                       (ior (match_test "TARGET_SHIFT1")
10248                            (match_test "optimize_function_for_size_p (cfun)")))))
10249        (const_string "0")
10250        (const_string "*")))
10251    (set_attr "mode" "<MODE>")])
10253 ;; See comment above `ashl<mode>3' about how this works.
10255 (define_expand "<shift_insn><mode>3"
10256   [(set (match_operand:SDWIM 0 "<shift_operand>")
10257         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10258                            (match_operand:QI 2 "nonmemory_operand")))]
10259   ""
10260   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10262 ;; Avoid useless masking of count operand.
10263 (define_insn_and_split "*<shift_insn><mode>3_mask"
10264   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10265         (any_shiftrt:SWI48
10266           (match_operand:SWI48 1 "nonimmediate_operand")
10267           (subreg:QI
10268             (and:SI
10269               (match_operand:SI 2 "register_operand")
10270               (match_operand:SI 3 "const_int_operand")) 0)))
10271    (clobber (reg:CC FLAGS_REG))]
10272   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10273    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10274       == GET_MODE_BITSIZE (<MODE>mode)-1
10275    && can_create_pseudo_p ()"
10276   "#"
10277   "&& 1"
10278   [(parallel
10279      [(set (match_dup 0)
10280            (any_shiftrt:SWI48 (match_dup 1)
10281                               (match_dup 2)))
10282       (clobber (reg:CC FLAGS_REG))])]
10283   "operands[2] = gen_lowpart (QImode, operands[2]);")
10285 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10286   [(set (match_operand:DWI 0 "register_operand" "=&r")
10287         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10288                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10289    (clobber (reg:CC FLAGS_REG))]
10290   ""
10291   "#"
10292   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10293   [(const_int 0)]
10294   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10295   [(set_attr "type" "multi")])
10297 ;; By default we don't ask for a scratch register, because when DWImode
10298 ;; values are manipulated, registers are already at a premium.  But if
10299 ;; we have one handy, we won't turn it away.
10301 (define_peephole2
10302   [(match_scratch:DWIH 3 "r")
10303    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10304                    (any_shiftrt:<DWI>
10305                      (match_operand:<DWI> 1 "register_operand")
10306                      (match_operand:QI 2 "nonmemory_operand")))
10307               (clobber (reg:CC FLAGS_REG))])
10308    (match_dup 3)]
10309   "TARGET_CMOVE"
10310   [(const_int 0)]
10311   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10313 (define_insn "x86_64_shrd"
10314   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10315         (ior:DI (lshiftrt:DI (match_dup 0)
10316                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10317                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10318                   (minus:QI (const_int 64) (match_dup 2)))))
10319    (clobber (reg:CC FLAGS_REG))]
10320   "TARGET_64BIT"
10321   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10322   [(set_attr "type" "ishift")
10323    (set_attr "prefix_0f" "1")
10324    (set_attr "mode" "DI")
10325    (set_attr "athlon_decode" "vector")
10326    (set_attr "amdfam10_decode" "vector")
10327    (set_attr "bdver1_decode" "vector")])
10329 (define_insn "x86_shrd"
10330   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10331         (ior:SI (lshiftrt:SI (match_dup 0)
10332                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10333                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10334                   (minus:QI (const_int 32) (match_dup 2)))))
10335    (clobber (reg:CC FLAGS_REG))]
10336   ""
10337   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10338   [(set_attr "type" "ishift")
10339    (set_attr "prefix_0f" "1")
10340    (set_attr "mode" "SI")
10341    (set_attr "pent_pair" "np")
10342    (set_attr "athlon_decode" "vector")
10343    (set_attr "amdfam10_decode" "vector")
10344    (set_attr "bdver1_decode" "vector")])
10346 (define_insn "ashrdi3_cvt"
10347   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10348         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10349                      (match_operand:QI 2 "const_int_operand")))
10350    (clobber (reg:CC FLAGS_REG))]
10351   "TARGET_64BIT && INTVAL (operands[2]) == 63
10352    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10353    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10354   "@
10355    {cqto|cqo}
10356    sar{q}\t{%2, %0|%0, %2}"
10357   [(set_attr "type" "imovx,ishift")
10358    (set_attr "prefix_0f" "0,*")
10359    (set_attr "length_immediate" "0,*")
10360    (set_attr "modrm" "0,1")
10361    (set_attr "mode" "DI")])
10363 (define_insn "*ashrsi3_cvt_zext"
10364   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10365         (zero_extend:DI
10366           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10367                        (match_operand:QI 2 "const_int_operand"))))
10368    (clobber (reg:CC FLAGS_REG))]
10369   "TARGET_64BIT && INTVAL (operands[2]) == 31
10370    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10371    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10372   "@
10373    {cltd|cdq}
10374    sar{l}\t{%2, %k0|%k0, %2}"
10375   [(set_attr "type" "imovx,ishift")
10376    (set_attr "prefix_0f" "0,*")
10377    (set_attr "length_immediate" "0,*")
10378    (set_attr "modrm" "0,1")
10379    (set_attr "mode" "SI")])
10381 (define_insn "ashrsi3_cvt"
10382   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10383         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10384                      (match_operand:QI 2 "const_int_operand")))
10385    (clobber (reg:CC FLAGS_REG))]
10386   "INTVAL (operands[2]) == 31
10387    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10388    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10389   "@
10390    {cltd|cdq}
10391    sar{l}\t{%2, %0|%0, %2}"
10392   [(set_attr "type" "imovx,ishift")
10393    (set_attr "prefix_0f" "0,*")
10394    (set_attr "length_immediate" "0,*")
10395    (set_attr "modrm" "0,1")
10396    (set_attr "mode" "SI")])
10398 (define_expand "x86_shift<mode>_adj_3"
10399   [(use (match_operand:SWI48 0 "register_operand"))
10400    (use (match_operand:SWI48 1 "register_operand"))
10401    (use (match_operand:QI 2 "register_operand"))]
10402   ""
10404   rtx_code_label *label = gen_label_rtx ();
10405   rtx tmp;
10407   emit_insn (gen_testqi_ccz_1 (operands[2],
10408                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10410   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10411   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10412   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10413                               gen_rtx_LABEL_REF (VOIDmode, label),
10414                               pc_rtx);
10415   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10416   JUMP_LABEL (tmp) = label;
10418   emit_move_insn (operands[0], operands[1]);
10419   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10420                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10421   emit_label (label);
10422   LABEL_NUSES (label) = 1;
10424   DONE;
10427 (define_insn "*bmi2_<shift_insn><mode>3_1"
10428   [(set (match_operand:SWI48 0 "register_operand" "=r")
10429         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10430                            (match_operand:SWI48 2 "register_operand" "r")))]
10431   "TARGET_BMI2"
10432   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10433   [(set_attr "type" "ishiftx")
10434    (set_attr "mode" "<MODE>")])
10436 (define_insn "*<shift_insn><mode>3_1"
10437   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10438         (any_shiftrt:SWI48
10439           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10440           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10441    (clobber (reg:CC FLAGS_REG))]
10442   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10444   switch (get_attr_type (insn))
10445     {
10446     case TYPE_ISHIFTX:
10447       return "#";
10449     default:
10450       if (operands[2] == const1_rtx
10451           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10452         return "<shift>{<imodesuffix>}\t%0";
10453       else
10454         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10455     }
10457   [(set_attr "isa" "*,bmi2")
10458    (set_attr "type" "ishift,ishiftx")
10459    (set (attr "length_immediate")
10460      (if_then_else
10461        (and (match_operand 2 "const1_operand")
10462             (ior (match_test "TARGET_SHIFT1")
10463                  (match_test "optimize_function_for_size_p (cfun)")))
10464        (const_string "0")
10465        (const_string "*")))
10466    (set_attr "mode" "<MODE>")])
10468 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10469 (define_split
10470   [(set (match_operand:SWI48 0 "register_operand")
10471         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10472                            (match_operand:QI 2 "register_operand")))
10473    (clobber (reg:CC FLAGS_REG))]
10474   "TARGET_BMI2 && reload_completed"
10475   [(set (match_dup 0)
10476         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10477   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10479 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10480   [(set (match_operand:DI 0 "register_operand" "=r")
10481         (zero_extend:DI
10482           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10483                           (match_operand:SI 2 "register_operand" "r"))))]
10484   "TARGET_64BIT && TARGET_BMI2"
10485   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10486   [(set_attr "type" "ishiftx")
10487    (set_attr "mode" "SI")])
10489 (define_insn "*<shift_insn>si3_1_zext"
10490   [(set (match_operand:DI 0 "register_operand" "=r,r")
10491         (zero_extend:DI
10492           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10493                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10494    (clobber (reg:CC FLAGS_REG))]
10495   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10497   switch (get_attr_type (insn))
10498     {
10499     case TYPE_ISHIFTX:
10500       return "#";
10502     default:
10503       if (operands[2] == const1_rtx
10504           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10505         return "<shift>{l}\t%k0";
10506       else
10507         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10508     }
10510   [(set_attr "isa" "*,bmi2")
10511    (set_attr "type" "ishift,ishiftx")
10512    (set (attr "length_immediate")
10513      (if_then_else
10514        (and (match_operand 2 "const1_operand")
10515             (ior (match_test "TARGET_SHIFT1")
10516                  (match_test "optimize_function_for_size_p (cfun)")))
10517        (const_string "0")
10518        (const_string "*")))
10519    (set_attr "mode" "SI")])
10521 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10522 (define_split
10523   [(set (match_operand:DI 0 "register_operand")
10524         (zero_extend:DI
10525           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10526                           (match_operand:QI 2 "register_operand"))))
10527    (clobber (reg:CC FLAGS_REG))]
10528   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10529   [(set (match_dup 0)
10530         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10531   "operands[2] = gen_lowpart (SImode, operands[2]);")
10533 (define_insn "*<shift_insn><mode>3_1"
10534   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10535         (any_shiftrt:SWI12
10536           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10537           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10538    (clobber (reg:CC FLAGS_REG))]
10539   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10541   if (operands[2] == const1_rtx
10542       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10543     return "<shift>{<imodesuffix>}\t%0";
10544   else
10545     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10547   [(set_attr "type" "ishift")
10548    (set (attr "length_immediate")
10549      (if_then_else
10550        (and (match_operand 2 "const1_operand")
10551             (ior (match_test "TARGET_SHIFT1")
10552                  (match_test "optimize_function_for_size_p (cfun)")))
10553        (const_string "0")
10554        (const_string "*")))
10555    (set_attr "mode" "<MODE>")])
10557 (define_insn "*<shift_insn>qi3_1_slp"
10558   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10559         (any_shiftrt:QI (match_dup 0)
10560                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10561    (clobber (reg:CC FLAGS_REG))]
10562   "(optimize_function_for_size_p (cfun)
10563     || !TARGET_PARTIAL_REG_STALL
10564     || (operands[1] == const1_rtx
10565         && TARGET_SHIFT1))"
10567   if (operands[1] == const1_rtx
10568       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10569     return "<shift>{b}\t%0";
10570   else
10571     return "<shift>{b}\t{%1, %0|%0, %1}";
10573   [(set_attr "type" "ishift1")
10574    (set (attr "length_immediate")
10575      (if_then_else
10576        (and (match_operand 1 "const1_operand")
10577             (ior (match_test "TARGET_SHIFT1")
10578                  (match_test "optimize_function_for_size_p (cfun)")))
10579        (const_string "0")
10580        (const_string "*")))
10581    (set_attr "mode" "QI")])
10583 ;; This pattern can't accept a variable shift count, since shifts by
10584 ;; zero don't affect the flags.  We assume that shifts by constant
10585 ;; zero are optimized away.
10586 (define_insn "*<shift_insn><mode>3_cmp"
10587   [(set (reg FLAGS_REG)
10588         (compare
10589           (any_shiftrt:SWI
10590             (match_operand:SWI 1 "nonimmediate_operand" "0")
10591             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10592           (const_int 0)))
10593    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10594         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10595   "(optimize_function_for_size_p (cfun)
10596     || !TARGET_PARTIAL_FLAG_REG_STALL
10597     || (operands[2] == const1_rtx
10598         && TARGET_SHIFT1))
10599    && ix86_match_ccmode (insn, CCGOCmode)
10600    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10602   if (operands[2] == const1_rtx
10603       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10604     return "<shift>{<imodesuffix>}\t%0";
10605   else
10606     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10608   [(set_attr "type" "ishift")
10609    (set (attr "length_immediate")
10610      (if_then_else
10611        (and (match_operand 2 "const1_operand")
10612             (ior (match_test "TARGET_SHIFT1")
10613                  (match_test "optimize_function_for_size_p (cfun)")))
10614        (const_string "0")
10615        (const_string "*")))
10616    (set_attr "mode" "<MODE>")])
10618 (define_insn "*<shift_insn>si3_cmp_zext"
10619   [(set (reg FLAGS_REG)
10620         (compare
10621           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10622                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10623           (const_int 0)))
10624    (set (match_operand:DI 0 "register_operand" "=r")
10625         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10626   "TARGET_64BIT
10627    && (optimize_function_for_size_p (cfun)
10628        || !TARGET_PARTIAL_FLAG_REG_STALL
10629        || (operands[2] == const1_rtx
10630            && TARGET_SHIFT1))
10631    && ix86_match_ccmode (insn, CCGOCmode)
10632    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10634   if (operands[2] == const1_rtx
10635       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10636     return "<shift>{l}\t%k0";
10637   else
10638     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10640   [(set_attr "type" "ishift")
10641    (set (attr "length_immediate")
10642      (if_then_else
10643        (and (match_operand 2 "const1_operand")
10644             (ior (match_test "TARGET_SHIFT1")
10645                  (match_test "optimize_function_for_size_p (cfun)")))
10646        (const_string "0")
10647        (const_string "*")))
10648    (set_attr "mode" "SI")])
10650 (define_insn "*<shift_insn><mode>3_cconly"
10651   [(set (reg FLAGS_REG)
10652         (compare
10653           (any_shiftrt:SWI
10654             (match_operand:SWI 1 "register_operand" "0")
10655             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10656           (const_int 0)))
10657    (clobber (match_scratch:SWI 0 "=<r>"))]
10658   "(optimize_function_for_size_p (cfun)
10659     || !TARGET_PARTIAL_FLAG_REG_STALL
10660     || (operands[2] == const1_rtx
10661         && TARGET_SHIFT1))
10662    && ix86_match_ccmode (insn, CCGOCmode)"
10664   if (operands[2] == const1_rtx
10665       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10666     return "<shift>{<imodesuffix>}\t%0";
10667   else
10668     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10670   [(set_attr "type" "ishift")
10671    (set (attr "length_immediate")
10672      (if_then_else
10673        (and (match_operand 2 "const1_operand")
10674             (ior (match_test "TARGET_SHIFT1")
10675                  (match_test "optimize_function_for_size_p (cfun)")))
10676        (const_string "0")
10677        (const_string "*")))
10678    (set_attr "mode" "<MODE>")])
10680 ;; Rotate instructions
10682 (define_expand "<rotate_insn>ti3"
10683   [(set (match_operand:TI 0 "register_operand")
10684         (any_rotate:TI (match_operand:TI 1 "register_operand")
10685                        (match_operand:QI 2 "nonmemory_operand")))]
10686   "TARGET_64BIT"
10688   if (const_1_to_63_operand (operands[2], VOIDmode))
10689     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10690                 (operands[0], operands[1], operands[2]));
10691   else
10692     FAIL;
10694   DONE;
10697 (define_expand "<rotate_insn>di3"
10698   [(set (match_operand:DI 0 "shiftdi_operand")
10699         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10700                        (match_operand:QI 2 "nonmemory_operand")))]
10701  ""
10703   if (TARGET_64BIT)
10704     ix86_expand_binary_operator (<CODE>, DImode, operands);
10705   else if (const_1_to_31_operand (operands[2], VOIDmode))
10706     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10707                 (operands[0], operands[1], operands[2]));
10708   else
10709     FAIL;
10711   DONE;
10714 (define_expand "<rotate_insn><mode>3"
10715   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10716         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10717                             (match_operand:QI 2 "nonmemory_operand")))]
10718   ""
10719   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10721 ;; Avoid useless masking of count operand.
10722 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10723   [(set (match_operand:SWI48 0 "nonimmediate_operand")
10724         (any_rotate:SWI48
10725           (match_operand:SWI48 1 "nonimmediate_operand")
10726           (subreg:QI
10727             (and:SI
10728               (match_operand:SI 2 "register_operand")
10729               (match_operand:SI 3 "const_int_operand")) 0)))
10730    (clobber (reg:CC FLAGS_REG))]
10731   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10732    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10733       == GET_MODE_BITSIZE (<MODE>mode)-1
10734    && can_create_pseudo_p ()"
10735   "#"
10736   "&& 1"
10737   [(parallel
10738      [(set (match_dup 0)
10739            (any_rotate:SWI48 (match_dup 1)
10740                              (match_dup 2)))
10741       (clobber (reg:CC FLAGS_REG))])]
10742   "operands[2] = gen_lowpart (QImode, operands[2]);")
10744 ;; Implement rotation using two double-precision
10745 ;; shift instructions and a scratch register.
10747 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10748  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10749        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10750                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10751   (clobber (reg:CC FLAGS_REG))
10752   (clobber (match_scratch:DWIH 3 "=&r"))]
10753  ""
10754  "#"
10755  "reload_completed"
10756  [(set (match_dup 3) (match_dup 4))
10757   (parallel
10758    [(set (match_dup 4)
10759          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10760                    (lshiftrt:DWIH (match_dup 5)
10761                                   (minus:QI (match_dup 6) (match_dup 2)))))
10762     (clobber (reg:CC FLAGS_REG))])
10763   (parallel
10764    [(set (match_dup 5)
10765          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10766                    (lshiftrt:DWIH (match_dup 3)
10767                                   (minus:QI (match_dup 6) (match_dup 2)))))
10768     (clobber (reg:CC FLAGS_REG))])]
10770   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10772   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10775 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10776  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10777        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10778                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10779   (clobber (reg:CC FLAGS_REG))
10780   (clobber (match_scratch:DWIH 3 "=&r"))]
10781  ""
10782  "#"
10783  "reload_completed"
10784  [(set (match_dup 3) (match_dup 4))
10785   (parallel
10786    [(set (match_dup 4)
10787          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10788                    (ashift:DWIH (match_dup 5)
10789                                 (minus:QI (match_dup 6) (match_dup 2)))))
10790     (clobber (reg:CC FLAGS_REG))])
10791   (parallel
10792    [(set (match_dup 5)
10793          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10794                    (ashift:DWIH (match_dup 3)
10795                                 (minus:QI (match_dup 6) (match_dup 2)))))
10796     (clobber (reg:CC FLAGS_REG))])]
10798   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10800   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10803 (define_mode_attr rorx_immediate_operand
10804         [(SI "const_0_to_31_operand")
10805          (DI "const_0_to_63_operand")])
10807 (define_insn "*bmi2_rorx<mode>3_1"
10808   [(set (match_operand:SWI48 0 "register_operand" "=r")
10809         (rotatert:SWI48
10810           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10811           (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
10812   "TARGET_BMI2"
10813   "rorx\t{%2, %1, %0|%0, %1, %2}"
10814   [(set_attr "type" "rotatex")
10815    (set_attr "mode" "<MODE>")])
10817 (define_insn "*<rotate_insn><mode>3_1"
10818   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10819         (any_rotate:SWI48
10820           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10821           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10822    (clobber (reg:CC FLAGS_REG))]
10823   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10825   switch (get_attr_type (insn))
10826     {
10827     case TYPE_ROTATEX:
10828       return "#";
10830     default:
10831       if (operands[2] == const1_rtx
10832           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10833         return "<rotate>{<imodesuffix>}\t%0";
10834       else
10835         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10836     }
10838   [(set_attr "isa" "*,bmi2")
10839    (set_attr "type" "rotate,rotatex")
10840    (set (attr "length_immediate")
10841      (if_then_else
10842        (and (eq_attr "type" "rotate")
10843             (and (match_operand 2 "const1_operand")
10844                  (ior (match_test "TARGET_SHIFT1")
10845                       (match_test "optimize_function_for_size_p (cfun)"))))
10846        (const_string "0")
10847        (const_string "*")))
10848    (set_attr "mode" "<MODE>")])
10850 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10851 (define_split
10852   [(set (match_operand:SWI48 0 "register_operand")
10853         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10854                       (match_operand:QI 2 "const_int_operand")))
10855    (clobber (reg:CC FLAGS_REG))]
10856   "TARGET_BMI2 && reload_completed"
10857   [(set (match_dup 0)
10858         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10860   int bitsize = GET_MODE_BITSIZE (<MODE>mode);
10862   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10865 (define_split
10866   [(set (match_operand:SWI48 0 "register_operand")
10867         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10868                         (match_operand:QI 2 "const_int_operand")))
10869    (clobber (reg:CC FLAGS_REG))]
10870   "TARGET_BMI2 && reload_completed"
10871   [(set (match_dup 0)
10872         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10874 (define_insn "*bmi2_rorxsi3_1_zext"
10875   [(set (match_operand:DI 0 "register_operand" "=r")
10876         (zero_extend:DI
10877           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10878                        (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
10879   "TARGET_64BIT && TARGET_BMI2"
10880   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10881   [(set_attr "type" "rotatex")
10882    (set_attr "mode" "SI")])
10884 (define_insn "*<rotate_insn>si3_1_zext"
10885   [(set (match_operand:DI 0 "register_operand" "=r,r")
10886         (zero_extend:DI
10887           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10888                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10889    (clobber (reg:CC FLAGS_REG))]
10890   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10892   switch (get_attr_type (insn))
10893     {
10894     case TYPE_ROTATEX:
10895       return "#";
10897     default:
10898       if (operands[2] == const1_rtx
10899           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10900         return "<rotate>{l}\t%k0";
10901       else
10902         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10903     }
10905   [(set_attr "isa" "*,bmi2")
10906    (set_attr "type" "rotate,rotatex")
10907    (set (attr "length_immediate")
10908      (if_then_else
10909        (and (eq_attr "type" "rotate")
10910             (and (match_operand 2 "const1_operand")
10911                  (ior (match_test "TARGET_SHIFT1")
10912                       (match_test "optimize_function_for_size_p (cfun)"))))
10913        (const_string "0")
10914        (const_string "*")))
10915    (set_attr "mode" "SI")])
10917 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10918 (define_split
10919   [(set (match_operand:DI 0 "register_operand")
10920         (zero_extend:DI
10921           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10922                      (match_operand:QI 2 "const_int_operand"))))
10923    (clobber (reg:CC FLAGS_REG))]
10924   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10925   [(set (match_dup 0)
10926         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10928   int bitsize = GET_MODE_BITSIZE (SImode);
10930   operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
10933 (define_split
10934   [(set (match_operand:DI 0 "register_operand")
10935         (zero_extend:DI
10936           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10937                        (match_operand:QI 2 "const_int_operand"))))
10938    (clobber (reg:CC FLAGS_REG))]
10939   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10940   [(set (match_dup 0)
10941         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10943 (define_insn "*<rotate_insn><mode>3_1"
10944   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10945         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10946                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10947    (clobber (reg:CC FLAGS_REG))]
10948   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10950   if (operands[2] == const1_rtx
10951       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10952     return "<rotate>{<imodesuffix>}\t%0";
10953   else
10954     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10956   [(set_attr "type" "rotate")
10957    (set (attr "length_immediate")
10958      (if_then_else
10959        (and (match_operand 2 "const1_operand")
10960             (ior (match_test "TARGET_SHIFT1")
10961                  (match_test "optimize_function_for_size_p (cfun)")))
10962        (const_string "0")
10963        (const_string "*")))
10964    (set_attr "mode" "<MODE>")])
10966 (define_insn "*<rotate_insn>qi3_1_slp"
10967   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10968         (any_rotate:QI (match_dup 0)
10969                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10970    (clobber (reg:CC FLAGS_REG))]
10971   "(optimize_function_for_size_p (cfun)
10972     || !TARGET_PARTIAL_REG_STALL
10973     || (operands[1] == const1_rtx
10974         && TARGET_SHIFT1))"
10976   if (operands[1] == const1_rtx
10977       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10978     return "<rotate>{b}\t%0";
10979   else
10980     return "<rotate>{b}\t{%1, %0|%0, %1}";
10982   [(set_attr "type" "rotate1")
10983    (set (attr "length_immediate")
10984      (if_then_else
10985        (and (match_operand 1 "const1_operand")
10986             (ior (match_test "TARGET_SHIFT1")
10987                  (match_test "optimize_function_for_size_p (cfun)")))
10988        (const_string "0")
10989        (const_string "*")))
10990    (set_attr "mode" "QI")])
10992 (define_split
10993  [(set (match_operand:HI 0 "register_operand")
10994        (any_rotate:HI (match_dup 0) (const_int 8)))
10995   (clobber (reg:CC FLAGS_REG))]
10996  "reload_completed
10997   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10998  [(parallel [(set (strict_low_part (match_dup 0))
10999                   (bswap:HI (match_dup 0)))
11000              (clobber (reg:CC FLAGS_REG))])])
11002 ;; Bit set / bit test instructions
11004 ;; %%% bts, btr, btc
11006 ;; These instructions are *slow* when applied to memory.
11008 (define_code_attr btsc [(ior "bts") (xor "btc")])
11010 (define_insn "*<btsc><mode>"
11011   [(set (match_operand:SWI48 0 "register_operand" "=r")
11012         (any_or:SWI48
11013           (ashift:SWI48 (const_int 1)
11014                         (match_operand:QI 2 "register_operand" "r"))
11015           (match_operand:SWI48 1 "register_operand" "0")))
11016    (clobber (reg:CC FLAGS_REG))]
11017   "TARGET_USE_BT"
11018   "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11019   [(set_attr "type" "alu1")
11020    (set_attr "prefix_0f" "1")
11021    (set_attr "znver1_decode" "double")
11022    (set_attr "mode" "<MODE>")])
11024 ;; Avoid useless masking of count operand.
11025 (define_insn_and_split "*<btsc><mode>_mask"
11026   [(set (match_operand:SWI48 0 "register_operand")
11027         (any_or:SWI48
11028           (ashift:SWI48
11029             (const_int 1)
11030             (subreg:QI
11031               (and:SI
11032                 (match_operand:SI 1 "register_operand")
11033                 (match_operand:SI 2 "const_int_operand")) 0))
11034           (match_operand:SWI48 3 "register_operand")))
11035    (clobber (reg:CC FLAGS_REG))]
11036   "TARGET_USE_BT
11037    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11038       == GET_MODE_BITSIZE (<MODE>mode)-1
11039    && can_create_pseudo_p ()"
11040   "#"
11041   "&& 1"
11042   [(parallel
11043      [(set (match_dup 0)
11044            (any_or:SWI48
11045              (ashift:SWI48 (const_int 1)
11046                            (match_dup 1))
11047              (match_dup 3)))
11048       (clobber (reg:CC FLAGS_REG))])]
11049   "operands[1] = gen_lowpart (QImode, operands[1]);")
11051 (define_insn "*btr<mode>"
11052   [(set (match_operand:SWI48 0 "register_operand" "=r")
11053         (and:SWI48
11054           (rotate:SWI48 (const_int -2)
11055                         (match_operand:QI 2 "register_operand" "r"))
11056         (match_operand:SWI48 1 "register_operand" "0")))
11057    (clobber (reg:CC FLAGS_REG))]
11058   "TARGET_USE_BT"
11059   "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11060   [(set_attr "type" "alu1")
11061    (set_attr "prefix_0f" "1")
11062    (set_attr "znver1_decode" "double")
11063    (set_attr "mode" "<MODE>")])
11065 ;; Avoid useless masking of count operand.
11066 (define_insn_and_split "*btr<mode>_mask"
11067   [(set (match_operand:SWI48 0 "register_operand")
11068         (and:SWI48
11069           (rotate:SWI48
11070             (const_int -2)
11071             (subreg:QI
11072               (and:SI
11073                 (match_operand:SI 1 "register_operand")
11074                 (match_operand:SI 2 "const_int_operand")) 0))
11075           (match_operand:SWI48 3 "register_operand")))
11076    (clobber (reg:CC FLAGS_REG))]
11077   "TARGET_USE_BT
11078    && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11079       == GET_MODE_BITSIZE (<MODE>mode)-1
11080    && can_create_pseudo_p ()"
11081   "#"
11082   "&& 1"
11083   [(parallel
11084      [(set (match_dup 0)
11085            (and:SWI48
11086              (rotate:SWI48 (const_int -2)
11087                            (match_dup 1))
11088              (match_dup 3)))
11089       (clobber (reg:CC FLAGS_REG))])]
11090   "operands[1] = gen_lowpart (QImode, operands[1]);")
11092 ;; These instructions are never faster than the corresponding
11093 ;; and/ior/xor operations when using immediate operand, so with
11094 ;; 32-bit there's no point.  But in 64-bit, we can't hold the
11095 ;; relevant immediates within the instruction itself, so operating
11096 ;; on bits in the high 32-bits of a register becomes easier.
11098 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11099 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11100 ;; negdf respectively, so they can never be disabled entirely.
11102 (define_insn "*btsq_imm"
11103   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11104                          (const_int 1)
11105                          (match_operand 1 "const_0_to_63_operand" "J"))
11106         (const_int 1))
11107    (clobber (reg:CC FLAGS_REG))]
11108   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11109   "bts{q}\t{%1, %0|%0, %1}"
11110   [(set_attr "type" "alu1")
11111    (set_attr "prefix_0f" "1")
11112    (set_attr "znver1_decode" "double")
11113    (set_attr "mode" "DI")])
11115 (define_insn "*btrq_imm"
11116   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11117                          (const_int 1)
11118                          (match_operand 1 "const_0_to_63_operand" "J"))
11119         (const_int 0))
11120    (clobber (reg:CC FLAGS_REG))]
11121   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11122   "btr{q}\t{%1, %0|%0, %1}"
11123   [(set_attr "type" "alu1")
11124    (set_attr "prefix_0f" "1")
11125    (set_attr "znver1_decode" "double")
11126    (set_attr "mode" "DI")])
11128 (define_insn "*btcq_imm"
11129   [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11130                          (const_int 1)
11131                          (match_operand 1 "const_0_to_63_operand" "J"))
11132         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11133    (clobber (reg:CC FLAGS_REG))]
11134   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11135   "btc{q}\t{%1, %0|%0, %1}"
11136   [(set_attr "type" "alu1")
11137    (set_attr "prefix_0f" "1")
11138    (set_attr "znver1_decode" "double")
11139    (set_attr "mode" "DI")])
11141 ;; Allow Nocona to avoid these instructions if a register is available.
11143 (define_peephole2
11144   [(match_scratch:DI 2 "r")
11145    (parallel [(set (zero_extract:DI
11146                      (match_operand:DI 0 "nonimmediate_operand")
11147                      (const_int 1)
11148                      (match_operand 1 "const_0_to_63_operand"))
11149                    (const_int 1))
11150               (clobber (reg:CC FLAGS_REG))])]
11151   "TARGET_64BIT && !TARGET_USE_BT"
11152   [(parallel [(set (match_dup 0)
11153                    (ior:DI (match_dup 0) (match_dup 3)))
11154               (clobber (reg:CC FLAGS_REG))])]
11156   int i = INTVAL (operands[1]);
11158   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11160   if (!x86_64_immediate_operand (operands[3], DImode))
11161     {
11162       emit_move_insn (operands[2], operands[3]);
11163       operands[3] = operands[2];
11164     }
11167 (define_peephole2
11168   [(match_scratch:DI 2 "r")
11169    (parallel [(set (zero_extract:DI
11170                      (match_operand:DI 0 "nonimmediate_operand")
11171                      (const_int 1)
11172                      (match_operand 1 "const_0_to_63_operand"))
11173                    (const_int 0))
11174               (clobber (reg:CC FLAGS_REG))])]
11175   "TARGET_64BIT && !TARGET_USE_BT"
11176   [(parallel [(set (match_dup 0)
11177                    (and:DI (match_dup 0) (match_dup 3)))
11178               (clobber (reg:CC FLAGS_REG))])]
11180   int i = INTVAL (operands[1]);
11182   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11184   if (!x86_64_immediate_operand (operands[3], DImode))
11185     {
11186       emit_move_insn (operands[2], operands[3]);
11187       operands[3] = operands[2];
11188     }
11191 (define_peephole2
11192   [(match_scratch:DI 2 "r")
11193    (parallel [(set (zero_extract:DI
11194                      (match_operand:DI 0 "nonimmediate_operand")
11195                      (const_int 1)
11196                      (match_operand 1 "const_0_to_63_operand"))
11197               (not:DI (zero_extract:DI
11198                         (match_dup 0) (const_int 1) (match_dup 1))))
11199               (clobber (reg:CC FLAGS_REG))])]
11200   "TARGET_64BIT && !TARGET_USE_BT"
11201   [(parallel [(set (match_dup 0)
11202                    (xor:DI (match_dup 0) (match_dup 3)))
11203               (clobber (reg:CC FLAGS_REG))])]
11205   int i = INTVAL (operands[1]);
11207   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11209   if (!x86_64_immediate_operand (operands[3], DImode))
11210     {
11211       emit_move_insn (operands[2], operands[3]);
11212       operands[3] = operands[2];
11213     }
11216 ;; %%% bt
11218 (define_insn "*bt<mode>"
11219   [(set (reg:CCC FLAGS_REG)
11220         (compare:CCC
11221           (zero_extract:SWI48
11222             (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11223             (const_int 1)
11224             (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11225           (const_int 0)))]
11226   ""
11228   switch (get_attr_mode (insn))
11229     {
11230     case MODE_SI:
11231       return "bt{l}\t{%1, %k0|%k0, %1}";
11233     case MODE_DI:
11234       return "bt{q}\t{%q1, %0|%0, %q1}";
11236     default:
11237       gcc_unreachable ();
11238     }
11240   [(set_attr "type" "alu1")
11241    (set_attr "prefix_0f" "1")
11242    (set (attr "mode")
11243         (if_then_else
11244           (and (match_test "CONST_INT_P (operands[1])")
11245                (match_test "INTVAL (operands[1]) < 32"))
11246           (const_string "SI")
11247           (const_string "<MODE>")))])
11249 (define_insn_and_split "*jcc_bt<mode>"
11250   [(set (pc)
11251         (if_then_else (match_operator 0 "bt_comparison_operator"
11252                         [(zero_extract:SWI48
11253                            (match_operand:SWI48 1 "nonimmediate_operand")
11254                            (const_int 1)
11255                            (match_operand:SI 2 "nonmemory_operand"))
11256                          (const_int 0)])
11257                       (label_ref (match_operand 3))
11258                       (pc)))
11259    (clobber (reg:CC FLAGS_REG))]
11260   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11261    && (CONST_INT_P (operands[2])
11262        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11263           && INTVAL (operands[2])
11264                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11265        : !memory_operand (operands[1], <MODE>mode))
11266    && can_create_pseudo_p ()"
11267   "#"
11268   "&& 1"
11269   [(set (reg:CCC FLAGS_REG)
11270         (compare:CCC
11271           (zero_extract:SWI48
11272             (match_dup 1)
11273             (const_int 1)
11274             (match_dup 2))
11275           (const_int 0)))
11276    (set (pc)
11277         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11278                       (label_ref (match_dup 3))
11279                       (pc)))]
11281   operands[0] = shallow_copy_rtx (operands[0]);
11282   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11285 (define_insn_and_split "*jcc_bt<mode>_1"
11286   [(set (pc)
11287         (if_then_else (match_operator 0 "bt_comparison_operator"
11288                         [(zero_extract:SWI48
11289                            (match_operand:SWI48 1 "register_operand")
11290                            (const_int 1)
11291                            (zero_extend:SI
11292                              (match_operand:QI 2 "register_operand")))
11293                          (const_int 0)])
11294                       (label_ref (match_operand 3))
11295                       (pc)))
11296    (clobber (reg:CC FLAGS_REG))]
11297   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11298    && can_create_pseudo_p ()"
11299   "#"
11300   "&& 1"
11301   [(set (reg:CCC FLAGS_REG)
11302         (compare:CCC
11303           (zero_extract:SWI48
11304             (match_dup 1)
11305             (const_int 1)
11306             (match_dup 2))
11307           (const_int 0)))
11308    (set (pc)
11309         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11310                       (label_ref (match_dup 3))
11311                       (pc)))]
11313   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11314   operands[0] = shallow_copy_rtx (operands[0]);
11315   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11318 ;; Avoid useless masking of bit offset operand.
11319 (define_insn_and_split "*jcc_bt<mode>_mask"
11320   [(set (pc)
11321         (if_then_else (match_operator 0 "bt_comparison_operator"
11322                         [(zero_extract:SWI48
11323                            (match_operand:SWI48 1 "register_operand")
11324                            (const_int 1)
11325                            (and:SI
11326                              (match_operand:SI 2 "register_operand")
11327                              (match_operand 3 "const_int_operand")))])
11328                       (label_ref (match_operand 4))
11329                       (pc)))
11330    (clobber (reg:CC FLAGS_REG))]
11331   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11332    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11333       == GET_MODE_BITSIZE (<MODE>mode)-1
11334    && can_create_pseudo_p ()"
11335   "#"
11336   "&& 1"
11337   [(set (reg:CCC FLAGS_REG)
11338         (compare:CCC
11339           (zero_extract:SWI48
11340             (match_dup 1)
11341             (const_int 1)
11342             (match_dup 2))
11343           (const_int 0)))
11344    (set (pc)
11345         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11346                       (label_ref (match_dup 4))
11347                       (pc)))]
11349   operands[0] = shallow_copy_rtx (operands[0]);
11350   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11353 ;; Store-flag instructions.
11355 ;; For all sCOND expanders, also expand the compare or test insn that
11356 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11358 (define_insn_and_split "*setcc_di_1"
11359   [(set (match_operand:DI 0 "register_operand" "=q")
11360         (match_operator:DI 1 "ix86_comparison_operator"
11361           [(reg FLAGS_REG) (const_int 0)]))]
11362   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11363   "#"
11364   "&& reload_completed"
11365   [(set (match_dup 2) (match_dup 1))
11366    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11368   operands[1] = shallow_copy_rtx (operands[1]);
11369   PUT_MODE (operands[1], QImode);
11370   operands[2] = gen_lowpart (QImode, operands[0]);
11373 (define_insn_and_split "*setcc_si_1_and"
11374   [(set (match_operand:SI 0 "register_operand" "=q")
11375         (match_operator:SI 1 "ix86_comparison_operator"
11376           [(reg FLAGS_REG) (const_int 0)]))
11377    (clobber (reg:CC FLAGS_REG))]
11378   "!TARGET_PARTIAL_REG_STALL
11379    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11380   "#"
11381   "&& reload_completed"
11382   [(set (match_dup 2) (match_dup 1))
11383    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11384               (clobber (reg:CC FLAGS_REG))])]
11386   operands[1] = shallow_copy_rtx (operands[1]);
11387   PUT_MODE (operands[1], QImode);
11388   operands[2] = gen_lowpart (QImode, operands[0]);
11391 (define_insn_and_split "*setcc_si_1_movzbl"
11392   [(set (match_operand:SI 0 "register_operand" "=q")
11393         (match_operator:SI 1 "ix86_comparison_operator"
11394           [(reg FLAGS_REG) (const_int 0)]))]
11395   "!TARGET_PARTIAL_REG_STALL
11396    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11397   "#"
11398   "&& reload_completed"
11399   [(set (match_dup 2) (match_dup 1))
11400    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11402   operands[1] = shallow_copy_rtx (operands[1]);
11403   PUT_MODE (operands[1], QImode);
11404   operands[2] = gen_lowpart (QImode, operands[0]);
11407 (define_insn "*setcc_qi"
11408   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11409         (match_operator:QI 1 "ix86_comparison_operator"
11410           [(reg FLAGS_REG) (const_int 0)]))]
11411   ""
11412   "set%C1\t%0"
11413   [(set_attr "type" "setcc")
11414    (set_attr "mode" "QI")])
11416 (define_insn "*setcc_qi_slp"
11417   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11418         (match_operator:QI 1 "ix86_comparison_operator"
11419           [(reg FLAGS_REG) (const_int 0)]))]
11420   ""
11421   "set%C1\t%0"
11422   [(set_attr "type" "setcc")
11423    (set_attr "mode" "QI")])
11425 ;; In general it is not safe to assume too much about CCmode registers,
11426 ;; so simplify-rtx stops when it sees a second one.  Under certain
11427 ;; conditions this is safe on x86, so help combine not create
11429 ;;      seta    %al
11430 ;;      testb   %al, %al
11431 ;;      sete    %al
11433 (define_split
11434   [(set (match_operand:QI 0 "nonimmediate_operand")
11435         (ne:QI (match_operator 1 "ix86_comparison_operator"
11436                  [(reg FLAGS_REG) (const_int 0)])
11437             (const_int 0)))]
11438   ""
11439   [(set (match_dup 0) (match_dup 1))]
11441   operands[1] = shallow_copy_rtx (operands[1]);
11442   PUT_MODE (operands[1], QImode);
11445 (define_split
11446   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11447         (ne:QI (match_operator 1 "ix86_comparison_operator"
11448                  [(reg FLAGS_REG) (const_int 0)])
11449             (const_int 0)))]
11450   ""
11451   [(set (match_dup 0) (match_dup 1))]
11453   operands[1] = shallow_copy_rtx (operands[1]);
11454   PUT_MODE (operands[1], QImode);
11457 (define_split
11458   [(set (match_operand:QI 0 "nonimmediate_operand")
11459         (eq:QI (match_operator 1 "ix86_comparison_operator"
11460                  [(reg FLAGS_REG) (const_int 0)])
11461             (const_int 0)))]
11462   ""
11463   [(set (match_dup 0) (match_dup 1))]
11465   operands[1] = shallow_copy_rtx (operands[1]);
11466   PUT_MODE (operands[1], QImode);
11467   PUT_CODE (operands[1],
11468             ix86_reverse_condition (GET_CODE (operands[1]),
11469                                     GET_MODE (XEXP (operands[1], 0))));
11471   /* Make sure that (a) the CCmode we have for the flags is strong
11472      enough for the reversed compare or (b) we have a valid FP compare.  */
11473   if (! ix86_comparison_operator (operands[1], VOIDmode))
11474     FAIL;
11477 (define_split
11478   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11479         (eq:QI (match_operator 1 "ix86_comparison_operator"
11480                  [(reg FLAGS_REG) (const_int 0)])
11481             (const_int 0)))]
11482   ""
11483   [(set (match_dup 0) (match_dup 1))]
11485   operands[1] = shallow_copy_rtx (operands[1]);
11486   PUT_MODE (operands[1], QImode);
11487   PUT_CODE (operands[1],
11488             ix86_reverse_condition (GET_CODE (operands[1]),
11489                                     GET_MODE (XEXP (operands[1], 0))));
11491   /* Make sure that (a) the CCmode we have for the flags is strong
11492      enough for the reversed compare or (b) we have a valid FP compare.  */
11493   if (! ix86_comparison_operator (operands[1], VOIDmode))
11494     FAIL;
11497 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11498 ;; subsequent logical operations are used to imitate conditional moves.
11499 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11500 ;; it directly.
11502 (define_insn "setcc_<mode>_sse"
11503   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11504         (match_operator:MODEF 3 "sse_comparison_operator"
11505           [(match_operand:MODEF 1 "register_operand" "0,x")
11506            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11507   "SSE_FLOAT_MODE_P (<MODE>mode)"
11508   "@
11509    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11510    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11511   [(set_attr "isa" "noavx,avx")
11512    (set_attr "type" "ssecmp")
11513    (set_attr "length_immediate" "1")
11514    (set_attr "prefix" "orig,vex")
11515    (set_attr "mode" "<MODE>")])
11517 ;; Basic conditional jump instructions.
11518 ;; We ignore the overflow flag for signed branch instructions.
11520 (define_insn "*jcc_1"
11521   [(set (pc)
11522         (if_then_else (match_operator 1 "ix86_comparison_operator"
11523                                       [(reg FLAGS_REG) (const_int 0)])
11524                       (label_ref (match_operand 0))
11525                       (pc)))]
11526   ""
11527   "%!%+j%C1\t%l0"
11528   [(set_attr "type" "ibr")
11529    (set_attr "modrm" "0")
11530    (set (attr "length")
11531         (if_then_else
11532           (and (ge (minus (match_dup 0) (pc))
11533                    (const_int -126))
11534                (lt (minus (match_dup 0) (pc))
11535                    (const_int 128)))
11536           (const_int 2)
11537           (const_int 6)))
11538    (set_attr "maybe_prefix_bnd" "1")])
11540 (define_insn "*jcc_2"
11541   [(set (pc)
11542         (if_then_else (match_operator 1 "ix86_comparison_operator"
11543                                       [(reg FLAGS_REG) (const_int 0)])
11544                       (pc)
11545                       (label_ref (match_operand 0))))]
11546   ""
11547   "%!%+j%c1\t%l0"
11548   [(set_attr "type" "ibr")
11549    (set_attr "modrm" "0")
11550    (set (attr "length")
11551         (if_then_else
11552           (and (ge (minus (match_dup 0) (pc))
11553                    (const_int -126))
11554                (lt (minus (match_dup 0) (pc))
11555                    (const_int 128)))
11556           (const_int 2)
11557           (const_int 6)))
11558    (set_attr "maybe_prefix_bnd" "1")])
11560 ;; In general it is not safe to assume too much about CCmode registers,
11561 ;; so simplify-rtx stops when it sees a second one.  Under certain
11562 ;; conditions this is safe on x86, so help combine not create
11564 ;;      seta    %al
11565 ;;      testb   %al, %al
11566 ;;      je      Lfoo
11568 (define_split
11569   [(set (pc)
11570         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11571                                       [(reg FLAGS_REG) (const_int 0)])
11572                           (const_int 0))
11573                       (label_ref (match_operand 1))
11574                       (pc)))]
11575   ""
11576   [(set (pc)
11577         (if_then_else (match_dup 0)
11578                       (label_ref (match_dup 1))
11579                       (pc)))]
11581   operands[0] = shallow_copy_rtx (operands[0]);
11582   PUT_MODE (operands[0], VOIDmode);
11585 (define_split
11586   [(set (pc)
11587         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11588                                       [(reg FLAGS_REG) (const_int 0)])
11589                           (const_int 0))
11590                       (label_ref (match_operand 1))
11591                       (pc)))]
11592   ""
11593   [(set (pc)
11594         (if_then_else (match_dup 0)
11595                       (label_ref (match_dup 1))
11596                       (pc)))]
11598   operands[0] = shallow_copy_rtx (operands[0]);
11599   PUT_MODE (operands[0], VOIDmode);
11600   PUT_CODE (operands[0],
11601             ix86_reverse_condition (GET_CODE (operands[0]),
11602                                     GET_MODE (XEXP (operands[0], 0))));
11604   /* Make sure that (a) the CCmode we have for the flags is strong
11605      enough for the reversed compare or (b) we have a valid FP compare.  */
11606   if (! ix86_comparison_operator (operands[0], VOIDmode))
11607     FAIL;
11610 ;; Define combination compare-and-branch fp compare instructions to help
11611 ;; combine.
11613 (define_insn "*jcc<mode>_0_i387"
11614   [(set (pc)
11615         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11616                         [(match_operand:X87MODEF 1 "register_operand" "f")
11617                          (match_operand:X87MODEF 2 "const0_operand")])
11618           (label_ref (match_operand 3))
11619           (pc)))
11620    (clobber (reg:CCFP FPSR_REG))
11621    (clobber (reg:CCFP FLAGS_REG))
11622    (clobber (match_scratch:HI 4 "=a"))]
11623   "TARGET_80387 && !TARGET_CMOVE"
11624   "#")
11626 (define_insn "*jcc<mode>_0_r_i387"
11627   [(set (pc)
11628         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11629                         [(match_operand:X87MODEF 1 "register_operand" "f")
11630                          (match_operand:X87MODEF 2 "const0_operand")])
11631           (pc)
11632           (label_ref (match_operand 3))))
11633    (clobber (reg:CCFP FPSR_REG))
11634    (clobber (reg:CCFP FLAGS_REG))
11635    (clobber (match_scratch:HI 4 "=a"))]
11636   "TARGET_80387 && !TARGET_CMOVE"
11637   "#")
11639 (define_insn "*jccxf_i387"
11640   [(set (pc)
11641         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11642                         [(match_operand:XF 1 "register_operand" "f")
11643                          (match_operand:XF 2 "register_operand" "f")])
11644           (label_ref (match_operand 3))
11645           (pc)))
11646    (clobber (reg:CCFP FPSR_REG))
11647    (clobber (reg:CCFP FLAGS_REG))
11648    (clobber (match_scratch:HI 4 "=a"))]
11649   "TARGET_80387 && !TARGET_CMOVE"
11650   "#")
11652 (define_insn "*jccxf_r_i387"
11653   [(set (pc)
11654         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11655                         [(match_operand:XF 1 "register_operand" "f")
11656                          (match_operand:XF 2 "register_operand" "f")])
11657           (pc)
11658           (label_ref (match_operand 3))))
11659    (clobber (reg:CCFP FPSR_REG))
11660    (clobber (reg:CCFP FLAGS_REG))
11661    (clobber (match_scratch:HI 4 "=a"))]
11662   "TARGET_80387 && !TARGET_CMOVE"
11663   "#")
11665 (define_insn "*jcc<mode>_i387"
11666   [(set (pc)
11667         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11668                         [(match_operand:MODEF 1 "register_operand" "f")
11669                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11670           (label_ref (match_operand 3))
11671           (pc)))
11672    (clobber (reg:CCFP FPSR_REG))
11673    (clobber (reg:CCFP FLAGS_REG))
11674    (clobber (match_scratch:HI 4 "=a"))]
11675   "TARGET_80387 && !TARGET_CMOVE"
11676   "#")
11678 (define_insn "*jcc<mode>_r_i387"
11679   [(set (pc)
11680         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11681                         [(match_operand:MODEF 1 "register_operand" "f")
11682                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11683           (pc)
11684           (label_ref (match_operand 3))))
11685    (clobber (reg:CCFP FPSR_REG))
11686    (clobber (reg:CCFP FLAGS_REG))
11687    (clobber (match_scratch:HI 4 "=a"))]
11688   "TARGET_80387 && !TARGET_CMOVE"
11689   "#")
11691 (define_insn "*jccu<mode>_i387"
11692   [(set (pc)
11693         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11694                         [(match_operand:X87MODEF 1 "register_operand" "f")
11695                          (match_operand:X87MODEF 2 "register_operand" "f")])
11696           (label_ref (match_operand 3))
11697           (pc)))
11698    (clobber (reg:CCFP FPSR_REG))
11699    (clobber (reg:CCFP FLAGS_REG))
11700    (clobber (match_scratch:HI 4 "=a"))]
11701   "TARGET_80387 && !TARGET_CMOVE"
11702   "#")
11704 (define_insn "*jccu<mode>_r_i387"
11705   [(set (pc)
11706         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11707                         [(match_operand:X87MODEF 1 "register_operand" "f")
11708                          (match_operand:X87MODEF 2 "register_operand" "f")])
11709           (pc)
11710           (label_ref (match_operand 3))))
11711    (clobber (reg:CCFP FPSR_REG))
11712    (clobber (reg:CCFP FLAGS_REG))
11713    (clobber (match_scratch:HI 4 "=a"))]
11714   "TARGET_80387 && !TARGET_CMOVE"
11715   "#")
11717 (define_split
11718   [(set (pc)
11719         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11720                         [(match_operand:X87MODEF 1 "register_operand")
11721                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11722           (match_operand 3)
11723           (match_operand 4)))
11724    (clobber (reg:CCFP FPSR_REG))
11725    (clobber (reg:CCFP FLAGS_REG))]
11726   "TARGET_80387 && !TARGET_CMOVE
11727    && reload_completed"
11728   [(const_int 0)]
11730   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11731                         operands[3], operands[4], NULL_RTX);
11732   DONE;
11735 (define_split
11736   [(set (pc)
11737         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11738                         [(match_operand:X87MODEF 1 "register_operand")
11739                          (match_operand:X87MODEF 2 "general_operand")])
11740           (match_operand 3)
11741           (match_operand 4)))
11742    (clobber (reg:CCFP FPSR_REG))
11743    (clobber (reg:CCFP FLAGS_REG))
11744    (clobber (match_scratch:HI 5))]
11745   "TARGET_80387 && !TARGET_CMOVE
11746    && reload_completed"
11747   [(const_int 0)]
11749   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11750                         operands[3], operands[4], operands[5]);
11751   DONE;
11754 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11755 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11756 ;; with a precedence over other operators and is always put in the first
11757 ;; place. Swap condition and operands to match ficom instruction.
11759 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11760   [(set (pc)
11761         (if_then_else
11762           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11763             [(match_operator:X87MODEF 1 "float_operator"
11764               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11765              (match_operand:X87MODEF 3 "register_operand" "f")])
11766           (label_ref (match_operand 4))
11767           (pc)))
11768    (clobber (reg:CCFP FPSR_REG))
11769    (clobber (reg:CCFP FLAGS_REG))
11770    (clobber (match_scratch:HI 5 "=a"))]
11771   "TARGET_80387 && !TARGET_CMOVE
11772    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11773        || optimize_function_for_size_p (cfun))"
11774   "#")
11776 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11777   [(set (pc)
11778         (if_then_else
11779           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11780             [(match_operator:X87MODEF 1 "float_operator"
11781               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11782              (match_operand:X87MODEF 3 "register_operand" "f")])
11783           (pc)
11784           (label_ref (match_operand 4))))
11785    (clobber (reg:CCFP FPSR_REG))
11786    (clobber (reg:CCFP FLAGS_REG))
11787    (clobber (match_scratch:HI 5 "=a"))]
11788   "TARGET_80387 && !TARGET_CMOVE
11789    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11790        || optimize_function_for_size_p (cfun))"
11791   "#")
11793 (define_split
11794   [(set (pc)
11795         (if_then_else
11796           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11797             [(match_operator:X87MODEF 1 "float_operator"
11798               [(match_operand:SWI24 2 "memory_operand")])
11799              (match_operand:X87MODEF 3 "register_operand")])
11800           (match_operand 4)
11801           (match_operand 5)))
11802    (clobber (reg:CCFP FPSR_REG))
11803    (clobber (reg:CCFP FLAGS_REG))
11804    (clobber (match_scratch:HI 6))]
11805   "TARGET_80387 && !TARGET_CMOVE
11806    && reload_completed"
11807   [(const_int 0)]
11809   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11810                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11811                         operands[4], operands[5], operands[6]);
11812   DONE;
11815 ;; Unconditional and other jump instructions
11817 (define_insn "jump"
11818   [(set (pc)
11819         (label_ref (match_operand 0)))]
11820   ""
11821   "%!jmp\t%l0"
11822   [(set_attr "type" "ibr")
11823    (set_attr "modrm" "0")
11824    (set (attr "length")
11825         (if_then_else
11826           (and (ge (minus (match_dup 0) (pc))
11827                    (const_int -126))
11828                (lt (minus (match_dup 0) (pc))
11829                    (const_int 128)))
11830           (const_int 2)
11831           (const_int 5)))
11832    (set_attr "maybe_prefix_bnd" "1")])
11834 (define_expand "indirect_jump"
11835   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11836   ""
11838   if (TARGET_X32)
11839     operands[0] = convert_memory_address (word_mode, operands[0]);
11842 (define_insn "*indirect_jump"
11843   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11844   ""
11845   "%!jmp\t%A0"
11846   [(set_attr "type" "ibr")
11847    (set_attr "length_immediate" "0")
11848    (set_attr "maybe_prefix_bnd" "1")])
11850 (define_expand "tablejump"
11851   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11852               (use (label_ref (match_operand 1)))])]
11853   ""
11855   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11856      relative.  Convert the relative address to an absolute address.  */
11857   if (flag_pic)
11858     {
11859       rtx op0, op1;
11860       enum rtx_code code;
11862       /* We can't use @GOTOFF for text labels on VxWorks;
11863          see gotoff_operand.  */
11864       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11865         {
11866           code = PLUS;
11867           op0 = operands[0];
11868           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11869         }
11870       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11871         {
11872           code = PLUS;
11873           op0 = operands[0];
11874           op1 = pic_offset_table_rtx;
11875         }
11876       else
11877         {
11878           code = MINUS;
11879           op0 = pic_offset_table_rtx;
11880           op1 = operands[0];
11881         }
11883       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11884                                          OPTAB_DIRECT);
11885     }
11887   if (TARGET_X32)
11888     operands[0] = convert_memory_address (word_mode, operands[0]);
11891 (define_insn "*tablejump_1"
11892   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11893    (use (label_ref (match_operand 1)))]
11894   ""
11895   "%!jmp\t%A0"
11896   [(set_attr "type" "ibr")
11897    (set_attr "length_immediate" "0")
11898    (set_attr "maybe_prefix_bnd" "1")])
11900 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11902 (define_peephole2
11903   [(set (reg FLAGS_REG) (match_operand 0))
11904    (set (match_operand:QI 1 "register_operand")
11905         (match_operator:QI 2 "ix86_comparison_operator"
11906           [(reg FLAGS_REG) (const_int 0)]))
11907    (set (match_operand 3 "any_QIreg_operand")
11908         (zero_extend (match_dup 1)))]
11909   "(peep2_reg_dead_p (3, operands[1])
11910     || operands_match_p (operands[1], operands[3]))
11911    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11912    && peep2_regno_dead_p (0, FLAGS_REG)"
11913   [(set (match_dup 4) (match_dup 0))
11914    (set (strict_low_part (match_dup 5))
11915         (match_dup 2))]
11917   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11918   operands[5] = gen_lowpart (QImode, operands[3]);
11919   ix86_expand_clear (operands[3]);
11922 (define_peephole2
11923   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11924               (match_operand 4)])
11925    (set (match_operand:QI 1 "register_operand")
11926         (match_operator:QI 2 "ix86_comparison_operator"
11927           [(reg FLAGS_REG) (const_int 0)]))
11928    (set (match_operand 3 "any_QIreg_operand")
11929         (zero_extend (match_dup 1)))]
11930   "(peep2_reg_dead_p (3, operands[1])
11931     || operands_match_p (operands[1], operands[3]))
11932    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11933    && ! reg_set_p (operands[3], operands[4])
11934    && peep2_regno_dead_p (0, FLAGS_REG)"
11935   [(parallel [(set (match_dup 5) (match_dup 0))
11936               (match_dup 4)])
11937    (set (strict_low_part (match_dup 6))
11938         (match_dup 2))]
11940   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11941   operands[6] = gen_lowpart (QImode, operands[3]);
11942   ix86_expand_clear (operands[3]);
11945 ;; Similar, but match zero extend with andsi3.
11947 (define_peephole2
11948   [(set (reg FLAGS_REG) (match_operand 0))
11949    (set (match_operand:QI 1 "register_operand")
11950         (match_operator:QI 2 "ix86_comparison_operator"
11951           [(reg FLAGS_REG) (const_int 0)]))
11952    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11953                    (and:SI (match_dup 3) (const_int 255)))
11954               (clobber (reg:CC FLAGS_REG))])]
11955   "REGNO (operands[1]) == REGNO (operands[3])
11956    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11957    && peep2_regno_dead_p (0, FLAGS_REG)"
11958   [(set (match_dup 4) (match_dup 0))
11959    (set (strict_low_part (match_dup 5))
11960         (match_dup 2))]
11962   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11963   operands[5] = gen_lowpart (QImode, operands[3]);
11964   ix86_expand_clear (operands[3]);
11967 (define_peephole2
11968   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11969               (match_operand 4)])
11970    (set (match_operand:QI 1 "register_operand")
11971         (match_operator:QI 2 "ix86_comparison_operator"
11972           [(reg FLAGS_REG) (const_int 0)]))
11973    (parallel [(set (match_operand 3 "any_QIreg_operand")
11974                    (zero_extend (match_dup 1)))
11975               (clobber (reg:CC FLAGS_REG))])]
11976   "(peep2_reg_dead_p (3, operands[1])
11977     || operands_match_p (operands[1], operands[3]))
11978    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11979    && ! reg_set_p (operands[3], operands[4])
11980    && peep2_regno_dead_p (0, FLAGS_REG)"
11981   [(parallel [(set (match_dup 5) (match_dup 0))
11982               (match_dup 4)])
11983    (set (strict_low_part (match_dup 6))
11984         (match_dup 2))]
11986   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11987   operands[6] = gen_lowpart (QImode, operands[3]);
11988   ix86_expand_clear (operands[3]);
11991 ;; Call instructions.
11993 ;; The predicates normally associated with named expanders are not properly
11994 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11995 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11997 ;; P6 processors will jump to the address after the decrement when %esp
11998 ;; is used as a call operand, so they will execute return address as a code.
11999 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12001 ;; Register constraint for call instruction.
12002 (define_mode_attr c [(SI "l") (DI "r")])
12004 ;; Call subroutine returning no value.
12006 (define_expand "call"
12007   [(call (match_operand:QI 0)
12008          (match_operand 1))
12009    (use (match_operand 2))]
12010   ""
12012   ix86_expand_call (NULL, operands[0], operands[1],
12013                     operands[2], NULL, false);
12014   DONE;
12017 (define_expand "sibcall"
12018   [(call (match_operand:QI 0)
12019          (match_operand 1))
12020    (use (match_operand 2))]
12021   ""
12023   ix86_expand_call (NULL, operands[0], operands[1],
12024                     operands[2], NULL, true);
12025   DONE;
12028 (define_insn "*call"
12029   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12030          (match_operand 1))]
12031   "!SIBLING_CALL_P (insn)"
12032   "* return ix86_output_call_insn (insn, operands[0]);"
12033   [(set_attr "type" "call")])
12035 ;; This covers both call and sibcall since only GOT slot is allowed.
12036 (define_insn "*call_got_x32"
12037   [(call (mem:QI (zero_extend:DI
12038                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12039          (match_operand 1))]
12040   "TARGET_X32"
12042   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12043   return ix86_output_call_insn (insn, fnaddr);
12045   [(set_attr "type" "call")])
12047 ;; Since sibcall never returns, we can only use call-clobbered register
12048 ;; as GOT base.
12049 (define_insn "*sibcall_GOT_32"
12050   [(call (mem:QI
12051            (mem:SI (plus:SI
12052                      (match_operand:SI 0 "register_no_elim_operand" "U")
12053                      (match_operand:SI 1 "GOT32_symbol_operand"))))
12054          (match_operand 2))]
12055   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12057   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12058   fnaddr = gen_const_mem (SImode, fnaddr);
12059   return ix86_output_call_insn (insn, fnaddr);
12061   [(set_attr "type" "call")])
12063 (define_insn "*sibcall"
12064   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12065          (match_operand 1))]
12066   "SIBLING_CALL_P (insn)"
12067   "* return ix86_output_call_insn (insn, operands[0]);"
12068   [(set_attr "type" "call")])
12070 (define_insn "*sibcall_memory"
12071   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12072          (match_operand 1))
12073    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12074   "!TARGET_X32"
12075   "* return ix86_output_call_insn (insn, operands[0]);"
12076   [(set_attr "type" "call")])
12078 (define_peephole2
12079   [(set (match_operand:W 0 "register_operand")
12080         (match_operand:W 1 "memory_operand"))
12081    (call (mem:QI (match_dup 0))
12082          (match_operand 3))]
12083   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12084    && !reg_mentioned_p (operands[0],
12085                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12086   [(parallel [(call (mem:QI (match_dup 1))
12087                     (match_dup 3))
12088               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12090 (define_peephole2
12091   [(set (match_operand:W 0 "register_operand")
12092         (match_operand:W 1 "memory_operand"))
12093    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12094    (call (mem:QI (match_dup 0))
12095          (match_operand 3))]
12096   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12097    && !reg_mentioned_p (operands[0],
12098                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12099   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12100    (parallel [(call (mem:QI (match_dup 1))
12101                     (match_dup 3))
12102               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12104 (define_expand "call_pop"
12105   [(parallel [(call (match_operand:QI 0)
12106                     (match_operand:SI 1))
12107               (set (reg:SI SP_REG)
12108                    (plus:SI (reg:SI SP_REG)
12109                             (match_operand:SI 3)))])]
12110   "!TARGET_64BIT"
12112   ix86_expand_call (NULL, operands[0], operands[1],
12113                     operands[2], operands[3], false);
12114   DONE;
12117 (define_insn "*call_pop"
12118   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12119          (match_operand 1))
12120    (set (reg:SI SP_REG)
12121         (plus:SI (reg:SI SP_REG)
12122                  (match_operand:SI 2 "immediate_operand" "i")))]
12123   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12124   "* return ix86_output_call_insn (insn, operands[0]);"
12125   [(set_attr "type" "call")])
12127 (define_insn "*sibcall_pop"
12128   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12129          (match_operand 1))
12130    (set (reg:SI SP_REG)
12131         (plus:SI (reg:SI SP_REG)
12132                  (match_operand:SI 2 "immediate_operand" "i")))]
12133   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12134   "* return ix86_output_call_insn (insn, operands[0]);"
12135   [(set_attr "type" "call")])
12137 (define_insn "*sibcall_pop_memory"
12138   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12139          (match_operand 1))
12140    (set (reg:SI SP_REG)
12141         (plus:SI (reg:SI SP_REG)
12142                  (match_operand:SI 2 "immediate_operand" "i")))
12143    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12144   "!TARGET_64BIT"
12145   "* return ix86_output_call_insn (insn, operands[0]);"
12146   [(set_attr "type" "call")])
12148 (define_peephole2
12149   [(set (match_operand:SI 0 "register_operand")
12150         (match_operand:SI 1 "memory_operand"))
12151    (parallel [(call (mem:QI (match_dup 0))
12152                     (match_operand 3))
12153               (set (reg:SI SP_REG)
12154                    (plus:SI (reg:SI SP_REG)
12155                             (match_operand:SI 4 "immediate_operand")))])]
12156   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12157    && !reg_mentioned_p (operands[0],
12158                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12159   [(parallel [(call (mem:QI (match_dup 1))
12160                     (match_dup 3))
12161               (set (reg:SI SP_REG)
12162                    (plus:SI (reg:SI SP_REG)
12163                             (match_dup 4)))
12164               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12166 (define_peephole2
12167   [(set (match_operand:SI 0 "register_operand")
12168         (match_operand:SI 1 "memory_operand"))
12169    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12170    (parallel [(call (mem:QI (match_dup 0))
12171                     (match_operand 3))
12172               (set (reg:SI SP_REG)
12173                    (plus:SI (reg:SI SP_REG)
12174                             (match_operand:SI 4 "immediate_operand")))])]
12175   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12176    && !reg_mentioned_p (operands[0],
12177                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12178   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12179    (parallel [(call (mem:QI (match_dup 1))
12180                     (match_dup 3))
12181               (set (reg:SI SP_REG)
12182                    (plus:SI (reg:SI SP_REG)
12183                             (match_dup 4)))
12184               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12186 ;; Combining simple memory jump instruction
12188 (define_peephole2
12189   [(set (match_operand:W 0 "register_operand")
12190         (match_operand:W 1 "memory_operand"))
12191    (set (pc) (match_dup 0))]
12192   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12193   [(set (pc) (match_dup 1))])
12195 ;; Call subroutine, returning value in operand 0
12197 (define_expand "call_value"
12198   [(set (match_operand 0)
12199         (call (match_operand:QI 1)
12200               (match_operand 2)))
12201    (use (match_operand 3))]
12202   ""
12204   ix86_expand_call (operands[0], operands[1], operands[2],
12205                     operands[3], NULL, false);
12206   DONE;
12209 (define_expand "sibcall_value"
12210   [(set (match_operand 0)
12211         (call (match_operand:QI 1)
12212               (match_operand 2)))
12213    (use (match_operand 3))]
12214   ""
12216   ix86_expand_call (operands[0], operands[1], operands[2],
12217                     operands[3], NULL, true);
12218   DONE;
12221 (define_insn "*call_value"
12222   [(set (match_operand 0)
12223         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12224               (match_operand 2)))]
12225   "!SIBLING_CALL_P (insn)"
12226   "* return ix86_output_call_insn (insn, operands[1]);"
12227   [(set_attr "type" "callv")])
12229 ;; This covers both call and sibcall since only GOT slot is allowed.
12230 (define_insn "*call_value_got_x32"
12231   [(set (match_operand 0)
12232         (call (mem:QI
12233                 (zero_extend:DI
12234                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12235               (match_operand 2)))]
12236   "TARGET_X32"
12238   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12239   return ix86_output_call_insn (insn, fnaddr);
12241   [(set_attr "type" "callv")])
12243 ;; Since sibcall never returns, we can only use call-clobbered register
12244 ;; as GOT base.
12245 (define_insn "*sibcall_value_GOT_32"
12246   [(set (match_operand 0)
12247         (call (mem:QI
12248                 (mem:SI (plus:SI
12249                           (match_operand:SI 1 "register_no_elim_operand" "U")
12250                           (match_operand:SI 2 "GOT32_symbol_operand"))))
12251          (match_operand 3)))]
12252   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12254   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12255   fnaddr = gen_const_mem (SImode, fnaddr);
12256   return ix86_output_call_insn (insn, fnaddr);
12258   [(set_attr "type" "callv")])
12260 (define_insn "*sibcall_value"
12261   [(set (match_operand 0)
12262         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12263               (match_operand 2)))]
12264   "SIBLING_CALL_P (insn)"
12265   "* return ix86_output_call_insn (insn, operands[1]);"
12266   [(set_attr "type" "callv")])
12268 (define_insn "*sibcall_value_memory"
12269   [(set (match_operand 0)
12270         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12271               (match_operand 2)))
12272    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12273   "!TARGET_X32"
12274   "* return ix86_output_call_insn (insn, operands[1]);"
12275   [(set_attr "type" "callv")])
12277 (define_peephole2
12278   [(set (match_operand:W 0 "register_operand")
12279         (match_operand:W 1 "memory_operand"))
12280    (set (match_operand 2)
12281    (call (mem:QI (match_dup 0))
12282                  (match_operand 3)))]
12283   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12284    && !reg_mentioned_p (operands[0],
12285                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12286   [(parallel [(set (match_dup 2)
12287                    (call (mem:QI (match_dup 1))
12288                          (match_dup 3)))
12289               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12291 (define_peephole2
12292   [(set (match_operand:W 0 "register_operand")
12293         (match_operand:W 1 "memory_operand"))
12294    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12295    (set (match_operand 2)
12296         (call (mem:QI (match_dup 0))
12297               (match_operand 3)))]
12298   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12299    && !reg_mentioned_p (operands[0],
12300                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12301   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12302    (parallel [(set (match_dup 2)
12303                    (call (mem:QI (match_dup 1))
12304                          (match_dup 3)))
12305               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12307 (define_expand "call_value_pop"
12308   [(parallel [(set (match_operand 0)
12309                    (call (match_operand:QI 1)
12310                          (match_operand:SI 2)))
12311               (set (reg:SI SP_REG)
12312                    (plus:SI (reg:SI SP_REG)
12313                             (match_operand:SI 4)))])]
12314   "!TARGET_64BIT"
12316   ix86_expand_call (operands[0], operands[1], operands[2],
12317                     operands[3], operands[4], false);
12318   DONE;
12321 (define_insn "*call_value_pop"
12322   [(set (match_operand 0)
12323         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12324               (match_operand 2)))
12325    (set (reg:SI SP_REG)
12326         (plus:SI (reg:SI SP_REG)
12327                  (match_operand:SI 3 "immediate_operand" "i")))]
12328   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12329   "* return ix86_output_call_insn (insn, operands[1]);"
12330   [(set_attr "type" "callv")])
12332 (define_insn "*sibcall_value_pop"
12333   [(set (match_operand 0)
12334         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12335               (match_operand 2)))
12336    (set (reg:SI SP_REG)
12337         (plus:SI (reg:SI SP_REG)
12338                  (match_operand:SI 3 "immediate_operand" "i")))]
12339   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12340   "* return ix86_output_call_insn (insn, operands[1]);"
12341   [(set_attr "type" "callv")])
12343 (define_insn "*sibcall_value_pop_memory"
12344   [(set (match_operand 0)
12345         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12346               (match_operand 2)))
12347    (set (reg:SI SP_REG)
12348         (plus:SI (reg:SI SP_REG)
12349                  (match_operand:SI 3 "immediate_operand" "i")))
12350    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12351   "!TARGET_64BIT"
12352   "* return ix86_output_call_insn (insn, operands[1]);"
12353   [(set_attr "type" "callv")])
12355 (define_peephole2
12356   [(set (match_operand:SI 0 "register_operand")
12357         (match_operand:SI 1 "memory_operand"))
12358    (parallel [(set (match_operand 2)
12359                    (call (mem:QI (match_dup 0))
12360                          (match_operand 3)))
12361               (set (reg:SI SP_REG)
12362                    (plus:SI (reg:SI SP_REG)
12363                             (match_operand:SI 4 "immediate_operand")))])]
12364   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12365    && !reg_mentioned_p (operands[0],
12366                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12367   [(parallel [(set (match_dup 2)
12368                    (call (mem:QI (match_dup 1))
12369                          (match_dup 3)))
12370               (set (reg:SI SP_REG)
12371                    (plus:SI (reg:SI SP_REG)
12372                             (match_dup 4)))
12373               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12375 (define_peephole2
12376   [(set (match_operand:SI 0 "register_operand")
12377         (match_operand:SI 1 "memory_operand"))
12378    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12379    (parallel [(set (match_operand 2)
12380                    (call (mem:QI (match_dup 0))
12381                          (match_operand 3)))
12382               (set (reg:SI SP_REG)
12383                    (plus:SI (reg:SI SP_REG)
12384                             (match_operand:SI 4 "immediate_operand")))])]
12385   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12386    && !reg_mentioned_p (operands[0],
12387                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12388   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12389    (parallel [(set (match_dup 2)
12390                    (call (mem:QI (match_dup 1))
12391                          (match_dup 3)))
12392               (set (reg:SI SP_REG)
12393                    (plus:SI (reg:SI SP_REG)
12394                             (match_dup 4)))
12395               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12397 ;; Call subroutine returning any type.
12399 (define_expand "untyped_call"
12400   [(parallel [(call (match_operand 0)
12401                     (const_int 0))
12402               (match_operand 1)
12403               (match_operand 2)])]
12404   ""
12406   int i;
12408   /* In order to give reg-stack an easier job in validating two
12409      coprocessor registers as containing a possible return value,
12410      simply pretend the untyped call returns a complex long double
12411      value. 
12413      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12414      and should have the default ABI.  */
12416   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12417                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12418                     operands[0], const0_rtx,
12419                     GEN_INT ((TARGET_64BIT
12420                               ? (ix86_abi == SYSV_ABI
12421                                  ? X86_64_SSE_REGPARM_MAX
12422                                  : X86_64_MS_SSE_REGPARM_MAX)
12423                               : X86_32_SSE_REGPARM_MAX)
12424                              - 1),
12425                     NULL, false);
12427   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12428     {
12429       rtx set = XVECEXP (operands[2], 0, i);
12430       emit_move_insn (SET_DEST (set), SET_SRC (set));
12431     }
12433   /* The optimizer does not know that the call sets the function value
12434      registers we stored in the result block.  We avoid problems by
12435      claiming that all hard registers are used and clobbered at this
12436      point.  */
12437   emit_insn (gen_blockage ());
12439   DONE;
12442 ;; Prologue and epilogue instructions
12444 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12445 ;; all of memory.  This blocks insns from being moved across this point.
12447 (define_insn "blockage"
12448   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12449   ""
12450   ""
12451   [(set_attr "length" "0")])
12453 ;; Do not schedule instructions accessing memory across this point.
12455 (define_expand "memory_blockage"
12456   [(set (match_dup 0)
12457         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12458   ""
12460   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12461   MEM_VOLATILE_P (operands[0]) = 1;
12464 (define_insn "*memory_blockage"
12465   [(set (match_operand:BLK 0)
12466         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12467   ""
12468   ""
12469   [(set_attr "length" "0")])
12471 ;; As USE insns aren't meaningful after reload, this is used instead
12472 ;; to prevent deleting instructions setting registers for PIC code
12473 (define_insn "prologue_use"
12474   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12475   ""
12476   ""
12477   [(set_attr "length" "0")])
12479 ;; Insn emitted into the body of a function to return from a function.
12480 ;; This is only done if the function's epilogue is known to be simple.
12481 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12483 (define_expand "return"
12484   [(simple_return)]
12485   "ix86_can_use_return_insn_p ()"
12487   if (crtl->args.pops_args)
12488     {
12489       rtx popc = GEN_INT (crtl->args.pops_args);
12490       emit_jump_insn (gen_simple_return_pop_internal (popc));
12491       DONE;
12492     }
12495 ;; We need to disable this for TARGET_SEH, as otherwise
12496 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12497 ;; the maximum size of prologue in unwind information.
12498 ;; Also disallow shrink-wrapping if using stack slot to pass the
12499 ;; static chain pointer - the first instruction has to be pushl %esi
12500 ;; and it can't be moved around, as we use alternate entry points
12501 ;; in that case.
12503 (define_expand "simple_return"
12504   [(simple_return)]
12505   "!TARGET_SEH && !ix86_static_chain_on_stack"
12507   if (crtl->args.pops_args)
12508     {
12509       rtx popc = GEN_INT (crtl->args.pops_args);
12510       emit_jump_insn (gen_simple_return_pop_internal (popc));
12511       DONE;
12512     }
12515 (define_insn "simple_return_internal"
12516   [(simple_return)]
12517   "reload_completed"
12518   "%!ret"
12519   [(set_attr "length" "1")
12520    (set_attr "atom_unit" "jeu")
12521    (set_attr "length_immediate" "0")
12522    (set_attr "modrm" "0")
12523    (set_attr "maybe_prefix_bnd" "1")])
12525 (define_insn "interrupt_return"
12526   [(simple_return)
12527    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12528   "reload_completed"
12530   return TARGET_64BIT ? "iretq" : "iret";
12533 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12534 ;; instruction Athlon and K8 have.
12536 (define_insn "simple_return_internal_long"
12537   [(simple_return)
12538    (unspec [(const_int 0)] UNSPEC_REP)]
12539   "reload_completed"
12541   if (ix86_bnd_prefixed_insn_p (insn))
12542     return "%!ret";
12544   return "rep%; ret";
12546   [(set_attr "length" "2")
12547    (set_attr "atom_unit" "jeu")
12548    (set_attr "length_immediate" "0")
12549    (set_attr "prefix_rep" "1")
12550    (set_attr "modrm" "0")])
12552 (define_insn "simple_return_pop_internal"
12553   [(simple_return)
12554    (use (match_operand:SI 0 "const_int_operand"))]
12555   "reload_completed"
12556   "%!ret\t%0"
12557   [(set_attr "length" "3")
12558    (set_attr "atom_unit" "jeu")
12559    (set_attr "length_immediate" "2")
12560    (set_attr "modrm" "0")
12561    (set_attr "maybe_prefix_bnd" "1")])
12563 (define_insn "simple_return_indirect_internal"
12564   [(simple_return)
12565    (use (match_operand:SI 0 "register_operand" "r"))]
12566   "reload_completed"
12567   "%!jmp\t%A0"
12568   [(set_attr "type" "ibr")
12569    (set_attr "length_immediate" "0")
12570    (set_attr "maybe_prefix_bnd" "1")])
12572 (define_insn "nop"
12573   [(const_int 0)]
12574   ""
12575   "nop"
12576   [(set_attr "length" "1")
12577    (set_attr "length_immediate" "0")
12578    (set_attr "modrm" "0")])
12580 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12581 (define_insn "nops"
12582   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12583                     UNSPECV_NOPS)]
12584   "reload_completed"
12586   int num = INTVAL (operands[0]);
12588   gcc_assert (IN_RANGE (num, 1, 8));
12590   while (num--)
12591     fputs ("\tnop\n", asm_out_file);
12593   return "";
12595   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12596    (set_attr "length_immediate" "0")
12597    (set_attr "modrm" "0")])
12599 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12600 ;; branch prediction penalty for the third jump in a 16-byte
12601 ;; block on K8.
12603 (define_insn "pad"
12604   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12605   ""
12607 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12608   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12609 #else
12610   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12611      The align insn is used to avoid 3 jump instructions in the row to improve
12612      branch prediction and the benefits hardly outweigh the cost of extra 8
12613      nops on the average inserted by full alignment pseudo operation.  */
12614 #endif
12615   return "";
12617   [(set_attr "length" "16")])
12619 (define_expand "prologue"
12620   [(const_int 0)]
12621   ""
12622   "ix86_expand_prologue (); DONE;")
12624 (define_expand "set_got"
12625   [(parallel
12626      [(set (match_operand:SI 0 "register_operand")
12627            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12628       (clobber (reg:CC FLAGS_REG))])]
12629   "!TARGET_64BIT"
12631   if (flag_pic && !TARGET_VXWORKS_RTP)
12632     ix86_pc_thunk_call_expanded = true;
12635 (define_insn "*set_got"
12636   [(set (match_operand:SI 0 "register_operand" "=r")
12637         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12638    (clobber (reg:CC FLAGS_REG))]
12639   "!TARGET_64BIT"
12640   "* return output_set_got (operands[0], NULL_RTX);"
12641   [(set_attr "type" "multi")
12642    (set_attr "length" "12")])
12644 (define_expand "set_got_labelled"
12645   [(parallel
12646      [(set (match_operand:SI 0 "register_operand")
12647            (unspec:SI [(label_ref (match_operand 1))]
12648                       UNSPEC_SET_GOT))
12649       (clobber (reg:CC FLAGS_REG))])]
12650   "!TARGET_64BIT"
12652   if (flag_pic && !TARGET_VXWORKS_RTP)
12653     ix86_pc_thunk_call_expanded = true;
12656 (define_insn "*set_got_labelled"
12657   [(set (match_operand:SI 0 "register_operand" "=r")
12658         (unspec:SI [(label_ref (match_operand 1))]
12659          UNSPEC_SET_GOT))
12660    (clobber (reg:CC FLAGS_REG))]
12661   "!TARGET_64BIT"
12662   "* return output_set_got (operands[0], operands[1]);"
12663   [(set_attr "type" "multi")
12664    (set_attr "length" "12")])
12666 (define_insn "set_got_rex64"
12667   [(set (match_operand:DI 0 "register_operand" "=r")
12668         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12669   "TARGET_64BIT"
12670   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12671   [(set_attr "type" "lea")
12672    (set_attr "length_address" "4")
12673    (set_attr "modrm_class" "unknown")
12674    (set_attr "mode" "DI")])
12676 (define_insn "set_rip_rex64"
12677   [(set (match_operand:DI 0 "register_operand" "=r")
12678         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12679   "TARGET_64BIT"
12680   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12681   [(set_attr "type" "lea")
12682    (set_attr "length_address" "4")
12683    (set_attr "mode" "DI")])
12685 (define_insn "set_got_offset_rex64"
12686   [(set (match_operand:DI 0 "register_operand" "=r")
12687         (unspec:DI
12688           [(label_ref (match_operand 1))]
12689           UNSPEC_SET_GOT_OFFSET))]
12690   "TARGET_LP64"
12691   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12692   [(set_attr "type" "imov")
12693    (set_attr "length_immediate" "0")
12694    (set_attr "length_address" "8")
12695    (set_attr "mode" "DI")])
12697 (define_expand "epilogue"
12698   [(const_int 0)]
12699   ""
12700   "ix86_expand_epilogue (1); DONE;")
12702 (define_expand "sibcall_epilogue"
12703   [(const_int 0)]
12704   ""
12705   "ix86_expand_epilogue (0); DONE;")
12707 (define_expand "eh_return"
12708   [(use (match_operand 0 "register_operand"))]
12709   ""
12711   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12713   /* Tricky bit: we write the address of the handler to which we will
12714      be returning into someone else's stack frame, one word below the
12715      stack address we wish to restore.  */
12716   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12717   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12718   tmp = gen_rtx_MEM (Pmode, tmp);
12719   emit_move_insn (tmp, ra);
12721   emit_jump_insn (gen_eh_return_internal ());
12722   emit_barrier ();
12723   DONE;
12726 (define_insn_and_split "eh_return_internal"
12727   [(eh_return)]
12728   ""
12729   "#"
12730   "epilogue_completed"
12731   [(const_int 0)]
12732   "ix86_expand_epilogue (2); DONE;")
12734 (define_insn "leave"
12735   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12736    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12737    (clobber (mem:BLK (scratch)))]
12738   "!TARGET_64BIT"
12739   "leave"
12740   [(set_attr "type" "leave")])
12742 (define_insn "leave_rex64"
12743   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12744    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12745    (clobber (mem:BLK (scratch)))]
12746   "TARGET_64BIT"
12747   "leave"
12748   [(set_attr "type" "leave")])
12750 ;; Handle -fsplit-stack.
12752 (define_expand "split_stack_prologue"
12753   [(const_int 0)]
12754   ""
12756   ix86_expand_split_stack_prologue ();
12757   DONE;
12760 ;; In order to support the call/return predictor, we use a return
12761 ;; instruction which the middle-end doesn't see.
12762 (define_insn "split_stack_return"
12763   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12764                      UNSPECV_SPLIT_STACK_RETURN)]
12765   ""
12767   if (operands[0] == const0_rtx)
12768     return "ret";
12769   else
12770     return "ret\t%0";
12772   [(set_attr "atom_unit" "jeu")
12773    (set_attr "modrm" "0")
12774    (set (attr "length")
12775         (if_then_else (match_operand:SI 0 "const0_operand")
12776                       (const_int 1)
12777                       (const_int 3)))
12778    (set (attr "length_immediate")
12779         (if_then_else (match_operand:SI 0 "const0_operand")
12780                       (const_int 0)
12781                       (const_int 2)))])
12783 ;; If there are operand 0 bytes available on the stack, jump to
12784 ;; operand 1.
12786 (define_expand "split_stack_space_check"
12787   [(set (pc) (if_then_else
12788               (ltu (minus (reg SP_REG)
12789                           (match_operand 0 "register_operand"))
12790                    (match_dup 2))
12791               (label_ref (match_operand 1))
12792               (pc)))]
12793   ""
12795   rtx reg = gen_reg_rtx (Pmode);
12797   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
12799   operands[2] = ix86_split_stack_guard ();
12800   ix86_expand_branch (GEU, reg, operands[2], operands[1]);
12802   DONE;
12805 ;; Bit manipulation instructions.
12807 (define_expand "ffs<mode>2"
12808   [(set (match_dup 2) (const_int -1))
12809    (parallel [(set (match_dup 3) (match_dup 4))
12810               (set (match_operand:SWI48 0 "register_operand")
12811                    (ctz:SWI48
12812                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12813    (set (match_dup 0) (if_then_else:SWI48
12814                         (eq (match_dup 3) (const_int 0))
12815                         (match_dup 2)
12816                         (match_dup 0)))
12817    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12818               (clobber (reg:CC FLAGS_REG))])]
12819   ""
12821   machine_mode flags_mode;
12823   if (<MODE>mode == SImode && !TARGET_CMOVE)
12824     {
12825       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12826       DONE;
12827     }
12829   flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12831   operands[2] = gen_reg_rtx (<MODE>mode);
12832   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12833   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12836 (define_insn_and_split "ffssi2_no_cmove"
12837   [(set (match_operand:SI 0 "register_operand" "=r")
12838         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12839    (clobber (match_scratch:SI 2 "=&q"))
12840    (clobber (reg:CC FLAGS_REG))]
12841   "!TARGET_CMOVE"
12842   "#"
12843   "&& reload_completed"
12844   [(parallel [(set (match_dup 4) (match_dup 5))
12845               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12846    (set (strict_low_part (match_dup 3))
12847         (eq:QI (match_dup 4) (const_int 0)))
12848    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12849               (clobber (reg:CC FLAGS_REG))])
12850    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12851               (clobber (reg:CC FLAGS_REG))])
12852    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12853               (clobber (reg:CC FLAGS_REG))])]
12855   machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12857   operands[3] = gen_lowpart (QImode, operands[2]);
12858   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12859   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12861   ix86_expand_clear (operands[2]);
12864 (define_insn_and_split "*tzcnt<mode>_1"
12865   [(set (reg:CCC FLAGS_REG)
12866         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12867                      (const_int 0)))
12868    (set (match_operand:SWI48 0 "register_operand" "=r")
12869         (ctz:SWI48 (match_dup 1)))]
12870   "TARGET_BMI"
12871   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12872   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12873    && optimize_function_for_speed_p (cfun)
12874    && !reg_mentioned_p (operands[0], operands[1])"
12875   [(parallel
12876     [(set (reg:CCC FLAGS_REG)
12877           (compare:CCC (match_dup 1) (const_int 0)))
12878      (set (match_dup 0)
12879           (ctz:SWI48 (match_dup 1)))
12880      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
12881   "ix86_expand_clear (operands[0]);"
12882   [(set_attr "type" "alu1")
12883    (set_attr "prefix_0f" "1")
12884    (set_attr "prefix_rep" "1")
12885    (set_attr "btver2_decode" "double")
12886    (set_attr "mode" "<MODE>")])
12888 ; False dependency happens when destination is only updated by tzcnt,
12889 ; lzcnt or popcnt.  There is no false dependency when destination is
12890 ; also used in source.
12891 (define_insn "*tzcnt<mode>_1_falsedep"
12892   [(set (reg:CCC FLAGS_REG)
12893         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12894                      (const_int 0)))
12895    (set (match_operand:SWI48 0 "register_operand" "=r")
12896         (ctz:SWI48 (match_dup 1)))
12897    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12898            UNSPEC_INSN_FALSE_DEP)]
12899   "TARGET_BMI"
12900   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12901   [(set_attr "type" "alu1")
12902    (set_attr "prefix_0f" "1")
12903    (set_attr "prefix_rep" "1")
12904    (set_attr "btver2_decode" "double")
12905    (set_attr "mode" "<MODE>")])
12907 (define_insn "*bsf<mode>_1"
12908   [(set (reg:CCZ FLAGS_REG)
12909         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12910                      (const_int 0)))
12911    (set (match_operand:SWI48 0 "register_operand" "=r")
12912         (ctz:SWI48 (match_dup 1)))]
12913   ""
12914   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12915   [(set_attr "type" "alu1")
12916    (set_attr "prefix_0f" "1")
12917    (set_attr "btver2_decode" "double")
12918    (set_attr "znver1_decode" "vector")
12919    (set_attr "mode" "<MODE>")])
12921 (define_insn_and_split "ctz<mode>2"
12922   [(set (match_operand:SWI48 0 "register_operand" "=r")
12923         (ctz:SWI48
12924           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12925    (clobber (reg:CC FLAGS_REG))]
12926   ""
12928   if (TARGET_BMI)
12929     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12930   else if (optimize_function_for_size_p (cfun))
12931     ;
12932   else if (TARGET_GENERIC)
12933     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12934     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12936   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12938   "(TARGET_BMI || TARGET_GENERIC)
12939    && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
12940    && optimize_function_for_speed_p (cfun)
12941    && !reg_mentioned_p (operands[0], operands[1])"
12942   [(parallel
12943     [(set (match_dup 0)
12944           (ctz:SWI48 (match_dup 1)))
12945      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12946      (clobber (reg:CC FLAGS_REG))])]
12947   "ix86_expand_clear (operands[0]);"
12948   [(set_attr "type" "alu1")
12949    (set_attr "prefix_0f" "1")
12950    (set (attr "prefix_rep")
12951      (if_then_else
12952        (ior (match_test "TARGET_BMI")
12953             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12954                  (match_test "TARGET_GENERIC")))
12955        (const_string "1")
12956        (const_string "0")))
12957    (set_attr "mode" "<MODE>")])
12959 ; False dependency happens when destination is only updated by tzcnt,
12960 ; lzcnt or popcnt.  There is no false dependency when destination is
12961 ; also used in source.
12962 (define_insn "*ctz<mode>2_falsedep"
12963   [(set (match_operand:SWI48 0 "register_operand" "=r")
12964         (ctz:SWI48
12965           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12966    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12967            UNSPEC_INSN_FALSE_DEP)
12968    (clobber (reg:CC FLAGS_REG))]
12969   ""
12971   if (TARGET_BMI)
12972     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12973   else if (TARGET_GENERIC)
12974     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12975     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12976   else
12977     gcc_unreachable ();
12979   [(set_attr "type" "alu1")
12980    (set_attr "prefix_0f" "1")
12981    (set_attr "prefix_rep" "1")
12982    (set_attr "mode" "<MODE>")])
12984 (define_insn "bsr_rex64"
12985   [(set (match_operand:DI 0 "register_operand" "=r")
12986         (minus:DI (const_int 63)
12987                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12988    (clobber (reg:CC FLAGS_REG))]
12989   "TARGET_64BIT"
12990   "bsr{q}\t{%1, %0|%0, %1}"
12991   [(set_attr "type" "alu1")
12992    (set_attr "prefix_0f" "1")
12993    (set_attr "znver1_decode" "vector")
12994    (set_attr "mode" "DI")])
12996 (define_insn "bsr"
12997   [(set (match_operand:SI 0 "register_operand" "=r")
12998         (minus:SI (const_int 31)
12999                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13000    (clobber (reg:CC FLAGS_REG))]
13001   ""
13002   "bsr{l}\t{%1, %0|%0, %1}"
13003   [(set_attr "type" "alu1")
13004    (set_attr "prefix_0f" "1")
13005    (set_attr "znver1_decode" "vector")
13006    (set_attr "mode" "SI")])
13008 (define_insn "*bsrhi"
13009   [(set (match_operand:HI 0 "register_operand" "=r")
13010         (minus:HI (const_int 15)
13011                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13012    (clobber (reg:CC FLAGS_REG))]
13013   ""
13014   "bsr{w}\t{%1, %0|%0, %1}"
13015   [(set_attr "type" "alu1")
13016    (set_attr "prefix_0f" "1")
13017    (set_attr "znver1_decode" "vector")
13018    (set_attr "mode" "HI")])
13020 (define_expand "clz<mode>2"
13021   [(parallel
13022      [(set (match_operand:SWI48 0 "register_operand")
13023            (minus:SWI48
13024              (match_dup 2)
13025              (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13026       (clobber (reg:CC FLAGS_REG))])
13027    (parallel
13028      [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13029       (clobber (reg:CC FLAGS_REG))])]
13030   ""
13032   if (TARGET_LZCNT)
13033     {
13034       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13035       DONE;
13036     }
13037   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13040 (define_insn_and_split "clz<mode>2_lzcnt"
13041   [(set (match_operand:SWI48 0 "register_operand" "=r")
13042         (clz:SWI48
13043           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13044    (clobber (reg:CC FLAGS_REG))]
13045   "TARGET_LZCNT"
13046   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13047   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13048    && optimize_function_for_speed_p (cfun)
13049    && !reg_mentioned_p (operands[0], operands[1])"
13050   [(parallel
13051     [(set (match_dup 0)
13052           (clz:SWI48 (match_dup 1)))
13053      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13054      (clobber (reg:CC FLAGS_REG))])]
13055   "ix86_expand_clear (operands[0]);"
13056   [(set_attr "prefix_rep" "1")
13057    (set_attr "type" "bitmanip")
13058    (set_attr "mode" "<MODE>")])
13060 ; False dependency happens when destination is only updated by tzcnt,
13061 ; lzcnt or popcnt.  There is no false dependency when destination is
13062 ; also used in source.
13063 (define_insn "*clz<mode>2_lzcnt_falsedep"
13064   [(set (match_operand:SWI48 0 "register_operand" "=r")
13065         (clz:SWI48
13066           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13067    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13068            UNSPEC_INSN_FALSE_DEP)
13069    (clobber (reg:CC FLAGS_REG))]
13070   "TARGET_LZCNT"
13071   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13072   [(set_attr "prefix_rep" "1")
13073    (set_attr "type" "bitmanip")
13074    (set_attr "mode" "<MODE>")])
13076 (define_int_iterator LT_ZCNT
13077         [(UNSPEC_TZCNT "TARGET_BMI")
13078          (UNSPEC_LZCNT "TARGET_LZCNT")])
13080 (define_int_attr lt_zcnt
13081         [(UNSPEC_TZCNT "tzcnt")
13082          (UNSPEC_LZCNT "lzcnt")])
13084 (define_int_attr lt_zcnt_type
13085         [(UNSPEC_TZCNT "alu1")
13086          (UNSPEC_LZCNT "bitmanip")])
13088 ;; Version of lzcnt/tzcnt that is expanded from intrinsics.  This version
13089 ;; provides operand size as output when source operand is zero. 
13091 (define_insn_and_split "<lt_zcnt>_<mode>"
13092   [(set (match_operand:SWI48 0 "register_operand" "=r")
13093         (unspec:SWI48
13094           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13095    (clobber (reg:CC FLAGS_REG))]
13096   ""
13097   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13098   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13099    && optimize_function_for_speed_p (cfun)
13100    && !reg_mentioned_p (operands[0], operands[1])"
13101   [(parallel
13102     [(set (match_dup 0)
13103           (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13104      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13105      (clobber (reg:CC FLAGS_REG))])]
13106   "ix86_expand_clear (operands[0]);"
13107   [(set_attr "type" "<lt_zcnt_type>")
13108    (set_attr "prefix_0f" "1")
13109    (set_attr "prefix_rep" "1")
13110    (set_attr "mode" "<MODE>")])
13112 ; False dependency happens when destination is only updated by tzcnt,
13113 ; lzcnt or popcnt.  There is no false dependency when destination is
13114 ; also used in source.
13115 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13116   [(set (match_operand:SWI48 0 "register_operand" "=r")
13117         (unspec:SWI48
13118           [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13119    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13120            UNSPEC_INSN_FALSE_DEP)
13121    (clobber (reg:CC FLAGS_REG))]
13122   ""
13123   "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13124   [(set_attr "type" "<lt_zcnt_type>")
13125    (set_attr "prefix_0f" "1")
13126    (set_attr "prefix_rep" "1")
13127    (set_attr "mode" "<MODE>")])
13129 (define_insn "<lt_zcnt>_hi"
13130   [(set (match_operand:HI 0 "register_operand" "=r")
13131         (unspec:HI
13132           [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13133    (clobber (reg:CC FLAGS_REG))]
13134   ""
13135   "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13136   [(set_attr "type" "<lt_zcnt_type>")
13137    (set_attr "prefix_0f" "1")
13138    (set_attr "prefix_rep" "1")
13139    (set_attr "mode" "HI")])
13141 ;; BMI instructions.
13143 (define_insn "bmi_bextr_<mode>"
13144   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13145         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13146                        (match_operand:SWI48 2 "register_operand" "r,r")]
13147                       UNSPEC_BEXTR))
13148    (clobber (reg:CC FLAGS_REG))]
13149   "TARGET_BMI"
13150   "bextr\t{%2, %1, %0|%0, %1, %2}"
13151   [(set_attr "type" "bitmanip")
13152    (set_attr "btver2_decode" "direct, double")
13153    (set_attr "mode" "<MODE>")])
13155 (define_insn "*bmi_bextr_<mode>_ccz"
13156   [(set (reg:CCZ FLAGS_REG)
13157         (compare:CCZ
13158           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13159                          (match_operand:SWI48 2 "register_operand" "r,r")]
13160                         UNSPEC_BEXTR)
13161           (const_int 0)))
13162    (clobber (match_scratch:SWI48 0 "=r,r"))]
13163   "TARGET_BMI"
13164   "bextr\t{%2, %1, %0|%0, %1, %2}"
13165   [(set_attr "type" "bitmanip")
13166    (set_attr "btver2_decode" "direct, double")
13167    (set_attr "mode" "<MODE>")])
13169 (define_insn "*bmi_blsi_<mode>"
13170   [(set (match_operand:SWI48 0 "register_operand" "=r")
13171         (and:SWI48
13172           (neg:SWI48
13173             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13174           (match_dup 1)))
13175    (clobber (reg:CC FLAGS_REG))]
13176   "TARGET_BMI"
13177   "blsi\t{%1, %0|%0, %1}"
13178   [(set_attr "type" "bitmanip")
13179    (set_attr "btver2_decode" "double")
13180    (set_attr "mode" "<MODE>")])
13182 (define_insn "*bmi_blsmsk_<mode>"
13183   [(set (match_operand:SWI48 0 "register_operand" "=r")
13184         (xor:SWI48
13185           (plus:SWI48
13186             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13187             (const_int -1))
13188           (match_dup 1)))
13189    (clobber (reg:CC FLAGS_REG))]
13190   "TARGET_BMI"
13191   "blsmsk\t{%1, %0|%0, %1}"
13192   [(set_attr "type" "bitmanip")
13193    (set_attr "btver2_decode" "double")
13194    (set_attr "mode" "<MODE>")])
13196 (define_insn "*bmi_blsr_<mode>"
13197   [(set (match_operand:SWI48 0 "register_operand" "=r")
13198         (and:SWI48
13199           (plus:SWI48
13200             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13201             (const_int -1))
13202           (match_dup 1)))
13203    (clobber (reg:CC FLAGS_REG))]
13204    "TARGET_BMI"
13205    "blsr\t{%1, %0|%0, %1}"
13206   [(set_attr "type" "bitmanip")
13207    (set_attr "btver2_decode" "double")
13208    (set_attr "mode" "<MODE>")])
13210 ;; BMI2 instructions.
13211 (define_expand "bmi2_bzhi_<mode>3"
13212   [(parallel
13213     [(set (match_operand:SWI48 0 "register_operand")
13214           (zero_extract:SWI48
13215             (match_operand:SWI48 1 "nonimmediate_operand")
13216             (umin:SWI48
13217               (and:SWI48 (match_operand:SWI48 2 "register_operand")
13218                          (const_int 255))
13219               (match_dup 3))
13220             (const_int 0)))
13221      (clobber (reg:CC FLAGS_REG))])]
13222   "TARGET_BMI2"
13223   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13225 (define_insn "*bmi2_bzhi_<mode>3"
13226   [(set (match_operand:SWI48 0 "register_operand" "=r")
13227         (zero_extract:SWI48
13228           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13229           (umin:SWI48
13230             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13231                        (const_int 255))
13232             (match_operand:SWI48 3 "const_int_operand" "n"))
13233           (const_int 0)))
13234    (clobber (reg:CC FLAGS_REG))]
13235   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13236   "bzhi\t{%2, %1, %0|%0, %1, %2}"
13237   [(set_attr "type" "bitmanip")
13238    (set_attr "prefix" "vex")
13239    (set_attr "mode" "<MODE>")])
13241 (define_insn "*bmi2_bzhi_<mode>3_1"
13242   [(set (match_operand:SWI48 0 "register_operand" "=r")
13243         (zero_extract:SWI48
13244           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13245           (umin:SWI48
13246             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13247             (match_operand:SWI48 3 "const_int_operand" "n"))
13248           (const_int 0)))
13249    (clobber (reg:CC FLAGS_REG))]
13250   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13251   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13252   [(set_attr "type" "bitmanip")
13253    (set_attr "prefix" "vex")
13254    (set_attr "mode" "<MODE>")])
13256 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13257   [(set (reg:CCZ FLAGS_REG)
13258         (compare:CCZ
13259           (zero_extract:SWI48
13260             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13261             (umin:SWI48
13262               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13263               (match_operand:SWI48 3 "const_int_operand" "n"))
13264             (const_int 0))
13265         (const_int 0)))
13266    (clobber (match_scratch:SWI48 0 "=r"))]
13267   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13268   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13269   [(set_attr "type" "bitmanip")
13270    (set_attr "prefix" "vex")
13271    (set_attr "mode" "<MODE>")])
13273 (define_insn "bmi2_pdep_<mode>3"
13274   [(set (match_operand:SWI48 0 "register_operand" "=r")
13275         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13276                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13277                        UNSPEC_PDEP))]
13278   "TARGET_BMI2"
13279   "pdep\t{%2, %1, %0|%0, %1, %2}"
13280   [(set_attr "type" "bitmanip")
13281    (set_attr "prefix" "vex")
13282    (set_attr "mode" "<MODE>")])
13284 (define_insn "bmi2_pext_<mode>3"
13285   [(set (match_operand:SWI48 0 "register_operand" "=r")
13286         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13287                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13288                        UNSPEC_PEXT))]
13289   "TARGET_BMI2"
13290   "pext\t{%2, %1, %0|%0, %1, %2}"
13291   [(set_attr "type" "bitmanip")
13292    (set_attr "prefix" "vex")
13293    (set_attr "mode" "<MODE>")])
13295 ;; TBM instructions.
13296 (define_insn "tbm_bextri_<mode>"
13297   [(set (match_operand:SWI48 0 "register_operand" "=r")
13298         (zero_extract:SWI48
13299           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13300           (match_operand 2 "const_0_to_255_operand" "N")
13301           (match_operand 3 "const_0_to_255_operand" "N")))
13302    (clobber (reg:CC FLAGS_REG))]
13303    "TARGET_TBM"
13305   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13306   return "bextr\t{%2, %1, %0|%0, %1, %2}";
13308   [(set_attr "type" "bitmanip")
13309    (set_attr "mode" "<MODE>")])
13311 (define_insn "*tbm_blcfill_<mode>"
13312   [(set (match_operand:SWI48 0 "register_operand" "=r")
13313         (and:SWI48
13314           (plus:SWI48
13315             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13316             (const_int 1))
13317           (match_dup 1)))
13318    (clobber (reg:CC FLAGS_REG))]
13319    "TARGET_TBM"
13320    "blcfill\t{%1, %0|%0, %1}"
13321   [(set_attr "type" "bitmanip")
13322    (set_attr "mode" "<MODE>")])
13324 (define_insn "*tbm_blci_<mode>"
13325   [(set (match_operand:SWI48 0 "register_operand" "=r")
13326         (ior:SWI48
13327           (not:SWI48
13328             (plus:SWI48
13329               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13330               (const_int 1)))
13331           (match_dup 1)))
13332    (clobber (reg:CC FLAGS_REG))]
13333    "TARGET_TBM"
13334    "blci\t{%1, %0|%0, %1}"
13335   [(set_attr "type" "bitmanip")
13336    (set_attr "mode" "<MODE>")])
13338 (define_insn "*tbm_blcic_<mode>"
13339   [(set (match_operand:SWI48 0 "register_operand" "=r")
13340         (and:SWI48
13341           (plus:SWI48
13342             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13343             (const_int 1))
13344           (not:SWI48
13345             (match_dup 1))))
13346    (clobber (reg:CC FLAGS_REG))]
13347    "TARGET_TBM"
13348    "blcic\t{%1, %0|%0, %1}"
13349   [(set_attr "type" "bitmanip")
13350    (set_attr "mode" "<MODE>")])
13352 (define_insn "*tbm_blcmsk_<mode>"
13353   [(set (match_operand:SWI48 0 "register_operand" "=r")
13354         (xor:SWI48
13355           (plus:SWI48
13356             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13357             (const_int 1))
13358           (match_dup 1)))
13359    (clobber (reg:CC FLAGS_REG))]
13360    "TARGET_TBM"
13361    "blcmsk\t{%1, %0|%0, %1}"
13362   [(set_attr "type" "bitmanip")
13363    (set_attr "mode" "<MODE>")])
13365 (define_insn "*tbm_blcs_<mode>"
13366   [(set (match_operand:SWI48 0 "register_operand" "=r")
13367         (ior:SWI48
13368           (plus:SWI48
13369             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13370             (const_int 1))
13371           (match_dup 1)))
13372    (clobber (reg:CC FLAGS_REG))]
13373    "TARGET_TBM"
13374    "blcs\t{%1, %0|%0, %1}"
13375   [(set_attr "type" "bitmanip")
13376    (set_attr "mode" "<MODE>")])
13378 (define_insn "*tbm_blsfill_<mode>"
13379   [(set (match_operand:SWI48 0 "register_operand" "=r")
13380         (ior:SWI48
13381           (plus:SWI48
13382             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13383             (const_int -1))
13384           (match_dup 1)))
13385    (clobber (reg:CC FLAGS_REG))]
13386    "TARGET_TBM"
13387    "blsfill\t{%1, %0|%0, %1}"
13388   [(set_attr "type" "bitmanip")
13389    (set_attr "mode" "<MODE>")])
13391 (define_insn "*tbm_blsic_<mode>"
13392   [(set (match_operand:SWI48 0 "register_operand" "=r")
13393         (ior:SWI48
13394           (plus:SWI48
13395             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13396             (const_int -1))
13397           (not:SWI48
13398             (match_dup 1))))
13399    (clobber (reg:CC FLAGS_REG))]
13400    "TARGET_TBM"
13401    "blsic\t{%1, %0|%0, %1}"
13402   [(set_attr "type" "bitmanip")
13403    (set_attr "mode" "<MODE>")])
13405 (define_insn "*tbm_t1mskc_<mode>"
13406   [(set (match_operand:SWI48 0 "register_operand" "=r")
13407         (ior:SWI48
13408           (plus:SWI48
13409             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13410             (const_int 1))
13411           (not:SWI48
13412             (match_dup 1))))
13413    (clobber (reg:CC FLAGS_REG))]
13414    "TARGET_TBM"
13415    "t1mskc\t{%1, %0|%0, %1}"
13416   [(set_attr "type" "bitmanip")
13417    (set_attr "mode" "<MODE>")])
13419 (define_insn "*tbm_tzmsk_<mode>"
13420   [(set (match_operand:SWI48 0 "register_operand" "=r")
13421         (and:SWI48
13422           (plus:SWI48
13423             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13424             (const_int -1))
13425           (not:SWI48
13426             (match_dup 1))))
13427    (clobber (reg:CC FLAGS_REG))]
13428    "TARGET_TBM"
13429    "tzmsk\t{%1, %0|%0, %1}"
13430   [(set_attr "type" "bitmanip")
13431    (set_attr "mode" "<MODE>")])
13433 (define_insn_and_split "popcount<mode>2"
13434   [(set (match_operand:SWI48 0 "register_operand" "=r")
13435         (popcount:SWI48
13436           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13437    (clobber (reg:CC FLAGS_REG))]
13438   "TARGET_POPCNT"
13440 #if TARGET_MACHO
13441   return "popcnt\t{%1, %0|%0, %1}";
13442 #else
13443   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13444 #endif
13446   "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13447    && optimize_function_for_speed_p (cfun)
13448    && !reg_mentioned_p (operands[0], operands[1])"
13449   [(parallel
13450     [(set (match_dup 0)
13451           (popcount:SWI48 (match_dup 1)))
13452      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13453      (clobber (reg:CC FLAGS_REG))])]
13454   "ix86_expand_clear (operands[0]);"
13455   [(set_attr "prefix_rep" "1")
13456    (set_attr "type" "bitmanip")
13457    (set_attr "mode" "<MODE>")])
13459 ; False dependency happens when destination is only updated by tzcnt,
13460 ; lzcnt or popcnt.  There is no false dependency when destination is
13461 ; also used in source.
13462 (define_insn "*popcount<mode>2_falsedep"
13463   [(set (match_operand:SWI48 0 "register_operand" "=r")
13464         (popcount:SWI48
13465           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13466    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13467            UNSPEC_INSN_FALSE_DEP)
13468    (clobber (reg:CC FLAGS_REG))]
13469   "TARGET_POPCNT"
13471 #if TARGET_MACHO
13472   return "popcnt\t{%1, %0|%0, %1}";
13473 #else
13474   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13475 #endif
13477   [(set_attr "prefix_rep" "1")
13478    (set_attr "type" "bitmanip")
13479    (set_attr "mode" "<MODE>")])
13481 (define_insn_and_split "*popcounthi2_1"
13482   [(set (match_operand:SI 0 "register_operand")
13483         (popcount:SI
13484           (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13485    (clobber (reg:CC FLAGS_REG))]
13486   "TARGET_POPCNT
13487    && can_create_pseudo_p ()"
13488   "#"
13489   "&& 1"
13490   [(const_int 0)]
13492   rtx tmp = gen_reg_rtx (HImode);
13494   emit_insn (gen_popcounthi2 (tmp, operands[1]));
13495   emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13496   DONE;
13499 (define_insn "popcounthi2"
13500   [(set (match_operand:HI 0 "register_operand" "=r")
13501         (popcount:HI
13502           (match_operand:HI 1 "nonimmediate_operand" "rm")))
13503    (clobber (reg:CC FLAGS_REG))]
13504   "TARGET_POPCNT"
13506 #if TARGET_MACHO
13507   return "popcnt\t{%1, %0|%0, %1}";
13508 #else
13509   return "popcnt{w}\t{%1, %0|%0, %1}";
13510 #endif
13512   [(set_attr "prefix_rep" "1")
13513    (set_attr "type" "bitmanip")
13514    (set_attr "mode" "HI")])
13516 (define_expand "bswapdi2"
13517   [(set (match_operand:DI 0 "register_operand")
13518         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13519   "TARGET_64BIT"
13521   if (!TARGET_MOVBE)
13522     operands[1] = force_reg (DImode, operands[1]);
13525 (define_expand "bswapsi2"
13526   [(set (match_operand:SI 0 "register_operand")
13527         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13528   ""
13530   if (TARGET_MOVBE)
13531     ;
13532   else if (TARGET_BSWAP)
13533     operands[1] = force_reg (SImode, operands[1]);
13534   else
13535     {
13536       rtx x = operands[0];
13538       emit_move_insn (x, operands[1]);
13539       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13540       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13541       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13542       DONE;
13543     }
13546 (define_insn "*bswap<mode>2_movbe"
13547   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13548         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13549   "TARGET_MOVBE
13550    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13551   "@
13552     bswap\t%0
13553     movbe\t{%1, %0|%0, %1}
13554     movbe\t{%1, %0|%0, %1}"
13555   [(set_attr "type" "bitmanip,imov,imov")
13556    (set_attr "modrm" "0,1,1")
13557    (set_attr "prefix_0f" "*,1,1")
13558    (set_attr "prefix_extra" "*,1,1")
13559    (set_attr "mode" "<MODE>")])
13561 (define_insn "*bswap<mode>2"
13562   [(set (match_operand:SWI48 0 "register_operand" "=r")
13563         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13564   "TARGET_BSWAP"
13565   "bswap\t%0"
13566   [(set_attr "type" "bitmanip")
13567    (set_attr "modrm" "0")
13568    (set_attr "mode" "<MODE>")])
13570 (define_insn "*bswaphi_lowpart_1"
13571   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13572         (bswap:HI (match_dup 0)))
13573    (clobber (reg:CC FLAGS_REG))]
13574   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13575   "@
13576     xchg{b}\t{%h0, %b0|%b0, %h0}
13577     rol{w}\t{$8, %0|%0, 8}"
13578   [(set_attr "length" "2,4")
13579    (set_attr "mode" "QI,HI")])
13581 (define_insn "bswaphi_lowpart"
13582   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13583         (bswap:HI (match_dup 0)))
13584    (clobber (reg:CC FLAGS_REG))]
13585   ""
13586   "rol{w}\t{$8, %0|%0, 8}"
13587   [(set_attr "length" "4")
13588    (set_attr "mode" "HI")])
13590 (define_expand "paritydi2"
13591   [(set (match_operand:DI 0 "register_operand")
13592         (parity:DI (match_operand:DI 1 "register_operand")))]
13593   "! TARGET_POPCNT"
13595   rtx scratch = gen_reg_rtx (QImode);
13597   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13598                                 NULL_RTX, operands[1]));
13600   ix86_expand_setcc (scratch, ORDERED,
13601                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13603   if (TARGET_64BIT)
13604     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13605   else
13606     {
13607       rtx tmp = gen_reg_rtx (SImode);
13609       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13610       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13611     }
13612   DONE;
13615 (define_expand "paritysi2"
13616   [(set (match_operand:SI 0 "register_operand")
13617         (parity:SI (match_operand:SI 1 "register_operand")))]
13618   "! TARGET_POPCNT"
13620   rtx scratch = gen_reg_rtx (QImode);
13622   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13624   ix86_expand_setcc (scratch, ORDERED,
13625                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13627   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13628   DONE;
13631 (define_insn_and_split "paritydi2_cmp"
13632   [(set (reg:CC FLAGS_REG)
13633         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13634                    UNSPEC_PARITY))
13635    (clobber (match_scratch:DI 0 "=r"))
13636    (clobber (match_scratch:SI 1 "=&r"))
13637    (clobber (match_scratch:HI 2 "=Q"))]
13638   "! TARGET_POPCNT"
13639   "#"
13640   "&& reload_completed"
13641   [(parallel
13642      [(set (match_dup 1)
13643            (xor:SI (match_dup 1) (match_dup 4)))
13644       (clobber (reg:CC FLAGS_REG))])
13645    (parallel
13646      [(set (reg:CC FLAGS_REG)
13647            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13648       (clobber (match_dup 1))
13649       (clobber (match_dup 2))])]
13651   operands[4] = gen_lowpart (SImode, operands[3]);
13653   if (TARGET_64BIT)
13654     {
13655       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13656       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13657     }
13658   else
13659     operands[1] = gen_highpart (SImode, operands[3]);
13662 (define_insn_and_split "paritysi2_cmp"
13663   [(set (reg:CC FLAGS_REG)
13664         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13665                    UNSPEC_PARITY))
13666    (clobber (match_scratch:SI 0 "=r"))
13667    (clobber (match_scratch:HI 1 "=&Q"))]
13668   "! TARGET_POPCNT"
13669   "#"
13670   "&& reload_completed"
13671   [(parallel
13672      [(set (match_dup 1)
13673            (xor:HI (match_dup 1) (match_dup 3)))
13674       (clobber (reg:CC FLAGS_REG))])
13675    (parallel
13676      [(set (reg:CC FLAGS_REG)
13677            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13678       (clobber (match_dup 1))])]
13680   operands[3] = gen_lowpart (HImode, operands[2]);
13682   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13683   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13686 (define_insn "*parityhi2_cmp"
13687   [(set (reg:CC FLAGS_REG)
13688         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13689                    UNSPEC_PARITY))
13690    (clobber (match_scratch:HI 0 "=Q"))]
13691   "! TARGET_POPCNT"
13692   "xor{b}\t{%h0, %b0|%b0, %h0}"
13693   [(set_attr "length" "2")
13694    (set_attr "mode" "HI")])
13697 ;; Thread-local storage patterns for ELF.
13699 ;; Note that these code sequences must appear exactly as shown
13700 ;; in order to allow linker relaxation.
13702 (define_insn "*tls_global_dynamic_32_gnu"
13703   [(set (match_operand:SI 0 "register_operand" "=a")
13704         (unspec:SI
13705          [(match_operand:SI 1 "register_operand" "Yb")
13706           (match_operand 2 "tls_symbolic_operand")
13707           (match_operand 3 "constant_call_address_operand" "Bz")
13708           (reg:SI SP_REG)]
13709          UNSPEC_TLS_GD))
13710    (clobber (match_scratch:SI 4 "=d"))
13711    (clobber (match_scratch:SI 5 "=c"))
13712    (clobber (reg:CC FLAGS_REG))]
13713   "!TARGET_64BIT && TARGET_GNU_TLS"
13715   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13716     output_asm_insn
13717       ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13718   else
13719     output_asm_insn
13720       ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
13721   if (TARGET_SUN_TLS)
13722 #ifdef HAVE_AS_IX86_TLSGDPLT
13723     return "call\t%a2@tlsgdplt";
13724 #else
13725     return "call\t%p3@plt";
13726 #endif
13727   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13728     return "call\t%P3";
13729   return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
13731   [(set_attr "type" "multi")
13732    (set_attr "length" "12")])
13734 (define_expand "tls_global_dynamic_32"
13735   [(parallel
13736     [(set (match_operand:SI 0 "register_operand")
13737           (unspec:SI [(match_operand:SI 2 "register_operand")
13738                       (match_operand 1 "tls_symbolic_operand")
13739                       (match_operand 3 "constant_call_address_operand")
13740                       (reg:SI SP_REG)]
13741                      UNSPEC_TLS_GD))
13742      (clobber (match_scratch:SI 4))
13743      (clobber (match_scratch:SI 5))
13744      (clobber (reg:CC FLAGS_REG))])]
13745   ""
13746   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13748 (define_insn "*tls_global_dynamic_64_<mode>"
13749   [(set (match_operand:P 0 "register_operand" "=a")
13750         (call:P
13751          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13752          (match_operand 3)))
13753    (unspec:P [(match_operand 1 "tls_symbolic_operand")
13754               (reg:P SP_REG)]
13755              UNSPEC_TLS_GD)]
13756   "TARGET_64BIT"
13758   if (!TARGET_X32)
13759     fputs (ASM_BYTE "0x66\n", asm_out_file);
13760   output_asm_insn
13761     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13762   if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13763     fputs (ASM_SHORT "0x6666\n", asm_out_file);
13764   else
13765     fputs (ASM_BYTE "0x66\n", asm_out_file);
13766   fputs ("\trex64\n", asm_out_file);
13767   if (TARGET_SUN_TLS)
13768     return "call\t%p2@plt";
13769   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13770     return "call\t%P2";
13771   return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
13773   [(set_attr "type" "multi")
13774    (set (attr "length")
13775         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13777 (define_insn "*tls_global_dynamic_64_largepic"
13778   [(set (match_operand:DI 0 "register_operand" "=a")
13779         (call:DI
13780          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13781                           (match_operand:DI 3 "immediate_operand" "i")))
13782          (match_operand 4)))
13783    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13784                (reg:DI SP_REG)]
13785               UNSPEC_TLS_GD)]
13786   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13787    && GET_CODE (operands[3]) == CONST
13788    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13789    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13791   output_asm_insn
13792     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13793   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13794   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13795   return "call\t{*%%rax|rax}";
13797   [(set_attr "type" "multi")
13798    (set_attr "length" "22")])
13800 (define_expand "tls_global_dynamic_64_<mode>"
13801   [(parallel
13802     [(set (match_operand:P 0 "register_operand")
13803           (call:P
13804            (mem:QI (match_operand 2))
13805            (const_int 0)))
13806      (unspec:P [(match_operand 1 "tls_symbolic_operand")
13807                 (reg:P SP_REG)]
13808                UNSPEC_TLS_GD)])]
13809   "TARGET_64BIT"
13810   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13812 (define_insn "*tls_local_dynamic_base_32_gnu"
13813   [(set (match_operand:SI 0 "register_operand" "=a")
13814         (unspec:SI
13815          [(match_operand:SI 1 "register_operand" "Yb")
13816           (match_operand 2 "constant_call_address_operand" "Bz")
13817           (reg:SI SP_REG)]
13818          UNSPEC_TLS_LD_BASE))
13819    (clobber (match_scratch:SI 3 "=d"))
13820    (clobber (match_scratch:SI 4 "=c"))
13821    (clobber (reg:CC FLAGS_REG))]
13822   "!TARGET_64BIT && TARGET_GNU_TLS"
13824   output_asm_insn
13825     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13826   if (TARGET_SUN_TLS)
13827     {
13828       if (HAVE_AS_IX86_TLSLDMPLT)
13829         return "call\t%&@tlsldmplt";
13830       else
13831         return "call\t%p2@plt";
13832     }
13833   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13834     return "call\t%P2";
13835   return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
13837   [(set_attr "type" "multi")
13838    (set_attr "length" "11")])
13840 (define_expand "tls_local_dynamic_base_32"
13841   [(parallel
13842      [(set (match_operand:SI 0 "register_operand")
13843            (unspec:SI
13844             [(match_operand:SI 1 "register_operand")
13845              (match_operand 2 "constant_call_address_operand")
13846              (reg:SI SP_REG)]
13847             UNSPEC_TLS_LD_BASE))
13848       (clobber (match_scratch:SI 3))
13849       (clobber (match_scratch:SI 4))
13850       (clobber (reg:CC FLAGS_REG))])]
13851   ""
13852   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13854 (define_insn "*tls_local_dynamic_base_64_<mode>"
13855   [(set (match_operand:P 0 "register_operand" "=a")
13856         (call:P
13857          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13858          (match_operand 2)))
13859    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13860   "TARGET_64BIT"
13862   output_asm_insn
13863     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13864   if (TARGET_SUN_TLS)
13865     return "call\t%p1@plt";
13866   if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
13867     return "call\t%P1";
13868   return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
13870   [(set_attr "type" "multi")
13871    (set_attr "length" "12")])
13873 (define_insn "*tls_local_dynamic_base_64_largepic"
13874   [(set (match_operand:DI 0 "register_operand" "=a")
13875         (call:DI
13876          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13877                           (match_operand:DI 2 "immediate_operand" "i")))
13878          (match_operand 3)))
13879    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13880   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13881    && GET_CODE (operands[2]) == CONST
13882    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13883    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13885   output_asm_insn
13886     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13887   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13888   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13889   return "call\t{*%%rax|rax}";
13891   [(set_attr "type" "multi")
13892    (set_attr "length" "22")])
13894 (define_expand "tls_local_dynamic_base_64_<mode>"
13895   [(parallel
13896      [(set (match_operand:P 0 "register_operand")
13897            (call:P
13898             (mem:QI (match_operand 1))
13899             (const_int 0)))
13900       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13901   "TARGET_64BIT"
13902   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13904 ;; Local dynamic of a single variable is a lose.  Show combine how
13905 ;; to convert that back to global dynamic.
13907 (define_insn_and_split "*tls_local_dynamic_32_once"
13908   [(set (match_operand:SI 0 "register_operand" "=a")
13909         (plus:SI
13910          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13911                      (match_operand 2 "constant_call_address_operand" "Bz")
13912                      (reg:SI SP_REG)]
13913                     UNSPEC_TLS_LD_BASE)
13914          (const:SI (unspec:SI
13915                     [(match_operand 3 "tls_symbolic_operand")]
13916                     UNSPEC_DTPOFF))))
13917    (clobber (match_scratch:SI 4 "=d"))
13918    (clobber (match_scratch:SI 5 "=c"))
13919    (clobber (reg:CC FLAGS_REG))]
13920   ""
13921   "#"
13922   ""
13923   [(parallel
13924      [(set (match_dup 0)
13925            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13926                        (reg:SI SP_REG)]
13927                       UNSPEC_TLS_GD))
13928       (clobber (match_dup 4))
13929       (clobber (match_dup 5))
13930       (clobber (reg:CC FLAGS_REG))])])
13932 ;; Load and add the thread base pointer from %<tp_seg>:0.
13933 (define_insn_and_split "*load_tp_<mode>"
13934   [(set (match_operand:PTR 0 "register_operand" "=r")
13935         (unspec:PTR [(const_int 0)] UNSPEC_TP))]
13936   ""
13937   "#"
13938   ""
13939   [(set (match_dup 0)
13940         (match_dup 1))]
13942   addr_space_t as = DEFAULT_TLS_SEG_REG;
13944   operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
13945   set_mem_addr_space (operands[1], as);
13948 (define_insn_and_split "*load_tp_x32_zext"
13949   [(set (match_operand:DI 0 "register_operand" "=r")
13950         (zero_extend:DI
13951           (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13952   "TARGET_X32"
13953   "#"
13954   ""
13955   [(set (match_dup 0)
13956         (zero_extend:DI (match_dup 1)))]
13958   addr_space_t as = DEFAULT_TLS_SEG_REG;
13960   operands[1] = gen_const_mem (SImode, const0_rtx);
13961   set_mem_addr_space (operands[1], as);
13964 (define_insn_and_split "*add_tp_<mode>"
13965   [(set (match_operand:PTR 0 "register_operand" "=r")
13966         (plus:PTR
13967           (unspec:PTR [(const_int 0)] UNSPEC_TP)
13968           (match_operand:PTR 1 "register_operand" "0")))
13969    (clobber (reg:CC FLAGS_REG))]
13970   ""
13971   "#"
13972   ""
13973   [(parallel
13974      [(set (match_dup 0)
13975            (plus:PTR (match_dup 1) (match_dup 2)))
13976       (clobber (reg:CC FLAGS_REG))])]
13978   addr_space_t as = DEFAULT_TLS_SEG_REG;
13980   operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
13981   set_mem_addr_space (operands[2], as);
13984 (define_insn_and_split "*add_tp_x32_zext"
13985   [(set (match_operand:DI 0 "register_operand" "=r")
13986         (zero_extend:DI
13987           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13988                    (match_operand:SI 1 "register_operand" "0"))))
13989    (clobber (reg:CC FLAGS_REG))]
13990   "TARGET_X32"
13991   "#"
13992   ""
13993   [(parallel
13994      [(set (match_dup 0)
13995            (zero_extend:DI
13996              (plus:SI (match_dup 1) (match_dup 2))))
13997       (clobber (reg:CC FLAGS_REG))])]
13999   addr_space_t as = DEFAULT_TLS_SEG_REG;
14001   operands[2] = gen_const_mem (SImode, const0_rtx);
14002   set_mem_addr_space (operands[2], as);
14005 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14006 ;; %rax as destination of the initial executable code sequence.
14007 (define_insn "tls_initial_exec_64_sun"
14008   [(set (match_operand:DI 0 "register_operand" "=a")
14009         (unspec:DI
14010          [(match_operand 1 "tls_symbolic_operand")]
14011          UNSPEC_TLS_IE_SUN))
14012    (clobber (reg:CC FLAGS_REG))]
14013   "TARGET_64BIT && TARGET_SUN_TLS"
14015   output_asm_insn
14016     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14017   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14019   [(set_attr "type" "multi")])
14021 ;; GNU2 TLS patterns can be split.
14023 (define_expand "tls_dynamic_gnu2_32"
14024   [(set (match_dup 3)
14025         (plus:SI (match_operand:SI 2 "register_operand")
14026                  (const:SI
14027                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14028                              UNSPEC_TLSDESC))))
14029    (parallel
14030     [(set (match_operand:SI 0 "register_operand")
14031           (unspec:SI [(match_dup 1) (match_dup 3)
14032                       (match_dup 2) (reg:SI SP_REG)]
14033                       UNSPEC_TLSDESC))
14034      (clobber (reg:CC FLAGS_REG))])]
14035   "!TARGET_64BIT && TARGET_GNU2_TLS"
14037   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14038   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14041 (define_insn "*tls_dynamic_gnu2_lea_32"
14042   [(set (match_operand:SI 0 "register_operand" "=r")
14043         (plus:SI (match_operand:SI 1 "register_operand" "b")
14044                  (const:SI
14045                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14046                               UNSPEC_TLSDESC))))]
14047   "!TARGET_64BIT && TARGET_GNU2_TLS"
14048   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14049   [(set_attr "type" "lea")
14050    (set_attr "mode" "SI")
14051    (set_attr "length" "6")
14052    (set_attr "length_address" "4")])
14054 (define_insn "*tls_dynamic_gnu2_call_32"
14055   [(set (match_operand:SI 0 "register_operand" "=a")
14056         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14057                     (match_operand:SI 2 "register_operand" "0")
14058                     ;; we have to make sure %ebx still points to the GOT
14059                     (match_operand:SI 3 "register_operand" "b")
14060                     (reg:SI SP_REG)]
14061                    UNSPEC_TLSDESC))
14062    (clobber (reg:CC FLAGS_REG))]
14063   "!TARGET_64BIT && TARGET_GNU2_TLS"
14064   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14065   [(set_attr "type" "call")
14066    (set_attr "length" "2")
14067    (set_attr "length_address" "0")])
14069 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14070   [(set (match_operand:SI 0 "register_operand" "=&a")
14071         (plus:SI
14072          (unspec:SI [(match_operand 3 "tls_modbase_operand")
14073                      (match_operand:SI 4)
14074                      (match_operand:SI 2 "register_operand" "b")
14075                      (reg:SI SP_REG)]
14076                     UNSPEC_TLSDESC)
14077          (const:SI (unspec:SI
14078                     [(match_operand 1 "tls_symbolic_operand")]
14079                     UNSPEC_DTPOFF))))
14080    (clobber (reg:CC FLAGS_REG))]
14081   "!TARGET_64BIT && TARGET_GNU2_TLS"
14082   "#"
14083   ""
14084   [(set (match_dup 0) (match_dup 5))]
14086   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14087   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14090 (define_expand "tls_dynamic_gnu2_64"
14091   [(set (match_dup 2)
14092         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14093                    UNSPEC_TLSDESC))
14094    (parallel
14095     [(set (match_operand:DI 0 "register_operand")
14096           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14097                      UNSPEC_TLSDESC))
14098      (clobber (reg:CC FLAGS_REG))])]
14099   "TARGET_64BIT && TARGET_GNU2_TLS"
14101   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14102   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14105 (define_insn "*tls_dynamic_gnu2_lea_64"
14106   [(set (match_operand:DI 0 "register_operand" "=r")
14107         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14108                    UNSPEC_TLSDESC))]
14109   "TARGET_64BIT && TARGET_GNU2_TLS"
14110   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14111   [(set_attr "type" "lea")
14112    (set_attr "mode" "DI")
14113    (set_attr "length" "7")
14114    (set_attr "length_address" "4")])
14116 (define_insn "*tls_dynamic_gnu2_call_64"
14117   [(set (match_operand:DI 0 "register_operand" "=a")
14118         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14119                     (match_operand:DI 2 "register_operand" "0")
14120                     (reg:DI SP_REG)]
14121                    UNSPEC_TLSDESC))
14122    (clobber (reg:CC FLAGS_REG))]
14123   "TARGET_64BIT && TARGET_GNU2_TLS"
14124   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14125   [(set_attr "type" "call")
14126    (set_attr "length" "2")
14127    (set_attr "length_address" "0")])
14129 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14130   [(set (match_operand:DI 0 "register_operand" "=&a")
14131         (plus:DI
14132          (unspec:DI [(match_operand 2 "tls_modbase_operand")
14133                      (match_operand:DI 3)
14134                      (reg:DI SP_REG)]
14135                     UNSPEC_TLSDESC)
14136          (const:DI (unspec:DI
14137                     [(match_operand 1 "tls_symbolic_operand")]
14138                     UNSPEC_DTPOFF))))
14139    (clobber (reg:CC FLAGS_REG))]
14140   "TARGET_64BIT && TARGET_GNU2_TLS"
14141   "#"
14142   ""
14143   [(set (match_dup 0) (match_dup 4))]
14145   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14146   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14149 (define_split
14150   [(match_operand 0 "tls_address_pattern")]
14151   "TARGET_TLS_DIRECT_SEG_REFS"
14152   [(match_dup 0)]
14153   "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14156 ;; These patterns match the binary 387 instructions for addM3, subM3,
14157 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14158 ;; SFmode.  The first is the normal insn, the second the same insn but
14159 ;; with one operand a conversion, and the third the same insn but with
14160 ;; the other operand a conversion.  The conversion may be SFmode or
14161 ;; SImode if the target mode DFmode, but only SImode if the target mode
14162 ;; is SFmode.
14164 ;; Gcc is slightly more smart about handling normal two address instructions
14165 ;; so use special patterns for add and mull.
14167 (define_insn "*fop_<mode>_comm"
14168   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14169         (match_operator:MODEF 3 "binary_fp_operator"
14170           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14171            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14172   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14173     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14174    && COMMUTATIVE_ARITH_P (operands[3])
14175    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14176   "* return output_387_binary_op (insn, operands);"
14177   [(set (attr "type")
14178         (if_then_else (eq_attr "alternative" "1,2")
14179            (if_then_else (match_operand:MODEF 3 "mult_operator")
14180               (const_string "ssemul")
14181               (const_string "sseadd"))
14182            (if_then_else (match_operand:MODEF 3 "mult_operator")
14183               (const_string "fmul")
14184               (const_string "fop"))))
14185    (set_attr "isa" "*,noavx,avx")
14186    (set_attr "prefix" "orig,orig,vex")
14187    (set_attr "mode" "<MODE>")
14188    (set (attr "enabled")
14189      (if_then_else
14190        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14191        (if_then_else
14192          (eq_attr "alternative" "0")
14193          (symbol_ref "TARGET_MIX_SSE_I387
14194                       && X87_ENABLE_ARITH (<MODE>mode)")
14195          (const_string "*"))
14196        (if_then_else
14197          (eq_attr "alternative" "0")
14198          (symbol_ref "true")
14199          (symbol_ref "false"))))])
14201 (define_insn "*rcpsf2_sse"
14202   [(set (match_operand:SF 0 "register_operand" "=x")
14203         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14204                    UNSPEC_RCP))]
14205   "TARGET_SSE && TARGET_SSE_MATH"
14206   "%vrcpss\t{%1, %d0|%d0, %1}"
14207   [(set_attr "type" "sse")
14208    (set_attr "atom_sse_attr" "rcp")
14209    (set_attr "btver2_sse_attr" "rcp")
14210    (set_attr "prefix" "maybe_vex")
14211    (set_attr "mode" "SF")])
14213 (define_insn "*fop_<mode>_1"
14214   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14215         (match_operator:MODEF 3 "binary_fp_operator"
14216           [(match_operand:MODEF 1
14217              "x87nonimm_ssenomem_operand" "0,fm,0,v")
14218            (match_operand:MODEF 2
14219              "nonimmediate_operand"       "fm,0,xm,vm")]))]
14220   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14221     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14222    && !COMMUTATIVE_ARITH_P (operands[3])
14223    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14224   "* return output_387_binary_op (insn, operands);"
14225   [(set (attr "type")
14226         (if_then_else (eq_attr "alternative" "2,3")
14227            (if_then_else (match_operand:MODEF 3 "div_operator")
14228               (const_string "ssediv")
14229               (const_string "sseadd"))
14230            (if_then_else (match_operand:MODEF 3 "div_operator")
14231               (const_string "fdiv")
14232               (const_string "fop"))))
14233    (set_attr "isa" "*,*,noavx,avx")
14234    (set_attr "prefix" "orig,orig,orig,vex")
14235    (set_attr "mode" "<MODE>")
14236    (set (attr "enabled")
14237      (if_then_else
14238        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14239        (if_then_else
14240          (eq_attr "alternative" "0,1")
14241          (symbol_ref "TARGET_MIX_SSE_I387
14242                       && X87_ENABLE_ARITH (<MODE>mode)")
14243          (const_string "*"))
14244        (if_then_else
14245          (eq_attr "alternative" "0,1")
14246          (symbol_ref "true")
14247          (symbol_ref "false"))))])
14249 ;; ??? Add SSE splitters for these!
14250 (define_insn "*fop_<MODEF:mode>_2_i387"
14251   [(set (match_operand:MODEF 0 "register_operand" "=f")
14252         (match_operator:MODEF 3 "binary_fp_operator"
14253           [(float:MODEF
14254              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14255            (match_operand:MODEF 2 "register_operand" "0")]))]
14256   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14257    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14258    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14259        || optimize_function_for_size_p (cfun))"
14260   "* return output_387_binary_op (insn, operands);"
14261   [(set (attr "type")
14262         (cond [(match_operand:MODEF 3 "mult_operator")
14263                  (const_string "fmul")
14264                (match_operand:MODEF 3 "div_operator")
14265                  (const_string "fdiv")
14266               ]
14267               (const_string "fop")))
14268    (set_attr "fp_int_src" "true")
14269    (set_attr "mode" "<SWI24:MODE>")])
14271 (define_insn "*fop_<MODEF:mode>_3_i387"
14272   [(set (match_operand:MODEF 0 "register_operand" "=f")
14273         (match_operator:MODEF 3 "binary_fp_operator"
14274           [(match_operand:MODEF 1 "register_operand" "0")
14275            (float:MODEF
14276              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14277   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14278    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14279    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14280        || optimize_function_for_size_p (cfun))"
14281   "* return output_387_binary_op (insn, operands);"
14282   [(set (attr "type")
14283         (cond [(match_operand:MODEF 3 "mult_operator")
14284                  (const_string "fmul")
14285                (match_operand:MODEF 3 "div_operator")
14286                  (const_string "fdiv")
14287               ]
14288               (const_string "fop")))
14289    (set_attr "fp_int_src" "true")
14290    (set_attr "mode" "<MODE>")])
14292 (define_insn "*fop_df_4_i387"
14293   [(set (match_operand:DF 0 "register_operand" "=f,f")
14294         (match_operator:DF 3 "binary_fp_operator"
14295            [(float_extend:DF
14296              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14297             (match_operand:DF 2 "register_operand" "0,f")]))]
14298   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14299    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14300   "* return output_387_binary_op (insn, operands);"
14301   [(set (attr "type")
14302         (cond [(match_operand:DF 3 "mult_operator")
14303                  (const_string "fmul")
14304                (match_operand:DF 3 "div_operator")
14305                  (const_string "fdiv")
14306               ]
14307               (const_string "fop")))
14308    (set_attr "mode" "SF")])
14310 (define_insn "*fop_df_5_i387"
14311   [(set (match_operand:DF 0 "register_operand" "=f,f")
14312         (match_operator:DF 3 "binary_fp_operator"
14313           [(match_operand:DF 1 "register_operand" "0,f")
14314            (float_extend:DF
14315             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14316   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14317    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14318   "* return output_387_binary_op (insn, operands);"
14319   [(set (attr "type")
14320         (cond [(match_operand:DF 3 "mult_operator")
14321                  (const_string "fmul")
14322                (match_operand:DF 3 "div_operator")
14323                  (const_string "fdiv")
14324               ]
14325               (const_string "fop")))
14326    (set_attr "mode" "SF")])
14328 (define_insn "*fop_df_6_i387"
14329   [(set (match_operand:DF 0 "register_operand" "=f,f")
14330         (match_operator:DF 3 "binary_fp_operator"
14331           [(float_extend:DF
14332             (match_operand:SF 1 "register_operand" "0,f"))
14333            (float_extend:DF
14334             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14335   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14336    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14337   "* return output_387_binary_op (insn, operands);"
14338   [(set (attr "type")
14339         (cond [(match_operand:DF 3 "mult_operator")
14340                  (const_string "fmul")
14341                (match_operand:DF 3 "div_operator")
14342                  (const_string "fdiv")
14343               ]
14344               (const_string "fop")))
14345    (set_attr "mode" "SF")])
14347 (define_insn "*fop_xf_comm_i387"
14348   [(set (match_operand:XF 0 "register_operand" "=f")
14349         (match_operator:XF 3 "binary_fp_operator"
14350                         [(match_operand:XF 1 "register_operand" "%0")
14351                          (match_operand:XF 2 "register_operand" "f")]))]
14352   "TARGET_80387
14353    && COMMUTATIVE_ARITH_P (operands[3])"
14354   "* return output_387_binary_op (insn, operands);"
14355   [(set (attr "type")
14356         (if_then_else (match_operand:XF 3 "mult_operator")
14357            (const_string "fmul")
14358            (const_string "fop")))
14359    (set_attr "mode" "XF")])
14361 (define_insn "*fop_xf_1_i387"
14362   [(set (match_operand:XF 0 "register_operand" "=f,f")
14363         (match_operator:XF 3 "binary_fp_operator"
14364                         [(match_operand:XF 1 "register_operand" "0,f")
14365                          (match_operand:XF 2 "register_operand" "f,0")]))]
14366   "TARGET_80387
14367    && !COMMUTATIVE_ARITH_P (operands[3])"
14368   "* return output_387_binary_op (insn, operands);"
14369   [(set (attr "type")
14370         (if_then_else (match_operand:XF 3 "div_operator")
14371            (const_string "fdiv")
14372            (const_string "fop")))
14373    (set_attr "mode" "XF")])
14375 (define_insn "*fop_xf_2_i387"
14376   [(set (match_operand:XF 0 "register_operand" "=f")
14377         (match_operator:XF 3 "binary_fp_operator"
14378           [(float:XF
14379              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14380            (match_operand:XF 2 "register_operand" "0")]))]
14381   "TARGET_80387
14382    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14383   "* return output_387_binary_op (insn, operands);"
14384   [(set (attr "type")
14385         (cond [(match_operand:XF 3 "mult_operator")
14386                  (const_string "fmul")
14387                (match_operand:XF 3 "div_operator")
14388                  (const_string "fdiv")
14389               ]
14390               (const_string "fop")))
14391    (set_attr "fp_int_src" "true")
14392    (set_attr "mode" "<MODE>")])
14394 (define_insn "*fop_xf_3_i387"
14395   [(set (match_operand:XF 0 "register_operand" "=f")
14396         (match_operator:XF 3 "binary_fp_operator"
14397           [(match_operand:XF 1 "register_operand" "0")
14398            (float:XF
14399              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14400   "TARGET_80387
14401    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14402   "* return output_387_binary_op (insn, operands);"
14403   [(set (attr "type")
14404         (cond [(match_operand:XF 3 "mult_operator")
14405                  (const_string "fmul")
14406                (match_operand:XF 3 "div_operator")
14407                  (const_string "fdiv")
14408               ]
14409               (const_string "fop")))
14410    (set_attr "fp_int_src" "true")
14411    (set_attr "mode" "<MODE>")])
14413 (define_insn "*fop_xf_4_i387"
14414   [(set (match_operand:XF 0 "register_operand" "=f,f")
14415         (match_operator:XF 3 "binary_fp_operator"
14416            [(float_extend:XF
14417               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14418             (match_operand:XF 2 "register_operand" "0,f")]))]
14419   "TARGET_80387"
14420   "* return output_387_binary_op (insn, operands);"
14421   [(set (attr "type")
14422         (cond [(match_operand:XF 3 "mult_operator")
14423                  (const_string "fmul")
14424                (match_operand:XF 3 "div_operator")
14425                  (const_string "fdiv")
14426               ]
14427               (const_string "fop")))
14428    (set_attr "mode" "<MODE>")])
14430 (define_insn "*fop_xf_5_i387"
14431   [(set (match_operand:XF 0 "register_operand" "=f,f")
14432         (match_operator:XF 3 "binary_fp_operator"
14433           [(match_operand:XF 1 "register_operand" "0,f")
14434            (float_extend:XF
14435              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14436   "TARGET_80387"
14437   "* return output_387_binary_op (insn, operands);"
14438   [(set (attr "type")
14439         (cond [(match_operand:XF 3 "mult_operator")
14440                  (const_string "fmul")
14441                (match_operand:XF 3 "div_operator")
14442                  (const_string "fdiv")
14443               ]
14444               (const_string "fop")))
14445    (set_attr "mode" "<MODE>")])
14447 (define_insn "*fop_xf_6_i387"
14448   [(set (match_operand:XF 0 "register_operand" "=f,f")
14449         (match_operator:XF 3 "binary_fp_operator"
14450           [(float_extend:XF
14451              (match_operand:MODEF 1 "register_operand" "0,f"))
14452            (float_extend:XF
14453              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14454   "TARGET_80387"
14455   "* return output_387_binary_op (insn, operands);"
14456   [(set (attr "type")
14457         (cond [(match_operand:XF 3 "mult_operator")
14458                  (const_string "fmul")
14459                (match_operand:XF 3 "div_operator")
14460                  (const_string "fdiv")
14461               ]
14462               (const_string "fop")))
14463    (set_attr "mode" "<MODE>")])
14465 ;; FPU special functions.
14467 ;; This pattern implements a no-op XFmode truncation for
14468 ;; all fancy i386 XFmode math functions.
14470 (define_insn "truncxf<mode>2_i387_noop_unspec"
14471   [(set (match_operand:MODEF 0 "register_operand" "=f")
14472         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14473         UNSPEC_TRUNC_NOOP))]
14474   "TARGET_USE_FANCY_MATH_387"
14475   "* return output_387_reg_move (insn, operands);"
14476   [(set_attr "type" "fmov")
14477    (set_attr "mode" "<MODE>")])
14479 (define_insn "sqrtxf2"
14480   [(set (match_operand:XF 0 "register_operand" "=f")
14481         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14482   "TARGET_USE_FANCY_MATH_387"
14483   "fsqrt"
14484   [(set_attr "type" "fpspc")
14485    (set_attr "mode" "XF")
14486    (set_attr "athlon_decode" "direct")
14487    (set_attr "amdfam10_decode" "direct")
14488    (set_attr "bdver1_decode" "direct")])
14490 (define_insn "sqrt_extend<mode>xf2_i387"
14491   [(set (match_operand:XF 0 "register_operand" "=f")
14492         (sqrt:XF
14493           (float_extend:XF
14494             (match_operand:MODEF 1 "register_operand" "0"))))]
14495   "TARGET_USE_FANCY_MATH_387"
14496   "fsqrt"
14497   [(set_attr "type" "fpspc")
14498    (set_attr "mode" "XF")
14499    (set_attr "athlon_decode" "direct")
14500    (set_attr "amdfam10_decode" "direct")
14501    (set_attr "bdver1_decode" "direct")])
14503 (define_insn "*rsqrtsf2_sse"
14504   [(set (match_operand:SF 0 "register_operand" "=x")
14505         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14506                    UNSPEC_RSQRT))]
14507   "TARGET_SSE && TARGET_SSE_MATH"
14508   "%vrsqrtss\t{%1, %d0|%d0, %1}"
14509   [(set_attr "type" "sse")
14510    (set_attr "atom_sse_attr" "rcp")
14511    (set_attr "btver2_sse_attr" "rcp")
14512    (set_attr "prefix" "maybe_vex")
14513    (set_attr "mode" "SF")])
14515 (define_expand "rsqrtsf2"
14516   [(set (match_operand:SF 0 "register_operand")
14517         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14518                    UNSPEC_RSQRT))]
14519   "TARGET_SSE && TARGET_SSE_MATH"
14521   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14522   DONE;
14525 (define_insn "*sqrt<mode>2_sse"
14526   [(set (match_operand:MODEF 0 "register_operand" "=v")
14527         (sqrt:MODEF
14528           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14529   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14530   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14531   [(set_attr "type" "sse")
14532    (set_attr "atom_sse_attr" "sqrt")
14533    (set_attr "btver2_sse_attr" "sqrt")
14534    (set_attr "prefix" "maybe_vex")
14535    (set_attr "mode" "<MODE>")
14536    (set_attr "athlon_decode" "*")
14537    (set_attr "amdfam10_decode" "*")
14538    (set_attr "bdver1_decode" "*")])
14540 (define_expand "sqrt<mode>2"
14541   [(set (match_operand:MODEF 0 "register_operand")
14542         (sqrt:MODEF
14543           (match_operand:MODEF 1 "nonimmediate_operand")))]
14544   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14545    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14547   if (<MODE>mode == SFmode
14548       && TARGET_SSE && TARGET_SSE_MATH
14549       && TARGET_RECIP_SQRT
14550       && !optimize_function_for_size_p (cfun)
14551       && flag_finite_math_only && !flag_trapping_math
14552       && flag_unsafe_math_optimizations)
14553     {
14554       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14555       DONE;
14556     }
14558   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14559     {
14560       rtx op0 = gen_reg_rtx (XFmode);
14561       rtx op1 = force_reg (<MODE>mode, operands[1]);
14563       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14564       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14565       DONE;
14566    }
14569 (define_insn "fpremxf4_i387"
14570   [(set (match_operand:XF 0 "register_operand" "=f")
14571         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14572                     (match_operand:XF 3 "register_operand" "1")]
14573                    UNSPEC_FPREM_F))
14574    (set (match_operand:XF 1 "register_operand" "=u")
14575         (unspec:XF [(match_dup 2) (match_dup 3)]
14576                    UNSPEC_FPREM_U))
14577    (set (reg:CCFP FPSR_REG)
14578         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14579                      UNSPEC_C2_FLAG))]
14580   "TARGET_USE_FANCY_MATH_387
14581    && flag_finite_math_only"
14582   "fprem"
14583   [(set_attr "type" "fpspc")
14584    (set_attr "znver1_decode" "vector")
14585    (set_attr "mode" "XF")])
14587 (define_expand "fmodxf3"
14588   [(use (match_operand:XF 0 "register_operand"))
14589    (use (match_operand:XF 1 "general_operand"))
14590    (use (match_operand:XF 2 "general_operand"))]
14591   "TARGET_USE_FANCY_MATH_387
14592    && flag_finite_math_only"
14594   rtx_code_label *label = gen_label_rtx ();
14596   rtx op1 = gen_reg_rtx (XFmode);
14597   rtx op2 = gen_reg_rtx (XFmode);
14599   emit_move_insn (op2, operands[2]);
14600   emit_move_insn (op1, operands[1]);
14602   emit_label (label);
14603   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14604   ix86_emit_fp_unordered_jump (label);
14605   LABEL_NUSES (label) = 1;
14607   emit_move_insn (operands[0], op1);
14608   DONE;
14611 (define_expand "fmod<mode>3"
14612   [(use (match_operand:MODEF 0 "register_operand"))
14613    (use (match_operand:MODEF 1 "general_operand"))
14614    (use (match_operand:MODEF 2 "general_operand"))]
14615   "TARGET_USE_FANCY_MATH_387
14616    && flag_finite_math_only"
14618   rtx (*gen_truncxf) (rtx, rtx);
14620   rtx_code_label *label = gen_label_rtx ();
14622   rtx op1 = gen_reg_rtx (XFmode);
14623   rtx op2 = gen_reg_rtx (XFmode);
14625   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14626   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14628   emit_label (label);
14629   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14630   ix86_emit_fp_unordered_jump (label);
14631   LABEL_NUSES (label) = 1;
14633   /* Truncate the result properly for strict SSE math.  */
14634   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14635       && !TARGET_MIX_SSE_I387)
14636     gen_truncxf = gen_truncxf<mode>2;
14637   else
14638     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14640   emit_insn (gen_truncxf (operands[0], op1));
14641   DONE;
14644 (define_insn "fprem1xf4_i387"
14645   [(set (match_operand:XF 0 "register_operand" "=f")
14646         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14647                     (match_operand:XF 3 "register_operand" "1")]
14648                    UNSPEC_FPREM1_F))
14649    (set (match_operand:XF 1 "register_operand" "=u")
14650         (unspec:XF [(match_dup 2) (match_dup 3)]
14651                    UNSPEC_FPREM1_U))
14652    (set (reg:CCFP FPSR_REG)
14653         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14654                      UNSPEC_C2_FLAG))]
14655   "TARGET_USE_FANCY_MATH_387
14656    && flag_finite_math_only"
14657   "fprem1"
14658   [(set_attr "type" "fpspc")
14659    (set_attr "znver1_decode" "vector")
14660    (set_attr "mode" "XF")])
14662 (define_expand "remainderxf3"
14663   [(use (match_operand:XF 0 "register_operand"))
14664    (use (match_operand:XF 1 "general_operand"))
14665    (use (match_operand:XF 2 "general_operand"))]
14666   "TARGET_USE_FANCY_MATH_387
14667    && flag_finite_math_only"
14669   rtx_code_label *label = gen_label_rtx ();
14671   rtx op1 = gen_reg_rtx (XFmode);
14672   rtx op2 = gen_reg_rtx (XFmode);
14674   emit_move_insn (op2, operands[2]);
14675   emit_move_insn (op1, operands[1]);
14677   emit_label (label);
14678   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14679   ix86_emit_fp_unordered_jump (label);
14680   LABEL_NUSES (label) = 1;
14682   emit_move_insn (operands[0], op1);
14683   DONE;
14686 (define_expand "remainder<mode>3"
14687   [(use (match_operand:MODEF 0 "register_operand"))
14688    (use (match_operand:MODEF 1 "general_operand"))
14689    (use (match_operand:MODEF 2 "general_operand"))]
14690   "TARGET_USE_FANCY_MATH_387
14691    && flag_finite_math_only"
14693   rtx (*gen_truncxf) (rtx, rtx);
14695   rtx_code_label *label = gen_label_rtx ();
14697   rtx op1 = gen_reg_rtx (XFmode);
14698   rtx op2 = gen_reg_rtx (XFmode);
14700   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14701   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14703   emit_label (label);
14705   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14706   ix86_emit_fp_unordered_jump (label);
14707   LABEL_NUSES (label) = 1;
14709   /* Truncate the result properly for strict SSE math.  */
14710   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14711       && !TARGET_MIX_SSE_I387)
14712     gen_truncxf = gen_truncxf<mode>2;
14713   else
14714     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14716   emit_insn (gen_truncxf (operands[0], op1));
14717   DONE;
14720 (define_int_iterator SINCOS
14721         [UNSPEC_SIN
14722          UNSPEC_COS])
14724 (define_int_attr sincos
14725         [(UNSPEC_SIN "sin")
14726          (UNSPEC_COS "cos")])
14728 (define_insn "*<sincos>xf2_i387"
14729   [(set (match_operand:XF 0 "register_operand" "=f")
14730         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14731                    SINCOS))]
14732   "TARGET_USE_FANCY_MATH_387
14733    && flag_unsafe_math_optimizations"
14734   "f<sincos>"
14735   [(set_attr "type" "fpspc")
14736    (set_attr "znver1_decode" "vector")
14737    (set_attr "mode" "XF")])
14739 (define_insn "*<sincos>_extend<mode>xf2_i387"
14740   [(set (match_operand:XF 0 "register_operand" "=f")
14741         (unspec:XF [(float_extend:XF
14742                       (match_operand:MODEF 1 "register_operand" "0"))]
14743                    SINCOS))]
14744   "TARGET_USE_FANCY_MATH_387
14745    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14746        || TARGET_MIX_SSE_I387)
14747    && flag_unsafe_math_optimizations"
14748   "f<sincos>"
14749   [(set_attr "type" "fpspc")
14750    (set_attr "znver1_decode" "vector")
14751    (set_attr "mode" "XF")])
14753 ;; When sincos pattern is defined, sin and cos builtin functions will be
14754 ;; expanded to sincos pattern with one of its outputs left unused.
14755 ;; CSE pass will figure out if two sincos patterns can be combined,
14756 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14757 ;; depending on the unused output.
14759 (define_insn "sincosxf3"
14760   [(set (match_operand:XF 0 "register_operand" "=f")
14761         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14762                    UNSPEC_SINCOS_COS))
14763    (set (match_operand:XF 1 "register_operand" "=u")
14764         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14765   "TARGET_USE_FANCY_MATH_387
14766    && flag_unsafe_math_optimizations"
14767   "fsincos"
14768   [(set_attr "type" "fpspc")
14769    (set_attr "znver1_decode" "vector")
14770    (set_attr "mode" "XF")])
14772 (define_split
14773   [(set (match_operand:XF 0 "register_operand")
14774         (unspec:XF [(match_operand:XF 2 "register_operand")]
14775                    UNSPEC_SINCOS_COS))
14776    (set (match_operand:XF 1 "register_operand")
14777         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14778   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14779    && can_create_pseudo_p ()"
14780   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14782 (define_split
14783   [(set (match_operand:XF 0 "register_operand")
14784         (unspec:XF [(match_operand:XF 2 "register_operand")]
14785                    UNSPEC_SINCOS_COS))
14786    (set (match_operand:XF 1 "register_operand")
14787         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14788   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14789    && can_create_pseudo_p ()"
14790   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14792 (define_insn "sincos_extend<mode>xf3_i387"
14793   [(set (match_operand:XF 0 "register_operand" "=f")
14794         (unspec:XF [(float_extend:XF
14795                       (match_operand:MODEF 2 "register_operand" "0"))]
14796                    UNSPEC_SINCOS_COS))
14797    (set (match_operand:XF 1 "register_operand" "=u")
14798         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14799   "TARGET_USE_FANCY_MATH_387
14800    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14801        || TARGET_MIX_SSE_I387)
14802    && flag_unsafe_math_optimizations"
14803   "fsincos"
14804   [(set_attr "type" "fpspc")
14805    (set_attr "znver1_decode" "vector")
14806    (set_attr "mode" "XF")])
14808 (define_split
14809   [(set (match_operand:XF 0 "register_operand")
14810         (unspec:XF [(float_extend:XF
14811                       (match_operand:MODEF 2 "register_operand"))]
14812                    UNSPEC_SINCOS_COS))
14813    (set (match_operand:XF 1 "register_operand")
14814         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14815   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14816    && can_create_pseudo_p ()"
14817   [(set (match_dup 1)
14818         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14820 (define_split
14821   [(set (match_operand:XF 0 "register_operand")
14822         (unspec:XF [(float_extend:XF
14823                       (match_operand:MODEF 2 "register_operand"))]
14824                    UNSPEC_SINCOS_COS))
14825    (set (match_operand:XF 1 "register_operand")
14826         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14827   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14828    && can_create_pseudo_p ()"
14829   [(set (match_dup 0)
14830         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14832 (define_expand "sincos<mode>3"
14833   [(use (match_operand:MODEF 0 "register_operand"))
14834    (use (match_operand:MODEF 1 "register_operand"))
14835    (use (match_operand:MODEF 2 "register_operand"))]
14836   "TARGET_USE_FANCY_MATH_387
14837    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838        || TARGET_MIX_SSE_I387)
14839    && flag_unsafe_math_optimizations"
14841   rtx op0 = gen_reg_rtx (XFmode);
14842   rtx op1 = gen_reg_rtx (XFmode);
14844   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14845   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14846   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14847   DONE;
14850 (define_insn "fptanxf4_i387"
14851   [(set (match_operand:XF 0 "register_operand" "=f")
14852         (match_operand:XF 3 "const_double_operand" "F"))
14853    (set (match_operand:XF 1 "register_operand" "=u")
14854         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14855                    UNSPEC_TAN))]
14856   "TARGET_USE_FANCY_MATH_387
14857    && flag_unsafe_math_optimizations
14858    && standard_80387_constant_p (operands[3]) == 2"
14859   "fptan"
14860   [(set_attr "type" "fpspc")
14861    (set_attr "znver1_decode" "vector")
14862    (set_attr "mode" "XF")])
14864 (define_insn "fptan_extend<mode>xf4_i387"
14865   [(set (match_operand:MODEF 0 "register_operand" "=f")
14866         (match_operand:MODEF 3 "const_double_operand" "F"))
14867    (set (match_operand:XF 1 "register_operand" "=u")
14868         (unspec:XF [(float_extend:XF
14869                       (match_operand:MODEF 2 "register_operand" "0"))]
14870                    UNSPEC_TAN))]
14871   "TARGET_USE_FANCY_MATH_387
14872    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14873        || TARGET_MIX_SSE_I387)
14874    && flag_unsafe_math_optimizations
14875    && standard_80387_constant_p (operands[3]) == 2"
14876   "fptan"
14877   [(set_attr "type" "fpspc")
14878    (set_attr "znver1_decode" "vector")
14879    (set_attr "mode" "XF")])
14881 (define_expand "tanxf2"
14882   [(use (match_operand:XF 0 "register_operand"))
14883    (use (match_operand:XF 1 "register_operand"))]
14884   "TARGET_USE_FANCY_MATH_387
14885    && flag_unsafe_math_optimizations"
14887   rtx one = gen_reg_rtx (XFmode);
14888   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14890   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14891   DONE;
14894 (define_expand "tan<mode>2"
14895   [(use (match_operand:MODEF 0 "register_operand"))
14896    (use (match_operand:MODEF 1 "register_operand"))]
14897   "TARGET_USE_FANCY_MATH_387
14898    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14899        || TARGET_MIX_SSE_I387)
14900    && flag_unsafe_math_optimizations"
14902   rtx op0 = gen_reg_rtx (XFmode);
14904   rtx one = gen_reg_rtx (<MODE>mode);
14905   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14907   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14908                                              operands[1], op2));
14909   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14910   DONE;
14913 (define_insn "*fpatanxf3_i387"
14914   [(set (match_operand:XF 0 "register_operand" "=f")
14915         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14916                     (match_operand:XF 2 "register_operand" "u")]
14917                    UNSPEC_FPATAN))
14918    (clobber (match_scratch:XF 3 "=2"))]
14919   "TARGET_USE_FANCY_MATH_387
14920    && flag_unsafe_math_optimizations"
14921   "fpatan"
14922   [(set_attr "type" "fpspc")
14923    (set_attr "znver1_decode" "vector")
14924    (set_attr "mode" "XF")])
14926 (define_insn "fpatan_extend<mode>xf3_i387"
14927   [(set (match_operand:XF 0 "register_operand" "=f")
14928         (unspec:XF [(float_extend:XF
14929                       (match_operand:MODEF 1 "register_operand" "0"))
14930                     (float_extend:XF
14931                       (match_operand:MODEF 2 "register_operand" "u"))]
14932                    UNSPEC_FPATAN))
14933    (clobber (match_scratch:XF 3 "=2"))]
14934   "TARGET_USE_FANCY_MATH_387
14935    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14936        || TARGET_MIX_SSE_I387)
14937    && flag_unsafe_math_optimizations"
14938   "fpatan"
14939   [(set_attr "type" "fpspc")
14940    (set_attr "znver1_decode" "vector")
14941    (set_attr "mode" "XF")])
14943 (define_expand "atan2xf3"
14944   [(parallel [(set (match_operand:XF 0 "register_operand")
14945                    (unspec:XF [(match_operand:XF 2 "register_operand")
14946                                (match_operand:XF 1 "register_operand")]
14947                               UNSPEC_FPATAN))
14948               (clobber (match_scratch:XF 3))])]
14949   "TARGET_USE_FANCY_MATH_387
14950    && flag_unsafe_math_optimizations")
14952 (define_expand "atan2<mode>3"
14953   [(use (match_operand:MODEF 0 "register_operand"))
14954    (use (match_operand:MODEF 1 "register_operand"))
14955    (use (match_operand:MODEF 2 "register_operand"))]
14956   "TARGET_USE_FANCY_MATH_387
14957    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14958        || TARGET_MIX_SSE_I387)
14959    && flag_unsafe_math_optimizations"
14961   rtx op0 = gen_reg_rtx (XFmode);
14963   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14964   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14965   DONE;
14968 (define_expand "atanxf2"
14969   [(parallel [(set (match_operand:XF 0 "register_operand")
14970                    (unspec:XF [(match_dup 2)
14971                                (match_operand:XF 1 "register_operand")]
14972                               UNSPEC_FPATAN))
14973               (clobber (match_scratch:XF 3))])]
14974   "TARGET_USE_FANCY_MATH_387
14975    && flag_unsafe_math_optimizations"
14977   operands[2] = gen_reg_rtx (XFmode);
14978   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14981 (define_expand "atan<mode>2"
14982   [(use (match_operand:MODEF 0 "register_operand"))
14983    (use (match_operand:MODEF 1 "register_operand"))]
14984   "TARGET_USE_FANCY_MATH_387
14985    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14986        || TARGET_MIX_SSE_I387)
14987    && flag_unsafe_math_optimizations"
14989   rtx op0 = gen_reg_rtx (XFmode);
14991   rtx op2 = gen_reg_rtx (<MODE>mode);
14992   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14994   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14995   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14996   DONE;
14999 (define_expand "asinxf2"
15000   [(set (match_dup 2)
15001         (mult:XF (match_operand:XF 1 "register_operand")
15002                  (match_dup 1)))
15003    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15004    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15005    (parallel [(set (match_operand:XF 0 "register_operand")
15006                    (unspec:XF [(match_dup 5) (match_dup 1)]
15007                               UNSPEC_FPATAN))
15008               (clobber (match_scratch:XF 6))])]
15009   "TARGET_USE_FANCY_MATH_387
15010    && flag_unsafe_math_optimizations"
15012   int i;
15014   for (i = 2; i < 6; i++)
15015     operands[i] = gen_reg_rtx (XFmode);
15017   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15020 (define_expand "asin<mode>2"
15021   [(use (match_operand:MODEF 0 "register_operand"))
15022    (use (match_operand:MODEF 1 "general_operand"))]
15023   "TARGET_USE_FANCY_MATH_387
15024    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15025        || TARGET_MIX_SSE_I387)
15026    && flag_unsafe_math_optimizations"
15028   rtx op0 = gen_reg_rtx (XFmode);
15029   rtx op1 = gen_reg_rtx (XFmode);
15031   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15032   emit_insn (gen_asinxf2 (op0, op1));
15033   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15034   DONE;
15037 (define_expand "acosxf2"
15038   [(set (match_dup 2)
15039         (mult:XF (match_operand:XF 1 "register_operand")
15040                  (match_dup 1)))
15041    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15042    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15043    (parallel [(set (match_operand:XF 0 "register_operand")
15044                    (unspec:XF [(match_dup 1) (match_dup 5)]
15045                               UNSPEC_FPATAN))
15046               (clobber (match_scratch:XF 6))])]
15047   "TARGET_USE_FANCY_MATH_387
15048    && flag_unsafe_math_optimizations"
15050   int i;
15052   for (i = 2; i < 6; i++)
15053     operands[i] = gen_reg_rtx (XFmode);
15055   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15058 (define_expand "acos<mode>2"
15059   [(use (match_operand:MODEF 0 "register_operand"))
15060    (use (match_operand:MODEF 1 "general_operand"))]
15061   "TARGET_USE_FANCY_MATH_387
15062    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15063        || TARGET_MIX_SSE_I387)
15064    && flag_unsafe_math_optimizations"
15066   rtx op0 = gen_reg_rtx (XFmode);
15067   rtx op1 = gen_reg_rtx (XFmode);
15069   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15070   emit_insn (gen_acosxf2 (op0, op1));
15071   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15072   DONE;
15075 (define_insn "fyl2xxf3_i387"
15076   [(set (match_operand:XF 0 "register_operand" "=f")
15077         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15078                     (match_operand:XF 2 "register_operand" "u")]
15079                    UNSPEC_FYL2X))
15080    (clobber (match_scratch:XF 3 "=2"))]
15081   "TARGET_USE_FANCY_MATH_387
15082    && flag_unsafe_math_optimizations"
15083   "fyl2x"
15084   [(set_attr "type" "fpspc")
15085    (set_attr "znver1_decode" "vector")
15086    (set_attr "mode" "XF")])
15088 (define_insn "fyl2x_extend<mode>xf3_i387"
15089   [(set (match_operand:XF 0 "register_operand" "=f")
15090         (unspec:XF [(float_extend:XF
15091                       (match_operand:MODEF 1 "register_operand" "0"))
15092                     (match_operand:XF 2 "register_operand" "u")]
15093                    UNSPEC_FYL2X))
15094    (clobber (match_scratch:XF 3 "=2"))]
15095   "TARGET_USE_FANCY_MATH_387
15096    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15097        || TARGET_MIX_SSE_I387)
15098    && flag_unsafe_math_optimizations"
15099   "fyl2x"
15100   [(set_attr "type" "fpspc")
15101    (set_attr "znver1_decode" "vector")
15102    (set_attr "mode" "XF")])
15104 (define_expand "logxf2"
15105   [(parallel [(set (match_operand:XF 0 "register_operand")
15106                    (unspec:XF [(match_operand:XF 1 "register_operand")
15107                                (match_dup 2)] UNSPEC_FYL2X))
15108               (clobber (match_scratch:XF 3))])]
15109   "TARGET_USE_FANCY_MATH_387
15110    && flag_unsafe_math_optimizations"
15112   operands[2] = gen_reg_rtx (XFmode);
15113   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15116 (define_expand "log<mode>2"
15117   [(use (match_operand:MODEF 0 "register_operand"))
15118    (use (match_operand:MODEF 1 "register_operand"))]
15119   "TARGET_USE_FANCY_MATH_387
15120    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15121        || TARGET_MIX_SSE_I387)
15122    && flag_unsafe_math_optimizations"
15124   rtx op0 = gen_reg_rtx (XFmode);
15126   rtx op2 = gen_reg_rtx (XFmode);
15127   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15129   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15130   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15131   DONE;
15134 (define_expand "log10xf2"
15135   [(parallel [(set (match_operand:XF 0 "register_operand")
15136                    (unspec:XF [(match_operand:XF 1 "register_operand")
15137                                (match_dup 2)] UNSPEC_FYL2X))
15138               (clobber (match_scratch:XF 3))])]
15139   "TARGET_USE_FANCY_MATH_387
15140    && flag_unsafe_math_optimizations"
15142   operands[2] = gen_reg_rtx (XFmode);
15143   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15146 (define_expand "log10<mode>2"
15147   [(use (match_operand:MODEF 0 "register_operand"))
15148    (use (match_operand:MODEF 1 "register_operand"))]
15149   "TARGET_USE_FANCY_MATH_387
15150    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15151        || TARGET_MIX_SSE_I387)
15152    && flag_unsafe_math_optimizations"
15154   rtx op0 = gen_reg_rtx (XFmode);
15156   rtx op2 = gen_reg_rtx (XFmode);
15157   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15159   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15160   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15161   DONE;
15164 (define_expand "log2xf2"
15165   [(parallel [(set (match_operand:XF 0 "register_operand")
15166                    (unspec:XF [(match_operand:XF 1 "register_operand")
15167                                (match_dup 2)] UNSPEC_FYL2X))
15168               (clobber (match_scratch:XF 3))])]
15169   "TARGET_USE_FANCY_MATH_387
15170    && flag_unsafe_math_optimizations"
15172   operands[2] = gen_reg_rtx (XFmode);
15173   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15176 (define_expand "log2<mode>2"
15177   [(use (match_operand:MODEF 0 "register_operand"))
15178    (use (match_operand:MODEF 1 "register_operand"))]
15179   "TARGET_USE_FANCY_MATH_387
15180    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15181        || TARGET_MIX_SSE_I387)
15182    && flag_unsafe_math_optimizations"
15184   rtx op0 = gen_reg_rtx (XFmode);
15186   rtx op2 = gen_reg_rtx (XFmode);
15187   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15189   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15190   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15191   DONE;
15194 (define_insn "fyl2xp1xf3_i387"
15195   [(set (match_operand:XF 0 "register_operand" "=f")
15196         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15197                     (match_operand:XF 2 "register_operand" "u")]
15198                    UNSPEC_FYL2XP1))
15199    (clobber (match_scratch:XF 3 "=2"))]
15200   "TARGET_USE_FANCY_MATH_387
15201    && flag_unsafe_math_optimizations"
15202   "fyl2xp1"
15203   [(set_attr "type" "fpspc")
15204    (set_attr "znver1_decode" "vector")
15205    (set_attr "mode" "XF")])
15207 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15208   [(set (match_operand:XF 0 "register_operand" "=f")
15209         (unspec:XF [(float_extend:XF
15210                       (match_operand:MODEF 1 "register_operand" "0"))
15211                     (match_operand:XF 2 "register_operand" "u")]
15212                    UNSPEC_FYL2XP1))
15213    (clobber (match_scratch:XF 3 "=2"))]
15214   "TARGET_USE_FANCY_MATH_387
15215    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15216        || TARGET_MIX_SSE_I387)
15217    && flag_unsafe_math_optimizations"
15218   "fyl2xp1"
15219   [(set_attr "type" "fpspc")
15220    (set_attr "znver1_decode" "vector")
15221    (set_attr "mode" "XF")])
15223 (define_expand "log1pxf2"
15224   [(use (match_operand:XF 0 "register_operand"))
15225    (use (match_operand:XF 1 "register_operand"))]
15226   "TARGET_USE_FANCY_MATH_387
15227    && flag_unsafe_math_optimizations"
15229   ix86_emit_i387_log1p (operands[0], operands[1]);
15230   DONE;
15233 (define_expand "log1p<mode>2"
15234   [(use (match_operand:MODEF 0 "register_operand"))
15235    (use (match_operand:MODEF 1 "register_operand"))]
15236   "TARGET_USE_FANCY_MATH_387
15237    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15238        || TARGET_MIX_SSE_I387)
15239    && flag_unsafe_math_optimizations"
15241   rtx op0;
15243   op0 = gen_reg_rtx (XFmode);
15245   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15247   ix86_emit_i387_log1p (op0, operands[1]);
15248   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15249   DONE;
15252 (define_insn "fxtractxf3_i387"
15253   [(set (match_operand:XF 0 "register_operand" "=f")
15254         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15255                    UNSPEC_XTRACT_FRACT))
15256    (set (match_operand:XF 1 "register_operand" "=u")
15257         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15258   "TARGET_USE_FANCY_MATH_387
15259    && flag_unsafe_math_optimizations"
15260   "fxtract"
15261   [(set_attr "type" "fpspc")
15262    (set_attr "znver1_decode" "vector")
15263    (set_attr "mode" "XF")])
15265 (define_insn "fxtract_extend<mode>xf3_i387"
15266   [(set (match_operand:XF 0 "register_operand" "=f")
15267         (unspec:XF [(float_extend:XF
15268                       (match_operand:MODEF 2 "register_operand" "0"))]
15269                    UNSPEC_XTRACT_FRACT))
15270    (set (match_operand:XF 1 "register_operand" "=u")
15271         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15272   "TARGET_USE_FANCY_MATH_387
15273    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15274        || TARGET_MIX_SSE_I387)
15275    && flag_unsafe_math_optimizations"
15276   "fxtract"
15277   [(set_attr "type" "fpspc")
15278    (set_attr "znver1_decode" "vector")
15279    (set_attr "mode" "XF")])
15281 (define_expand "logbxf2"
15282   [(parallel [(set (match_dup 2)
15283                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15284                               UNSPEC_XTRACT_FRACT))
15285               (set (match_operand:XF 0 "register_operand")
15286                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15287   "TARGET_USE_FANCY_MATH_387
15288    && flag_unsafe_math_optimizations"
15289   "operands[2] = gen_reg_rtx (XFmode);")
15291 (define_expand "logb<mode>2"
15292   [(use (match_operand:MODEF 0 "register_operand"))
15293    (use (match_operand:MODEF 1 "register_operand"))]
15294   "TARGET_USE_FANCY_MATH_387
15295    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15296        || TARGET_MIX_SSE_I387)
15297    && flag_unsafe_math_optimizations"
15299   rtx op0 = gen_reg_rtx (XFmode);
15300   rtx op1 = gen_reg_rtx (XFmode);
15302   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15303   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15304   DONE;
15307 (define_expand "ilogbxf2"
15308   [(use (match_operand:SI 0 "register_operand"))
15309    (use (match_operand:XF 1 "register_operand"))]
15310   "TARGET_USE_FANCY_MATH_387
15311    && flag_unsafe_math_optimizations"
15313   rtx op0, op1;
15315   if (optimize_insn_for_size_p ())
15316     FAIL;
15318   op0 = gen_reg_rtx (XFmode);
15319   op1 = gen_reg_rtx (XFmode);
15321   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15322   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15323   DONE;
15326 (define_expand "ilogb<mode>2"
15327   [(use (match_operand:SI 0 "register_operand"))
15328    (use (match_operand:MODEF 1 "register_operand"))]
15329   "TARGET_USE_FANCY_MATH_387
15330    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15331        || TARGET_MIX_SSE_I387)
15332    && flag_unsafe_math_optimizations"
15334   rtx op0, op1;
15336   if (optimize_insn_for_size_p ())
15337     FAIL;
15339   op0 = gen_reg_rtx (XFmode);
15340   op1 = gen_reg_rtx (XFmode);
15342   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15343   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15344   DONE;
15347 (define_insn "*f2xm1xf2_i387"
15348   [(set (match_operand:XF 0 "register_operand" "=f")
15349         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15350                    UNSPEC_F2XM1))]
15351   "TARGET_USE_FANCY_MATH_387
15352    && flag_unsafe_math_optimizations"
15353   "f2xm1"
15354   [(set_attr "type" "fpspc")
15355    (set_attr "znver1_decode" "vector")
15356    (set_attr "mode" "XF")])
15358 (define_insn "fscalexf4_i387"
15359   [(set (match_operand:XF 0 "register_operand" "=f")
15360         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15361                     (match_operand:XF 3 "register_operand" "1")]
15362                    UNSPEC_FSCALE_FRACT))
15363    (set (match_operand:XF 1 "register_operand" "=u")
15364         (unspec:XF [(match_dup 2) (match_dup 3)]
15365                    UNSPEC_FSCALE_EXP))]
15366   "TARGET_USE_FANCY_MATH_387
15367    && flag_unsafe_math_optimizations"
15368   "fscale"
15369   [(set_attr "type" "fpspc")
15370    (set_attr "znver1_decode" "vector")
15371    (set_attr "mode" "XF")])
15373 (define_expand "expNcorexf3"
15374   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15375                                (match_operand:XF 2 "register_operand")))
15376    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15377    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15378    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15379    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15380    (parallel [(set (match_operand:XF 0 "register_operand")
15381                    (unspec:XF [(match_dup 8) (match_dup 4)]
15382                               UNSPEC_FSCALE_FRACT))
15383               (set (match_dup 9)
15384                    (unspec:XF [(match_dup 8) (match_dup 4)]
15385                               UNSPEC_FSCALE_EXP))])]
15386   "TARGET_USE_FANCY_MATH_387
15387    && flag_unsafe_math_optimizations"
15389   int i;
15391   for (i = 3; i < 10; i++)
15392     operands[i] = gen_reg_rtx (XFmode);
15394   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15397 (define_expand "expxf2"
15398   [(use (match_operand:XF 0 "register_operand"))
15399    (use (match_operand:XF 1 "register_operand"))]
15400   "TARGET_USE_FANCY_MATH_387
15401    && flag_unsafe_math_optimizations"
15403   rtx op2;
15405   op2 = gen_reg_rtx (XFmode);
15406   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15408   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15409   DONE;
15412 (define_expand "exp<mode>2"
15413   [(use (match_operand:MODEF 0 "register_operand"))
15414    (use (match_operand:MODEF 1 "general_operand"))]
15415   "TARGET_USE_FANCY_MATH_387
15416    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15417        || TARGET_MIX_SSE_I387)
15418    && flag_unsafe_math_optimizations"
15420   rtx op0, op1;
15422   op0 = gen_reg_rtx (XFmode);
15423   op1 = gen_reg_rtx (XFmode);
15425   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15426   emit_insn (gen_expxf2 (op0, op1));
15427   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15428   DONE;
15431 (define_expand "exp10xf2"
15432   [(use (match_operand:XF 0 "register_operand"))
15433    (use (match_operand:XF 1 "register_operand"))]
15434   "TARGET_USE_FANCY_MATH_387
15435    && flag_unsafe_math_optimizations"
15437   rtx op2;
15439   op2 = gen_reg_rtx (XFmode);
15440   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15442   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15443   DONE;
15446 (define_expand "exp10<mode>2"
15447   [(use (match_operand:MODEF 0 "register_operand"))
15448    (use (match_operand:MODEF 1 "general_operand"))]
15449   "TARGET_USE_FANCY_MATH_387
15450    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15451        || TARGET_MIX_SSE_I387)
15452    && flag_unsafe_math_optimizations"
15454   rtx op0, op1;
15456   op0 = gen_reg_rtx (XFmode);
15457   op1 = gen_reg_rtx (XFmode);
15459   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15460   emit_insn (gen_exp10xf2 (op0, op1));
15461   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15462   DONE;
15465 (define_expand "exp2xf2"
15466   [(use (match_operand:XF 0 "register_operand"))
15467    (use (match_operand:XF 1 "register_operand"))]
15468   "TARGET_USE_FANCY_MATH_387
15469    && flag_unsafe_math_optimizations"
15471   rtx op2;
15473   op2 = gen_reg_rtx (XFmode);
15474   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
15476   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15477   DONE;
15480 (define_expand "exp2<mode>2"
15481   [(use (match_operand:MODEF 0 "register_operand"))
15482    (use (match_operand:MODEF 1 "general_operand"))]
15483   "TARGET_USE_FANCY_MATH_387
15484    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15485        || TARGET_MIX_SSE_I387)
15486    && flag_unsafe_math_optimizations"
15488   rtx op0, op1;
15490   op0 = gen_reg_rtx (XFmode);
15491   op1 = gen_reg_rtx (XFmode);
15493   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15494   emit_insn (gen_exp2xf2 (op0, op1));
15495   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15496   DONE;
15499 (define_expand "expm1xf2"
15500   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15501                                (match_dup 2)))
15502    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15503    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15504    (set (match_dup 9) (float_extend:XF (match_dup 13)))
15505    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15506    (parallel [(set (match_dup 7)
15507                    (unspec:XF [(match_dup 6) (match_dup 4)]
15508                               UNSPEC_FSCALE_FRACT))
15509               (set (match_dup 8)
15510                    (unspec:XF [(match_dup 6) (match_dup 4)]
15511                               UNSPEC_FSCALE_EXP))])
15512    (parallel [(set (match_dup 10)
15513                    (unspec:XF [(match_dup 9) (match_dup 8)]
15514                               UNSPEC_FSCALE_FRACT))
15515               (set (match_dup 11)
15516                    (unspec:XF [(match_dup 9) (match_dup 8)]
15517                               UNSPEC_FSCALE_EXP))])
15518    (set (match_dup 12) (minus:XF (match_dup 10)
15519                                  (float_extend:XF (match_dup 13))))
15520    (set (match_operand:XF 0 "register_operand")
15521         (plus:XF (match_dup 12) (match_dup 7)))]
15522   "TARGET_USE_FANCY_MATH_387
15523    && flag_unsafe_math_optimizations"
15525   int i;
15527   for (i = 2; i < 13; i++)
15528     operands[i] = gen_reg_rtx (XFmode);
15530   operands[13]
15531     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15533   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15536 (define_expand "expm1<mode>2"
15537   [(use (match_operand:MODEF 0 "register_operand"))
15538    (use (match_operand:MODEF 1 "general_operand"))]
15539   "TARGET_USE_FANCY_MATH_387
15540    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15541        || TARGET_MIX_SSE_I387)
15542    && flag_unsafe_math_optimizations"
15544   rtx op0, op1;
15546   op0 = gen_reg_rtx (XFmode);
15547   op1 = gen_reg_rtx (XFmode);
15549   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15550   emit_insn (gen_expm1xf2 (op0, op1));
15551   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15552   DONE;
15555 (define_expand "ldexpxf3"
15556   [(match_operand:XF 0 "register_operand")
15557    (match_operand:XF 1 "register_operand")
15558    (match_operand:SI 2 "register_operand")]
15559   "TARGET_USE_FANCY_MATH_387
15560    && flag_unsafe_math_optimizations"
15562   rtx tmp1, tmp2;
15564   tmp1 = gen_reg_rtx (XFmode);
15565   tmp2 = gen_reg_rtx (XFmode);
15567   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15568   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15569                                  operands[1], tmp1));
15570   DONE;
15573 (define_expand "ldexp<mode>3"
15574   [(use (match_operand:MODEF 0 "register_operand"))
15575    (use (match_operand:MODEF 1 "general_operand"))
15576    (use (match_operand:SI 2 "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, op1;
15584   op0 = gen_reg_rtx (XFmode);
15585   op1 = gen_reg_rtx (XFmode);
15587   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15588   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15589   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15590   DONE;
15593 (define_expand "scalbxf3"
15594   [(parallel [(set (match_operand:XF 0 " register_operand")
15595                    (unspec:XF [(match_operand:XF 1 "register_operand")
15596                                (match_operand:XF 2 "register_operand")]
15597                               UNSPEC_FSCALE_FRACT))
15598               (set (match_dup 3)
15599                    (unspec:XF [(match_dup 1) (match_dup 2)]
15600                               UNSPEC_FSCALE_EXP))])]
15601   "TARGET_USE_FANCY_MATH_387
15602    && flag_unsafe_math_optimizations"
15604   operands[3] = gen_reg_rtx (XFmode);
15607 (define_expand "scalb<mode>3"
15608   [(use (match_operand:MODEF 0 "register_operand"))
15609    (use (match_operand:MODEF 1 "general_operand"))
15610    (use (match_operand:MODEF 2 "general_operand"))]
15611   "TARGET_USE_FANCY_MATH_387
15612    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15613        || TARGET_MIX_SSE_I387)
15614    && flag_unsafe_math_optimizations"
15616   rtx op0, op1, op2;
15618   op0 = gen_reg_rtx (XFmode);
15619   op1 = gen_reg_rtx (XFmode);
15620   op2 = gen_reg_rtx (XFmode);
15622   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15623   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15624   emit_insn (gen_scalbxf3 (op0, op1, op2));
15625   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15626   DONE;
15629 (define_expand "significandxf2"
15630   [(parallel [(set (match_operand:XF 0 "register_operand")
15631                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15632                               UNSPEC_XTRACT_FRACT))
15633               (set (match_dup 2)
15634                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15635   "TARGET_USE_FANCY_MATH_387
15636    && flag_unsafe_math_optimizations"
15637   "operands[2] = gen_reg_rtx (XFmode);")
15639 (define_expand "significand<mode>2"
15640   [(use (match_operand:MODEF 0 "register_operand"))
15641    (use (match_operand:MODEF 1 "register_operand"))]
15642   "TARGET_USE_FANCY_MATH_387
15643    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15644        || TARGET_MIX_SSE_I387)
15645    && flag_unsafe_math_optimizations"
15647   rtx op0 = gen_reg_rtx (XFmode);
15648   rtx op1 = gen_reg_rtx (XFmode);
15650   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15651   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15652   DONE;
15656 (define_insn "sse4_1_round<mode>2"
15657   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15658         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
15659                        (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15660                       UNSPEC_ROUND))]
15661   "TARGET_SSE4_1"
15662   "@
15663    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15664    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15665   [(set_attr "type" "ssecvt")
15666    (set_attr "prefix_extra" "1,*")
15667    (set_attr "length_immediate" "*,1")
15668    (set_attr "prefix" "maybe_vex,evex")
15669    (set_attr "isa" "noavx512f,avx512f")
15670    (set_attr "mode" "<MODE>")])
15672 (define_insn "rintxf2"
15673   [(set (match_operand:XF 0 "register_operand" "=f")
15674         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15675                    UNSPEC_FRNDINT))]
15676   "TARGET_USE_FANCY_MATH_387"
15677   "frndint"
15678   [(set_attr "type" "fpspc")
15679    (set_attr "znver1_decode" "vector")
15680    (set_attr "mode" "XF")])
15682 (define_insn "rint<mode>2_frndint"
15683   [(set (match_operand:MODEF 0 "register_operand" "=f")
15684         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
15685                       UNSPEC_FRNDINT))]
15686   "TARGET_USE_FANCY_MATH_387"
15687   "frndint"
15688   [(set_attr "type" "fpspc")
15689    (set_attr "znver1_decode" "vector")
15690    (set_attr "mode" "<MODE>")])
15692 (define_expand "rint<mode>2"
15693   [(use (match_operand:MODEF 0 "register_operand"))
15694    (use (match_operand:MODEF 1 "register_operand"))]
15695   "(TARGET_USE_FANCY_MATH_387
15696     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15697         || TARGET_MIX_SSE_I387))
15698    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15700   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15701     {
15702       if (TARGET_SSE4_1)
15703         emit_insn (gen_sse4_1_round<mode>2
15704                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15705       else
15706         ix86_expand_rint (operands[0], operands[1]);
15707     }
15708   else
15709     emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
15710   DONE;
15713 (define_expand "round<mode>2"
15714   [(match_operand:X87MODEF 0 "register_operand")
15715    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15716   "(TARGET_USE_FANCY_MATH_387
15717     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15718         || TARGET_MIX_SSE_I387)
15719     && flag_unsafe_math_optimizations)
15720    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15721        && !flag_trapping_math && !flag_rounding_math)"
15723   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15724       && !flag_trapping_math && !flag_rounding_math)
15725     {
15726       if (TARGET_SSE4_1)
15727         {
15728           operands[1] = force_reg (<MODE>mode, operands[1]);
15729           ix86_expand_round_sse4 (operands[0], operands[1]);
15730         }
15731       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15732         ix86_expand_round (operands[0], operands[1]);
15733       else
15734         ix86_expand_rounddf_32 (operands[0], operands[1]);
15735     }
15736   else
15737     {
15738       operands[1] = force_reg (<MODE>mode, operands[1]);
15739       ix86_emit_i387_round (operands[0], operands[1]);
15740     }
15741   DONE;
15744 (define_insn_and_split "*fistdi2_1"
15745   [(set (match_operand:DI 0 "nonimmediate_operand")
15746         (unspec:DI [(match_operand:XF 1 "register_operand")]
15747                    UNSPEC_FIST))]
15748   "TARGET_USE_FANCY_MATH_387
15749    && can_create_pseudo_p ()"
15750   "#"
15751   "&& 1"
15752   [(const_int 0)]
15754   if (memory_operand (operands[0], VOIDmode))
15755     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15756   else
15757     {
15758       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15759       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15760                                          operands[2]));
15761     }
15762   DONE;
15764   [(set_attr "type" "fpspc")
15765    (set_attr "mode" "DI")])
15767 (define_insn "fistdi2"
15768   [(set (match_operand:DI 0 "memory_operand" "=m")
15769         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15770                    UNSPEC_FIST))
15771    (clobber (match_scratch:XF 2 "=&1f"))]
15772   "TARGET_USE_FANCY_MATH_387"
15773   "* return output_fix_trunc (insn, operands, false);"
15774   [(set_attr "type" "fpspc")
15775    (set_attr "mode" "DI")])
15777 (define_insn "fistdi2_with_temp"
15778   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15779         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15780                    UNSPEC_FIST))
15781    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15782    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15783   "TARGET_USE_FANCY_MATH_387"
15784   "#"
15785   [(set_attr "type" "fpspc")
15786    (set_attr "mode" "DI")])
15788 (define_split
15789   [(set (match_operand:DI 0 "register_operand")
15790         (unspec:DI [(match_operand:XF 1 "register_operand")]
15791                    UNSPEC_FIST))
15792    (clobber (match_operand:DI 2 "memory_operand"))
15793    (clobber (match_scratch 3))]
15794   "reload_completed"
15795   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15796               (clobber (match_dup 3))])
15797    (set (match_dup 0) (match_dup 2))])
15799 (define_split
15800   [(set (match_operand:DI 0 "memory_operand")
15801         (unspec:DI [(match_operand:XF 1 "register_operand")]
15802                    UNSPEC_FIST))
15803    (clobber (match_operand:DI 2 "memory_operand"))
15804    (clobber (match_scratch 3))]
15805   "reload_completed"
15806   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15807               (clobber (match_dup 3))])])
15809 (define_insn_and_split "*fist<mode>2_1"
15810   [(set (match_operand:SWI24 0 "register_operand")
15811         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15812                       UNSPEC_FIST))]
15813   "TARGET_USE_FANCY_MATH_387
15814    && can_create_pseudo_p ()"
15815   "#"
15816   "&& 1"
15817   [(const_int 0)]
15819   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15820   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15821                                         operands[2]));
15822   DONE;
15824   [(set_attr "type" "fpspc")
15825    (set_attr "mode" "<MODE>")])
15827 (define_insn "fist<mode>2"
15828   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15829         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15830                       UNSPEC_FIST))]
15831   "TARGET_USE_FANCY_MATH_387"
15832   "* return output_fix_trunc (insn, operands, false);"
15833   [(set_attr "type" "fpspc")
15834    (set_attr "mode" "<MODE>")])
15836 (define_insn "fist<mode>2_with_temp"
15837   [(set (match_operand:SWI24 0 "register_operand" "=r")
15838         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15839                       UNSPEC_FIST))
15840    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15841   "TARGET_USE_FANCY_MATH_387"
15842   "#"
15843   [(set_attr "type" "fpspc")
15844    (set_attr "mode" "<MODE>")])
15846 (define_split
15847   [(set (match_operand:SWI24 0 "register_operand")
15848         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15849                       UNSPEC_FIST))
15850    (clobber (match_operand:SWI24 2 "memory_operand"))]
15851   "reload_completed"
15852   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15853    (set (match_dup 0) (match_dup 2))])
15855 (define_split
15856   [(set (match_operand:SWI24 0 "memory_operand")
15857         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15858                       UNSPEC_FIST))
15859    (clobber (match_operand:SWI24 2 "memory_operand"))]
15860   "reload_completed"
15861   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15863 (define_expand "lrintxf<mode>2"
15864   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15865      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15866                      UNSPEC_FIST))]
15867   "TARGET_USE_FANCY_MATH_387")
15869 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15870   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15871      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15872                    UNSPEC_FIX_NOTRUNC))]
15873   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15875 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15876   [(match_operand:SWI248x 0 "nonimmediate_operand")
15877    (match_operand:X87MODEF 1 "register_operand")]
15878   "(TARGET_USE_FANCY_MATH_387
15879     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15880         || TARGET_MIX_SSE_I387)
15881     && flag_unsafe_math_optimizations)
15882    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15883        && <SWI248x:MODE>mode != HImode 
15884        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15885        && !flag_trapping_math && !flag_rounding_math)"
15887   if (optimize_insn_for_size_p ())
15888     FAIL;
15890   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15891       && <SWI248x:MODE>mode != HImode
15892       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15893       && !flag_trapping_math && !flag_rounding_math)
15894     ix86_expand_lround (operands[0], operands[1]);
15895   else
15896     ix86_emit_i387_round (operands[0], operands[1]);
15897   DONE;
15900 (define_int_iterator FRNDINT_ROUNDING
15901         [UNSPEC_FRNDINT_FLOOR
15902          UNSPEC_FRNDINT_CEIL
15903          UNSPEC_FRNDINT_TRUNC])
15905 (define_int_iterator FIST_ROUNDING
15906         [UNSPEC_FIST_FLOOR
15907          UNSPEC_FIST_CEIL])
15909 ;; Base name for define_insn
15910 (define_int_attr rounding_insn
15911         [(UNSPEC_FRNDINT_FLOOR "floor")
15912          (UNSPEC_FRNDINT_CEIL "ceil")
15913          (UNSPEC_FRNDINT_TRUNC "btrunc")
15914          (UNSPEC_FIST_FLOOR "floor")
15915          (UNSPEC_FIST_CEIL "ceil")])
15917 (define_int_attr rounding
15918         [(UNSPEC_FRNDINT_FLOOR "floor")
15919          (UNSPEC_FRNDINT_CEIL "ceil")
15920          (UNSPEC_FRNDINT_TRUNC "trunc")
15921          (UNSPEC_FIST_FLOOR "floor")
15922          (UNSPEC_FIST_CEIL "ceil")])
15924 (define_int_attr ROUNDING
15925         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15926          (UNSPEC_FRNDINT_CEIL "CEIL")
15927          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15928          (UNSPEC_FIST_FLOOR "FLOOR")
15929          (UNSPEC_FIST_CEIL "CEIL")])
15931 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15932 (define_insn_and_split "frndint<mode>2_<rounding>"
15933   [(set (match_operand:X87MODEF 0 "register_operand")
15934         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
15935                    FRNDINT_ROUNDING))
15936    (clobber (reg:CC FLAGS_REG))]
15937   "TARGET_USE_FANCY_MATH_387
15938    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
15939    && can_create_pseudo_p ()"
15940   "#"
15941   "&& 1"
15942   [(const_int 0)]
15944   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15946   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15947   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15949   emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
15950                                                  operands[2], operands[3]));
15951   DONE;
15953   [(set_attr "type" "frndint")
15954    (set_attr "i387_cw" "<rounding>")
15955    (set_attr "mode" "<MODE>")])
15957 (define_insn "frndint<mode>2_<rounding>_i387"
15958   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15959         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
15960                          FRNDINT_ROUNDING))
15961    (use (match_operand:HI 2 "memory_operand" "m"))
15962    (use (match_operand:HI 3 "memory_operand" "m"))]
15963   "TARGET_USE_FANCY_MATH_387
15964    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
15965   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15966   [(set_attr "type" "frndint")
15967    (set_attr "i387_cw" "<rounding>")
15968    (set_attr "mode" "<MODE>")])
15970 (define_expand "<rounding_insn>xf2"
15971   [(parallel [(set (match_operand:XF 0 "register_operand")
15972                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15973                               FRNDINT_ROUNDING))
15974               (clobber (reg:CC FLAGS_REG))])]
15975   "TARGET_USE_FANCY_MATH_387
15976    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
15978 (define_expand "<rounding_insn><mode>2"
15979   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15980                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15981                                  FRNDINT_ROUNDING))
15982               (clobber (reg:CC FLAGS_REG))])]
15983   "(TARGET_USE_FANCY_MATH_387
15984     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15985         || TARGET_MIX_SSE_I387)
15986     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
15987    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15988        && (TARGET_SSE4_1 || !flag_trapping_math
15989            || flag_fp_int_builtin_inexact))"
15991   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15992       && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
15993     {
15994       if (TARGET_SSE4_1)
15995         emit_insn (gen_sse4_1_round<mode>2
15996                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
15997                                                        | ROUND_NO_EXC)));
15998       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15999         {
16000           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16001             ix86_expand_floorceil (operands[0], operands[1], true);
16002           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16003             ix86_expand_floorceil (operands[0], operands[1], false);
16004           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16005             ix86_expand_trunc (operands[0], operands[1]);
16006           else
16007             gcc_unreachable ();
16008         }
16009       else
16010         {
16011           if (ROUND_<ROUNDING> == ROUND_FLOOR)
16012             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16013           else if (ROUND_<ROUNDING> == ROUND_CEIL)
16014             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16015           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16016             ix86_expand_truncdf_32 (operands[0], operands[1]);
16017           else
16018             gcc_unreachable ();
16019         }
16020     }
16021   else
16022     emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16023   DONE;
16026 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16027 (define_insn_and_split "frndintxf2_mask_pm"
16028   [(set (match_operand:XF 0 "register_operand")
16029         (unspec:XF [(match_operand:XF 1 "register_operand")]
16030                    UNSPEC_FRNDINT_MASK_PM))
16031    (clobber (reg:CC FLAGS_REG))]
16032   "TARGET_USE_FANCY_MATH_387
16033    && flag_unsafe_math_optimizations
16034    && can_create_pseudo_p ()"
16035   "#"
16036   "&& 1"
16037   [(const_int 0)]
16039   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16041   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16042   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16044   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16045                                           operands[2], operands[3]));
16046   DONE;
16048   [(set_attr "type" "frndint")
16049    (set_attr "i387_cw" "mask_pm")
16050    (set_attr "mode" "XF")])
16052 (define_insn "frndintxf2_mask_pm_i387"
16053   [(set (match_operand:XF 0 "register_operand" "=f")
16054         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16055                    UNSPEC_FRNDINT_MASK_PM))
16056    (use (match_operand:HI 2 "memory_operand" "m"))
16057    (use (match_operand:HI 3 "memory_operand" "m"))]
16058   "TARGET_USE_FANCY_MATH_387
16059    && flag_unsafe_math_optimizations"
16060   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16061   [(set_attr "type" "frndint")
16062    (set_attr "i387_cw" "mask_pm")
16063    (set_attr "mode" "XF")])
16065 (define_expand "nearbyintxf2"
16066   [(parallel [(set (match_operand:XF 0 "register_operand")
16067                    (unspec:XF [(match_operand:XF 1 "register_operand")]
16068                               UNSPEC_FRNDINT_MASK_PM))
16069               (clobber (reg:CC FLAGS_REG))])]
16070   "TARGET_USE_FANCY_MATH_387
16071    && flag_unsafe_math_optimizations")
16073 (define_expand "nearbyint<mode>2"
16074   [(use (match_operand:MODEF 0 "register_operand"))
16075    (use (match_operand:MODEF 1 "register_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 = gen_reg_rtx (XFmode);
16082   rtx op1 = gen_reg_rtx (XFmode);
16084   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16085   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16087   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16088   DONE;
16091 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16092 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16093   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16094         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16095                         FIST_ROUNDING))
16096    (clobber (reg:CC FLAGS_REG))]
16097   "TARGET_USE_FANCY_MATH_387
16098    && flag_unsafe_math_optimizations
16099    && can_create_pseudo_p ()"
16100   "#"
16101   "&& 1"
16102   [(const_int 0)]
16104   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16106   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16107   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16108   if (memory_operand (operands[0], VOIDmode))
16109     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16110                                            operands[2], operands[3]));
16111   else
16112     {
16113       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16114       emit_insn (gen_fist<mode>2_<rounding>_with_temp
16115                   (operands[0], operands[1], operands[2],
16116                    operands[3], operands[4]));
16117     }
16118   DONE;
16120   [(set_attr "type" "fistp")
16121    (set_attr "i387_cw" "<rounding>")
16122    (set_attr "mode" "<MODE>")])
16124 (define_insn "fistdi2_<rounding>"
16125   [(set (match_operand:DI 0 "memory_operand" "=m")
16126         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16127                    FIST_ROUNDING))
16128    (use (match_operand:HI 2 "memory_operand" "m"))
16129    (use (match_operand:HI 3 "memory_operand" "m"))
16130    (clobber (match_scratch:XF 4 "=&1f"))]
16131   "TARGET_USE_FANCY_MATH_387
16132    && flag_unsafe_math_optimizations"
16133   "* return output_fix_trunc (insn, operands, false);"
16134   [(set_attr "type" "fistp")
16135    (set_attr "i387_cw" "<rounding>")
16136    (set_attr "mode" "DI")])
16138 (define_insn "fistdi2_<rounding>_with_temp"
16139   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16140         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16141                    FIST_ROUNDING))
16142    (use (match_operand:HI 2 "memory_operand" "m,m"))
16143    (use (match_operand:HI 3 "memory_operand" "m,m"))
16144    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16145    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16146   "TARGET_USE_FANCY_MATH_387
16147    && flag_unsafe_math_optimizations"
16148   "#"
16149   [(set_attr "type" "fistp")
16150    (set_attr "i387_cw" "<rounding>")
16151    (set_attr "mode" "DI")])
16153 (define_split
16154   [(set (match_operand:DI 0 "register_operand")
16155         (unspec:DI [(match_operand:XF 1 "register_operand")]
16156                    FIST_ROUNDING))
16157    (use (match_operand:HI 2 "memory_operand"))
16158    (use (match_operand:HI 3 "memory_operand"))
16159    (clobber (match_operand:DI 4 "memory_operand"))
16160    (clobber (match_scratch 5))]
16161   "reload_completed"
16162   [(parallel [(set (match_dup 4)
16163                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16164               (use (match_dup 2))
16165               (use (match_dup 3))
16166               (clobber (match_dup 5))])
16167    (set (match_dup 0) (match_dup 4))])
16169 (define_split
16170   [(set (match_operand:DI 0 "memory_operand")
16171         (unspec:DI [(match_operand:XF 1 "register_operand")]
16172                    FIST_ROUNDING))
16173    (use (match_operand:HI 2 "memory_operand"))
16174    (use (match_operand:HI 3 "memory_operand"))
16175    (clobber (match_operand:DI 4 "memory_operand"))
16176    (clobber (match_scratch 5))]
16177   "reload_completed"
16178   [(parallel [(set (match_dup 0)
16179                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16180               (use (match_dup 2))
16181               (use (match_dup 3))
16182               (clobber (match_dup 5))])])
16184 (define_insn "fist<mode>2_<rounding>"
16185   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16186         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16187                       FIST_ROUNDING))
16188    (use (match_operand:HI 2 "memory_operand" "m"))
16189    (use (match_operand:HI 3 "memory_operand" "m"))]
16190   "TARGET_USE_FANCY_MATH_387
16191    && flag_unsafe_math_optimizations"
16192   "* return output_fix_trunc (insn, operands, false);"
16193   [(set_attr "type" "fistp")
16194    (set_attr "i387_cw" "<rounding>")
16195    (set_attr "mode" "<MODE>")])
16197 (define_insn "fist<mode>2_<rounding>_with_temp"
16198   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16199         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16200                       FIST_ROUNDING))
16201    (use (match_operand:HI 2 "memory_operand" "m,m"))
16202    (use (match_operand:HI 3 "memory_operand" "m,m"))
16203    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16204   "TARGET_USE_FANCY_MATH_387
16205    && flag_unsafe_math_optimizations"
16206   "#"
16207   [(set_attr "type" "fistp")
16208    (set_attr "i387_cw" "<rounding>")
16209    (set_attr "mode" "<MODE>")])
16211 (define_split
16212   [(set (match_operand:SWI24 0 "register_operand")
16213         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16214                       FIST_ROUNDING))
16215    (use (match_operand:HI 2 "memory_operand"))
16216    (use (match_operand:HI 3 "memory_operand"))
16217    (clobber (match_operand:SWI24 4 "memory_operand"))]
16218   "reload_completed"
16219   [(parallel [(set (match_dup 4)
16220                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16221               (use (match_dup 2))
16222               (use (match_dup 3))])
16223    (set (match_dup 0) (match_dup 4))])
16225 (define_split
16226   [(set (match_operand:SWI24 0 "memory_operand")
16227         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16228                       FIST_ROUNDING))
16229    (use (match_operand:HI 2 "memory_operand"))
16230    (use (match_operand:HI 3 "memory_operand"))
16231    (clobber (match_operand:SWI24 4 "memory_operand"))]
16232   "reload_completed"
16233   [(parallel [(set (match_dup 0)
16234                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16235               (use (match_dup 2))
16236               (use (match_dup 3))])])
16238 (define_expand "l<rounding_insn>xf<mode>2"
16239   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16240                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16241                                    FIST_ROUNDING))
16242               (clobber (reg:CC FLAGS_REG))])]
16243   "TARGET_USE_FANCY_MATH_387
16244    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16245    && flag_unsafe_math_optimizations")
16247 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16248   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16249                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16250                                  FIST_ROUNDING))
16251               (clobber (reg:CC FLAGS_REG))])]
16252   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16253    && !flag_trapping_math"
16255   if (TARGET_64BIT && optimize_insn_for_size_p ())
16256     FAIL;
16258   if (ROUND_<ROUNDING> == ROUND_FLOOR)
16259     ix86_expand_lfloorceil (operands[0], operands[1], true);
16260   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16261     ix86_expand_lfloorceil (operands[0], operands[1], false);
16262   else
16263     gcc_unreachable ();
16265   DONE;
16268 (define_insn "fxam<mode>2_i387"
16269   [(set (match_operand:HI 0 "register_operand" "=a")
16270         (unspec:HI
16271           [(match_operand:X87MODEF 1 "register_operand" "f")]
16272           UNSPEC_FXAM))]
16273   "TARGET_USE_FANCY_MATH_387"
16274   "fxam\n\tfnstsw\t%0"
16275   [(set_attr "type" "multi")
16276    (set_attr "length" "4")
16277    (set_attr "unit" "i387")
16278    (set_attr "mode" "<MODE>")])
16280 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16281   [(set (match_operand:HI 0 "register_operand")
16282         (unspec:HI
16283           [(match_operand:MODEF 1 "memory_operand")]
16284           UNSPEC_FXAM_MEM))]
16285   "TARGET_USE_FANCY_MATH_387
16286    && can_create_pseudo_p ()"
16287   "#"
16288   "&& 1"
16289   [(set (match_dup 2)(match_dup 1))
16290    (set (match_dup 0)
16291         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16293   operands[2] = gen_reg_rtx (<MODE>mode);
16295   MEM_VOLATILE_P (operands[1]) = 1;
16297   [(set_attr "type" "multi")
16298    (set_attr "unit" "i387")
16299    (set_attr "mode" "<MODE>")])
16301 (define_expand "isinfxf2"
16302   [(use (match_operand:SI 0 "register_operand"))
16303    (use (match_operand:XF 1 "register_operand"))]
16304   "TARGET_USE_FANCY_MATH_387
16305    && ix86_libc_has_function (function_c99_misc)"
16307   rtx mask = GEN_INT (0x45);
16308   rtx val = GEN_INT (0x05);
16310   rtx scratch = gen_reg_rtx (HImode);
16311   rtx res = gen_reg_rtx (QImode);
16313   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16315   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16316   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16317   ix86_expand_setcc (res, EQ,
16318                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16319   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16320   DONE;
16323 (define_expand "isinf<mode>2"
16324   [(use (match_operand:SI 0 "register_operand"))
16325    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16326   "TARGET_USE_FANCY_MATH_387
16327    && ix86_libc_has_function (function_c99_misc)
16328    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16330   rtx mask = GEN_INT (0x45);
16331   rtx val = GEN_INT (0x05);
16333   rtx scratch = gen_reg_rtx (HImode);
16334   rtx res = gen_reg_rtx (QImode);
16336   /* Remove excess precision by forcing value through memory. */
16337   if (memory_operand (operands[1], VOIDmode))
16338     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16339   else
16340     {
16341       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16343       emit_move_insn (temp, operands[1]);
16344       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16345     }
16347   emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16348   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16349   ix86_expand_setcc (res, EQ,
16350                      gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16351   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16352   DONE;
16355 (define_expand "signbittf2"
16356   [(use (match_operand:SI 0 "register_operand"))
16357    (use (match_operand:TF 1 "register_operand"))]
16358   "TARGET_SSE"
16360   if (TARGET_SSE4_1)
16361     {
16362       rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16363       rtx scratch = gen_reg_rtx (QImode);
16365       emit_insn (gen_ptesttf2 (operands[1], mask));
16366         ix86_expand_setcc (scratch, NE,
16367                            gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16369       emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16370     }
16371   else
16372     {
16373       emit_insn (gen_sse_movmskps (operands[0],
16374                                    gen_lowpart (V4SFmode, operands[1])));
16375       emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16376     }
16377   DONE;
16380 (define_expand "signbitxf2"
16381   [(use (match_operand:SI 0 "register_operand"))
16382    (use (match_operand:XF 1 "register_operand"))]
16383   "TARGET_USE_FANCY_MATH_387"
16385   rtx scratch = gen_reg_rtx (HImode);
16387   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16388   emit_insn (gen_andsi3 (operands[0],
16389              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16390   DONE;
16393 (define_insn "movmsk_df"
16394   [(set (match_operand:SI 0 "register_operand" "=r")
16395         (unspec:SI
16396           [(match_operand:DF 1 "register_operand" "x")]
16397           UNSPEC_MOVMSK))]
16398   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16399   "%vmovmskpd\t{%1, %0|%0, %1}"
16400   [(set_attr "type" "ssemov")
16401    (set_attr "prefix" "maybe_vex")
16402    (set_attr "mode" "DF")])
16404 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16405 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16406 (define_expand "signbitdf2"
16407   [(use (match_operand:SI 0 "register_operand"))
16408    (use (match_operand:DF 1 "register_operand"))]
16409   "TARGET_USE_FANCY_MATH_387
16410    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16412   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16413     {
16414       emit_insn (gen_movmsk_df (operands[0], operands[1]));
16415       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16416     }
16417   else
16418     {
16419       rtx scratch = gen_reg_rtx (HImode);
16421       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16422       emit_insn (gen_andsi3 (operands[0],
16423                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16424     }
16425   DONE;
16428 (define_expand "signbitsf2"
16429   [(use (match_operand:SI 0 "register_operand"))
16430    (use (match_operand:SF 1 "register_operand"))]
16431   "TARGET_USE_FANCY_MATH_387
16432    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16434   rtx scratch = gen_reg_rtx (HImode);
16436   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16437   emit_insn (gen_andsi3 (operands[0],
16438              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16439   DONE;
16442 ;; Block operation instructions
16444 (define_insn "cld"
16445   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16446   ""
16447   "cld"
16448   [(set_attr "length" "1")
16449    (set_attr "length_immediate" "0")
16450    (set_attr "modrm" "0")])
16452 (define_expand "movmem<mode>"
16453   [(use (match_operand:BLK 0 "memory_operand"))
16454    (use (match_operand:BLK 1 "memory_operand"))
16455    (use (match_operand:SWI48 2 "nonmemory_operand"))
16456    (use (match_operand:SWI48 3 "const_int_operand"))
16457    (use (match_operand:SI 4 "const_int_operand"))
16458    (use (match_operand:SI 5 "const_int_operand"))
16459    (use (match_operand:SI 6 ""))
16460    (use (match_operand:SI 7 ""))
16461    (use (match_operand:SI 8 ""))]
16462   ""
16464  if (ix86_expand_set_or_movmem (operands[0], operands[1],
16465                                 operands[2], NULL, operands[3],
16466                                 operands[4], operands[5],
16467                                 operands[6], operands[7],
16468                                 operands[8], false))
16469    DONE;
16470  else
16471    FAIL;
16474 ;; Most CPUs don't like single string operations
16475 ;; Handle this case here to simplify previous expander.
16477 (define_expand "strmov"
16478   [(set (match_dup 4) (match_operand 3 "memory_operand"))
16479    (set (match_operand 1 "memory_operand") (match_dup 4))
16480    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16481               (clobber (reg:CC FLAGS_REG))])
16482    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16483               (clobber (reg:CC FLAGS_REG))])]
16484   ""
16486   /* Can't use this for non-default address spaces.  */
16487   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16488     FAIL;
16490   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16492   /* If .md ever supports :P for Pmode, these can be directly
16493      in the pattern above.  */
16494   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16495   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16497   /* Can't use this if the user has appropriated esi or edi.  */
16498   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16499       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16500     {
16501       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16502                                       operands[2], operands[3],
16503                                       operands[5], operands[6]));
16504       DONE;
16505     }
16507   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16510 (define_expand "strmov_singleop"
16511   [(parallel [(set (match_operand 1 "memory_operand")
16512                    (match_operand 3 "memory_operand"))
16513               (set (match_operand 0 "register_operand")
16514                    (match_operand 4))
16515               (set (match_operand 2 "register_operand")
16516                    (match_operand 5))])]
16517   ""
16519   if (TARGET_CLD)
16520     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16523 (define_insn "*strmovdi_rex_1"
16524   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16525         (mem:DI (match_operand:P 3 "register_operand" "1")))
16526    (set (match_operand:P 0 "register_operand" "=D")
16527         (plus:P (match_dup 2)
16528                 (const_int 8)))
16529    (set (match_operand:P 1 "register_operand" "=S")
16530         (plus:P (match_dup 3)
16531                 (const_int 8)))]
16532   "TARGET_64BIT
16533    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16534    && ix86_check_no_addr_space (insn)"
16535   "%^movsq"
16536   [(set_attr "type" "str")
16537    (set_attr "memory" "both")
16538    (set_attr "mode" "DI")])
16540 (define_insn "*strmovsi_1"
16541   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16542         (mem:SI (match_operand:P 3 "register_operand" "1")))
16543    (set (match_operand:P 0 "register_operand" "=D")
16544         (plus:P (match_dup 2)
16545                 (const_int 4)))
16546    (set (match_operand:P 1 "register_operand" "=S")
16547         (plus:P (match_dup 3)
16548                 (const_int 4)))]
16549   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16550    && ix86_check_no_addr_space (insn)"
16551   "%^movs{l|d}"
16552   [(set_attr "type" "str")
16553    (set_attr "memory" "both")
16554    (set_attr "mode" "SI")])
16556 (define_insn "*strmovhi_1"
16557   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16558         (mem:HI (match_operand:P 3 "register_operand" "1")))
16559    (set (match_operand:P 0 "register_operand" "=D")
16560         (plus:P (match_dup 2)
16561                 (const_int 2)))
16562    (set (match_operand:P 1 "register_operand" "=S")
16563         (plus:P (match_dup 3)
16564                 (const_int 2)))]
16565   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16566    && ix86_check_no_addr_space (insn)"
16567   "%^movsw"
16568   [(set_attr "type" "str")
16569    (set_attr "memory" "both")
16570    (set_attr "mode" "HI")])
16572 (define_insn "*strmovqi_1"
16573   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16574         (mem:QI (match_operand:P 3 "register_operand" "1")))
16575    (set (match_operand:P 0 "register_operand" "=D")
16576         (plus:P (match_dup 2)
16577                 (const_int 1)))
16578    (set (match_operand:P 1 "register_operand" "=S")
16579         (plus:P (match_dup 3)
16580                 (const_int 1)))]
16581   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16582    && ix86_check_no_addr_space (insn)"
16583   "%^movsb"
16584   [(set_attr "type" "str")
16585    (set_attr "memory" "both")
16586    (set (attr "prefix_rex")
16587         (if_then_else
16588           (match_test "<P:MODE>mode == DImode")
16589           (const_string "0")
16590           (const_string "*")))
16591    (set_attr "mode" "QI")])
16593 (define_expand "rep_mov"
16594   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16595               (set (match_operand 0 "register_operand")
16596                    (match_operand 5))
16597               (set (match_operand 2 "register_operand")
16598                    (match_operand 6))
16599               (set (match_operand 1 "memory_operand")
16600                    (match_operand 3 "memory_operand"))
16601               (use (match_dup 4))])]
16602   ""
16604   if (TARGET_CLD)
16605     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16608 (define_insn "*rep_movdi_rex64"
16609   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16610    (set (match_operand:P 0 "register_operand" "=D")
16611         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16612                           (const_int 3))
16613                 (match_operand:P 3 "register_operand" "0")))
16614    (set (match_operand:P 1 "register_operand" "=S")
16615         (plus:P (ashift:P (match_dup 5) (const_int 3))
16616                 (match_operand:P 4 "register_operand" "1")))
16617    (set (mem:BLK (match_dup 3))
16618         (mem:BLK (match_dup 4)))
16619    (use (match_dup 5))]
16620   "TARGET_64BIT
16621    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16622    && ix86_check_no_addr_space (insn)"
16623   "%^rep{%;} movsq"
16624   [(set_attr "type" "str")
16625    (set_attr "prefix_rep" "1")
16626    (set_attr "memory" "both")
16627    (set_attr "mode" "DI")])
16629 (define_insn "*rep_movsi"
16630   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16631    (set (match_operand:P 0 "register_operand" "=D")
16632         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16633                           (const_int 2))
16634                  (match_operand:P 3 "register_operand" "0")))
16635    (set (match_operand:P 1 "register_operand" "=S")
16636         (plus:P (ashift:P (match_dup 5) (const_int 2))
16637                 (match_operand:P 4 "register_operand" "1")))
16638    (set (mem:BLK (match_dup 3))
16639         (mem:BLK (match_dup 4)))
16640    (use (match_dup 5))]
16641   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16642    && ix86_check_no_addr_space (insn)"
16643   "%^rep{%;} movs{l|d}"
16644   [(set_attr "type" "str")
16645    (set_attr "prefix_rep" "1")
16646    (set_attr "memory" "both")
16647    (set_attr "mode" "SI")])
16649 (define_insn "*rep_movqi"
16650   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16651    (set (match_operand:P 0 "register_operand" "=D")
16652         (plus:P (match_operand:P 3 "register_operand" "0")
16653                 (match_operand:P 5 "register_operand" "2")))
16654    (set (match_operand:P 1 "register_operand" "=S")
16655         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16656    (set (mem:BLK (match_dup 3))
16657         (mem:BLK (match_dup 4)))
16658    (use (match_dup 5))]
16659   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16660    && ix86_check_no_addr_space (insn)"
16661   "%^rep{%;} movsb"
16662   [(set_attr "type" "str")
16663    (set_attr "prefix_rep" "1")
16664    (set_attr "memory" "both")
16665    (set_attr "mode" "QI")])
16667 (define_expand "setmem<mode>"
16668    [(use (match_operand:BLK 0 "memory_operand"))
16669     (use (match_operand:SWI48 1 "nonmemory_operand"))
16670     (use (match_operand:QI 2 "nonmemory_operand"))
16671     (use (match_operand 3 "const_int_operand"))
16672     (use (match_operand:SI 4 "const_int_operand"))
16673     (use (match_operand:SI 5 "const_int_operand"))
16674     (use (match_operand:SI 6 ""))
16675     (use (match_operand:SI 7 ""))
16676     (use (match_operand:SI 8 ""))]
16677   ""
16679  if (ix86_expand_set_or_movmem (operands[0], NULL,
16680                                 operands[1], operands[2],
16681                                 operands[3], operands[4],
16682                                 operands[5], operands[6],
16683                                 operands[7], operands[8], true))
16684    DONE;
16685  else
16686    FAIL;
16689 ;; Most CPUs don't like single string operations
16690 ;; Handle this case here to simplify previous expander.
16692 (define_expand "strset"
16693   [(set (match_operand 1 "memory_operand")
16694         (match_operand 2 "register_operand"))
16695    (parallel [(set (match_operand 0 "register_operand")
16696                    (match_dup 3))
16697               (clobber (reg:CC FLAGS_REG))])]
16698   ""
16700   /* Can't use this for non-default address spaces.  */
16701   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16702     FAIL;
16704   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16705     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16707   /* If .md ever supports :P for Pmode, this can be directly
16708      in the pattern above.  */
16709   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16710                               GEN_INT (GET_MODE_SIZE (GET_MODE
16711                                                       (operands[2]))));
16712   /* Can't use this if the user has appropriated eax or edi.  */
16713   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16714       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16715     {
16716       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16717                                       operands[3]));
16718       DONE;
16719     }
16722 (define_expand "strset_singleop"
16723   [(parallel [(set (match_operand 1 "memory_operand")
16724                    (match_operand 2 "register_operand"))
16725               (set (match_operand 0 "register_operand")
16726                    (match_operand 3))
16727               (unspec [(const_int 0)] UNSPEC_STOS)])]
16728   ""
16730   if (TARGET_CLD)
16731     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16734 (define_insn "*strsetdi_rex_1"
16735   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16736         (match_operand:DI 2 "register_operand" "a"))
16737    (set (match_operand:P 0 "register_operand" "=D")
16738         (plus:P (match_dup 1)
16739                 (const_int 8)))
16740    (unspec [(const_int 0)] UNSPEC_STOS)]
16741   "TARGET_64BIT
16742    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16743    && ix86_check_no_addr_space (insn)"
16744   "%^stosq"
16745   [(set_attr "type" "str")
16746    (set_attr "memory" "store")
16747    (set_attr "mode" "DI")])
16749 (define_insn "*strsetsi_1"
16750   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16751         (match_operand:SI 2 "register_operand" "a"))
16752    (set (match_operand:P 0 "register_operand" "=D")
16753         (plus:P (match_dup 1)
16754                 (const_int 4)))
16755    (unspec [(const_int 0)] UNSPEC_STOS)]
16756   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16757    && ix86_check_no_addr_space (insn)"
16758   "%^stos{l|d}"
16759   [(set_attr "type" "str")
16760    (set_attr "memory" "store")
16761    (set_attr "mode" "SI")])
16763 (define_insn "*strsethi_1"
16764   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16765         (match_operand:HI 2 "register_operand" "a"))
16766    (set (match_operand:P 0 "register_operand" "=D")
16767         (plus:P (match_dup 1)
16768                 (const_int 2)))
16769    (unspec [(const_int 0)] UNSPEC_STOS)]
16770   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16771    && ix86_check_no_addr_space (insn)"
16772   "%^stosw"
16773   [(set_attr "type" "str")
16774    (set_attr "memory" "store")
16775    (set_attr "mode" "HI")])
16777 (define_insn "*strsetqi_1"
16778   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16779         (match_operand:QI 2 "register_operand" "a"))
16780    (set (match_operand:P 0 "register_operand" "=D")
16781         (plus:P (match_dup 1)
16782                 (const_int 1)))
16783    (unspec [(const_int 0)] UNSPEC_STOS)]
16784   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16785    && ix86_check_no_addr_space (insn)"
16786   "%^stosb"
16787   [(set_attr "type" "str")
16788    (set_attr "memory" "store")
16789    (set (attr "prefix_rex")
16790         (if_then_else
16791           (match_test "<P:MODE>mode == DImode")
16792           (const_string "0")
16793           (const_string "*")))
16794    (set_attr "mode" "QI")])
16796 (define_expand "rep_stos"
16797   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16798               (set (match_operand 0 "register_operand")
16799                    (match_operand 4))
16800               (set (match_operand 2 "memory_operand") (const_int 0))
16801               (use (match_operand 3 "register_operand"))
16802               (use (match_dup 1))])]
16803   ""
16805   if (TARGET_CLD)
16806     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16809 (define_insn "*rep_stosdi_rex64"
16810   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16811    (set (match_operand:P 0 "register_operand" "=D")
16812         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16813                           (const_int 3))
16814                  (match_operand:P 3 "register_operand" "0")))
16815    (set (mem:BLK (match_dup 3))
16816         (const_int 0))
16817    (use (match_operand:DI 2 "register_operand" "a"))
16818    (use (match_dup 4))]
16819   "TARGET_64BIT
16820    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16821    && ix86_check_no_addr_space (insn)"
16822   "%^rep{%;} stosq"
16823   [(set_attr "type" "str")
16824    (set_attr "prefix_rep" "1")
16825    (set_attr "memory" "store")
16826    (set_attr "mode" "DI")])
16828 (define_insn "*rep_stossi"
16829   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16830    (set (match_operand:P 0 "register_operand" "=D")
16831         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16832                           (const_int 2))
16833                  (match_operand:P 3 "register_operand" "0")))
16834    (set (mem:BLK (match_dup 3))
16835         (const_int 0))
16836    (use (match_operand:SI 2 "register_operand" "a"))
16837    (use (match_dup 4))]
16838   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16839    && ix86_check_no_addr_space (insn)"
16840   "%^rep{%;} stos{l|d}"
16841   [(set_attr "type" "str")
16842    (set_attr "prefix_rep" "1")
16843    (set_attr "memory" "store")
16844    (set_attr "mode" "SI")])
16846 (define_insn "*rep_stosqi"
16847   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16848    (set (match_operand:P 0 "register_operand" "=D")
16849         (plus:P (match_operand:P 3 "register_operand" "0")
16850                 (match_operand:P 4 "register_operand" "1")))
16851    (set (mem:BLK (match_dup 3))
16852         (const_int 0))
16853    (use (match_operand:QI 2 "register_operand" "a"))
16854    (use (match_dup 4))]
16855   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16856    && ix86_check_no_addr_space (insn)"
16857   "%^rep{%;} stosb"
16858   [(set_attr "type" "str")
16859    (set_attr "prefix_rep" "1")
16860    (set_attr "memory" "store")
16861    (set (attr "prefix_rex")
16862         (if_then_else
16863           (match_test "<P:MODE>mode == DImode")
16864           (const_string "0")
16865           (const_string "*")))
16866    (set_attr "mode" "QI")])
16868 (define_expand "cmpstrnsi"
16869   [(set (match_operand:SI 0 "register_operand")
16870         (compare:SI (match_operand:BLK 1 "general_operand")
16871                     (match_operand:BLK 2 "general_operand")))
16872    (use (match_operand 3 "general_operand"))
16873    (use (match_operand 4 "immediate_operand"))]
16874   ""
16876   rtx addr1, addr2, out, outlow, count, countreg, align;
16878   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16879     FAIL;
16881   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16882   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16883     FAIL;
16885   /* One of the strings must be a constant.  If so, expand_builtin_strncmp()
16886      will have rewritten the length arg to be the minimum of the const string
16887      length and the actual length arg.  If both strings are the same and
16888      shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16889      will incorrectly base the results on chars past the 0 byte.  */
16890   tree t1 = MEM_EXPR (operands[1]);
16891   tree t2 = MEM_EXPR (operands[2]);
16892   if (!((t1 && TREE_CODE (t1) == MEM_REF
16893          && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16894          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16895       || (t2 && TREE_CODE (t2) == MEM_REF
16896           && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16897           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16898     FAIL;
16900   out = operands[0];
16901   if (!REG_P (out))
16902     out = gen_reg_rtx (SImode);
16904   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16905   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16906   if (addr1 != XEXP (operands[1], 0))
16907     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16908   if (addr2 != XEXP (operands[2], 0))
16909     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16911   count = operands[3];
16912   countreg = ix86_zero_extend_to_Pmode (count);
16914   /* %%% Iff we are testing strict equality, we can use known alignment
16915      to good advantage.  This may be possible with combine, particularly
16916      once cc0 is dead.  */
16917   align = operands[4];
16919   if (CONST_INT_P (count))
16920     {
16921       if (INTVAL (count) == 0)
16922         {
16923           emit_move_insn (operands[0], const0_rtx);
16924           DONE;
16925         }
16926       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16927                                      operands[1], operands[2]));
16928     }
16929   else
16930     {
16931       rtx (*gen_cmp) (rtx, rtx);
16933       gen_cmp = (TARGET_64BIT
16934                  ? gen_cmpdi_1 : gen_cmpsi_1);
16936       emit_insn (gen_cmp (countreg, countreg));
16937       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16938                                   operands[1], operands[2]));
16939     }
16941   outlow = gen_lowpart (QImode, out);
16942   emit_insn (gen_cmpintqi (outlow));
16943   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16945   if (operands[0] != out)
16946     emit_move_insn (operands[0], out);
16948   DONE;
16951 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16953 (define_expand "cmpintqi"
16954   [(set (match_dup 1)
16955         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16956    (set (match_dup 2)
16957         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16958    (parallel [(set (match_operand:QI 0 "register_operand")
16959                    (minus:QI (match_dup 1)
16960                              (match_dup 2)))
16961               (clobber (reg:CC FLAGS_REG))])]
16962   ""
16964   operands[1] = gen_reg_rtx (QImode);
16965   operands[2] = gen_reg_rtx (QImode);
16968 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16969 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16971 (define_expand "cmpstrnqi_nz_1"
16972   [(parallel [(set (reg:CC FLAGS_REG)
16973                    (compare:CC (match_operand 4 "memory_operand")
16974                                (match_operand 5 "memory_operand")))
16975               (use (match_operand 2 "register_operand"))
16976               (use (match_operand:SI 3 "immediate_operand"))
16977               (clobber (match_operand 0 "register_operand"))
16978               (clobber (match_operand 1 "register_operand"))
16979               (clobber (match_dup 2))])]
16980   ""
16982   if (TARGET_CLD)
16983     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16986 (define_insn "*cmpstrnqi_nz_1"
16987   [(set (reg:CC FLAGS_REG)
16988         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16989                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16990    (use (match_operand:P 6 "register_operand" "2"))
16991    (use (match_operand:SI 3 "immediate_operand" "i"))
16992    (clobber (match_operand:P 0 "register_operand" "=S"))
16993    (clobber (match_operand:P 1 "register_operand" "=D"))
16994    (clobber (match_operand:P 2 "register_operand" "=c"))]
16995   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16996    && ix86_check_no_addr_space (insn)"
16997   "%^repz{%;} cmpsb"
16998   [(set_attr "type" "str")
16999    (set_attr "mode" "QI")
17000    (set (attr "prefix_rex")
17001         (if_then_else
17002           (match_test "<P:MODE>mode == DImode")
17003           (const_string "0")
17004           (const_string "*")))
17005    (set_attr "prefix_rep" "1")])
17007 ;; The same, but the count is not known to not be zero.
17009 (define_expand "cmpstrnqi_1"
17010   [(parallel [(set (reg:CC FLAGS_REG)
17011                 (if_then_else:CC (ne (match_operand 2 "register_operand")
17012                                      (const_int 0))
17013                   (compare:CC (match_operand 4 "memory_operand")
17014                               (match_operand 5 "memory_operand"))
17015                   (const_int 0)))
17016               (use (match_operand:SI 3 "immediate_operand"))
17017               (use (reg:CC FLAGS_REG))
17018               (clobber (match_operand 0 "register_operand"))
17019               (clobber (match_operand 1 "register_operand"))
17020               (clobber (match_dup 2))])]
17021   ""
17023   if (TARGET_CLD)
17024     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17027 (define_insn "*cmpstrnqi_1"
17028   [(set (reg:CC FLAGS_REG)
17029         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17030                              (const_int 0))
17031           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17032                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
17033           (const_int 0)))
17034    (use (match_operand:SI 3 "immediate_operand" "i"))
17035    (use (reg:CC FLAGS_REG))
17036    (clobber (match_operand:P 0 "register_operand" "=S"))
17037    (clobber (match_operand:P 1 "register_operand" "=D"))
17038    (clobber (match_operand:P 2 "register_operand" "=c"))]
17039   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17040    && ix86_check_no_addr_space (insn)"
17041   "%^repz{%;} cmpsb"
17042   [(set_attr "type" "str")
17043    (set_attr "mode" "QI")
17044    (set (attr "prefix_rex")
17045         (if_then_else
17046           (match_test "<P:MODE>mode == DImode")
17047           (const_string "0")
17048           (const_string "*")))
17049    (set_attr "prefix_rep" "1")])
17051 (define_expand "strlen<mode>"
17052   [(set (match_operand:P 0 "register_operand")
17053         (unspec:P [(match_operand:BLK 1 "general_operand")
17054                    (match_operand:QI 2 "immediate_operand")
17055                    (match_operand 3 "immediate_operand")]
17056                   UNSPEC_SCAS))]
17057   ""
17059  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17060    DONE;
17061  else
17062    FAIL;
17065 (define_expand "strlenqi_1"
17066   [(parallel [(set (match_operand 0 "register_operand")
17067                    (match_operand 2))
17068               (clobber (match_operand 1 "register_operand"))
17069               (clobber (reg:CC FLAGS_REG))])]
17070   ""
17072   if (TARGET_CLD)
17073     ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17076 (define_insn "*strlenqi_1"
17077   [(set (match_operand:P 0 "register_operand" "=&c")
17078         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17079                    (match_operand:QI 2 "register_operand" "a")
17080                    (match_operand:P 3 "immediate_operand" "i")
17081                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17082    (clobber (match_operand:P 1 "register_operand" "=D"))
17083    (clobber (reg:CC FLAGS_REG))]
17084   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17085    && ix86_check_no_addr_space (insn)"
17086   "%^repnz{%;} scasb"
17087   [(set_attr "type" "str")
17088    (set_attr "mode" "QI")
17089    (set (attr "prefix_rex")
17090         (if_then_else
17091           (match_test "<P:MODE>mode == DImode")
17092           (const_string "0")
17093           (const_string "*")))
17094    (set_attr "prefix_rep" "1")])
17096 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
17097 ;; handled in combine, but it is not currently up to the task.
17098 ;; When used for their truth value, the cmpstrn* expanders generate
17099 ;; code like this:
17101 ;;   repz cmpsb
17102 ;;   seta       %al
17103 ;;   setb       %dl
17104 ;;   cmpb       %al, %dl
17105 ;;   jcc        label
17107 ;; The intermediate three instructions are unnecessary.
17109 ;; This one handles cmpstrn*_nz_1...
17110 (define_peephole2
17111   [(parallel[
17112      (set (reg:CC FLAGS_REG)
17113           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17114                       (mem:BLK (match_operand 5 "register_operand"))))
17115      (use (match_operand 6 "register_operand"))
17116      (use (match_operand:SI 3 "immediate_operand"))
17117      (clobber (match_operand 0 "register_operand"))
17118      (clobber (match_operand 1 "register_operand"))
17119      (clobber (match_operand 2 "register_operand"))])
17120    (set (match_operand:QI 7 "register_operand")
17121         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17122    (set (match_operand:QI 8 "register_operand")
17123         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17124    (set (reg FLAGS_REG)
17125         (compare (match_dup 7) (match_dup 8)))
17126   ]
17127   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17128   [(parallel[
17129      (set (reg:CC FLAGS_REG)
17130           (compare:CC (mem:BLK (match_dup 4))
17131                       (mem:BLK (match_dup 5))))
17132      (use (match_dup 6))
17133      (use (match_dup 3))
17134      (clobber (match_dup 0))
17135      (clobber (match_dup 1))
17136      (clobber (match_dup 2))])])
17138 ;; ...and this one handles cmpstrn*_1.
17139 (define_peephole2
17140   [(parallel[
17141      (set (reg:CC FLAGS_REG)
17142           (if_then_else:CC (ne (match_operand 6 "register_operand")
17143                                (const_int 0))
17144             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17145                         (mem:BLK (match_operand 5 "register_operand")))
17146             (const_int 0)))
17147      (use (match_operand:SI 3 "immediate_operand"))
17148      (use (reg:CC FLAGS_REG))
17149      (clobber (match_operand 0 "register_operand"))
17150      (clobber (match_operand 1 "register_operand"))
17151      (clobber (match_operand 2 "register_operand"))])
17152    (set (match_operand:QI 7 "register_operand")
17153         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17154    (set (match_operand:QI 8 "register_operand")
17155         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17156    (set (reg FLAGS_REG)
17157         (compare (match_dup 7) (match_dup 8)))
17158   ]
17159   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17160   [(parallel[
17161      (set (reg:CC FLAGS_REG)
17162           (if_then_else:CC (ne (match_dup 6)
17163                                (const_int 0))
17164             (compare:CC (mem:BLK (match_dup 4))
17165                         (mem:BLK (match_dup 5)))
17166             (const_int 0)))
17167      (use (match_dup 3))
17168      (use (reg:CC FLAGS_REG))
17169      (clobber (match_dup 0))
17170      (clobber (match_dup 1))
17171      (clobber (match_dup 2))])])
17173 ;; Conditional move instructions.
17175 (define_expand "mov<mode>cc"
17176   [(set (match_operand:SWIM 0 "register_operand")
17177         (if_then_else:SWIM (match_operand 1 "comparison_operator")
17178                            (match_operand:SWIM 2 "<general_operand>")
17179                            (match_operand:SWIM 3 "<general_operand>")))]
17180   ""
17181   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17183 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17184 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17185 ;; So just document what we're doing explicitly.
17187 (define_expand "x86_mov<mode>cc_0_m1"
17188   [(parallel
17189     [(set (match_operand:SWI48 0 "register_operand")
17190           (if_then_else:SWI48
17191             (match_operator:SWI48 2 "ix86_carry_flag_operator"
17192              [(match_operand 1 "flags_reg_operand")
17193               (const_int 0)])
17194             (const_int -1)
17195             (const_int 0)))
17196      (clobber (reg:CC FLAGS_REG))])])
17198 (define_insn "*x86_mov<mode>cc_0_m1"
17199   [(set (match_operand:SWI48 0 "register_operand" "=r")
17200         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17201                              [(reg FLAGS_REG) (const_int 0)])
17202           (const_int -1)
17203           (const_int 0)))
17204    (clobber (reg:CC FLAGS_REG))]
17205   ""
17206   "sbb{<imodesuffix>}\t%0, %0"
17207   ; Since we don't have the proper number of operands for an alu insn,
17208   ; fill in all the blanks.
17209   [(set_attr "type" "alu")
17210    (set_attr "modrm_class" "op0")
17211    (set_attr "use_carry" "1")
17212    (set_attr "pent_pair" "pu")
17213    (set_attr "memory" "none")
17214    (set_attr "imm_disp" "false")
17215    (set_attr "mode" "<MODE>")
17216    (set_attr "length_immediate" "0")])
17218 (define_insn "*x86_mov<mode>cc_0_m1_se"
17219   [(set (match_operand:SWI48 0 "register_operand" "=r")
17220         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17221                              [(reg FLAGS_REG) (const_int 0)])
17222                             (const_int 1)
17223                             (const_int 0)))
17224    (clobber (reg:CC FLAGS_REG))]
17225   ""
17226   "sbb{<imodesuffix>}\t%0, %0"
17227   [(set_attr "type" "alu")
17228    (set_attr "modrm_class" "op0")
17229    (set_attr "use_carry" "1")
17230    (set_attr "pent_pair" "pu")
17231    (set_attr "memory" "none")
17232    (set_attr "imm_disp" "false")
17233    (set_attr "mode" "<MODE>")
17234    (set_attr "length_immediate" "0")])
17236 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17237   [(set (match_operand:SWI48 0 "register_operand" "=r")
17238         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17239                     [(reg FLAGS_REG) (const_int 0)])))
17240    (clobber (reg:CC FLAGS_REG))]
17241   ""
17242   "sbb{<imodesuffix>}\t%0, %0"
17243   [(set_attr "type" "alu")
17244    (set_attr "modrm_class" "op0")
17245    (set_attr "use_carry" "1")
17246    (set_attr "pent_pair" "pu")
17247    (set_attr "memory" "none")
17248    (set_attr "imm_disp" "false")
17249    (set_attr "mode" "<MODE>")
17250    (set_attr "length_immediate" "0")])
17252 (define_insn "*mov<mode>cc_noc"
17253   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17254         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17255                                [(reg FLAGS_REG) (const_int 0)])
17256           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17257           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17258   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17259   "@
17260    cmov%O2%C1\t{%2, %0|%0, %2}
17261    cmov%O2%c1\t{%3, %0|%0, %3}"
17262   [(set_attr "type" "icmov")
17263    (set_attr "mode" "<MODE>")])
17265 (define_insn "*movsicc_noc_zext"
17266   [(set (match_operand:DI 0 "register_operand" "=r,r")
17267         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17268                            [(reg FLAGS_REG) (const_int 0)])
17269           (zero_extend:DI
17270             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17271           (zero_extend:DI
17272             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17273   "TARGET_64BIT
17274    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17275   "@
17276    cmov%O2%C1\t{%2, %k0|%k0, %2}
17277    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17278   [(set_attr "type" "icmov")
17279    (set_attr "mode" "SI")])
17281 ;; Don't do conditional moves with memory inputs.  This splitter helps
17282 ;; register starved x86_32 by forcing inputs into registers before reload.
17283 (define_split
17284   [(set (match_operand:SWI248 0 "register_operand")
17285         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17286                                [(reg FLAGS_REG) (const_int 0)])
17287           (match_operand:SWI248 2 "nonimmediate_operand")
17288           (match_operand:SWI248 3 "nonimmediate_operand")))]
17289   "!TARGET_64BIT && TARGET_CMOVE
17290    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17291    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17292    && can_create_pseudo_p ()
17293    && optimize_insn_for_speed_p ()"
17294   [(set (match_dup 0)
17295         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17297   if (MEM_P (operands[2]))
17298     operands[2] = force_reg (<MODE>mode, operands[2]);
17299   if (MEM_P (operands[3]))
17300     operands[3] = force_reg (<MODE>mode, operands[3]);
17303 (define_insn "*movqicc_noc"
17304   [(set (match_operand:QI 0 "register_operand" "=r,r")
17305         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17306                            [(reg FLAGS_REG) (const_int 0)])
17307                       (match_operand:QI 2 "register_operand" "r,0")
17308                       (match_operand:QI 3 "register_operand" "0,r")))]
17309   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17310   "#"
17311   [(set_attr "type" "icmov")
17312    (set_attr "mode" "QI")])
17314 (define_split
17315   [(set (match_operand:SWI12 0 "register_operand")
17316         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17317                               [(reg FLAGS_REG) (const_int 0)])
17318                       (match_operand:SWI12 2 "register_operand")
17319                       (match_operand:SWI12 3 "register_operand")))]
17320   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17321    && reload_completed"
17322   [(set (match_dup 0)
17323         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17325   operands[0] = gen_lowpart (SImode, operands[0]);
17326   operands[2] = gen_lowpart (SImode, operands[2]);
17327   operands[3] = gen_lowpart (SImode, operands[3]);
17330 ;; Don't do conditional moves with memory inputs
17331 (define_peephole2
17332   [(match_scratch:SWI248 4 "r")
17333    (set (match_operand:SWI248 0 "register_operand")
17334         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17335                                [(reg FLAGS_REG) (const_int 0)])
17336           (match_operand:SWI248 2 "nonimmediate_operand")
17337           (match_operand:SWI248 3 "nonimmediate_operand")))]
17338   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17339    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17340    && optimize_insn_for_speed_p ()"
17341   [(set (match_dup 4) (match_dup 5))
17342    (set (match_dup 0)
17343         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17345   if (MEM_P (operands[2]))
17346     {
17347       operands[5] = operands[2];
17348       operands[2] = operands[4];
17349     }
17350   else if (MEM_P (operands[3]))
17351     {
17352       operands[5] = operands[3];
17353       operands[3] = operands[4];
17354     }
17355   else
17356     gcc_unreachable ();
17359 (define_peephole2
17360   [(match_scratch:SI 4 "r")
17361    (set (match_operand:DI 0 "register_operand")
17362         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17363                            [(reg FLAGS_REG) (const_int 0)])
17364           (zero_extend:DI
17365             (match_operand:SI 2 "nonimmediate_operand"))
17366           (zero_extend:DI
17367             (match_operand:SI 3 "nonimmediate_operand"))))]
17368   "TARGET_64BIT
17369    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17370    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17371    && optimize_insn_for_speed_p ()"
17372   [(set (match_dup 4) (match_dup 5))
17373    (set (match_dup 0)
17374         (if_then_else:DI (match_dup 1)
17375           (zero_extend:DI (match_dup 2))
17376           (zero_extend:DI (match_dup 3))))]
17378   if (MEM_P (operands[2]))
17379     {
17380       operands[5] = operands[2];
17381       operands[2] = operands[4];
17382     }
17383   else if (MEM_P (operands[3]))
17384     {
17385       operands[5] = operands[3];
17386       operands[3] = operands[4];
17387     }
17388   else
17389     gcc_unreachable ();
17392 (define_expand "mov<mode>cc"
17393   [(set (match_operand:X87MODEF 0 "register_operand")
17394         (if_then_else:X87MODEF
17395           (match_operand 1 "comparison_operator")
17396           (match_operand:X87MODEF 2 "register_operand")
17397           (match_operand:X87MODEF 3 "register_operand")))]
17398   "(TARGET_80387 && TARGET_CMOVE)
17399    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17400   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17402 (define_insn "*movxfcc_1"
17403   [(set (match_operand:XF 0 "register_operand" "=f,f")
17404         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17405                                 [(reg FLAGS_REG) (const_int 0)])
17406                       (match_operand:XF 2 "register_operand" "f,0")
17407                       (match_operand:XF 3 "register_operand" "0,f")))]
17408   "TARGET_80387 && TARGET_CMOVE"
17409   "@
17410    fcmov%F1\t{%2, %0|%0, %2}
17411    fcmov%f1\t{%3, %0|%0, %3}"
17412   [(set_attr "type" "fcmov")
17413    (set_attr "mode" "XF")])
17415 (define_insn "*movdfcc_1"
17416   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17417         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17418                                 [(reg FLAGS_REG) (const_int 0)])
17419                       (match_operand:DF 2 "nonimmediate_operand"
17420                                                "f ,0,rm,0 ,rm,0")
17421                       (match_operand:DF 3 "nonimmediate_operand"
17422                                                "0 ,f,0 ,rm,0, rm")))]
17423   "TARGET_80387 && TARGET_CMOVE
17424    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17425   "@
17426    fcmov%F1\t{%2, %0|%0, %2}
17427    fcmov%f1\t{%3, %0|%0, %3}
17428    #
17429    #
17430    cmov%O2%C1\t{%2, %0|%0, %2}
17431    cmov%O2%c1\t{%3, %0|%0, %3}"
17432   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17433    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17434    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17436 (define_split
17437   [(set (match_operand:DF 0 "general_reg_operand")
17438         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17439                                 [(reg FLAGS_REG) (const_int 0)])
17440                       (match_operand:DF 2 "nonimmediate_operand")
17441                       (match_operand:DF 3 "nonimmediate_operand")))]
17442   "!TARGET_64BIT && reload_completed"
17443   [(set (match_dup 2)
17444         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17445    (set (match_dup 3)
17446         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17448   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17449   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17452 (define_insn "*movsfcc_1_387"
17453   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17454         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17455                                 [(reg FLAGS_REG) (const_int 0)])
17456                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17457                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17458   "TARGET_80387 && TARGET_CMOVE
17459    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17460   "@
17461    fcmov%F1\t{%2, %0|%0, %2}
17462    fcmov%f1\t{%3, %0|%0, %3}
17463    cmov%O2%C1\t{%2, %0|%0, %2}
17464    cmov%O2%c1\t{%3, %0|%0, %3}"
17465   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17466    (set_attr "mode" "SF,SF,SI,SI")])
17468 ;; Don't do conditional moves with memory inputs.  This splitter helps
17469 ;; register starved x86_32 by forcing inputs into registers before reload.
17470 (define_split
17471   [(set (match_operand:MODEF 0 "register_operand")
17472         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17473                               [(reg FLAGS_REG) (const_int 0)])
17474           (match_operand:MODEF 2 "nonimmediate_operand")
17475           (match_operand:MODEF 3 "nonimmediate_operand")))]
17476   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17477    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17478    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17479    && can_create_pseudo_p ()
17480    && optimize_insn_for_speed_p ()"
17481   [(set (match_dup 0)
17482         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17484   if (MEM_P (operands[2]))
17485     operands[2] = force_reg (<MODE>mode, operands[2]);
17486   if (MEM_P (operands[3]))
17487     operands[3] = force_reg (<MODE>mode, operands[3]);
17490 ;; Don't do conditional moves with memory inputs
17491 (define_peephole2
17492   [(match_scratch:MODEF 4 "r")
17493    (set (match_operand:MODEF 0 "general_reg_operand")
17494         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17495                               [(reg FLAGS_REG) (const_int 0)])
17496           (match_operand:MODEF 2 "nonimmediate_operand")
17497           (match_operand:MODEF 3 "nonimmediate_operand")))]
17498   "(<MODE>mode != DFmode || TARGET_64BIT)
17499    && TARGET_80387 && TARGET_CMOVE
17500    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17501    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17502    && optimize_insn_for_speed_p ()"
17503   [(set (match_dup 4) (match_dup 5))
17504    (set (match_dup 0)
17505         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17507   if (MEM_P (operands[2]))
17508     {
17509       operands[5] = operands[2];
17510       operands[2] = operands[4];
17511     }
17512   else if (MEM_P (operands[3]))
17513     {
17514       operands[5] = operands[3];
17515       operands[3] = operands[4];
17516     }
17517   else
17518     gcc_unreachable ();
17521 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17522 ;; the scalar versions to have only XMM registers as operands.
17524 ;; XOP conditional move
17525 (define_insn "*xop_pcmov_<mode>"
17526   [(set (match_operand:MODEF 0 "register_operand" "=x")
17527         (if_then_else:MODEF
17528           (match_operand:MODEF 1 "register_operand" "x")
17529           (match_operand:MODEF 2 "register_operand" "x")
17530           (match_operand:MODEF 3 "register_operand" "x")))]
17531   "TARGET_XOP"
17532   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17533   [(set_attr "type" "sse4arg")])
17535 ;; These versions of the min/max patterns are intentionally ignorant of
17536 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17537 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17538 ;; are undefined in this condition, we're certain this is correct.
17540 (define_insn "<code><mode>3"
17541   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17542         (smaxmin:MODEF
17543           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17544           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17545   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17546   "@
17547    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17548    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17549   [(set_attr "isa" "noavx,avx")
17550    (set_attr "prefix" "orig,vex")
17551    (set_attr "type" "sseadd")
17552    (set_attr "mode" "<MODE>")])
17554 ;; These versions of the min/max patterns implement exactly the operations
17555 ;;   min = (op1 < op2 ? op1 : op2)
17556 ;;   max = (!(op1 < op2) ? op1 : op2)
17557 ;; Their operands are not commutative, and thus they may be used in the
17558 ;; presence of -0.0 and NaN.
17560 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17561   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17562         (unspec:MODEF
17563           [(match_operand:MODEF 1 "register_operand" "0,v")
17564            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17565           IEEE_MAXMIN))]
17566   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17567   "@
17568    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17569    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17570   [(set_attr "isa" "noavx,avx")
17571    (set_attr "prefix" "orig,maybe_evex")
17572    (set_attr "type" "sseadd")
17573    (set_attr "mode" "<MODE>")])
17575 ;; Make two stack loads independent:
17576 ;;   fld aa              fld aa
17577 ;;   fld %st(0)     ->   fld bb
17578 ;;   fmul bb             fmul %st(1), %st
17580 ;; Actually we only match the last two instructions for simplicity.
17582 (define_peephole2
17583   [(set (match_operand 0 "fp_register_operand")
17584         (match_operand 1 "fp_register_operand"))
17585    (set (match_dup 0)
17586         (match_operator 2 "binary_fp_operator"
17587            [(match_dup 0)
17588             (match_operand 3 "memory_operand")]))]
17589   "REGNO (operands[0]) != REGNO (operands[1])"
17590   [(set (match_dup 0) (match_dup 3))
17591    (set (match_dup 0)
17592         (match_op_dup 2
17593           [(match_dup 5) (match_dup 4)]))]
17595   operands[4] = operands[0];
17596   operands[5] = operands[1];
17598   /* The % modifier is not operational anymore in peephole2's, so we have to
17599      swap the operands manually in the case of addition and multiplication. */
17600   if (COMMUTATIVE_ARITH_P (operands[2]))
17601     std::swap (operands[4], operands[5]);
17604 (define_peephole2
17605   [(set (match_operand 0 "fp_register_operand")
17606         (match_operand 1 "fp_register_operand"))
17607    (set (match_dup 0)
17608         (match_operator 2 "binary_fp_operator"
17609            [(match_operand 3 "memory_operand")
17610             (match_dup 0)]))]
17611   "REGNO (operands[0]) != REGNO (operands[1])"
17612   [(set (match_dup 0) (match_dup 3))
17613    (set (match_dup 0)
17614         (match_op_dup 2
17615           [(match_dup 4) (match_dup 5)]))]
17617   operands[4] = operands[0];
17618   operands[5] = operands[1];
17620   /* The % modifier is not operational anymore in peephole2's, so we have to
17621      swap the operands manually in the case of addition and multiplication. */
17622   if (COMMUTATIVE_ARITH_P (operands[2]))
17623     std::swap (operands[4], operands[5]);
17626 ;; Conditional addition patterns
17627 (define_expand "add<mode>cc"
17628   [(match_operand:SWI 0 "register_operand")
17629    (match_operand 1 "ordered_comparison_operator")
17630    (match_operand:SWI 2 "register_operand")
17631    (match_operand:SWI 3 "const_int_operand")]
17632   ""
17633   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17635 ;; Misc patterns (?)
17637 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17638 ;; Otherwise there will be nothing to keep
17640 ;; [(set (reg ebp) (reg esp))]
17641 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17642 ;;  (clobber (eflags)]
17643 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17645 ;; in proper program order.
17647 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17648   [(set (match_operand:P 0 "register_operand" "=r,r")
17649         (plus:P (match_operand:P 1 "register_operand" "0,r")
17650                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17651    (clobber (reg:CC FLAGS_REG))
17652    (clobber (mem:BLK (scratch)))]
17653   ""
17655   switch (get_attr_type (insn))
17656     {
17657     case TYPE_IMOV:
17658       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17660     case TYPE_ALU:
17661       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17662       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17663         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17665       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17667     default:
17668       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17669       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17670     }
17672   [(set (attr "type")
17673         (cond [(and (eq_attr "alternative" "0")
17674                     (not (match_test "TARGET_OPT_AGU")))
17675                  (const_string "alu")
17676                (match_operand:<MODE> 2 "const0_operand")
17677                  (const_string "imov")
17678               ]
17679               (const_string "lea")))
17680    (set (attr "length_immediate")
17681         (cond [(eq_attr "type" "imov")
17682                  (const_string "0")
17683                (and (eq_attr "type" "alu")
17684                     (match_operand 2 "const128_operand"))
17685                  (const_string "1")
17686               ]
17687               (const_string "*")))
17688    (set_attr "mode" "<MODE>")])
17690 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17691   [(set (match_operand:P 0 "register_operand" "=r")
17692         (minus:P (match_operand:P 1 "register_operand" "0")
17693                  (match_operand:P 2 "register_operand" "r")))
17694    (clobber (reg:CC FLAGS_REG))
17695    (clobber (mem:BLK (scratch)))]
17696   ""
17697   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17698   [(set_attr "type" "alu")
17699    (set_attr "mode" "<MODE>")])
17701 (define_insn "allocate_stack_worker_probe_<mode>"
17702   [(set (match_operand:P 0 "register_operand" "=a")
17703         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17704                             UNSPECV_STACK_PROBE))
17705    (clobber (reg:CC FLAGS_REG))]
17706   "ix86_target_stack_probe ()"
17707   "call\t___chkstk_ms"
17708   [(set_attr "type" "multi")
17709    (set_attr "length" "5")])
17711 (define_expand "allocate_stack"
17712   [(match_operand 0 "register_operand")
17713    (match_operand 1 "general_operand")]
17714   "ix86_target_stack_probe ()"
17716   rtx x;
17718 #ifndef CHECK_STACK_LIMIT
17719 #define CHECK_STACK_LIMIT 0
17720 #endif
17722   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17723       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17724     x = operands[1];
17725   else
17726     {
17727       rtx (*insn) (rtx, rtx);
17729       x = copy_to_mode_reg (Pmode, operands[1]);
17731       insn = (TARGET_64BIT
17732               ? gen_allocate_stack_worker_probe_di
17733               : gen_allocate_stack_worker_probe_si);
17735       emit_insn (insn (x, x));
17736     }
17738   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17739                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17741   if (x != stack_pointer_rtx)
17742     emit_move_insn (stack_pointer_rtx, x);
17744   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17745   DONE;
17748 (define_expand "probe_stack"
17749   [(match_operand 0 "memory_operand")]
17750   ""
17752   rtx (*insn) (rtx, rtx)
17753     = (GET_MODE (operands[0]) == DImode
17754        ? gen_probe_stack_di : gen_probe_stack_si);
17756   emit_insn (insn (operands[0], const0_rtx));
17757   DONE;
17760 ;; Use OR for stack probes, this is shorter.
17761 (define_insn "probe_stack_<mode>"
17762   [(set (match_operand:W 0 "memory_operand" "=m")
17763         (unspec:W [(match_operand:W 1 "const0_operand")]
17764                   UNSPEC_PROBE_STACK))
17765    (clobber (reg:CC FLAGS_REG))]
17766   ""
17767   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17768   [(set_attr "type" "alu1")
17769    (set_attr "mode" "<MODE>")
17770    (set_attr "length_immediate" "1")])
17771   
17772 (define_insn "adjust_stack_and_probe<mode>"
17773   [(set (match_operand:P 0 "register_operand" "=r")
17774         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17775                             UNSPECV_PROBE_STACK_RANGE))
17776    (set (reg:P SP_REG)
17777         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17778    (clobber (reg:CC FLAGS_REG))
17779    (clobber (mem:BLK (scratch)))]
17780   ""
17781   "* return output_adjust_stack_and_probe (operands[0]);"
17782   [(set_attr "type" "multi")])
17784 (define_insn "probe_stack_range<mode>"
17785   [(set (match_operand:P 0 "register_operand" "=r")
17786         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17787                             (match_operand:P 2 "const_int_operand" "n")]
17788                             UNSPECV_PROBE_STACK_RANGE))
17789    (clobber (reg:CC FLAGS_REG))]
17790   ""
17791   "* return output_probe_stack_range (operands[0], operands[2]);"
17792   [(set_attr "type" "multi")])
17794 (define_expand "builtin_setjmp_receiver"
17795   [(label_ref (match_operand 0))]
17796   "!TARGET_64BIT && flag_pic"
17798 #if TARGET_MACHO
17799   if (TARGET_MACHO)
17800     {
17801       rtx xops[3];
17802       rtx_code_label *label_rtx = gen_label_rtx ();
17803       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17804       xops[0] = xops[1] = pic_offset_table_rtx;
17805       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17806       ix86_expand_binary_operator (MINUS, SImode, xops);
17807     }
17808   else
17809 #endif
17810     emit_insn (gen_set_got (pic_offset_table_rtx));
17811   DONE;
17814 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17815 ;; Do not split instructions with mask registers.
17816 (define_split
17817   [(set (match_operand 0 "general_reg_operand")
17818         (match_operator 3 "promotable_binary_operator"
17819            [(match_operand 1 "general_reg_operand")
17820             (match_operand 2 "aligned_operand")]))
17821    (clobber (reg:CC FLAGS_REG))]
17822   "! TARGET_PARTIAL_REG_STALL && reload_completed
17823    && ((GET_MODE (operands[0]) == HImode
17824         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17825             /* ??? next two lines just !satisfies_constraint_K (...) */
17826             || !CONST_INT_P (operands[2])
17827             || satisfies_constraint_K (operands[2])))
17828        || (GET_MODE (operands[0]) == QImode
17829            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17830   [(parallel [(set (match_dup 0)
17831                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17832               (clobber (reg:CC FLAGS_REG))])]
17834   operands[0] = gen_lowpart (SImode, operands[0]);
17835   operands[1] = gen_lowpart (SImode, operands[1]);
17836   if (GET_CODE (operands[3]) != ASHIFT)
17837     operands[2] = gen_lowpart (SImode, operands[2]);
17838   operands[3] = shallow_copy_rtx (operands[3]);
17839   PUT_MODE (operands[3], SImode);
17842 ; Promote the QImode tests, as i386 has encoding of the AND
17843 ; instruction with 32-bit sign-extended immediate and thus the
17844 ; instruction size is unchanged, except in the %eax case for
17845 ; which it is increased by one byte, hence the ! optimize_size.
17846 (define_split
17847   [(set (match_operand 0 "flags_reg_operand")
17848         (match_operator 2 "compare_operator"
17849           [(and (match_operand 3 "aligned_operand")
17850                 (match_operand 4 "const_int_operand"))
17851            (const_int 0)]))
17852    (set (match_operand 1 "register_operand")
17853         (and (match_dup 3) (match_dup 4)))]
17854   "! TARGET_PARTIAL_REG_STALL && reload_completed
17855    && optimize_insn_for_speed_p ()
17856    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17857        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17858    /* Ensure that the operand will remain sign-extended immediate.  */
17859    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17860   [(parallel [(set (match_dup 0)
17861                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17862                                     (const_int 0)]))
17863               (set (match_dup 1)
17864                    (and:SI (match_dup 3) (match_dup 4)))])]
17866   operands[4]
17867     = gen_int_mode (INTVAL (operands[4])
17868                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17869   operands[1] = gen_lowpart (SImode, operands[1]);
17870   operands[3] = gen_lowpart (SImode, operands[3]);
17873 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17874 ; the TEST instruction with 32-bit sign-extended immediate and thus
17875 ; the instruction size would at least double, which is not what we
17876 ; want even with ! optimize_size.
17877 (define_split
17878   [(set (match_operand 0 "flags_reg_operand")
17879         (match_operator 1 "compare_operator"
17880           [(and (match_operand:HI 2 "aligned_operand")
17881                 (match_operand:HI 3 "const_int_operand"))
17882            (const_int 0)]))]
17883   "! TARGET_PARTIAL_REG_STALL && reload_completed
17884    && ! TARGET_FAST_PREFIX
17885    && optimize_insn_for_speed_p ()
17886    /* Ensure that the operand will remain sign-extended immediate.  */
17887    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17888   [(set (match_dup 0)
17889         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17890                          (const_int 0)]))]
17892   operands[3]
17893     = gen_int_mode (INTVAL (operands[3])
17894                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17895   operands[2] = gen_lowpart (SImode, operands[2]);
17898 (define_split
17899   [(set (match_operand 0 "register_operand")
17900         (neg (match_operand 1 "register_operand")))
17901    (clobber (reg:CC FLAGS_REG))]
17902   "! TARGET_PARTIAL_REG_STALL && reload_completed
17903    && (GET_MODE (operands[0]) == HImode
17904        || (GET_MODE (operands[0]) == QImode
17905            && (TARGET_PROMOTE_QImode
17906                || optimize_insn_for_size_p ())))"
17907   [(parallel [(set (match_dup 0)
17908                    (neg:SI (match_dup 1)))
17909               (clobber (reg:CC FLAGS_REG))])]
17911   operands[0] = gen_lowpart (SImode, operands[0]);
17912   operands[1] = gen_lowpart (SImode, operands[1]);
17915 ;; Do not split instructions with mask regs.
17916 (define_split
17917   [(set (match_operand 0 "general_reg_operand")
17918         (not (match_operand 1 "general_reg_operand")))]
17919   "! TARGET_PARTIAL_REG_STALL && reload_completed
17920    && (GET_MODE (operands[0]) == HImode
17921        || (GET_MODE (operands[0]) == QImode
17922            && (TARGET_PROMOTE_QImode
17923                || optimize_insn_for_size_p ())))"
17924   [(set (match_dup 0)
17925         (not:SI (match_dup 1)))]
17927   operands[0] = gen_lowpart (SImode, operands[0]);
17928   operands[1] = gen_lowpart (SImode, operands[1]);
17931 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17932 ;; transform a complex memory operation into two memory to register operations.
17934 ;; Don't push memory operands
17935 (define_peephole2
17936   [(set (match_operand:SWI 0 "push_operand")
17937         (match_operand:SWI 1 "memory_operand"))
17938    (match_scratch:SWI 2 "<r>")]
17939   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17940    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17941   [(set (match_dup 2) (match_dup 1))
17942    (set (match_dup 0) (match_dup 2))])
17944 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17945 ;; SImode pushes.
17946 (define_peephole2
17947   [(set (match_operand:SF 0 "push_operand")
17948         (match_operand:SF 1 "memory_operand"))
17949    (match_scratch:SF 2 "r")]
17950   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17951    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17952   [(set (match_dup 2) (match_dup 1))
17953    (set (match_dup 0) (match_dup 2))])
17955 ;; Don't move an immediate directly to memory when the instruction
17956 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17957 (define_peephole2
17958   [(match_scratch:SWI124 1 "<r>")
17959    (set (match_operand:SWI124 0 "memory_operand")
17960         (const_int 0))]
17961   "optimize_insn_for_speed_p ()
17962    && ((<MODE>mode == HImode
17963        && TARGET_LCP_STALL)
17964        || (!TARGET_USE_MOV0
17965           && TARGET_SPLIT_LONG_MOVES
17966           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17967    && peep2_regno_dead_p (0, FLAGS_REG)"
17968   [(parallel [(set (match_dup 2) (const_int 0))
17969               (clobber (reg:CC FLAGS_REG))])
17970    (set (match_dup 0) (match_dup 1))]
17971   "operands[2] = gen_lowpart (SImode, operands[1]);")
17973 (define_peephole2
17974   [(match_scratch:SWI124 2 "<r>")
17975    (set (match_operand:SWI124 0 "memory_operand")
17976         (match_operand:SWI124 1 "immediate_operand"))]
17977   "optimize_insn_for_speed_p ()
17978    && ((<MODE>mode == HImode
17979        && TARGET_LCP_STALL)
17980        || (TARGET_SPLIT_LONG_MOVES
17981           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17982   [(set (match_dup 2) (match_dup 1))
17983    (set (match_dup 0) (match_dup 2))])
17985 ;; Don't compare memory with zero, load and use a test instead.
17986 (define_peephole2
17987   [(set (match_operand 0 "flags_reg_operand")
17988         (match_operator 1 "compare_operator"
17989           [(match_operand:SI 2 "memory_operand")
17990            (const_int 0)]))
17991    (match_scratch:SI 3 "r")]
17992   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17993   [(set (match_dup 3) (match_dup 2))
17994    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17996 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17997 ;; Don't split NOTs with a displacement operand, because resulting XOR
17998 ;; will not be pairable anyway.
18000 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18001 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18002 ;; so this split helps here as well.
18004 ;; Note: Can't do this as a regular split because we can't get proper
18005 ;; lifetime information then.
18007 (define_peephole2
18008   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18009         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18010   "optimize_insn_for_speed_p ()
18011    && ((TARGET_NOT_UNPAIRABLE
18012         && (!MEM_P (operands[0])
18013             || !memory_displacement_operand (operands[0], <MODE>mode)))
18014        || (TARGET_NOT_VECTORMODE
18015            && long_memory_operand (operands[0], <MODE>mode)))
18016    && peep2_regno_dead_p (0, FLAGS_REG)"
18017   [(parallel [(set (match_dup 0)
18018                    (xor:SWI124 (match_dup 1) (const_int -1)))
18019               (clobber (reg:CC FLAGS_REG))])])
18021 ;; Non pairable "test imm, reg" instructions can be translated to
18022 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18023 ;; byte opcode instead of two, have a short form for byte operands),
18024 ;; so do it for other CPUs as well.  Given that the value was dead,
18025 ;; this should not create any new dependencies.  Pass on the sub-word
18026 ;; versions if we're concerned about partial register stalls.
18028 (define_peephole2
18029   [(set (match_operand 0 "flags_reg_operand")
18030         (match_operator 1 "compare_operator"
18031           [(and:SI (match_operand:SI 2 "register_operand")
18032                    (match_operand:SI 3 "immediate_operand"))
18033            (const_int 0)]))]
18034   "ix86_match_ccmode (insn, CCNOmode)
18035    && (REGNO (operands[2]) != AX_REG
18036        || satisfies_constraint_K (operands[3]))
18037    && peep2_reg_dead_p (1, operands[2])"
18038   [(parallel
18039      [(set (match_dup 0)
18040            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18041                             (const_int 0)]))
18042       (set (match_dup 2)
18043            (and:SI (match_dup 2) (match_dup 3)))])])
18045 ;; We don't need to handle HImode case, because it will be promoted to SImode
18046 ;; on ! TARGET_PARTIAL_REG_STALL
18048 (define_peephole2
18049   [(set (match_operand 0 "flags_reg_operand")
18050         (match_operator 1 "compare_operator"
18051           [(and:QI (match_operand:QI 2 "register_operand")
18052                    (match_operand:QI 3 "immediate_operand"))
18053            (const_int 0)]))]
18054   "! TARGET_PARTIAL_REG_STALL
18055    && ix86_match_ccmode (insn, CCNOmode)
18056    && REGNO (operands[2]) != AX_REG
18057    && peep2_reg_dead_p (1, operands[2])"
18058   [(parallel
18059      [(set (match_dup 0)
18060            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18061                             (const_int 0)]))
18062       (set (match_dup 2)
18063            (and:QI (match_dup 2) (match_dup 3)))])])
18065 (define_peephole2
18066   [(set (match_operand 0 "flags_reg_operand")
18067         (match_operator 1 "compare_operator"
18068           [(and:QI
18069              (subreg:QI
18070                (zero_extract:SI (match_operand 2 "QIreg_operand")
18071                                 (const_int 8)
18072                                 (const_int 8)) 0)
18073              (match_operand 3 "const_int_operand"))
18074            (const_int 0)]))]
18075   "! TARGET_PARTIAL_REG_STALL
18076    && ix86_match_ccmode (insn, CCNOmode)
18077    && REGNO (operands[2]) != AX_REG
18078    && peep2_reg_dead_p (1, operands[2])"
18079   [(parallel
18080      [(set (match_dup 0)
18081            (match_op_dup 1
18082              [(and:QI
18083                 (subreg:QI
18084                   (zero_extract:SI (match_dup 2)
18085                                    (const_int 8)
18086                                    (const_int 8)) 0)
18087                 (match_dup 3))
18088               (const_int 0)]))
18089       (set (zero_extract:SI (match_dup 2)
18090                             (const_int 8)
18091                             (const_int 8))
18092            (subreg:SI
18093              (and:QI
18094                (subreg:QI
18095                  (zero_extract:SI (match_dup 2)
18096                                   (const_int 8)
18097                                   (const_int 8)) 0)
18098                (match_dup 3)) 0))])])
18100 ;; Don't do logical operations with memory inputs.
18101 (define_peephole2
18102   [(match_scratch:SWI 2 "<r>")
18103    (parallel [(set (match_operand:SWI 0 "register_operand")
18104                    (match_operator:SWI 3 "arith_or_logical_operator"
18105                      [(match_dup 0)
18106                       (match_operand:SWI 1 "memory_operand")]))
18107               (clobber (reg:CC FLAGS_REG))])]
18108   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18109   [(set (match_dup 2) (match_dup 1))
18110    (parallel [(set (match_dup 0)
18111                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18112               (clobber (reg:CC FLAGS_REG))])])
18114 (define_peephole2
18115   [(match_scratch:SWI 2 "<r>")
18116    (parallel [(set (match_operand:SWI 0 "register_operand")
18117                    (match_operator:SWI 3 "arith_or_logical_operator"
18118                      [(match_operand:SWI 1 "memory_operand")
18119                       (match_dup 0)]))
18120               (clobber (reg:CC FLAGS_REG))])]
18121   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18122   [(set (match_dup 2) (match_dup 1))
18123    (parallel [(set (match_dup 0)
18124                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18125               (clobber (reg:CC FLAGS_REG))])])
18127 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
18128 ;; the memory address refers to the destination of the load!
18130 (define_peephole2
18131   [(set (match_operand:SWI 0 "general_reg_operand")
18132         (match_operand:SWI 1 "general_reg_operand"))
18133    (parallel [(set (match_dup 0)
18134                    (match_operator:SWI 3 "commutative_operator"
18135                      [(match_dup 0)
18136                       (match_operand:SWI 2 "memory_operand")]))
18137               (clobber (reg:CC FLAGS_REG))])]
18138   "REGNO (operands[0]) != REGNO (operands[1])
18139    && (<MODE>mode != QImode
18140        || any_QIreg_operand (operands[1], QImode))"
18141   [(set (match_dup 0) (match_dup 4))
18142    (parallel [(set (match_dup 0)
18143                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18144               (clobber (reg:CC FLAGS_REG))])]
18145   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18147 (define_peephole2
18148   [(set (match_operand 0 "mmx_reg_operand")
18149         (match_operand 1 "mmx_reg_operand"))
18150    (set (match_dup 0)
18151         (match_operator 3 "commutative_operator"
18152           [(match_dup 0)
18153            (match_operand 2 "memory_operand")]))]
18154   "REGNO (operands[0]) != REGNO (operands[1])"
18155   [(set (match_dup 0) (match_dup 2))
18156    (set (match_dup 0)
18157         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18159 (define_peephole2
18160   [(set (match_operand 0 "sse_reg_operand")
18161         (match_operand 1 "sse_reg_operand"))
18162    (set (match_dup 0)
18163         (match_operator 3 "commutative_operator"
18164           [(match_dup 0)
18165            (match_operand 2 "memory_operand")]))]
18166   "REGNO (operands[0]) != REGNO (operands[1])"
18167   [(set (match_dup 0) (match_dup 2))
18168    (set (match_dup 0)
18169         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18171 ; Don't do logical operations with memory outputs
18173 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18174 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18175 ; the same decoder scheduling characteristics as the original.
18177 (define_peephole2
18178   [(match_scratch:SWI 2 "<r>")
18179    (parallel [(set (match_operand:SWI 0 "memory_operand")
18180                    (match_operator:SWI 3 "arith_or_logical_operator"
18181                      [(match_dup 0)
18182                       (match_operand:SWI 1 "<nonmemory_operand>")]))
18183               (clobber (reg:CC FLAGS_REG))])]
18184   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18185   [(set (match_dup 2) (match_dup 0))
18186    (parallel [(set (match_dup 2)
18187                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18188               (clobber (reg:CC FLAGS_REG))])
18189    (set (match_dup 0) (match_dup 2))])
18191 (define_peephole2
18192   [(match_scratch:SWI 2 "<r>")
18193    (parallel [(set (match_operand:SWI 0 "memory_operand")
18194                    (match_operator:SWI 3 "arith_or_logical_operator"
18195                      [(match_operand:SWI 1 "<nonmemory_operand>")
18196                       (match_dup 0)]))
18197               (clobber (reg:CC FLAGS_REG))])]
18198   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18199   [(set (match_dup 2) (match_dup 0))
18200    (parallel [(set (match_dup 2)
18201                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18202               (clobber (reg:CC FLAGS_REG))])
18203    (set (match_dup 0) (match_dup 2))])
18205 ;; Attempt to use arith or logical operations with memory outputs with
18206 ;; setting of flags.
18207 (define_peephole2
18208   [(set (match_operand:SWI 0 "register_operand")
18209         (match_operand:SWI 1 "memory_operand"))
18210    (parallel [(set (match_dup 0)
18211                    (match_operator:SWI 3 "plusminuslogic_operator"
18212                      [(match_dup 0)
18213                       (match_operand:SWI 2 "<nonmemory_operand>")]))
18214               (clobber (reg:CC FLAGS_REG))])
18215    (set (match_dup 1) (match_dup 0))
18216    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18217   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18218    && peep2_reg_dead_p (4, operands[0])
18219    && !reg_overlap_mentioned_p (operands[0], operands[1])
18220    && !reg_overlap_mentioned_p (operands[0], operands[2])
18221    && (<MODE>mode != QImode
18222        || immediate_operand (operands[2], QImode)
18223        || any_QIreg_operand (operands[2], QImode))
18224    && ix86_match_ccmode (peep2_next_insn (3),
18225                          (GET_CODE (operands[3]) == PLUS
18226                           || GET_CODE (operands[3]) == MINUS)
18227                          ? CCGOCmode : CCNOmode)"
18228   [(parallel [(set (match_dup 4) (match_dup 6))
18229               (set (match_dup 1) (match_dup 5))])]
18231   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18232   operands[5]
18233     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18234                       copy_rtx (operands[1]),
18235                       operands[2]);
18236   operands[6]
18237     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18238                        copy_rtx (operands[5]),
18239                        const0_rtx);
18242 ;; Likewise for instances where we have a lea pattern.
18243 (define_peephole2
18244   [(set (match_operand:SWI 0 "register_operand")
18245         (match_operand:SWI 1 "memory_operand"))
18246    (set (match_operand:SWI 3 "register_operand")
18247         (plus:SWI (match_dup 0)
18248                   (match_operand:SWI 2 "<nonmemory_operand>")))
18249    (set (match_dup 1) (match_dup 3))
18250    (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18251   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18252    && peep2_reg_dead_p (4, operands[3])
18253    && (rtx_equal_p (operands[0], operands[3])
18254        || peep2_reg_dead_p (2, operands[0]))
18255    && !reg_overlap_mentioned_p (operands[0], operands[1])
18256    && !reg_overlap_mentioned_p (operands[3], operands[1])
18257    && !reg_overlap_mentioned_p (operands[0], operands[2])
18258    && (<MODE>mode != QImode
18259        || immediate_operand (operands[2], QImode)
18260        || any_QIreg_operand (operands[2], QImode))
18261    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18262   [(parallel [(set (match_dup 4) (match_dup 6))
18263               (set (match_dup 1) (match_dup 5))])]
18265   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18266   operands[5]
18267     = gen_rtx_PLUS (<MODE>mode,
18268                     copy_rtx (operands[1]),
18269                     operands[2]);
18270   operands[6]
18271     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18272                        copy_rtx (operands[5]),
18273                        const0_rtx);
18276 (define_peephole2
18277   [(parallel [(set (match_operand:SWI 0 "register_operand")
18278                    (match_operator:SWI 2 "plusminuslogic_operator"
18279                      [(match_dup 0)
18280                       (match_operand:SWI 1 "memory_operand")]))
18281               (clobber (reg:CC FLAGS_REG))])
18282    (set (match_dup 1) (match_dup 0))
18283    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18284   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18285    && GET_CODE (operands[2]) != MINUS
18286    && peep2_reg_dead_p (3, operands[0])
18287    && !reg_overlap_mentioned_p (operands[0], operands[1])
18288    && ix86_match_ccmode (peep2_next_insn (2),
18289                          GET_CODE (operands[2]) == PLUS
18290                          ? CCGOCmode : CCNOmode)"
18291   [(parallel [(set (match_dup 3) (match_dup 5))
18292               (set (match_dup 1) (match_dup 4))])]
18294   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18295   operands[4]
18296     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18297                       copy_rtx (operands[1]),
18298                       operands[0]);
18299   operands[5]
18300     = gen_rtx_COMPARE (GET_MODE (operands[3]),
18301                        copy_rtx (operands[4]),
18302                        const0_rtx);
18305 (define_peephole2
18306   [(set (match_operand:SWI12 0 "register_operand")
18307         (match_operand:SWI12 1 "memory_operand"))
18308    (parallel [(set (match_operand:SI 4 "register_operand")
18309                    (match_operator:SI 3 "plusminuslogic_operator"
18310                      [(match_dup 4)
18311                       (match_operand:SI 2 "nonmemory_operand")]))
18312               (clobber (reg:CC FLAGS_REG))])
18313    (set (match_dup 1) (match_dup 0))
18314    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18315   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18316    && REGNO (operands[0]) == REGNO (operands[4])
18317    && peep2_reg_dead_p (4, operands[0])
18318    && (<MODE>mode != QImode
18319        || immediate_operand (operands[2], SImode)
18320        || any_QIreg_operand (operands[2], SImode))
18321    && !reg_overlap_mentioned_p (operands[0], operands[1])
18322    && !reg_overlap_mentioned_p (operands[0], operands[2])
18323    && ix86_match_ccmode (peep2_next_insn (3),
18324                          (GET_CODE (operands[3]) == PLUS
18325                           || GET_CODE (operands[3]) == MINUS)
18326                          ? CCGOCmode : CCNOmode)"
18327   [(parallel [(set (match_dup 4) (match_dup 6))
18328               (set (match_dup 1) (match_dup 5))])]
18330   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18331   operands[5]
18332     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18333                       copy_rtx (operands[1]),
18334                       gen_lowpart (<MODE>mode, operands[2]));
18335   operands[6]
18336     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18337                        copy_rtx (operands[5]),
18338                        const0_rtx);
18341 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18342 (define_peephole2
18343   [(set (match_operand 0 "general_reg_operand")
18344         (match_operand 1 "const0_operand"))]
18345   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18346    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18347    && peep2_regno_dead_p (0, FLAGS_REG)"
18348   [(parallel [(set (match_dup 0) (const_int 0))
18349               (clobber (reg:CC FLAGS_REG))])]
18350   "operands[0] = gen_lowpart (word_mode, operands[0]);")
18352 (define_peephole2
18353   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18354         (const_int 0))]
18355   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18356    && peep2_regno_dead_p (0, FLAGS_REG)"
18357   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18358               (clobber (reg:CC FLAGS_REG))])])
18360 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18361 (define_peephole2
18362   [(set (match_operand:SWI248 0 "general_reg_operand")
18363         (const_int -1))]
18364   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18365    && peep2_regno_dead_p (0, FLAGS_REG)"
18366   [(parallel [(set (match_dup 0) (const_int -1))
18367               (clobber (reg:CC FLAGS_REG))])]
18369   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18370     operands[0] = gen_lowpart (SImode, operands[0]);
18373 ;; Attempt to convert simple lea to add/shift.
18374 ;; These can be created by move expanders.
18375 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18376 ;; relevant lea instructions were already split.
18378 (define_peephole2
18379   [(set (match_operand:SWI48 0 "register_operand")
18380         (plus:SWI48 (match_dup 0)
18381                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
18382   "!TARGET_OPT_AGU
18383    && peep2_regno_dead_p (0, FLAGS_REG)"
18384   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18385               (clobber (reg:CC FLAGS_REG))])])
18387 (define_peephole2
18388   [(set (match_operand:SWI48 0 "register_operand")
18389         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18390                     (match_dup 0)))]
18391   "!TARGET_OPT_AGU
18392    && peep2_regno_dead_p (0, FLAGS_REG)"
18393   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18394               (clobber (reg:CC FLAGS_REG))])])
18396 (define_peephole2
18397   [(set (match_operand:DI 0 "register_operand")
18398         (zero_extend:DI
18399           (plus:SI (match_operand:SI 1 "register_operand")
18400                    (match_operand:SI 2 "nonmemory_operand"))))]
18401   "TARGET_64BIT && !TARGET_OPT_AGU
18402    && REGNO (operands[0]) == REGNO (operands[1])
18403    && peep2_regno_dead_p (0, FLAGS_REG)"
18404   [(parallel [(set (match_dup 0)
18405                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18406               (clobber (reg:CC FLAGS_REG))])])
18408 (define_peephole2
18409   [(set (match_operand:DI 0 "register_operand")
18410         (zero_extend:DI
18411           (plus:SI (match_operand:SI 1 "nonmemory_operand")
18412                    (match_operand:SI 2 "register_operand"))))]
18413   "TARGET_64BIT && !TARGET_OPT_AGU
18414    && REGNO (operands[0]) == REGNO (operands[2])
18415    && peep2_regno_dead_p (0, FLAGS_REG)"
18416   [(parallel [(set (match_dup 0)
18417                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18418               (clobber (reg:CC FLAGS_REG))])])
18420 (define_peephole2
18421   [(set (match_operand:SWI48 0 "register_operand")
18422         (mult:SWI48 (match_dup 0)
18423                     (match_operand:SWI48 1 "const_int_operand")))]
18424   "pow2p_hwi (INTVAL (operands[1]))
18425    && peep2_regno_dead_p (0, FLAGS_REG)"
18426   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18427               (clobber (reg:CC FLAGS_REG))])]
18428   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18430 (define_peephole2
18431   [(set (match_operand:DI 0 "register_operand")
18432         (zero_extend:DI
18433           (mult:SI (match_operand:SI 1 "register_operand")
18434                    (match_operand:SI 2 "const_int_operand"))))]
18435   "TARGET_64BIT
18436    && pow2p_hwi (INTVAL (operands[2]))
18437    && REGNO (operands[0]) == REGNO (operands[1])
18438    && peep2_regno_dead_p (0, FLAGS_REG)"
18439   [(parallel [(set (match_dup 0)
18440                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18441               (clobber (reg:CC FLAGS_REG))])]
18442   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18444 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18445 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18446 ;; On many CPUs it is also faster, since special hardware to avoid esp
18447 ;; dependencies is present.
18449 ;; While some of these conversions may be done using splitters, we use
18450 ;; peepholes in order to allow combine_stack_adjustments pass to see
18451 ;; nonobfuscated RTL.
18453 ;; Convert prologue esp subtractions to push.
18454 ;; We need register to push.  In order to keep verify_flow_info happy we have
18455 ;; two choices
18456 ;; - use scratch and clobber it in order to avoid dependencies
18457 ;; - use already live register
18458 ;; We can't use the second way right now, since there is no reliable way how to
18459 ;; verify that given register is live.  First choice will also most likely in
18460 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18461 ;; call clobbered registers are dead.  We may want to use base pointer as an
18462 ;; alternative when no register is available later.
18464 (define_peephole2
18465   [(match_scratch:W 1 "r")
18466    (parallel [(set (reg:P SP_REG)
18467                    (plus:P (reg:P SP_REG)
18468                            (match_operand:P 0 "const_int_operand")))
18469               (clobber (reg:CC FLAGS_REG))
18470               (clobber (mem:BLK (scratch)))])]
18471   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18472    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18473    && !ix86_using_red_zone ()"
18474   [(clobber (match_dup 1))
18475    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18476               (clobber (mem:BLK (scratch)))])])
18478 (define_peephole2
18479   [(match_scratch:W 1 "r")
18480    (parallel [(set (reg:P SP_REG)
18481                    (plus:P (reg:P SP_REG)
18482                            (match_operand:P 0 "const_int_operand")))
18483               (clobber (reg:CC FLAGS_REG))
18484               (clobber (mem:BLK (scratch)))])]
18485   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18486    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18487    && !ix86_using_red_zone ()"
18488   [(clobber (match_dup 1))
18489    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18490    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18491               (clobber (mem:BLK (scratch)))])])
18493 ;; Convert esp subtractions to push.
18494 (define_peephole2
18495   [(match_scratch:W 1 "r")
18496    (parallel [(set (reg:P SP_REG)
18497                    (plus:P (reg:P SP_REG)
18498                            (match_operand:P 0 "const_int_operand")))
18499               (clobber (reg:CC FLAGS_REG))])]
18500   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18501    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18502    && !ix86_using_red_zone ()"
18503   [(clobber (match_dup 1))
18504    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18506 (define_peephole2
18507   [(match_scratch:W 1 "r")
18508    (parallel [(set (reg:P SP_REG)
18509                    (plus:P (reg:P SP_REG)
18510                            (match_operand:P 0 "const_int_operand")))
18511               (clobber (reg:CC FLAGS_REG))])]
18512   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18513    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18514    && !ix86_using_red_zone ()"
18515   [(clobber (match_dup 1))
18516    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18517    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18519 ;; Convert epilogue deallocator to pop.
18520 (define_peephole2
18521   [(match_scratch:W 1 "r")
18522    (parallel [(set (reg:P SP_REG)
18523                    (plus:P (reg:P SP_REG)
18524                            (match_operand:P 0 "const_int_operand")))
18525               (clobber (reg:CC FLAGS_REG))
18526               (clobber (mem:BLK (scratch)))])]
18527   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18528    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18529   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18530               (clobber (mem:BLK (scratch)))])])
18532 ;; Two pops case is tricky, since pop causes dependency
18533 ;; on destination register.  We use two registers if available.
18534 (define_peephole2
18535   [(match_scratch:W 1 "r")
18536    (match_scratch:W 2 "r")
18537    (parallel [(set (reg:P SP_REG)
18538                    (plus:P (reg:P SP_REG)
18539                            (match_operand:P 0 "const_int_operand")))
18540               (clobber (reg:CC FLAGS_REG))
18541               (clobber (mem:BLK (scratch)))])]
18542   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18543    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18544   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18545               (clobber (mem:BLK (scratch)))])
18546    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18548 (define_peephole2
18549   [(match_scratch:W 1 "r")
18550    (parallel [(set (reg:P SP_REG)
18551                    (plus:P (reg:P SP_REG)
18552                            (match_operand:P 0 "const_int_operand")))
18553               (clobber (reg:CC FLAGS_REG))
18554               (clobber (mem:BLK (scratch)))])]
18555   "optimize_insn_for_size_p ()
18556    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18557   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18558               (clobber (mem:BLK (scratch)))])
18559    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18561 ;; Convert esp additions to pop.
18562 (define_peephole2
18563   [(match_scratch:W 1 "r")
18564    (parallel [(set (reg:P SP_REG)
18565                    (plus:P (reg:P SP_REG)
18566                            (match_operand:P 0 "const_int_operand")))
18567               (clobber (reg:CC FLAGS_REG))])]
18568   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18569   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18571 ;; Two pops case is tricky, since pop causes dependency
18572 ;; on destination register.  We use two registers if available.
18573 (define_peephole2
18574   [(match_scratch:W 1 "r")
18575    (match_scratch:W 2 "r")
18576    (parallel [(set (reg:P SP_REG)
18577                    (plus:P (reg:P SP_REG)
18578                            (match_operand:P 0 "const_int_operand")))
18579               (clobber (reg:CC FLAGS_REG))])]
18580   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18581   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18582    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18584 (define_peephole2
18585   [(match_scratch:W 1 "r")
18586    (parallel [(set (reg:P SP_REG)
18587                    (plus:P (reg:P SP_REG)
18588                            (match_operand:P 0 "const_int_operand")))
18589               (clobber (reg:CC FLAGS_REG))])]
18590   "optimize_insn_for_size_p ()
18591    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18592   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18593    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18595 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18596 ;; required and register dies.  Similarly for 128 to -128.
18597 (define_peephole2
18598   [(set (match_operand 0 "flags_reg_operand")
18599         (match_operator 1 "compare_operator"
18600           [(match_operand 2 "register_operand")
18601            (match_operand 3 "const_int_operand")]))]
18602   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18603      && incdec_operand (operands[3], GET_MODE (operands[3])))
18604     || (!TARGET_FUSE_CMP_AND_BRANCH
18605         && INTVAL (operands[3]) == 128))
18606    && ix86_match_ccmode (insn, CCGCmode)
18607    && peep2_reg_dead_p (1, operands[2])"
18608   [(parallel [(set (match_dup 0)
18609                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18610               (clobber (match_dup 2))])])
18612 ;; Convert imul by three, five and nine into lea
18613 (define_peephole2
18614   [(parallel
18615     [(set (match_operand:SWI48 0 "register_operand")
18616           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18617                       (match_operand:SWI48 2 "const359_operand")))
18618      (clobber (reg:CC FLAGS_REG))])]
18619   "!TARGET_PARTIAL_REG_STALL
18620    || <MODE>mode == SImode
18621    || optimize_function_for_size_p (cfun)"
18622   [(set (match_dup 0)
18623         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18624                     (match_dup 1)))]
18625   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18627 (define_peephole2
18628   [(parallel
18629     [(set (match_operand:SWI48 0 "register_operand")
18630           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18631                       (match_operand:SWI48 2 "const359_operand")))
18632      (clobber (reg:CC FLAGS_REG))])]
18633   "optimize_insn_for_speed_p ()
18634    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18635   [(set (match_dup 0) (match_dup 1))
18636    (set (match_dup 0)
18637         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18638                     (match_dup 0)))]
18639   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18641 ;; imul $32bit_imm, mem, reg is vector decoded, while
18642 ;; imul $32bit_imm, reg, reg is direct decoded.
18643 (define_peephole2
18644   [(match_scratch:SWI48 3 "r")
18645    (parallel [(set (match_operand:SWI48 0 "register_operand")
18646                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18647                                (match_operand:SWI48 2 "immediate_operand")))
18648               (clobber (reg:CC FLAGS_REG))])]
18649   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18650    && !satisfies_constraint_K (operands[2])"
18651   [(set (match_dup 3) (match_dup 1))
18652    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18653               (clobber (reg:CC FLAGS_REG))])])
18655 (define_peephole2
18656   [(match_scratch:SI 3 "r")
18657    (parallel [(set (match_operand:DI 0 "register_operand")
18658                    (zero_extend:DI
18659                      (mult:SI (match_operand:SI 1 "memory_operand")
18660                               (match_operand:SI 2 "immediate_operand"))))
18661               (clobber (reg:CC FLAGS_REG))])]
18662   "TARGET_64BIT
18663    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18664    && !satisfies_constraint_K (operands[2])"
18665   [(set (match_dup 3) (match_dup 1))
18666    (parallel [(set (match_dup 0)
18667                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18668               (clobber (reg:CC FLAGS_REG))])])
18670 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18671 ;; Convert it into imul reg, reg
18672 ;; It would be better to force assembler to encode instruction using long
18673 ;; immediate, but there is apparently no way to do so.
18674 (define_peephole2
18675   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18676                    (mult:SWI248
18677                     (match_operand:SWI248 1 "nonimmediate_operand")
18678                     (match_operand:SWI248 2 "const_int_operand")))
18679               (clobber (reg:CC FLAGS_REG))])
18680    (match_scratch:SWI248 3 "r")]
18681   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18682    && satisfies_constraint_K (operands[2])"
18683   [(set (match_dup 3) (match_dup 2))
18684    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18685               (clobber (reg:CC FLAGS_REG))])]
18687   if (!rtx_equal_p (operands[0], operands[1]))
18688     emit_move_insn (operands[0], operands[1]);
18691 ;; After splitting up read-modify operations, array accesses with memory
18692 ;; operands might end up in form:
18693 ;;  sall    $2, %eax
18694 ;;  movl    4(%esp), %edx
18695 ;;  addl    %edx, %eax
18696 ;; instead of pre-splitting:
18697 ;;  sall    $2, %eax
18698 ;;  addl    4(%esp), %eax
18699 ;; Turn it into:
18700 ;;  movl    4(%esp), %edx
18701 ;;  leal    (%edx,%eax,4), %eax
18703 (define_peephole2
18704   [(match_scratch:W 5 "r")
18705    (parallel [(set (match_operand 0 "register_operand")
18706                    (ashift (match_operand 1 "register_operand")
18707                            (match_operand 2 "const_int_operand")))
18708                (clobber (reg:CC FLAGS_REG))])
18709    (parallel [(set (match_operand 3 "register_operand")
18710                    (plus (match_dup 0)
18711                          (match_operand 4 "x86_64_general_operand")))
18712                    (clobber (reg:CC FLAGS_REG))])]
18713   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18714    /* Validate MODE for lea.  */
18715    && ((!TARGET_PARTIAL_REG_STALL
18716         && (GET_MODE (operands[0]) == QImode
18717             || GET_MODE (operands[0]) == HImode))
18718        || GET_MODE (operands[0]) == SImode
18719        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18720    && (rtx_equal_p (operands[0], operands[3])
18721        || peep2_reg_dead_p (2, operands[0]))
18722    /* We reorder load and the shift.  */
18723    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18724   [(set (match_dup 5) (match_dup 4))
18725    (set (match_dup 0) (match_dup 1))]
18727   machine_mode op1mode = GET_MODE (operands[1]);
18728   machine_mode mode = op1mode == DImode ? DImode : SImode;
18729   int scale = 1 << INTVAL (operands[2]);
18730   rtx index = gen_lowpart (word_mode, operands[1]);
18731   rtx base = gen_lowpart (word_mode, operands[5]);
18732   rtx dest = gen_lowpart (mode, operands[3]);
18734   operands[1] = gen_rtx_PLUS (word_mode, base,
18735                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18736   if (mode != word_mode)
18737     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18739   operands[5] = base;
18740   if (op1mode != word_mode)
18741     operands[5] = gen_lowpart (op1mode, operands[5]);
18743   operands[0] = dest;
18746 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18747 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18748 ;; caught for use by garbage collectors and the like.  Using an insn that
18749 ;; maps to SIGILL makes it more likely the program will rightfully die.
18750 ;; Keeping with tradition, "6" is in honor of #UD.
18751 (define_insn "trap"
18752   [(trap_if (const_int 1) (const_int 6))]
18753   ""
18755 #ifdef HAVE_AS_IX86_UD2
18756   return "ud2";
18757 #else
18758   return ASM_SHORT "0x0b0f";
18759 #endif
18761   [(set_attr "length" "2")])
18763 (define_insn "ud2"
18764   [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
18765   ""
18767 #ifdef HAVE_AS_IX86_UD2
18768   return "ud2";
18769 #else
18770   return ASM_SHORT "0x0b0f";
18771 #endif
18773   [(set_attr "length" "2")])
18775 (define_expand "prefetch"
18776   [(prefetch (match_operand 0 "address_operand")
18777              (match_operand:SI 1 "const_int_operand")
18778              (match_operand:SI 2 "const_int_operand"))]
18779   "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18781   bool write = INTVAL (operands[1]) != 0;
18782   int locality = INTVAL (operands[2]);
18784   gcc_assert (IN_RANGE (locality, 0, 3));
18786   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18787      supported by SSE counterpart (non-SSE2 athlon machines) or the
18788      SSE prefetch is not available (K6 machines).  Otherwise use SSE
18789      prefetch as it allows specifying of locality.  */
18791   if (write)
18792     {
18793       if (TARGET_PREFETCHWT1)
18794         operands[2] = GEN_INT (MAX (locality, 2)); 
18795       else if (TARGET_PRFCHW)
18796         operands[2] = GEN_INT (3);
18797       else if (TARGET_3DNOW && !TARGET_SSE2)
18798         operands[2] = GEN_INT (3);
18799       else if (TARGET_PREFETCH_SSE)
18800         operands[1] = const0_rtx;
18801       else
18802         {
18803           gcc_assert (TARGET_3DNOW);
18804           operands[2] = GEN_INT (3);
18805         }
18806     }
18807   else
18808     {
18809       if (TARGET_PREFETCH_SSE)
18810         ;
18811       else
18812         {
18813           gcc_assert (TARGET_3DNOW);
18814           operands[2] = GEN_INT (3);
18815         }
18816     }
18819 (define_insn "*prefetch_sse"
18820   [(prefetch (match_operand 0 "address_operand" "p")
18821              (const_int 0)
18822              (match_operand:SI 1 "const_int_operand"))]
18823   "TARGET_PREFETCH_SSE"
18825   static const char * const patterns[4] = {
18826    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18827   };
18829   int locality = INTVAL (operands[1]);
18830   gcc_assert (IN_RANGE (locality, 0, 3));
18832   return patterns[locality];
18834   [(set_attr "type" "sse")
18835    (set_attr "atom_sse_attr" "prefetch")
18836    (set (attr "length_address")
18837         (symbol_ref "memory_address_length (operands[0], false)"))
18838    (set_attr "memory" "none")])
18840 (define_insn "*prefetch_3dnow"
18841   [(prefetch (match_operand 0 "address_operand" "p")
18842              (match_operand:SI 1 "const_int_operand" "n")
18843              (const_int 3))]
18844   "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18846   if (INTVAL (operands[1]) == 0)
18847     return "prefetch\t%a0";
18848   else
18849     return "prefetchw\t%a0";
18851   [(set_attr "type" "mmx")
18852    (set (attr "length_address")
18853         (symbol_ref "memory_address_length (operands[0], false)"))
18854    (set_attr "memory" "none")])
18856 (define_insn "*prefetch_prefetchwt1"
18857   [(prefetch (match_operand 0 "address_operand" "p")
18858              (const_int 1)
18859              (const_int 2))]
18860   "TARGET_PREFETCHWT1"
18861   "prefetchwt1\t%a0";
18862   [(set_attr "type" "sse")
18863    (set (attr "length_address")
18864         (symbol_ref "memory_address_length (operands[0], false)"))
18865    (set_attr "memory" "none")])
18867 (define_expand "stack_protect_set"
18868   [(match_operand 0 "memory_operand")
18869    (match_operand 1 "memory_operand")]
18870   "TARGET_SSP_TLS_GUARD"
18872   rtx (*insn)(rtx, rtx);
18874   insn = (TARGET_LP64
18875           ? gen_stack_protect_set_di
18876           : gen_stack_protect_set_si);
18878   emit_insn (insn (operands[0], operands[1]));
18879   DONE;
18882 (define_insn "stack_protect_set_<mode>"
18883   [(set (match_operand:PTR 0 "memory_operand" "=m")
18884         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18885                     UNSPEC_SP_SET))
18886    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18887    (clobber (reg:CC FLAGS_REG))]
18888   "TARGET_SSP_TLS_GUARD"
18889   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18890   [(set_attr "type" "multi")])
18892 (define_expand "stack_protect_test"
18893   [(match_operand 0 "memory_operand")
18894    (match_operand 1 "memory_operand")
18895    (match_operand 2)]
18896   "TARGET_SSP_TLS_GUARD"
18898   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18900   rtx (*insn)(rtx, rtx, rtx);
18902   insn = (TARGET_LP64
18903           ? gen_stack_protect_test_di
18904           : gen_stack_protect_test_si);
18906   emit_insn (insn (flags, operands[0], operands[1]));
18908   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18909                                   flags, const0_rtx, operands[2]));
18910   DONE;
18913 (define_insn "stack_protect_test_<mode>"
18914   [(set (match_operand:CCZ 0 "flags_reg_operand")
18915         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18916                      (match_operand:PTR 2 "memory_operand" "m")]
18917                     UNSPEC_SP_TEST))
18918    (clobber (match_scratch:PTR 3 "=&r"))]
18919   "TARGET_SSP_TLS_GUARD"
18920   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18921   [(set_attr "type" "multi")])
18923 (define_insn "sse4_2_crc32<mode>"
18924   [(set (match_operand:SI 0 "register_operand" "=r")
18925         (unspec:SI
18926           [(match_operand:SI 1 "register_operand" "0")
18927            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18928           UNSPEC_CRC32))]
18929   "TARGET_SSE4_2 || TARGET_CRC32"
18930   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18931   [(set_attr "type" "sselog1")
18932    (set_attr "prefix_rep" "1")
18933    (set_attr "prefix_extra" "1")
18934    (set (attr "prefix_data16")
18935      (if_then_else (match_operand:HI 2)
18936        (const_string "1")
18937        (const_string "*")))
18938    (set (attr "prefix_rex")
18939      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18940        (const_string "1")
18941        (const_string "*")))
18942    (set_attr "mode" "SI")])
18944 (define_insn "sse4_2_crc32di"
18945   [(set (match_operand:DI 0 "register_operand" "=r")
18946         (unspec:DI
18947           [(match_operand:DI 1 "register_operand" "0")
18948            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18949           UNSPEC_CRC32))]
18950   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18951   "crc32{q}\t{%2, %0|%0, %2}"
18952   [(set_attr "type" "sselog1")
18953    (set_attr "prefix_rep" "1")
18954    (set_attr "prefix_extra" "1")
18955    (set_attr "mode" "DI")])
18957 (define_insn "rdpmc"
18958   [(set (match_operand:DI 0 "register_operand" "=A")
18959         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18960                             UNSPECV_RDPMC))]
18961   "!TARGET_64BIT"
18962   "rdpmc"
18963   [(set_attr "type" "other")
18964    (set_attr "length" "2")])
18966 (define_insn "rdpmc_rex64"
18967   [(set (match_operand:DI 0 "register_operand" "=a")
18968         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18969                             UNSPECV_RDPMC))
18970    (set (match_operand:DI 1 "register_operand" "=d")
18971         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18972   "TARGET_64BIT"
18973   "rdpmc"
18974   [(set_attr "type" "other")
18975    (set_attr "length" "2")])
18977 (define_insn "rdtsc"
18978   [(set (match_operand:DI 0 "register_operand" "=A")
18979         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18980   "!TARGET_64BIT"
18981   "rdtsc"
18982   [(set_attr "type" "other")
18983    (set_attr "length" "2")])
18985 (define_insn "rdtsc_rex64"
18986   [(set (match_operand:DI 0 "register_operand" "=a")
18987         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18988    (set (match_operand:DI 1 "register_operand" "=d")
18989         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18990   "TARGET_64BIT"
18991   "rdtsc"
18992   [(set_attr "type" "other")
18993    (set_attr "length" "2")])
18995 (define_insn "rdtscp"
18996   [(set (match_operand:DI 0 "register_operand" "=A")
18997         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18998    (set (match_operand:SI 1 "register_operand" "=c")
18999         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19000   "!TARGET_64BIT"
19001   "rdtscp"
19002   [(set_attr "type" "other")
19003    (set_attr "length" "3")])
19005 (define_insn "rdtscp_rex64"
19006   [(set (match_operand:DI 0 "register_operand" "=a")
19007         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19008    (set (match_operand:DI 1 "register_operand" "=d")
19009         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19010    (set (match_operand:SI 2 "register_operand" "=c")
19011         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19012   "TARGET_64BIT"
19013   "rdtscp"
19014   [(set_attr "type" "other")
19015    (set_attr "length" "3")])
19017 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19019 ;; FXSR, XSAVE and XSAVEOPT instructions
19021 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19023 (define_insn "fxsave"
19024   [(set (match_operand:BLK 0 "memory_operand" "=m")
19025         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19026   "TARGET_FXSR"
19027   "fxsave\t%0"
19028   [(set_attr "type" "other")
19029    (set_attr "memory" "store")
19030    (set (attr "length")
19031         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19033 (define_insn "fxsave64"
19034   [(set (match_operand:BLK 0 "memory_operand" "=m")
19035         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19036   "TARGET_64BIT && TARGET_FXSR"
19037   "fxsave64\t%0"
19038   [(set_attr "type" "other")
19039    (set_attr "memory" "store")
19040    (set (attr "length")
19041         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19043 (define_insn "fxrstor"
19044   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19045                     UNSPECV_FXRSTOR)]
19046   "TARGET_FXSR"
19047   "fxrstor\t%0"
19048   [(set_attr "type" "other")
19049    (set_attr "memory" "load")
19050    (set (attr "length")
19051         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19053 (define_insn "fxrstor64"
19054   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19055                     UNSPECV_FXRSTOR64)]
19056   "TARGET_64BIT && TARGET_FXSR"
19057   "fxrstor64\t%0"
19058   [(set_attr "type" "other")
19059    (set_attr "memory" "load")
19060    (set (attr "length")
19061         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19063 (define_int_iterator ANY_XSAVE
19064         [UNSPECV_XSAVE
19065          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19066          (UNSPECV_XSAVEC "TARGET_XSAVEC")
19067          (UNSPECV_XSAVES "TARGET_XSAVES")])
19069 (define_int_iterator ANY_XSAVE64
19070         [UNSPECV_XSAVE64
19071          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19072          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19073          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19075 (define_int_attr xsave
19076         [(UNSPECV_XSAVE "xsave")
19077          (UNSPECV_XSAVE64 "xsave64")
19078          (UNSPECV_XSAVEOPT "xsaveopt")
19079          (UNSPECV_XSAVEOPT64 "xsaveopt64")
19080          (UNSPECV_XSAVEC "xsavec")
19081          (UNSPECV_XSAVEC64 "xsavec64")
19082          (UNSPECV_XSAVES "xsaves")
19083          (UNSPECV_XSAVES64 "xsaves64")])
19085 (define_int_iterator ANY_XRSTOR
19086         [UNSPECV_XRSTOR
19087          (UNSPECV_XRSTORS "TARGET_XSAVES")])
19089 (define_int_iterator ANY_XRSTOR64
19090         [UNSPECV_XRSTOR64
19091          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19093 (define_int_attr xrstor
19094         [(UNSPECV_XRSTOR "xrstor")
19095          (UNSPECV_XRSTOR64 "xrstor")
19096          (UNSPECV_XRSTORS "xrstors")
19097          (UNSPECV_XRSTORS64 "xrstors")])
19099 (define_insn "<xsave>"
19100   [(set (match_operand:BLK 0 "memory_operand" "=m")
19101         (unspec_volatile:BLK
19102          [(match_operand:DI 1 "register_operand" "A")]
19103          ANY_XSAVE))]
19104   "!TARGET_64BIT && TARGET_XSAVE"
19105   "<xsave>\t%0"
19106   [(set_attr "type" "other")
19107    (set_attr "memory" "store")
19108    (set (attr "length")
19109         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19111 (define_insn "<xsave>_rex64"
19112   [(set (match_operand:BLK 0 "memory_operand" "=m")
19113         (unspec_volatile:BLK
19114          [(match_operand:SI 1 "register_operand" "a")
19115           (match_operand:SI 2 "register_operand" "d")]
19116          ANY_XSAVE))]
19117   "TARGET_64BIT && TARGET_XSAVE"
19118   "<xsave>\t%0"
19119   [(set_attr "type" "other")
19120    (set_attr "memory" "store")
19121    (set (attr "length")
19122         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19124 (define_insn "<xsave>"
19125   [(set (match_operand:BLK 0 "memory_operand" "=m")
19126         (unspec_volatile:BLK
19127          [(match_operand:SI 1 "register_operand" "a")
19128           (match_operand:SI 2 "register_operand" "d")]
19129          ANY_XSAVE64))]
19130   "TARGET_64BIT && TARGET_XSAVE"
19131   "<xsave>\t%0"
19132   [(set_attr "type" "other")
19133    (set_attr "memory" "store")
19134    (set (attr "length")
19135         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19137 (define_insn "<xrstor>"
19138    [(unspec_volatile:BLK
19139      [(match_operand:BLK 0 "memory_operand" "m")
19140       (match_operand:DI 1 "register_operand" "A")]
19141      ANY_XRSTOR)]
19142   "!TARGET_64BIT && TARGET_XSAVE"
19143   "<xrstor>\t%0"
19144   [(set_attr "type" "other")
19145    (set_attr "memory" "load")
19146    (set (attr "length")
19147         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19149 (define_insn "<xrstor>_rex64"
19150    [(unspec_volatile:BLK
19151      [(match_operand:BLK 0 "memory_operand" "m")
19152       (match_operand:SI 1 "register_operand" "a")
19153       (match_operand:SI 2 "register_operand" "d")]
19154      ANY_XRSTOR)]
19155   "TARGET_64BIT && TARGET_XSAVE"
19156   "<xrstor>\t%0"
19157   [(set_attr "type" "other")
19158    (set_attr "memory" "load")
19159    (set (attr "length")
19160         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19162 (define_insn "<xrstor>64"
19163    [(unspec_volatile:BLK
19164      [(match_operand:BLK 0 "memory_operand" "m")
19165       (match_operand:SI 1 "register_operand" "a")
19166       (match_operand:SI 2 "register_operand" "d")]
19167      ANY_XRSTOR64)]
19168   "TARGET_64BIT && TARGET_XSAVE"
19169   "<xrstor>64\t%0"
19170   [(set_attr "type" "other")
19171    (set_attr "memory" "load")
19172    (set (attr "length")
19173         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19175 (define_insn "xsetbv"
19176   [(unspec_volatile:SI
19177          [(match_operand:SI 0 "register_operand" "c")
19178           (match_operand:DI 1 "register_operand" "A")]
19179          UNSPECV_XSETBV)]
19180   "!TARGET_64BIT && TARGET_XSAVE"
19181   "xsetbv"
19182   [(set_attr "type" "other")])
19184 (define_insn "xsetbv_rex64"
19185   [(unspec_volatile:SI
19186          [(match_operand:SI 0 "register_operand" "c")
19187           (match_operand:SI 1 "register_operand" "a")
19188           (match_operand:SI 2 "register_operand" "d")]
19189          UNSPECV_XSETBV)]
19190   "TARGET_64BIT && TARGET_XSAVE"
19191   "xsetbv"
19192   [(set_attr "type" "other")])
19194 (define_insn "xgetbv"
19195   [(set (match_operand:DI 0 "register_operand" "=A")
19196         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19197                             UNSPECV_XGETBV))]
19198   "!TARGET_64BIT && TARGET_XSAVE"
19199   "xgetbv"
19200   [(set_attr "type" "other")])
19202 (define_insn "xgetbv_rex64"
19203   [(set (match_operand:DI 0 "register_operand" "=a")
19204         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19205                             UNSPECV_XGETBV))
19206    (set (match_operand:DI 1 "register_operand" "=d")
19207         (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19208   "TARGET_64BIT && TARGET_XSAVE"
19209   "xgetbv"
19210   [(set_attr "type" "other")])
19212 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19214 ;; Floating-point instructions for atomic compound assignments
19216 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19218 ; Clobber all floating-point registers on environment save and restore
19219 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19220 (define_insn "fnstenv"
19221   [(set (match_operand:BLK 0 "memory_operand" "=m")
19222         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19223    (clobber (reg:HI FPCR_REG))
19224    (clobber (reg:XF ST0_REG))
19225    (clobber (reg:XF ST1_REG))
19226    (clobber (reg:XF ST2_REG))
19227    (clobber (reg:XF ST3_REG))
19228    (clobber (reg:XF ST4_REG))
19229    (clobber (reg:XF ST5_REG))
19230    (clobber (reg:XF ST6_REG))
19231    (clobber (reg:XF ST7_REG))]
19232   "TARGET_80387"
19233   "fnstenv\t%0"
19234   [(set_attr "type" "other")
19235    (set_attr "memory" "store")
19236    (set (attr "length")
19237         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19239 (define_insn "fldenv"
19240   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19241                     UNSPECV_FLDENV)
19242    (clobber (reg:CCFP FPSR_REG))
19243    (clobber (reg:HI FPCR_REG))
19244    (clobber (reg:XF ST0_REG))
19245    (clobber (reg:XF ST1_REG))
19246    (clobber (reg:XF ST2_REG))
19247    (clobber (reg:XF ST3_REG))
19248    (clobber (reg:XF ST4_REG))
19249    (clobber (reg:XF ST5_REG))
19250    (clobber (reg:XF ST6_REG))
19251    (clobber (reg:XF ST7_REG))]
19252   "TARGET_80387"
19253   "fldenv\t%0"
19254   [(set_attr "type" "other")
19255    (set_attr "memory" "load")
19256    (set (attr "length")
19257         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19259 (define_insn "fnstsw"
19260   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19261         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19262   "TARGET_80387"
19263   "fnstsw\t%0"
19264   [(set_attr "type" "other,other")
19265    (set_attr "memory" "none,store")
19266    (set (attr "length")
19267         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19269 (define_insn "fnclex"
19270   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19271   "TARGET_80387"
19272   "fnclex"
19273   [(set_attr "type" "other")
19274    (set_attr "memory" "none")
19275    (set_attr "length" "2")])
19277 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19279 ;; LWP instructions
19281 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19283 (define_expand "lwp_llwpcb"
19284   [(unspec_volatile [(match_operand 0 "register_operand")]
19285                     UNSPECV_LLWP_INTRINSIC)]
19286   "TARGET_LWP")
19288 (define_insn "*lwp_llwpcb<mode>1"
19289   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19290                     UNSPECV_LLWP_INTRINSIC)]
19291   "TARGET_LWP"
19292   "llwpcb\t%0"
19293   [(set_attr "type" "lwp")
19294    (set_attr "mode" "<MODE>")
19295    (set_attr "length" "5")])
19297 (define_expand "lwp_slwpcb"
19298   [(set (match_operand 0 "register_operand")
19299         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19300   "TARGET_LWP"
19302   rtx (*insn)(rtx);
19304   insn = (Pmode == DImode
19305           ? gen_lwp_slwpcbdi
19306           : gen_lwp_slwpcbsi);
19308   emit_insn (insn (operands[0]));
19309   DONE;
19312 (define_insn "lwp_slwpcb<mode>"
19313   [(set (match_operand:P 0 "register_operand" "=r")
19314         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19315   "TARGET_LWP"
19316   "slwpcb\t%0"
19317   [(set_attr "type" "lwp")
19318    (set_attr "mode" "<MODE>")
19319    (set_attr "length" "5")])
19321 (define_expand "lwp_lwpval<mode>3"
19322   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19323                      (match_operand:SI 2 "nonimmediate_operand")
19324                      (match_operand:SI 3 "const_int_operand")]
19325                     UNSPECV_LWPVAL_INTRINSIC)]
19326   "TARGET_LWP"
19327   ;; Avoid unused variable warning.
19328   "(void) operands[0];")
19330 (define_insn "*lwp_lwpval<mode>3_1"
19331   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19332                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19333                      (match_operand:SI 2 "const_int_operand" "i")]
19334                     UNSPECV_LWPVAL_INTRINSIC)]
19335   "TARGET_LWP"
19336   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19337   [(set_attr "type" "lwp")
19338    (set_attr "mode" "<MODE>")
19339    (set (attr "length")
19340         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19342 (define_expand "lwp_lwpins<mode>3"
19343   [(set (reg:CCC FLAGS_REG)
19344         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19345                               (match_operand:SI 2 "nonimmediate_operand")
19346                               (match_operand:SI 3 "const_int_operand")]
19347                              UNSPECV_LWPINS_INTRINSIC))
19348    (set (match_operand:QI 0 "nonimmediate_operand")
19349         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19350   "TARGET_LWP")
19352 (define_insn "*lwp_lwpins<mode>3_1"
19353   [(set (reg:CCC FLAGS_REG)
19354         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19355                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19356                               (match_operand:SI 2 "const_int_operand" "i")]
19357                              UNSPECV_LWPINS_INTRINSIC))]
19358   "TARGET_LWP"
19359   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19360   [(set_attr "type" "lwp")
19361    (set_attr "mode" "<MODE>")
19362    (set (attr "length")
19363         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19365 (define_int_iterator RDFSGSBASE
19366         [UNSPECV_RDFSBASE
19367          UNSPECV_RDGSBASE])
19369 (define_int_iterator WRFSGSBASE
19370         [UNSPECV_WRFSBASE
19371          UNSPECV_WRGSBASE])
19373 (define_int_attr fsgs
19374         [(UNSPECV_RDFSBASE "fs")
19375          (UNSPECV_RDGSBASE "gs")
19376          (UNSPECV_WRFSBASE "fs")
19377          (UNSPECV_WRGSBASE "gs")])
19379 (define_insn "rd<fsgs>base<mode>"
19380   [(set (match_operand:SWI48 0 "register_operand" "=r")
19381         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19382   "TARGET_64BIT && TARGET_FSGSBASE"
19383   "rd<fsgs>base\t%0"
19384   [(set_attr "type" "other")
19385    (set_attr "prefix_extra" "2")])
19387 (define_insn "wr<fsgs>base<mode>"
19388   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19389                     WRFSGSBASE)]
19390   "TARGET_64BIT && TARGET_FSGSBASE"
19391   "wr<fsgs>base\t%0"
19392   [(set_attr "type" "other")
19393    (set_attr "prefix_extra" "2")])
19395 (define_insn "rdrand<mode>_1"
19396   [(set (match_operand:SWI248 0 "register_operand" "=r")
19397         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19398    (set (reg:CCC FLAGS_REG)
19399         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19400   "TARGET_RDRND"
19401   "rdrand\t%0"
19402   [(set_attr "type" "other")
19403    (set_attr "prefix_extra" "1")])
19405 (define_insn "rdseed<mode>_1"
19406   [(set (match_operand:SWI248 0 "register_operand" "=r")
19407         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19408    (set (reg:CCC FLAGS_REG)
19409         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19410   "TARGET_RDSEED"
19411   "rdseed\t%0"
19412   [(set_attr "type" "other")
19413    (set_attr "prefix_extra" "1")])
19415 (define_expand "pause"
19416   [(set (match_dup 0)
19417         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19418   ""
19420   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19421   MEM_VOLATILE_P (operands[0]) = 1;
19424 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19425 ;; They have the same encoding.
19426 (define_insn "*pause"
19427   [(set (match_operand:BLK 0)
19428         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19429   ""
19430   "rep%; nop"
19431   [(set_attr "length" "2")
19432    (set_attr "memory" "unknown")])
19434 (define_expand "xbegin"
19435   [(set (match_operand:SI 0 "register_operand")
19436         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19437   "TARGET_RTM"
19439   rtx_code_label *label = gen_label_rtx ();
19441   /* xbegin is emitted as jump_insn, so reload won't be able
19442      to reload its operand.  Force the value into AX hard register.  */
19443   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19444   emit_move_insn (ax_reg, constm1_rtx);
19446   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19448   emit_label (label);
19449   LABEL_NUSES (label) = 1;
19451   emit_move_insn (operands[0], ax_reg);
19453   DONE;
19456 (define_insn "xbegin_1"
19457   [(set (pc)
19458         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19459                           (const_int 0))
19460                       (label_ref (match_operand 1))
19461                       (pc)))
19462    (set (match_operand:SI 0 "register_operand" "+a")
19463         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19464   "TARGET_RTM"
19465   "xbegin\t%l1"
19466   [(set_attr "type" "other")
19467    (set_attr "length" "6")])
19469 (define_insn "xend"
19470   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19471   "TARGET_RTM"
19472   "xend"
19473   [(set_attr "type" "other")
19474    (set_attr "length" "3")])
19476 (define_insn "xabort"
19477   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19478                     UNSPECV_XABORT)]
19479   "TARGET_RTM"
19480   "xabort\t%0"
19481   [(set_attr "type" "other")
19482    (set_attr "length" "3")])
19484 (define_expand "xtest"
19485   [(set (match_operand:QI 0 "register_operand")
19486         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19487   "TARGET_RTM"
19489   emit_insn (gen_xtest_1 ());
19491   ix86_expand_setcc (operands[0], NE,
19492                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19493   DONE;
19496 (define_insn "xtest_1"
19497   [(set (reg:CCZ FLAGS_REG)
19498         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19499   "TARGET_RTM"
19500   "xtest"
19501   [(set_attr "type" "other")
19502    (set_attr "length" "3")])
19504 (define_insn "clwb"
19505   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19506                    UNSPECV_CLWB)]
19507   "TARGET_CLWB"
19508   "clwb\t%a0"
19509   [(set_attr "type" "sse")
19510    (set_attr "atom_sse_attr" "fence")
19511    (set_attr "memory" "unknown")])
19513 (define_insn "clflushopt"
19514   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19515                    UNSPECV_CLFLUSHOPT)]
19516   "TARGET_CLFLUSHOPT"
19517   "clflushopt\t%a0"
19518   [(set_attr "type" "sse")
19519    (set_attr "atom_sse_attr" "fence")
19520    (set_attr "memory" "unknown")])
19522 ;; MONITORX and MWAITX
19523 (define_insn "mwaitx"
19524   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19525                      (match_operand:SI 1 "register_operand" "a")
19526                      (match_operand:SI 2 "register_operand" "b")]
19527                    UNSPECV_MWAITX)]
19528   "TARGET_MWAITX"
19529 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19530 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19531 ;; we only need to set up 32bit registers.
19532   "mwaitx"
19533   [(set_attr "length" "3")])
19535 (define_insn "monitorx_<mode>"
19536   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19537                      (match_operand:SI 1 "register_operand" "c")
19538                      (match_operand:SI 2 "register_operand" "d")]
19539                    UNSPECV_MONITORX)]
19540   "TARGET_MWAITX"
19541 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19542 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
19543 ;; zero extended to 64bit, we only need to set up 32bit registers.
19544   "%^monitorx"
19545   [(set (attr "length")
19546      (symbol_ref ("(Pmode != word_mode) + 3")))])
19548 ;; CLZERO
19549 (define_insn "clzero_<mode>"
19550   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19551                    UNSPECV_CLZERO)]
19552   "TARGET_CLZERO"
19553   "clzero"
19554   [(set_attr "length" "3")
19555   (set_attr "memory" "unknown")])
19557 ;; MPX instructions
19559 (define_expand "<mode>_mk"
19560   [(set (match_operand:BND 0 "register_operand")
19561         (unspec:BND
19562           [(mem:<bnd_ptr>
19563            (match_par_dup 3
19564              [(match_operand:<bnd_ptr> 1 "register_operand")
19565               (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19566           UNSPEC_BNDMK))]
19567   "TARGET_MPX"
19569   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19570                                                   operands[2]),
19571                                 UNSPEC_BNDMK_ADDR);
19574 (define_insn "*<mode>_mk"
19575   [(set (match_operand:BND 0 "register_operand" "=w")
19576         (unspec:BND
19577           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19578              [(unspec:<bnd_ptr>
19579                 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19580                  (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19581                 UNSPEC_BNDMK_ADDR)])]
19582           UNSPEC_BNDMK))]
19583   "TARGET_MPX"
19584   "bndmk\t{%3, %0|%0, %3}"
19585   [(set_attr "type" "mpxmk")])
19587 (define_expand "mov<mode>"
19588   [(set (match_operand:BND 0 "general_operand")
19589         (match_operand:BND 1 "general_operand"))]
19590   "TARGET_MPX"
19591   "ix86_expand_move (<MODE>mode, operands); DONE;")
19593 (define_insn "*mov<mode>_internal_mpx"
19594   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19595         (match_operand:BND 1 "general_operand" "wm,w"))]
19596   "TARGET_MPX"
19597   "bndmov\t{%1, %0|%0, %1}"
19598   [(set_attr "type" "mpxmov")])
19600 (define_expand "<mode>_<bndcheck>"
19601   [(parallel
19602      [(unspec
19603         [(match_operand:BND 0 "register_operand")
19604          (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19605       (set (match_dup 2)
19606            (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19607   "TARGET_MPX"
19609   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19610   MEM_VOLATILE_P (operands[2]) = 1;
19613 (define_insn "*<mode>_<bndcheck>"
19614   [(unspec
19615      [(match_operand:BND 0 "register_operand" "w")
19616       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19617    (set (match_operand:BLK 2 "bnd_mem_operator")
19618         (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19619   "TARGET_MPX"
19620   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19621   [(set_attr "type" "mpxchk")])
19623 (define_expand "<mode>_ldx"
19624   [(parallel
19625      [(set (match_operand:BND 0 "register_operand")
19626            (unspec:BND
19627              [(mem:<bnd_ptr>
19628                 (match_par_dup 3
19629                   [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19630                    (match_operand:<bnd_ptr> 2 "register_operand")]))]
19631              UNSPEC_BNDLDX))
19632       (use (mem:BLK (match_dup 1)))])]
19633   "TARGET_MPX"
19635   /* Avoid registers which cannot be used as index.  */
19636   if (!index_register_operand (operands[2], Pmode))
19637     operands[2] = copy_addr_to_reg (operands[2]);
19639   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19640                                                   operands[2]),
19641                                 UNSPEC_BNDLDX_ADDR);
19644 (define_insn "*<mode>_ldx"
19645   [(set (match_operand:BND 0 "register_operand" "=w")
19646         (unspec:BND
19647           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19648              [(unspec:<bnd_ptr>
19649                 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19650                  (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19651                 UNSPEC_BNDLDX_ADDR)])]
19652           UNSPEC_BNDLDX))
19653    (use (mem:BLK (match_dup 1)))]
19654   "TARGET_MPX"
19655   "bndldx\t{%3, %0|%0, %3}"
19656   [(set_attr "type" "mpxld")])
19658 (define_expand "<mode>_stx"
19659   [(parallel
19660      [(unspec
19661         [(mem:<bnd_ptr>
19662            (match_par_dup 3
19663              [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19664               (match_operand:<bnd_ptr> 1 "register_operand")]))
19665          (match_operand:BND 2 "register_operand")]
19666         UNSPEC_BNDSTX)
19667       (set (match_dup 4)
19668            (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19669   "TARGET_MPX"
19671   /* Avoid registers which cannot be used as index.  */
19672   if (!index_register_operand (operands[1], Pmode))
19673     operands[1] = copy_addr_to_reg (operands[1]);
19675   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19676                                                   operands[1]),
19677                                 UNSPEC_BNDLDX_ADDR);
19678   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19679   MEM_VOLATILE_P (operands[4]) = 1;
19682 (define_insn "*<mode>_stx"
19683   [(unspec
19684      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19685         [(unspec:<bnd_ptr>
19686            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19687             (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19688            UNSPEC_BNDLDX_ADDR)])
19689          (match_operand:BND 2 "register_operand" "w")]
19690         UNSPEC_BNDSTX)
19691    (set (match_operand:BLK 4 "bnd_mem_operator")
19692         (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19693   "TARGET_MPX"
19694   "bndstx\t{%2, %3|%3, %2}"
19695   [(set_attr "type" "mpxst")])
19697 (define_insn "move_size_reloc_<mode>"
19698   [(set (match_operand:SWI48 0 "register_operand" "=r")
19699         (unspec:SWI48
19700           [(match_operand:SWI48 1 "symbol_operand")]
19701         UNSPEC_SIZEOF))]
19702   "TARGET_MPX"
19704   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19705     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19706   else
19707     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19709   [(set_attr "type" "imov")
19710    (set_attr "mode" "<MODE>")])
19712 ;; RDPKRU and WRPKRU
19714 (define_expand "rdpkru"
19715   [(parallel
19716      [(set (match_operand:SI 0 "register_operand")
19717            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19718       (set (match_dup 2) (const_int 0))])]
19719   "TARGET_PKU"
19721   operands[1] = force_reg (SImode, const0_rtx);
19722   operands[2] = gen_reg_rtx (SImode);
19725 (define_insn "*rdpkru"
19726   [(set (match_operand:SI 0 "register_operand" "=a")
19727         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19728                             UNSPECV_PKU))
19729    (set (match_operand:SI 1 "register_operand" "=d")
19730         (const_int 0))]
19731   "TARGET_PKU"
19732   "rdpkru"
19733   [(set_attr "type" "other")])
19735 (define_expand "wrpkru"
19736   [(unspec_volatile:SI
19737      [(match_operand:SI 0 "register_operand")
19738       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19739   "TARGET_PKU"
19741   operands[1] = force_reg (SImode, const0_rtx);
19742   operands[2] = force_reg (SImode, const0_rtx);
19745 (define_insn "*wrpkru"
19746   [(unspec_volatile:SI
19747      [(match_operand:SI 0 "register_operand" "a")
19748       (match_operand:SI 1 "register_operand" "d")
19749       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19750   "TARGET_PKU"
19751   "wrpkru"
19752   [(set_attr "type" "other")])
19754 (define_insn "rdpid"
19755   [(set (match_operand:SI 0 "register_operand" "=r")
19756         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
19757   "TARGET_RDPID"
19758   "rdpid\t%0"
19759   [(set_attr "type" "other")])
19761 (include "mmx.md")
19762 (include "sse.md")
19763 (include "sync.md")