Add option for whether ceil etc. can raise "inexact", adjust x86 conditions.
[official-gcc.git] / gcc / config / i386 / i386.md
bloba32c4e204ce317dbf9cc40bb452d3e7b559db9a8
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2016 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 a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69   ;; Relocation specifiers
70   UNSPEC_GOT
71   UNSPEC_GOTOFF
72   UNSPEC_GOTPCREL
73   UNSPEC_GOTTPOFF
74   UNSPEC_TPOFF
75   UNSPEC_NTPOFF
76   UNSPEC_DTPOFF
77   UNSPEC_GOTNTPOFF
78   UNSPEC_INDNTPOFF
79   UNSPEC_PLTOFF
80   UNSPEC_MACHOPIC_OFFSET
81   UNSPEC_PCREL
82   UNSPEC_SIZEOF
84   ;; Prologue support
85   UNSPEC_STACK_ALLOC
86   UNSPEC_SET_GOT
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
91   UNSPEC_PROBE_STACK
93   ;; TLS support
94   UNSPEC_TP
95   UNSPEC_TLS_GD
96   UNSPEC_TLS_LD_BASE
97   UNSPEC_TLSDESC
98   UNSPEC_TLS_IE_SUN
100   ;; Other random patterns
101   UNSPEC_SCAS
102   UNSPEC_FNSTSW
103   UNSPEC_SAHF
104   UNSPEC_PARITY
105   UNSPEC_FSTCW
106   UNSPEC_FLDCW
107   UNSPEC_REP
108   UNSPEC_LD_MPIC        ; load_macho_picbase
109   UNSPEC_TRUNC_NOOP
110   UNSPEC_DIV_ALREADY_SPLIT
111   UNSPEC_PAUSE
112   UNSPEC_LEA_ADDR
113   UNSPEC_XBEGIN_ABORT
114   UNSPEC_STOS
115   UNSPEC_PEEPSIB
116   UNSPEC_INSN_FALSE_DEP
118   ;; For SSE/MMX support:
119   UNSPEC_FIX_NOTRUNC
120   UNSPEC_MASKMOV
121   UNSPEC_MOVMSK
122   UNSPEC_RCP
123   UNSPEC_RSQRT
124   UNSPEC_PSADBW
126   ;; Generic math support
127   UNSPEC_COPYSIGN
128   UNSPEC_IEEE_MIN       ; not commutative
129   UNSPEC_IEEE_MAX       ; not commutative
131   ;; x87 Floating point
132   UNSPEC_SIN
133   UNSPEC_COS
134   UNSPEC_FPATAN
135   UNSPEC_FYL2X
136   UNSPEC_FYL2XP1
137   UNSPEC_FRNDINT
138   UNSPEC_FIST
139   UNSPEC_F2XM1
140   UNSPEC_TAN
141   UNSPEC_FXAM
143   ;; x87 Rounding
144   UNSPEC_FRNDINT_FLOOR
145   UNSPEC_FRNDINT_CEIL
146   UNSPEC_FRNDINT_TRUNC
147   UNSPEC_FRNDINT_MASK_PM
148   UNSPEC_FIST_FLOOR
149   UNSPEC_FIST_CEIL
151   ;; x87 Double output FP
152   UNSPEC_SINCOS_COS
153   UNSPEC_SINCOS_SIN
154   UNSPEC_XTRACT_FRACT
155   UNSPEC_XTRACT_EXP
156   UNSPEC_FSCALE_FRACT
157   UNSPEC_FSCALE_EXP
158   UNSPEC_FPREM_F
159   UNSPEC_FPREM_U
160   UNSPEC_FPREM1_F
161   UNSPEC_FPREM1_U
163   UNSPEC_C2_FLAG
164   UNSPEC_FXAM_MEM
166   ;; SSP patterns
167   UNSPEC_SP_SET
168   UNSPEC_SP_TEST
169   UNSPEC_SP_TLS_SET
170   UNSPEC_SP_TLS_TEST
172   ;; For ROUND support
173   UNSPEC_ROUND
175   ;; For CRC32 support
176   UNSPEC_CRC32
178   ;; For BMI support
179   UNSPEC_BEXTR
181   ;; For BMI2 support
182   UNSPEC_PDEP
183   UNSPEC_PEXT
185   ;; For AVX512F support
186   UNSPEC_KMOV
188   UNSPEC_BNDMK
189   UNSPEC_BNDMK_ADDR
190   UNSPEC_BNDSTX
191   UNSPEC_BNDLDX
192   UNSPEC_BNDLDX_ADDR
193   UNSPEC_BNDCL
194   UNSPEC_BNDCU
195   UNSPEC_BNDCN
196   UNSPEC_MPX_FENCE
198   ;; IRET support
199   UNSPEC_INTERRUPT_RETURN
202 (define_c_enum "unspecv" [
203   UNSPECV_BLOCKAGE
204   UNSPECV_STACK_PROBE
205   UNSPECV_PROBE_STACK_RANGE
206   UNSPECV_ALIGN
207   UNSPECV_PROLOGUE_USE
208   UNSPECV_SPLIT_STACK_RETURN
209   UNSPECV_CLD
210   UNSPECV_NOPS
211   UNSPECV_RDTSC
212   UNSPECV_RDTSCP
213   UNSPECV_RDPMC
214   UNSPECV_LLWP_INTRINSIC
215   UNSPECV_SLWP_INTRINSIC
216   UNSPECV_LWPVAL_INTRINSIC
217   UNSPECV_LWPINS_INTRINSIC
218   UNSPECV_RDFSBASE
219   UNSPECV_RDGSBASE
220   UNSPECV_WRFSBASE
221   UNSPECV_WRGSBASE
222   UNSPECV_FXSAVE
223   UNSPECV_FXRSTOR
224   UNSPECV_FXSAVE64
225   UNSPECV_FXRSTOR64
226   UNSPECV_XSAVE
227   UNSPECV_XRSTOR
228   UNSPECV_XSAVE64
229   UNSPECV_XRSTOR64
230   UNSPECV_XSAVEOPT
231   UNSPECV_XSAVEOPT64
232   UNSPECV_XSAVES
233   UNSPECV_XRSTORS
234   UNSPECV_XSAVES64
235   UNSPECV_XRSTORS64
236   UNSPECV_XSAVEC
237   UNSPECV_XSAVEC64
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 PCOMMIT support
263   UNSPECV_PCOMMIT
265   ;; For CLFLUSHOPT support
266   UNSPECV_CLFLUSHOPT
268   ;; For MONITORX and MWAITX support 
269   UNSPECV_MONITORX
270   UNSPECV_MWAITX
272   ;; For CLZERO support
273   UNSPECV_CLZERO
275   ;; For RDPKRU and WRPKRU support
276   UNSPECV_PKU
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"
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" "nox64") (symbol_ref "!TARGET_64BIT")
816          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
817          (eq_attr "isa" "sse2_noavx")
818            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
819          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
820          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
821          (eq_attr "isa" "sse4_noavx")
822            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
823          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
824          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
825          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
826          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
827          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
828          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
829          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
830          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
831          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
832          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
833          (eq_attr "isa" "fma_avx512f")
834            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
835          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
836          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
837          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
838          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
839          (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
840          (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
841         ]
842         (const_int 1)))
844 (define_attr "preferred_for_size" "" (const_int 1))
845 (define_attr "preferred_for_speed" "" (const_int 1))
847 ;; Describe a user's asm statement.
848 (define_asm_attributes
849   [(set_attr "length" "128")
850    (set_attr "type" "multi")])
852 (define_code_iterator plusminus [plus minus])
854 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
856 (define_code_iterator multdiv [mult div])
858 ;; Base name for define_insn
859 (define_code_attr plusminus_insn
860   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
861    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
863 ;; Base name for insn mnemonic.
864 (define_code_attr plusminus_mnemonic
865   [(plus "add") (ss_plus "adds") (us_plus "addus")
866    (minus "sub") (ss_minus "subs") (us_minus "subus")])
867 (define_code_attr multdiv_mnemonic
868   [(mult "mul") (div "div")])
870 ;; Mark commutative operators as such in constraints.
871 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
872                         (minus "") (ss_minus "") (us_minus "")])
874 ;; Mapping of max and min
875 (define_code_iterator maxmin [smax smin umax umin])
877 ;; Mapping of signed max and min
878 (define_code_iterator smaxmin [smax smin])
880 ;; Mapping of unsigned max and min
881 (define_code_iterator umaxmin [umax umin])
883 ;; Base name for integer and FP insn mnemonic
884 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
885                               (umax "maxu") (umin "minu")])
886 (define_code_attr maxmin_float [(smax "max") (smin "min")])
888 ;; Mapping of logic operators
889 (define_code_iterator any_logic [and ior xor])
890 (define_code_iterator any_or [ior xor])
891 (define_code_iterator fpint_logic [and xor])
893 ;; Base name for insn mnemonic.
894 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
896 ;; Mapping of logic-shift operators
897 (define_code_iterator any_lshift [ashift lshiftrt])
899 ;; Mapping of shift-right operators
900 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
902 ;; Mapping of all shift operators
903 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
905 ;; Base name for define_insn
906 (define_code_attr shift_insn
907   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
909 ;; Base name for insn mnemonic.
910 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
911 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
913 ;; Mask variant left right mnemonics
914 (define_code_attr mshift [(ashift "shiftl") (lshiftrt "shiftr")])
916 ;; Mapping of rotate operators
917 (define_code_iterator any_rotate [rotate rotatert])
919 ;; Base name for define_insn
920 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
922 ;; Base name for insn mnemonic.
923 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
925 ;; Mapping of abs neg operators
926 (define_code_iterator absneg [abs neg])
928 ;; Base name for x87 insn mnemonic.
929 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
931 ;; Used in signed and unsigned widening multiplications.
932 (define_code_iterator any_extend [sign_extend zero_extend])
934 ;; Prefix for insn menmonic.
935 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
937 ;; Prefix for define_insn
938 (define_code_attr u [(sign_extend "") (zero_extend "u")])
939 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
940 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
942 ;; Used in signed and unsigned truncations.
943 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
944 ;; Instruction suffix for truncations.
945 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
947 ;; Used in signed and unsigned fix.
948 (define_code_iterator any_fix [fix unsigned_fix])
949 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
951 ;; Used in signed and unsigned float.
952 (define_code_iterator any_float [float unsigned_float])
953 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
955 ;; All integer modes.
956 (define_mode_iterator SWI1248x [QI HI SI DI])
958 ;; All integer modes with AVX512BW/DQ.
959 (define_mode_iterator SWI1248_AVX512BWDQ
960   [(QI "TARGET_AVX512DQ") HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
962 ;; All integer modes without QImode.
963 (define_mode_iterator SWI248x [HI SI DI])
965 ;; All integer modes without QImode and HImode.
966 (define_mode_iterator SWI48x [SI DI])
968 ;; All integer modes without SImode and DImode.
969 (define_mode_iterator SWI12 [QI HI])
971 ;; All integer modes without DImode.
972 (define_mode_iterator SWI124 [QI HI SI])
974 ;; All integer modes without QImode and DImode.
975 (define_mode_iterator SWI24 [HI SI])
977 ;; Single word integer modes.
978 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
980 ;; Single word integer modes without QImode.
981 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
983 ;; Single word integer modes without QImode and HImode.
984 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
986 ;; All math-dependant single and double word integer modes.
987 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
988                              (HI "TARGET_HIMODE_MATH")
989                              SI DI (TI "TARGET_64BIT")])
991 ;; Math-dependant single word integer modes.
992 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
993                             (HI "TARGET_HIMODE_MATH")
994                             SI (DI "TARGET_64BIT")])
996 ;; Math-dependant integer modes without DImode.
997 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
998                                (HI "TARGET_HIMODE_MATH")
999                                SI])
1001 ;; Math-dependant integer modes with DImode.
1002 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1003                                  (HI "TARGET_HIMODE_MATH")
1004                                  SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1006 ;; Math-dependant single word integer modes without QImode.
1007 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1008                                SI (DI "TARGET_64BIT")])
1010 ;; Double word integer modes.
1011 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1012                            (TI "TARGET_64BIT")])
1014 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
1015 ;; compile time constant, it is faster to use <MODE_SIZE> than
1016 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
1017 ;; command line options just use GET_MODE_SIZE macro.
1018 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1019                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1020                              (V16QI "16") (V32QI "32") (V64QI "64")
1021                              (V8HI "16") (V16HI "32") (V32HI "64")
1022                              (V4SI "16") (V8SI "32") (V16SI "64")
1023                              (V2DI "16") (V4DI "32") (V8DI "64")
1024                              (V1TI "16") (V2TI "32") (V4TI "64")
1025                              (V2DF "16") (V4DF "32") (V8DF "64")
1026                              (V4SF "16") (V8SF "32") (V16SF "64")])
1028 ;; Double word integer modes as mode attribute.
1029 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1030 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1032 ;; LEA mode corresponding to an integer mode
1033 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1035 ;; Half mode for double word integer modes.
1036 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1037                             (DI "TARGET_64BIT")])
1039 ;; Bound modes.
1040 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1041                            (BND64 "TARGET_LP64")])
1043 ;; Pointer mode corresponding to bound mode.
1044 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1046 ;; MPX check types
1047 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1049 ;; Check name
1050 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1051                            (UNSPEC_BNDCU "cu")
1052                            (UNSPEC_BNDCN "cn")])
1054 ;; Instruction suffix for integer modes.
1055 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1057 ;; Instruction suffix for masks.
1058 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1060 ;; Pointer size prefix for integer modes (Intel asm dialect)
1061 (define_mode_attr iptrsize [(QI "BYTE")
1062                             (HI "WORD")
1063                             (SI "DWORD")
1064                             (DI "QWORD")])
1066 ;; Register class for integer modes.
1067 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1069 ;; Immediate operand constraint for integer modes.
1070 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1072 ;; General operand constraint for word modes.
1073 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1075 ;; Immediate operand constraint for double integer modes.
1076 (define_mode_attr di [(SI "nF") (DI "Wd")])
1078 ;; Immediate operand constraint for shifts.
1079 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1081 ;; General operand predicate for integer modes.
1082 (define_mode_attr general_operand
1083         [(QI "general_operand")
1084          (HI "general_operand")
1085          (SI "x86_64_general_operand")
1086          (DI "x86_64_general_operand")
1087          (TI "x86_64_general_operand")])
1089 ;; General operand predicate for integer modes, where for TImode
1090 ;; we need both words of the operand to be general operands.
1091 (define_mode_attr general_hilo_operand
1092         [(QI "general_operand")
1093          (HI "general_operand")
1094          (SI "x86_64_general_operand")
1095          (DI "x86_64_general_operand")
1096          (TI "x86_64_hilo_general_operand")])
1098 ;; General sign extend operand predicate for integer modes,
1099 ;; which disallows VOIDmode operands and thus it is suitable
1100 ;; for use inside sign_extend.
1101 (define_mode_attr general_sext_operand
1102         [(QI "sext_operand")
1103          (HI "sext_operand")
1104          (SI "x86_64_sext_operand")
1105          (DI "x86_64_sext_operand")])
1107 ;; General sign/zero extend operand predicate for integer modes.
1108 (define_mode_attr general_szext_operand
1109         [(QI "general_operand")
1110          (HI "general_operand")
1111          (SI "x86_64_szext_general_operand")
1112          (DI "x86_64_szext_general_operand")])
1114 ;; Immediate operand predicate for integer modes.
1115 (define_mode_attr immediate_operand
1116         [(QI "immediate_operand")
1117          (HI "immediate_operand")
1118          (SI "x86_64_immediate_operand")
1119          (DI "x86_64_immediate_operand")])
1121 ;; Nonmemory operand predicate for integer modes.
1122 (define_mode_attr nonmemory_operand
1123         [(QI "nonmemory_operand")
1124          (HI "nonmemory_operand")
1125          (SI "x86_64_nonmemory_operand")
1126          (DI "x86_64_nonmemory_operand")])
1128 ;; Operand predicate for shifts.
1129 (define_mode_attr shift_operand
1130         [(QI "nonimmediate_operand")
1131          (HI "nonimmediate_operand")
1132          (SI "nonimmediate_operand")
1133          (DI "shiftdi_operand")
1134          (TI "register_operand")])
1136 ;; Operand predicate for shift argument.
1137 (define_mode_attr shift_immediate_operand
1138         [(QI "const_1_to_31_operand")
1139          (HI "const_1_to_31_operand")
1140          (SI "const_1_to_31_operand")
1141          (DI "const_1_to_63_operand")])
1143 ;; Input operand predicate for arithmetic left shifts.
1144 (define_mode_attr ashl_input_operand
1145         [(QI "nonimmediate_operand")
1146          (HI "nonimmediate_operand")
1147          (SI "nonimmediate_operand")
1148          (DI "ashldi_input_operand")
1149          (TI "reg_or_pm1_operand")])
1151 ;; SSE and x87 SFmode and DFmode floating point modes
1152 (define_mode_iterator MODEF [SF DF])
1154 ;; All x87 floating point modes
1155 (define_mode_iterator X87MODEF [SF DF XF])
1157 ;; SSE instruction suffix for various modes
1158 (define_mode_attr ssemodesuffix
1159   [(SF "ss") (DF "sd")
1160    (V16SF "ps") (V8DF "pd")
1161    (V8SF "ps") (V4DF "pd")
1162    (V4SF "ps") (V2DF "pd")
1163    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1164    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1165    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1167 ;; SSE vector suffix for floating point modes
1168 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1170 ;; SSE vector mode corresponding to a scalar mode
1171 (define_mode_attr ssevecmode
1172   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1173 (define_mode_attr ssevecmodelower
1174   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1176 ;; AVX512F vector mode corresponding to a scalar mode
1177 (define_mode_attr avx512fvecmode
1178   [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1180 ;; Instruction suffix for REX 64bit operators.
1181 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1183 ;; This mode iterator allows :P to be used for patterns that operate on
1184 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1185 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1187 ;; This mode iterator allows :W to be used for patterns that operate on
1188 ;; word_mode sized quantities.
1189 (define_mode_iterator W
1190   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1192 ;; This mode iterator allows :PTR to be used for patterns that operate on
1193 ;; ptr_mode sized quantities.
1194 (define_mode_iterator PTR
1195   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1197 ;; Scheduling descriptions
1199 (include "pentium.md")
1200 (include "ppro.md")
1201 (include "k6.md")
1202 (include "athlon.md")
1203 (include "bdver1.md")
1204 (include "bdver3.md")
1205 (include "btver2.md")
1206 (include "znver1.md")
1207 (include "geode.md")
1208 (include "atom.md")
1209 (include "slm.md")
1210 (include "core2.md")
1211 (include "haswell.md")
1214 ;; Operand and operator predicates and constraints
1216 (include "predicates.md")
1217 (include "constraints.md")
1220 ;; Compare and branch/compare and store instructions.
1222 (define_expand "cbranch<mode>4"
1223   [(set (reg:CC FLAGS_REG)
1224         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1225                     (match_operand:SDWIM 2 "<general_operand>")))
1226    (set (pc) (if_then_else
1227                (match_operator 0 "ordered_comparison_operator"
1228                 [(reg:CC FLAGS_REG) (const_int 0)])
1229                (label_ref (match_operand 3))
1230                (pc)))]
1231   ""
1233   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1234     operands[1] = force_reg (<MODE>mode, operands[1]);
1235   ix86_expand_branch (GET_CODE (operands[0]),
1236                       operands[1], operands[2], operands[3]);
1237   DONE;
1240 (define_expand "cstore<mode>4"
1241   [(set (reg:CC FLAGS_REG)
1242         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1243                     (match_operand:SWIM 3 "<general_operand>")))
1244    (set (match_operand:QI 0 "register_operand")
1245         (match_operator 1 "ordered_comparison_operator"
1246           [(reg:CC FLAGS_REG) (const_int 0)]))]
1247   ""
1249   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1250     operands[2] = force_reg (<MODE>mode, operands[2]);
1251   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1252                      operands[2], operands[3]);
1253   DONE;
1256 (define_expand "cmp<mode>_1"
1257   [(set (reg:CC FLAGS_REG)
1258         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1259                     (match_operand:SWI48 1 "<general_operand>")))])
1261 (define_insn "*cmp<mode>_ccno_1"
1262   [(set (reg FLAGS_REG)
1263         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1264                  (match_operand:SWI 1 "const0_operand")))]
1265   "ix86_match_ccmode (insn, CCNOmode)"
1266   "@
1267    test{<imodesuffix>}\t%0, %0
1268    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1269   [(set_attr "type" "test,icmp")
1270    (set_attr "length_immediate" "0,1")
1271    (set_attr "modrm_class" "op0,unknown")
1272    (set_attr "mode" "<MODE>")])
1274 (define_insn "*cmp<mode>_1"
1275   [(set (reg FLAGS_REG)
1276         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1277                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1278   "ix86_match_ccmode (insn, CCmode)"
1279   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1280   [(set_attr "type" "icmp")
1281    (set_attr "mode" "<MODE>")])
1283 (define_insn "*cmp<mode>_minus_1"
1284   [(set (reg FLAGS_REG)
1285         (compare
1286           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1287                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1288           (const_int 0)))]
1289   "ix86_match_ccmode (insn, CCGOCmode)"
1290   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1291   [(set_attr "type" "icmp")
1292    (set_attr "mode" "<MODE>")])
1294 (define_insn "*cmpqi_ext_1"
1295   [(set (reg FLAGS_REG)
1296         (compare
1297           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1298           (subreg:QI
1299             (zero_extract:SI
1300               (match_operand 1 "ext_register_operand" "Q,Q")
1301               (const_int 8)
1302               (const_int 8)) 0)))]
1303   "ix86_match_ccmode (insn, CCmode)"
1304   "cmp{b}\t{%h1, %0|%0, %h1}"
1305   [(set_attr "isa" "*,nox64")
1306    (set_attr "type" "icmp")
1307    (set_attr "mode" "QI")])
1309 (define_insn "*cmpqi_ext_2"
1310   [(set (reg FLAGS_REG)
1311         (compare
1312           (subreg:QI
1313             (zero_extract:SI
1314               (match_operand 0 "ext_register_operand" "Q")
1315               (const_int 8)
1316               (const_int 8)) 0)
1317           (match_operand:QI 1 "const0_operand")))]
1318   "ix86_match_ccmode (insn, CCNOmode)"
1319   "test{b}\t%h0, %h0"
1320   [(set_attr "type" "test")
1321    (set_attr "length_immediate" "0")
1322    (set_attr "mode" "QI")])
1324 (define_expand "cmpqi_ext_3"
1325   [(set (reg:CC FLAGS_REG)
1326         (compare:CC
1327           (subreg:QI
1328             (zero_extract:SI
1329               (match_operand 0 "ext_register_operand")
1330               (const_int 8)
1331               (const_int 8)) 0)
1332           (match_operand:QI 1 "const_int_operand")))])
1334 (define_insn "*cmpqi_ext_3"
1335   [(set (reg FLAGS_REG)
1336         (compare
1337           (subreg:QI
1338             (zero_extract:SI
1339               (match_operand 0 "ext_register_operand" "Q,Q")
1340               (const_int 8)
1341               (const_int 8)) 0)
1342           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1343   "ix86_match_ccmode (insn, CCmode)"
1344   "cmp{b}\t{%1, %h0|%h0, %1}"
1345   [(set_attr "isa" "*,nox64")
1346    (set_attr "type" "icmp")
1347    (set_attr "modrm" "1")
1348    (set_attr "mode" "QI")])
1350 (define_insn "*cmpqi_ext_4"
1351   [(set (reg FLAGS_REG)
1352         (compare
1353           (subreg:QI
1354             (zero_extract:SI
1355               (match_operand 0 "ext_register_operand" "Q")
1356               (const_int 8)
1357               (const_int 8)) 0)
1358           (subreg:QI
1359             (zero_extract:SI
1360               (match_operand 1 "ext_register_operand" "Q")
1361               (const_int 8)
1362               (const_int 8)) 0)))]
1363   "ix86_match_ccmode (insn, CCmode)"
1364   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1365   [(set_attr "type" "icmp")
1366    (set_attr "mode" "QI")])
1368 ;; These implement float point compares.
1369 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1370 ;; which would allow mix and match FP modes on the compares.  Which is what
1371 ;; the old patterns did, but with many more of them.
1373 (define_expand "cbranchxf4"
1374   [(set (reg:CC FLAGS_REG)
1375         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1376                     (match_operand:XF 2 "nonmemory_operand")))
1377    (set (pc) (if_then_else
1378               (match_operator 0 "ix86_fp_comparison_operator"
1379                [(reg:CC FLAGS_REG)
1380                 (const_int 0)])
1381               (label_ref (match_operand 3))
1382               (pc)))]
1383   "TARGET_80387"
1385   ix86_expand_branch (GET_CODE (operands[0]),
1386                       operands[1], operands[2], operands[3]);
1387   DONE;
1390 (define_expand "cstorexf4"
1391   [(set (reg:CC FLAGS_REG)
1392         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1393                     (match_operand:XF 3 "nonmemory_operand")))
1394    (set (match_operand:QI 0 "register_operand")
1395               (match_operator 1 "ix86_fp_comparison_operator"
1396                [(reg:CC FLAGS_REG)
1397                 (const_int 0)]))]
1398   "TARGET_80387"
1400   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1401                      operands[2], operands[3]);
1402   DONE;
1405 (define_expand "cbranch<mode>4"
1406   [(set (reg:CC FLAGS_REG)
1407         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1408                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1409    (set (pc) (if_then_else
1410               (match_operator 0 "ix86_fp_comparison_operator"
1411                [(reg:CC FLAGS_REG)
1412                 (const_int 0)])
1413               (label_ref (match_operand 3))
1414               (pc)))]
1415   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1417   ix86_expand_branch (GET_CODE (operands[0]),
1418                       operands[1], operands[2], operands[3]);
1419   DONE;
1422 (define_expand "cstore<mode>4"
1423   [(set (reg:CC FLAGS_REG)
1424         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1425                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1426    (set (match_operand:QI 0 "register_operand")
1427               (match_operator 1 "ix86_fp_comparison_operator"
1428                [(reg:CC FLAGS_REG)
1429                 (const_int 0)]))]
1430   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1432   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1433                      operands[2], operands[3]);
1434   DONE;
1437 (define_expand "cbranchcc4"
1438   [(set (pc) (if_then_else
1439               (match_operator 0 "comparison_operator"
1440                [(match_operand 1 "flags_reg_operand")
1441                 (match_operand 2 "const0_operand")])
1442               (label_ref (match_operand 3))
1443               (pc)))]
1444   ""
1446   ix86_expand_branch (GET_CODE (operands[0]),
1447                       operands[1], operands[2], operands[3]);
1448   DONE;
1451 (define_expand "cstorecc4"
1452   [(set (match_operand:QI 0 "register_operand")
1453               (match_operator 1 "comparison_operator"
1454                [(match_operand 2 "flags_reg_operand")
1455                 (match_operand 3 "const0_operand")]))]
1456   ""
1458   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1459                      operands[2], operands[3]);
1460   DONE;
1464 ;; FP compares, step 1:
1465 ;; Set the FP condition codes.
1467 ;; CCFPmode     compare with exceptions
1468 ;; CCFPUmode    compare with no exceptions
1470 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1471 ;; used to manage the reg stack popping would not be preserved.
1473 (define_insn "*cmp<mode>_0_i387"
1474   [(set (match_operand:HI 0 "register_operand" "=a")
1475         (unspec:HI
1476           [(compare:CCFP
1477              (match_operand:X87MODEF 1 "register_operand" "f")
1478              (match_operand:X87MODEF 2 "const0_operand"))]
1479         UNSPEC_FNSTSW))]
1480   "TARGET_80387"
1481   "* return output_fp_compare (insn, operands, false, false);"
1482   [(set_attr "type" "multi")
1483    (set_attr "unit" "i387")
1484    (set_attr "mode" "<MODE>")])
1486 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1487   [(set (reg:CCFP FLAGS_REG)
1488         (compare:CCFP
1489           (match_operand:X87MODEF 1 "register_operand" "f")
1490           (match_operand:X87MODEF 2 "const0_operand")))
1491    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1492   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1493   "#"
1494   "&& reload_completed"
1495   [(set (match_dup 0)
1496         (unspec:HI
1497           [(compare:CCFP (match_dup 1)(match_dup 2))]
1498         UNSPEC_FNSTSW))
1499    (set (reg:CC FLAGS_REG)
1500         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1501   ""
1502   [(set_attr "type" "multi")
1503    (set_attr "unit" "i387")
1504    (set_attr "mode" "<MODE>")])
1506 (define_insn "*cmpxf_i387"
1507   [(set (match_operand:HI 0 "register_operand" "=a")
1508         (unspec:HI
1509           [(compare:CCFP
1510              (match_operand:XF 1 "register_operand" "f")
1511              (match_operand:XF 2 "register_operand" "f"))]
1512           UNSPEC_FNSTSW))]
1513   "TARGET_80387"
1514   "* return output_fp_compare (insn, operands, false, false);"
1515   [(set_attr "type" "multi")
1516    (set_attr "unit" "i387")
1517    (set_attr "mode" "XF")])
1519 (define_insn_and_split "*cmpxf_cc_i387"
1520   [(set (reg:CCFP FLAGS_REG)
1521         (compare:CCFP
1522           (match_operand:XF 1 "register_operand" "f")
1523           (match_operand:XF 2 "register_operand" "f")))
1524    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1525   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1526   "#"
1527   "&& reload_completed"
1528   [(set (match_dup 0)
1529         (unspec:HI
1530           [(compare:CCFP (match_dup 1)(match_dup 2))]
1531         UNSPEC_FNSTSW))
1532    (set (reg:CC FLAGS_REG)
1533         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1534   ""
1535   [(set_attr "type" "multi")
1536    (set_attr "unit" "i387")
1537    (set_attr "mode" "XF")])
1539 (define_insn "*cmp<mode>_i387"
1540   [(set (match_operand:HI 0 "register_operand" "=a")
1541         (unspec:HI
1542           [(compare:CCFP
1543              (match_operand:MODEF 1 "register_operand" "f")
1544              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1545           UNSPEC_FNSTSW))]
1546   "TARGET_80387"
1547   "* return output_fp_compare (insn, operands, false, false);"
1548   [(set_attr "type" "multi")
1549    (set_attr "unit" "i387")
1550    (set_attr "mode" "<MODE>")])
1552 (define_insn_and_split "*cmp<mode>_cc_i387"
1553   [(set (reg:CCFP FLAGS_REG)
1554         (compare:CCFP
1555           (match_operand:MODEF 1 "register_operand" "f")
1556           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1557    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1558   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1559   "#"
1560   "&& reload_completed"
1561   [(set (match_dup 0)
1562         (unspec:HI
1563           [(compare:CCFP (match_dup 1)(match_dup 2))]
1564         UNSPEC_FNSTSW))
1565    (set (reg:CC FLAGS_REG)
1566         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1567   ""
1568   [(set_attr "type" "multi")
1569    (set_attr "unit" "i387")
1570    (set_attr "mode" "<MODE>")])
1572 (define_insn "*cmpu<mode>_i387"
1573   [(set (match_operand:HI 0 "register_operand" "=a")
1574         (unspec:HI
1575           [(compare:CCFPU
1576              (match_operand:X87MODEF 1 "register_operand" "f")
1577              (match_operand:X87MODEF 2 "register_operand" "f"))]
1578           UNSPEC_FNSTSW))]
1579   "TARGET_80387"
1580   "* return output_fp_compare (insn, operands, false, true);"
1581   [(set_attr "type" "multi")
1582    (set_attr "unit" "i387")
1583    (set_attr "mode" "<MODE>")])
1585 (define_insn_and_split "*cmpu<mode>_cc_i387"
1586   [(set (reg:CCFPU FLAGS_REG)
1587         (compare:CCFPU
1588           (match_operand:X87MODEF 1 "register_operand" "f")
1589           (match_operand:X87MODEF 2 "register_operand" "f")))
1590    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1591   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1592   "#"
1593   "&& reload_completed"
1594   [(set (match_dup 0)
1595         (unspec:HI
1596           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1597         UNSPEC_FNSTSW))
1598    (set (reg:CC FLAGS_REG)
1599         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1600   ""
1601   [(set_attr "type" "multi")
1602    (set_attr "unit" "i387")
1603    (set_attr "mode" "<MODE>")])
1605 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1606   [(set (match_operand:HI 0 "register_operand" "=a")
1607         (unspec:HI
1608           [(compare:CCFP
1609              (match_operand:X87MODEF 1 "register_operand" "f")
1610              (match_operator:X87MODEF 3 "float_operator"
1611                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1612           UNSPEC_FNSTSW))]
1613   "TARGET_80387
1614    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1615        || optimize_function_for_size_p (cfun))"
1616   "* return output_fp_compare (insn, operands, false, false);"
1617   [(set_attr "type" "multi")
1618    (set_attr "unit" "i387")
1619    (set_attr "fp_int_src" "true")
1620    (set_attr "mode" "<SWI24:MODE>")])
1622 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1623   [(set (reg:CCFP FLAGS_REG)
1624         (compare:CCFP
1625           (match_operand:X87MODEF 1 "register_operand" "f")
1626           (match_operator:X87MODEF 3 "float_operator"
1627             [(match_operand:SWI24 2 "memory_operand" "m")])))
1628    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1629   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1630    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1631        || optimize_function_for_size_p (cfun))"
1632   "#"
1633   "&& reload_completed"
1634   [(set (match_dup 0)
1635         (unspec:HI
1636           [(compare:CCFP
1637              (match_dup 1)
1638              (match_op_dup 3 [(match_dup 2)]))]
1639         UNSPEC_FNSTSW))
1640    (set (reg:CC FLAGS_REG)
1641         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1642   ""
1643   [(set_attr "type" "multi")
1644    (set_attr "unit" "i387")
1645    (set_attr "fp_int_src" "true")
1646    (set_attr "mode" "<SWI24:MODE>")])
1648 ;; FP compares, step 2
1649 ;; Move the fpsw to ax.
1651 (define_insn "x86_fnstsw_1"
1652   [(set (match_operand:HI 0 "register_operand" "=a")
1653         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1654   "TARGET_80387"
1655   "fnstsw\t%0"
1656   [(set_attr "length" "2")
1657    (set_attr "mode" "SI")
1658    (set_attr "unit" "i387")])
1660 ;; FP compares, step 3
1661 ;; Get ax into flags, general case.
1663 (define_insn "x86_sahf_1"
1664   [(set (reg:CC FLAGS_REG)
1665         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1666                    UNSPEC_SAHF))]
1667   "TARGET_SAHF"
1669 #ifndef HAVE_AS_IX86_SAHF
1670   if (TARGET_64BIT)
1671     return ASM_BYTE "0x9e";
1672   else
1673 #endif
1674   return "sahf";
1676   [(set_attr "length" "1")
1677    (set_attr "athlon_decode" "vector")
1678    (set_attr "amdfam10_decode" "direct")
1679    (set_attr "bdver1_decode" "direct")
1680    (set_attr "mode" "SI")])
1682 ;; Pentium Pro can do steps 1 through 3 in one go.
1683 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1684 ;; (these i387 instructions set flags directly)
1686 (define_mode_iterator FPCMP [CCFP CCFPU])
1687 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1689 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
1690   [(set (reg:FPCMP FLAGS_REG)
1691         (compare:FPCMP
1692           (match_operand:MODEF 0 "register_operand" "f,v")
1693           (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1694   "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1695    || (TARGET_80387 && TARGET_CMOVE)"
1696   "* return output_fp_compare (insn, operands, true,
1697                                <FPCMP:MODE>mode == CCFPUmode);"
1698   [(set_attr "type" "fcmp,ssecomi")
1699    (set_attr "prefix" "orig,maybe_vex")
1700    (set_attr "mode" "<MODEF:MODE>")
1701    (set_attr "prefix_rep" "*,0")
1702    (set (attr "prefix_data16")
1703         (cond [(eq_attr "alternative" "0")
1704                  (const_string "*")
1705                (eq_attr "mode" "DF")
1706                  (const_string "1")
1707               ]
1708               (const_string "0")))
1709    (set_attr "athlon_decode" "vector")
1710    (set_attr "amdfam10_decode" "direct")
1711    (set_attr "bdver1_decode" "double")
1712    (set_attr "znver1_decode" "double")
1713    (set (attr "enabled")
1714      (if_then_else
1715        (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1716        (if_then_else
1717          (eq_attr "alternative" "0")
1718          (symbol_ref "TARGET_MIX_SSE_I387")
1719          (symbol_ref "true"))
1720        (if_then_else
1721          (eq_attr "alternative" "0")
1722          (symbol_ref "true")
1723          (symbol_ref "false"))))])
1725 (define_insn "*cmpi<unord>xf_i387"
1726   [(set (reg:FPCMP FLAGS_REG)
1727         (compare:FPCMP
1728           (match_operand:XF 0 "register_operand" "f")
1729           (match_operand:XF 1 "register_operand" "f")))]
1730   "TARGET_80387 && TARGET_CMOVE"
1731   "* return output_fp_compare (insn, operands, true,
1732                                <MODE>mode == CCFPUmode);"
1733   [(set_attr "type" "fcmp")
1734    (set_attr "mode" "XF")
1735    (set_attr "athlon_decode" "vector")
1736    (set_attr "amdfam10_decode" "direct")
1737    (set_attr "bdver1_decode" "double")
1738    (set_attr "znver1_decode" "double")])
1740 ;; Push/pop instructions.
1742 (define_insn "*push<mode>2"
1743   [(set (match_operand:DWI 0 "push_operand" "=<")
1744         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1745   ""
1746   "#"
1747   [(set_attr "type" "multi")
1748    (set_attr "mode" "<MODE>")])
1750 (define_split
1751   [(set (match_operand:TI 0 "push_operand")
1752         (match_operand:TI 1 "general_operand"))]
1753   "TARGET_64BIT && reload_completed
1754    && !SSE_REG_P (operands[1])"
1755   [(const_int 0)]
1756   "ix86_split_long_move (operands); DONE;")
1758 (define_insn "*pushdi2_rex64"
1759   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1760         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1761   "TARGET_64BIT"
1762   "@
1763    push{q}\t%1
1764    #"
1765   [(set_attr "type" "push,multi")
1766    (set_attr "mode" "DI")])
1768 ;; Convert impossible pushes of immediate to existing instructions.
1769 ;; First try to get scratch register and go through it.  In case this
1770 ;; fails, push sign extended lower part first and then overwrite
1771 ;; upper part by 32bit move.
1772 (define_peephole2
1773   [(match_scratch:DI 2 "r")
1774    (set (match_operand:DI 0 "push_operand")
1775         (match_operand:DI 1 "immediate_operand"))]
1776   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1777    && !x86_64_immediate_operand (operands[1], DImode)"
1778   [(set (match_dup 2) (match_dup 1))
1779    (set (match_dup 0) (match_dup 2))])
1781 ;; We need to define this as both peepholer and splitter for case
1782 ;; peephole2 pass is not run.
1783 ;; "&& 1" is needed to keep it from matching the previous pattern.
1784 (define_peephole2
1785   [(set (match_operand:DI 0 "push_operand")
1786         (match_operand:DI 1 "immediate_operand"))]
1787   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1788    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1789   [(set (match_dup 0) (match_dup 1))
1790    (set (match_dup 2) (match_dup 3))]
1792   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1794   operands[1] = gen_lowpart (DImode, operands[2]);
1795   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1796                                                    GEN_INT (4)));
1799 (define_split
1800   [(set (match_operand:DI 0 "push_operand")
1801         (match_operand:DI 1 "immediate_operand"))]
1802   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1803                     ? epilogue_completed : reload_completed)
1804    && !symbolic_operand (operands[1], DImode)
1805    && !x86_64_immediate_operand (operands[1], DImode)"
1806   [(set (match_dup 0) (match_dup 1))
1807    (set (match_dup 2) (match_dup 3))]
1809   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1811   operands[1] = gen_lowpart (DImode, operands[2]);
1812   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1813                                                    GEN_INT (4)));
1816 (define_split
1817   [(set (match_operand:DI 0 "push_operand")
1818         (match_operand:DI 1 "general_operand"))]
1819   "!TARGET_64BIT && reload_completed
1820    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1821   [(const_int 0)]
1822   "ix86_split_long_move (operands); DONE;")
1824 (define_insn "*pushsi2"
1825   [(set (match_operand:SI 0 "push_operand" "=<")
1826         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1827   "!TARGET_64BIT"
1828   "push{l}\t%1"
1829   [(set_attr "type" "push")
1830    (set_attr "mode" "SI")])
1832 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1833 ;; "push a byte/word".  But actually we use pushl, which has the effect
1834 ;; of rounding the amount pushed up to a word.
1836 ;; For TARGET_64BIT we always round up to 8 bytes.
1837 (define_insn "*push<mode>2_rex64"
1838   [(set (match_operand:SWI124 0 "push_operand" "=X")
1839         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1840   "TARGET_64BIT"
1841   "push{q}\t%q1"
1842   [(set_attr "type" "push")
1843    (set_attr "mode" "DI")])
1845 (define_insn "*push<mode>2"
1846   [(set (match_operand:SWI12 0 "push_operand" "=X")
1847         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1848   "!TARGET_64BIT"
1849   "push{l}\t%k1"
1850   [(set_attr "type" "push")
1851    (set_attr "mode" "SI")])
1853 (define_insn "*push<mode>2_prologue"
1854   [(set (match_operand:W 0 "push_operand" "=<")
1855         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1856    (clobber (mem:BLK (scratch)))]
1857   ""
1858   "push{<imodesuffix>}\t%1"
1859   [(set_attr "type" "push")
1860    (set_attr "mode" "<MODE>")])
1862 (define_insn "*pop<mode>1"
1863   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1864         (match_operand:W 1 "pop_operand" ">"))]
1865   ""
1866   "pop{<imodesuffix>}\t%0"
1867   [(set_attr "type" "pop")
1868    (set_attr "mode" "<MODE>")])
1870 (define_insn "*pop<mode>1_epilogue"
1871   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1872         (match_operand:W 1 "pop_operand" ">"))
1873    (clobber (mem:BLK (scratch)))]
1874   ""
1875   "pop{<imodesuffix>}\t%0"
1876   [(set_attr "type" "pop")
1877    (set_attr "mode" "<MODE>")])
1879 (define_insn "*pushfl<mode>2"
1880   [(set (match_operand:W 0 "push_operand" "=<")
1881         (match_operand:W 1 "flags_reg_operand"))]
1882   ""
1883   "pushf{<imodesuffix>}"
1884   [(set_attr "type" "push")
1885    (set_attr "mode" "<MODE>")])
1887 (define_insn "*popfl<mode>1"
1888   [(set (match_operand:W 0 "flags_reg_operand")
1889         (match_operand:W 1 "pop_operand" ">"))]
1890   ""
1891   "popf{<imodesuffix>}"
1892   [(set_attr "type" "pop")
1893    (set_attr "mode" "<MODE>")])
1896 ;; Reload patterns to support multi-word load/store
1897 ;; with non-offsetable address.
1898 (define_expand "reload_noff_store"
1899   [(parallel [(match_operand 0 "memory_operand" "=m")
1900               (match_operand 1 "register_operand" "r")
1901               (match_operand:DI 2 "register_operand" "=&r")])]
1902   "TARGET_64BIT"
1904   rtx mem = operands[0];
1905   rtx addr = XEXP (mem, 0);
1907   emit_move_insn (operands[2], addr);
1908   mem = replace_equiv_address_nv (mem, operands[2]);
1910   emit_insn (gen_rtx_SET (mem, operands[1]));
1911   DONE;
1914 (define_expand "reload_noff_load"
1915   [(parallel [(match_operand 0 "register_operand" "=r")
1916               (match_operand 1 "memory_operand" "m")
1917               (match_operand:DI 2 "register_operand" "=r")])]
1918   "TARGET_64BIT"
1920   rtx mem = operands[1];
1921   rtx addr = XEXP (mem, 0);
1923   emit_move_insn (operands[2], addr);
1924   mem = replace_equiv_address_nv (mem, operands[2]);
1926   emit_insn (gen_rtx_SET (operands[0], mem));
1927   DONE;
1930 ;; Move instructions.
1932 (define_expand "movxi"
1933   [(set (match_operand:XI 0 "nonimmediate_operand")
1934         (match_operand:XI 1 "general_operand"))]
1935   "TARGET_AVX512F"
1936   "ix86_expand_vector_move (XImode, operands); DONE;")
1938 (define_expand "movoi"
1939   [(set (match_operand:OI 0 "nonimmediate_operand")
1940         (match_operand:OI 1 "general_operand"))]
1941   "TARGET_AVX"
1942   "ix86_expand_vector_move (OImode, operands); DONE;")
1944 (define_expand "movti"
1945   [(set (match_operand:TI 0 "nonimmediate_operand")
1946         (match_operand:TI 1 "general_operand"))]
1947   "TARGET_64BIT || TARGET_SSE"
1949   if (TARGET_64BIT)
1950     ix86_expand_move (TImode, operands);
1951   else
1952     ix86_expand_vector_move (TImode, operands);
1953   DONE;
1956 ;; This expands to what emit_move_complex would generate if we didn't
1957 ;; have a movti pattern.  Having this avoids problems with reload on
1958 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1959 ;; to have around all the time.
1960 (define_expand "movcdi"
1961   [(set (match_operand:CDI 0 "nonimmediate_operand")
1962         (match_operand:CDI 1 "general_operand"))]
1963   ""
1965   if (push_operand (operands[0], CDImode))
1966     emit_move_complex_push (CDImode, operands[0], operands[1]);
1967   else
1968     emit_move_complex_parts (operands[0], operands[1]);
1969   DONE;
1972 (define_expand "mov<mode>"
1973   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1974         (match_operand:SWI1248x 1 "general_operand"))]
1975   ""
1976   "ix86_expand_move (<MODE>mode, operands); DONE;")
1978 (define_insn "*mov<mode>_xor"
1979   [(set (match_operand:SWI48 0 "register_operand" "=r")
1980         (match_operand:SWI48 1 "const0_operand"))
1981    (clobber (reg:CC FLAGS_REG))]
1982   "reload_completed"
1983   "xor{l}\t%k0, %k0"
1984   [(set_attr "type" "alu1")
1985    (set_attr "modrm_class" "op0")
1986    (set_attr "mode" "SI")
1987    (set_attr "length_immediate" "0")])
1989 (define_insn "*mov<mode>_or"
1990   [(set (match_operand:SWI48 0 "register_operand" "=r")
1991         (match_operand:SWI48 1 "constm1_operand"))
1992    (clobber (reg:CC FLAGS_REG))]
1993   "reload_completed"
1994   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1995   [(set_attr "type" "alu1")
1996    (set_attr "mode" "<MODE>")
1997    (set_attr "length_immediate" "1")])
1999 (define_insn "*movxi_internal_avx512f"
2000   [(set (match_operand:XI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2001         (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2002   "TARGET_AVX512F
2003    && (register_operand (operands[0], XImode)
2004        || register_operand (operands[1], XImode))"
2006   switch (get_attr_type (insn))
2007     {
2008     case TYPE_SSELOG1:
2009       return standard_sse_constant_opcode (insn, operands[1]);
2011     case TYPE_SSEMOV:
2012       if (misaligned_operand (operands[0], XImode)
2013           || misaligned_operand (operands[1], XImode))
2014         return "vmovdqu32\t{%1, %0|%0, %1}";
2015       else
2016         return "vmovdqa32\t{%1, %0|%0, %1}";
2018     default:
2019       gcc_unreachable ();
2020     }
2022   [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2023    (set_attr "prefix" "evex")
2024    (set_attr "mode" "XI")])
2026 (define_insn "*movoi_internal_avx"
2027   [(set (match_operand:OI 0 "nonimmediate_operand"              "=v,v ,v ,m")
2028         (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2029   "TARGET_AVX
2030    && (register_operand (operands[0], OImode)
2031        || register_operand (operands[1], OImode))"
2033   switch (get_attr_type (insn))
2034     {
2035     case TYPE_SSELOG1:
2036       return standard_sse_constant_opcode (insn, operands[1]);
2038     case TYPE_SSEMOV:
2039       if (misaligned_operand (operands[0], OImode)
2040           || misaligned_operand (operands[1], OImode))
2041         {
2042           if (get_attr_mode (insn) == MODE_V8SF)
2043             return "vmovups\t{%1, %0|%0, %1}";
2044           else if (get_attr_mode (insn) == MODE_XI)
2045             return "vmovdqu32\t{%1, %0|%0, %1}";
2046           else
2047             return "vmovdqu\t{%1, %0|%0, %1}";
2048         }
2049       else
2050         {
2051           if (get_attr_mode (insn) == MODE_V8SF)
2052             return "vmovaps\t{%1, %0|%0, %1}";
2053           else if (get_attr_mode (insn) == MODE_XI)
2054             return "vmovdqa32\t{%1, %0|%0, %1}";
2055           else
2056             return "vmovdqa\t{%1, %0|%0, %1}";
2057         }
2059     default:
2060       gcc_unreachable ();
2061     }
2063   [(set_attr "isa" "*,avx2,*,*")
2064    (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2065    (set_attr "prefix" "vex")
2066    (set (attr "mode")
2067         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2068                     (match_operand 1 "ext_sse_reg_operand"))
2069                  (const_string "XI")
2070                (and (eq_attr "alternative" "1")
2071                     (match_test "TARGET_AVX512VL"))
2072                  (const_string "XI")
2073                (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2074                     (and (eq_attr "alternative" "3")
2075                          (match_test "TARGET_SSE_TYPELESS_STORES")))
2076                  (const_string "V8SF")
2077               ]
2078               (const_string "OI")))])
2080 (define_insn "*movti_internal"
2081   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m")
2082         (match_operand:TI 1 "general_operand"      "riFo,re,C,BC,vm,v"))]
2083   "(TARGET_64BIT
2084     && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2085    || (TARGET_SSE
2086        && nonimmediate_or_sse_const_operand (operands[1], TImode)
2087        && (register_operand (operands[0], TImode)
2088            || register_operand (operands[1], TImode)))"
2090   switch (get_attr_type (insn))
2091     {
2092     case TYPE_MULTI:
2093       return "#";
2095     case TYPE_SSELOG1:
2096       return standard_sse_constant_opcode (insn, operands[1]);
2098     case TYPE_SSEMOV:
2099       /* TDmode values are passed as TImode on the stack.  Moving them
2100          to stack may result in unaligned memory access.  */
2101       if (misaligned_operand (operands[0], TImode)
2102           || misaligned_operand (operands[1], TImode))
2103         {
2104           if (get_attr_mode (insn) == MODE_V4SF)
2105             return "%vmovups\t{%1, %0|%0, %1}";
2106           else if (get_attr_mode (insn) == MODE_XI)
2107             return "vmovdqu32\t{%1, %0|%0, %1}";
2108           else
2109             return "%vmovdqu\t{%1, %0|%0, %1}";
2110         }
2111       else
2112         {
2113           if (get_attr_mode (insn) == MODE_V4SF)
2114             return "%vmovaps\t{%1, %0|%0, %1}";
2115           else if (get_attr_mode (insn) == MODE_XI)
2116             return "vmovdqa32\t{%1, %0|%0, %1}";
2117           else
2118             return "%vmovdqa\t{%1, %0|%0, %1}";
2119         }
2121     default:
2122       gcc_unreachable ();
2123     }
2125   [(set_attr "isa" "x64,x64,*,sse2,*,*")
2126    (set_attr "type" "multi,multi,sselog1,sselog1,ssemov,ssemov")
2127    (set (attr "prefix")
2128      (if_then_else (eq_attr "type" "sselog1,ssemov")
2129        (const_string "maybe_vex")
2130        (const_string "orig")))
2131    (set (attr "mode")
2132         (cond [(eq_attr "alternative" "0,1")
2133                  (const_string "DI")
2134                (ior (match_operand 0 "ext_sse_reg_operand")
2135                     (match_operand 1 "ext_sse_reg_operand"))
2136                  (const_string "XI")
2137                (and (eq_attr "alternative" "3")
2138                     (match_test "TARGET_AVX512VL"))
2139                  (const_string "XI")
2140                (ior (not (match_test "TARGET_SSE2"))
2141                     (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2142                          (and (eq_attr "alternative" "5")
2143                               (match_test "TARGET_SSE_TYPELESS_STORES"))))
2144                  (const_string "V4SF")
2145                (match_test "TARGET_AVX")
2146                  (const_string "TI")
2147                (match_test "optimize_function_for_size_p (cfun)")
2148                  (const_string "V4SF")
2149                ]
2150                (const_string "TI")))])
2152 (define_split
2153   [(set (match_operand:TI 0 "nonimmediate_operand")
2154         (match_operand:TI 1 "general_operand"))]
2155   "reload_completed
2156    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2157   [(const_int 0)]
2158   "ix86_split_long_move (operands); DONE;")
2160 (define_insn "*movdi_internal"
2161   [(set (match_operand:DI 0 "nonimmediate_operand"
2162     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2163         (match_operand:DI 1 "general_operand"
2164     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,v,*Yj,*v,r   ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2165   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2167   switch (get_attr_type (insn))
2168     {
2169     case TYPE_MSKMOV:
2170       return "kmovq\t{%1, %0|%0, %1}";
2172     case TYPE_MULTI:
2173       return "#";
2175     case TYPE_MMX:
2176       return "pxor\t%0, %0";
2178     case TYPE_MMXMOV:
2179       /* Handle broken assemblers that require movd instead of movq.  */
2180       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2181           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2182         return "movd\t{%1, %0|%0, %1}";
2183       return "movq\t{%1, %0|%0, %1}";
2185     case TYPE_SSELOG1:
2186       if (GENERAL_REG_P (operands[0]))
2187         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2189       return standard_sse_constant_opcode (insn, operands[1]);
2191     case TYPE_SSEMOV:
2192       switch (get_attr_mode (insn))
2193         {
2194         case MODE_DI:
2195           /* Handle broken assemblers that require movd instead of movq.  */
2196           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2197               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2198             return "%vmovd\t{%1, %0|%0, %1}";
2199           return "%vmovq\t{%1, %0|%0, %1}";
2200         case MODE_TI:
2201           return "%vmovdqa\t{%1, %0|%0, %1}";
2202         case MODE_XI:
2203           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2205         case MODE_V2SF:
2206           gcc_assert (!TARGET_AVX);
2207           return "movlps\t{%1, %0|%0, %1}";
2208         case MODE_V4SF:
2209           return "%vmovaps\t{%1, %0|%0, %1}";
2211         default:
2212           gcc_unreachable ();
2213         }
2215     case TYPE_SSECVT:
2216       if (SSE_REG_P (operands[0]))
2217         return "movq2dq\t{%1, %0|%0, %1}";
2218       else
2219         return "movdq2q\t{%1, %0|%0, %1}";
2221     case TYPE_LEA:
2222       return "lea{q}\t{%E1, %0|%0, %E1}";
2224     case TYPE_IMOV:
2225       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2226       if (get_attr_mode (insn) == MODE_SI)
2227         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2228       else if (which_alternative == 4)
2229         return "movabs{q}\t{%1, %0|%0, %1}";
2230       else if (ix86_use_lea_for_mov (insn, operands))
2231         return "lea{q}\t{%E1, %0|%0, %E1}";
2232       else
2233         return "mov{q}\t{%1, %0|%0, %1}";
2235     default:
2236       gcc_unreachable ();
2237     }
2239   [(set (attr "isa")
2240      (cond [(eq_attr "alternative" "0,1")
2241               (const_string "nox64")
2242             (eq_attr "alternative" "2,3,4,5,10,11,17,19,22,24")
2243               (const_string "x64")
2244             (eq_attr "alternative" "18")
2245               (const_string "x64_sse4")
2246            ]
2247            (const_string "*")))
2248    (set (attr "type")
2249      (cond [(eq_attr "alternative" "0,1")
2250               (const_string "multi")
2251             (eq_attr "alternative" "6")
2252               (const_string "mmx")
2253             (eq_attr "alternative" "7,8,9,10,11")
2254               (const_string "mmxmov")
2255             (eq_attr "alternative" "12,18")
2256               (const_string "sselog1")
2257             (eq_attr "alternative" "13,14,15,16,17,19")
2258               (const_string "ssemov")
2259             (eq_attr "alternative" "20,21")
2260               (const_string "ssecvt")
2261             (eq_attr "alternative" "22,23,24,25")
2262               (const_string "mskmov")
2263             (and (match_operand 0 "register_operand")
2264                  (match_operand 1 "pic_32bit_operand"))
2265               (const_string "lea")
2266            ]
2267            (const_string "imov")))
2268    (set (attr "modrm")
2269      (if_then_else
2270        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2271          (const_string "0")
2272          (const_string "*")))
2273    (set (attr "length_immediate")
2274      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2275               (const_string "8")
2276             (eq_attr "alternative" "18")
2277               (const_string "1")
2278            ]
2279            (const_string "*")))
2280    (set (attr "prefix_rex")
2281      (if_then_else (eq_attr "alternative" "10,11,17,18,19")
2282        (const_string "1")
2283        (const_string "*")))
2284    (set (attr "prefix_extra")
2285      (if_then_else (eq_attr "alternative" "18")
2286        (const_string "1")
2287        (const_string "*")))
2288    (set (attr "prefix")
2289      (if_then_else (eq_attr "type" "sselog1,ssemov")
2290        (const_string "maybe_vex")
2291        (const_string "orig")))
2292    (set (attr "prefix_data16")
2293      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2294        (const_string "1")
2295        (const_string "*")))
2296    (set (attr "mode")
2297      (cond [(eq_attr "alternative" "2")
2298               (const_string "SI")
2299             (eq_attr "alternative" "12,13")
2300               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2301                           (match_operand 1 "ext_sse_reg_operand"))
2302                        (const_string "XI")
2303                      (ior (not (match_test "TARGET_SSE2"))
2304                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2305                        (const_string "V4SF")
2306                      (match_test "TARGET_AVX")
2307                        (const_string "TI")
2308                      (match_test "optimize_function_for_size_p (cfun)")
2309                        (const_string "V4SF")
2310                     ]
2311                     (const_string "TI"))
2313             (and (eq_attr "alternative" "14,15,16")
2314                  (not (match_test "TARGET_SSE2")))
2315               (const_string "V2SF")
2316             (eq_attr "alternative" "18")
2317               (const_string "TI")
2318            ]
2319            (const_string "DI")))
2320    (set (attr "enabled")
2321      (cond [(eq_attr "alternative" "15")
2322               (if_then_else
2323                 (match_test "TARGET_STV && TARGET_SSE2")
2324                 (symbol_ref "false")
2325                 (const_string "*"))
2326             (eq_attr "alternative" "16")
2327               (if_then_else
2328                 (match_test "TARGET_STV && TARGET_SSE2")
2329                 (symbol_ref "true")
2330                 (symbol_ref "false"))
2331            ]
2332            (const_string "*")))])
2334 (define_split
2335   [(set (match_operand:DI 0 "nonimmediate_operand")
2336         (match_operand:DI 1 "general_operand"))]
2337   "!TARGET_64BIT && reload_completed
2338    && !(MMX_REG_P (operands[0])
2339         || SSE_REG_P (operands[0])
2340         || MASK_REG_P (operands[0]))
2341    && !(MMX_REG_P (operands[1])
2342         || SSE_REG_P (operands[1])
2343         || MASK_REG_P (operands[1]))"
2344   [(const_int 0)]
2345   "ix86_split_long_move (operands); DONE;")
2347 (define_insn "*movsi_internal"
2348   [(set (match_operand:SI 0 "nonimmediate_operand"
2349                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2350         (match_operand:SI 1 "general_operand"
2351                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2352   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2354   switch (get_attr_type (insn))
2355     {
2356     case TYPE_SSELOG1:
2357       if (GENERAL_REG_P (operands[0]))
2358         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2360       return standard_sse_constant_opcode (insn, operands[1]);
2362     case TYPE_MSKMOV:
2363       return "kmovd\t{%1, %0|%0, %1}";
2365     case TYPE_SSEMOV:
2366       switch (get_attr_mode (insn))
2367         {
2368         case MODE_SI:
2369           return "%vmovd\t{%1, %0|%0, %1}";
2370         case MODE_TI:
2371           return "%vmovdqa\t{%1, %0|%0, %1}";
2372         case MODE_XI:
2373           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2375         case MODE_V4SF:
2376           return "%vmovaps\t{%1, %0|%0, %1}";
2378         case MODE_SF:
2379           gcc_assert (!TARGET_AVX);
2380           return "movss\t{%1, %0|%0, %1}";
2382         default:
2383           gcc_unreachable ();
2384         }
2386     case TYPE_MMX:
2387       return "pxor\t%0, %0";
2389     case TYPE_MMXMOV:
2390       switch (get_attr_mode (insn))
2391         {
2392         case MODE_DI:
2393           return "movq\t{%1, %0|%0, %1}";
2394         case MODE_SI:
2395           return "movd\t{%1, %0|%0, %1}";
2397         default:
2398           gcc_unreachable ();
2399         }
2401     case TYPE_LEA:
2402       return "lea{l}\t{%E1, %0|%0, %E1}";
2404     case TYPE_IMOV:
2405       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2406       if (ix86_use_lea_for_mov (insn, operands))
2407         return "lea{l}\t{%E1, %0|%0, %E1}";
2408       else
2409         return "mov{l}\t{%1, %0|%0, %1}";
2411     default:
2412       gcc_unreachable ();
2413     }
2415   [(set (attr "isa")
2416      (if_then_else (eq_attr "alternative" "11")
2417        (const_string "sse4")
2418        (const_string "*")))
2419    (set (attr "type")
2420      (cond [(eq_attr "alternative" "2")
2421               (const_string "mmx")
2422             (eq_attr "alternative" "3,4,5")
2423               (const_string "mmxmov")
2424             (eq_attr "alternative" "6,11")
2425               (const_string "sselog1")
2426             (eq_attr "alternative" "7,8,9,10,12")
2427               (const_string "ssemov")
2428             (eq_attr "alternative" "13,14")
2429               (const_string "mskmov")
2430             (and (match_operand 0 "register_operand")
2431                  (match_operand 1 "pic_32bit_operand"))
2432               (const_string "lea")
2433            ]
2434            (const_string "imov")))
2435    (set (attr "length_immediate")
2436      (if_then_else (eq_attr "alternative" "11")
2437        (const_string "1")
2438        (const_string "*")))
2439    (set (attr "prefix_extra")
2440      (if_then_else (eq_attr "alternative" "11")
2441        (const_string "1")
2442        (const_string "*")))
2443    (set (attr "prefix")
2444      (if_then_else (eq_attr "type" "sselog1,ssemov")
2445        (const_string "maybe_vex")
2446        (const_string "orig")))
2447    (set (attr "prefix_data16")
2448      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2449        (const_string "1")
2450        (const_string "*")))
2451    (set (attr "mode")
2452      (cond [(eq_attr "alternative" "2,3")
2453               (const_string "DI")
2454             (eq_attr "alternative" "6,7")
2455               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2456                           (match_operand 1 "ext_sse_reg_operand"))
2457                        (const_string "XI")
2458                      (ior (not (match_test "TARGET_SSE2"))
2459                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2460                        (const_string "V4SF")
2461                      (match_test "TARGET_AVX")
2462                        (const_string "TI")
2463                      (match_test "optimize_function_for_size_p (cfun)")
2464                        (const_string "V4SF")
2465                     ]
2466                     (const_string "TI"))
2468             (and (eq_attr "alternative" "8,9")
2469                  (not (match_test "TARGET_SSE2")))
2470               (const_string "SF")
2471             (eq_attr "alternative" "11")
2472               (const_string "TI")
2473            ]
2474            (const_string "SI")))])
2476 (define_insn "kmovw"
2477   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2478         (unspec:HI
2479           [(match_operand:HI 1 "nonimmediate_operand" "r,km")]
2480           UNSPEC_KMOV))]
2481   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2482   "@
2483    kmovw\t{%k1, %0|%0, %k1}
2484    kmovw\t{%1, %0|%0, %1}";
2485   [(set_attr "mode" "HI")
2486    (set_attr "type" "mskmov")
2487    (set_attr "prefix" "vex")])
2490 (define_insn "*movhi_internal"
2491   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m")
2492         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,r,km,k,k"))]
2493   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2495   switch (get_attr_type (insn))
2496     {
2497     case TYPE_IMOVX:
2498       /* movzwl is faster than movw on p2 due to partial word stalls,
2499          though not as fast as an aligned movl.  */
2500       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2502     case TYPE_MSKMOV:
2503       switch (which_alternative)
2504         {
2505         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2506         case 5: /* FALLTHRU */
2507         case 7: return "kmovw\t{%1, %0|%0, %1}";
2508         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2509         default: gcc_unreachable ();
2510         }
2512     default:
2513       if (get_attr_mode (insn) == MODE_SI)
2514         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2515       else
2516         return "mov{w}\t{%1, %0|%0, %1}";
2517     }
2519   [(set (attr "type")
2520      (cond [(eq_attr "alternative" "4,5,6,7")
2521               (const_string "mskmov")
2522             (match_test "optimize_function_for_size_p (cfun)")
2523               (const_string "imov")
2524             (and (eq_attr "alternative" "0")
2525                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2526                       (not (match_test "TARGET_HIMODE_MATH"))))
2527               (const_string "imov")
2528             (and (eq_attr "alternative" "1,2")
2529                  (match_operand:HI 1 "aligned_operand"))
2530               (const_string "imov")
2531             (and (match_test "TARGET_MOVX")
2532                  (eq_attr "alternative" "0,2"))
2533               (const_string "imovx")
2534            ]
2535            (const_string "imov")))
2536     (set (attr "prefix")
2537       (if_then_else (eq_attr "alternative" "4,5,6,7")
2538         (const_string "vex")
2539         (const_string "orig")))
2540     (set (attr "mode")
2541       (cond [(eq_attr "type" "imovx")
2542                (const_string "SI")
2543              (and (eq_attr "alternative" "1,2")
2544                   (match_operand:HI 1 "aligned_operand"))
2545                (const_string "SI")
2546              (and (eq_attr "alternative" "0")
2547                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2548                        (not (match_test "TARGET_HIMODE_MATH"))))
2549                (const_string "SI")
2550             ]
2551             (const_string "HI")))])
2553 ;; Situation is quite tricky about when to choose full sized (SImode) move
2554 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2555 ;; partial register dependency machines (such as AMD Athlon), where QImode
2556 ;; moves issue extra dependency and for partial register stalls machines
2557 ;; that don't use QImode patterns (and QImode move cause stall on the next
2558 ;; instruction).
2560 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2561 ;; register stall machines with, where we use QImode instructions, since
2562 ;; partial register stall can be caused there.  Then we use movzx.
2564 (define_insn "*movqi_internal"
2565   [(set (match_operand:QI 0 "nonimmediate_operand"
2566                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2567         (match_operand:QI 1 "general_operand"
2568                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2569   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2571   switch (get_attr_type (insn))
2572     {
2573     case TYPE_IMOVX:
2574       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2575       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2577     case TYPE_MSKMOV:
2578       switch (which_alternative)
2579         {
2580         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2581                                        : "kmovw\t{%k1, %0|%0, %k1}";
2582         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2583                                        : "kmovw\t{%1, %0|%0, %1}";
2584         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2585                                        : "kmovw\t{%1, %k0|%k0, %1}";
2586         case 10:
2587         case 11:
2588           gcc_assert (TARGET_AVX512DQ);
2589           return "kmovb\t{%1, %0|%0, %1}";
2590         default: gcc_unreachable ();
2591         }
2593     default:
2594       if (get_attr_mode (insn) == MODE_SI)
2595         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2596       else
2597         return "mov{b}\t{%1, %0|%0, %1}";
2598     }
2600   [(set (attr "isa")
2601      (if_then_else (eq_attr "alternative" "10,11")
2602        (const_string "avx512dq")
2603        (const_string "*")))
2604    (set (attr "type")
2605      (cond [(eq_attr "alternative" "7,8,9,10,11")
2606               (const_string "mskmov")
2607             (and (eq_attr "alternative" "5")
2608                  (not (match_operand:QI 1 "aligned_operand")))
2609               (const_string "imovx")
2610             (match_test "optimize_function_for_size_p (cfun)")
2611               (const_string "imov")
2612             (and (eq_attr "alternative" "3")
2613                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2614                       (not (match_test "TARGET_QIMODE_MATH"))))
2615               (const_string "imov")
2616             (eq_attr "alternative" "3,5")
2617               (const_string "imovx")
2618             (and (match_test "TARGET_MOVX")
2619                  (eq_attr "alternative" "2"))
2620               (const_string "imovx")
2621            ]
2622            (const_string "imov")))
2623    (set (attr "prefix")
2624      (if_then_else (eq_attr "alternative" "7,8,9")
2625        (const_string "vex")
2626        (const_string "orig")))
2627    (set (attr "mode")
2628       (cond [(eq_attr "alternative" "3,4,5")
2629                (const_string "SI")
2630              (eq_attr "alternative" "6")
2631                (const_string "QI")
2632              (eq_attr "type" "imovx")
2633                (const_string "SI")
2634              (and (eq_attr "type" "imov")
2635                   (and (eq_attr "alternative" "0,1")
2636                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2637                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2638                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2639                (const_string "SI")
2640              ;; Avoid partial register stalls when not using QImode arithmetic
2641              (and (eq_attr "type" "imov")
2642                   (and (eq_attr "alternative" "0,1")
2643                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2644                             (not (match_test "TARGET_QIMODE_MATH")))))
2645                (const_string "SI")
2646            ]
2647            (const_string "QI")))])
2649 ;; Stores and loads of ax to arbitrary constant address.
2650 ;; We fake an second form of instruction to force reload to load address
2651 ;; into register when rax is not available
2652 (define_insn "*movabs<mode>_1"
2653   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2654         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2655   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2657   /* Recover the full memory rtx.  */
2658   operands[0] = SET_DEST (PATTERN (insn));
2659   switch (which_alternative)
2660     {
2661     case 0:
2662       return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2663     case 1:
2664       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2665     default:
2666       gcc_unreachable ();
2667     }
2669   [(set_attr "type" "imov")
2670    (set_attr "modrm" "0,*")
2671    (set_attr "length_address" "8,0")
2672    (set_attr "length_immediate" "0,*")
2673    (set_attr "memory" "store")
2674    (set_attr "mode" "<MODE>")])
2676 (define_insn "*movabs<mode>_2"
2677   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2678         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2679   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2681   /* Recover the full memory rtx.  */
2682   operands[1] = SET_SRC (PATTERN (insn));
2683   switch (which_alternative)
2684     {
2685     case 0:
2686       return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
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" "load")
2698    (set_attr "mode" "<MODE>")])
2700 (define_insn "*swap<mode>"
2701   [(set (match_operand:SWI48 0 "register_operand" "+r")
2702         (match_operand:SWI48 1 "register_operand" "+r"))
2703    (set (match_dup 1)
2704         (match_dup 0))]
2705   ""
2706   "xchg{<imodesuffix>}\t%1, %0"
2707   [(set_attr "type" "imov")
2708    (set_attr "mode" "<MODE>")
2709    (set_attr "pent_pair" "np")
2710    (set_attr "athlon_decode" "vector")
2711    (set_attr "amdfam10_decode" "double")
2712    (set_attr "bdver1_decode" "double")])
2714 (define_insn "*swap<mode>"
2715   [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2716         (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2717    (set (match_dup 1)
2718         (match_dup 0))]
2719   ""
2720   "@
2721    xchg{<imodesuffix>}\t%1, %0
2722    xchg{l}\t%k1, %k0"
2723   [(set_attr "type" "imov")
2724    (set_attr "mode" "<MODE>,SI")
2725    (set (attr "preferred_for_size")
2726      (cond [(eq_attr "alternative" "0")
2727               (symbol_ref "false")]
2728            (symbol_ref "true")))
2729    ;; Potential partial reg stall on alternative 1.
2730    (set (attr "preferred_for_speed")
2731      (cond [(eq_attr "alternative" "1")
2732               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2733            (symbol_ref "true")))
2734    (set_attr "pent_pair" "np")
2735    (set_attr "athlon_decode" "vector")
2736    (set_attr "amdfam10_decode" "double")
2737    (set_attr "bdver1_decode" "double")])
2739 (define_expand "movstrict<mode>"
2740   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2741         (match_operand:SWI12 1 "general_operand"))]
2742   ""
2744   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2745     FAIL;
2746   if (SUBREG_P (operands[0])
2747       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2748     FAIL;
2749   /* Don't generate memory->memory moves, go through a register */
2750   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2751     operands[1] = force_reg (<MODE>mode, operands[1]);
2754 (define_insn "*movstrict<mode>_1"
2755   [(set (strict_low_part
2756           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2757         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2758   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2759    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2760   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2761   [(set_attr "type" "imov")
2762    (set_attr "mode" "<MODE>")])
2764 (define_insn "*movstrict<mode>_xor"
2765   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2766         (match_operand:SWI12 1 "const0_operand"))
2767    (clobber (reg:CC FLAGS_REG))]
2768   "reload_completed"
2769   "xor{<imodesuffix>}\t%0, %0"
2770   [(set_attr "type" "alu1")
2771    (set_attr "modrm_class" "op0")
2772    (set_attr "mode" "<MODE>")
2773    (set_attr "length_immediate" "0")])
2775 (define_expand "extv<mode>"
2776   [(set (match_operand:SWI24 0 "register_operand")
2777         (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2778                             (match_operand:SI 2 "const_int_operand")
2779                             (match_operand:SI 3 "const_int_operand")))]
2780   ""
2782   /* Handle extractions from %ah et al.  */
2783   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2784     FAIL;
2786   if (! ext_register_operand (operands[1], VOIDmode))
2787     operands[1] = copy_to_reg (operands[1]);
2790 (define_insn "*extv<mode>"
2791   [(set (match_operand:SWI24 0 "register_operand" "=R")
2792         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2793                             (const_int 8)
2794                             (const_int 8)))]
2795   ""
2796   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2797   [(set_attr "type" "imovx")
2798    (set_attr "mode" "SI")])
2800 (define_insn "*extvqi"
2801   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2802         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2803                          (const_int 8)
2804                          (const_int 8)))]
2805   ""
2807   switch (get_attr_type (insn))
2808     {
2809     case TYPE_IMOVX:
2810       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2811     default:
2812       return "mov{b}\t{%h1, %0|%0, %h1}";
2813     }
2815   [(set_attr "isa" "*,*,nox64")
2816    (set (attr "type")
2817      (if_then_else (and (match_operand:QI 0 "register_operand")
2818                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2819                              (match_test "TARGET_MOVX")))
2820         (const_string "imovx")
2821         (const_string "imov")))
2822    (set (attr "mode")
2823      (if_then_else (eq_attr "type" "imovx")
2824         (const_string "SI")
2825         (const_string "QI")))])
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   if (! ext_register_operand (operands[1], VOIDmode))
2842     operands[1] = copy_to_reg (operands[1]);
2845 (define_insn "*extzv<mode>"
2846   [(set (match_operand:SWI248 0 "register_operand" "=R")
2847         (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2848                              (const_int 8)
2849                              (const_int 8)))]
2850   ""
2851   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2852   [(set_attr "type" "imovx")
2853    (set_attr "mode" "SI")])
2855 (define_insn "*extzvqi"
2856   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2857         (subreg:QI
2858           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2859                            (const_int 8)
2860                            (const_int 8)) 0))]
2861   ""
2863   switch (get_attr_type (insn))
2864     {
2865     case TYPE_IMOVX:
2866       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2867     default:
2868       return "mov{b}\t{%h1, %0|%0, %h1}";
2869     }
2871   [(set_attr "isa" "*,*,nox64")
2872    (set (attr "type")
2873      (if_then_else (and (match_operand:QI 0 "register_operand")
2874                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2875                              (match_test "TARGET_MOVX")))
2876         (const_string "imovx")
2877         (const_string "imov")))
2878    (set (attr "mode")
2879      (if_then_else (eq_attr "type" "imovx")
2880         (const_string "SI")
2881         (const_string "QI")))])
2883 (define_expand "insv<mode>"
2884   [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2885                              (match_operand:SI 1 "const_int_operand")
2886                              (match_operand:SI 2 "const_int_operand"))
2887         (match_operand:SWI248 3 "register_operand"))]
2888   ""
2890   rtx dst;
2892   if (ix86_expand_pinsr (operands))
2893     DONE;
2895   /* Handle insertions to %ah et al.  */
2896   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2897     FAIL;
2899   dst = operands[0];
2900   
2901   if (!ext_register_operand (dst, VOIDmode))
2902     dst = copy_to_reg (dst);
2904   emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2906   /* Fix up the destination if needed.  */
2907   if (dst != operands[0])
2908     emit_move_insn (operands[0], dst);
2910   DONE;
2913 (define_insn "insv<mode>_1"
2914   [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2915                              (const_int 8)
2916                              (const_int 8))
2917         (match_operand:SWI248 1 "general_x64nomem_operand" "Qn,m"))]
2918   ""
2920   if (CONST_INT_P (operands[1]))
2921     operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2922   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2924   [(set_attr "isa" "*,nox64")
2925    (set_attr "type" "imov")
2926    (set_attr "mode" "QI")])
2928 (define_insn "*insvqi"
2929   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2930                          (const_int 8)
2931                          (const_int 8))
2932         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2933                      (const_int 8)))]
2934   ""
2935   "mov{b}\t{%h1, %h0|%h0, %h1}"
2936   [(set_attr "type" "imov")
2937    (set_attr "mode" "QI")])
2939 ;; Floating point push instructions.
2941 (define_insn "*pushtf"
2942   [(set (match_operand:TF 0 "push_operand" "=<,<")
2943         (match_operand:TF 1 "general_no_elim_operand" "v,*roF"))]
2944   "TARGET_64BIT || TARGET_SSE"
2946   /* This insn should be already split before reg-stack.  */
2947   gcc_unreachable ();
2949   [(set_attr "isa" "*,x64")
2950    (set_attr "type" "multi")
2951    (set_attr "unit" "sse,*")
2952    (set_attr "mode" "TF,DI")])
2954 ;; %%% Kill this when call knows how to work this out.
2955 (define_split
2956   [(set (match_operand:TF 0 "push_operand")
2957         (match_operand:TF 1 "sse_reg_operand"))]
2958   "TARGET_SSE && reload_completed"
2959   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2960    (set (match_dup 0) (match_dup 1))]
2962   /* Preserve memory attributes. */
2963   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2966 (define_insn "*pushxf"
2967   [(set (match_operand:XF 0 "push_operand" "=<,<,<,<")
2968         (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))]
2969   ""
2971   /* This insn should be already split before reg-stack.  */
2972   gcc_unreachable ();
2974   [(set_attr "type" "multi")
2975    (set_attr "unit" "i387,*,*,*")
2976    (set (attr "mode")
2977         (cond [(eq_attr "alternative" "1,2,3")
2978                  (if_then_else (match_test "TARGET_64BIT")
2979                    (const_string "DI")
2980                    (const_string "SI"))
2981               ]
2982               (const_string "XF")))
2983    (set (attr "preferred_for_size")
2984      (cond [(eq_attr "alternative" "1")
2985               (symbol_ref "false")]
2986            (symbol_ref "true")))])
2988 ;; %%% Kill this when call knows how to work this out.
2989 (define_split
2990   [(set (match_operand:XF 0 "push_operand")
2991         (match_operand:XF 1 "fp_register_operand"))]
2992   "reload_completed"
2993   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2994    (set (match_dup 0) (match_dup 1))]
2996   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2997   /* Preserve memory attributes. */
2998   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3001 (define_insn "*pushdf"
3002   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3003         (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))]
3004   ""
3006   /* This insn should be already split before reg-stack.  */
3007   gcc_unreachable ();
3009   [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3010    (set_attr "type" "multi")
3011    (set_attr "unit" "i387,*,*,*,*,sse")
3012    (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3013    (set (attr "preferred_for_size")
3014      (cond [(eq_attr "alternative" "1")
3015               (symbol_ref "false")]
3016            (symbol_ref "true")))
3017    (set (attr "preferred_for_speed")
3018      (cond [(eq_attr "alternative" "1")
3019               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3020            (symbol_ref "true")))])
3021    
3022 ;; %%% Kill this when call knows how to work this out.
3023 (define_split
3024   [(set (match_operand:DF 0 "push_operand")
3025         (match_operand:DF 1 "any_fp_register_operand"))]
3026   "reload_completed"
3027   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3028    (set (match_dup 0) (match_dup 1))]
3030   /* Preserve memory attributes. */
3031   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3034 (define_insn "*pushsf_rex64"
3035   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3036         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3037   "TARGET_64BIT"
3039   /* Anything else should be already split before reg-stack.  */
3040   gcc_assert (which_alternative == 1);
3041   return "push{q}\t%q1";
3043   [(set_attr "type" "multi,push,multi")
3044    (set_attr "unit" "i387,*,*")
3045    (set_attr "mode" "SF,DI,SF")])
3047 (define_insn "*pushsf"
3048   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3049         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3050   "!TARGET_64BIT"
3052   /* Anything else should be already split before reg-stack.  */
3053   gcc_assert (which_alternative == 1);
3054   return "push{l}\t%1";
3056   [(set_attr "type" "multi,push,multi")
3057    (set_attr "unit" "i387,*,*")
3058    (set_attr "mode" "SF,SI,SF")])
3060 ;; %%% Kill this when call knows how to work this out.
3061 (define_split
3062   [(set (match_operand:SF 0 "push_operand")
3063         (match_operand:SF 1 "any_fp_register_operand"))]
3064   "reload_completed"
3065   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3066    (set (match_dup 0) (match_dup 1))]
3068   rtx op = XEXP (operands[0], 0);
3069   if (GET_CODE (op) == PRE_DEC)
3070     {
3071       gcc_assert (!TARGET_64BIT);
3072       op = GEN_INT (-4);
3073     }
3074   else
3075     {
3076       op = XEXP (XEXP (op, 1), 1);
3077       gcc_assert (CONST_INT_P (op));
3078     }
3079   operands[2] = op;
3080   /* Preserve memory attributes. */
3081   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3084 (define_split
3085   [(set (match_operand:SF 0 "push_operand")
3086         (match_operand:SF 1 "memory_operand"))]
3087   "reload_completed
3088    && find_constant_src (insn)"
3089   [(set (match_dup 0) (match_dup 2))]
3090   "operands[2] = find_constant_src (curr_insn);")
3092 (define_split
3093   [(set (match_operand 0 "push_operand")
3094         (match_operand 1 "general_operand"))]
3095   "reload_completed
3096    && (GET_MODE (operands[0]) == TFmode
3097        || GET_MODE (operands[0]) == XFmode
3098        || GET_MODE (operands[0]) == DFmode)
3099    && !ANY_FP_REG_P (operands[1])"
3100   [(const_int 0)]
3101   "ix86_split_long_move (operands); DONE;")
3103 ;; Floating point move instructions.
3105 (define_expand "movtf"
3106   [(set (match_operand:TF 0 "nonimmediate_operand")
3107         (match_operand:TF 1 "nonimmediate_operand"))]
3108   "TARGET_64BIT || TARGET_SSE"
3109   "ix86_expand_move (TFmode, operands); DONE;")
3111 (define_expand "mov<mode>"
3112   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3113         (match_operand:X87MODEF 1 "general_operand"))]
3114   ""
3115   "ix86_expand_move (<MODE>mode, operands); DONE;")
3117 (define_insn "*movtf_internal"
3118   [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3119         (match_operand:TF 1 "general_operand"      "C ,vm,v,*roF,*rC"))]
3120   "(TARGET_64BIT || TARGET_SSE)
3121    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3122    && (!can_create_pseudo_p ()
3123        || !CONST_DOUBLE_P (operands[1])
3124        || ((optimize_function_for_size_p (cfun)
3125             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3126            && standard_sse_constant_p (operands[1], TFmode) == 1
3127            && !memory_operand (operands[0], TFmode))
3128        || (!TARGET_MEMORY_MISMATCH_STALL
3129            && memory_operand (operands[0], TFmode)))"
3131   switch (get_attr_type (insn))
3132     {
3133     case TYPE_SSELOG1:
3134       return standard_sse_constant_opcode (insn, operands[1]);
3136     case TYPE_SSEMOV:
3137       /* Handle misaligned load/store since we
3138          don't have movmisaligntf pattern. */
3139       if (misaligned_operand (operands[0], TFmode)
3140           || misaligned_operand (operands[1], TFmode))
3141         {
3142           if (get_attr_mode (insn) == MODE_V4SF)
3143             return "%vmovups\t{%1, %0|%0, %1}";
3144           else if (TARGET_AVX512VL
3145                    && (EXT_REX_SSE_REG_P (operands[0])
3146                        || EXT_REX_SSE_REG_P (operands[1])))
3147             return "vmovdqu64\t{%1, %0|%0, %1}";
3148           else
3149             return "%vmovdqu\t{%1, %0|%0, %1}";
3150         }
3151       else
3152         {
3153           if (get_attr_mode (insn) == MODE_V4SF)
3154             return "%vmovaps\t{%1, %0|%0, %1}";
3155           else if (TARGET_AVX512VL
3156                    && (EXT_REX_SSE_REG_P (operands[0])
3157                        || EXT_REX_SSE_REG_P (operands[1])))
3158             return "vmovdqa64\t{%1, %0|%0, %1}";
3159           else
3160             return "%vmovdqa\t{%1, %0|%0, %1}";
3161         }
3163     case TYPE_MULTI:
3164         return "#";
3166     default:
3167       gcc_unreachable ();
3168     }
3170   [(set_attr "isa" "*,*,*,x64,x64")
3171    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3172    (set (attr "prefix")
3173      (if_then_else (eq_attr "type" "sselog1,ssemov")
3174        (const_string "maybe_vex")
3175        (const_string "orig")))
3176    (set (attr "mode")
3177         (cond [(eq_attr "alternative" "3,4")
3178                  (const_string "DI")
3179                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3180                  (const_string "V4SF")
3181                (and (eq_attr "alternative" "2")
3182                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3183                  (const_string "V4SF")
3184                (match_test "TARGET_AVX")
3185                  (const_string "TI")
3186                (ior (not (match_test "TARGET_SSE2"))
3187                     (match_test "optimize_function_for_size_p (cfun)"))
3188                  (const_string "V4SF")
3189                ]
3190                (const_string "TI")))])
3192 (define_split
3193   [(set (match_operand:TF 0 "nonimmediate_operand")
3194         (match_operand:TF 1 "general_operand"))]
3195   "reload_completed
3196    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3197   [(const_int 0)]
3198   "ix86_split_long_move (operands); DONE;")
3200 ;; Possible store forwarding (partial memory) stall
3201 ;; in alternatives 4, 6, 7 and 8.
3202 (define_insn "*movxf_internal"
3203   [(set (match_operand:XF 0 "nonimmediate_operand"
3204          "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r  ,o")
3205         (match_operand:XF 1 "general_operand"
3206          "fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
3207   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3208    && (!can_create_pseudo_p ()
3209        || !CONST_DOUBLE_P (operands[1])
3210        || ((optimize_function_for_size_p (cfun)
3211             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3212            && standard_80387_constant_p (operands[1]) > 0
3213            && !memory_operand (operands[0], XFmode))
3214        || (!TARGET_MEMORY_MISMATCH_STALL
3215            && memory_operand (operands[0], XFmode))
3216        || !TARGET_HARD_XF_REGS)"
3218   switch (get_attr_type (insn))
3219     {
3220     case TYPE_FMOV:
3221       if (which_alternative == 2)
3222         return standard_80387_constant_opcode (operands[1]);
3223       return output_387_reg_move (insn, operands);
3225     case TYPE_MULTI:
3226       return "#";
3228     default:
3229       gcc_unreachable ();
3230     }
3232   [(set (attr "isa")
3233         (cond [(eq_attr "alternative" "7")
3234                  (const_string "nox64")
3235                (eq_attr "alternative" "8")
3236                  (const_string "x64")
3237               ]
3238               (const_string "*")))
3239    (set (attr "type")
3240         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3241                  (const_string "multi")
3242               ]
3243               (const_string "fmov")))
3244    (set (attr "mode")
3245         (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10")
3246                  (if_then_else (match_test "TARGET_64BIT")
3247                    (const_string "DI")
3248                    (const_string "SI"))
3249               ]
3250               (const_string "XF")))
3251    (set (attr "preferred_for_size")
3252      (cond [(eq_attr "alternative" "3,4")
3253               (symbol_ref "false")]
3254            (symbol_ref "true")))
3255    (set (attr "enabled")
3256      (cond [(eq_attr "alternative" "9,10")
3257               (if_then_else
3258                 (match_test "TARGET_HARD_XF_REGS")
3259                 (symbol_ref "false")
3260                 (const_string "*"))
3261             (not (match_test "TARGET_HARD_XF_REGS"))
3262               (symbol_ref "false")
3263            ]
3264            (const_string "*")))])
3265    
3266 (define_split
3267   [(set (match_operand:XF 0 "nonimmediate_operand")
3268         (match_operand:XF 1 "general_operand"))]
3269   "reload_completed
3270    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3271   [(const_int 0)]
3272   "ix86_split_long_move (operands); DONE;")
3274 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3275 (define_insn "*movdf_internal"
3276   [(set (match_operand:DF 0 "nonimmediate_operand"
3277     "=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")
3278         (match_operand:DF 1 "general_operand"
3279     "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"))]
3280   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3281    && (!can_create_pseudo_p ()
3282        || !CONST_DOUBLE_P (operands[1])
3283        || ((optimize_function_for_size_p (cfun)
3284             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3285            && ((IS_STACK_MODE (DFmode)
3286                 && standard_80387_constant_p (operands[1]) > 0)
3287                || (TARGET_SSE2 && TARGET_SSE_MATH
3288                    && standard_sse_constant_p (operands[1], DFmode) == 1))
3289            && !memory_operand (operands[0], DFmode))
3290        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3291            && memory_operand (operands[0], DFmode))
3292        || !TARGET_HARD_DF_REGS)"
3294   switch (get_attr_type (insn))
3295     {
3296     case TYPE_FMOV:
3297       if (which_alternative == 2)
3298         return standard_80387_constant_opcode (operands[1]);
3299       return output_387_reg_move (insn, operands);
3301     case TYPE_MULTI:
3302       return "#";
3304     case TYPE_IMOV:
3305       if (get_attr_mode (insn) == MODE_SI)
3306         return "mov{l}\t{%1, %k0|%k0, %1}";
3307       else if (which_alternative == 11)
3308         return "movabs{q}\t{%1, %0|%0, %1}";
3309       else
3310         return "mov{q}\t{%1, %0|%0, %1}";
3312     case TYPE_SSELOG1:
3313       return standard_sse_constant_opcode (insn, operands[1]);
3315     case TYPE_SSEMOV:
3316       switch (get_attr_mode (insn))
3317         {
3318         case MODE_DF:
3319           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3320             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3321           return "%vmovsd\t{%1, %0|%0, %1}";
3323         case MODE_V4SF:
3324           return "%vmovaps\t{%1, %0|%0, %1}";
3325         case MODE_V8DF:
3326           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3327         case MODE_V2DF:
3328           return "%vmovapd\t{%1, %0|%0, %1}";
3330         case MODE_V2SF:
3331           gcc_assert (!TARGET_AVX);
3332           return "movlps\t{%1, %0|%0, %1}";
3333         case MODE_V1DF:
3334           gcc_assert (!TARGET_AVX);
3335           return "movlpd\t{%1, %0|%0, %1}";
3337         case MODE_DI:
3338           /* Handle broken assemblers that require movd instead of movq.  */
3339           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3340               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3341             return "%vmovd\t{%1, %0|%0, %1}";
3342           return "%vmovq\t{%1, %0|%0, %1}";
3344         default:
3345           gcc_unreachable ();
3346         }
3348     default:
3349       gcc_unreachable ();
3350     }
3352   [(set (attr "isa")
3353         (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3354                  (const_string "nox64")
3355                (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3356                  (const_string "x64")
3357                (eq_attr "alternative" "12,13,14,15")
3358                  (const_string "sse2")
3359               ]
3360               (const_string "*")))
3361    (set (attr "type")
3362         (cond [(eq_attr "alternative" "0,1,2")
3363                  (const_string "fmov")
3364                (eq_attr "alternative" "3,4,5,6,7,22,23")
3365                  (const_string "multi")
3366                (eq_attr "alternative" "8,9,10,11,24,25")
3367                  (const_string "imov")
3368                (eq_attr "alternative" "12,16")
3369                  (const_string "sselog1")
3370               ]
3371               (const_string "ssemov")))
3372    (set (attr "modrm")
3373      (if_then_else (eq_attr "alternative" "11")
3374        (const_string "0")
3375        (const_string "*")))
3376    (set (attr "length_immediate")
3377      (if_then_else (eq_attr "alternative" "11")
3378        (const_string "8")
3379        (const_string "*")))
3380    (set (attr "prefix")
3381      (if_then_else (eq_attr "type" "sselog1,ssemov")
3382        (const_string "maybe_vex")
3383        (const_string "orig")))
3384    (set (attr "prefix_data16")
3385      (if_then_else
3386        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3387             (eq_attr "mode" "V1DF"))
3388        (const_string "1")
3389        (const_string "*")))
3390    (set (attr "mode")
3391         (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3392                  (const_string "SI")
3393                (eq_attr "alternative" "8,9,11,20,21,24,25")
3394                  (const_string "DI")
3396                /* xorps is one byte shorter for non-AVX targets.  */
3397                (eq_attr "alternative" "12,16")
3398                  (cond [(not (match_test "TARGET_SSE2"))
3399                           (const_string "V4SF")
3400                         (match_test "TARGET_AVX512F")
3401                           (const_string "XI")
3402                         (match_test "TARGET_AVX")
3403                           (const_string "V2DF")
3404                         (match_test "optimize_function_for_size_p (cfun)")
3405                           (const_string "V4SF")
3406                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3407                           (const_string "TI")
3408                        ]
3409                        (const_string "V2DF"))
3411                /* For architectures resolving dependencies on
3412                   whole SSE registers use movapd to break dependency
3413                   chains, otherwise use short move to avoid extra work.  */
3415                /* movaps is one byte shorter for non-AVX targets.  */
3416                (eq_attr "alternative" "13,17")
3417                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3418                              (match_operand 1 "ext_sse_reg_operand"))
3419                           (const_string "V8DF")
3420                         (ior (not (match_test "TARGET_SSE2"))
3421                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3422                           (const_string "V4SF")
3423                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3424                           (const_string "V2DF")
3425                         (match_test "TARGET_AVX")
3426                           (const_string "DF")
3427                         (match_test "optimize_function_for_size_p (cfun)")
3428                           (const_string "V4SF")
3429                        ]
3430                        (const_string "DF"))
3432                /* For architectures resolving dependencies on register
3433                   parts we may avoid extra work to zero out upper part
3434                   of register.  */
3435                (eq_attr "alternative" "14,18")
3436                  (cond [(not (match_test "TARGET_SSE2"))
3437                           (const_string "V2SF")
3438                         (match_test "TARGET_AVX")
3439                           (const_string "DF")
3440                         (match_test "TARGET_SSE_SPLIT_REGS")
3441                           (const_string "V1DF")
3442                        ]
3443                        (const_string "DF"))
3445                (and (eq_attr "alternative" "15,19")
3446                     (not (match_test "TARGET_SSE2")))
3447                  (const_string "V2SF")
3448               ]
3449               (const_string "DF")))
3450    (set (attr "preferred_for_size")
3451      (cond [(eq_attr "alternative" "3,4")
3452               (symbol_ref "false")]
3453            (symbol_ref "true")))
3454    (set (attr "preferred_for_speed")
3455      (cond [(eq_attr "alternative" "3,4")
3456               (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3457            (symbol_ref "true")))
3458    (set (attr "enabled")
3459      (cond [(eq_attr "alternative" "22,23,24,25")
3460               (if_then_else
3461                 (match_test "TARGET_HARD_DF_REGS")
3462                 (symbol_ref "false")
3463                 (const_string "*"))
3464             (not (match_test "TARGET_HARD_DF_REGS"))
3465               (symbol_ref "false")
3466            ]
3467            (const_string "*")))])
3469 (define_split
3470   [(set (match_operand:DF 0 "nonimmediate_operand")
3471         (match_operand:DF 1 "general_operand"))]
3472   "!TARGET_64BIT && reload_completed
3473    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3474   [(const_int 0)]
3475   "ix86_split_long_move (operands); DONE;")
3477 (define_insn "*movsf_internal"
3478   [(set (match_operand:SF 0 "nonimmediate_operand"
3479           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r  ,m")
3480         (match_operand:SF 1 "general_operand"
3481           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r   ,rmF,rF"))]
3482   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3483    && (!can_create_pseudo_p ()
3484        || !CONST_DOUBLE_P (operands[1])
3485        || ((optimize_function_for_size_p (cfun)
3486             || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3487            && ((IS_STACK_MODE (SFmode)
3488                 && standard_80387_constant_p (operands[1]) > 0)
3489                || (TARGET_SSE && TARGET_SSE_MATH
3490                    && standard_sse_constant_p (operands[1], SFmode) == 1)))
3491        || memory_operand (operands[0], SFmode)
3492        || !TARGET_HARD_SF_REGS)"
3494   switch (get_attr_type (insn))
3495     {
3496     case TYPE_FMOV:
3497       if (which_alternative == 2)
3498         return standard_80387_constant_opcode (operands[1]);
3499       return output_387_reg_move (insn, operands);
3501     case TYPE_IMOV:
3502       return "mov{l}\t{%1, %0|%0, %1}";
3504     case TYPE_SSELOG1:
3505       return standard_sse_constant_opcode (insn, operands[1]);
3507     case TYPE_SSEMOV:
3508       switch (get_attr_mode (insn))
3509         {
3510         case MODE_SF:
3511           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3512             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3513           return "%vmovss\t{%1, %0|%0, %1}";
3515         case MODE_V16SF:
3516           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3517         case MODE_V4SF:
3518           return "%vmovaps\t{%1, %0|%0, %1}";
3520         case MODE_SI:
3521           return "%vmovd\t{%1, %0|%0, %1}";
3523         default:
3524           gcc_unreachable ();
3525         }
3527     case TYPE_MMXMOV:
3528       switch (get_attr_mode (insn))
3529         {
3530         case MODE_DI:
3531           return "movq\t{%1, %0|%0, %1}";
3532         case MODE_SI:
3533           return "movd\t{%1, %0|%0, %1}";
3535         default:
3536           gcc_unreachable ();
3537         }
3539     default:
3540       gcc_unreachable ();
3541     }
3543   [(set (attr "type")
3544         (cond [(eq_attr "alternative" "0,1,2")
3545                  (const_string "fmov")
3546                (eq_attr "alternative" "3,4,16,17")
3547                  (const_string "imov")
3548                (eq_attr "alternative" "5")
3549                  (const_string "sselog1")
3550                (eq_attr "alternative" "11,12,13,14,15")
3551                  (const_string "mmxmov")
3552               ]
3553               (const_string "ssemov")))
3554    (set (attr "prefix")
3555      (if_then_else (eq_attr "type" "sselog1,ssemov")
3556        (const_string "maybe_vex")
3557        (const_string "orig")))
3558    (set (attr "prefix_data16")
3559      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3560        (const_string "1")
3561        (const_string "*")))
3562    (set (attr "mode")
3563         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3564                  (const_string "SI")
3565                (eq_attr "alternative" "11")
3566                  (const_string "DI")
3567                (eq_attr "alternative" "5")
3568                  (cond [(not (match_test "TARGET_SSE2"))
3569                           (const_string "V4SF")
3570                         (match_test "TARGET_AVX512F")
3571                           (const_string "V16SF")
3572                         (match_test "TARGET_AVX")
3573                           (const_string "V4SF")
3574                         (match_test "optimize_function_for_size_p (cfun)")
3575                           (const_string "V4SF")
3576                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3577                           (const_string "TI")
3578                        ]
3579                        (const_string "V4SF"))
3581                /* For architectures resolving dependencies on
3582                   whole SSE registers use APS move to break dependency
3583                   chains, otherwise use short move to avoid extra work.
3585                   Do the same for architectures resolving dependencies on
3586                   the parts.  While in DF mode it is better to always handle
3587                   just register parts, the SF mode is different due to lack
3588                   of instructions to load just part of the register.  It is
3589                   better to maintain the whole registers in single format
3590                   to avoid problems on using packed logical operations.  */
3591                (eq_attr "alternative" "6")
3592                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3593                               (match_operand 1 "ext_sse_reg_operand"))
3594                           (const_string "V16SF")
3595                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3596                              (match_test "TARGET_SSE_SPLIT_REGS"))
3597                           (const_string "V4SF")
3598                        ]
3599                        (const_string "SF"))
3600               ]
3601               (const_string "SF")))
3602    (set (attr "enabled")
3603      (cond [(eq_attr "alternative" "16,17")
3604               (if_then_else
3605                 (match_test "TARGET_HARD_SF_REGS")
3606                 (symbol_ref "false")
3607                 (const_string "*"))
3608             (not (match_test "TARGET_HARD_SF_REGS"))
3609               (symbol_ref "false")
3610            ]
3611            (const_string "*")))])
3613 (define_split
3614   [(set (match_operand 0 "any_fp_register_operand")
3615         (match_operand 1 "memory_operand"))]
3616   "reload_completed
3617    && (GET_MODE (operands[0]) == TFmode
3618        || GET_MODE (operands[0]) == XFmode
3619        || GET_MODE (operands[0]) == DFmode
3620        || GET_MODE (operands[0]) == SFmode)
3621    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3622   [(set (match_dup 0) (match_dup 2))]
3623   "operands[2] = find_constant_src (curr_insn);")
3625 (define_split
3626   [(set (match_operand 0 "any_fp_register_operand")
3627         (float_extend (match_operand 1 "memory_operand")))]
3628   "reload_completed
3629    && (GET_MODE (operands[0]) == TFmode
3630        || GET_MODE (operands[0]) == XFmode
3631        || GET_MODE (operands[0]) == DFmode)
3632    && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3633   [(set (match_dup 0) (match_dup 2))]
3634   "operands[2] = find_constant_src (curr_insn);")
3636 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3637 (define_split
3638   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3639         (match_operand:X87MODEF 1 "immediate_operand"))]
3640   "reload_completed
3641    && (standard_80387_constant_p (operands[1]) == 8
3642        || standard_80387_constant_p (operands[1]) == 9)"
3643   [(set (match_dup 0)(match_dup 1))
3644    (set (match_dup 0)
3645         (neg:X87MODEF (match_dup 0)))]
3647   if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3648     operands[1] = CONST0_RTX (<MODE>mode);
3649   else
3650     operands[1] = CONST1_RTX (<MODE>mode);
3653 (define_insn "swapxf"
3654   [(set (match_operand:XF 0 "register_operand" "+f")
3655         (match_operand:XF 1 "register_operand" "+f"))
3656    (set (match_dup 1)
3657         (match_dup 0))]
3658   "TARGET_80387"
3660   if (STACK_TOP_P (operands[0]))
3661     return "fxch\t%1";
3662   else
3663     return "fxch\t%0";
3665   [(set_attr "type" "fxch")
3666    (set_attr "mode" "XF")])
3668 (define_insn "*swap<mode>"
3669   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3670         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3671    (set (match_dup 1)
3672         (match_dup 0))]
3673   "TARGET_80387 || reload_completed"
3675   if (STACK_TOP_P (operands[0]))
3676     return "fxch\t%1";
3677   else
3678     return "fxch\t%0";
3680   [(set_attr "type" "fxch")
3681    (set_attr "mode" "<MODE>")])
3683 ;; Zero extension instructions
3685 (define_expand "zero_extendsidi2"
3686   [(set (match_operand:DI 0 "nonimmediate_operand")
3687         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3689 (define_insn "*zero_extendsidi2"
3690   [(set (match_operand:DI 0 "nonimmediate_operand"
3691                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3692         (zero_extend:DI
3693          (match_operand:SI 1 "x86_64_zext_operand"
3694                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3695   ""
3697   switch (get_attr_type (insn))
3698     {
3699     case TYPE_IMOVX:
3700       if (ix86_use_lea_for_mov (insn, operands))
3701         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3702       else
3703         return "mov{l}\t{%1, %k0|%k0, %1}";
3705     case TYPE_MULTI:
3706       return "#";
3708     case TYPE_MMXMOV:
3709       return "movd\t{%1, %0|%0, %1}";
3711     case TYPE_SSELOG1:
3712       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3714     case TYPE_SSEMOV:
3715       if (GENERAL_REG_P (operands[0]))
3716         return "%vmovd\t{%1, %k0|%k0, %1}";
3718       return "%vmovd\t{%1, %0|%0, %1}";
3720     default:
3721       gcc_unreachable ();
3722     }
3724   [(set (attr "isa")
3725      (cond [(eq_attr "alternative" "0,1,2")
3726               (const_string "nox64")
3727             (eq_attr "alternative" "3,7")
3728               (const_string "x64")
3729             (eq_attr "alternative" "8")
3730               (const_string "x64_sse4")
3731             (eq_attr "alternative" "10")
3732               (const_string "sse2")
3733            ]
3734            (const_string "*")))
3735    (set (attr "type")
3736      (cond [(eq_attr "alternative" "0,1,2,4")
3737               (const_string "multi")
3738             (eq_attr "alternative" "5,6")
3739               (const_string "mmxmov")
3740             (eq_attr "alternative" "7,9,10")
3741               (const_string "ssemov")
3742             (eq_attr "alternative" "8")
3743               (const_string "sselog1")
3744            ]
3745            (const_string "imovx")))
3746    (set (attr "prefix_extra")
3747      (if_then_else (eq_attr "alternative" "8")
3748        (const_string "1")
3749        (const_string "*")))
3750    (set (attr "length_immediate")
3751      (if_then_else (eq_attr "alternative" "8")
3752        (const_string "1")
3753        (const_string "*")))
3754    (set (attr "prefix")
3755      (if_then_else (eq_attr "type" "ssemov,sselog1")
3756        (const_string "maybe_vex")
3757        (const_string "orig")))
3758    (set (attr "prefix_0f")
3759      (if_then_else (eq_attr "type" "imovx")
3760        (const_string "0")
3761        (const_string "*")))
3762    (set (attr "mode")
3763      (cond [(eq_attr "alternative" "5,6")
3764               (const_string "DI")
3765             (eq_attr "alternative" "7,8,9")
3766               (const_string "TI")
3767            ]
3768            (const_string "SI")))])
3770 (define_split
3771   [(set (match_operand:DI 0 "memory_operand")
3772         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3773   "reload_completed"
3774   [(set (match_dup 4) (const_int 0))]
3775   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3777 (define_split
3778   [(set (match_operand:DI 0 "general_reg_operand")
3779         (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3780   "!TARGET_64BIT && reload_completed
3781    && REGNO (operands[0]) == REGNO (operands[1])"
3782   [(set (match_dup 4) (const_int 0))]
3783   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3785 (define_split
3786   [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3787         (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))]
3788   "!TARGET_64BIT && reload_completed
3789    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3790   [(set (match_dup 3) (match_dup 1))
3791    (set (match_dup 4) (const_int 0))]
3792   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3794 (define_insn "zero_extend<mode>di2"
3795   [(set (match_operand:DI 0 "register_operand" "=r")
3796         (zero_extend:DI
3797          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3798   "TARGET_64BIT"
3799   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3800   [(set_attr "type" "imovx")
3801    (set_attr "mode" "SI")])
3803 (define_expand "zero_extend<mode>si2"
3804   [(set (match_operand:SI 0 "register_operand")
3805         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3806   ""
3808   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3809     {
3810       operands[1] = force_reg (<MODE>mode, operands[1]);
3811       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3812       DONE;
3813     }
3816 (define_insn_and_split "zero_extend<mode>si2_and"
3817   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3818         (zero_extend:SI
3819           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3820    (clobber (reg:CC FLAGS_REG))]
3821   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3822   "#"
3823   "&& reload_completed"
3824   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3825               (clobber (reg:CC FLAGS_REG))])]
3827   if (!REG_P (operands[1])
3828       || REGNO (operands[0]) != REGNO (operands[1]))
3829     {
3830       ix86_expand_clear (operands[0]);
3832       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3833       emit_insn (gen_movstrict<mode>
3834                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3835       DONE;
3836     }
3838   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3840   [(set_attr "type" "alu1")
3841    (set_attr "mode" "SI")])
3843 (define_insn "*zero_extend<mode>si2"
3844   [(set (match_operand:SI 0 "register_operand" "=r")
3845         (zero_extend:SI
3846           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3847   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3848   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3849   [(set_attr "type" "imovx")
3850    (set_attr "mode" "SI")])
3852 (define_expand "zero_extendqihi2"
3853   [(set (match_operand:HI 0 "register_operand")
3854         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3855   ""
3857   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3858     {
3859       operands[1] = force_reg (QImode, operands[1]);
3860       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3861       DONE;
3862     }
3865 (define_insn_and_split "zero_extendqihi2_and"
3866   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3867         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3868    (clobber (reg:CC FLAGS_REG))]
3869   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3870   "#"
3871   "&& reload_completed"
3872   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3873               (clobber (reg:CC FLAGS_REG))])]
3875   if (!REG_P (operands[1])
3876       || REGNO (operands[0]) != REGNO (operands[1]))
3877     {
3878       ix86_expand_clear (operands[0]);
3880       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3881       emit_insn (gen_movstrictqi
3882                   (gen_lowpart (QImode, operands[0]), operands[1]));
3883       DONE;
3884     }
3886   operands[0] = gen_lowpart (SImode, operands[0]);
3888   [(set_attr "type" "alu1")
3889    (set_attr "mode" "SI")])
3891 ; zero extend to SImode to avoid partial register stalls
3892 (define_insn "*zero_extendqihi2"
3893   [(set (match_operand:HI 0 "register_operand" "=r")
3894         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3895   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3896   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3897   [(set_attr "type" "imovx")
3898    (set_attr "mode" "SI")])
3900 (define_insn_and_split "*zext<mode>_doubleword_and"
3901   [(set (match_operand:DI 0 "register_operand" "=&<r>")
3902         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3903   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3904    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3905   "#"
3906   "&& reload_completed && GENERAL_REG_P (operands[0])"
3907   [(set (match_dup 2) (const_int 0))]
3909   split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
3911   emit_move_insn (operands[0], const0_rtx);
3913   gcc_assert (!TARGET_PARTIAL_REG_STALL);
3914   emit_insn (gen_movstrict<mode>
3915              (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3918 (define_insn_and_split "*zext<mode>_doubleword"
3919   [(set (match_operand:DI 0 "register_operand" "=r")
3920         (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3921   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
3922    && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3923   "#"
3924   "&& reload_completed && GENERAL_REG_P (operands[0])"
3925   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
3926    (set (match_dup 2) (const_int 0))]
3927   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3929 (define_insn_and_split "*zextsi_doubleword"
3930   [(set (match_operand:DI 0 "register_operand" "=r")
3931         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3932   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
3933   "#"
3934   "&& reload_completed && GENERAL_REG_P (operands[0])"
3935   [(set (match_dup 0) (match_dup 1))
3936    (set (match_dup 2) (const_int 0))]
3937   "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
3939 ;; Sign extension instructions
3941 (define_expand "extendsidi2"
3942   [(set (match_operand:DI 0 "register_operand")
3943         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3944   ""
3946   if (!TARGET_64BIT)
3947     {
3948       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3949       DONE;
3950     }
3953 (define_insn "*extendsidi2_rex64"
3954   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3955         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3956   "TARGET_64BIT"
3957   "@
3958    {cltq|cdqe}
3959    movs{lq|x}\t{%1, %0|%0, %1}"
3960   [(set_attr "type" "imovx")
3961    (set_attr "mode" "DI")
3962    (set_attr "prefix_0f" "0")
3963    (set_attr "modrm" "0,1")])
3965 (define_insn "extendsidi2_1"
3966   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3967         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3968    (clobber (reg:CC FLAGS_REG))
3969    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3970   "!TARGET_64BIT"
3971   "#")
3973 ;; Split the memory case.  If the source register doesn't die, it will stay
3974 ;; this way, if it does die, following peephole2s take care of it.
3975 (define_split
3976   [(set (match_operand:DI 0 "memory_operand")
3977         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3978    (clobber (reg:CC FLAGS_REG))
3979    (clobber (match_operand:SI 2 "register_operand"))]
3980   "reload_completed"
3981   [(const_int 0)]
3983   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3985   emit_move_insn (operands[3], operands[1]);
3987   /* Generate a cltd if possible and doing so it profitable.  */
3988   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3989       && REGNO (operands[1]) == AX_REG
3990       && REGNO (operands[2]) == DX_REG)
3991     {
3992       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3993     }
3994   else
3995     {
3996       emit_move_insn (operands[2], operands[1]);
3997       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3998     }
3999   emit_move_insn (operands[4], operands[2]);
4000   DONE;
4003 ;; Peepholes for the case where the source register does die, after
4004 ;; being split with the above splitter.
4005 (define_peephole2
4006   [(set (match_operand:SI 0 "memory_operand")
4007         (match_operand:SI 1 "general_reg_operand"))
4008    (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4009    (parallel [(set (match_dup 2)
4010                    (ashiftrt:SI (match_dup 2) (const_int 31)))
4011                (clobber (reg:CC FLAGS_REG))])
4012    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4013   "REGNO (operands[1]) != REGNO (operands[2])
4014    && peep2_reg_dead_p (2, operands[1])
4015    && peep2_reg_dead_p (4, operands[2])
4016    && !reg_mentioned_p (operands[2], operands[3])"
4017   [(set (match_dup 0) (match_dup 1))
4018    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4019               (clobber (reg:CC FLAGS_REG))])
4020    (set (match_dup 3) (match_dup 1))])
4022 (define_peephole2
4023   [(set (match_operand:SI 0 "memory_operand")
4024         (match_operand:SI 1 "general_reg_operand"))
4025    (parallel [(set (match_operand:SI 2 "general_reg_operand")
4026                    (ashiftrt:SI (match_dup 1) (const_int 31)))
4027                (clobber (reg:CC FLAGS_REG))])
4028    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4029   "/* cltd is shorter than sarl $31, %eax */
4030    !optimize_function_for_size_p (cfun)
4031    && REGNO (operands[1]) == AX_REG
4032    && REGNO (operands[2]) == DX_REG
4033    && peep2_reg_dead_p (2, operands[1])
4034    && peep2_reg_dead_p (3, operands[2])
4035    && !reg_mentioned_p (operands[2], operands[3])"
4036   [(set (match_dup 0) (match_dup 1))
4037    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4038               (clobber (reg:CC FLAGS_REG))])
4039    (set (match_dup 3) (match_dup 1))])
4041 ;; Extend to register case.  Optimize case where source and destination
4042 ;; registers match and cases where we can use cltd.
4043 (define_split
4044   [(set (match_operand:DI 0 "register_operand")
4045         (sign_extend:DI (match_operand:SI 1 "register_operand")))
4046    (clobber (reg:CC FLAGS_REG))
4047    (clobber (match_scratch:SI 2))]
4048   "reload_completed"
4049   [(const_int 0)]
4051   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4053   if (REGNO (operands[3]) != REGNO (operands[1]))
4054     emit_move_insn (operands[3], operands[1]);
4056   /* Generate a cltd if possible and doing so it profitable.  */
4057   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4058       && REGNO (operands[3]) == AX_REG
4059       && REGNO (operands[4]) == DX_REG)
4060     {
4061       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4062       DONE;
4063     }
4065   if (REGNO (operands[4]) != REGNO (operands[1]))
4066     emit_move_insn (operands[4], operands[1]);
4068   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4069   DONE;
4072 (define_insn "extend<mode>di2"
4073   [(set (match_operand:DI 0 "register_operand" "=r")
4074         (sign_extend:DI
4075          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4076   "TARGET_64BIT"
4077   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4078   [(set_attr "type" "imovx")
4079    (set_attr "mode" "DI")])
4081 (define_insn "extendhisi2"
4082   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4083         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4084   ""
4086   switch (get_attr_prefix_0f (insn))
4087     {
4088     case 0:
4089       return "{cwtl|cwde}";
4090     default:
4091       return "movs{wl|x}\t{%1, %0|%0, %1}";
4092     }
4094   [(set_attr "type" "imovx")
4095    (set_attr "mode" "SI")
4096    (set (attr "prefix_0f")
4097      ;; movsx is short decodable while cwtl is vector decoded.
4098      (if_then_else (and (eq_attr "cpu" "!k6")
4099                         (eq_attr "alternative" "0"))
4100         (const_string "0")
4101         (const_string "1")))
4102    (set (attr "znver1_decode")
4103      (if_then_else (eq_attr "prefix_0f" "0")
4104         (const_string "double")
4105         (const_string "direct")))
4106    (set (attr "modrm")
4107      (if_then_else (eq_attr "prefix_0f" "0")
4108         (const_string "0")
4109         (const_string "1")))])
4111 (define_insn "*extendhisi2_zext"
4112   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4113         (zero_extend:DI
4114          (sign_extend:SI
4115           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4116   "TARGET_64BIT"
4118   switch (get_attr_prefix_0f (insn))
4119     {
4120     case 0:
4121       return "{cwtl|cwde}";
4122     default:
4123       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4124     }
4126   [(set_attr "type" "imovx")
4127    (set_attr "mode" "SI")
4128    (set (attr "prefix_0f")
4129      ;; movsx is short decodable while cwtl is vector decoded.
4130      (if_then_else (and (eq_attr "cpu" "!k6")
4131                         (eq_attr "alternative" "0"))
4132         (const_string "0")
4133         (const_string "1")))
4134    (set (attr "modrm")
4135      (if_then_else (eq_attr "prefix_0f" "0")
4136         (const_string "0")
4137         (const_string "1")))])
4139 (define_insn "extendqisi2"
4140   [(set (match_operand:SI 0 "register_operand" "=r")
4141         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4142   ""
4143   "movs{bl|x}\t{%1, %0|%0, %1}"
4144    [(set_attr "type" "imovx")
4145     (set_attr "mode" "SI")])
4147 (define_insn "*extendqisi2_zext"
4148   [(set (match_operand:DI 0 "register_operand" "=r")
4149         (zero_extend:DI
4150           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4151   "TARGET_64BIT"
4152   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4153    [(set_attr "type" "imovx")
4154     (set_attr "mode" "SI")])
4156 (define_insn "extendqihi2"
4157   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4158         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4159   ""
4161   switch (get_attr_prefix_0f (insn))
4162     {
4163     case 0:
4164       return "{cbtw|cbw}";
4165     default:
4166       return "movs{bw|x}\t{%1, %0|%0, %1}";
4167     }
4169   [(set_attr "type" "imovx")
4170    (set_attr "mode" "HI")
4171    (set (attr "prefix_0f")
4172      ;; movsx is short decodable while cwtl is vector decoded.
4173      (if_then_else (and (eq_attr "cpu" "!k6")
4174                         (eq_attr "alternative" "0"))
4175         (const_string "0")
4176         (const_string "1")))
4177    (set (attr "modrm")
4178      (if_then_else (eq_attr "prefix_0f" "0")
4179         (const_string "0")
4180         (const_string "1")))])
4182 ;; Conversions between float and double.
4184 ;; These are all no-ops in the model used for the 80387.
4185 ;; So just emit moves.
4187 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4188 (define_split
4189   [(set (match_operand:DF 0 "push_operand")
4190         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4191   "reload_completed"
4192   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4193    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4195 (define_split
4196   [(set (match_operand:XF 0 "push_operand")
4197         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4198   "reload_completed"
4199   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4200    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4201   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4203 (define_expand "extendsfdf2"
4204   [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4205         (float_extend:DF (match_operand:SF 1 "general_operand")))]
4206   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4208   /* ??? Needed for compress_float_constant since all fp constants
4209      are TARGET_LEGITIMATE_CONSTANT_P.  */
4210   if (CONST_DOUBLE_P (operands[1]))
4211     {
4212       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4213           && standard_80387_constant_p (operands[1]) > 0)
4214         {
4215           operands[1] = simplify_const_unary_operation
4216             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4217           emit_move_insn_1 (operands[0], operands[1]);
4218           DONE;
4219         }
4220       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4221     }
4224 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4225    cvtss2sd:
4226       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4227       cvtps2pd xmm2,xmm1
4228    We do the conversion post reload to avoid producing of 128bit spills
4229    that might lead to ICE on 32bit target.  The sequence unlikely combine
4230    anyway.  */
4231 (define_split
4232   [(set (match_operand:DF 0 "sse_reg_operand")
4233         (float_extend:DF
4234           (match_operand:SF 1 "nonimmediate_operand")))]
4235   "TARGET_USE_VECTOR_FP_CONVERTS
4236    && optimize_insn_for_speed_p ()
4237    && reload_completed
4238    && (!EXT_REX_SSE_REG_P (operands[0])
4239        || TARGET_AVX512VL)"
4240    [(set (match_dup 2)
4241          (float_extend:V2DF
4242            (vec_select:V2SF
4243              (match_dup 3)
4244              (parallel [(const_int 0) (const_int 1)]))))]
4246   operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4247   operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4248   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4249      Try to avoid move when unpacking can be done in source.  */
4250   if (REG_P (operands[1]))
4251     {
4252       /* If it is unsafe to overwrite upper half of source, we need
4253          to move to destination and unpack there.  */
4254       if (REGNO (operands[0]) != REGNO (operands[1])
4255           || (EXT_REX_SSE_REG_P (operands[1])
4256               && !TARGET_AVX512VL))
4257         {
4258           rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4259           emit_move_insn (tmp, operands[1]);
4260         }
4261       else
4262         operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4263       /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4264          =v, v, then vbroadcastss will be only needed for AVX512F without
4265          AVX512VL.  */
4266       if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4267         emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4268                                                operands[3]));
4269       else
4270         {
4271           rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4272           emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4273         }
4274     }
4275   else
4276     emit_insn (gen_vec_setv4sf_0 (operands[3],
4277                                   CONST0_RTX (V4SFmode), operands[1]));
4280 ;; It's more profitable to split and then extend in the same register.
4281 (define_peephole2
4282   [(set (match_operand:DF 0 "sse_reg_operand")
4283         (float_extend:DF
4284           (match_operand:SF 1 "memory_operand")))]
4285   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4286    && optimize_insn_for_speed_p ()"
4287   [(set (match_dup 2) (match_dup 1))
4288    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4289   "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4291 (define_insn "*extendsfdf2"
4292   [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4293         (float_extend:DF
4294           (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4295   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4297   switch (which_alternative)
4298     {
4299     case 0:
4300     case 1:
4301       return output_387_reg_move (insn, operands);
4303     case 2:
4304       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4306     default:
4307       gcc_unreachable ();
4308     }
4310   [(set_attr "type" "fmov,fmov,ssecvt")
4311    (set_attr "prefix" "orig,orig,maybe_vex")
4312    (set_attr "mode" "SF,XF,DF")
4313    (set (attr "enabled")
4314      (if_then_else
4315        (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4316        (if_then_else
4317          (eq_attr "alternative" "0,1")
4318          (symbol_ref "TARGET_MIX_SSE_I387")
4319          (symbol_ref "true"))
4320        (if_then_else
4321          (eq_attr "alternative" "0,1")
4322          (symbol_ref "true")
4323          (symbol_ref "false"))))])
4325 (define_expand "extend<mode>xf2"
4326   [(set (match_operand:XF 0 "nonimmediate_operand")
4327         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4328   "TARGET_80387"
4330   /* ??? Needed for compress_float_constant since all fp constants
4331      are TARGET_LEGITIMATE_CONSTANT_P.  */
4332   if (CONST_DOUBLE_P (operands[1]))
4333     {
4334       if (standard_80387_constant_p (operands[1]) > 0)
4335         {
4336           operands[1] = simplify_const_unary_operation
4337             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4338           emit_move_insn_1 (operands[0], operands[1]);
4339           DONE;
4340         }
4341       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4342     }
4345 (define_insn "*extend<mode>xf2_i387"
4346   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4347         (float_extend:XF
4348           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4349   "TARGET_80387"
4350   "* return output_387_reg_move (insn, operands);"
4351   [(set_attr "type" "fmov")
4352    (set_attr "mode" "<MODE>,XF")])
4354 ;; %%% This seems like bad news.
4355 ;; This cannot output into an f-reg because there is no way to be sure
4356 ;; of truncating in that case.  Otherwise this is just like a simple move
4357 ;; insn.  So we pretend we can output to a reg in order to get better
4358 ;; register preferencing, but we really use a stack slot.
4360 ;; Conversion from DFmode to SFmode.
4362 (define_expand "truncdfsf2"
4363   [(set (match_operand:SF 0 "nonimmediate_operand")
4364         (float_truncate:SF
4365           (match_operand:DF 1 "nonimmediate_operand")))]
4366   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4368   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4369     ;
4370   else if (flag_unsafe_math_optimizations)
4371     ;
4372   else
4373     {
4374       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4375       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4376       DONE;
4377     }
4380 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4381    cvtsd2ss:
4382       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4383       cvtpd2ps xmm2,xmm1
4384    We do the conversion post reload to avoid producing of 128bit spills
4385    that might lead to ICE on 32bit target.  The sequence unlikely combine
4386    anyway.  */
4387 (define_split
4388   [(set (match_operand:SF 0 "sse_reg_operand")
4389         (float_truncate:SF
4390           (match_operand:DF 1 "nonimmediate_operand")))]
4391   "TARGET_USE_VECTOR_FP_CONVERTS
4392    && optimize_insn_for_speed_p ()
4393    && reload_completed
4394    && (!EXT_REX_SSE_REG_P (operands[0])
4395        || TARGET_AVX512VL)"
4396    [(set (match_dup 2)
4397          (vec_concat:V4SF
4398            (float_truncate:V2SF
4399              (match_dup 4))
4400            (match_dup 3)))]
4402   operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4403   operands[3] = CONST0_RTX (V2SFmode);
4404   operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4405   /* Use movsd for loading from memory, unpcklpd for registers.
4406      Try to avoid move when unpacking can be done in source, or SSE3
4407      movddup is available.  */
4408   if (REG_P (operands[1]))
4409     {
4410       if (!TARGET_SSE3
4411           && REGNO (operands[0]) != REGNO (operands[1]))
4412         {
4413           rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4414           emit_move_insn (tmp, operands[1]);
4415           operands[1] = tmp;
4416         }
4417       else if (!TARGET_SSE3)
4418         operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4419       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4420     }
4421   else
4422     emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4423                                    CONST0_RTX (DFmode)));
4426 ;; It's more profitable to split and then extend in the same register.
4427 (define_peephole2
4428   [(set (match_operand:SF 0 "sse_reg_operand")
4429         (float_truncate:SF
4430           (match_operand:DF 1 "memory_operand")))]
4431   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4432    && optimize_insn_for_speed_p ()"
4433   [(set (match_dup 2) (match_dup 1))
4434    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4435   "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4437 (define_expand "truncdfsf2_with_temp"
4438   [(parallel [(set (match_operand:SF 0)
4439                    (float_truncate:SF (match_operand:DF 1)))
4440               (clobber (match_operand:SF 2))])])
4442 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4443 ;; because nothing we do there is unsafe.
4444 (define_insn "*truncdfsf_fast_mixed"
4445   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,v")
4446         (float_truncate:SF
4447           (match_operand:DF 1 "nonimmediate_operand" "f  ,vm")))]
4448   "TARGET_SSE2 && TARGET_SSE_MATH"
4450   switch (which_alternative)
4451     {
4452     case 0:
4453       return output_387_reg_move (insn, operands);
4454     case 1:
4455       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4456     default:
4457       gcc_unreachable ();
4458     }
4460   [(set_attr "type" "fmov,ssecvt")
4461    (set_attr "prefix" "orig,maybe_vex")
4462    (set_attr "mode" "SF")
4463    (set (attr "enabled")
4464      (cond [(eq_attr "alternative" "0")
4465               (symbol_ref "TARGET_MIX_SSE_I387
4466                            && flag_unsafe_math_optimizations")
4467            ]
4468            (symbol_ref "true")))])
4470 (define_insn "*truncdfsf_fast_i387"
4471   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4472         (float_truncate:SF
4473           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4474   "TARGET_80387 && flag_unsafe_math_optimizations"
4475   "* return output_387_reg_move (insn, operands);"
4476   [(set_attr "type" "fmov")
4477    (set_attr "mode" "SF")])
4479 (define_insn "*truncdfsf_mixed"
4480   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,v ,?f,?v,?*r")
4481         (float_truncate:SF
4482           (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4483    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4484   "TARGET_MIX_SSE_I387"
4486   switch (which_alternative)
4487     {
4488     case 0:
4489       return output_387_reg_move (insn, operands);
4490     case 1:
4491       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4493     default:
4494       return "#";
4495     }
4497   [(set_attr "isa" "*,sse2,*,*,*")
4498    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4499    (set_attr "unit" "*,*,i387,i387,i387")
4500    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4501    (set_attr "mode" "SF")])
4503 (define_insn "*truncdfsf_i387"
4504   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?v,?*r")
4505         (float_truncate:SF
4506           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4507    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4508   "TARGET_80387"
4510   switch (which_alternative)
4511     {
4512     case 0:
4513       return output_387_reg_move (insn, operands);
4515     default:
4516       return "#";
4517     }
4519   [(set_attr "type" "fmov,multi,multi,multi")
4520    (set_attr "unit" "*,i387,i387,i387")
4521    (set_attr "mode" "SF")])
4523 (define_insn "*truncdfsf2_i387_1"
4524   [(set (match_operand:SF 0 "memory_operand" "=m")
4525         (float_truncate:SF
4526           (match_operand:DF 1 "register_operand" "f")))]
4527   "TARGET_80387
4528    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4529    && !TARGET_MIX_SSE_I387"
4530   "* return output_387_reg_move (insn, operands);"
4531   [(set_attr "type" "fmov")
4532    (set_attr "mode" "SF")])
4534 (define_split
4535   [(set (match_operand:SF 0 "register_operand")
4536         (float_truncate:SF
4537          (match_operand:DF 1 "fp_register_operand")))
4538    (clobber (match_operand 2))]
4539   "reload_completed"
4540   [(set (match_dup 2) (match_dup 1))
4541    (set (match_dup 0) (match_dup 2))]
4542   "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4544 ;; Conversion from XFmode to {SF,DF}mode
4546 (define_expand "truncxf<mode>2"
4547   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4548                    (float_truncate:MODEF
4549                      (match_operand:XF 1 "register_operand")))
4550               (clobber (match_dup 2))])]
4551   "TARGET_80387"
4553   if (flag_unsafe_math_optimizations)
4554     {
4555       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4556       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4557       if (reg != operands[0])
4558         emit_move_insn (operands[0], reg);
4559       DONE;
4560     }
4561   else
4562     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4565 (define_insn "*truncxfsf2_mixed"
4566   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4567         (float_truncate:SF
4568           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4569    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4570   "TARGET_80387"
4572   gcc_assert (!which_alternative);
4573   return output_387_reg_move (insn, operands);
4575   [(set_attr "type" "fmov,multi,multi,multi")
4576    (set_attr "unit" "*,i387,i387,i387")
4577    (set_attr "mode" "SF")])
4579 (define_insn "*truncxfdf2_mixed"
4580   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4581         (float_truncate:DF
4582           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4583    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4584   "TARGET_80387"
4586   gcc_assert (!which_alternative);
4587   return output_387_reg_move (insn, operands);
4589   [(set_attr "isa" "*,*,sse2,*")
4590    (set_attr "type" "fmov,multi,multi,multi")
4591    (set_attr "unit" "*,i387,i387,i387")
4592    (set_attr "mode" "DF")])
4594 (define_insn "truncxf<mode>2_i387_noop"
4595   [(set (match_operand:MODEF 0 "register_operand" "=f")
4596         (float_truncate:MODEF
4597           (match_operand:XF 1 "register_operand" "f")))]
4598   "TARGET_80387 && flag_unsafe_math_optimizations"
4599   "* return output_387_reg_move (insn, operands);"
4600   [(set_attr "type" "fmov")
4601    (set_attr "mode" "<MODE>")])
4603 (define_insn "*truncxf<mode>2_i387"
4604   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4605         (float_truncate:MODEF
4606           (match_operand:XF 1 "register_operand" "f")))]
4607   "TARGET_80387"
4608   "* return output_387_reg_move (insn, operands);"
4609   [(set_attr "type" "fmov")
4610    (set_attr "mode" "<MODE>")])
4612 (define_split
4613   [(set (match_operand:MODEF 0 "register_operand")
4614         (float_truncate:MODEF
4615           (match_operand:XF 1 "register_operand")))
4616    (clobber (match_operand:MODEF 2 "memory_operand"))]
4617   "TARGET_80387 && reload_completed"
4618   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4619    (set (match_dup 0) (match_dup 2))])
4621 (define_split
4622   [(set (match_operand:MODEF 0 "memory_operand")
4623         (float_truncate:MODEF
4624           (match_operand:XF 1 "register_operand")))
4625    (clobber (match_operand:MODEF 2 "memory_operand"))]
4626   "TARGET_80387"
4627   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4629 ;; Signed conversion to DImode.
4631 (define_expand "fix_truncxfdi2"
4632   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4633                    (fix:DI (match_operand:XF 1 "register_operand")))
4634               (clobber (reg:CC FLAGS_REG))])]
4635   "TARGET_80387"
4637   if (TARGET_FISTTP)
4638    {
4639      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4640      DONE;
4641    }
4644 (define_expand "fix_trunc<mode>di2"
4645   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4646                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4647               (clobber (reg:CC FLAGS_REG))])]
4648   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4650   if (TARGET_FISTTP
4651       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4652    {
4653      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4654      DONE;
4655    }
4656   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4657    {
4658      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4659      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4660      if (out != operands[0])
4661         emit_move_insn (operands[0], out);
4662      DONE;
4663    }
4666 ;; Signed conversion to SImode.
4668 (define_expand "fix_truncxfsi2"
4669   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4670                    (fix:SI (match_operand:XF 1 "register_operand")))
4671               (clobber (reg:CC FLAGS_REG))])]
4672   "TARGET_80387"
4674   if (TARGET_FISTTP)
4675    {
4676      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4677      DONE;
4678    }
4681 (define_expand "fix_trunc<mode>si2"
4682   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4683                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4684               (clobber (reg:CC FLAGS_REG))])]
4685   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4687   if (TARGET_FISTTP
4688       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4689    {
4690      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4691      DONE;
4692    }
4693   if (SSE_FLOAT_MODE_P (<MODE>mode))
4694    {
4695      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4696      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4697      if (out != operands[0])
4698         emit_move_insn (operands[0], out);
4699      DONE;
4700    }
4703 ;; Signed conversion to HImode.
4705 (define_expand "fix_trunc<mode>hi2"
4706   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4707                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4708               (clobber (reg:CC FLAGS_REG))])]
4709   "TARGET_80387
4710    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4712   if (TARGET_FISTTP)
4713    {
4714      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4715      DONE;
4716    }
4719 ;; Unsigned conversion to SImode.
4721 (define_expand "fixuns_trunc<mode>si2"
4722   [(parallel
4723     [(set (match_operand:SI 0 "register_operand")
4724           (unsigned_fix:SI
4725             (match_operand:MODEF 1 "nonimmediate_operand")))
4726      (use (match_dup 2))
4727      (clobber (match_scratch:<ssevecmode> 3))
4728      (clobber (match_scratch:<ssevecmode> 4))])]
4729   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4731   machine_mode mode = <MODE>mode;
4732   machine_mode vecmode = <ssevecmode>mode;
4733   REAL_VALUE_TYPE TWO31r;
4734   rtx two31;
4736   if (optimize_insn_for_size_p ())
4737     FAIL;
4739   real_ldexp (&TWO31r, &dconst1, 31);
4740   two31 = const_double_from_real_value (TWO31r, mode);
4741   two31 = ix86_build_const_vector (vecmode, true, two31);
4742   operands[2] = force_reg (vecmode, two31);
4745 (define_insn_and_split "*fixuns_trunc<mode>_1"
4746   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4747         (unsigned_fix:SI
4748           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4749    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4750    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4751    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4752   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4753    && optimize_function_for_speed_p (cfun)"
4754   "#"
4755   "&& reload_completed"
4756   [(const_int 0)]
4758   ix86_split_convert_uns_si_sse (operands);
4759   DONE;
4762 ;; Unsigned conversion to HImode.
4763 ;; Without these patterns, we'll try the unsigned SI conversion which
4764 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4766 (define_expand "fixuns_trunc<mode>hi2"
4767   [(set (match_dup 2)
4768         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4769    (set (match_operand:HI 0 "nonimmediate_operand")
4770         (subreg:HI (match_dup 2) 0))]
4771   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4772   "operands[2] = gen_reg_rtx (SImode);")
4774 ;; When SSE is available, it is always faster to use it!
4775 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4776   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4777         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4778   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4779    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4780   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4781   [(set_attr "type" "sseicvt")
4782    (set_attr "prefix" "maybe_vex")
4783    (set (attr "prefix_rex")
4784         (if_then_else
4785           (match_test "<SWI48:MODE>mode == DImode")
4786           (const_string "1")
4787           (const_string "*")))
4788    (set_attr "mode" "<MODEF:MODE>")
4789    (set_attr "athlon_decode" "double,vector")
4790    (set_attr "amdfam10_decode" "double,double")
4791    (set_attr "bdver1_decode" "double,double")])
4793 ;; Avoid vector decoded forms of the instruction.
4794 (define_peephole2
4795   [(match_scratch:MODEF 2 "x")
4796    (set (match_operand:SWI48 0 "register_operand")
4797         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4798   "TARGET_AVOID_VECTOR_DECODE
4799    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4800    && optimize_insn_for_speed_p ()"
4801   [(set (match_dup 2) (match_dup 1))
4802    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4804 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4805   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4806         (fix:SWI248x (match_operand 1 "register_operand")))]
4807   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4808    && TARGET_FISTTP
4809    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4810          && (TARGET_64BIT || <MODE>mode != DImode))
4811         && TARGET_SSE_MATH)
4812    && can_create_pseudo_p ()"
4813   "#"
4814   "&& 1"
4815   [(const_int 0)]
4817   if (memory_operand (operands[0], VOIDmode))
4818     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4819   else
4820     {
4821       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4822       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4823                                                             operands[1],
4824                                                             operands[2]));
4825     }
4826   DONE;
4828   [(set_attr "type" "fisttp")
4829    (set_attr "mode" "<MODE>")])
4831 (define_insn "fix_trunc<mode>_i387_fisttp"
4832   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4833         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4834    (clobber (match_scratch:XF 2 "=&1f"))]
4835   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4836    && TARGET_FISTTP
4837    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4838          && (TARGET_64BIT || <MODE>mode != DImode))
4839         && TARGET_SSE_MATH)"
4840   "* return output_fix_trunc (insn, operands, true);"
4841   [(set_attr "type" "fisttp")
4842    (set_attr "mode" "<MODE>")])
4844 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4845   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4846         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4847    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4848    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4849   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4850    && TARGET_FISTTP
4851    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4852         && (TARGET_64BIT || <MODE>mode != DImode))
4853         && TARGET_SSE_MATH)"
4854   "#"
4855   [(set_attr "type" "fisttp")
4856    (set_attr "mode" "<MODE>")])
4858 (define_split
4859   [(set (match_operand:SWI248x 0 "register_operand")
4860         (fix:SWI248x (match_operand 1 "register_operand")))
4861    (clobber (match_operand:SWI248x 2 "memory_operand"))
4862    (clobber (match_scratch 3))]
4863   "reload_completed"
4864   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4865               (clobber (match_dup 3))])
4866    (set (match_dup 0) (match_dup 2))])
4868 (define_split
4869   [(set (match_operand:SWI248x 0 "memory_operand")
4870         (fix:SWI248x (match_operand 1 "register_operand")))
4871    (clobber (match_operand:SWI248x 2 "memory_operand"))
4872    (clobber (match_scratch 3))]
4873   "reload_completed"
4874   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4875               (clobber (match_dup 3))])])
4877 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4878 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4879 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4880 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4881 ;; function in i386.c.
4882 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4883   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4884         (fix:SWI248x (match_operand 1 "register_operand")))
4885    (clobber (reg:CC FLAGS_REG))]
4886   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4887    && !TARGET_FISTTP
4888    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4889          && (TARGET_64BIT || <MODE>mode != DImode))
4890    && can_create_pseudo_p ()"
4891   "#"
4892   "&& 1"
4893   [(const_int 0)]
4895   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4897   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4898   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4899   if (memory_operand (operands[0], VOIDmode))
4900     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4901                                          operands[2], operands[3]));
4902   else
4903     {
4904       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4905       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4906                                                      operands[2], operands[3],
4907                                                      operands[4]));
4908     }
4909   DONE;
4911   [(set_attr "type" "fistp")
4912    (set_attr "i387_cw" "trunc")
4913    (set_attr "mode" "<MODE>")])
4915 (define_insn "fix_truncdi_i387"
4916   [(set (match_operand:DI 0 "memory_operand" "=m")
4917         (fix:DI (match_operand 1 "register_operand" "f")))
4918    (use (match_operand:HI 2 "memory_operand" "m"))
4919    (use (match_operand:HI 3 "memory_operand" "m"))
4920    (clobber (match_scratch:XF 4 "=&1f"))]
4921   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4922    && !TARGET_FISTTP
4923    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4924   "* return output_fix_trunc (insn, operands, false);"
4925   [(set_attr "type" "fistp")
4926    (set_attr "i387_cw" "trunc")
4927    (set_attr "mode" "DI")])
4929 (define_insn "fix_truncdi_i387_with_temp"
4930   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4931         (fix:DI (match_operand 1 "register_operand" "f,f")))
4932    (use (match_operand:HI 2 "memory_operand" "m,m"))
4933    (use (match_operand:HI 3 "memory_operand" "m,m"))
4934    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4935    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4936   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4937    && !TARGET_FISTTP
4938    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4939   "#"
4940   [(set_attr "type" "fistp")
4941    (set_attr "i387_cw" "trunc")
4942    (set_attr "mode" "DI")])
4944 (define_split
4945   [(set (match_operand:DI 0 "register_operand")
4946         (fix:DI (match_operand 1 "register_operand")))
4947    (use (match_operand:HI 2 "memory_operand"))
4948    (use (match_operand:HI 3 "memory_operand"))
4949    (clobber (match_operand:DI 4 "memory_operand"))
4950    (clobber (match_scratch 5))]
4951   "reload_completed"
4952   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4953               (use (match_dup 2))
4954               (use (match_dup 3))
4955               (clobber (match_dup 5))])
4956    (set (match_dup 0) (match_dup 4))])
4958 (define_split
4959   [(set (match_operand:DI 0 "memory_operand")
4960         (fix:DI (match_operand 1 "register_operand")))
4961    (use (match_operand:HI 2 "memory_operand"))
4962    (use (match_operand:HI 3 "memory_operand"))
4963    (clobber (match_operand:DI 4 "memory_operand"))
4964    (clobber (match_scratch 5))]
4965   "reload_completed"
4966   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4967               (use (match_dup 2))
4968               (use (match_dup 3))
4969               (clobber (match_dup 5))])])
4971 (define_insn "fix_trunc<mode>_i387"
4972   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4973         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4974    (use (match_operand:HI 2 "memory_operand" "m"))
4975    (use (match_operand:HI 3 "memory_operand" "m"))]
4976   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977    && !TARGET_FISTTP
4978    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4979   "* return output_fix_trunc (insn, operands, false);"
4980   [(set_attr "type" "fistp")
4981    (set_attr "i387_cw" "trunc")
4982    (set_attr "mode" "<MODE>")])
4984 (define_insn "fix_trunc<mode>_i387_with_temp"
4985   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4986         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4987    (use (match_operand:HI 2 "memory_operand" "m,m"))
4988    (use (match_operand:HI 3 "memory_operand" "m,m"))
4989    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4990   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4991    && !TARGET_FISTTP
4992    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4993   "#"
4994   [(set_attr "type" "fistp")
4995    (set_attr "i387_cw" "trunc")
4996    (set_attr "mode" "<MODE>")])
4998 (define_split
4999   [(set (match_operand:SWI24 0 "register_operand")
5000         (fix:SWI24 (match_operand 1 "register_operand")))
5001    (use (match_operand:HI 2 "memory_operand"))
5002    (use (match_operand:HI 3 "memory_operand"))
5003    (clobber (match_operand:SWI24 4 "memory_operand"))]
5004   "reload_completed"
5005   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5006               (use (match_dup 2))
5007               (use (match_dup 3))])
5008    (set (match_dup 0) (match_dup 4))])
5010 (define_split
5011   [(set (match_operand:SWI24 0 "memory_operand")
5012         (fix:SWI24 (match_operand 1 "register_operand")))
5013    (use (match_operand:HI 2 "memory_operand"))
5014    (use (match_operand:HI 3 "memory_operand"))
5015    (clobber (match_operand:SWI24 4 "memory_operand"))]
5016   "reload_completed"
5017   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5018               (use (match_dup 2))
5019               (use (match_dup 3))])])
5021 (define_insn "x86_fnstcw_1"
5022   [(set (match_operand:HI 0 "memory_operand" "=m")
5023         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5024   "TARGET_80387"
5025   "fnstcw\t%0"
5026   [(set (attr "length")
5027         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5028    (set_attr "mode" "HI")
5029    (set_attr "unit" "i387")
5030    (set_attr "bdver1_decode" "vector")])
5032 (define_insn "x86_fldcw_1"
5033   [(set (reg:HI FPCR_REG)
5034         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5035   "TARGET_80387"
5036   "fldcw\t%0"
5037   [(set (attr "length")
5038         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5039    (set_attr "mode" "HI")
5040    (set_attr "unit" "i387")
5041    (set_attr "athlon_decode" "vector")
5042    (set_attr "amdfam10_decode" "vector")
5043    (set_attr "bdver1_decode" "vector")])
5045 ;; Conversion between fixed point and floating point.
5047 ;; Even though we only accept memory inputs, the backend _really_
5048 ;; wants to be able to do this between registers.  Thankfully, LRA
5049 ;; will fix this up for us during register allocation.
5051 (define_insn "floathi<mode>2"
5052   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5053         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5054   "TARGET_80387
5055    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5056        || TARGET_MIX_SSE_I387)"
5057   "fild%Z1\t%1"
5058   [(set_attr "type" "fmov")
5059    (set_attr "mode" "<MODE>")
5060    (set_attr "znver1_decode" "double")
5061    (set_attr "fp_int_src" "true")])
5063 (define_insn "float<SWI48x:mode>xf2"
5064   [(set (match_operand:XF 0 "register_operand" "=f")
5065         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5066   "TARGET_80387"
5067   "fild%Z1\t%1"
5068   [(set_attr "type" "fmov")
5069    (set_attr "mode" "XF")
5070    (set_attr "znver1_decode" "double")
5071    (set_attr "fp_int_src" "true")])
5073 (define_expand "float<SWI48:mode><MODEF:mode>2"
5074   [(set (match_operand:MODEF 0 "register_operand")
5075         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5076   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5078   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5079       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5080     {
5081       rtx reg = gen_reg_rtx (XFmode);
5082       rtx (*insn)(rtx, rtx);
5084       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5086       if (<MODEF:MODE>mode == SFmode)
5087         insn = gen_truncxfsf2;
5088       else if (<MODEF:MODE>mode == DFmode)
5089         insn = gen_truncxfdf2;
5090       else
5091         gcc_unreachable ();
5093       emit_insn (insn (operands[0], reg));
5094       DONE;
5095     }
5098 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5099   [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5100         (float:MODEF
5101           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5102   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5103   "@
5104    fild%Z1\t%1
5105    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5106    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5107   [(set_attr "type" "fmov,sseicvt,sseicvt")
5108    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5109    (set_attr "mode" "<MODEF:MODE>")
5110    (set (attr "prefix_rex")
5111      (if_then_else
5112        (and (eq_attr "prefix" "maybe_vex")
5113             (match_test "<SWI48:MODE>mode == DImode"))
5114        (const_string "1")
5115        (const_string "*")))
5116    (set_attr "unit" "i387,*,*")
5117    (set_attr "athlon_decode" "*,double,direct")
5118    (set_attr "amdfam10_decode" "*,vector,double")
5119    (set_attr "bdver1_decode" "*,double,direct")
5120    (set_attr "znver1_decode" "double,*,*")
5121    (set_attr "fp_int_src" "true")
5122    (set (attr "enabled")
5123      (cond [(eq_attr "alternative" "0")
5124               (symbol_ref "TARGET_MIX_SSE_I387
5125                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5126                                                 <SWI48:MODE>mode)")
5127            ]
5128            (symbol_ref "true")))
5129    (set (attr "preferred_for_speed")
5130      (cond [(eq_attr "alternative" "1")
5131               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5132            (symbol_ref "true")))])
5134 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5135   [(set (match_operand:MODEF 0 "register_operand" "=f")
5136         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5137   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5138   "fild%Z1\t%1"
5139   [(set_attr "type" "fmov")
5140    (set_attr "mode" "<MODEF:MODE>")
5141    (set_attr "znver1_decode" "double")
5142    (set_attr "fp_int_src" "true")])
5144 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5145 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5146 ;; alternative in sse2_loadld.
5147 (define_split
5148   [(set (match_operand:MODEF 0 "sse_reg_operand")
5149         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5150   "TARGET_USE_VECTOR_CONVERTS
5151    && optimize_function_for_speed_p (cfun)
5152    && reload_completed
5153    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5154    && (!EXT_REX_SSE_REG_P (operands[0])
5155        || TARGET_AVX512VL)"
5156   [(const_int 0)]
5158   operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5159   operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5161   emit_insn (gen_sse2_loadld (operands[4],
5162                               CONST0_RTX (V4SImode), operands[1]));
5164   if (<ssevecmode>mode == V4SFmode)
5165     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5166   else
5167     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5168   DONE;
5171 ;; Avoid partial SSE register dependency stalls.  This splitter should split
5172 ;; late in the pass sequence (after register rename pass), so allocated
5173 ;; registers won't change anymore
5175 (define_split
5176   [(set (match_operand:MODEF 0 "sse_reg_operand")
5177         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5178   "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5179    && optimize_function_for_speed_p (cfun)
5180    && epilogue_completed
5181    && (!EXT_REX_SSE_REG_P (operands[0])
5182        || TARGET_AVX512VL)"
5183   [(set (match_dup 0)
5184         (vec_merge:<MODEF:ssevecmode>
5185           (vec_duplicate:<MODEF:ssevecmode>
5186             (float:MODEF
5187               (match_dup 1)))
5188           (match_dup 0)
5189           (const_int 1)))]
5191   const machine_mode vmode = <MODEF:ssevecmode>mode;
5193   operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5194   emit_move_insn (operands[0], CONST0_RTX (vmode));
5197 ;; Break partial reg stall for cvtsd2ss.  This splitter should split
5198 ;; late in the pass sequence (after register rename pass),
5199 ;; so allocated registers won't change anymore.
5201 (define_split
5202   [(set (match_operand:SF 0 "sse_reg_operand")
5203         (float_truncate:SF
5204           (match_operand:DF 1 "nonimmediate_operand")))]
5205   "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5206    && optimize_function_for_speed_p (cfun)
5207    && epilogue_completed
5208    && (!REG_P (operands[1])
5209        || REGNO (operands[0]) != REGNO (operands[1]))
5210    && (!EXT_REX_SSE_REG_P (operands[0])
5211        || TARGET_AVX512VL)"
5212   [(set (match_dup 0)
5213         (vec_merge:V4SF
5214           (vec_duplicate:V4SF
5215             (float_truncate:SF
5216               (match_dup 1)))
5217           (match_dup 0)
5218           (const_int 1)))]
5220   operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5221   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5224 ;; Break partial reg stall for cvtss2sd.  This splitter should split
5225 ;; late in the pass sequence (after register rename pass),
5226 ;; so allocated registers won't change anymore.
5228 (define_split
5229   [(set (match_operand:DF 0 "sse_reg_operand")
5230         (float_extend:DF
5231           (match_operand:SF 1 "nonimmediate_operand")))]
5232   "TARGET_SSE_PARTIAL_REG_DEPENDENCY
5233    && optimize_function_for_speed_p (cfun)
5234    && epilogue_completed
5235    && (!REG_P (operands[1])
5236        || REGNO (operands[0]) != REGNO (operands[1]))
5237    && (!EXT_REX_SSE_REG_P (operands[0])
5238        || TARGET_AVX512VL)"
5239   [(set (match_dup 0)
5240         (vec_merge:V2DF
5241           (vec_duplicate:V2DF
5242             (float_extend:DF
5243               (match_dup 1)))
5244           (match_dup 0)
5245           (const_int 1)))]
5247   operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5248   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5251 ;; Avoid store forwarding (partial memory) stall penalty
5252 ;; by passing DImode value through XMM registers.  */
5254 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5255   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5256         (float:X87MODEF
5257           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5258    (clobber (match_scratch:V4SI 3 "=X,x"))
5259    (clobber (match_scratch:V4SI 4 "=X,x"))
5260    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5261   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5262    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5263    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5264   "#"
5265   [(set_attr "type" "multi")
5266    (set_attr "mode" "<X87MODEF:MODE>")
5267    (set_attr "unit" "i387")
5268    (set_attr "fp_int_src" "true")])
5270 (define_split
5271   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5272         (float:X87MODEF (match_operand:DI 1 "register_operand")))
5273    (clobber (match_scratch:V4SI 3))
5274    (clobber (match_scratch:V4SI 4))
5275    (clobber (match_operand:DI 2 "memory_operand"))]
5276   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5277    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5278    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5279    && reload_completed"
5280   [(set (match_dup 2) (match_dup 3))
5281    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5283   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5284      Assemble the 64-bit DImode value in an xmm register.  */
5285   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5286                               gen_lowpart (SImode, operands[1])));
5287   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5288                               gen_highpart (SImode, operands[1])));
5289   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5290                                          operands[4]));
5292   operands[3] = gen_lowpart (DImode, operands[3]);
5295 (define_split
5296   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5297         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5298    (clobber (match_scratch:V4SI 3))
5299    (clobber (match_scratch:V4SI 4))
5300    (clobber (match_operand:DI 2 "memory_operand"))]
5301   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5302    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5303    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5304    && reload_completed"
5305   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5307 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5308   [(set (match_operand:MODEF 0 "register_operand")
5309         (unsigned_float:MODEF
5310           (match_operand:SWI12 1 "nonimmediate_operand")))]
5311   "!TARGET_64BIT
5312    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5314   operands[1] = convert_to_mode (SImode, operands[1], 1);
5315   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5316   DONE;
5319 ;; Avoid store forwarding (partial memory) stall penalty by extending
5320 ;; SImode value to DImode through XMM register instead of pushing two
5321 ;; SImode values to stack. Also note that fild loads from memory only.
5323 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5324   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5325         (unsigned_float:X87MODEF
5326           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5327    (clobber (match_scratch:DI 3 "=x"))
5328    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5329   "!TARGET_64BIT
5330    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5331    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5332   "#"
5333   "&& reload_completed"
5334   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5335    (set (match_dup 2) (match_dup 3))
5336    (set (match_dup 0)
5337         (float:X87MODEF (match_dup 2)))]
5338   ""
5339   [(set_attr "type" "multi")
5340    (set_attr "mode" "<MODE>")])
5342 (define_expand "floatunssi<mode>2"
5343   [(parallel
5344      [(set (match_operand:X87MODEF 0 "register_operand")
5345            (unsigned_float:X87MODEF
5346              (match_operand:SI 1 "nonimmediate_operand")))
5347       (clobber (match_scratch:DI 3))
5348       (clobber (match_dup 2))])]
5349   "!TARGET_64BIT
5350    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5352        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5354   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5355     {
5356       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5357       DONE;
5358     }
5359   else
5360     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5363 (define_expand "floatunsdisf2"
5364   [(use (match_operand:SF 0 "register_operand"))
5365    (use (match_operand:DI 1 "nonimmediate_operand"))]
5366   "TARGET_64BIT && TARGET_SSE_MATH"
5367   "x86_emit_floatuns (operands); DONE;")
5369 (define_expand "floatunsdidf2"
5370   [(use (match_operand:DF 0 "register_operand"))
5371    (use (match_operand:DI 1 "nonimmediate_operand"))]
5372   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5373    && TARGET_SSE2 && TARGET_SSE_MATH"
5375   if (TARGET_64BIT)
5376     x86_emit_floatuns (operands);
5377   else
5378     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5379   DONE;
5382 ;; Load effective address instructions
5384 (define_insn_and_split "*lea<mode>"
5385   [(set (match_operand:SWI48 0 "register_operand" "=r")
5386         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5387   ""
5389   if (SImode_address_operand (operands[1], VOIDmode))
5390     {
5391       gcc_assert (TARGET_64BIT);
5392       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5393     }
5394   else 
5395     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5397   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5398   [(const_int 0)]
5400   machine_mode mode = <MODE>mode;
5401   rtx pat;
5403   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5404      change operands[] array behind our back.  */
5405   pat = PATTERN (curr_insn);
5407   operands[0] = SET_DEST (pat);
5408   operands[1] = SET_SRC (pat);
5410   /* Emit all operations in SImode for zero-extended addresses.  */
5411   if (SImode_address_operand (operands[1], VOIDmode))
5412     mode = SImode;
5414   ix86_split_lea_for_addr (curr_insn, operands, mode);
5416   /* Zero-extend return register to DImode for zero-extended addresses.  */
5417   if (mode != <MODE>mode)
5418     emit_insn (gen_zero_extendsidi2
5419                (operands[0], gen_lowpart (mode, operands[0])));
5421   DONE;
5423   [(set_attr "type" "lea")
5424    (set (attr "mode")
5425      (if_then_else
5426        (match_operand 1 "SImode_address_operand")
5427        (const_string "SI")
5428        (const_string "<MODE>")))])
5430 ;; Add instructions
5432 (define_expand "add<mode>3"
5433   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5434         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5435                     (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5436   ""
5437   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5439 (define_insn_and_split "*add<dwi>3_doubleword"
5440   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5441         (plus:<DWI>
5442           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5443           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5444                                                         "ro<di>,r<di>")))
5445    (clobber (reg:CC FLAGS_REG))]
5446   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5447   "#"
5448   "reload_completed"
5449   [(parallel [(set (reg:CCC FLAGS_REG)
5450                    (compare:CCC
5451                      (plus:DWIH (match_dup 1) (match_dup 2))
5452                      (match_dup 1)))
5453               (set (match_dup 0)
5454                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5455    (parallel [(set (match_dup 3)
5456                    (plus:DWIH
5457                      (plus:DWIH
5458                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5459                        (match_dup 4))
5460                      (match_dup 5)))
5461               (clobber (reg:CC FLAGS_REG))])]
5463   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5464   if (operands[2] == const0_rtx)
5465     {
5466       ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5467       DONE;
5468     }
5471 (define_insn "*add<mode>_1"
5472   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5473         (plus:SWI48
5474           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5475           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5476    (clobber (reg:CC FLAGS_REG))]
5477   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5479   switch (get_attr_type (insn))
5480     {
5481     case TYPE_LEA:
5482       return "#";
5484     case TYPE_INCDEC:
5485       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5486       if (operands[2] == const1_rtx)
5487         return "inc{<imodesuffix>}\t%0";
5488       else
5489         {
5490           gcc_assert (operands[2] == constm1_rtx);
5491           return "dec{<imodesuffix>}\t%0";
5492         }
5494     default:
5495       /* For most processors, ADD is faster than LEA.  This alternative
5496          was added to use ADD as much as possible.  */
5497       if (which_alternative == 2)
5498         std::swap (operands[1], operands[2]);
5499         
5500       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5501       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5502         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5504       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5505     }
5507   [(set (attr "type")
5508      (cond [(eq_attr "alternative" "3")
5509               (const_string "lea")
5510             (match_operand:SWI48 2 "incdec_operand")
5511               (const_string "incdec")
5512            ]
5513            (const_string "alu")))
5514    (set (attr "length_immediate")
5515       (if_then_else
5516         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5517         (const_string "1")
5518         (const_string "*")))
5519    (set_attr "mode" "<MODE>")])
5521 ;; It may seem that nonimmediate operand is proper one for operand 1.
5522 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5523 ;; we take care in ix86_binary_operator_ok to not allow two memory
5524 ;; operands so proper swapping will be done in reload.  This allow
5525 ;; patterns constructed from addsi_1 to match.
5527 (define_insn "addsi_1_zext"
5528   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5529         (zero_extend:DI
5530           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5531                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5532    (clobber (reg:CC FLAGS_REG))]
5533   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5535   switch (get_attr_type (insn))
5536     {
5537     case TYPE_LEA:
5538       return "#";
5540     case TYPE_INCDEC:
5541       if (operands[2] == const1_rtx)
5542         return "inc{l}\t%k0";
5543       else
5544         {
5545           gcc_assert (operands[2] == constm1_rtx);
5546           return "dec{l}\t%k0";
5547         }
5549     default:
5550       /* For most processors, ADD is faster than LEA.  This alternative
5551          was added to use ADD as much as possible.  */
5552       if (which_alternative == 1)
5553         std::swap (operands[1], operands[2]);
5555       if (x86_maybe_negate_const_int (&operands[2], SImode))
5556         return "sub{l}\t{%2, %k0|%k0, %2}";
5558       return "add{l}\t{%2, %k0|%k0, %2}";
5559     }
5561   [(set (attr "type")
5562      (cond [(eq_attr "alternative" "2")
5563               (const_string "lea")
5564             (match_operand:SI 2 "incdec_operand")
5565               (const_string "incdec")
5566            ]
5567            (const_string "alu")))
5568    (set (attr "length_immediate")
5569       (if_then_else
5570         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5571         (const_string "1")
5572         (const_string "*")))
5573    (set_attr "mode" "SI")])
5575 (define_insn "*addhi_1"
5576   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5577         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5578                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5579    (clobber (reg:CC FLAGS_REG))]
5580   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5582   switch (get_attr_type (insn))
5583     {
5584     case TYPE_LEA:
5585       return "#";
5587     case TYPE_INCDEC:
5588       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5589       if (operands[2] == const1_rtx)
5590         return "inc{w}\t%0";
5591       else
5592         {
5593           gcc_assert (operands[2] == constm1_rtx);
5594           return "dec{w}\t%0";
5595         }
5597     default:
5598       /* For most processors, ADD is faster than LEA.  This alternative
5599          was added to use ADD as much as possible.  */
5600       if (which_alternative == 2)
5601         std::swap (operands[1], operands[2]);
5603       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5604       if (x86_maybe_negate_const_int (&operands[2], HImode))
5605         return "sub{w}\t{%2, %0|%0, %2}";
5607       return "add{w}\t{%2, %0|%0, %2}";
5608     }
5610   [(set (attr "type")
5611      (cond [(eq_attr "alternative" "3")
5612               (const_string "lea")
5613             (match_operand:HI 2 "incdec_operand")
5614               (const_string "incdec")
5615            ]
5616            (const_string "alu")))
5617    (set (attr "length_immediate")
5618       (if_then_else
5619         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5620         (const_string "1")
5621         (const_string "*")))
5622    (set_attr "mode" "HI,HI,HI,SI")])
5624 (define_insn "*addqi_1"
5625   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5626         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5627                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5628    (clobber (reg:CC FLAGS_REG))]
5629   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5631   bool widen = (get_attr_mode (insn) != MODE_QI);
5633   switch (get_attr_type (insn))
5634     {
5635     case TYPE_LEA:
5636       return "#";
5638     case TYPE_INCDEC:
5639       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5640       if (operands[2] == const1_rtx)
5641         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5642       else
5643         {
5644           gcc_assert (operands[2] == constm1_rtx);
5645           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5646         }
5648     default:
5649       /* For most processors, ADD is faster than LEA.  These alternatives
5650          were added to use ADD as much as possible.  */
5651       if (which_alternative == 2 || which_alternative == 4)
5652         std::swap (operands[1], operands[2]);
5654       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5655       if (x86_maybe_negate_const_int (&operands[2], QImode))
5656         {
5657           if (widen)
5658             return "sub{l}\t{%2, %k0|%k0, %2}";
5659           else
5660             return "sub{b}\t{%2, %0|%0, %2}";
5661         }
5662       if (widen)
5663         return "add{l}\t{%k2, %k0|%k0, %k2}";
5664       else
5665         return "add{b}\t{%2, %0|%0, %2}";
5666     }
5668   [(set (attr "type")
5669      (cond [(eq_attr "alternative" "5")
5670               (const_string "lea")
5671             (match_operand:QI 2 "incdec_operand")
5672               (const_string "incdec")
5673            ]
5674            (const_string "alu")))
5675    (set (attr "length_immediate")
5676       (if_then_else
5677         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5678         (const_string "1")
5679         (const_string "*")))
5680    (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5681    ;; Potential partial reg stall on alternatives 3 and 4.
5682    (set (attr "preferred_for_speed")
5683      (cond [(eq_attr "alternative" "3,4")
5684               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5685            (symbol_ref "true")))])
5687 (define_insn "*addqi_1_slp"
5688   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5689         (plus:QI (match_dup 0)
5690                  (match_operand:QI 1 "general_operand" "qn,qm")))
5691    (clobber (reg:CC FLAGS_REG))]
5692   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5693    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5695   switch (get_attr_type (insn))
5696     {
5697     case TYPE_INCDEC:
5698       if (operands[1] == const1_rtx)
5699         return "inc{b}\t%0";
5700       else
5701         {
5702           gcc_assert (operands[1] == constm1_rtx);
5703           return "dec{b}\t%0";
5704         }
5706     default:
5707       if (x86_maybe_negate_const_int (&operands[1], QImode))
5708         return "sub{b}\t{%1, %0|%0, %1}";
5710       return "add{b}\t{%1, %0|%0, %1}";
5711     }
5713   [(set (attr "type")
5714      (if_then_else (match_operand:QI 1 "incdec_operand")
5715         (const_string "incdec")
5716         (const_string "alu1")))
5717    (set (attr "memory")
5718      (if_then_else (match_operand 1 "memory_operand")
5719         (const_string "load")
5720         (const_string "none")))
5721    (set_attr "mode" "QI")])
5723 ;; Split non destructive adds if we cannot use lea.
5724 (define_split
5725   [(set (match_operand:SWI48 0 "register_operand")
5726         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5727                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5728    (clobber (reg:CC FLAGS_REG))]
5729   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5730   [(set (match_dup 0) (match_dup 1))
5731    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5732               (clobber (reg:CC FLAGS_REG))])])
5734 ;; Split non destructive adds if we cannot use lea.
5735 (define_split
5736   [(set (match_operand:DI 0 "register_operand")
5737         (zero_extend:DI
5738           (plus:SI (match_operand:SI 1 "register_operand")
5739                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5740    (clobber (reg:CC FLAGS_REG))]
5741   "TARGET_64BIT
5742    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5743   [(set (match_dup 3) (match_dup 1))
5744    (parallel [(set (match_dup 0)
5745                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5746               (clobber (reg:CC FLAGS_REG))])]
5747   "operands[3] = gen_lowpart (SImode, operands[0]);")
5749 ;; Convert add to the lea pattern to avoid flags dependency.
5750 (define_split
5751   [(set (match_operand:SWI 0 "register_operand")
5752         (plus:SWI (match_operand:SWI 1 "register_operand")
5753                   (match_operand:SWI 2 "<nonmemory_operand>")))
5754    (clobber (reg:CC FLAGS_REG))]
5755   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5756   [(set (match_dup 0)
5757         (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5759   if (<MODE>mode != <LEAMODE>mode)
5760     {
5761       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5762       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5763       operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5764     }
5767 ;; Convert add to the lea pattern to avoid flags dependency.
5768 (define_split
5769   [(set (match_operand:DI 0 "register_operand")
5770         (zero_extend:DI
5771           (plus:SI (match_operand:SI 1 "register_operand")
5772                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5773    (clobber (reg:CC FLAGS_REG))]
5774   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5775   [(set (match_dup 0)
5776         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5778 (define_insn "*add<mode>_2"
5779   [(set (reg FLAGS_REG)
5780         (compare
5781           (plus:SWI
5782             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5783             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5784           (const_int 0)))
5785    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5786         (plus:SWI (match_dup 1) (match_dup 2)))]
5787   "ix86_match_ccmode (insn, CCGOCmode)
5788    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5790   switch (get_attr_type (insn))
5791     {
5792     case TYPE_INCDEC:
5793       if (operands[2] == const1_rtx)
5794         return "inc{<imodesuffix>}\t%0";
5795       else
5796         {
5797           gcc_assert (operands[2] == constm1_rtx);
5798           return "dec{<imodesuffix>}\t%0";
5799         }
5801     default:
5802       if (which_alternative == 2)
5803         std::swap (operands[1], operands[2]);
5804         
5805       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5806       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5807         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5809       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5810     }
5812   [(set (attr "type")
5813      (if_then_else (match_operand:SWI 2 "incdec_operand")
5814         (const_string "incdec")
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" "<MODE>")])
5823 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5824 (define_insn "*addsi_2_zext"
5825   [(set (reg FLAGS_REG)
5826         (compare
5827           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5828                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5829           (const_int 0)))
5830    (set (match_operand:DI 0 "register_operand" "=r,r")
5831         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5832   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5833    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5835   switch (get_attr_type (insn))
5836     {
5837     case TYPE_INCDEC:
5838       if (operands[2] == const1_rtx)
5839         return "inc{l}\t%k0";
5840       else
5841         {
5842           gcc_assert (operands[2] == constm1_rtx);
5843           return "dec{l}\t%k0";
5844         }
5846     default:
5847       if (which_alternative == 1)
5848         std::swap (operands[1], operands[2]);
5850       if (x86_maybe_negate_const_int (&operands[2], SImode))
5851         return "sub{l}\t{%2, %k0|%k0, %2}";
5853       return "add{l}\t{%2, %k0|%k0, %2}";
5854     }
5856   [(set (attr "type")
5857      (if_then_else (match_operand:SI 2 "incdec_operand")
5858         (const_string "incdec")
5859         (const_string "alu")))
5860    (set (attr "length_immediate")
5861       (if_then_else
5862         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5863         (const_string "1")
5864         (const_string "*")))
5865    (set_attr "mode" "SI")])
5867 (define_insn "*add<mode>_3"
5868   [(set (reg FLAGS_REG)
5869         (compare
5870           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5871           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5872    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5873   "ix86_match_ccmode (insn, CCZmode)
5874    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5876   switch (get_attr_type (insn))
5877     {
5878     case TYPE_INCDEC:
5879       if (operands[2] == const1_rtx)
5880         return "inc{<imodesuffix>}\t%0";
5881       else
5882         {
5883           gcc_assert (operands[2] == constm1_rtx);
5884           return "dec{<imodesuffix>}\t%0";
5885         }
5887     default:
5888       if (which_alternative == 1)
5889         std::swap (operands[1], operands[2]);
5891       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5892       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5893         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5895       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5896     }
5898   [(set (attr "type")
5899      (if_then_else (match_operand:SWI 2 "incdec_operand")
5900         (const_string "incdec")
5901         (const_string "alu")))
5902    (set (attr "length_immediate")
5903       (if_then_else
5904         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5905         (const_string "1")
5906         (const_string "*")))
5907    (set_attr "mode" "<MODE>")])
5909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5910 (define_insn "*addsi_3_zext"
5911   [(set (reg FLAGS_REG)
5912         (compare
5913           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5914           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5915    (set (match_operand:DI 0 "register_operand" "=r,r")
5916         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5917   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5918    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5920   switch (get_attr_type (insn))
5921     {
5922     case TYPE_INCDEC:
5923       if (operands[2] == const1_rtx)
5924         return "inc{l}\t%k0";
5925       else
5926         {
5927           gcc_assert (operands[2] == constm1_rtx);
5928           return "dec{l}\t%k0";
5929         }
5931     default:
5932       if (which_alternative == 1)
5933         std::swap (operands[1], operands[2]);
5935       if (x86_maybe_negate_const_int (&operands[2], SImode))
5936         return "sub{l}\t{%2, %k0|%k0, %2}";
5938       return "add{l}\t{%2, %k0|%k0, %2}";
5939     }
5941   [(set (attr "type")
5942      (if_then_else (match_operand:SI 2 "incdec_operand")
5943         (const_string "incdec")
5944         (const_string "alu")))
5945    (set (attr "length_immediate")
5946       (if_then_else
5947         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5948         (const_string "1")
5949         (const_string "*")))
5950    (set_attr "mode" "SI")])
5952 ; For comparisons against 1, -1 and 128, we may generate better code
5953 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5954 ; is matched then.  We can't accept general immediate, because for
5955 ; case of overflows,  the result is messed up.
5956 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5957 ; only for comparisons not depending on it.
5959 (define_insn "*adddi_4"
5960   [(set (reg FLAGS_REG)
5961         (compare
5962           (match_operand:DI 1 "nonimmediate_operand" "0")
5963           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5964    (clobber (match_scratch:DI 0 "=rm"))]
5965   "TARGET_64BIT
5966    && ix86_match_ccmode (insn, CCGCmode)"
5968   switch (get_attr_type (insn))
5969     {
5970     case TYPE_INCDEC:
5971       if (operands[2] == constm1_rtx)
5972         return "inc{q}\t%0";
5973       else
5974         {
5975           gcc_assert (operands[2] == const1_rtx);
5976           return "dec{q}\t%0";
5977         }
5979     default:
5980       if (x86_maybe_negate_const_int (&operands[2], DImode))
5981         return "add{q}\t{%2, %0|%0, %2}";
5983       return "sub{q}\t{%2, %0|%0, %2}";
5984     }
5986   [(set (attr "type")
5987      (if_then_else (match_operand:DI 2 "incdec_operand")
5988         (const_string "incdec")
5989         (const_string "alu")))
5990    (set (attr "length_immediate")
5991       (if_then_else
5992         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5993         (const_string "1")
5994         (const_string "*")))
5995    (set_attr "mode" "DI")])
5997 ; For comparisons against 1, -1 and 128, we may generate better code
5998 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5999 ; is matched then.  We can't accept general immediate, because for
6000 ; case of overflows,  the result is messed up.
6001 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6002 ; only for comparisons not depending on it.
6004 (define_insn "*add<mode>_4"
6005   [(set (reg FLAGS_REG)
6006         (compare
6007           (match_operand:SWI124 1 "nonimmediate_operand" "0")
6008           (match_operand:SWI124 2 "const_int_operand" "n")))
6009    (clobber (match_scratch:SWI124 0 "=<r>m"))]
6010   "ix86_match_ccmode (insn, CCGCmode)"
6012   switch (get_attr_type (insn))
6013     {
6014     case TYPE_INCDEC:
6015       if (operands[2] == constm1_rtx)
6016         return "inc{<imodesuffix>}\t%0";
6017       else
6018         {
6019           gcc_assert (operands[2] == const1_rtx);
6020           return "dec{<imodesuffix>}\t%0";
6021         }
6023     default:
6024       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6025         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6027       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6028     }
6030   [(set (attr "type")
6031      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6032         (const_string "incdec")
6033         (const_string "alu")))
6034    (set (attr "length_immediate")
6035       (if_then_else
6036         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6037         (const_string "1")
6038         (const_string "*")))
6039    (set_attr "mode" "<MODE>")])
6041 (define_insn "*add<mode>_5"
6042   [(set (reg FLAGS_REG)
6043         (compare
6044           (plus:SWI
6045             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6046             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6047           (const_int 0)))
6048    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6049   "ix86_match_ccmode (insn, CCGOCmode)
6050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6052   switch (get_attr_type (insn))
6053     {
6054     case TYPE_INCDEC:
6055       if (operands[2] == const1_rtx)
6056         return "inc{<imodesuffix>}\t%0";
6057       else
6058         {
6059           gcc_assert (operands[2] == constm1_rtx);
6060           return "dec{<imodesuffix>}\t%0";
6061         }
6063     default:
6064       if (which_alternative == 1)
6065         std::swap (operands[1], operands[2]);
6067       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6068       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6069         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6071       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6072     }
6074   [(set (attr "type")
6075      (if_then_else (match_operand:SWI 2 "incdec_operand")
6076         (const_string "incdec")
6077         (const_string "alu")))
6078    (set (attr "length_immediate")
6079       (if_then_else
6080         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6081         (const_string "1")
6082         (const_string "*")))
6083    (set_attr "mode" "<MODE>")])
6085 (define_insn "addqi_ext_1"
6086   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
6087                          (const_int 8)
6088                          (const_int 8))
6089         (plus:SI
6090           (zero_extract:SI
6091             (match_operand 1 "ext_register_operand" "0,0")
6092             (const_int 8)
6093             (const_int 8))
6094           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
6095    (clobber (reg:CC FLAGS_REG))]
6096   ""
6098   switch (get_attr_type (insn))
6099     {
6100     case TYPE_INCDEC:
6101       if (operands[2] == const1_rtx)
6102         return "inc{b}\t%h0";
6103       else
6104         {
6105           gcc_assert (operands[2] == constm1_rtx);
6106           return "dec{b}\t%h0";
6107         }
6109     default:
6110       return "add{b}\t{%2, %h0|%h0, %2}";
6111     }
6113   [(set_attr "isa" "*,nox64")
6114    (set (attr "type")
6115      (if_then_else (match_operand:QI 2 "incdec_operand")
6116         (const_string "incdec")
6117         (const_string "alu")))
6118    (set_attr "modrm" "1")
6119    (set_attr "mode" "QI")])
6121 (define_insn "*addqi_ext_2"
6122   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6123                          (const_int 8)
6124                          (const_int 8))
6125         (plus:SI
6126           (zero_extract:SI
6127             (match_operand 1 "ext_register_operand" "%0")
6128             (const_int 8)
6129             (const_int 8))
6130           (zero_extract:SI
6131             (match_operand 2 "ext_register_operand" "Q")
6132             (const_int 8)
6133             (const_int 8))))
6134    (clobber (reg:CC FLAGS_REG))]
6135   ""
6136   "add{b}\t{%h2, %h0|%h0, %h2}"
6137   [(set_attr "type" "alu")
6138    (set_attr "mode" "QI")])
6140 ;; Add with jump on overflow.
6141 (define_expand "addv<mode>4"
6142   [(parallel [(set (reg:CCO FLAGS_REG)
6143                    (eq:CCO (plus:<DWI>
6144                               (sign_extend:<DWI>
6145                                  (match_operand:SWI 1 "nonimmediate_operand"))
6146                               (match_dup 4))
6147                            (sign_extend:<DWI>
6148                               (plus:SWI (match_dup 1)
6149                                         (match_operand:SWI 2
6150                                            "<general_operand>")))))
6151               (set (match_operand:SWI 0 "register_operand")
6152                    (plus:SWI (match_dup 1) (match_dup 2)))])
6153    (set (pc) (if_then_else
6154                (eq (reg:CCO FLAGS_REG) (const_int 0))
6155                (label_ref (match_operand 3))
6156                (pc)))]
6157   ""
6159   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6160   if (CONST_INT_P (operands[2]))
6161     operands[4] = operands[2];
6162   else
6163     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6166 (define_insn "*addv<mode>4"
6167   [(set (reg:CCO FLAGS_REG)
6168         (eq:CCO (plus:<DWI>
6169                    (sign_extend:<DWI>
6170                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6171                    (sign_extend:<DWI>
6172                       (match_operand:SWI 2 "<general_sext_operand>"
6173                                            "<r>mWe,<r>We")))
6174                 (sign_extend:<DWI>
6175                    (plus:SWI (match_dup 1) (match_dup 2)))))
6176    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6177         (plus:SWI (match_dup 1) (match_dup 2)))]
6178   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6179   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6180   [(set_attr "type" "alu")
6181    (set_attr "mode" "<MODE>")])
6183 (define_insn "*addv<mode>4_1"
6184   [(set (reg:CCO FLAGS_REG)
6185         (eq:CCO (plus:<DWI>
6186                    (sign_extend:<DWI>
6187                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6188                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6189                 (sign_extend:<DWI>
6190                    (plus:SWI (match_dup 1)
6191                              (match_operand:SWI 2 "x86_64_immediate_operand"
6192                                                   "<i>")))))
6193    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6194         (plus:SWI (match_dup 1) (match_dup 2)))]
6195   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6196    && CONST_INT_P (operands[2])
6197    && INTVAL (operands[2]) == INTVAL (operands[3])"
6198   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6199   [(set_attr "type" "alu")
6200    (set_attr "mode" "<MODE>")
6201    (set (attr "length_immediate")
6202         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6203                   (const_string "1")
6204                (match_test "<MODE_SIZE> == 8")
6205                   (const_string "4")]
6206               (const_string "<MODE_SIZE>")))])
6208 (define_expand "uaddv<mode>4"
6209   [(parallel [(set (reg:CCC FLAGS_REG)
6210                    (compare:CCC
6211                      (plus:SWI
6212                        (match_operand:SWI 1 "nonimmediate_operand")
6213                        (match_operand:SWI 2 "<general_operand>"))
6214                      (match_dup 1)))
6215               (set (match_operand:SWI 0 "register_operand")
6216                    (plus:SWI (match_dup 1) (match_dup 2)))])
6217    (set (pc) (if_then_else
6218                (ltu (reg:CCC FLAGS_REG) (const_int 0))
6219                (label_ref (match_operand 3))
6220                (pc)))]
6221   ""
6222   "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6224 ;; The lea patterns for modes less than 32 bits need to be matched by
6225 ;; several insns converted to real lea by splitters.
6227 (define_insn_and_split "*lea<mode>_general_1"
6228   [(set (match_operand:SWI12 0 "register_operand" "=r")
6229         (plus:SWI12
6230           (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6231                       (match_operand:SWI12 2 "register_operand" "r"))
6232           (match_operand:SWI12 3 "immediate_operand" "i")))]
6233   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6234   "#"
6235   "&& reload_completed"
6236   [(set (match_dup 0)
6237         (plus:SI
6238           (plus:SI (match_dup 1) (match_dup 2))
6239           (match_dup 3)))]
6241   operands[0] = gen_lowpart (SImode, operands[0]);
6242   operands[1] = gen_lowpart (SImode, operands[1]);
6243   operands[2] = gen_lowpart (SImode, operands[2]);
6244   operands[3] = gen_lowpart (SImode, operands[3]);
6246   [(set_attr "type" "lea")
6247    (set_attr "mode" "SI")])
6249 (define_insn_and_split "*lea<mode>_general_2"
6250   [(set (match_operand:SWI12 0 "register_operand" "=r")
6251         (plus:SWI12
6252           (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6253                       (match_operand 2 "const248_operand" "n"))
6254           (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6255   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6256   "#"
6257   "&& reload_completed"
6258   [(set (match_dup 0)
6259         (plus:SI
6260           (mult:SI (match_dup 1) (match_dup 2))
6261           (match_dup 3)))]
6263   operands[0] = gen_lowpart (SImode, operands[0]);
6264   operands[1] = gen_lowpart (SImode, operands[1]);
6265   operands[3] = gen_lowpart (SImode, operands[3]);
6267   [(set_attr "type" "lea")
6268    (set_attr "mode" "SI")])
6270 (define_insn_and_split "*lea<mode>_general_3"
6271   [(set (match_operand:SWI12 0 "register_operand" "=r")
6272         (plus:SWI12
6273           (plus:SWI12
6274             (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6275                         (match_operand 2 "const248_operand" "n"))
6276             (match_operand:SWI12 3 "register_operand" "r"))
6277           (match_operand:SWI12 4 "immediate_operand" "i")))]
6278   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6279   "#"
6280   "&& reload_completed"
6281   [(set (match_dup 0)
6282         (plus:SI
6283           (plus:SI
6284             (mult:SI (match_dup 1) (match_dup 2))
6285             (match_dup 3))
6286           (match_dup 4)))]
6288   operands[0] = gen_lowpart (SImode, operands[0]);
6289   operands[1] = gen_lowpart (SImode, operands[1]);
6290   operands[3] = gen_lowpart (SImode, operands[3]);
6291   operands[4] = gen_lowpart (SImode, operands[4]);
6293   [(set_attr "type" "lea")
6294    (set_attr "mode" "SI")])
6296 (define_insn_and_split "*lea<mode>_general_4"
6297   [(set (match_operand:SWI12 0 "register_operand" "=r")
6298         (any_or:SWI12
6299           (ashift:SWI12
6300             (match_operand:SWI12 1 "index_register_operand" "l")
6301             (match_operand 2 "const_0_to_3_operand" "n"))
6302           (match_operand 3 "const_int_operand" "n")))]
6303   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6304    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6305        < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6306   "#"
6307   "&& reload_completed"
6308   [(set (match_dup 0)
6309         (plus:SI
6310           (mult:SI (match_dup 1) (match_dup 2))
6311           (match_dup 3)))]
6313   operands[0] = gen_lowpart (SImode, operands[0]);
6314   operands[1] = gen_lowpart (SImode, operands[1]);
6315   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6317   [(set_attr "type" "lea")
6318    (set_attr "mode" "SI")])
6320 (define_insn_and_split "*lea<mode>_general_4"
6321   [(set (match_operand:SWI48 0 "register_operand" "=r")
6322         (any_or:SWI48
6323           (ashift:SWI48
6324             (match_operand:SWI48 1 "index_register_operand" "l")
6325             (match_operand 2 "const_0_to_3_operand" "n"))
6326           (match_operand 3 "const_int_operand" "n")))]
6327   "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6328    < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6329   "#"
6330   "&& reload_completed"
6331   [(set (match_dup 0)
6332         (plus:SWI48
6333           (mult:SWI48 (match_dup 1) (match_dup 2))
6334           (match_dup 3)))]
6335   "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6336   [(set_attr "type" "lea")
6337    (set_attr "mode" "<MODE>")])
6339 ;; Subtract instructions
6341 (define_expand "sub<mode>3"
6342   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6343         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6344                      (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6345   ""
6346   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6348 (define_insn_and_split "*sub<dwi>3_doubleword"
6349   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6350         (minus:<DWI>
6351           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6352           (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6353                                                         "ro<di>,r<di>")))
6354    (clobber (reg:CC FLAGS_REG))]
6355   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6356   "#"
6357   "reload_completed"
6358   [(parallel [(set (reg:CC FLAGS_REG)
6359                    (compare:CC (match_dup 1) (match_dup 2)))
6360               (set (match_dup 0)
6361                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6362    (parallel [(set (match_dup 3)
6363                    (minus:DWIH
6364                      (minus:DWIH
6365                        (match_dup 4)
6366                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6367                      (match_dup 5)))
6368               (clobber (reg:CC FLAGS_REG))])]
6370   split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6371   if (operands[2] == const0_rtx)
6372     {
6373       ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6374       DONE;
6375     }
6378 (define_insn "*sub<mode>_1"
6379   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6380         (minus:SWI
6381           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6382           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6383    (clobber (reg:CC FLAGS_REG))]
6384   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6385   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6386   [(set_attr "type" "alu")
6387    (set_attr "mode" "<MODE>")])
6389 (define_insn "*subsi_1_zext"
6390   [(set (match_operand:DI 0 "register_operand" "=r")
6391         (zero_extend:DI
6392           (minus:SI (match_operand:SI 1 "register_operand" "0")
6393                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6394    (clobber (reg:CC FLAGS_REG))]
6395   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6396   "sub{l}\t{%2, %k0|%k0, %2}"
6397   [(set_attr "type" "alu")
6398    (set_attr "mode" "SI")])
6400 (define_insn "*subqi_1_slp"
6401   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6402         (minus:QI (match_dup 0)
6403                   (match_operand:QI 1 "general_operand" "qn,qm")))
6404    (clobber (reg:CC FLAGS_REG))]
6405   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6406    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6407   "sub{b}\t{%1, %0|%0, %1}"
6408   [(set_attr "type" "alu1")
6409    (set_attr "mode" "QI")])
6411 (define_insn "*sub<mode>_2"
6412   [(set (reg FLAGS_REG)
6413         (compare
6414           (minus:SWI
6415             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6416             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6417           (const_int 0)))
6418    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6419         (minus:SWI (match_dup 1) (match_dup 2)))]
6420   "ix86_match_ccmode (insn, CCGOCmode)
6421    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6422   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6423   [(set_attr "type" "alu")
6424    (set_attr "mode" "<MODE>")])
6426 (define_insn "*subsi_2_zext"
6427   [(set (reg FLAGS_REG)
6428         (compare
6429           (minus:SI (match_operand:SI 1 "register_operand" "0")
6430                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6431           (const_int 0)))
6432    (set (match_operand:DI 0 "register_operand" "=r")
6433         (zero_extend:DI
6434           (minus:SI (match_dup 1)
6435                     (match_dup 2))))]
6436   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6437    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6438   "sub{l}\t{%2, %k0|%k0, %2}"
6439   [(set_attr "type" "alu")
6440    (set_attr "mode" "SI")])
6442 ;; Subtract with jump on overflow.
6443 (define_expand "subv<mode>4"
6444   [(parallel [(set (reg:CCO FLAGS_REG)
6445                    (eq:CCO (minus:<DWI>
6446                               (sign_extend:<DWI>
6447                                  (match_operand:SWI 1 "nonimmediate_operand"))
6448                               (match_dup 4))
6449                            (sign_extend:<DWI>
6450                               (minus:SWI (match_dup 1)
6451                                          (match_operand:SWI 2
6452                                             "<general_operand>")))))
6453               (set (match_operand:SWI 0 "register_operand")
6454                    (minus:SWI (match_dup 1) (match_dup 2)))])
6455    (set (pc) (if_then_else
6456                (eq (reg:CCO FLAGS_REG) (const_int 0))
6457                (label_ref (match_operand 3))
6458                (pc)))]
6459   ""
6461   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6462   if (CONST_INT_P (operands[2]))
6463     operands[4] = operands[2];
6464   else
6465     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6468 (define_insn "*subv<mode>4"
6469   [(set (reg:CCO FLAGS_REG)
6470         (eq:CCO (minus:<DWI>
6471                    (sign_extend:<DWI>
6472                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6473                    (sign_extend:<DWI>
6474                       (match_operand:SWI 2 "<general_sext_operand>"
6475                                            "<r>We,<r>m")))
6476                 (sign_extend:<DWI>
6477                    (minus:SWI (match_dup 1) (match_dup 2)))))
6478    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6479         (minus:SWI (match_dup 1) (match_dup 2)))]
6480   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6481   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6482   [(set_attr "type" "alu")
6483    (set_attr "mode" "<MODE>")])
6485 (define_insn "*subv<mode>4_1"
6486   [(set (reg:CCO FLAGS_REG)
6487         (eq:CCO (minus:<DWI>
6488                    (sign_extend:<DWI>
6489                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6490                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6491                 (sign_extend:<DWI>
6492                    (minus:SWI (match_dup 1)
6493                               (match_operand:SWI 2 "x86_64_immediate_operand"
6494                                                    "<i>")))))
6495    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6496         (minus:SWI (match_dup 1) (match_dup 2)))]
6497   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6498    && CONST_INT_P (operands[2])
6499    && INTVAL (operands[2]) == INTVAL (operands[3])"
6500   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6501   [(set_attr "type" "alu")
6502    (set_attr "mode" "<MODE>")
6503    (set (attr "length_immediate")
6504         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6505                   (const_string "1")
6506                (match_test "<MODE_SIZE> == 8")
6507                   (const_string "4")]
6508               (const_string "<MODE_SIZE>")))])
6510 (define_expand "usubv<mode>4"
6511   [(parallel [(set (reg:CC FLAGS_REG)
6512                    (compare:CC
6513                      (match_operand:SWI 1 "nonimmediate_operand")
6514                      (match_operand:SWI 2 "<general_operand>")))
6515               (set (match_operand:SWI 0 "register_operand")
6516                    (minus:SWI (match_dup 1) (match_dup 2)))])
6517    (set (pc) (if_then_else
6518                (ltu (reg:CC FLAGS_REG) (const_int 0))
6519                (label_ref (match_operand 3))
6520                (pc)))]
6521   ""
6522   "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6524 (define_insn "*sub<mode>_3"
6525   [(set (reg FLAGS_REG)
6526         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6527                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6528    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6529         (minus:SWI (match_dup 1) (match_dup 2)))]
6530   "ix86_match_ccmode (insn, CCmode)
6531    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6532   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6533   [(set_attr "type" "alu")
6534    (set_attr "mode" "<MODE>")])
6536 (define_insn "*subsi_3_zext"
6537   [(set (reg FLAGS_REG)
6538         (compare (match_operand:SI 1 "register_operand" "0")
6539                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6540    (set (match_operand:DI 0 "register_operand" "=r")
6541         (zero_extend:DI
6542           (minus:SI (match_dup 1)
6543                     (match_dup 2))))]
6544   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6545    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6546   "sub{l}\t{%2, %1|%1, %2}"
6547   [(set_attr "type" "alu")
6548    (set_attr "mode" "SI")])
6550 ;; Add with carry and subtract with borrow
6552 (define_insn "add<mode>3_carry"
6553   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6554         (plus:SWI
6555           (plus:SWI
6556             (match_operator:SWI 4 "ix86_carry_flag_operator"
6557              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6558             (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6559           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6560    (clobber (reg:CC FLAGS_REG))]
6561   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6562   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6563   [(set_attr "type" "alu")
6564    (set_attr "use_carry" "1")
6565    (set_attr "pent_pair" "pu")
6566    (set_attr "mode" "<MODE>")])
6568 (define_insn "*addsi3_carry_zext"
6569   [(set (match_operand:DI 0 "register_operand" "=r")
6570         (zero_extend:DI
6571           (plus:SI
6572             (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6573                       [(reg FLAGS_REG) (const_int 0)])
6574                      (match_operand:SI 1 "register_operand" "%0"))
6575             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6576    (clobber (reg:CC FLAGS_REG))]
6577   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6578   "adc{l}\t{%2, %k0|%k0, %2}"
6579   [(set_attr "type" "alu")
6580    (set_attr "use_carry" "1")
6581    (set_attr "pent_pair" "pu")
6582    (set_attr "mode" "SI")])
6584 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6586 (define_insn "addcarry<mode>"
6587   [(set (reg:CCC FLAGS_REG)
6588         (compare:CCC
6589           (plus:SWI48
6590             (plus:SWI48
6591               (match_operator:SWI48 4 "ix86_carry_flag_operator"
6592                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6593               (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6594             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))
6595           (match_dup 1)))
6596    (set (match_operand:SWI48 0 "register_operand" "=r")
6597         (plus:SWI48 (plus:SWI48 (match_op_dup 4
6598                                  [(match_dup 3) (const_int 0)])
6599                                 (match_dup 1))
6600                     (match_dup 2)))]
6601   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6602   "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6603   [(set_attr "type" "alu")
6604    (set_attr "use_carry" "1")
6605    (set_attr "pent_pair" "pu")
6606    (set_attr "mode" "<MODE>")])
6608 (define_insn "sub<mode>3_carry"
6609   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6610         (minus:SWI
6611           (minus:SWI
6612             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6613             (match_operator:SWI 4 "ix86_carry_flag_operator"
6614              [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6615           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6616    (clobber (reg:CC FLAGS_REG))]
6617   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6618   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6619   [(set_attr "type" "alu")
6620    (set_attr "use_carry" "1")
6621    (set_attr "pent_pair" "pu")
6622    (set_attr "mode" "<MODE>")])
6624 (define_insn "*subsi3_carry_zext"
6625   [(set (match_operand:DI 0 "register_operand" "=r")
6626         (zero_extend:DI
6627           (minus:SI
6628             (minus:SI
6629               (match_operand:SI 1 "register_operand" "0")
6630               (match_operator:SI 3 "ix86_carry_flag_operator"
6631                [(reg FLAGS_REG) (const_int 0)]))
6632             (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6633    (clobber (reg:CC FLAGS_REG))]
6634   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6635   "sbb{l}\t{%2, %k0|%k0, %2}"
6636   [(set_attr "type" "alu")
6637    (set_attr "use_carry" "1")
6638    (set_attr "pent_pair" "pu")
6639    (set_attr "mode" "SI")])
6641 (define_insn "subborrow<mode>"
6642   [(set (reg:CCC FLAGS_REG)
6643         (compare:CCC
6644           (match_operand:SWI48 1 "nonimmediate_operand" "0")
6645           (plus:SWI48
6646             (match_operator:SWI48 4 "ix86_carry_flag_operator"
6647              [(match_operand 3 "flags_reg_operand") (const_int 0)])
6648             (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
6649    (set (match_operand:SWI48 0 "register_operand" "=r")
6650         (minus:SWI48 (minus:SWI48 (match_dup 1)
6651                                   (match_op_dup 4
6652                                    [(match_dup 3) (const_int 0)]))
6653                      (match_dup 2)))]
6654   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6655   "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6656   [(set_attr "type" "alu")
6657    (set_attr "use_carry" "1")
6658    (set_attr "pent_pair" "pu")
6659    (set_attr "mode" "<MODE>")])
6661 ;; Overflow setting add instructions
6663 (define_expand "addqi3_cconly_overflow"
6664   [(parallel
6665      [(set (reg:CCC FLAGS_REG)
6666            (compare:CCC
6667              (plus:QI
6668                (match_operand:QI 0 "nonimmediate_operand")
6669                (match_operand:QI 1 "general_operand"))
6670              (match_dup 0)))
6671       (clobber (match_scratch:QI 2))])]
6672   "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6674 (define_insn "*add<mode>3_cconly_overflow_1"
6675   [(set (reg:CCC FLAGS_REG)
6676         (compare:CCC
6677           (plus:SWI
6678             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6679             (match_operand:SWI 2 "<general_operand>" "<g>"))
6680           (match_dup 1)))
6681    (clobber (match_scratch:SWI 0 "=<r>"))]
6682   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6683   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6684   [(set_attr "type" "alu")
6685    (set_attr "mode" "<MODE>")])
6687 (define_insn "*add<mode>3_cconly_overflow_2"
6688   [(set (reg:CCC FLAGS_REG)
6689         (compare:CCC
6690           (plus:SWI
6691             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6692             (match_operand:SWI 2 "<general_operand>" "<g>"))
6693           (match_dup 2)))
6694    (clobber (match_scratch:SWI 0 "=<r>"))]
6695   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6696   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6697   [(set_attr "type" "alu")
6698    (set_attr "mode" "<MODE>")])
6700 (define_insn "*add<mode>3_cc_overflow_1"
6701   [(set (reg:CCC FLAGS_REG)
6702         (compare:CCC
6703             (plus:SWI
6704                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6705                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6706             (match_dup 1)))
6707    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6708         (plus:SWI (match_dup 1) (match_dup 2)))]
6709   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6710   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6711   [(set_attr "type" "alu")
6712    (set_attr "mode" "<MODE>")])
6714 (define_insn "*add<mode>3_cc_overflow_2"
6715   [(set (reg:CCC FLAGS_REG)
6716         (compare:CCC
6717             (plus:SWI
6718                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6719                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6720             (match_dup 2)))
6721    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6722         (plus:SWI (match_dup 1) (match_dup 2)))]
6723   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6724   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6725   [(set_attr "type" "alu")
6726    (set_attr "mode" "<MODE>")])
6728 (define_insn "*addsi3_zext_cc_overflow_1"
6729   [(set (reg:CCC FLAGS_REG)
6730         (compare:CCC
6731           (plus:SI
6732             (match_operand:SI 1 "nonimmediate_operand" "%0")
6733             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6734           (match_dup 1)))
6735    (set (match_operand:DI 0 "register_operand" "=r")
6736         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6737   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6738   "add{l}\t{%2, %k0|%k0, %2}"
6739   [(set_attr "type" "alu")
6740    (set_attr "mode" "SI")])
6742 (define_insn "*addsi3_zext_cc_overflow_2"
6743   [(set (reg:CCC FLAGS_REG)
6744         (compare:CCC
6745           (plus:SI
6746             (match_operand:SI 1 "nonimmediate_operand" "%0")
6747             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6748           (match_dup 2)))
6749    (set (match_operand:DI 0 "register_operand" "=r")
6750         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6751   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6752   "add{l}\t{%2, %k0|%k0, %2}"
6753   [(set_attr "type" "alu")
6754    (set_attr "mode" "SI")])
6756 ;; The patterns that match these are at the end of this file.
6758 (define_expand "<plusminus_insn>xf3"
6759   [(set (match_operand:XF 0 "register_operand")
6760         (plusminus:XF
6761           (match_operand:XF 1 "register_operand")
6762           (match_operand:XF 2 "register_operand")))]
6763   "TARGET_80387")
6765 (define_expand "<plusminus_insn><mode>3"
6766   [(set (match_operand:MODEF 0 "register_operand")
6767         (plusminus:MODEF
6768           (match_operand:MODEF 1 "register_operand")
6769           (match_operand:MODEF 2 "nonimmediate_operand")))]
6770   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6771     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6773 ;; Multiply instructions
6775 (define_expand "mul<mode>3"
6776   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6777                    (mult:SWIM248
6778                      (match_operand:SWIM248 1 "register_operand")
6779                      (match_operand:SWIM248 2 "<general_operand>")))
6780               (clobber (reg:CC FLAGS_REG))])])
6782 (define_expand "mulqi3"
6783   [(parallel [(set (match_operand:QI 0 "register_operand")
6784                    (mult:QI
6785                      (match_operand:QI 1 "register_operand")
6786                      (match_operand:QI 2 "nonimmediate_operand")))
6787               (clobber (reg:CC FLAGS_REG))])]
6788   "TARGET_QIMODE_MATH")
6790 ;; On AMDFAM10
6791 ;; IMUL reg32/64, reg32/64, imm8        Direct
6792 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6793 ;; IMUL reg32/64, reg32/64, imm32       Direct
6794 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6795 ;; IMUL reg32/64, reg32/64              Direct
6796 ;; IMUL reg32/64, mem32/64              Direct
6798 ;; On BDVER1, all above IMULs use DirectPath
6800 ;; On AMDFAM10
6801 ;; IMUL reg16, reg16, imm8      VectorPath
6802 ;; IMUL reg16, mem16, imm8      VectorPath
6803 ;; IMUL reg16, reg16, imm16     VectorPath
6804 ;; IMUL reg16, mem16, imm16     VectorPath
6805 ;; IMUL reg16, reg16            Direct
6806 ;; IMUL reg16, mem16            Direct
6808 ;; On BDVER1, all HI MULs use DoublePath
6810 (define_insn "*mul<mode>3_1"
6811   [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6812         (mult:SWIM248
6813           (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6814           (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6815    (clobber (reg:CC FLAGS_REG))]
6816   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6817   "@
6818    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6819    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6820    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "imul")
6822    (set_attr "prefix_0f" "0,0,1")
6823    (set (attr "athlon_decode")
6824         (cond [(eq_attr "cpu" "athlon")
6825                   (const_string "vector")
6826                (eq_attr "alternative" "1")
6827                   (const_string "vector")
6828                (and (eq_attr "alternative" "2")
6829                     (ior (match_test "<MODE>mode == HImode")
6830                          (match_operand 1 "memory_operand")))
6831                   (const_string "vector")]
6832               (const_string "direct")))
6833    (set (attr "amdfam10_decode")
6834         (cond [(and (eq_attr "alternative" "0,1")
6835                     (ior (match_test "<MODE>mode == HImode")
6836                          (match_operand 1 "memory_operand")))
6837                   (const_string "vector")]
6838               (const_string "direct")))
6839    (set (attr "bdver1_decode")
6840         (if_then_else
6841           (match_test "<MODE>mode == HImode")
6842             (const_string "double")
6843             (const_string "direct")))
6844    (set_attr "mode" "<MODE>")])
6846 (define_insn "*mulsi3_1_zext"
6847   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6848         (zero_extend:DI
6849           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6850                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6851    (clobber (reg:CC FLAGS_REG))]
6852   "TARGET_64BIT
6853    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6854   "@
6855    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6856    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6857    imul{l}\t{%2, %k0|%k0, %2}"
6858   [(set_attr "type" "imul")
6859    (set_attr "prefix_0f" "0,0,1")
6860    (set (attr "athlon_decode")
6861         (cond [(eq_attr "cpu" "athlon")
6862                   (const_string "vector")
6863                (eq_attr "alternative" "1")
6864                   (const_string "vector")
6865                (and (eq_attr "alternative" "2")
6866                     (match_operand 1 "memory_operand"))
6867                   (const_string "vector")]
6868               (const_string "direct")))
6869    (set (attr "amdfam10_decode")
6870         (cond [(and (eq_attr "alternative" "0,1")
6871                     (match_operand 1 "memory_operand"))
6872                   (const_string "vector")]
6873               (const_string "direct")))
6874    (set_attr "bdver1_decode" "direct")
6875    (set_attr "mode" "SI")])
6877 ;;On AMDFAM10 and BDVER1
6878 ;; MUL reg8     Direct
6879 ;; MUL mem8     Direct
6881 (define_insn "*mulqi3_1"
6882   [(set (match_operand:QI 0 "register_operand" "=a")
6883         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6884                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6885    (clobber (reg:CC FLAGS_REG))]
6886   "TARGET_QIMODE_MATH
6887    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888   "mul{b}\t%2"
6889   [(set_attr "type" "imul")
6890    (set_attr "length_immediate" "0")
6891    (set (attr "athlon_decode")
6892      (if_then_else (eq_attr "cpu" "athlon")
6893         (const_string "vector")
6894         (const_string "direct")))
6895    (set_attr "amdfam10_decode" "direct")
6896    (set_attr "bdver1_decode" "direct")
6897    (set_attr "mode" "QI")])
6899 ;; Multiply with jump on overflow.
6900 (define_expand "mulv<mode>4"
6901   [(parallel [(set (reg:CCO FLAGS_REG)
6902                    (eq:CCO (mult:<DWI>
6903                               (sign_extend:<DWI>
6904                                  (match_operand:SWI248 1 "register_operand"))
6905                               (match_dup 4))
6906                            (sign_extend:<DWI>
6907                               (mult:SWI248 (match_dup 1)
6908                                            (match_operand:SWI248 2
6909                                               "<general_operand>")))))
6910               (set (match_operand:SWI248 0 "register_operand")
6911                    (mult:SWI248 (match_dup 1) (match_dup 2)))])
6912    (set (pc) (if_then_else
6913                (eq (reg:CCO FLAGS_REG) (const_int 0))
6914                (label_ref (match_operand 3))
6915                (pc)))]
6916   ""
6918   if (CONST_INT_P (operands[2]))
6919     operands[4] = operands[2];
6920   else
6921     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6924 (define_insn "*mulv<mode>4"
6925   [(set (reg:CCO FLAGS_REG)
6926         (eq:CCO (mult:<DWI>
6927                    (sign_extend:<DWI>
6928                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6929                    (sign_extend:<DWI>
6930                       (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6931                 (sign_extend:<DWI>
6932                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6933    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6934         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6935   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6936   "@
6937    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6938    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6939   [(set_attr "type" "imul")
6940    (set_attr "prefix_0f" "0,1")
6941    (set (attr "athlon_decode")
6942         (cond [(eq_attr "cpu" "athlon")
6943                   (const_string "vector")
6944                (eq_attr "alternative" "0")
6945                   (const_string "vector")
6946                (and (eq_attr "alternative" "1")
6947                     (match_operand 1 "memory_operand"))
6948                   (const_string "vector")]
6949               (const_string "direct")))
6950    (set (attr "amdfam10_decode")
6951         (cond [(and (eq_attr "alternative" "1")
6952                     (match_operand 1 "memory_operand"))
6953                   (const_string "vector")]
6954               (const_string "direct")))
6955    (set_attr "bdver1_decode" "direct")
6956    (set_attr "mode" "<MODE>")])
6958 (define_insn "*mulvhi4"
6959   [(set (reg:CCO FLAGS_REG)
6960         (eq:CCO (mult:SI
6961                    (sign_extend:SI
6962                       (match_operand:HI 1 "nonimmediate_operand" "%0"))
6963                    (sign_extend:SI
6964                       (match_operand:HI 2 "nonimmediate_operand" "mr")))
6965                 (sign_extend:SI
6966                    (mult:HI (match_dup 1) (match_dup 2)))))
6967    (set (match_operand:HI 0 "register_operand" "=r")
6968         (mult:HI (match_dup 1) (match_dup 2)))]
6969   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6970   "imul{w}\t{%2, %0|%0, %2}"
6971   [(set_attr "type" "imul")
6972    (set_attr "prefix_0f" "1")
6973    (set_attr "athlon_decode" "vector")
6974    (set_attr "amdfam10_decode" "direct")
6975    (set_attr "bdver1_decode" "double")
6976    (set_attr "mode" "HI")])
6978 (define_insn "*mulv<mode>4_1"
6979   [(set (reg:CCO FLAGS_REG)
6980         (eq:CCO (mult:<DWI>
6981                    (sign_extend:<DWI>
6982                       (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
6983                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6984                 (sign_extend:<DWI>
6985                    (mult:SWI248 (match_dup 1)
6986                                 (match_operand:SWI248 2
6987                                    "<immediate_operand>" "K,<i>")))))
6988    (set (match_operand:SWI248 0 "register_operand" "=r,r")
6989         (mult:SWI248 (match_dup 1) (match_dup 2)))]
6990   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6991    && CONST_INT_P (operands[2])
6992    && INTVAL (operands[2]) == INTVAL (operands[3])"
6993   "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6994   [(set_attr "type" "imul")
6995    (set (attr "prefix_0f")
6996         (if_then_else
6997           (match_test "<MODE>mode == HImode")
6998             (const_string "0")
6999             (const_string "*")))
7000    (set (attr "athlon_decode")
7001         (cond [(eq_attr "cpu" "athlon")
7002                   (const_string "vector")
7003                (eq_attr "alternative" "1")
7004                   (const_string "vector")]
7005               (const_string "direct")))
7006    (set (attr "amdfam10_decode")
7007         (cond [(ior (match_test "<MODE>mode == HImode")
7008                     (match_operand 1 "memory_operand"))
7009                   (const_string "vector")]
7010               (const_string "direct")))
7011    (set (attr "bdver1_decode")
7012         (if_then_else
7013           (match_test "<MODE>mode == HImode")
7014             (const_string "double")
7015             (const_string "direct")))
7016    (set_attr "mode" "<MODE>")
7017    (set (attr "length_immediate")
7018         (cond [(eq_attr "alternative" "0")
7019                   (const_string "1")
7020                (match_test "<MODE_SIZE> == 8")
7021                   (const_string "4")]
7022               (const_string "<MODE_SIZE>")))])
7024 (define_expand "umulv<mode>4"
7025   [(parallel [(set (reg:CCO FLAGS_REG)
7026                    (eq:CCO (mult:<DWI>
7027                               (zero_extend:<DWI>
7028                                  (match_operand:SWI248 1
7029                                                       "nonimmediate_operand"))
7030                               (zero_extend:<DWI>
7031                                  (match_operand:SWI248 2
7032                                                       "nonimmediate_operand")))
7033                            (zero_extend:<DWI>
7034                               (mult:SWI248 (match_dup 1) (match_dup 2)))))
7035               (set (match_operand:SWI248 0 "register_operand")
7036                    (mult:SWI248 (match_dup 1) (match_dup 2)))
7037               (clobber (match_scratch:SWI248 4))])
7038    (set (pc) (if_then_else
7039                (eq (reg:CCO FLAGS_REG) (const_int 0))
7040                (label_ref (match_operand 3))
7041                (pc)))]
7042   ""
7044   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7045     operands[1] = force_reg (<MODE>mode, operands[1]);
7048 (define_insn "*umulv<mode>4"
7049   [(set (reg:CCO FLAGS_REG)
7050         (eq:CCO (mult:<DWI>
7051                    (zero_extend:<DWI>
7052                       (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7053                    (zero_extend:<DWI>
7054                       (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7055                 (zero_extend:<DWI>
7056                    (mult:SWI248 (match_dup 1) (match_dup 2)))))
7057    (set (match_operand:SWI248 0 "register_operand" "=a")
7058         (mult:SWI248 (match_dup 1) (match_dup 2)))
7059    (clobber (match_scratch:SWI248 3 "=d"))]
7060   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7061   "mul{<imodesuffix>}\t%2"
7062   [(set_attr "type" "imul")
7063    (set_attr "length_immediate" "0")
7064    (set (attr "athlon_decode")
7065      (if_then_else (eq_attr "cpu" "athlon")
7066        (const_string "vector")
7067        (const_string "double")))
7068    (set_attr "amdfam10_decode" "double")
7069    (set_attr "bdver1_decode" "direct")
7070    (set_attr "mode" "<MODE>")])
7072 (define_expand "<u>mulvqi4"
7073   [(parallel [(set (reg:CCO FLAGS_REG)
7074                    (eq:CCO (mult:HI
7075                               (any_extend:HI
7076                                  (match_operand:QI 1 "nonimmediate_operand"))
7077                               (any_extend:HI
7078                                  (match_operand:QI 2 "nonimmediate_operand")))
7079                            (any_extend:HI
7080                               (mult:QI (match_dup 1) (match_dup 2)))))
7081               (set (match_operand:QI 0 "register_operand")
7082                    (mult:QI (match_dup 1) (match_dup 2)))])
7083    (set (pc) (if_then_else
7084                (eq (reg:CCO FLAGS_REG) (const_int 0))
7085                (label_ref (match_operand 3))
7086                (pc)))]
7087   "TARGET_QIMODE_MATH"
7089   if (MEM_P (operands[1]) && MEM_P (operands[2]))
7090     operands[1] = force_reg (QImode, operands[1]);
7093 (define_insn "*<u>mulvqi4"
7094   [(set (reg:CCO FLAGS_REG)
7095         (eq:CCO (mult:HI
7096                    (any_extend:HI
7097                       (match_operand:QI 1 "nonimmediate_operand" "%0"))
7098                    (any_extend:HI
7099                       (match_operand:QI 2 "nonimmediate_operand" "qm")))
7100                 (any_extend:HI
7101                    (mult:QI (match_dup 1) (match_dup 2)))))
7102    (set (match_operand:QI 0 "register_operand" "=a")
7103         (mult:QI (match_dup 1) (match_dup 2)))]
7104   "TARGET_QIMODE_MATH
7105    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7106   "<sgnprefix>mul{b}\t%2"
7107   [(set_attr "type" "imul")
7108    (set_attr "length_immediate" "0")
7109    (set (attr "athlon_decode")
7110      (if_then_else (eq_attr "cpu" "athlon")
7111         (const_string "vector")
7112         (const_string "direct")))
7113    (set_attr "amdfam10_decode" "direct")
7114    (set_attr "bdver1_decode" "direct")
7115    (set_attr "mode" "QI")])
7117 (define_expand "<u>mul<mode><dwi>3"
7118   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7119                    (mult:<DWI>
7120                      (any_extend:<DWI>
7121                        (match_operand:DWIH 1 "nonimmediate_operand"))
7122                      (any_extend:<DWI>
7123                        (match_operand:DWIH 2 "register_operand"))))
7124               (clobber (reg:CC FLAGS_REG))])])
7126 (define_expand "<u>mulqihi3"
7127   [(parallel [(set (match_operand:HI 0 "register_operand")
7128                    (mult:HI
7129                      (any_extend:HI
7130                        (match_operand:QI 1 "nonimmediate_operand"))
7131                      (any_extend:HI
7132                        (match_operand:QI 2 "register_operand"))))
7133               (clobber (reg:CC FLAGS_REG))])]
7134   "TARGET_QIMODE_MATH")
7136 (define_insn "*bmi2_umul<mode><dwi>3_1"
7137   [(set (match_operand:DWIH 0 "register_operand" "=r")
7138         (mult:DWIH
7139           (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7140           (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7141    (set (match_operand:DWIH 1 "register_operand" "=r")
7142         (truncate:DWIH
7143           (lshiftrt:<DWI>
7144             (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7145                         (zero_extend:<DWI> (match_dup 3)))
7146             (match_operand:QI 4 "const_int_operand" "n"))))]
7147   "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7148    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7149   "mulx\t{%3, %0, %1|%1, %0, %3}"
7150   [(set_attr "type" "imulx")
7151    (set_attr "prefix" "vex")
7152    (set_attr "mode" "<MODE>")])
7154 (define_insn "*umul<mode><dwi>3_1"
7155   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7156         (mult:<DWI>
7157           (zero_extend:<DWI>
7158             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7159           (zero_extend:<DWI>
7160             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7161    (clobber (reg:CC FLAGS_REG))]
7162   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7163   "@
7164    #
7165    mul{<imodesuffix>}\t%2"
7166   [(set_attr "isa" "bmi2,*")
7167    (set_attr "type" "imulx,imul")
7168    (set_attr "length_immediate" "*,0")
7169    (set (attr "athlon_decode")
7170         (cond [(eq_attr "alternative" "1")
7171                  (if_then_else (eq_attr "cpu" "athlon")
7172                    (const_string "vector")
7173                    (const_string "double"))]
7174               (const_string "*")))
7175    (set_attr "amdfam10_decode" "*,double")
7176    (set_attr "bdver1_decode" "*,direct")
7177    (set_attr "prefix" "vex,orig")
7178    (set_attr "mode" "<MODE>")])
7180 ;; Convert mul to the mulx pattern to avoid flags dependency.
7181 (define_split
7182  [(set (match_operand:<DWI> 0 "register_operand")
7183        (mult:<DWI>
7184          (zero_extend:<DWI>
7185            (match_operand:DWIH 1 "register_operand"))
7186          (zero_extend:<DWI>
7187            (match_operand:DWIH 2 "nonimmediate_operand"))))
7188   (clobber (reg:CC FLAGS_REG))]
7189  "TARGET_BMI2 && reload_completed
7190   && REGNO (operands[1]) == DX_REG"
7191   [(parallel [(set (match_dup 3)
7192                    (mult:DWIH (match_dup 1) (match_dup 2)))
7193               (set (match_dup 4)
7194                    (truncate:DWIH
7195                      (lshiftrt:<DWI>
7196                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7197                                    (zero_extend:<DWI> (match_dup 2)))
7198                        (match_dup 5))))])]
7200   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7202   operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7205 (define_insn "*mul<mode><dwi>3_1"
7206   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7207         (mult:<DWI>
7208           (sign_extend:<DWI>
7209             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7210           (sign_extend:<DWI>
7211             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7212    (clobber (reg:CC FLAGS_REG))]
7213   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7214   "imul{<imodesuffix>}\t%2"
7215   [(set_attr "type" "imul")
7216    (set_attr "length_immediate" "0")
7217    (set (attr "athlon_decode")
7218      (if_then_else (eq_attr "cpu" "athlon")
7219         (const_string "vector")
7220         (const_string "double")))
7221    (set_attr "amdfam10_decode" "double")
7222    (set_attr "bdver1_decode" "direct")
7223    (set_attr "mode" "<MODE>")])
7225 (define_insn "*<u>mulqihi3_1"
7226   [(set (match_operand:HI 0 "register_operand" "=a")
7227         (mult:HI
7228           (any_extend:HI
7229             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7230           (any_extend:HI
7231             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7232    (clobber (reg:CC FLAGS_REG))]
7233   "TARGET_QIMODE_MATH
7234    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7235   "<sgnprefix>mul{b}\t%2"
7236   [(set_attr "type" "imul")
7237    (set_attr "length_immediate" "0")
7238    (set (attr "athlon_decode")
7239      (if_then_else (eq_attr "cpu" "athlon")
7240         (const_string "vector")
7241         (const_string "direct")))
7242    (set_attr "amdfam10_decode" "direct")
7243    (set_attr "bdver1_decode" "direct")
7244    (set_attr "mode" "QI")])
7246 (define_expand "<s>mul<mode>3_highpart"
7247   [(parallel [(set (match_operand:SWI48 0 "register_operand")
7248                    (truncate:SWI48
7249                      (lshiftrt:<DWI>
7250                        (mult:<DWI>
7251                          (any_extend:<DWI>
7252                            (match_operand:SWI48 1 "nonimmediate_operand"))
7253                          (any_extend:<DWI>
7254                            (match_operand:SWI48 2 "register_operand")))
7255                        (match_dup 4))))
7256               (clobber (match_scratch:SWI48 3))
7257               (clobber (reg:CC FLAGS_REG))])]
7258   ""
7259   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7261 (define_insn "*<s>muldi3_highpart_1"
7262   [(set (match_operand:DI 0 "register_operand" "=d")
7263         (truncate:DI
7264           (lshiftrt:TI
7265             (mult:TI
7266               (any_extend:TI
7267                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7268               (any_extend:TI
7269                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7270             (const_int 64))))
7271    (clobber (match_scratch:DI 3 "=1"))
7272    (clobber (reg:CC FLAGS_REG))]
7273   "TARGET_64BIT
7274    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7275   "<sgnprefix>mul{q}\t%2"
7276   [(set_attr "type" "imul")
7277    (set_attr "length_immediate" "0")
7278    (set (attr "athlon_decode")
7279      (if_then_else (eq_attr "cpu" "athlon")
7280         (const_string "vector")
7281         (const_string "double")))
7282    (set_attr "amdfam10_decode" "double")
7283    (set_attr "bdver1_decode" "direct")
7284    (set_attr "mode" "DI")])
7286 (define_insn "*<s>mulsi3_highpart_1"
7287   [(set (match_operand:SI 0 "register_operand" "=d")
7288         (truncate:SI
7289           (lshiftrt:DI
7290             (mult:DI
7291               (any_extend:DI
7292                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7293               (any_extend:DI
7294                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7295             (const_int 32))))
7296    (clobber (match_scratch:SI 3 "=1"))
7297    (clobber (reg:CC FLAGS_REG))]
7298   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7299   "<sgnprefix>mul{l}\t%2"
7300   [(set_attr "type" "imul")
7301    (set_attr "length_immediate" "0")
7302    (set (attr "athlon_decode")
7303      (if_then_else (eq_attr "cpu" "athlon")
7304         (const_string "vector")
7305         (const_string "double")))
7306    (set_attr "amdfam10_decode" "double")
7307    (set_attr "bdver1_decode" "direct")
7308    (set_attr "mode" "SI")])
7310 (define_insn "*<s>mulsi3_highpart_zext"
7311   [(set (match_operand:DI 0 "register_operand" "=d")
7312         (zero_extend:DI (truncate:SI
7313           (lshiftrt:DI
7314             (mult:DI (any_extend:DI
7315                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7316                      (any_extend:DI
7317                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7318             (const_int 32)))))
7319    (clobber (match_scratch:SI 3 "=1"))
7320    (clobber (reg:CC FLAGS_REG))]
7321   "TARGET_64BIT
7322    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7323   "<sgnprefix>mul{l}\t%2"
7324   [(set_attr "type" "imul")
7325    (set_attr "length_immediate" "0")
7326    (set (attr "athlon_decode")
7327      (if_then_else (eq_attr "cpu" "athlon")
7328         (const_string "vector")
7329         (const_string "double")))
7330    (set_attr "amdfam10_decode" "double")
7331    (set_attr "bdver1_decode" "direct")
7332    (set_attr "mode" "SI")])
7334 ;; The patterns that match these are at the end of this file.
7336 (define_expand "mulxf3"
7337   [(set (match_operand:XF 0 "register_operand")
7338         (mult:XF (match_operand:XF 1 "register_operand")
7339                  (match_operand:XF 2 "register_operand")))]
7340   "TARGET_80387")
7342 (define_expand "mul<mode>3"
7343   [(set (match_operand:MODEF 0 "register_operand")
7344         (mult:MODEF (match_operand:MODEF 1 "register_operand")
7345                     (match_operand:MODEF 2 "nonimmediate_operand")))]
7346   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7347     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7349 ;; Divide instructions
7351 ;; The patterns that match these are at the end of this file.
7353 (define_expand "divxf3"
7354   [(set (match_operand:XF 0 "register_operand")
7355         (div:XF (match_operand:XF 1 "register_operand")
7356                 (match_operand:XF 2 "register_operand")))]
7357   "TARGET_80387")
7359 (define_expand "divdf3"
7360   [(set (match_operand:DF 0 "register_operand")
7361         (div:DF (match_operand:DF 1 "register_operand")
7362                 (match_operand:DF 2 "nonimmediate_operand")))]
7363    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7364     || (TARGET_SSE2 && TARGET_SSE_MATH)")
7366 (define_expand "divsf3"
7367   [(set (match_operand:SF 0 "register_operand")
7368         (div:SF (match_operand:SF 1 "register_operand")
7369                 (match_operand:SF 2 "nonimmediate_operand")))]
7370   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7371     || TARGET_SSE_MATH"
7373   if (TARGET_SSE_MATH
7374       && TARGET_RECIP_DIV
7375       && optimize_insn_for_speed_p ()
7376       && flag_finite_math_only && !flag_trapping_math
7377       && flag_unsafe_math_optimizations)
7378     {
7379       ix86_emit_swdivsf (operands[0], operands[1],
7380                          operands[2], SFmode);
7381       DONE;
7382     }
7385 ;; Divmod instructions.
7387 (define_expand "divmod<mode>4"
7388   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7389                    (div:SWIM248
7390                      (match_operand:SWIM248 1 "register_operand")
7391                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7392               (set (match_operand:SWIM248 3 "register_operand")
7393                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7394               (clobber (reg:CC FLAGS_REG))])])
7396 ;; Split with 8bit unsigned divide:
7397 ;;      if (dividend an divisor are in [0-255])
7398 ;;         use 8bit unsigned integer divide
7399 ;;       else
7400 ;;         use original integer divide
7401 (define_split
7402   [(set (match_operand:SWI48 0 "register_operand")
7403         (div:SWI48 (match_operand:SWI48 2 "register_operand")
7404                     (match_operand:SWI48 3 "nonimmediate_operand")))
7405    (set (match_operand:SWI48 1 "register_operand")
7406         (mod:SWI48 (match_dup 2) (match_dup 3)))
7407    (clobber (reg:CC FLAGS_REG))]
7408   "TARGET_USE_8BIT_IDIV
7409    && TARGET_QIMODE_MATH
7410    && can_create_pseudo_p ()
7411    && !optimize_insn_for_size_p ()"
7412   [(const_int 0)]
7413   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7415 (define_insn_and_split "divmod<mode>4_1"
7416   [(set (match_operand:SWI48 0 "register_operand" "=a")
7417         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7418                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7419    (set (match_operand:SWI48 1 "register_operand" "=&d")
7420         (mod:SWI48 (match_dup 2) (match_dup 3)))
7421    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7422    (clobber (reg:CC FLAGS_REG))]
7423   ""
7424   "#"
7425   "reload_completed"
7426   [(parallel [(set (match_dup 1)
7427                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7428               (clobber (reg:CC FLAGS_REG))])
7429    (parallel [(set (match_dup 0)
7430                    (div:SWI48 (match_dup 2) (match_dup 3)))
7431               (set (match_dup 1)
7432                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7433               (use (match_dup 1))
7434               (clobber (reg:CC FLAGS_REG))])]
7436   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7438   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7439     operands[4] = operands[2];
7440   else
7441     {
7442       /* Avoid use of cltd in favor of a mov+shift.  */
7443       emit_move_insn (operands[1], operands[2]);
7444       operands[4] = operands[1];
7445     }
7447   [(set_attr "type" "multi")
7448    (set_attr "mode" "<MODE>")])
7450 (define_insn_and_split "*divmod<mode>4"
7451   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7452         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7453                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7454    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7455         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7456    (clobber (reg:CC FLAGS_REG))]
7457   ""
7458   "#"
7459   "reload_completed"
7460   [(parallel [(set (match_dup 1)
7461                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7462               (clobber (reg:CC FLAGS_REG))])
7463    (parallel [(set (match_dup 0)
7464                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7465               (set (match_dup 1)
7466                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7467               (use (match_dup 1))
7468               (clobber (reg:CC FLAGS_REG))])]
7470   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7472   if (<MODE>mode != HImode
7473       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7474     operands[4] = operands[2];
7475   else
7476     {
7477       /* Avoid use of cltd in favor of a mov+shift.  */
7478       emit_move_insn (operands[1], operands[2]);
7479       operands[4] = operands[1];
7480     }
7482   [(set_attr "type" "multi")
7483    (set_attr "mode" "<MODE>")])
7485 (define_insn "*divmod<mode>4_noext"
7486   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7487         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7488                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7489    (set (match_operand:SWIM248 1 "register_operand" "=d")
7490         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7491    (use (match_operand:SWIM248 4 "register_operand" "1"))
7492    (clobber (reg:CC FLAGS_REG))]
7493   ""
7494   "idiv{<imodesuffix>}\t%3"
7495   [(set_attr "type" "idiv")
7496    (set_attr "mode" "<MODE>")])
7498 (define_expand "divmodqi4"
7499   [(parallel [(set (match_operand:QI 0 "register_operand")
7500                    (div:QI
7501                      (match_operand:QI 1 "register_operand")
7502                      (match_operand:QI 2 "nonimmediate_operand")))
7503               (set (match_operand:QI 3 "register_operand")
7504                    (mod:QI (match_dup 1) (match_dup 2)))
7505               (clobber (reg:CC FLAGS_REG))])]
7506   "TARGET_QIMODE_MATH"
7508   rtx div, mod;
7509   rtx tmp0, tmp1;
7510   
7511   tmp0 = gen_reg_rtx (HImode);
7512   tmp1 = gen_reg_rtx (HImode);
7514   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7515      in AX.  */
7516   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7517   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7519   /* Extract remainder from AH.  */
7520   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7521   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7523   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7524   set_unique_reg_note (insn, REG_EQUAL, mod);
7526   /* Extract quotient from AL.  */
7527   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7529   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7530   set_unique_reg_note (insn, REG_EQUAL, div);
7532   DONE;
7535 ;; Divide AX by r/m8, with result stored in
7536 ;; AL <- Quotient
7537 ;; AH <- Remainder
7538 ;; Change div/mod to HImode and extend the second argument to HImode
7539 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7540 ;; combine may fail.
7541 (define_insn "divmodhiqi3"
7542   [(set (match_operand:HI 0 "register_operand" "=a")
7543         (ior:HI
7544           (ashift:HI
7545             (zero_extend:HI
7546               (truncate:QI
7547                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7548                         (sign_extend:HI
7549                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7550             (const_int 8))
7551           (zero_extend:HI
7552             (truncate:QI
7553               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7554    (clobber (reg:CC FLAGS_REG))]
7555   "TARGET_QIMODE_MATH"
7556   "idiv{b}\t%2"
7557   [(set_attr "type" "idiv")
7558    (set_attr "mode" "QI")])
7560 (define_expand "udivmod<mode>4"
7561   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7562                    (udiv:SWIM248
7563                      (match_operand:SWIM248 1 "register_operand")
7564                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7565               (set (match_operand:SWIM248 3 "register_operand")
7566                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7567               (clobber (reg:CC FLAGS_REG))])])
7569 ;; Split with 8bit unsigned divide:
7570 ;;      if (dividend an divisor are in [0-255])
7571 ;;         use 8bit unsigned integer divide
7572 ;;       else
7573 ;;         use original integer divide
7574 (define_split
7575   [(set (match_operand:SWI48 0 "register_operand")
7576         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7577                     (match_operand:SWI48 3 "nonimmediate_operand")))
7578    (set (match_operand:SWI48 1 "register_operand")
7579         (umod:SWI48 (match_dup 2) (match_dup 3)))
7580    (clobber (reg:CC FLAGS_REG))]
7581   "TARGET_USE_8BIT_IDIV
7582    && TARGET_QIMODE_MATH
7583    && can_create_pseudo_p ()
7584    && !optimize_insn_for_size_p ()"
7585   [(const_int 0)]
7586   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7588 (define_insn_and_split "udivmod<mode>4_1"
7589   [(set (match_operand:SWI48 0 "register_operand" "=a")
7590         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7591                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7592    (set (match_operand:SWI48 1 "register_operand" "=&d")
7593         (umod:SWI48 (match_dup 2) (match_dup 3)))
7594    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7595    (clobber (reg:CC FLAGS_REG))]
7596   ""
7597   "#"
7598   "reload_completed"
7599   [(set (match_dup 1) (const_int 0))
7600    (parallel [(set (match_dup 0)
7601                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7602               (set (match_dup 1)
7603                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7604               (use (match_dup 1))
7605               (clobber (reg:CC FLAGS_REG))])]
7606   ""
7607   [(set_attr "type" "multi")
7608    (set_attr "mode" "<MODE>")])
7610 (define_insn_and_split "*udivmod<mode>4"
7611   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7612         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7613                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7614    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7615         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7616    (clobber (reg:CC FLAGS_REG))]
7617   ""
7618   "#"
7619   "reload_completed"
7620   [(set (match_dup 1) (const_int 0))
7621    (parallel [(set (match_dup 0)
7622                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7623               (set (match_dup 1)
7624                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7625               (use (match_dup 1))
7626               (clobber (reg:CC FLAGS_REG))])]
7627   ""
7628   [(set_attr "type" "multi")
7629    (set_attr "mode" "<MODE>")])
7631 ;; Optimize division or modulo by constant power of 2, if the constant
7632 ;; materializes only after expansion.
7633 (define_insn_and_split "*udivmod<mode>4_pow2"
7634   [(set (match_operand:SWI48 0 "register_operand" "=r")
7635         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7636                     (match_operand:SWI48 3 "const_int_operand" "n")))
7637    (set (match_operand:SWI48 1 "register_operand" "=r")
7638         (umod:SWI48 (match_dup 2) (match_dup 3)))
7639    (clobber (reg:CC FLAGS_REG))]
7640   "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7641    && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7642   "#"
7643   "&& 1"
7644   [(set (match_dup 1) (match_dup 2))
7645    (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7646               (clobber (reg:CC FLAGS_REG))])
7647    (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7648               (clobber (reg:CC FLAGS_REG))])]
7650   int v = exact_log2 (UINTVAL (operands[3]));
7651   operands[4] = GEN_INT (v);
7652   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7654   [(set_attr "type" "multi")
7655    (set_attr "mode" "<MODE>")])
7657 (define_insn "*udivmod<mode>4_noext"
7658   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7659         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7660                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7661    (set (match_operand:SWIM248 1 "register_operand" "=d")
7662         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7663    (use (match_operand:SWIM248 4 "register_operand" "1"))
7664    (clobber (reg:CC FLAGS_REG))]
7665   ""
7666   "div{<imodesuffix>}\t%3"
7667   [(set_attr "type" "idiv")
7668    (set_attr "mode" "<MODE>")])
7670 (define_expand "udivmodqi4"
7671   [(parallel [(set (match_operand:QI 0 "register_operand")
7672                    (udiv:QI
7673                      (match_operand:QI 1 "register_operand")
7674                      (match_operand:QI 2 "nonimmediate_operand")))
7675               (set (match_operand:QI 3 "register_operand")
7676                    (umod:QI (match_dup 1) (match_dup 2)))
7677               (clobber (reg:CC FLAGS_REG))])]
7678   "TARGET_QIMODE_MATH"
7680   rtx div, mod;
7681   rtx tmp0, tmp1;
7682   
7683   tmp0 = gen_reg_rtx (HImode);
7684   tmp1 = gen_reg_rtx (HImode);
7686   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is in AX.  */
7687   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7688   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7690   /* Extract remainder from AH.  */
7691   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7692   tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7693   rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7695   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7696   set_unique_reg_note (insn, REG_EQUAL, mod);
7698   /* Extract quotient from AL.  */
7699   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7701   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7702   set_unique_reg_note (insn, REG_EQUAL, div);
7704   DONE;
7707 (define_insn "udivmodhiqi3"
7708   [(set (match_operand:HI 0 "register_operand" "=a")
7709         (ior:HI
7710           (ashift:HI
7711             (zero_extend:HI
7712               (truncate:QI
7713                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7714                         (zero_extend:HI
7715                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7716             (const_int 8))
7717           (zero_extend:HI
7718             (truncate:QI
7719               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7720    (clobber (reg:CC FLAGS_REG))]
7721   "TARGET_QIMODE_MATH"
7722   "div{b}\t%2"
7723   [(set_attr "type" "idiv")
7724    (set_attr "mode" "QI")])
7726 ;; We cannot use div/idiv for double division, because it causes
7727 ;; "division by zero" on the overflow and that's not what we expect
7728 ;; from truncate.  Because true (non truncating) double division is
7729 ;; never generated, we can't create this insn anyway.
7731 ;(define_insn ""
7732 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7733 ;       (truncate:SI
7734 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7735 ;                  (zero_extend:DI
7736 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7737 ;   (set (match_operand:SI 3 "register_operand" "=d")
7738 ;       (truncate:SI
7739 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7740 ;   (clobber (reg:CC FLAGS_REG))]
7741 ;  ""
7742 ;  "div{l}\t{%2, %0|%0, %2}"
7743 ;  [(set_attr "type" "idiv")])
7745 ;;- Logical AND instructions
7747 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7748 ;; Note that this excludes ah.
7750 (define_expand "testsi_ccno_1"
7751   [(set (reg:CCNO FLAGS_REG)
7752         (compare:CCNO
7753           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7754                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7755           (const_int 0)))])
7757 (define_expand "testqi_ccz_1"
7758   [(set (reg:CCZ FLAGS_REG)
7759         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7760                              (match_operand:QI 1 "nonmemory_operand"))
7761                  (const_int 0)))])
7763 (define_expand "testdi_ccno_1"
7764   [(set (reg:CCNO FLAGS_REG)
7765         (compare:CCNO
7766           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7767                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7768           (const_int 0)))]
7769   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7771 (define_insn "*testdi_1"
7772   [(set (reg FLAGS_REG)
7773         (compare
7774          (and:DI
7775           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7776           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7777          (const_int 0)))]
7778   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7779    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7780   "@
7781    test{l}\t{%k1, %k0|%k0, %k1}
7782    test{l}\t{%k1, %k0|%k0, %k1}
7783    test{q}\t{%1, %0|%0, %1}
7784    test{q}\t{%1, %0|%0, %1}
7785    test{q}\t{%1, %0|%0, %1}"
7786   [(set_attr "type" "test")
7787    (set_attr "modrm" "0,1,0,1,1")
7788    (set_attr "mode" "SI,SI,DI,DI,DI")])
7790 (define_insn "*testqi_1_maybe_si"
7791   [(set (reg FLAGS_REG)
7792         (compare
7793           (and:QI
7794             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7795             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7796           (const_int 0)))]
7797    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7798     && ix86_match_ccmode (insn,
7799                          CONST_INT_P (operands[1])
7800                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7802   if (which_alternative == 3)
7803     {
7804       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7805         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7806       return "test{l}\t{%1, %k0|%k0, %1}";
7807     }
7808   return "test{b}\t{%1, %0|%0, %1}";
7810   [(set_attr "type" "test")
7811    (set_attr "modrm" "0,1,1,1")
7812    (set_attr "mode" "QI,QI,QI,SI")
7813    (set_attr "pent_pair" "uv,np,uv,np")])
7815 (define_insn "*test<mode>_1"
7816   [(set (reg FLAGS_REG)
7817         (compare
7818          (and:SWI124
7819           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7820           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7821          (const_int 0)))]
7822   "ix86_match_ccmode (insn, CCNOmode)
7823    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7824   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7825   [(set_attr "type" "test")
7826    (set_attr "modrm" "0,1,1")
7827    (set_attr "mode" "<MODE>")
7828    (set_attr "pent_pair" "uv,np,uv")])
7830 (define_expand "testqi_ext_ccno_0"
7831   [(set (reg:CCNO FLAGS_REG)
7832         (compare:CCNO
7833           (and:SI
7834             (zero_extract:SI
7835               (match_operand 0 "ext_register_operand")
7836               (const_int 8)
7837               (const_int 8))
7838             (match_operand 1 "const_int_operand"))
7839           (const_int 0)))])
7841 (define_insn "*testqi_ext_0"
7842   [(set (reg FLAGS_REG)
7843         (compare
7844           (and:SI
7845             (zero_extract:SI
7846               (match_operand 0 "ext_register_operand" "Q")
7847               (const_int 8)
7848               (const_int 8))
7849             (match_operand 1 "const_int_operand" "n"))
7850           (const_int 0)))]
7851   "ix86_match_ccmode (insn, CCNOmode)"
7852   "test{b}\t{%1, %h0|%h0, %1}"
7853   [(set_attr "type" "test")
7854    (set_attr "mode" "QI")
7855    (set_attr "length_immediate" "1")
7856    (set_attr "modrm" "1")
7857    (set_attr "pent_pair" "np")])
7859 (define_insn "*testqi_ext_1"
7860   [(set (reg FLAGS_REG)
7861         (compare
7862           (and:SI
7863             (zero_extract:SI
7864               (match_operand 0 "ext_register_operand" "Q,Q")
7865               (const_int 8)
7866               (const_int 8))
7867             (zero_extend:SI
7868               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7869           (const_int 0)))]
7870   "ix86_match_ccmode (insn, CCNOmode)"
7871   "test{b}\t{%1, %h0|%h0, %1}"
7872   [(set_attr "isa" "*,nox64")
7873    (set_attr "type" "test")
7874    (set_attr "mode" "QI")])
7876 (define_insn "*testqi_ext_2"
7877   [(set (reg FLAGS_REG)
7878         (compare
7879           (and:SI
7880             (zero_extract:SI
7881               (match_operand 0 "ext_register_operand" "Q")
7882               (const_int 8)
7883               (const_int 8))
7884             (zero_extract:SI
7885               (match_operand 1 "ext_register_operand" "Q")
7886               (const_int 8)
7887               (const_int 8)))
7888           (const_int 0)))]
7889   "ix86_match_ccmode (insn, CCNOmode)"
7890   "test{b}\t{%h1, %h0|%h0, %h1}"
7891   [(set_attr "type" "test")
7892    (set_attr "mode" "QI")])
7894 ;; Combine likes to form bit extractions for some tests.  Humor it.
7895 (define_insn "*testqi_ext_3"
7896   [(set (reg FLAGS_REG)
7897         (compare (zero_extract:SWI248
7898                    (match_operand 0 "nonimmediate_operand" "rm")
7899                    (match_operand 1 "const_int_operand" "n")
7900                    (match_operand 2 "const_int_operand" "n"))
7901                  (const_int 0)))]
7902   "ix86_match_ccmode (insn, CCNOmode)
7903    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7904        || GET_MODE (operands[0]) == SImode
7905        || GET_MODE (operands[0]) == HImode
7906        || GET_MODE (operands[0]) == QImode)
7907    /* Ensure that resulting mask is zero or sign extended operand.  */
7908    && INTVAL (operands[2]) >= 0
7909    && ((INTVAL (operands[1]) > 0
7910         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7911        || (<MODE>mode == DImode
7912            && INTVAL (operands[1]) > 32
7913            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7914   "#")
7916 (define_split
7917   [(set (match_operand 0 "flags_reg_operand")
7918         (match_operator 1 "compare_operator"
7919           [(zero_extract
7920              (match_operand 2 "nonimmediate_operand")
7921              (match_operand 3 "const_int_operand")
7922              (match_operand 4 "const_int_operand"))
7923            (const_int 0)]))]
7924   "ix86_match_ccmode (insn, CCNOmode)"
7925   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7927   rtx val = operands[2];
7928   HOST_WIDE_INT len = INTVAL (operands[3]);
7929   HOST_WIDE_INT pos = INTVAL (operands[4]);
7930   HOST_WIDE_INT mask;
7931   machine_mode mode, submode;
7933   mode = GET_MODE (val);
7934   if (MEM_P (val))
7935     {
7936       /* ??? Combine likes to put non-volatile mem extractions in QImode
7937          no matter the size of the test.  So find a mode that works.  */
7938       if (! MEM_VOLATILE_P (val))
7939         {
7940           mode = smallest_mode_for_size (pos + len, MODE_INT);
7941           val = adjust_address (val, mode, 0);
7942         }
7943     }
7944   else if (SUBREG_P (val)
7945            && (submode = GET_MODE (SUBREG_REG (val)),
7946                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7947            && pos + len <= GET_MODE_BITSIZE (submode)
7948            && GET_MODE_CLASS (submode) == MODE_INT)
7949     {
7950       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7951       mode = submode;
7952       val = SUBREG_REG (val);
7953     }
7954   else if (mode == HImode && pos + len <= 8)
7955     {
7956       /* Small HImode tests can be converted to QImode.  */
7957       mode = QImode;
7958       val = gen_lowpart (QImode, val);
7959     }
7961   if (len == HOST_BITS_PER_WIDE_INT)
7962     mask = -1;
7963   else
7964     mask = (HOST_WIDE_INT_1 << len) - 1;
7965   mask <<= pos;
7967   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7970 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7971 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7972 ;; this is relatively important trick.
7973 ;; Do the conversion only post-reload to avoid limiting of the register class
7974 ;; to QI regs.
7975 (define_split
7976   [(set (match_operand 0 "flags_reg_operand")
7977         (match_operator 1 "compare_operator"
7978           [(and (match_operand 2 "QIreg_operand")
7979                 (match_operand 3 "const_int_operand"))
7980            (const_int 0)]))]
7981    "reload_completed
7982     && GET_MODE (operands[2]) != QImode
7983     && ((ix86_match_ccmode (insn, CCZmode)
7984          && !(INTVAL (operands[3]) & ~(255 << 8)))
7985         || (ix86_match_ccmode (insn, CCNOmode)
7986             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7987   [(set (match_dup 0)
7988         (match_op_dup 1
7989           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7990                    (match_dup 3))
7991            (const_int 0)]))]
7993   operands[2] = gen_lowpart (SImode, operands[2]);
7994   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7997 (define_split
7998   [(set (match_operand 0 "flags_reg_operand")
7999         (match_operator 1 "compare_operator"
8000           [(and (match_operand 2 "nonimmediate_operand")
8001                 (match_operand 3 "const_int_operand"))
8002            (const_int 0)]))]
8003    "reload_completed
8004     && GET_MODE (operands[2]) != QImode
8005     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8006     && ((ix86_match_ccmode (insn, CCZmode)
8007          && !(INTVAL (operands[3]) & ~255))
8008         || (ix86_match_ccmode (insn, CCNOmode)
8009             && !(INTVAL (operands[3]) & ~127)))"
8010   [(set (match_dup 0)
8011         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8012                          (const_int 0)]))]
8014   operands[2] = gen_lowpart (QImode, operands[2]);
8015   operands[3] = gen_lowpart (QImode, operands[3]);
8018 (define_split
8019   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
8020         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
8021                             (match_operand:SWI1248x 2 "mask_reg_operand")))
8022    (clobber (reg:CC FLAGS_REG))]
8023   "TARGET_AVX512F && reload_completed"
8024   [(set (match_dup 0)
8025         (any_logic:SWI1248x (match_dup 1)
8026                             (match_dup 2)))])
8028 (define_mode_iterator SWI1248_AVX512BW
8029   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
8031 (define_insn "*k<logic><mode>"
8032   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
8033         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
8034                                     (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
8035   "TARGET_AVX512F"
8036   {
8037     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
8038       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
8039     else
8040       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
8041   }
8042   [(set_attr "mode" "<MODE>")
8043    (set_attr "type" "msklog")
8044    (set_attr "prefix" "vex")])
8046 ;; %%% This used to optimize known byte-wide and operations to memory,
8047 ;; and sometimes to QImode registers.  If this is considered useful,
8048 ;; it should be done with splitters.
8050 (define_expand "and<mode>3"
8051   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8052         (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8053                       (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8054   ""
8056   machine_mode mode = <MODE>mode;
8057   rtx (*insn) (rtx, rtx);
8059   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8060     {
8061       HOST_WIDE_INT ival = INTVAL (operands[2]);
8063       if (ival == (HOST_WIDE_INT) 0xffffffff)
8064         mode = SImode;
8065       else if (ival == 0xffff)
8066         mode = HImode;
8067       else if (ival == 0xff)
8068         mode = QImode;
8069       }
8071   if (mode == <MODE>mode)
8072     {
8073       ix86_expand_binary_operator (AND, <MODE>mode, operands);
8074       DONE;
8075     }
8077   if (<MODE>mode == DImode)
8078     insn = (mode == SImode)
8079            ? gen_zero_extendsidi2
8080            : (mode == HImode)
8081            ? gen_zero_extendhidi2
8082            : gen_zero_extendqidi2;
8083   else if (<MODE>mode == SImode)
8084     insn = (mode == HImode)
8085            ? gen_zero_extendhisi2
8086            : gen_zero_extendqisi2;
8087   else if (<MODE>mode == HImode)
8088     insn = gen_zero_extendqihi2;
8089   else
8090     gcc_unreachable ();
8092   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8093   DONE;
8096 (define_insn "*anddi_1"
8097   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
8098         (and:DI
8099          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
8100          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
8101    (clobber (reg:CC FLAGS_REG))]
8102   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8104   switch (get_attr_type (insn))
8105     {
8106     case TYPE_IMOVX:
8107       return "#";
8109     case TYPE_MSKLOG:
8110       return "kandq\t{%2, %1, %0|%0, %1, %2}";
8112     default:
8113       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8114       if (get_attr_mode (insn) == MODE_SI)
8115         return "and{l}\t{%k2, %k0|%k0, %k2}";
8116       else
8117         return "and{q}\t{%2, %0|%0, %2}";
8118     }
8120   [(set_attr "type" "alu,alu,alu,imovx,msklog")
8121    (set_attr "length_immediate" "*,*,*,0,0")
8122    (set (attr "prefix_rex")
8123      (if_then_else
8124        (and (eq_attr "type" "imovx")
8125             (and (match_test "INTVAL (operands[2]) == 0xff")
8126                  (match_operand 1 "ext_QIreg_operand")))
8127        (const_string "1")
8128        (const_string "*")))
8129    (set_attr "mode" "SI,DI,DI,SI,DI")])
8131 (define_insn_and_split "*anddi3_doubleword"
8132   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8133         (and:DI
8134          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8135          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8136    (clobber (reg:CC FLAGS_REG))]
8137   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8138    && ix86_binary_operator_ok (AND, DImode, operands)"
8139   "#"
8140   "&& reload_completed"
8141   [(const_int 0)]
8143   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8144   if (operands[2] == const0_rtx)
8145     {
8146       operands[1] = const0_rtx;
8147       ix86_expand_move (SImode, &operands[0]);
8148     }
8149   else if (operands[2] != constm1_rtx)
8150     ix86_expand_binary_operator (AND, SImode, &operands[0]);
8151   else if (operands[5] == constm1_rtx)
8152     emit_note (NOTE_INSN_DELETED);
8153   if (operands[5] == const0_rtx)
8154     {
8155       operands[4] = const0_rtx;
8156       ix86_expand_move (SImode, &operands[3]);
8157     }
8158   else if (operands[5] != constm1_rtx)
8159     ix86_expand_binary_operator (AND, SImode, &operands[3]);
8160   DONE;
8163 (define_insn "*andsi_1"
8164   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8165         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
8166                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
8167    (clobber (reg:CC FLAGS_REG))]
8168   "ix86_binary_operator_ok (AND, SImode, operands)"
8170   switch (get_attr_type (insn))
8171     {
8172     case TYPE_IMOVX:
8173       return "#";
8175     case TYPE_MSKLOG:
8176       return "kandd\t{%2, %1, %0|%0, %1, %2}";
8178     default:
8179       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8180       return "and{l}\t{%2, %0|%0, %2}";
8181     }
8183   [(set_attr "type" "alu,alu,imovx,msklog")
8184    (set (attr "prefix_rex")
8185      (if_then_else
8186        (and (eq_attr "type" "imovx")
8187             (and (match_test "INTVAL (operands[2]) == 0xff")
8188                  (match_operand 1 "ext_QIreg_operand")))
8189        (const_string "1")
8190        (const_string "*")))
8191    (set_attr "length_immediate" "*,*,0,0")
8192    (set_attr "mode" "SI")])
8194 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8195 (define_insn "*andsi_1_zext"
8196   [(set (match_operand:DI 0 "register_operand" "=r")
8197         (zero_extend:DI
8198           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8199                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8202   "and{l}\t{%2, %k0|%k0, %2}"
8203   [(set_attr "type" "alu")
8204    (set_attr "mode" "SI")])
8206 (define_insn "*andhi_1"
8207   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
8208         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
8209                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
8210    (clobber (reg:CC FLAGS_REG))]
8211   "ix86_binary_operator_ok (AND, HImode, operands)"
8213   switch (get_attr_type (insn))
8214     {
8215     case TYPE_IMOVX:
8216       return "#";
8218     case TYPE_MSKLOG:
8219       return "kandw\t{%2, %1, %0|%0, %1, %2}";
8221     default:
8222       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8223       return "and{w}\t{%2, %0|%0, %2}";
8224     }
8226   [(set_attr "type" "alu,alu,imovx,msklog")
8227    (set_attr "length_immediate" "*,*,0,*")
8228    (set (attr "prefix_rex")
8229      (if_then_else
8230        (and (eq_attr "type" "imovx")
8231             (match_operand 1 "ext_QIreg_operand"))
8232        (const_string "1")
8233        (const_string "*")))
8234    (set_attr "mode" "HI,HI,SI,HI")])
8236 (define_insn "*andqi_1"
8237   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
8238         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8239                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
8240    (clobber (reg:CC FLAGS_REG))]
8241   "ix86_binary_operator_ok (AND, QImode, operands)"
8243   switch (which_alternative)
8244     {
8245     case 0:
8246     case 1:
8247       return "and{b}\t{%2, %0|%0, %2}";
8248     case 2:
8249       return "and{l}\t{%k2, %k0|%k0, %k2}";
8250     case 3:
8251       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
8252                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
8253     default:
8254       gcc_unreachable ();
8255     }
8257   [(set_attr "type" "alu,alu,alu,msklog")
8258    (set_attr "mode" "QI,QI,SI,HI")
8259    ;; Potential partial reg stall on alternative 2.
8260    (set (attr "preferred_for_speed")
8261      (cond [(eq_attr "alternative" "2")
8262               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8263            (symbol_ref "true")))])
8265 (define_insn "*andqi_1_slp"
8266   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8267         (and:QI (match_dup 0)
8268                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8269    (clobber (reg:CC FLAGS_REG))]
8270   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8271    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8272   "and{b}\t{%1, %0|%0, %1}"
8273   [(set_attr "type" "alu1")
8274    (set_attr "mode" "QI")])
8276 (define_insn "kandn<mode>"
8277   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
8278         (and:SWI12
8279           (not:SWI12
8280             (match_operand:SWI12 1 "register_operand" "r,0,k"))
8281           (match_operand:SWI12 2 "register_operand" "r,r,k")))
8282    (clobber (reg:CC FLAGS_REG))]
8283   "TARGET_AVX512F"
8285   switch (which_alternative)
8286     {
8287     case 0:
8288       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
8289     case 1:
8290       return "#";
8291     case 2:
8292       if (TARGET_AVX512DQ && <MODE>mode == QImode)
8293         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
8294       else
8295         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
8296     default:
8297       gcc_unreachable ();
8298     }
8300   [(set_attr "isa" "bmi,*,avx512f")
8301    (set_attr "type" "bitmanip,*,msklog")
8302    (set_attr "prefix" "*,*,vex")
8303    (set_attr "btver2_decode" "direct,*,*")
8304    (set_attr "mode" "<MODE>")])
8306 (define_split
8307   [(set (match_operand:SWI12 0 "general_reg_operand")
8308         (and:SWI12
8309           (not:SWI12
8310             (match_dup 0))
8311           (match_operand:SWI12 1 "general_reg_operand")))
8312    (clobber (reg:CC FLAGS_REG))]
8313   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
8314   [(set (match_dup 0)
8315         (not:SWI12 (match_dup 0)))
8316    (parallel [(set (match_dup 0)
8317                    (and:SWI12 (match_dup 0)
8318                               (match_dup 1)))
8319               (clobber (reg:CC FLAGS_REG))])])
8321 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8322 (define_split
8323   [(set (match_operand:DI 0 "register_operand")
8324         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8325                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8326    (clobber (reg:CC FLAGS_REG))]
8327   "TARGET_64BIT"
8328   [(parallel [(set (match_dup 0)
8329                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8330               (clobber (reg:CC FLAGS_REG))])]
8331   "operands[2] = gen_lowpart (SImode, operands[2]);")
8333 (define_split
8334   [(set (match_operand:SWI248 0 "register_operand")
8335         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8336                     (match_operand:SWI248 2 "const_int_operand")))
8337    (clobber (reg:CC FLAGS_REG))]
8338   "reload_completed
8339    && (!REG_P (operands[1])
8340        || REGNO (operands[0]) != REGNO (operands[1]))"
8341   [(const_int 0)]
8343   HOST_WIDE_INT ival = INTVAL (operands[2]);
8344   machine_mode mode;
8345   rtx (*insn) (rtx, rtx);
8347   if (ival == (HOST_WIDE_INT) 0xffffffff)
8348     mode = SImode;
8349   else if (ival == 0xffff)
8350     mode = HImode;
8351   else
8352     {
8353       gcc_assert (ival == 0xff);
8354       mode = QImode;
8355     }
8357   if (<MODE>mode == DImode)
8358     insn = (mode == SImode)
8359            ? gen_zero_extendsidi2
8360            : (mode == HImode)
8361            ? gen_zero_extendhidi2
8362            : gen_zero_extendqidi2;
8363   else
8364     {
8365       if (<MODE>mode != SImode)
8366         /* Zero extend to SImode to avoid partial register stalls.  */
8367         operands[0] = gen_lowpart (SImode, operands[0]);
8369       insn = (mode == HImode)
8370              ? gen_zero_extendhisi2
8371              : gen_zero_extendqisi2;
8372     }
8373   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8374   DONE;
8377 (define_split
8378   [(set (match_operand:SWI48 0 "register_operand")
8379         (and:SWI48 (match_dup 0)
8380                    (const_int -65536)))
8381    (clobber (reg:CC FLAGS_REG))]
8382   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8383     || optimize_function_for_size_p (cfun)"
8384   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8385   "operands[1] = gen_lowpart (HImode, operands[0]);")
8387 (define_split
8388   [(set (match_operand:SWI248 0 "any_QIreg_operand")
8389         (and:SWI248 (match_dup 0)
8390                     (const_int -256)))
8391    (clobber (reg:CC FLAGS_REG))]
8392   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8393    && reload_completed"
8394   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8395   "operands[1] = gen_lowpart (QImode, operands[0]);")
8397 (define_split
8398   [(set (match_operand:SWI248 0 "QIreg_operand")
8399         (and:SWI248 (match_dup 0)
8400                     (const_int -65281)))
8401    (clobber (reg:CC FLAGS_REG))]
8402   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8403    && reload_completed"
8404   [(parallel [(set (zero_extract:SI (match_dup 0)
8405                                     (const_int 8)
8406                                     (const_int 8))
8407                    (xor:SI
8408                      (zero_extract:SI (match_dup 0)
8409                                       (const_int 8)
8410                                       (const_int 8))
8411                      (zero_extract:SI (match_dup 0)
8412                                       (const_int 8)
8413                                       (const_int 8))))
8414               (clobber (reg:CC FLAGS_REG))])]
8415   "operands[0] = gen_lowpart (SImode, operands[0]);")
8417 (define_insn "*anddi_2"
8418   [(set (reg FLAGS_REG)
8419         (compare
8420          (and:DI
8421           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8422           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8423          (const_int 0)))
8424    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8425         (and:DI (match_dup 1) (match_dup 2)))]
8426   "TARGET_64BIT
8427    && ix86_match_ccmode
8428         (insn,
8429          /* If we are going to emit andl instead of andq, and the operands[2]
8430             constant might have the SImode sign bit set, make sure the sign
8431             flag isn't tested, because the instruction will set the sign flag
8432             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
8433             conservatively assume it might have bit 31 set.  */
8434          (satisfies_constraint_Z (operands[2])
8435           && (!CONST_INT_P (operands[2])
8436               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8437          ? CCZmode : CCNOmode)
8438    && ix86_binary_operator_ok (AND, DImode, operands)"
8439   "@
8440    and{l}\t{%k2, %k0|%k0, %k2}
8441    and{q}\t{%2, %0|%0, %2}
8442    and{q}\t{%2, %0|%0, %2}"
8443   [(set_attr "type" "alu")
8444    (set_attr "mode" "SI,DI,DI")])
8446 (define_insn "*andqi_2_maybe_si"
8447   [(set (reg FLAGS_REG)
8448         (compare (and:QI
8449                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8450                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8451                  (const_int 0)))
8452    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8453         (and:QI (match_dup 1) (match_dup 2)))]
8454   "ix86_binary_operator_ok (AND, QImode, operands)
8455    && ix86_match_ccmode (insn,
8456                          CONST_INT_P (operands[2])
8457                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8459   if (which_alternative == 2)
8460     {
8461       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8462         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8463       return "and{l}\t{%2, %k0|%k0, %2}";
8464     }
8465   return "and{b}\t{%2, %0|%0, %2}";
8467   [(set_attr "type" "alu")
8468    (set_attr "mode" "QI,QI,SI")])
8470 (define_insn "*and<mode>_2"
8471   [(set (reg FLAGS_REG)
8472         (compare (and:SWI124
8473                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8474                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8475                  (const_int 0)))
8476    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8477         (and:SWI124 (match_dup 1) (match_dup 2)))]
8478   "ix86_match_ccmode (insn, CCNOmode)
8479    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8480   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8481   [(set_attr "type" "alu")
8482    (set_attr "mode" "<MODE>")])
8484 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8485 (define_insn "*andsi_2_zext"
8486   [(set (reg FLAGS_REG)
8487         (compare (and:SI
8488                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8489                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
8490                  (const_int 0)))
8491    (set (match_operand:DI 0 "register_operand" "=r")
8492         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8493   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8494    && ix86_binary_operator_ok (AND, SImode, operands)"
8495   "and{l}\t{%2, %k0|%k0, %2}"
8496   [(set_attr "type" "alu")
8497    (set_attr "mode" "SI")])
8499 (define_insn "*andqi_2_slp"
8500   [(set (reg FLAGS_REG)
8501         (compare (and:QI
8502                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8503                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8504                  (const_int 0)))
8505    (set (strict_low_part (match_dup 0))
8506         (and:QI (match_dup 0) (match_dup 1)))]
8507   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8508    && ix86_match_ccmode (insn, CCNOmode)
8509    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8510   "and{b}\t{%1, %0|%0, %1}"
8511   [(set_attr "type" "alu1")
8512    (set_attr "mode" "QI")])
8514 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8515 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8516 ;; for a QImode operand, which of course failed.
8517 (define_insn "andqi_ext_0"
8518   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8519                          (const_int 8)
8520                          (const_int 8))
8521         (and:SI
8522           (zero_extract:SI
8523             (match_operand 1 "ext_register_operand" "0")
8524             (const_int 8)
8525             (const_int 8))
8526           (match_operand 2 "const_int_operand" "n")))
8527    (clobber (reg:CC FLAGS_REG))]
8528   ""
8529   "and{b}\t{%2, %h0|%h0, %2}"
8530   [(set_attr "type" "alu")
8531    (set_attr "length_immediate" "1")
8532    (set_attr "modrm" "1")
8533    (set_attr "mode" "QI")])
8535 ;; Generated by peephole translating test to and.  This shows up
8536 ;; often in fp comparisons.
8537 (define_insn "*andqi_ext_0_cc"
8538   [(set (reg FLAGS_REG)
8539         (compare
8540           (and:SI
8541             (zero_extract:SI
8542               (match_operand 1 "ext_register_operand" "0")
8543               (const_int 8)
8544               (const_int 8))
8545             (match_operand 2 "const_int_operand" "n"))
8546           (const_int 0)))
8547    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8548                          (const_int 8)
8549                          (const_int 8))
8550         (and:SI
8551           (zero_extract:SI
8552             (match_dup 1)
8553             (const_int 8)
8554             (const_int 8))
8555           (match_dup 2)))]
8556   "ix86_match_ccmode (insn, CCNOmode)"
8557   "and{b}\t{%2, %h0|%h0, %2}"
8558   [(set_attr "type" "alu")
8559    (set_attr "length_immediate" "1")
8560    (set_attr "modrm" "1")
8561    (set_attr "mode" "QI")])
8563 (define_insn "*andqi_ext_1"
8564   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8565                          (const_int 8)
8566                          (const_int 8))
8567         (and:SI
8568           (zero_extract:SI
8569             (match_operand 1 "ext_register_operand" "0,0")
8570             (const_int 8)
8571             (const_int 8))
8572           (zero_extend:SI
8573             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8574    (clobber (reg:CC FLAGS_REG))]
8575   ""
8576   "and{b}\t{%2, %h0|%h0, %2}"
8577   [(set_attr "isa" "*,nox64")
8578    (set_attr "type" "alu")
8579    (set_attr "length_immediate" "0")
8580    (set_attr "mode" "QI")])
8582 (define_insn "*andqi_ext_2"
8583   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8584                          (const_int 8)
8585                          (const_int 8))
8586         (and:SI
8587           (zero_extract:SI
8588             (match_operand 1 "ext_register_operand" "%0")
8589             (const_int 8)
8590             (const_int 8))
8591           (zero_extract:SI
8592             (match_operand 2 "ext_register_operand" "Q")
8593             (const_int 8)
8594             (const_int 8))))
8595    (clobber (reg:CC FLAGS_REG))]
8596   ""
8597   "and{b}\t{%h2, %h0|%h0, %h2}"
8598   [(set_attr "type" "alu")
8599    (set_attr "length_immediate" "0")
8600    (set_attr "mode" "QI")])
8602 ;; Convert wide AND instructions with immediate operand to shorter QImode
8603 ;; equivalents when possible.
8604 ;; Don't do the splitting with memory operands, since it introduces risk
8605 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8606 ;; for size, but that can (should?) be handled by generic code instead.
8607 (define_split
8608   [(set (match_operand 0 "QIreg_operand")
8609         (and (match_operand 1 "register_operand")
8610              (match_operand 2 "const_int_operand")))
8611    (clobber (reg:CC FLAGS_REG))]
8612    "reload_completed
8613     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8614     && !(~INTVAL (operands[2]) & ~(255 << 8))
8615     && GET_MODE (operands[0]) != QImode"
8616   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8617                    (and:SI (zero_extract:SI (match_dup 1)
8618                                             (const_int 8) (const_int 8))
8619                            (match_dup 2)))
8620               (clobber (reg:CC FLAGS_REG))])]
8622   operands[0] = gen_lowpart (SImode, operands[0]);
8623   operands[1] = gen_lowpart (SImode, operands[1]);
8624   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8627 ;; Since AND can be encoded with sign extended immediate, this is only
8628 ;; profitable when 7th bit is not set.
8629 (define_split
8630   [(set (match_operand 0 "any_QIreg_operand")
8631         (and (match_operand 1 "general_operand")
8632              (match_operand 2 "const_int_operand")))
8633    (clobber (reg:CC FLAGS_REG))]
8634    "reload_completed
8635     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8636     && !(~INTVAL (operands[2]) & ~255)
8637     && !(INTVAL (operands[2]) & 128)
8638     && GET_MODE (operands[0]) != QImode"
8639   [(parallel [(set (strict_low_part (match_dup 0))
8640                    (and:QI (match_dup 1)
8641                            (match_dup 2)))
8642               (clobber (reg:CC FLAGS_REG))])]
8644   operands[0] = gen_lowpart (QImode, operands[0]);
8645   operands[1] = gen_lowpart (QImode, operands[1]);
8646   operands[2] = gen_lowpart (QImode, operands[2]);
8649 ;; Logical inclusive and exclusive OR instructions
8651 ;; %%% This used to optimize known byte-wide and operations to memory.
8652 ;; If this is considered useful, it should be done with splitters.
8654 (define_expand "<code><mode>3"
8655   [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8656         (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8657                              (match_operand:SWIM1248x 2 "<general_operand>")))]
8658   ""
8659   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8661 (define_insn "*<code><mode>_1"
8662   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8663         (any_or:SWI48
8664          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8665          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8668   "@
8669    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8670    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8671    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8672   [(set_attr "type" "alu,alu,msklog")
8673    (set_attr "mode" "<MODE>")])
8675 (define_insn_and_split "*<code>di3_doubleword"
8676   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8677         (any_or:DI
8678          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8679          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8680    (clobber (reg:CC FLAGS_REG))]
8681   "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8682    && ix86_binary_operator_ok (<CODE>, DImode, operands)"
8683   "#"
8684   "&& reload_completed"
8685   [(const_int 0)]
8687   split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8688   if (operands[2] == constm1_rtx)
8689     {
8690       if (<CODE> == IOR)
8691         {
8692           operands[1] = constm1_rtx;
8693           ix86_expand_move (SImode, &operands[0]);
8694         }
8695       else
8696         ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8697     }
8698   else if (operands[2] != const0_rtx)
8699     ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8700   else if (operands[5] == const0_rtx)
8701     emit_note (NOTE_INSN_DELETED);
8702   if (operands[5] == constm1_rtx)
8703     {
8704       if (<CODE> == IOR)
8705         {
8706           operands[4] = constm1_rtx;
8707           ix86_expand_move (SImode, &operands[3]);
8708         }
8709       else
8710         ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8711     }
8712   else if (operands[5] != const0_rtx)
8713     ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8714   DONE;
8717 (define_insn_and_split "*andndi3_doubleword"
8718   [(set (match_operand:DI 0 "register_operand" "=r,r")
8719         (and:DI
8720           (not:DI (match_operand:DI 1 "register_operand" "r,r"))
8721           (match_operand:DI 2 "nonimmediate_operand" "r,m")))
8722    (clobber (reg:CC FLAGS_REG))]
8723   "TARGET_BMI && !TARGET_64BIT && TARGET_STV && TARGET_SSE"
8724   "#"
8725   "&& reload_completed"
8726   [(parallel [(set (match_dup 0)
8727                    (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8728               (clobber (reg:CC FLAGS_REG))])
8729    (parallel [(set (match_dup 3)
8730                    (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8731               (clobber (reg:CC FLAGS_REG))])]
8732   "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8734 (define_insn "*<code>hi_1"
8735   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8736         (any_or:HI
8737          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8738          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8739    (clobber (reg:CC FLAGS_REG))]
8740   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8741   "@
8742   <logic>{w}\t{%2, %0|%0, %2}
8743   <logic>{w}\t{%2, %0|%0, %2}
8744   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8745   [(set_attr "type" "alu,alu,msklog")
8746    (set_attr "mode" "HI")])
8748 (define_insn "*<code>qi_1"
8749   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8750         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8751                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8752    (clobber (reg:CC FLAGS_REG))]
8753   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8754   "@
8755    <logic>{b}\t{%2, %0|%0, %2}
8756    <logic>{b}\t{%2, %0|%0, %2}
8757    <logic>{l}\t{%k2, %k0|%k0, %k2}
8758    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8759   [(set_attr "type" "alu,alu,alu,msklog")
8760    (set_attr "mode" "QI,QI,SI,HI")
8761    ;; Potential partial reg stall on alternative 2.
8762    (set (attr "preferred_for_speed")
8763      (cond [(eq_attr "alternative" "2")
8764               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8765            (symbol_ref "true")))])
8767 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8768 (define_insn "*<code>si_1_zext"
8769   [(set (match_operand:DI 0 "register_operand" "=r")
8770         (zero_extend:DI
8771          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8772                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8775   "<logic>{l}\t{%2, %k0|%k0, %2}"
8776   [(set_attr "type" "alu")
8777    (set_attr "mode" "SI")])
8779 (define_insn "*<code>si_1_zext_imm"
8780   [(set (match_operand:DI 0 "register_operand" "=r")
8781         (any_or:DI
8782          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8783          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8784    (clobber (reg:CC FLAGS_REG))]
8785   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8786   "<logic>{l}\t{%2, %k0|%k0, %2}"
8787   [(set_attr "type" "alu")
8788    (set_attr "mode" "SI")])
8790 (define_insn "*<code>qi_1_slp"
8791   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8792         (any_or:QI (match_dup 0)
8793                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8794    (clobber (reg:CC FLAGS_REG))]
8795   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8796    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8797   "<logic>{b}\t{%1, %0|%0, %1}"
8798   [(set_attr "type" "alu1")
8799    (set_attr "mode" "QI")])
8801 (define_insn "*<code><mode>_2"
8802   [(set (reg FLAGS_REG)
8803         (compare (any_or:SWI
8804                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8805                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8806                  (const_int 0)))
8807    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8808         (any_or:SWI (match_dup 1) (match_dup 2)))]
8809   "ix86_match_ccmode (insn, CCNOmode)
8810    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8811   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8812   [(set_attr "type" "alu")
8813    (set_attr "mode" "<MODE>")])
8815 (define_insn "kxnor<mode>"
8816   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8817         (not:SWI12
8818           (xor:SWI12
8819             (match_operand:SWI12 1 "register_operand" "0,k")
8820             (match_operand:SWI12 2 "register_operand" "r,k"))))
8821    (clobber (reg:CC FLAGS_REG))]
8822   "TARGET_AVX512F"
8824   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8825     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8826   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8828   [(set_attr "type" "*,msklog")
8829    (set_attr "prefix" "*,vex")
8830    (set_attr "mode" "<MODE>")])
8832 (define_insn "kxnor<mode>"
8833   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8834         (not:SWI48x
8835           (xor:SWI48x
8836             (match_operand:SWI48x 1 "register_operand" "0,k")
8837             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8838    (clobber (reg:CC FLAGS_REG))]
8839   "TARGET_AVX512BW"
8840   "@
8841    #
8842    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8843   [(set_attr "type" "*,msklog")
8844    (set_attr "prefix" "*,vex")
8845    (set_attr "mode" "<MODE>")])
8847 (define_split
8848   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8849         (not:SWI1248x
8850           (xor:SWI1248x
8851             (match_dup 0)
8852             (match_operand:SWI1248x 1 "general_reg_operand"))))
8853    (clobber (reg:CC FLAGS_REG))]
8854   "TARGET_AVX512F && reload_completed"
8855    [(parallel [(set (match_dup 0)
8856                     (xor:SWI1248x (match_dup 0)
8857                                   (match_dup 1)))
8858                (clobber (reg:CC FLAGS_REG))])
8859     (set (match_dup 0)
8860          (not:SWI1248x (match_dup 0)))])
8862 ;;There are kortrest[bdq] but no intrinsics for them.
8863 ;;We probably don't need to implement them.
8864 (define_insn "kortestzhi"
8865   [(set (reg:CCZ FLAGS_REG)
8866         (compare:CCZ
8867           (ior:HI
8868             (match_operand:HI 0 "register_operand" "k")
8869             (match_operand:HI 1 "register_operand" "k"))
8870           (const_int 0)))]
8871   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8872   "kortestw\t{%1, %0|%0, %1}"
8873   [(set_attr "mode" "HI")
8874    (set_attr "type" "msklog")
8875    (set_attr "prefix" "vex")])
8877 (define_insn "kortestchi"
8878   [(set (reg:CCC FLAGS_REG)
8879         (compare:CCC
8880           (ior:HI
8881             (match_operand:HI 0 "register_operand" "k")
8882             (match_operand:HI 1 "register_operand" "k"))
8883           (const_int -1)))]
8884   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8885   "kortestw\t{%1, %0|%0, %1}"
8886   [(set_attr "mode" "HI")
8887    (set_attr "type" "msklog")
8888    (set_attr "prefix" "vex")])
8890 (define_insn "kunpckhi"
8891   [(set (match_operand:HI 0 "register_operand" "=k")
8892         (ior:HI
8893           (ashift:HI
8894             (zero_extend:HI (match_operand:QI 1 "register_operand" "k"))
8895             (const_int 8))
8896           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8897   "TARGET_AVX512F"
8898   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8899   [(set_attr "mode" "HI")
8900    (set_attr "type" "msklog")
8901    (set_attr "prefix" "vex")])
8903 (define_insn "kunpcksi"
8904   [(set (match_operand:SI 0 "register_operand" "=k")
8905         (ior:SI
8906           (ashift:SI
8907             (zero_extend:SI (match_operand:HI 1 "register_operand" "k"))
8908             (const_int 16))
8909           (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))]
8910   "TARGET_AVX512BW"
8911   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8912   [(set_attr "mode" "SI")])
8914 (define_insn "kunpckdi"
8915   [(set (match_operand:DI 0 "register_operand" "=k")
8916         (ior:DI
8917           (ashift:DI
8918             (zero_extend:DI (match_operand:SI 1 "register_operand" "k"))
8919             (const_int 32))
8920           (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))]
8921   "TARGET_AVX512BW"
8922   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8923   [(set_attr "mode" "DI")])
8925 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8926 ;; ??? Special case for immediate operand is missing - it is tricky.
8927 (define_insn "*<code>si_2_zext"
8928   [(set (reg FLAGS_REG)
8929         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8930                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8931                  (const_int 0)))
8932    (set (match_operand:DI 0 "register_operand" "=r")
8933         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8934   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8935    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8936   "<logic>{l}\t{%2, %k0|%k0, %2}"
8937   [(set_attr "type" "alu")
8938    (set_attr "mode" "SI")])
8940 (define_insn "*<code>si_2_zext_imm"
8941   [(set (reg FLAGS_REG)
8942         (compare (any_or:SI
8943                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8944                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8945                  (const_int 0)))
8946    (set (match_operand:DI 0 "register_operand" "=r")
8947         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8948   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8949    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8950   "<logic>{l}\t{%2, %k0|%k0, %2}"
8951   [(set_attr "type" "alu")
8952    (set_attr "mode" "SI")])
8954 (define_insn "*<code>qi_2_slp"
8955   [(set (reg FLAGS_REG)
8956         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8957                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8958                  (const_int 0)))
8959    (set (strict_low_part (match_dup 0))
8960         (any_or:QI (match_dup 0) (match_dup 1)))]
8961   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8962    && ix86_match_ccmode (insn, CCNOmode)
8963    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8964   "<logic>{b}\t{%1, %0|%0, %1}"
8965   [(set_attr "type" "alu1")
8966    (set_attr "mode" "QI")])
8968 (define_insn "*<code><mode>_3"
8969   [(set (reg FLAGS_REG)
8970         (compare (any_or:SWI
8971                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8972                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8973                  (const_int 0)))
8974    (clobber (match_scratch:SWI 0 "=<r>"))]
8975   "ix86_match_ccmode (insn, CCNOmode)
8976    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8977   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "mode" "<MODE>")])
8981 (define_insn "*<code>qi_ext_0"
8982   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8983                          (const_int 8)
8984                          (const_int 8))
8985         (any_or:SI
8986           (zero_extract:SI
8987             (match_operand 1 "ext_register_operand" "0")
8988             (const_int 8)
8989             (const_int 8))
8990           (match_operand 2 "const_int_operand" "n")))
8991    (clobber (reg:CC FLAGS_REG))]
8992   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8993   "<logic>{b}\t{%2, %h0|%h0, %2}"
8994   [(set_attr "type" "alu")
8995    (set_attr "length_immediate" "1")
8996    (set_attr "modrm" "1")
8997    (set_attr "mode" "QI")])
8999 (define_insn "*<code>qi_ext_1"
9000   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
9001                          (const_int 8)
9002                          (const_int 8))
9003         (any_or:SI
9004           (zero_extract:SI
9005             (match_operand 1 "ext_register_operand" "0,0")
9006             (const_int 8)
9007             (const_int 8))
9008           (zero_extend:SI
9009             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
9010    (clobber (reg:CC FLAGS_REG))]
9011   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9012   "<logic>{b}\t{%2, %h0|%h0, %2}"
9013   [(set_attr "isa" "*,nox64")
9014    (set_attr "type" "alu")
9015    (set_attr "length_immediate" "0")
9016    (set_attr "mode" "QI")])
9018 (define_insn "*<code>qi_ext_2"
9019   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9020                          (const_int 8)
9021                          (const_int 8))
9022         (any_or:SI
9023           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9024                            (const_int 8)
9025                            (const_int 8))
9026           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9027                            (const_int 8)
9028                            (const_int 8))))
9029    (clobber (reg:CC FLAGS_REG))]
9030   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9031   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9032   [(set_attr "type" "alu")
9033    (set_attr "length_immediate" "0")
9034    (set_attr "mode" "QI")])
9036 (define_split
9037   [(set (match_operand 0 "QIreg_operand")
9038         (any_or (match_operand 1 "register_operand")
9039                 (match_operand 2 "const_int_operand")))
9040    (clobber (reg:CC FLAGS_REG))]
9041    "reload_completed
9042     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9043     && !(INTVAL (operands[2]) & ~(255 << 8))
9044     && GET_MODE (operands[0]) != QImode"
9045   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9046                    (any_or:SI (zero_extract:SI (match_dup 1)
9047                                                (const_int 8) (const_int 8))
9048                               (match_dup 2)))
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) & 0xff, SImode);
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 0 "any_QIreg_operand")
9060         (any_or (match_operand 1 "general_operand")
9061                 (match_operand 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     && GET_MODE (operands[0]) != QImode"
9068   [(parallel [(set (strict_low_part (match_dup 0))
9069                    (any_or:QI (match_dup 1)
9070                               (match_dup 2)))
9071               (clobber (reg:CC FLAGS_REG))])]
9073   operands[0] = gen_lowpart (QImode, operands[0]);
9074   operands[1] = gen_lowpart (QImode, operands[1]);
9075   operands[2] = gen_lowpart (QImode, operands[2]);
9078 (define_expand "xorqi_cc_ext_1"
9079   [(parallel [
9080      (set (reg:CCNO FLAGS_REG)
9081           (compare:CCNO
9082             (xor:SI
9083               (zero_extract:SI
9084                 (match_operand 1 "ext_register_operand")
9085                 (const_int 8)
9086                 (const_int 8))
9087               (match_operand:QI 2 "const_int_operand"))
9088             (const_int 0)))
9089      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9090                            (const_int 8)
9091                            (const_int 8))
9092           (xor:SI
9093             (zero_extract:SI
9094              (match_dup 1)
9095              (const_int 8)
9096              (const_int 8))
9097             (match_dup 2)))])])
9099 (define_insn "*xorqi_cc_ext_1"
9100   [(set (reg FLAGS_REG)
9101         (compare
9102           (xor:SI
9103             (zero_extract:SI
9104               (match_operand 1 "ext_register_operand" "0,0")
9105               (const_int 8)
9106               (const_int 8))
9107             (match_operand:QI 2 "general_x64nomem_operand" "Qn,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         (xor:SI
9113           (zero_extract:SI
9114            (match_dup 1)
9115            (const_int 8)
9116            (const_int 8))
9117           (match_dup 2)))]
9118   "ix86_match_ccmode (insn, CCNOmode)"
9119   "xor{b}\t{%2, %h0|%h0, %2}"
9120   [(set_attr "isa" "*,nox64")
9121    (set_attr "type" "alu")
9122    (set_attr "modrm" "1")
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:SWIM 0 "nonimmediate_operand")
9516         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
9517   ""
9518   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9520 (define_insn "*one_cmpl<mode>2_1"
9521   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
9522         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
9523   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9524   "@
9525    not{<imodesuffix>}\t%0
9526    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
9527   [(set_attr "isa" "*,avx512bw")
9528    (set_attr "type" "negnot,msklog")
9529    (set_attr "prefix" "*,vex")
9530    (set_attr "mode" "<MODE>")])
9532 (define_insn "*one_cmplhi2_1"
9533   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
9534         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
9535   "ix86_unary_operator_ok (NOT, HImode, operands)"
9536   "@
9537    not{w}\t%0
9538    knotw\t{%1, %0|%0, %1}"
9539   [(set_attr "isa" "*,avx512f")
9540    (set_attr "type" "negnot,msklog")
9541    (set_attr "prefix" "*,vex")
9542    (set_attr "mode" "HI")])
9544 (define_insn "*one_cmplqi2_1"
9545   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
9546         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
9547   "ix86_unary_operator_ok (NOT, QImode, operands)"
9549   switch (which_alternative)
9550     {
9551     case 0:
9552       return "not{b}\t%0";
9553     case 1:
9554       return "not{l}\t%k0";
9555     case 2:
9556       if (TARGET_AVX512DQ)
9557         return "knotb\t{%1, %0|%0, %1}";
9558       return "knotw\t{%1, %0|%0, %1}";
9559     default:
9560       gcc_unreachable ();
9561     }
9563   [(set_attr "isa" "*,*,avx512f")
9564    (set_attr "type" "negnot,negnot,msklog")
9565    (set_attr "prefix" "*,*,vex")
9566    (set_attr "mode" "QI,SI,QI")
9567    ;; Potential partial reg stall on alternative 1.
9568    (set (attr "preferred_for_speed")
9569      (cond [(eq_attr "alternative" "1")
9570               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9571            (symbol_ref "true")))])
9573 ;; ??? Currently never generated - xor is used instead.
9574 (define_insn "*one_cmplsi2_1_zext"
9575   [(set (match_operand:DI 0 "register_operand" "=r")
9576         (zero_extend:DI
9577           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9578   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9579   "not{l}\t%k0"
9580   [(set_attr "type" "negnot")
9581    (set_attr "mode" "SI")])
9583 (define_insn "*one_cmpl<mode>2_2"
9584   [(set (reg FLAGS_REG)
9585         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9586                  (const_int 0)))
9587    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9588         (not:SWI (match_dup 1)))]
9589   "ix86_match_ccmode (insn, CCNOmode)
9590    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9591   "#"
9592   [(set_attr "type" "alu1")
9593    (set_attr "mode" "<MODE>")])
9595 (define_split
9596   [(set (match_operand 0 "flags_reg_operand")
9597         (match_operator 2 "compare_operator"
9598           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9599            (const_int 0)]))
9600    (set (match_operand:SWI 1 "nonimmediate_operand")
9601         (not:SWI (match_dup 3)))]
9602   "ix86_match_ccmode (insn, CCNOmode)"
9603   [(parallel [(set (match_dup 0)
9604                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9605                                     (const_int 0)]))
9606               (set (match_dup 1)
9607                    (xor:SWI (match_dup 3) (const_int -1)))])])
9609 ;; ??? Currently never generated - xor is used instead.
9610 (define_insn "*one_cmplsi2_2_zext"
9611   [(set (reg FLAGS_REG)
9612         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9613                  (const_int 0)))
9614    (set (match_operand:DI 0 "register_operand" "=r")
9615         (zero_extend:DI (not:SI (match_dup 1))))]
9616   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9617    && ix86_unary_operator_ok (NOT, SImode, operands)"
9618   "#"
9619   [(set_attr "type" "alu1")
9620    (set_attr "mode" "SI")])
9622 (define_split
9623   [(set (match_operand 0 "flags_reg_operand")
9624         (match_operator 2 "compare_operator"
9625           [(not:SI (match_operand:SI 3 "register_operand"))
9626            (const_int 0)]))
9627    (set (match_operand:DI 1 "register_operand")
9628         (zero_extend:DI (not:SI (match_dup 3))))]
9629   "ix86_match_ccmode (insn, CCNOmode)"
9630   [(parallel [(set (match_dup 0)
9631                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9632                                     (const_int 0)]))
9633               (set (match_dup 1)
9634                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9636 ;; Shift instructions
9638 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9639 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9640 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9641 ;; from the assembler input.
9643 ;; This instruction shifts the target reg/mem as usual, but instead of
9644 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9645 ;; is a left shift double, bits are taken from the high order bits of
9646 ;; reg, else if the insn is a shift right double, bits are taken from the
9647 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9648 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9650 ;; Since sh[lr]d does not change the `reg' operand, that is done
9651 ;; separately, making all shifts emit pairs of shift double and normal
9652 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9653 ;; support a 63 bit shift, each shift where the count is in a reg expands
9654 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9656 ;; If the shift count is a constant, we need never emit more than one
9657 ;; shift pair, instead using moves and sign extension for counts greater
9658 ;; than 31.
9660 (define_insn "*<mshift><mode>3"
9661   [(set (match_operand:SWI1248_AVX512BWDQ 0 "register_operand" "=k")
9662         (any_lshift:SWI1248_AVX512BWDQ (match_operand:SWI1248_AVX512BWDQ 1 "register_operand" "k")
9663                                        (match_operand:QI 2 "immediate_operand" "i")))]
9664   "TARGET_AVX512F"
9665   "k<mshift><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
9666   [(set_attr "type" "msklog")
9667    (set_attr "prefix" "vex")])
9669 (define_expand "ashl<mode>3"
9670   [(set (match_operand:SDWIM 0 "<shift_operand>")
9671         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9672                       (match_operand:QI 2 "nonmemory_operand")))]
9673   ""
9674   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9676 (define_insn "*ashl<mode>3_doubleword"
9677   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9678         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9679                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9680    (clobber (reg:CC FLAGS_REG))]
9681   ""
9682   "#"
9683   [(set_attr "type" "multi")])
9685 (define_split
9686   [(set (match_operand:DWI 0 "register_operand")
9687         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9688                     (match_operand:QI 2 "nonmemory_operand")))
9689    (clobber (reg:CC FLAGS_REG))]
9690   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9691   [(const_int 0)]
9692   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9694 ;; By default we don't ask for a scratch register, because when DWImode
9695 ;; values are manipulated, registers are already at a premium.  But if
9696 ;; we have one handy, we won't turn it away.
9698 (define_peephole2
9699   [(match_scratch:DWIH 3 "r")
9700    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9701                    (ashift:<DWI>
9702                      (match_operand:<DWI> 1 "nonmemory_operand")
9703                      (match_operand:QI 2 "nonmemory_operand")))
9704               (clobber (reg:CC FLAGS_REG))])
9705    (match_dup 3)]
9706   "TARGET_CMOVE"
9707   [(const_int 0)]
9708   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9710 (define_insn "x86_64_shld"
9711   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9712         (ior:DI (ashift:DI (match_dup 0)
9713                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9714                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9715                   (minus:QI (const_int 64) (match_dup 2)))))
9716    (clobber (reg:CC FLAGS_REG))]
9717   "TARGET_64BIT"
9718   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9719   [(set_attr "type" "ishift")
9720    (set_attr "prefix_0f" "1")
9721    (set_attr "mode" "DI")
9722    (set_attr "athlon_decode" "vector")
9723    (set_attr "amdfam10_decode" "vector")
9724    (set_attr "bdver1_decode" "vector")])
9726 (define_insn "x86_shld"
9727   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9728         (ior:SI (ashift:SI (match_dup 0)
9729                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9730                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9731                   (minus:QI (const_int 32) (match_dup 2)))))
9732    (clobber (reg:CC FLAGS_REG))]
9733   ""
9734   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9735   [(set_attr "type" "ishift")
9736    (set_attr "prefix_0f" "1")
9737    (set_attr "mode" "SI")
9738    (set_attr "pent_pair" "np")
9739    (set_attr "athlon_decode" "vector")
9740    (set_attr "amdfam10_decode" "vector")
9741    (set_attr "bdver1_decode" "vector")])
9743 (define_expand "x86_shift<mode>_adj_1"
9744   [(set (reg:CCZ FLAGS_REG)
9745         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9746                              (match_dup 4))
9747                      (const_int 0)))
9748    (set (match_operand:SWI48 0 "register_operand")
9749         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9750                             (match_operand:SWI48 1 "register_operand")
9751                             (match_dup 0)))
9752    (set (match_dup 1)
9753         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9754                             (match_operand:SWI48 3 "register_operand")
9755                             (match_dup 1)))]
9756   "TARGET_CMOVE"
9757   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9759 (define_expand "x86_shift<mode>_adj_2"
9760   [(use (match_operand:SWI48 0 "register_operand"))
9761    (use (match_operand:SWI48 1 "register_operand"))
9762    (use (match_operand:QI 2 "register_operand"))]
9763   ""
9765   rtx_code_label *label = gen_label_rtx ();
9766   rtx tmp;
9768   emit_insn (gen_testqi_ccz_1 (operands[2],
9769                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9771   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9772   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9773   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9774                               gen_rtx_LABEL_REF (VOIDmode, label),
9775                               pc_rtx);
9776   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9777   JUMP_LABEL (tmp) = label;
9779   emit_move_insn (operands[0], operands[1]);
9780   ix86_expand_clear (operands[1]);
9782   emit_label (label);
9783   LABEL_NUSES (label) = 1;
9785   DONE;
9788 ;; Avoid useless masking of count operand.
9789 (define_insn "*ashl<mode>3_mask"
9790   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9791         (ashift:SWI48
9792           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9793           (subreg:QI
9794             (and:SI
9795               (match_operand:SI 2 "register_operand" "c")
9796               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9799    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9800       == GET_MODE_BITSIZE (<MODE>mode)-1"
9802   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9804   [(set_attr "type" "ishift")
9805    (set_attr "mode" "<MODE>")])
9807 (define_insn "*bmi2_ashl<mode>3_1"
9808   [(set (match_operand:SWI48 0 "register_operand" "=r")
9809         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9810                       (match_operand:SWI48 2 "register_operand" "r")))]
9811   "TARGET_BMI2"
9812   "shlx\t{%2, %1, %0|%0, %1, %2}"
9813   [(set_attr "type" "ishiftx")
9814    (set_attr "mode" "<MODE>")])
9816 (define_insn "*ashl<mode>3_1"
9817   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9818         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9819                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9820    (clobber (reg:CC FLAGS_REG))]
9821   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9823   switch (get_attr_type (insn))
9824     {
9825     case TYPE_LEA:
9826     case TYPE_ISHIFTX:
9827       return "#";
9829     case TYPE_ALU:
9830       gcc_assert (operands[2] == const1_rtx);
9831       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9832       return "add{<imodesuffix>}\t%0, %0";
9834     default:
9835       if (operands[2] == const1_rtx
9836           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9837         return "sal{<imodesuffix>}\t%0";
9838       else
9839         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9840     }
9842   [(set_attr "isa" "*,*,bmi2")
9843    (set (attr "type")
9844      (cond [(eq_attr "alternative" "1")
9845               (const_string "lea")
9846             (eq_attr "alternative" "2")
9847               (const_string "ishiftx")
9848             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9849                       (match_operand 0 "register_operand"))
9850                  (match_operand 2 "const1_operand"))
9851               (const_string "alu")
9852            ]
9853            (const_string "ishift")))
9854    (set (attr "length_immediate")
9855      (if_then_else
9856        (ior (eq_attr "type" "alu")
9857             (and (eq_attr "type" "ishift")
9858                  (and (match_operand 2 "const1_operand")
9859                       (ior (match_test "TARGET_SHIFT1")
9860                            (match_test "optimize_function_for_size_p (cfun)")))))
9861        (const_string "0")
9862        (const_string "*")))
9863    (set_attr "mode" "<MODE>")])
9865 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9866 (define_split
9867   [(set (match_operand:SWI48 0 "register_operand")
9868         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9869                       (match_operand:QI 2 "register_operand")))
9870    (clobber (reg:CC FLAGS_REG))]
9871   "TARGET_BMI2 && reload_completed"
9872   [(set (match_dup 0)
9873         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9874   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9876 (define_insn "*bmi2_ashlsi3_1_zext"
9877   [(set (match_operand:DI 0 "register_operand" "=r")
9878         (zero_extend:DI
9879           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9880                      (match_operand:SI 2 "register_operand" "r"))))]
9881   "TARGET_64BIT && TARGET_BMI2"
9882   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9883   [(set_attr "type" "ishiftx")
9884    (set_attr "mode" "SI")])
9886 (define_insn "*ashlsi3_1_zext"
9887   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9888         (zero_extend:DI
9889           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9890                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9894   switch (get_attr_type (insn))
9895     {
9896     case TYPE_LEA:
9897     case TYPE_ISHIFTX:
9898       return "#";
9900     case TYPE_ALU:
9901       gcc_assert (operands[2] == const1_rtx);
9902       return "add{l}\t%k0, %k0";
9904     default:
9905       if (operands[2] == const1_rtx
9906           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9907         return "sal{l}\t%k0";
9908       else
9909         return "sal{l}\t{%2, %k0|%k0, %2}";
9910     }
9912   [(set_attr "isa" "*,*,bmi2")
9913    (set (attr "type")
9914      (cond [(eq_attr "alternative" "1")
9915               (const_string "lea")
9916             (eq_attr "alternative" "2")
9917               (const_string "ishiftx")
9918             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9919                  (match_operand 2 "const1_operand"))
9920               (const_string "alu")
9921            ]
9922            (const_string "ishift")))
9923    (set (attr "length_immediate")
9924      (if_then_else
9925        (ior (eq_attr "type" "alu")
9926             (and (eq_attr "type" "ishift")
9927                  (and (match_operand 2 "const1_operand")
9928                       (ior (match_test "TARGET_SHIFT1")
9929                            (match_test "optimize_function_for_size_p (cfun)")))))
9930        (const_string "0")
9931        (const_string "*")))
9932    (set_attr "mode" "SI")])
9934 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9935 (define_split
9936   [(set (match_operand:DI 0 "register_operand")
9937         (zero_extend:DI
9938           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9939                      (match_operand:QI 2 "register_operand"))))
9940    (clobber (reg:CC FLAGS_REG))]
9941   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9942   [(set (match_dup 0)
9943         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9944   "operands[2] = gen_lowpart (SImode, operands[2]);")
9946 (define_insn "*ashlhi3_1"
9947   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9948         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9949                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9950    (clobber (reg:CC FLAGS_REG))]
9951   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9953   switch (get_attr_type (insn))
9954     {
9955     case TYPE_LEA:
9956       return "#";
9958     case TYPE_ALU:
9959       gcc_assert (operands[2] == const1_rtx);
9960       return "add{w}\t%0, %0";
9962     default:
9963       if (operands[2] == const1_rtx
9964           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9965         return "sal{w}\t%0";
9966       else
9967         return "sal{w}\t{%2, %0|%0, %2}";
9968     }
9970   [(set (attr "type")
9971      (cond [(eq_attr "alternative" "1")
9972               (const_string "lea")
9973             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9974                       (match_operand 0 "register_operand"))
9975                  (match_operand 2 "const1_operand"))
9976               (const_string "alu")
9977            ]
9978            (const_string "ishift")))
9979    (set (attr "length_immediate")
9980      (if_then_else
9981        (ior (eq_attr "type" "alu")
9982             (and (eq_attr "type" "ishift")
9983                  (and (match_operand 2 "const1_operand")
9984                       (ior (match_test "TARGET_SHIFT1")
9985                            (match_test "optimize_function_for_size_p (cfun)")))))
9986        (const_string "0")
9987        (const_string "*")))
9988    (set_attr "mode" "HI,SI")])
9990 (define_insn "*ashlqi3_1"
9991   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9992         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9993                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9994    (clobber (reg:CC FLAGS_REG))]
9995   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9997   switch (get_attr_type (insn))
9998     {
9999     case TYPE_LEA:
10000       return "#";
10002     case TYPE_ALU:
10003       gcc_assert (operands[2] == const1_rtx);
10004       if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10005         return "add{l}\t%k0, %k0";
10006       else
10007         return "add{b}\t%0, %0";
10009     default:
10010       if (operands[2] == const1_rtx
10011           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10012         {
10013           if (get_attr_mode (insn) == MODE_SI)
10014             return "sal{l}\t%k0";
10015           else
10016             return "sal{b}\t%0";
10017         }
10018       else
10019         {
10020           if (get_attr_mode (insn) == MODE_SI)
10021             return "sal{l}\t{%2, %k0|%k0, %2}";
10022           else
10023             return "sal{b}\t{%2, %0|%0, %2}";
10024         }
10025     }
10027   [(set (attr "type")
10028      (cond [(eq_attr "alternative" "2")
10029               (const_string "lea")
10030             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10031                       (match_operand 0 "register_operand"))
10032                  (match_operand 2 "const1_operand"))
10033               (const_string "alu")
10034            ]
10035            (const_string "ishift")))
10036    (set (attr "length_immediate")
10037      (if_then_else
10038        (ior (eq_attr "type" "alu")
10039             (and (eq_attr "type" "ishift")
10040                  (and (match_operand 2 "const1_operand")
10041                       (ior (match_test "TARGET_SHIFT1")
10042                            (match_test "optimize_function_for_size_p (cfun)")))))
10043        (const_string "0")
10044        (const_string "*")))
10045    (set_attr "mode" "QI,SI,SI")
10046    ;; Potential partial reg stall on alternative 1.
10047    (set (attr "preferred_for_speed")
10048      (cond [(eq_attr "alternative" "1")
10049               (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10050            (symbol_ref "true")))])
10052 (define_insn "*ashlqi3_1_slp"
10053   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10054         (ashift:QI (match_dup 0)
10055                    (match_operand:QI 1 "nonmemory_operand" "cI")))
10056    (clobber (reg:CC FLAGS_REG))]
10057   "(optimize_function_for_size_p (cfun)
10058     || !TARGET_PARTIAL_FLAG_REG_STALL
10059     || (operands[1] == const1_rtx
10060         && (TARGET_SHIFT1
10061             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10063   switch (get_attr_type (insn))
10064     {
10065     case TYPE_ALU:
10066       gcc_assert (operands[1] == const1_rtx);
10067       return "add{b}\t%0, %0";
10069     default:
10070       if (operands[1] == const1_rtx
10071           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10072         return "sal{b}\t%0";
10073       else
10074         return "sal{b}\t{%1, %0|%0, %1}";
10075     }
10077   [(set (attr "type")
10078      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10079                       (match_operand 0 "register_operand"))
10080                  (match_operand 1 "const1_operand"))
10081               (const_string "alu")
10082            ]
10083            (const_string "ishift1")))
10084    (set (attr "length_immediate")
10085      (if_then_else
10086        (ior (eq_attr "type" "alu")
10087             (and (eq_attr "type" "ishift1")
10088                  (and (match_operand 1 "const1_operand")
10089                       (ior (match_test "TARGET_SHIFT1")
10090                            (match_test "optimize_function_for_size_p (cfun)")))))
10091        (const_string "0")
10092        (const_string "*")))
10093    (set_attr "mode" "QI")])
10095 ;; Convert ashift to the lea pattern to avoid flags dependency.
10096 (define_split
10097   [(set (match_operand:SWI 0 "register_operand")
10098         (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10099                     (match_operand 2 "const_0_to_3_operand")))
10100    (clobber (reg:CC FLAGS_REG))]
10101   "reload_completed
10102    && REGNO (operands[0]) != REGNO (operands[1])"
10103   [(set (match_dup 0)
10104         (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10106   if (<MODE>mode != <LEAMODE>mode)
10107     {
10108       operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10109       operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10110     }
10111   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10114 ;; Convert ashift to the lea pattern to avoid flags dependency.
10115 (define_split
10116   [(set (match_operand:DI 0 "register_operand")
10117         (zero_extend:DI
10118           (ashift:SI (match_operand:SI 1 "index_register_operand")
10119                      (match_operand 2 "const_0_to_3_operand"))))
10120    (clobber (reg:CC FLAGS_REG))]
10121   "TARGET_64BIT && reload_completed
10122    && REGNO (operands[0]) != REGNO (operands[1])"
10123   [(set (match_dup 0)
10124         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10126   operands[1] = gen_lowpart (SImode, operands[1]);
10127   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10130 ;; This pattern can't accept a variable shift count, since shifts by
10131 ;; zero don't affect the flags.  We assume that shifts by constant
10132 ;; zero are optimized away.
10133 (define_insn "*ashl<mode>3_cmp"
10134   [(set (reg FLAGS_REG)
10135         (compare
10136           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10137                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10138           (const_int 0)))
10139    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10140         (ashift:SWI (match_dup 1) (match_dup 2)))]
10141   "(optimize_function_for_size_p (cfun)
10142     || !TARGET_PARTIAL_FLAG_REG_STALL
10143     || (operands[2] == const1_rtx
10144         && (TARGET_SHIFT1
10145             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10146    && ix86_match_ccmode (insn, CCGOCmode)
10147    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10149   switch (get_attr_type (insn))
10150     {
10151     case TYPE_ALU:
10152       gcc_assert (operands[2] == const1_rtx);
10153       return "add{<imodesuffix>}\t%0, %0";
10155     default:
10156       if (operands[2] == const1_rtx
10157           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10158         return "sal{<imodesuffix>}\t%0";
10159       else
10160         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10161     }
10163   [(set (attr "type")
10164      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10165                       (match_operand 0 "register_operand"))
10166                  (match_operand 2 "const1_operand"))
10167               (const_string "alu")
10168            ]
10169            (const_string "ishift")))
10170    (set (attr "length_immediate")
10171      (if_then_else
10172        (ior (eq_attr "type" "alu")
10173             (and (eq_attr "type" "ishift")
10174                  (and (match_operand 2 "const1_operand")
10175                       (ior (match_test "TARGET_SHIFT1")
10176                            (match_test "optimize_function_for_size_p (cfun)")))))
10177        (const_string "0")
10178        (const_string "*")))
10179    (set_attr "mode" "<MODE>")])
10181 (define_insn "*ashlsi3_cmp_zext"
10182   [(set (reg FLAGS_REG)
10183         (compare
10184           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10185                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10186           (const_int 0)))
10187    (set (match_operand:DI 0 "register_operand" "=r")
10188         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10189   "TARGET_64BIT
10190    && (optimize_function_for_size_p (cfun)
10191        || !TARGET_PARTIAL_FLAG_REG_STALL
10192        || (operands[2] == const1_rtx
10193            && (TARGET_SHIFT1
10194                || TARGET_DOUBLE_WITH_ADD)))
10195    && ix86_match_ccmode (insn, CCGOCmode)
10196    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10198   switch (get_attr_type (insn))
10199     {
10200     case TYPE_ALU:
10201       gcc_assert (operands[2] == const1_rtx);
10202       return "add{l}\t%k0, %k0";
10204     default:
10205       if (operands[2] == const1_rtx
10206           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10207         return "sal{l}\t%k0";
10208       else
10209         return "sal{l}\t{%2, %k0|%k0, %2}";
10210     }
10212   [(set (attr "type")
10213      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10214                  (match_operand 2 "const1_operand"))
10215               (const_string "alu")
10216            ]
10217            (const_string "ishift")))
10218    (set (attr "length_immediate")
10219      (if_then_else
10220        (ior (eq_attr "type" "alu")
10221             (and (eq_attr "type" "ishift")
10222                  (and (match_operand 2 "const1_operand")
10223                       (ior (match_test "TARGET_SHIFT1")
10224                            (match_test "optimize_function_for_size_p (cfun)")))))
10225        (const_string "0")
10226        (const_string "*")))
10227    (set_attr "mode" "SI")])
10229 (define_insn "*ashl<mode>3_cconly"
10230   [(set (reg FLAGS_REG)
10231         (compare
10232           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10233                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10234           (const_int 0)))
10235    (clobber (match_scratch:SWI 0 "=<r>"))]
10236   "(optimize_function_for_size_p (cfun)
10237     || !TARGET_PARTIAL_FLAG_REG_STALL
10238     || (operands[2] == const1_rtx
10239         && (TARGET_SHIFT1
10240             || TARGET_DOUBLE_WITH_ADD)))
10241    && ix86_match_ccmode (insn, CCGOCmode)"
10243   switch (get_attr_type (insn))
10244     {
10245     case TYPE_ALU:
10246       gcc_assert (operands[2] == const1_rtx);
10247       return "add{<imodesuffix>}\t%0, %0";
10249     default:
10250       if (operands[2] == const1_rtx
10251           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10252         return "sal{<imodesuffix>}\t%0";
10253       else
10254         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10255     }
10257   [(set (attr "type")
10258      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10259                       (match_operand 0 "register_operand"))
10260                  (match_operand 2 "const1_operand"))
10261               (const_string "alu")
10262            ]
10263            (const_string "ishift")))
10264    (set (attr "length_immediate")
10265      (if_then_else
10266        (ior (eq_attr "type" "alu")
10267             (and (eq_attr "type" "ishift")
10268                  (and (match_operand 2 "const1_operand")
10269                       (ior (match_test "TARGET_SHIFT1")
10270                            (match_test "optimize_function_for_size_p (cfun)")))))
10271        (const_string "0")
10272        (const_string "*")))
10273    (set_attr "mode" "<MODE>")])
10275 ;; See comment above `ashl<mode>3' about how this works.
10277 (define_expand "<shift_insn><mode>3"
10278   [(set (match_operand:SDWIM 0 "<shift_operand>")
10279         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10280                            (match_operand:QI 2 "nonmemory_operand")))]
10281   ""
10282   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10284 ;; Avoid useless masking of count operand.
10285 (define_insn "*<shift_insn><mode>3_mask"
10286   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10287         (any_shiftrt:SWI48
10288           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10289           (subreg:QI
10290             (and:SI
10291               (match_operand:SI 2 "register_operand" "c")
10292               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10293    (clobber (reg:CC FLAGS_REG))]
10294   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10295    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10296       == GET_MODE_BITSIZE (<MODE>mode)-1"
10298   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10300   [(set_attr "type" "ishift")
10301    (set_attr "mode" "<MODE>")])
10303 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10304   [(set (match_operand:DWI 0 "register_operand" "=r")
10305         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10306                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10307    (clobber (reg:CC FLAGS_REG))]
10308   ""
10309   "#"
10310   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10311   [(const_int 0)]
10312   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10313   [(set_attr "type" "multi")])
10315 ;; By default we don't ask for a scratch register, because when DWImode
10316 ;; values are manipulated, registers are already at a premium.  But if
10317 ;; we have one handy, we won't turn it away.
10319 (define_peephole2
10320   [(match_scratch:DWIH 3 "r")
10321    (parallel [(set (match_operand:<DWI> 0 "register_operand")
10322                    (any_shiftrt:<DWI>
10323                      (match_operand:<DWI> 1 "register_operand")
10324                      (match_operand:QI 2 "nonmemory_operand")))
10325               (clobber (reg:CC FLAGS_REG))])
10326    (match_dup 3)]
10327   "TARGET_CMOVE"
10328   [(const_int 0)]
10329   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10331 (define_insn "x86_64_shrd"
10332   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10333         (ior:DI (lshiftrt:DI (match_dup 0)
10334                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10335                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10336                   (minus:QI (const_int 64) (match_dup 2)))))
10337    (clobber (reg:CC FLAGS_REG))]
10338   "TARGET_64BIT"
10339   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10340   [(set_attr "type" "ishift")
10341    (set_attr "prefix_0f" "1")
10342    (set_attr "mode" "DI")
10343    (set_attr "athlon_decode" "vector")
10344    (set_attr "amdfam10_decode" "vector")
10345    (set_attr "bdver1_decode" "vector")])
10347 (define_insn "x86_shrd"
10348   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10349         (ior:SI (lshiftrt:SI (match_dup 0)
10350                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10351                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10352                   (minus:QI (const_int 32) (match_dup 2)))))
10353    (clobber (reg:CC FLAGS_REG))]
10354   ""
10355   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10356   [(set_attr "type" "ishift")
10357    (set_attr "prefix_0f" "1")
10358    (set_attr "mode" "SI")
10359    (set_attr "pent_pair" "np")
10360    (set_attr "athlon_decode" "vector")
10361    (set_attr "amdfam10_decode" "vector")
10362    (set_attr "bdver1_decode" "vector")])
10364 (define_insn "ashrdi3_cvt"
10365   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10366         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10367                      (match_operand:QI 2 "const_int_operand")))
10368    (clobber (reg:CC FLAGS_REG))]
10369   "TARGET_64BIT && INTVAL (operands[2]) == 63
10370    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10371    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10372   "@
10373    {cqto|cqo}
10374    sar{q}\t{%2, %0|%0, %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" "DI")])
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_insn "*ashrsi3_cvt_zext"
10399   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10400         (zero_extend:DI
10401           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10402                        (match_operand:QI 2 "const_int_operand"))))
10403    (clobber (reg:CC FLAGS_REG))]
10404   "TARGET_64BIT && INTVAL (operands[2]) == 31
10405    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10406    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10407   "@
10408    {cltd|cdq}
10409    sar{l}\t{%2, %k0|%k0, %2}"
10410   [(set_attr "type" "imovx,ishift")
10411    (set_attr "prefix_0f" "0,*")
10412    (set_attr "length_immediate" "0,*")
10413    (set_attr "modrm" "0,1")
10414    (set_attr "mode" "SI")])
10416 (define_expand "x86_shift<mode>_adj_3"
10417   [(use (match_operand:SWI48 0 "register_operand"))
10418    (use (match_operand:SWI48 1 "register_operand"))
10419    (use (match_operand:QI 2 "register_operand"))]
10420   ""
10422   rtx_code_label *label = gen_label_rtx ();
10423   rtx tmp;
10425   emit_insn (gen_testqi_ccz_1 (operands[2],
10426                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10428   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10429   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10430   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10431                               gen_rtx_LABEL_REF (VOIDmode, label),
10432                               pc_rtx);
10433   tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10434   JUMP_LABEL (tmp) = label;
10436   emit_move_insn (operands[0], operands[1]);
10437   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10438                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10439   emit_label (label);
10440   LABEL_NUSES (label) = 1;
10442   DONE;
10445 (define_insn "*bmi2_<shift_insn><mode>3_1"
10446   [(set (match_operand:SWI48 0 "register_operand" "=r")
10447         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10448                            (match_operand:SWI48 2 "register_operand" "r")))]
10449   "TARGET_BMI2"
10450   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10451   [(set_attr "type" "ishiftx")
10452    (set_attr "mode" "<MODE>")])
10454 (define_insn "*<shift_insn><mode>3_1"
10455   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10456         (any_shiftrt:SWI48
10457           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10458           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10459    (clobber (reg:CC FLAGS_REG))]
10460   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10462   switch (get_attr_type (insn))
10463     {
10464     case TYPE_ISHIFTX:
10465       return "#";
10467     default:
10468       if (operands[2] == const1_rtx
10469           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10470         return "<shift>{<imodesuffix>}\t%0";
10471       else
10472         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10473     }
10475   [(set_attr "isa" "*,bmi2")
10476    (set_attr "type" "ishift,ishiftx")
10477    (set (attr "length_immediate")
10478      (if_then_else
10479        (and (match_operand 2 "const1_operand")
10480             (ior (match_test "TARGET_SHIFT1")
10481                  (match_test "optimize_function_for_size_p (cfun)")))
10482        (const_string "0")
10483        (const_string "*")))
10484    (set_attr "mode" "<MODE>")])
10486 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10487 (define_split
10488   [(set (match_operand:SWI48 0 "register_operand")
10489         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10490                            (match_operand:QI 2 "register_operand")))
10491    (clobber (reg:CC FLAGS_REG))]
10492   "TARGET_BMI2 && reload_completed"
10493   [(set (match_dup 0)
10494         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10495   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10497 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10498   [(set (match_operand:DI 0 "register_operand" "=r")
10499         (zero_extend:DI
10500           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10501                           (match_operand:SI 2 "register_operand" "r"))))]
10502   "TARGET_64BIT && TARGET_BMI2"
10503   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10504   [(set_attr "type" "ishiftx")
10505    (set_attr "mode" "SI")])
10507 (define_insn "*<shift_insn>si3_1_zext"
10508   [(set (match_operand:DI 0 "register_operand" "=r,r")
10509         (zero_extend:DI
10510           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10511                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10512    (clobber (reg:CC FLAGS_REG))]
10513   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10515   switch (get_attr_type (insn))
10516     {
10517     case TYPE_ISHIFTX:
10518       return "#";
10520     default:
10521       if (operands[2] == const1_rtx
10522           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10523         return "<shift>{l}\t%k0";
10524       else
10525         return "<shift>{l}\t{%2, %k0|%k0, %2}";
10526     }
10528   [(set_attr "isa" "*,bmi2")
10529    (set_attr "type" "ishift,ishiftx")
10530    (set (attr "length_immediate")
10531      (if_then_else
10532        (and (match_operand 2 "const1_operand")
10533             (ior (match_test "TARGET_SHIFT1")
10534                  (match_test "optimize_function_for_size_p (cfun)")))
10535        (const_string "0")
10536        (const_string "*")))
10537    (set_attr "mode" "SI")])
10539 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10540 (define_split
10541   [(set (match_operand:DI 0 "register_operand")
10542         (zero_extend:DI
10543           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10544                           (match_operand:QI 2 "register_operand"))))
10545    (clobber (reg:CC FLAGS_REG))]
10546   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10547   [(set (match_dup 0)
10548         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10549   "operands[2] = gen_lowpart (SImode, operands[2]);")
10551 (define_insn "*<shift_insn><mode>3_1"
10552   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10553         (any_shiftrt:SWI12
10554           (match_operand:SWI12 1 "nonimmediate_operand" "0")
10555           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10556    (clobber (reg:CC FLAGS_REG))]
10557   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10559   if (operands[2] == const1_rtx
10560       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10561     return "<shift>{<imodesuffix>}\t%0";
10562   else
10563     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10565   [(set_attr "type" "ishift")
10566    (set (attr "length_immediate")
10567      (if_then_else
10568        (and (match_operand 2 "const1_operand")
10569             (ior (match_test "TARGET_SHIFT1")
10570                  (match_test "optimize_function_for_size_p (cfun)")))
10571        (const_string "0")
10572        (const_string "*")))
10573    (set_attr "mode" "<MODE>")])
10575 (define_insn "*<shift_insn>qi3_1_slp"
10576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10577         (any_shiftrt:QI (match_dup 0)
10578                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10579    (clobber (reg:CC FLAGS_REG))]
10580   "(optimize_function_for_size_p (cfun)
10581     || !TARGET_PARTIAL_REG_STALL
10582     || (operands[1] == const1_rtx
10583         && TARGET_SHIFT1))"
10585   if (operands[1] == const1_rtx
10586       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10587     return "<shift>{b}\t%0";
10588   else
10589     return "<shift>{b}\t{%1, %0|%0, %1}";
10591   [(set_attr "type" "ishift1")
10592    (set (attr "length_immediate")
10593      (if_then_else
10594        (and (match_operand 1 "const1_operand")
10595             (ior (match_test "TARGET_SHIFT1")
10596                  (match_test "optimize_function_for_size_p (cfun)")))
10597        (const_string "0")
10598        (const_string "*")))
10599    (set_attr "mode" "QI")])
10601 ;; This pattern can't accept a variable shift count, since shifts by
10602 ;; zero don't affect the flags.  We assume that shifts by constant
10603 ;; zero are optimized away.
10604 (define_insn "*<shift_insn><mode>3_cmp"
10605   [(set (reg FLAGS_REG)
10606         (compare
10607           (any_shiftrt:SWI
10608             (match_operand:SWI 1 "nonimmediate_operand" "0")
10609             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10610           (const_int 0)))
10611    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10612         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10613   "(optimize_function_for_size_p (cfun)
10614     || !TARGET_PARTIAL_FLAG_REG_STALL
10615     || (operands[2] == const1_rtx
10616         && TARGET_SHIFT1))
10617    && ix86_match_ccmode (insn, CCGOCmode)
10618    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10620   if (operands[2] == const1_rtx
10621       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10622     return "<shift>{<imodesuffix>}\t%0";
10623   else
10624     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10626   [(set_attr "type" "ishift")
10627    (set (attr "length_immediate")
10628      (if_then_else
10629        (and (match_operand 2 "const1_operand")
10630             (ior (match_test "TARGET_SHIFT1")
10631                  (match_test "optimize_function_for_size_p (cfun)")))
10632        (const_string "0")
10633        (const_string "*")))
10634    (set_attr "mode" "<MODE>")])
10636 (define_insn "*<shift_insn>si3_cmp_zext"
10637   [(set (reg FLAGS_REG)
10638         (compare
10639           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10640                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10641           (const_int 0)))
10642    (set (match_operand:DI 0 "register_operand" "=r")
10643         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10644   "TARGET_64BIT
10645    && (optimize_function_for_size_p (cfun)
10646        || !TARGET_PARTIAL_FLAG_REG_STALL
10647        || (operands[2] == const1_rtx
10648            && TARGET_SHIFT1))
10649    && ix86_match_ccmode (insn, CCGOCmode)
10650    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10652   if (operands[2] == const1_rtx
10653       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10654     return "<shift>{l}\t%k0";
10655   else
10656     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10658   [(set_attr "type" "ishift")
10659    (set (attr "length_immediate")
10660      (if_then_else
10661        (and (match_operand 2 "const1_operand")
10662             (ior (match_test "TARGET_SHIFT1")
10663                  (match_test "optimize_function_for_size_p (cfun)")))
10664        (const_string "0")
10665        (const_string "*")))
10666    (set_attr "mode" "SI")])
10668 (define_insn "*<shift_insn><mode>3_cconly"
10669   [(set (reg FLAGS_REG)
10670         (compare
10671           (any_shiftrt:SWI
10672             (match_operand:SWI 1 "register_operand" "0")
10673             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10674           (const_int 0)))
10675    (clobber (match_scratch:SWI 0 "=<r>"))]
10676   "(optimize_function_for_size_p (cfun)
10677     || !TARGET_PARTIAL_FLAG_REG_STALL
10678     || (operands[2] == const1_rtx
10679         && TARGET_SHIFT1))
10680    && ix86_match_ccmode (insn, CCGOCmode)"
10682   if (operands[2] == const1_rtx
10683       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10684     return "<shift>{<imodesuffix>}\t%0";
10685   else
10686     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10688   [(set_attr "type" "ishift")
10689    (set (attr "length_immediate")
10690      (if_then_else
10691        (and (match_operand 2 "const1_operand")
10692             (ior (match_test "TARGET_SHIFT1")
10693                  (match_test "optimize_function_for_size_p (cfun)")))
10694        (const_string "0")
10695        (const_string "*")))
10696    (set_attr "mode" "<MODE>")])
10698 ;; Rotate instructions
10700 (define_expand "<rotate_insn>ti3"
10701   [(set (match_operand:TI 0 "register_operand")
10702         (any_rotate:TI (match_operand:TI 1 "register_operand")
10703                        (match_operand:QI 2 "nonmemory_operand")))]
10704   "TARGET_64BIT"
10706   if (const_1_to_63_operand (operands[2], VOIDmode))
10707     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10708                 (operands[0], operands[1], operands[2]));
10709   else
10710     FAIL;
10712   DONE;
10715 (define_expand "<rotate_insn>di3"
10716   [(set (match_operand:DI 0 "shiftdi_operand")
10717         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10718                        (match_operand:QI 2 "nonmemory_operand")))]
10719  ""
10721   if (TARGET_64BIT)
10722     ix86_expand_binary_operator (<CODE>, DImode, operands);
10723   else if (const_1_to_31_operand (operands[2], VOIDmode))
10724     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10725                 (operands[0], operands[1], operands[2]));
10726   else
10727     FAIL;
10729   DONE;
10732 (define_expand "<rotate_insn><mode>3"
10733   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10734         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10735                             (match_operand:QI 2 "nonmemory_operand")))]
10736   ""
10737   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10739 ;; Avoid useless masking of count operand.
10740 (define_insn "*<rotate_insn><mode>3_mask"
10741   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10742         (any_rotate:SWI48
10743           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10744           (subreg:QI
10745             (and:SI
10746               (match_operand:SI 2 "register_operand" "c")
10747               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10748    (clobber (reg:CC FLAGS_REG))]
10749   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10750    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10751       == GET_MODE_BITSIZE (<MODE>mode)-1"
10753   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10755   [(set_attr "type" "rotate")
10756    (set_attr "mode" "<MODE>")])
10758 ;; Implement rotation using two double-precision
10759 ;; shift instructions and a scratch register.
10761 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10762  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10763        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10764                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10765   (clobber (reg:CC FLAGS_REG))
10766   (clobber (match_scratch:DWIH 3 "=&r"))]
10767  ""
10768  "#"
10769  "reload_completed"
10770  [(set (match_dup 3) (match_dup 4))
10771   (parallel
10772    [(set (match_dup 4)
10773          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10774                    (lshiftrt:DWIH (match_dup 5)
10775                                   (minus:QI (match_dup 6) (match_dup 2)))))
10776     (clobber (reg:CC FLAGS_REG))])
10777   (parallel
10778    [(set (match_dup 5)
10779          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10780                    (lshiftrt:DWIH (match_dup 3)
10781                                   (minus:QI (match_dup 6) (match_dup 2)))))
10782     (clobber (reg:CC FLAGS_REG))])]
10784   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10786   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10789 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10790  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10791        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10792                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10793   (clobber (reg:CC FLAGS_REG))
10794   (clobber (match_scratch:DWIH 3 "=&r"))]
10795  ""
10796  "#"
10797  "reload_completed"
10798  [(set (match_dup 3) (match_dup 4))
10799   (parallel
10800    [(set (match_dup 4)
10801          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10802                    (ashift:DWIH (match_dup 5)
10803                                 (minus:QI (match_dup 6) (match_dup 2)))))
10804     (clobber (reg:CC FLAGS_REG))])
10805   (parallel
10806    [(set (match_dup 5)
10807          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10808                    (ashift:DWIH (match_dup 3)
10809                                 (minus:QI (match_dup 6) (match_dup 2)))))
10810     (clobber (reg:CC FLAGS_REG))])]
10812   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10814   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10817 (define_insn "*bmi2_rorx<mode>3_1"
10818   [(set (match_operand:SWI48 0 "register_operand" "=r")
10819         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10820                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10821   "TARGET_BMI2"
10822   "rorx\t{%2, %1, %0|%0, %1, %2}"
10823   [(set_attr "type" "rotatex")
10824    (set_attr "mode" "<MODE>")])
10826 (define_insn "*<rotate_insn><mode>3_1"
10827   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10828         (any_rotate:SWI48
10829           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10830           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10831    (clobber (reg:CC FLAGS_REG))]
10832   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10834   switch (get_attr_type (insn))
10835     {
10836     case TYPE_ROTATEX:
10837       return "#";
10839     default:
10840       if (operands[2] == const1_rtx
10841           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10842         return "<rotate>{<imodesuffix>}\t%0";
10843       else
10844         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10845     }
10847   [(set_attr "isa" "*,bmi2")
10848    (set_attr "type" "rotate,rotatex")
10849    (set (attr "length_immediate")
10850      (if_then_else
10851        (and (eq_attr "type" "rotate")
10852             (and (match_operand 2 "const1_operand")
10853                  (ior (match_test "TARGET_SHIFT1")
10854                       (match_test "optimize_function_for_size_p (cfun)"))))
10855        (const_string "0")
10856        (const_string "*")))
10857    (set_attr "mode" "<MODE>")])
10859 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10860 (define_split
10861   [(set (match_operand:SWI48 0 "register_operand")
10862         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10863                       (match_operand:QI 2 "immediate_operand")))
10864    (clobber (reg:CC FLAGS_REG))]
10865   "TARGET_BMI2 && reload_completed"
10866   [(set (match_dup 0)
10867         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10869   operands[2]
10870     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10873 (define_split
10874   [(set (match_operand:SWI48 0 "register_operand")
10875         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10876                         (match_operand:QI 2 "immediate_operand")))
10877    (clobber (reg:CC FLAGS_REG))]
10878   "TARGET_BMI2 && reload_completed"
10879   [(set (match_dup 0)
10880         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10882 (define_insn "*bmi2_rorxsi3_1_zext"
10883   [(set (match_operand:DI 0 "register_operand" "=r")
10884         (zero_extend:DI
10885           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10886                        (match_operand:QI 2 "immediate_operand" "I"))))]
10887   "TARGET_64BIT && TARGET_BMI2"
10888   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10889   [(set_attr "type" "rotatex")
10890    (set_attr "mode" "SI")])
10892 (define_insn "*<rotate_insn>si3_1_zext"
10893   [(set (match_operand:DI 0 "register_operand" "=r,r")
10894         (zero_extend:DI
10895           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10896                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10897    (clobber (reg:CC FLAGS_REG))]
10898   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10900   switch (get_attr_type (insn))
10901     {
10902     case TYPE_ROTATEX:
10903       return "#";
10905     default:
10906       if (operands[2] == const1_rtx
10907           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10908         return "<rotate>{l}\t%k0";
10909       else
10910         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10911     }
10913   [(set_attr "isa" "*,bmi2")
10914    (set_attr "type" "rotate,rotatex")
10915    (set (attr "length_immediate")
10916      (if_then_else
10917        (and (eq_attr "type" "rotate")
10918             (and (match_operand 2 "const1_operand")
10919                  (ior (match_test "TARGET_SHIFT1")
10920                       (match_test "optimize_function_for_size_p (cfun)"))))
10921        (const_string "0")
10922        (const_string "*")))
10923    (set_attr "mode" "SI")])
10925 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10926 (define_split
10927   [(set (match_operand:DI 0 "register_operand")
10928         (zero_extend:DI
10929           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10930                      (match_operand:QI 2 "immediate_operand"))))
10931    (clobber (reg:CC FLAGS_REG))]
10932   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10933   [(set (match_dup 0)
10934         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10936   operands[2]
10937     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10940 (define_split
10941   [(set (match_operand:DI 0 "register_operand")
10942         (zero_extend:DI
10943           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10944                        (match_operand:QI 2 "immediate_operand"))))
10945    (clobber (reg:CC FLAGS_REG))]
10946   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10947   [(set (match_dup 0)
10948         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10950 (define_insn "*<rotate_insn><mode>3_1"
10951   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10952         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10953                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10954    (clobber (reg:CC FLAGS_REG))]
10955   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10957   if (operands[2] == const1_rtx
10958       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10959     return "<rotate>{<imodesuffix>}\t%0";
10960   else
10961     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10963   [(set_attr "type" "rotate")
10964    (set (attr "length_immediate")
10965      (if_then_else
10966        (and (match_operand 2 "const1_operand")
10967             (ior (match_test "TARGET_SHIFT1")
10968                  (match_test "optimize_function_for_size_p (cfun)")))
10969        (const_string "0")
10970        (const_string "*")))
10971    (set_attr "mode" "<MODE>")])
10973 (define_insn "*<rotate_insn>qi3_1_slp"
10974   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10975         (any_rotate:QI (match_dup 0)
10976                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10977    (clobber (reg:CC FLAGS_REG))]
10978   "(optimize_function_for_size_p (cfun)
10979     || !TARGET_PARTIAL_REG_STALL
10980     || (operands[1] == const1_rtx
10981         && TARGET_SHIFT1))"
10983   if (operands[1] == const1_rtx
10984       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10985     return "<rotate>{b}\t%0";
10986   else
10987     return "<rotate>{b}\t{%1, %0|%0, %1}";
10989   [(set_attr "type" "rotate1")
10990    (set (attr "length_immediate")
10991      (if_then_else
10992        (and (match_operand 1 "const1_operand")
10993             (ior (match_test "TARGET_SHIFT1")
10994                  (match_test "optimize_function_for_size_p (cfun)")))
10995        (const_string "0")
10996        (const_string "*")))
10997    (set_attr "mode" "QI")])
10999 (define_split
11000  [(set (match_operand:HI 0 "register_operand")
11001        (any_rotate:HI (match_dup 0) (const_int 8)))
11002   (clobber (reg:CC FLAGS_REG))]
11003  "reload_completed
11004   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11005  [(parallel [(set (strict_low_part (match_dup 0))
11006                   (bswap:HI (match_dup 0)))
11007              (clobber (reg:CC FLAGS_REG))])])
11009 ;; Bit set / bit test instructions
11011 ;; %%% bts, btr, btc, bt.
11012 ;; In general these instructions are *slow* when applied to memory,
11013 ;; since they enforce atomic operation.  When applied to registers,
11014 ;; it depends on the cpu implementation.  They're never faster than
11015 ;; the corresponding and/ior/xor operations, so with 32-bit there's
11016 ;; no point.  But in 64-bit, we can't hold the relevant immediates
11017 ;; within the instruction itself, so operating on bits in the high
11018 ;; 32-bits of a register becomes easier.
11020 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
11021 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11022 ;; negdf respectively, so they can never be disabled entirely.
11024 (define_insn "*btsq"
11025   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11026                          (const_int 1)
11027                          (match_operand 1 "const_0_to_63_operand" "J"))
11028         (const_int 1))
11029    (clobber (reg:CC FLAGS_REG))]
11030   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11031   "bts{q}\t{%1, %0|%0, %1}"
11032   [(set_attr "type" "alu1")
11033    (set_attr "prefix_0f" "1")
11034    (set_attr "znver1_decode" "double")
11035    (set_attr "mode" "DI")])
11037 (define_insn "*btrq"
11038   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11039                          (const_int 1)
11040                          (match_operand 1 "const_0_to_63_operand" "J"))
11041         (const_int 0))
11042    (clobber (reg:CC FLAGS_REG))]
11043   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11044   "btr{q}\t{%1, %0|%0, %1}"
11045   [(set_attr "type" "alu1")
11046    (set_attr "prefix_0f" "1")
11047    (set_attr "znver1_decode" "double")
11048    (set_attr "mode" "DI")])
11050 (define_insn "*btcq"
11051   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
11052                          (const_int 1)
11053                          (match_operand 1 "const_0_to_63_operand" "J"))
11054         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11055    (clobber (reg:CC FLAGS_REG))]
11056   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11057   "btc{q}\t{%1, %0|%0, %1}"
11058   [(set_attr "type" "alu1")
11059    (set_attr "prefix_0f" "1")
11060    (set_attr "znver1_decode" "double")
11061    (set_attr "mode" "DI")])
11063 ;; Allow Nocona to avoid these instructions if a register is available.
11065 (define_peephole2
11066   [(match_scratch:DI 2 "r")
11067    (parallel [(set (zero_extract:DI
11068                      (match_operand:DI 0 "register_operand")
11069                      (const_int 1)
11070                      (match_operand 1 "const_0_to_63_operand"))
11071                    (const_int 1))
11072               (clobber (reg:CC FLAGS_REG))])]
11073   "TARGET_64BIT && !TARGET_USE_BT"
11074   [(parallel [(set (match_dup 0)
11075                    (ior:DI (match_dup 0) (match_dup 3)))
11076               (clobber (reg:CC FLAGS_REG))])]
11078   int i = INTVAL (operands[1]);
11080   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11082   if (!x86_64_immediate_operand (operands[3], DImode))
11083     {
11084       emit_move_insn (operands[2], operands[3]);
11085       operands[3] = operands[2];
11086     }
11089 (define_peephole2
11090   [(match_scratch:DI 2 "r")
11091    (parallel [(set (zero_extract:DI
11092                      (match_operand:DI 0 "register_operand")
11093                      (const_int 1)
11094                      (match_operand 1 "const_0_to_63_operand"))
11095                    (const_int 0))
11096               (clobber (reg:CC FLAGS_REG))])]
11097   "TARGET_64BIT && !TARGET_USE_BT"
11098   [(parallel [(set (match_dup 0)
11099                    (and:DI (match_dup 0) (match_dup 3)))
11100               (clobber (reg:CC FLAGS_REG))])]
11102   int i = INTVAL (operands[1]);
11104   operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11106   if (!x86_64_immediate_operand (operands[3], DImode))
11107     {
11108       emit_move_insn (operands[2], operands[3]);
11109       operands[3] = operands[2];
11110     }
11113 (define_peephole2
11114   [(match_scratch:DI 2 "r")
11115    (parallel [(set (zero_extract:DI
11116                      (match_operand:DI 0 "register_operand")
11117                      (const_int 1)
11118                      (match_operand 1 "const_0_to_63_operand"))
11119               (not:DI (zero_extract:DI
11120                         (match_dup 0) (const_int 1) (match_dup 1))))
11121               (clobber (reg:CC FLAGS_REG))])]
11122   "TARGET_64BIT && !TARGET_USE_BT"
11123   [(parallel [(set (match_dup 0)
11124                    (xor:DI (match_dup 0) (match_dup 3)))
11125               (clobber (reg:CC FLAGS_REG))])]
11127   int i = INTVAL (operands[1]);
11129   operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11131   if (!x86_64_immediate_operand (operands[3], DImode))
11132     {
11133       emit_move_insn (operands[2], operands[3]);
11134       operands[3] = operands[2];
11135     }
11138 (define_insn "*bt<mode>"
11139   [(set (reg:CCC FLAGS_REG)
11140         (compare:CCC
11141           (zero_extract:SWI48
11142             (match_operand:SWI48 0 "register_operand" "r")
11143             (const_int 1)
11144             (match_operand:SI 1 "nonmemory_operand" "rN"))
11145           (const_int 0)))]
11146   ""
11148   switch (get_attr_mode (insn))
11149     {
11150     case MODE_SI:
11151       return "bt{l}\t{%1, %k0|%k0, %1}";
11153     case MODE_DI:
11154       return "bt{q}\t{%q1, %0|%0, %q1}";
11156     default:
11157       gcc_unreachable ();
11158     }
11160   [(set_attr "type" "alu1")
11161    (set_attr "prefix_0f" "1")
11162    (set (attr "mode")
11163         (if_then_else
11164           (and (match_test "CONST_INT_P (operands[1])")
11165                (match_test "INTVAL (operands[1]) < 32"))
11166           (const_string "SI")
11167           (const_string "<MODE>")))])
11169 (define_insn_and_split "*jcc_bt<mode>"
11170   [(set (pc)
11171         (if_then_else (match_operator 0 "bt_comparison_operator"
11172                         [(zero_extract:SWI48
11173                            (match_operand:SWI48 1 "register_operand")
11174                            (const_int 1)
11175                            (match_operand:SI 2 "nonmemory_operand"))
11176                          (const_int 0)])
11177                       (label_ref (match_operand 3))
11178                       (pc)))
11179    (clobber (reg:CC FLAGS_REG))]
11180   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11181    && (CONST_INT_P (operands[2])
11182        ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11183           && INTVAL (operands[2])
11184                >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11185        : register_operand (operands[2], SImode))
11186    && can_create_pseudo_p ()"
11187   "#"
11188   "&& 1"
11189   [(set (reg:CCC FLAGS_REG)
11190         (compare:CCC
11191           (zero_extract:SWI48
11192             (match_dup 1)
11193             (const_int 1)
11194             (match_dup 2))
11195           (const_int 0)))
11196    (set (pc)
11197         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11198                       (label_ref (match_dup 3))
11199                       (pc)))]
11201   operands[0] = shallow_copy_rtx (operands[0]);
11202   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11205 (define_insn_and_split "*jcc_bt<mode>_1"
11206   [(set (pc)
11207         (if_then_else (match_operator 0 "bt_comparison_operator"
11208                         [(zero_extract:SWI48
11209                            (match_operand:SWI48 1 "register_operand")
11210                            (const_int 1)
11211                            (zero_extend:SI
11212                              (match_operand:QI 2 "register_operand")))
11213                          (const_int 0)])
11214                       (label_ref (match_operand 3))
11215                       (pc)))
11216    (clobber (reg:CC FLAGS_REG))]
11217   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11218    && can_create_pseudo_p ()"
11219   "#"
11220   "&& 1"
11221   [(set (reg:CCC FLAGS_REG)
11222         (compare:CCC
11223           (zero_extract:SWI48
11224             (match_dup 1)
11225             (const_int 1)
11226             (match_dup 2))
11227           (const_int 0)))
11228    (set (pc)
11229         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11230                       (label_ref (match_dup 3))
11231                       (pc)))]
11233   operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11234   operands[0] = shallow_copy_rtx (operands[0]);
11235   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11238 ;; Avoid useless masking of bit offset operand.
11239 (define_insn_and_split "*jcc_bt<mode>_mask"
11240   [(set (pc)
11241         (if_then_else (match_operator 0 "bt_comparison_operator"
11242                         [(zero_extract:SWI48
11243                            (match_operand:SWI48 1 "register_operand")
11244                            (const_int 1)
11245                            (and:SI
11246                              (match_operand:SI 2 "register_operand")
11247                              (match_operand 3 "const_int_operand")))])
11248                       (label_ref (match_operand 4))
11249                       (pc)))
11250    (clobber (reg:CC FLAGS_REG))]
11251   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11252    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11253       == GET_MODE_BITSIZE (<MODE>mode)-1
11254    && can_create_pseudo_p ()"
11255   "#"
11256   "&& 1"
11257   [(set (reg:CCC FLAGS_REG)
11258         (compare:CCC
11259           (zero_extract:SWI48
11260             (match_dup 1)
11261             (const_int 1)
11262             (match_dup 2))
11263           (const_int 0)))
11264    (set (pc)
11265         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11266                       (label_ref (match_dup 4))
11267                       (pc)))]
11269   operands[0] = shallow_copy_rtx (operands[0]);
11270   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11273 ;; Store-flag instructions.
11275 ;; For all sCOND expanders, also expand the compare or test insn that
11276 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11278 (define_insn_and_split "*setcc_di_1"
11279   [(set (match_operand:DI 0 "register_operand" "=q")
11280         (match_operator:DI 1 "ix86_comparison_operator"
11281           [(reg FLAGS_REG) (const_int 0)]))]
11282   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11283   "#"
11284   "&& reload_completed"
11285   [(set (match_dup 2) (match_dup 1))
11286    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11288   operands[1] = shallow_copy_rtx (operands[1]);
11289   PUT_MODE (operands[1], QImode);
11290   operands[2] = gen_lowpart (QImode, operands[0]);
11293 (define_insn_and_split "*setcc_si_1_and"
11294   [(set (match_operand:SI 0 "register_operand" "=q")
11295         (match_operator:SI 1 "ix86_comparison_operator"
11296           [(reg FLAGS_REG) (const_int 0)]))
11297    (clobber (reg:CC FLAGS_REG))]
11298   "!TARGET_PARTIAL_REG_STALL
11299    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11300   "#"
11301   "&& reload_completed"
11302   [(set (match_dup 2) (match_dup 1))
11303    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11304               (clobber (reg:CC FLAGS_REG))])]
11306   operands[1] = shallow_copy_rtx (operands[1]);
11307   PUT_MODE (operands[1], QImode);
11308   operands[2] = gen_lowpart (QImode, operands[0]);
11311 (define_insn_and_split "*setcc_si_1_movzbl"
11312   [(set (match_operand:SI 0 "register_operand" "=q")
11313         (match_operator:SI 1 "ix86_comparison_operator"
11314           [(reg FLAGS_REG) (const_int 0)]))]
11315   "!TARGET_PARTIAL_REG_STALL
11316    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11317   "#"
11318   "&& reload_completed"
11319   [(set (match_dup 2) (match_dup 1))
11320    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11322   operands[1] = shallow_copy_rtx (operands[1]);
11323   PUT_MODE (operands[1], QImode);
11324   operands[2] = gen_lowpart (QImode, operands[0]);
11327 (define_insn "*setcc_qi"
11328   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11329         (match_operator:QI 1 "ix86_comparison_operator"
11330           [(reg FLAGS_REG) (const_int 0)]))]
11331   ""
11332   "set%C1\t%0"
11333   [(set_attr "type" "setcc")
11334    (set_attr "mode" "QI")])
11336 (define_insn "*setcc_qi_slp"
11337   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11338         (match_operator:QI 1 "ix86_comparison_operator"
11339           [(reg FLAGS_REG) (const_int 0)]))]
11340   ""
11341   "set%C1\t%0"
11342   [(set_attr "type" "setcc")
11343    (set_attr "mode" "QI")])
11345 ;; In general it is not safe to assume too much about CCmode registers,
11346 ;; so simplify-rtx stops when it sees a second one.  Under certain
11347 ;; conditions this is safe on x86, so help combine not create
11349 ;;      seta    %al
11350 ;;      testb   %al, %al
11351 ;;      sete    %al
11353 (define_split
11354   [(set (match_operand:QI 0 "nonimmediate_operand")
11355         (ne:QI (match_operator 1 "ix86_comparison_operator"
11356                  [(reg FLAGS_REG) (const_int 0)])
11357             (const_int 0)))]
11358   ""
11359   [(set (match_dup 0) (match_dup 1))]
11361   operands[1] = shallow_copy_rtx (operands[1]);
11362   PUT_MODE (operands[1], QImode);
11365 (define_split
11366   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11367         (ne:QI (match_operator 1 "ix86_comparison_operator"
11368                  [(reg FLAGS_REG) (const_int 0)])
11369             (const_int 0)))]
11370   ""
11371   [(set (match_dup 0) (match_dup 1))]
11373   operands[1] = shallow_copy_rtx (operands[1]);
11374   PUT_MODE (operands[1], QImode);
11377 (define_split
11378   [(set (match_operand:QI 0 "nonimmediate_operand")
11379         (eq:QI (match_operator 1 "ix86_comparison_operator"
11380                  [(reg FLAGS_REG) (const_int 0)])
11381             (const_int 0)))]
11382   ""
11383   [(set (match_dup 0) (match_dup 1))]
11385   operands[1] = shallow_copy_rtx (operands[1]);
11386   PUT_MODE (operands[1], QImode);
11387   PUT_CODE (operands[1],
11388             ix86_reverse_condition (GET_CODE (operands[1]),
11389                                     GET_MODE (XEXP (operands[1], 0))));
11391   /* Make sure that (a) the CCmode we have for the flags is strong
11392      enough for the reversed compare or (b) we have a valid FP compare.  */
11393   if (! ix86_comparison_operator (operands[1], VOIDmode))
11394     FAIL;
11397 (define_split
11398   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11399         (eq:QI (match_operator 1 "ix86_comparison_operator"
11400                  [(reg FLAGS_REG) (const_int 0)])
11401             (const_int 0)))]
11402   ""
11403   [(set (match_dup 0) (match_dup 1))]
11405   operands[1] = shallow_copy_rtx (operands[1]);
11406   PUT_MODE (operands[1], QImode);
11407   PUT_CODE (operands[1],
11408             ix86_reverse_condition (GET_CODE (operands[1]),
11409                                     GET_MODE (XEXP (operands[1], 0))));
11411   /* Make sure that (a) the CCmode we have for the flags is strong
11412      enough for the reversed compare or (b) we have a valid FP compare.  */
11413   if (! ix86_comparison_operator (operands[1], VOIDmode))
11414     FAIL;
11417 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11418 ;; subsequent logical operations are used to imitate conditional moves.
11419 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11420 ;; it directly.
11422 (define_insn "setcc_<mode>_sse"
11423   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11424         (match_operator:MODEF 3 "sse_comparison_operator"
11425           [(match_operand:MODEF 1 "register_operand" "0,x")
11426            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11427   "SSE_FLOAT_MODE_P (<MODE>mode)"
11428   "@
11429    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11430    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11431   [(set_attr "isa" "noavx,avx")
11432    (set_attr "type" "ssecmp")
11433    (set_attr "length_immediate" "1")
11434    (set_attr "prefix" "orig,vex")
11435    (set_attr "mode" "<MODE>")])
11437 ;; Basic conditional jump instructions.
11438 ;; We ignore the overflow flag for signed branch instructions.
11440 (define_insn "*jcc_1"
11441   [(set (pc)
11442         (if_then_else (match_operator 1 "ix86_comparison_operator"
11443                                       [(reg FLAGS_REG) (const_int 0)])
11444                       (label_ref (match_operand 0))
11445                       (pc)))]
11446   ""
11447   "%!%+j%C1\t%l0"
11448   [(set_attr "type" "ibr")
11449    (set_attr "modrm" "0")
11450    (set (attr "length")
11451         (if_then_else
11452           (and (ge (minus (match_dup 0) (pc))
11453                    (const_int -126))
11454                (lt (minus (match_dup 0) (pc))
11455                    (const_int 128)))
11456           (const_int 2)
11457           (const_int 6)))
11458    (set_attr "maybe_prefix_bnd" "1")])
11460 (define_insn "*jcc_2"
11461   [(set (pc)
11462         (if_then_else (match_operator 1 "ix86_comparison_operator"
11463                                       [(reg FLAGS_REG) (const_int 0)])
11464                       (pc)
11465                       (label_ref (match_operand 0))))]
11466   ""
11467   "%!%+j%c1\t%l0"
11468   [(set_attr "type" "ibr")
11469    (set_attr "modrm" "0")
11470    (set (attr "length")
11471         (if_then_else
11472           (and (ge (minus (match_dup 0) (pc))
11473                    (const_int -126))
11474                (lt (minus (match_dup 0) (pc))
11475                    (const_int 128)))
11476           (const_int 2)
11477           (const_int 6)))
11478    (set_attr "maybe_prefix_bnd" "1")])
11480 ;; In general it is not safe to assume too much about CCmode registers,
11481 ;; so simplify-rtx stops when it sees a second one.  Under certain
11482 ;; conditions this is safe on x86, so help combine not create
11484 ;;      seta    %al
11485 ;;      testb   %al, %al
11486 ;;      je      Lfoo
11488 (define_split
11489   [(set (pc)
11490         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11491                                       [(reg FLAGS_REG) (const_int 0)])
11492                           (const_int 0))
11493                       (label_ref (match_operand 1))
11494                       (pc)))]
11495   ""
11496   [(set (pc)
11497         (if_then_else (match_dup 0)
11498                       (label_ref (match_dup 1))
11499                       (pc)))]
11501   operands[0] = shallow_copy_rtx (operands[0]);
11502   PUT_MODE (operands[0], VOIDmode);
11505 (define_split
11506   [(set (pc)
11507         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11508                                       [(reg FLAGS_REG) (const_int 0)])
11509                           (const_int 0))
11510                       (label_ref (match_operand 1))
11511                       (pc)))]
11512   ""
11513   [(set (pc)
11514         (if_then_else (match_dup 0)
11515                       (label_ref (match_dup 1))
11516                       (pc)))]
11518   operands[0] = shallow_copy_rtx (operands[0]);
11519   PUT_MODE (operands[0], VOIDmode);
11520   PUT_CODE (operands[0],
11521             ix86_reverse_condition (GET_CODE (operands[0]),
11522                                     GET_MODE (XEXP (operands[0], 0))));
11524   /* Make sure that (a) the CCmode we have for the flags is strong
11525      enough for the reversed compare or (b) we have a valid FP compare.  */
11526   if (! ix86_comparison_operator (operands[0], VOIDmode))
11527     FAIL;
11530 ;; Define combination compare-and-branch fp compare instructions to help
11531 ;; combine.
11533 (define_insn "*jcc<mode>_0_i387"
11534   [(set (pc)
11535         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11536                         [(match_operand:X87MODEF 1 "register_operand" "f")
11537                          (match_operand:X87MODEF 2 "const0_operand")])
11538           (label_ref (match_operand 3))
11539           (pc)))
11540    (clobber (reg:CCFP FPSR_REG))
11541    (clobber (reg:CCFP FLAGS_REG))
11542    (clobber (match_scratch:HI 4 "=a"))]
11543   "TARGET_80387 && !TARGET_CMOVE"
11544   "#")
11546 (define_insn "*jcc<mode>_0_r_i387"
11547   [(set (pc)
11548         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11549                         [(match_operand:X87MODEF 1 "register_operand" "f")
11550                          (match_operand:X87MODEF 2 "const0_operand")])
11551           (pc)
11552           (label_ref (match_operand 3))))
11553    (clobber (reg:CCFP FPSR_REG))
11554    (clobber (reg:CCFP FLAGS_REG))
11555    (clobber (match_scratch:HI 4 "=a"))]
11556   "TARGET_80387 && !TARGET_CMOVE"
11557   "#")
11559 (define_insn "*jccxf_i387"
11560   [(set (pc)
11561         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11562                         [(match_operand:XF 1 "register_operand" "f")
11563                          (match_operand:XF 2 "register_operand" "f")])
11564           (label_ref (match_operand 3))
11565           (pc)))
11566    (clobber (reg:CCFP FPSR_REG))
11567    (clobber (reg:CCFP FLAGS_REG))
11568    (clobber (match_scratch:HI 4 "=a"))]
11569   "TARGET_80387 && !TARGET_CMOVE"
11570   "#")
11572 (define_insn "*jccxf_r_i387"
11573   [(set (pc)
11574         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11575                         [(match_operand:XF 1 "register_operand" "f")
11576                          (match_operand:XF 2 "register_operand" "f")])
11577           (pc)
11578           (label_ref (match_operand 3))))
11579    (clobber (reg:CCFP FPSR_REG))
11580    (clobber (reg:CCFP FLAGS_REG))
11581    (clobber (match_scratch:HI 4 "=a"))]
11582   "TARGET_80387 && !TARGET_CMOVE"
11583   "#")
11585 (define_insn "*jcc<mode>_i387"
11586   [(set (pc)
11587         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11588                         [(match_operand:MODEF 1 "register_operand" "f")
11589                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11590           (label_ref (match_operand 3))
11591           (pc)))
11592    (clobber (reg:CCFP FPSR_REG))
11593    (clobber (reg:CCFP FLAGS_REG))
11594    (clobber (match_scratch:HI 4 "=a"))]
11595   "TARGET_80387 && !TARGET_CMOVE"
11596   "#")
11598 (define_insn "*jcc<mode>_r_i387"
11599   [(set (pc)
11600         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11601                         [(match_operand:MODEF 1 "register_operand" "f")
11602                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11603           (pc)
11604           (label_ref (match_operand 3))))
11605    (clobber (reg:CCFP FPSR_REG))
11606    (clobber (reg:CCFP FLAGS_REG))
11607    (clobber (match_scratch:HI 4 "=a"))]
11608   "TARGET_80387 && !TARGET_CMOVE"
11609   "#")
11611 (define_insn "*jccu<mode>_i387"
11612   [(set (pc)
11613         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11614                         [(match_operand:X87MODEF 1 "register_operand" "f")
11615                          (match_operand:X87MODEF 2 "register_operand" "f")])
11616           (label_ref (match_operand 3))
11617           (pc)))
11618    (clobber (reg:CCFP FPSR_REG))
11619    (clobber (reg:CCFP FLAGS_REG))
11620    (clobber (match_scratch:HI 4 "=a"))]
11621   "TARGET_80387 && !TARGET_CMOVE"
11622   "#")
11624 (define_insn "*jccu<mode>_r_i387"
11625   [(set (pc)
11626         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11627                         [(match_operand:X87MODEF 1 "register_operand" "f")
11628                          (match_operand:X87MODEF 2 "register_operand" "f")])
11629           (pc)
11630           (label_ref (match_operand 3))))
11631    (clobber (reg:CCFP FPSR_REG))
11632    (clobber (reg:CCFP FLAGS_REG))
11633    (clobber (match_scratch:HI 4 "=a"))]
11634   "TARGET_80387 && !TARGET_CMOVE"
11635   "#")
11637 (define_split
11638   [(set (pc)
11639         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11640                         [(match_operand:X87MODEF 1 "register_operand")
11641                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11642           (match_operand 3)
11643           (match_operand 4)))
11644    (clobber (reg:CCFP FPSR_REG))
11645    (clobber (reg:CCFP FLAGS_REG))]
11646   "TARGET_80387 && !TARGET_CMOVE
11647    && reload_completed"
11648   [(const_int 0)]
11650   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11651                         operands[3], operands[4], NULL_RTX);
11652   DONE;
11655 (define_split
11656   [(set (pc)
11657         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11658                         [(match_operand:X87MODEF 1 "register_operand")
11659                          (match_operand:X87MODEF 2 "general_operand")])
11660           (match_operand 3)
11661           (match_operand 4)))
11662    (clobber (reg:CCFP FPSR_REG))
11663    (clobber (reg:CCFP FLAGS_REG))
11664    (clobber (match_scratch:HI 5))]
11665   "TARGET_80387 && !TARGET_CMOVE
11666    && reload_completed"
11667   [(const_int 0)]
11669   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11670                         operands[3], operands[4], operands[5]);
11671   DONE;
11674 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11675 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11676 ;; with a precedence over other operators and is always put in the first
11677 ;; place. Swap condition and operands to match ficom instruction.
11679 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11680   [(set (pc)
11681         (if_then_else
11682           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11683             [(match_operator:X87MODEF 1 "float_operator"
11684               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11685              (match_operand:X87MODEF 3 "register_operand" "f")])
11686           (label_ref (match_operand 4))
11687           (pc)))
11688    (clobber (reg:CCFP FPSR_REG))
11689    (clobber (reg:CCFP FLAGS_REG))
11690    (clobber (match_scratch:HI 5 "=a"))]
11691   "TARGET_80387 && !TARGET_CMOVE
11692    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11693        || optimize_function_for_size_p (cfun))"
11694   "#")
11696 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11697   [(set (pc)
11698         (if_then_else
11699           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11700             [(match_operator:X87MODEF 1 "float_operator"
11701               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11702              (match_operand:X87MODEF 3 "register_operand" "f")])
11703           (pc)
11704           (label_ref (match_operand 4))))
11705    (clobber (reg:CCFP FPSR_REG))
11706    (clobber (reg:CCFP FLAGS_REG))
11707    (clobber (match_scratch:HI 5 "=a"))]
11708   "TARGET_80387 && !TARGET_CMOVE
11709    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11710        || optimize_function_for_size_p (cfun))"
11711   "#")
11713 (define_split
11714   [(set (pc)
11715         (if_then_else
11716           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11717             [(match_operator:X87MODEF 1 "float_operator"
11718               [(match_operand:SWI24 2 "memory_operand")])
11719              (match_operand:X87MODEF 3 "register_operand")])
11720           (match_operand 4)
11721           (match_operand 5)))
11722    (clobber (reg:CCFP FPSR_REG))
11723    (clobber (reg:CCFP FLAGS_REG))
11724    (clobber (match_scratch:HI 6))]
11725   "TARGET_80387 && !TARGET_CMOVE
11726    && reload_completed"
11727   [(const_int 0)]
11729   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11730                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11731                         operands[4], operands[5], operands[6]);
11732   DONE;
11735 ;; Unconditional and other jump instructions
11737 (define_insn "jump"
11738   [(set (pc)
11739         (label_ref (match_operand 0)))]
11740   ""
11741   "%!jmp\t%l0"
11742   [(set_attr "type" "ibr")
11743    (set_attr "modrm" "0")
11744    (set (attr "length")
11745         (if_then_else
11746           (and (ge (minus (match_dup 0) (pc))
11747                    (const_int -126))
11748                (lt (minus (match_dup 0) (pc))
11749                    (const_int 128)))
11750           (const_int 2)
11751           (const_int 5)))
11752    (set_attr "maybe_prefix_bnd" "1")])
11754 (define_expand "indirect_jump"
11755   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11756   ""
11758   if (TARGET_X32)
11759     operands[0] = convert_memory_address (word_mode, operands[0]);
11762 (define_insn "*indirect_jump"
11763   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11764   ""
11765   "%!jmp\t%A0"
11766   [(set_attr "type" "ibr")
11767    (set_attr "length_immediate" "0")
11768    (set_attr "maybe_prefix_bnd" "1")])
11770 (define_expand "tablejump"
11771   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11772               (use (label_ref (match_operand 1)))])]
11773   ""
11775   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11776      relative.  Convert the relative address to an absolute address.  */
11777   if (flag_pic)
11778     {
11779       rtx op0, op1;
11780       enum rtx_code code;
11782       /* We can't use @GOTOFF for text labels on VxWorks;
11783          see gotoff_operand.  */
11784       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11785         {
11786           code = PLUS;
11787           op0 = operands[0];
11788           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11789         }
11790       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11791         {
11792           code = PLUS;
11793           op0 = operands[0];
11794           op1 = pic_offset_table_rtx;
11795         }
11796       else
11797         {
11798           code = MINUS;
11799           op0 = pic_offset_table_rtx;
11800           op1 = operands[0];
11801         }
11803       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11804                                          OPTAB_DIRECT);
11805     }
11807   if (TARGET_X32)
11808     operands[0] = convert_memory_address (word_mode, operands[0]);
11811 (define_insn "*tablejump_1"
11812   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11813    (use (label_ref (match_operand 1)))]
11814   ""
11815   "%!jmp\t%A0"
11816   [(set_attr "type" "ibr")
11817    (set_attr "length_immediate" "0")
11818    (set_attr "maybe_prefix_bnd" "1")])
11820 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11822 (define_peephole2
11823   [(set (reg FLAGS_REG) (match_operand 0))
11824    (set (match_operand:QI 1 "register_operand")
11825         (match_operator:QI 2 "ix86_comparison_operator"
11826           [(reg FLAGS_REG) (const_int 0)]))
11827    (set (match_operand 3 "any_QIreg_operand")
11828         (zero_extend (match_dup 1)))]
11829   "(peep2_reg_dead_p (3, operands[1])
11830     || operands_match_p (operands[1], operands[3]))
11831    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11832   [(set (match_dup 4) (match_dup 0))
11833    (set (strict_low_part (match_dup 5))
11834         (match_dup 2))]
11836   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11837   operands[5] = gen_lowpart (QImode, operands[3]);
11838   ix86_expand_clear (operands[3]);
11841 (define_peephole2
11842   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11843               (match_operand 4)])
11844    (set (match_operand:QI 1 "register_operand")
11845         (match_operator:QI 2 "ix86_comparison_operator"
11846           [(reg FLAGS_REG) (const_int 0)]))
11847    (set (match_operand 3 "any_QIreg_operand")
11848         (zero_extend (match_dup 1)))]
11849   "(peep2_reg_dead_p (3, operands[1])
11850     || operands_match_p (operands[1], operands[3]))
11851    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11852    && ! (GET_CODE (operands[4]) == CLOBBER
11853          && reg_mentioned_p (operands[3], operands[4]))"
11854   [(parallel [(set (match_dup 5) (match_dup 0))
11855               (match_dup 4)])
11856    (set (strict_low_part (match_dup 6))
11857         (match_dup 2))]
11859   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11860   operands[6] = gen_lowpart (QImode, operands[3]);
11861   ix86_expand_clear (operands[3]);
11864 ;; Similar, but match zero extend with andsi3.
11866 (define_peephole2
11867   [(set (reg FLAGS_REG) (match_operand 0))
11868    (set (match_operand:QI 1 "register_operand")
11869         (match_operator:QI 2 "ix86_comparison_operator"
11870           [(reg FLAGS_REG) (const_int 0)]))
11871    (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
11872                    (and:SI (match_dup 3) (const_int 255)))
11873               (clobber (reg:CC FLAGS_REG))])]
11874   "REGNO (operands[1]) == REGNO (operands[3])
11875    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11876   [(set (match_dup 4) (match_dup 0))
11877    (set (strict_low_part (match_dup 5))
11878         (match_dup 2))]
11880   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11881   operands[5] = gen_lowpart (QImode, operands[3]);
11882   ix86_expand_clear (operands[3]);
11885 (define_peephole2
11886   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11887               (match_operand 4)])
11888    (set (match_operand:QI 1 "register_operand")
11889         (match_operator:QI 2 "ix86_comparison_operator"
11890           [(reg FLAGS_REG) (const_int 0)]))
11891    (parallel [(set (match_operand 3 "any_QIreg_operand")
11892                    (zero_extend (match_dup 1)))
11893               (clobber (reg:CC FLAGS_REG))])]
11894   "(peep2_reg_dead_p (3, operands[1])
11895     || operands_match_p (operands[1], operands[3]))
11896    && ! reg_overlap_mentioned_p (operands[3], operands[0])
11897    && ! (GET_CODE (operands[4]) == CLOBBER
11898          && reg_mentioned_p (operands[3], operands[4]))"
11899   [(parallel [(set (match_dup 5) (match_dup 0))
11900               (match_dup 4)])
11901    (set (strict_low_part (match_dup 6))
11902         (match_dup 2))]
11904   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11905   operands[6] = gen_lowpart (QImode, operands[3]);
11906   ix86_expand_clear (operands[3]);
11909 ;; Call instructions.
11911 ;; The predicates normally associated with named expanders are not properly
11912 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11913 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11915 ;; P6 processors will jump to the address after the decrement when %esp
11916 ;; is used as a call operand, so they will execute return address as a code.
11917 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11919 ;; Register constraint for call instruction.
11920 (define_mode_attr c [(SI "l") (DI "r")])
11922 ;; Call subroutine returning no value.
11924 (define_expand "call"
11925   [(call (match_operand:QI 0)
11926          (match_operand 1))
11927    (use (match_operand 2))]
11928   ""
11930   ix86_expand_call (NULL, operands[0], operands[1],
11931                     operands[2], NULL, false);
11932   DONE;
11935 (define_expand "sibcall"
11936   [(call (match_operand:QI 0)
11937          (match_operand 1))
11938    (use (match_operand 2))]
11939   ""
11941   ix86_expand_call (NULL, operands[0], operands[1],
11942                     operands[2], NULL, true);
11943   DONE;
11946 (define_insn "*call"
11947   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11948          (match_operand 1))]
11949   "!SIBLING_CALL_P (insn)"
11950   "* return ix86_output_call_insn (insn, operands[0]);"
11951   [(set_attr "type" "call")])
11953 ;; This covers both call and sibcall since only GOT slot is allowed.
11954 (define_insn "*call_got_x32"
11955   [(call (mem:QI (zero_extend:DI
11956                    (match_operand:SI 0 "GOT_memory_operand" "Bg")))
11957          (match_operand 1))]
11958   "TARGET_X32"
11960   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
11961   return ix86_output_call_insn (insn, fnaddr);
11963   [(set_attr "type" "call")])
11965 ;; Since sibcall never returns, we can only use call-clobbered register
11966 ;; as GOT base.
11967 (define_insn "*sibcall_GOT_32"
11968   [(call (mem:QI
11969            (mem:SI (plus:SI
11970                      (match_operand:SI 0 "register_no_elim_operand" "U")
11971                      (match_operand:SI 1 "GOT32_symbol_operand"))))
11972          (match_operand 2))]
11973   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11975   rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
11976   fnaddr = gen_const_mem (SImode, fnaddr);
11977   return ix86_output_call_insn (insn, fnaddr);
11979   [(set_attr "type" "call")])
11981 (define_insn "*sibcall"
11982   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11983          (match_operand 1))]
11984   "SIBLING_CALL_P (insn)"
11985   "* return ix86_output_call_insn (insn, operands[0]);"
11986   [(set_attr "type" "call")])
11988 (define_insn "*sibcall_memory"
11989   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11990          (match_operand 1))
11991    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11992   "!TARGET_X32"
11993   "* return ix86_output_call_insn (insn, operands[0]);"
11994   [(set_attr "type" "call")])
11996 (define_peephole2
11997   [(set (match_operand:W 0 "register_operand")
11998         (match_operand:W 1 "memory_operand"))
11999    (call (mem:QI (match_dup 0))
12000          (match_operand 3))]
12001   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12002    && !reg_mentioned_p (operands[0],
12003                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12004   [(parallel [(call (mem:QI (match_dup 1))
12005                     (match_dup 3))
12006               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12008 (define_peephole2
12009   [(set (match_operand:W 0 "register_operand")
12010         (match_operand:W 1 "memory_operand"))
12011    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12012    (call (mem:QI (match_dup 0))
12013          (match_operand 3))]
12014   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12015    && !reg_mentioned_p (operands[0],
12016                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12017   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12018    (parallel [(call (mem:QI (match_dup 1))
12019                     (match_dup 3))
12020               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12022 (define_expand "call_pop"
12023   [(parallel [(call (match_operand:QI 0)
12024                     (match_operand:SI 1))
12025               (set (reg:SI SP_REG)
12026                    (plus:SI (reg:SI SP_REG)
12027                             (match_operand:SI 3)))])]
12028   "!TARGET_64BIT"
12030   ix86_expand_call (NULL, operands[0], operands[1],
12031                     operands[2], operands[3], false);
12032   DONE;
12035 (define_insn "*call_pop"
12036   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12037          (match_operand 1))
12038    (set (reg:SI SP_REG)
12039         (plus:SI (reg:SI SP_REG)
12040                  (match_operand:SI 2 "immediate_operand" "i")))]
12041   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12042   "* return ix86_output_call_insn (insn, operands[0]);"
12043   [(set_attr "type" "call")])
12045 (define_insn "*sibcall_pop"
12046   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12047          (match_operand 1))
12048    (set (reg:SI SP_REG)
12049         (plus:SI (reg:SI SP_REG)
12050                  (match_operand:SI 2 "immediate_operand" "i")))]
12051   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12052   "* return ix86_output_call_insn (insn, operands[0]);"
12053   [(set_attr "type" "call")])
12055 (define_insn "*sibcall_pop_memory"
12056   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12057          (match_operand 1))
12058    (set (reg:SI SP_REG)
12059         (plus:SI (reg:SI SP_REG)
12060                  (match_operand:SI 2 "immediate_operand" "i")))
12061    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12062   "!TARGET_64BIT"
12063   "* return ix86_output_call_insn (insn, operands[0]);"
12064   [(set_attr "type" "call")])
12066 (define_peephole2
12067   [(set (match_operand:SI 0 "register_operand")
12068         (match_operand:SI 1 "memory_operand"))
12069    (parallel [(call (mem:QI (match_dup 0))
12070                     (match_operand 3))
12071               (set (reg:SI SP_REG)
12072                    (plus:SI (reg:SI SP_REG)
12073                             (match_operand:SI 4 "immediate_operand")))])]
12074   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12075    && !reg_mentioned_p (operands[0],
12076                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12077   [(parallel [(call (mem:QI (match_dup 1))
12078                     (match_dup 3))
12079               (set (reg:SI SP_REG)
12080                    (plus:SI (reg:SI SP_REG)
12081                             (match_dup 4)))
12082               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12084 (define_peephole2
12085   [(set (match_operand:SI 0 "register_operand")
12086         (match_operand:SI 1 "memory_operand"))
12087    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12088    (parallel [(call (mem:QI (match_dup 0))
12089                     (match_operand 3))
12090               (set (reg:SI SP_REG)
12091                    (plus:SI (reg:SI SP_REG)
12092                             (match_operand:SI 4 "immediate_operand")))])]
12093   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12094    && !reg_mentioned_p (operands[0],
12095                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12096   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12097    (parallel [(call (mem:QI (match_dup 1))
12098                     (match_dup 3))
12099               (set (reg:SI SP_REG)
12100                    (plus:SI (reg:SI SP_REG)
12101                             (match_dup 4)))
12102               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12104 ;; Combining simple memory jump instruction
12106 (define_peephole2
12107   [(set (match_operand:W 0 "register_operand")
12108         (match_operand:W 1 "memory_operand"))
12109    (set (pc) (match_dup 0))]
12110   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12111   [(set (pc) (match_dup 1))])
12113 ;; Call subroutine, returning value in operand 0
12115 (define_expand "call_value"
12116   [(set (match_operand 0)
12117         (call (match_operand:QI 1)
12118               (match_operand 2)))
12119    (use (match_operand 3))]
12120   ""
12122   ix86_expand_call (operands[0], operands[1], operands[2],
12123                     operands[3], NULL, false);
12124   DONE;
12127 (define_expand "sibcall_value"
12128   [(set (match_operand 0)
12129         (call (match_operand:QI 1)
12130               (match_operand 2)))
12131    (use (match_operand 3))]
12132   ""
12134   ix86_expand_call (operands[0], operands[1], operands[2],
12135                     operands[3], NULL, true);
12136   DONE;
12139 (define_insn "*call_value"
12140   [(set (match_operand 0)
12141         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12142               (match_operand 2)))]
12143   "!SIBLING_CALL_P (insn)"
12144   "* return ix86_output_call_insn (insn, operands[1]);"
12145   [(set_attr "type" "callv")])
12147 ;; This covers both call and sibcall since only GOT slot is allowed.
12148 (define_insn "*call_value_got_x32"
12149   [(set (match_operand 0)
12150         (call (mem:QI
12151                 (zero_extend:DI
12152                   (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12153               (match_operand 2)))]
12154   "TARGET_X32"
12156   rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12157   return ix86_output_call_insn (insn, fnaddr);
12159   [(set_attr "type" "callv")])
12161 ;; Since sibcall never returns, we can only use call-clobbered register
12162 ;; as GOT base.
12163 (define_insn "*sibcall_value_GOT_32"
12164   [(set (match_operand 0)
12165         (call (mem:QI
12166                 (mem:SI (plus:SI
12167                           (match_operand:SI 1 "register_no_elim_operand" "U")
12168                           (match_operand:SI 2 "GOT32_symbol_operand"))))
12169          (match_operand 3)))]
12170   "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12172   rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12173   fnaddr = gen_const_mem (SImode, fnaddr);
12174   return ix86_output_call_insn (insn, fnaddr);
12176   [(set_attr "type" "callv")])
12178 (define_insn "*sibcall_value"
12179   [(set (match_operand 0)
12180         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12181               (match_operand 2)))]
12182   "SIBLING_CALL_P (insn)"
12183   "* return ix86_output_call_insn (insn, operands[1]);"
12184   [(set_attr "type" "callv")])
12186 (define_insn "*sibcall_value_memory"
12187   [(set (match_operand 0)
12188         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12189               (match_operand 2)))
12190    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12191   "!TARGET_X32"
12192   "* return ix86_output_call_insn (insn, operands[1]);"
12193   [(set_attr "type" "callv")])
12195 (define_peephole2
12196   [(set (match_operand:W 0 "register_operand")
12197         (match_operand:W 1 "memory_operand"))
12198    (set (match_operand 2)
12199    (call (mem:QI (match_dup 0))
12200                  (match_operand 3)))]
12201   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12202    && !reg_mentioned_p (operands[0],
12203                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12204   [(parallel [(set (match_dup 2)
12205                    (call (mem:QI (match_dup 1))
12206                          (match_dup 3)))
12207               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12209 (define_peephole2
12210   [(set (match_operand:W 0 "register_operand")
12211         (match_operand:W 1 "memory_operand"))
12212    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12213    (set (match_operand 2)
12214         (call (mem:QI (match_dup 0))
12215               (match_operand 3)))]
12216   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12217    && !reg_mentioned_p (operands[0],
12218                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12219   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12220    (parallel [(set (match_dup 2)
12221                    (call (mem:QI (match_dup 1))
12222                          (match_dup 3)))
12223               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12225 (define_expand "call_value_pop"
12226   [(parallel [(set (match_operand 0)
12227                    (call (match_operand:QI 1)
12228                          (match_operand:SI 2)))
12229               (set (reg:SI SP_REG)
12230                    (plus:SI (reg:SI SP_REG)
12231                             (match_operand:SI 4)))])]
12232   "!TARGET_64BIT"
12234   ix86_expand_call (operands[0], operands[1], operands[2],
12235                     operands[3], operands[4], false);
12236   DONE;
12239 (define_insn "*call_value_pop"
12240   [(set (match_operand 0)
12241         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12242               (match_operand 2)))
12243    (set (reg:SI SP_REG)
12244         (plus:SI (reg:SI SP_REG)
12245                  (match_operand:SI 3 "immediate_operand" "i")))]
12246   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12247   "* return ix86_output_call_insn (insn, operands[1]);"
12248   [(set_attr "type" "callv")])
12250 (define_insn "*sibcall_value_pop"
12251   [(set (match_operand 0)
12252         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12253               (match_operand 2)))
12254    (set (reg:SI SP_REG)
12255         (plus:SI (reg:SI SP_REG)
12256                  (match_operand:SI 3 "immediate_operand" "i")))]
12257   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12258   "* return ix86_output_call_insn (insn, operands[1]);"
12259   [(set_attr "type" "callv")])
12261 (define_insn "*sibcall_value_pop_memory"
12262   [(set (match_operand 0)
12263         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12264               (match_operand 2)))
12265    (set (reg:SI SP_REG)
12266         (plus:SI (reg:SI SP_REG)
12267                  (match_operand:SI 3 "immediate_operand" "i")))
12268    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12269   "!TARGET_64BIT"
12270   "* return ix86_output_call_insn (insn, operands[1]);"
12271   [(set_attr "type" "callv")])
12273 (define_peephole2
12274   [(set (match_operand:SI 0 "register_operand")
12275         (match_operand:SI 1 "memory_operand"))
12276    (parallel [(set (match_operand 2)
12277                    (call (mem:QI (match_dup 0))
12278                          (match_operand 3)))
12279               (set (reg:SI SP_REG)
12280                    (plus:SI (reg:SI SP_REG)
12281                             (match_operand:SI 4 "immediate_operand")))])]
12282   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12283    && !reg_mentioned_p (operands[0],
12284                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12285   [(parallel [(set (match_dup 2)
12286                    (call (mem:QI (match_dup 1))
12287                          (match_dup 3)))
12288               (set (reg:SI SP_REG)
12289                    (plus:SI (reg:SI SP_REG)
12290                             (match_dup 4)))
12291               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12293 (define_peephole2
12294   [(set (match_operand:SI 0 "register_operand")
12295         (match_operand:SI 1 "memory_operand"))
12296    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12297    (parallel [(set (match_operand 2)
12298                    (call (mem:QI (match_dup 0))
12299                          (match_operand 3)))
12300               (set (reg:SI SP_REG)
12301                    (plus:SI (reg:SI SP_REG)
12302                             (match_operand:SI 4 "immediate_operand")))])]
12303   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12304    && !reg_mentioned_p (operands[0],
12305                         CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12306   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12307    (parallel [(set (match_dup 2)
12308                    (call (mem:QI (match_dup 1))
12309                          (match_dup 3)))
12310               (set (reg:SI SP_REG)
12311                    (plus:SI (reg:SI SP_REG)
12312                             (match_dup 4)))
12313               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12315 ;; Call subroutine returning any type.
12317 (define_expand "untyped_call"
12318   [(parallel [(call (match_operand 0)
12319                     (const_int 0))
12320               (match_operand 1)
12321               (match_operand 2)])]
12322   ""
12324   int i;
12326   /* In order to give reg-stack an easier job in validating two
12327      coprocessor registers as containing a possible return value,
12328      simply pretend the untyped call returns a complex long double
12329      value. 
12331      We can't use SSE_REGPARM_MAX here since callee is unprototyped
12332      and should have the default ABI.  */
12334   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12335                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12336                     operands[0], const0_rtx,
12337                     GEN_INT ((TARGET_64BIT
12338                               ? (ix86_abi == SYSV_ABI
12339                                  ? X86_64_SSE_REGPARM_MAX
12340                                  : X86_64_MS_SSE_REGPARM_MAX)
12341                               : X86_32_SSE_REGPARM_MAX)
12342                              - 1),
12343                     NULL, false);
12345   for (i = 0; i < XVECLEN (operands[2], 0); i++)
12346     {
12347       rtx set = XVECEXP (operands[2], 0, i);
12348       emit_move_insn (SET_DEST (set), SET_SRC (set));
12349     }
12351   /* The optimizer does not know that the call sets the function value
12352      registers we stored in the result block.  We avoid problems by
12353      claiming that all hard registers are used and clobbered at this
12354      point.  */
12355   emit_insn (gen_blockage ());
12357   DONE;
12360 ;; Prologue and epilogue instructions
12362 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12363 ;; all of memory.  This blocks insns from being moved across this point.
12365 (define_insn "blockage"
12366   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12367   ""
12368   ""
12369   [(set_attr "length" "0")])
12371 ;; Do not schedule instructions accessing memory across this point.
12373 (define_expand "memory_blockage"
12374   [(set (match_dup 0)
12375         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12376   ""
12378   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12379   MEM_VOLATILE_P (operands[0]) = 1;
12382 (define_insn "*memory_blockage"
12383   [(set (match_operand:BLK 0)
12384         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12385   ""
12386   ""
12387   [(set_attr "length" "0")])
12389 ;; As USE insns aren't meaningful after reload, this is used instead
12390 ;; to prevent deleting instructions setting registers for PIC code
12391 (define_insn "prologue_use"
12392   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12393   ""
12394   ""
12395   [(set_attr "length" "0")])
12397 ;; Insn emitted into the body of a function to return from a function.
12398 ;; This is only done if the function's epilogue is known to be simple.
12399 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12401 (define_expand "return"
12402   [(simple_return)]
12403   "ix86_can_use_return_insn_p ()"
12405   if (crtl->args.pops_args)
12406     {
12407       rtx popc = GEN_INT (crtl->args.pops_args);
12408       emit_jump_insn (gen_simple_return_pop_internal (popc));
12409       DONE;
12410     }
12413 ;; We need to disable this for TARGET_SEH, as otherwise
12414 ;; shrink-wrapped prologue gets enabled too.  This might exceed
12415 ;; the maximum size of prologue in unwind information.
12416 ;; Also disallow shrink-wrapping if using stack slot to pass the
12417 ;; static chain pointer - the first instruction has to be pushl %esi
12418 ;; and it can't be moved around, as we use alternate entry points
12419 ;; in that case.
12421 (define_expand "simple_return"
12422   [(simple_return)]
12423   "!TARGET_SEH && !ix86_static_chain_on_stack"
12425   if (crtl->args.pops_args)
12426     {
12427       rtx popc = GEN_INT (crtl->args.pops_args);
12428       emit_jump_insn (gen_simple_return_pop_internal (popc));
12429       DONE;
12430     }
12433 (define_insn "simple_return_internal"
12434   [(simple_return)]
12435   "reload_completed"
12436   "%!ret"
12437   [(set_attr "length" "1")
12438    (set_attr "atom_unit" "jeu")
12439    (set_attr "length_immediate" "0")
12440    (set_attr "modrm" "0")
12441    (set_attr "maybe_prefix_bnd" "1")])
12443 (define_insn "interrupt_return"
12444   [(simple_return)
12445    (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12446   "reload_completed"
12448   return TARGET_64BIT ? "iretq" : "iret";
12451 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12452 ;; instruction Athlon and K8 have.
12454 (define_insn "simple_return_internal_long"
12455   [(simple_return)
12456    (unspec [(const_int 0)] UNSPEC_REP)]
12457   "reload_completed"
12459   if (ix86_bnd_prefixed_insn_p (insn))
12460     return "%!ret";
12462   return "rep%; ret";
12464   [(set_attr "length" "2")
12465    (set_attr "atom_unit" "jeu")
12466    (set_attr "length_immediate" "0")
12467    (set_attr "prefix_rep" "1")
12468    (set_attr "modrm" "0")])
12470 (define_insn "simple_return_pop_internal"
12471   [(simple_return)
12472    (use (match_operand:SI 0 "const_int_operand"))]
12473   "reload_completed"
12474   "%!ret\t%0"
12475   [(set_attr "length" "3")
12476    (set_attr "atom_unit" "jeu")
12477    (set_attr "length_immediate" "2")
12478    (set_attr "modrm" "0")
12479    (set_attr "maybe_prefix_bnd" "1")])
12481 (define_insn "simple_return_indirect_internal"
12482   [(simple_return)
12483    (use (match_operand:SI 0 "register_operand" "r"))]
12484   "reload_completed"
12485   "%!jmp\t%A0"
12486   [(set_attr "type" "ibr")
12487    (set_attr "length_immediate" "0")
12488    (set_attr "maybe_prefix_bnd" "1")])
12490 (define_insn "nop"
12491   [(const_int 0)]
12492   ""
12493   "nop"
12494   [(set_attr "length" "1")
12495    (set_attr "length_immediate" "0")
12496    (set_attr "modrm" "0")])
12498 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
12499 (define_insn "nops"
12500   [(unspec_volatile [(match_operand 0 "const_int_operand")]
12501                     UNSPECV_NOPS)]
12502   "reload_completed"
12504   int num = INTVAL (operands[0]);
12506   gcc_assert (IN_RANGE (num, 1, 8));
12508   while (num--)
12509     fputs ("\tnop\n", asm_out_file);
12511   return "";
12513   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12514    (set_attr "length_immediate" "0")
12515    (set_attr "modrm" "0")])
12517 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12518 ;; branch prediction penalty for the third jump in a 16-byte
12519 ;; block on K8.
12521 (define_insn "pad"
12522   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12523   ""
12525 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12526   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12527 #else
12528   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12529      The align insn is used to avoid 3 jump instructions in the row to improve
12530      branch prediction and the benefits hardly outweigh the cost of extra 8
12531      nops on the average inserted by full alignment pseudo operation.  */
12532 #endif
12533   return "";
12535   [(set_attr "length" "16")])
12537 (define_expand "prologue"
12538   [(const_int 0)]
12539   ""
12540   "ix86_expand_prologue (); DONE;")
12542 (define_expand "set_got"
12543   [(parallel
12544      [(set (match_operand:SI 0 "register_operand")
12545            (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12546       (clobber (reg:CC FLAGS_REG))])]
12547   "!TARGET_64BIT"
12549   if (flag_pic && !TARGET_VXWORKS_RTP)
12550     ix86_pc_thunk_call_expanded = true;
12553 (define_insn "*set_got"
12554   [(set (match_operand:SI 0 "register_operand" "=r")
12555         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12556    (clobber (reg:CC FLAGS_REG))]
12557   "!TARGET_64BIT"
12558   "* return output_set_got (operands[0], NULL_RTX);"
12559   [(set_attr "type" "multi")
12560    (set_attr "length" "12")])
12562 (define_expand "set_got_labelled"
12563   [(parallel
12564      [(set (match_operand:SI 0 "register_operand")
12565            (unspec:SI [(label_ref (match_operand 1))]
12566                       UNSPEC_SET_GOT))
12567       (clobber (reg:CC FLAGS_REG))])]
12568   "!TARGET_64BIT"
12570   if (flag_pic && !TARGET_VXWORKS_RTP)
12571     ix86_pc_thunk_call_expanded = true;
12574 (define_insn "*set_got_labelled"
12575   [(set (match_operand:SI 0 "register_operand" "=r")
12576         (unspec:SI [(label_ref (match_operand 1))]
12577          UNSPEC_SET_GOT))
12578    (clobber (reg:CC FLAGS_REG))]
12579   "!TARGET_64BIT"
12580   "* return output_set_got (operands[0], operands[1]);"
12581   [(set_attr "type" "multi")
12582    (set_attr "length" "12")])
12584 (define_insn "set_got_rex64"
12585   [(set (match_operand:DI 0 "register_operand" "=r")
12586         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12587   "TARGET_64BIT"
12588   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12589   [(set_attr "type" "lea")
12590    (set_attr "length_address" "4")
12591    (set_attr "modrm_class" "unknown")
12592    (set_attr "mode" "DI")])
12594 (define_insn "set_rip_rex64"
12595   [(set (match_operand:DI 0 "register_operand" "=r")
12596         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12597   "TARGET_64BIT"
12598   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12599   [(set_attr "type" "lea")
12600    (set_attr "length_address" "4")
12601    (set_attr "mode" "DI")])
12603 (define_insn "set_got_offset_rex64"
12604   [(set (match_operand:DI 0 "register_operand" "=r")
12605         (unspec:DI
12606           [(label_ref (match_operand 1))]
12607           UNSPEC_SET_GOT_OFFSET))]
12608   "TARGET_LP64"
12609   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12610   [(set_attr "type" "imov")
12611    (set_attr "length_immediate" "0")
12612    (set_attr "length_address" "8")
12613    (set_attr "mode" "DI")])
12615 (define_expand "epilogue"
12616   [(const_int 0)]
12617   ""
12618   "ix86_expand_epilogue (1); DONE;")
12620 (define_expand "sibcall_epilogue"
12621   [(const_int 0)]
12622   ""
12623   "ix86_expand_epilogue (0); DONE;")
12625 (define_expand "eh_return"
12626   [(use (match_operand 0 "register_operand"))]
12627   ""
12629   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12631   /* Tricky bit: we write the address of the handler to which we will
12632      be returning into someone else's stack frame, one word below the
12633      stack address we wish to restore.  */
12634   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12635   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12636   tmp = gen_rtx_MEM (Pmode, tmp);
12637   emit_move_insn (tmp, ra);
12639   emit_jump_insn (gen_eh_return_internal ());
12640   emit_barrier ();
12641   DONE;
12644 (define_insn_and_split "eh_return_internal"
12645   [(eh_return)]
12646   ""
12647   "#"
12648   "epilogue_completed"
12649   [(const_int 0)]
12650   "ix86_expand_epilogue (2); DONE;")
12652 (define_insn "leave"
12653   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12654    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12655    (clobber (mem:BLK (scratch)))]
12656   "!TARGET_64BIT"
12657   "leave"
12658   [(set_attr "type" "leave")])
12660 (define_insn "leave_rex64"
12661   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12662    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12663    (clobber (mem:BLK (scratch)))]
12664   "TARGET_64BIT"
12665   "leave"
12666   [(set_attr "type" "leave")])
12668 ;; Handle -fsplit-stack.
12670 (define_expand "split_stack_prologue"
12671   [(const_int 0)]
12672   ""
12674   ix86_expand_split_stack_prologue ();
12675   DONE;
12678 ;; In order to support the call/return predictor, we use a return
12679 ;; instruction which the middle-end doesn't see.
12680 (define_insn "split_stack_return"
12681   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12682                      UNSPECV_SPLIT_STACK_RETURN)]
12683   ""
12685   if (operands[0] == const0_rtx)
12686     return "ret";
12687   else
12688     return "ret\t%0";
12690   [(set_attr "atom_unit" "jeu")
12691    (set_attr "modrm" "0")
12692    (set (attr "length")
12693         (if_then_else (match_operand:SI 0 "const0_operand")
12694                       (const_int 1)
12695                       (const_int 3)))
12696    (set (attr "length_immediate")
12697         (if_then_else (match_operand:SI 0 "const0_operand")
12698                       (const_int 0)
12699                       (const_int 2)))])
12701 ;; If there are operand 0 bytes available on the stack, jump to
12702 ;; operand 1.
12704 (define_expand "split_stack_space_check"
12705   [(set (pc) (if_then_else
12706               (ltu (minus (reg SP_REG)
12707                           (match_operand 0 "register_operand"))
12708                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12709               (label_ref (match_operand 1))
12710               (pc)))]
12711   ""
12713   rtx reg, size, limit;
12715   reg = gen_reg_rtx (Pmode);
12716   size = force_reg (Pmode, operands[0]);
12717   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12718   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12719                           UNSPEC_STACK_CHECK);
12720   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12721   ix86_expand_branch (GEU, reg, limit, operands[1]);
12723   DONE;
12726 ;; Bit manipulation instructions.
12728 (define_expand "ffs<mode>2"
12729   [(set (match_dup 2) (const_int -1))
12730    (parallel [(set (match_dup 3) (match_dup 4))
12731               (set (match_operand:SWI48 0 "register_operand")
12732                    (ctz:SWI48
12733                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12734    (set (match_dup 0) (if_then_else:SWI48
12735                         (eq (match_dup 3) (const_int 0))
12736                         (match_dup 2)
12737                         (match_dup 0)))
12738    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12739               (clobber (reg:CC FLAGS_REG))])]
12740   ""
12742   machine_mode flags_mode;
12744   if (<MODE>mode == SImode && !TARGET_CMOVE)
12745     {
12746       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12747       DONE;
12748     }
12750   flags_mode
12751     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12753   operands[2] = gen_reg_rtx (<MODE>mode);
12754   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12755   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12758 (define_insn_and_split "ffssi2_no_cmove"
12759   [(set (match_operand:SI 0 "register_operand" "=r")
12760         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12761    (clobber (match_scratch:SI 2 "=&q"))
12762    (clobber (reg:CC FLAGS_REG))]
12763   "!TARGET_CMOVE"
12764   "#"
12765   "&& reload_completed"
12766   [(parallel [(set (match_dup 4) (match_dup 5))
12767               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12768    (set (strict_low_part (match_dup 3))
12769         (eq:QI (match_dup 4) (const_int 0)))
12770    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12771               (clobber (reg:CC FLAGS_REG))])
12772    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12773               (clobber (reg:CC FLAGS_REG))])
12774    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12775               (clobber (reg:CC FLAGS_REG))])]
12777   machine_mode flags_mode
12778     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12780   operands[3] = gen_lowpart (QImode, operands[2]);
12781   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12782   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12784   ix86_expand_clear (operands[2]);
12787 (define_insn "*tzcnt<mode>_1"
12788   [(set (reg:CCC FLAGS_REG)
12789         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12790                      (const_int 0)))
12791    (set (match_operand:SWI48 0 "register_operand" "=r")
12792         (ctz:SWI48 (match_dup 1)))]
12793   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12794   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12795   [(set_attr "type" "alu1")
12796    (set_attr "prefix_0f" "1")
12797    (set_attr "prefix_rep" "1")
12798    (set_attr "btver2_decode" "double")
12799    (set_attr "mode" "<MODE>")])
12801 (define_insn "*bsf<mode>_1"
12802   [(set (reg:CCZ FLAGS_REG)
12803         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12804                      (const_int 0)))
12805    (set (match_operand:SWI48 0 "register_operand" "=r")
12806         (ctz:SWI48 (match_dup 1)))]
12807   ""
12808   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12809   [(set_attr "type" "alu1")
12810    (set_attr "prefix_0f" "1")
12811    (set_attr "btver2_decode" "double")
12812    (set_attr "znver1_decode" "vector")
12813    (set_attr "mode" "<MODE>")])
12815 (define_expand "ctz<mode>2"
12816   [(parallel
12817     [(set (match_operand:SWI248 0 "register_operand")
12818           (ctz:SWI248
12819             (match_operand:SWI248 1 "nonimmediate_operand")))
12820      (clobber (reg:CC FLAGS_REG))])])
12822 ; False dependency happens when destination is only updated by tzcnt,
12823 ; lzcnt or popcnt.  There is no false dependency when destination is
12824 ; also used in source.
12825 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12826   [(set (match_operand:SWI48 0 "register_operand" "=r")
12827         (ctz:SWI48
12828           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12829    (clobber (reg:CC FLAGS_REG))]
12830   "(TARGET_BMI || TARGET_GENERIC)
12831    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12832   "#"
12833   "&& reload_completed"
12834   [(parallel
12835     [(set (match_dup 0)
12836           (ctz:SWI48 (match_dup 1)))
12837      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12838      (clobber (reg:CC FLAGS_REG))])]
12840   if (!reg_mentioned_p (operands[0], operands[1]))
12841     ix86_expand_clear (operands[0]);
12844 (define_insn "*ctz<mode>2_falsedep"
12845   [(set (match_operand:SWI48 0 "register_operand" "=r")
12846         (ctz:SWI48
12847           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12848    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12849            UNSPEC_INSN_FALSE_DEP)
12850    (clobber (reg:CC FLAGS_REG))]
12851   ""
12853   if (TARGET_BMI)
12854     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12855   else if (TARGET_GENERIC)
12856     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12857     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12858   else
12859     gcc_unreachable ();
12861   [(set_attr "type" "alu1")
12862    (set_attr "prefix_0f" "1")
12863    (set_attr "prefix_rep" "1")
12864    (set_attr "mode" "<MODE>")])
12866 (define_insn "*ctz<mode>2"
12867   [(set (match_operand:SWI248 0 "register_operand" "=r")
12868         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12869    (clobber (reg:CC FLAGS_REG))]
12870   ""
12872   if (TARGET_BMI)
12873     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12874   else if (optimize_function_for_size_p (cfun))
12875     ;
12876   else if (TARGET_GENERIC)
12877     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12878     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12880   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12882   [(set_attr "type" "alu1")
12883    (set_attr "prefix_0f" "1")
12884    (set (attr "prefix_rep")
12885      (if_then_else
12886        (ior (match_test "TARGET_BMI")
12887             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12888                  (match_test "TARGET_GENERIC")))
12889        (const_string "1")
12890        (const_string "0")))
12891    (set_attr "mode" "<MODE>")])
12893 (define_expand "clz<mode>2"
12894   [(parallel
12895      [(set (match_operand:SWI248 0 "register_operand")
12896            (minus:SWI248
12897              (match_dup 2)
12898              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12899       (clobber (reg:CC FLAGS_REG))])
12900    (parallel
12901      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12902       (clobber (reg:CC FLAGS_REG))])]
12903   ""
12905   if (TARGET_LZCNT)
12906     {
12907       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12908       DONE;
12909     }
12910   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12913 (define_expand "clz<mode>2_lzcnt"
12914   [(parallel
12915     [(set (match_operand:SWI248 0 "register_operand")
12916           (clz:SWI248
12917             (match_operand:SWI248 1 "nonimmediate_operand")))
12918      (clobber (reg:CC FLAGS_REG))])]
12919   "TARGET_LZCNT")
12921 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12922   [(set (match_operand:SWI48 0 "register_operand" "=r")
12923         (clz:SWI48
12924           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12925    (clobber (reg:CC FLAGS_REG))]
12926   "TARGET_LZCNT
12927    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12928   "#"
12929   "&& reload_completed"
12930   [(parallel
12931     [(set (match_dup 0)
12932           (clz:SWI48 (match_dup 1)))
12933      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12934      (clobber (reg:CC FLAGS_REG))])]
12936   if (!reg_mentioned_p (operands[0], operands[1]))
12937     ix86_expand_clear (operands[0]);
12940 (define_insn "*clz<mode>2_lzcnt_falsedep"
12941   [(set (match_operand:SWI48 0 "register_operand" "=r")
12942         (clz:SWI48
12943           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12944    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12945            UNSPEC_INSN_FALSE_DEP)
12946    (clobber (reg:CC FLAGS_REG))]
12947   "TARGET_LZCNT"
12948   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12949   [(set_attr "prefix_rep" "1")
12950    (set_attr "type" "bitmanip")
12951    (set_attr "mode" "<MODE>")])
12953 (define_insn "*clz<mode>2_lzcnt"
12954   [(set (match_operand:SWI248 0 "register_operand" "=r")
12955         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12956    (clobber (reg:CC FLAGS_REG))]
12957   "TARGET_LZCNT"
12958   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12959   [(set_attr "prefix_rep" "1")
12960    (set_attr "type" "bitmanip")
12961    (set_attr "mode" "<MODE>")])
12963 ;; BMI instructions.
12964 (define_insn "*bmi_andn_<mode>"
12965   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12966         (and:SWI48
12967           (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12968           (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12969    (clobber (reg:CC FLAGS_REG))]
12970   "TARGET_BMI"
12971   "andn\t{%2, %1, %0|%0, %1, %2}"
12972   [(set_attr "type" "bitmanip")
12973    (set_attr "btver2_decode" "direct, double")
12974    (set_attr "mode" "<MODE>")])
12976 (define_insn "*bmi_andn_<mode>_ccno"
12977   [(set (reg FLAGS_REG)
12978         (compare
12979           (and:SWI48
12980             (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
12981             (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
12982           (const_int 0)))
12983    (clobber (match_scratch:SWI48 0 "=r,r"))]
12984   "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
12985   "andn\t{%2, %1, %0|%0, %1, %2}"
12986   [(set_attr "type" "bitmanip")
12987    (set_attr "btver2_decode" "direct, double")
12988    (set_attr "mode" "<MODE>")])
12990 (define_insn "bmi_bextr_<mode>"
12991   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12992         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12993                        (match_operand:SWI48 2 "register_operand" "r,r")]
12994                       UNSPEC_BEXTR))
12995    (clobber (reg:CC FLAGS_REG))]
12996   "TARGET_BMI"
12997   "bextr\t{%2, %1, %0|%0, %1, %2}"
12998   [(set_attr "type" "bitmanip")
12999    (set_attr "btver2_decode" "direct, double")
13000    (set_attr "mode" "<MODE>")])
13002 (define_insn "*bmi_bextr_<mode>_ccz"
13003   [(set (reg:CCZ FLAGS_REG)
13004         (compare:CCZ
13005           (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13006                          (match_operand:SWI48 2 "register_operand" "r,r")]
13007                         UNSPEC_BEXTR)
13008           (const_int 0)))
13009    (clobber (match_scratch:SWI48 0 "=r,r"))]
13010   "TARGET_BMI"
13011   "bextr\t{%2, %1, %0|%0, %1, %2}"
13012   [(set_attr "type" "bitmanip")
13013    (set_attr "btver2_decode" "direct, double")
13014    (set_attr "mode" "<MODE>")])
13016 (define_insn "*bmi_blsi_<mode>"
13017   [(set (match_operand:SWI48 0 "register_operand" "=r")
13018         (and:SWI48
13019           (neg:SWI48
13020             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13021           (match_dup 1)))
13022    (clobber (reg:CC FLAGS_REG))]
13023   "TARGET_BMI"
13024   "blsi\t{%1, %0|%0, %1}"
13025   [(set_attr "type" "bitmanip")
13026    (set_attr "btver2_decode" "double")
13027    (set_attr "mode" "<MODE>")])
13029 (define_insn "*bmi_blsmsk_<mode>"
13030   [(set (match_operand:SWI48 0 "register_operand" "=r")
13031         (xor:SWI48
13032           (plus:SWI48
13033             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13034             (const_int -1))
13035           (match_dup 1)))
13036    (clobber (reg:CC FLAGS_REG))]
13037   "TARGET_BMI"
13038   "blsmsk\t{%1, %0|%0, %1}"
13039   [(set_attr "type" "bitmanip")
13040    (set_attr "btver2_decode" "double")
13041    (set_attr "mode" "<MODE>")])
13043 (define_insn "*bmi_blsr_<mode>"
13044   [(set (match_operand:SWI48 0 "register_operand" "=r")
13045         (and:SWI48
13046           (plus:SWI48
13047             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13048             (const_int -1))
13049           (match_dup 1)))
13050    (clobber (reg:CC FLAGS_REG))]
13051    "TARGET_BMI"
13052    "blsr\t{%1, %0|%0, %1}"
13053   [(set_attr "type" "bitmanip")
13054    (set_attr "btver2_decode" "double")
13055    (set_attr "mode" "<MODE>")])
13057 ;; BMI2 instructions.
13058 (define_expand "bmi2_bzhi_<mode>3"
13059   [(parallel
13060     [(set (match_operand:SWI48 0 "register_operand")
13061           (zero_extract:SWI48
13062             (match_operand:SWI48 1 "nonimmediate_operand")
13063             (umin:SWI48
13064               (and:SWI48 (match_operand:SWI48 2 "register_operand")
13065                          (const_int 255))
13066               (match_dup 3))
13067             (const_int 0)))
13068      (clobber (reg:CC FLAGS_REG))])]
13069   "TARGET_BMI2"
13070   "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13072 (define_insn "*bmi2_bzhi_<mode>3"
13073   [(set (match_operand:SWI48 0 "register_operand" "=r")
13074         (zero_extract:SWI48
13075           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13076           (umin:SWI48
13077             (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13078                        (const_int 255))
13079             (match_operand:SWI48 3 "const_int_operand" "n"))
13080           (const_int 0)))
13081    (clobber (reg:CC FLAGS_REG))]
13082   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13083   "bzhi\t{%2, %1, %0|%0, %1, %2}"
13084   [(set_attr "type" "bitmanip")
13085    (set_attr "prefix" "vex")
13086    (set_attr "mode" "<MODE>")])
13088 (define_mode_attr k [(SI "k") (DI "q")])
13090 (define_insn "*bmi2_bzhi_<mode>3_1"
13091   [(set (match_operand:SWI48 0 "register_operand" "=r")
13092         (zero_extract:SWI48
13093           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13094           (umin:SWI48
13095             (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13096             (match_operand:SWI48 3 "const_int_operand" "n"))
13097           (const_int 0)))
13098    (clobber (reg:CC FLAGS_REG))]
13099   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13100   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13101   [(set_attr "type" "bitmanip")
13102    (set_attr "prefix" "vex")
13103    (set_attr "mode" "<MODE>")])
13105 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13106   [(set (reg:CCZ FLAGS_REG)
13107         (compare:CCZ
13108           (zero_extract:SWI48
13109             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13110             (umin:SWI48
13111               (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13112               (match_operand:SWI48 3 "const_int_operand" "n"))
13113             (const_int 0))
13114         (const_int 0)))
13115    (clobber (match_scratch:SWI48 0 "=r"))]
13116   "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13117   "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13118   [(set_attr "type" "bitmanip")
13119    (set_attr "prefix" "vex")
13120    (set_attr "mode" "<MODE>")])
13122 (define_insn "bmi2_pdep_<mode>3"
13123   [(set (match_operand:SWI48 0 "register_operand" "=r")
13124         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13125                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13126                        UNSPEC_PDEP))]
13127   "TARGET_BMI2"
13128   "pdep\t{%2, %1, %0|%0, %1, %2}"
13129   [(set_attr "type" "bitmanip")
13130    (set_attr "prefix" "vex")
13131    (set_attr "mode" "<MODE>")])
13133 (define_insn "bmi2_pext_<mode>3"
13134   [(set (match_operand:SWI48 0 "register_operand" "=r")
13135         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13136                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13137                        UNSPEC_PEXT))]
13138   "TARGET_BMI2"
13139   "pext\t{%2, %1, %0|%0, %1, %2}"
13140   [(set_attr "type" "bitmanip")
13141    (set_attr "prefix" "vex")
13142    (set_attr "mode" "<MODE>")])
13144 ;; TBM instructions.
13145 (define_insn "tbm_bextri_<mode>"
13146   [(set (match_operand:SWI48 0 "register_operand" "=r")
13147         (zero_extract:SWI48
13148           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13149           (match_operand 2 "const_0_to_255_operand" "N")
13150           (match_operand 3 "const_0_to_255_operand" "N")))
13151    (clobber (reg:CC FLAGS_REG))]
13152    "TARGET_TBM"
13154   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13155   return "bextr\t{%2, %1, %0|%0, %1, %2}";
13157   [(set_attr "type" "bitmanip")
13158    (set_attr "mode" "<MODE>")])
13160 (define_insn "*tbm_blcfill_<mode>"
13161   [(set (match_operand:SWI48 0 "register_operand" "=r")
13162         (and:SWI48
13163           (plus:SWI48
13164             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13165             (const_int 1))
13166           (match_dup 1)))
13167    (clobber (reg:CC FLAGS_REG))]
13168    "TARGET_TBM"
13169    "blcfill\t{%1, %0|%0, %1}"
13170   [(set_attr "type" "bitmanip")
13171    (set_attr "mode" "<MODE>")])
13173 (define_insn "*tbm_blci_<mode>"
13174   [(set (match_operand:SWI48 0 "register_operand" "=r")
13175         (ior:SWI48
13176           (not:SWI48
13177             (plus:SWI48
13178               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13179               (const_int 1)))
13180           (match_dup 1)))
13181    (clobber (reg:CC FLAGS_REG))]
13182    "TARGET_TBM"
13183    "blci\t{%1, %0|%0, %1}"
13184   [(set_attr "type" "bitmanip")
13185    (set_attr "mode" "<MODE>")])
13187 (define_insn "*tbm_blcic_<mode>"
13188   [(set (match_operand:SWI48 0 "register_operand" "=r")
13189         (and:SWI48
13190           (plus:SWI48
13191             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13192             (const_int 1))
13193           (not:SWI48
13194             (match_dup 1))))
13195    (clobber (reg:CC FLAGS_REG))]
13196    "TARGET_TBM"
13197    "blcic\t{%1, %0|%0, %1}"
13198   [(set_attr "type" "bitmanip")
13199    (set_attr "mode" "<MODE>")])
13201 (define_insn "*tbm_blcmsk_<mode>"
13202   [(set (match_operand:SWI48 0 "register_operand" "=r")
13203         (xor:SWI48
13204           (plus:SWI48
13205             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13206             (const_int 1))
13207           (match_dup 1)))
13208    (clobber (reg:CC FLAGS_REG))]
13209    "TARGET_TBM"
13210    "blcmsk\t{%1, %0|%0, %1}"
13211   [(set_attr "type" "bitmanip")
13212    (set_attr "mode" "<MODE>")])
13214 (define_insn "*tbm_blcs_<mode>"
13215   [(set (match_operand:SWI48 0 "register_operand" "=r")
13216         (ior:SWI48
13217           (plus:SWI48
13218             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13219             (const_int 1))
13220           (match_dup 1)))
13221    (clobber (reg:CC FLAGS_REG))]
13222    "TARGET_TBM"
13223    "blcs\t{%1, %0|%0, %1}"
13224   [(set_attr "type" "bitmanip")
13225    (set_attr "mode" "<MODE>")])
13227 (define_insn "*tbm_blsfill_<mode>"
13228   [(set (match_operand:SWI48 0 "register_operand" "=r")
13229         (ior:SWI48
13230           (plus:SWI48
13231             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13232             (const_int -1))
13233           (match_dup 1)))
13234    (clobber (reg:CC FLAGS_REG))]
13235    "TARGET_TBM"
13236    "blsfill\t{%1, %0|%0, %1}"
13237   [(set_attr "type" "bitmanip")
13238    (set_attr "mode" "<MODE>")])
13240 (define_insn "*tbm_blsic_<mode>"
13241   [(set (match_operand:SWI48 0 "register_operand" "=r")
13242         (ior:SWI48
13243           (plus:SWI48
13244             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13245             (const_int -1))
13246           (not:SWI48
13247             (match_dup 1))))
13248    (clobber (reg:CC FLAGS_REG))]
13249    "TARGET_TBM"
13250    "blsic\t{%1, %0|%0, %1}"
13251   [(set_attr "type" "bitmanip")
13252    (set_attr "mode" "<MODE>")])
13254 (define_insn "*tbm_t1mskc_<mode>"
13255   [(set (match_operand:SWI48 0 "register_operand" "=r")
13256         (ior:SWI48
13257           (plus:SWI48
13258             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13259             (const_int 1))
13260           (not:SWI48
13261             (match_dup 1))))
13262    (clobber (reg:CC FLAGS_REG))]
13263    "TARGET_TBM"
13264    "t1mskc\t{%1, %0|%0, %1}"
13265   [(set_attr "type" "bitmanip")
13266    (set_attr "mode" "<MODE>")])
13268 (define_insn "*tbm_tzmsk_<mode>"
13269   [(set (match_operand:SWI48 0 "register_operand" "=r")
13270         (and:SWI48
13271           (plus:SWI48
13272             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13273             (const_int -1))
13274           (not:SWI48
13275             (match_dup 1))))
13276    (clobber (reg:CC FLAGS_REG))]
13277    "TARGET_TBM"
13278    "tzmsk\t{%1, %0|%0, %1}"
13279   [(set_attr "type" "bitmanip")
13280    (set_attr "mode" "<MODE>")])
13282 (define_insn "bsr_rex64"
13283   [(set (match_operand:DI 0 "register_operand" "=r")
13284         (minus:DI (const_int 63)
13285                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13286    (clobber (reg:CC FLAGS_REG))]
13287   "TARGET_64BIT"
13288   "bsr{q}\t{%1, %0|%0, %1}"
13289   [(set_attr "type" "alu1")
13290    (set_attr "prefix_0f" "1")
13291    (set_attr "znver1_decode" "vector")
13292    (set_attr "mode" "DI")])
13294 (define_insn "bsr"
13295   [(set (match_operand:SI 0 "register_operand" "=r")
13296         (minus:SI (const_int 31)
13297                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13298    (clobber (reg:CC FLAGS_REG))]
13299   ""
13300   "bsr{l}\t{%1, %0|%0, %1}"
13301   [(set_attr "type" "alu1")
13302    (set_attr "prefix_0f" "1")
13303    (set_attr "znver1_decode" "vector")
13304    (set_attr "mode" "SI")])
13306 (define_insn "*bsrhi"
13307   [(set (match_operand:HI 0 "register_operand" "=r")
13308         (minus:HI (const_int 15)
13309                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13310    (clobber (reg:CC FLAGS_REG))]
13311   ""
13312   "bsr{w}\t{%1, %0|%0, %1}"
13313   [(set_attr "type" "alu1")
13314    (set_attr "prefix_0f" "1")
13315    (set_attr "znver1_decode" "vector")
13316    (set_attr "mode" "HI")])
13318 (define_expand "popcount<mode>2"
13319   [(parallel
13320     [(set (match_operand:SWI248 0 "register_operand")
13321           (popcount:SWI248
13322             (match_operand:SWI248 1 "nonimmediate_operand")))
13323      (clobber (reg:CC FLAGS_REG))])]
13324   "TARGET_POPCNT")
13326 (define_insn_and_split "*popcount<mode>2_falsedep_1"
13327   [(set (match_operand:SWI48 0 "register_operand" "=r")
13328         (popcount:SWI48
13329           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13330    (clobber (reg:CC FLAGS_REG))]
13331   "TARGET_POPCNT
13332    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
13333   "#"
13334   "&& reload_completed"
13335   [(parallel
13336     [(set (match_dup 0)
13337           (popcount:SWI48 (match_dup 1)))
13338      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13339      (clobber (reg:CC FLAGS_REG))])]
13341   if (!reg_mentioned_p (operands[0], operands[1]))
13342     ix86_expand_clear (operands[0]);
13345 (define_insn "*popcount<mode>2_falsedep"
13346   [(set (match_operand:SWI48 0 "register_operand" "=r")
13347         (popcount:SWI48
13348           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13349    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13350            UNSPEC_INSN_FALSE_DEP)
13351    (clobber (reg:CC FLAGS_REG))]
13352   "TARGET_POPCNT"
13354 #if TARGET_MACHO
13355   return "popcnt\t{%1, %0|%0, %1}";
13356 #else
13357   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13358 #endif
13360   [(set_attr "prefix_rep" "1")
13361    (set_attr "type" "bitmanip")
13362    (set_attr "mode" "<MODE>")])
13364 (define_insn "*popcount<mode>2"
13365   [(set (match_operand:SWI248 0 "register_operand" "=r")
13366         (popcount:SWI248
13367           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13368    (clobber (reg:CC FLAGS_REG))]
13369   "TARGET_POPCNT"
13371 #if TARGET_MACHO
13372   return "popcnt\t{%1, %0|%0, %1}";
13373 #else
13374   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13375 #endif
13377   [(set_attr "prefix_rep" "1")
13378    (set_attr "type" "bitmanip")
13379    (set_attr "mode" "<MODE>")])
13381 (define_expand "bswapdi2"
13382   [(set (match_operand:DI 0 "register_operand")
13383         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13384   "TARGET_64BIT"
13386   if (!TARGET_MOVBE)
13387     operands[1] = force_reg (DImode, operands[1]);
13390 (define_expand "bswapsi2"
13391   [(set (match_operand:SI 0 "register_operand")
13392         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13393   ""
13395   if (TARGET_MOVBE)
13396     ;
13397   else if (TARGET_BSWAP)
13398     operands[1] = force_reg (SImode, operands[1]);
13399   else
13400     {
13401       rtx x = operands[0];
13403       emit_move_insn (x, operands[1]);
13404       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13405       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13406       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13407       DONE;
13408     }
13411 (define_insn "*bswap<mode>2_movbe"
13412   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13413         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13414   "TARGET_MOVBE
13415    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13416   "@
13417     bswap\t%0
13418     movbe\t{%1, %0|%0, %1}
13419     movbe\t{%1, %0|%0, %1}"
13420   [(set_attr "type" "bitmanip,imov,imov")
13421    (set_attr "modrm" "0,1,1")
13422    (set_attr "prefix_0f" "*,1,1")
13423    (set_attr "prefix_extra" "*,1,1")
13424    (set_attr "mode" "<MODE>")])
13426 (define_insn "*bswap<mode>2"
13427   [(set (match_operand:SWI48 0 "register_operand" "=r")
13428         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13429   "TARGET_BSWAP"
13430   "bswap\t%0"
13431   [(set_attr "type" "bitmanip")
13432    (set_attr "modrm" "0")
13433    (set_attr "mode" "<MODE>")])
13435 (define_insn "*bswaphi_lowpart_1"
13436   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13437         (bswap:HI (match_dup 0)))
13438    (clobber (reg:CC FLAGS_REG))]
13439   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
13440   "@
13441     xchg{b}\t{%h0, %b0|%b0, %h0}
13442     rol{w}\t{$8, %0|%0, 8}"
13443   [(set_attr "length" "2,4")
13444    (set_attr "mode" "QI,HI")])
13446 (define_insn "bswaphi_lowpart"
13447   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
13448         (bswap:HI (match_dup 0)))
13449    (clobber (reg:CC FLAGS_REG))]
13450   ""
13451   "rol{w}\t{$8, %0|%0, 8}"
13452   [(set_attr "length" "4")
13453    (set_attr "mode" "HI")])
13455 (define_expand "paritydi2"
13456   [(set (match_operand:DI 0 "register_operand")
13457         (parity:DI (match_operand:DI 1 "register_operand")))]
13458   "! TARGET_POPCNT"
13460   rtx scratch = gen_reg_rtx (QImode);
13461   rtx cond;
13463   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13464                                 NULL_RTX, operands[1]));
13466   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13467                          gen_rtx_REG (CCmode, FLAGS_REG),
13468                          const0_rtx);
13469   emit_insn (gen_rtx_SET (scratch, cond));
13471   if (TARGET_64BIT)
13472     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13473   else
13474     {
13475       rtx tmp = gen_reg_rtx (SImode);
13477       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13478       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13479     }
13480   DONE;
13483 (define_expand "paritysi2"
13484   [(set (match_operand:SI 0 "register_operand")
13485         (parity:SI (match_operand:SI 1 "register_operand")))]
13486   "! TARGET_POPCNT"
13488   rtx scratch = gen_reg_rtx (QImode);
13489   rtx cond;
13491   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13493   cond = gen_rtx_fmt_ee (ORDERED, QImode,
13494                          gen_rtx_REG (CCmode, FLAGS_REG),
13495                          const0_rtx);
13496   emit_insn (gen_rtx_SET (scratch, cond));
13498   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13499   DONE;
13502 (define_insn_and_split "paritydi2_cmp"
13503   [(set (reg:CC FLAGS_REG)
13504         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
13505                    UNSPEC_PARITY))
13506    (clobber (match_scratch:DI 0 "=r"))
13507    (clobber (match_scratch:SI 1 "=&r"))
13508    (clobber (match_scratch:HI 2 "=Q"))]
13509   "! TARGET_POPCNT"
13510   "#"
13511   "&& reload_completed"
13512   [(parallel
13513      [(set (match_dup 1)
13514            (xor:SI (match_dup 1) (match_dup 4)))
13515       (clobber (reg:CC FLAGS_REG))])
13516    (parallel
13517      [(set (reg:CC FLAGS_REG)
13518            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13519       (clobber (match_dup 1))
13520       (clobber (match_dup 2))])]
13522   operands[4] = gen_lowpart (SImode, operands[3]);
13524   if (TARGET_64BIT)
13525     {
13526       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
13527       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
13528     }
13529   else
13530     operands[1] = gen_highpart (SImode, operands[3]);
13533 (define_insn_and_split "paritysi2_cmp"
13534   [(set (reg:CC FLAGS_REG)
13535         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
13536                    UNSPEC_PARITY))
13537    (clobber (match_scratch:SI 0 "=r"))
13538    (clobber (match_scratch:HI 1 "=&Q"))]
13539   "! TARGET_POPCNT"
13540   "#"
13541   "&& reload_completed"
13542   [(parallel
13543      [(set (match_dup 1)
13544            (xor:HI (match_dup 1) (match_dup 3)))
13545       (clobber (reg:CC FLAGS_REG))])
13546    (parallel
13547      [(set (reg:CC FLAGS_REG)
13548            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
13549       (clobber (match_dup 1))])]
13551   operands[3] = gen_lowpart (HImode, operands[2]);
13553   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
13554   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
13557 (define_insn "*parityhi2_cmp"
13558   [(set (reg:CC FLAGS_REG)
13559         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
13560                    UNSPEC_PARITY))
13561    (clobber (match_scratch:HI 0 "=Q"))]
13562   "! TARGET_POPCNT"
13563   "xor{b}\t{%h0, %b0|%b0, %h0}"
13564   [(set_attr "length" "2")
13565    (set_attr "mode" "HI")])
13568 ;; Thread-local storage patterns for ELF.
13570 ;; Note that these code sequences must appear exactly as shown
13571 ;; in order to allow linker relaxation.
13573 (define_insn "*tls_global_dynamic_32_gnu"
13574   [(set (match_operand:SI 0 "register_operand" "=a")
13575         (unspec:SI
13576          [(match_operand:SI 1 "register_operand" "b")
13577           (match_operand 2 "tls_symbolic_operand")
13578           (match_operand 3 "constant_call_address_operand" "Bz")
13579           (reg:SI SP_REG)]
13580          UNSPEC_TLS_GD))
13581    (clobber (match_scratch:SI 4 "=d"))
13582    (clobber (match_scratch:SI 5 "=c"))
13583    (clobber (reg:CC FLAGS_REG))]
13584   "!TARGET_64BIT && TARGET_GNU_TLS"
13586   output_asm_insn
13587     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
13588   if (TARGET_SUN_TLS)
13589 #ifdef HAVE_AS_IX86_TLSGDPLT
13590     return "call\t%a2@tlsgdplt";
13591 #else
13592     return "call\t%p3@plt";
13593 #endif
13594   return "call\t%P3";
13596   [(set_attr "type" "multi")
13597    (set_attr "length" "12")])
13599 (define_expand "tls_global_dynamic_32"
13600   [(parallel
13601     [(set (match_operand:SI 0 "register_operand")
13602           (unspec:SI [(match_operand:SI 2 "register_operand")
13603                       (match_operand 1 "tls_symbolic_operand")
13604                       (match_operand 3 "constant_call_address_operand")
13605                       (reg:SI SP_REG)]
13606                      UNSPEC_TLS_GD))
13607      (clobber (match_scratch:SI 4))
13608      (clobber (match_scratch:SI 5))
13609      (clobber (reg:CC FLAGS_REG))])]
13610   ""
13611   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13613 (define_insn "*tls_global_dynamic_64_<mode>"
13614   [(set (match_operand:P 0 "register_operand" "=a")
13615         (call:P
13616          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
13617          (match_operand 3)))
13618    (unspec:P [(match_operand 1 "tls_symbolic_operand")
13619               (reg:P SP_REG)]
13620              UNSPEC_TLS_GD)]
13621   "TARGET_64BIT"
13623   if (!TARGET_X32)
13624     fputs (ASM_BYTE "0x66\n", asm_out_file);
13625   output_asm_insn
13626     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13627   fputs (ASM_SHORT "0x6666\n", asm_out_file);
13628   fputs ("\trex64\n", asm_out_file);
13629   if (TARGET_SUN_TLS)
13630     return "call\t%p2@plt";
13631   return "call\t%P2";
13633   [(set_attr "type" "multi")
13634    (set (attr "length")
13635         (symbol_ref "TARGET_X32 ? 15 : 16"))])
13637 (define_insn "*tls_global_dynamic_64_largepic"
13638   [(set (match_operand:DI 0 "register_operand" "=a")
13639         (call:DI
13640          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
13641                           (match_operand:DI 3 "immediate_operand" "i")))
13642          (match_operand 4)))
13643    (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13644                (reg:DI SP_REG)]
13645               UNSPEC_TLS_GD)]
13646   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13647    && GET_CODE (operands[3]) == CONST
13648    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13649    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13651   output_asm_insn
13652     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13653   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13654   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13655   return "call\t{*%%rax|rax}";
13657   [(set_attr "type" "multi")
13658    (set_attr "length" "22")])
13660 (define_expand "tls_global_dynamic_64_<mode>"
13661   [(parallel
13662     [(set (match_operand:P 0 "register_operand")
13663           (call:P
13664            (mem:QI (match_operand 2))
13665            (const_int 0)))
13666      (unspec:P [(match_operand 1 "tls_symbolic_operand")
13667                 (reg:P SP_REG)]
13668                UNSPEC_TLS_GD)])]
13669   "TARGET_64BIT"
13670   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13672 (define_insn "*tls_local_dynamic_base_32_gnu"
13673   [(set (match_operand:SI 0 "register_operand" "=a")
13674         (unspec:SI
13675          [(match_operand:SI 1 "register_operand" "b")
13676           (match_operand 2 "constant_call_address_operand" "Bz")
13677           (reg:SI SP_REG)]
13678          UNSPEC_TLS_LD_BASE))
13679    (clobber (match_scratch:SI 3 "=d"))
13680    (clobber (match_scratch:SI 4 "=c"))
13681    (clobber (reg:CC FLAGS_REG))]
13682   "!TARGET_64BIT && TARGET_GNU_TLS"
13684   output_asm_insn
13685     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13686   if (TARGET_SUN_TLS)
13687     {
13688       if (HAVE_AS_IX86_TLSLDMPLT)
13689         return "call\t%&@tlsldmplt";
13690       else
13691         return "call\t%p2@plt";
13692     }
13693   return "call\t%P2";
13695   [(set_attr "type" "multi")
13696    (set_attr "length" "11")])
13698 (define_expand "tls_local_dynamic_base_32"
13699   [(parallel
13700      [(set (match_operand:SI 0 "register_operand")
13701            (unspec:SI
13702             [(match_operand:SI 1 "register_operand")
13703              (match_operand 2 "constant_call_address_operand")
13704              (reg:SI SP_REG)]
13705             UNSPEC_TLS_LD_BASE))
13706       (clobber (match_scratch:SI 3))
13707       (clobber (match_scratch:SI 4))
13708       (clobber (reg:CC FLAGS_REG))])]
13709   ""
13710   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13712 (define_insn "*tls_local_dynamic_base_64_<mode>"
13713   [(set (match_operand:P 0 "register_operand" "=a")
13714         (call:P
13715          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13716          (match_operand 2)))
13717    (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
13718   "TARGET_64BIT"
13720   output_asm_insn
13721     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13722   if (TARGET_SUN_TLS)
13723     return "call\t%p1@plt";
13724   return "call\t%P1";
13726   [(set_attr "type" "multi")
13727    (set_attr "length" "12")])
13729 (define_insn "*tls_local_dynamic_base_64_largepic"
13730   [(set (match_operand:DI 0 "register_operand" "=a")
13731         (call:DI
13732          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13733                           (match_operand:DI 2 "immediate_operand" "i")))
13734          (match_operand 3)))
13735    (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
13736   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13737    && GET_CODE (operands[2]) == CONST
13738    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13739    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13741   output_asm_insn
13742     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13743   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13744   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13745   return "call\t{*%%rax|rax}";
13747   [(set_attr "type" "multi")
13748    (set_attr "length" "22")])
13750 (define_expand "tls_local_dynamic_base_64_<mode>"
13751   [(parallel
13752      [(set (match_operand:P 0 "register_operand")
13753            (call:P
13754             (mem:QI (match_operand 1))
13755             (const_int 0)))
13756       (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
13757   "TARGET_64BIT"
13758   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13760 ;; Local dynamic of a single variable is a lose.  Show combine how
13761 ;; to convert that back to global dynamic.
13763 (define_insn_and_split "*tls_local_dynamic_32_once"
13764   [(set (match_operand:SI 0 "register_operand" "=a")
13765         (plus:SI
13766          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13767                      (match_operand 2 "constant_call_address_operand" "Bz")
13768                      (reg:SI SP_REG)]
13769                     UNSPEC_TLS_LD_BASE)
13770          (const:SI (unspec:SI
13771                     [(match_operand 3 "tls_symbolic_operand")]
13772                     UNSPEC_DTPOFF))))
13773    (clobber (match_scratch:SI 4 "=d"))
13774    (clobber (match_scratch:SI 5 "=c"))
13775    (clobber (reg:CC FLAGS_REG))]
13776   ""
13777   "#"
13778   ""
13779   [(parallel
13780      [(set (match_dup 0)
13781            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13782                        (reg:SI SP_REG)]
13783                       UNSPEC_TLS_GD))
13784       (clobber (match_dup 4))
13785       (clobber (match_dup 5))
13786       (clobber (reg:CC FLAGS_REG))])])
13788 ;; Segment register for the thread base ptr load
13789 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13791 ;; Load and add the thread base pointer from %<tp_seg>:0.
13792 (define_insn "*load_tp_x32"
13793   [(set (match_operand:SI 0 "register_operand" "=r")
13794         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13795   "TARGET_X32"
13796   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13797   [(set_attr "type" "imov")
13798    (set_attr "modrm" "0")
13799    (set_attr "length" "7")
13800    (set_attr "memory" "load")
13801    (set_attr "imm_disp" "false")])
13803 (define_insn "*load_tp_x32_zext"
13804   [(set (match_operand:DI 0 "register_operand" "=r")
13805         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13806   "TARGET_X32"
13807   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13808   [(set_attr "type" "imov")
13809    (set_attr "modrm" "0")
13810    (set_attr "length" "7")
13811    (set_attr "memory" "load")
13812    (set_attr "imm_disp" "false")])
13814 (define_insn "*load_tp_<mode>"
13815   [(set (match_operand:P 0 "register_operand" "=r")
13816         (unspec:P [(const_int 0)] UNSPEC_TP))]
13817   "!TARGET_X32"
13818   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13819   [(set_attr "type" "imov")
13820    (set_attr "modrm" "0")
13821    (set_attr "length" "7")
13822    (set_attr "memory" "load")
13823    (set_attr "imm_disp" "false")])
13825 (define_insn "*add_tp_x32"
13826   [(set (match_operand:SI 0 "register_operand" "=r")
13827         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13828                  (match_operand:SI 1 "register_operand" "0")))
13829    (clobber (reg:CC FLAGS_REG))]
13830   "TARGET_X32"
13831   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13832   [(set_attr "type" "alu")
13833    (set_attr "modrm" "0")
13834    (set_attr "length" "7")
13835    (set_attr "memory" "load")
13836    (set_attr "imm_disp" "false")])
13838 (define_insn "*add_tp_x32_zext"
13839   [(set (match_operand:DI 0 "register_operand" "=r")
13840         (zero_extend:DI
13841           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13842                    (match_operand:SI 1 "register_operand" "0"))))
13843    (clobber (reg:CC FLAGS_REG))]
13844   "TARGET_X32"
13845   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13846   [(set_attr "type" "alu")
13847    (set_attr "modrm" "0")
13848    (set_attr "length" "7")
13849    (set_attr "memory" "load")
13850    (set_attr "imm_disp" "false")])
13852 (define_insn "*add_tp_<mode>"
13853   [(set (match_operand:P 0 "register_operand" "=r")
13854         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13855                 (match_operand:P 1 "register_operand" "0")))
13856    (clobber (reg:CC FLAGS_REG))]
13857   "!TARGET_X32"
13858   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13859   [(set_attr "type" "alu")
13860    (set_attr "modrm" "0")
13861    (set_attr "length" "7")
13862    (set_attr "memory" "load")
13863    (set_attr "imm_disp" "false")])
13865 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13866 ;; %rax as destination of the initial executable code sequence.
13867 (define_insn "tls_initial_exec_64_sun"
13868   [(set (match_operand:DI 0 "register_operand" "=a")
13869         (unspec:DI
13870          [(match_operand 1 "tls_symbolic_operand")]
13871          UNSPEC_TLS_IE_SUN))
13872    (clobber (reg:CC FLAGS_REG))]
13873   "TARGET_64BIT && TARGET_SUN_TLS"
13875   output_asm_insn
13876     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13877   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13879   [(set_attr "type" "multi")])
13881 ;; GNU2 TLS patterns can be split.
13883 (define_expand "tls_dynamic_gnu2_32"
13884   [(set (match_dup 3)
13885         (plus:SI (match_operand:SI 2 "register_operand")
13886                  (const:SI
13887                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13888                              UNSPEC_TLSDESC))))
13889    (parallel
13890     [(set (match_operand:SI 0 "register_operand")
13891           (unspec:SI [(match_dup 1) (match_dup 3)
13892                       (match_dup 2) (reg:SI SP_REG)]
13893                       UNSPEC_TLSDESC))
13894      (clobber (reg:CC FLAGS_REG))])]
13895   "!TARGET_64BIT && TARGET_GNU2_TLS"
13897   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13898   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13901 (define_insn "*tls_dynamic_gnu2_lea_32"
13902   [(set (match_operand:SI 0 "register_operand" "=r")
13903         (plus:SI (match_operand:SI 1 "register_operand" "b")
13904                  (const:SI
13905                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13906                               UNSPEC_TLSDESC))))]
13907   "!TARGET_64BIT && TARGET_GNU2_TLS"
13908   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13909   [(set_attr "type" "lea")
13910    (set_attr "mode" "SI")
13911    (set_attr "length" "6")
13912    (set_attr "length_address" "4")])
13914 (define_insn "*tls_dynamic_gnu2_call_32"
13915   [(set (match_operand:SI 0 "register_operand" "=a")
13916         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13917                     (match_operand:SI 2 "register_operand" "0")
13918                     ;; we have to make sure %ebx still points to the GOT
13919                     (match_operand:SI 3 "register_operand" "b")
13920                     (reg:SI SP_REG)]
13921                    UNSPEC_TLSDESC))
13922    (clobber (reg:CC FLAGS_REG))]
13923   "!TARGET_64BIT && TARGET_GNU2_TLS"
13924   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13925   [(set_attr "type" "call")
13926    (set_attr "length" "2")
13927    (set_attr "length_address" "0")])
13929 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13930   [(set (match_operand:SI 0 "register_operand" "=&a")
13931         (plus:SI
13932          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13933                      (match_operand:SI 4)
13934                      (match_operand:SI 2 "register_operand" "b")
13935                      (reg:SI SP_REG)]
13936                     UNSPEC_TLSDESC)
13937          (const:SI (unspec:SI
13938                     [(match_operand 1 "tls_symbolic_operand")]
13939                     UNSPEC_DTPOFF))))
13940    (clobber (reg:CC FLAGS_REG))]
13941   "!TARGET_64BIT && TARGET_GNU2_TLS"
13942   "#"
13943   ""
13944   [(set (match_dup 0) (match_dup 5))]
13946   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13947   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13950 (define_expand "tls_dynamic_gnu2_64"
13951   [(set (match_dup 2)
13952         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13953                    UNSPEC_TLSDESC))
13954    (parallel
13955     [(set (match_operand:DI 0 "register_operand")
13956           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13957                      UNSPEC_TLSDESC))
13958      (clobber (reg:CC FLAGS_REG))])]
13959   "TARGET_64BIT && TARGET_GNU2_TLS"
13961   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13962   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13965 (define_insn "*tls_dynamic_gnu2_lea_64"
13966   [(set (match_operand:DI 0 "register_operand" "=r")
13967         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13968                    UNSPEC_TLSDESC))]
13969   "TARGET_64BIT && TARGET_GNU2_TLS"
13970   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13971   [(set_attr "type" "lea")
13972    (set_attr "mode" "DI")
13973    (set_attr "length" "7")
13974    (set_attr "length_address" "4")])
13976 (define_insn "*tls_dynamic_gnu2_call_64"
13977   [(set (match_operand:DI 0 "register_operand" "=a")
13978         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13979                     (match_operand:DI 2 "register_operand" "0")
13980                     (reg:DI SP_REG)]
13981                    UNSPEC_TLSDESC))
13982    (clobber (reg:CC FLAGS_REG))]
13983   "TARGET_64BIT && TARGET_GNU2_TLS"
13984   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13985   [(set_attr "type" "call")
13986    (set_attr "length" "2")
13987    (set_attr "length_address" "0")])
13989 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13990   [(set (match_operand:DI 0 "register_operand" "=&a")
13991         (plus:DI
13992          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13993                      (match_operand:DI 3)
13994                      (reg:DI SP_REG)]
13995                     UNSPEC_TLSDESC)
13996          (const:DI (unspec:DI
13997                     [(match_operand 1 "tls_symbolic_operand")]
13998                     UNSPEC_DTPOFF))))
13999    (clobber (reg:CC FLAGS_REG))]
14000   "TARGET_64BIT && TARGET_GNU2_TLS"
14001   "#"
14002   ""
14003   [(set (match_dup 0) (match_dup 4))]
14005   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14006   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14009 ;; These patterns match the binary 387 instructions for addM3, subM3,
14010 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14011 ;; SFmode.  The first is the normal insn, the second the same insn but
14012 ;; with one operand a conversion, and the third the same insn but with
14013 ;; the other operand a conversion.  The conversion may be SFmode or
14014 ;; SImode if the target mode DFmode, but only SImode if the target mode
14015 ;; is SFmode.
14017 ;; Gcc is slightly more smart about handling normal two address instructions
14018 ;; so use special patterns for add and mull.
14020 (define_insn "*fop_<mode>_comm"
14021   [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14022         (match_operator:MODEF 3 "binary_fp_operator"
14023           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14024            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14025   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14026     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14027    && COMMUTATIVE_ARITH_P (operands[3])
14028    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14029   "* return output_387_binary_op (insn, operands);"
14030   [(set (attr "type")
14031         (if_then_else (eq_attr "alternative" "1,2")
14032            (if_then_else (match_operand:MODEF 3 "mult_operator")
14033               (const_string "ssemul")
14034               (const_string "sseadd"))
14035            (if_then_else (match_operand:MODEF 3 "mult_operator")
14036               (const_string "fmul")
14037               (const_string "fop"))))
14038    (set_attr "isa" "*,noavx,avx")
14039    (set_attr "prefix" "orig,orig,vex")
14040    (set_attr "mode" "<MODE>")
14041    (set (attr "enabled")
14042      (if_then_else
14043        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14044        (if_then_else
14045          (eq_attr "alternative" "0")
14046          (symbol_ref "TARGET_MIX_SSE_I387
14047                       && X87_ENABLE_ARITH (<MODE>mode)")
14048          (const_string "*"))
14049        (if_then_else
14050          (eq_attr "alternative" "0")
14051          (symbol_ref "true")
14052          (symbol_ref "false"))))])
14054 (define_insn "*rcpsf2_sse"
14055   [(set (match_operand:SF 0 "register_operand" "=x")
14056         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14057                    UNSPEC_RCP))]
14058   "TARGET_SSE_MATH"
14059   "%vrcpss\t{%1, %d0|%d0, %1}"
14060   [(set_attr "type" "sse")
14061    (set_attr "atom_sse_attr" "rcp")
14062    (set_attr "btver2_sse_attr" "rcp")
14063    (set_attr "prefix" "maybe_vex")
14064    (set_attr "mode" "SF")])
14066 (define_insn "*fop_<mode>_1"
14067   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14068         (match_operator:MODEF 3 "binary_fp_operator"
14069           [(match_operand:MODEF 1
14070              "x87nonimm_ssenomem_operand" "0,fm,0,v")
14071            (match_operand:MODEF 2
14072              "nonimmediate_operand"       "fm,0,xm,vm")]))]
14073   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14074     || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14075    && !COMMUTATIVE_ARITH_P (operands[3])
14076    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14077   "* return output_387_binary_op (insn, operands);"
14078   [(set (attr "type")
14079         (if_then_else (eq_attr "alternative" "2,3")
14080            (if_then_else (match_operand:MODEF 3 "div_operator")
14081               (const_string "ssediv")
14082               (const_string "sseadd"))
14083            (if_then_else (match_operand:MODEF 3 "div_operator")
14084               (const_string "fdiv")
14085               (const_string "fop"))))
14086    (set_attr "isa" "*,*,noavx,avx")
14087    (set_attr "prefix" "orig,orig,orig,vex")
14088    (set_attr "mode" "<MODE>")
14089    (set (attr "enabled")
14090      (if_then_else
14091        (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14092        (if_then_else
14093          (eq_attr "alternative" "0,1")
14094          (symbol_ref "TARGET_MIX_SSE_I387
14095                       && X87_ENABLE_ARITH (<MODE>mode)")
14096          (const_string "*"))
14097        (if_then_else
14098          (eq_attr "alternative" "0,1")
14099          (symbol_ref "true")
14100          (symbol_ref "false"))))])
14102 ;; ??? Add SSE splitters for these!
14103 (define_insn "*fop_<MODEF:mode>_2_i387"
14104   [(set (match_operand:MODEF 0 "register_operand" "=f")
14105         (match_operator:MODEF 3 "binary_fp_operator"
14106           [(float:MODEF
14107              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14108            (match_operand:MODEF 2 "register_operand" "0")]))]
14109   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14110    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14111    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14112        || optimize_function_for_size_p (cfun))"
14113   "* return output_387_binary_op (insn, operands);"
14114   [(set (attr "type")
14115         (cond [(match_operand:MODEF 3 "mult_operator")
14116                  (const_string "fmul")
14117                (match_operand:MODEF 3 "div_operator")
14118                  (const_string "fdiv")
14119               ]
14120               (const_string "fop")))
14121    (set_attr "fp_int_src" "true")
14122    (set_attr "mode" "<SWI24:MODE>")])
14124 (define_insn "*fop_<MODEF:mode>_3_i387"
14125   [(set (match_operand:MODEF 0 "register_operand" "=f")
14126         (match_operator:MODEF 3 "binary_fp_operator"
14127           [(match_operand:MODEF 1 "register_operand" "0")
14128            (float:MODEF
14129              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14130   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14131    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14132    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14133        || optimize_function_for_size_p (cfun))"
14134   "* return output_387_binary_op (insn, operands);"
14135   [(set (attr "type")
14136         (cond [(match_operand:MODEF 3 "mult_operator")
14137                  (const_string "fmul")
14138                (match_operand:MODEF 3 "div_operator")
14139                  (const_string "fdiv")
14140               ]
14141               (const_string "fop")))
14142    (set_attr "fp_int_src" "true")
14143    (set_attr "mode" "<MODE>")])
14145 (define_insn "*fop_df_4_i387"
14146   [(set (match_operand:DF 0 "register_operand" "=f,f")
14147         (match_operator:DF 3 "binary_fp_operator"
14148            [(float_extend:DF
14149              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14150             (match_operand:DF 2 "register_operand" "0,f")]))]
14151   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14152    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14153   "* return output_387_binary_op (insn, operands);"
14154   [(set (attr "type")
14155         (cond [(match_operand:DF 3 "mult_operator")
14156                  (const_string "fmul")
14157                (match_operand:DF 3 "div_operator")
14158                  (const_string "fdiv")
14159               ]
14160               (const_string "fop")))
14161    (set_attr "mode" "SF")])
14163 (define_insn "*fop_df_5_i387"
14164   [(set (match_operand:DF 0 "register_operand" "=f,f")
14165         (match_operator:DF 3 "binary_fp_operator"
14166           [(match_operand:DF 1 "register_operand" "0,f")
14167            (float_extend:DF
14168             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14169   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14170    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14171   "* return output_387_binary_op (insn, operands);"
14172   [(set (attr "type")
14173         (cond [(match_operand:DF 3 "mult_operator")
14174                  (const_string "fmul")
14175                (match_operand:DF 3 "div_operator")
14176                  (const_string "fdiv")
14177               ]
14178               (const_string "fop")))
14179    (set_attr "mode" "SF")])
14181 (define_insn "*fop_df_6_i387"
14182   [(set (match_operand:DF 0 "register_operand" "=f,f")
14183         (match_operator:DF 3 "binary_fp_operator"
14184           [(float_extend:DF
14185             (match_operand:SF 1 "register_operand" "0,f"))
14186            (float_extend:DF
14187             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14188   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14189    && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14190   "* return output_387_binary_op (insn, operands);"
14191   [(set (attr "type")
14192         (cond [(match_operand:DF 3 "mult_operator")
14193                  (const_string "fmul")
14194                (match_operand:DF 3 "div_operator")
14195                  (const_string "fdiv")
14196               ]
14197               (const_string "fop")))
14198    (set_attr "mode" "SF")])
14200 (define_insn "*fop_xf_comm_i387"
14201   [(set (match_operand:XF 0 "register_operand" "=f")
14202         (match_operator:XF 3 "binary_fp_operator"
14203                         [(match_operand:XF 1 "register_operand" "%0")
14204                          (match_operand:XF 2 "register_operand" "f")]))]
14205   "TARGET_80387
14206    && COMMUTATIVE_ARITH_P (operands[3])"
14207   "* return output_387_binary_op (insn, operands);"
14208   [(set (attr "type")
14209         (if_then_else (match_operand:XF 3 "mult_operator")
14210            (const_string "fmul")
14211            (const_string "fop")))
14212    (set_attr "mode" "XF")])
14214 (define_insn "*fop_xf_1_i387"
14215   [(set (match_operand:XF 0 "register_operand" "=f,f")
14216         (match_operator:XF 3 "binary_fp_operator"
14217                         [(match_operand:XF 1 "register_operand" "0,f")
14218                          (match_operand:XF 2 "register_operand" "f,0")]))]
14219   "TARGET_80387
14220    && !COMMUTATIVE_ARITH_P (operands[3])"
14221   "* return output_387_binary_op (insn, operands);"
14222   [(set (attr "type")
14223         (if_then_else (match_operand:XF 3 "div_operator")
14224            (const_string "fdiv")
14225            (const_string "fop")))
14226    (set_attr "mode" "XF")])
14228 (define_insn "*fop_xf_2_i387"
14229   [(set (match_operand:XF 0 "register_operand" "=f")
14230         (match_operator:XF 3 "binary_fp_operator"
14231           [(float:XF
14232              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14233            (match_operand:XF 2 "register_operand" "0")]))]
14234   "TARGET_80387
14235    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14236   "* return output_387_binary_op (insn, operands);"
14237   [(set (attr "type")
14238         (cond [(match_operand:XF 3 "mult_operator")
14239                  (const_string "fmul")
14240                (match_operand:XF 3 "div_operator")
14241                  (const_string "fdiv")
14242               ]
14243               (const_string "fop")))
14244    (set_attr "fp_int_src" "true")
14245    (set_attr "mode" "<MODE>")])
14247 (define_insn "*fop_xf_3_i387"
14248   [(set (match_operand:XF 0 "register_operand" "=f")
14249         (match_operator:XF 3 "binary_fp_operator"
14250           [(match_operand:XF 1 "register_operand" "0")
14251            (float:XF
14252              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14253   "TARGET_80387
14254    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14255   "* return output_387_binary_op (insn, operands);"
14256   [(set (attr "type")
14257         (cond [(match_operand:XF 3 "mult_operator")
14258                  (const_string "fmul")
14259                (match_operand:XF 3 "div_operator")
14260                  (const_string "fdiv")
14261               ]
14262               (const_string "fop")))
14263    (set_attr "fp_int_src" "true")
14264    (set_attr "mode" "<MODE>")])
14266 (define_insn "*fop_xf_4_i387"
14267   [(set (match_operand:XF 0 "register_operand" "=f,f")
14268         (match_operator:XF 3 "binary_fp_operator"
14269            [(float_extend:XF
14270               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14271             (match_operand:XF 2 "register_operand" "0,f")]))]
14272   "TARGET_80387"
14273   "* return output_387_binary_op (insn, operands);"
14274   [(set (attr "type")
14275         (cond [(match_operand:XF 3 "mult_operator")
14276                  (const_string "fmul")
14277                (match_operand:XF 3 "div_operator")
14278                  (const_string "fdiv")
14279               ]
14280               (const_string "fop")))
14281    (set_attr "mode" "<MODE>")])
14283 (define_insn "*fop_xf_5_i387"
14284   [(set (match_operand:XF 0 "register_operand" "=f,f")
14285         (match_operator:XF 3 "binary_fp_operator"
14286           [(match_operand:XF 1 "register_operand" "0,f")
14287            (float_extend:XF
14288              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14289   "TARGET_80387"
14290   "* return output_387_binary_op (insn, operands);"
14291   [(set (attr "type")
14292         (cond [(match_operand:XF 3 "mult_operator")
14293                  (const_string "fmul")
14294                (match_operand:XF 3 "div_operator")
14295                  (const_string "fdiv")
14296               ]
14297               (const_string "fop")))
14298    (set_attr "mode" "<MODE>")])
14300 (define_insn "*fop_xf_6_i387"
14301   [(set (match_operand:XF 0 "register_operand" "=f,f")
14302         (match_operator:XF 3 "binary_fp_operator"
14303           [(float_extend:XF
14304              (match_operand:MODEF 1 "register_operand" "0,f"))
14305            (float_extend:XF
14306              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14307   "TARGET_80387"
14308   "* return output_387_binary_op (insn, operands);"
14309   [(set (attr "type")
14310         (cond [(match_operand:XF 3 "mult_operator")
14311                  (const_string "fmul")
14312                (match_operand:XF 3 "div_operator")
14313                  (const_string "fdiv")
14314               ]
14315               (const_string "fop")))
14316    (set_attr "mode" "<MODE>")])
14318 ;; FPU special functions.
14320 ;; This pattern implements a no-op XFmode truncation for
14321 ;; all fancy i386 XFmode math functions.
14323 (define_insn "truncxf<mode>2_i387_noop_unspec"
14324   [(set (match_operand:MODEF 0 "register_operand" "=f")
14325         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14326         UNSPEC_TRUNC_NOOP))]
14327   "TARGET_USE_FANCY_MATH_387"
14328   "* return output_387_reg_move (insn, operands);"
14329   [(set_attr "type" "fmov")
14330    (set_attr "mode" "<MODE>")])
14332 (define_insn "sqrtxf2"
14333   [(set (match_operand:XF 0 "register_operand" "=f")
14334         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14335   "TARGET_USE_FANCY_MATH_387"
14336   "fsqrt"
14337   [(set_attr "type" "fpspc")
14338    (set_attr "mode" "XF")
14339    (set_attr "athlon_decode" "direct")
14340    (set_attr "amdfam10_decode" "direct")
14341    (set_attr "bdver1_decode" "direct")])
14343 (define_insn "sqrt_extend<mode>xf2_i387"
14344   [(set (match_operand:XF 0 "register_operand" "=f")
14345         (sqrt:XF
14346           (float_extend:XF
14347             (match_operand:MODEF 1 "register_operand" "0"))))]
14348   "TARGET_USE_FANCY_MATH_387"
14349   "fsqrt"
14350   [(set_attr "type" "fpspc")
14351    (set_attr "mode" "XF")
14352    (set_attr "athlon_decode" "direct")
14353    (set_attr "amdfam10_decode" "direct")
14354    (set_attr "bdver1_decode" "direct")])
14356 (define_insn "*rsqrtsf2_sse"
14357   [(set (match_operand:SF 0 "register_operand" "=x")
14358         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14359                    UNSPEC_RSQRT))]
14360   "TARGET_SSE_MATH"
14361   "%vrsqrtss\t{%1, %d0|%d0, %1}"
14362   [(set_attr "type" "sse")
14363    (set_attr "atom_sse_attr" "rcp")
14364    (set_attr "btver2_sse_attr" "rcp")
14365    (set_attr "prefix" "maybe_vex")
14366    (set_attr "mode" "SF")])
14368 (define_expand "rsqrtsf2"
14369   [(set (match_operand:SF 0 "register_operand")
14370         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14371                    UNSPEC_RSQRT))]
14372   "TARGET_SSE_MATH"
14374   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14375   DONE;
14378 (define_insn "*sqrt<mode>2_sse"
14379   [(set (match_operand:MODEF 0 "register_operand" "=v")
14380         (sqrt:MODEF
14381           (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
14382   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14383   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14384   [(set_attr "type" "sse")
14385    (set_attr "atom_sse_attr" "sqrt")
14386    (set_attr "btver2_sse_attr" "sqrt")
14387    (set_attr "prefix" "maybe_vex")
14388    (set_attr "mode" "<MODE>")
14389    (set_attr "athlon_decode" "*")
14390    (set_attr "amdfam10_decode" "*")
14391    (set_attr "bdver1_decode" "*")])
14393 (define_expand "sqrt<mode>2"
14394   [(set (match_operand:MODEF 0 "register_operand")
14395         (sqrt:MODEF
14396           (match_operand:MODEF 1 "nonimmediate_operand")))]
14397   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14398    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14400   if (<MODE>mode == SFmode
14401       && TARGET_SSE_MATH
14402       && TARGET_RECIP_SQRT
14403       && !optimize_function_for_size_p (cfun)
14404       && flag_finite_math_only && !flag_trapping_math
14405       && flag_unsafe_math_optimizations)
14406     {
14407       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14408       DONE;
14409     }
14411   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14412     {
14413       rtx op0 = gen_reg_rtx (XFmode);
14414       rtx op1 = force_reg (<MODE>mode, operands[1]);
14416       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
14417       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14418       DONE;
14419    }
14422 (define_insn "fpremxf4_i387"
14423   [(set (match_operand:XF 0 "register_operand" "=f")
14424         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14425                     (match_operand:XF 3 "register_operand" "1")]
14426                    UNSPEC_FPREM_F))
14427    (set (match_operand:XF 1 "register_operand" "=u")
14428         (unspec:XF [(match_dup 2) (match_dup 3)]
14429                    UNSPEC_FPREM_U))
14430    (set (reg:CCFP FPSR_REG)
14431         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14432                      UNSPEC_C2_FLAG))]
14433   "TARGET_USE_FANCY_MATH_387
14434    && flag_finite_math_only"
14435   "fprem"
14436   [(set_attr "type" "fpspc")
14437    (set_attr "znver1_decode" "vector")
14438    (set_attr "mode" "XF")])
14440 (define_expand "fmodxf3"
14441   [(use (match_operand:XF 0 "register_operand"))
14442    (use (match_operand:XF 1 "general_operand"))
14443    (use (match_operand:XF 2 "general_operand"))]
14444   "TARGET_USE_FANCY_MATH_387
14445    && flag_finite_math_only"
14447   rtx_code_label *label = gen_label_rtx ();
14449   rtx op1 = gen_reg_rtx (XFmode);
14450   rtx op2 = gen_reg_rtx (XFmode);
14452   emit_move_insn (op2, operands[2]);
14453   emit_move_insn (op1, operands[1]);
14455   emit_label (label);
14456   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14457   ix86_emit_fp_unordered_jump (label);
14458   LABEL_NUSES (label) = 1;
14460   emit_move_insn (operands[0], op1);
14461   DONE;
14464 (define_expand "fmod<mode>3"
14465   [(use (match_operand:MODEF 0 "register_operand"))
14466    (use (match_operand:MODEF 1 "general_operand"))
14467    (use (match_operand:MODEF 2 "general_operand"))]
14468   "TARGET_USE_FANCY_MATH_387
14469    && flag_finite_math_only"
14471   rtx (*gen_truncxf) (rtx, rtx);
14473   rtx_code_label *label = gen_label_rtx ();
14475   rtx op1 = gen_reg_rtx (XFmode);
14476   rtx op2 = gen_reg_rtx (XFmode);
14478   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14479   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14481   emit_label (label);
14482   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14483   ix86_emit_fp_unordered_jump (label);
14484   LABEL_NUSES (label) = 1;
14486   /* Truncate the result properly for strict SSE math.  */
14487   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14488       && !TARGET_MIX_SSE_I387)
14489     gen_truncxf = gen_truncxf<mode>2;
14490   else
14491     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14493   emit_insn (gen_truncxf (operands[0], op1));
14494   DONE;
14497 (define_insn "fprem1xf4_i387"
14498   [(set (match_operand:XF 0 "register_operand" "=f")
14499         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14500                     (match_operand:XF 3 "register_operand" "1")]
14501                    UNSPEC_FPREM1_F))
14502    (set (match_operand:XF 1 "register_operand" "=u")
14503         (unspec:XF [(match_dup 2) (match_dup 3)]
14504                    UNSPEC_FPREM1_U))
14505    (set (reg:CCFP FPSR_REG)
14506         (unspec:CCFP [(match_dup 2) (match_dup 3)]
14507                      UNSPEC_C2_FLAG))]
14508   "TARGET_USE_FANCY_MATH_387
14509    && flag_finite_math_only"
14510   "fprem1"
14511   [(set_attr "type" "fpspc")
14512    (set_attr "znver1_decode" "vector")
14513    (set_attr "mode" "XF")])
14515 (define_expand "remainderxf3"
14516   [(use (match_operand:XF 0 "register_operand"))
14517    (use (match_operand:XF 1 "general_operand"))
14518    (use (match_operand:XF 2 "general_operand"))]
14519   "TARGET_USE_FANCY_MATH_387
14520    && flag_finite_math_only"
14522   rtx_code_label *label = gen_label_rtx ();
14524   rtx op1 = gen_reg_rtx (XFmode);
14525   rtx op2 = gen_reg_rtx (XFmode);
14527   emit_move_insn (op2, operands[2]);
14528   emit_move_insn (op1, operands[1]);
14530   emit_label (label);
14531   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14532   ix86_emit_fp_unordered_jump (label);
14533   LABEL_NUSES (label) = 1;
14535   emit_move_insn (operands[0], op1);
14536   DONE;
14539 (define_expand "remainder<mode>3"
14540   [(use (match_operand:MODEF 0 "register_operand"))
14541    (use (match_operand:MODEF 1 "general_operand"))
14542    (use (match_operand:MODEF 2 "general_operand"))]
14543   "TARGET_USE_FANCY_MATH_387
14544    && flag_finite_math_only"
14546   rtx (*gen_truncxf) (rtx, rtx);
14548   rtx_code_label *label = gen_label_rtx ();
14550   rtx op1 = gen_reg_rtx (XFmode);
14551   rtx op2 = gen_reg_rtx (XFmode);
14553   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14554   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14556   emit_label (label);
14558   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
14559   ix86_emit_fp_unordered_jump (label);
14560   LABEL_NUSES (label) = 1;
14562   /* Truncate the result properly for strict SSE math.  */
14563   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14564       && !TARGET_MIX_SSE_I387)
14565     gen_truncxf = gen_truncxf<mode>2;
14566   else
14567     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
14569   emit_insn (gen_truncxf (operands[0], op1));
14570   DONE;
14573 (define_int_iterator SINCOS
14574         [UNSPEC_SIN
14575          UNSPEC_COS])
14577 (define_int_attr sincos
14578         [(UNSPEC_SIN "sin")
14579          (UNSPEC_COS "cos")])
14581 (define_insn "*<sincos>xf2_i387"
14582   [(set (match_operand:XF 0 "register_operand" "=f")
14583         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14584                    SINCOS))]
14585   "TARGET_USE_FANCY_MATH_387
14586    && flag_unsafe_math_optimizations"
14587   "f<sincos>"
14588   [(set_attr "type" "fpspc")
14589    (set_attr "znver1_decode" "vector")
14590    (set_attr "mode" "XF")])
14592 (define_insn "*<sincos>_extend<mode>xf2_i387"
14593   [(set (match_operand:XF 0 "register_operand" "=f")
14594         (unspec:XF [(float_extend:XF
14595                       (match_operand:MODEF 1 "register_operand" "0"))]
14596                    SINCOS))]
14597   "TARGET_USE_FANCY_MATH_387
14598    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14599        || TARGET_MIX_SSE_I387)
14600    && flag_unsafe_math_optimizations"
14601   "f<sincos>"
14602   [(set_attr "type" "fpspc")
14603    (set_attr "znver1_decode" "vector")
14604    (set_attr "mode" "XF")])
14606 ;; When sincos pattern is defined, sin and cos builtin functions will be
14607 ;; expanded to sincos pattern with one of its outputs left unused.
14608 ;; CSE pass will figure out if two sincos patterns can be combined,
14609 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14610 ;; depending on the unused output.
14612 (define_insn "sincosxf3"
14613   [(set (match_operand:XF 0 "register_operand" "=f")
14614         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14615                    UNSPEC_SINCOS_COS))
14616    (set (match_operand:XF 1 "register_operand" "=u")
14617         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14618   "TARGET_USE_FANCY_MATH_387
14619    && flag_unsafe_math_optimizations"
14620   "fsincos"
14621   [(set_attr "type" "fpspc")
14622    (set_attr "znver1_decode" "vector")
14623    (set_attr "mode" "XF")])
14625 (define_split
14626   [(set (match_operand:XF 0 "register_operand")
14627         (unspec:XF [(match_operand:XF 2 "register_operand")]
14628                    UNSPEC_SINCOS_COS))
14629    (set (match_operand:XF 1 "register_operand")
14630         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14631   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14632    && can_create_pseudo_p ()"
14633   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14635 (define_split
14636   [(set (match_operand:XF 0 "register_operand")
14637         (unspec:XF [(match_operand:XF 2 "register_operand")]
14638                    UNSPEC_SINCOS_COS))
14639    (set (match_operand:XF 1 "register_operand")
14640         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14641   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14642    && can_create_pseudo_p ()"
14643   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14645 (define_insn "sincos_extend<mode>xf3_i387"
14646   [(set (match_operand:XF 0 "register_operand" "=f")
14647         (unspec:XF [(float_extend:XF
14648                       (match_operand:MODEF 2 "register_operand" "0"))]
14649                    UNSPEC_SINCOS_COS))
14650    (set (match_operand:XF 1 "register_operand" "=u")
14651         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14652   "TARGET_USE_FANCY_MATH_387
14653    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14654        || TARGET_MIX_SSE_I387)
14655    && flag_unsafe_math_optimizations"
14656   "fsincos"
14657   [(set_attr "type" "fpspc")
14658    (set_attr "znver1_decode" "vector")
14659    (set_attr "mode" "XF")])
14661 (define_split
14662   [(set (match_operand:XF 0 "register_operand")
14663         (unspec:XF [(float_extend:XF
14664                       (match_operand:MODEF 2 "register_operand"))]
14665                    UNSPEC_SINCOS_COS))
14666    (set (match_operand:XF 1 "register_operand")
14667         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14668   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14669    && can_create_pseudo_p ()"
14670   [(set (match_dup 1)
14671         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14673 (define_split
14674   [(set (match_operand:XF 0 "register_operand")
14675         (unspec:XF [(float_extend:XF
14676                       (match_operand:MODEF 2 "register_operand"))]
14677                    UNSPEC_SINCOS_COS))
14678    (set (match_operand:XF 1 "register_operand")
14679         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14680   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14681    && can_create_pseudo_p ()"
14682   [(set (match_dup 0)
14683         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14685 (define_expand "sincos<mode>3"
14686   [(use (match_operand:MODEF 0 "register_operand"))
14687    (use (match_operand:MODEF 1 "register_operand"))
14688    (use (match_operand:MODEF 2 "register_operand"))]
14689   "TARGET_USE_FANCY_MATH_387
14690    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14691        || TARGET_MIX_SSE_I387)
14692    && flag_unsafe_math_optimizations"
14694   rtx op0 = gen_reg_rtx (XFmode);
14695   rtx op1 = gen_reg_rtx (XFmode);
14697   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14698   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14699   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14700   DONE;
14703 (define_insn "fptanxf4_i387"
14704   [(set (match_operand:XF 0 "register_operand" "=f")
14705         (match_operand:XF 3 "const_double_operand" "F"))
14706    (set (match_operand:XF 1 "register_operand" "=u")
14707         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14708                    UNSPEC_TAN))]
14709   "TARGET_USE_FANCY_MATH_387
14710    && flag_unsafe_math_optimizations
14711    && standard_80387_constant_p (operands[3]) == 2"
14712   "fptan"
14713   [(set_attr "type" "fpspc")
14714    (set_attr "znver1_decode" "vector")
14715    (set_attr "mode" "XF")])
14717 (define_insn "fptan_extend<mode>xf4_i387"
14718   [(set (match_operand:MODEF 0 "register_operand" "=f")
14719         (match_operand:MODEF 3 "const_double_operand" "F"))
14720    (set (match_operand:XF 1 "register_operand" "=u")
14721         (unspec:XF [(float_extend:XF
14722                       (match_operand:MODEF 2 "register_operand" "0"))]
14723                    UNSPEC_TAN))]
14724   "TARGET_USE_FANCY_MATH_387
14725    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14726        || TARGET_MIX_SSE_I387)
14727    && flag_unsafe_math_optimizations
14728    && standard_80387_constant_p (operands[3]) == 2"
14729   "fptan"
14730   [(set_attr "type" "fpspc")
14731    (set_attr "znver1_decode" "vector")
14732    (set_attr "mode" "XF")])
14734 (define_expand "tanxf2"
14735   [(use (match_operand:XF 0 "register_operand"))
14736    (use (match_operand:XF 1 "register_operand"))]
14737   "TARGET_USE_FANCY_MATH_387
14738    && flag_unsafe_math_optimizations"
14740   rtx one = gen_reg_rtx (XFmode);
14741   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14743   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14744   DONE;
14747 (define_expand "tan<mode>2"
14748   [(use (match_operand:MODEF 0 "register_operand"))
14749    (use (match_operand:MODEF 1 "register_operand"))]
14750   "TARGET_USE_FANCY_MATH_387
14751    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14752        || TARGET_MIX_SSE_I387)
14753    && flag_unsafe_math_optimizations"
14755   rtx op0 = gen_reg_rtx (XFmode);
14757   rtx one = gen_reg_rtx (<MODE>mode);
14758   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14760   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14761                                              operands[1], op2));
14762   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14763   DONE;
14766 (define_insn "*fpatanxf3_i387"
14767   [(set (match_operand:XF 0 "register_operand" "=f")
14768         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14769                     (match_operand:XF 2 "register_operand" "u")]
14770                    UNSPEC_FPATAN))
14771    (clobber (match_scratch:XF 3 "=2"))]
14772   "TARGET_USE_FANCY_MATH_387
14773    && flag_unsafe_math_optimizations"
14774   "fpatan"
14775   [(set_attr "type" "fpspc")
14776    (set_attr "znver1_decode" "vector")
14777    (set_attr "mode" "XF")])
14779 (define_insn "fpatan_extend<mode>xf3_i387"
14780   [(set (match_operand:XF 0 "register_operand" "=f")
14781         (unspec:XF [(float_extend:XF
14782                       (match_operand:MODEF 1 "register_operand" "0"))
14783                     (float_extend:XF
14784                       (match_operand:MODEF 2 "register_operand" "u"))]
14785                    UNSPEC_FPATAN))
14786    (clobber (match_scratch:XF 3 "=2"))]
14787   "TARGET_USE_FANCY_MATH_387
14788    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14789        || TARGET_MIX_SSE_I387)
14790    && flag_unsafe_math_optimizations"
14791   "fpatan"
14792   [(set_attr "type" "fpspc")
14793    (set_attr "znver1_decode" "vector")
14794    (set_attr "mode" "XF")])
14796 (define_expand "atan2xf3"
14797   [(parallel [(set (match_operand:XF 0 "register_operand")
14798                    (unspec:XF [(match_operand:XF 2 "register_operand")
14799                                (match_operand:XF 1 "register_operand")]
14800                               UNSPEC_FPATAN))
14801               (clobber (match_scratch:XF 3))])]
14802   "TARGET_USE_FANCY_MATH_387
14803    && flag_unsafe_math_optimizations")
14805 (define_expand "atan2<mode>3"
14806   [(use (match_operand:MODEF 0 "register_operand"))
14807    (use (match_operand:MODEF 1 "register_operand"))
14808    (use (match_operand:MODEF 2 "register_operand"))]
14809   "TARGET_USE_FANCY_MATH_387
14810    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14811        || TARGET_MIX_SSE_I387)
14812    && flag_unsafe_math_optimizations"
14814   rtx op0 = gen_reg_rtx (XFmode);
14816   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14817   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14818   DONE;
14821 (define_expand "atanxf2"
14822   [(parallel [(set (match_operand:XF 0 "register_operand")
14823                    (unspec:XF [(match_dup 2)
14824                                (match_operand:XF 1 "register_operand")]
14825                               UNSPEC_FPATAN))
14826               (clobber (match_scratch:XF 3))])]
14827   "TARGET_USE_FANCY_MATH_387
14828    && flag_unsafe_math_optimizations"
14830   operands[2] = gen_reg_rtx (XFmode);
14831   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14834 (define_expand "atan<mode>2"
14835   [(use (match_operand:MODEF 0 "register_operand"))
14836    (use (match_operand:MODEF 1 "register_operand"))]
14837   "TARGET_USE_FANCY_MATH_387
14838    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14839        || TARGET_MIX_SSE_I387)
14840    && flag_unsafe_math_optimizations"
14842   rtx op0 = gen_reg_rtx (XFmode);
14844   rtx op2 = gen_reg_rtx (<MODE>mode);
14845   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14847   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14848   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14849   DONE;
14852 (define_expand "asinxf2"
14853   [(set (match_dup 2)
14854         (mult:XF (match_operand:XF 1 "register_operand")
14855                  (match_dup 1)))
14856    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14857    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14858    (parallel [(set (match_operand:XF 0 "register_operand")
14859                    (unspec:XF [(match_dup 5) (match_dup 1)]
14860                               UNSPEC_FPATAN))
14861               (clobber (match_scratch:XF 6))])]
14862   "TARGET_USE_FANCY_MATH_387
14863    && flag_unsafe_math_optimizations"
14865   int i;
14867   for (i = 2; i < 6; i++)
14868     operands[i] = gen_reg_rtx (XFmode);
14870   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14873 (define_expand "asin<mode>2"
14874   [(use (match_operand:MODEF 0 "register_operand"))
14875    (use (match_operand:MODEF 1 "general_operand"))]
14876   "TARGET_USE_FANCY_MATH_387
14877    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878        || TARGET_MIX_SSE_I387)
14879    && flag_unsafe_math_optimizations"
14881   rtx op0 = gen_reg_rtx (XFmode);
14882   rtx op1 = gen_reg_rtx (XFmode);
14884   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14885   emit_insn (gen_asinxf2 (op0, op1));
14886   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14887   DONE;
14890 (define_expand "acosxf2"
14891   [(set (match_dup 2)
14892         (mult:XF (match_operand:XF 1 "register_operand")
14893                  (match_dup 1)))
14894    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14895    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14896    (parallel [(set (match_operand:XF 0 "register_operand")
14897                    (unspec:XF [(match_dup 1) (match_dup 5)]
14898                               UNSPEC_FPATAN))
14899               (clobber (match_scratch:XF 6))])]
14900   "TARGET_USE_FANCY_MATH_387
14901    && flag_unsafe_math_optimizations"
14903   int i;
14905   for (i = 2; i < 6; i++)
14906     operands[i] = gen_reg_rtx (XFmode);
14908   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14911 (define_expand "acos<mode>2"
14912   [(use (match_operand:MODEF 0 "register_operand"))
14913    (use (match_operand:MODEF 1 "general_operand"))]
14914   "TARGET_USE_FANCY_MATH_387
14915    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14916        || TARGET_MIX_SSE_I387)
14917    && flag_unsafe_math_optimizations"
14919   rtx op0 = gen_reg_rtx (XFmode);
14920   rtx op1 = gen_reg_rtx (XFmode);
14922   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14923   emit_insn (gen_acosxf2 (op0, op1));
14924   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14925   DONE;
14928 (define_insn "fyl2xxf3_i387"
14929   [(set (match_operand:XF 0 "register_operand" "=f")
14930         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14931                     (match_operand:XF 2 "register_operand" "u")]
14932                    UNSPEC_FYL2X))
14933    (clobber (match_scratch:XF 3 "=2"))]
14934   "TARGET_USE_FANCY_MATH_387
14935    && flag_unsafe_math_optimizations"
14936   "fyl2x"
14937   [(set_attr "type" "fpspc")
14938    (set_attr "znver1_decode" "vector")
14939    (set_attr "mode" "XF")])
14941 (define_insn "fyl2x_extend<mode>xf3_i387"
14942   [(set (match_operand:XF 0 "register_operand" "=f")
14943         (unspec:XF [(float_extend:XF
14944                       (match_operand:MODEF 1 "register_operand" "0"))
14945                     (match_operand:XF 2 "register_operand" "u")]
14946                    UNSPEC_FYL2X))
14947    (clobber (match_scratch:XF 3 "=2"))]
14948   "TARGET_USE_FANCY_MATH_387
14949    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14950        || TARGET_MIX_SSE_I387)
14951    && flag_unsafe_math_optimizations"
14952   "fyl2x"
14953   [(set_attr "type" "fpspc")
14954    (set_attr "znver1_decode" "vector")
14955    (set_attr "mode" "XF")])
14957 (define_expand "logxf2"
14958   [(parallel [(set (match_operand:XF 0 "register_operand")
14959                    (unspec:XF [(match_operand:XF 1 "register_operand")
14960                                (match_dup 2)] UNSPEC_FYL2X))
14961               (clobber (match_scratch:XF 3))])]
14962   "TARGET_USE_FANCY_MATH_387
14963    && flag_unsafe_math_optimizations"
14965   operands[2] = gen_reg_rtx (XFmode);
14966   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14969 (define_expand "log<mode>2"
14970   [(use (match_operand:MODEF 0 "register_operand"))
14971    (use (match_operand:MODEF 1 "register_operand"))]
14972   "TARGET_USE_FANCY_MATH_387
14973    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14974        || TARGET_MIX_SSE_I387)
14975    && flag_unsafe_math_optimizations"
14977   rtx op0 = gen_reg_rtx (XFmode);
14979   rtx op2 = gen_reg_rtx (XFmode);
14980   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14982   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14983   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14984   DONE;
14987 (define_expand "log10xf2"
14988   [(parallel [(set (match_operand:XF 0 "register_operand")
14989                    (unspec:XF [(match_operand:XF 1 "register_operand")
14990                                (match_dup 2)] UNSPEC_FYL2X))
14991               (clobber (match_scratch:XF 3))])]
14992   "TARGET_USE_FANCY_MATH_387
14993    && flag_unsafe_math_optimizations"
14995   operands[2] = gen_reg_rtx (XFmode);
14996   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14999 (define_expand "log10<mode>2"
15000   [(use (match_operand:MODEF 0 "register_operand"))
15001    (use (match_operand:MODEF 1 "register_operand"))]
15002   "TARGET_USE_FANCY_MATH_387
15003    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15004        || TARGET_MIX_SSE_I387)
15005    && flag_unsafe_math_optimizations"
15007   rtx op0 = gen_reg_rtx (XFmode);
15009   rtx op2 = gen_reg_rtx (XFmode);
15010   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15012   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15013   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15014   DONE;
15017 (define_expand "log2xf2"
15018   [(parallel [(set (match_operand:XF 0 "register_operand")
15019                    (unspec:XF [(match_operand:XF 1 "register_operand")
15020                                (match_dup 2)] UNSPEC_FYL2X))
15021               (clobber (match_scratch:XF 3))])]
15022   "TARGET_USE_FANCY_MATH_387
15023    && flag_unsafe_math_optimizations"
15025   operands[2] = gen_reg_rtx (XFmode);
15026   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15029 (define_expand "log2<mode>2"
15030   [(use (match_operand:MODEF 0 "register_operand"))
15031    (use (match_operand:MODEF 1 "register_operand"))]
15032   "TARGET_USE_FANCY_MATH_387
15033    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15034        || TARGET_MIX_SSE_I387)
15035    && flag_unsafe_math_optimizations"
15037   rtx op0 = gen_reg_rtx (XFmode);
15039   rtx op2 = gen_reg_rtx (XFmode);
15040   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15042   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15043   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15044   DONE;
15047 (define_insn "fyl2xp1xf3_i387"
15048   [(set (match_operand:XF 0 "register_operand" "=f")
15049         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15050                     (match_operand:XF 2 "register_operand" "u")]
15051                    UNSPEC_FYL2XP1))
15052    (clobber (match_scratch:XF 3 "=2"))]
15053   "TARGET_USE_FANCY_MATH_387
15054    && flag_unsafe_math_optimizations"
15055   "fyl2xp1"
15056   [(set_attr "type" "fpspc")
15057    (set_attr "znver1_decode" "vector")
15058    (set_attr "mode" "XF")])
15060 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15061   [(set (match_operand:XF 0 "register_operand" "=f")
15062         (unspec:XF [(float_extend:XF
15063                       (match_operand:MODEF 1 "register_operand" "0"))
15064                     (match_operand:XF 2 "register_operand" "u")]
15065                    UNSPEC_FYL2XP1))
15066    (clobber (match_scratch:XF 3 "=2"))]
15067   "TARGET_USE_FANCY_MATH_387
15068    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15069        || TARGET_MIX_SSE_I387)
15070    && flag_unsafe_math_optimizations"
15071   "fyl2xp1"
15072   [(set_attr "type" "fpspc")
15073    (set_attr "znver1_decode" "vector")
15074    (set_attr "mode" "XF")])
15076 (define_expand "log1pxf2"
15077   [(use (match_operand:XF 0 "register_operand"))
15078    (use (match_operand:XF 1 "register_operand"))]
15079   "TARGET_USE_FANCY_MATH_387
15080    && flag_unsafe_math_optimizations"
15082   ix86_emit_i387_log1p (operands[0], operands[1]);
15083   DONE;
15086 (define_expand "log1p<mode>2"
15087   [(use (match_operand:MODEF 0 "register_operand"))
15088    (use (match_operand:MODEF 1 "register_operand"))]
15089   "TARGET_USE_FANCY_MATH_387
15090    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15091        || TARGET_MIX_SSE_I387)
15092    && flag_unsafe_math_optimizations"
15094   rtx op0;
15096   op0 = gen_reg_rtx (XFmode);
15098   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15100   ix86_emit_i387_log1p (op0, operands[1]);
15101   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15102   DONE;
15105 (define_insn "fxtractxf3_i387"
15106   [(set (match_operand:XF 0 "register_operand" "=f")
15107         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15108                    UNSPEC_XTRACT_FRACT))
15109    (set (match_operand:XF 1 "register_operand" "=u")
15110         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15111   "TARGET_USE_FANCY_MATH_387
15112    && flag_unsafe_math_optimizations"
15113   "fxtract"
15114   [(set_attr "type" "fpspc")
15115    (set_attr "znver1_decode" "vector")
15116    (set_attr "mode" "XF")])
15118 (define_insn "fxtract_extend<mode>xf3_i387"
15119   [(set (match_operand:XF 0 "register_operand" "=f")
15120         (unspec:XF [(float_extend:XF
15121                       (match_operand:MODEF 2 "register_operand" "0"))]
15122                    UNSPEC_XTRACT_FRACT))
15123    (set (match_operand:XF 1 "register_operand" "=u")
15124         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15125   "TARGET_USE_FANCY_MATH_387
15126    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15127        || TARGET_MIX_SSE_I387)
15128    && flag_unsafe_math_optimizations"
15129   "fxtract"
15130   [(set_attr "type" "fpspc")
15131    (set_attr "znver1_decode" "vector")
15132    (set_attr "mode" "XF")])
15134 (define_expand "logbxf2"
15135   [(parallel [(set (match_dup 2)
15136                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15137                               UNSPEC_XTRACT_FRACT))
15138               (set (match_operand:XF 0 "register_operand")
15139                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15140   "TARGET_USE_FANCY_MATH_387
15141    && flag_unsafe_math_optimizations"
15142   "operands[2] = gen_reg_rtx (XFmode);")
15144 (define_expand "logb<mode>2"
15145   [(use (match_operand:MODEF 0 "register_operand"))
15146    (use (match_operand:MODEF 1 "register_operand"))]
15147   "TARGET_USE_FANCY_MATH_387
15148    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15149        || TARGET_MIX_SSE_I387)
15150    && flag_unsafe_math_optimizations"
15152   rtx op0 = gen_reg_rtx (XFmode);
15153   rtx op1 = gen_reg_rtx (XFmode);
15155   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15156   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15157   DONE;
15160 (define_expand "ilogbxf2"
15161   [(use (match_operand:SI 0 "register_operand"))
15162    (use (match_operand:XF 1 "register_operand"))]
15163   "TARGET_USE_FANCY_MATH_387
15164    && flag_unsafe_math_optimizations"
15166   rtx op0, op1;
15168   if (optimize_insn_for_size_p ())
15169     FAIL;
15171   op0 = gen_reg_rtx (XFmode);
15172   op1 = gen_reg_rtx (XFmode);
15174   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15175   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15176   DONE;
15179 (define_expand "ilogb<mode>2"
15180   [(use (match_operand:SI 0 "register_operand"))
15181    (use (match_operand:MODEF 1 "register_operand"))]
15182   "TARGET_USE_FANCY_MATH_387
15183    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15184        || TARGET_MIX_SSE_I387)
15185    && flag_unsafe_math_optimizations"
15187   rtx op0, op1;
15189   if (optimize_insn_for_size_p ())
15190     FAIL;
15192   op0 = gen_reg_rtx (XFmode);
15193   op1 = gen_reg_rtx (XFmode);
15195   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15196   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15197   DONE;
15200 (define_insn "*f2xm1xf2_i387"
15201   [(set (match_operand:XF 0 "register_operand" "=f")
15202         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15203                    UNSPEC_F2XM1))]
15204   "TARGET_USE_FANCY_MATH_387
15205    && flag_unsafe_math_optimizations"
15206   "f2xm1"
15207   [(set_attr "type" "fpspc")
15208    (set_attr "znver1_decode" "vector")
15209    (set_attr "mode" "XF")])
15211 (define_insn "fscalexf4_i387"
15212   [(set (match_operand:XF 0 "register_operand" "=f")
15213         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15214                     (match_operand:XF 3 "register_operand" "1")]
15215                    UNSPEC_FSCALE_FRACT))
15216    (set (match_operand:XF 1 "register_operand" "=u")
15217         (unspec:XF [(match_dup 2) (match_dup 3)]
15218                    UNSPEC_FSCALE_EXP))]
15219   "TARGET_USE_FANCY_MATH_387
15220    && flag_unsafe_math_optimizations"
15221   "fscale"
15222   [(set_attr "type" "fpspc")
15223    (set_attr "znver1_decode" "vector")
15224    (set_attr "mode" "XF")])
15226 (define_expand "expNcorexf3"
15227   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15228                                (match_operand:XF 2 "register_operand")))
15229    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15230    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15231    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15232    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15233    (parallel [(set (match_operand:XF 0 "register_operand")
15234                    (unspec:XF [(match_dup 8) (match_dup 4)]
15235                               UNSPEC_FSCALE_FRACT))
15236               (set (match_dup 9)
15237                    (unspec:XF [(match_dup 8) (match_dup 4)]
15238                               UNSPEC_FSCALE_EXP))])]
15239   "TARGET_USE_FANCY_MATH_387
15240    && flag_unsafe_math_optimizations"
15242   int i;
15244   for (i = 3; i < 10; i++)
15245     operands[i] = gen_reg_rtx (XFmode);
15247   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
15250 (define_expand "expxf2"
15251   [(use (match_operand:XF 0 "register_operand"))
15252    (use (match_operand:XF 1 "register_operand"))]
15253   "TARGET_USE_FANCY_MATH_387
15254    && flag_unsafe_math_optimizations"
15256   rtx op2;
15258   op2 = gen_reg_rtx (XFmode);
15259   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15261   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15262   DONE;
15265 (define_expand "exp<mode>2"
15266   [(use (match_operand:MODEF 0 "register_operand"))
15267    (use (match_operand:MODEF 1 "general_operand"))]
15268   "TARGET_USE_FANCY_MATH_387
15269    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15270        || TARGET_MIX_SSE_I387)
15271    && flag_unsafe_math_optimizations"
15273   rtx op0, op1;
15275   op0 = gen_reg_rtx (XFmode);
15276   op1 = gen_reg_rtx (XFmode);
15278   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15279   emit_insn (gen_expxf2 (op0, op1));
15280   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15281   DONE;
15284 (define_expand "exp10xf2"
15285   [(use (match_operand:XF 0 "register_operand"))
15286    (use (match_operand:XF 1 "register_operand"))]
15287   "TARGET_USE_FANCY_MATH_387
15288    && flag_unsafe_math_optimizations"
15290   rtx op2;
15292   op2 = gen_reg_rtx (XFmode);
15293   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15295   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15296   DONE;
15299 (define_expand "exp10<mode>2"
15300   [(use (match_operand:MODEF 0 "register_operand"))
15301    (use (match_operand:MODEF 1 "general_operand"))]
15302   "TARGET_USE_FANCY_MATH_387
15303    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15304        || TARGET_MIX_SSE_I387)
15305    && flag_unsafe_math_optimizations"
15307   rtx op0, op1;
15309   op0 = gen_reg_rtx (XFmode);
15310   op1 = gen_reg_rtx (XFmode);
15312   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15313   emit_insn (gen_exp10xf2 (op0, op1));
15314   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15315   DONE;
15318 (define_expand "exp2xf2"
15319   [(use (match_operand:XF 0 "register_operand"))
15320    (use (match_operand:XF 1 "register_operand"))]
15321   "TARGET_USE_FANCY_MATH_387
15322    && flag_unsafe_math_optimizations"
15324   rtx op2;
15326   op2 = gen_reg_rtx (XFmode);
15327   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
15329   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15330   DONE;
15333 (define_expand "exp2<mode>2"
15334   [(use (match_operand:MODEF 0 "register_operand"))
15335    (use (match_operand:MODEF 1 "general_operand"))]
15336   "TARGET_USE_FANCY_MATH_387
15337    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15338        || TARGET_MIX_SSE_I387)
15339    && flag_unsafe_math_optimizations"
15341   rtx op0, op1;
15343   op0 = gen_reg_rtx (XFmode);
15344   op1 = gen_reg_rtx (XFmode);
15346   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15347   emit_insn (gen_exp2xf2 (op0, op1));
15348   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15349   DONE;
15352 (define_expand "expm1xf2"
15353   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15354                                (match_dup 2)))
15355    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15356    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15357    (set (match_dup 9) (float_extend:XF (match_dup 13)))
15358    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15359    (parallel [(set (match_dup 7)
15360                    (unspec:XF [(match_dup 6) (match_dup 4)]
15361                               UNSPEC_FSCALE_FRACT))
15362               (set (match_dup 8)
15363                    (unspec:XF [(match_dup 6) (match_dup 4)]
15364                               UNSPEC_FSCALE_EXP))])
15365    (parallel [(set (match_dup 10)
15366                    (unspec:XF [(match_dup 9) (match_dup 8)]
15367                               UNSPEC_FSCALE_FRACT))
15368               (set (match_dup 11)
15369                    (unspec:XF [(match_dup 9) (match_dup 8)]
15370                               UNSPEC_FSCALE_EXP))])
15371    (set (match_dup 12) (minus:XF (match_dup 10)
15372                                  (float_extend:XF (match_dup 13))))
15373    (set (match_operand:XF 0 "register_operand")
15374         (plus:XF (match_dup 12) (match_dup 7)))]
15375   "TARGET_USE_FANCY_MATH_387
15376    && flag_unsafe_math_optimizations"
15378   int i;
15380   for (i = 2; i < 13; i++)
15381     operands[i] = gen_reg_rtx (XFmode);
15383   operands[13]
15384     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
15386   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15389 (define_expand "expm1<mode>2"
15390   [(use (match_operand:MODEF 0 "register_operand"))
15391    (use (match_operand:MODEF 1 "general_operand"))]
15392   "TARGET_USE_FANCY_MATH_387
15393    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15394        || TARGET_MIX_SSE_I387)
15395    && flag_unsafe_math_optimizations"
15397   rtx op0, op1;
15399   op0 = gen_reg_rtx (XFmode);
15400   op1 = gen_reg_rtx (XFmode);
15402   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15403   emit_insn (gen_expm1xf2 (op0, op1));
15404   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15405   DONE;
15408 (define_expand "ldexpxf3"
15409   [(match_operand:XF 0 "register_operand")
15410    (match_operand:XF 1 "register_operand")
15411    (match_operand:SI 2 "register_operand")]
15412   "TARGET_USE_FANCY_MATH_387
15413    && flag_unsafe_math_optimizations"
15415   rtx tmp1, tmp2;
15417   tmp1 = gen_reg_rtx (XFmode);
15418   tmp2 = gen_reg_rtx (XFmode);
15420   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15421   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15422                                  operands[1], tmp1));
15423   DONE;
15426 (define_expand "ldexp<mode>3"
15427   [(use (match_operand:MODEF 0 "register_operand"))
15428    (use (match_operand:MODEF 1 "general_operand"))
15429    (use (match_operand:SI 2 "register_operand"))]
15430   "TARGET_USE_FANCY_MATH_387
15431    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15432        || TARGET_MIX_SSE_I387)
15433    && flag_unsafe_math_optimizations"
15435   rtx op0, op1;
15437   op0 = gen_reg_rtx (XFmode);
15438   op1 = gen_reg_rtx (XFmode);
15440   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15441   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15442   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15443   DONE;
15446 (define_expand "scalbxf3"
15447   [(parallel [(set (match_operand:XF 0 " register_operand")
15448                    (unspec:XF [(match_operand:XF 1 "register_operand")
15449                                (match_operand:XF 2 "register_operand")]
15450                               UNSPEC_FSCALE_FRACT))
15451               (set (match_dup 3)
15452                    (unspec:XF [(match_dup 1) (match_dup 2)]
15453                               UNSPEC_FSCALE_EXP))])]
15454   "TARGET_USE_FANCY_MATH_387
15455    && flag_unsafe_math_optimizations"
15457   operands[3] = gen_reg_rtx (XFmode);
15460 (define_expand "scalb<mode>3"
15461   [(use (match_operand:MODEF 0 "register_operand"))
15462    (use (match_operand:MODEF 1 "general_operand"))
15463    (use (match_operand:MODEF 2 "general_operand"))]
15464   "TARGET_USE_FANCY_MATH_387
15465    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15466        || TARGET_MIX_SSE_I387)
15467    && flag_unsafe_math_optimizations"
15469   rtx op0, op1, op2;
15471   op0 = gen_reg_rtx (XFmode);
15472   op1 = gen_reg_rtx (XFmode);
15473   op2 = gen_reg_rtx (XFmode);
15475   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15476   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15477   emit_insn (gen_scalbxf3 (op0, op1, op2));
15478   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15479   DONE;
15482 (define_expand "significandxf2"
15483   [(parallel [(set (match_operand:XF 0 "register_operand")
15484                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15485                               UNSPEC_XTRACT_FRACT))
15486               (set (match_dup 2)
15487                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15488   "TARGET_USE_FANCY_MATH_387
15489    && flag_unsafe_math_optimizations"
15490   "operands[2] = gen_reg_rtx (XFmode);")
15492 (define_expand "significand<mode>2"
15493   [(use (match_operand:MODEF 0 "register_operand"))
15494    (use (match_operand:MODEF 1 "register_operand"))]
15495   "TARGET_USE_FANCY_MATH_387
15496    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15497        || TARGET_MIX_SSE_I387)
15498    && flag_unsafe_math_optimizations"
15500   rtx op0 = gen_reg_rtx (XFmode);
15501   rtx op1 = gen_reg_rtx (XFmode);
15503   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15504   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15505   DONE;
15509 (define_insn "sse4_1_round<mode>2"
15510   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15511         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
15512                        (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15513                       UNSPEC_ROUND))]
15514   "TARGET_ROUND"
15515   "@
15516    %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15517    vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15518   [(set_attr "type" "ssecvt")
15519    (set_attr "prefix_extra" "1,*")
15520    (set_attr "length_immediate" "*,1")
15521    (set_attr "prefix" "maybe_vex,evex")
15522    (set_attr "isa" "noavx512f,avx512f")
15523    (set_attr "mode" "<MODE>")])
15525 (define_insn "rintxf2"
15526   [(set (match_operand:XF 0 "register_operand" "=f")
15527         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15528                    UNSPEC_FRNDINT))]
15529   "TARGET_USE_FANCY_MATH_387"
15530   "frndint"
15531   [(set_attr "type" "fpspc")
15532    (set_attr "znver1_decode" "vector")
15533    (set_attr "mode" "XF")])
15535 (define_insn "rint<mode>2_frndint"
15536   [(set (match_operand:MODEF 0 "register_operand" "=f")
15537         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
15538                       UNSPEC_FRNDINT))]
15539   "TARGET_USE_FANCY_MATH_387"
15540   "frndint"
15541   [(set_attr "type" "fpspc")
15542    (set_attr "znver1_decode" "vector")
15543    (set_attr "mode" "<MODE>")])
15545 (define_expand "rint<mode>2"
15546   [(use (match_operand:MODEF 0 "register_operand"))
15547    (use (match_operand:MODEF 1 "register_operand"))]
15548   "(TARGET_USE_FANCY_MATH_387
15549     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15550         || TARGET_MIX_SSE_I387))
15551    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15553   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15554     {
15555       if (TARGET_ROUND)
15556         emit_insn (gen_sse4_1_round<mode>2
15557                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15558       else
15559         ix86_expand_rint (operands[0], operands[1]);
15560     }
15561   else
15562     emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
15563   DONE;
15566 (define_expand "round<mode>2"
15567   [(match_operand:X87MODEF 0 "register_operand")
15568    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15569   "(TARGET_USE_FANCY_MATH_387
15570     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15571         || TARGET_MIX_SSE_I387)
15572     && flag_unsafe_math_optimizations)
15573    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15574        && !flag_trapping_math && !flag_rounding_math)"
15576   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15577       && !flag_trapping_math && !flag_rounding_math)
15578     {
15579       if (TARGET_ROUND)
15580         {
15581           operands[1] = force_reg (<MODE>mode, operands[1]);
15582           ix86_expand_round_sse4 (operands[0], operands[1]);
15583         }
15584       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15585         ix86_expand_round (operands[0], operands[1]);
15586       else
15587         ix86_expand_rounddf_32 (operands[0], operands[1]);
15588     }
15589   else
15590     {
15591       operands[1] = force_reg (<MODE>mode, operands[1]);
15592       ix86_emit_i387_round (operands[0], operands[1]);
15593     }
15594   DONE;
15597 (define_insn_and_split "*fistdi2_1"
15598   [(set (match_operand:DI 0 "nonimmediate_operand")
15599         (unspec:DI [(match_operand:XF 1 "register_operand")]
15600                    UNSPEC_FIST))]
15601   "TARGET_USE_FANCY_MATH_387
15602    && can_create_pseudo_p ()"
15603   "#"
15604   "&& 1"
15605   [(const_int 0)]
15607   if (memory_operand (operands[0], VOIDmode))
15608     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15609   else
15610     {
15611       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15612       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15613                                          operands[2]));
15614     }
15615   DONE;
15617   [(set_attr "type" "fpspc")
15618    (set_attr "mode" "DI")])
15620 (define_insn "fistdi2"
15621   [(set (match_operand:DI 0 "memory_operand" "=m")
15622         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15623                    UNSPEC_FIST))
15624    (clobber (match_scratch:XF 2 "=&1f"))]
15625   "TARGET_USE_FANCY_MATH_387"
15626   "* return output_fix_trunc (insn, operands, false);"
15627   [(set_attr "type" "fpspc")
15628    (set_attr "mode" "DI")])
15630 (define_insn "fistdi2_with_temp"
15631   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15632         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15633                    UNSPEC_FIST))
15634    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15635    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15636   "TARGET_USE_FANCY_MATH_387"
15637   "#"
15638   [(set_attr "type" "fpspc")
15639    (set_attr "mode" "DI")])
15641 (define_split
15642   [(set (match_operand:DI 0 "register_operand")
15643         (unspec:DI [(match_operand:XF 1 "register_operand")]
15644                    UNSPEC_FIST))
15645    (clobber (match_operand:DI 2 "memory_operand"))
15646    (clobber (match_scratch 3))]
15647   "reload_completed"
15648   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15649               (clobber (match_dup 3))])
15650    (set (match_dup 0) (match_dup 2))])
15652 (define_split
15653   [(set (match_operand:DI 0 "memory_operand")
15654         (unspec:DI [(match_operand:XF 1 "register_operand")]
15655                    UNSPEC_FIST))
15656    (clobber (match_operand:DI 2 "memory_operand"))
15657    (clobber (match_scratch 3))]
15658   "reload_completed"
15659   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15660               (clobber (match_dup 3))])])
15662 (define_insn_and_split "*fist<mode>2_1"
15663   [(set (match_operand:SWI24 0 "register_operand")
15664         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15665                       UNSPEC_FIST))]
15666   "TARGET_USE_FANCY_MATH_387
15667    && can_create_pseudo_p ()"
15668   "#"
15669   "&& 1"
15670   [(const_int 0)]
15672   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15673   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15674                                         operands[2]));
15675   DONE;
15677   [(set_attr "type" "fpspc")
15678    (set_attr "mode" "<MODE>")])
15680 (define_insn "fist<mode>2"
15681   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15682         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15683                       UNSPEC_FIST))]
15684   "TARGET_USE_FANCY_MATH_387"
15685   "* return output_fix_trunc (insn, operands, false);"
15686   [(set_attr "type" "fpspc")
15687    (set_attr "mode" "<MODE>")])
15689 (define_insn "fist<mode>2_with_temp"
15690   [(set (match_operand:SWI24 0 "register_operand" "=r")
15691         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15692                       UNSPEC_FIST))
15693    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15694   "TARGET_USE_FANCY_MATH_387"
15695   "#"
15696   [(set_attr "type" "fpspc")
15697    (set_attr "mode" "<MODE>")])
15699 (define_split
15700   [(set (match_operand:SWI24 0 "register_operand")
15701         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15702                       UNSPEC_FIST))
15703    (clobber (match_operand:SWI24 2 "memory_operand"))]
15704   "reload_completed"
15705   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15706    (set (match_dup 0) (match_dup 2))])
15708 (define_split
15709   [(set (match_operand:SWI24 0 "memory_operand")
15710         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15711                       UNSPEC_FIST))
15712    (clobber (match_operand:SWI24 2 "memory_operand"))]
15713   "reload_completed"
15714   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15716 (define_expand "lrintxf<mode>2"
15717   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15718      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15719                      UNSPEC_FIST))]
15720   "TARGET_USE_FANCY_MATH_387")
15722 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15723   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15724      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15725                    UNSPEC_FIX_NOTRUNC))]
15726   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15728 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15729   [(match_operand:SWI248x 0 "nonimmediate_operand")
15730    (match_operand:X87MODEF 1 "register_operand")]
15731   "(TARGET_USE_FANCY_MATH_387
15732     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15733         || TARGET_MIX_SSE_I387)
15734     && flag_unsafe_math_optimizations)
15735    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15736        && <SWI248x:MODE>mode != HImode 
15737        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15738        && !flag_trapping_math && !flag_rounding_math)"
15740   if (optimize_insn_for_size_p ())
15741     FAIL;
15743   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15744       && <SWI248x:MODE>mode != HImode
15745       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15746       && !flag_trapping_math && !flag_rounding_math)
15747     ix86_expand_lround (operands[0], operands[1]);
15748   else
15749     ix86_emit_i387_round (operands[0], operands[1]);
15750   DONE;
15753 (define_int_iterator FRNDINT_ROUNDING
15754         [UNSPEC_FRNDINT_FLOOR
15755          UNSPEC_FRNDINT_CEIL
15756          UNSPEC_FRNDINT_TRUNC])
15758 (define_int_iterator FIST_ROUNDING
15759         [UNSPEC_FIST_FLOOR
15760          UNSPEC_FIST_CEIL])
15762 ;; Base name for define_insn
15763 (define_int_attr rounding_insn
15764         [(UNSPEC_FRNDINT_FLOOR "floor")
15765          (UNSPEC_FRNDINT_CEIL "ceil")
15766          (UNSPEC_FRNDINT_TRUNC "btrunc")
15767          (UNSPEC_FIST_FLOOR "floor")
15768          (UNSPEC_FIST_CEIL "ceil")])
15770 (define_int_attr rounding
15771         [(UNSPEC_FRNDINT_FLOOR "floor")
15772          (UNSPEC_FRNDINT_CEIL "ceil")
15773          (UNSPEC_FRNDINT_TRUNC "trunc")
15774          (UNSPEC_FIST_FLOOR "floor")
15775          (UNSPEC_FIST_CEIL "ceil")])
15777 (define_int_attr ROUNDING
15778         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15779          (UNSPEC_FRNDINT_CEIL "CEIL")
15780          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15781          (UNSPEC_FIST_FLOOR "FLOOR")
15782          (UNSPEC_FIST_CEIL "CEIL")])
15784 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15785 (define_insn_and_split "frndint<mode>2_<rounding>"
15786   [(set (match_operand:X87MODEF 0 "register_operand")
15787         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
15788                    FRNDINT_ROUNDING))
15789    (clobber (reg:CC FLAGS_REG))]
15790   "TARGET_USE_FANCY_MATH_387
15791    && (flag_fp_int_builtin_inexact || !flag_trapping_math)
15792    && can_create_pseudo_p ()"
15793   "#"
15794   "&& 1"
15795   [(const_int 0)]
15797   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15799   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15800   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15802   emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
15803                                                  operands[2], operands[3]));
15804   DONE;
15806   [(set_attr "type" "frndint")
15807    (set_attr "i387_cw" "<rounding>")
15808    (set_attr "mode" "<MODE>")])
15810 (define_insn "frndint<mode>2_<rounding>_i387"
15811   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15812         (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
15813                          FRNDINT_ROUNDING))
15814    (use (match_operand:HI 2 "memory_operand" "m"))
15815    (use (match_operand:HI 3 "memory_operand" "m"))]
15816   "TARGET_USE_FANCY_MATH_387
15817    && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
15818   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15819   [(set_attr "type" "frndint")
15820    (set_attr "i387_cw" "<rounding>")
15821    (set_attr "mode" "<MODE>")])
15823 (define_expand "<rounding_insn>xf2"
15824   [(parallel [(set (match_operand:XF 0 "register_operand")
15825                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15826                               FRNDINT_ROUNDING))
15827               (clobber (reg:CC FLAGS_REG))])]
15828   "TARGET_USE_FANCY_MATH_387
15829    && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
15831 (define_expand "<rounding_insn><mode>2"
15832   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15833                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15834                                  FRNDINT_ROUNDING))
15835               (clobber (reg:CC FLAGS_REG))])]
15836   "(TARGET_USE_FANCY_MATH_387
15837     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15838         || TARGET_MIX_SSE_I387)
15839     && (flag_fp_int_builtin_inexact || !flag_trapping_math))
15840    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15841        && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))"
15843   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15844       && (TARGET_ROUND || !flag_trapping_math || flag_fp_int_builtin_inexact))
15845     {
15846       if (TARGET_ROUND)
15847         emit_insn (gen_sse4_1_round<mode>2
15848                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
15849                                                        | ROUND_NO_EXC)));
15850       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15851         {
15852           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15853             ix86_expand_floorceil (operands[0], operands[1], true);
15854           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15855             ix86_expand_floorceil (operands[0], operands[1], false);
15856           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15857             ix86_expand_trunc (operands[0], operands[1]);
15858           else
15859             gcc_unreachable ();
15860         }
15861       else
15862         {
15863           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15864             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15865           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15866             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15867           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15868             ix86_expand_truncdf_32 (operands[0], operands[1]);
15869           else
15870             gcc_unreachable ();
15871         }
15872     }
15873   else
15874     emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
15875   DONE;
15878 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15879 (define_insn_and_split "frndintxf2_mask_pm"
15880   [(set (match_operand:XF 0 "register_operand")
15881         (unspec:XF [(match_operand:XF 1 "register_operand")]
15882                    UNSPEC_FRNDINT_MASK_PM))
15883    (clobber (reg:CC FLAGS_REG))]
15884   "TARGET_USE_FANCY_MATH_387
15885    && flag_unsafe_math_optimizations
15886    && can_create_pseudo_p ()"
15887   "#"
15888   "&& 1"
15889   [(const_int 0)]
15891   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15893   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15894   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15896   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15897                                           operands[2], operands[3]));
15898   DONE;
15900   [(set_attr "type" "frndint")
15901    (set_attr "i387_cw" "mask_pm")
15902    (set_attr "mode" "XF")])
15904 (define_insn "frndintxf2_mask_pm_i387"
15905   [(set (match_operand:XF 0 "register_operand" "=f")
15906         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15907                    UNSPEC_FRNDINT_MASK_PM))
15908    (use (match_operand:HI 2 "memory_operand" "m"))
15909    (use (match_operand:HI 3 "memory_operand" "m"))]
15910   "TARGET_USE_FANCY_MATH_387
15911    && flag_unsafe_math_optimizations"
15912   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15913   [(set_attr "type" "frndint")
15914    (set_attr "i387_cw" "mask_pm")
15915    (set_attr "mode" "XF")])
15917 (define_expand "nearbyintxf2"
15918   [(parallel [(set (match_operand:XF 0 "register_operand")
15919                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15920                               UNSPEC_FRNDINT_MASK_PM))
15921               (clobber (reg:CC FLAGS_REG))])]
15922   "TARGET_USE_FANCY_MATH_387
15923    && flag_unsafe_math_optimizations")
15925 (define_expand "nearbyint<mode>2"
15926   [(use (match_operand:MODEF 0 "register_operand"))
15927    (use (match_operand:MODEF 1 "register_operand"))]
15928   "TARGET_USE_FANCY_MATH_387
15929    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15930        || TARGET_MIX_SSE_I387)
15931    && flag_unsafe_math_optimizations"
15933   rtx op0 = gen_reg_rtx (XFmode);
15934   rtx op1 = gen_reg_rtx (XFmode);
15936   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15937   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15939   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15940   DONE;
15943 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15944 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15945   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15946         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15947                         FIST_ROUNDING))
15948    (clobber (reg:CC FLAGS_REG))]
15949   "TARGET_USE_FANCY_MATH_387
15950    && flag_unsafe_math_optimizations
15951    && can_create_pseudo_p ()"
15952   "#"
15953   "&& 1"
15954   [(const_int 0)]
15956   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15958   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15959   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15960   if (memory_operand (operands[0], VOIDmode))
15961     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15962                                            operands[2], operands[3]));
15963   else
15964     {
15965       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15966       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15967                   (operands[0], operands[1], operands[2],
15968                    operands[3], operands[4]));
15969     }
15970   DONE;
15972   [(set_attr "type" "fistp")
15973    (set_attr "i387_cw" "<rounding>")
15974    (set_attr "mode" "<MODE>")])
15976 (define_insn "fistdi2_<rounding>"
15977   [(set (match_operand:DI 0 "memory_operand" "=m")
15978         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15979                    FIST_ROUNDING))
15980    (use (match_operand:HI 2 "memory_operand" "m"))
15981    (use (match_operand:HI 3 "memory_operand" "m"))
15982    (clobber (match_scratch:XF 4 "=&1f"))]
15983   "TARGET_USE_FANCY_MATH_387
15984    && flag_unsafe_math_optimizations"
15985   "* return output_fix_trunc (insn, operands, false);"
15986   [(set_attr "type" "fistp")
15987    (set_attr "i387_cw" "<rounding>")
15988    (set_attr "mode" "DI")])
15990 (define_insn "fistdi2_<rounding>_with_temp"
15991   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15992         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15993                    FIST_ROUNDING))
15994    (use (match_operand:HI 2 "memory_operand" "m,m"))
15995    (use (match_operand:HI 3 "memory_operand" "m,m"))
15996    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15997    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15998   "TARGET_USE_FANCY_MATH_387
15999    && flag_unsafe_math_optimizations"
16000   "#"
16001   [(set_attr "type" "fistp")
16002    (set_attr "i387_cw" "<rounding>")
16003    (set_attr "mode" "DI")])
16005 (define_split
16006   [(set (match_operand:DI 0 "register_operand")
16007         (unspec:DI [(match_operand:XF 1 "register_operand")]
16008                    FIST_ROUNDING))
16009    (use (match_operand:HI 2 "memory_operand"))
16010    (use (match_operand:HI 3 "memory_operand"))
16011    (clobber (match_operand:DI 4 "memory_operand"))
16012    (clobber (match_scratch 5))]
16013   "reload_completed"
16014   [(parallel [(set (match_dup 4)
16015                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16016               (use (match_dup 2))
16017               (use (match_dup 3))
16018               (clobber (match_dup 5))])
16019    (set (match_dup 0) (match_dup 4))])
16021 (define_split
16022   [(set (match_operand:DI 0 "memory_operand")
16023         (unspec:DI [(match_operand:XF 1 "register_operand")]
16024                    FIST_ROUNDING))
16025    (use (match_operand:HI 2 "memory_operand"))
16026    (use (match_operand:HI 3 "memory_operand"))
16027    (clobber (match_operand:DI 4 "memory_operand"))
16028    (clobber (match_scratch 5))]
16029   "reload_completed"
16030   [(parallel [(set (match_dup 0)
16031                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16032               (use (match_dup 2))
16033               (use (match_dup 3))
16034               (clobber (match_dup 5))])])
16036 (define_insn "fist<mode>2_<rounding>"
16037   [(set (match_operand:SWI24 0 "memory_operand" "=m")
16038         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16039                       FIST_ROUNDING))
16040    (use (match_operand:HI 2 "memory_operand" "m"))
16041    (use (match_operand:HI 3 "memory_operand" "m"))]
16042   "TARGET_USE_FANCY_MATH_387
16043    && flag_unsafe_math_optimizations"
16044   "* return output_fix_trunc (insn, operands, false);"
16045   [(set_attr "type" "fistp")
16046    (set_attr "i387_cw" "<rounding>")
16047    (set_attr "mode" "<MODE>")])
16049 (define_insn "fist<mode>2_<rounding>_with_temp"
16050   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16051         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16052                       FIST_ROUNDING))
16053    (use (match_operand:HI 2 "memory_operand" "m,m"))
16054    (use (match_operand:HI 3 "memory_operand" "m,m"))
16055    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16056   "TARGET_USE_FANCY_MATH_387
16057    && flag_unsafe_math_optimizations"
16058   "#"
16059   [(set_attr "type" "fistp")
16060    (set_attr "i387_cw" "<rounding>")
16061    (set_attr "mode" "<MODE>")])
16063 (define_split
16064   [(set (match_operand:SWI24 0 "register_operand")
16065         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16066                       FIST_ROUNDING))
16067    (use (match_operand:HI 2 "memory_operand"))
16068    (use (match_operand:HI 3 "memory_operand"))
16069    (clobber (match_operand:SWI24 4 "memory_operand"))]
16070   "reload_completed"
16071   [(parallel [(set (match_dup 4)
16072                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16073               (use (match_dup 2))
16074               (use (match_dup 3))])
16075    (set (match_dup 0) (match_dup 4))])
16077 (define_split
16078   [(set (match_operand:SWI24 0 "memory_operand")
16079         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16080                       FIST_ROUNDING))
16081    (use (match_operand:HI 2 "memory_operand"))
16082    (use (match_operand:HI 3 "memory_operand"))
16083    (clobber (match_operand:SWI24 4 "memory_operand"))]
16084   "reload_completed"
16085   [(parallel [(set (match_dup 0)
16086                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16087               (use (match_dup 2))
16088               (use (match_dup 3))])])
16090 (define_expand "l<rounding_insn>xf<mode>2"
16091   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16092                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16093                                    FIST_ROUNDING))
16094               (clobber (reg:CC FLAGS_REG))])]
16095   "TARGET_USE_FANCY_MATH_387
16096    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16097    && flag_unsafe_math_optimizations")
16099 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16100   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16101                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16102                                  FIST_ROUNDING))
16103               (clobber (reg:CC FLAGS_REG))])]
16104   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16105    && !flag_trapping_math"
16107   if (TARGET_64BIT && optimize_insn_for_size_p ())
16108     FAIL;
16110   if (ROUND_<ROUNDING> == ROUND_FLOOR)
16111     ix86_expand_lfloorceil (operands[0], operands[1], true);
16112   else if (ROUND_<ROUNDING> == ROUND_CEIL)
16113     ix86_expand_lfloorceil (operands[0], operands[1], false);
16114   else
16115     gcc_unreachable ();
16117   DONE;
16120 (define_insn "fxam<mode>2_i387"
16121   [(set (match_operand:HI 0 "register_operand" "=a")
16122         (unspec:HI
16123           [(match_operand:X87MODEF 1 "register_operand" "f")]
16124           UNSPEC_FXAM))]
16125   "TARGET_USE_FANCY_MATH_387"
16126   "fxam\n\tfnstsw\t%0"
16127   [(set_attr "type" "multi")
16128    (set_attr "length" "4")
16129    (set_attr "unit" "i387")
16130    (set_attr "mode" "<MODE>")])
16132 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16133   [(set (match_operand:HI 0 "register_operand")
16134         (unspec:HI
16135           [(match_operand:MODEF 1 "memory_operand")]
16136           UNSPEC_FXAM_MEM))]
16137   "TARGET_USE_FANCY_MATH_387
16138    && can_create_pseudo_p ()"
16139   "#"
16140   "&& 1"
16141   [(set (match_dup 2)(match_dup 1))
16142    (set (match_dup 0)
16143         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16145   operands[2] = gen_reg_rtx (<MODE>mode);
16147   MEM_VOLATILE_P (operands[1]) = 1;
16149   [(set_attr "type" "multi")
16150    (set_attr "unit" "i387")
16151    (set_attr "mode" "<MODE>")])
16153 (define_expand "isinfxf2"
16154   [(use (match_operand:SI 0 "register_operand"))
16155    (use (match_operand:XF 1 "register_operand"))]
16156   "TARGET_USE_FANCY_MATH_387
16157    && ix86_libc_has_function (function_c99_misc)"
16159   rtx mask = GEN_INT (0x45);
16160   rtx val = GEN_INT (0x05);
16162   rtx cond;
16164   rtx scratch = gen_reg_rtx (HImode);
16165   rtx res = gen_reg_rtx (QImode);
16167   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16169   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16170   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16171   cond = gen_rtx_fmt_ee (EQ, QImode,
16172                          gen_rtx_REG (CCmode, FLAGS_REG),
16173                          const0_rtx);
16174   emit_insn (gen_rtx_SET (res, cond));
16175   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16176   DONE;
16179 (define_expand "isinf<mode>2"
16180   [(use (match_operand:SI 0 "register_operand"))
16181    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16182   "TARGET_USE_FANCY_MATH_387
16183    && ix86_libc_has_function (function_c99_misc)
16184    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16186   rtx mask = GEN_INT (0x45);
16187   rtx val = GEN_INT (0x05);
16189   rtx cond;
16191   rtx scratch = gen_reg_rtx (HImode);
16192   rtx res = gen_reg_rtx (QImode);
16194   /* Remove excess precision by forcing value through memory. */
16195   if (memory_operand (operands[1], VOIDmode))
16196     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16197   else
16198     {
16199       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16201       emit_move_insn (temp, operands[1]);
16202       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16203     }
16205   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
16206   emit_insn (gen_cmpqi_ext_3 (scratch, val));
16207   cond = gen_rtx_fmt_ee (EQ, QImode,
16208                          gen_rtx_REG (CCmode, FLAGS_REG),
16209                          const0_rtx);
16210   emit_insn (gen_rtx_SET (res, cond));
16211   emit_insn (gen_zero_extendqisi2 (operands[0], res));
16212   DONE;
16215 (define_expand "signbitxf2"
16216   [(use (match_operand:SI 0 "register_operand"))
16217    (use (match_operand:XF 1 "register_operand"))]
16218   "TARGET_USE_FANCY_MATH_387"
16220   rtx scratch = gen_reg_rtx (HImode);
16222   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16223   emit_insn (gen_andsi3 (operands[0],
16224              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16225   DONE;
16228 (define_insn "movmsk_df"
16229   [(set (match_operand:SI 0 "register_operand" "=r")
16230         (unspec:SI
16231           [(match_operand:DF 1 "register_operand" "x")]
16232           UNSPEC_MOVMSK))]
16233   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16234   "%vmovmskpd\t{%1, %0|%0, %1}"
16235   [(set_attr "type" "ssemov")
16236    (set_attr "prefix" "maybe_vex")
16237    (set_attr "mode" "DF")])
16239 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16240 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16241 (define_expand "signbitdf2"
16242   [(use (match_operand:SI 0 "register_operand"))
16243    (use (match_operand:DF 1 "register_operand"))]
16244   "TARGET_USE_FANCY_MATH_387
16245    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16247   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16248     {
16249       emit_insn (gen_movmsk_df (operands[0], operands[1]));
16250       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16251     }
16252   else
16253     {
16254       rtx scratch = gen_reg_rtx (HImode);
16256       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16257       emit_insn (gen_andsi3 (operands[0],
16258                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16259     }
16260   DONE;
16263 (define_expand "signbitsf2"
16264   [(use (match_operand:SI 0 "register_operand"))
16265    (use (match_operand:SF 1 "register_operand"))]
16266   "TARGET_USE_FANCY_MATH_387
16267    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16269   rtx scratch = gen_reg_rtx (HImode);
16271   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16272   emit_insn (gen_andsi3 (operands[0],
16273              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16274   DONE;
16277 ;; Block operation instructions
16279 (define_insn "cld"
16280   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16281   ""
16282   "cld"
16283   [(set_attr "length" "1")
16284    (set_attr "length_immediate" "0")
16285    (set_attr "modrm" "0")])
16287 (define_expand "movmem<mode>"
16288   [(use (match_operand:BLK 0 "memory_operand"))
16289    (use (match_operand:BLK 1 "memory_operand"))
16290    (use (match_operand:SWI48 2 "nonmemory_operand"))
16291    (use (match_operand:SWI48 3 "const_int_operand"))
16292    (use (match_operand:SI 4 "const_int_operand"))
16293    (use (match_operand:SI 5 "const_int_operand"))
16294    (use (match_operand:SI 6 ""))
16295    (use (match_operand:SI 7 ""))
16296    (use (match_operand:SI 8 ""))]
16297   ""
16299  if (ix86_expand_set_or_movmem (operands[0], operands[1],
16300                                 operands[2], NULL, operands[3],
16301                                 operands[4], operands[5],
16302                                 operands[6], operands[7],
16303                                 operands[8], false))
16304    DONE;
16305  else
16306    FAIL;
16309 ;; Most CPUs don't like single string operations
16310 ;; Handle this case here to simplify previous expander.
16312 (define_expand "strmov"
16313   [(set (match_dup 4) (match_operand 3 "memory_operand"))
16314    (set (match_operand 1 "memory_operand") (match_dup 4))
16315    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16316               (clobber (reg:CC FLAGS_REG))])
16317    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16318               (clobber (reg:CC FLAGS_REG))])]
16319   ""
16321   /* Can't use this for non-default address spaces.  */
16322   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16323     FAIL;
16325   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16327   /* If .md ever supports :P for Pmode, these can be directly
16328      in the pattern above.  */
16329   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16330   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16332   /* Can't use this if the user has appropriated esi or edi.  */
16333   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16334       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16335     {
16336       emit_insn (gen_strmov_singleop (operands[0], operands[1],
16337                                       operands[2], operands[3],
16338                                       operands[5], operands[6]));
16339       DONE;
16340     }
16342   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16345 (define_expand "strmov_singleop"
16346   [(parallel [(set (match_operand 1 "memory_operand")
16347                    (match_operand 3 "memory_operand"))
16348               (set (match_operand 0 "register_operand")
16349                    (match_operand 4))
16350               (set (match_operand 2 "register_operand")
16351                    (match_operand 5))])]
16352   ""
16353   "ix86_current_function_needs_cld = 1;")
16355 (define_insn "*strmovdi_rex_1"
16356   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16357         (mem:DI (match_operand:P 3 "register_operand" "1")))
16358    (set (match_operand:P 0 "register_operand" "=D")
16359         (plus:P (match_dup 2)
16360                 (const_int 8)))
16361    (set (match_operand:P 1 "register_operand" "=S")
16362         (plus:P (match_dup 3)
16363                 (const_int 8)))]
16364   "TARGET_64BIT
16365    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16366    && ix86_check_no_addr_space (insn)"
16367   "%^movsq"
16368   [(set_attr "type" "str")
16369    (set_attr "memory" "both")
16370    (set_attr "mode" "DI")])
16372 (define_insn "*strmovsi_1"
16373   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16374         (mem:SI (match_operand:P 3 "register_operand" "1")))
16375    (set (match_operand:P 0 "register_operand" "=D")
16376         (plus:P (match_dup 2)
16377                 (const_int 4)))
16378    (set (match_operand:P 1 "register_operand" "=S")
16379         (plus:P (match_dup 3)
16380                 (const_int 4)))]
16381   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16382    && ix86_check_no_addr_space (insn)"
16383   "%^movs{l|d}"
16384   [(set_attr "type" "str")
16385    (set_attr "memory" "both")
16386    (set_attr "mode" "SI")])
16388 (define_insn "*strmovhi_1"
16389   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16390         (mem:HI (match_operand:P 3 "register_operand" "1")))
16391    (set (match_operand:P 0 "register_operand" "=D")
16392         (plus:P (match_dup 2)
16393                 (const_int 2)))
16394    (set (match_operand:P 1 "register_operand" "=S")
16395         (plus:P (match_dup 3)
16396                 (const_int 2)))]
16397   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16398    && ix86_check_no_addr_space (insn)"
16399   "%^movsw"
16400   [(set_attr "type" "str")
16401    (set_attr "memory" "both")
16402    (set_attr "mode" "HI")])
16404 (define_insn "*strmovqi_1"
16405   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16406         (mem:QI (match_operand:P 3 "register_operand" "1")))
16407    (set (match_operand:P 0 "register_operand" "=D")
16408         (plus:P (match_dup 2)
16409                 (const_int 1)))
16410    (set (match_operand:P 1 "register_operand" "=S")
16411         (plus:P (match_dup 3)
16412                 (const_int 1)))]
16413   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16414    && ix86_check_no_addr_space (insn)"
16415   "%^movsb"
16416   [(set_attr "type" "str")
16417    (set_attr "memory" "both")
16418    (set (attr "prefix_rex")
16419         (if_then_else
16420           (match_test "<P:MODE>mode == DImode")
16421           (const_string "0")
16422           (const_string "*")))
16423    (set_attr "mode" "QI")])
16425 (define_expand "rep_mov"
16426   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16427               (set (match_operand 0 "register_operand")
16428                    (match_operand 5))
16429               (set (match_operand 2 "register_operand")
16430                    (match_operand 6))
16431               (set (match_operand 1 "memory_operand")
16432                    (match_operand 3 "memory_operand"))
16433               (use (match_dup 4))])]
16434   ""
16435   "ix86_current_function_needs_cld = 1;")
16437 (define_insn "*rep_movdi_rex64"
16438   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16439    (set (match_operand:P 0 "register_operand" "=D")
16440         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16441                           (const_int 3))
16442                 (match_operand:P 3 "register_operand" "0")))
16443    (set (match_operand:P 1 "register_operand" "=S")
16444         (plus:P (ashift:P (match_dup 5) (const_int 3))
16445                 (match_operand:P 4 "register_operand" "1")))
16446    (set (mem:BLK (match_dup 3))
16447         (mem:BLK (match_dup 4)))
16448    (use (match_dup 5))]
16449   "TARGET_64BIT
16450    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16451    && ix86_check_no_addr_space (insn)"
16452   "%^rep{%;} movsq"
16453   [(set_attr "type" "str")
16454    (set_attr "prefix_rep" "1")
16455    (set_attr "memory" "both")
16456    (set_attr "mode" "DI")])
16458 (define_insn "*rep_movsi"
16459   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16460    (set (match_operand:P 0 "register_operand" "=D")
16461         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16462                           (const_int 2))
16463                  (match_operand:P 3 "register_operand" "0")))
16464    (set (match_operand:P 1 "register_operand" "=S")
16465         (plus:P (ashift:P (match_dup 5) (const_int 2))
16466                 (match_operand:P 4 "register_operand" "1")))
16467    (set (mem:BLK (match_dup 3))
16468         (mem:BLK (match_dup 4)))
16469    (use (match_dup 5))]
16470   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16471    && ix86_check_no_addr_space (insn)"
16472   "%^rep{%;} movs{l|d}"
16473   [(set_attr "type" "str")
16474    (set_attr "prefix_rep" "1")
16475    (set_attr "memory" "both")
16476    (set_attr "mode" "SI")])
16478 (define_insn "*rep_movqi"
16479   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16480    (set (match_operand:P 0 "register_operand" "=D")
16481         (plus:P (match_operand:P 3 "register_operand" "0")
16482                 (match_operand:P 5 "register_operand" "2")))
16483    (set (match_operand:P 1 "register_operand" "=S")
16484         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16485    (set (mem:BLK (match_dup 3))
16486         (mem:BLK (match_dup 4)))
16487    (use (match_dup 5))]
16488   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16489    && ix86_check_no_addr_space (insn)"
16490   "%^rep{%;} movsb"
16491   [(set_attr "type" "str")
16492    (set_attr "prefix_rep" "1")
16493    (set_attr "memory" "both")
16494    (set_attr "mode" "QI")])
16496 (define_expand "setmem<mode>"
16497    [(use (match_operand:BLK 0 "memory_operand"))
16498     (use (match_operand:SWI48 1 "nonmemory_operand"))
16499     (use (match_operand:QI 2 "nonmemory_operand"))
16500     (use (match_operand 3 "const_int_operand"))
16501     (use (match_operand:SI 4 "const_int_operand"))
16502     (use (match_operand:SI 5 "const_int_operand"))
16503     (use (match_operand:SI 6 ""))
16504     (use (match_operand:SI 7 ""))
16505     (use (match_operand:SI 8 ""))]
16506   ""
16508  if (ix86_expand_set_or_movmem (operands[0], NULL,
16509                                 operands[1], operands[2],
16510                                 operands[3], operands[4],
16511                                 operands[5], operands[6],
16512                                 operands[7], operands[8], true))
16513    DONE;
16514  else
16515    FAIL;
16518 ;; Most CPUs don't like single string operations
16519 ;; Handle this case here to simplify previous expander.
16521 (define_expand "strset"
16522   [(set (match_operand 1 "memory_operand")
16523         (match_operand 2 "register_operand"))
16524    (parallel [(set (match_operand 0 "register_operand")
16525                    (match_dup 3))
16526               (clobber (reg:CC FLAGS_REG))])]
16527   ""
16529   /* Can't use this for non-default address spaces.  */
16530   if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16531     FAIL;
16533   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16534     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16536   /* If .md ever supports :P for Pmode, this can be directly
16537      in the pattern above.  */
16538   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16539                               GEN_INT (GET_MODE_SIZE (GET_MODE
16540                                                       (operands[2]))));
16541   /* Can't use this if the user has appropriated eax or edi.  */
16542   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16543       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16544     {
16545       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16546                                       operands[3]));
16547       DONE;
16548     }
16551 (define_expand "strset_singleop"
16552   [(parallel [(set (match_operand 1 "memory_operand")
16553                    (match_operand 2 "register_operand"))
16554               (set (match_operand 0 "register_operand")
16555                    (match_operand 3))
16556               (unspec [(const_int 0)] UNSPEC_STOS)])]
16557   ""
16558   "ix86_current_function_needs_cld = 1;")
16560 (define_insn "*strsetdi_rex_1"
16561   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16562         (match_operand:DI 2 "register_operand" "a"))
16563    (set (match_operand:P 0 "register_operand" "=D")
16564         (plus:P (match_dup 1)
16565                 (const_int 8)))
16566    (unspec [(const_int 0)] UNSPEC_STOS)]
16567   "TARGET_64BIT
16568    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16569    && ix86_check_no_addr_space (insn)"
16570   "%^stosq"
16571   [(set_attr "type" "str")
16572    (set_attr "memory" "store")
16573    (set_attr "mode" "DI")])
16575 (define_insn "*strsetsi_1"
16576   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16577         (match_operand:SI 2 "register_operand" "a"))
16578    (set (match_operand:P 0 "register_operand" "=D")
16579         (plus:P (match_dup 1)
16580                 (const_int 4)))
16581    (unspec [(const_int 0)] UNSPEC_STOS)]
16582   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16583    && ix86_check_no_addr_space (insn)"
16584   "%^stos{l|d}"
16585   [(set_attr "type" "str")
16586    (set_attr "memory" "store")
16587    (set_attr "mode" "SI")])
16589 (define_insn "*strsethi_1"
16590   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16591         (match_operand:HI 2 "register_operand" "a"))
16592    (set (match_operand:P 0 "register_operand" "=D")
16593         (plus:P (match_dup 1)
16594                 (const_int 2)))
16595    (unspec [(const_int 0)] UNSPEC_STOS)]
16596   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16597    && ix86_check_no_addr_space (insn)"
16598   "%^stosw"
16599   [(set_attr "type" "str")
16600    (set_attr "memory" "store")
16601    (set_attr "mode" "HI")])
16603 (define_insn "*strsetqi_1"
16604   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16605         (match_operand:QI 2 "register_operand" "a"))
16606    (set (match_operand:P 0 "register_operand" "=D")
16607         (plus:P (match_dup 1)
16608                 (const_int 1)))
16609    (unspec [(const_int 0)] UNSPEC_STOS)]
16610   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16611    && ix86_check_no_addr_space (insn)"
16612   "%^stosb"
16613   [(set_attr "type" "str")
16614    (set_attr "memory" "store")
16615    (set (attr "prefix_rex")
16616         (if_then_else
16617           (match_test "<P:MODE>mode == DImode")
16618           (const_string "0")
16619           (const_string "*")))
16620    (set_attr "mode" "QI")])
16622 (define_expand "rep_stos"
16623   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16624               (set (match_operand 0 "register_operand")
16625                    (match_operand 4))
16626               (set (match_operand 2 "memory_operand") (const_int 0))
16627               (use (match_operand 3 "register_operand"))
16628               (use (match_dup 1))])]
16629   ""
16630   "ix86_current_function_needs_cld = 1;")
16632 (define_insn "*rep_stosdi_rex64"
16633   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16634    (set (match_operand:P 0 "register_operand" "=D")
16635         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16636                           (const_int 3))
16637                  (match_operand:P 3 "register_operand" "0")))
16638    (set (mem:BLK (match_dup 3))
16639         (const_int 0))
16640    (use (match_operand:DI 2 "register_operand" "a"))
16641    (use (match_dup 4))]
16642   "TARGET_64BIT
16643    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16644    && ix86_check_no_addr_space (insn)"
16645   "%^rep{%;} stosq"
16646   [(set_attr "type" "str")
16647    (set_attr "prefix_rep" "1")
16648    (set_attr "memory" "store")
16649    (set_attr "mode" "DI")])
16651 (define_insn "*rep_stossi"
16652   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16653    (set (match_operand:P 0 "register_operand" "=D")
16654         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16655                           (const_int 2))
16656                  (match_operand:P 3 "register_operand" "0")))
16657    (set (mem:BLK (match_dup 3))
16658         (const_int 0))
16659    (use (match_operand:SI 2 "register_operand" "a"))
16660    (use (match_dup 4))]
16661   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16662    && ix86_check_no_addr_space (insn)"
16663   "%^rep{%;} stos{l|d}"
16664   [(set_attr "type" "str")
16665    (set_attr "prefix_rep" "1")
16666    (set_attr "memory" "store")
16667    (set_attr "mode" "SI")])
16669 (define_insn "*rep_stosqi"
16670   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16671    (set (match_operand:P 0 "register_operand" "=D")
16672         (plus:P (match_operand:P 3 "register_operand" "0")
16673                 (match_operand:P 4 "register_operand" "1")))
16674    (set (mem:BLK (match_dup 3))
16675         (const_int 0))
16676    (use (match_operand:QI 2 "register_operand" "a"))
16677    (use (match_dup 4))]
16678   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16679    && ix86_check_no_addr_space (insn)"
16680   "%^rep{%;} stosb"
16681   [(set_attr "type" "str")
16682    (set_attr "prefix_rep" "1")
16683    (set_attr "memory" "store")
16684    (set (attr "prefix_rex")
16685         (if_then_else
16686           (match_test "<P:MODE>mode == DImode")
16687           (const_string "0")
16688           (const_string "*")))
16689    (set_attr "mode" "QI")])
16691 (define_expand "cmpstrnsi"
16692   [(set (match_operand:SI 0 "register_operand")
16693         (compare:SI (match_operand:BLK 1 "general_operand")
16694                     (match_operand:BLK 2 "general_operand")))
16695    (use (match_operand 3 "general_operand"))
16696    (use (match_operand 4 "immediate_operand"))]
16697   ""
16699   rtx addr1, addr2, out, outlow, count, countreg, align;
16701   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16702     FAIL;
16704   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16705   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16706     FAIL;
16708   out = operands[0];
16709   if (!REG_P (out))
16710     out = gen_reg_rtx (SImode);
16712   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16713   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16714   if (addr1 != XEXP (operands[1], 0))
16715     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16716   if (addr2 != XEXP (operands[2], 0))
16717     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16719   count = operands[3];
16720   countreg = ix86_zero_extend_to_Pmode (count);
16722   /* %%% Iff we are testing strict equality, we can use known alignment
16723      to good advantage.  This may be possible with combine, particularly
16724      once cc0 is dead.  */
16725   align = operands[4];
16727   if (CONST_INT_P (count))
16728     {
16729       if (INTVAL (count) == 0)
16730         {
16731           emit_move_insn (operands[0], const0_rtx);
16732           DONE;
16733         }
16734       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16735                                      operands[1], operands[2]));
16736     }
16737   else
16738     {
16739       rtx (*gen_cmp) (rtx, rtx);
16741       gen_cmp = (TARGET_64BIT
16742                  ? gen_cmpdi_1 : gen_cmpsi_1);
16744       emit_insn (gen_cmp (countreg, countreg));
16745       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16746                                   operands[1], operands[2]));
16747     }
16749   outlow = gen_lowpart (QImode, out);
16750   emit_insn (gen_cmpintqi (outlow));
16751   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16753   if (operands[0] != out)
16754     emit_move_insn (operands[0], out);
16756   DONE;
16759 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16761 (define_expand "cmpintqi"
16762   [(set (match_dup 1)
16763         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16764    (set (match_dup 2)
16765         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16766    (parallel [(set (match_operand:QI 0 "register_operand")
16767                    (minus:QI (match_dup 1)
16768                              (match_dup 2)))
16769               (clobber (reg:CC FLAGS_REG))])]
16770   ""
16772   operands[1] = gen_reg_rtx (QImode);
16773   operands[2] = gen_reg_rtx (QImode);
16776 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16777 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16779 (define_expand "cmpstrnqi_nz_1"
16780   [(parallel [(set (reg:CC FLAGS_REG)
16781                    (compare:CC (match_operand 4 "memory_operand")
16782                                (match_operand 5 "memory_operand")))
16783               (use (match_operand 2 "register_operand"))
16784               (use (match_operand:SI 3 "immediate_operand"))
16785               (clobber (match_operand 0 "register_operand"))
16786               (clobber (match_operand 1 "register_operand"))
16787               (clobber (match_dup 2))])]
16788   ""
16789   "ix86_current_function_needs_cld = 1;")
16791 (define_insn "*cmpstrnqi_nz_1"
16792   [(set (reg:CC FLAGS_REG)
16793         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16794                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16795    (use (match_operand:P 6 "register_operand" "2"))
16796    (use (match_operand:SI 3 "immediate_operand" "i"))
16797    (clobber (match_operand:P 0 "register_operand" "=S"))
16798    (clobber (match_operand:P 1 "register_operand" "=D"))
16799    (clobber (match_operand:P 2 "register_operand" "=c"))]
16800   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16801    && ix86_check_no_addr_space (insn)"
16802   "%^repz{%;} cmpsb"
16803   [(set_attr "type" "str")
16804    (set_attr "mode" "QI")
16805    (set (attr "prefix_rex")
16806         (if_then_else
16807           (match_test "<P:MODE>mode == DImode")
16808           (const_string "0")
16809           (const_string "*")))
16810    (set_attr "prefix_rep" "1")])
16812 ;; The same, but the count is not known to not be zero.
16814 (define_expand "cmpstrnqi_1"
16815   [(parallel [(set (reg:CC FLAGS_REG)
16816                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16817                                      (const_int 0))
16818                   (compare:CC (match_operand 4 "memory_operand")
16819                               (match_operand 5 "memory_operand"))
16820                   (const_int 0)))
16821               (use (match_operand:SI 3 "immediate_operand"))
16822               (use (reg:CC FLAGS_REG))
16823               (clobber (match_operand 0 "register_operand"))
16824               (clobber (match_operand 1 "register_operand"))
16825               (clobber (match_dup 2))])]
16826   ""
16827   "ix86_current_function_needs_cld = 1;")
16829 (define_insn "*cmpstrnqi_1"
16830   [(set (reg:CC FLAGS_REG)
16831         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16832                              (const_int 0))
16833           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16834                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16835           (const_int 0)))
16836    (use (match_operand:SI 3 "immediate_operand" "i"))
16837    (use (reg:CC FLAGS_REG))
16838    (clobber (match_operand:P 0 "register_operand" "=S"))
16839    (clobber (match_operand:P 1 "register_operand" "=D"))
16840    (clobber (match_operand:P 2 "register_operand" "=c"))]
16841   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16842    && ix86_check_no_addr_space (insn)"
16843   "%^repz{%;} cmpsb"
16844   [(set_attr "type" "str")
16845    (set_attr "mode" "QI")
16846    (set (attr "prefix_rex")
16847         (if_then_else
16848           (match_test "<P:MODE>mode == DImode")
16849           (const_string "0")
16850           (const_string "*")))
16851    (set_attr "prefix_rep" "1")])
16853 (define_expand "strlen<mode>"
16854   [(set (match_operand:P 0 "register_operand")
16855         (unspec:P [(match_operand:BLK 1 "general_operand")
16856                    (match_operand:QI 2 "immediate_operand")
16857                    (match_operand 3 "immediate_operand")]
16858                   UNSPEC_SCAS))]
16859   ""
16861  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16862    DONE;
16863  else
16864    FAIL;
16867 (define_expand "strlenqi_1"
16868   [(parallel [(set (match_operand 0 "register_operand")
16869                    (match_operand 2))
16870               (clobber (match_operand 1 "register_operand"))
16871               (clobber (reg:CC FLAGS_REG))])]
16872   ""
16873   "ix86_current_function_needs_cld = 1;")
16875 (define_insn "*strlenqi_1"
16876   [(set (match_operand:P 0 "register_operand" "=&c")
16877         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16878                    (match_operand:QI 2 "register_operand" "a")
16879                    (match_operand:P 3 "immediate_operand" "i")
16880                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16881    (clobber (match_operand:P 1 "register_operand" "=D"))
16882    (clobber (reg:CC FLAGS_REG))]
16883   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16884    && ix86_check_no_addr_space (insn)"
16885   "%^repnz{%;} scasb"
16886   [(set_attr "type" "str")
16887    (set_attr "mode" "QI")
16888    (set (attr "prefix_rex")
16889         (if_then_else
16890           (match_test "<P:MODE>mode == DImode")
16891           (const_string "0")
16892           (const_string "*")))
16893    (set_attr "prefix_rep" "1")])
16895 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16896 ;; handled in combine, but it is not currently up to the task.
16897 ;; When used for their truth value, the cmpstrn* expanders generate
16898 ;; code like this:
16900 ;;   repz cmpsb
16901 ;;   seta       %al
16902 ;;   setb       %dl
16903 ;;   cmpb       %al, %dl
16904 ;;   jcc        label
16906 ;; The intermediate three instructions are unnecessary.
16908 ;; This one handles cmpstrn*_nz_1...
16909 (define_peephole2
16910   [(parallel[
16911      (set (reg:CC FLAGS_REG)
16912           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16913                       (mem:BLK (match_operand 5 "register_operand"))))
16914      (use (match_operand 6 "register_operand"))
16915      (use (match_operand:SI 3 "immediate_operand"))
16916      (clobber (match_operand 0 "register_operand"))
16917      (clobber (match_operand 1 "register_operand"))
16918      (clobber (match_operand 2 "register_operand"))])
16919    (set (match_operand:QI 7 "register_operand")
16920         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16921    (set (match_operand:QI 8 "register_operand")
16922         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16923    (set (reg FLAGS_REG)
16924         (compare (match_dup 7) (match_dup 8)))
16925   ]
16926   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16927   [(parallel[
16928      (set (reg:CC FLAGS_REG)
16929           (compare:CC (mem:BLK (match_dup 4))
16930                       (mem:BLK (match_dup 5))))
16931      (use (match_dup 6))
16932      (use (match_dup 3))
16933      (clobber (match_dup 0))
16934      (clobber (match_dup 1))
16935      (clobber (match_dup 2))])])
16937 ;; ...and this one handles cmpstrn*_1.
16938 (define_peephole2
16939   [(parallel[
16940      (set (reg:CC FLAGS_REG)
16941           (if_then_else:CC (ne (match_operand 6 "register_operand")
16942                                (const_int 0))
16943             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16944                         (mem:BLK (match_operand 5 "register_operand")))
16945             (const_int 0)))
16946      (use (match_operand:SI 3 "immediate_operand"))
16947      (use (reg:CC FLAGS_REG))
16948      (clobber (match_operand 0 "register_operand"))
16949      (clobber (match_operand 1 "register_operand"))
16950      (clobber (match_operand 2 "register_operand"))])
16951    (set (match_operand:QI 7 "register_operand")
16952         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16953    (set (match_operand:QI 8 "register_operand")
16954         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16955    (set (reg FLAGS_REG)
16956         (compare (match_dup 7) (match_dup 8)))
16957   ]
16958   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16959   [(parallel[
16960      (set (reg:CC FLAGS_REG)
16961           (if_then_else:CC (ne (match_dup 6)
16962                                (const_int 0))
16963             (compare:CC (mem:BLK (match_dup 4))
16964                         (mem:BLK (match_dup 5)))
16965             (const_int 0)))
16966      (use (match_dup 3))
16967      (use (reg:CC FLAGS_REG))
16968      (clobber (match_dup 0))
16969      (clobber (match_dup 1))
16970      (clobber (match_dup 2))])])
16972 ;; Conditional move instructions.
16974 (define_expand "mov<mode>cc"
16975   [(set (match_operand:SWIM 0 "register_operand")
16976         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16977                            (match_operand:SWIM 2 "<general_operand>")
16978                            (match_operand:SWIM 3 "<general_operand>")))]
16979   ""
16980   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16982 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16983 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16984 ;; So just document what we're doing explicitly.
16986 (define_expand "x86_mov<mode>cc_0_m1"
16987   [(parallel
16988     [(set (match_operand:SWI48 0 "register_operand")
16989           (if_then_else:SWI48
16990             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16991              [(match_operand 1 "flags_reg_operand")
16992               (const_int 0)])
16993             (const_int -1)
16994             (const_int 0)))
16995      (clobber (reg:CC FLAGS_REG))])])
16997 (define_insn "*x86_mov<mode>cc_0_m1"
16998   [(set (match_operand:SWI48 0 "register_operand" "=r")
16999         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17000                              [(reg FLAGS_REG) (const_int 0)])
17001           (const_int -1)
17002           (const_int 0)))
17003    (clobber (reg:CC FLAGS_REG))]
17004   ""
17005   "sbb{<imodesuffix>}\t%0, %0"
17006   ; Since we don't have the proper number of operands for an alu insn,
17007   ; fill in all the blanks.
17008   [(set_attr "type" "alu")
17009    (set_attr "modrm_class" "op0")
17010    (set_attr "use_carry" "1")
17011    (set_attr "pent_pair" "pu")
17012    (set_attr "memory" "none")
17013    (set_attr "imm_disp" "false")
17014    (set_attr "mode" "<MODE>")
17015    (set_attr "length_immediate" "0")])
17017 (define_insn "*x86_mov<mode>cc_0_m1_se"
17018   [(set (match_operand:SWI48 0 "register_operand" "=r")
17019         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17020                              [(reg FLAGS_REG) (const_int 0)])
17021                             (const_int 1)
17022                             (const_int 0)))
17023    (clobber (reg:CC FLAGS_REG))]
17024   ""
17025   "sbb{<imodesuffix>}\t%0, %0"
17026   [(set_attr "type" "alu")
17027    (set_attr "modrm_class" "op0")
17028    (set_attr "use_carry" "1")
17029    (set_attr "pent_pair" "pu")
17030    (set_attr "memory" "none")
17031    (set_attr "imm_disp" "false")
17032    (set_attr "mode" "<MODE>")
17033    (set_attr "length_immediate" "0")])
17035 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17036   [(set (match_operand:SWI48 0 "register_operand" "=r")
17037         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17038                     [(reg FLAGS_REG) (const_int 0)])))
17039    (clobber (reg:CC FLAGS_REG))]
17040   ""
17041   "sbb{<imodesuffix>}\t%0, %0"
17042   [(set_attr "type" "alu")
17043    (set_attr "modrm_class" "op0")
17044    (set_attr "use_carry" "1")
17045    (set_attr "pent_pair" "pu")
17046    (set_attr "memory" "none")
17047    (set_attr "imm_disp" "false")
17048    (set_attr "mode" "<MODE>")
17049    (set_attr "length_immediate" "0")])
17051 (define_insn "*mov<mode>cc_noc"
17052   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17053         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17054                                [(reg FLAGS_REG) (const_int 0)])
17055           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17056           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17057   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17058   "@
17059    cmov%O2%C1\t{%2, %0|%0, %2}
17060    cmov%O2%c1\t{%3, %0|%0, %3}"
17061   [(set_attr "type" "icmov")
17062    (set_attr "mode" "<MODE>")])
17064 (define_insn "*movsicc_noc_zext"
17065   [(set (match_operand:DI 0 "register_operand" "=r,r")
17066         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17067                            [(reg FLAGS_REG) (const_int 0)])
17068           (zero_extend:DI
17069             (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17070           (zero_extend:DI
17071             (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17072   "TARGET_64BIT
17073    && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17074   "@
17075    cmov%O2%C1\t{%2, %k0|%k0, %2}
17076    cmov%O2%c1\t{%3, %k0|%k0, %3}"
17077   [(set_attr "type" "icmov")
17078    (set_attr "mode" "SI")])
17080 ;; Don't do conditional moves with memory inputs.  This splitter helps
17081 ;; register starved x86_32 by forcing inputs into registers before reload.
17082 (define_split
17083   [(set (match_operand:SWI248 0 "register_operand")
17084         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17085                                [(reg FLAGS_REG) (const_int 0)])
17086           (match_operand:SWI248 2 "nonimmediate_operand")
17087           (match_operand:SWI248 3 "nonimmediate_operand")))]
17088   "!TARGET_64BIT && TARGET_CMOVE
17089    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17090    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17091    && can_create_pseudo_p ()
17092    && optimize_insn_for_speed_p ()"
17093   [(set (match_dup 0)
17094         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17096   if (MEM_P (operands[2]))
17097     operands[2] = force_reg (<MODE>mode, operands[2]);
17098   if (MEM_P (operands[3]))
17099     operands[3] = force_reg (<MODE>mode, operands[3]);
17102 (define_insn "*movqicc_noc"
17103   [(set (match_operand:QI 0 "register_operand" "=r,r")
17104         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17105                            [(reg FLAGS_REG) (const_int 0)])
17106                       (match_operand:QI 2 "register_operand" "r,0")
17107                       (match_operand:QI 3 "register_operand" "0,r")))]
17108   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17109   "#"
17110   [(set_attr "type" "icmov")
17111    (set_attr "mode" "QI")])
17113 (define_split
17114   [(set (match_operand:SWI12 0 "register_operand")
17115         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17116                               [(reg FLAGS_REG) (const_int 0)])
17117                       (match_operand:SWI12 2 "register_operand")
17118                       (match_operand:SWI12 3 "register_operand")))]
17119   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17120    && reload_completed"
17121   [(set (match_dup 0)
17122         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17124   operands[0] = gen_lowpart (SImode, operands[0]);
17125   operands[2] = gen_lowpart (SImode, operands[2]);
17126   operands[3] = gen_lowpart (SImode, operands[3]);
17129 ;; Don't do conditional moves with memory inputs
17130 (define_peephole2
17131   [(match_scratch:SWI248 4 "r")
17132    (set (match_operand:SWI248 0 "register_operand")
17133         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17134                                [(reg FLAGS_REG) (const_int 0)])
17135           (match_operand:SWI248 2 "nonimmediate_operand")
17136           (match_operand:SWI248 3 "nonimmediate_operand")))]
17137   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17138    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17139    && optimize_insn_for_speed_p ()"
17140   [(set (match_dup 4) (match_dup 5))
17141    (set (match_dup 0)
17142         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17144   if (MEM_P (operands[2]))
17145     {
17146       operands[5] = operands[2];
17147       operands[2] = operands[4];
17148     }
17149   else if (MEM_P (operands[3]))
17150     {
17151       operands[5] = operands[3];
17152       operands[3] = operands[4];
17153     }
17154   else
17155     gcc_unreachable ();
17158 (define_peephole2
17159   [(match_scratch:SI 4 "r")
17160    (set (match_operand:DI 0 "register_operand")
17161         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17162                            [(reg FLAGS_REG) (const_int 0)])
17163           (zero_extend:DI
17164             (match_operand:SI 2 "nonimmediate_operand"))
17165           (zero_extend:DI
17166             (match_operand:SI 3 "nonimmediate_operand"))))]
17167   "TARGET_64BIT
17168    && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17169    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17170    && optimize_insn_for_speed_p ()"
17171   [(set (match_dup 4) (match_dup 5))
17172    (set (match_dup 0)
17173         (if_then_else:DI (match_dup 1)
17174           (zero_extend:DI (match_dup 2))
17175           (zero_extend:DI (match_dup 3))))]
17177   if (MEM_P (operands[2]))
17178     {
17179       operands[5] = operands[2];
17180       operands[2] = operands[4];
17181     }
17182   else if (MEM_P (operands[3]))
17183     {
17184       operands[5] = operands[3];
17185       operands[3] = operands[4];
17186     }
17187   else
17188     gcc_unreachable ();
17191 (define_expand "mov<mode>cc"
17192   [(set (match_operand:X87MODEF 0 "register_operand")
17193         (if_then_else:X87MODEF
17194           (match_operand 1 "comparison_operator")
17195           (match_operand:X87MODEF 2 "register_operand")
17196           (match_operand:X87MODEF 3 "register_operand")))]
17197   "(TARGET_80387 && TARGET_CMOVE)
17198    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17199   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17201 (define_insn "*movxfcc_1"
17202   [(set (match_operand:XF 0 "register_operand" "=f,f")
17203         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17204                                 [(reg FLAGS_REG) (const_int 0)])
17205                       (match_operand:XF 2 "register_operand" "f,0")
17206                       (match_operand:XF 3 "register_operand" "0,f")))]
17207   "TARGET_80387 && TARGET_CMOVE"
17208   "@
17209    fcmov%F1\t{%2, %0|%0, %2}
17210    fcmov%f1\t{%3, %0|%0, %3}"
17211   [(set_attr "type" "fcmov")
17212    (set_attr "mode" "XF")])
17214 (define_insn "*movdfcc_1"
17215   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17216         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17217                                 [(reg FLAGS_REG) (const_int 0)])
17218                       (match_operand:DF 2 "nonimmediate_operand"
17219                                                "f ,0,rm,0 ,rm,0")
17220                       (match_operand:DF 3 "nonimmediate_operand"
17221                                                "0 ,f,0 ,rm,0, rm")))]
17222   "TARGET_80387 && TARGET_CMOVE
17223    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17224   "@
17225    fcmov%F1\t{%2, %0|%0, %2}
17226    fcmov%f1\t{%3, %0|%0, %3}
17227    #
17228    #
17229    cmov%O2%C1\t{%2, %0|%0, %2}
17230    cmov%O2%c1\t{%3, %0|%0, %3}"
17231   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17232    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17233    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17235 (define_split
17236   [(set (match_operand:DF 0 "general_reg_operand")
17237         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17238                                 [(reg FLAGS_REG) (const_int 0)])
17239                       (match_operand:DF 2 "nonimmediate_operand")
17240                       (match_operand:DF 3 "nonimmediate_operand")))]
17241   "!TARGET_64BIT && reload_completed"
17242   [(set (match_dup 2)
17243         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17244    (set (match_dup 3)
17245         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17247   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17248   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17251 (define_insn "*movsfcc_1_387"
17252   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17253         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17254                                 [(reg FLAGS_REG) (const_int 0)])
17255                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17256                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17257   "TARGET_80387 && TARGET_CMOVE
17258    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17259   "@
17260    fcmov%F1\t{%2, %0|%0, %2}
17261    fcmov%f1\t{%3, %0|%0, %3}
17262    cmov%O2%C1\t{%2, %0|%0, %2}
17263    cmov%O2%c1\t{%3, %0|%0, %3}"
17264   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17265    (set_attr "mode" "SF,SF,SI,SI")])
17267 ;; Don't do conditional moves with memory inputs.  This splitter helps
17268 ;; register starved x86_32 by forcing inputs into registers before reload.
17269 (define_split
17270   [(set (match_operand:MODEF 0 "register_operand")
17271         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17272                               [(reg FLAGS_REG) (const_int 0)])
17273           (match_operand:MODEF 2 "nonimmediate_operand")
17274           (match_operand:MODEF 3 "nonimmediate_operand")))]
17275   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17276    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17277    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17278    && can_create_pseudo_p ()
17279    && optimize_insn_for_speed_p ()"
17280   [(set (match_dup 0)
17281         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17283   if (MEM_P (operands[2]))
17284     operands[2] = force_reg (<MODE>mode, operands[2]);
17285   if (MEM_P (operands[3]))
17286     operands[3] = force_reg (<MODE>mode, operands[3]);
17289 ;; Don't do conditional moves with memory inputs
17290 (define_peephole2
17291   [(match_scratch:MODEF 4 "r")
17292    (set (match_operand:MODEF 0 "general_reg_operand")
17293         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17294                               [(reg FLAGS_REG) (const_int 0)])
17295           (match_operand:MODEF 2 "nonimmediate_operand")
17296           (match_operand:MODEF 3 "nonimmediate_operand")))]
17297   "(<MODE>mode != DFmode || TARGET_64BIT)
17298    && TARGET_80387 && TARGET_CMOVE
17299    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17300    && (MEM_P (operands[2]) || MEM_P (operands[3]))
17301    && optimize_insn_for_speed_p ()"
17302   [(set (match_dup 4) (match_dup 5))
17303    (set (match_dup 0)
17304         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17306   if (MEM_P (operands[2]))
17307     {
17308       operands[5] = operands[2];
17309       operands[2] = operands[4];
17310     }
17311   else if (MEM_P (operands[3]))
17312     {
17313       operands[5] = operands[3];
17314       operands[3] = operands[4];
17315     }
17316   else
17317     gcc_unreachable ();
17320 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17321 ;; the scalar versions to have only XMM registers as operands.
17323 ;; XOP conditional move
17324 (define_insn "*xop_pcmov_<mode>"
17325   [(set (match_operand:MODEF 0 "register_operand" "=x")
17326         (if_then_else:MODEF
17327           (match_operand:MODEF 1 "register_operand" "x")
17328           (match_operand:MODEF 2 "register_operand" "x")
17329           (match_operand:MODEF 3 "register_operand" "x")))]
17330   "TARGET_XOP"
17331   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17332   [(set_attr "type" "sse4arg")])
17334 ;; These versions of the min/max patterns are intentionally ignorant of
17335 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17336 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17337 ;; are undefined in this condition, we're certain this is correct.
17339 (define_insn "<code><mode>3"
17340   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17341         (smaxmin:MODEF
17342           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17343           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17344   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17345   "@
17346    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17347    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17348   [(set_attr "isa" "noavx,avx")
17349    (set_attr "prefix" "orig,vex")
17350    (set_attr "type" "sseadd")
17351    (set_attr "mode" "<MODE>")])
17353 ;; These versions of the min/max patterns implement exactly the operations
17354 ;;   min = (op1 < op2 ? op1 : op2)
17355 ;;   max = (!(op1 < op2) ? op1 : op2)
17356 ;; Their operands are not commutative, and thus they may be used in the
17357 ;; presence of -0.0 and NaN.
17359 (define_int_iterator IEEE_MAXMIN
17360         [UNSPEC_IEEE_MAX
17361          UNSPEC_IEEE_MIN])
17363 (define_int_attr ieee_maxmin
17364         [(UNSPEC_IEEE_MAX "max")
17365          (UNSPEC_IEEE_MIN "min")])
17367 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17368   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17369         (unspec:MODEF
17370           [(match_operand:MODEF 1 "register_operand" "0,v")
17371            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17372           IEEE_MAXMIN))]
17373   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17374   "@
17375    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17376    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17377   [(set_attr "isa" "noavx,avx")
17378    (set_attr "prefix" "orig,maybe_evex")
17379    (set_attr "type" "sseadd")
17380    (set_attr "mode" "<MODE>")])
17382 ;; Make two stack loads independent:
17383 ;;   fld aa              fld aa
17384 ;;   fld %st(0)     ->   fld bb
17385 ;;   fmul bb             fmul %st(1), %st
17387 ;; Actually we only match the last two instructions for simplicity.
17389 (define_peephole2
17390   [(set (match_operand 0 "fp_register_operand")
17391         (match_operand 1 "fp_register_operand"))
17392    (set (match_dup 0)
17393         (match_operator 2 "binary_fp_operator"
17394            [(match_dup 0)
17395             (match_operand 3 "memory_operand")]))]
17396   "REGNO (operands[0]) != REGNO (operands[1])"
17397   [(set (match_dup 0) (match_dup 3))
17398    (set (match_dup 0)
17399         (match_op_dup 2
17400           [(match_dup 5) (match_dup 4)]))]
17402   operands[4] = operands[0];
17403   operands[5] = operands[1];
17405   /* The % modifier is not operational anymore in peephole2's, so we have to
17406      swap the operands manually in the case of addition and multiplication. */
17407   if (COMMUTATIVE_ARITH_P (operands[2]))
17408     std::swap (operands[4], operands[5]);
17411 (define_peephole2
17412   [(set (match_operand 0 "fp_register_operand")
17413         (match_operand 1 "fp_register_operand"))
17414    (set (match_dup 0)
17415         (match_operator 2 "binary_fp_operator"
17416            [(match_operand 3 "memory_operand")
17417             (match_dup 0)]))]
17418   "REGNO (operands[0]) != REGNO (operands[1])"
17419   [(set (match_dup 0) (match_dup 3))
17420    (set (match_dup 0)
17421         (match_op_dup 2
17422           [(match_dup 4) (match_dup 5)]))]
17424   operands[4] = operands[0];
17425   operands[5] = operands[1];
17427   /* The % modifier is not operational anymore in peephole2's, so we have to
17428      swap the operands manually in the case of addition and multiplication. */
17429   if (COMMUTATIVE_ARITH_P (operands[2]))
17430     std::swap (operands[4], operands[5]);
17433 ;; Conditional addition patterns
17434 (define_expand "add<mode>cc"
17435   [(match_operand:SWI 0 "register_operand")
17436    (match_operand 1 "ordered_comparison_operator")
17437    (match_operand:SWI 2 "register_operand")
17438    (match_operand:SWI 3 "const_int_operand")]
17439   ""
17440   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17442 ;; Misc patterns (?)
17444 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17445 ;; Otherwise there will be nothing to keep
17447 ;; [(set (reg ebp) (reg esp))]
17448 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17449 ;;  (clobber (eflags)]
17450 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17452 ;; in proper program order.
17454 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17455   [(set (match_operand:P 0 "register_operand" "=r,r")
17456         (plus:P (match_operand:P 1 "register_operand" "0,r")
17457                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17458    (clobber (reg:CC FLAGS_REG))
17459    (clobber (mem:BLK (scratch)))]
17460   ""
17462   switch (get_attr_type (insn))
17463     {
17464     case TYPE_IMOV:
17465       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17467     case TYPE_ALU:
17468       gcc_assert (rtx_equal_p (operands[0], operands[1]));
17469       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17470         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17472       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17474     default:
17475       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17476       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17477     }
17479   [(set (attr "type")
17480         (cond [(and (eq_attr "alternative" "0")
17481                     (not (match_test "TARGET_OPT_AGU")))
17482                  (const_string "alu")
17483                (match_operand:<MODE> 2 "const0_operand")
17484                  (const_string "imov")
17485               ]
17486               (const_string "lea")))
17487    (set (attr "length_immediate")
17488         (cond [(eq_attr "type" "imov")
17489                  (const_string "0")
17490                (and (eq_attr "type" "alu")
17491                     (match_operand 2 "const128_operand"))
17492                  (const_string "1")
17493               ]
17494               (const_string "*")))
17495    (set_attr "mode" "<MODE>")])
17497 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17498   [(set (match_operand:P 0 "register_operand" "=r")
17499         (minus:P (match_operand:P 1 "register_operand" "0")
17500                  (match_operand:P 2 "register_operand" "r")))
17501    (clobber (reg:CC FLAGS_REG))
17502    (clobber (mem:BLK (scratch)))]
17503   ""
17504   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17505   [(set_attr "type" "alu")
17506    (set_attr "mode" "<MODE>")])
17508 (define_insn "allocate_stack_worker_probe_<mode>"
17509   [(set (match_operand:P 0 "register_operand" "=a")
17510         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17511                             UNSPECV_STACK_PROBE))
17512    (clobber (reg:CC FLAGS_REG))]
17513   "ix86_target_stack_probe ()"
17514   "call\t___chkstk_ms"
17515   [(set_attr "type" "multi")
17516    (set_attr "length" "5")])
17518 (define_expand "allocate_stack"
17519   [(match_operand 0 "register_operand")
17520    (match_operand 1 "general_operand")]
17521   "ix86_target_stack_probe ()"
17523   rtx x;
17525 #ifndef CHECK_STACK_LIMIT
17526 #define CHECK_STACK_LIMIT 0
17527 #endif
17529   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17530       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17531     x = operands[1];
17532   else
17533     {
17534       rtx (*insn) (rtx, rtx);
17536       x = copy_to_mode_reg (Pmode, operands[1]);
17538       insn = (TARGET_64BIT
17539               ? gen_allocate_stack_worker_probe_di
17540               : gen_allocate_stack_worker_probe_si);
17542       emit_insn (insn (x, x));
17543     }
17545   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17546                            stack_pointer_rtx, 0, OPTAB_DIRECT);
17548   if (x != stack_pointer_rtx)
17549     emit_move_insn (stack_pointer_rtx, x);
17551   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17552   DONE;
17555 (define_expand "probe_stack"
17556   [(match_operand 0 "memory_operand")]
17557   ""
17559   rtx (*insn) (rtx, rtx)
17560     = (GET_MODE (operands[0]) == DImode
17561        ? gen_probe_stack_di : gen_probe_stack_si);
17563   emit_insn (insn (operands[0], const0_rtx));
17564   DONE;
17567 ;; Use OR for stack probes, this is shorter.
17568 (define_insn "probe_stack_<mode>"
17569   [(set (match_operand:W 0 "memory_operand" "=m")
17570         (unspec:W [(match_operand:W 1 "const0_operand")]
17571                   UNSPEC_PROBE_STACK))
17572    (clobber (reg:CC FLAGS_REG))]
17573   ""
17574   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17575   [(set_attr "type" "alu1")
17576    (set_attr "mode" "<MODE>")
17577    (set_attr "length_immediate" "1")])
17578   
17579 (define_insn "adjust_stack_and_probe<mode>"
17580   [(set (match_operand:P 0 "register_operand" "=r")
17581         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17582                             UNSPECV_PROBE_STACK_RANGE))
17583    (set (reg:P SP_REG)
17584         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17585    (clobber (reg:CC FLAGS_REG))
17586    (clobber (mem:BLK (scratch)))]
17587   ""
17588   "* return output_adjust_stack_and_probe (operands[0]);"
17589   [(set_attr "type" "multi")])
17591 (define_insn "probe_stack_range<mode>"
17592   [(set (match_operand:P 0 "register_operand" "=r")
17593         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17594                             (match_operand:P 2 "const_int_operand" "n")]
17595                             UNSPECV_PROBE_STACK_RANGE))
17596    (clobber (reg:CC FLAGS_REG))]
17597   ""
17598   "* return output_probe_stack_range (operands[0], operands[2]);"
17599   [(set_attr "type" "multi")])
17601 (define_expand "builtin_setjmp_receiver"
17602   [(label_ref (match_operand 0))]
17603   "!TARGET_64BIT && flag_pic"
17605 #if TARGET_MACHO
17606   if (TARGET_MACHO)
17607     {
17608       rtx xops[3];
17609       rtx_code_label *label_rtx = gen_label_rtx ();
17610       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17611       xops[0] = xops[1] = pic_offset_table_rtx;
17612       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17613       ix86_expand_binary_operator (MINUS, SImode, xops);
17614     }
17615   else
17616 #endif
17617     emit_insn (gen_set_got (pic_offset_table_rtx));
17618   DONE;
17621 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17622 ;; Do not split instructions with mask registers.
17623 (define_split
17624   [(set (match_operand 0 "general_reg_operand")
17625         (match_operator 3 "promotable_binary_operator"
17626            [(match_operand 1 "general_reg_operand")
17627             (match_operand 2 "aligned_operand")]))
17628    (clobber (reg:CC FLAGS_REG))]
17629   "! TARGET_PARTIAL_REG_STALL && reload_completed
17630    && ((GET_MODE (operands[0]) == HImode
17631         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17632             /* ??? next two lines just !satisfies_constraint_K (...) */
17633             || !CONST_INT_P (operands[2])
17634             || satisfies_constraint_K (operands[2])))
17635        || (GET_MODE (operands[0]) == QImode
17636            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17637   [(parallel [(set (match_dup 0)
17638                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17639               (clobber (reg:CC FLAGS_REG))])]
17641   operands[0] = gen_lowpart (SImode, operands[0]);
17642   operands[1] = gen_lowpart (SImode, operands[1]);
17643   if (GET_CODE (operands[3]) != ASHIFT)
17644     operands[2] = gen_lowpart (SImode, operands[2]);
17645   operands[3] = shallow_copy_rtx (operands[3]);
17646   PUT_MODE (operands[3], SImode);
17649 ; Promote the QImode tests, as i386 has encoding of the AND
17650 ; instruction with 32-bit sign-extended immediate and thus the
17651 ; instruction size is unchanged, except in the %eax case for
17652 ; which it is increased by one byte, hence the ! optimize_size.
17653 (define_split
17654   [(set (match_operand 0 "flags_reg_operand")
17655         (match_operator 2 "compare_operator"
17656           [(and (match_operand 3 "aligned_operand")
17657                 (match_operand 4 "const_int_operand"))
17658            (const_int 0)]))
17659    (set (match_operand 1 "register_operand")
17660         (and (match_dup 3) (match_dup 4)))]
17661   "! TARGET_PARTIAL_REG_STALL && reload_completed
17662    && optimize_insn_for_speed_p ()
17663    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17664        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17665    /* Ensure that the operand will remain sign-extended immediate.  */
17666    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17667   [(parallel [(set (match_dup 0)
17668                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17669                                     (const_int 0)]))
17670               (set (match_dup 1)
17671                    (and:SI (match_dup 3) (match_dup 4)))])]
17673   operands[4]
17674     = gen_int_mode (INTVAL (operands[4])
17675                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17676   operands[1] = gen_lowpart (SImode, operands[1]);
17677   operands[3] = gen_lowpart (SImode, operands[3]);
17680 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17681 ; the TEST instruction with 32-bit sign-extended immediate and thus
17682 ; the instruction size would at least double, which is not what we
17683 ; want even with ! optimize_size.
17684 (define_split
17685   [(set (match_operand 0 "flags_reg_operand")
17686         (match_operator 1 "compare_operator"
17687           [(and (match_operand:HI 2 "aligned_operand")
17688                 (match_operand:HI 3 "const_int_operand"))
17689            (const_int 0)]))]
17690   "! TARGET_PARTIAL_REG_STALL && reload_completed
17691    && ! TARGET_FAST_PREFIX
17692    && optimize_insn_for_speed_p ()
17693    /* Ensure that the operand will remain sign-extended immediate.  */
17694    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17695   [(set (match_dup 0)
17696         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17697                          (const_int 0)]))]
17699   operands[3]
17700     = gen_int_mode (INTVAL (operands[3])
17701                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17702   operands[2] = gen_lowpart (SImode, operands[2]);
17705 (define_split
17706   [(set (match_operand 0 "register_operand")
17707         (neg (match_operand 1 "register_operand")))
17708    (clobber (reg:CC FLAGS_REG))]
17709   "! TARGET_PARTIAL_REG_STALL && reload_completed
17710    && (GET_MODE (operands[0]) == HImode
17711        || (GET_MODE (operands[0]) == QImode
17712            && (TARGET_PROMOTE_QImode
17713                || optimize_insn_for_size_p ())))"
17714   [(parallel [(set (match_dup 0)
17715                    (neg:SI (match_dup 1)))
17716               (clobber (reg:CC FLAGS_REG))])]
17718   operands[0] = gen_lowpart (SImode, operands[0]);
17719   operands[1] = gen_lowpart (SImode, operands[1]);
17722 ;; Do not split instructions with mask regs.
17723 (define_split
17724   [(set (match_operand 0 "general_reg_operand")
17725         (not (match_operand 1 "general_reg_operand")))]
17726   "! TARGET_PARTIAL_REG_STALL && reload_completed
17727    && (GET_MODE (operands[0]) == HImode
17728        || (GET_MODE (operands[0]) == QImode
17729            && (TARGET_PROMOTE_QImode
17730                || optimize_insn_for_size_p ())))"
17731   [(set (match_dup 0)
17732         (not:SI (match_dup 1)))]
17734   operands[0] = gen_lowpart (SImode, operands[0]);
17735   operands[1] = gen_lowpart (SImode, operands[1]);
17738 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17739 ;; transform a complex memory operation into two memory to register operations.
17741 ;; Don't push memory operands
17742 (define_peephole2
17743   [(set (match_operand:SWI 0 "push_operand")
17744         (match_operand:SWI 1 "memory_operand"))
17745    (match_scratch:SWI 2 "<r>")]
17746   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17747    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17748   [(set (match_dup 2) (match_dup 1))
17749    (set (match_dup 0) (match_dup 2))])
17751 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17752 ;; SImode pushes.
17753 (define_peephole2
17754   [(set (match_operand:SF 0 "push_operand")
17755         (match_operand:SF 1 "memory_operand"))
17756    (match_scratch:SF 2 "r")]
17757   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17758    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17759   [(set (match_dup 2) (match_dup 1))
17760    (set (match_dup 0) (match_dup 2))])
17762 ;; Don't move an immediate directly to memory when the instruction
17763 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17764 (define_peephole2
17765   [(match_scratch:SWI124 1 "<r>")
17766    (set (match_operand:SWI124 0 "memory_operand")
17767         (const_int 0))]
17768   "optimize_insn_for_speed_p ()
17769    && ((<MODE>mode == HImode
17770        && TARGET_LCP_STALL)
17771        || (!TARGET_USE_MOV0
17772           && TARGET_SPLIT_LONG_MOVES
17773           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17774    && peep2_regno_dead_p (0, FLAGS_REG)"
17775   [(parallel [(set (match_dup 2) (const_int 0))
17776               (clobber (reg:CC FLAGS_REG))])
17777    (set (match_dup 0) (match_dup 1))]
17778   "operands[2] = gen_lowpart (SImode, operands[1]);")
17780 (define_peephole2
17781   [(match_scratch:SWI124 2 "<r>")
17782    (set (match_operand:SWI124 0 "memory_operand")
17783         (match_operand:SWI124 1 "immediate_operand"))]
17784   "optimize_insn_for_speed_p ()
17785    && ((<MODE>mode == HImode
17786        && TARGET_LCP_STALL)
17787        || (TARGET_SPLIT_LONG_MOVES
17788           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17789   [(set (match_dup 2) (match_dup 1))
17790    (set (match_dup 0) (match_dup 2))])
17792 ;; Don't compare memory with zero, load and use a test instead.
17793 (define_peephole2
17794   [(set (match_operand 0 "flags_reg_operand")
17795         (match_operator 1 "compare_operator"
17796           [(match_operand:SI 2 "memory_operand")
17797            (const_int 0)]))
17798    (match_scratch:SI 3 "r")]
17799   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17800   [(set (match_dup 3) (match_dup 2))
17801    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17803 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17804 ;; Don't split NOTs with a displacement operand, because resulting XOR
17805 ;; will not be pairable anyway.
17807 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17808 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17809 ;; so this split helps here as well.
17811 ;; Note: Can't do this as a regular split because we can't get proper
17812 ;; lifetime information then.
17814 (define_peephole2
17815   [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
17816         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
17817   "optimize_insn_for_speed_p ()
17818    && ((TARGET_NOT_UNPAIRABLE
17819         && (!MEM_P (operands[0])
17820             || !memory_displacement_operand (operands[0], <MODE>mode)))
17821        || (TARGET_NOT_VECTORMODE
17822            && long_memory_operand (operands[0], <MODE>mode)))
17823    && peep2_regno_dead_p (0, FLAGS_REG)"
17824   [(parallel [(set (match_dup 0)
17825                    (xor:SWI124 (match_dup 1) (const_int -1)))
17826               (clobber (reg:CC FLAGS_REG))])])
17828 ;; Non pairable "test imm, reg" instructions can be translated to
17829 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17830 ;; byte opcode instead of two, have a short form for byte operands),
17831 ;; so do it for other CPUs as well.  Given that the value was dead,
17832 ;; this should not create any new dependencies.  Pass on the sub-word
17833 ;; versions if we're concerned about partial register stalls.
17835 (define_peephole2
17836   [(set (match_operand 0 "flags_reg_operand")
17837         (match_operator 1 "compare_operator"
17838           [(and:SI (match_operand:SI 2 "register_operand")
17839                    (match_operand:SI 3 "immediate_operand"))
17840            (const_int 0)]))]
17841   "ix86_match_ccmode (insn, CCNOmode)
17842    && (REGNO (operands[2]) != AX_REG
17843        || satisfies_constraint_K (operands[3]))
17844    && peep2_reg_dead_p (1, operands[2])"
17845   [(parallel
17846      [(set (match_dup 0)
17847            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17848                             (const_int 0)]))
17849       (set (match_dup 2)
17850            (and:SI (match_dup 2) (match_dup 3)))])])
17852 ;; We don't need to handle HImode case, because it will be promoted to SImode
17853 ;; on ! TARGET_PARTIAL_REG_STALL
17855 (define_peephole2
17856   [(set (match_operand 0 "flags_reg_operand")
17857         (match_operator 1 "compare_operator"
17858           [(and:QI (match_operand:QI 2 "register_operand")
17859                    (match_operand:QI 3 "immediate_operand"))
17860            (const_int 0)]))]
17861   "! TARGET_PARTIAL_REG_STALL
17862    && ix86_match_ccmode (insn, CCNOmode)
17863    && REGNO (operands[2]) != AX_REG
17864    && peep2_reg_dead_p (1, operands[2])"
17865   [(parallel
17866      [(set (match_dup 0)
17867            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17868                             (const_int 0)]))
17869       (set (match_dup 2)
17870            (and:QI (match_dup 2) (match_dup 3)))])])
17872 (define_peephole2
17873   [(set (match_operand 0 "flags_reg_operand")
17874         (match_operator 1 "compare_operator"
17875           [(and:SI
17876              (zero_extract:SI
17877                (match_operand 2 "QIreg_operand")
17878                (const_int 8)
17879                (const_int 8))
17880              (match_operand 3 "const_int_operand"))
17881            (const_int 0)]))]
17882   "! TARGET_PARTIAL_REG_STALL
17883    && ix86_match_ccmode (insn, CCNOmode)
17884    && REGNO (operands[2]) != AX_REG
17885    && peep2_reg_dead_p (1, operands[2])"
17886   [(parallel [(set (match_dup 0)
17887                    (match_op_dup 1
17888                      [(and:SI
17889                         (zero_extract:SI
17890                           (match_dup 2)
17891                           (const_int 8)
17892                           (const_int 8))
17893                         (match_dup 3))
17894                       (const_int 0)]))
17895               (set (zero_extract:SI (match_dup 2)
17896                                     (const_int 8)
17897                                     (const_int 8))
17898                    (and:SI
17899                      (zero_extract:SI
17900                        (match_dup 2)
17901                        (const_int 8)
17902                        (const_int 8))
17903                      (match_dup 3)))])])
17905 ;; Don't do logical operations with memory inputs.
17906 (define_peephole2
17907   [(match_scratch:SWI 2 "<r>")
17908    (parallel [(set (match_operand:SWI 0 "register_operand")
17909                    (match_operator:SWI 3 "arith_or_logical_operator"
17910                      [(match_dup 0)
17911                       (match_operand:SWI 1 "memory_operand")]))
17912               (clobber (reg:CC FLAGS_REG))])]
17913   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17914   [(set (match_dup 2) (match_dup 1))
17915    (parallel [(set (match_dup 0)
17916                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17917               (clobber (reg:CC FLAGS_REG))])])
17919 (define_peephole2
17920   [(match_scratch:SWI 2 "<r>")
17921    (parallel [(set (match_operand:SWI 0 "register_operand")
17922                    (match_operator:SWI 3 "arith_or_logical_operator"
17923                      [(match_operand:SWI 1 "memory_operand")
17924                       (match_dup 0)]))
17925               (clobber (reg:CC FLAGS_REG))])]
17926   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17927   [(set (match_dup 2) (match_dup 1))
17928    (parallel [(set (match_dup 0)
17929                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17930               (clobber (reg:CC FLAGS_REG))])])
17932 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when
17933 ;; the memory address refers to the destination of the load!
17935 (define_peephole2
17936   [(set (match_operand:SWI 0 "general_reg_operand")
17937         (match_operand:SWI 1 "general_reg_operand"))
17938    (parallel [(set (match_dup 0)
17939                    (match_operator:SWI 3 "commutative_operator"
17940                      [(match_dup 0)
17941                       (match_operand:SWI 2 "memory_operand")]))
17942               (clobber (reg:CC FLAGS_REG))])]
17943   "REGNO (operands[0]) != REGNO (operands[1])
17944    && (<MODE>mode != QImode
17945        || any_QIreg_operand (operands[1], QImode))"
17946   [(set (match_dup 0) (match_dup 4))
17947    (parallel [(set (match_dup 0)
17948                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17949               (clobber (reg:CC FLAGS_REG))])]
17950   "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
17952 (define_peephole2
17953   [(set (match_operand 0 "mmx_reg_operand")
17954         (match_operand 1 "mmx_reg_operand"))
17955    (set (match_dup 0)
17956         (match_operator 3 "commutative_operator"
17957           [(match_dup 0)
17958            (match_operand 2 "memory_operand")]))]
17959   "REGNO (operands[0]) != REGNO (operands[1])"
17960   [(set (match_dup 0) (match_dup 2))
17961    (set (match_dup 0)
17962         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17964 (define_peephole2
17965   [(set (match_operand 0 "sse_reg_operand")
17966         (match_operand 1 "sse_reg_operand"))
17967    (set (match_dup 0)
17968         (match_operator 3 "commutative_operator"
17969           [(match_dup 0)
17970            (match_operand 2 "memory_operand")]))]
17971   "REGNO (operands[0]) != REGNO (operands[1])"
17972   [(set (match_dup 0) (match_dup 2))
17973    (set (match_dup 0)
17974         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17976 ; Don't do logical operations with memory outputs
17978 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17979 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17980 ; the same decoder scheduling characteristics as the original.
17982 (define_peephole2
17983   [(match_scratch:SWI 2 "<r>")
17984    (parallel [(set (match_operand:SWI 0 "memory_operand")
17985                    (match_operator:SWI 3 "arith_or_logical_operator"
17986                      [(match_dup 0)
17987                       (match_operand:SWI 1 "<nonmemory_operand>")]))
17988               (clobber (reg:CC FLAGS_REG))])]
17989   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
17990   [(set (match_dup 2) (match_dup 0))
17991    (parallel [(set (match_dup 2)
17992                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17993               (clobber (reg:CC FLAGS_REG))])
17994    (set (match_dup 0) (match_dup 2))])
17996 (define_peephole2
17997   [(match_scratch:SWI 2 "<r>")
17998    (parallel [(set (match_operand:SWI 0 "memory_operand")
17999                    (match_operator:SWI 3 "arith_or_logical_operator"
18000                      [(match_operand:SWI 1 "<nonmemory_operand>")
18001                       (match_dup 0)]))
18002               (clobber (reg:CC FLAGS_REG))])]
18003   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18004   [(set (match_dup 2) (match_dup 0))
18005    (parallel [(set (match_dup 2)
18006                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18007               (clobber (reg:CC FLAGS_REG))])
18008    (set (match_dup 0) (match_dup 2))])
18010 ;; Attempt to use arith or logical operations with memory outputs with
18011 ;; setting of flags.
18012 (define_peephole2
18013   [(set (match_operand:SWI 0 "register_operand")
18014         (match_operand:SWI 1 "memory_operand"))
18015    (parallel [(set (match_dup 0)
18016                    (match_operator:SWI 3 "plusminuslogic_operator"
18017                      [(match_dup 0)
18018                       (match_operand:SWI 2 "<nonmemory_operand>")]))
18019               (clobber (reg:CC FLAGS_REG))])
18020    (set (match_dup 1) (match_dup 0))
18021    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18022   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18023    && peep2_reg_dead_p (4, operands[0])
18024    && !reg_overlap_mentioned_p (operands[0], operands[1])
18025    && !reg_overlap_mentioned_p (operands[0], operands[2])
18026    && (<MODE>mode != QImode
18027        || immediate_operand (operands[2], QImode)
18028        || any_QIreg_operand (operands[2], QImode))
18029    && ix86_match_ccmode (peep2_next_insn (3),
18030                          (GET_CODE (operands[3]) == PLUS
18031                           || GET_CODE (operands[3]) == MINUS)
18032                          ? CCGOCmode : CCNOmode)"
18033   [(parallel [(set (match_dup 4) (match_dup 6))
18034               (set (match_dup 1) (match_dup 5))])]
18036   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18037   operands[5]
18038     = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18039                       copy_rtx (operands[1]),
18040                       operands[2]);
18041   operands[6]
18042     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18043                        copy_rtx (operands[5]),
18044                        const0_rtx);
18047 ;; Likewise for instances where we have a lea pattern.
18048 (define_peephole2
18049   [(set (match_operand:SWI 0 "register_operand")
18050         (match_operand:SWI 1 "memory_operand"))
18051    (set (match_operand:SWI 3 "register_operand")
18052         (plus:SWI (match_dup 0)
18053                   (match_operand:SWI 2 "<nonmemory_operand>")))
18054    (set (match_dup 1) (match_dup 3))
18055    (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18056   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18057    && peep2_reg_dead_p (4, operands[3])
18058    && (rtx_equal_p (operands[0], operands[3])
18059        || peep2_reg_dead_p (2, operands[0]))
18060    && !reg_overlap_mentioned_p (operands[0], operands[1])
18061    && !reg_overlap_mentioned_p (operands[3], operands[1])
18062    && !reg_overlap_mentioned_p (operands[0], operands[2])
18063    && (<MODE>mode != QImode
18064        || immediate_operand (operands[2], QImode)
18065        || any_QIreg_operand (operands[2], QImode))
18066    && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18067   [(parallel [(set (match_dup 4) (match_dup 6))
18068               (set (match_dup 1) (match_dup 5))])]
18070   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18071   operands[5]
18072     = gen_rtx_PLUS (<MODE>mode,
18073                     copy_rtx (operands[1]),
18074                     operands[2]);
18075   operands[6]
18076     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18077                        copy_rtx (operands[5]),
18078                        const0_rtx);
18081 (define_peephole2
18082   [(parallel [(set (match_operand:SWI 0 "register_operand")
18083                    (match_operator:SWI 2 "plusminuslogic_operator"
18084                      [(match_dup 0)
18085                       (match_operand:SWI 1 "memory_operand")]))
18086               (clobber (reg:CC FLAGS_REG))])
18087    (set (match_dup 1) (match_dup 0))
18088    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18089   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18090    && GET_CODE (operands[2]) != MINUS
18091    && peep2_reg_dead_p (3, operands[0])
18092    && !reg_overlap_mentioned_p (operands[0], operands[1])
18093    && ix86_match_ccmode (peep2_next_insn (2),
18094                          GET_CODE (operands[2]) == PLUS
18095                          ? CCGOCmode : CCNOmode)"
18096   [(parallel [(set (match_dup 3) (match_dup 5))
18097               (set (match_dup 1) (match_dup 4))])]
18099   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18100   operands[4]
18101     = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18102                       copy_rtx (operands[1]),
18103                       operands[0]);
18104   operands[5]
18105     = gen_rtx_COMPARE (GET_MODE (operands[3]),
18106                        copy_rtx (operands[4]),
18107                        const0_rtx);
18110 (define_peephole2
18111   [(set (match_operand:SWI12 0 "register_operand")
18112         (match_operand:SWI12 1 "memory_operand"))
18113    (parallel [(set (match_operand:SI 4 "register_operand")
18114                    (match_operator:SI 3 "plusminuslogic_operator"
18115                      [(match_dup 4)
18116                       (match_operand:SI 2 "nonmemory_operand")]))
18117               (clobber (reg:CC FLAGS_REG))])
18118    (set (match_dup 1) (match_dup 0))
18119    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18120   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18121    && REGNO (operands[0]) == REGNO (operands[4])
18122    && peep2_reg_dead_p (4, operands[0])
18123    && (<MODE>mode != QImode
18124        || immediate_operand (operands[2], SImode)
18125        || any_QIreg_operand (operands[2], SImode))
18126    && !reg_overlap_mentioned_p (operands[0], operands[1])
18127    && !reg_overlap_mentioned_p (operands[0], operands[2])
18128    && ix86_match_ccmode (peep2_next_insn (3),
18129                          (GET_CODE (operands[3]) == PLUS
18130                           || GET_CODE (operands[3]) == MINUS)
18131                          ? CCGOCmode : CCNOmode)"
18132   [(parallel [(set (match_dup 4) (match_dup 6))
18133               (set (match_dup 1) (match_dup 5))])]
18135   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18136   operands[5]
18137     = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18138                       copy_rtx (operands[1]),
18139                       gen_lowpart (<MODE>mode, operands[2]));
18140   operands[6]
18141     = gen_rtx_COMPARE (GET_MODE (operands[4]),
18142                        copy_rtx (operands[5]),
18143                        const0_rtx);
18146 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18147 (define_peephole2
18148   [(set (match_operand 0 "general_reg_operand")
18149         (match_operand 1 "const0_operand"))]
18150   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18151    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18152    && peep2_regno_dead_p (0, FLAGS_REG)"
18153   [(parallel [(set (match_dup 0) (const_int 0))
18154               (clobber (reg:CC FLAGS_REG))])]
18155   "operands[0] = gen_lowpart (word_mode, operands[0]);")
18157 (define_peephole2
18158   [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18159         (const_int 0))]
18160   "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18161    && peep2_regno_dead_p (0, FLAGS_REG)"
18162   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18163               (clobber (reg:CC FLAGS_REG))])])
18165 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18166 (define_peephole2
18167   [(set (match_operand:SWI248 0 "general_reg_operand")
18168         (const_int -1))]
18169   "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18170    && peep2_regno_dead_p (0, FLAGS_REG)"
18171   [(parallel [(set (match_dup 0) (const_int -1))
18172               (clobber (reg:CC FLAGS_REG))])]
18174   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18175     operands[0] = gen_lowpart (SImode, operands[0]);
18178 ;; Attempt to convert simple lea to add/shift.
18179 ;; These can be created by move expanders.
18180 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18181 ;; relevant lea instructions were already split.
18183 (define_peephole2
18184   [(set (match_operand:SWI48 0 "register_operand")
18185         (plus:SWI48 (match_dup 0)
18186                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
18187   "!TARGET_OPT_AGU
18188    && peep2_regno_dead_p (0, FLAGS_REG)"
18189   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18190               (clobber (reg:CC FLAGS_REG))])])
18192 (define_peephole2
18193   [(set (match_operand:SWI48 0 "register_operand")
18194         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18195                     (match_dup 0)))]
18196   "!TARGET_OPT_AGU
18197    && peep2_regno_dead_p (0, FLAGS_REG)"
18198   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18199               (clobber (reg:CC FLAGS_REG))])])
18201 (define_peephole2
18202   [(set (match_operand:DI 0 "register_operand")
18203         (zero_extend:DI
18204           (plus:SI (match_operand:SI 1 "register_operand")
18205                    (match_operand:SI 2 "nonmemory_operand"))))]
18206   "TARGET_64BIT && !TARGET_OPT_AGU
18207    && REGNO (operands[0]) == REGNO (operands[1])
18208    && peep2_regno_dead_p (0, FLAGS_REG)"
18209   [(parallel [(set (match_dup 0)
18210                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18211               (clobber (reg:CC FLAGS_REG))])])
18213 (define_peephole2
18214   [(set (match_operand:DI 0 "register_operand")
18215         (zero_extend:DI
18216           (plus:SI (match_operand:SI 1 "nonmemory_operand")
18217                    (match_operand:SI 2 "register_operand"))))]
18218   "TARGET_64BIT && !TARGET_OPT_AGU
18219    && REGNO (operands[0]) == REGNO (operands[2])
18220    && peep2_regno_dead_p (0, FLAGS_REG)"
18221   [(parallel [(set (match_dup 0)
18222                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18223               (clobber (reg:CC FLAGS_REG))])])
18225 (define_peephole2
18226   [(set (match_operand:SWI48 0 "register_operand")
18227         (mult:SWI48 (match_dup 0)
18228                     (match_operand:SWI48 1 "const_int_operand")))]
18229   "exact_log2 (INTVAL (operands[1])) >= 0
18230    && peep2_regno_dead_p (0, FLAGS_REG)"
18231   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18232               (clobber (reg:CC FLAGS_REG))])]
18233   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18235 (define_peephole2
18236   [(set (match_operand:DI 0 "register_operand")
18237         (zero_extend:DI
18238           (mult:SI (match_operand:SI 1 "register_operand")
18239                    (match_operand:SI 2 "const_int_operand"))))]
18240   "TARGET_64BIT
18241    && exact_log2 (INTVAL (operands[2])) >= 0
18242    && REGNO (operands[0]) == REGNO (operands[1])
18243    && peep2_regno_dead_p (0, FLAGS_REG)"
18244   [(parallel [(set (match_dup 0)
18245                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18246               (clobber (reg:CC FLAGS_REG))])]
18247   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18249 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18250 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18251 ;; On many CPUs it is also faster, since special hardware to avoid esp
18252 ;; dependencies is present.
18254 ;; While some of these conversions may be done using splitters, we use
18255 ;; peepholes in order to allow combine_stack_adjustments pass to see
18256 ;; nonobfuscated RTL.
18258 ;; Convert prologue esp subtractions to push.
18259 ;; We need register to push.  In order to keep verify_flow_info happy we have
18260 ;; two choices
18261 ;; - use scratch and clobber it in order to avoid dependencies
18262 ;; - use already live register
18263 ;; We can't use the second way right now, since there is no reliable way how to
18264 ;; verify that given register is live.  First choice will also most likely in
18265 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18266 ;; call clobbered registers are dead.  We may want to use base pointer as an
18267 ;; alternative when no register is available later.
18269 (define_peephole2
18270   [(match_scratch:W 1 "r")
18271    (parallel [(set (reg:P SP_REG)
18272                    (plus:P (reg:P SP_REG)
18273                            (match_operand:P 0 "const_int_operand")))
18274               (clobber (reg:CC FLAGS_REG))
18275               (clobber (mem:BLK (scratch)))])]
18276   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18277    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18278    && !ix86_using_red_zone ()"
18279   [(clobber (match_dup 1))
18280    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18281               (clobber (mem:BLK (scratch)))])])
18283 (define_peephole2
18284   [(match_scratch:W 1 "r")
18285    (parallel [(set (reg:P SP_REG)
18286                    (plus:P (reg:P SP_REG)
18287                            (match_operand:P 0 "const_int_operand")))
18288               (clobber (reg:CC FLAGS_REG))
18289               (clobber (mem:BLK (scratch)))])]
18290   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18291    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18292    && !ix86_using_red_zone ()"
18293   [(clobber (match_dup 1))
18294    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18295    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18296               (clobber (mem:BLK (scratch)))])])
18298 ;; Convert esp subtractions to push.
18299 (define_peephole2
18300   [(match_scratch:W 1 "r")
18301    (parallel [(set (reg:P SP_REG)
18302                    (plus:P (reg:P SP_REG)
18303                            (match_operand:P 0 "const_int_operand")))
18304               (clobber (reg:CC FLAGS_REG))])]
18305   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18306    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18307    && !ix86_using_red_zone ()"
18308   [(clobber (match_dup 1))
18309    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18311 (define_peephole2
18312   [(match_scratch:W 1 "r")
18313    (parallel [(set (reg:P SP_REG)
18314                    (plus:P (reg:P SP_REG)
18315                            (match_operand:P 0 "const_int_operand")))
18316               (clobber (reg:CC FLAGS_REG))])]
18317   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18318    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18319    && !ix86_using_red_zone ()"
18320   [(clobber (match_dup 1))
18321    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18322    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18324 ;; Convert epilogue deallocator to pop.
18325 (define_peephole2
18326   [(match_scratch:W 1 "r")
18327    (parallel [(set (reg:P SP_REG)
18328                    (plus:P (reg:P SP_REG)
18329                            (match_operand:P 0 "const_int_operand")))
18330               (clobber (reg:CC FLAGS_REG))
18331               (clobber (mem:BLK (scratch)))])]
18332   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18333    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18334   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18335               (clobber (mem:BLK (scratch)))])])
18337 ;; Two pops case is tricky, since pop causes dependency
18338 ;; on destination register.  We use two registers if available.
18339 (define_peephole2
18340   [(match_scratch:W 1 "r")
18341    (match_scratch:W 2 "r")
18342    (parallel [(set (reg:P SP_REG)
18343                    (plus:P (reg:P SP_REG)
18344                            (match_operand:P 0 "const_int_operand")))
18345               (clobber (reg:CC FLAGS_REG))
18346               (clobber (mem:BLK (scratch)))])]
18347   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18348    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18349   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18350               (clobber (mem:BLK (scratch)))])
18351    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18353 (define_peephole2
18354   [(match_scratch:W 1 "r")
18355    (parallel [(set (reg:P SP_REG)
18356                    (plus:P (reg:P SP_REG)
18357                            (match_operand:P 0 "const_int_operand")))
18358               (clobber (reg:CC FLAGS_REG))
18359               (clobber (mem:BLK (scratch)))])]
18360   "optimize_insn_for_size_p ()
18361    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18362   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18363               (clobber (mem:BLK (scratch)))])
18364    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18366 ;; Convert esp additions to pop.
18367 (define_peephole2
18368   [(match_scratch:W 1 "r")
18369    (parallel [(set (reg:P SP_REG)
18370                    (plus:P (reg:P SP_REG)
18371                            (match_operand:P 0 "const_int_operand")))
18372               (clobber (reg:CC FLAGS_REG))])]
18373   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18374   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18376 ;; Two pops case is tricky, since pop causes dependency
18377 ;; on destination register.  We use two registers if available.
18378 (define_peephole2
18379   [(match_scratch:W 1 "r")
18380    (match_scratch:W 2 "r")
18381    (parallel [(set (reg:P SP_REG)
18382                    (plus:P (reg:P SP_REG)
18383                            (match_operand:P 0 "const_int_operand")))
18384               (clobber (reg:CC FLAGS_REG))])]
18385   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18386   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18387    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18389 (define_peephole2
18390   [(match_scratch:W 1 "r")
18391    (parallel [(set (reg:P SP_REG)
18392                    (plus:P (reg:P SP_REG)
18393                            (match_operand:P 0 "const_int_operand")))
18394               (clobber (reg:CC FLAGS_REG))])]
18395   "optimize_insn_for_size_p ()
18396    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18397   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18398    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18400 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18401 ;; required and register dies.  Similarly for 128 to -128.
18402 (define_peephole2
18403   [(set (match_operand 0 "flags_reg_operand")
18404         (match_operator 1 "compare_operator"
18405           [(match_operand 2 "register_operand")
18406            (match_operand 3 "const_int_operand")]))]
18407   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18408      && incdec_operand (operands[3], GET_MODE (operands[3])))
18409     || (!TARGET_FUSE_CMP_AND_BRANCH
18410         && INTVAL (operands[3]) == 128))
18411    && ix86_match_ccmode (insn, CCGCmode)
18412    && peep2_reg_dead_p (1, operands[2])"
18413   [(parallel [(set (match_dup 0)
18414                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18415               (clobber (match_dup 2))])])
18417 ;; Convert imul by three, five and nine into lea
18418 (define_peephole2
18419   [(parallel
18420     [(set (match_operand:SWI48 0 "register_operand")
18421           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18422                       (match_operand:SWI48 2 "const359_operand")))
18423      (clobber (reg:CC FLAGS_REG))])]
18424   "!TARGET_PARTIAL_REG_STALL
18425    || <MODE>mode == SImode
18426    || optimize_function_for_size_p (cfun)"
18427   [(set (match_dup 0)
18428         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18429                     (match_dup 1)))]
18430   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18432 (define_peephole2
18433   [(parallel
18434     [(set (match_operand:SWI48 0 "register_operand")
18435           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18436                       (match_operand:SWI48 2 "const359_operand")))
18437      (clobber (reg:CC FLAGS_REG))])]
18438   "optimize_insn_for_speed_p ()
18439    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18440   [(set (match_dup 0) (match_dup 1))
18441    (set (match_dup 0)
18442         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18443                     (match_dup 0)))]
18444   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18446 ;; imul $32bit_imm, mem, reg is vector decoded, while
18447 ;; imul $32bit_imm, reg, reg is direct decoded.
18448 (define_peephole2
18449   [(match_scratch:SWI48 3 "r")
18450    (parallel [(set (match_operand:SWI48 0 "register_operand")
18451                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18452                                (match_operand:SWI48 2 "immediate_operand")))
18453               (clobber (reg:CC FLAGS_REG))])]
18454   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18455    && !satisfies_constraint_K (operands[2])"
18456   [(set (match_dup 3) (match_dup 1))
18457    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18458               (clobber (reg:CC FLAGS_REG))])])
18460 (define_peephole2
18461   [(match_scratch:SI 3 "r")
18462    (parallel [(set (match_operand:DI 0 "register_operand")
18463                    (zero_extend:DI
18464                      (mult:SI (match_operand:SI 1 "memory_operand")
18465                               (match_operand:SI 2 "immediate_operand"))))
18466               (clobber (reg:CC FLAGS_REG))])]
18467   "TARGET_64BIT
18468    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18469    && !satisfies_constraint_K (operands[2])"
18470   [(set (match_dup 3) (match_dup 1))
18471    (parallel [(set (match_dup 0)
18472                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18473               (clobber (reg:CC FLAGS_REG))])])
18475 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18476 ;; Convert it into imul reg, reg
18477 ;; It would be better to force assembler to encode instruction using long
18478 ;; immediate, but there is apparently no way to do so.
18479 (define_peephole2
18480   [(parallel [(set (match_operand:SWI248 0 "register_operand")
18481                    (mult:SWI248
18482                     (match_operand:SWI248 1 "nonimmediate_operand")
18483                     (match_operand:SWI248 2 "const_int_operand")))
18484               (clobber (reg:CC FLAGS_REG))])
18485    (match_scratch:SWI248 3 "r")]
18486   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18487    && satisfies_constraint_K (operands[2])"
18488   [(set (match_dup 3) (match_dup 2))
18489    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18490               (clobber (reg:CC FLAGS_REG))])]
18492   if (!rtx_equal_p (operands[0], operands[1]))
18493     emit_move_insn (operands[0], operands[1]);
18496 ;; After splitting up read-modify operations, array accesses with memory
18497 ;; operands might end up in form:
18498 ;;  sall    $2, %eax
18499 ;;  movl    4(%esp), %edx
18500 ;;  addl    %edx, %eax
18501 ;; instead of pre-splitting:
18502 ;;  sall    $2, %eax
18503 ;;  addl    4(%esp), %eax
18504 ;; Turn it into:
18505 ;;  movl    4(%esp), %edx
18506 ;;  leal    (%edx,%eax,4), %eax
18508 (define_peephole2
18509   [(match_scratch:W 5 "r")
18510    (parallel [(set (match_operand 0 "register_operand")
18511                    (ashift (match_operand 1 "register_operand")
18512                            (match_operand 2 "const_int_operand")))
18513                (clobber (reg:CC FLAGS_REG))])
18514    (parallel [(set (match_operand 3 "register_operand")
18515                    (plus (match_dup 0)
18516                          (match_operand 4 "x86_64_general_operand")))
18517                    (clobber (reg:CC FLAGS_REG))])]
18518   "IN_RANGE (INTVAL (operands[2]), 1, 3)
18519    /* Validate MODE for lea.  */
18520    && ((!TARGET_PARTIAL_REG_STALL
18521         && (GET_MODE (operands[0]) == QImode
18522             || GET_MODE (operands[0]) == HImode))
18523        || GET_MODE (operands[0]) == SImode
18524        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18525    && (rtx_equal_p (operands[0], operands[3])
18526        || peep2_reg_dead_p (2, operands[0]))
18527    /* We reorder load and the shift.  */
18528    && !reg_overlap_mentioned_p (operands[0], operands[4])"
18529   [(set (match_dup 5) (match_dup 4))
18530    (set (match_dup 0) (match_dup 1))]
18532   machine_mode op1mode = GET_MODE (operands[1]);
18533   machine_mode mode = op1mode == DImode ? DImode : SImode;
18534   int scale = 1 << INTVAL (operands[2]);
18535   rtx index = gen_lowpart (word_mode, operands[1]);
18536   rtx base = gen_lowpart (word_mode, operands[5]);
18537   rtx dest = gen_lowpart (mode, operands[3]);
18539   operands[1] = gen_rtx_PLUS (word_mode, base,
18540                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18541   if (mode != word_mode)
18542     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18544   operands[5] = base;
18545   if (op1mode != word_mode)
18546     operands[5] = gen_lowpart (op1mode, operands[5]);
18548   operands[0] = dest;
18551 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18552 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18553 ;; caught for use by garbage collectors and the like.  Using an insn that
18554 ;; maps to SIGILL makes it more likely the program will rightfully die.
18555 ;; Keeping with tradition, "6" is in honor of #UD.
18556 (define_insn "trap"
18557   [(trap_if (const_int 1) (const_int 6))]
18558   ""
18560 #ifdef HAVE_AS_IX86_UD2
18561   return "ud2";
18562 #else
18563   return ASM_SHORT "0x0b0f";
18564 #endif
18566   [(set_attr "length" "2")])
18568 (define_expand "prefetch"
18569   [(prefetch (match_operand 0 "address_operand")
18570              (match_operand:SI 1 "const_int_operand")
18571              (match_operand:SI 2 "const_int_operand"))]
18572   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18574   bool write = INTVAL (operands[1]) != 0;
18575   int locality = INTVAL (operands[2]);
18577   gcc_assert (IN_RANGE (locality, 0, 3));
18579   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18580      supported by SSE counterpart or the SSE prefetch is not available
18581      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18582      of locality.  */
18583   if (TARGET_PREFETCHWT1 && write && locality <= 2)
18584     operands[2] = const2_rtx;
18585   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
18586     operands[2] = GEN_INT (3);
18587   else
18588     operands[1] = const0_rtx;
18591 (define_insn "*prefetch_sse"
18592   [(prefetch (match_operand 0 "address_operand" "p")
18593              (const_int 0)
18594              (match_operand:SI 1 "const_int_operand"))]
18595   "TARGET_PREFETCH_SSE"
18597   static const char * const patterns[4] = {
18598    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18599   };
18601   int locality = INTVAL (operands[1]);
18602   gcc_assert (IN_RANGE (locality, 0, 3));
18604   return patterns[locality];
18606   [(set_attr "type" "sse")
18607    (set_attr "atom_sse_attr" "prefetch")
18608    (set (attr "length_address")
18609         (symbol_ref "memory_address_length (operands[0], false)"))
18610    (set_attr "memory" "none")])
18612 (define_insn "*prefetch_3dnow"
18613   [(prefetch (match_operand 0 "address_operand" "p")
18614              (match_operand:SI 1 "const_int_operand" "n")
18615              (const_int 3))]
18616   "TARGET_PRFCHW"
18618   if (INTVAL (operands[1]) == 0)
18619     return "prefetch\t%a0";
18620   else
18621     return "prefetchw\t%a0";
18623   [(set_attr "type" "mmx")
18624    (set (attr "length_address")
18625         (symbol_ref "memory_address_length (operands[0], false)"))
18626    (set_attr "memory" "none")])
18628 (define_insn "*prefetch_prefetchwt1"
18629   [(prefetch (match_operand 0 "address_operand" "p")
18630              (const_int 1)
18631              (const_int 2))]
18632   "TARGET_PREFETCHWT1"
18633   "prefetchwt1\t%a0";
18634   [(set_attr "type" "sse")
18635    (set (attr "length_address")
18636         (symbol_ref "memory_address_length (operands[0], false)"))
18637    (set_attr "memory" "none")])
18639 (define_expand "stack_protect_set"
18640   [(match_operand 0 "memory_operand")
18641    (match_operand 1 "memory_operand")]
18642   "TARGET_SSP_TLS_GUARD"
18644   rtx (*insn)(rtx, rtx);
18646 #ifdef TARGET_THREAD_SSP_OFFSET
18647   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18648   insn = (TARGET_LP64
18649           ? gen_stack_tls_protect_set_di
18650           : gen_stack_tls_protect_set_si);
18651 #else
18652   insn = (TARGET_LP64
18653           ? gen_stack_protect_set_di
18654           : gen_stack_protect_set_si);
18655 #endif
18657   emit_insn (insn (operands[0], operands[1]));
18658   DONE;
18661 (define_insn "stack_protect_set_<mode>"
18662   [(set (match_operand:PTR 0 "memory_operand" "=m")
18663         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18664                     UNSPEC_SP_SET))
18665    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18666    (clobber (reg:CC FLAGS_REG))]
18667   "TARGET_SSP_TLS_GUARD"
18668   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18669   [(set_attr "type" "multi")])
18671 (define_insn "stack_tls_protect_set_<mode>"
18672   [(set (match_operand:PTR 0 "memory_operand" "=m")
18673         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
18674                     UNSPEC_SP_TLS_SET))
18675    (set (match_scratch:PTR 2 "=&r") (const_int 0))
18676    (clobber (reg:CC FLAGS_REG))]
18677   ""
18678   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18679   [(set_attr "type" "multi")])
18681 (define_expand "stack_protect_test"
18682   [(match_operand 0 "memory_operand")
18683    (match_operand 1 "memory_operand")
18684    (match_operand 2)]
18685   "TARGET_SSP_TLS_GUARD"
18687   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18689   rtx (*insn)(rtx, rtx, rtx);
18691 #ifdef TARGET_THREAD_SSP_OFFSET
18692   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
18693   insn = (TARGET_LP64
18694           ? gen_stack_tls_protect_test_di
18695           : gen_stack_tls_protect_test_si);
18696 #else
18697   insn = (TARGET_LP64
18698           ? gen_stack_protect_test_di
18699           : gen_stack_protect_test_si);
18700 #endif
18702   emit_insn (insn (flags, operands[0], operands[1]));
18704   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18705                                   flags, const0_rtx, operands[2]));
18706   DONE;
18709 (define_insn "stack_protect_test_<mode>"
18710   [(set (match_operand:CCZ 0 "flags_reg_operand")
18711         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18712                      (match_operand:PTR 2 "memory_operand" "m")]
18713                     UNSPEC_SP_TEST))
18714    (clobber (match_scratch:PTR 3 "=&r"))]
18715   "TARGET_SSP_TLS_GUARD"
18716   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18717   [(set_attr "type" "multi")])
18719 (define_insn "stack_tls_protect_test_<mode>"
18720   [(set (match_operand:CCZ 0 "flags_reg_operand")
18721         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18722                      (match_operand:PTR 2 "const_int_operand" "i")]
18723                     UNSPEC_SP_TLS_TEST))
18724    (clobber (match_scratch:PTR 3 "=r"))]
18725   ""
18726   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18727   [(set_attr "type" "multi")])
18729 (define_insn "sse4_2_crc32<mode>"
18730   [(set (match_operand:SI 0 "register_operand" "=r")
18731         (unspec:SI
18732           [(match_operand:SI 1 "register_operand" "0")
18733            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18734           UNSPEC_CRC32))]
18735   "TARGET_SSE4_2 || TARGET_CRC32"
18736   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18737   [(set_attr "type" "sselog1")
18738    (set_attr "prefix_rep" "1")
18739    (set_attr "prefix_extra" "1")
18740    (set (attr "prefix_data16")
18741      (if_then_else (match_operand:HI 2)
18742        (const_string "1")
18743        (const_string "*")))
18744    (set (attr "prefix_rex")
18745      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18746        (const_string "1")
18747        (const_string "*")))
18748    (set_attr "mode" "SI")])
18750 (define_insn "sse4_2_crc32di"
18751   [(set (match_operand:DI 0 "register_operand" "=r")
18752         (unspec:DI
18753           [(match_operand:DI 1 "register_operand" "0")
18754            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18755           UNSPEC_CRC32))]
18756   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18757   "crc32{q}\t{%2, %0|%0, %2}"
18758   [(set_attr "type" "sselog1")
18759    (set_attr "prefix_rep" "1")
18760    (set_attr "prefix_extra" "1")
18761    (set_attr "mode" "DI")])
18763 (define_insn "rdpmc"
18764   [(set (match_operand:DI 0 "register_operand" "=A")
18765         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18766                             UNSPECV_RDPMC))]
18767   "!TARGET_64BIT"
18768   "rdpmc"
18769   [(set_attr "type" "other")
18770    (set_attr "length" "2")])
18772 (define_insn "rdpmc_rex64"
18773   [(set (match_operand:DI 0 "register_operand" "=a")
18774         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18775                             UNSPECV_RDPMC))
18776    (set (match_operand:DI 1 "register_operand" "=d")
18777         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18778   "TARGET_64BIT"
18779   "rdpmc"
18780   [(set_attr "type" "other")
18781    (set_attr "length" "2")])
18783 (define_insn "rdtsc"
18784   [(set (match_operand:DI 0 "register_operand" "=A")
18785         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18786   "!TARGET_64BIT"
18787   "rdtsc"
18788   [(set_attr "type" "other")
18789    (set_attr "length" "2")])
18791 (define_insn "rdtsc_rex64"
18792   [(set (match_operand:DI 0 "register_operand" "=a")
18793         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18794    (set (match_operand:DI 1 "register_operand" "=d")
18795         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18796   "TARGET_64BIT"
18797   "rdtsc"
18798   [(set_attr "type" "other")
18799    (set_attr "length" "2")])
18801 (define_insn "rdtscp"
18802   [(set (match_operand:DI 0 "register_operand" "=A")
18803         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18804    (set (match_operand:SI 1 "register_operand" "=c")
18805         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18806   "!TARGET_64BIT"
18807   "rdtscp"
18808   [(set_attr "type" "other")
18809    (set_attr "length" "3")])
18811 (define_insn "rdtscp_rex64"
18812   [(set (match_operand:DI 0 "register_operand" "=a")
18813         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18814    (set (match_operand:DI 1 "register_operand" "=d")
18815         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18816    (set (match_operand:SI 2 "register_operand" "=c")
18817         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18818   "TARGET_64BIT"
18819   "rdtscp"
18820   [(set_attr "type" "other")
18821    (set_attr "length" "3")])
18823 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18825 ;; FXSR, XSAVE and XSAVEOPT instructions
18827 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18829 (define_insn "fxsave"
18830   [(set (match_operand:BLK 0 "memory_operand" "=m")
18831         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18832   "TARGET_FXSR"
18833   "fxsave\t%0"
18834   [(set_attr "type" "other")
18835    (set_attr "memory" "store")
18836    (set (attr "length")
18837         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18839 (define_insn "fxsave64"
18840   [(set (match_operand:BLK 0 "memory_operand" "=m")
18841         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18842   "TARGET_64BIT && TARGET_FXSR"
18843   "fxsave64\t%0"
18844   [(set_attr "type" "other")
18845    (set_attr "memory" "store")
18846    (set (attr "length")
18847         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18849 (define_insn "fxrstor"
18850   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18851                     UNSPECV_FXRSTOR)]
18852   "TARGET_FXSR"
18853   "fxrstor\t%0"
18854   [(set_attr "type" "other")
18855    (set_attr "memory" "load")
18856    (set (attr "length")
18857         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18859 (define_insn "fxrstor64"
18860   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18861                     UNSPECV_FXRSTOR64)]
18862   "TARGET_64BIT && TARGET_FXSR"
18863   "fxrstor64\t%0"
18864   [(set_attr "type" "other")
18865    (set_attr "memory" "load")
18866    (set (attr "length")
18867         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18869 (define_int_iterator ANY_XSAVE
18870         [UNSPECV_XSAVE
18871          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18872          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18873          (UNSPECV_XSAVES "TARGET_XSAVES")])
18875 (define_int_iterator ANY_XSAVE64
18876         [UNSPECV_XSAVE64
18877          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18878          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18879          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18881 (define_int_attr xsave
18882         [(UNSPECV_XSAVE "xsave")
18883          (UNSPECV_XSAVE64 "xsave64")
18884          (UNSPECV_XSAVEOPT "xsaveopt")
18885          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18886          (UNSPECV_XSAVEC "xsavec")
18887          (UNSPECV_XSAVEC64 "xsavec64")
18888          (UNSPECV_XSAVES "xsaves")
18889          (UNSPECV_XSAVES64 "xsaves64")])
18891 (define_int_iterator ANY_XRSTOR
18892         [UNSPECV_XRSTOR
18893          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18895 (define_int_iterator ANY_XRSTOR64
18896         [UNSPECV_XRSTOR64
18897          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18899 (define_int_attr xrstor
18900         [(UNSPECV_XRSTOR "xrstor")
18901          (UNSPECV_XRSTOR64 "xrstor")
18902          (UNSPECV_XRSTORS "xrstors")
18903          (UNSPECV_XRSTORS64 "xrstors")])
18905 (define_insn "<xsave>"
18906   [(set (match_operand:BLK 0 "memory_operand" "=m")
18907         (unspec_volatile:BLK
18908          [(match_operand:DI 1 "register_operand" "A")]
18909          ANY_XSAVE))]
18910   "!TARGET_64BIT && TARGET_XSAVE"
18911   "<xsave>\t%0"
18912   [(set_attr "type" "other")
18913    (set_attr "memory" "store")
18914    (set (attr "length")
18915         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18917 (define_insn "<xsave>_rex64"
18918   [(set (match_operand:BLK 0 "memory_operand" "=m")
18919         (unspec_volatile:BLK
18920          [(match_operand:SI 1 "register_operand" "a")
18921           (match_operand:SI 2 "register_operand" "d")]
18922          ANY_XSAVE))]
18923   "TARGET_64BIT && TARGET_XSAVE"
18924   "<xsave>\t%0"
18925   [(set_attr "type" "other")
18926    (set_attr "memory" "store")
18927    (set (attr "length")
18928         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18930 (define_insn "<xsave>"
18931   [(set (match_operand:BLK 0 "memory_operand" "=m")
18932         (unspec_volatile:BLK
18933          [(match_operand:SI 1 "register_operand" "a")
18934           (match_operand:SI 2 "register_operand" "d")]
18935          ANY_XSAVE64))]
18936   "TARGET_64BIT && TARGET_XSAVE"
18937   "<xsave>\t%0"
18938   [(set_attr "type" "other")
18939    (set_attr "memory" "store")
18940    (set (attr "length")
18941         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18943 (define_insn "<xrstor>"
18944    [(unspec_volatile:BLK
18945      [(match_operand:BLK 0 "memory_operand" "m")
18946       (match_operand:DI 1 "register_operand" "A")]
18947      ANY_XRSTOR)]
18948   "!TARGET_64BIT && TARGET_XSAVE"
18949   "<xrstor>\t%0"
18950   [(set_attr "type" "other")
18951    (set_attr "memory" "load")
18952    (set (attr "length")
18953         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18955 (define_insn "<xrstor>_rex64"
18956    [(unspec_volatile:BLK
18957      [(match_operand:BLK 0 "memory_operand" "m")
18958       (match_operand:SI 1 "register_operand" "a")
18959       (match_operand:SI 2 "register_operand" "d")]
18960      ANY_XRSTOR)]
18961   "TARGET_64BIT && TARGET_XSAVE"
18962   "<xrstor>\t%0"
18963   [(set_attr "type" "other")
18964    (set_attr "memory" "load")
18965    (set (attr "length")
18966         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18968 (define_insn "<xrstor>64"
18969    [(unspec_volatile:BLK
18970      [(match_operand:BLK 0 "memory_operand" "m")
18971       (match_operand:SI 1 "register_operand" "a")
18972       (match_operand:SI 2 "register_operand" "d")]
18973      ANY_XRSTOR64)]
18974   "TARGET_64BIT && TARGET_XSAVE"
18975   "<xrstor>64\t%0"
18976   [(set_attr "type" "other")
18977    (set_attr "memory" "load")
18978    (set (attr "length")
18979         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18981 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18983 ;; Floating-point instructions for atomic compound assignments
18985 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18987 ; Clobber all floating-point registers on environment save and restore
18988 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18989 (define_insn "fnstenv"
18990   [(set (match_operand:BLK 0 "memory_operand" "=m")
18991         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18992    (clobber (reg:HI FPCR_REG))
18993    (clobber (reg:XF ST0_REG))
18994    (clobber (reg:XF ST1_REG))
18995    (clobber (reg:XF ST2_REG))
18996    (clobber (reg:XF ST3_REG))
18997    (clobber (reg:XF ST4_REG))
18998    (clobber (reg:XF ST5_REG))
18999    (clobber (reg:XF ST6_REG))
19000    (clobber (reg:XF ST7_REG))]
19001   "TARGET_80387"
19002   "fnstenv\t%0"
19003   [(set_attr "type" "other")
19004    (set_attr "memory" "store")
19005    (set (attr "length")
19006         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19008 (define_insn "fldenv"
19009   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19010                     UNSPECV_FLDENV)
19011    (clobber (reg:CCFP FPSR_REG))
19012    (clobber (reg:HI FPCR_REG))
19013    (clobber (reg:XF ST0_REG))
19014    (clobber (reg:XF ST1_REG))
19015    (clobber (reg:XF ST2_REG))
19016    (clobber (reg:XF ST3_REG))
19017    (clobber (reg:XF ST4_REG))
19018    (clobber (reg:XF ST5_REG))
19019    (clobber (reg:XF ST6_REG))
19020    (clobber (reg:XF ST7_REG))]
19021   "TARGET_80387"
19022   "fldenv\t%0"
19023   [(set_attr "type" "other")
19024    (set_attr "memory" "load")
19025    (set (attr "length")
19026         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19028 (define_insn "fnstsw"
19029   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19030         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19031   "TARGET_80387"
19032   "fnstsw\t%0"
19033   [(set_attr "type" "other,other")
19034    (set_attr "memory" "none,store")
19035    (set (attr "length")
19036         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19038 (define_insn "fnclex"
19039   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19040   "TARGET_80387"
19041   "fnclex"
19042   [(set_attr "type" "other")
19043    (set_attr "memory" "none")
19044    (set_attr "length" "2")])
19046 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19048 ;; LWP instructions
19050 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19052 (define_expand "lwp_llwpcb"
19053   [(unspec_volatile [(match_operand 0 "register_operand")]
19054                     UNSPECV_LLWP_INTRINSIC)]
19055   "TARGET_LWP")
19057 (define_insn "*lwp_llwpcb<mode>1"
19058   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19059                     UNSPECV_LLWP_INTRINSIC)]
19060   "TARGET_LWP"
19061   "llwpcb\t%0"
19062   [(set_attr "type" "lwp")
19063    (set_attr "mode" "<MODE>")
19064    (set_attr "length" "5")])
19066 (define_expand "lwp_slwpcb"
19067   [(set (match_operand 0 "register_operand")
19068         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19069   "TARGET_LWP"
19071   rtx (*insn)(rtx);
19073   insn = (Pmode == DImode
19074           ? gen_lwp_slwpcbdi
19075           : gen_lwp_slwpcbsi);
19077   emit_insn (insn (operands[0]));
19078   DONE;
19081 (define_insn "lwp_slwpcb<mode>"
19082   [(set (match_operand:P 0 "register_operand" "=r")
19083         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19084   "TARGET_LWP"
19085   "slwpcb\t%0"
19086   [(set_attr "type" "lwp")
19087    (set_attr "mode" "<MODE>")
19088    (set_attr "length" "5")])
19090 (define_expand "lwp_lwpval<mode>3"
19091   [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19092                      (match_operand:SI 2 "nonimmediate_operand")
19093                      (match_operand:SI 3 "const_int_operand")]
19094                     UNSPECV_LWPVAL_INTRINSIC)]
19095   "TARGET_LWP"
19096   ;; Avoid unused variable warning.
19097   "(void) operands[0];")
19099 (define_insn "*lwp_lwpval<mode>3_1"
19100   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19101                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19102                      (match_operand:SI 2 "const_int_operand" "i")]
19103                     UNSPECV_LWPVAL_INTRINSIC)]
19104   "TARGET_LWP"
19105   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19106   [(set_attr "type" "lwp")
19107    (set_attr "mode" "<MODE>")
19108    (set (attr "length")
19109         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19111 (define_expand "lwp_lwpins<mode>3"
19112   [(set (reg:CCC FLAGS_REG)
19113         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19114                               (match_operand:SI 2 "nonimmediate_operand")
19115                               (match_operand:SI 3 "const_int_operand")]
19116                              UNSPECV_LWPINS_INTRINSIC))
19117    (set (match_operand:QI 0 "nonimmediate_operand")
19118         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19119   "TARGET_LWP")
19121 (define_insn "*lwp_lwpins<mode>3_1"
19122   [(set (reg:CCC FLAGS_REG)
19123         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19124                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19125                               (match_operand:SI 2 "const_int_operand" "i")]
19126                              UNSPECV_LWPINS_INTRINSIC))]
19127   "TARGET_LWP"
19128   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19129   [(set_attr "type" "lwp")
19130    (set_attr "mode" "<MODE>")
19131    (set (attr "length")
19132         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19134 (define_int_iterator RDFSGSBASE
19135         [UNSPECV_RDFSBASE
19136          UNSPECV_RDGSBASE])
19138 (define_int_iterator WRFSGSBASE
19139         [UNSPECV_WRFSBASE
19140          UNSPECV_WRGSBASE])
19142 (define_int_attr fsgs
19143         [(UNSPECV_RDFSBASE "fs")
19144          (UNSPECV_RDGSBASE "gs")
19145          (UNSPECV_WRFSBASE "fs")
19146          (UNSPECV_WRGSBASE "gs")])
19148 (define_insn "rd<fsgs>base<mode>"
19149   [(set (match_operand:SWI48 0 "register_operand" "=r")
19150         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19151   "TARGET_64BIT && TARGET_FSGSBASE"
19152   "rd<fsgs>base\t%0"
19153   [(set_attr "type" "other")
19154    (set_attr "prefix_extra" "2")])
19156 (define_insn "wr<fsgs>base<mode>"
19157   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19158                     WRFSGSBASE)]
19159   "TARGET_64BIT && TARGET_FSGSBASE"
19160   "wr<fsgs>base\t%0"
19161   [(set_attr "type" "other")
19162    (set_attr "prefix_extra" "2")])
19164 (define_insn "rdrand<mode>_1"
19165   [(set (match_operand:SWI248 0 "register_operand" "=r")
19166         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19167    (set (reg:CCC FLAGS_REG)
19168         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19169   "TARGET_RDRND"
19170   "rdrand\t%0"
19171   [(set_attr "type" "other")
19172    (set_attr "prefix_extra" "1")])
19174 (define_insn "rdseed<mode>_1"
19175   [(set (match_operand:SWI248 0 "register_operand" "=r")
19176         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19177    (set (reg:CCC FLAGS_REG)
19178         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19179   "TARGET_RDSEED"
19180   "rdseed\t%0"
19181   [(set_attr "type" "other")
19182    (set_attr "prefix_extra" "1")])
19184 (define_expand "pause"
19185   [(set (match_dup 0)
19186         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19187   ""
19189   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19190   MEM_VOLATILE_P (operands[0]) = 1;
19193 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19194 ;; They have the same encoding.
19195 (define_insn "*pause"
19196   [(set (match_operand:BLK 0)
19197         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19198   ""
19199   "rep%; nop"
19200   [(set_attr "length" "2")
19201    (set_attr "memory" "unknown")])
19203 (define_expand "xbegin"
19204   [(set (match_operand:SI 0 "register_operand")
19205         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19206   "TARGET_RTM"
19208   rtx_code_label *label = gen_label_rtx ();
19210   /* xbegin is emitted as jump_insn, so reload won't be able
19211      to reload its operand.  Force the value into AX hard register.  */
19212   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19213   emit_move_insn (ax_reg, constm1_rtx);
19215   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19217   emit_label (label);
19218   LABEL_NUSES (label) = 1;
19220   emit_move_insn (operands[0], ax_reg);
19222   DONE;
19225 (define_insn "xbegin_1"
19226   [(set (pc)
19227         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19228                           (const_int 0))
19229                       (label_ref (match_operand 1))
19230                       (pc)))
19231    (set (match_operand:SI 0 "register_operand" "+a")
19232         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19233   "TARGET_RTM"
19234   "xbegin\t%l1"
19235   [(set_attr "type" "other")
19236    (set_attr "length" "6")])
19238 (define_insn "xend"
19239   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19240   "TARGET_RTM"
19241   "xend"
19242   [(set_attr "type" "other")
19243    (set_attr "length" "3")])
19245 (define_insn "xabort"
19246   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19247                     UNSPECV_XABORT)]
19248   "TARGET_RTM"
19249   "xabort\t%0"
19250   [(set_attr "type" "other")
19251    (set_attr "length" "3")])
19253 (define_expand "xtest"
19254   [(set (match_operand:QI 0 "register_operand")
19255         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19256   "TARGET_RTM"
19258   emit_insn (gen_xtest_1 ());
19260   ix86_expand_setcc (operands[0], NE,
19261                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19262   DONE;
19265 (define_insn "xtest_1"
19266   [(set (reg:CCZ FLAGS_REG)
19267         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19268   "TARGET_RTM"
19269   "xtest"
19270   [(set_attr "type" "other")
19271    (set_attr "length" "3")])
19273 (define_insn "pcommit"
19274   [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)]
19275   "TARGET_PCOMMIT"
19276   "pcommit"
19277   [(set_attr "type" "other")
19278    (set_attr "length" "4")])
19280 (define_insn "clwb"
19281   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19282                    UNSPECV_CLWB)]
19283   "TARGET_CLWB"
19284   "clwb\t%a0"
19285   [(set_attr "type" "sse")
19286    (set_attr "atom_sse_attr" "fence")
19287    (set_attr "memory" "unknown")])
19289 (define_insn "clflushopt"
19290   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19291                    UNSPECV_CLFLUSHOPT)]
19292   "TARGET_CLFLUSHOPT"
19293   "clflushopt\t%a0"
19294   [(set_attr "type" "sse")
19295    (set_attr "atom_sse_attr" "fence")
19296    (set_attr "memory" "unknown")])
19298 ;; MONITORX and MWAITX
19299 (define_insn "mwaitx"
19300   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19301                      (match_operand:SI 1 "register_operand" "a")
19302                      (match_operand:SI 2 "register_operand" "b")]
19303                    UNSPECV_MWAITX)]
19304   "TARGET_MWAITX"
19305 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19306 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19307 ;; we only need to set up 32bit registers.
19308   "mwaitx"
19309   [(set_attr "length" "3")])
19311 (define_insn "monitorx_<mode>"
19312   [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19313                      (match_operand:SI 1 "register_operand" "c")
19314                      (match_operand:SI 2 "register_operand" "d")]
19315                    UNSPECV_MONITORX)]
19316   "TARGET_MWAITX"
19317 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19318 ;; RCX and RDX are used.  Since 32bit register operands are implicitly
19319 ;; zero extended to 64bit, we only need to set up 32bit registers.
19320   "%^monitorx"
19321   [(set (attr "length")
19322      (symbol_ref ("(Pmode != word_mode) + 3")))])
19324 ;; CLZERO
19325 (define_insn "clzero_<mode>"
19326   [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19327                    UNSPECV_CLZERO)]
19328   "TARGET_CLZERO"
19329   "clzero"
19330   [(set_attr "length" "3")
19331   (set_attr "memory" "unknown")])
19333 ;; MPX instructions
19335 (define_expand "<mode>_mk"
19336   [(set (match_operand:BND 0 "register_operand")
19337         (unspec:BND
19338           [(mem:<bnd_ptr>
19339            (match_par_dup 3
19340              [(match_operand:<bnd_ptr> 1 "register_operand")
19341               (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
19342           UNSPEC_BNDMK))]
19343   "TARGET_MPX"
19345   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19346                                                   operands[2]),
19347                                 UNSPEC_BNDMK_ADDR);
19350 (define_insn "*<mode>_mk"
19351   [(set (match_operand:BND 0 "register_operand" "=w")
19352         (unspec:BND
19353           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19354              [(unspec:<bnd_ptr>
19355                 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
19356                  (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
19357                 UNSPEC_BNDMK_ADDR)])]
19358           UNSPEC_BNDMK))]
19359   "TARGET_MPX"
19360   "bndmk\t{%3, %0|%0, %3}"
19361   [(set_attr "type" "mpxmk")])
19363 (define_expand "mov<mode>"
19364   [(set (match_operand:BND 0 "general_operand")
19365         (match_operand:BND 1 "general_operand"))]
19366   "TARGET_MPX"
19367   "ix86_expand_move (<MODE>mode, operands); DONE;")
19369 (define_insn "*mov<mode>_internal_mpx"
19370   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
19371         (match_operand:BND 1 "general_operand" "wm,w"))]
19372   "TARGET_MPX"
19373   "bndmov\t{%1, %0|%0, %1}"
19374   [(set_attr "type" "mpxmov")])
19376 (define_expand "<mode>_<bndcheck>"
19377   [(parallel
19378      [(unspec
19379         [(match_operand:BND 0 "register_operand")
19380          (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
19381       (set (match_dup 2)
19382            (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
19383   "TARGET_MPX"
19385   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
19386   MEM_VOLATILE_P (operands[2]) = 1;
19389 (define_insn "*<mode>_<bndcheck>"
19390   [(unspec
19391      [(match_operand:BND 0 "register_operand" "w")
19392       (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
19393    (set (match_operand:BLK 2 "bnd_mem_operator")
19394         (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
19395   "TARGET_MPX"
19396   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
19397   [(set_attr "type" "mpxchk")])
19399 (define_expand "<mode>_ldx"
19400   [(parallel
19401      [(set (match_operand:BND 0 "register_operand")
19402            (unspec:BND
19403              [(mem:<bnd_ptr>
19404                 (match_par_dup 3
19405                   [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
19406                    (match_operand:<bnd_ptr> 2 "register_operand")]))]
19407              UNSPEC_BNDLDX))
19408       (use (mem:BLK (match_dup 1)))])]
19409   "TARGET_MPX"
19411   /* Avoid registers which cannot be used as index.  */
19412   if (!index_register_operand (operands[2], Pmode))
19413     operands[2] = copy_addr_to_reg (operands[2]);
19415   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
19416                                                   operands[2]),
19417                                 UNSPEC_BNDLDX_ADDR);
19420 (define_insn "*<mode>_ldx"
19421   [(set (match_operand:BND 0 "register_operand" "=w")
19422         (unspec:BND
19423           [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19424              [(unspec:<bnd_ptr>
19425                 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
19426                  (match_operand:<bnd_ptr> 2 "register_operand" "l")]
19427                 UNSPEC_BNDLDX_ADDR)])]
19428           UNSPEC_BNDLDX))
19429    (use (mem:BLK (match_dup 1)))]
19430   "TARGET_MPX"
19431   "bndldx\t{%3, %0|%0, %3}"
19432   [(set_attr "type" "mpxld")])
19434 (define_expand "<mode>_stx"
19435   [(parallel
19436      [(unspec
19437         [(mem:<bnd_ptr>
19438            (match_par_dup 3
19439              [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
19440               (match_operand:<bnd_ptr> 1 "register_operand")]))
19441          (match_operand:BND 2 "register_operand")]
19442         UNSPEC_BNDSTX)
19443       (set (match_dup 4)
19444            (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
19445   "TARGET_MPX"
19447   /* Avoid registers which cannot be used as index.  */
19448   if (!index_register_operand (operands[1], Pmode))
19449     operands[1] = copy_addr_to_reg (operands[1]);
19451   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
19452                                                   operands[1]),
19453                                 UNSPEC_BNDLDX_ADDR);
19454   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
19455   MEM_VOLATILE_P (operands[4]) = 1;
19458 (define_insn "*<mode>_stx"
19459   [(unspec
19460      [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
19461         [(unspec:<bnd_ptr>
19462            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
19463             (match_operand:<bnd_ptr> 1 "register_operand" "l")]
19464            UNSPEC_BNDLDX_ADDR)])
19465          (match_operand:BND 2 "register_operand" "w")]
19466         UNSPEC_BNDSTX)
19467    (set (match_operand:BLK 4 "bnd_mem_operator")
19468         (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
19469   "TARGET_MPX"
19470   "bndstx\t{%2, %3|%3, %2}"
19471   [(set_attr "type" "mpxst")])
19473 (define_insn "move_size_reloc_<mode>"
19474   [(set (match_operand:SWI48 0 "register_operand" "=r")
19475         (unspec:SWI48
19476           [(match_operand:SWI48 1 "symbol_operand")]
19477         UNSPEC_SIZEOF))]
19478   "TARGET_MPX"
19480   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
19481     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
19482   else
19483     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
19485   [(set_attr "type" "imov")
19486    (set_attr "mode" "<MODE>")])
19488 ;; RDPKRU and WRPKRU
19490 (define_expand "rdpkru"
19491   [(parallel
19492      [(set (match_operand:SI 0 "register_operand")
19493            (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19494       (set (match_dup 2) (const_int 0))])]
19495   "TARGET_PKU"
19497   operands[1] = force_reg (SImode, const0_rtx);
19498   operands[2] = gen_reg_rtx (SImode);
19501 (define_insn "*rdpkru"
19502   [(set (match_operand:SI 0 "register_operand" "=a")
19503         (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19504                             UNSPECV_PKU))
19505    (set (match_operand:SI 1 "register_operand" "=d")
19506         (const_int 0))]
19507   "TARGET_PKU"
19508   "rdpkru"
19509   [(set_attr "type" "other")])
19511 (define_expand "wrpkru"
19512   [(unspec_volatile:SI
19513      [(match_operand:SI 0 "register_operand")
19514       (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19515   "TARGET_PKU"
19517   operands[1] = force_reg (SImode, const0_rtx);
19518   operands[2] = force_reg (SImode, const0_rtx);
19521 (define_insn "*wrpkru"
19522   [(unspec_volatile:SI
19523      [(match_operand:SI 0 "register_operand" "a")
19524       (match_operand:SI 1 "register_operand" "d")
19525       (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19526   "TARGET_PKU"
19527   "wrpkru"
19528   [(set_attr "type" "other")])
19530 (include "mmx.md")
19531 (include "sse.md")
19532 (include "sync.md")